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