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