Index: /trunk/include/iprt/process.h
===================================================================
--- /trunk/include/iprt/process.h	(revision 27450)
+++ /trunk/include/iprt/process.h	(revision 27451)
@@ -164,4 +164,6 @@
  * @param   pszAsUser   User to run the process as.  Pass NULL to use the same
  *                      user as the current process.
+ * @param   pszPassword Password for user account to run the process as.
+ *                      Pass NULL to use the same user as the current process.
  * @param   phProcess   Where to store the process handle on successful return.
  *                      The content is not changed on failure.  NULL is allowed.
@@ -172,5 +174,5 @@
 RTR3DECL(int)   RTProcCreateEx(const char *pszExec, const char * const *papszArgs, RTENV hEnv, uint32_t fFlags,
                                PCRTHANDLE phStdIn, PCRTHANDLE phStdOut, PCRTHANDLE phStdErr, const char *pszAsUser,
-                               PRTPROCESS phProcess);
+                               const char *pszPassword, PRTPROCESS phProcess);
 
 /** @name RTProcCreate and RTProcCreateEx flags
Index: /trunk/src/VBox/Runtime/r3/win/process-win.cpp
===================================================================
--- /trunk/src/VBox/Runtime/r3/win/process-win.cpp	(revision 27450)
+++ /trunk/src/VBox/Runtime/r3/win/process-win.cpp	(revision 27451)
@@ -169,5 +169,5 @@
 RTR3DECL(int)   RTProcCreateEx(const char *pszExec, const char * const *papszArgs, RTENV hEnv, uint32_t fFlags,
                                PCRTHANDLE phStdIn, PCRTHANDLE phStdOut, PCRTHANDLE phStdErr, const char *pszAsUser,
-                               PRTPROCESS phProcess)
+                               const char *pszPassword, PRTPROCESS phProcess)
 {
 #if 1 /* needs more work... dinner time. */
@@ -183,5 +183,4 @@
     AssertPtrReturn(papszArgs, VERR_INVALID_PARAMETER);
     /** @todo search the PATH (add flag for this). */
-    AssertPtrNullReturn(pszAsUser, VERR_INVALID_POINTER);
 
     /*
@@ -253,62 +252,117 @@
             if (RT_SUCCESS(rc))
             {
-                HANDLE hToken = INVALID_HANDLE_VALUE;
-                if (pszAsUser)
+                /*
+                 * Get going...
+                 */
+                PROCESS_INFORMATION ProcInfo;
+                RT_ZERO(ProcInfo);
+                BOOL fRc;
+                if (pszAsUser == NULL)
+                    fRc = CreateProcessW(pwszExec,
+                                         pwszCmdLine,
+                                         NULL,         /* pProcessAttributes */
+                                         NULL,         /* pThreadAttributes */
+                                         TRUE,         /* fInheritHandles */
+                                         CREATE_UNICODE_ENVIRONMENT, /* dwCreationFlags */
+                                         pwszzBlock,
+                                         NULL,          /* pCurrentDirectory */
+                                         &StartupInfo,
+                                         &ProcInfo);
+                else
                 {
-                    /** @todo - Maybe use CreateProcessWithLoginW? That'll require a password, but
-                     *        we may need that anyway because it looks like LogonUserW is the only
-                     *        way to get a hToken.  FIXME */
-                    rc = VERR_NOT_IMPLEMENTED;
+                    HANDLE hToken = INVALID_HANDLE_VALUE;
+                    PRTUTF16 pwszUser;
+
+                    rc = RTStrToUtf16(pszAsUser, &pwszUser);                    
+                    if (RT_SUCCESS(rc))
+                    {
+                        PRTUTF16 pwszPassword;
+                        rc = RTStrToUtf16(pszPassword, &pwszPassword);   
+                        if (RT_SUCCESS(rc))
+                        {
+                            /* 
+                             * User needs to be specified in UPN format because we
+                             * don't fill a domain name. 
+                             */
+
+                            /*
+                             * The following rights are needed in order to use
+                             * LogonUserW and CreateProcessAsUserW:
+                             *
+                             * - SE_ASSIGNPRIMARYTOKEN_NAME
+                             * - SE_INCREASE_QUOTA_NAME 
+                             * - SE_TCB_NAME
+                             */
+                            fRc = LogonUserW(pwszUser,
+                                             NULL,      /* lpDomain */
+                                             pszPassword ? pwszPassword : L"",
+                                             LOGON32_LOGON_INTERACTIVE,
+                                             LOGON32_PROVIDER_DEFAULT,
+                                             &hToken);
+                            if (fRc)
+                            {
+                                fRc = CreateProcessAsUserW(hToken,
+                                                           pwszExec,
+                                                           pwszCmdLine,
+                                                           NULL,         /* pProcessAttributes */
+                                                           NULL,         /* pThreadAttributes */
+                                                           TRUE,         /* fInheritHandles */
+                                                           CREATE_UNICODE_ENVIRONMENT, /* dwCreationFlags */
+                                                           pwszzBlock,
+                                                           NULL,         /* pCurrentDirectory */
+                                                           &StartupInfo,
+                                                           &ProcInfo);
+                                if (!fRc)
+                                {
+/* CreateProcessWithLogonW is not available on NT4 ... so enabling the following code
+* would blow up compatibility but is a legitim fallback if the above method isn't working. */
+#if 0
+                                    DWORD dwErr = GetLastError();
+        
+                                    /*
+                                     * If we don't hold enough priviledges to spawn a new
+                                     * process with different credentials we have to use 
+                                     * CreateProcessWithLogonW here.
+                                     *
+                                     * @todo Use fFlags to either use this feature or just fail.
+                                     */
+                                    if (ERROR_PRIVILEGE_NOT_HELD == dwErr)
+                                    {
+                                        fRc = CreateProcessWithLogonW(pwszUser,
+                                                                      NULL,                 /* lpDomain*/
+                                                                      pwszPassword,
+                                                                      LOGON_WITH_PROFILE,   /* dwLogonFlags */
+                                                                      pwszExec,
+                                                                      pwszCmdLine,
+                                                                      CREATE_UNICODE_ENVIRONMENT, /* dwCreationFlags */
+                                                                      pwszzBlock,
+                                                                      NULL,                 /* pCurrentDirectory */
+                                                                      &StartupInfo,
+                                                                      &ProcInfo);
+                                    }
+#endif
+                                }
+                                CloseHandle(hToken);
+                            }
+                            RTUtf16Free(pwszPassword);
+                        }
+                        RTUtf16Free(pwszUser);
+                    }
                 }
