Previous page

Next page

Locate page in Contents

Managing Parallels Service Users

This topic applies to Parallels Server only.

Parallels Service doesn't have its own user database. It performs user authentication against the host operating system user database. However, it has a user registry where the user information that relates to Parallels Service operations is kept. The information includes user UUID (Universally Unique ID), user name, the name and path of the virtual machine directory for the user, and two flags indicating if a user is allowed to modify server preferences and use management console application. A new user record is created in the registry for every user as soon as he/she logs in to a Parallels Service for the very first time.

There are two API handles that are used to obtain information about Parallels Service users and to modify some of the user profile parameters. These handles are PHT_USER_INFO and PHT_USER_PROFILE. Both handles are containers that contain information about a user. The difference between the two is PHT_USER_PROFILE is used to obtain information about currently logged in user while PHT_USER_INFO is used to obtain information about a specified user. There are also some differences in the type of the information provided.

Getting the information about the currently logged in user

The information about the currently logged in user can be retrieved using functions of the PHT_USER_PROFILE handle. The following sample demonstrates how to obtain the handle and how to use its functions to retrieve user information. The sample also shows how to set up a default virtual machine directory for the user. Parallels Service automatically assigns a default virtual machine directory (the directory where new virtual machines are created) for every new user. If needed, a user can specify a different directory for his/her virtual machines. At the time of this writing, this is the only property of the Parallels Service user profile that can be modified. Every user profile modification must begin with the PrlSrv_UserProfileBeginEdit function call and end with the PrlSrv_UserProfileCommit call. These two functions are used to prevent collisions with other clients trying to modify the same user profile at the same time.

PRL_RESULT UserProfileSample(const PRL_HANDLE &hServer)

{

    PRL_HANDLE hJob = PRL_INVALID_HANDLE;

    PRL_HANDLE hJobResult = PRL_INVALID_HANDLE;

    PRL_HANDLE hUserProfile = PRL_INVALID_HANDLE;

    

    PRL_RESULT ret = PRL_ERR_UNINITIALIZED;

    PRL_RESULT nJobReturnCode = PRL_ERR_UNINITIALIZED;

    

    // Get user info from the server.

    hJob = PrlSrv_GetUserProfile(hServer);

    

    // Wait for the job to complete.

    ret = PrlJob_Wait(hJob, 1000);

    if (PRL_FAILED(ret))

    {

        // Handle the error...

        return -1;

    }

    

    // Analyze the result of PrlSrv_GetUserProfile.

    ret = PrlJob_GetRetCode(hJob, &nJobReturnCode);

    if (PRL_FAILED(ret))

    {

        // Handle the error...

        PrlHandle_Free(hJob);

        return -1;

    }

    // Check the job return code.

    if (PRL_FAILED(nJobReturnCode))

    {

        // Handle the error...

        PrlHandle_Free(hJob);

        return -1;

    }

    

    // Get job result.

    ret = PrlJob_GetResult(hJob, &hJobResult);

    PrlHandle_Free(hJob);

    if (PRL_FAILED(ret))

    {

        // Handle the error...

        return -1;

    }

    

    // Get the user profile handle (PHT_USER_PROFILE) from

    // the result.

    ret = PrlResult_GetParam(hJobResult, &hUserProfile);

    if (PRL_FAILED(ret))

    {

        // Handle the error...

        PrlHandle_Free(hJobResult);

        return -1;

    }

    

    // Free job result handle.

    PrlHandle_Free(hJobResult);

    

    // See if the user is allowed to modify

    // the Parallels server preferences.

    PRL_BOOL bCanChange = PRL_FALSE;

    ret = PrlUsrCfg_CanChangeSrvSets(hUserProfile, &bCanChange);

    printf("Can modify server preferences: %d\n", bCanChange);

    

    // See if the user is allowed to use management

    // console application.

    ret = PrlUsrCfg_CanUseMngConsole(hUserProfile, &bCanChange);

    printf("Can use management console: %d\n", bCanChange);

    

    // Get the default virtual machine folder

    // for the user.

    PRL_CHAR sBufFolder[1024];

    PRL_UINT32 nBufSize = sizeof(sBufFolder);

    ret = PrlUsrCfg_GetDefaultVmFolder(hUserProfile, sBufFolder, &nBufSize);

    

    // If sBufFolder contains an empty string then this user

    // does not have a default virtual machine folder and is

    // currently using the default virtual machine folder set

    // for this Parallels server. If this is the case, retrieve

    // that folder.

    if (sBufFolder == "")

    {

        ret = PrlUsrCfg_GetVmDirUuid(hUserProfile, sBufFolder, &nBufSize);      

    }

    

    printf("VM folder: %s\n", sBufFolder);

    

    // Modify the name and location of the virtual

    // machine folder.

    // This operation must begin with the

    // PrlSrv_UserProfileBeginEdit that marks the

    // beginning of the operation. This is done to

    // prevent collisions with other sessions trying to

    // modify the same profile at the same time.

    hJob = PrlSrv_UserProfileBeginEdit(hServer);

    ret = PrlJob_Wait(hJob, 1000);

    if (PRL_FAILED(ret))

    {

        // Handle the error...

        PrlHandle_Free(hJob);

        return -1;

    }

    // Analyze the result of PrlSrv_UserProfileBeginEdit.

    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;

    }

    // Set the new virtual machine folder.

    // The folder must already exist on the server.

    ret = PrlUsrCfg_SetDefaultVmFolder(hUserProfile, "/Users/Shared/Parallels/JDoe");

    if (PRL_FAILED(ret))

    {

        // Handle the error...

        PrlHandle_Free(hUserProfile);

        return -1;

    }

    // Finally, commit the changes to the server.

    hJob = PrlSrv_UserProfileCommit(hServer, hUserProfile);

    ret = PrlJob_Wait(hJob, 1000);

    if (PRL_FAILED(ret))

    {

        // Handle the error...

        PrlHandle_Free(hJob);

        return -1;

    }

    // Analyze the result of PrlSrv_UserProfileCommit.

    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;

    }

    

    PrlHandle_Free(hUserProfile);

}

