diff --git a/dlls/advapi32/security.c b/dlls/advapi32/security.c index 8498ab0a578..9f6215ec4af 100644 --- a/dlls/advapi32/security.c +++ b/dlls/advapi32/security.c @@ -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 @@ -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[] = +/****************************************************************************** + * AllocateLocallyUniqueId [ADVAPI32.@] + * + * PARAMS + * lpLuid [] + */ +BOOL WINAPI AllocateLocallyUniqueId( PLUID lpLuid ) { - 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", + 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; iLowPart = 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; + } } /****************************************************************************** diff --git a/dlls/advapi32/service.c b/dlls/advapi32/service.c index 6ec9bf7f18d..c9c0794e683 100644 --- a/dlls/advapi32/service.c +++ b/dlls/advapi32/service.c @@ -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.@] * diff --git a/dlls/advapi32/tests/security.c b/dlls/advapi32/tests/security.c index 431236b744e..860ea988a00 100644 --- a/dlls/advapi32/tests/security.c +++ b/dlls/advapi32/tests/security.c @@ -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(); } diff --git a/dlls/ntdll/nt.c b/dlls/ntdll/nt.c index 9ab8f90d588..670f32c6273 100644 --- a/dlls/ntdll/nt.c +++ b/dlls/ntdll/nt.c @@ -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) diff --git a/include/winternl.h b/include/winternl.h index f1f6c0bfd5f..0094bee0c9e 100644 --- a/include/winternl.h +++ b/include/winternl.h @@ -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*);