-                if (RT_SUCCESS(rc))
+
+                if (fRc)
                 {
-                    /*
-                     * Get going...
-                     */
-                    PROCESS_INFORMATION ProcInfo;
-                    RT_ZERO(ProcInfo);
-                    BOOL fRc;
-                    if (hToken == INVALID_HANDLE_VALUE)
-                        fRc = CreateProcessW(pwszExec,
-                                             pwszCmdLine,
-                                             NULL,         /* pProcessAttributes */
-                                             NULL,         /* pThreadAttributes */
-                                             TRUE,         /* fInheritHandles */
-                                             CREATE_UNICODE_ENVIRONMENT, /* dwCreationFlags */
-                                             pwszzBlock,
-                                             NULL,          /* pCurrentDirectory */
-                                             &StartupInfo,
-                                             &ProcInfo);
-                    else
-                        fRc = CreateProcessAsUserW(hToken,
-                                                   pwszExec,
-                                                   pwszCmdLine,
-                                                   NULL,         /* pProcessAttributes */
-                                                   NULL,         /* pThreadAttributes */
-                                                   TRUE,         /* fInheritHandles */
-                                                   CREATE_UNICODE_ENVIRONMENT, /* dwCreationFlags */
-                                                   pwszzBlock,
-                                                   NULL,          /* pCurrentDirectory */
-                                                   &StartupInfo,
-                                                   &ProcInfo);
-
-                    if (fRc)
+                    CloseHandle(ProcInfo.hThread);
+                    if (phProcess)
                     {
-                        CloseHandle(ProcInfo.hThread);
-                        if (phProcess)
-                        {
-                            /** @todo Remember the process handle and pick it up in RTProcWait. */
-                            *phProcess = ProcInfo.dwProcessId;
-                        }
-                        else
-                            CloseHandle(ProcInfo.hProcess);
-                        rc = VINF_SUCCESS;
+                        /** @todo Remember the process handle and pick it up in RTProcWait. */
+                        *phProcess = ProcInfo.dwProcessId;
                     }
                     else
-                        rc = RTErrConvertFromWin32(GetLastError());
-
-                    if (hToken != INVALID_HANDLE_VALUE)
-                        CloseHandle(hToken);
+                        CloseHandle(ProcInfo.hProcess);
+                    rc = VINF_SUCCESS;
                 }
