locked
CreateProcessAsUser doesn't work under impersonate while UAC is turned on RRS feed

  • Question

  • Hi guys,
    I've been crazy about this problem for several days, great hands are needed here:-)

    I have a SQLServer CLR stored procedure sp_A which doing the following steps:
    1. Get the access token of SQLContext
    2. Duplicate this token as a primary token
    3. CreateProcessAsUser using this duplicated token to start  processA

    And in the client side I have the following code,
    1. Create a sql connection and use windows authentication
    2. Impersonate to UserA who is a windows admin and also has enough privilege in SQLServer
    3. Invoke the stored procedure sp_A

    The problem is,
    1. If I turn on the UAC under vista(haven't tried win7 yet), the CreateProcessAsUser returns successful and accutally the process was not been started.
    2. If I turn off the UAC, it works
    3. If I don't use impersonation in client code and keep the UAC on, it works too.

    My guess is, when I turn on the UAC, I need to explicitly grant some privilege about start a process to the access token even it's from an admin account.

    Could anyone help me out here? Thank you in advance.

    Sunday, June 14, 2009 2:52 PM

All replies

  • If you use CreateProcessAsUser, the process will start with that user's restricted token and your code will fail if it requiress Administrative rights. You need to use ShellExecute with the runas verb in order to invoke a UAC prompt if the code needs to run with elevated permissions.
    Sunday, June 14, 2009 6:12 PM
  • If you use CreateProcessAsUser, the process will start with that user's restricted token and your code will fail if it requiress Administrative rights. You need to use ShellExecute with the runas verb in order to invoke a UAC prompt if the code needs to run with elevated permissions.
    Thanks, AndyCadley
    But I don't feel like to use ShellExecute because I don't want to prompt a UAC window on the server side.
    The client side program has already run under admin account with sufficient privilege. If the token is restricted because of UAC, how can I get it elevated?
    Monday, June 15, 2009 5:02 AM
  • Try getting the LinkedToken in the Token you provide (hSuToken):


           DWORD dwErrorCode = 0;
           DWORD Size = 0;

           printf("User Token is NOT Elevated; attempting to get Elevated Token.\n");
           GetTokenInformation(hSuToken, TokenLinkedToken, NULL, 0, &Size);
           if (Size)
           {
            TOKEN_LINKED_TOKEN *LinkedToken;
            LinkedToken = (TOKEN_LINKED_TOKEN *)malloc(Size);
            if (GetTokenInformation(hSuToken, TokenLinkedToken, LinkedToken, Size, &Size))
            {
             printf("LinkedToken: 0x%lx\n", LinkedToken->LinkedToken);
             hSuToken = LinkedToken->LinkedToken;
            }
            else
             printf("Error getting token TokenLinkedToken: error code %d\n", GetLastError());
            free(LinkedToken);
           }
           else
           {
            printf("Error getting token TokenLinkedToken: error code %d\n", GetLastError());
           }

    Thursday, July 9, 2009 5:44 PM
  • Does not seem to work. Get the following error

    C:\Users\sturla\Desktop\New folder (2)\UACTest\Debug>GetTokenInfo.exe
    User Token is NOT Elevated; attempting to get Elevated Token.
    GetTokenInformation not ok: error code 24
    LinkedToken: 0x60

    Rewrote the code a bit to check the result of the first GetTokenInformation

    DWORD dwErrorCode = 0;
                DWORD Size = 0;

                HANDLE hSuToken;

                OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY,  &hSuToken);

                printf("User Token is NOT Elevated; attempting to get Elevated Token.\n");
                if (GetTokenInformation(hSuToken, TokenLinkedToken, NULL, 0, &Size))
                {
                    printf("GetTokenInformation ok");
                }
                else
                {
                    printf("GetTokenInformation not ok: error code %d\n", GetLastError());
                   
                }

                if (Size)
                {
                    TOKEN_LINKED_TOKEN* LinkedToken;
                    LinkedToken = (TOKEN_LINKED_TOKEN*)malloc(Size);
                    if (GetTokenInformation(hSuToken, TokenLinkedToken, LinkedToken, Size, &Size))
                    {
                        printf("LinkedToken: 0x%lx\n", LinkedToken->LinkedToken);
                        hSuToken = LinkedToken->LinkedToken;
                    }
                    else
                        printf("Error getting token TokenLinkedToken: error code %d\n", GetLastError());
                    free(LinkedToken);
                }
                else
                {
                    printf("Error getting token TokenLinkedToken: error code %d\n", GetLastError());
                }


    Also wrote a managed version of this code. Same result! The app was run under the administrator role by starting cmd with runas administrator.

    I think the error is the following. Can the third parameter be 0?

    24     The program issued a command but the command length is incorrect.     ERROR_BAD_LENGTH



    Edit: Tested some more and eventhough the first call to GetTokenInformation failed i still get a valid token from the second call.....



    Thursday, December 17, 2009 11:02 AM