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 3479 WINAPI 3480 CreateProcessWithLogonW( 3481 _In_ LPCWSTR lpUsername, 3482 _In_opt_ LPCWSTR lpDomain, 3483 _In_ LPCWSTR lpPassword, 3484 _In_ DWORD dwLogonFlags, 3485 _In_opt_ LPCWSTR lpApplicationName, 3486 _Inout_opt_ LPWSTR lpCommandLine, 3487 _In_ DWORD dwCreationFlags, 3488 _In_opt_ LPVOID lpEnvironment, 3489 _In_opt_ LPCWSTR lpCurrentDirectory, 3490 _In_ LPSTARTUPINFOW lpStartupInfo, 3491 _Out_ LPPROCESS_INFORMATION lpProcessInformation) 3492 { 3493 LPWSTR pszStringBinding = NULL; 3494 handle_t hBinding = NULL; 3495 SECL_REQUEST Request; 3496 SECL_RESPONSE Response; 3497 RPC_STATUS Status; 3498 3499 TRACE("CreateProcessWithLogonW(%s %s %s 0x%08x %s %s 0x%08x %p %s %p %p)\n", debugstr_w(lpUsername), debugstr_w(lpDomain), 3500 debugstr_w(lpPassword), dwLogonFlags, debugstr_w(lpApplicationName), 3501 debugstr_w(lpCommandLine), dwCreationFlags, lpEnvironment, debugstr_w(lpCurrentDirectory), 3502 lpStartupInfo, lpProcessInformation); 3503 3504 Status = RpcStringBindingComposeW(NULL, 3505 L"ncacn_np", 3506 NULL, 3507 L"\\pipe\\seclogon", 3508 NULL, 3509 &pszStringBinding); 3510 if (Status != RPC_S_OK) 3511 { 3512 WARN("RpcStringBindingCompose returned 0x%x\n", Status); 3513 SetLastError(Status); 3514 return FALSE; 3515 } 3516 3517 /* Set the binding handle that will be used to bind to the server. */ 3518 Status = RpcBindingFromStringBindingW(pszStringBinding, 3519 &hBinding); 3520 if (Status != RPC_S_OK) 3521 { 3522 WARN("RpcBindingFromStringBinding returned 0x%x\n", Status); 3523 } 3524 3525 Status = RpcStringFreeW(&pszStringBinding); 3526 if (Status != RPC_S_OK) 3527 { 3528 WARN("RpcStringFree returned 0x%x\n", Status); 3529 } 3530 3531 Request.Username = (LPWSTR)lpUsername; 3532 Request.Domain = (LPWSTR)lpDomain; 3533 Request.Password = (LPWSTR)lpPassword; 3534 Request.ApplicationName = (LPWSTR)lpApplicationName; 3535 Request.CommandLine = (LPWSTR)lpCommandLine; 3536 Request.CurrentDirectory = (LPWSTR)lpCurrentDirectory; 3537 3538 Request.dwLogonFlags = dwLogonFlags; 3539 Request.dwCreationFlags = dwCreationFlags; 3540 3541 Request.dwProcessId = GetCurrentProcessId(); 3542 TRACE("Request.dwProcessId %lu\n", Request.dwProcessId); 3543 3544 Response.hProcess = 0; 3545 Response.hThread = 0; 3546 Response.dwProcessId = 0; 3547 Response.dwThreadId = 0; 3548 Response.dwError = ERROR_SUCCESS; 3549 3550 RpcTryExcept 3551 { 3552 SeclCreateProcessWithLogonW(hBinding, &Request, &Response); 3553 } 3554 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 3555 { 3556 WARN("Exception: %lx\n", RpcExceptionCode()); 3557 } 3558 RpcEndExcept; 3559 3560 if (hBinding) 3561 { 3562 Status = RpcBindingFree(&hBinding); 3563 if (Status != RPC_S_OK) 3564 { 3565 WARN("RpcBindingFree returned 0x%x\n", Status); 3566 } 3567 3568 hBinding = NULL; 3569 } 3570 3571 TRACE("Response.hProcess %p\n", Response.hProcess); 3572 TRACE("Response.hThread %p\n", Response.hThread); 3573 TRACE("Response.dwProcessId %lu\n", Response.dwProcessId); 3574 TRACE("Response.dwThreadId %lu\n", Response.dwThreadId); 3575 TRACE("Response.dwError %lu\n", Response.dwError); 3576 if (Response.dwError != ERROR_SUCCESS) 3577 SetLastError(Response.dwError); 3578 3579 TRACE("CreateProcessWithLogonW() done\n"); 3580 3581 return (Response.dwError == ERROR_SUCCESS); 3582 } 3583 3584 BOOL WINAPI CreateProcessWithTokenW(HANDLE token, DWORD logon_flags, LPCWSTR application_name, LPWSTR command_line, 3585 DWORD creation_flags, void *environment, LPCWSTR current_directory, STARTUPINFOW *startup_info, 3586 PROCESS_INFORMATION *process_information ) 3587 { 3588 FIXME("%p 0x%08x %s %s 0x%08x %p %s %p %p - semi-stub\n", token, 3589 logon_flags, debugstr_w(application_name), debugstr_w(command_line), 3590 creation_flags, environment, debugstr_w(current_directory), 3591 startup_info, process_information); 3592 3593 /* FIXME: check if handles should be inherited */ 3594 return CreateProcessW( application_name, command_line, NULL, NULL, FALSE, creation_flags, environment, 3595 current_directory, startup_info, process_information ); 3596 } 3597 3598 /* 3599 * @implemented 3600 */ 3601 BOOL WINAPI 3602 DuplicateTokenEx(IN HANDLE ExistingTokenHandle, 3603 IN DWORD dwDesiredAccess, 3604 IN LPSECURITY_ATTRIBUTES lpTokenAttributes OPTIONAL, 3605 IN SECURITY_IMPERSONATION_LEVEL ImpersonationLevel, 3606 IN TOKEN_TYPE TokenType, 3607 OUT PHANDLE DuplicateTokenHandle) 3608 { 3609 OBJECT_ATTRIBUTES ObjectAttributes; 3610 NTSTATUS Status; 3611 SECURITY_QUALITY_OF_SERVICE Sqos; 3612 3613 TRACE("%p 0x%08x 0x%08x 0x%08x %p\n", ExistingTokenHandle, dwDesiredAccess, 3614 ImpersonationLevel, TokenType, DuplicateTokenHandle); 3615 3616 Sqos.Length = sizeof(SECURITY_QUALITY_OF_SERVICE); 3617 Sqos.ImpersonationLevel = ImpersonationLevel; 3618 Sqos.ContextTrackingMode = 0; 3619 Sqos.EffectiveOnly = FALSE; 3620 3621 if (lpTokenAttributes != NULL) 3622 { 3623 InitializeObjectAttributes(&ObjectAttributes, 3624 NULL, 3625 lpTokenAttributes->bInheritHandle ? OBJ_INHERIT : 0, 3626 NULL, 3627 lpTokenAttributes->lpSecurityDescriptor); 3628 } 3629 else 3630 { 3631 InitializeObjectAttributes(&ObjectAttributes, 3632 NULL, 3633 0, 3634 NULL, 3635 NULL); 3636 } 3637 3638 ObjectAttributes.SecurityQualityOfService = &Sqos; 3639 3640 Status = NtDuplicateToken(ExistingTokenHandle, 3641 dwDesiredAccess, 3642 &ObjectAttributes, 3643 FALSE, 3644 TokenType, 3645 DuplicateTokenHandle); 3646 if (!NT_SUCCESS(Status)) 3647 { 3648 ERR("NtDuplicateToken failed: Status %08x\n", Status); 3649 SetLastError(RtlNtStatusToDosError(Status)); 3650 return FALSE; 3651 } 3652 3653 TRACE("Returning token %p.\n", *DuplicateTokenHandle); 3654 3655 return TRUE; 3656 } 3657 3658 /* 3659 * @implemented 3660 */ 3661 BOOL WINAPI 3662 DuplicateToken(IN HANDLE ExistingTokenHandle, 3663 IN SECURITY_IMPERSONATION_LEVEL ImpersonationLevel, 3664 OUT PHANDLE DuplicateTokenHandle) 3665 { 3666 return DuplicateTokenEx(ExistingTokenHandle, 3667 TOKEN_IMPERSONATE | TOKEN_QUERY, 3668 NULL, 3669 ImpersonationLevel, 3670 TokenImpersonation, 3671 DuplicateTokenHandle); 3672 } 3673 3674 /****************************************************************************** 3675 * ComputeStringSidSize 3676 */ 3677 static DWORD ComputeStringSidSize(LPCWSTR StringSid) 3678 { 3679 if (StringSid[0] == 'S' && StringSid[1] == '-') /* S-R-I(-S)+ */ 3680 { 3681 int ctok = 0; 3682 while (*StringSid) 3683 { 3684 if (*StringSid == '-') 3685 ctok++; 3686 StringSid++; 3687 } 3688 3689 if (ctok >= 3) 3690 return GetSidLengthRequired(ctok - 2); 3691 } 3692 else /* String constant format - Only available in winxp and above */ 3693 { 3694 unsigned int i; 3695 3696 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++) 3697 if (!strncmpW(WellKnownSids[i].wstr, StringSid, 2)) 3698 return GetSidLengthRequired(WellKnownSids[i].Sid.SubAuthorityCount); 3699 3700 for (i = 0; i < sizeof(WellKnownRids)/sizeof(WellKnownRids[0]); i++) 3701 if (!strncmpW(WellKnownRids[i].wstr, StringSid, 2)) 3702 { 3703 MAX_SID local; 3704 ADVAPI_GetComputerSid(&local); 3705 return GetSidLengthRequired(*GetSidSubAuthorityCount(&local) + 1); 3706 } 3707 3708 } 3709 3710 return GetSidLengthRequired(0); 3711 } 3712 3713 /****************************************************************************** 3714 * ParseStringSidToSid 3715 */ 3716 static BOOL ParseStringSidToSid(LPCWSTR StringSid, PSID pSid, LPDWORD cBytes) 3717 { 3718 BOOL bret = FALSE; 3719 SID* pisid=pSid; 3720 3721 TRACE("%s, %p, %p\n", debugstr_w(StringSid), pSid, cBytes); 3722 if (!StringSid) 3723 { 3724 SetLastError(ERROR_INVALID_PARAMETER); 3725 TRACE("StringSid is NULL, returning FALSE\n"); 3726 return FALSE; 3727 } 3728 3729 while (*StringSid == ' ') 3730 StringSid++; 3731 3732 if (!*StringSid) 3733 goto lend; /* ERROR_INVALID_SID */ 3734 3735 *cBytes = ComputeStringSidSize(StringSid); 3736 if (!pisid) /* Simply compute the size */ 3737 { 3738 TRACE("only size requested, returning TRUE with %d\n", *cBytes); 3739 return TRUE; 3740 } 3741 3742 if (StringSid[0] == 'S' && StringSid[1] == '-') /* S-R-I-S-S */ 3743 { 3744 DWORD i = 0, identAuth; 3745 DWORD csubauth = ((*cBytes - GetSidLengthRequired(0)) / sizeof(DWORD)); 3746 3747 StringSid += 2; /* Advance to Revision */ 3748 pisid->Revision = atoiW(StringSid); 3749 3750 if (pisid->Revision != SDDL_REVISION) 3751 { 3752 TRACE("Revision %d is unknown\n", pisid->Revision); 3753 goto lend; /* ERROR_INVALID_SID */ 3754 } 3755 if (csubauth == 0) 3756 { 3757 TRACE("SubAuthorityCount is 0\n"); 3758 goto lend; /* ERROR_INVALID_SID */ 3759 } 3760 3761 pisid->SubAuthorityCount = csubauth; 3762 3763 /* Advance to identifier authority */ 3764 while (*StringSid && *StringSid != '-') 3765 StringSid++; 3766 if (*StringSid == '-') 3767 StringSid++; 3768 3769 /* MS' implementation can't handle values greater than 2^32 - 1, so 3770 * we don't either; assume most significant bytes are always 0 3771 */ 3772 pisid->IdentifierAuthority.Value[0] = 0; 3773 pisid->IdentifierAuthority.Value[1] = 0; 3774 identAuth = atoiW(StringSid); 3775 pisid->IdentifierAuthority.Value[5] = identAuth & 0xff; 3776 pisid->IdentifierAuthority.Value[4] = (identAuth & 0xff00) >> 8; 3777 pisid->IdentifierAuthority.Value[3] = (identAuth & 0xff0000) >> 16; 3778 pisid->IdentifierAuthority.Value[2] = (identAuth & 0xff000000) >> 24; 3779 3780 /* Advance to first sub authority */ 3781 while (*StringSid && *StringSid != '-') 3782 StringSid++; 3783 if (*StringSid == '-') 3784 StringSid++; 3785 3786 while (*StringSid) 3787 { 3788 pisid->SubAuthority[i++] = atoiW(StringSid); 3789 3790 while (*StringSid && *StringSid != '-') 3791 StringSid++; 3792 if (*StringSid == '-') 3793 StringSid++; 3794 } 3795 3796 if (i != pisid->SubAuthorityCount) 3797 goto lend; /* ERROR_INVALID_SID */ 3798 3799 bret = TRUE; 3800 } 3801 else /* String constant format - Only available in winxp and above */ 3802 { 3803 unsigned int i; 3804 pisid->Revision = SDDL_REVISION; 3805 3806 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++) 3807 if (!strncmpW(WellKnownSids[i].wstr, StringSid, 2)) 3808 { 3809 DWORD j; 3810 pisid->SubAuthorityCount = WellKnownSids[i].Sid.SubAuthorityCount; 3811 pisid->IdentifierAuthority = WellKnownSids[i].Sid.IdentifierAuthority; 3812 for (j = 0; j < WellKnownSids[i].Sid.SubAuthorityCount; j++) 3813 pisid->SubAuthority[j] = WellKnownSids[i].Sid.SubAuthority[j]; 3814 bret = TRUE; 3815 } 3816 3817 for (i = 0; i < sizeof(WellKnownRids)/sizeof(WellKnownRids[0]); i++) 3818 if (!strncmpW(WellKnownRids[i].wstr, StringSid, 2)) 3819 { 3820 ADVAPI_GetComputerSid(pisid); 3821 pisid->SubAuthority[pisid->SubAuthorityCount] = WellKnownRids[i].Rid; 3822 pisid->SubAuthorityCount++; 3823 bret = TRUE; 3824 } 3825 3826 if (!bret) 3827 FIXME("String constant not supported: %s\n", debugstr_wn(StringSid, 2)); 3828 } 3829 3830 lend: 3831 if (!bret) 3832 SetLastError(ERROR_INVALID_SID); 3833 3834 TRACE("returning %s\n", bret ? "TRUE" : "FALSE"); 3835 return bret; 3836 } 3837 3838 /********************************************************************** 3839 * GetNamedSecurityInfoA EXPORTED 3840 * 3841 * @implemented 3842 */ 3843 DWORD 3844 WINAPI 3845 GetNamedSecurityInfoA(LPSTR pObjectName, 3846 SE_OBJECT_TYPE ObjectType, 3847 SECURITY_INFORMATION SecurityInfo, 3848 PSID *ppsidOwner, 3849 PSID *ppsidGroup, 3850 PACL *ppDacl, 3851 PACL *ppSacl, 3852 PSECURITY_DESCRIPTOR *ppSecurityDescriptor) 3853 { 3854 DWORD len; 3855 LPWSTR wstr = NULL; 3856 DWORD r; 3857 3858 TRACE("%s %d %d %p %p %p %p %p\n", pObjectName, ObjectType, SecurityInfo, 3859 ppsidOwner, ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor); 3860 3861 if( pObjectName ) 3862 { 3863 len = MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, NULL, 0 ); 3864 wstr = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR)); 3865 MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, wstr, len ); 3866 } 3867 3868 r = GetNamedSecurityInfoW( wstr, ObjectType, SecurityInfo, ppsidOwner, 3869 ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor ); 3870 3871 HeapFree( GetProcessHeap(), 0, wstr ); 3872 3873 return r; 3874 } 3875 3876 /****************************************************************************** 3877 * GetWindowsAccountDomainSid [ADVAPI32.@] 3878 */ 3879 BOOL WINAPI GetWindowsAccountDomainSid( PSID sid, PSID domain_sid, DWORD *size ) 3880 { 3881 SID_IDENTIFIER_AUTHORITY domain_ident = { SECURITY_NT_AUTHORITY }; 3882 DWORD required_size; 3883 int i; 3884 3885 FIXME( "(%p %p %p): semi-stub\n", sid, domain_sid, size ); 3886 3887 if (!sid || !IsValidSid( sid )) 3888 { 3889 SetLastError( ERROR_INVALID_SID ); 3890 return FALSE; 3891 } 3892 3893 if (!size) 3894 { 3895 SetLastError( ERROR_INVALID_PARAMETER ); 3896 return FALSE; 3897 } 3898 3899 if (*GetSidSubAuthorityCount( sid ) < 4) 3900 { 3901 SetLastError( ERROR_INVALID_SID ); 3902 return FALSE; 3903 } 3904 3905 required_size = GetSidLengthRequired( 4 ); 3906 if (*size < required_size || !domain_sid) 3907 { 3908 *size = required_size; 3909 SetLastError( domain_sid ? ERROR_INSUFFICIENT_BUFFER : 3910 ERROR_INVALID_PARAMETER ); 3911 return FALSE; 3912 } 3913 3914 InitializeSid( domain_sid, &domain_ident, 4 ); 3915 for (i = 0; i < 4; i++) 3916 *GetSidSubAuthority( domain_sid, i ) = *GetSidSubAuthority( sid, i ); 3917 3918 *size = required_size; 3919 return TRUE; 3920 } 3921 3922 /* 3923 * @unimplemented 3924 */ 3925 BOOL 3926 WINAPI 3927 EqualDomainSid(IN PSID pSid1, 3928 IN PSID pSid2, 3929 OUT BOOL* pfEqual) 3930 { 3931 UNIMPLEMENTED; 3932 return FALSE; 3933 } 3934 3935 /* EOF */ 3936