1*c2c66affSColin Finck /* 2*c2c66affSColin Finck * COPYRIGHT: See COPYING in the top level directory 3*c2c66affSColin Finck * WINE COPYRIGHT: 4*c2c66affSColin Finck * Copyright 1999, 2000 Juergen Schmied <juergen.schmied@debitel.net> 5*c2c66affSColin Finck * Copyright 2003 CodeWeavers Inc. (Ulrich Czekalla) 6*c2c66affSColin Finck * Copyright 2006 Robert Reif 7*c2c66affSColin Finck * 8*c2c66affSColin Finck * PROJECT: ReactOS system libraries 9*c2c66affSColin Finck * FILE: dll/win32/advapi32/sec/misc.c 10*c2c66affSColin Finck * PURPOSE: Miscellaneous security functions (some ported from Wine) 11*c2c66affSColin Finck */ 12*c2c66affSColin Finck 13*c2c66affSColin Finck #include <advapi32.h> 14*c2c66affSColin Finck 15*c2c66affSColin Finck WINE_DEFAULT_DEBUG_CHANNEL(advapi); 16*c2c66affSColin Finck 17*c2c66affSColin Finck /* Interface to ntmarta.dll ***************************************************/ 18*c2c66affSColin Finck 19*c2c66affSColin Finck NTMARTA NtMartaStatic = { 0 }; 20*c2c66affSColin Finck static PNTMARTA NtMarta = NULL; 21*c2c66affSColin Finck 22*c2c66affSColin Finck #define FindNtMartaProc(Name) \ 23*c2c66affSColin Finck NtMartaStatic.Name = (PVOID)GetProcAddress(NtMartaStatic.hDllInstance, \ 24*c2c66affSColin Finck "Acc" # Name ); \ 25*c2c66affSColin Finck if (NtMartaStatic.Name == NULL) \ 26*c2c66affSColin Finck { \ 27*c2c66affSColin Finck return GetLastError(); \ 28*c2c66affSColin Finck } 29*c2c66affSColin Finck 30*c2c66affSColin Finck 31*c2c66affSColin Finck static DWORD 32*c2c66affSColin Finck LoadAndInitializeNtMarta(VOID) 33*c2c66affSColin Finck { 34*c2c66affSColin Finck /* this code may be executed simultaneously by multiple threads in case they're 35*c2c66affSColin Finck trying to initialize the interface at the same time, but that's no problem 36*c2c66affSColin Finck because the pointers returned by GetProcAddress will be the same. However, 37*c2c66affSColin Finck only one of the threads will change the NtMarta pointer to the NtMartaStatic 38*c2c66affSColin Finck structure, the others threads will detect that there were other threads 39*c2c66affSColin Finck initializing the structure faster and will release the reference to the 40*c2c66affSColin Finck DLL */ 41*c2c66affSColin Finck 42*c2c66affSColin Finck NtMartaStatic.hDllInstance = LoadLibraryW(L"ntmarta.dll"); 43*c2c66affSColin Finck if (NtMartaStatic.hDllInstance == NULL) 44*c2c66affSColin Finck { 45*c2c66affSColin Finck return GetLastError(); 46*c2c66affSColin Finck } 47*c2c66affSColin Finck 48*c2c66affSColin Finck #if 0 49*c2c66affSColin Finck FindNtMartaProc(LookupAccountTrustee); 50*c2c66affSColin Finck FindNtMartaProc(LookupAccountName); 51*c2c66affSColin Finck FindNtMartaProc(LookupAccountSid); 52*c2c66affSColin Finck FindNtMartaProc(SetEntriesInAList); 53*c2c66affSColin Finck FindNtMartaProc(ConvertAccessToSecurityDescriptor); 54*c2c66affSColin Finck FindNtMartaProc(ConvertSDToAccess); 55*c2c66affSColin Finck FindNtMartaProc(ConvertAclToAccess); 56*c2c66affSColin Finck FindNtMartaProc(GetAccessForTrustee); 57*c2c66affSColin Finck FindNtMartaProc(GetExplicitEntries); 58*c2c66affSColin Finck #endif 59*c2c66affSColin Finck FindNtMartaProc(RewriteGetNamedRights); 60*c2c66affSColin Finck FindNtMartaProc(RewriteSetNamedRights); 61*c2c66affSColin Finck FindNtMartaProc(RewriteGetHandleRights); 62*c2c66affSColin Finck FindNtMartaProc(RewriteSetHandleRights); 63*c2c66affSColin Finck FindNtMartaProc(RewriteSetEntriesInAcl); 64*c2c66affSColin Finck FindNtMartaProc(RewriteGetExplicitEntriesFromAcl); 65*c2c66affSColin Finck FindNtMartaProc(TreeResetNamedSecurityInfo); 66*c2c66affSColin Finck FindNtMartaProc(GetInheritanceSource); 67*c2c66affSColin Finck FindNtMartaProc(FreeIndexArray); 68*c2c66affSColin Finck 69*c2c66affSColin Finck return ERROR_SUCCESS; 70*c2c66affSColin Finck } 71*c2c66affSColin Finck 72*c2c66affSColin Finck 73*c2c66affSColin Finck DWORD 74*c2c66affSColin Finck CheckNtMartaPresent(VOID) 75*c2c66affSColin Finck { 76*c2c66affSColin Finck DWORD ErrorCode; 77*c2c66affSColin Finck 78*c2c66affSColin Finck if (InterlockedCompareExchangePointer((PVOID)&NtMarta, 79*c2c66affSColin Finck NULL, 80*c2c66affSColin Finck NULL) == NULL) 81*c2c66affSColin Finck { 82*c2c66affSColin Finck /* we're the first one trying to use ntmarta, initialize it and change 83*c2c66affSColin Finck the pointer after initialization */ 84*c2c66affSColin Finck ErrorCode = LoadAndInitializeNtMarta(); 85*c2c66affSColin Finck 86*c2c66affSColin Finck if (ErrorCode == ERROR_SUCCESS) 87*c2c66affSColin Finck { 88*c2c66affSColin Finck /* try change the NtMarta pointer */ 89*c2c66affSColin Finck if (InterlockedCompareExchangePointer((PVOID)&NtMarta, 90*c2c66affSColin Finck &NtMartaStatic, 91*c2c66affSColin Finck NULL) != NULL) 92*c2c66affSColin Finck { 93*c2c66affSColin Finck /* another thread initialized ntmarta in the meanwhile, release 94*c2c66affSColin Finck the reference of the dll loaded. */ 95*c2c66affSColin Finck FreeLibrary(NtMartaStatic.hDllInstance); 96*c2c66affSColin Finck } 97*c2c66affSColin Finck } 98*c2c66affSColin Finck #if DBG 99*c2c66affSColin Finck else 100*c2c66affSColin Finck { 101*c2c66affSColin Finck ERR("Failed to initialize ntmarta.dll! Error: 0x%x", ErrorCode); 102*c2c66affSColin Finck } 103*c2c66affSColin Finck #endif 104*c2c66affSColin Finck } 105*c2c66affSColin Finck else 106*c2c66affSColin Finck { 107*c2c66affSColin Finck /* ntmarta was already initialized */ 108*c2c66affSColin Finck ErrorCode = ERROR_SUCCESS; 109*c2c66affSColin Finck } 110*c2c66affSColin Finck 111*c2c66affSColin Finck return ErrorCode; 112*c2c66affSColin Finck } 113*c2c66affSColin Finck 114*c2c66affSColin Finck 115*c2c66affSColin Finck VOID 116*c2c66affSColin Finck UnloadNtMarta(VOID) 117*c2c66affSColin Finck { 118*c2c66affSColin Finck if (InterlockedExchangePointer((PVOID)&NtMarta, 119*c2c66affSColin Finck NULL) != NULL) 120*c2c66affSColin Finck { 121*c2c66affSColin Finck FreeLibrary(NtMartaStatic.hDllInstance); 122*c2c66affSColin Finck } 123*c2c66affSColin Finck } 124*c2c66affSColin Finck 125*c2c66affSColin Finck 126*c2c66affSColin Finck /******************************************************************************/ 127*c2c66affSColin Finck 128*c2c66affSColin Finck /* 129*c2c66affSColin Finck * @implemented 130*c2c66affSColin Finck */ 131*c2c66affSColin Finck BOOL 132*c2c66affSColin Finck WINAPI 133*c2c66affSColin Finck ImpersonateAnonymousToken(IN HANDLE ThreadHandle) 134*c2c66affSColin Finck { 135*c2c66affSColin Finck NTSTATUS Status; 136*c2c66affSColin Finck 137*c2c66affSColin Finck Status = NtImpersonateAnonymousToken(ThreadHandle); 138*c2c66affSColin Finck if (!NT_SUCCESS(Status)) 139*c2c66affSColin Finck { 140*c2c66affSColin Finck SetLastError(RtlNtStatusToDosError(Status)); 141*c2c66affSColin Finck return FALSE; 142*c2c66affSColin Finck } 143*c2c66affSColin Finck 144*c2c66affSColin Finck return TRUE; 145*c2c66affSColin Finck } 146*c2c66affSColin Finck 147*c2c66affSColin Finck /* 148*c2c66affSColin Finck * @implemented 149*c2c66affSColin Finck */ 150*c2c66affSColin Finck BOOL 151*c2c66affSColin Finck WINAPI 152*c2c66affSColin Finck ImpersonateLoggedOnUser(HANDLE hToken) 153*c2c66affSColin Finck { 154*c2c66affSColin Finck SECURITY_QUALITY_OF_SERVICE Qos; 155*c2c66affSColin Finck OBJECT_ATTRIBUTES ObjectAttributes; 156*c2c66affSColin Finck HANDLE NewToken; 157*c2c66affSColin Finck TOKEN_TYPE Type; 158*c2c66affSColin Finck ULONG ReturnLength; 159*c2c66affSColin Finck BOOL Duplicated; 160*c2c66affSColin Finck NTSTATUS Status; 161*c2c66affSColin Finck 162*c2c66affSColin Finck /* Get the token type */ 163*c2c66affSColin Finck Status = NtQueryInformationToken(hToken, 164*c2c66affSColin Finck TokenType, 165*c2c66affSColin Finck &Type, 166*c2c66affSColin Finck sizeof(TOKEN_TYPE), 167*c2c66affSColin Finck &ReturnLength); 168*c2c66affSColin Finck if (!NT_SUCCESS(Status)) 169*c2c66affSColin Finck { 170*c2c66affSColin Finck SetLastError(RtlNtStatusToDosError(Status)); 171*c2c66affSColin Finck return FALSE; 172*c2c66affSColin Finck } 173*c2c66affSColin Finck 174*c2c66affSColin Finck if (Type == TokenPrimary) 175*c2c66affSColin Finck { 176*c2c66affSColin Finck /* Create a duplicate impersonation token */ 177*c2c66affSColin Finck Qos.Length = sizeof(SECURITY_QUALITY_OF_SERVICE); 178*c2c66affSColin Finck Qos.ImpersonationLevel = SecurityImpersonation; 179*c2c66affSColin Finck Qos.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING; 180*c2c66affSColin Finck Qos.EffectiveOnly = FALSE; 181*c2c66affSColin Finck 182*c2c66affSColin Finck ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES); 183*c2c66affSColin Finck ObjectAttributes.RootDirectory = NULL; 184*c2c66affSColin Finck ObjectAttributes.ObjectName = NULL; 185*c2c66affSColin Finck ObjectAttributes.Attributes = 0; 186*c2c66affSColin Finck ObjectAttributes.SecurityDescriptor = NULL; 187*c2c66affSColin Finck ObjectAttributes.SecurityQualityOfService = &Qos; 188*c2c66affSColin Finck 189*c2c66affSColin Finck Status = NtDuplicateToken(hToken, 190*c2c66affSColin Finck TOKEN_IMPERSONATE | TOKEN_QUERY, 191*c2c66affSColin Finck &ObjectAttributes, 192*c2c66affSColin Finck FALSE, 193*c2c66affSColin Finck TokenImpersonation, 194*c2c66affSColin Finck &NewToken); 195*c2c66affSColin Finck if (!NT_SUCCESS(Status)) 196*c2c66affSColin Finck { 197*c2c66affSColin Finck ERR("NtDuplicateToken failed: Status %08x\n", Status); 198*c2c66affSColin Finck SetLastError(RtlNtStatusToDosError(Status)); 199*c2c66affSColin Finck return FALSE; 200*c2c66affSColin Finck } 201*c2c66affSColin Finck 202*c2c66affSColin Finck Duplicated = TRUE; 203*c2c66affSColin Finck } 204*c2c66affSColin Finck else 205*c2c66affSColin Finck { 206*c2c66affSColin Finck /* User the original impersonation token */ 207*c2c66affSColin Finck NewToken = hToken; 208*c2c66affSColin Finck Duplicated = FALSE; 209*c2c66affSColin Finck } 210*c2c66affSColin Finck 211*c2c66affSColin Finck /* Impersonate the the current thread */ 212*c2c66affSColin Finck Status = NtSetInformationThread(NtCurrentThread(), 213*c2c66affSColin Finck ThreadImpersonationToken, 214*c2c66affSColin Finck &NewToken, 215*c2c66affSColin Finck sizeof(HANDLE)); 216*c2c66affSColin Finck 217*c2c66affSColin Finck if (Duplicated != FALSE) 218*c2c66affSColin Finck { 219*c2c66affSColin Finck NtClose(NewToken); 220*c2c66affSColin Finck } 221*c2c66affSColin Finck 222*c2c66affSColin Finck if (!NT_SUCCESS(Status)) 223*c2c66affSColin Finck { 224*c2c66affSColin Finck ERR("NtSetInformationThread failed: Status %08x\n", Status); 225*c2c66affSColin Finck SetLastError(RtlNtStatusToDosError(Status)); 226*c2c66affSColin Finck return FALSE; 227*c2c66affSColin Finck } 228*c2c66affSColin Finck 229*c2c66affSColin Finck return TRUE; 230*c2c66affSColin Finck } 231*c2c66affSColin Finck 232*c2c66affSColin Finck /****************************************************************************** 233*c2c66affSColin Finck * GetUserNameA [ADVAPI32.@] 234*c2c66affSColin Finck * 235*c2c66affSColin Finck * Get the current user name. 236*c2c66affSColin Finck * 237*c2c66affSColin Finck * PARAMS 238*c2c66affSColin Finck * lpszName [O] Destination for the user name. 239*c2c66affSColin Finck * lpSize [I/O] Size of lpszName. 240*c2c66affSColin Finck * 241*c2c66affSColin Finck * 242*c2c66affSColin Finck * @implemented 243*c2c66affSColin Finck */ 244*c2c66affSColin Finck BOOL 245*c2c66affSColin Finck WINAPI 246*c2c66affSColin Finck GetUserNameA(LPSTR lpszName, 247*c2c66affSColin Finck LPDWORD lpSize) 248*c2c66affSColin Finck { 249*c2c66affSColin Finck UNICODE_STRING NameW; 250*c2c66affSColin Finck ANSI_STRING NameA; 251*c2c66affSColin Finck BOOL Ret; 252*c2c66affSColin Finck 253*c2c66affSColin Finck /* apparently Win doesn't check whether lpSize is valid at all! */ 254*c2c66affSColin Finck 255*c2c66affSColin Finck NameW.MaximumLength = (*lpSize) * sizeof(WCHAR); 256*c2c66affSColin Finck NameW.Buffer = LocalAlloc(LMEM_FIXED, NameW.MaximumLength); 257*c2c66affSColin Finck if(NameW.Buffer == NULL) 258*c2c66affSColin Finck { 259*c2c66affSColin Finck SetLastError(ERROR_NOT_ENOUGH_MEMORY); 260*c2c66affSColin Finck return FALSE; 261*c2c66affSColin Finck } 262*c2c66affSColin Finck 263*c2c66affSColin Finck NameA.Length = 0; 264*c2c66affSColin Finck NameA.MaximumLength = ((*lpSize) < 0xFFFF ? (USHORT)(*lpSize) : 0xFFFF); 265*c2c66affSColin Finck NameA.Buffer = lpszName; 266*c2c66affSColin Finck 267*c2c66affSColin Finck Ret = GetUserNameW(NameW.Buffer, 268*c2c66affSColin Finck lpSize); 269*c2c66affSColin Finck if(Ret) 270*c2c66affSColin Finck { 271*c2c66affSColin Finck NameW.Length = (*lpSize - 1) * sizeof(WCHAR); 272*c2c66affSColin Finck RtlUnicodeStringToAnsiString(&NameA, &NameW, FALSE); 273*c2c66affSColin Finck 274*c2c66affSColin Finck *lpSize = NameA.Length + 1; 275*c2c66affSColin Finck } 276*c2c66affSColin Finck 277*c2c66affSColin Finck LocalFree(NameW.Buffer); 278*c2c66affSColin Finck 279*c2c66affSColin Finck return Ret; 280*c2c66affSColin Finck } 281*c2c66affSColin Finck 282*c2c66affSColin Finck /****************************************************************************** 283*c2c66affSColin Finck * GetUserNameW [ADVAPI32.@] 284*c2c66affSColin Finck * 285*c2c66affSColin Finck * See GetUserNameA. 286*c2c66affSColin Finck * 287*c2c66affSColin Finck * @implemented 288*c2c66affSColin Finck */ 289*c2c66affSColin Finck BOOL 290*c2c66affSColin Finck WINAPI 291*c2c66affSColin Finck GetUserNameW(LPWSTR lpszName, 292*c2c66affSColin Finck LPDWORD lpSize) 293*c2c66affSColin Finck { 294*c2c66affSColin Finck HANDLE hToken = INVALID_HANDLE_VALUE; 295*c2c66affSColin Finck DWORD tu_len = 0; 296*c2c66affSColin Finck char* tu_buf = NULL; 297*c2c66affSColin Finck TOKEN_USER* token_user = NULL; 298*c2c66affSColin Finck DWORD an_len = 0; 299*c2c66affSColin Finck SID_NAME_USE snu = SidTypeUser; 300*c2c66affSColin Finck WCHAR* domain_name = NULL; 301*c2c66affSColin Finck DWORD dn_len = 0; 302*c2c66affSColin Finck 303*c2c66affSColin Finck if (!OpenThreadToken (GetCurrentThread(), TOKEN_QUERY, FALSE, &hToken)) 304*c2c66affSColin Finck { 305*c2c66affSColin Finck DWORD dwLastError = GetLastError(); 306*c2c66affSColin Finck if (dwLastError != ERROR_NO_TOKEN 307*c2c66affSColin Finck && dwLastError != ERROR_NO_IMPERSONATION_TOKEN) 308*c2c66affSColin Finck { 309*c2c66affSColin Finck /* don't call SetLastError(), 310*c2c66affSColin Finck as OpenThreadToken() ought to have set one */ 311*c2c66affSColin Finck return FALSE; 312*c2c66affSColin Finck } 313*c2c66affSColin Finck 314*c2c66affSColin Finck if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken)) 315*c2c66affSColin Finck { 316*c2c66affSColin Finck /* don't call SetLastError(), 317*c2c66affSColin Finck as OpenProcessToken() ought to have set one */ 318*c2c66affSColin Finck return FALSE; 319*c2c66affSColin Finck } 320*c2c66affSColin Finck } 321*c2c66affSColin Finck 322*c2c66affSColin Finck tu_buf = LocalAlloc(LMEM_FIXED, 36); 323*c2c66affSColin Finck if (!tu_buf) 324*c2c66affSColin Finck { 325*c2c66affSColin Finck SetLastError(ERROR_NOT_ENOUGH_MEMORY); 326*c2c66affSColin Finck CloseHandle(hToken); 327*c2c66affSColin Finck return FALSE; 328*c2c66affSColin Finck } 329*c2c66affSColin Finck 330*c2c66affSColin Finck if (!GetTokenInformation(hToken, TokenUser, tu_buf, 36, &tu_len) || tu_len > 36) 331*c2c66affSColin Finck { 332*c2c66affSColin Finck LocalFree(tu_buf); 333*c2c66affSColin Finck tu_buf = LocalAlloc(LMEM_FIXED, tu_len); 334*c2c66affSColin Finck if (!tu_buf) 335*c2c66affSColin Finck { 336*c2c66affSColin Finck SetLastError(ERROR_NOT_ENOUGH_MEMORY); 337*c2c66affSColin Finck CloseHandle(hToken); 338*c2c66affSColin Finck return FALSE; 339*c2c66affSColin Finck } 340*c2c66affSColin Finck 341*c2c66affSColin Finck if (!GetTokenInformation(hToken, TokenUser, tu_buf, tu_len, &tu_len)) 342*c2c66affSColin Finck { 343*c2c66affSColin Finck /* don't call SetLastError(), 344*c2c66affSColin Finck as GetTokenInformation() ought to have set one */ 345*c2c66affSColin Finck LocalFree(tu_buf); 346*c2c66affSColin Finck CloseHandle(hToken); 347*c2c66affSColin Finck return FALSE; 348*c2c66affSColin Finck } 349*c2c66affSColin Finck } 350*c2c66affSColin Finck 351*c2c66affSColin Finck CloseHandle(hToken); 352*c2c66affSColin Finck token_user = (TOKEN_USER*)tu_buf; 353*c2c66affSColin Finck 354*c2c66affSColin Finck an_len = *lpSize; 355*c2c66affSColin Finck dn_len = 32; 356*c2c66affSColin Finck domain_name = LocalAlloc(LMEM_FIXED, dn_len * sizeof(WCHAR)); 357*c2c66affSColin Finck if (!domain_name) 358*c2c66affSColin Finck { 359*c2c66affSColin Finck LocalFree(tu_buf); 360*c2c66affSColin Finck SetLastError(ERROR_NOT_ENOUGH_MEMORY); 361*c2c66affSColin Finck return FALSE; 362*c2c66affSColin Finck } 363*c2c66affSColin Finck 364*c2c66affSColin Finck if (!LookupAccountSidW(NULL, token_user->User.Sid, lpszName, &an_len, domain_name, &dn_len, &snu) 365*c2c66affSColin Finck || dn_len > 32) 366*c2c66affSColin Finck { 367*c2c66affSColin Finck if (dn_len > 32) 368*c2c66affSColin Finck { 369*c2c66affSColin Finck LocalFree(domain_name); 370*c2c66affSColin Finck domain_name = LocalAlloc(LMEM_FIXED, dn_len * sizeof(WCHAR)); 371*c2c66affSColin Finck if (!domain_name) 372*c2c66affSColin Finck { 373*c2c66affSColin Finck LocalFree(tu_buf); 374*c2c66affSColin Finck SetLastError(ERROR_NOT_ENOUGH_MEMORY); 375*c2c66affSColin Finck return FALSE; 376*c2c66affSColin Finck } 377*c2c66affSColin Finck } 378*c2c66affSColin Finck 379*c2c66affSColin Finck an_len = *lpSize; 380*c2c66affSColin Finck if (!LookupAccountSidW(NULL, token_user->User.Sid, lpszName, &an_len, domain_name, &dn_len, &snu)) 381*c2c66affSColin Finck { 382*c2c66affSColin Finck /* don't call SetLastError(), 383*c2c66affSColin Finck as LookupAccountSid() ought to have set one */ 384*c2c66affSColin Finck LocalFree(domain_name); 385*c2c66affSColin Finck LocalFree(tu_buf); 386*c2c66affSColin Finck *lpSize = an_len; 387*c2c66affSColin Finck return FALSE; 388*c2c66affSColin Finck } 389*c2c66affSColin Finck } 390*c2c66affSColin Finck 391*c2c66affSColin Finck LocalFree(domain_name); 392*c2c66affSColin Finck LocalFree(tu_buf); 393*c2c66affSColin Finck *lpSize = an_len + 1; 394*c2c66affSColin Finck return TRUE; 395*c2c66affSColin Finck } 396*c2c66affSColin Finck 397*c2c66affSColin Finck 398*c2c66affSColin Finck /****************************************************************************** 399*c2c66affSColin Finck * LookupAccountSidA [ADVAPI32.@] 400*c2c66affSColin Finck * 401*c2c66affSColin Finck * @implemented 402*c2c66affSColin Finck */ 403*c2c66affSColin Finck BOOL 404*c2c66affSColin Finck WINAPI 405*c2c66affSColin Finck LookupAccountSidA(LPCSTR lpSystemName, 406*c2c66affSColin Finck PSID lpSid, 407*c2c66affSColin Finck LPSTR lpName, 408*c2c66affSColin Finck LPDWORD cchName, 409*c2c66affSColin Finck LPSTR lpReferencedDomainName, 410*c2c66affSColin Finck LPDWORD cchReferencedDomainName, 411*c2c66affSColin Finck PSID_NAME_USE peUse) 412*c2c66affSColin Finck { 413*c2c66affSColin Finck UNICODE_STRING NameW, ReferencedDomainNameW, SystemNameW; 414*c2c66affSColin Finck LPWSTR NameBuffer = NULL; 415*c2c66affSColin Finck LPWSTR ReferencedDomainNameBuffer = NULL; 416*c2c66affSColin Finck DWORD dwName, dwReferencedDomainName; 417*c2c66affSColin Finck BOOL Ret; 418*c2c66affSColin Finck 419*c2c66affSColin Finck /* 420*c2c66affSColin Finck * save the buffer sizes the caller passed to us, as they may get modified and 421*c2c66affSColin Finck * we require the original values when converting back to ansi 422*c2c66affSColin Finck */ 423*c2c66affSColin Finck dwName = *cchName; 424*c2c66affSColin Finck dwReferencedDomainName = *cchReferencedDomainName; 425*c2c66affSColin Finck 426*c2c66affSColin Finck /* allocate buffers for the unicode strings to receive */ 427*c2c66affSColin Finck if (dwName > 0) 428*c2c66affSColin Finck { 429*c2c66affSColin Finck NameBuffer = LocalAlloc(LMEM_FIXED, dwName * sizeof(WCHAR)); 430*c2c66affSColin Finck if (NameBuffer == NULL) 431*c2c66affSColin Finck { 432*c2c66affSColin Finck SetLastError(ERROR_OUTOFMEMORY); 433*c2c66affSColin Finck return FALSE; 434*c2c66affSColin Finck } 435*c2c66affSColin Finck } 436*c2c66affSColin Finck else 437*c2c66affSColin Finck NameBuffer = NULL; 438*c2c66affSColin Finck 439*c2c66affSColin Finck if (dwReferencedDomainName > 0) 440*c2c66affSColin Finck { 441*c2c66affSColin Finck ReferencedDomainNameBuffer = LocalAlloc(LMEM_FIXED, dwReferencedDomainName * sizeof(WCHAR)); 442*c2c66affSColin Finck if (ReferencedDomainNameBuffer == NULL) 443*c2c66affSColin Finck { 444*c2c66affSColin Finck if (dwName > 0) 445*c2c66affSColin Finck { 446*c2c66affSColin Finck LocalFree(NameBuffer); 447*c2c66affSColin Finck } 448*c2c66affSColin Finck 449*c2c66affSColin Finck SetLastError(ERROR_OUTOFMEMORY); 450*c2c66affSColin Finck return FALSE; 451*c2c66affSColin Finck } 452*c2c66affSColin Finck } 453*c2c66affSColin Finck else 454*c2c66affSColin Finck ReferencedDomainNameBuffer = NULL; 455*c2c66affSColin Finck 456*c2c66affSColin Finck 457*c2c66affSColin Finck /* convert the system name to unicode - if present */ 458*c2c66affSColin Finck if (lpSystemName != NULL) 459*c2c66affSColin Finck { 460*c2c66affSColin Finck ANSI_STRING SystemNameA; 461*c2c66affSColin Finck 462*c2c66affSColin Finck RtlInitAnsiString(&SystemNameA, lpSystemName); 463*c2c66affSColin Finck RtlAnsiStringToUnicodeString(&SystemNameW, &SystemNameA, TRUE); 464*c2c66affSColin Finck } 465*c2c66affSColin Finck else 466*c2c66affSColin Finck SystemNameW.Buffer = NULL; 467*c2c66affSColin Finck 468*c2c66affSColin Finck /* it's time to call the unicode version */ 469*c2c66affSColin Finck Ret = LookupAccountSidW(SystemNameW.Buffer, 470*c2c66affSColin Finck lpSid, 471*c2c66affSColin Finck NameBuffer, 472*c2c66affSColin Finck cchName, 473*c2c66affSColin Finck ReferencedDomainNameBuffer, 474*c2c66affSColin Finck cchReferencedDomainName, 475*c2c66affSColin Finck peUse); 476*c2c66affSColin Finck if (Ret) 477*c2c66affSColin Finck { 478*c2c66affSColin Finck /* 479*c2c66affSColin Finck * convert unicode strings back to ansi, don't forget that we can't convert 480*c2c66affSColin Finck * more than 0xFFFF (USHORT) characters! Also don't forget to explicitly 481*c2c66affSColin Finck * terminate the converted string, the Rtl functions don't do that! 482*c2c66affSColin Finck */ 483*c2c66affSColin Finck if (lpName != NULL) 484*c2c66affSColin Finck { 485*c2c66affSColin Finck ANSI_STRING NameA; 486*c2c66affSColin Finck 487*c2c66affSColin Finck NameA.Length = 0; 488*c2c66affSColin Finck NameA.MaximumLength = ((dwName <= 0xFFFF) ? (USHORT)dwName : 0xFFFF); 489*c2c66affSColin Finck NameA.Buffer = lpName; 490*c2c66affSColin Finck 491*c2c66affSColin Finck RtlInitUnicodeString(&NameW, NameBuffer); 492*c2c66affSColin Finck RtlUnicodeStringToAnsiString(&NameA, &NameW, FALSE); 493*c2c66affSColin Finck NameA.Buffer[NameA.Length] = '\0'; 494*c2c66affSColin Finck } 495*c2c66affSColin Finck 496*c2c66affSColin Finck if (lpReferencedDomainName != NULL) 497*c2c66affSColin Finck { 498*c2c66affSColin Finck ANSI_STRING ReferencedDomainNameA; 499*c2c66affSColin Finck 500*c2c66affSColin Finck ReferencedDomainNameA.Length = 0; 501*c2c66affSColin Finck ReferencedDomainNameA.MaximumLength = ((dwReferencedDomainName <= 0xFFFF) ? 502*c2c66affSColin Finck (USHORT)dwReferencedDomainName : 0xFFFF); 503*c2c66affSColin Finck ReferencedDomainNameA.Buffer = lpReferencedDomainName; 504*c2c66affSColin Finck 505*c2c66affSColin Finck RtlInitUnicodeString(&ReferencedDomainNameW, ReferencedDomainNameBuffer); 506*c2c66affSColin Finck RtlUnicodeStringToAnsiString(&ReferencedDomainNameA, &ReferencedDomainNameW, FALSE); 507*c2c66affSColin Finck ReferencedDomainNameA.Buffer[ReferencedDomainNameA.Length] = '\0'; 508*c2c66affSColin Finck } 509*c2c66affSColin Finck } 510*c2c66affSColin Finck 511*c2c66affSColin Finck /* free previously allocated buffers */ 512*c2c66affSColin Finck if (SystemNameW.Buffer != NULL) 513*c2c66affSColin Finck { 514*c2c66affSColin Finck RtlFreeUnicodeString(&SystemNameW); 515*c2c66affSColin Finck } 516*c2c66affSColin Finck 517*c2c66affSColin Finck if (NameBuffer != NULL) 518*c2c66affSColin Finck { 519*c2c66affSColin Finck LocalFree(NameBuffer); 520*c2c66affSColin Finck } 521*c2c66affSColin Finck 522*c2c66affSColin Finck if (ReferencedDomainNameBuffer != NULL) 523*c2c66affSColin Finck { 524*c2c66affSColin Finck LocalFree(ReferencedDomainNameBuffer); 525*c2c66affSColin Finck } 526*c2c66affSColin Finck 527*c2c66affSColin Finck return Ret; 528*c2c66affSColin Finck } 529*c2c66affSColin Finck 530*c2c66affSColin Finck 531*c2c66affSColin Finck /****************************************************************************** 532*c2c66affSColin Finck * LookupAccountSidW [ADVAPI32.@] 533*c2c66affSColin Finck * 534*c2c66affSColin Finck * @implemented 535*c2c66affSColin Finck */ 536*c2c66affSColin Finck BOOL WINAPI 537*c2c66affSColin Finck LookupAccountSidW(LPCWSTR pSystemName, 538*c2c66affSColin Finck PSID pSid, 539*c2c66affSColin Finck LPWSTR pAccountName, 540*c2c66affSColin Finck LPDWORD pdwAccountName, 541*c2c66affSColin Finck LPWSTR pDomainName, 542*c2c66affSColin Finck LPDWORD pdwDomainName, 543*c2c66affSColin Finck PSID_NAME_USE peUse) 544*c2c66affSColin Finck { 545*c2c66affSColin Finck LSA_UNICODE_STRING SystemName; 546*c2c66affSColin Finck LSA_OBJECT_ATTRIBUTES ObjectAttributes = {0}; 547*c2c66affSColin Finck LSA_HANDLE PolicyHandle = NULL; 548*c2c66affSColin Finck NTSTATUS Status; 549*c2c66affSColin Finck PLSA_REFERENCED_DOMAIN_LIST ReferencedDomain = NULL; 550*c2c66affSColin Finck PLSA_TRANSLATED_NAME TranslatedName = NULL; 551*c2c66affSColin Finck BOOL ret; 552*c2c66affSColin Finck DWORD dwAccountName, dwDomainName; 553*c2c66affSColin Finck 554*c2c66affSColin Finck RtlInitUnicodeString(&SystemName, pSystemName); 555*c2c66affSColin Finck Status = LsaOpenPolicy(&SystemName, &ObjectAttributes, POLICY_LOOKUP_NAMES, &PolicyHandle); 556*c2c66affSColin Finck if (!NT_SUCCESS(Status)) 557*c2c66affSColin Finck { 558*c2c66affSColin Finck SetLastError(LsaNtStatusToWinError(Status)); 559*c2c66affSColin Finck return FALSE; 560*c2c66affSColin Finck } 561*c2c66affSColin Finck 562*c2c66affSColin Finck Status = LsaLookupSids(PolicyHandle, 1, &pSid, &ReferencedDomain, &TranslatedName); 563*c2c66affSColin Finck 564*c2c66affSColin Finck LsaClose(PolicyHandle); 565*c2c66affSColin Finck 566*c2c66affSColin Finck if (!NT_SUCCESS(Status) || Status == STATUS_SOME_NOT_MAPPED) 567*c2c66affSColin Finck { 568*c2c66affSColin Finck SetLastError(LsaNtStatusToWinError(Status)); 569*c2c66affSColin Finck ret = FALSE; 570*c2c66affSColin Finck } 571*c2c66affSColin Finck else 572*c2c66affSColin Finck { 573*c2c66affSColin Finck ret = TRUE; 574*c2c66affSColin Finck 575*c2c66affSColin Finck dwAccountName = TranslatedName->Name.Length / sizeof(WCHAR); 576*c2c66affSColin Finck if (ReferencedDomain && ReferencedDomain->Entries > 0) 577*c2c66affSColin Finck dwDomainName = ReferencedDomain->Domains[0].Name.Length / sizeof(WCHAR); 578*c2c66affSColin Finck else 579*c2c66affSColin Finck dwDomainName = 0; 580*c2c66affSColin Finck 581*c2c66affSColin Finck if (*pdwAccountName <= dwAccountName || *pdwDomainName <= dwDomainName) 582*c2c66affSColin Finck { 583*c2c66affSColin Finck /* One or two buffers are insufficient, add up a char for NULL termination */ 584*c2c66affSColin Finck *pdwAccountName = dwAccountName + 1; 585*c2c66affSColin Finck *pdwDomainName = dwDomainName + 1; 586*c2c66affSColin Finck ret = FALSE; 587*c2c66affSColin Finck } 588*c2c66affSColin Finck else 589*c2c66affSColin Finck { 590*c2c66affSColin Finck /* Lengths are sufficient, copy the data */ 591*c2c66affSColin Finck if (dwAccountName) 592*c2c66affSColin Finck RtlCopyMemory(pAccountName, TranslatedName->Name.Buffer, dwAccountName * sizeof(WCHAR)); 593*c2c66affSColin Finck pAccountName[dwAccountName] = L'\0'; 594*c2c66affSColin Finck 595*c2c66affSColin Finck if (dwDomainName) 596*c2c66affSColin Finck RtlCopyMemory(pDomainName, ReferencedDomain->Domains[0].Name.Buffer, dwDomainName * sizeof(WCHAR)); 597*c2c66affSColin Finck pDomainName[dwDomainName] = L'\0'; 598*c2c66affSColin Finck 599*c2c66affSColin Finck *pdwAccountName = dwAccountName; 600*c2c66affSColin Finck *pdwDomainName = dwDomainName; 601*c2c66affSColin Finck 602*c2c66affSColin Finck if (peUse) 603*c2c66affSColin Finck *peUse = TranslatedName->Use; 604*c2c66affSColin Finck } 605*c2c66affSColin Finck 606*c2c66affSColin Finck if (!ret) 607*c2c66affSColin Finck SetLastError(ERROR_INSUFFICIENT_BUFFER); 608*c2c66affSColin Finck } 609*c2c66affSColin Finck 610*c2c66affSColin Finck if (ReferencedDomain) 611*c2c66affSColin Finck LsaFreeMemory(ReferencedDomain); 612*c2c66affSColin Finck 613*c2c66affSColin Finck if (TranslatedName) 614*c2c66affSColin Finck LsaFreeMemory(TranslatedName); 615*c2c66affSColin Finck 616*c2c66affSColin Finck return ret; 617*c2c66affSColin Finck } 618*c2c66affSColin Finck 619*c2c66affSColin Finck /****************************************************************************** 620*c2c66affSColin Finck * LookupAccountNameW [ADVAPI32.@] 621*c2c66affSColin Finck * 622*c2c66affSColin Finck * @implemented 623*c2c66affSColin Finck */ 624*c2c66affSColin Finck BOOL 625*c2c66affSColin Finck WINAPI 626*c2c66affSColin Finck LookupAccountNameW(LPCWSTR lpSystemName, 627*c2c66affSColin Finck LPCWSTR lpAccountName, 628*c2c66affSColin Finck PSID Sid, 629*c2c66affSColin Finck LPDWORD cbSid, 630*c2c66affSColin Finck LPWSTR ReferencedDomainName, 631*c2c66affSColin Finck LPDWORD cchReferencedDomainName, 632*c2c66affSColin Finck PSID_NAME_USE peUse) 633*c2c66affSColin Finck { 634*c2c66affSColin Finck OBJECT_ATTRIBUTES ObjectAttributes = {0}; 635*c2c66affSColin Finck UNICODE_STRING SystemName; 636*c2c66affSColin Finck UNICODE_STRING AccountName; 637*c2c66affSColin Finck LSA_HANDLE PolicyHandle = NULL; 638*c2c66affSColin Finck PLSA_REFERENCED_DOMAIN_LIST ReferencedDomains = NULL; 639*c2c66affSColin Finck PLSA_TRANSLATED_SID TranslatedSid = NULL; 640*c2c66affSColin Finck PSID pDomainSid; 641*c2c66affSColin Finck DWORD dwDomainNameLength; 642*c2c66affSColin Finck DWORD dwSidLength; 643*c2c66affSColin Finck UCHAR nSubAuthorities; 644*c2c66affSColin Finck BOOL bResult; 645*c2c66affSColin Finck NTSTATUS Status; 646*c2c66affSColin Finck 647*c2c66affSColin Finck TRACE("%s %s %p %p %p %p %p\n", lpSystemName, lpAccountName, 648*c2c66affSColin Finck Sid, cbSid, ReferencedDomainName, cchReferencedDomainName, peUse); 649*c2c66affSColin Finck 650*c2c66affSColin Finck RtlInitUnicodeString(&SystemName, 651*c2c66affSColin Finck lpSystemName); 652*c2c66affSColin Finck 653*c2c66affSColin Finck Status = LsaOpenPolicy(lpSystemName ? &SystemName : NULL, 654*c2c66affSColin Finck &ObjectAttributes, 655*c2c66affSColin Finck POLICY_LOOKUP_NAMES, 656*c2c66affSColin Finck &PolicyHandle); 657*c2c66affSColin Finck if (!NT_SUCCESS(Status)) 658*c2c66affSColin Finck { 659*c2c66affSColin Finck SetLastError(LsaNtStatusToWinError(Status)); 660*c2c66affSColin Finck return FALSE; 661*c2c66affSColin Finck } 662*c2c66affSColin Finck 663*c2c66affSColin Finck RtlInitUnicodeString(&AccountName, 664*c2c66affSColin Finck lpAccountName); 665*c2c66affSColin Finck 666*c2c66affSColin Finck Status = LsaLookupNames(PolicyHandle, 667*c2c66affSColin Finck 1, 668*c2c66affSColin Finck &AccountName, 669*c2c66affSColin Finck &ReferencedDomains, 670*c2c66affSColin Finck &TranslatedSid); 671*c2c66affSColin Finck 672*c2c66affSColin Finck LsaClose(PolicyHandle); 673*c2c66affSColin Finck 674*c2c66affSColin Finck if (!NT_SUCCESS(Status) || Status == STATUS_SOME_NOT_MAPPED) 675*c2c66affSColin Finck { 676*c2c66affSColin Finck SetLastError(LsaNtStatusToWinError(Status)); 677*c2c66affSColin Finck bResult = FALSE; 678*c2c66affSColin Finck } 679*c2c66affSColin Finck else 680*c2c66affSColin Finck { 681*c2c66affSColin Finck pDomainSid = ReferencedDomains->Domains[TranslatedSid->DomainIndex].Sid; 682*c2c66affSColin Finck nSubAuthorities = *GetSidSubAuthorityCount(pDomainSid); 683*c2c66affSColin Finck dwSidLength = GetSidLengthRequired(nSubAuthorities + 1); 684*c2c66affSColin Finck 685*c2c66affSColin Finck dwDomainNameLength = ReferencedDomains->Domains->Name.Length / sizeof(WCHAR); 686*c2c66affSColin Finck 687*c2c66affSColin Finck if (*cbSid < dwSidLength || 688*c2c66affSColin Finck *cchReferencedDomainName < dwDomainNameLength + 1) 689*c2c66affSColin Finck { 690*c2c66affSColin Finck *cbSid = dwSidLength; 691*c2c66affSColin Finck *cchReferencedDomainName = dwDomainNameLength + 1; 692*c2c66affSColin Finck 693*c2c66affSColin Finck bResult = FALSE; 694*c2c66affSColin Finck } 695*c2c66affSColin Finck else 696*c2c66affSColin Finck { 697*c2c66affSColin Finck CopySid(*cbSid, Sid, pDomainSid); 698*c2c66affSColin Finck *GetSidSubAuthorityCount(Sid) = nSubAuthorities + 1; 699*c2c66affSColin Finck *GetSidSubAuthority(Sid, (DWORD)nSubAuthorities) = TranslatedSid->RelativeId; 700*c2c66affSColin Finck 701*c2c66affSColin Finck RtlCopyMemory(ReferencedDomainName, ReferencedDomains->Domains->Name.Buffer, dwDomainNameLength * sizeof(WCHAR)); 702*c2c66affSColin Finck ReferencedDomainName[dwDomainNameLength] = L'\0'; 703*c2c66affSColin Finck 704*c2c66affSColin Finck *cchReferencedDomainName = dwDomainNameLength; 705*c2c66affSColin Finck 706*c2c66affSColin Finck *peUse = TranslatedSid->Use; 707*c2c66affSColin Finck 708*c2c66affSColin Finck bResult = TRUE; 709*c2c66affSColin Finck } 710*c2c66affSColin Finck 711*c2c66affSColin Finck if (bResult == FALSE) 712*c2c66affSColin Finck SetLastError(ERROR_INSUFFICIENT_BUFFER); 713*c2c66affSColin Finck } 714*c2c66affSColin Finck 715*c2c66affSColin Finck if (ReferencedDomains != NULL) 716*c2c66affSColin Finck LsaFreeMemory(ReferencedDomains); 717*c2c66affSColin Finck 718*c2c66affSColin Finck if (TranslatedSid != NULL) 719*c2c66affSColin Finck LsaFreeMemory(TranslatedSid); 720*c2c66affSColin Finck 721*c2c66affSColin Finck return bResult; 722*c2c66affSColin Finck } 723*c2c66affSColin Finck 724*c2c66affSColin Finck 725*c2c66affSColin Finck /********************************************************************** 726*c2c66affSColin Finck * LookupPrivilegeValueA EXPORTED 727*c2c66affSColin Finck * 728*c2c66affSColin Finck * @implemented 729*c2c66affSColin Finck */ 730*c2c66affSColin Finck BOOL 731*c2c66affSColin Finck WINAPI 732*c2c66affSColin Finck LookupPrivilegeValueA(LPCSTR lpSystemName, 733*c2c66affSColin Finck LPCSTR lpName, 734*c2c66affSColin Finck PLUID lpLuid) 735*c2c66affSColin Finck { 736*c2c66affSColin Finck UNICODE_STRING SystemName; 737*c2c66affSColin Finck UNICODE_STRING Name; 738*c2c66affSColin Finck BOOL Result; 739*c2c66affSColin Finck 740*c2c66affSColin Finck /* Remote system? */ 741*c2c66affSColin Finck if (lpSystemName != NULL) 742*c2c66affSColin Finck { 743*c2c66affSColin Finck RtlCreateUnicodeStringFromAsciiz(&SystemName, 744*c2c66affSColin Finck (LPSTR)lpSystemName); 745*c2c66affSColin Finck } 746*c2c66affSColin Finck else 747*c2c66affSColin Finck SystemName.Buffer = NULL; 748*c2c66affSColin Finck 749*c2c66affSColin Finck /* Check the privilege name is not NULL */ 750*c2c66affSColin Finck if (lpName == NULL) 751*c2c66affSColin Finck { 752*c2c66affSColin Finck SetLastError(ERROR_NO_SUCH_PRIVILEGE); 753*c2c66affSColin Finck return FALSE; 754*c2c66affSColin Finck } 755*c2c66affSColin Finck 756*c2c66affSColin Finck RtlCreateUnicodeStringFromAsciiz(&Name, 757*c2c66affSColin Finck (LPSTR)lpName); 758*c2c66affSColin Finck 759*c2c66affSColin Finck Result = LookupPrivilegeValueW(SystemName.Buffer, 760*c2c66affSColin Finck Name.Buffer, 761*c2c66affSColin Finck lpLuid); 762*c2c66affSColin Finck 763*c2c66affSColin Finck RtlFreeUnicodeString(&Name); 764*c2c66affSColin Finck 765*c2c66affSColin Finck /* Remote system? */ 766*c2c66affSColin Finck if (SystemName.Buffer != NULL) 767*c2c66affSColin Finck { 768*c2c66affSColin Finck RtlFreeUnicodeString(&SystemName); 769*c2c66affSColin Finck } 770*c2c66affSColin Finck 771*c2c66affSColin Finck return Result; 772*c2c66affSColin Finck } 773*c2c66affSColin Finck 774*c2c66affSColin Finck 775*c2c66affSColin Finck /********************************************************************** 776*c2c66affSColin Finck * LookupPrivilegeValueW 777*c2c66affSColin Finck * 778*c2c66affSColin Finck * @implemented 779*c2c66affSColin Finck */ 780*c2c66affSColin Finck BOOL 781*c2c66affSColin Finck WINAPI 782*c2c66affSColin Finck LookupPrivilegeValueW(LPCWSTR lpSystemName, 783*c2c66affSColin Finck LPCWSTR lpPrivilegeName, 784*c2c66affSColin Finck PLUID lpLuid) 785*c2c66affSColin Finck { 786*c2c66affSColin Finck OBJECT_ATTRIBUTES ObjectAttributes = {0}; 787*c2c66affSColin Finck UNICODE_STRING SystemName; 788*c2c66affSColin Finck UNICODE_STRING PrivilegeName; 789*c2c66affSColin Finck LSA_HANDLE PolicyHandle = NULL; 790*c2c66affSColin Finck NTSTATUS Status; 791*c2c66affSColin Finck 792*c2c66affSColin Finck TRACE("%S,%S,%p\n", lpSystemName, lpPrivilegeName, lpLuid); 793*c2c66affSColin Finck 794*c2c66affSColin Finck RtlInitUnicodeString(&SystemName, 795*c2c66affSColin Finck lpSystemName); 796*c2c66affSColin Finck 797*c2c66affSColin Finck Status = LsaOpenPolicy(lpSystemName ? &SystemName : NULL, 798*c2c66affSColin Finck &ObjectAttributes, 799*c2c66affSColin Finck POLICY_LOOKUP_NAMES, 800*c2c66affSColin Finck &PolicyHandle); 801*c2c66affSColin Finck if (!NT_SUCCESS(Status)) 802*c2c66affSColin Finck { 803*c2c66affSColin Finck SetLastError(LsaNtStatusToWinError(Status)); 804*c2c66affSColin Finck return FALSE; 805*c2c66affSColin Finck } 806*c2c66affSColin Finck 807*c2c66affSColin Finck RtlInitUnicodeString(&PrivilegeName, 808*c2c66affSColin Finck lpPrivilegeName); 809*c2c66affSColin Finck 810*c2c66affSColin Finck Status = LsaLookupPrivilegeValue(PolicyHandle, 811*c2c66affSColin Finck &PrivilegeName, 812*c2c66affSColin Finck lpLuid); 813*c2c66affSColin Finck 814*c2c66affSColin Finck LsaClose(PolicyHandle); 815*c2c66affSColin Finck 816*c2c66affSColin Finck if (!NT_SUCCESS(Status)) 817*c2c66affSColin Finck { 818*c2c66affSColin Finck SetLastError(LsaNtStatusToWinError(Status)); 819*c2c66affSColin Finck return FALSE; 820*c2c66affSColin Finck } 821*c2c66affSColin Finck 822*c2c66affSColin Finck return TRUE; 823*c2c66affSColin Finck } 824*c2c66affSColin Finck 825*c2c66affSColin Finck /********************************************************************** 826*c2c66affSColin Finck * LookupPrivilegeNameW EXPORTED 827*c2c66affSColin Finck * 828*c2c66affSColin Finck * @implemented 829*c2c66affSColin Finck */ 830*c2c66affSColin Finck BOOL 831*c2c66affSColin Finck WINAPI 832*c2c66affSColin Finck LookupPrivilegeNameW(LPCWSTR lpSystemName, 833*c2c66affSColin Finck PLUID lpLuid, 834*c2c66affSColin Finck LPWSTR lpName, 835*c2c66affSColin Finck LPDWORD cchName) 836*c2c66affSColin Finck { 837*c2c66affSColin Finck OBJECT_ATTRIBUTES ObjectAttributes = {0}; 838*c2c66affSColin Finck UNICODE_STRING SystemName; 839*c2c66affSColin Finck PUNICODE_STRING PrivilegeName = NULL; 840*c2c66affSColin Finck LSA_HANDLE PolicyHandle = NULL; 841*c2c66affSColin Finck NTSTATUS Status; 842*c2c66affSColin Finck 843*c2c66affSColin Finck TRACE("%S,%p,%p,%p\n", lpSystemName, lpLuid, lpName, cchName); 844*c2c66affSColin Finck 845*c2c66affSColin Finck RtlInitUnicodeString(&SystemName, 846*c2c66affSColin Finck lpSystemName); 847*c2c66affSColin Finck 848*c2c66affSColin Finck Status = LsaOpenPolicy(lpSystemName ? &SystemName : NULL, 849*c2c66affSColin Finck &ObjectAttributes, 850*c2c66affSColin Finck POLICY_LOOKUP_NAMES, 851*c2c66affSColin Finck &PolicyHandle); 852*c2c66affSColin Finck if (!NT_SUCCESS(Status)) 853*c2c66affSColin Finck { 854*c2c66affSColin Finck SetLastError(LsaNtStatusToWinError(Status)); 855*c2c66affSColin Finck return FALSE; 856*c2c66affSColin Finck } 857*c2c66affSColin Finck 858*c2c66affSColin Finck Status = LsaLookupPrivilegeName(PolicyHandle, 859*c2c66affSColin Finck lpLuid, 860*c2c66affSColin Finck &PrivilegeName); 861*c2c66affSColin Finck if (NT_SUCCESS(Status)) 862*c2c66affSColin Finck { 863*c2c66affSColin Finck if (PrivilegeName->Length + sizeof(WCHAR) > *cchName * sizeof(WCHAR)) 864*c2c66affSColin Finck { 865*c2c66affSColin Finck Status = STATUS_BUFFER_TOO_SMALL; 866*c2c66affSColin Finck 867*c2c66affSColin Finck *cchName = (PrivilegeName->Length + sizeof(WCHAR)) / sizeof(WCHAR); 868*c2c66affSColin Finck } 869*c2c66affSColin Finck else 870*c2c66affSColin Finck { 871*c2c66affSColin Finck RtlMoveMemory(lpName, 872*c2c66affSColin Finck PrivilegeName->Buffer, 873*c2c66affSColin Finck PrivilegeName->Length); 874*c2c66affSColin Finck lpName[PrivilegeName->Length / sizeof(WCHAR)] = 0; 875*c2c66affSColin Finck 876*c2c66affSColin Finck *cchName = PrivilegeName->Length / sizeof(WCHAR); 877*c2c66affSColin Finck } 878*c2c66affSColin Finck 879*c2c66affSColin Finck LsaFreeMemory(PrivilegeName->Buffer); 880*c2c66affSColin Finck LsaFreeMemory(PrivilegeName); 881*c2c66affSColin Finck } 882*c2c66affSColin Finck 883*c2c66affSColin Finck LsaClose(PolicyHandle); 884*c2c66affSColin Finck 885*c2c66affSColin Finck if (!NT_SUCCESS(Status)) 886*c2c66affSColin Finck { 887*c2c66affSColin Finck SetLastError(LsaNtStatusToWinError(Status)); 888*c2c66affSColin Finck return FALSE; 889*c2c66affSColin Finck } 890*c2c66affSColin Finck 891*c2c66affSColin Finck return TRUE; 892*c2c66affSColin Finck } 893*c2c66affSColin Finck 894*c2c66affSColin Finck /********************************************************************** 895*c2c66affSColin Finck * LookupPrivilegeDisplayNameW EXPORTED 896*c2c66affSColin Finck * 897*c2c66affSColin Finck * @unimplemented 898*c2c66affSColin Finck */ 899*c2c66affSColin Finck BOOL 900*c2c66affSColin Finck WINAPI 901*c2c66affSColin Finck LookupPrivilegeDisplayNameW(LPCWSTR lpSystemName, 902*c2c66affSColin Finck LPCWSTR lpName, 903*c2c66affSColin Finck LPWSTR lpDisplayName, 904*c2c66affSColin Finck LPDWORD cchDisplayName, 905*c2c66affSColin Finck LPDWORD lpLanguageId) 906*c2c66affSColin Finck { 907*c2c66affSColin Finck OBJECT_ATTRIBUTES ObjectAttributes = {0}; 908*c2c66affSColin Finck UNICODE_STRING SystemName, Name; 909*c2c66affSColin Finck PUNICODE_STRING DisplayName; 910*c2c66affSColin Finck LSA_HANDLE PolicyHandle = NULL; 911*c2c66affSColin Finck USHORT LanguageId; 912*c2c66affSColin Finck NTSTATUS Status; 913*c2c66affSColin Finck 914*c2c66affSColin Finck TRACE("%S,%S,%p,%p,%p\n", lpSystemName, lpName, lpDisplayName, cchDisplayName, lpLanguageId); 915*c2c66affSColin Finck 916*c2c66affSColin Finck RtlInitUnicodeString(&SystemName, lpSystemName); 917*c2c66affSColin Finck RtlInitUnicodeString(&Name, lpName); 918*c2c66affSColin Finck 919*c2c66affSColin Finck Status = LsaOpenPolicy(lpSystemName ? &SystemName : NULL, 920*c2c66affSColin Finck &ObjectAttributes, 921*c2c66affSColin Finck POLICY_LOOKUP_NAMES, 922*c2c66affSColin Finck &PolicyHandle); 923*c2c66affSColin Finck if (!NT_SUCCESS(Status)) 924*c2c66affSColin Finck { 925*c2c66affSColin Finck SetLastError(LsaNtStatusToWinError(Status)); 926*c2c66affSColin Finck return FALSE; 927*c2c66affSColin Finck } 928*c2c66affSColin Finck 929*c2c66affSColin Finck Status = LsaLookupPrivilegeDisplayName(PolicyHandle, &Name, &DisplayName, &LanguageId); 930*c2c66affSColin Finck if (NT_SUCCESS(Status)) 931*c2c66affSColin Finck { 932*c2c66affSColin Finck *lpLanguageId = LanguageId; 933*c2c66affSColin Finck if (DisplayName->Length + sizeof(WCHAR) > *cchDisplayName * sizeof(WCHAR)) 934*c2c66affSColin Finck { 935*c2c66affSColin Finck Status = STATUS_BUFFER_TOO_SMALL; 936*c2c66affSColin Finck 937*c2c66affSColin Finck *cchDisplayName = (DisplayName->Length + sizeof(WCHAR)) / sizeof(WCHAR); 938*c2c66affSColin Finck } 939*c2c66affSColin Finck else 940*c2c66affSColin Finck { 941*c2c66affSColin Finck RtlMoveMemory(lpDisplayName, 942*c2c66affSColin Finck DisplayName->Buffer, 943*c2c66affSColin Finck DisplayName->Length); 944*c2c66affSColin Finck lpDisplayName[DisplayName->Length / sizeof(WCHAR)] = 0; 945*c2c66affSColin Finck 946*c2c66affSColin Finck *cchDisplayName = DisplayName->Length / sizeof(WCHAR); 947*c2c66affSColin Finck } 948*c2c66affSColin Finck 949*c2c66affSColin Finck LsaFreeMemory(DisplayName->Buffer); 950*c2c66affSColin Finck LsaFreeMemory(DisplayName); 951*c2c66affSColin Finck } 952*c2c66affSColin Finck 953*c2c66affSColin Finck LsaClose(PolicyHandle); 954*c2c66affSColin Finck 955*c2c66affSColin Finck if (!NT_SUCCESS(Status)) 956*c2c66affSColin Finck { 957*c2c66affSColin Finck SetLastError(LsaNtStatusToWinError(Status)); 958*c2c66affSColin Finck return FALSE; 959*c2c66affSColin Finck } 960*c2c66affSColin Finck 961*c2c66affSColin Finck return TRUE; 962*c2c66affSColin Finck } 963*c2c66affSColin Finck 964*c2c66affSColin Finck static DWORD 965*c2c66affSColin Finck pGetSecurityInfoCheck(SECURITY_INFORMATION SecurityInfo, 966*c2c66affSColin Finck PSID *ppsidOwner, 967*c2c66affSColin Finck PSID *ppsidGroup, 968*c2c66affSColin Finck PACL *ppDacl, 969*c2c66affSColin Finck PACL *ppSacl, 970*c2c66affSColin Finck PSECURITY_DESCRIPTOR* ppSecurityDescriptor) 971*c2c66affSColin Finck { 972*c2c66affSColin Finck if ((SecurityInfo & (OWNER_SECURITY_INFORMATION | 973*c2c66affSColin Finck GROUP_SECURITY_INFORMATION | 974*c2c66affSColin Finck DACL_SECURITY_INFORMATION | 975*c2c66affSColin Finck SACL_SECURITY_INFORMATION)) && 976*c2c66affSColin Finck ppSecurityDescriptor == NULL) 977*c2c66affSColin Finck { 978*c2c66affSColin Finck /* if one of the SIDs or ACLs are present, the security descriptor 979*c2c66affSColin Finck most not be NULL */ 980*c2c66affSColin Finck return ERROR_INVALID_PARAMETER; 981*c2c66affSColin Finck } 982*c2c66affSColin Finck else 983*c2c66affSColin Finck { 984*c2c66affSColin Finck /* reset the pointers unless they're ignored */ 985*c2c66affSColin Finck if ((SecurityInfo & OWNER_SECURITY_INFORMATION) && 986*c2c66affSColin Finck ppsidOwner != NULL) 987*c2c66affSColin Finck { 988*c2c66affSColin Finck *ppsidOwner = NULL; 989*c2c66affSColin Finck } 990*c2c66affSColin Finck if ((SecurityInfo & GROUP_SECURITY_INFORMATION) && 991*c2c66affSColin Finck ppsidGroup != NULL) 992*c2c66affSColin Finck { 993*c2c66affSColin Finck *ppsidGroup = NULL; 994*c2c66affSColin Finck } 995*c2c66affSColin Finck if ((SecurityInfo & DACL_SECURITY_INFORMATION) && 996*c2c66affSColin Finck ppDacl != NULL) 997*c2c66affSColin Finck { 998*c2c66affSColin Finck *ppDacl = NULL; 999*c2c66affSColin Finck } 1000*c2c66affSColin Finck if ((SecurityInfo & SACL_SECURITY_INFORMATION) && 1001*c2c66affSColin Finck ppSacl != NULL) 1002*c2c66affSColin Finck { 1003*c2c66affSColin Finck *ppSacl = NULL; 1004*c2c66affSColin Finck } 1005*c2c66affSColin Finck 1006*c2c66affSColin Finck if (SecurityInfo & (OWNER_SECURITY_INFORMATION | 1007*c2c66affSColin Finck GROUP_SECURITY_INFORMATION | 1008*c2c66affSColin Finck DACL_SECURITY_INFORMATION | 1009*c2c66affSColin Finck SACL_SECURITY_INFORMATION)) 1010*c2c66affSColin Finck { 1011*c2c66affSColin Finck *ppSecurityDescriptor = NULL; 1012*c2c66affSColin Finck } 1013*c2c66affSColin Finck 1014*c2c66affSColin Finck return ERROR_SUCCESS; 1015*c2c66affSColin Finck } 1016*c2c66affSColin Finck } 1017*c2c66affSColin Finck 1018*c2c66affSColin Finck 1019*c2c66affSColin Finck static DWORD 1020*c2c66affSColin Finck pSetSecurityInfoCheck(PSECURITY_DESCRIPTOR pSecurityDescriptor, 1021*c2c66affSColin Finck SECURITY_INFORMATION SecurityInfo, 1022*c2c66affSColin Finck PSID psidOwner, 1023*c2c66affSColin Finck PSID psidGroup, 1024*c2c66affSColin Finck PACL pDacl, 1025*c2c66affSColin Finck PACL pSacl) 1026*c2c66affSColin Finck { 1027*c2c66affSColin Finck /* initialize a security descriptor on the stack */ 1028*c2c66affSColin Finck if (!InitializeSecurityDescriptor(pSecurityDescriptor, 1029*c2c66affSColin Finck SECURITY_DESCRIPTOR_REVISION)) 1030*c2c66affSColin Finck { 1031*c2c66affSColin Finck return GetLastError(); 1032*c2c66affSColin Finck } 1033*c2c66affSColin Finck 1034*c2c66affSColin Finck if (SecurityInfo & OWNER_SECURITY_INFORMATION) 1035*c2c66affSColin Finck { 1036*c2c66affSColin Finck if (RtlValidSid(psidOwner)) 1037*c2c66affSColin Finck { 1038*c2c66affSColin Finck if (!SetSecurityDescriptorOwner(pSecurityDescriptor, 1039*c2c66affSColin Finck psidOwner, 1040*c2c66affSColin Finck FALSE)) 1041*c2c66affSColin Finck { 1042*c2c66affSColin Finck return GetLastError(); 1043*c2c66affSColin Finck } 1044*c2c66affSColin Finck } 1045*c2c66affSColin Finck else 1046*c2c66affSColin Finck { 1047*c2c66affSColin Finck return ERROR_INVALID_PARAMETER; 1048*c2c66affSColin Finck } 1049*c2c66affSColin Finck } 1050*c2c66affSColin Finck 1051*c2c66affSColin Finck if (SecurityInfo & GROUP_SECURITY_INFORMATION) 1052*c2c66affSColin Finck { 1053*c2c66affSColin Finck if (RtlValidSid(psidGroup)) 1054*c2c66affSColin Finck { 1055*c2c66affSColin Finck if (!SetSecurityDescriptorGroup(pSecurityDescriptor, 1056*c2c66affSColin Finck psidGroup, 1057*c2c66affSColin Finck FALSE)) 1058*c2c66affSColin Finck { 1059*c2c66affSColin Finck return GetLastError(); 1060*c2c66affSColin Finck } 1061*c2c66affSColin Finck } 1062*c2c66affSColin Finck else 1063*c2c66affSColin Finck { 1064*c2c66affSColin Finck return ERROR_INVALID_PARAMETER; 1065*c2c66affSColin Finck } 1066*c2c66affSColin Finck } 1067*c2c66affSColin Finck 1068*c2c66affSColin Finck if (SecurityInfo & DACL_SECURITY_INFORMATION) 1069*c2c66affSColin Finck { 1070*c2c66affSColin Finck if (pDacl != NULL) 1071*c2c66affSColin Finck { 1072*c2c66affSColin Finck if (SetSecurityDescriptorDacl(pSecurityDescriptor, 1073*c2c66affSColin Finck TRUE, 1074*c2c66affSColin Finck pDacl, 1075*c2c66affSColin Finck FALSE)) 1076*c2c66affSColin Finck { 1077*c2c66affSColin Finck /* check if the DACL needs to be protected from being 1078*c2c66affSColin Finck modified by inheritable ACEs */ 1079*c2c66affSColin Finck if (SecurityInfo & PROTECTED_DACL_SECURITY_INFORMATION) 1080*c2c66affSColin Finck { 1081*c2c66affSColin Finck goto ProtectDacl; 1082*c2c66affSColin Finck } 1083*c2c66affSColin Finck } 1084*c2c66affSColin Finck else 1085*c2c66affSColin Finck { 1086*c2c66affSColin Finck return GetLastError(); 1087*c2c66affSColin Finck } 1088*c2c66affSColin Finck } 1089*c2c66affSColin Finck else 1090*c2c66affSColin Finck { 1091*c2c66affSColin Finck ProtectDacl: 1092*c2c66affSColin Finck /* protect the DACL from being modified by inheritable ACEs */ 1093*c2c66affSColin Finck if (!SetSecurityDescriptorControl(pSecurityDescriptor, 1094*c2c66affSColin Finck SE_DACL_PROTECTED, 1095*c2c66affSColin Finck SE_DACL_PROTECTED)) 1096*c2c66affSColin Finck { 1097*c2c66affSColin Finck return GetLastError(); 1098*c2c66affSColin Finck } 1099*c2c66affSColin Finck } 1100*c2c66affSColin Finck } 1101*c2c66affSColin Finck 1102*c2c66affSColin Finck if (SecurityInfo & SACL_SECURITY_INFORMATION) 1103*c2c66affSColin Finck { 1104*c2c66affSColin Finck if (pSacl != NULL) 1105*c2c66affSColin Finck { 1106*c2c66affSColin Finck if (SetSecurityDescriptorSacl(pSecurityDescriptor, 1107*c2c66affSColin Finck TRUE, 1108*c2c66affSColin Finck pSacl, 1109*c2c66affSColin Finck FALSE)) 1110*c2c66affSColin Finck { 1111*c2c66affSColin Finck /* check if the SACL needs to be protected from being 1112*c2c66affSColin Finck modified by inheritable ACEs */ 1113*c2c66affSColin Finck if (SecurityInfo & PROTECTED_SACL_SECURITY_INFORMATION) 1114*c2c66affSColin Finck { 1115*c2c66affSColin Finck goto ProtectSacl; 1116*c2c66affSColin Finck } 1117*c2c66affSColin Finck } 1118*c2c66affSColin Finck else 1119*c2c66affSColin Finck { 1120*c2c66affSColin Finck return GetLastError(); 1121*c2c66affSColin Finck } 1122*c2c66affSColin Finck } 1123*c2c66affSColin Finck else 1124*c2c66affSColin Finck { 1125*c2c66affSColin Finck ProtectSacl: 1126*c2c66affSColin Finck /* protect the SACL from being modified by inheritable ACEs */ 1127*c2c66affSColin Finck if (!SetSecurityDescriptorControl(pSecurityDescriptor, 1128*c2c66affSColin Finck SE_SACL_PROTECTED, 1129*c2c66affSColin Finck SE_SACL_PROTECTED)) 1130*c2c66affSColin Finck { 1131*c2c66affSColin Finck return GetLastError(); 1132*c2c66affSColin Finck } 1133*c2c66affSColin Finck } 1134*c2c66affSColin Finck } 1135*c2c66affSColin Finck 1136*c2c66affSColin Finck return ERROR_SUCCESS; 1137*c2c66affSColin Finck } 1138*c2c66affSColin Finck 1139*c2c66affSColin Finck 1140*c2c66affSColin Finck /********************************************************************** 1141*c2c66affSColin Finck * GetNamedSecurityInfoW EXPORTED 1142*c2c66affSColin Finck * 1143*c2c66affSColin Finck * @implemented 1144*c2c66affSColin Finck */ 1145*c2c66affSColin Finck DWORD 1146*c2c66affSColin Finck WINAPI 1147*c2c66affSColin Finck GetNamedSecurityInfoW(LPWSTR pObjectName, 1148*c2c66affSColin Finck SE_OBJECT_TYPE ObjectType, 1149*c2c66affSColin Finck SECURITY_INFORMATION SecurityInfo, 1150*c2c66affSColin Finck PSID *ppsidOwner, 1151*c2c66affSColin Finck PSID *ppsidGroup, 1152*c2c66affSColin Finck PACL *ppDacl, 1153*c2c66affSColin Finck PACL *ppSacl, 1154*c2c66affSColin Finck PSECURITY_DESCRIPTOR *ppSecurityDescriptor) 1155*c2c66affSColin Finck { 1156*c2c66affSColin Finck DWORD ErrorCode; 1157*c2c66affSColin Finck 1158*c2c66affSColin Finck if (pObjectName != NULL) 1159*c2c66affSColin Finck { 1160*c2c66affSColin Finck ErrorCode = CheckNtMartaPresent(); 1161*c2c66affSColin Finck if (ErrorCode == ERROR_SUCCESS) 1162*c2c66affSColin Finck { 1163*c2c66affSColin Finck ErrorCode = pGetSecurityInfoCheck(SecurityInfo, 1164*c2c66affSColin Finck ppsidOwner, 1165*c2c66affSColin Finck ppsidGroup, 1166*c2c66affSColin Finck ppDacl, 1167*c2c66affSColin Finck ppSacl, 1168*c2c66affSColin Finck ppSecurityDescriptor); 1169*c2c66affSColin Finck 1170*c2c66affSColin Finck if (ErrorCode == ERROR_SUCCESS) 1171*c2c66affSColin Finck { 1172*c2c66affSColin Finck /* call the MARTA provider */ 1173*c2c66affSColin Finck ErrorCode = AccRewriteGetNamedRights(pObjectName, 1174*c2c66affSColin Finck ObjectType, 1175*c2c66affSColin Finck SecurityInfo, 1176*c2c66affSColin Finck ppsidOwner, 1177*c2c66affSColin Finck ppsidGroup, 1178*c2c66affSColin Finck ppDacl, 1179*c2c66affSColin Finck ppSacl, 1180*c2c66affSColin Finck ppSecurityDescriptor); 1181*c2c66affSColin Finck } 1182*c2c66affSColin Finck } 1183*c2c66affSColin Finck } 1184*c2c66affSColin Finck else 1185*c2c66affSColin Finck ErrorCode = ERROR_INVALID_PARAMETER; 1186*c2c66affSColin Finck 1187*c2c66affSColin Finck return ErrorCode; 1188*c2c66affSColin Finck } 1189*c2c66affSColin Finck 1190*c2c66affSColin Finck /********************************************************************** 1191*c2c66affSColin Finck * SetNamedSecurityInfoW EXPORTED 1192*c2c66affSColin Finck * 1193*c2c66affSColin Finck * @implemented 1194*c2c66affSColin Finck */ 1195*c2c66affSColin Finck DWORD 1196*c2c66affSColin Finck WINAPI 1197*c2c66affSColin Finck SetNamedSecurityInfoW(LPWSTR pObjectName, 1198*c2c66affSColin Finck SE_OBJECT_TYPE ObjectType, 1199*c2c66affSColin Finck SECURITY_INFORMATION SecurityInfo, 1200*c2c66affSColin Finck PSID psidOwner, 1201*c2c66affSColin Finck PSID psidGroup, 1202*c2c66affSColin Finck PACL pDacl, 1203*c2c66affSColin Finck PACL pSacl) 1204*c2c66affSColin Finck { 1205*c2c66affSColin Finck DWORD ErrorCode; 1206*c2c66affSColin Finck 1207*c2c66affSColin Finck if (pObjectName != NULL) 1208*c2c66affSColin Finck { 1209*c2c66affSColin Finck ErrorCode = CheckNtMartaPresent(); 1210*c2c66affSColin Finck if (ErrorCode == ERROR_SUCCESS) 1211*c2c66affSColin Finck { 1212*c2c66affSColin Finck SECURITY_DESCRIPTOR SecurityDescriptor; 1213*c2c66affSColin Finck 1214*c2c66affSColin Finck ErrorCode = pSetSecurityInfoCheck(&SecurityDescriptor, 1215*c2c66affSColin Finck SecurityInfo, 1216*c2c66affSColin Finck psidOwner, 1217*c2c66affSColin Finck psidGroup, 1218*c2c66affSColin Finck pDacl, 1219*c2c66affSColin Finck pSacl); 1220*c2c66affSColin Finck 1221*c2c66affSColin Finck if (ErrorCode == ERROR_SUCCESS) 1222*c2c66affSColin Finck { 1223*c2c66affSColin Finck /* call the MARTA provider */ 1224*c2c66affSColin Finck ErrorCode = AccRewriteSetNamedRights(pObjectName, 1225*c2c66affSColin Finck ObjectType, 1226*c2c66affSColin Finck SecurityInfo, 1227*c2c66affSColin Finck &SecurityDescriptor); 1228*c2c66affSColin Finck } 1229*c2c66affSColin Finck } 1230*c2c66affSColin Finck } 1231*c2c66affSColin Finck else 1232*c2c66affSColin Finck ErrorCode = ERROR_INVALID_PARAMETER; 1233*c2c66affSColin Finck 1234*c2c66affSColin Finck return ErrorCode; 1235*c2c66affSColin Finck } 1236*c2c66affSColin Finck 1237*c2c66affSColin Finck /********************************************************************** 1238*c2c66affSColin Finck * GetSecurityInfo EXPORTED 1239*c2c66affSColin Finck * 1240*c2c66affSColin Finck * @implemented 1241*c2c66affSColin Finck */ 1242*c2c66affSColin Finck DWORD 1243*c2c66affSColin Finck WINAPI 1244*c2c66affSColin Finck GetSecurityInfo(HANDLE handle, 1245*c2c66affSColin Finck SE_OBJECT_TYPE ObjectType, 1246*c2c66affSColin Finck SECURITY_INFORMATION SecurityInfo, 1247*c2c66affSColin Finck PSID *ppsidOwner, 1248*c2c66affSColin Finck PSID *ppsidGroup, 1249*c2c66affSColin Finck PACL *ppDacl, 1250*c2c66affSColin Finck PACL *ppSacl, 1251*c2c66affSColin Finck PSECURITY_DESCRIPTOR *ppSecurityDescriptor) 1252*c2c66affSColin Finck { 1253*c2c66affSColin Finck DWORD ErrorCode; 1254*c2c66affSColin Finck 1255*c2c66affSColin Finck if (handle != NULL) 1256*c2c66affSColin Finck { 1257*c2c66affSColin Finck ErrorCode = CheckNtMartaPresent(); 1258*c2c66affSColin Finck if (ErrorCode == ERROR_SUCCESS) 1259*c2c66affSColin Finck { 1260*c2c66affSColin Finck ErrorCode = pGetSecurityInfoCheck(SecurityInfo, 1261*c2c66affSColin Finck ppsidOwner, 1262*c2c66affSColin Finck ppsidGroup, 1263*c2c66affSColin Finck ppDacl, 1264*c2c66affSColin Finck ppSacl, 1265*c2c66affSColin Finck ppSecurityDescriptor); 1266*c2c66affSColin Finck 1267*c2c66affSColin Finck if (ErrorCode == ERROR_SUCCESS) 1268*c2c66affSColin Finck { 1269*c2c66affSColin Finck /* call the MARTA provider */ 1270*c2c66affSColin Finck ErrorCode = AccRewriteGetHandleRights(handle, 1271*c2c66affSColin Finck ObjectType, 1272*c2c66affSColin Finck SecurityInfo, 1273*c2c66affSColin Finck ppsidOwner, 1274*c2c66affSColin Finck ppsidGroup, 1275*c2c66affSColin Finck ppDacl, 1276*c2c66affSColin Finck ppSacl, 1277*c2c66affSColin Finck ppSecurityDescriptor); 1278*c2c66affSColin Finck } 1279*c2c66affSColin Finck } 1280*c2c66affSColin Finck } 1281*c2c66affSColin Finck else 1282*c2c66affSColin Finck ErrorCode = ERROR_INVALID_HANDLE; 1283*c2c66affSColin Finck 1284*c2c66affSColin Finck return ErrorCode; 1285*c2c66affSColin Finck } 1286*c2c66affSColin Finck 1287*c2c66affSColin Finck 1288*c2c66affSColin Finck /********************************************************************** 1289*c2c66affSColin Finck * SetSecurityInfo EXPORTED 1290*c2c66affSColin Finck * 1291*c2c66affSColin Finck * @implemented 1292*c2c66affSColin Finck */ 1293*c2c66affSColin Finck DWORD 1294*c2c66affSColin Finck WINAPI 1295*c2c66affSColin Finck SetSecurityInfo(HANDLE handle, 1296*c2c66affSColin Finck SE_OBJECT_TYPE ObjectType, 1297*c2c66affSColin Finck SECURITY_INFORMATION SecurityInfo, 1298*c2c66affSColin Finck PSID psidOwner, 1299*c2c66affSColin Finck PSID psidGroup, 1300*c2c66affSColin Finck PACL pDacl, 1301*c2c66affSColin Finck PACL pSacl) 1302*c2c66affSColin Finck { 1303*c2c66affSColin Finck DWORD ErrorCode; 1304*c2c66affSColin Finck 1305*c2c66affSColin Finck if (handle != NULL) 1306*c2c66affSColin Finck { 1307*c2c66affSColin Finck ErrorCode = CheckNtMartaPresent(); 1308*c2c66affSColin Finck if (ErrorCode == ERROR_SUCCESS) 1309*c2c66affSColin Finck { 1310*c2c66affSColin Finck SECURITY_DESCRIPTOR SecurityDescriptor; 1311*c2c66affSColin Finck 1312*c2c66affSColin Finck ErrorCode = pSetSecurityInfoCheck(&SecurityDescriptor, 1313*c2c66affSColin Finck SecurityInfo, 1314*c2c66affSColin Finck psidOwner, 1315*c2c66affSColin Finck psidGroup, 1316*c2c66affSColin Finck pDacl, 1317*c2c66affSColin Finck pSacl); 1318*c2c66affSColin Finck 1319*c2c66affSColin Finck if (ErrorCode == ERROR_SUCCESS) 1320*c2c66affSColin Finck { 1321*c2c66affSColin Finck /* call the MARTA provider */ 1322*c2c66affSColin Finck ErrorCode = AccRewriteSetHandleRights(handle, 1323*c2c66affSColin Finck ObjectType, 1324*c2c66affSColin Finck SecurityInfo, 1325*c2c66affSColin Finck &SecurityDescriptor); 1326*c2c66affSColin Finck } 1327*c2c66affSColin Finck } 1328*c2c66affSColin Finck } 1329*c2c66affSColin Finck else 1330*c2c66affSColin Finck ErrorCode = ERROR_INVALID_HANDLE; 1331*c2c66affSColin Finck 1332*c2c66affSColin Finck return ErrorCode; 1333*c2c66affSColin Finck } 1334*c2c66affSColin Finck 1335*c2c66affSColin Finck /* 1336*c2c66affSColin Finck * @implemented 1337*c2c66affSColin Finck */ 1338*c2c66affSColin Finck BOOL 1339*c2c66affSColin Finck WINAPI 1340*c2c66affSColin Finck CreatePrivateObjectSecurity(PSECURITY_DESCRIPTOR ParentDescriptor, 1341*c2c66affSColin Finck PSECURITY_DESCRIPTOR CreatorDescriptor, 1342*c2c66affSColin Finck PSECURITY_DESCRIPTOR *NewDescriptor, 1343*c2c66affSColin Finck BOOL IsDirectoryObject, 1344*c2c66affSColin Finck HANDLE Token, 1345*c2c66affSColin Finck PGENERIC_MAPPING GenericMapping) 1346*c2c66affSColin Finck { 1347*c2c66affSColin Finck NTSTATUS Status; 1348*c2c66affSColin Finck 1349*c2c66affSColin Finck Status = RtlNewSecurityObject(ParentDescriptor, 1350*c2c66affSColin Finck CreatorDescriptor, 1351*c2c66affSColin Finck NewDescriptor, 1352*c2c66affSColin Finck IsDirectoryObject, 1353*c2c66affSColin Finck Token, 1354*c2c66affSColin Finck GenericMapping); 1355*c2c66affSColin Finck if (!NT_SUCCESS(Status)) 1356*c2c66affSColin Finck { 1357*c2c66affSColin Finck SetLastError(RtlNtStatusToDosError(Status)); 1358*c2c66affSColin Finck return FALSE; 1359*c2c66affSColin Finck } 1360*c2c66affSColin Finck 1361*c2c66affSColin Finck return TRUE; 1362*c2c66affSColin Finck } 1363*c2c66affSColin Finck 1364*c2c66affSColin Finck 1365*c2c66affSColin Finck /* 1366*c2c66affSColin Finck * @unimplemented 1367*c2c66affSColin Finck */ 1368*c2c66affSColin Finck BOOL 1369*c2c66affSColin Finck WINAPI 1370*c2c66affSColin Finck CreatePrivateObjectSecurityEx(PSECURITY_DESCRIPTOR ParentDescriptor, 1371*c2c66affSColin Finck PSECURITY_DESCRIPTOR CreatorDescriptor, 1372*c2c66affSColin Finck PSECURITY_DESCRIPTOR* NewDescriptor, 1373*c2c66affSColin Finck GUID* ObjectType, 1374*c2c66affSColin Finck BOOL IsContainerObject, 1375*c2c66affSColin Finck ULONG AutoInheritFlags, 1376*c2c66affSColin Finck HANDLE Token, 1377*c2c66affSColin Finck PGENERIC_MAPPING GenericMapping) 1378*c2c66affSColin Finck { 1379*c2c66affSColin Finck FIXME("%s() not implemented!\n", __FUNCTION__); 1380*c2c66affSColin Finck return FALSE; 1381*c2c66affSColin Finck } 1382*c2c66affSColin Finck 1383*c2c66affSColin Finck 1384*c2c66affSColin Finck /* 1385*c2c66affSColin Finck * @unimplemented 1386*c2c66affSColin Finck */ 1387*c2c66affSColin Finck BOOL 1388*c2c66affSColin Finck WINAPI 1389*c2c66affSColin Finck CreatePrivateObjectSecurityWithMultipleInheritance(PSECURITY_DESCRIPTOR ParentDescriptor, 1390*c2c66affSColin Finck PSECURITY_DESCRIPTOR CreatorDescriptor, 1391*c2c66affSColin Finck PSECURITY_DESCRIPTOR* NewDescriptor, 1392*c2c66affSColin Finck GUID** ObjectTypes, 1393*c2c66affSColin Finck ULONG GuidCount, 1394*c2c66affSColin Finck BOOL IsContainerObject, 1395*c2c66affSColin Finck ULONG AutoInheritFlags, 1396*c2c66affSColin Finck HANDLE Token, 1397*c2c66affSColin Finck PGENERIC_MAPPING GenericMapping) 1398*c2c66affSColin Finck { 1399*c2c66affSColin Finck FIXME("%s() semi-stub\n", __FUNCTION__); 1400*c2c66affSColin Finck return CreatePrivateObjectSecurity(ParentDescriptor, CreatorDescriptor, NewDescriptor, IsContainerObject, Token, GenericMapping); 1401*c2c66affSColin Finck } 1402*c2c66affSColin Finck 1403*c2c66affSColin Finck 1404*c2c66affSColin Finck /* 1405*c2c66affSColin Finck * @implemented 1406*c2c66affSColin Finck */ 1407*c2c66affSColin Finck BOOL 1408*c2c66affSColin Finck WINAPI 1409*c2c66affSColin Finck DestroyPrivateObjectSecurity(PSECURITY_DESCRIPTOR *ObjectDescriptor) 1410*c2c66affSColin Finck { 1411*c2c66affSColin Finck NTSTATUS Status; 1412*c2c66affSColin Finck 1413*c2c66affSColin Finck Status = RtlDeleteSecurityObject(ObjectDescriptor); 1414*c2c66affSColin Finck if (!NT_SUCCESS(Status)) 1415*c2c66affSColin Finck { 1416*c2c66affSColin Finck SetLastError(RtlNtStatusToDosError(Status)); 1417*c2c66affSColin Finck return FALSE; 1418*c2c66affSColin Finck } 1419*c2c66affSColin Finck 1420*c2c66affSColin Finck return TRUE; 1421*c2c66affSColin Finck } 1422*c2c66affSColin Finck 1423*c2c66affSColin Finck 1424*c2c66affSColin Finck /* 1425*c2c66affSColin Finck * @implemented 1426*c2c66affSColin Finck */ 1427*c2c66affSColin Finck BOOL 1428*c2c66affSColin Finck WINAPI 1429*c2c66affSColin Finck GetPrivateObjectSecurity(IN PSECURITY_DESCRIPTOR ObjectDescriptor, 1430*c2c66affSColin Finck IN SECURITY_INFORMATION SecurityInformation, 1431*c2c66affSColin Finck OUT PSECURITY_DESCRIPTOR ResultantDescriptor OPTIONAL, 1432*c2c66affSColin Finck IN DWORD DescriptorLength, 1433*c2c66affSColin Finck OUT PDWORD ReturnLength) 1434*c2c66affSColin Finck { 1435*c2c66affSColin Finck NTSTATUS Status; 1436*c2c66affSColin Finck 1437*c2c66affSColin Finck /* Call RTL */ 1438*c2c66affSColin Finck Status = RtlQuerySecurityObject(ObjectDescriptor, 1439*c2c66affSColin Finck SecurityInformation, 1440*c2c66affSColin Finck ResultantDescriptor, 1441*c2c66affSColin Finck DescriptorLength, 1442*c2c66affSColin Finck ReturnLength); 1443*c2c66affSColin Finck if (!NT_SUCCESS(Status)) 1444*c2c66affSColin Finck { 1445*c2c66affSColin Finck /* Fail */ 1446*c2c66affSColin Finck SetLastError(RtlNtStatusToDosError(Status)); 1447*c2c66affSColin Finck return FALSE; 1448*c2c66affSColin Finck } 1449*c2c66affSColin Finck 1450*c2c66affSColin Finck /* Success */ 1451*c2c66affSColin Finck return TRUE; 1452*c2c66affSColin Finck } 1453*c2c66affSColin Finck 1454*c2c66affSColin Finck 1455*c2c66affSColin Finck /* 1456*c2c66affSColin Finck * @implemented 1457*c2c66affSColin Finck */ 1458*c2c66affSColin Finck BOOL 1459*c2c66affSColin Finck WINAPI 1460*c2c66affSColin Finck SetPrivateObjectSecurity(SECURITY_INFORMATION SecurityInformation, 1461*c2c66affSColin Finck PSECURITY_DESCRIPTOR ModificationDescriptor, 1462*c2c66affSColin Finck PSECURITY_DESCRIPTOR *ObjectsSecurityDescriptor, 1463*c2c66affSColin Finck PGENERIC_MAPPING GenericMapping, 1464*c2c66affSColin Finck HANDLE Token) 1465*c2c66affSColin Finck { 1466*c2c66affSColin Finck NTSTATUS Status; 1467*c2c66affSColin Finck 1468*c2c66affSColin Finck Status = RtlSetSecurityObject(SecurityInformation, 1469*c2c66affSColin Finck ModificationDescriptor, 1470*c2c66affSColin Finck ObjectsSecurityDescriptor, 1471*c2c66affSColin Finck GenericMapping, 1472*c2c66affSColin Finck Token); 1473*c2c66affSColin Finck if (!NT_SUCCESS(Status)) 1474*c2c66affSColin Finck { 1475*c2c66affSColin Finck SetLastError(RtlNtStatusToDosError(Status)); 1476*c2c66affSColin Finck return FALSE; 1477*c2c66affSColin Finck } 1478*c2c66affSColin Finck 1479*c2c66affSColin Finck return TRUE; 1480*c2c66affSColin Finck } 1481*c2c66affSColin Finck 1482*c2c66affSColin Finck 1483*c2c66affSColin Finck /* 1484*c2c66affSColin Finck * @implemented 1485*c2c66affSColin Finck */ 1486*c2c66affSColin Finck DWORD 1487*c2c66affSColin Finck WINAPI 1488*c2c66affSColin Finck TreeResetNamedSecurityInfoW(LPWSTR pObjectName, 1489*c2c66affSColin Finck SE_OBJECT_TYPE ObjectType, 1490*c2c66affSColin Finck SECURITY_INFORMATION SecurityInfo, 1491*c2c66affSColin Finck PSID pOwner, 1492*c2c66affSColin Finck PSID pGroup, 1493*c2c66affSColin Finck PACL pDacl, 1494*c2c66affSColin Finck PACL pSacl, 1495*c2c66affSColin Finck BOOL KeepExplicit, 1496*c2c66affSColin Finck FN_PROGRESSW fnProgress, 1497*c2c66affSColin Finck PROG_INVOKE_SETTING ProgressInvokeSetting, 1498*c2c66affSColin Finck PVOID Args) 1499*c2c66affSColin Finck { 1500*c2c66affSColin Finck DWORD ErrorCode; 1501*c2c66affSColin Finck 1502*c2c66affSColin Finck if (pObjectName != NULL) 1503*c2c66affSColin Finck { 1504*c2c66affSColin Finck ErrorCode = CheckNtMartaPresent(); 1505*c2c66affSColin Finck if (ErrorCode == ERROR_SUCCESS) 1506*c2c66affSColin Finck { 1507*c2c66affSColin Finck switch (ObjectType) 1508*c2c66affSColin Finck { 1509*c2c66affSColin Finck case SE_FILE_OBJECT: 1510*c2c66affSColin Finck case SE_REGISTRY_KEY: 1511*c2c66affSColin Finck { 1512*c2c66affSColin Finck /* check the SecurityInfo flags for sanity (both, the protected 1513*c2c66affSColin Finck and unprotected dacl/sacl flag must not be passed together) */ 1514*c2c66affSColin Finck if (((SecurityInfo & DACL_SECURITY_INFORMATION) && 1515*c2c66affSColin Finck (SecurityInfo & (PROTECTED_DACL_SECURITY_INFORMATION | UNPROTECTED_DACL_SECURITY_INFORMATION)) == 1516*c2c66affSColin Finck (PROTECTED_DACL_SECURITY_INFORMATION | UNPROTECTED_DACL_SECURITY_INFORMATION)) 1517*c2c66affSColin Finck 1518*c2c66affSColin Finck || 1519*c2c66affSColin Finck 1520*c2c66affSColin Finck ((SecurityInfo & SACL_SECURITY_INFORMATION) && 1521*c2c66affSColin Finck (SecurityInfo & (PROTECTED_SACL_SECURITY_INFORMATION | UNPROTECTED_SACL_SECURITY_INFORMATION)) == 1522*c2c66affSColin Finck (PROTECTED_SACL_SECURITY_INFORMATION | UNPROTECTED_SACL_SECURITY_INFORMATION))) 1523*c2c66affSColin Finck { 1524*c2c66affSColin Finck ErrorCode = ERROR_INVALID_PARAMETER; 1525*c2c66affSColin Finck break; 1526*c2c66affSColin Finck } 1527*c2c66affSColin Finck 1528*c2c66affSColin Finck /* call the MARTA provider */ 1529*c2c66affSColin Finck ErrorCode = AccTreeResetNamedSecurityInfo(pObjectName, 1530*c2c66affSColin Finck ObjectType, 1531*c2c66affSColin Finck SecurityInfo, 1532*c2c66affSColin Finck pOwner, 1533*c2c66affSColin Finck pGroup, 1534*c2c66affSColin Finck pDacl, 1535*c2c66affSColin Finck pSacl, 1536*c2c66affSColin Finck KeepExplicit, 1537*c2c66affSColin Finck fnProgress, 1538*c2c66affSColin Finck ProgressInvokeSetting, 1539*c2c66affSColin Finck Args); 1540*c2c66affSColin Finck break; 1541*c2c66affSColin Finck } 1542*c2c66affSColin Finck 1543*c2c66affSColin Finck default: 1544*c2c66affSColin Finck /* object type not supported */ 1545*c2c66affSColin Finck ErrorCode = ERROR_INVALID_PARAMETER; 1546*c2c66affSColin Finck break; 1547*c2c66affSColin Finck } 1548*c2c66affSColin Finck } 1549*c2c66affSColin Finck } 1550*c2c66affSColin Finck else 1551*c2c66affSColin Finck ErrorCode = ERROR_INVALID_PARAMETER; 1552*c2c66affSColin Finck 1553*c2c66affSColin Finck return ErrorCode; 1554*c2c66affSColin Finck } 1555*c2c66affSColin Finck 1556*c2c66affSColin Finck #ifdef HAS_FN_PROGRESSW 1557*c2c66affSColin Finck 1558*c2c66affSColin Finck typedef struct _INTERNAL_FNPROGRESSW_DATA 1559*c2c66affSColin Finck { 1560*c2c66affSColin Finck FN_PROGRESSA fnProgress; 1561*c2c66affSColin Finck PVOID Args; 1562*c2c66affSColin Finck } INTERNAL_FNPROGRESSW_DATA, *PINTERNAL_FNPROGRESSW_DATA; 1563*c2c66affSColin Finck 1564*c2c66affSColin Finck static VOID WINAPI 1565*c2c66affSColin Finck InternalfnProgressW(LPWSTR pObjectName, 1566*c2c66affSColin Finck DWORD Status, 1567*c2c66affSColin Finck PPROG_INVOKE_SETTING pInvokeSetting, 1568*c2c66affSColin Finck PVOID Args, 1569*c2c66affSColin Finck BOOL SecuritySet) 1570*c2c66affSColin Finck { 1571*c2c66affSColin Finck PINTERNAL_FNPROGRESSW_DATA pifnProgressData = (PINTERNAL_FNPROGRESSW_DATA)Args; 1572*c2c66affSColin Finck INT ObjectNameSize; 1573*c2c66affSColin Finck LPSTR pObjectNameA; 1574*c2c66affSColin Finck 1575*c2c66affSColin Finck ObjectNameSize = WideCharToMultiByte(CP_ACP, 1576*c2c66affSColin Finck 0, 1577*c2c66affSColin Finck pObjectName, 1578*c2c66affSColin Finck -1, 1579*c2c66affSColin Finck NULL, 1580*c2c66affSColin Finck 0, 1581*c2c66affSColin Finck NULL, 1582*c2c66affSColin Finck NULL); 1583*c2c66affSColin Finck 1584*c2c66affSColin Finck if (ObjectNameSize > 0) 1585*c2c66affSColin Finck { 1586*c2c66affSColin Finck pObjectNameA = RtlAllocateHeap(RtlGetProcessHeap(), 1587*c2c66affSColin Finck 0, 1588*c2c66affSColin Finck ObjectNameSize); 1589*c2c66affSColin Finck if (pObjectNameA != NULL) 1590*c2c66affSColin Finck { 1591*c2c66affSColin Finck pObjectNameA[0] = '\0'; 1592*c2c66affSColin Finck WideCharToMultiByte(CP_ACP, 1593*c2c66affSColin Finck 0, 1594*c2c66affSColin Finck pObjectName, 1595*c2c66affSColin Finck -1, 1596*c2c66affSColin Finck pObjectNameA, 1597*c2c66affSColin Finck ObjectNameSize, 1598*c2c66affSColin Finck NULL, 1599*c2c66affSColin Finck NULL); 1600*c2c66affSColin Finck 1601*c2c66affSColin Finck pifnProgressData->fnProgress((LPWSTR)pObjectNameA, /* FIXME: wrong cast!! */ 1602*c2c66affSColin Finck Status, 1603*c2c66affSColin Finck pInvokeSetting, 1604*c2c66affSColin Finck pifnProgressData->Args, 1605*c2c66affSColin Finck SecuritySet); 1606*c2c66affSColin Finck 1607*c2c66affSColin Finck RtlFreeHeap(RtlGetProcessHeap(), 1608*c2c66affSColin Finck 0, 1609*c2c66affSColin Finck pObjectNameA); 1610*c2c66affSColin Finck } 1611*c2c66affSColin Finck } 1612*c2c66affSColin Finck } 1613*c2c66affSColin Finck #endif 1614*c2c66affSColin Finck 1615*c2c66affSColin Finck 1616*c2c66affSColin Finck /* 1617*c2c66affSColin Finck * @implemented 1618*c2c66affSColin Finck */ 1619*c2c66affSColin Finck DWORD 1620*c2c66affSColin Finck WINAPI 1621*c2c66affSColin Finck TreeResetNamedSecurityInfoA(LPSTR pObjectName, 1622*c2c66affSColin Finck SE_OBJECT_TYPE ObjectType, 1623*c2c66affSColin Finck SECURITY_INFORMATION SecurityInfo, 1624*c2c66affSColin Finck PSID pOwner, 1625*c2c66affSColin Finck PSID pGroup, 1626*c2c66affSColin Finck PACL pDacl, 1627*c2c66affSColin Finck PACL pSacl, 1628*c2c66affSColin Finck BOOL KeepExplicit, 1629*c2c66affSColin Finck FN_PROGRESSA fnProgress, 1630*c2c66affSColin Finck PROG_INVOKE_SETTING ProgressInvokeSetting, 1631*c2c66affSColin Finck PVOID Args) 1632*c2c66affSColin Finck { 1633*c2c66affSColin Finck #ifndef HAS_FN_PROGRESSW 1634*c2c66affSColin Finck /* That's all this function does, at least up to w2k3... Even MS was too 1635*c2c66affSColin Finck lazy to implement it... */ 1636*c2c66affSColin Finck return ERROR_CALL_NOT_IMPLEMENTED; 1637*c2c66affSColin Finck #else 1638*c2c66affSColin Finck INTERNAL_FNPROGRESSW_DATA ifnProgressData; 1639*c2c66affSColin Finck UNICODE_STRING ObjectName; 1640*c2c66affSColin Finck DWORD Ret; 1641*c2c66affSColin Finck 1642*c2c66affSColin Finck if (!RtlCreateUnicodeStringFromAsciiz(&ObjectName, pObjectName)) 1643*c2c66affSColin Finck { 1644*c2c66affSColin Finck return ERROR_NOT_ENOUGH_MEMORY; 1645*c2c66affSColin Finck } 1646*c2c66affSColin Finck 1647*c2c66affSColin Finck ifnProgressData.fnProgress = fnProgress; 1648*c2c66affSColin Finck ifnProgressData.Args = Args; 1649*c2c66affSColin Finck 1650*c2c66affSColin Finck Ret = TreeResetNamedSecurityInfoW(ObjectName.Buffer, 1651*c2c66affSColin Finck ObjectType, 1652*c2c66affSColin Finck SecurityInfo, 1653*c2c66affSColin Finck pOwner, 1654*c2c66affSColin Finck pGroup, 1655*c2c66affSColin Finck pDacl, 1656*c2c66affSColin Finck pSacl, 1657*c2c66affSColin Finck KeepExplicit, 1658*c2c66affSColin Finck (fnProgress != NULL ? InternalfnProgressW : NULL), 1659*c2c66affSColin Finck ProgressInvokeSetting, 1660*c2c66affSColin Finck &ifnProgressData); 1661*c2c66affSColin Finck 1662*c2c66affSColin Finck RtlFreeUnicodeString(&ObjectName); 1663*c2c66affSColin Finck 1664*c2c66affSColin Finck return Ret; 1665*c2c66affSColin Finck #endif 1666*c2c66affSColin Finck } 1667*c2c66affSColin Finck 1668*c2c66affSColin Finck /* EOF */ 1669