1 /* 2 * PROJECT: ReactOS system libraries 3 * LICENSE: See COPYING in the top level directory 4 * WINE COPYRIGHT: 5 * Copyright 1999, 2000 Juergen Schmied <juergen.schmied@debitel.net> 6 * Copyright 2003 CodeWeavers Inc. (Ulrich Czekalla) 7 * Copyright 2006 Robert Reif 8 * Copyright 2006 Hervé Poussineau 9 */ 10 11 #include <advapi32.h> 12 13 #include <sddl.h> 14 15 WINE_DEFAULT_DEBUG_CHANNEL(advapi); 16 17 static BOOL ParseStringSidToSid(LPCWSTR StringSid, PSID pSid, LPDWORD cBytes); 18 #ifdef __REACTOS__ 19 VOID WINAPI QuerySecurityAccessMask(SECURITY_INFORMATION,LPDWORD); 20 VOID WINAPI SetSecurityAccessMask(SECURITY_INFORMATION,LPDWORD); 21 #endif 22 23 typedef struct _ACEFLAG 24 { 25 LPCWSTR wstr; 26 DWORD value; 27 } ACEFLAG, *LPACEFLAG; 28 29 typedef struct _MAX_SID 30 { 31 /* same fields as struct _SID */ 32 BYTE Revision; 33 BYTE SubAuthorityCount; 34 SID_IDENTIFIER_AUTHORITY IdentifierAuthority; 35 DWORD SubAuthority[SID_MAX_SUB_AUTHORITIES]; 36 } MAX_SID; 37 38 typedef struct WELLKNOWNSID 39 { 40 WCHAR wstr[2]; 41 WELL_KNOWN_SID_TYPE Type; 42 MAX_SID Sid; 43 } WELLKNOWNSID; 44 45 static const WELLKNOWNSID WellKnownSids[] = 46 { 47 { {0,0}, WinNullSid, { SID_REVISION, 1, { SECURITY_NULL_SID_AUTHORITY }, { SECURITY_NULL_RID } } }, 48 { {'W','D'}, WinWorldSid, { SID_REVISION, 1, { SECURITY_WORLD_SID_AUTHORITY }, { SECURITY_WORLD_RID } } }, 49 { {0,0}, WinLocalSid, { SID_REVISION, 1, { SECURITY_LOCAL_SID_AUTHORITY }, { SECURITY_LOCAL_RID } } }, 50 { {'C','O'}, WinCreatorOwnerSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_OWNER_RID } } }, 51 { {'C','G'}, WinCreatorGroupSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_GROUP_RID } } }, 52 { {0,0}, WinCreatorOwnerServerSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_OWNER_SERVER_RID } } }, 53 { {0,0}, WinCreatorGroupServerSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_GROUP_SERVER_RID } } }, 54 { {0,0}, WinNtAuthoritySid, { SID_REVISION, 0, { SECURITY_NT_AUTHORITY }, { SECURITY_NULL_RID } } }, 55 { {0,0}, WinDialupSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_DIALUP_RID } } }, 56 { {'N','U'}, WinNetworkSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_NETWORK_RID } } }, 57 { {0,0}, WinBatchSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_BATCH_RID } } }, 58 { {'I','U'}, WinInteractiveSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_INTERACTIVE_RID } } }, 59 { {'S','U'}, WinServiceSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_SERVICE_RID } } }, 60 { {'A','N'}, WinAnonymousSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_ANONYMOUS_LOGON_RID } } }, 61 { {0,0}, WinProxySid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_PROXY_RID } } }, 62 { {'E','D'}, WinEnterpriseControllersSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_ENTERPRISE_CONTROLLERS_RID } } }, 63 { {'P','S'}, WinSelfSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_PRINCIPAL_SELF_RID } } }, 64 { {'A','U'}, WinAuthenticatedUserSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_AUTHENTICATED_USER_RID } } }, 65 { {'R','C'}, WinRestrictedCodeSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_RESTRICTED_CODE_RID } } }, 66 { {0,0}, WinTerminalServerSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_TERMINAL_SERVER_RID } } }, 67 { {0,0}, WinRemoteLogonIdSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_REMOTE_LOGON_RID } } }, 68 { {'S','Y'}, WinLocalSystemSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_LOCAL_SYSTEM_RID } } }, 69 { {'L','S'}, WinLocalServiceSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_LOCAL_SERVICE_RID } } }, 70 { {'N','S'}, WinNetworkServiceSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_NETWORK_SERVICE_RID } } }, 71 { {0,0}, WinBuiltinDomainSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID } } }, 72 { {'B','A'}, WinBuiltinAdministratorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS } } }, 73 { {'B','U'}, WinBuiltinUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_USERS } } }, 74 { {'B','G'}, WinBuiltinGuestsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_GUESTS } } }, 75 { {'P','U'}, WinBuiltinPowerUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_POWER_USERS } } }, 76 { {'A','O'}, WinBuiltinAccountOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ACCOUNT_OPS } } }, 77 { {'S','O'}, WinBuiltinSystemOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_SYSTEM_OPS } } }, 78 { {'P','O'}, WinBuiltinPrintOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_PRINT_OPS } } }, 79 { {'B','O'}, WinBuiltinBackupOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_BACKUP_OPS } } }, 80 { {'R','E'}, WinBuiltinReplicatorSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_REPLICATOR } } }, 81 { {'R','U'}, WinBuiltinPreWindows2000CompatibleAccessSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_PREW2KCOMPACCESS } } }, 82 { {'R','D'}, WinBuiltinRemoteDesktopUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_REMOTE_DESKTOP_USERS } } }, 83 { {'N','O'}, WinBuiltinNetworkConfigurationOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_NETWORK_CONFIGURATION_OPS } } }, 84 { {0,0}, WinNTLMAuthenticationSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_PACKAGE_BASE_RID, SECURITY_PACKAGE_NTLM_RID } } }, 85 { {0,0}, WinDigestAuthenticationSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_PACKAGE_BASE_RID, SECURITY_PACKAGE_DIGEST_RID } } }, 86 { {0,0}, WinSChannelAuthenticationSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_PACKAGE_BASE_RID, SECURITY_PACKAGE_SCHANNEL_RID } } }, 87 { {0,0}, WinThisOrganizationSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_THIS_ORGANIZATION_RID } } }, 88 { {0,0}, WinOtherOrganizationSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_OTHER_ORGANIZATION_RID } } }, 89 { {0,0}, WinBuiltinIncomingForestTrustBuildersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_INCOMING_FOREST_TRUST_BUILDERS } } }, 90 { {0,0}, WinBuiltinPerfMonitoringUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_MONITORING_USERS } } }, 91 { {0,0}, WinBuiltinPerfLoggingUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_LOGGING_USERS } } }, 92 { {0,0}, WinBuiltinAuthorizationAccessSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_AUTHORIZATIONACCESS } } }, 93 { {0,0}, WinBuiltinTerminalServerLicenseServersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_TS_LICENSE_SERVERS } } }, 94 { {0,0}, WinBuiltinDCOMUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_DCOM_USERS } } }, 95 { {'L','W'}, WinLowLabelSid, { SID_REVISION, 1, { SECURITY_MANDATORY_LABEL_AUTHORITY}, { SECURITY_MANDATORY_LOW_RID} } }, 96 { {'M','E'}, WinMediumLabelSid, { SID_REVISION, 1, { SECURITY_MANDATORY_LABEL_AUTHORITY}, { SECURITY_MANDATORY_MEDIUM_RID } } }, 97 { {'H','I'}, WinHighLabelSid, { SID_REVISION, 1, { SECURITY_MANDATORY_LABEL_AUTHORITY}, { SECURITY_MANDATORY_HIGH_RID } } }, 98 { {'S','I'}, WinSystemLabelSid, { SID_REVISION, 1, { SECURITY_MANDATORY_LABEL_AUTHORITY}, { SECURITY_MANDATORY_SYSTEM_RID } } }, 99 }; 100 101 /* these SIDs must be constructed as relative to some domain - only the RID is well-known */ 102 typedef struct WELLKNOWNRID 103 { 104 WCHAR wstr[2]; 105 WELL_KNOWN_SID_TYPE Type; 106 DWORD Rid; 107 } WELLKNOWNRID; 108 109 static const WELLKNOWNRID WellKnownRids[] = { 110 { {'L','A'}, WinAccountAdministratorSid, DOMAIN_USER_RID_ADMIN }, 111 { {'L','G'}, WinAccountGuestSid, DOMAIN_USER_RID_GUEST }, 112 { {0,0}, WinAccountKrbtgtSid, DOMAIN_USER_RID_KRBTGT }, 113 { {'D','A'}, WinAccountDomainAdminsSid, DOMAIN_GROUP_RID_ADMINS }, 114 { {'D','U'}, WinAccountDomainUsersSid, DOMAIN_GROUP_RID_USERS }, 115 { {'D','G'}, WinAccountDomainGuestsSid, DOMAIN_GROUP_RID_GUESTS }, 116 { {'D','C'}, WinAccountComputersSid, DOMAIN_GROUP_RID_COMPUTERS }, 117 { {'D','D'}, WinAccountControllersSid, DOMAIN_GROUP_RID_CONTROLLERS }, 118 { {'C','A'}, WinAccountCertAdminsSid, DOMAIN_GROUP_RID_CERT_ADMINS }, 119 { {'S','A'}, WinAccountSchemaAdminsSid, DOMAIN_GROUP_RID_SCHEMA_ADMINS }, 120 { {'E','A'}, WinAccountEnterpriseAdminsSid, DOMAIN_GROUP_RID_ENTERPRISE_ADMINS }, 121 { {'P','A'}, WinAccountPolicyAdminsSid, DOMAIN_GROUP_RID_POLICY_ADMINS }, 122 { {'R','S'}, WinAccountRasAndIasServersSid, DOMAIN_ALIAS_RID_RAS_SERVERS }, 123 }; 124 125 #ifndef __REACTOS__ 126 static const SID sidWorld = { SID_REVISION, 1, { SECURITY_WORLD_SID_AUTHORITY} , { SECURITY_WORLD_RID } }; 127 #endif 128 129 static const WCHAR SDDL_NO_READ_UP[] = {'N','R',0}; 130 static const WCHAR SDDL_NO_WRITE_UP[] = {'N','W',0}; 131 static const WCHAR SDDL_NO_EXECUTE_UP[] = {'N','X',0}; 132 133 /* 134 * ACE types 135 */ 136 static const WCHAR SDDL_ACCESS_ALLOWED[] = {'A',0}; 137 static const WCHAR SDDL_ACCESS_DENIED[] = {'D',0}; 138 #ifndef __REACTOS__ 139 static const WCHAR SDDL_OBJECT_ACCESS_ALLOWED[] = {'O','A',0}; 140 static const WCHAR SDDL_OBJECT_ACCESS_DENIED[] = {'O','D',0}; 141 #endif 142 static const WCHAR SDDL_AUDIT[] = {'A','U',0}; 143 static const WCHAR SDDL_ALARM[] = {'A','L',0}; 144 static const WCHAR SDDL_MANDATORY_LABEL[] = {'M','L',0}; 145 #ifndef __REACTOS__ 146 static const WCHAR SDDL_OBJECT_AUDIT[] = {'O','U',0}; 147 static const WCHAR SDDL_OBJECT_ALARM[] = {'O','L',0}; 148 #endif 149 150 /* 151 * SDDL ADS Rights 152 */ 153 #define ADS_RIGHT_DS_CREATE_CHILD 0x0001 154 #define ADS_RIGHT_DS_DELETE_CHILD 0x0002 155 #define ADS_RIGHT_ACTRL_DS_LIST 0x0004 156 #define ADS_RIGHT_DS_SELF 0x0008 157 #define ADS_RIGHT_DS_READ_PROP 0x0010 158 #define ADS_RIGHT_DS_WRITE_PROP 0x0020 159 #define ADS_RIGHT_DS_DELETE_TREE 0x0040 160 #define ADS_RIGHT_DS_LIST_OBJECT 0x0080 161 #define ADS_RIGHT_DS_CONTROL_ACCESS 0x0100 162 163 /* 164 * ACE flags 165 */ 166 static const WCHAR SDDL_CONTAINER_INHERIT[] = {'C','I',0}; 167 static const WCHAR SDDL_OBJECT_INHERIT[] = {'O','I',0}; 168 static const WCHAR SDDL_NO_PROPAGATE[] = {'N','P',0}; 169 static const WCHAR SDDL_INHERIT_ONLY[] = {'I','O',0}; 170 static const WCHAR SDDL_INHERITED[] = {'I','D',0}; 171 static const WCHAR SDDL_AUDIT_SUCCESS[] = {'S','A',0}; 172 static const WCHAR SDDL_AUDIT_FAILURE[] = {'F','A',0}; 173 174 static const char * debugstr_sid(PSID sid) 175 { 176 int auth = 0; 177 SID * psid = (SID *)sid; 178 179 if (psid == NULL) 180 return "(null)"; 181 182 auth = psid->IdentifierAuthority.Value[5] + 183 (psid->IdentifierAuthority.Value[4] << 8) + 184 (psid->IdentifierAuthority.Value[3] << 16) + 185 (psid->IdentifierAuthority.Value[2] << 24); 186 187 switch (psid->SubAuthorityCount) { 188 case 0: 189 return wine_dbg_sprintf("S-%d-%d", psid->Revision, auth); 190 case 1: 191 return wine_dbg_sprintf("S-%d-%d-%lu", psid->Revision, auth, 192 psid->SubAuthority[0]); 193 case 2: 194 return wine_dbg_sprintf("S-%d-%d-%lu-%lu", psid->Revision, auth, 195 psid->SubAuthority[0], psid->SubAuthority[1]); 196 case 3: 197 return wine_dbg_sprintf("S-%d-%d-%lu-%lu-%lu", psid->Revision, auth, 198 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2]); 199 case 4: 200 return wine_dbg_sprintf("S-%d-%d-%lu-%lu-%lu-%lu", psid->Revision, auth, 201 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2], 202 psid->SubAuthority[3]); 203 case 5: 204 return wine_dbg_sprintf("S-%d-%d-%lu-%lu-%lu-%lu-%lu", psid->Revision, auth, 205 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2], 206 psid->SubAuthority[3], psid->SubAuthority[4]); 207 case 6: 208 return wine_dbg_sprintf("S-%d-%d-%lu-%lu-%lu-%lu-%lu-%lu", psid->Revision, auth, 209 psid->SubAuthority[3], psid->SubAuthority[1], psid->SubAuthority[2], 210 psid->SubAuthority[0], psid->SubAuthority[4], psid->SubAuthority[5]); 211 case 7: 212 return wine_dbg_sprintf("S-%d-%d-%lu-%lu-%lu-%lu-%lu-%lu-%lu", psid->Revision, auth, 213 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2], 214 psid->SubAuthority[3], psid->SubAuthority[4], psid->SubAuthority[5], 215 psid->SubAuthority[6]); 216 case 8: 217 return wine_dbg_sprintf("S-%d-%d-%lu-%lu-%lu-%lu-%lu-%lu-%lu-%lu", psid->Revision, auth, 218 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2], 219 psid->SubAuthority[3], psid->SubAuthority[4], psid->SubAuthority[5], 220 psid->SubAuthority[6], psid->SubAuthority[7]); 221 } 222 return "(too-big)"; 223 } 224 225 /* set last error code from NT status and get the proper boolean return value */ 226 /* used for functions that are a simple wrapper around the corresponding ntdll API */ 227 static __inline BOOL set_ntstatus( NTSTATUS status ) 228 { 229 if (!NT_SUCCESS(status)) SetLastError( RtlNtStatusToDosError( status )); 230 return NT_SUCCESS(status); 231 } 232 233 static LPWSTR SERV_dup( LPCSTR str ) 234 { 235 UINT len; 236 LPWSTR wstr; 237 238 if( !str ) 239 return NULL; 240 len = MultiByteToWideChar( CP_ACP, 0, str, -1, NULL, 0 ); 241 wstr = heap_alloc( len*sizeof (WCHAR) ); 242 MultiByteToWideChar( CP_ACP, 0, str, -1, wstr, len ); 243 return wstr; 244 } 245 246 /************************************************************ 247 * ADVAPI_IsLocalComputer 248 * 249 * Checks whether the server name indicates local machine. 250 */ 251 BOOL ADVAPI_IsLocalComputer(LPCWSTR ServerName) 252 { 253 DWORD dwSize = MAX_COMPUTERNAME_LENGTH + 1; 254 BOOL Result; 255 LPWSTR buf; 256 257 if (!ServerName || !ServerName[0]) 258 return TRUE; 259 260 buf = heap_alloc(dwSize * sizeof(WCHAR)); 261 Result = GetComputerNameW(buf, &dwSize); 262 if (Result && (ServerName[0] == '\\') && (ServerName[1] == '\\')) 263 ServerName += 2; 264 Result = Result && !lstrcmpW(ServerName, buf); 265 heap_free(buf); 266 267 return Result; 268 } 269 270 /************************************************************ 271 * ADVAPI_GetComputerSid 272 */ 273 BOOL ADVAPI_GetComputerSid(PSID sid) 274 { 275 static const struct /* same fields as struct SID */ 276 { 277 BYTE Revision; 278 BYTE SubAuthorityCount; 279 SID_IDENTIFIER_AUTHORITY IdentifierAuthority; 280 DWORD SubAuthority[4]; 281 } computer_sid = 282 { SID_REVISION, 4, { SECURITY_NT_AUTHORITY }, { SECURITY_NT_NON_UNIQUE, 0, 0, 0 } }; 283 284 memcpy( sid, &computer_sid, sizeof(computer_sid) ); 285 return TRUE; 286 } 287 288 /* Exported functions */ 289 290 /* 291 * @implemented 292 */ 293 BOOL WINAPI 294 OpenProcessToken(HANDLE ProcessHandle, 295 DWORD DesiredAccess, 296 PHANDLE TokenHandle) 297 { 298 NTSTATUS Status; 299 300 TRACE("%p, %x, %p.\n", ProcessHandle, DesiredAccess, TokenHandle); 301 302 Status = NtOpenProcessToken(ProcessHandle, 303 DesiredAccess, 304 TokenHandle); 305 if (!NT_SUCCESS(Status)) 306 { 307 WARN("NtOpenProcessToken failed! Status %08x\n", Status); 308 SetLastError(RtlNtStatusToDosError(Status)); 309 return FALSE; 310 } 311 312 TRACE("Returning token %p.\n", *TokenHandle); 313 314 return TRUE; 315 } 316 317 /****************************************************************************** 318 * OpenThreadToken [ADVAPI32.@] 319 * 320 * Opens the access token associated with a thread handle. 321 * 322 * PARAMS 323 * ThreadHandle [I] Handle to process 324 * DesiredAccess [I] Desired access to the thread 325 * OpenAsSelf [I] ??? 326 * TokenHandle [O] Destination for the token handle 327 * 328 * RETURNS 329 * Success: TRUE. TokenHandle contains the access token. 330 * Failure: FALSE. 331 * 332 * NOTES 333 * See NtOpenThreadToken. 334 */ 335 BOOL WINAPI 336 OpenThreadToken( HANDLE ThreadHandle, DWORD DesiredAccess, 337 BOOL OpenAsSelf, HANDLE *TokenHandle) 338 { 339 return set_ntstatus( NtOpenThreadToken(ThreadHandle, DesiredAccess, OpenAsSelf, TokenHandle)); 340 } 341 342 /* 343 * @implemented 344 */ 345 BOOL WINAPI 346 AdjustTokenGroups(HANDLE TokenHandle, 347 BOOL ResetToDefault, 348 PTOKEN_GROUPS NewState, 349 DWORD BufferLength, 350 PTOKEN_GROUPS PreviousState, 351 PDWORD ReturnLength) 352 { 353 NTSTATUS Status; 354 355 Status = NtAdjustGroupsToken(TokenHandle, 356 ResetToDefault, 357 NewState, 358 BufferLength, 359 PreviousState, 360 (PULONG)ReturnLength); 361 if (!NT_SUCCESS(Status)) 362 { 363 SetLastError(RtlNtStatusToDosError(Status)); 364 return FALSE; 365 } 366 367 return TRUE; 368 } 369 370 /* 371 * @implemented 372 */ 373 BOOL WINAPI 374 AdjustTokenPrivileges(HANDLE TokenHandle, 375 BOOL DisableAllPrivileges, 376 PTOKEN_PRIVILEGES NewState, 377 DWORD BufferLength, 378 PTOKEN_PRIVILEGES PreviousState, 379 PDWORD ReturnLength) 380 { 381 NTSTATUS Status; 382 383 Status = NtAdjustPrivilegesToken(TokenHandle, 384 DisableAllPrivileges, 385 NewState, 386 BufferLength, 387 PreviousState, 388 (PULONG)ReturnLength); 389 if (STATUS_NOT_ALL_ASSIGNED == Status) 390 { 391 SetLastError(ERROR_NOT_ALL_ASSIGNED); 392 return TRUE; 393 } 394 395 if (!NT_SUCCESS(Status)) 396 { 397 SetLastError(RtlNtStatusToDosError(Status)); 398 return FALSE; 399 } 400 401 /* AdjustTokenPrivileges is documented to do this */ 402 SetLastError(ERROR_SUCCESS); 403 404 return TRUE; 405 } 406 407 /* 408 * @implemented 409 */ 410 BOOL WINAPI 411 GetTokenInformation(HANDLE TokenHandle, 412 TOKEN_INFORMATION_CLASS TokenInformationClass, 413 LPVOID TokenInformation, 414 DWORD TokenInformationLength, 415 PDWORD ReturnLength) 416 { 417 NTSTATUS Status; 418 419 Status = NtQueryInformationToken(TokenHandle, 420 TokenInformationClass, 421 TokenInformation, 422 TokenInformationLength, 423 (PULONG)ReturnLength); 424 if (!NT_SUCCESS(Status)) 425 { 426 SetLastError(RtlNtStatusToDosError(Status)); 427 return FALSE; 428 } 429 430 return TRUE; 431 } 432 433 /* 434 * @implemented 435 */ 436 BOOL WINAPI 437 SetTokenInformation(HANDLE TokenHandle, 438 TOKEN_INFORMATION_CLASS TokenInformationClass, 439 LPVOID TokenInformation, 440 DWORD TokenInformationLength) 441 { 442 NTSTATUS Status; 443 444 Status = NtSetInformationToken(TokenHandle, 445 TokenInformationClass, 446 TokenInformation, 447 TokenInformationLength); 448 if (!NT_SUCCESS(Status)) 449 { 450 SetLastError(RtlNtStatusToDosError(Status)); 451 return FALSE; 452 } 453 454 return TRUE; 455 } 456 457 /* 458 * @implemented 459 */ 460 BOOL WINAPI 461 SetThreadToken(IN PHANDLE ThreadHandle OPTIONAL, 462 IN HANDLE TokenHandle) 463 { 464 NTSTATUS Status; 465 HANDLE hThread; 466 467 hThread = (ThreadHandle != NULL) ? *ThreadHandle : NtCurrentThread(); 468 469 Status = NtSetInformationThread(hThread, 470 ThreadImpersonationToken, 471 &TokenHandle, 472 sizeof(HANDLE)); 473 if (!NT_SUCCESS(Status)) 474 { 475 SetLastError(RtlNtStatusToDosError(Status)); 476 return FALSE; 477 } 478 479 return TRUE; 480 } 481 482 /** 483 * @brief 484 * Creates a filtered token that is a restricted one 485 * of the regular access token. A restricted token 486 * can have disabled SIDs, deleted privileges and/or 487 * restricted SIDs added. 488 * 489 * @param[in] ExistingTokenHandle 490 * An existing handle to a token where it's to be 491 * filtered. 492 * 493 * @param[in] Flags 494 * Privilege flag options. This parameter argument influences how the token 495 * is filtered. Such parameter can be 0. 496 * 497 * @param[in] DisableSidCount 498 * The count number of SIDs to disable. 499 * 500 * @param[in] SidsToDisable 501 * An array list with SIDs that have to be disabled in 502 * a token. 503 * 504 * @param[in] DeletePrivilegeCount 505 * The count number of privileges to be deleted. 506 * 507 * @param[in] PrivilegesToDelete 508 * An array list with privileges that have to be deleted 509 * in a token. 510 * 511 * @param[in] RestrictedSidCount 512 * The count number of restricted SIDs. 513 * 514 * @param[in] SidsToRestrict 515 * An array list with restricted SIDs to be added into 516 * the token. If the token already has restricted SIDs 517 * then the array provided by the caller is redundant 518 * information alongside with the existing restricted 519 * SIDs in the token. 520 * 521 * @param[out] NewTokenHandle 522 * The newly received handle to a restricted (filtered) 523 * token. The caller can use such handle to duplicate 524 * a new token. 525 * 526 * @return 527 * Returns TRUE if the function has successfully completed 528 * the operations, otherwise FALSE is returned to indicate 529 * failure. For further details the caller has to invoke 530 * GetLastError() API call for extended information 531 * about the failure. 532 */ 533 BOOL WINAPI CreateRestrictedToken( 534 _In_ HANDLE ExistingTokenHandle, 535 _In_ DWORD Flags, 536 _In_ DWORD DisableSidCount, 537 _In_reads_opt_(DisableSidCount) PSID_AND_ATTRIBUTES SidsToDisable, 538 _In_ DWORD DeletePrivilegeCount, 539 _In_reads_opt_(DeletePrivilegeCount) PLUID_AND_ATTRIBUTES PrivilegesToDelete, 540 _In_ DWORD RestrictedSidCount, 541 _In_reads_opt_(RestrictedSidCount) PSID_AND_ATTRIBUTES SidsToRestrict, 542 _Outptr_ PHANDLE NewTokenHandle) 543 { 544 NTSTATUS Status; 545 BOOL Success; 546 ULONG Index; 547 PTOKEN_GROUPS DisableSids = NULL; 548 PTOKEN_GROUPS RestrictedSids = NULL; 549 PTOKEN_PRIVILEGES DeletePrivileges = NULL; 550 551 /* 552 * Capture the elements we're being given from 553 * the caller and allocate the groups and/or 554 * privileges that have to be filtered in 555 * the token. 556 */ 557 if (SidsToDisable != NULL) 558 { 559 DisableSids = (PTOKEN_GROUPS)LocalAlloc(LMEM_FIXED, DisableSidCount * sizeof(TOKEN_GROUPS)); 560 if (DisableSids == NULL) 561 { 562 /* We failed, bail out */ 563 SetLastError(RtlNtStatusToDosError(STATUS_INSUFFICIENT_RESOURCES)); 564 return FALSE; 565 } 566 567 /* Copy the counter and loop the elements to copy the rest */ 568 DisableSids->GroupCount = DisableSidCount; 569 for (Index = 0; Index < DisableSidCount; Index++) 570 { 571 DisableSids->Groups[Index].Sid = SidsToDisable[Index].Sid; 572 DisableSids->Groups[Index].Attributes = SidsToDisable[Index].Attributes; 573 } 574 } 575 576 if (PrivilegesToDelete != NULL) 577 { 578 DeletePrivileges = (PTOKEN_PRIVILEGES)LocalAlloc(LMEM_FIXED, DeletePrivilegeCount * sizeof(TOKEN_PRIVILEGES)); 579 if (DeletePrivileges == NULL) 580 { 581 /* We failed, bail out */ 582 SetLastError(RtlNtStatusToDosError(STATUS_INSUFFICIENT_RESOURCES)); 583 Success = FALSE; 584 goto Cleanup; 585 } 586 587 /* Copy the counter and loop the elements to copy the rest */ 588 DeletePrivileges->PrivilegeCount = DeletePrivilegeCount; 589 for (Index = 0; Index < DeletePrivilegeCount; Index++) 590 { 591 DeletePrivileges->Privileges[Index].Luid = PrivilegesToDelete[Index].Luid; 592 DeletePrivileges->Privileges[Index].Attributes = PrivilegesToDelete[Index].Attributes; 593 } 594 } 595 596 if (SidsToRestrict != NULL) 597 { 598 RestrictedSids = (PTOKEN_GROUPS)LocalAlloc(LMEM_FIXED, RestrictedSidCount * sizeof(TOKEN_GROUPS)); 599 if (RestrictedSids == NULL) 600 { 601 /* We failed, bail out */ 602 SetLastError(RtlNtStatusToDosError(STATUS_INSUFFICIENT_RESOURCES)); 603 Success = FALSE; 604 goto Cleanup; 605 } 606 607 /* Copy the counter and loop the elements to copy the rest */ 608 RestrictedSids->GroupCount = RestrictedSidCount; 609 for (Index = 0; Index < RestrictedSidCount; Index++) 610 { 611 RestrictedSids->Groups[Index].Sid = SidsToRestrict[Index].Sid; 612 RestrictedSids->Groups[Index].Attributes = SidsToRestrict[Index].Attributes; 613 } 614 } 615 616 /* 617 * Call the NT API to request a token filtering 618 * operation for us. 619 */ 620 Status = NtFilterToken(ExistingTokenHandle, 621 Flags, 622 DisableSids, 623 DeletePrivileges, 624 RestrictedSids, 625 NewTokenHandle); 626 if (!NT_SUCCESS(Status)) 627 { 628 /* We failed to do the job, bail out */ 629 SetLastError(RtlNtStatusToDosError(Status)); 630 Success = FALSE; 631 goto Cleanup; 632 } 633 634 /* If we reach here then we've successfully filtered the token */ 635 Success = TRUE; 636 637 Cleanup: 638 /* Free whatever we allocated before */ 639 if (DisableSids != NULL) 640 { 641 LocalFree(DisableSids); 642 } 643 644 if (DeletePrivileges != NULL) 645 { 646 LocalFree(DeletePrivileges); 647 } 648 649 if (RestrictedSids != NULL) 650 { 651 LocalFree(RestrictedSids); 652 } 653 654 return Success; 655 } 656 657 /****************************************************************************** 658 * AllocateAndInitializeSid [ADVAPI32.@] 659 * 660 * PARAMS 661 * pIdentifierAuthority [] 662 * nSubAuthorityCount [] 663 * nSubAuthority0 [] 664 * nSubAuthority1 [] 665 * nSubAuthority2 [] 666 * nSubAuthority3 [] 667 * nSubAuthority4 [] 668 * nSubAuthority5 [] 669 * nSubAuthority6 [] 670 * nSubAuthority7 [] 671 * pSid [] 672 */ 673 BOOL WINAPI 674 AllocateAndInitializeSid( PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority, 675 BYTE nSubAuthorityCount, 676 DWORD nSubAuthority0, DWORD nSubAuthority1, 677 DWORD nSubAuthority2, DWORD nSubAuthority3, 678 DWORD nSubAuthority4, DWORD nSubAuthority5, 679 DWORD nSubAuthority6, DWORD nSubAuthority7, 680 PSID *pSid ) 681 { 682 return set_ntstatus( RtlAllocateAndInitializeSid( 683 pIdentifierAuthority, nSubAuthorityCount, 684 nSubAuthority0, nSubAuthority1, nSubAuthority2, nSubAuthority3, 685 nSubAuthority4, nSubAuthority5, nSubAuthority6, nSubAuthority7, 686 pSid )); 687 } 688 689 /* 690 * @implemented 691 * 692 * RETURNS 693 * Docs says this function does NOT return a value 694 * even thou it's defined to return a PVOID... 695 */ 696 PVOID 697 WINAPI 698 FreeSid(PSID pSid) 699 { 700 return RtlFreeSid(pSid); 701 } 702 703 /****************************************************************************** 704 * CopySid [ADVAPI32.@] 705 * 706 * PARAMS 707 * nDestinationSidLength [] 708 * pDestinationSid [] 709 * pSourceSid [] 710 */ 711 BOOL WINAPI 712 CopySid( DWORD nDestinationSidLength, PSID pDestinationSid, PSID pSourceSid ) 713 { 714 return set_ntstatus(RtlCopySid(nDestinationSidLength, pDestinationSid, pSourceSid)); 715 } 716 717 /* 718 * @unimplemented 719 */ 720 BOOL 721 WINAPI 722 CreateWellKnownSid(IN WELL_KNOWN_SID_TYPE WellKnownSidType, 723 IN PSID DomainSid OPTIONAL, 724 OUT PSID pSid, 725 IN OUT DWORD* cbSid) 726 { 727 unsigned int i; 728 TRACE("(%d, %s, %p, %p)\n", WellKnownSidType, debugstr_sid(DomainSid), pSid, cbSid); 729 730 if (cbSid == NULL || (DomainSid && !IsValidSid(DomainSid))) 731 { 732 SetLastError(ERROR_INVALID_PARAMETER); 733 return FALSE; 734 } 735 736 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++) { 737 if (WellKnownSids[i].Type == WellKnownSidType) { 738 DWORD length = GetSidLengthRequired(WellKnownSids[i].Sid.SubAuthorityCount); 739 740 if (*cbSid < length) 741 { 742 *cbSid = length; 743 SetLastError(ERROR_INSUFFICIENT_BUFFER); 744 return FALSE; 745 } 746 if (!pSid) 747 { 748 SetLastError(ERROR_INVALID_PARAMETER); 749 return FALSE; 750 } 751 CopyMemory(pSid, &WellKnownSids[i].Sid.Revision, length); 752 *cbSid = length; 753 return TRUE; 754 } 755 } 756 757 if (DomainSid == NULL || *GetSidSubAuthorityCount(DomainSid) == SID_MAX_SUB_AUTHORITIES) 758 { 759 SetLastError(ERROR_INVALID_PARAMETER); 760 return FALSE; 761 } 762 763 for (i = 0; i < sizeof(WellKnownRids)/sizeof(WellKnownRids[0]); i++) 764 if (WellKnownRids[i].Type == WellKnownSidType) { 765 UCHAR domain_subauth = *GetSidSubAuthorityCount(DomainSid); 766 DWORD domain_sid_length = GetSidLengthRequired(domain_subauth); 767 DWORD output_sid_length = GetSidLengthRequired(domain_subauth + 1); 768 769 if (*cbSid < output_sid_length) 770 { 771 *cbSid = output_sid_length; 772 SetLastError(ERROR_INSUFFICIENT_BUFFER); 773 return FALSE; 774 } 775 if (!pSid) 776 { 777 SetLastError(ERROR_INVALID_PARAMETER); 778 return FALSE; 779 } 780 CopyMemory(pSid, DomainSid, domain_sid_length); 781 (*GetSidSubAuthorityCount(pSid))++; 782 (*GetSidSubAuthority(pSid, domain_subauth)) = WellKnownRids[i].Rid; 783 *cbSid = output_sid_length; 784 return TRUE; 785 } 786 787 SetLastError(ERROR_INVALID_PARAMETER); 788 return FALSE; 789 } 790 791 /* 792 * @unimplemented 793 */ 794 BOOL 795 WINAPI 796 IsWellKnownSid(IN PSID pSid, 797 IN WELL_KNOWN_SID_TYPE WellKnownSidType) 798 { 799 unsigned int i; 800 TRACE("(%s, %d)\n", debugstr_sid(pSid), WellKnownSidType); 801 802 for (i = 0; i < sizeof(WellKnownSids) / sizeof(WellKnownSids[0]); i++) 803 { 804 if (WellKnownSids[i].Type == WellKnownSidType) 805 { 806 if (EqualSid(pSid, (PSID)(&WellKnownSids[i].Sid.Revision))) 807 return TRUE; 808 } 809 } 810 811 return FALSE; 812 } 813 814 /* 815 * @implemented 816 */ 817 BOOL 818 WINAPI 819 IsValidSid(PSID pSid) 820 { 821 return (BOOL)RtlValidSid(pSid); 822 } 823 824 /* 825 * @implemented 826 */ 827 BOOL 828 WINAPI 829 EqualSid(PSID pSid1, 830 PSID pSid2) 831 { 832 SetLastError(ERROR_SUCCESS); 833 return RtlEqualSid (pSid1, pSid2); 834 } 835 836 /* 837 * @implemented 838 */ 839 BOOL 840 WINAPI 841 EqualPrefixSid(PSID pSid1, 842 PSID pSid2) 843 { 844 return RtlEqualPrefixSid (pSid1, pSid2); 845 } 846 847 /* 848 * @implemented 849 */ 850 DWORD 851 WINAPI 852 GetSidLengthRequired(UCHAR nSubAuthorityCount) 853 { 854 return (DWORD)RtlLengthRequiredSid(nSubAuthorityCount); 855 } 856 857 /* 858 * @implemented 859 */ 860 BOOL 861 WINAPI 862 InitializeSid(PSID Sid, 863 PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority, 864 BYTE nSubAuthorityCount) 865 { 866 NTSTATUS Status; 867 868 Status = RtlInitializeSid(Sid, 869 pIdentifierAuthority, 870 nSubAuthorityCount); 871 if (!NT_SUCCESS(Status)) 872 { 873 SetLastError(RtlNtStatusToDosError(Status)); 874 return FALSE; 875 } 876 877 return TRUE; 878 } 879 880 /* 881 * @implemented 882 */ 883 PSID_IDENTIFIER_AUTHORITY 884 WINAPI 885 GetSidIdentifierAuthority(PSID pSid) 886 { 887 SetLastError(ERROR_SUCCESS); 888 return RtlIdentifierAuthoritySid(pSid); 889 } 890 891 /* 892 * @implemented 893 */ 894 PDWORD 895 WINAPI 896 GetSidSubAuthority(PSID pSid, 897 DWORD nSubAuthority) 898 { 899 SetLastError(ERROR_SUCCESS); 900 return (PDWORD)RtlSubAuthoritySid(pSid, nSubAuthority); 901 } 902 903 /* 904 * @implemented 905 */ 906 PUCHAR 907 WINAPI 908 GetSidSubAuthorityCount(PSID pSid) 909 { 910 SetLastError(ERROR_SUCCESS); 911 return RtlSubAuthorityCountSid(pSid); 912 } 913 914 /* 915 * @implemented 916 */ 917 DWORD 918 WINAPI 919 GetLengthSid(PSID pSid) 920 { 921 return (DWORD)RtlLengthSid(pSid); 922 } 923 924 /* 925 * @implemented 926 */ 927 BOOL 928 WINAPI 929 InitializeSecurityDescriptor(PSECURITY_DESCRIPTOR pSecurityDescriptor, 930 DWORD dwRevision) 931 { 932 NTSTATUS Status; 933 934 Status = RtlCreateSecurityDescriptor(pSecurityDescriptor, 935 dwRevision); 936 if (!NT_SUCCESS(Status)) 937 { 938 SetLastError(RtlNtStatusToDosError(Status)); 939 return FALSE; 940 } 941 942 return TRUE; 943 } 944 945 /* 946 * @implemented 947 */ 948 BOOL 949 WINAPI 950 MakeAbsoluteSD(PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor, 951 PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor, 952 LPDWORD lpdwAbsoluteSecurityDescriptorSize, 953 PACL pDacl, 954 LPDWORD lpdwDaclSize, 955 PACL pSacl, 956 LPDWORD lpdwSaclSize, 957 PSID pOwner, 958 LPDWORD lpdwOwnerSize, 959 PSID pPrimaryGroup, 960 LPDWORD lpdwPrimaryGroupSize) 961 { 962 NTSTATUS Status; 963 964 Status = RtlSelfRelativeToAbsoluteSD(pSelfRelativeSecurityDescriptor, 965 pAbsoluteSecurityDescriptor, 966 lpdwAbsoluteSecurityDescriptorSize, 967 pDacl, 968 lpdwDaclSize, 969 pSacl, 970 lpdwSaclSize, 971 pOwner, 972 lpdwOwnerSize, 973 pPrimaryGroup, 974 lpdwPrimaryGroupSize); 975 if (!NT_SUCCESS(Status)) 976 { 977 SetLastError(RtlNtStatusToDosError(Status)); 978 return FALSE; 979 } 980 981 return TRUE; 982 } 983 984 /****************************************************************************** 985 * GetKernelObjectSecurity [ADVAPI32.@] 986 */ 987 BOOL WINAPI GetKernelObjectSecurity( 988 HANDLE Handle, 989 SECURITY_INFORMATION RequestedInformation, 990 PSECURITY_DESCRIPTOR pSecurityDescriptor, 991 DWORD nLength, 992 LPDWORD lpnLengthNeeded ) 993 { 994 TRACE("(%p,0x%08x,%p,0x%08x,%p)\n", Handle, RequestedInformation, 995 pSecurityDescriptor, nLength, lpnLengthNeeded); 996 997 return set_ntstatus( NtQuerySecurityObject(Handle, RequestedInformation, pSecurityDescriptor, 998 nLength, lpnLengthNeeded )); 999 } 1000 1001 /* 1002 * @implemented 1003 */ 1004 BOOL 1005 WINAPI 1006 InitializeAcl(PACL pAcl, 1007 DWORD nAclLength, 1008 DWORD dwAclRevision) 1009 { 1010 NTSTATUS Status; 1011 1012 Status = RtlCreateAcl(pAcl, 1013 nAclLength, 1014 dwAclRevision); 1015 if (!NT_SUCCESS(Status)) 1016 { 1017 SetLastError(RtlNtStatusToDosError(Status)); 1018 return FALSE; 1019 } 1020 1021 return TRUE; 1022 } 1023 1024 BOOL WINAPI ImpersonateNamedPipeClient( HANDLE hNamedPipe ) 1025 { 1026 IO_STATUS_BLOCK io_block; 1027 1028 TRACE("(%p)\n", hNamedPipe); 1029 1030 return set_ntstatus( NtFsControlFile(hNamedPipe, NULL, NULL, NULL, 1031 &io_block, FSCTL_PIPE_IMPERSONATE, NULL, 0, NULL, 0) ); 1032 } 1033 1034 /* 1035 * @implemented 1036 */ 1037 BOOL 1038 WINAPI 1039 AddAccessAllowedAce(PACL pAcl, 1040 DWORD dwAceRevision, 1041 DWORD AccessMask, 1042 PSID pSid) 1043 { 1044 NTSTATUS Status; 1045 1046 Status = RtlAddAccessAllowedAce(pAcl, 1047 dwAceRevision, 1048 AccessMask, 1049 pSid); 1050 if (!NT_SUCCESS(Status)) 1051 { 1052 SetLastError(RtlNtStatusToDosError(Status)); 1053 return FALSE; 1054 } 1055 1056 return TRUE; 1057 } 1058 1059 /* 1060 * @implemented 1061 */ 1062 BOOL WINAPI 1063 AddAccessAllowedAceEx(PACL pAcl, 1064 DWORD dwAceRevision, 1065 DWORD AceFlags, 1066 DWORD AccessMask, 1067 PSID pSid) 1068 { 1069 NTSTATUS Status; 1070 1071 Status = RtlAddAccessAllowedAceEx(pAcl, 1072 dwAceRevision, 1073 AceFlags, 1074 AccessMask, 1075 pSid); 1076 if (!NT_SUCCESS(Status)) 1077 { 1078 SetLastError(RtlNtStatusToDosError(Status)); 1079 return FALSE; 1080 } 1081 1082 return TRUE; 1083 } 1084 1085 /* 1086 * @implemented 1087 */ 1088 BOOL 1089 WINAPI 1090 AddAccessDeniedAce(PACL pAcl, 1091 DWORD dwAceRevision, 1092 DWORD AccessMask, 1093 PSID pSid) 1094 { 1095 NTSTATUS Status; 1096 1097 Status = RtlAddAccessDeniedAce(pAcl, 1098 dwAceRevision, 1099 AccessMask, 1100 pSid); 1101 if (!NT_SUCCESS(Status)) 1102 { 1103 SetLastError(RtlNtStatusToDosError(Status)); 1104 return FALSE; 1105 } 1106 1107 return TRUE; 1108 } 1109 1110 /* 1111 * @implemented 1112 */ 1113 BOOL WINAPI 1114 AddAccessDeniedAceEx(PACL pAcl, 1115 DWORD dwAceRevision, 1116 DWORD AceFlags, 1117 DWORD AccessMask, 1118 PSID pSid) 1119 { 1120 NTSTATUS Status; 1121 1122 Status = RtlAddAccessDeniedAceEx(pAcl, 1123 dwAceRevision, 1124 AceFlags, 1125 AccessMask, 1126 pSid); 1127 if (!NT_SUCCESS(Status)) 1128 { 1129 SetLastError(RtlNtStatusToDosError(Status)); 1130 return FALSE; 1131 } 1132 1133 return TRUE; 1134 } 1135 1136 /* 1137 * @implemented 1138 */ 1139 BOOL 1140 WINAPI 1141 AddAce(PACL pAcl, 1142 DWORD dwAceRevision, 1143 DWORD dwStartingAceIndex, 1144 LPVOID pAceList, 1145 DWORD nAceListLength) 1146 { 1147 NTSTATUS Status; 1148 1149 Status = RtlAddAce(pAcl, 1150 dwAceRevision, 1151 dwStartingAceIndex, 1152 pAceList, 1153 nAceListLength); 1154 if (!NT_SUCCESS(Status)) 1155 { 1156 SetLastError(RtlNtStatusToDosError(Status)); 1157 return FALSE; 1158 } 1159 1160 return TRUE; 1161 } 1162 1163 /****************************************************************************** 1164 * DeleteAce [ADVAPI32.@] 1165 */ 1166 BOOL WINAPI DeleteAce(PACL pAcl, DWORD dwAceIndex) 1167 { 1168 return set_ntstatus(RtlDeleteAce(pAcl, dwAceIndex)); 1169 } 1170 1171 /* 1172 * @implemented 1173 */ 1174 BOOL 1175 WINAPI 1176 FindFirstFreeAce(PACL pAcl, 1177 LPVOID *pAce) 1178 { 1179 return RtlFirstFreeAce(pAcl, 1180 (PACE*)pAce); 1181 } 1182 1183 /****************************************************************************** 1184 * GetAce [ADVAPI32.@] 1185 */ 1186 BOOL WINAPI GetAce(PACL pAcl,DWORD dwAceIndex,LPVOID *pAce ) 1187 { 1188 return set_ntstatus(RtlGetAce(pAcl, dwAceIndex, pAce)); 1189 } 1190 1191 /****************************************************************************** 1192 * GetAclInformation [ADVAPI32.@] 1193 */ 1194 BOOL WINAPI GetAclInformation( 1195 PACL pAcl, 1196 LPVOID pAclInformation, 1197 DWORD nAclInformationLength, 1198 ACL_INFORMATION_CLASS dwAclInformationClass) 1199 { 1200 return set_ntstatus(RtlQueryInformationAcl(pAcl, pAclInformation, 1201 nAclInformationLength, dwAclInformationClass)); 1202 } 1203 1204 /* 1205 * @implemented 1206 */ 1207 BOOL 1208 WINAPI 1209 IsValidAcl(PACL pAcl) 1210 { 1211 return RtlValidAcl (pAcl); 1212 } 1213 1214 /* 1215 * @implemented 1216 */ 1217 BOOL WINAPI 1218 AllocateLocallyUniqueId(PLUID Luid) 1219 { 1220 NTSTATUS Status; 1221 1222 Status = NtAllocateLocallyUniqueId (Luid); 1223 if (!NT_SUCCESS (Status)) 1224 { 1225 SetLastError(RtlNtStatusToDosError(Status)); 1226 return FALSE; 1227 } 1228 1229 return TRUE; 1230 } 1231 1232 /********************************************************************** 1233 * LookupPrivilegeDisplayNameA EXPORTED 1234 * 1235 * @unimplemented 1236 */ 1237 BOOL 1238 WINAPI 1239 LookupPrivilegeDisplayNameA(LPCSTR lpSystemName, 1240 LPCSTR lpName, 1241 LPSTR lpDisplayName, 1242 LPDWORD cchDisplayName, 1243 LPDWORD lpLanguageId) 1244 { 1245 UNICODE_STRING lpSystemNameW; 1246 UNICODE_STRING lpNameW; 1247 BOOL ret; 1248 DWORD wLen = 0; 1249 1250 TRACE("%s %s %p %p %p\n", debugstr_a(lpSystemName), debugstr_a(lpName), lpName, cchDisplayName, lpLanguageId); 1251 1252 RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW, lpSystemName); 1253 RtlCreateUnicodeStringFromAsciiz(&lpNameW, lpName); 1254 ret = LookupPrivilegeDisplayNameW(lpSystemNameW.Buffer, lpNameW.Buffer, NULL, &wLen, lpLanguageId); 1255 if (!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER) 1256 { 1257 LPWSTR lpDisplayNameW = HeapAlloc(GetProcessHeap(), 0, wLen * sizeof(WCHAR)); 1258 1259 ret = LookupPrivilegeDisplayNameW(lpSystemNameW.Buffer, lpNameW.Buffer, lpDisplayNameW, 1260 &wLen, lpLanguageId); 1261 if (ret) 1262 { 1263 unsigned int len = WideCharToMultiByte(CP_ACP, 0, lpDisplayNameW, -1, lpDisplayName, 1264 *cchDisplayName, NULL, NULL); 1265 1266 if (len == 0) 1267 { 1268 /* WideCharToMultiByte failed */ 1269 ret = FALSE; 1270 } 1271 else if (len > *cchDisplayName) 1272 { 1273 *cchDisplayName = len; 1274 SetLastError(ERROR_INSUFFICIENT_BUFFER); 1275 ret = FALSE; 1276 } 1277 else 1278 { 1279 /* WideCharToMultiByte succeeded, output length needs to be 1280 * length not including NULL terminator 1281 */ 1282 *cchDisplayName = len - 1; 1283 } 1284 } 1285 HeapFree(GetProcessHeap(), 0, lpDisplayNameW); 1286 } 1287 RtlFreeUnicodeString(&lpSystemNameW); 1288 RtlFreeUnicodeString(&lpNameW); 1289 return ret; 1290 } 1291 1292 /********************************************************************** 1293 * LookupPrivilegeNameA EXPORTED 1294 * 1295 * @implemented 1296 */ 1297 BOOL 1298 WINAPI 1299 LookupPrivilegeNameA(LPCSTR lpSystemName, 1300 PLUID lpLuid, 1301 LPSTR lpName, 1302 LPDWORD cchName) 1303 { 1304 UNICODE_STRING lpSystemNameW; 1305 BOOL ret; 1306 DWORD wLen = 0; 1307 1308 TRACE("%s %p %p %p\n", debugstr_a(lpSystemName), lpLuid, lpName, cchName); 1309 1310 RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW, lpSystemName); 1311 ret = LookupPrivilegeNameW(lpSystemNameW.Buffer, lpLuid, NULL, &wLen); 1312 if (!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER) 1313 { 1314 LPWSTR lpNameW = HeapAlloc(GetProcessHeap(), 0, wLen * sizeof(WCHAR)); 1315 1316 ret = LookupPrivilegeNameW(lpSystemNameW.Buffer, lpLuid, lpNameW, 1317 &wLen); 1318 if (ret) 1319 { 1320 /* Windows crashes if cchName is NULL, so will I */ 1321 unsigned int len = WideCharToMultiByte(CP_ACP, 0, lpNameW, -1, lpName, 1322 *cchName, NULL, NULL); 1323 1324 if (len == 0) 1325 { 1326 /* WideCharToMultiByte failed */ 1327 ret = FALSE; 1328 } 1329 else if (len > *cchName) 1330 { 1331 *cchName = len; 1332 SetLastError(ERROR_INSUFFICIENT_BUFFER); 1333 ret = FALSE; 1334 } 1335 else 1336 { 1337 /* WideCharToMultiByte succeeded, output length needs to be 1338 * length not including NULL terminator 1339 */ 1340 *cchName = len - 1; 1341 } 1342 } 1343 HeapFree(GetProcessHeap(), 0, lpNameW); 1344 } 1345 RtlFreeUnicodeString(&lpSystemNameW); 1346 return ret; 1347 } 1348 1349 /****************************************************************************** 1350 * GetFileSecurityA [ADVAPI32.@] 1351 * 1352 * Obtains Specified information about the security of a file or directory. 1353 * 1354 * PARAMS 1355 * lpFileName [I] Name of the file to get info for 1356 * RequestedInformation [I] SE_ flags from "winnt.h" 1357 * pSecurityDescriptor [O] Destination for security information 1358 * nLength [I] Length of pSecurityDescriptor 1359 * lpnLengthNeeded [O] Destination for length of returned security information 1360 * 1361 * RETURNS 1362 * Success: TRUE. pSecurityDescriptor contains the requested information. 1363 * Failure: FALSE. lpnLengthNeeded contains the required space to return the info. 1364 * 1365 * NOTES 1366 * The information returned is constrained by the callers access rights and 1367 * privileges. 1368 * 1369 * @implemented 1370 */ 1371 BOOL 1372 WINAPI 1373 GetFileSecurityA(LPCSTR lpFileName, 1374 SECURITY_INFORMATION RequestedInformation, 1375 PSECURITY_DESCRIPTOR pSecurityDescriptor, 1376 DWORD nLength, 1377 LPDWORD lpnLengthNeeded) 1378 { 1379 UNICODE_STRING FileName; 1380 BOOL bResult; 1381 1382 if (!RtlCreateUnicodeStringFromAsciiz(&FileName, lpFileName)) 1383 { 1384 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 1385 return FALSE; 1386 } 1387 1388 bResult = GetFileSecurityW(FileName.Buffer, 1389 RequestedInformation, 1390 pSecurityDescriptor, 1391 nLength, 1392 lpnLengthNeeded); 1393 1394 RtlFreeUnicodeString(&FileName); 1395 1396 return bResult; 1397 } 1398 1399 /* 1400 * @implemented 1401 */ 1402 BOOL 1403 WINAPI 1404 GetFileSecurityW(LPCWSTR lpFileName, 1405 SECURITY_INFORMATION RequestedInformation, 1406 PSECURITY_DESCRIPTOR pSecurityDescriptor, 1407 DWORD nLength, 1408 LPDWORD lpnLengthNeeded) 1409 { 1410 OBJECT_ATTRIBUTES ObjectAttributes; 1411 IO_STATUS_BLOCK StatusBlock; 1412 UNICODE_STRING FileName; 1413 ULONG AccessMask = 0; 1414 HANDLE FileHandle; 1415 NTSTATUS Status; 1416 1417 TRACE("GetFileSecurityW() called\n"); 1418 1419 QuerySecurityAccessMask(RequestedInformation, &AccessMask); 1420 1421 if (!RtlDosPathNameToNtPathName_U(lpFileName, 1422 &FileName, 1423 NULL, 1424 NULL)) 1425 { 1426 ERR("Invalid path\n"); 1427 SetLastError(ERROR_INVALID_NAME); 1428 return FALSE; 1429 } 1430 1431 InitializeObjectAttributes(&ObjectAttributes, 1432 &FileName, 1433 OBJ_CASE_INSENSITIVE, 1434 NULL, 1435 NULL); 1436 1437 Status = NtOpenFile(&FileHandle, 1438 AccessMask, 1439 &ObjectAttributes, 1440 &StatusBlock, 1441 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, 1442 0); 1443 1444 RtlFreeHeap(RtlGetProcessHeap(), 1445 0, 1446 FileName.Buffer); 1447 1448 if (!NT_SUCCESS(Status)) 1449 { 1450 ERR("NtOpenFile() failed (Status %lx)\n", Status); 1451 SetLastError(RtlNtStatusToDosError(Status)); 1452 return FALSE; 1453 } 1454 1455 Status = NtQuerySecurityObject(FileHandle, 1456 RequestedInformation, 1457 pSecurityDescriptor, 1458 nLength, 1459 lpnLengthNeeded); 1460 NtClose(FileHandle); 1461 if (!NT_SUCCESS(Status)) 1462 { 1463 ERR("NtQuerySecurityObject() failed (Status %lx)\n", Status); 1464 SetLastError(RtlNtStatusToDosError(Status)); 1465 return FALSE; 1466 } 1467 1468 return TRUE; 1469 } 1470 1471 /****************************************************************************** 1472 * SetFileSecurityA [ADVAPI32.@] 1473 * Sets the security of a file or directory 1474 * 1475 * @implemented 1476 */ 1477 BOOL 1478 WINAPI 1479 SetFileSecurityA(LPCSTR lpFileName, 1480 SECURITY_INFORMATION SecurityInformation, 1481 PSECURITY_DESCRIPTOR pSecurityDescriptor) 1482 { 1483 UNICODE_STRING FileName; 1484 BOOL bResult; 1485 1486 if (!RtlCreateUnicodeStringFromAsciiz(&FileName, lpFileName)) 1487 { 1488 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 1489 return FALSE; 1490 } 1491 1492 bResult = SetFileSecurityW(FileName.Buffer, 1493 SecurityInformation, 1494 pSecurityDescriptor); 1495 1496 RtlFreeUnicodeString(&FileName); 1497 1498 return bResult; 1499 } 1500 1501 /****************************************************************************** 1502 * SetFileSecurityW [ADVAPI32.@] 1503 * Sets the security of a file or directory 1504 * 1505 * @implemented 1506 */ 1507 BOOL 1508 WINAPI 1509 SetFileSecurityW(LPCWSTR lpFileName, 1510 SECURITY_INFORMATION SecurityInformation, 1511 PSECURITY_DESCRIPTOR pSecurityDescriptor) 1512 { 1513 OBJECT_ATTRIBUTES ObjectAttributes; 1514 IO_STATUS_BLOCK StatusBlock; 1515 UNICODE_STRING FileName; 1516 ULONG AccessMask = 0; 1517 HANDLE FileHandle; 1518 NTSTATUS Status; 1519 1520 TRACE("SetFileSecurityW() called\n"); 1521 1522 SetSecurityAccessMask(SecurityInformation, &AccessMask); 1523 1524 if (!RtlDosPathNameToNtPathName_U(lpFileName, 1525 &FileName, 1526 NULL, 1527 NULL)) 1528 { 1529 ERR("Invalid path\n"); 1530 SetLastError(ERROR_INVALID_NAME); 1531 return FALSE; 1532 } 1533 1534 InitializeObjectAttributes(&ObjectAttributes, 1535 &FileName, 1536 OBJ_CASE_INSENSITIVE, 1537 NULL, 1538 NULL); 1539 1540 Status = NtOpenFile(&FileHandle, 1541 AccessMask, 1542 &ObjectAttributes, 1543 &StatusBlock, 1544 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, 1545 0); 1546 1547 RtlFreeHeap(RtlGetProcessHeap(), 1548 0, 1549 FileName.Buffer); 1550 1551 if (!NT_SUCCESS(Status)) 1552 { 1553 ERR("NtOpenFile() failed (Status %lx)\n", Status); 1554 SetLastError(RtlNtStatusToDosError(Status)); 1555 return FALSE; 1556 } 1557 1558 Status = NtSetSecurityObject(FileHandle, 1559 SecurityInformation, 1560 pSecurityDescriptor); 1561 NtClose(FileHandle); 1562 1563 if (!NT_SUCCESS(Status)) 1564 { 1565 ERR("NtSetSecurityObject() failed (Status %lx)\n", Status); 1566 SetLastError(RtlNtStatusToDosError(Status)); 1567 return FALSE; 1568 } 1569 1570 return TRUE; 1571 } 1572 1573 /****************************************************************************** 1574 * QueryWindows31FilesMigration [ADVAPI32.@] 1575 * 1576 * PARAMS 1577 * x1 [] 1578 */ 1579 BOOL WINAPI 1580 QueryWindows31FilesMigration( DWORD x1 ) 1581 { 1582 FIXME("(%d):stub\n",x1); 1583 return TRUE; 1584 } 1585 1586 /****************************************************************************** 1587 * SynchronizeWindows31FilesAndWindowsNTRegistry [ADVAPI32.@] 1588 * 1589 * PARAMS 1590 * x1 [] 1591 * x2 [] 1592 * x3 [] 1593 * x4 [] 1594 */ 1595 BOOL WINAPI 1596 SynchronizeWindows31FilesAndWindowsNTRegistry( DWORD x1, DWORD x2, DWORD x3, 1597 DWORD x4 ) 1598 { 1599 FIXME("(0x%08x,0x%08x,0x%08x,0x%08x):stub\n",x1,x2,x3,x4); 1600 return TRUE; 1601 } 1602 1603 /* 1604 * @implemented 1605 */ 1606 BOOL 1607 WINAPI 1608 RevertToSelf(VOID) 1609 { 1610 NTSTATUS Status; 1611 HANDLE Token = NULL; 1612 1613 Status = NtSetInformationThread(NtCurrentThread(), 1614 ThreadImpersonationToken, 1615 &Token, 1616 sizeof(HANDLE)); 1617 if (!NT_SUCCESS(Status)) 1618 { 1619 SetLastError(RtlNtStatusToDosError(Status)); 1620 return FALSE; 1621 } 1622 1623 return TRUE; 1624 } 1625 1626 /* 1627 * @implemented 1628 */ 1629 BOOL 1630 WINAPI 1631 ImpersonateSelf(SECURITY_IMPERSONATION_LEVEL ImpersonationLevel) 1632 { 1633 NTSTATUS Status; 1634 1635 Status = RtlImpersonateSelf(ImpersonationLevel); 1636 if (!NT_SUCCESS(Status)) 1637 { 1638 SetLastError(RtlNtStatusToDosError(Status)); 1639 return FALSE; 1640 } 1641 1642 return TRUE; 1643 } 1644 1645 /* 1646 * @implemented 1647 */ 1648 BOOL 1649 WINAPI 1650 AccessCheck(IN PSECURITY_DESCRIPTOR pSecurityDescriptor, 1651 IN HANDLE ClientToken, 1652 IN DWORD DesiredAccess, 1653 IN PGENERIC_MAPPING GenericMapping, 1654 OUT PPRIVILEGE_SET PrivilegeSet OPTIONAL, 1655 IN OUT LPDWORD PrivilegeSetLength, 1656 OUT LPDWORD GrantedAccess, 1657 OUT LPBOOL AccessStatus) 1658 { 1659 NTSTATUS Status; 1660 NTSTATUS NtAccessStatus; 1661 1662 /* Do the access check */ 1663 Status = NtAccessCheck(pSecurityDescriptor, 1664 ClientToken, 1665 DesiredAccess, 1666 GenericMapping, 1667 PrivilegeSet, 1668 (PULONG)PrivilegeSetLength, 1669 (PACCESS_MASK)GrantedAccess, 1670 &NtAccessStatus); 1671 1672 /* See if the access check operation succeeded */ 1673 if (!NT_SUCCESS(Status)) 1674 { 1675 /* Check failed */ 1676 SetLastError(RtlNtStatusToDosError(Status)); 1677 return FALSE; 1678 } 1679 1680 /* Now check the access status */ 1681 if (!NT_SUCCESS(NtAccessStatus)) 1682 { 1683 /* Access denied */ 1684 SetLastError(RtlNtStatusToDosError(NtAccessStatus)); 1685 *AccessStatus = FALSE; 1686 } 1687 else 1688 { 1689 /* Access granted */ 1690 *AccessStatus = TRUE; 1691 } 1692 1693 /* Check succeeded */ 1694 return TRUE; 1695 } 1696 1697 /** 1698 * @brief 1699 * Determines whether security access can be granted to a client 1700 * that requests such access on the object type list. The access 1701 * is either granted or denied for the whole object hierarchy 1702 * in the list. 1703 * 1704 * @param[in] pSecurityDescriptor 1705 * A pointer to a security descriptor that identifies the security 1706 * information of an object being accessed. This function walks 1707 * through this descriptor for any ACLs and respective access 1708 * rights if access can be granted. 1709 * 1710 * @param[in] PrincipalSelfSid 1711 * A pointer to a principal self SID. This parameter can be NULL if 1712 * the associated object being checked for access does not represent 1713 * a principal. 1714 * 1715 * @param[in] ClientToken 1716 * A handle to an access token, that identifies the client of which 1717 * requests access to the target object. 1718 * 1719 * @param[in] DesiredAccess 1720 * The access right bitmask where the client wants to acquire. This 1721 * can be an OR'ed set of multiple access rights or MAXIMUM_ALLOWED 1722 * to request all of possible access rights the target object allows. 1723 * If only some rights were granted but not all the access is deemed 1724 * as denied. 1725 * 1726 * @param[in] ObjectTypeList 1727 * A pointer to a given object type list. If this parameter is not NULL 1728 * the function will perform an access check against the main object 1729 * and sub-objects of this list. If this parameter is NULL and 1730 * ObjectTypeListLength is 0, the function will perform a normal 1731 * access check instead. 1732 * 1733 * @param[in] ObjectTypeListLength 1734 * The length of the object type list array, pointed by ObjectTypeList. 1735 * This length in question represents the number of elements in such array. 1736 * This parameter must be 0 if no array list is provided. 1737 * 1738 * @param[in] GenericMapping 1739 * The generic mapping of access rights of an object type. 1740 * 1741 * @param[out] PrivilegeSet 1742 * A pointer to a set of privileges that were used to perform the 1743 * access check, returned to caller. This function will return no 1744 * privileges (privilege count set to 0) if no privileges were used 1745 * to accomplish the access check. This parameter must not be NULL! 1746 * 1747 * @param[in,out] PrivilegeSetLength 1748 * The total length size of a set of privileges. This length represents 1749 * the count of elements in the privilege set array. 1750 * 1751 * @param[out] GrantedAccess 1752 * A pointer to granted access rights, returned to the caller. 1753 * 1754 * @param[out] AccessStatus 1755 * A pointer to a boolean value that indicates whether access is granted 1756 * or denied to the client that requests access to the entire hierarchy 1757 * of an object type list. If ObjectTypeList is NULL, this value represents 1758 * the access that is granted or denied to the target object, just like 1759 * in AccessCheck. 1760 * 1761 * @return 1762 * The function returns TRUE if the access check operation has completed 1763 * successfully, otherwise it returns FALSE. 1764 */ 1765 BOOL 1766 WINAPI 1767 AccessCheckByType( 1768 _In_ PSECURITY_DESCRIPTOR pSecurityDescriptor, 1769 _In_opt_ PSID PrincipalSelfSid, 1770 _In_ HANDLE ClientToken, 1771 _In_ DWORD DesiredAccess, 1772 _In_reads_opt_(ObjectTypeListLength) POBJECT_TYPE_LIST ObjectTypeList, 1773 _In_ DWORD ObjectTypeListLength, 1774 _In_ PGENERIC_MAPPING GenericMapping, 1775 _Out_writes_bytes_(*PrivilegeSetLength) PPRIVILEGE_SET PrivilegeSet, 1776 _Inout_ LPDWORD PrivilegeSetLength, 1777 _Out_ LPDWORD GrantedAccess, 1778 _Out_ LPBOOL AccessStatus) 1779 { 1780 NTSTATUS Status; 1781 NTSTATUS NtAccessStatus; 1782 1783 Status = NtAccessCheckByType(pSecurityDescriptor, 1784 PrincipalSelfSid, 1785 ClientToken, 1786 DesiredAccess, 1787 ObjectTypeList, 1788 ObjectTypeListLength, 1789 GenericMapping, 1790 PrivilegeSet, 1791 PrivilegeSetLength, 1792 (PACCESS_MASK)GrantedAccess, 1793 &NtAccessStatus); 1794 if (!NT_SUCCESS(Status)) 1795 { 1796 SetLastError(RtlNtStatusToDosError(Status)); 1797 return FALSE; 1798 } 1799 1800 if (!NT_SUCCESS(NtAccessStatus)) 1801 { 1802 SetLastError(RtlNtStatusToDosError(NtAccessStatus)); 1803 *AccessStatus = FALSE; 1804 } 1805 else 1806 { 1807 *AccessStatus = TRUE; 1808 } 1809 1810 return TRUE; 1811 } 1812 1813 /** 1814 * @brief 1815 * Determines whether security access can be granted to a client 1816 * that requests such access on the object type list. Unlike the 1817 * AccessCheckByType variant, this function will grant or deny 1818 * access to each individual object and sub-object in the list. 1819 * 1820 * @param[in] pSecurityDescriptor 1821 * A pointer to a security descriptor that identifies the security 1822 * information of an object being accessed. This function walks 1823 * through this descriptor for any ACLs and respective access 1824 * rights if access can be granted. 1825 * 1826 * @param[in] PrincipalSelfSid 1827 * A pointer to a principal self SID. This parameter can be NULL if 1828 * the associated object being checked for access does not represent 1829 * a principal. 1830 * 1831 * @param[in] ClientToken 1832 * A handle to an access token, that identifies the client of which 1833 * requests access to the target object. 1834 * 1835 * @param[in] DesiredAccess 1836 * The access right bitmask where the client wants to acquire. This 1837 * can be an OR'ed set of multiple access rights or MAXIMUM_ALLOWED 1838 * to request all of possible access rights the target object allows. 1839 * If only some rights were granted but not all the access is deemed 1840 * as denied. 1841 * 1842 * @param[in] ObjectTypeList 1843 * A pointer to a given object type list. This function will perform an 1844 * access check against the main object and sub-objects of this list. 1845 * This parameter must not be NULL! 1846 * 1847 * @param[in] ObjectTypeListLength 1848 * The length of the object type list array, pointed by ObjectTypeList. 1849 * This length in question represents the number of elements in such array. 1850 * This parameter must be 0 if no array list is provided. 1851 * 1852 * @param[in] GenericMapping 1853 * The generic mapping of access rights of an object type. 1854 * 1855 * @param[out] PrivilegeSet 1856 * A pointer to a set of privileges that were used to perform the 1857 * access check, returned to caller. This function will return no 1858 * privileges (privilege count set to 0) if no privileges were used 1859 * to accomplish the access check. This parameter must not be NULL! 1860 * 1861 * @param[in,out] PrivilegeSetLength 1862 * The total length size of a set of privileges. This length represents 1863 * the count of elements in the privilege set array. 1864 * 1865 * @param[out] GrantedAccess 1866 * A pointer to granted access rights. This parameter is an array of granted 1867 * rights for the object and each sub-object of an object type list. 1868 * 1869 * @param[out] AccessStatus 1870 * A pointer to a boolean value that indicates whether access is granted 1871 * or denied to the client that requests access to the object and sub-objects 1872 * of an object type list. This parameter is an array of boolean values for the 1873 * object and each individual sub-object of the list. 1874 * 1875 * @return 1876 * The function returns TRUE if the access check operation has completed 1877 * successfully, otherwise it returns FALSE. 1878 */ 1879 BOOL 1880 WINAPI 1881 AccessCheckByTypeResultList( 1882 _In_ PSECURITY_DESCRIPTOR pSecurityDescriptor, 1883 _In_opt_ PSID PrincipalSelfSid, 1884 _In_ HANDLE ClientToken, 1885 _In_ DWORD DesiredAccess, 1886 _In_reads_(ObjectTypeListLength) POBJECT_TYPE_LIST ObjectTypeList, 1887 _In_ DWORD ObjectTypeListLength, 1888 _In_ PGENERIC_MAPPING GenericMapping, 1889 _Out_writes_bytes_(*PrivilegeSetLength) PPRIVILEGE_SET PrivilegeSet, 1890 _Inout_ LPDWORD PrivilegeSetLength, 1891 _Out_writes_(ObjectTypeListLength) LPDWORD GrantedAccess, 1892 _Out_writes_(ObjectTypeListLength) LPBOOL AccessStatus) 1893 { 1894 NTSTATUS Status; 1895 DWORD ResultListIndex; 1896 PNTSTATUS NtAccessStatus = NULL; 1897 1898 Status = NtAccessCheckByTypeResultList(pSecurityDescriptor, 1899 PrincipalSelfSid, 1900 ClientToken, 1901 DesiredAccess, 1902 ObjectTypeList, 1903 ObjectTypeListLength, 1904 GenericMapping, 1905 PrivilegeSet, 1906 PrivilegeSetLength, 1907 (PACCESS_MASK)GrantedAccess, 1908 NtAccessStatus); 1909 if (!NT_SUCCESS(Status)) 1910 { 1911 SetLastError(RtlNtStatusToDosError(Status)); 1912 return FALSE; 1913 } 1914 1915 for (ResultListIndex = 0; ResultListIndex < ObjectTypeListLength; ResultListIndex++) 1916 { 1917 AccessStatus[ResultListIndex] = RtlNtStatusToDosError(NtAccessStatus[ResultListIndex]); 1918 } 1919 1920 return TRUE; 1921 } 1922 1923 /* 1924 * @implemented 1925 */ 1926 BOOL 1927 WINAPI 1928 SetKernelObjectSecurity(HANDLE Handle, 1929 SECURITY_INFORMATION SecurityInformation, 1930 PSECURITY_DESCRIPTOR SecurityDescriptor) 1931 { 1932 NTSTATUS Status; 1933 1934 Status = NtSetSecurityObject(Handle, 1935 SecurityInformation, 1936 SecurityDescriptor); 1937 if (!NT_SUCCESS(Status)) 1938 { 1939 SetLastError(RtlNtStatusToDosError(Status)); 1940 return FALSE; 1941 } 1942 1943 return TRUE; 1944 } 1945 1946 /* 1947 * @implemented 1948 */ 1949 BOOL 1950 WINAPI 1951 AddAuditAccessAce(PACL pAcl, 1952 DWORD dwAceRevision, 1953 DWORD dwAccessMask, 1954 PSID pSid, 1955 BOOL bAuditSuccess, 1956 BOOL bAuditFailure) 1957 { 1958 NTSTATUS Status; 1959 1960 Status = RtlAddAuditAccessAce(pAcl, 1961 dwAceRevision, 1962 dwAccessMask, 1963 pSid, 1964 bAuditSuccess, 1965 bAuditFailure); 1966 if (!NT_SUCCESS(Status)) 1967 { 1968 SetLastError(RtlNtStatusToDosError(Status)); 1969 return FALSE; 1970 } 1971 1972 return TRUE; 1973 } 1974 1975 /* 1976 * @implemented 1977 */ 1978 BOOL WINAPI 1979 AddAuditAccessAceEx(PACL pAcl, 1980 DWORD dwAceRevision, 1981 DWORD AceFlags, 1982 DWORD dwAccessMask, 1983 PSID pSid, 1984 BOOL bAuditSuccess, 1985 BOOL bAuditFailure) 1986 { 1987 NTSTATUS Status; 1988 1989 Status = RtlAddAuditAccessAceEx(pAcl, 1990 dwAceRevision, 1991 AceFlags, 1992 dwAccessMask, 1993 pSid, 1994 bAuditSuccess, 1995 bAuditFailure); 1996 if (!NT_SUCCESS(Status)) 1997 { 1998 SetLastError(RtlNtStatusToDosError(Status)); 1999 return FALSE; 2000 } 2001 2002 return TRUE; 2003 } 2004 2005 /****************************************************************************** 2006 * LookupAccountNameA [ADVAPI32.@] 2007 * 2008 * @implemented 2009 */ 2010 BOOL 2011 WINAPI 2012 LookupAccountNameA(LPCSTR SystemName, 2013 LPCSTR AccountName, 2014 PSID Sid, 2015 LPDWORD SidLength, 2016 LPSTR ReferencedDomainName, 2017 LPDWORD hReferencedDomainNameLength, 2018 PSID_NAME_USE SidNameUse) 2019 { 2020 BOOL ret; 2021 UNICODE_STRING lpSystemW; 2022 UNICODE_STRING lpAccountW; 2023 LPWSTR lpReferencedDomainNameW = NULL; 2024 2025 RtlCreateUnicodeStringFromAsciiz(&lpSystemW, SystemName); 2026 RtlCreateUnicodeStringFromAsciiz(&lpAccountW, AccountName); 2027 2028 if (ReferencedDomainName) 2029 lpReferencedDomainNameW = HeapAlloc(GetProcessHeap(), 2030 0, 2031 *hReferencedDomainNameLength * sizeof(WCHAR)); 2032 2033 ret = LookupAccountNameW(lpSystemW.Buffer, 2034 lpAccountW.Buffer, 2035 Sid, 2036 SidLength, 2037 lpReferencedDomainNameW, 2038 hReferencedDomainNameLength, 2039 SidNameUse); 2040 2041 if (ret && lpReferencedDomainNameW) 2042 { 2043 WideCharToMultiByte(CP_ACP, 2044 0, 2045 lpReferencedDomainNameW, 2046 *hReferencedDomainNameLength + 1, 2047 ReferencedDomainName, 2048 *hReferencedDomainNameLength + 1, 2049 NULL, 2050 NULL); 2051 } 2052 2053 RtlFreeUnicodeString(&lpSystemW); 2054 RtlFreeUnicodeString(&lpAccountW); 2055 HeapFree(GetProcessHeap(), 0, lpReferencedDomainNameW); 2056 2057 return ret; 2058 } 2059 2060 /********************************************************************** 2061 * PrivilegeCheck EXPORTED 2062 * 2063 * @implemented 2064 */ 2065 BOOL WINAPI 2066 PrivilegeCheck(HANDLE ClientToken, 2067 PPRIVILEGE_SET RequiredPrivileges, 2068 LPBOOL pfResult) 2069 { 2070 BOOLEAN Result; 2071 NTSTATUS Status; 2072 2073 Status = NtPrivilegeCheck(ClientToken, 2074 RequiredPrivileges, 2075 &Result); 2076 if (!NT_SUCCESS(Status)) 2077 { 2078 SetLastError(RtlNtStatusToDosError(Status)); 2079 return FALSE; 2080 } 2081 2082 *pfResult = (BOOL)Result; 2083 2084 return TRUE; 2085 } 2086 2087 /****************************************************************************** 2088 * GetSecurityInfoExW EXPORTED 2089 */ 2090 DWORD 2091 WINAPI 2092 GetSecurityInfoExA(HANDLE hObject, 2093 SE_OBJECT_TYPE ObjectType, 2094 SECURITY_INFORMATION SecurityInfo, 2095 LPCSTR lpProvider, 2096 LPCSTR lpProperty, 2097 PACTRL_ACCESSA *ppAccessList, 2098 PACTRL_AUDITA *ppAuditList, 2099 LPSTR *lppOwner, 2100 LPSTR *lppGroup) 2101 { 2102 FIXME("%s() not implemented!\n", __FUNCTION__); 2103 return ERROR_BAD_PROVIDER; 2104 } 2105 2106 2107 /****************************************************************************** 2108 * GetSecurityInfoExW EXPORTED 2109 */ 2110 DWORD 2111 WINAPI 2112 GetSecurityInfoExW(HANDLE hObject, 2113 SE_OBJECT_TYPE ObjectType, 2114 SECURITY_INFORMATION SecurityInfo, 2115 LPCWSTR lpProvider, 2116 LPCWSTR lpProperty, 2117 PACTRL_ACCESSW *ppAccessList, 2118 PACTRL_AUDITW *ppAuditList, 2119 LPWSTR *lppOwner, 2120 LPWSTR *lppGroup) 2121 { 2122 FIXME("%s() not implemented!\n", __FUNCTION__); 2123 return ERROR_BAD_PROVIDER; 2124 } 2125 2126 /****************************************************************************** 2127 * BuildExplicitAccessWithNameA [ADVAPI32.@] 2128 */ 2129 VOID WINAPI 2130 BuildExplicitAccessWithNameA(PEXPLICIT_ACCESSA pExplicitAccess, 2131 LPSTR pTrusteeName, 2132 DWORD AccessPermissions, 2133 ACCESS_MODE AccessMode, 2134 DWORD Inheritance) 2135 { 2136 pExplicitAccess->grfAccessPermissions = AccessPermissions; 2137 pExplicitAccess->grfAccessMode = AccessMode; 2138 pExplicitAccess->grfInheritance = Inheritance; 2139 2140 pExplicitAccess->Trustee.pMultipleTrustee = NULL; 2141 pExplicitAccess->Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE; 2142 pExplicitAccess->Trustee.TrusteeForm = TRUSTEE_IS_NAME; 2143 pExplicitAccess->Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN; 2144 pExplicitAccess->Trustee.ptstrName = pTrusteeName; 2145 } 2146 2147 2148 /****************************************************************************** 2149 * BuildExplicitAccessWithNameW [ADVAPI32.@] 2150 */ 2151 VOID WINAPI 2152 BuildExplicitAccessWithNameW(PEXPLICIT_ACCESSW pExplicitAccess, 2153 LPWSTR pTrusteeName, 2154 DWORD AccessPermissions, 2155 ACCESS_MODE AccessMode, 2156 DWORD Inheritance) 2157 { 2158 pExplicitAccess->grfAccessPermissions = AccessPermissions; 2159 pExplicitAccess->grfAccessMode = AccessMode; 2160 pExplicitAccess->grfInheritance = Inheritance; 2161 2162 pExplicitAccess->Trustee.pMultipleTrustee = NULL; 2163 pExplicitAccess->Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE; 2164 pExplicitAccess->Trustee.TrusteeForm = TRUSTEE_IS_NAME; 2165 pExplicitAccess->Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN; 2166 pExplicitAccess->Trustee.ptstrName = pTrusteeName; 2167 } 2168 2169 /****************************************************************************** 2170 * BuildTrusteeWithObjectsAndNameA [ADVAPI32.@] 2171 */ 2172 VOID WINAPI BuildTrusteeWithObjectsAndNameA( PTRUSTEEA pTrustee, POBJECTS_AND_NAME_A pObjName, 2173 SE_OBJECT_TYPE ObjectType, LPSTR ObjectTypeName, 2174 LPSTR InheritedObjectTypeName, LPSTR Name ) 2175 { 2176 DWORD ObjectsPresent = 0; 2177 2178 TRACE("%p %p 0x%08x %p %p %s\n", pTrustee, pObjName, 2179 ObjectType, ObjectTypeName, InheritedObjectTypeName, debugstr_a(Name)); 2180 2181 /* Fill the OBJECTS_AND_NAME structure */ 2182 pObjName->ObjectType = ObjectType; 2183 if (ObjectTypeName != NULL) 2184 { 2185 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT; 2186 } 2187 2188 pObjName->InheritedObjectTypeName = InheritedObjectTypeName; 2189 if (InheritedObjectTypeName != NULL) 2190 { 2191 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT; 2192 } 2193 2194 pObjName->ObjectsPresent = ObjectsPresent; 2195 pObjName->ptstrName = Name; 2196 2197 /* Fill the TRUSTEE structure */ 2198 pTrustee->pMultipleTrustee = NULL; 2199 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE; 2200 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_NAME; 2201 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN; 2202 pTrustee->ptstrName = (LPSTR)pObjName; 2203 } 2204 2205 /****************************************************************************** 2206 * BuildTrusteeWithObjectsAndNameW [ADVAPI32.@] 2207 */ 2208 VOID WINAPI BuildTrusteeWithObjectsAndNameW( PTRUSTEEW pTrustee, POBJECTS_AND_NAME_W pObjName, 2209 SE_OBJECT_TYPE ObjectType, LPWSTR ObjectTypeName, 2210 LPWSTR InheritedObjectTypeName, LPWSTR Name ) 2211 { 2212 DWORD ObjectsPresent = 0; 2213 2214 TRACE("%p %p 0x%08x %p %p %s\n", pTrustee, pObjName, 2215 ObjectType, ObjectTypeName, InheritedObjectTypeName, debugstr_w(Name)); 2216 2217 /* Fill the OBJECTS_AND_NAME structure */ 2218 pObjName->ObjectType = ObjectType; 2219 if (ObjectTypeName != NULL) 2220 { 2221 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT; 2222 } 2223 2224 pObjName->InheritedObjectTypeName = InheritedObjectTypeName; 2225 if (InheritedObjectTypeName != NULL) 2226 { 2227 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT; 2228 } 2229 2230 pObjName->ObjectsPresent = ObjectsPresent; 2231 pObjName->ptstrName = Name; 2232 2233 /* Fill the TRUSTEE structure */ 2234 pTrustee->pMultipleTrustee = NULL; 2235 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE; 2236 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_NAME; 2237 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN; 2238 pTrustee->ptstrName = (LPWSTR)pObjName; 2239 } 2240 2241 /****************************************************************************** 2242 * BuildTrusteeWithObjectsAndSidA [ADVAPI32.@] 2243 */ 2244 VOID WINAPI 2245 BuildTrusteeWithObjectsAndSidA(PTRUSTEEA pTrustee, 2246 POBJECTS_AND_SID pObjSid, 2247 GUID *pObjectGuid, 2248 GUID *pInheritedObjectGuid, 2249 PSID pSid) 2250 { 2251 DWORD ObjectsPresent = 0; 2252 2253 TRACE("%p %p %p %p %p\n", pTrustee, pObjSid, pObjectGuid, pInheritedObjectGuid, pSid); 2254 2255 /* Fill the OBJECTS_AND_SID structure */ 2256 if (pObjectGuid != NULL) 2257 { 2258 pObjSid->ObjectTypeGuid = *pObjectGuid; 2259 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT; 2260 } 2261 else 2262 { 2263 ZeroMemory(&pObjSid->ObjectTypeGuid, 2264 sizeof(GUID)); 2265 } 2266 2267 if (pInheritedObjectGuid != NULL) 2268 { 2269 pObjSid->InheritedObjectTypeGuid = *pInheritedObjectGuid; 2270 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT; 2271 } 2272 else 2273 { 2274 ZeroMemory(&pObjSid->InheritedObjectTypeGuid, 2275 sizeof(GUID)); 2276 } 2277 2278 pObjSid->ObjectsPresent = ObjectsPresent; 2279 pObjSid->pSid = pSid; 2280 2281 /* Fill the TRUSTEE structure */ 2282 pTrustee->pMultipleTrustee = NULL; 2283 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE; 2284 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_SID; 2285 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN; 2286 pTrustee->ptstrName = (LPSTR) pObjSid; 2287 } 2288 2289 2290 /****************************************************************************** 2291 * BuildTrusteeWithObjectsAndSidW [ADVAPI32.@] 2292 */ 2293 VOID WINAPI 2294 BuildTrusteeWithObjectsAndSidW(PTRUSTEEW pTrustee, 2295 POBJECTS_AND_SID pObjSid, 2296 GUID *pObjectGuid, 2297 GUID *pInheritedObjectGuid, 2298 PSID pSid) 2299 { 2300 DWORD ObjectsPresent = 0; 2301 2302 TRACE("%p %p %p %p %p\n", pTrustee, pObjSid, pObjectGuid, pInheritedObjectGuid, pSid); 2303 2304 /* Fill the OBJECTS_AND_SID structure */ 2305 if (pObjectGuid != NULL) 2306 { 2307 pObjSid->ObjectTypeGuid = *pObjectGuid; 2308 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT; 2309 } 2310 else 2311 { 2312 ZeroMemory(&pObjSid->ObjectTypeGuid, 2313 sizeof(GUID)); 2314 } 2315 2316 if (pInheritedObjectGuid != NULL) 2317 { 2318 pObjSid->InheritedObjectTypeGuid = *pInheritedObjectGuid; 2319 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT; 2320 } 2321 else 2322 { 2323 ZeroMemory(&pObjSid->InheritedObjectTypeGuid, 2324 sizeof(GUID)); 2325 } 2326 2327 pObjSid->ObjectsPresent = ObjectsPresent; 2328 pObjSid->pSid = pSid; 2329 2330 /* Fill the TRUSTEE structure */ 2331 pTrustee->pMultipleTrustee = NULL; 2332 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE; 2333 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_SID; 2334 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN; 2335 pTrustee->ptstrName = (LPWSTR) pObjSid; 2336 } 2337 2338 /****************************************************************************** 2339 * BuildTrusteeWithSidA [ADVAPI32.@] 2340 */ 2341 VOID WINAPI 2342 BuildTrusteeWithSidA(PTRUSTEE_A pTrustee, 2343 PSID pSid) 2344 { 2345 TRACE("%p %p\n", pTrustee, pSid); 2346 2347 pTrustee->pMultipleTrustee = NULL; 2348 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE; 2349 pTrustee->TrusteeForm = TRUSTEE_IS_SID; 2350 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN; 2351 pTrustee->ptstrName = (LPSTR) pSid; 2352 } 2353 2354 2355 /****************************************************************************** 2356 * BuildTrusteeWithSidW [ADVAPI32.@] 2357 */ 2358 VOID WINAPI 2359 BuildTrusteeWithSidW(PTRUSTEE_W pTrustee, 2360 PSID pSid) 2361 { 2362 TRACE("%p %p\n", pTrustee, pSid); 2363 2364 pTrustee->pMultipleTrustee = NULL; 2365 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE; 2366 pTrustee->TrusteeForm = TRUSTEE_IS_SID; 2367 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN; 2368 pTrustee->ptstrName = (LPWSTR) pSid; 2369 } 2370 2371 /****************************************************************************** 2372 * BuildTrusteeWithNameA [ADVAPI32.@] 2373 */ 2374 VOID WINAPI 2375 BuildTrusteeWithNameA(PTRUSTEE_A pTrustee, 2376 LPSTR name) 2377 { 2378 TRACE("%p %s\n", pTrustee, name); 2379 2380 pTrustee->pMultipleTrustee = NULL; 2381 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE; 2382 pTrustee->TrusteeForm = TRUSTEE_IS_NAME; 2383 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN; 2384 pTrustee->ptstrName = name; 2385 } 2386 2387 /****************************************************************************** 2388 * BuildTrusteeWithNameW [ADVAPI32.@] 2389 */ 2390 VOID WINAPI 2391 BuildTrusteeWithNameW(PTRUSTEE_W pTrustee, 2392 LPWSTR name) 2393 { 2394 TRACE("%p %s\n", pTrustee, name); 2395 2396 pTrustee->pMultipleTrustee = NULL; 2397 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE; 2398 pTrustee->TrusteeForm = TRUSTEE_IS_NAME; 2399 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN; 2400 pTrustee->ptstrName = name; 2401 } 2402 2403 /****************************************************************************** 2404 * GetTrusteeFormA [ADVAPI32.@] 2405 */ 2406 TRUSTEE_FORM WINAPI GetTrusteeFormA(PTRUSTEEA pTrustee) 2407 { 2408 TRACE("(%p)\n", pTrustee); 2409 2410 if (!pTrustee) 2411 return TRUSTEE_BAD_FORM; 2412 2413 return pTrustee->TrusteeForm; 2414 } 2415 2416 /****************************************************************************** 2417 * GetTrusteeFormW [ADVAPI32.@] 2418 */ 2419 TRUSTEE_FORM WINAPI GetTrusteeFormW(PTRUSTEEW pTrustee) 2420 { 2421 TRACE("(%p)\n", pTrustee); 2422 2423 if (!pTrustee) 2424 return TRUSTEE_BAD_FORM; 2425 2426 return pTrustee->TrusteeForm; 2427 } 2428 2429 /****************************************************************************** 2430 * GetTrusteeNameA [ADVAPI32.@] 2431 */ 2432 LPSTR WINAPI 2433 GetTrusteeNameA(PTRUSTEE_A pTrustee) 2434 { 2435 return pTrustee->ptstrName; 2436 } 2437 2438 2439 /****************************************************************************** 2440 * GetTrusteeNameW [ADVAPI32.@] 2441 */ 2442 LPWSTR WINAPI 2443 GetTrusteeNameW(PTRUSTEE_W pTrustee) 2444 { 2445 return pTrustee->ptstrName; 2446 } 2447 2448 /****************************************************************************** 2449 * GetTrusteeTypeA [ADVAPI32.@] 2450 */ 2451 TRUSTEE_TYPE WINAPI 2452 GetTrusteeTypeA(PTRUSTEE_A pTrustee) 2453 { 2454 return pTrustee->TrusteeType; 2455 } 2456 2457 /****************************************************************************** 2458 * GetTrusteeTypeW [ADVAPI32.@] 2459 */ 2460 TRUSTEE_TYPE WINAPI 2461 GetTrusteeTypeW(PTRUSTEE_W pTrustee) 2462 { 2463 return pTrustee->TrusteeType; 2464 } 2465 2466 /* 2467 * @implemented 2468 */ 2469 BOOL 2470 WINAPI 2471 SetAclInformation(PACL pAcl, 2472 LPVOID pAclInformation, 2473 DWORD nAclInformationLength, 2474 ACL_INFORMATION_CLASS dwAclInformationClass) 2475 { 2476 NTSTATUS Status; 2477 2478 Status = RtlSetInformationAcl(pAcl, 2479 pAclInformation, 2480 nAclInformationLength, 2481 dwAclInformationClass); 2482 if (!NT_SUCCESS(Status)) 2483 { 2484 SetLastError(RtlNtStatusToDosError(Status)); 2485 return FALSE; 2486 } 2487 2488 return TRUE; 2489 } 2490 2491 /********************************************************************** 2492 * SetNamedSecurityInfoA EXPORTED 2493 * 2494 * @implemented 2495 */ 2496 DWORD 2497 WINAPI 2498 SetNamedSecurityInfoA(LPSTR pObjectName, 2499 SE_OBJECT_TYPE ObjectType, 2500 SECURITY_INFORMATION SecurityInfo, 2501 PSID psidOwner, 2502 PSID psidGroup, 2503 PACL pDacl, 2504 PACL pSacl) 2505 { 2506 UNICODE_STRING ObjectName; 2507 DWORD Ret; 2508 2509 if (!RtlCreateUnicodeStringFromAsciiz(&ObjectName, pObjectName)) 2510 { 2511 return ERROR_NOT_ENOUGH_MEMORY; 2512 } 2513 2514 Ret = SetNamedSecurityInfoW(ObjectName.Buffer, 2515 ObjectType, 2516 SecurityInfo, 2517 psidOwner, 2518 psidGroup, 2519 pDacl, 2520 pSacl); 2521 2522 RtlFreeUnicodeString(&ObjectName); 2523 2524 return Ret; 2525 } 2526 2527 /* 2528 * @implemented 2529 */ 2530 BOOL 2531 WINAPI 2532 AreAllAccessesGranted(DWORD GrantedAccess, 2533 DWORD DesiredAccess) 2534 { 2535 return (BOOL)RtlAreAllAccessesGranted(GrantedAccess, 2536 DesiredAccess); 2537 } 2538 2539 /* 2540 * @implemented 2541 */ 2542 BOOL 2543 WINAPI 2544 AreAnyAccessesGranted(DWORD GrantedAccess, 2545 DWORD DesiredAccess) 2546 { 2547 return (BOOL)RtlAreAnyAccessesGranted(GrantedAccess, 2548 DesiredAccess); 2549 } 2550 2551 /****************************************************************************** 2552 * ParseAclStringFlags 2553 */ 2554 static DWORD ParseAclStringFlags(LPCWSTR* StringAcl) 2555 { 2556 DWORD flags = 0; 2557 LPCWSTR szAcl = *StringAcl; 2558 2559 while (*szAcl && *szAcl != '(') 2560 { 2561 if (*szAcl == 'P') 2562 { 2563 flags |= SE_DACL_PROTECTED; 2564 } 2565 else if (*szAcl == 'A') 2566 { 2567 szAcl++; 2568 if (*szAcl == 'R') 2569 flags |= SE_DACL_AUTO_INHERIT_REQ; 2570 else if (*szAcl == 'I') 2571 flags |= SE_DACL_AUTO_INHERITED; 2572 } 2573 szAcl++; 2574 } 2575 2576 *StringAcl = szAcl; 2577 return flags; 2578 } 2579 2580 /****************************************************************************** 2581 * ParseAceStringType 2582 */ 2583 static const ACEFLAG AceType[] = 2584 { 2585 { SDDL_ALARM, SYSTEM_ALARM_ACE_TYPE }, 2586 { SDDL_AUDIT, SYSTEM_AUDIT_ACE_TYPE }, 2587 { SDDL_ACCESS_ALLOWED, ACCESS_ALLOWED_ACE_TYPE }, 2588 { SDDL_ACCESS_DENIED, ACCESS_DENIED_ACE_TYPE }, 2589 { SDDL_MANDATORY_LABEL,SYSTEM_MANDATORY_LABEL_ACE_TYPE }, 2590 /* 2591 { SDDL_OBJECT_ACCESS_ALLOWED, ACCESS_ALLOWED_OBJECT_ACE_TYPE }, 2592 { SDDL_OBJECT_ACCESS_DENIED, ACCESS_DENIED_OBJECT_ACE_TYPE }, 2593 { SDDL_OBJECT_ALARM, SYSTEM_ALARM_OBJECT_ACE_TYPE }, 2594 { SDDL_OBJECT_AUDIT, SYSTEM_AUDIT_OBJECT_ACE_TYPE }, 2595 */ 2596 { NULL, 0 }, 2597 }; 2598 2599 static BYTE ParseAceStringType(LPCWSTR* StringAcl) 2600 { 2601 UINT len = 0; 2602 LPCWSTR szAcl = *StringAcl; 2603 const ACEFLAG *lpaf = AceType; 2604 2605 while (*szAcl == ' ') 2606 szAcl++; 2607 2608 while (lpaf->wstr && 2609 (len = strlenW(lpaf->wstr)) && 2610 strncmpW(lpaf->wstr, szAcl, len)) 2611 lpaf++; 2612 2613 if (!lpaf->wstr) 2614 return 0; 2615 2616 *StringAcl = szAcl + len; 2617 return lpaf->value; 2618 } 2619 2620 2621 /****************************************************************************** 2622 * ParseAceStringFlags 2623 */ 2624 static const ACEFLAG AceFlags[] = 2625 { 2626 { SDDL_CONTAINER_INHERIT, CONTAINER_INHERIT_ACE }, 2627 { SDDL_AUDIT_FAILURE, FAILED_ACCESS_ACE_FLAG }, 2628 { SDDL_INHERITED, INHERITED_ACE }, 2629 { SDDL_INHERIT_ONLY, INHERIT_ONLY_ACE }, 2630 { SDDL_NO_PROPAGATE, NO_PROPAGATE_INHERIT_ACE }, 2631 { SDDL_OBJECT_INHERIT, OBJECT_INHERIT_ACE }, 2632 { SDDL_AUDIT_SUCCESS, SUCCESSFUL_ACCESS_ACE_FLAG }, 2633 { NULL, 0 }, 2634 }; 2635 2636 static BYTE ParseAceStringFlags(LPCWSTR* StringAcl) 2637 { 2638 UINT len = 0; 2639 BYTE flags = 0; 2640 LPCWSTR szAcl = *StringAcl; 2641 2642 while (*szAcl == ' ') 2643 szAcl++; 2644 2645 while (*szAcl != ';') 2646 { 2647 const ACEFLAG *lpaf = AceFlags; 2648 2649 while (lpaf->wstr && 2650 (len = strlenW(lpaf->wstr)) && 2651 strncmpW(lpaf->wstr, szAcl, len)) 2652 lpaf++; 2653 2654 if (!lpaf->wstr) 2655 return 0; 2656 2657 flags |= lpaf->value; 2658 szAcl += len; 2659 } 2660 2661 *StringAcl = szAcl; 2662 return flags; 2663 } 2664 2665 2666 /****************************************************************************** 2667 * ParseAceStringRights 2668 */ 2669 static const ACEFLAG AceRights[] = 2670 { 2671 { SDDL_GENERIC_ALL, GENERIC_ALL }, 2672 { SDDL_GENERIC_READ, GENERIC_READ }, 2673 { SDDL_GENERIC_WRITE, GENERIC_WRITE }, 2674 { SDDL_GENERIC_EXECUTE, GENERIC_EXECUTE }, 2675 2676 { SDDL_READ_CONTROL, READ_CONTROL }, 2677 { SDDL_STANDARD_DELETE, DELETE }, 2678 { SDDL_WRITE_DAC, WRITE_DAC }, 2679 { SDDL_WRITE_OWNER, WRITE_OWNER }, 2680 2681 { SDDL_READ_PROPERTY, ADS_RIGHT_DS_READ_PROP}, 2682 { SDDL_WRITE_PROPERTY, ADS_RIGHT_DS_WRITE_PROP}, 2683 { SDDL_CREATE_CHILD, ADS_RIGHT_DS_CREATE_CHILD}, 2684 { SDDL_DELETE_CHILD, ADS_RIGHT_DS_DELETE_CHILD}, 2685 { SDDL_LIST_CHILDREN, ADS_RIGHT_ACTRL_DS_LIST}, 2686 { SDDL_SELF_WRITE, ADS_RIGHT_DS_SELF}, 2687 { SDDL_LIST_OBJECT, ADS_RIGHT_DS_LIST_OBJECT}, 2688 { SDDL_DELETE_TREE, ADS_RIGHT_DS_DELETE_TREE}, 2689 { SDDL_CONTROL_ACCESS, ADS_RIGHT_DS_CONTROL_ACCESS}, 2690 2691 { SDDL_FILE_ALL, FILE_ALL_ACCESS }, 2692 { SDDL_FILE_READ, FILE_GENERIC_READ }, 2693 { SDDL_FILE_WRITE, FILE_GENERIC_WRITE }, 2694 { SDDL_FILE_EXECUTE, FILE_GENERIC_EXECUTE }, 2695 2696 { SDDL_KEY_ALL, KEY_ALL_ACCESS }, 2697 { SDDL_KEY_READ, KEY_READ }, 2698 { SDDL_KEY_WRITE, KEY_WRITE }, 2699 { SDDL_KEY_EXECUTE, KEY_EXECUTE }, 2700 2701 { SDDL_NO_READ_UP, SYSTEM_MANDATORY_LABEL_NO_READ_UP }, 2702 { SDDL_NO_WRITE_UP, SYSTEM_MANDATORY_LABEL_NO_WRITE_UP }, 2703 { SDDL_NO_EXECUTE_UP, SYSTEM_MANDATORY_LABEL_NO_EXECUTE_UP }, 2704 { NULL, 0 }, 2705 }; 2706 2707 static DWORD ParseAceStringRights(LPCWSTR* StringAcl) 2708 { 2709 UINT len = 0; 2710 DWORD rights = 0; 2711 LPCWSTR szAcl = *StringAcl; 2712 2713 while (*szAcl == ' ') 2714 szAcl++; 2715 2716 if ((*szAcl == '0') && (*(szAcl + 1) == 'x')) 2717 { 2718 LPCWSTR p = szAcl; 2719 2720 while (*p && *p != ';') 2721 p++; 2722 2723 if (p - szAcl <= 10 /* 8 hex digits + "0x" */ ) 2724 { 2725 rights = strtoulW(szAcl, NULL, 16); 2726 szAcl = p; 2727 } 2728 else 2729 WARN("Invalid rights string format: %s\n", debugstr_wn(szAcl, p - szAcl)); 2730 } 2731 else 2732 { 2733 while (*szAcl != ';') 2734 { 2735 const ACEFLAG *lpaf = AceRights; 2736 2737 while (lpaf->wstr && 2738 (len = strlenW(lpaf->wstr)) && 2739 strncmpW(lpaf->wstr, szAcl, len)) 2740 { 2741 lpaf++; 2742 } 2743 2744 if (!lpaf->wstr) 2745 return 0; 2746 2747 rights |= lpaf->value; 2748 szAcl += len; 2749 } 2750 } 2751 2752 *StringAcl = szAcl; 2753 return rights; 2754 } 2755 2756 2757 /****************************************************************************** 2758 * ParseStringAclToAcl 2759 * 2760 * dacl_flags(string_ace1)(string_ace2)... (string_acen) 2761 */ 2762 static BOOL ParseStringAclToAcl(LPCWSTR StringAcl, LPDWORD lpdwFlags, 2763 PACL pAcl, LPDWORD cBytes) 2764 { 2765 DWORD val; 2766 DWORD sidlen; 2767 DWORD length = sizeof(ACL); 2768 DWORD acesize = 0; 2769 DWORD acecount = 0; 2770 PACCESS_ALLOWED_ACE pAce = NULL; /* pointer to current ACE */ 2771 DWORD error = ERROR_INVALID_ACL; 2772 2773 TRACE("%s\n", debugstr_w(StringAcl)); 2774 2775 if (!StringAcl) 2776 return FALSE; 2777 2778 if (pAcl) /* pAce is only useful if we're setting values */ 2779 pAce = (PACCESS_ALLOWED_ACE) (pAcl + 1); 2780 2781 /* Parse ACL flags */ 2782 *lpdwFlags = ParseAclStringFlags(&StringAcl); 2783 2784 /* Parse ACE */ 2785 while (*StringAcl == '(') 2786 { 2787 StringAcl++; 2788 2789 /* Parse ACE type */ 2790 val = ParseAceStringType(&StringAcl); 2791 if (pAce) 2792 pAce->Header.AceType = (BYTE) val; 2793 if (*StringAcl != ';') 2794 { 2795 error = RPC_S_INVALID_STRING_UUID; 2796 goto lerr; 2797 } 2798 StringAcl++; 2799 2800 /* Parse ACE flags */ 2801 val = ParseAceStringFlags(&StringAcl); 2802 if (pAce) 2803 pAce->Header.AceFlags = (BYTE) val; 2804 if (*StringAcl != ';') 2805 goto lerr; 2806 StringAcl++; 2807 2808 /* Parse ACE rights */ 2809 val = ParseAceStringRights(&StringAcl); 2810 if (pAce) 2811 pAce->Mask = val; 2812 if (*StringAcl != ';') 2813 goto lerr; 2814 StringAcl++; 2815 2816 /* Parse ACE object guid */ 2817 while (*StringAcl == ' ') 2818 StringAcl++; 2819 if (*StringAcl != ';') 2820 { 2821 FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n"); 2822 goto lerr; 2823 } 2824 StringAcl++; 2825 2826 /* Parse ACE inherit object guid */ 2827 while (*StringAcl == ' ') 2828 StringAcl++; 2829 if (*StringAcl != ';') 2830 { 2831 FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n"); 2832 goto lerr; 2833 } 2834 StringAcl++; 2835 2836 /* Parse ACE account sid */ 2837 if (ParseStringSidToSid(StringAcl, pAce ? &pAce->SidStart : NULL, &sidlen)) 2838 { 2839 while (*StringAcl && *StringAcl != ')') 2840 StringAcl++; 2841 } 2842 2843 if (*StringAcl != ')') 2844 goto lerr; 2845 StringAcl++; 2846 2847 acesize = sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + sidlen; 2848 length += acesize; 2849 if (pAce) 2850 { 2851 pAce->Header.AceSize = acesize; 2852 pAce = (PACCESS_ALLOWED_ACE)((LPBYTE)pAce + acesize); 2853 } 2854 acecount++; 2855 } 2856 2857 *cBytes = length; 2858 2859 if (length > 0xffff) 2860 { 2861 ERR("ACL too large\n"); 2862 goto lerr; 2863 } 2864 2865 if (pAcl) 2866 { 2867 pAcl->AclRevision = ACL_REVISION; 2868 pAcl->Sbz1 = 0; 2869 pAcl->AclSize = length; 2870 pAcl->AceCount = acecount; 2871 pAcl->Sbz2 = 0; 2872 } 2873 return TRUE; 2874 2875 lerr: 2876 SetLastError(error); 2877 WARN("Invalid ACE string format\n"); 2878 return FALSE; 2879 } 2880 2881 /****************************************************************************** 2882 * ParseStringSecurityDescriptorToSecurityDescriptor 2883 */ 2884 static BOOL ParseStringSecurityDescriptorToSecurityDescriptor( 2885 LPCWSTR StringSecurityDescriptor, 2886 SECURITY_DESCRIPTOR_RELATIVE* SecurityDescriptor, 2887 LPDWORD cBytes) 2888 { 2889 BOOL bret = FALSE; 2890 WCHAR toktype; 2891 WCHAR *tok; 2892 LPCWSTR lptoken; 2893 LPBYTE lpNext = NULL; 2894 DWORD len; 2895 2896 *cBytes = sizeof(SECURITY_DESCRIPTOR_RELATIVE); 2897 2898 tok = heap_alloc( (lstrlenW(StringSecurityDescriptor) + 1) * sizeof(WCHAR)); 2899 2900 if (SecurityDescriptor) 2901 lpNext = (LPBYTE)(SecurityDescriptor + 1); 2902 2903 while (*StringSecurityDescriptor == ' ') 2904 StringSecurityDescriptor++; 2905 2906 while (*StringSecurityDescriptor) 2907 { 2908 toktype = *StringSecurityDescriptor; 2909 2910 /* Expect char identifier followed by ':' */ 2911 StringSecurityDescriptor++; 2912 if (*StringSecurityDescriptor != ':') 2913 { 2914 SetLastError(ERROR_INVALID_PARAMETER); 2915 goto lend; 2916 } 2917 StringSecurityDescriptor++; 2918 2919 /* Extract token */ 2920 lptoken = StringSecurityDescriptor; 2921 while (*lptoken && *lptoken != ':') 2922 lptoken++; 2923 2924 if (*lptoken) 2925 lptoken--; 2926 2927 len = lptoken - StringSecurityDescriptor; 2928 memcpy( tok, StringSecurityDescriptor, len * sizeof(WCHAR) ); 2929 tok[len] = 0; 2930 2931 switch (toktype) 2932 { 2933 case 'O': 2934 { 2935 DWORD bytes; 2936 2937 if (!ParseStringSidToSid(tok, lpNext, &bytes)) 2938 goto lend; 2939 2940 if (SecurityDescriptor) 2941 { 2942 SecurityDescriptor->Owner = lpNext - (LPBYTE)SecurityDescriptor; 2943 lpNext += bytes; /* Advance to next token */ 2944 } 2945 2946 *cBytes += bytes; 2947 2948 break; 2949 } 2950 2951 case 'G': 2952 { 2953 DWORD bytes; 2954 2955 if (!ParseStringSidToSid(tok, lpNext, &bytes)) 2956 goto lend; 2957 2958 if (SecurityDescriptor) 2959 { 2960 SecurityDescriptor->Group = lpNext - (LPBYTE)SecurityDescriptor; 2961 lpNext += bytes; /* Advance to next token */ 2962 } 2963 2964 *cBytes += bytes; 2965 2966 break; 2967 } 2968 2969 case 'D': 2970 { 2971 DWORD flags; 2972 DWORD bytes; 2973 2974 if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes)) 2975 goto lend; 2976 2977 if (SecurityDescriptor) 2978 { 2979 SecurityDescriptor->Control |= SE_DACL_PRESENT | flags; 2980 SecurityDescriptor->Dacl = lpNext - (LPBYTE)SecurityDescriptor; 2981 lpNext += bytes; /* Advance to next token */ 2982 } 2983 2984 *cBytes += bytes; 2985 2986 break; 2987 } 2988 2989 case 'S': 2990 { 2991 DWORD flags; 2992 DWORD bytes; 2993 2994 if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes)) 2995 goto lend; 2996 2997 if (SecurityDescriptor) 2998 { 2999 SecurityDescriptor->Control |= SE_SACL_PRESENT | flags; 3000 SecurityDescriptor->Sacl = lpNext - (LPBYTE)SecurityDescriptor; 3001 lpNext += bytes; /* Advance to next token */ 3002 } 3003 3004 *cBytes += bytes; 3005 3006 break; 3007 } 3008 3009 default: 3010 FIXME("Unknown token\n"); 3011 SetLastError(ERROR_INVALID_PARAMETER); 3012 goto lend; 3013 } 3014 3015 StringSecurityDescriptor = lptoken; 3016 } 3017 3018 bret = TRUE; 3019 3020 lend: 3021 heap_free(tok); 3022 return bret; 3023 } 3024 3025 /* Winehq cvs 20050916 */ 3026 /****************************************************************************** 3027 * ConvertStringSecurityDescriptorToSecurityDescriptorA [ADVAPI32.@] 3028 * @implemented 3029 */ 3030 BOOL 3031 WINAPI 3032 ConvertStringSecurityDescriptorToSecurityDescriptorA(LPCSTR StringSecurityDescriptor, 3033 DWORD StringSDRevision, 3034 PSECURITY_DESCRIPTOR* SecurityDescriptor, 3035 PULONG SecurityDescriptorSize) 3036 { 3037 UINT len; 3038 BOOL ret = FALSE; 3039 LPWSTR StringSecurityDescriptorW; 3040 3041 len = MultiByteToWideChar(CP_ACP, 0, StringSecurityDescriptor, -1, NULL, 0); 3042 StringSecurityDescriptorW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); 3043 3044 if (StringSecurityDescriptorW) 3045 { 3046 MultiByteToWideChar(CP_ACP, 0, StringSecurityDescriptor, -1, StringSecurityDescriptorW, len); 3047 3048 ret = ConvertStringSecurityDescriptorToSecurityDescriptorW(StringSecurityDescriptorW, 3049 StringSDRevision, SecurityDescriptor, 3050 SecurityDescriptorSize); 3051 HeapFree(GetProcessHeap(), 0, StringSecurityDescriptorW); 3052 } 3053 3054 return ret; 3055 } 3056 3057 /****************************************************************************** 3058 * ConvertStringSecurityDescriptorToSecurityDescriptorW [ADVAPI32.@] 3059 * @implemented 3060 */ 3061 BOOL WINAPI 3062 ConvertStringSecurityDescriptorToSecurityDescriptorW(LPCWSTR StringSecurityDescriptor, 3063 DWORD StringSDRevision, 3064 PSECURITY_DESCRIPTOR* SecurityDescriptor, 3065 PULONG SecurityDescriptorSize) 3066 { 3067 DWORD cBytes; 3068 SECURITY_DESCRIPTOR* psd; 3069 BOOL bret = FALSE; 3070 3071 TRACE("%s\n", debugstr_w(StringSecurityDescriptor)); 3072 3073 if (GetVersion() & 0x80000000) 3074 { 3075 SetLastError(ERROR_CALL_NOT_IMPLEMENTED); 3076 goto lend; 3077 } 3078 else if (!StringSecurityDescriptor || !SecurityDescriptor) 3079 { 3080 SetLastError(ERROR_INVALID_PARAMETER); 3081 goto lend; 3082 } 3083 else if (StringSDRevision != SID_REVISION) 3084 { 3085 SetLastError(ERROR_UNKNOWN_REVISION); 3086 goto lend; 3087 } 3088 3089 /* Compute security descriptor length */ 3090 if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor, 3091 NULL, &cBytes)) 3092 goto lend; 3093 3094 psd = *SecurityDescriptor = LocalAlloc(GMEM_ZEROINIT, cBytes); 3095 if (!psd) goto lend; 3096 3097 psd->Revision = SID_REVISION; 3098 psd->Control |= SE_SELF_RELATIVE; 3099 3100 if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor, 3101 (SECURITY_DESCRIPTOR_RELATIVE *)psd, &cBytes)) 3102 { 3103 LocalFree(psd); 3104 goto lend; 3105 } 3106 3107 if (SecurityDescriptorSize) 3108 *SecurityDescriptorSize = cBytes; 3109 3110 bret = TRUE; 3111 3112 lend: 3113 TRACE(" ret=%d\n", bret); 3114 return bret; 3115 } 3116 3117 static void DumpString(LPCWSTR string, int cch, WCHAR **pwptr, ULONG *plen) 3118 { 3119 if (cch == -1) 3120 cch = strlenW(string); 3121 3122 if (plen) 3123 *plen += cch; 3124 3125 if (pwptr) 3126 { 3127 memcpy(*pwptr, string, sizeof(WCHAR)*cch); 3128 *pwptr += cch; 3129 } 3130 } 3131 3132 static BOOL DumpSidNumeric(PSID psid, WCHAR **pwptr, ULONG *plen) 3133 { 3134 DWORD i; 3135 WCHAR fmt[] = { 'S','-','%','u','-','%','d',0 }; 3136 WCHAR subauthfmt[] = { '-','%','u',0 }; 3137 WCHAR buf[26]; 3138 SID *pisid = psid; 3139 3140 if( !IsValidSid( psid ) || pisid->Revision != SDDL_REVISION) 3141 { 3142 SetLastError(ERROR_INVALID_SID); 3143 return FALSE; 3144 } 3145 3146 if (pisid->IdentifierAuthority.Value[0] || 3147 pisid->IdentifierAuthority.Value[1]) 3148 { 3149 FIXME("not matching MS' bugs\n"); 3150 SetLastError(ERROR_INVALID_SID); 3151 return FALSE; 3152 } 3153 3154 sprintfW( buf, fmt, pisid->Revision, 3155 MAKELONG( 3156 MAKEWORD( pisid->IdentifierAuthority.Value[5], 3157 pisid->IdentifierAuthority.Value[4] ), 3158 MAKEWORD( pisid->IdentifierAuthority.Value[3], 3159 pisid->IdentifierAuthority.Value[2] ) 3160 ) ); 3161 DumpString(buf, -1, pwptr, plen); 3162 3163 for( i=0; i<pisid->SubAuthorityCount; i++ ) 3164 { 3165 sprintfW( buf, subauthfmt, pisid->SubAuthority[i] ); 3166 DumpString(buf, -1, pwptr, plen); 3167 } 3168 return TRUE; 3169 } 3170 3171 static BOOL DumpSid(PSID psid, WCHAR **pwptr, ULONG *plen) 3172 { 3173 size_t i; 3174 for (i = 0; i < sizeof(WellKnownSids) / sizeof(WellKnownSids[0]); i++) 3175 { 3176 if (WellKnownSids[i].wstr[0] && EqualSid(psid, (PSID)&(WellKnownSids[i].Sid.Revision))) 3177 { 3178 DumpString(WellKnownSids[i].wstr, 2, pwptr, plen); 3179 return TRUE; 3180 } 3181 } 3182 3183 return DumpSidNumeric(psid, pwptr, plen); 3184 } 3185 3186 static const LPCWSTR AceRightBitNames[32] = { 3187 SDDL_CREATE_CHILD, /* 0 */ 3188 SDDL_DELETE_CHILD, 3189 SDDL_LIST_CHILDREN, 3190 SDDL_SELF_WRITE, 3191 SDDL_READ_PROPERTY, /* 4 */ 3192 SDDL_WRITE_PROPERTY, 3193 SDDL_DELETE_TREE, 3194 SDDL_LIST_OBJECT, 3195 SDDL_CONTROL_ACCESS, /* 8 */ 3196 NULL, 3197 NULL, 3198 NULL, 3199 NULL, /* 12 */ 3200 NULL, 3201 NULL, 3202 NULL, 3203 SDDL_STANDARD_DELETE, /* 16 */ 3204 SDDL_READ_CONTROL, 3205 SDDL_WRITE_DAC, 3206 SDDL_WRITE_OWNER, 3207 NULL, /* 20 */ 3208 NULL, 3209 NULL, 3210 NULL, 3211 NULL, /* 24 */ 3212 NULL, 3213 NULL, 3214 NULL, 3215 SDDL_GENERIC_ALL, /* 28 */ 3216 SDDL_GENERIC_EXECUTE, 3217 SDDL_GENERIC_WRITE, 3218 SDDL_GENERIC_READ 3219 }; 3220 3221 static void DumpRights(DWORD mask, WCHAR **pwptr, ULONG *plen) 3222 { 3223 static const WCHAR fmtW[] = {'0','x','%','x',0}; 3224 WCHAR buf[15]; 3225 size_t i; 3226 3227 if (mask == 0) 3228 return; 3229 3230 /* first check if the right have name */ 3231 for (i = 0; i < sizeof(AceRights)/sizeof(AceRights[0]); i++) 3232 { 3233 if (AceRights[i].wstr == NULL) 3234 break; 3235 if (mask == AceRights[i].value) 3236 { 3237 DumpString(AceRights[i].wstr, -1, pwptr, plen); 3238 return; 3239 } 3240 } 3241 3242 /* then check if it can be built from bit names */ 3243 for (i = 0; i < 32; i++) 3244 { 3245 if ((mask & (1 << i)) && (AceRightBitNames[i] == NULL)) 3246 { 3247 /* can't be built from bit names */ 3248 sprintfW(buf, fmtW, mask); 3249 DumpString(buf, -1, pwptr, plen); 3250 return; 3251 } 3252 } 3253 3254 /* build from bit names */ 3255 for (i = 0; i < 32; i++) 3256 if (mask & (1 << i)) 3257 DumpString(AceRightBitNames[i], -1, pwptr, plen); 3258 } 3259 3260 static BOOL DumpAce(LPVOID pace, WCHAR **pwptr, ULONG *plen) 3261 { 3262 ACCESS_ALLOWED_ACE *piace; /* all the supported ACEs have the same memory layout */ 3263 static const WCHAR openbr = '('; 3264 static const WCHAR closebr = ')'; 3265 static const WCHAR semicolon = ';'; 3266 3267 if (((PACE_HEADER)pace)->AceType > SYSTEM_ALARM_ACE_TYPE || ((PACE_HEADER)pace)->AceSize < sizeof(ACCESS_ALLOWED_ACE)) 3268 { 3269 SetLastError(ERROR_INVALID_ACL); 3270 return FALSE; 3271 } 3272 3273 piace = pace; 3274 DumpString(&openbr, 1, pwptr, plen); 3275 switch (piace->Header.AceType) 3276 { 3277 case ACCESS_ALLOWED_ACE_TYPE: 3278 DumpString(SDDL_ACCESS_ALLOWED, -1, pwptr, plen); 3279 break; 3280 case ACCESS_DENIED_ACE_TYPE: 3281 DumpString(SDDL_ACCESS_DENIED, -1, pwptr, plen); 3282 break; 3283 case SYSTEM_AUDIT_ACE_TYPE: 3284 DumpString(SDDL_AUDIT, -1, pwptr, plen); 3285 break; 3286 case SYSTEM_ALARM_ACE_TYPE: 3287 DumpString(SDDL_ALARM, -1, pwptr, plen); 3288 break; 3289 } 3290 DumpString(&semicolon, 1, pwptr, plen); 3291 3292 if (piace->Header.AceFlags & OBJECT_INHERIT_ACE) 3293 DumpString(SDDL_OBJECT_INHERIT, -1, pwptr, plen); 3294 if (piace->Header.AceFlags & CONTAINER_INHERIT_ACE) 3295 DumpString(SDDL_CONTAINER_INHERIT, -1, pwptr, plen); 3296 if (piace->Header.AceFlags & NO_PROPAGATE_INHERIT_ACE) 3297 DumpString(SDDL_NO_PROPAGATE, -1, pwptr, plen); 3298 if (piace->Header.AceFlags & INHERIT_ONLY_ACE) 3299 DumpString(SDDL_INHERIT_ONLY, -1, pwptr, plen); 3300 if (piace->Header.AceFlags & INHERITED_ACE) 3301 DumpString(SDDL_INHERITED, -1, pwptr, plen); 3302 if (piace->Header.AceFlags & SUCCESSFUL_ACCESS_ACE_FLAG) 3303 DumpString(SDDL_AUDIT_SUCCESS, -1, pwptr, plen); 3304 if (piace->Header.AceFlags & FAILED_ACCESS_ACE_FLAG) 3305 DumpString(SDDL_AUDIT_FAILURE, -1, pwptr, plen); 3306 DumpString(&semicolon, 1, pwptr, plen); 3307 DumpRights(piace->Mask, pwptr, plen); 3308 DumpString(&semicolon, 1, pwptr, plen); 3309 /* objects not supported */ 3310 DumpString(&semicolon, 1, pwptr, plen); 3311 /* objects not supported */ 3312 DumpString(&semicolon, 1, pwptr, plen); 3313 if (!DumpSid((PSID)&piace->SidStart, pwptr, plen)) 3314 return FALSE; 3315 DumpString(&closebr, 1, pwptr, plen); 3316 return TRUE; 3317 } 3318 3319 static BOOL DumpAcl(PACL pacl, WCHAR **pwptr, ULONG *plen, BOOL protected, BOOL autoInheritReq, BOOL autoInherited) 3320 { 3321 WORD count; 3322 int i; 3323 3324 if (protected) 3325 DumpString(SDDL_PROTECTED, -1, pwptr, plen); 3326 if (autoInheritReq) 3327 DumpString(SDDL_AUTO_INHERIT_REQ, -1, pwptr, plen); 3328 if (autoInherited) 3329 DumpString(SDDL_AUTO_INHERITED, -1, pwptr, plen); 3330 3331 if (pacl == NULL) 3332 return TRUE; 3333 3334 if (!IsValidAcl(pacl)) 3335 return FALSE; 3336 3337 count = pacl->AceCount; 3338 for (i = 0; i < count; i++) 3339 { 3340 LPVOID ace; 3341 if (!GetAce(pacl, i, &ace)) 3342 return FALSE; 3343 if (!DumpAce(ace, pwptr, plen)) 3344 return FALSE; 3345 } 3346 3347 return TRUE; 3348 } 3349 3350 static BOOL DumpOwner(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen) 3351 { 3352 static const WCHAR prefix[] = {'O',':',0}; 3353 BOOL bDefaulted; 3354 PSID psid; 3355 3356 if (!GetSecurityDescriptorOwner(SecurityDescriptor, &psid, &bDefaulted)) 3357 return FALSE; 3358 3359 if (psid == NULL) 3360 return TRUE; 3361 3362 DumpString(prefix, -1, pwptr, plen); 3363 if (!DumpSid(psid, pwptr, plen)) 3364 return FALSE; 3365 return TRUE; 3366 } 3367 3368 static BOOL DumpGroup(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen) 3369 { 3370 static const WCHAR prefix[] = {'G',':',0}; 3371 BOOL bDefaulted; 3372 PSID psid; 3373 3374 if (!GetSecurityDescriptorGroup(SecurityDescriptor, &psid, &bDefaulted)) 3375 return FALSE; 3376 3377 if (psid == NULL) 3378 return TRUE; 3379 3380 DumpString(prefix, -1, pwptr, plen); 3381 if (!DumpSid(psid, pwptr, plen)) 3382 return FALSE; 3383 return TRUE; 3384 } 3385 3386 static BOOL DumpDacl(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen) 3387 { 3388 static const WCHAR dacl[] = {'D',':',0}; 3389 SECURITY_DESCRIPTOR_CONTROL control; 3390 BOOL present, defaulted; 3391 DWORD revision; 3392 PACL pacl; 3393 3394 if (!GetSecurityDescriptorDacl(SecurityDescriptor, &present, &pacl, &defaulted)) 3395 return FALSE; 3396 3397 if (!GetSecurityDescriptorControl(SecurityDescriptor, &control, &revision)) 3398 return FALSE; 3399 3400 if (!present) 3401 return TRUE; 3402 3403 DumpString(dacl, 2, pwptr, plen); 3404 if (!DumpAcl(pacl, pwptr, plen, control & SE_DACL_PROTECTED, control & SE_DACL_AUTO_INHERIT_REQ, control & SE_DACL_AUTO_INHERITED)) 3405 return FALSE; 3406 return TRUE; 3407 } 3408 3409 static BOOL DumpSacl(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen) 3410 { 3411 static const WCHAR sacl[] = {'S',':',0}; 3412 SECURITY_DESCRIPTOR_CONTROL control; 3413 BOOL present, defaulted; 3414 DWORD revision; 3415 PACL pacl; 3416 3417 if (!GetSecurityDescriptorSacl(SecurityDescriptor, &present, &pacl, &defaulted)) 3418 return FALSE; 3419 3420 if (!GetSecurityDescriptorControl(SecurityDescriptor, &control, &revision)) 3421 return FALSE; 3422 3423 if (!present) 3424 return TRUE; 3425 3426 DumpString(sacl, 2, pwptr, plen); 3427 if (!DumpAcl(pacl, pwptr, plen, control & SE_SACL_PROTECTED, control & SE_SACL_AUTO_INHERIT_REQ, control & SE_SACL_AUTO_INHERITED)) 3428 return FALSE; 3429 return TRUE; 3430 } 3431 3432 /****************************************************************************** 3433 * ConvertSecurityDescriptorToStringSecurityDescriptorW [ADVAPI32.@] 3434 */ 3435 BOOL WINAPI ConvertSecurityDescriptorToStringSecurityDescriptorW(PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD SDRevision, SECURITY_INFORMATION RequestedInformation, LPWSTR *OutputString, PULONG OutputLen) 3436 { 3437 ULONG len; 3438 WCHAR *wptr, *wstr; 3439 3440 if (SDRevision != SDDL_REVISION_1) 3441 { 3442 ERR("Program requested unknown SDDL revision %d\n", SDRevision); 3443 SetLastError(ERROR_UNKNOWN_REVISION); 3444 return FALSE; 3445 } 3446 3447 len = 0; 3448 if (RequestedInformation & OWNER_SECURITY_INFORMATION) 3449 if (!DumpOwner(SecurityDescriptor, NULL, &len)) 3450 return FALSE; 3451 if (RequestedInformation & GROUP_SECURITY_INFORMATION) 3452 if (!DumpGroup(SecurityDescriptor, NULL, &len)) 3453 return FALSE; 3454 if (RequestedInformation & DACL_SECURITY_INFORMATION) 3455 if (!DumpDacl(SecurityDescriptor, NULL, &len)) 3456 return FALSE; 3457 if (RequestedInformation & SACL_SECURITY_INFORMATION) 3458 if (!DumpSacl(SecurityDescriptor, NULL, &len)) 3459 return FALSE; 3460 3461 wstr = wptr = LocalAlloc(0, (len + 1)*sizeof(WCHAR)); 3462 #ifdef __REACTOS__ 3463 if (wstr == NULL) 3464 return FALSE; 3465 #endif 3466 3467 if (RequestedInformation & OWNER_SECURITY_INFORMATION) 3468 if (!DumpOwner(SecurityDescriptor, &wptr, NULL)) { 3469 LocalFree (wstr); 3470 return FALSE; 3471 } 3472 if (RequestedInformation & GROUP_SECURITY_INFORMATION) 3473 if (!DumpGroup(SecurityDescriptor, &wptr, NULL)) { 3474 LocalFree (wstr); 3475 return FALSE; 3476 } 3477 if (RequestedInformation & DACL_SECURITY_INFORMATION) 3478 if (!DumpDacl(SecurityDescriptor, &wptr, NULL)) { 3479 LocalFree (wstr); 3480 return FALSE; 3481 } 3482 if (RequestedInformation & SACL_SECURITY_INFORMATION) 3483 if (!DumpSacl(SecurityDescriptor, &wptr, NULL)) { 3484 LocalFree (wstr); 3485 return FALSE; 3486 } 3487 *wptr = 0; 3488 3489 TRACE("ret: %s, %d\n", wine_dbgstr_w(wstr), len); 3490 *OutputString = wstr; 3491 if (OutputLen) 3492 *OutputLen = strlenW(*OutputString)+1; 3493 return TRUE; 3494 } 3495 3496 /****************************************************************************** 3497 * ConvertSecurityDescriptorToStringSecurityDescriptorA [ADVAPI32.@] 3498 */ 3499 BOOL WINAPI ConvertSecurityDescriptorToStringSecurityDescriptorA(PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD SDRevision, SECURITY_INFORMATION Information, LPSTR *OutputString, PULONG OutputLen) 3500 { 3501 LPWSTR wstr; 3502 ULONG len; 3503 if (ConvertSecurityDescriptorToStringSecurityDescriptorW(SecurityDescriptor, SDRevision, Information, &wstr, &len)) 3504 { 3505 int lenA; 3506 3507 lenA = WideCharToMultiByte(CP_ACP, 0, wstr, len, NULL, 0, NULL, NULL); 3508 *OutputString = heap_alloc(lenA); 3509 #ifdef __REACTOS__ 3510 if (*OutputString == NULL) 3511 { 3512 LocalFree(wstr); 3513 *OutputLen = 0; 3514 return FALSE; 3515 } 3516 #endif 3517 WideCharToMultiByte(CP_ACP, 0, wstr, len, *OutputString, lenA, NULL, NULL); 3518 LocalFree(wstr); 3519 3520 if (OutputLen != NULL) 3521 *OutputLen = lenA; 3522 return TRUE; 3523 } 3524 else 3525 { 3526 *OutputString = NULL; 3527 if (OutputLen) 3528 *OutputLen = 0; 3529 return FALSE; 3530 } 3531 } 3532 3533 /****************************************************************************** 3534 * ConvertStringSidToSidW [ADVAPI32.@] 3535 */ 3536 BOOL WINAPI ConvertStringSidToSidW(LPCWSTR StringSid, PSID* Sid) 3537 { 3538 BOOL bret = FALSE; 3539 DWORD cBytes; 3540 3541 TRACE("%s, %p\n", debugstr_w(StringSid), Sid); 3542 if (GetVersion() & 0x80000000) 3543 SetLastError(ERROR_CALL_NOT_IMPLEMENTED); 3544 else if (!StringSid || !Sid) 3545 SetLastError(ERROR_INVALID_PARAMETER); 3546 else if (ParseStringSidToSid(StringSid, NULL, &cBytes)) 3547 { 3548 PSID pSid = *Sid = LocalAlloc(0, cBytes); 3549 3550 bret = ParseStringSidToSid(StringSid, pSid, &cBytes); 3551 if (!bret) 3552 LocalFree(*Sid); 3553 } 3554 return bret; 3555 } 3556 3557 /****************************************************************************** 3558 * ConvertStringSidToSidA [ADVAPI32.@] 3559 */ 3560 BOOL WINAPI ConvertStringSidToSidA(LPCSTR StringSid, PSID* Sid) 3561 { 3562 BOOL bret = FALSE; 3563 3564 TRACE("%s, %p\n", debugstr_a(StringSid), Sid); 3565 if (GetVersion() & 0x80000000) 3566 SetLastError(ERROR_CALL_NOT_IMPLEMENTED); 3567 else if (!StringSid || !Sid) 3568 SetLastError(ERROR_INVALID_PARAMETER); 3569 else 3570 { 3571 WCHAR *wStringSid = SERV_dup(StringSid); 3572 bret = ConvertStringSidToSidW(wStringSid, Sid); 3573 heap_free(wStringSid); 3574 } 3575 return bret; 3576 } 3577 3578 /* 3579 * @implemented 3580 */ 3581 BOOL 3582 WINAPI 3583 ConvertSidToStringSidW(PSID Sid, 3584 LPWSTR *StringSid) 3585 { 3586 NTSTATUS Status; 3587 UNICODE_STRING UnicodeString; 3588 WCHAR FixedBuffer[64]; 3589 3590 if (!RtlValidSid(Sid)) 3591 { 3592 SetLastError(ERROR_INVALID_SID); 3593 return FALSE; 3594 } 3595 3596 UnicodeString.Length = 0; 3597 UnicodeString.MaximumLength = sizeof(FixedBuffer); 3598 UnicodeString.Buffer = FixedBuffer; 3599 Status = RtlConvertSidToUnicodeString(&UnicodeString, Sid, FALSE); 3600 if (STATUS_BUFFER_TOO_SMALL == Status) 3601 { 3602 Status = RtlConvertSidToUnicodeString(&UnicodeString, Sid, TRUE); 3603 } 3604 3605 if (!NT_SUCCESS(Status)) 3606 { 3607 SetLastError(RtlNtStatusToDosError(Status)); 3608 return FALSE; 3609 } 3610 3611 *StringSid = LocalAlloc(LMEM_FIXED, UnicodeString.Length + sizeof(WCHAR)); 3612 if (NULL == *StringSid) 3613 { 3614 if (UnicodeString.Buffer != FixedBuffer) 3615 { 3616 RtlFreeUnicodeString(&UnicodeString); 3617 } 3618 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 3619 return FALSE; 3620 } 3621 3622 MoveMemory(*StringSid, UnicodeString.Buffer, UnicodeString.Length); 3623 ZeroMemory((PCHAR) *StringSid + UnicodeString.Length, sizeof(WCHAR)); 3624 if (UnicodeString.Buffer != FixedBuffer) 3625 { 3626 RtlFreeUnicodeString(&UnicodeString); 3627 } 3628 3629 return TRUE; 3630 } 3631 3632 /* 3633 * @implemented 3634 */ 3635 BOOL 3636 WINAPI 3637 ConvertSidToStringSidA(PSID Sid, 3638 LPSTR *StringSid) 3639 { 3640 LPWSTR StringSidW; 3641 int Len; 3642 3643 if (!ConvertSidToStringSidW(Sid, &StringSidW)) 3644 { 3645 return FALSE; 3646 } 3647 3648 Len = WideCharToMultiByte(CP_ACP, 0, StringSidW, -1, NULL, 0, NULL, NULL); 3649 if (Len <= 0) 3650 { 3651 LocalFree(StringSidW); 3652 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 3653 return FALSE; 3654 } 3655 3656 *StringSid = LocalAlloc(LMEM_FIXED, Len); 3657 if (NULL == *StringSid) 3658 { 3659 LocalFree(StringSidW); 3660 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 3661 return FALSE; 3662 } 3663 3664 if (!WideCharToMultiByte(CP_ACP, 0, StringSidW, -1, *StringSid, Len, NULL, NULL)) 3665 { 3666 LocalFree(StringSid); 3667 LocalFree(StringSidW); 3668 return FALSE; 3669 } 3670 3671 LocalFree(StringSidW); 3672 3673 return TRUE; 3674 } 3675 3676 3677 static 3678 DWORD 3679 GetUnicodeEnvironmentSize( 3680 PVOID pEnvironment) 3681 { 3682 INT Length, TotalLength = 0; 3683 PWCHAR Ptr; 3684 3685 if (pEnvironment == NULL) 3686 return 0; 3687 3688 Ptr = (PWCHAR)pEnvironment; 3689 while (*Ptr != UNICODE_NULL) 3690 { 3691 Length = wcslen(Ptr) + 1; 3692 TotalLength += Length; 3693 Ptr = Ptr + Length; 3694 } 3695 3696 return (TotalLength + 1) * sizeof(WCHAR); 3697 } 3698 3699 3700 static 3701 DWORD 3702 GetAnsiEnvironmentSize( 3703 PVOID pEnvironment) 3704 { 3705 INT Length, TotalLength = 0; 3706 PCHAR Ptr; 3707 3708 if (pEnvironment == NULL) 3709 return 0; 3710 3711 Ptr = (PCHAR)pEnvironment; 3712 while (*Ptr != ANSI_NULL) 3713 { 3714 Length = strlen(Ptr) + 1; 3715 TotalLength += Length; 3716 Ptr = Ptr + Length; 3717 } 3718 3719 return TotalLength + 1; 3720 } 3721 3722 3723 /* 3724 * @unimplemented 3725 */ 3726 BOOL 3727 WINAPI 3728 CreateProcessWithLogonW( 3729 _In_ LPCWSTR lpUsername, 3730 _In_opt_ LPCWSTR lpDomain, 3731 _In_ LPCWSTR lpPassword, 3732 _In_ DWORD dwLogonFlags, 3733 _In_opt_ LPCWSTR lpApplicationName, 3734 _Inout_opt_ LPWSTR lpCommandLine, 3735 _In_ DWORD dwCreationFlags, 3736 _In_opt_ LPVOID lpEnvironment, 3737 _In_opt_ LPCWSTR lpCurrentDirectory, 3738 _In_ LPSTARTUPINFOW lpStartupInfo, 3739 _Out_ LPPROCESS_INFORMATION lpProcessInformation) 3740 { 3741 LPWSTR pszStringBinding = NULL; 3742 handle_t hBinding = NULL; 3743 SECL_REQUEST Request; 3744 SECL_RESPONSE Response; 3745 RPC_STATUS Status; 3746 3747 TRACE("CreateProcessWithLogonW(%s %s %s 0x%08x %s %s 0x%08x %p %s %p %p)\n", debugstr_w(lpUsername), debugstr_w(lpDomain), 3748 debugstr_w(lpPassword), dwLogonFlags, debugstr_w(lpApplicationName), 3749 debugstr_w(lpCommandLine), dwCreationFlags, lpEnvironment, debugstr_w(lpCurrentDirectory), 3750 lpStartupInfo, lpProcessInformation); 3751 3752 Status = RpcStringBindingComposeW(NULL, 3753 L"ncacn_np", 3754 NULL, 3755 L"\\pipe\\seclogon", 3756 NULL, 3757 &pszStringBinding); 3758 if (Status != RPC_S_OK) 3759 { 3760 WARN("RpcStringBindingCompose returned 0x%x\n", Status); 3761 SetLastError(Status); 3762 return FALSE; 3763 } 3764 3765 /* Set the binding handle that will be used to bind to the server. */ 3766 Status = RpcBindingFromStringBindingW(pszStringBinding, 3767 &hBinding); 3768 if (Status != RPC_S_OK) 3769 { 3770 WARN("RpcBindingFromStringBinding returned 0x%x\n", Status); 3771 } 3772 3773 Status = RpcStringFreeW(&pszStringBinding); 3774 if (Status != RPC_S_OK) 3775 { 3776 WARN("RpcStringFree returned 0x%x\n", Status); 3777 } 3778 3779 Request.Username = (LPWSTR)lpUsername; 3780 Request.Domain = (LPWSTR)lpDomain; 3781 Request.Password = (LPWSTR)lpPassword; 3782 Request.ApplicationName = (LPWSTR)lpApplicationName; 3783 Request.CommandLine = (LPWSTR)lpCommandLine; 3784 Request.CurrentDirectory = (LPWSTR)lpCurrentDirectory; 3785 3786 if (dwCreationFlags & CREATE_UNICODE_ENVIRONMENT) 3787 Request.dwEnvironmentSize = GetUnicodeEnvironmentSize(lpEnvironment); 3788 else 3789 Request.dwEnvironmentSize = GetAnsiEnvironmentSize(lpEnvironment); 3790 Request.Environment = lpEnvironment; 3791 3792 TRACE("Request.dwEnvironmentSize %lu\n", Request.dwEnvironmentSize); 3793 TRACE("Request.Environment %p\n", Request.Environment); 3794 3795 Request.dwLogonFlags = dwLogonFlags; 3796 Request.dwCreationFlags = dwCreationFlags; 3797 3798 Request.dwProcessId = GetCurrentProcessId(); 3799 TRACE("Request.dwProcessId %lu\n", Request.dwProcessId); 3800 3801 Response.hProcess = 0; 3802 Response.hThread = 0; 3803 Response.dwProcessId = 0; 3804 Response.dwThreadId = 0; 3805 Response.dwError = ERROR_SUCCESS; 3806 3807 RpcTryExcept 3808 { 3809 SeclCreateProcessWithLogonW(hBinding, &Request, &Response); 3810 } 3811 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 3812 { 3813 WARN("Exception: %lx\n", RpcExceptionCode()); 3814 } 3815 RpcEndExcept; 3816 3817 if (hBinding) 3818 { 3819 Status = RpcBindingFree(&hBinding); 3820 if (Status != RPC_S_OK) 3821 { 3822 WARN("RpcBindingFree returned 0x%x\n", Status); 3823 } 3824 3825 hBinding = NULL; 3826 } 3827 3828 TRACE("Response.hProcess %p\n", Response.hProcess); 3829 TRACE("Response.hThread %p\n", Response.hThread); 3830 TRACE("Response.dwProcessId %lu\n", Response.dwProcessId); 3831 TRACE("Response.dwThreadId %lu\n", Response.dwThreadId); 3832 TRACE("Response.dwError %lu\n", Response.dwError); 3833 if (Response.dwError != ERROR_SUCCESS) 3834 SetLastError(Response.dwError); 3835 3836 TRACE("CreateProcessWithLogonW() done\n"); 3837 3838 return (Response.dwError == ERROR_SUCCESS); 3839 } 3840 3841 BOOL WINAPI CreateProcessWithTokenW(HANDLE token, DWORD logon_flags, LPCWSTR application_name, LPWSTR command_line, 3842 DWORD creation_flags, void *environment, LPCWSTR current_directory, STARTUPINFOW *startup_info, 3843 PROCESS_INFORMATION *process_information ) 3844 { 3845 FIXME("%p 0x%08x %s %s 0x%08x %p %s %p %p - semi-stub\n", token, 3846 logon_flags, debugstr_w(application_name), debugstr_w(command_line), 3847 creation_flags, environment, debugstr_w(current_directory), 3848 startup_info, process_information); 3849 3850 /* FIXME: check if handles should be inherited */ 3851 return CreateProcessW( application_name, command_line, NULL, NULL, FALSE, creation_flags, environment, 3852 current_directory, startup_info, process_information ); 3853 } 3854 3855 /* 3856 * @implemented 3857 */ 3858 BOOL WINAPI 3859 DuplicateTokenEx(IN HANDLE ExistingTokenHandle, 3860 IN DWORD dwDesiredAccess, 3861 IN LPSECURITY_ATTRIBUTES lpTokenAttributes OPTIONAL, 3862 IN SECURITY_IMPERSONATION_LEVEL ImpersonationLevel, 3863 IN TOKEN_TYPE TokenType, 3864 OUT PHANDLE DuplicateTokenHandle) 3865 { 3866 OBJECT_ATTRIBUTES ObjectAttributes; 3867 NTSTATUS Status; 3868 SECURITY_QUALITY_OF_SERVICE Sqos; 3869 3870 TRACE("%p 0x%08x 0x%08x 0x%08x %p\n", ExistingTokenHandle, dwDesiredAccess, 3871 ImpersonationLevel, TokenType, DuplicateTokenHandle); 3872 3873 Sqos.Length = sizeof(SECURITY_QUALITY_OF_SERVICE); 3874 Sqos.ImpersonationLevel = ImpersonationLevel; 3875 Sqos.ContextTrackingMode = 0; 3876 Sqos.EffectiveOnly = FALSE; 3877 3878 if (lpTokenAttributes != NULL) 3879 { 3880 InitializeObjectAttributes(&ObjectAttributes, 3881 NULL, 3882 lpTokenAttributes->bInheritHandle ? OBJ_INHERIT : 0, 3883 NULL, 3884 lpTokenAttributes->lpSecurityDescriptor); 3885 } 3886 else 3887 { 3888 InitializeObjectAttributes(&ObjectAttributes, 3889 NULL, 3890 0, 3891 NULL, 3892 NULL); 3893 } 3894 3895 ObjectAttributes.SecurityQualityOfService = &Sqos; 3896 3897 Status = NtDuplicateToken(ExistingTokenHandle, 3898 dwDesiredAccess, 3899 &ObjectAttributes, 3900 FALSE, 3901 TokenType, 3902 DuplicateTokenHandle); 3903 if (!NT_SUCCESS(Status)) 3904 { 3905 ERR("NtDuplicateToken failed: Status %08x\n", Status); 3906 SetLastError(RtlNtStatusToDosError(Status)); 3907 return FALSE; 3908 } 3909 3910 TRACE("Returning token %p.\n", *DuplicateTokenHandle); 3911 3912 return TRUE; 3913 } 3914 3915 /* 3916 * @implemented 3917 */ 3918 BOOL WINAPI 3919 DuplicateToken(IN HANDLE ExistingTokenHandle, 3920 IN SECURITY_IMPERSONATION_LEVEL ImpersonationLevel, 3921 OUT PHANDLE DuplicateTokenHandle) 3922 { 3923 return DuplicateTokenEx(ExistingTokenHandle, 3924 TOKEN_IMPERSONATE | TOKEN_QUERY, 3925 NULL, 3926 ImpersonationLevel, 3927 TokenImpersonation, 3928 DuplicateTokenHandle); 3929 } 3930 3931 /****************************************************************************** 3932 * ComputeStringSidSize 3933 */ 3934 static DWORD ComputeStringSidSize(LPCWSTR StringSid) 3935 { 3936 if (StringSid[0] == 'S' && StringSid[1] == '-') /* S-R-I(-S)+ */ 3937 { 3938 int ctok = 0; 3939 while (*StringSid) 3940 { 3941 if (*StringSid == '-') 3942 ctok++; 3943 StringSid++; 3944 } 3945 3946 if (ctok >= 3) 3947 return GetSidLengthRequired(ctok - 2); 3948 } 3949 else /* String constant format - Only available in winxp and above */ 3950 { 3951 unsigned int i; 3952 3953 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++) 3954 if (!strncmpW(WellKnownSids[i].wstr, StringSid, 2)) 3955 return GetSidLengthRequired(WellKnownSids[i].Sid.SubAuthorityCount); 3956 3957 for (i = 0; i < sizeof(WellKnownRids)/sizeof(WellKnownRids[0]); i++) 3958 if (!strncmpW(WellKnownRids[i].wstr, StringSid, 2)) 3959 { 3960 MAX_SID local; 3961 ADVAPI_GetComputerSid(&local); 3962 return GetSidLengthRequired(*GetSidSubAuthorityCount(&local) + 1); 3963 } 3964 3965 } 3966 3967 return GetSidLengthRequired(0); 3968 } 3969 3970 /****************************************************************************** 3971 * ParseStringSidToSid 3972 */ 3973 static BOOL ParseStringSidToSid(LPCWSTR StringSid, PSID pSid, LPDWORD cBytes) 3974 { 3975 BOOL bret = FALSE; 3976 SID* pisid=pSid; 3977 3978 TRACE("%s, %p, %p\n", debugstr_w(StringSid), pSid, cBytes); 3979 if (!StringSid) 3980 { 3981 SetLastError(ERROR_INVALID_PARAMETER); 3982 TRACE("StringSid is NULL, returning FALSE\n"); 3983 return FALSE; 3984 } 3985 3986 while (*StringSid == ' ') 3987 StringSid++; 3988 3989 if (!*StringSid) 3990 goto lend; /* ERROR_INVALID_SID */ 3991 3992 *cBytes = ComputeStringSidSize(StringSid); 3993 if (!pisid) /* Simply compute the size */ 3994 { 3995 TRACE("only size requested, returning TRUE with %d\n", *cBytes); 3996 return TRUE; 3997 } 3998 3999 if (StringSid[0] == 'S' && StringSid[1] == '-') /* S-R-I-S-S */ 4000 { 4001 DWORD i = 0, identAuth; 4002 DWORD csubauth = ((*cBytes - GetSidLengthRequired(0)) / sizeof(DWORD)); 4003 4004 StringSid += 2; /* Advance to Revision */ 4005 pisid->Revision = atoiW(StringSid); 4006 4007 if (pisid->Revision != SDDL_REVISION) 4008 { 4009 TRACE("Revision %d is unknown\n", pisid->Revision); 4010 goto lend; /* ERROR_INVALID_SID */ 4011 } 4012 if (csubauth == 0) 4013 { 4014 TRACE("SubAuthorityCount is 0\n"); 4015 goto lend; /* ERROR_INVALID_SID */ 4016 } 4017 4018 pisid->SubAuthorityCount = csubauth; 4019 4020 /* Advance to identifier authority */ 4021 while (*StringSid && *StringSid != '-') 4022 StringSid++; 4023 if (*StringSid == '-') 4024 StringSid++; 4025 4026 /* MS' implementation can't handle values greater than 2^32 - 1, so 4027 * we don't either; assume most significant bytes are always 0 4028 */ 4029 pisid->IdentifierAuthority.Value[0] = 0; 4030 pisid->IdentifierAuthority.Value[1] = 0; 4031 identAuth = atoiW(StringSid); 4032 pisid->IdentifierAuthority.Value[5] = identAuth & 0xff; 4033 pisid->IdentifierAuthority.Value[4] = (identAuth & 0xff00) >> 8; 4034 pisid->IdentifierAuthority.Value[3] = (identAuth & 0xff0000) >> 16; 4035 pisid->IdentifierAuthority.Value[2] = (identAuth & 0xff000000) >> 24; 4036 4037 /* Advance to first sub authority */ 4038 while (*StringSid && *StringSid != '-') 4039 StringSid++; 4040 if (*StringSid == '-') 4041 StringSid++; 4042 4043 while (*StringSid) 4044 { 4045 pisid->SubAuthority[i++] = atoiW(StringSid); 4046 4047 while (*StringSid && *StringSid != '-') 4048 StringSid++; 4049 if (*StringSid == '-') 4050 StringSid++; 4051 } 4052 4053 if (i != pisid->SubAuthorityCount) 4054 goto lend; /* ERROR_INVALID_SID */ 4055 4056 bret = TRUE; 4057 } 4058 else /* String constant format - Only available in winxp and above */ 4059 { 4060 unsigned int i; 4061 pisid->Revision = SDDL_REVISION; 4062 4063 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++) 4064 if (!strncmpW(WellKnownSids[i].wstr, StringSid, 2)) 4065 { 4066 DWORD j; 4067 pisid->SubAuthorityCount = WellKnownSids[i].Sid.SubAuthorityCount; 4068 pisid->IdentifierAuthority = WellKnownSids[i].Sid.IdentifierAuthority; 4069 for (j = 0; j < WellKnownSids[i].Sid.SubAuthorityCount; j++) 4070 pisid->SubAuthority[j] = WellKnownSids[i].Sid.SubAuthority[j]; 4071 bret = TRUE; 4072 } 4073 4074 for (i = 0; i < sizeof(WellKnownRids)/sizeof(WellKnownRids[0]); i++) 4075 if (!strncmpW(WellKnownRids[i].wstr, StringSid, 2)) 4076 { 4077 ADVAPI_GetComputerSid(pisid); 4078 pisid->SubAuthority[pisid->SubAuthorityCount] = WellKnownRids[i].Rid; 4079 pisid->SubAuthorityCount++; 4080 bret = TRUE; 4081 } 4082 4083 if (!bret) 4084 FIXME("String constant not supported: %s\n", debugstr_wn(StringSid, 2)); 4085 } 4086 4087 lend: 4088 if (!bret) 4089 SetLastError(ERROR_INVALID_SID); 4090 4091 TRACE("returning %s\n", bret ? "TRUE" : "FALSE"); 4092 return bret; 4093 } 4094 4095 /********************************************************************** 4096 * GetNamedSecurityInfoA EXPORTED 4097 * 4098 * @implemented 4099 */ 4100 DWORD 4101 WINAPI 4102 GetNamedSecurityInfoA(LPSTR pObjectName, 4103 SE_OBJECT_TYPE ObjectType, 4104 SECURITY_INFORMATION SecurityInfo, 4105 PSID *ppsidOwner, 4106 PSID *ppsidGroup, 4107 PACL *ppDacl, 4108 PACL *ppSacl, 4109 PSECURITY_DESCRIPTOR *ppSecurityDescriptor) 4110 { 4111 DWORD len; 4112 LPWSTR wstr = NULL; 4113 DWORD r; 4114 4115 TRACE("%s %d %d %p %p %p %p %p\n", pObjectName, ObjectType, SecurityInfo, 4116 ppsidOwner, ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor); 4117 4118 if( pObjectName ) 4119 { 4120 len = MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, NULL, 0 ); 4121 wstr = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR)); 4122 MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, wstr, len ); 4123 } 4124 4125 r = GetNamedSecurityInfoW( wstr, ObjectType, SecurityInfo, ppsidOwner, 4126 ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor ); 4127 4128 HeapFree( GetProcessHeap(), 0, wstr ); 4129 4130 return r; 4131 } 4132 4133 /****************************************************************************** 4134 * GetWindowsAccountDomainSid [ADVAPI32.@] 4135 */ 4136 BOOL WINAPI GetWindowsAccountDomainSid( PSID sid, PSID domain_sid, DWORD *size ) 4137 { 4138 SID_IDENTIFIER_AUTHORITY domain_ident = { SECURITY_NT_AUTHORITY }; 4139 DWORD required_size; 4140 int i; 4141 4142 FIXME( "(%p %p %p): semi-stub\n", sid, domain_sid, size ); 4143 4144 if (!sid || !IsValidSid( sid )) 4145 { 4146 SetLastError( ERROR_INVALID_SID ); 4147 return FALSE; 4148 } 4149 4150 if (!size) 4151 { 4152 SetLastError( ERROR_INVALID_PARAMETER ); 4153 return FALSE; 4154 } 4155 4156 if (*GetSidSubAuthorityCount( sid ) < 4) 4157 { 4158 SetLastError( ERROR_INVALID_SID ); 4159 return FALSE; 4160 } 4161 4162 required_size = GetSidLengthRequired( 4 ); 4163 if (*size < required_size || !domain_sid) 4164 { 4165 *size = required_size; 4166 SetLastError( domain_sid ? ERROR_INSUFFICIENT_BUFFER : 4167 ERROR_INVALID_PARAMETER ); 4168 return FALSE; 4169 } 4170 4171 InitializeSid( domain_sid, &domain_ident, 4 ); 4172 for (i = 0; i < 4; i++) 4173 *GetSidSubAuthority( domain_sid, i ) = *GetSidSubAuthority( sid, i ); 4174 4175 *size = required_size; 4176 return TRUE; 4177 } 4178 4179 /* 4180 * @unimplemented 4181 */ 4182 BOOL 4183 WINAPI 4184 EqualDomainSid(IN PSID pSid1, 4185 IN PSID pSid2, 4186 OUT BOOL* pfEqual) 4187 { 4188 UNIMPLEMENTED; 4189 return FALSE; 4190 } 4191 4192 /* EOF */ 4193