Getting the information about a particular user

The information about a particular Parallels Service user can be obtained using the functions of the PHT_USER_INFO handle. The handle can be obtain using one of the following functions: PrlSrv_GetUserInfo or PrlSrv_GetUserInfoList. The first function takes the user UUID as an input parameter and returns a single handle of type PHT_USER_INFO containing the user information. The second function returns information about all users that exist in the Parallels Service user registry. The information is returned as a list of handles of type PHT_USER_INFO.

The following sample uses the PrlSrv_GetUserInfoList function to obtain information about all users in the Parallels Service user registry. It then iterates through the returned list of PHT_USER_INFO handles and retrieves information about individual users.

PRL_RESULT UserInfoSample(const PRL_HANDLE &hServer)

{

    PRL_HANDLE hJob = PRL_INVALID_HANDLE;

    PRL_HANDLE hJobResult = PRL_INVALID_HANDLE;

    PRL_HANDLE hUserInfo = PRL_INVALID_HANDLE;

    

    PRL_RESULT ret = PRL_ERR_UNINITIALIZED;

    PRL_RESULT nJobReturnCode = PRL_ERR_UNINITIALIZED;

    

    // Get user info from the Parallels Service.

    hJob = PrlSrv_GetUserInfoList(hServer);

    

    // Wait for the job to complete.

    ret = PrlJob_Wait(hJob, 1000);

    if (PRL_FAILED(ret))

    {

        // Handle the error...

        return -1;

    }

    

    // Analyze the result of PrlSrv_GetUserInfoList.

    ret = PrlJob_GetRetCode(hJob, &nJobReturnCode);

    if (PRL_FAILED(ret))

    {

        // Handle the error...

        PrlHandle_Free(hJob);

        return -1;

    }

    // Check the job return code.

    if (PRL_FAILED(nJobReturnCode))

    {

        // Handle the error...

        PrlHandle_Free(hJob);

        return -1;

    }

    

    // Get job result.

    ret = PrlJob_GetResult(hJob, &hJobResult);

    PrlHandle_Free(hJob);

    if (PRL_FAILED(ret))

    {

        // Handle the error...

        return -1;

    }

    

    // Get parameter count (the number of PHT_USER_INFO

    // handles in the result set).

    PRL_UINT32 nParamCount = 0;

    ret = PrlResult_GetParamsCount(hJobResult, &nParamCount);

    

    // Iterate through the list obtaining

    // a handle of type PHT_USER_INFO for

    // each user.

    for (PRL_UINT32 i = 0; i < nParamCount; ++i)

    {

        ret = PrlResult_GetParamByIndex(hJobResult, i, &hUserInfo);

        if (PRL_FAILED(ret))

        {

            // Handle the error...

            return -1;

        }

    

        // Get user UUID.

        PRL_CHAR sBufID[1024];

        PRL_UINT32 nBufSize = sizeof(sBufID);

        ret = PrlUsrInfo_GetUuid(hUserInfo, sBufID, &nBufSize);

        printf("UUID: %s\n", sBufID);

    

        // Get user name.

        PRL_CHAR sBufName[1024];

        nBufSize = sizeof(sBufName);

        PrlUsrInfo_GetName(hUserInfo, sBufName, &nBufSize);

        printf("Name: %s\n", sBufName);

    

        // Get default virtual machine folder

        // for the user.

        PRL_CHAR sBufFolder[1024];

        nBufSize = sizeof(sBufFolder);

        PrlUsrInfo_GetDefaultVmFolder(hUserInfo, sBufFolder, &nBufSize);

        printf("VM folder: %s\n", sBufFolder);

    

        // See if the user is allowed to modify

        // the Parallels server preferences.

        PRL_BOOL bCanChange = PRL_FALSE;

        PrlUsrInfo_CanChangeSrvSets(hUserInfo, &bCanChange);

        printf("Can modify server preferences: %d\n\n", bCanChange);

    

        PrlHandle_Free(hUserInfo);

    }

    PrlHandle_Free(hJobResult);

}