Previous page

Next page

Locate page in Contents

Managing User Access Rights

This topic applies to Parallels Server only,

User authorization (determining user access rights) is performed using OS-level file access permissions. Essentially, a virtual machine is a set of files that a user can read, write, and execute. When determining access rights of a user for a particular virtual machine, Parallels Service looks at the rights the user has on the virtual machine files and uses this information to allow or deny privileges. The Parallels Server Administration Guide has a section that describes the Parallels Server tasks in relation to the file access rights. Using this information, you can determine the tasks that a user is allowed to perform based on the file access rights the user has. The same goal can also be accomplished programmatically through Parallels C API.

The Parallels C API contains a PHT_ACCESS_RIGHTS object that is used to manage user access rights. A handle to it is obtained using the PrlVmCfg_GetAccessRights or the PrlVmInfo_GetAccessRights function. The difference between the two function is that PrlVmInfo_GetAccessRights takes an additional step: obtaining a handle of type PHT_VM_INFO which will also contain the virtual machine state information. If user access rights is all you need, you can use the PrlVmCfg_GetAccessRights function.

The PHT_ACCESS_RIGHTS object provides an easy way of determining access rights for the currently logged in user with the PrlAcl_IsAllowed function. The function allows to specify one of the available virtual machine tasks (defined in the PRL_ALLOWED_VM_COMMAND enumeration) and returns a boolean value indicating whether the user is allowed to perform the task or not. The security is enforced on the server side, so if a user tries to perform a tasks that he/she is not authorized to perform, the access will be denied. You can still use the functionality described here to determine user access rights in advance and use it in accordance with your client application logic.

An administrator of the host has full access rights to all virtual machines. A non-administrative user has full rights to the machines created by him/her and no rights to any other virtual machines by default (these machines will not even be included in the result set when the user requests a list of virtual machines from the host). The host administrator can grant virtual machine access privileges to other users when needed. Currently, the privileges can be granted to all existing users only. It is not possible to set access rights for an individual user through the API. The PrlAcl_SetAccessForOthers function is used to set access rights. The function takes the PHT_ACCESS_RIGHTS object identifying the virtual machine and one of the enumerators from the PRL_VM_ACCESS_FOR_OTHERS enumerations identifying the access level, which includes view, view and run, full access, and no access. Once again, the function sets access rights for all existing users (the users currently present in the Parallels Service user registry). To determine the current access level for other users on a particular virtual machine, use the PrlAcl_GetAccessForOthers function. For the complete set of user access management functions, see the PHT_ACCESS_RIGHTS object description in the Parallels C API Reference guide.

The following sample function demonstrates how to set virtual machine access rights and how to determine access rights on the specified virtual machine for the currently logged in user. The function accepts a virtual machine handle and operates on the referenced virtual machine.

PRL_RESULT AccessRightsSample(PRL_HANDLE hVm)

{

    PRL_HANDLE hJob = PRL_INVALID_HANDLE;

    PRL_HANDLE hAccessRights = PRL_INVALID_HANDLE;

    

    PRL_RESULT ret = PRL_ERR_UNINITIALIZED;

    PRL_RESULT nJobReturnCode = PRL_ERR_UNINITIALIZED;

    

    // Obtain a PHT_VM_CONFIGURATION handle.

    PRL_HANDLE hVmCfg = PRL_INVALID_HANDLE;

    ret = PrlVm_GetConfig(hVm, &hVmCfg);

  

    // Obtain the access rights handle (this will be a

    // handle of type PHT_ACCESS_RIGHTS).

    ret = PrlVmCfg_GetAccessRights(hVmCfg, &hAccessRights);

    if (PRL_FAILED(ret))

    {

        // Handle the error...

        PrlHandle_Free(hVmCfg);

        return -1;

    }

    

    PrlHandle_Free(hVmCfg);

  

    // Get the VM owner name from the access rights handle.

    PRL_CHAR sBuf[1024];

    PRL_UINT32 nBufSize = sizeof(sBuf);

    ret = PrlAcl_GetOwnerName(hAccessRights, sBuf, &nBufSize);

    if (PRL_FAILED(ret))

    {

        // Handle the error...

        PrlHandle_Free(hAccessRights);

        return -1;

    }

    printf("Owner: %s\n", sBuf);

    

    // Change the virtual machine access rights for other users

    // to PAO_VM_SHARED_ON_VIEW_AND_RUN, which means that the

    // users will be able to see the machine in the list and to

    // run it. When this operation completes, we will use

    // PrlAcl_IsAllowed function to determine whether the user

    // is allowed to perform a particular task on the virtual

    // machine.

    PRL_VM_ACCESS_FOR_OTHERS access = PAO_VM_SHARED_ON_VIEW_AND_RUN;

    ret = PrlAcl_SetAccessForOthers(hAccessRights, access);

    if (PRL_FAILED(ret))

    {

        // Handle the error...

        return -1;

    }

    

    // Commit the changes.

    hJob = PrlVm_UpdateSecurity(hVm, hAccessRights);

    ret = PrlJob_Wait(hJob, 1000);

    if (PRL_FAILED(ret))

    {

        // Handle the error...

        return -1;

    }

    // Analyze the result of PrlVm_UpdateSecurity.

    ret = PrlJob_GetRetCode(hJob, &nJobReturnCode);

    PrlHandle_Free(hJob);

    if (PRL_FAILED(ret))

    {

        // Handle the error...

        return -1;

    }

    // Check the job return code.

    if (PRL_FAILED(nJobReturnCode))

    {

        // Handle the error...

        return -1;

    }

    

    // Determine if the current user has the right to

    // start the virtual machine.

    PRL_ALLOWED_VM_COMMAND access_level = PAR_VM_START_ACCESS;

    PRL_BOOL isAllowed = PRL_FALSE;

    ret = PrlAcl_IsAllowed(hAccessRights, access_level, &isAllowed);

    if (PRL_FAILED(ret))

    {

        // Handle the error...

        return -1;

    }

    printf("Can start: %d\n", isAllowed);

    

    // Determine if the current user has the right to

    // delete the specified virtual machine.

    access_level = PAR_VM_DELETE_ACCESS;

    isAllowed = PRL_FALSE;

    ret = PrlAcl_IsAllowed(hAccessRights, access_level, &isAllowed);

    if (PRL_FAILED(ret))

    {

        // Handle the error...

        return -1;

    }

    printf("Can delete: %d\n", isAllowed);

    

    PrlHandle_Free(hAccessRights);

    return 0;

}