- implement LookupPrivilegeName
authorJuan Lang <juan_lang@yahoo.com>
Thu, 4 Nov 2004 04:52:17 +0000 (04:52 +0000)
committerAlexandre Julliard <julliard@winehq.org>
Thu, 4 Nov 2004 04:52:17 +0000 (04:52 +0000)
- correct LookupPrivilegeValue (had a buffer overrun and sometimes
  returned incorrect LUIDs for well-known values)
- make AllocateLocallyUniqueId less obviously incorrect
- add a bunch of test cases

dlls/advapi32/security.c
dlls/advapi32/service.c
dlls/advapi32/tests/security.c
dlls/ntdll/nt.c
include/winternl.h

index 8498ab0a57864af3114f58a7e8d001a191487902..9f6215ec4af2ce1d51b6713b81ed4e00a490d437 100644 (file)
@@ -16,7 +16,6 @@
  * License along with this library; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
- *  FIXME: for all functions thunking down to Rtl* functions:  implement SetLastError()
  */
 
 #include <stdarg.h>
@@ -123,6 +122,10 @@ BOOL ADVAPI_IsLocalComputer(LPCWSTR ServerName)
     {
         return TRUE;
     }
+    else if (!ServerName[0])
+    {
+        return TRUE;
+    }
     else
     {
         DWORD dwSize = MAX_COMPUTERNAME_LENGTH + 1;
@@ -844,26 +847,110 @@ BOOL WINAPI IsValidAcl(IN PACL pAcl)
        ##############################
 */
 
-static const char * const DefaultPrivNames[] =
-{
-    NULL, NULL,
-    "SeCreateTokenPrivilege", "SeAssignPrimaryTokenPrivilege",
-    "SeLockMemoryPrivilege", "SeIncreaseQuotaPrivilege",
-    "SeUnsolicitedInputPrivilege", "SeMachineAccountPrivilege",
-    "SeTcbPrivilege", "SeSecurityPrivilege",
-    "SeTakeOwnershipPrivilege", "SeLoadDriverPrivilege",
-    "SeSystemProfilePrivilege", "SeSystemtimePrivilege",
-    "SeProfileSingleProcessPrivilege", "SeIncreaseBasePriorityPrivilege",
-    "SeCreatePagefilePrivilege", "SeCreatePermanentPrivilege",
-    "SeBackupPrivilege", "SeRestorePrivilege",
-    "SeShutdownPrivilege", "SeDebugPrivilege",
-    "SeAuditPrivilege", "SeSystemEnvironmentPrivilege",
-    "SeChangeNotifyPrivilege", "SeRemoteShutdownPrivilege",
-    "SeUndockPrivilege", "SeSyncAgentPrivilege",
-    "SeEnableDelegationPrivilege", "SeManageVolumePrivilege",
-    "SeImpersonatePrivilege", "SeCreateGlobalPrivilege",
+/******************************************************************************
+ * AllocateLocallyUniqueId [ADVAPI32.@]
+ *
+ * PARAMS
+ *   lpLuid []
+ */
+BOOL WINAPI AllocateLocallyUniqueId( PLUID lpLuid )
+{
+       CallWin32ToNt(NtAllocateLocallyUniqueId(lpLuid));
+}
+
+static const WCHAR SE_CREATE_TOKEN_NAME_W[] =
+ { 'S','e','C','r','e','a','t','e','T','o','k','e','n','P','r','i','v','i','l','e','g','e',0 };
+static const WCHAR SE_ASSIGNPRIMARYTOKEN_NAME_W[] =
+ { 'S','e','A','s','s','i','g','n','P','r','i','m','a','r','y','T','o','k','e','n','P','r','i','v','i','l','e','g','e',0 };
+static const WCHAR SE_LOCK_MEMORY_NAME_W[] =
+ { 'S','e','L','o','c','k','M','e','m','o','r','y','P','r','i','v','i','l','e','g','e',0 };
+static const WCHAR SE_INCREASE_QUOTA_NAME_W[] =
+ { 'S','e','I','n','c','r','e','a','s','e','Q','u','o','t','a','P','r','i','v','i','l','e','g','e',0 };
+static const WCHAR SE_MACHINE_ACCOUNT_NAME_W[] =
+ { 'S','e','M','a','c','h','i','n','e','A','c','c','o','u','n','t','P','r','i','v','i','l','e','g','e',0 };
+static const WCHAR SE_TCB_NAME_W[] =
+ { 'S','e','T','c','b','P','r','i','v','i','l','e','g','e',0 };
+static const WCHAR SE_SECURITY_NAME_W[] =
+ { 'S','e','S','e','c','u','r','i','t','y','P','r','i','v','i','l','e','g','e',0 };
+static const WCHAR SE_TAKE_OWNERSHIP_NAME_W[] =
+ { 'S','e','T','a','k','e','O','w','n','e','r','s','h','i','p','P','r','i','v','i','l','e','g','e',0 };
+static const WCHAR SE_LOAD_DRIVER_NAME_W[] =
+ { 'S','e','L','o','a','d','D','r','i','v','e','r','P','r','i','v','i','l','e','g','e',0 };
+static const WCHAR SE_SYSTEM_PROFILE_NAME_W[] =
+ { 'S','e','S','y','s','t','e','m','P','r','o','f','i','l','e','P','r','i','v','i','l','e','g','e',0 };
+static const WCHAR SE_SYSTEMTIME_NAME_W[] =
+ { 'S','e','S','y','s','t','e','m','t','i','m','e','P','r','i','v','i','l','e','g','e',0 };
+static const WCHAR SE_PROF_SINGLE_PROCESS_NAME_W[] =
+ { 'S','e','P','r','o','f','i','l','e','S','i','n','g','l','e','P','r','o','c','e','s','s','P','r','i','v','i','l','e','g','e',0 };
+static const WCHAR SE_INC_BASE_PRIORITY_NAME_W[] =
+ { 'S','e','I','n','c','r','e','a','s','e','B','a','s','e','P','r','i','o','r','i','t','y','P','r','i','v','i','l','e','g','e',0 };
+static const WCHAR SE_CREATE_PAGEFILE_NAME_W[] =
+ { 'S','e','C','r','e','a','t','e','P','a','g','e','f','i','l','e','P','r','i','v','i','l','e','g','e',0 };
+static const WCHAR SE_CREATE_PERMANENT_NAME_W[] =
+ { 'S','e','C','r','e','a','t','e','P','e','r','m','a','n','e','n','t','P','r','i','v','i','l','e','g','e',0 };
+static const WCHAR SE_BACKUP_NAME_W[] =
+ { 'S','e','B','a','c','k','u','p','P','r','i','v','i','l','e','g','e',0 };
+static const WCHAR SE_RESTORE_NAME_W[] =
+ { 'S','e','R','e','s','t','o','r','e','P','r','i','v','i','l','e','g','e',0 };
+static const WCHAR SE_SHUTDOWN_NAME_W[] =
+ { 'S','e','S','h','u','t','d','o','w','n','P','r','i','v','i','l','e','g','e',0 };
+static const WCHAR SE_DEBUG_NAME_W[] =
+ { 'S','e','D','e','b','u','g','P','r','i','v','i','l','e','g','e',0 };
+static const WCHAR SE_AUDIT_NAME_W[] =
+ { 'S','e','A','u','d','i','t','P','r','i','v','i','l','e','g','e',0 };
+static const WCHAR SE_SYSTEM_ENVIRONMENT_NAME_W[] =
+ { 'S','e','S','y','s','t','e','m','E','n','v','i','r','o','n','m','e','n','t','P','r','i','v','i','l','e','g','e',0 };
+static const WCHAR SE_CHANGE_NOTIFY_NAME_W[] =
+ { 'S','e','C','h','a','n','g','e','N','o','t','i','f','y','P','r','i','v','i','l','e','g','e',0 };
+static const WCHAR SE_REMOTE_SHUTDOWN_NAME_W[] =
+ { 'S','e','R','e','m','o','t','e','S','h','u','t','d','o','w','n','P','r','i','v','i','l','e','g','e',0 };
+static const WCHAR SE_UNDOCK_NAME_W[] =
+ { 'S','e','U','n','d','o','c','k','P','r','i','v','i','l','e','g','e',0 };
+static const WCHAR SE_SYNC_AGENT_NAME_W[] =
+ { 'S','e','S','y','n','c','A','g','e','n','t','P','r','i','v','i','l','e','g','e',0 };
+static const WCHAR SE_ENABLE_DELEGATION_NAME_W[] =
+ { 'S','e','E','n','a','b','l','e','D','e','l','e','g','a','t','i','o','n','P','r','i','v','i','l','e','g','e',0 };
+static const WCHAR SE_MANAGE_VOLUME_NAME_W[] =
+ { 'S','e','M','a','n','a','g','e','V','o','l','u','m','e','P','r','i','v','i','l','e','g','e',0 };
+static const WCHAR SE_IMPERSONATE_NAME_W[] =
+ { 'S','e','I','m','p','e','r','s','o','n','a','t','e','P','r','i','v','i','l','e','g','e',0 };
+static const WCHAR SE_CREATE_GLOBAL_NAME_W[] =
+ { 'S','e','C','r','e','a','t','e','G','l','o','b','a','l','P','r','i','v','i','l','e','g','e',0 };
+
+static const WCHAR * const WellKnownPrivNames[SE_MAX_WELL_KNOWN_PRIVILEGE + 1] =
+{
+    NULL,
+    NULL,
+    SE_CREATE_TOKEN_NAME_W,
+    SE_ASSIGNPRIMARYTOKEN_NAME_W,
+    SE_LOCK_MEMORY_NAME_W,
+    SE_INCREASE_QUOTA_NAME_W,
+    SE_MACHINE_ACCOUNT_NAME_W,
+    SE_TCB_NAME_W,
+    SE_SECURITY_NAME_W,
+    SE_TAKE_OWNERSHIP_NAME_W,
+    SE_LOAD_DRIVER_NAME_W,
+    SE_SYSTEM_PROFILE_NAME_W,
+    SE_SYSTEMTIME_NAME_W,
+    SE_PROF_SINGLE_PROCESS_NAME_W,
+    SE_INC_BASE_PRIORITY_NAME_W,
+    SE_CREATE_PAGEFILE_NAME_W,
+    SE_CREATE_PERMANENT_NAME_W,
+    SE_BACKUP_NAME_W,
+    SE_RESTORE_NAME_W,
+    SE_SHUTDOWN_NAME_W,
+    SE_DEBUG_NAME_W,
+    SE_AUDIT_NAME_W,
+    SE_SYSTEM_ENVIRONMENT_NAME_W,
+    SE_CHANGE_NOTIFY_NAME_W,
+    SE_REMOTE_SHUTDOWN_NAME_W,
+    SE_UNDOCK_NAME_W,
+    SE_SYNC_AGENT_NAME_W,
+    SE_ENABLE_DELEGATION_NAME_W,
+    SE_MANAGE_VOLUME_NAME_W,
+    SE_IMPERSONATE_NAME_W,
+    SE_CREATE_GLOBAL_NAME_W,
 };
-#define NUMPRIVS (sizeof DefaultPrivNames/sizeof DefaultPrivNames[0])
 
 /******************************************************************************
  * LookupPrivilegeValueW                       [ADVAPI32.@]
@@ -874,17 +961,24 @@ BOOL WINAPI
 LookupPrivilegeValueW( LPCWSTR lpSystemName, LPCWSTR lpName, PLUID lpLuid )
 {
     UINT i;
-    WCHAR priv[0x28];
 
     TRACE("%s,%s,%p\n",debugstr_w(lpSystemName), debugstr_w(lpName), lpLuid);
 
-    for( i=0; i<NUMPRIVS; i++ )
+    if (!ADVAPI_IsLocalComputer(lpSystemName))
+    {
+        SetLastError(RPC_S_SERVER_UNAVAILABLE);
+        return FALSE;
+    }
+    if (!lpName)
     {
-        if( !DefaultPrivNames[i] )
+        SetLastError(ERROR_NO_SUCH_PRIVILEGE);
+        return FALSE;
+    }
+    for( i=SE_MIN_WELL_KNOWN_PRIVILEGE; i<SE_MAX_WELL_KNOWN_PRIVILEGE; i++ )
+    {
+        if( !WellKnownPrivNames[i] )
             continue;
-        MultiByteToWideChar( CP_ACP, 0, DefaultPrivNames[i], -1,
-                             priv, sizeof priv );
-        if( strcmpW( priv, lpName) )
+        if( strcmpiW( WellKnownPrivNames[i], lpName) )
             continue;
         lpLuid->LowPart = i;
         lpLuid->HighPart = 0;
@@ -892,6 +986,7 @@ LookupPrivilegeValueW( LPCWSTR lpSystemName, LPCWSTR lpName, PLUID lpLuid )
                lpLuid->HighPart, lpLuid->LowPart );
         return TRUE;
     }
+    SetLastError(ERROR_NO_SUCH_PRIVILEGE);
     return FALSE;
 }
 
@@ -927,22 +1022,116 @@ LookupPrivilegeValueA( LPCSTR lpSystemName, LPCSTR lpName, PLUID lpLuid )
 
 /******************************************************************************
  * LookupPrivilegeNameA                        [ADVAPI32.@]
+ *
+ * See LookupPrivilegeNameW
  */
 BOOL WINAPI
-LookupPrivilegeNameA( LPCSTR lpSystemName, PLUID lpLuid, LPSTR lpName, LPDWORD cchName)
+LookupPrivilegeNameA( LPCSTR lpSystemName, PLUID lpLuid, LPSTR lpName,
+ LPDWORD cchName)
 {
-    FIXME("%s %p %p %p\n", debugstr_a(lpSystemName), lpLuid, lpName, cchName);
-    return FALSE;
+    UNICODE_STRING lpSystemNameW;
+    BOOL ret;
+    DWORD wLen = 0;
+
+    TRACE("%s %p %p %p\n", debugstr_a(lpSystemName), lpLuid, lpName, cchName);
+
+    RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW, lpSystemName);
+    ret = LookupPrivilegeNameW(lpSystemNameW.Buffer, lpLuid, NULL, &wLen);
+    if (!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
+    {
+        LPWSTR lpNameW = HeapAlloc(GetProcessHeap(), 0, wLen * sizeof(WCHAR));
+
+        ret = LookupPrivilegeNameW(lpSystemNameW.Buffer, lpLuid, lpNameW,
+         &wLen);
+        if (ret)
+        {
+            /* Windows crashes if cchName is NULL, so will I */
+            int len = WideCharToMultiByte(CP_ACP, 0, lpNameW, -1, lpName,
+             *cchName, NULL, NULL);
+
+            if (len == 0)
+            {
+                /* WideCharToMultiByte failed */
+                ret = FALSE;
+            }
+            else if (len > *cchName)
+            {
+                *cchName = len;
+                SetLastError(ERROR_INSUFFICIENT_BUFFER);
+                ret = FALSE;
+            }
+            else
+            {
+                /* WideCharToMultiByte succeeded, output length needs to be
+                 * length not including NULL terminator
+                 */
+                *cchName = len - 1;
+            }
+        }
+        HeapFree(GetProcessHeap(), 0, lpNameW);
+    }
+    RtlFreeUnicodeString(&lpSystemNameW);
+    return ret;
 }
 
 /******************************************************************************
  * LookupPrivilegeNameW                        [ADVAPI32.@]
+ *
+ * Retrieves the privilege name referred to by the LUID lpLuid.
+ *
+ * PARAMS
+ *  lpSystemName [I]   Name of the system
+ *  lpLuid       [I]   Privilege value
+ *  lpName       [O]   Name of the privilege
+ *  cchName      [I/O] Number of characters in lpName.
+ *
+ * RETURNS
+ *  Success: TRUE. lpName contains the name of the privilege whose value is
+ *  *lpLuid.
+ *  Failure: FALSE.
+ *
+ * REMARKS
+ *  Only well-known privilege names (those defined in winnt.h) can be retrieved
+ *  using this function.
+ *  If the length of lpName is too small, on return *cchName will contain the
+ *  number of WCHARs needed to contain the privilege, including the NULL
+ *  terminator, and GetLastError will return ERROR_INSUFFICIENT_BUFFER.
+ *  On success, *cchName will contain the number of characters stored in
+ *  lpName, NOT including the NULL terminator.
  */
 BOOL WINAPI
-LookupPrivilegeNameW( LPCWSTR lpSystemName, PLUID lpLuid, LPWSTR lpName, LPDWORD cchName)
+LookupPrivilegeNameW( LPCWSTR lpSystemName, PLUID lpLuid, LPWSTR lpName,
+ LPDWORD cchName)
 {
-    FIXME("%s %p %p %p\n", debugstr_w(lpSystemName), lpLuid, lpName, cchName);
-    return FALSE;
+    size_t privNameLen;
+
+    TRACE("%s,%p,%p,%p\n",debugstr_w(lpSystemName), lpLuid, lpName, cchName);
+
+    if (!ADVAPI_IsLocalComputer(lpSystemName))
+    {
+        SetLastError(RPC_S_SERVER_UNAVAILABLE);
+        return FALSE;
+    }
+    if (lpLuid->HighPart || (lpLuid->LowPart < SE_MIN_WELL_KNOWN_PRIVILEGE ||
+     lpLuid->LowPart > SE_MAX_WELL_KNOWN_PRIVILEGE))
+    {
+        SetLastError(ERROR_NO_SUCH_PRIVILEGE);
+        return FALSE;
+    }
+    privNameLen = strlenW(WellKnownPrivNames[lpLuid->LowPart]);
+    /* Windows crashes if cchName is NULL, so will I */
+    if (*cchName <= privNameLen)
+    {
+        *cchName = privNameLen + 1;
+        SetLastError(ERROR_INSUFFICIENT_BUFFER);
+        return FALSE;
+    }
+    else
+    {
+        strcpyW(lpName, WellKnownPrivNames[lpLuid->LowPart]);
+        *cchName = privNameLen;
+        return TRUE;
+    }
 }
 
 /******************************************************************************
index 6ec9bf7f18d9b2435818462b3ce0b43ccf091eae..c9c0794e683844d1a799dc271da58004a36a03a5 100644 (file)
@@ -537,22 +537,6 @@ error:
     return NULL;
 }
 
-
-/******************************************************************************
- * AllocateLocallyUniqueId [ADVAPI32.@]
- *
- * PARAMS
- *   lpluid []
- */
-BOOL WINAPI
-AllocateLocallyUniqueId( PLUID lpluid )
-{
-       lpluid->LowPart = time(NULL);
-       lpluid->HighPart = 0;
-       return TRUE;
-}
-
-
 /******************************************************************************
  * ControlService [ADVAPI32.@]
  *
index 431236b744e9501c4e0d295a9cfab00c783fcd00..860ea988a00c59046fa6fb4567da72db02540c6a 100644 (file)
@@ -30,6 +30,8 @@
 typedef BOOL (WINAPI *fnConvertSidToStringSidA)( PSID pSid, LPSTR *str );
 typedef BOOL (WINAPI *fnConvertStringSidToSidA)( LPCSTR str, PSID pSid );
 
+static HMODULE hmod;
+
 fnConvertSidToStringSidA pConvertSidToStringSidA;
 fnConvertStringSidToSidA pConvertStringSidToSidA;
 
@@ -39,6 +41,11 @@ struct sidRef
     const char *refStr;
 };
 
+static void init(void)
+{
+    hmod = GetModuleHandle("advapi32.dll");
+}
+
 void test_sid()
 {
     struct sidRef refs[] = {
@@ -50,7 +57,6 @@ void test_sid()
      { { {0x00,0x00,0x00,0x00,0x00,0x0c} }, "S-1-12-1"        },
     };
     const char noSubAuthStr[] = "S-1-5";
-    HMODULE hmod = GetModuleHandle("advapi32.dll");
     unsigned int i;
     PSID psid = NULL;
     BOOL r;
@@ -166,8 +172,222 @@ void test_trustee()
     ok( trustee.ptstrName == str, "ptstrName wrong\n" );
 }
  
+/* If the first isn't defined, assume none is */
+#ifndef SE_MIN_WELL_KNOWN_PRIVILEGE
+#define SE_MIN_WELL_KNOWN_PRIVILEGE       2L
+#define SE_CREATE_TOKEN_PRIVILEGE         2L
+#define SE_ASSIGNPRIMARYTOKEN_PRIVILEGE   3L
+#define SE_LOCK_MEMORY_PRIVILEGE          4L
+#define SE_INCREASE_QUOTA_PRIVILEGE       5L
+#define SE_MACHINE_ACCOUNT_PRIVILEGE      6L
+#define SE_TCB_PRIVILEGE                  7L
+#define SE_SECURITY_PRIVILEGE             8L
+#define SE_TAKE_OWNERSHIP_PRIVILEGE       9L
+#define SE_LOAD_DRIVER_PRIVILEGE         10L
+#define SE_SYSTEM_PROFILE_PRIVILEGE      11L
+#define SE_SYSTEMTIME_PRIVILEGE          12L
+#define SE_PROF_SINGLE_PROCESS_PRIVILEGE 13L
+#define SE_INC_BASE_PRIORITY_PRIVILEGE   14L
+#define SE_CREATE_PAGEFILE_PRIVILEGE     15L
+#define SE_CREATE_PERMANENT_PRIVILEGE    16L
+#define SE_BACKUP_PRIVILEGE              17L
+#define SE_RESTORE_PRIVILEGE             18L
+#define SE_SHUTDOWN_PRIVILEGE            19L
+#define SE_DEBUG_PRIVILEGE               20L
+#define SE_AUDIT_PRIVILEGE               21L
+#define SE_SYSTEM_ENVIRONMENT_PRIVILEGE  22L
+#define SE_CHANGE_NOTIFY_PRIVILLEGE      23L
+#define SE_REMOTE_SHUTDOWN_PRIVILEGE     24L
+#define SE_UNDOCK_PRIVILEGE              25L
+#define SE_SYNC_AGENT_PRIVILEGE          26L
+#define SE_ENABLE_DELEGATION_PRIVILEGE   27L
+#define SE_MANAGE_VOLUME_PRIVILEGE       28L
+#define SE_IMPERSONATE_PRIVILEGE         29L
+#define SE_CREATE_GLOBAL_PRIVILEGE       30L
+#define SE_MAX_WELL_KNOWN_PRIVILEGE      SE_CREATE_GLOBAL_PRIVILEGE
+#endif /* ndef SE_MIN_WELL_KNOWN_PRIVILEGE */
+
+static void test_allocateLuid(void)
+{
+    BOOL (WINAPI *pAllocateLocallyUniqueId)(PLUID);
+    LUID luid1, luid2;
+    BOOL ret;
+
+    pAllocateLocallyUniqueId = GetProcAddress(hmod, "AllocateLocallyUniqueId");
+    if (!pAllocateLocallyUniqueId) return;
+
+    ret = pAllocateLocallyUniqueId(&luid1);
+    if (!ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
+        return;
+
+    ok(ret,
+     "AllocateLocallyUniqueId failed: %ld\n", GetLastError());
+    ok(pAllocateLocallyUniqueId(&luid2),
+     "AllocateLocallyUniqueId failed: %ld\n", GetLastError());
+    ok(luid1.LowPart > SE_MAX_WELL_KNOWN_PRIVILEGE || luid1.HighPart != 0,
+     "AllocateLocallyUniqueId returned a well-known LUID\n");
+    ok(luid1.LowPart != luid2.LowPart || luid1.HighPart != luid2.HighPart,
+     "AllocateLocallyUniqueId returned non-unique LUIDs\n");
+    ok(!pAllocateLocallyUniqueId(NULL) && GetLastError() == ERROR_NOACCESS,
+     "AllocateLocallyUniqueId(NULL) didn't return ERROR_NOACCESS: %ld\n",
+     GetLastError());
+}
+
+static void test_lookupPrivilegeName(void)
+{
+    BOOL (WINAPI *pLookupPrivilegeNameA)(LPSTR, PLUID, LPSTR, LPDWORD);
+    char buf[MAX_PATH]; /* arbitrary, seems long enough */
+    DWORD cchName = sizeof(buf);
+    LUID luid = { 0, 0 };
+    LONG i;
+    BOOL ret;
+
+    /* check whether it's available first */
+    pLookupPrivilegeNameA = GetProcAddress(hmod, "LookupPrivilegeNameA");
+    if (!pLookupPrivilegeNameA) return;
+    luid.LowPart = SE_CREATE_TOKEN_PRIVILEGE;
+    ret = pLookupPrivilegeNameA(NULL, &luid, buf, &cchName);
+    if (!ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
+        return;
+
+    /* check with a short buffer */
+    cchName = 0;
+    luid.LowPart = SE_CREATE_TOKEN_PRIVILEGE;
+    ok(!pLookupPrivilegeNameA(NULL, &luid, NULL, &cchName) &&
+     GetLastError() == ERROR_INSUFFICIENT_BUFFER,
+     "LookupPrivilegeNameA didn't fail with ERROR_INSUFFICIENT_BUFFER: %ld\n",
+     GetLastError());
+    ok(cchName == strlen("SeCreateTokenPrivilege") + 1,
+     "LookupPrivilegeNameA returned an incorrect required length for\n"
+     "SeCreateTokenPrivilege (got %ld, expected %d)\n", cchName,
+     strlen("SeCreateTokenPrivilege") + 1);
+    /* check a known value and its returned length on success */
+    cchName = sizeof(buf);
+    ok(pLookupPrivilegeNameA(NULL, &luid, buf, &cchName) &&
+     cchName == strlen("SeCreateTokenPrivilege"),
+     "LookupPrivilegeNameA returned an incorrect output length for\n"
+     "SeCreateTokenPrivilege (got %ld, expected %d)\n", cchName,
+     strlen("SeCreateTokenPrivilege"));
+    /* check known values */
+    for (i = SE_MIN_WELL_KNOWN_PRIVILEGE; i < SE_MAX_WELL_KNOWN_PRIVILEGE; i++)
+    {
+        luid.LowPart = i;
+        cchName = sizeof(buf);
+        ok(pLookupPrivilegeNameA(NULL, &luid, buf, &cchName),
+         "LookupPrivilegeNameA(0.%ld) failed: %ld\n", i, GetLastError());
+    }
+    /* check a bogus LUID */
+    luid.LowPart = 0xdeadbeef;
+    cchName = sizeof(buf);
+    ok(!pLookupPrivilegeNameA(NULL, &luid, buf, &cchName) &&
+     GetLastError() == ERROR_NO_SUCH_PRIVILEGE,
+     "LookupPrivilegeNameA didn't fail with ERROR_NO_SUCH_PRIVILEGE: %ld\n",
+     GetLastError());
+    /* check on a bogus system */
+    luid.LowPart = SE_CREATE_TOKEN_PRIVILEGE;
+    cchName = sizeof(buf);
+    ok(!pLookupPrivilegeNameA("b0gu5.Nam3", &luid, buf, &cchName) &&
+     GetLastError() == RPC_S_SERVER_UNAVAILABLE,
+     "LookupPrivilegeNameA didn't fail with RPC_S_SERVER_UNAVAILABLE: %ld\n",
+     GetLastError());
+}
+
+struct NameToLUID
+{
+    const char *name;
+    LONG lowPart;
+};
+
+static void test_lookupPrivilegeValue(void)
+{
+    static const struct NameToLUID privs[] = {
+     { "SeCreateTokenPrivilege", SE_CREATE_TOKEN_PRIVILEGE },
+     { "SeAssignPrimaryTokenPrivilege", SE_ASSIGNPRIMARYTOKEN_PRIVILEGE },
+     { "SeLockMemoryPrivilege", SE_LOCK_MEMORY_PRIVILEGE },
+     { "SeIncreaseQuotaPrivilege", SE_INCREASE_QUOTA_PRIVILEGE },
+     { "SeMachineAccountPrivilege", SE_MACHINE_ACCOUNT_PRIVILEGE },
+     { "SeTcbPrivilege", SE_TCB_PRIVILEGE },
+     { "SeSecurityPrivilege", SE_SECURITY_PRIVILEGE },
+     { "SeTakeOwnershipPrivilege", SE_TAKE_OWNERSHIP_PRIVILEGE },
+     { "SeLoadDriverPrivilege", SE_LOAD_DRIVER_PRIVILEGE },
+     { "SeSystemProfilePrivilege", SE_SYSTEM_PROFILE_PRIVILEGE },
+     { "SeSystemtimePrivilege", SE_SYSTEMTIME_PRIVILEGE },
+     { "SeProfileSingleProcessPrivilege", SE_PROF_SINGLE_PROCESS_PRIVILEGE },
+     { "SeIncreaseBasePriorityPrivilege", SE_INC_BASE_PRIORITY_PRIVILEGE },
+     { "SeCreatePagefilePrivilege", SE_CREATE_PAGEFILE_PRIVILEGE },
+     { "SeCreatePermanentPrivilege", SE_CREATE_PERMANENT_PRIVILEGE },
+     { "SeBackupPrivilege", SE_BACKUP_PRIVILEGE },
+     { "SeRestorePrivilege", SE_RESTORE_PRIVILEGE },
+     { "SeShutdownPrivilege", SE_SHUTDOWN_PRIVILEGE },
+     { "SeDebugPrivilege", SE_DEBUG_PRIVILEGE },
+     { "SeAuditPrivilege", SE_AUDIT_PRIVILEGE },
+     { "SeSystemEnvironmentPrivilege", SE_SYSTEM_ENVIRONMENT_PRIVILEGE },
+     { "SeChangeNotifyPrivilege", SE_CHANGE_NOTIFY_PRIVILLEGE },
+     { "SeRemoteShutdownPrivilege", SE_REMOTE_SHUTDOWN_PRIVILEGE },
+     { "SeUndockPrivilege", SE_UNDOCK_PRIVILEGE },
+     { "SeSyncAgentPrivilege", SE_SYNC_AGENT_PRIVILEGE },
+     { "SeEnableDelegationPrivilege", SE_ENABLE_DELEGATION_PRIVILEGE },
+     { "SeManageVolumePrivilege", SE_MANAGE_VOLUME_PRIVILEGE },
+     { "SeImpersonatePrivilege", SE_IMPERSONATE_PRIVILEGE },
+     { "SeCreateGlobalPrivilege", SE_CREATE_GLOBAL_PRIVILEGE },
+    };
+    BOOL (WINAPI *pLookupPrivilegeValueA)(LPCSTR, LPCSTR, PLUID);
+    int i;
+    LUID luid;
+    BOOL ret;
+
+    /* check whether it's available first */
+    pLookupPrivilegeValueA = GetProcAddress(hmod, "LookupPrivilegeValueA");
+    if (!pLookupPrivilegeValueA) return;
+    ret = pLookupPrivilegeValueA(NULL, "SeCreateTokenPrivilege", &luid);
+    if (!ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
+        return;
+
+    /* check a bogus system name */
+    ok(!pLookupPrivilegeValueA("b0gu5.Nam3", "SeCreateTokenPrivilege", &luid)
+     && GetLastError() == RPC_S_SERVER_UNAVAILABLE,
+     "LookupPrivilegeValueA didn't fail with RPC_S_SERVER_UNAVAILABLE: %ld\n",
+     GetLastError());
+    /* check a NULL string */
+    ok(!pLookupPrivilegeValueA(NULL, 0, &luid) &&
+     GetLastError() == ERROR_NO_SUCH_PRIVILEGE,
+     "LookupPrivilegeValueA didn't fail with ERROR_NO_SUCH_PRIVILEGE: %ld\n",
+     GetLastError());
+    /* check a bogus privilege name */
+    ok(!pLookupPrivilegeValueA(NULL, "SeBogusPrivilege", &luid) &&
+     GetLastError() == ERROR_NO_SUCH_PRIVILEGE,
+     "LookupPrivilegeValueA didn't fail with ERROR_NO_SUCH_PRIVILEGE: %ld\n",
+     GetLastError());
+    /* check case insensitive */
+    ok(pLookupPrivilegeValueA(NULL, "sEcREATEtOKENpRIVILEGE", &luid),
+     "LookupPrivilegeValueA(NULL, sEcREATEtOKENpRIVILEGE, &luid) failed: %ld\n",
+     GetLastError());
+    for (i = 0; i < sizeof(privs) / sizeof(privs[0]); i++)
+    {
+        /* Not all privileges are implemented on all Windows versions, so
+         * don't worry if the call fails
+         */
+        if (pLookupPrivilegeValueA(NULL, privs[i].name, &luid))
+        {
+            ok(luid.LowPart == privs[i].lowPart,
+             "LookupPrivilegeValueA returned an invalid LUID for %s\n",
+             privs[i].name);
+        }
+    }
+}
+
+static void test_luid(void)
+{
+    test_allocateLuid();
+    test_lookupPrivilegeName();
+    test_lookupPrivilegeValue();
+}
+
 START_TEST(security)
 {
+    init();
+    if (!hmod) return;
     test_sid();
     test_trustee();
+    test_luid();
 }
index 9ab8f90d5887461890f8b75a29e8834670eed130..670f32c62738659bd39021a94c26840bc21224a9 100644 (file)
@@ -808,9 +808,12 @@ NTSTATUS WINAPI NtShutdownSystem(DWORD x1)
  */
 NTSTATUS WINAPI NtAllocateLocallyUniqueId(PLUID Luid)
 {
-    static LUID luid;
+    static LUID luid = { SE_MAX_WELL_KNOWN_PRIVILEGE, 0 };
 
-    FIXME("%p (0x%08lx%08lx)\n", Luid, luid.HighPart, luid.LowPart);
+    FIXME("%p\n", Luid);
+
+    if (!Luid)
+        return STATUS_ACCESS_VIOLATION;
 
     luid.LowPart++;
     if (luid.LowPart==0)
index f1f6c0bfd5f0ee5451bfc1ff85229a6ad8e23503..0094bee0c9e539431dd0c2bc470359ecdccc75ae 100644 (file)
@@ -1238,6 +1238,40 @@ typedef void (CALLBACK *PRTL_THREAD_START_ROUTINE)(LPVOID); /* FIXME: not the ri
 #define DPFLTR_INFO_LEVEL      3
 #define DPFLTR_MASK    0x8000000
 
+/* Well-known LUID values */
+#define SE_MIN_WELL_KNOWN_PRIVILEGE       2L
+#define SE_CREATE_TOKEN_PRIVILEGE         2L
+#define SE_ASSIGNPRIMARYTOKEN_PRIVILEGE   3L
+#define SE_LOCK_MEMORY_PRIVILEGE          4L
+#define SE_INCREASE_QUOTA_PRIVILEGE       5L
+#define SE_UNSOLICITED_INPUT_PRIVILEGE    6L /* obsolete */
+#define SE_MACHINE_ACCOUNT_PRIVILEGE      6L
+#define SE_TCB_PRIVILEGE                  7L
+#define SE_SECURITY_PRIVILEGE             8L
+#define SE_TAKE_OWNERSHIP_PRIVILEGE       9L
+#define SE_LOAD_DRIVER_PRIVILEGE         10L
+#define SE_SYSTEM_PROFILE_PRIVILEGE      11L
+#define SE_SYSTEMTIME_PRIVILEGE          12L
+#define SE_PROF_SINGLE_PROCESS_PRIVILEGE 13L
+#define SE_INC_BASE_PRIORITY_PRIVILEGE   14L
+#define SE_CREATE_PAGEFILE_PRIVILEGE     15L
+#define SE_CREATE_PERMANENT_PRIVILEGE    16L
+#define SE_BACKUP_PRIVILEGE              17L
+#define SE_RESTORE_PRIVILEGE             18L
+#define SE_SHUTDOWN_PRIVILEGE            19L
+#define SE_DEBUG_PRIVILEGE               20L
+#define SE_AUDIT_PRIVILEGE               21L
+#define SE_SYSTEM_ENVIRONMENT_PRIVILEGE  22L
+#define SE_CHANGE_NOTIFY_PRIVILLEGE      23L
+#define SE_REMOTE_SHUTDOWN_PRIVILEGE     24L
+#define SE_UNDOCK_PRIVILEGE              25L
+#define SE_SYNC_AGENT_PRIVILEGE          26L
+#define SE_ENABLE_DELEGATION_PRIVILEGE   27L
+#define SE_MANAGE_VOLUME_PRIVILEGE       28L
+#define SE_IMPERSONATE_PRIVILEGE         29L
+#define SE_CREATE_GLOBAL_PRIVILEGE       30L
+#define SE_MAX_WELL_KNOWN_PRIVILEGE      SE_CREATE_GLOBAL_PRIVILEGE
+
 /***********************************************************************
  * Function declarations
  */
@@ -1268,6 +1302,7 @@ NTSTATUS  WINAPI NtAccessCheck(PSECURITY_DESCRIPTOR,HANDLE,ACCESS_MASK,PGENERIC_
 NTSTATUS  WINAPI NtAdjustGroupsToken(HANDLE,BOOLEAN,PTOKEN_GROUPS,ULONG,PTOKEN_GROUPS,PULONG);
 NTSTATUS  WINAPI NtAdjustPrivilegesToken(HANDLE,BOOLEAN,PTOKEN_PRIVILEGES,DWORD,PTOKEN_PRIVILEGES,PDWORD);
 NTSTATUS  WINAPI NtAlertThread(HANDLE ThreadHandle);
+NTSTATUS  WINAPI NtAllocateLocallyUniqueId(PLUID lpLuid);
 NTSTATUS  WINAPI NtAllocateVirtualMemory(HANDLE,PVOID*,ULONG,ULONG*,ULONG,ULONG);
 NTSTATUS  WINAPI NtCancelIoFile(HANDLE,PIO_STATUS_BLOCK);
 NTSTATUS  WINAPI NtCancelTimer(HANDLE, BOOLEAN*);