+                else
+                    rc = RTErrConvertFromWin32(GetLastError());
                 RTUtf16Free(pwszExec);
             }
Index: /trunk/src/VBox/Runtime/testcase/tstRTProcCreateEx.cpp
===================================================================
--- /trunk/src/VBox/Runtime/testcase/tstRTProcCreateEx.cpp	(revision 27450)
+++ /trunk/src/VBox/Runtime/testcase/tstRTProcCreateEx.cpp	(revision 27451)
@@ -130,10 +130,4 @@
             return VERR_AUTHENTICATION_FAILURE;
         }
-        else
-        {
-            RTPrintf("NameSamCompatible: %s\n"
-                     "DomainName: %s\n", 
-                     pszDomain, szUser);
-        }
         RTMemFree(pSid);
         RTMemFree(pszDomain);
@@ -147,5 +141,5 @@
 static void tstRTCreateProcEx5(void)
 {
-    RTTestISub("Impersonation (as user)");
+    RTTestISub("Impersonation (as user \"test\")");
 
     const char * apszArgs[3] =
@@ -158,5 +152,5 @@
     RTPROCESS hProc;
     RTTESTI_CHECK_RC_RETV(RTProcCreateEx(g_szExecName, apszArgs, RTENV_DEFAULT, 0 /*fFlags*/, NULL,
-                                         NULL, NULL, NULL, &hProc), VINF_SUCCESS);
+                                         NULL, NULL, "testcase", "test", &hProc), VINF_SUCCESS);
     RTPROCSTATUS ProcStatus = { -1, RTPROCEXITREASON_ABEND };
     RTTESTI_CHECK_RC(RTProcWait(hProc, RTPROCWAIT_FLAGS_BLOCK, &ProcStatus), VINF_SUCCESS);
@@ -193,5 +187,5 @@
     RTPROCESS hProc;
     RTTESTI_CHECK_RC_RETV(RTProcCreateEx(g_szExecName, g_apszArgs4, RTENV_DEFAULT, 0 /*fFlags*/, NULL,
-                                         NULL, NULL, NULL, &hProc), VINF_SUCCESS);
+                                         NULL, NULL, NULL, NULL, &hProc), VINF_SUCCESS);
     RTPROCSTATUS ProcStatus = { -1, RTPROCEXITREASON_ABEND };
     RTTESTI_CHECK_RC(RTProcWait(hProc, RTPROCWAIT_FLAGS_BLOCK, &ProcStatus), VINF_SUCCESS);
@@ -236,5 +230,5 @@
     RTPROCESS hProc;
     RTTESTI_CHECK_RC_RETV(RTProcCreateEx(g_szExecName, apszArgs, RTENV_DEFAULT, 0 /*fFlags*/, NULL,
-                                         &Handle, &Handle, NULL, &hProc), VINF_SUCCESS);
+                                         &Handle, &Handle, NULL, NULL, &hProc), VINF_SUCCESS);
     RTTESTI_CHECK_RC(RTPipeClose(hPipeW), VINF_SUCCESS);
 
@@ -303,5 +297,5 @@
     RTPROCESS hProc;
     RTTESTI_CHECK_RC_RETV(RTProcCreateEx(g_szExecName, apszArgs, RTENV_DEFAULT, 0 /*fFlags*/, NULL,
-                                         NULL, &Handle, NULL, &hProc), VINF_SUCCESS);
+                                         NULL, &Handle, NULL, NULL, &hProc), VINF_SUCCESS);
     RTTESTI_CHECK_RC(RTPipeClose(hPipeW), VINF_SUCCESS);
 
@@ -369,5 +363,5 @@
     RTPROCESS hProc;
     RTTESTI_CHECK_RC_RETV(RTProcCreateEx(g_szExecName, apszArgs, RTENV_DEFAULT, 0 /*fFlags*/, NULL,
-                                         &Handle, NULL, NULL, &hProc), VINF_SUCCESS);
+                                         &Handle, NULL, NULL, NULL, &hProc), VINF_SUCCESS);
     RTTESTI_CHECK_RC(RTPipeClose(hPipeW), VINF_SUCCESS);
 
