Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygensid.c
Go to the documentation of this file.
00001 /* 00002 * COPYRIGHT: See COPYING in the top level directory 00003 * WINE COPYRIGHT: 00004 * Copyright 1999, 2000 Juergen Schmied <juergen.schmied@debitel.net> 00005 * Copyright 2003 CodeWeavers Inc. (Ulrich Czekalla) 00006 * Copyright 2006 Robert Reif 00007 * Copyright 2006 Hervé Poussineau 00008 * 00009 * PROJECT: ReactOS system libraries 00010 * FILE: dll/win32/advapi32/sec/sid.c 00011 * PURPOSE: Security ID functions 00012 */ 00013 00014 #include <advapi32.h> 00015 WINE_DEFAULT_DEBUG_CHANNEL(advapi); 00016 00017 #define MAX_GUID_STRING_LEN 39 00018 00019 BOOL WINAPI 00020 AddAuditAccessAceEx(PACL pAcl, 00021 DWORD dwAceRevision, 00022 DWORD AceFlags, 00023 DWORD dwAccessMask, 00024 PSID pSid, 00025 BOOL bAuditSuccess, 00026 BOOL bAuditFailure); 00027 00028 typedef struct RECORD 00029 { 00030 LPCWSTR key; 00031 DWORD value; 00032 } RECORD; 00033 00034 00035 typedef struct _MAX_SID 00036 { 00037 /* same fields as struct _SID */ 00038 BYTE Revision; 00039 BYTE SubAuthorityCount; 00040 SID_IDENTIFIER_AUTHORITY IdentifierAuthority; 00041 DWORD SubAuthority[SID_MAX_SUB_AUTHORITIES]; 00042 } MAX_SID; 00043 00044 typedef struct WELLKNOWNSID 00045 { 00046 WCHAR wstr[2]; 00047 WELL_KNOWN_SID_TYPE Type; 00048 MAX_SID Sid; 00049 } WELLKNOWNSID; 00050 00051 typedef struct _ACEFLAG 00052 { 00053 LPCWSTR wstr; 00054 DWORD value; 00055 } ACEFLAG, *LPACEFLAG; 00056 00057 static const WELLKNOWNSID WellKnownSids[] = 00058 { 00059 { {0,0}, WinNullSid, { SID_REVISION, 1, { SECURITY_NULL_SID_AUTHORITY }, { SECURITY_NULL_RID } } }, 00060 { {'W','D'}, WinWorldSid, { SID_REVISION, 1, { SECURITY_WORLD_SID_AUTHORITY }, { SECURITY_WORLD_RID } } }, 00061 { {0,0}, WinLocalSid, { SID_REVISION, 1, { SECURITY_LOCAL_SID_AUTHORITY }, { SECURITY_LOCAL_RID } } }, 00062 { {'C','O'}, WinCreatorOwnerSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_OWNER_RID } } }, 00063 { {'C','G'}, WinCreatorGroupSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_GROUP_RID } } }, 00064 { {0,0}, WinCreatorOwnerServerSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_OWNER_SERVER_RID } } }, 00065 { {0,0}, WinCreatorGroupServerSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_GROUP_SERVER_RID } } }, 00066 { {0,0}, WinNtAuthoritySid, { SID_REVISION, 0, { SECURITY_NT_AUTHORITY }, { SECURITY_NULL_RID } } }, 00067 { {0,0}, WinDialupSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_DIALUP_RID } } }, 00068 { {'N','U'}, WinNetworkSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_NETWORK_RID } } }, 00069 { {0,0}, WinBatchSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_BATCH_RID } } }, 00070 { {'I','U'}, WinInteractiveSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_INTERACTIVE_RID } } }, 00071 { {'S','U'}, WinServiceSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_SERVICE_RID } } }, 00072 { {'A','N'}, WinAnonymousSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_ANONYMOUS_LOGON_RID } } }, 00073 { {0,0}, WinProxySid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_PROXY_RID } } }, 00074 { {'E','D'}, WinEnterpriseControllersSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_ENTERPRISE_CONTROLLERS_RID } } }, 00075 { {'P','S'}, WinSelfSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_PRINCIPAL_SELF_RID } } }, 00076 { {'A','U'}, WinAuthenticatedUserSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_AUTHENTICATED_USER_RID } } }, 00077 { {'R','C'}, WinRestrictedCodeSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_RESTRICTED_CODE_RID } } }, 00078 { {0,0}, WinTerminalServerSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_TERMINAL_SERVER_RID } } }, 00079 { {0,0}, WinRemoteLogonIdSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_REMOTE_LOGON_RID } } }, 00080 { {'S','Y'}, WinLocalSystemSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_LOCAL_SYSTEM_RID } } }, 00081 { {'L','S'}, WinLocalServiceSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_LOCAL_SERVICE_RID } } }, 00082 { {'N','S'}, WinNetworkServiceSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_NETWORK_SERVICE_RID } } }, 00083 { {0,0}, WinBuiltinDomainSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID } } }, 00084 { {'B','A'}, WinBuiltinAdministratorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS } } }, 00085 { {'B','U'}, WinBuiltinUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_USERS } } }, 00086 { {'B','G'}, WinBuiltinGuestsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_GUESTS } } }, 00087 { {'P','U'}, WinBuiltinPowerUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_POWER_USERS } } }, 00088 { {'A','O'}, WinBuiltinAccountOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ACCOUNT_OPS } } }, 00089 { {'S','O'}, WinBuiltinSystemOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_SYSTEM_OPS } } }, 00090 { {'P','O'}, WinBuiltinPrintOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_PRINT_OPS } } }, 00091 { {'B','O'}, WinBuiltinBackupOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_BACKUP_OPS } } }, 00092 { {'R','E'}, WinBuiltinReplicatorSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_REPLICATOR } } }, 00093 { {'R','U'}, WinBuiltinPreWindows2000CompatibleAccessSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_PREW2KCOMPACCESS } } }, 00094 { {'R','D'}, WinBuiltinRemoteDesktopUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_REMOTE_DESKTOP_USERS } } }, 00095 { {'N','O'}, WinBuiltinNetworkConfigurationOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_NETWORK_CONFIGURATION_OPS } } }, 00096 { {0,0}, WinNTLMAuthenticationSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_PACKAGE_BASE_RID, SECURITY_PACKAGE_NTLM_RID } } }, 00097 { {0,0}, WinDigestAuthenticationSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_PACKAGE_BASE_RID, SECURITY_PACKAGE_DIGEST_RID } } }, 00098 { {0,0}, WinSChannelAuthenticationSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_PACKAGE_BASE_RID, SECURITY_PACKAGE_SCHANNEL_RID } } }, 00099 { {0,0}, WinThisOrganizationSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_THIS_ORGANIZATION_RID } } }, 00100 { {0,0}, WinOtherOrganizationSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_OTHER_ORGANIZATION_RID } } }, 00101 { {0,0}, WinBuiltinIncomingForestTrustBuildersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_INCOMING_FOREST_TRUST_BUILDERS } } }, 00102 { {0,0}, WinBuiltinPerfMonitoringUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_MONITORING_USERS } } }, 00103 { {0,0}, WinBuiltinPerfLoggingUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_LOGGING_USERS } } }, 00104 { {0,0}, WinBuiltinAuthorizationAccessSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_AUTHORIZATIONACCESS } } }, 00105 { {0,0}, WinBuiltinTerminalServerLicenseServersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_TS_LICENSE_SERVERS } } }, 00106 { {0,0}, WinBuiltinDCOMUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_DCOM_USERS } } }, 00107 { {'L','W'}, WinLowLabelSid, { SID_REVISION, 1, { SECURITY_MANDATORY_LABEL_AUTHORITY}, { SECURITY_MANDATORY_LOW_RID} } }, 00108 { {'M','E'}, WinMediumLabelSid, { SID_REVISION, 1, { SECURITY_MANDATORY_LABEL_AUTHORITY}, { SECURITY_MANDATORY_MEDIUM_RID } } }, 00109 { {'H','I'}, WinHighLabelSid, { SID_REVISION, 1, { SECURITY_MANDATORY_LABEL_AUTHORITY}, { SECURITY_MANDATORY_HIGH_RID } } }, 00110 { {'S','I'}, WinSystemLabelSid, { SID_REVISION, 1, { SECURITY_MANDATORY_LABEL_AUTHORITY}, { SECURITY_MANDATORY_SYSTEM_RID } } }, 00111 }; 00112 00113 typedef struct WELLKNOWNRID 00114 { 00115 WELL_KNOWN_SID_TYPE Type; 00116 DWORD Rid; 00117 } WELLKNOWNRID; 00118 00119 static const WELLKNOWNRID WellKnownRids[] = { 00120 { WinAccountAdministratorSid, DOMAIN_USER_RID_ADMIN }, 00121 { WinAccountGuestSid, DOMAIN_USER_RID_GUEST }, 00122 { WinAccountKrbtgtSid, DOMAIN_USER_RID_KRBTGT }, 00123 { WinAccountDomainAdminsSid, DOMAIN_GROUP_RID_ADMINS }, 00124 { WinAccountDomainUsersSid, DOMAIN_GROUP_RID_USERS }, 00125 { WinAccountDomainGuestsSid, DOMAIN_GROUP_RID_GUESTS }, 00126 { WinAccountComputersSid, DOMAIN_GROUP_RID_COMPUTERS }, 00127 { WinAccountControllersSid, DOMAIN_GROUP_RID_CONTROLLERS }, 00128 { WinAccountCertAdminsSid, DOMAIN_GROUP_RID_CERT_ADMINS }, 00129 { WinAccountSchemaAdminsSid, DOMAIN_GROUP_RID_SCHEMA_ADMINS }, 00130 { WinAccountEnterpriseAdminsSid, DOMAIN_GROUP_RID_ENTERPRISE_ADMINS }, 00131 { WinAccountPolicyAdminsSid, DOMAIN_GROUP_RID_POLICY_ADMINS }, 00132 { WinAccountRasAndIasServersSid, DOMAIN_ALIAS_RID_RAS_SERVERS }, 00133 }; 00134 00135 static const SID sidWorld = { SID_REVISION, 1, { SECURITY_WORLD_SID_AUTHORITY} , { SECURITY_WORLD_RID } }; 00136 00137 /* 00138 * ACE types 00139 */ 00140 static const WCHAR SDDL_ACCESS_ALLOWED[] = {'A',0}; 00141 static const WCHAR SDDL_ACCESS_DENIED[] = {'D',0}; 00142 static const WCHAR SDDL_OBJECT_ACCESS_ALLOWED[] = {'O','A',0}; 00143 static const WCHAR SDDL_OBJECT_ACCESS_DENIED[] = {'O','D',0}; 00144 static const WCHAR SDDL_AUDIT[] = {'A','U',0}; 00145 static const WCHAR SDDL_ALARM[] = {'A','L',0}; 00146 static const WCHAR SDDL_OBJECT_AUDIT[] = {'O','U',0}; 00147 static const WCHAR SDDL_OBJECT_ALARM[] = {'O','L',0}; 00148 00149 /* 00150 * SDDL ADS Rights 00151 */ 00152 #define ADS_RIGHT_DS_CREATE_CHILD 0x0001 00153 #define ADS_RIGHT_DS_DELETE_CHILD 0x0002 00154 #define ADS_RIGHT_ACTRL_DS_LIST 0x0004 00155 #define ADS_RIGHT_DS_SELF 0x0008 00156 #define ADS_RIGHT_DS_READ_PROP 0x0010 00157 #define ADS_RIGHT_DS_WRITE_PROP 0x0020 00158 #define ADS_RIGHT_DS_DELETE_TREE 0x0040 00159 #define ADS_RIGHT_DS_LIST_OBJECT 0x0080 00160 #define ADS_RIGHT_DS_CONTROL_ACCESS 0x0100 00161 00162 /* 00163 * ACE flags 00164 */ 00165 static const WCHAR SDDL_CONTAINER_INHERIT[] = {'C','I',0}; 00166 static const WCHAR SDDL_OBJECT_INHERIT[] = {'O','I',0}; 00167 static const WCHAR SDDL_NO_PROPAGATE[] = {'N','P',0}; 00168 static const WCHAR SDDL_INHERIT_ONLY[] = {'I','O',0}; 00169 static const WCHAR SDDL_INHERITED[] = {'I','D',0}; 00170 static const WCHAR SDDL_AUDIT_SUCCESS[] = {'S','A',0}; 00171 static const WCHAR SDDL_AUDIT_FAILURE[] = {'F','A',0}; 00172 00173 static const char * debugstr_sid(PSID sid) 00174 { 00175 int auth = 0; 00176 SID * psid = (SID *)sid; 00177 00178 if (psid == NULL) 00179 return "(null)"; 00180 00181 auth = psid->IdentifierAuthority.Value[5] + 00182 (psid->IdentifierAuthority.Value[4] << 8) + 00183 (psid->IdentifierAuthority.Value[3] << 16) + 00184 (psid->IdentifierAuthority.Value[2] << 24); 00185 00186 switch (psid->SubAuthorityCount) { 00187 case 0: 00188 return wine_dbg_sprintf("S-%d-%d", psid->Revision, auth); 00189 case 1: 00190 return wine_dbg_sprintf("S-%d-%d-%lu", psid->Revision, auth, 00191 psid->SubAuthority[0]); 00192 case 2: 00193 return wine_dbg_sprintf("S-%d-%d-%lu-%lu", psid->Revision, auth, 00194 psid->SubAuthority[0], psid->SubAuthority[1]); 00195 case 3: 00196 return wine_dbg_sprintf("S-%d-%d-%lu-%lu-%lu", psid->Revision, auth, 00197 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2]); 00198 case 4: 00199 return wine_dbg_sprintf("S-%d-%d-%lu-%lu-%lu-%lu", psid->Revision, auth, 00200 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2], 00201 psid->SubAuthority[3]); 00202 case 5: 00203 return wine_dbg_sprintf("S-%d-%d-%lu-%lu-%lu-%lu-%lu", psid->Revision, auth, 00204 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2], 00205 psid->SubAuthority[3], psid->SubAuthority[4]); 00206 case 6: 00207 return wine_dbg_sprintf("S-%d-%d-%lu-%lu-%lu-%lu-%lu-%lu", psid->Revision, auth, 00208 psid->SubAuthority[3], psid->SubAuthority[1], psid->SubAuthority[2], 00209 psid->SubAuthority[0], psid->SubAuthority[4], psid->SubAuthority[5]); 00210 case 7: 00211 return wine_dbg_sprintf("S-%d-%d-%lu-%lu-%lu-%lu-%lu-%lu-%lu", psid->Revision, auth, 00212 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2], 00213 psid->SubAuthority[3], psid->SubAuthority[4], psid->SubAuthority[5], 00214 psid->SubAuthority[6]); 00215 case 8: 00216 return wine_dbg_sprintf("S-%d-%d-%lu-%lu-%lu-%lu-%lu-%lu-%lu-%lu", psid->Revision, auth, 00217 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2], 00218 psid->SubAuthority[3], psid->SubAuthority[4], psid->SubAuthority[5], 00219 psid->SubAuthority[6], psid->SubAuthority[7]); 00220 } 00221 return "(too-big)"; 00222 } 00223 00224 static const ACEFLAG AceRights[] = 00225 { 00226 { SDDL_GENERIC_ALL, GENERIC_ALL }, 00227 { SDDL_GENERIC_READ, GENERIC_READ }, 00228 { SDDL_GENERIC_WRITE, GENERIC_WRITE }, 00229 { SDDL_GENERIC_EXECUTE, GENERIC_EXECUTE }, 00230 00231 { SDDL_READ_CONTROL, READ_CONTROL }, 00232 { SDDL_STANDARD_DELETE, DELETE }, 00233 { SDDL_WRITE_DAC, WRITE_DAC }, 00234 { SDDL_WRITE_OWNER, WRITE_OWNER }, 00235 00236 { SDDL_READ_PROPERTY, ADS_RIGHT_DS_READ_PROP}, 00237 { SDDL_WRITE_PROPERTY, ADS_RIGHT_DS_WRITE_PROP}, 00238 { SDDL_CREATE_CHILD, ADS_RIGHT_DS_CREATE_CHILD}, 00239 { SDDL_DELETE_CHILD, ADS_RIGHT_DS_DELETE_CHILD}, 00240 { SDDL_LIST_CHILDREN, ADS_RIGHT_ACTRL_DS_LIST}, 00241 { SDDL_SELF_WRITE, ADS_RIGHT_DS_SELF}, 00242 { SDDL_LIST_OBJECT, ADS_RIGHT_DS_LIST_OBJECT}, 00243 { SDDL_DELETE_TREE, ADS_RIGHT_DS_DELETE_TREE}, 00244 { SDDL_CONTROL_ACCESS, ADS_RIGHT_DS_CONTROL_ACCESS}, 00245 00246 { SDDL_FILE_ALL, FILE_ALL_ACCESS }, 00247 { SDDL_FILE_READ, FILE_GENERIC_READ }, 00248 { SDDL_FILE_WRITE, FILE_GENERIC_WRITE }, 00249 { SDDL_FILE_EXECUTE, FILE_GENERIC_EXECUTE }, 00250 00251 { SDDL_KEY_ALL, KEY_ALL_ACCESS }, 00252 { SDDL_KEY_READ, KEY_READ }, 00253 { SDDL_KEY_WRITE, KEY_WRITE }, 00254 { SDDL_KEY_EXECUTE, KEY_EXECUTE }, 00255 { NULL, 0 }, 00256 }; 00257 00258 static const LPCWSTR AceRightBitNames[32] = { 00259 SDDL_CREATE_CHILD, /* 0 */ 00260 SDDL_DELETE_CHILD, 00261 SDDL_LIST_CHILDREN, 00262 SDDL_SELF_WRITE, 00263 SDDL_READ_PROPERTY, /* 4 */ 00264 SDDL_WRITE_PROPERTY, 00265 SDDL_DELETE_TREE, 00266 SDDL_LIST_OBJECT, 00267 SDDL_CONTROL_ACCESS, /* 8 */ 00268 NULL, 00269 NULL, 00270 NULL, 00271 NULL, /* 12 */ 00272 NULL, 00273 NULL, 00274 NULL, 00275 SDDL_STANDARD_DELETE, /* 16 */ 00276 SDDL_READ_CONTROL, 00277 SDDL_WRITE_DAC, 00278 SDDL_WRITE_OWNER, 00279 NULL, /* 20 */ 00280 NULL, 00281 NULL, 00282 NULL, 00283 NULL, /* 24 */ 00284 NULL, 00285 NULL, 00286 NULL, 00287 SDDL_GENERIC_ALL, /* 28 */ 00288 SDDL_GENERIC_EXECUTE, 00289 SDDL_GENERIC_WRITE, 00290 SDDL_GENERIC_READ 00291 }; 00292 00293 00294 /* set last error code from NT status and get the proper boolean return value */ 00295 /* used for functions that are a simple wrapper around the corresponding ntdll API */ 00296 static __inline BOOL set_ntstatus( NTSTATUS status ) 00297 { 00298 if (status) SetLastError( RtlNtStatusToDosError( status )); 00299 return !status; 00300 } 00301 00302 /************************************************************ 00303 * ADVAPI_GetComputerSid 00304 * 00305 * Reads the computer SID from the registry. 00306 */ 00307 BOOL ADVAPI_GetComputerSid(PSID sid) 00308 { 00309 HKEY key; 00310 LONG ret; 00311 BOOL retval = FALSE; 00312 static const WCHAR Account[] = { 'S','E','C','U','R','I','T','Y','\\','S','A','M','\\','D','o','m','a','i','n','s','\\','A','c','c','o','u','n','t',0 }; 00313 static const WCHAR V[] = { 'V',0 }; 00314 00315 if ((ret = RegOpenKeyExW(HKEY_LOCAL_MACHINE, Account, 0, 00316 KEY_READ, &key)) == ERROR_SUCCESS) 00317 { 00318 DWORD size = 0; 00319 ret = RegQueryValueExW(key, V, NULL, NULL, NULL, &size); 00320 if (ret == ERROR_MORE_DATA || ret == ERROR_SUCCESS) 00321 { 00322 BYTE * data = HeapAlloc(GetProcessHeap(), 0, size); 00323 if (data) 00324 { 00325 if ((ret = RegQueryValueExW(key, V, NULL, NULL, 00326 data, &size)) == ERROR_SUCCESS) 00327 { 00328 /* the SID is in the last 24 bytes of the binary data */ 00329 CopyMemory(sid, &data[size-24], 24); 00330 retval = TRUE; 00331 } 00332 HeapFree(GetProcessHeap(), 0, data); 00333 } 00334 } 00335 RegCloseKey(key); 00336 } 00337 00338 if(retval == TRUE) return retval; 00339 00340 /* create a new random SID */ 00341 if (RegCreateKeyExW(HKEY_LOCAL_MACHINE, Account, 00342 0, NULL, 0, KEY_ALL_ACCESS, NULL, &key, NULL) == ERROR_SUCCESS) 00343 { 00344 PSID new_sid; 00345 SID_IDENTIFIER_AUTHORITY identifierAuthority = {SECURITY_NT_AUTHORITY}; 00346 DWORD id[3]; 00347 00348 if (RtlGenRandom(id, sizeof(id))) 00349 { 00350 if (AllocateAndInitializeSid(&identifierAuthority, 4, SECURITY_NT_NON_UNIQUE, id[0], id[1], id[2], 0, 0, 0, 0, &new_sid)) 00351 { 00352 if (RegSetValueExW(key, V, 0, REG_BINARY, new_sid, GetLengthSid(new_sid)) == ERROR_SUCCESS) 00353 retval = CopySid(GetLengthSid(new_sid), sid, new_sid); 00354 00355 FreeSid(new_sid); 00356 } 00357 } 00358 RegCloseKey(key); 00359 } 00360 00361 return retval; 00362 } 00363 00364 /* Exported functions */ 00365 00366 /* 00367 * @implemented 00368 */ 00369 BOOL WINAPI 00370 AllocateLocallyUniqueId(PLUID Luid) 00371 { 00372 NTSTATUS Status; 00373 00374 Status = NtAllocateLocallyUniqueId (Luid); 00375 if (!NT_SUCCESS (Status)) 00376 { 00377 SetLastError(RtlNtStatusToDosError(Status)); 00378 return FALSE; 00379 } 00380 00381 return TRUE; 00382 } 00383 00384 00385 /* 00386 * @implemented 00387 */ 00388 BOOL WINAPI 00389 AllocateAndInitializeSid(PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority, 00390 BYTE nSubAuthorityCount, 00391 DWORD dwSubAuthority0, 00392 DWORD dwSubAuthority1, 00393 DWORD dwSubAuthority2, 00394 DWORD dwSubAuthority3, 00395 DWORD dwSubAuthority4, 00396 DWORD dwSubAuthority5, 00397 DWORD dwSubAuthority6, 00398 DWORD dwSubAuthority7, 00399 PSID *pSid) 00400 { 00401 NTSTATUS Status; 00402 00403 Status = RtlAllocateAndInitializeSid(pIdentifierAuthority, 00404 nSubAuthorityCount, 00405 dwSubAuthority0, 00406 dwSubAuthority1, 00407 dwSubAuthority2, 00408 dwSubAuthority3, 00409 dwSubAuthority4, 00410 dwSubAuthority5, 00411 dwSubAuthority6, 00412 dwSubAuthority7, 00413 pSid); 00414 if (!NT_SUCCESS(Status)) 00415 { 00416 SetLastError(RtlNtStatusToDosError(Status)); 00417 return FALSE; 00418 } 00419 00420 return TRUE; 00421 } 00422 00423 00424 /* 00425 * @implemented 00426 */ 00427 BOOL WINAPI 00428 CopySid(DWORD nDestinationSidLength, 00429 PSID pDestinationSid, 00430 PSID pSourceSid) 00431 { 00432 NTSTATUS Status; 00433 00434 Status = RtlCopySid(nDestinationSidLength, 00435 pDestinationSid, 00436 pSourceSid); 00437 if (!NT_SUCCESS (Status)) 00438 { 00439 SetLastError(RtlNtStatusToDosError(Status)); 00440 return FALSE; 00441 } 00442 00443 return TRUE; 00444 } 00445 00446 static void DumpString(LPCWSTR string, int cch, WCHAR **pwptr, ULONG *plen) 00447 { 00448 if (cch == -1) 00449 cch = strlenW(string); 00450 00451 if (plen) 00452 *plen += cch; 00453 00454 if (pwptr) 00455 { 00456 memcpy(*pwptr, string, sizeof(WCHAR)*cch); 00457 *pwptr += cch; 00458 } 00459 } 00460 00461 static BOOL DumpSidNumeric(PSID psid, WCHAR **pwptr, ULONG *plen) 00462 { 00463 DWORD i; 00464 WCHAR fmt[] = { 'S','-','%','u','-','%','d',0 }; 00465 WCHAR subauthfmt[] = { '-','%','u',0 }; 00466 WCHAR buf[26]; 00467 SID *pisid = psid; 00468 00469 if( !IsValidSid( psid ) || pisid->Revision != SDDL_REVISION) 00470 { 00471 SetLastError(ERROR_INVALID_SID); 00472 return FALSE; 00473 } 00474 00475 if (pisid->IdentifierAuthority.Value[0] || 00476 pisid->IdentifierAuthority.Value[1]) 00477 { 00478 FIXME("not matching MS' bugs\n"); 00479 SetLastError(ERROR_INVALID_SID); 00480 return FALSE; 00481 } 00482 00483 sprintfW( buf, fmt, pisid->Revision, 00484 MAKELONG( 00485 MAKEWORD( pisid->IdentifierAuthority.Value[5], 00486 pisid->IdentifierAuthority.Value[4] ), 00487 MAKEWORD( pisid->IdentifierAuthority.Value[3], 00488 pisid->IdentifierAuthority.Value[2] ) 00489 ) ); 00490 DumpString(buf, -1, pwptr, plen); 00491 00492 for( i=0; i<pisid->SubAuthorityCount; i++ ) 00493 { 00494 sprintfW( buf, subauthfmt, pisid->SubAuthority[i] ); 00495 DumpString(buf, -1, pwptr, plen); 00496 } 00497 return TRUE; 00498 } 00499 00500 static BOOL DumpSid(PSID psid, WCHAR **pwptr, ULONG *plen) 00501 { 00502 size_t i; 00503 for (i = 0; i < sizeof(WellKnownSids) / sizeof(WellKnownSids[0]); i++) 00504 { 00505 if (WellKnownSids[i].wstr[0] && EqualSid(psid, (PSID)&(WellKnownSids[i].Sid.Revision))) 00506 { 00507 DumpString(WellKnownSids[i].wstr, 2, pwptr, plen); 00508 return TRUE; 00509 } 00510 } 00511 00512 return DumpSidNumeric(psid, pwptr, plen); 00513 } 00514 00515 static void DumpRights(DWORD mask, WCHAR **pwptr, ULONG *plen) 00516 { 00517 static const WCHAR fmtW[] = {'0','x','%','x',0}; 00518 WCHAR buf[15]; 00519 size_t i; 00520 00521 if (mask == 0) 00522 return; 00523 00524 /* first check if the right have name */ 00525 for (i = 0; i < sizeof(AceRights)/sizeof(AceRights[0]); i++) 00526 { 00527 if (AceRights[i].wstr == NULL) 00528 break; 00529 if (mask == AceRights[i].value) 00530 { 00531 DumpString(AceRights[i].wstr, -1, pwptr, plen); 00532 return; 00533 } 00534 } 00535 00536 /* then check if it can be built from bit names */ 00537 for (i = 0; i < 32; i++) 00538 { 00539 if ((mask & (1 << i)) && (AceRightBitNames[i] == NULL)) 00540 { 00541 /* can't be built from bit names */ 00542 sprintfW(buf, fmtW, mask); 00543 DumpString(buf, -1, pwptr, plen); 00544 return; 00545 } 00546 } 00547 00548 /* build from bit names */ 00549 for (i = 0; i < 32; i++) 00550 if (mask & (1 << i)) 00551 DumpString(AceRightBitNames[i], -1, pwptr, plen); 00552 } 00553 00554 static BOOL DumpAce(LPVOID pace, WCHAR **pwptr, ULONG *plen) 00555 { 00556 ACCESS_ALLOWED_ACE *piace; /* all the supported ACEs have the same memory layout */ 00557 static const WCHAR openbr = '('; 00558 static const WCHAR closebr = ')'; 00559 static const WCHAR semicolon = ';'; 00560 00561 if (((PACE_HEADER)pace)->AceType > SYSTEM_ALARM_ACE_TYPE || ((PACE_HEADER)pace)->AceSize < sizeof(ACCESS_ALLOWED_ACE)) 00562 { 00563 SetLastError(ERROR_INVALID_ACL); 00564 return FALSE; 00565 } 00566 00567 piace = pace; 00568 DumpString(&openbr, 1, pwptr, plen); 00569 switch (piace->Header.AceType) 00570 { 00571 case ACCESS_ALLOWED_ACE_TYPE: 00572 DumpString(SDDL_ACCESS_ALLOWED, -1, pwptr, plen); 00573 break; 00574 case ACCESS_DENIED_ACE_TYPE: 00575 DumpString(SDDL_ACCESS_DENIED, -1, pwptr, plen); 00576 break; 00577 case SYSTEM_AUDIT_ACE_TYPE: 00578 DumpString(SDDL_AUDIT, -1, pwptr, plen); 00579 break; 00580 case SYSTEM_ALARM_ACE_TYPE: 00581 DumpString(SDDL_ALARM, -1, pwptr, plen); 00582 break; 00583 } 00584 DumpString(&semicolon, 1, pwptr, plen); 00585 00586 if (piace->Header.AceFlags & OBJECT_INHERIT_ACE) 00587 DumpString(SDDL_OBJECT_INHERIT, -1, pwptr, plen); 00588 if (piace->Header.AceFlags & CONTAINER_INHERIT_ACE) 00589 DumpString(SDDL_CONTAINER_INHERIT, -1, pwptr, plen); 00590 if (piace->Header.AceFlags & NO_PROPAGATE_INHERIT_ACE) 00591 DumpString(SDDL_NO_PROPAGATE, -1, pwptr, plen); 00592 if (piace->Header.AceFlags & INHERIT_ONLY_ACE) 00593 DumpString(SDDL_INHERIT_ONLY, -1, pwptr, plen); 00594 if (piace->Header.AceFlags & INHERITED_ACE) 00595 DumpString(SDDL_INHERITED, -1, pwptr, plen); 00596 if (piace->Header.AceFlags & SUCCESSFUL_ACCESS_ACE_FLAG) 00597 DumpString(SDDL_AUDIT_SUCCESS, -1, pwptr, plen); 00598 if (piace->Header.AceFlags & FAILED_ACCESS_ACE_FLAG) 00599 DumpString(SDDL_AUDIT_FAILURE, -1, pwptr, plen); 00600 DumpString(&semicolon, 1, pwptr, plen); 00601 DumpRights(piace->Mask, pwptr, plen); 00602 DumpString(&semicolon, 1, pwptr, plen); 00603 /* objects not supported */ 00604 DumpString(&semicolon, 1, pwptr, plen); 00605 /* objects not supported */ 00606 DumpString(&semicolon, 1, pwptr, plen); 00607 if (!DumpSid((PSID)&piace->SidStart, pwptr, plen)) 00608 return FALSE; 00609 DumpString(&closebr, 1, pwptr, plen); 00610 return TRUE; 00611 } 00612 00613 static BOOL DumpAcl(PACL pacl, WCHAR **pwptr, ULONG *plen, BOOL protected, BOOL autoInheritReq, BOOL autoInherited) 00614 { 00615 WORD count; 00616 int i; 00617 00618 if (protected) 00619 DumpString(SDDL_PROTECTED, -1, pwptr, plen); 00620 if (autoInheritReq) 00621 DumpString(SDDL_AUTO_INHERIT_REQ, -1, pwptr, plen); 00622 if (autoInherited) 00623 DumpString(SDDL_AUTO_INHERITED, -1, pwptr, plen); 00624 00625 if (pacl == NULL) 00626 return TRUE; 00627 00628 if (!IsValidAcl(pacl)) 00629 return FALSE; 00630 00631 count = pacl->AceCount; 00632 for (i = 0; i < count; i++) 00633 { 00634 LPVOID ace; 00635 if (!GetAce(pacl, i, &ace)) 00636 return FALSE; 00637 if (!DumpAce(ace, pwptr, plen)) 00638 return FALSE; 00639 } 00640 00641 return TRUE; 00642 } 00643 00644 static BOOL DumpOwner(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen) 00645 { 00646 static const WCHAR prefix[] = {'O',':',0}; 00647 BOOL bDefaulted; 00648 PSID psid; 00649 00650 if (!GetSecurityDescriptorOwner(SecurityDescriptor, &psid, &bDefaulted)) 00651 return FALSE; 00652 00653 if (psid == NULL) 00654 return TRUE; 00655 00656 DumpString(prefix, -1, pwptr, plen); 00657 if (!DumpSid(psid, pwptr, plen)) 00658 return FALSE; 00659 return TRUE; 00660 } 00661 00662 static BOOL DumpGroup(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen) 00663 { 00664 static const WCHAR prefix[] = {'G',':',0}; 00665 BOOL bDefaulted; 00666 PSID psid; 00667 00668 if (!GetSecurityDescriptorGroup(SecurityDescriptor, &psid, &bDefaulted)) 00669 return FALSE; 00670 00671 if (psid == NULL) 00672 return TRUE; 00673 00674 DumpString(prefix, -1, pwptr, plen); 00675 if (!DumpSid(psid, pwptr, plen)) 00676 return FALSE; 00677 return TRUE; 00678 } 00679 00680 static BOOL DumpDacl(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen) 00681 { 00682 static const WCHAR dacl[] = {'D',':',0}; 00683 SECURITY_DESCRIPTOR_CONTROL control; 00684 BOOL present, defaulted; 00685 DWORD revision; 00686 PACL pacl; 00687 00688 if (!GetSecurityDescriptorDacl(SecurityDescriptor, &present, &pacl, &defaulted)) 00689 return FALSE; 00690 00691 if (!GetSecurityDescriptorControl(SecurityDescriptor, &control, &revision)) 00692 return FALSE; 00693 00694 if (!present) 00695 return TRUE; 00696 00697 DumpString(dacl, 2, pwptr, plen); 00698 if (!DumpAcl(pacl, pwptr, plen, control & SE_DACL_PROTECTED, control & SE_DACL_AUTO_INHERIT_REQ, control & SE_DACL_AUTO_INHERITED)) 00699 return FALSE; 00700 return TRUE; 00701 } 00702 00703 static BOOL DumpSacl(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen) 00704 { 00705 static const WCHAR sacl[] = {'S',':',0}; 00706 SECURITY_DESCRIPTOR_CONTROL control; 00707 BOOL present, defaulted; 00708 DWORD revision; 00709 PACL pacl; 00710 00711 if (!GetSecurityDescriptorSacl(SecurityDescriptor, &present, &pacl, &defaulted)) 00712 return FALSE; 00713 00714 if (!GetSecurityDescriptorControl(SecurityDescriptor, &control, &revision)) 00715 return FALSE; 00716 00717 if (!present) 00718 return TRUE; 00719 00720 DumpString(sacl, 2, pwptr, plen); 00721 if (!DumpAcl(pacl, pwptr, plen, control & SE_SACL_PROTECTED, control & SE_SACL_AUTO_INHERIT_REQ, control & SE_SACL_AUTO_INHERITED)) 00722 return FALSE; 00723 return TRUE; 00724 } 00725 00726 /****************************************************************************** 00727 * ConvertSecurityDescriptorToStringSecurityDescriptorW [ADVAPI32.@] 00728 * @implemented 00729 */ 00730 BOOL WINAPI 00731 ConvertSecurityDescriptorToStringSecurityDescriptorW(PSECURITY_DESCRIPTOR SecurityDescriptor, 00732 DWORD SDRevision, 00733 SECURITY_INFORMATION SecurityInformation, 00734 LPWSTR *OutputString, 00735 PULONG OutputLen) 00736 { 00737 ULONG len; 00738 WCHAR *wptr, *wstr; 00739 00740 if (SDRevision != SDDL_REVISION_1) 00741 { 00742 ERR("Pogram requested unknown SDDL revision %d\n", SDRevision); 00743 SetLastError(ERROR_UNKNOWN_REVISION); 00744 return FALSE; 00745 } 00746 00747 len = 0; 00748 if (SecurityInformation & OWNER_SECURITY_INFORMATION) 00749 if (!DumpOwner(SecurityDescriptor, NULL, &len)) 00750 return FALSE; 00751 if (SecurityInformation & GROUP_SECURITY_INFORMATION) 00752 if (!DumpGroup(SecurityDescriptor, NULL, &len)) 00753 return FALSE; 00754 if (SecurityInformation & DACL_SECURITY_INFORMATION) 00755 if (!DumpDacl(SecurityDescriptor, NULL, &len)) 00756 return FALSE; 00757 if (SecurityInformation & SACL_SECURITY_INFORMATION) 00758 if (!DumpSacl(SecurityDescriptor, NULL, &len)) 00759 return FALSE; 00760 00761 wstr = wptr = LocalAlloc(0, (len + 1)*sizeof(WCHAR)); 00762 if (SecurityInformation & OWNER_SECURITY_INFORMATION) 00763 if (!DumpOwner(SecurityDescriptor, &wptr, NULL)) 00764 return FALSE; 00765 if (SecurityInformation & GROUP_SECURITY_INFORMATION) 00766 if (!DumpGroup(SecurityDescriptor, &wptr, NULL)) 00767 return FALSE; 00768 if (SecurityInformation & DACL_SECURITY_INFORMATION) 00769 if (!DumpDacl(SecurityDescriptor, &wptr, NULL)) 00770 return FALSE; 00771 if (SecurityInformation & SACL_SECURITY_INFORMATION) 00772 if (!DumpSacl(SecurityDescriptor, &wptr, NULL)) 00773 return FALSE; 00774 *wptr = 0; 00775 00776 TRACE("ret: %s, %d\n", wine_dbgstr_w(wstr), len); 00777 *OutputString = wstr; 00778 if (OutputLen) 00779 *OutputLen = strlenW(*OutputString)+1; 00780 return TRUE; 00781 } 00782 00783 00784 /****************************************************************************** 00785 * ConvertSecurityDescriptorToStringSecurityDescriptorA [ADVAPI32.@] 00786 * @implemented 00787 */ 00788 BOOL WINAPI 00789 ConvertSecurityDescriptorToStringSecurityDescriptorA(PSECURITY_DESCRIPTOR SecurityDescriptor, 00790 DWORD SDRevision, 00791 SECURITY_INFORMATION Information, 00792 LPSTR *OutputString, 00793 PULONG OutputLen) 00794 { 00795 LPWSTR wstr; 00796 ULONG len; 00797 if (ConvertSecurityDescriptorToStringSecurityDescriptorW(SecurityDescriptor, SDRevision, Information, &wstr, &len)) 00798 { 00799 int lenA; 00800 00801 lenA = WideCharToMultiByte(CP_ACP, 0, wstr, len, NULL, 0, NULL, NULL); 00802 *OutputString = HeapAlloc(GetProcessHeap(), 0, lenA); 00803 WideCharToMultiByte(CP_ACP, 0, wstr, len, *OutputString, lenA, NULL, NULL); 00804 LocalFree(wstr); 00805 00806 if (OutputLen != NULL) 00807 *OutputLen = lenA; 00808 return TRUE; 00809 } 00810 else 00811 { 00812 *OutputString = NULL; 00813 if (OutputLen) 00814 *OutputLen = 0; 00815 return FALSE; 00816 } 00817 } 00818 00819 00820 /****************************************************************************** 00821 * ComputeStringSidSize 00822 */ 00823 static DWORD ComputeStringSidSize(LPCWSTR StringSid) 00824 { 00825 if (StringSid[0] == 'S' && StringSid[1] == '-') /* S-R-I(-S)+ */ 00826 { 00827 int ctok = 0; 00828 while (*StringSid) 00829 { 00830 if (*StringSid == '-') 00831 ctok++; 00832 StringSid++; 00833 } 00834 00835 if (ctok >= 3) 00836 return GetSidLengthRequired(ctok - 2); 00837 } 00838 else /* String constant format - Only available in winxp and above */ 00839 { 00840 unsigned int i; 00841 00842 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++) 00843 if (!strncmpW(WellKnownSids[i].wstr, StringSid, 2)) 00844 return GetSidLengthRequired(WellKnownSids[i].Sid.SubAuthorityCount); 00845 } 00846 00847 return GetSidLengthRequired(0); 00848 } 00849 00850 /****************************************************************************** 00851 * ParseStringSidToSid 00852 */ 00853 static BOOL ParseStringSidToSid(LPCWSTR StringSid, PSID pSid, LPDWORD cBytes) 00854 { 00855 BOOL bret = FALSE; 00856 SID* pisid=pSid; 00857 00858 TRACE("%s, %p, %p\n", debugstr_w(StringSid), pSid, cBytes); 00859 if (!StringSid) 00860 { 00861 SetLastError(ERROR_INVALID_PARAMETER); 00862 TRACE("StringSid is NULL, returning FALSE\n"); 00863 return FALSE; 00864 } 00865 00866 while (*StringSid == ' ') 00867 StringSid++; 00868 00869 *cBytes = ComputeStringSidSize(StringSid); 00870 if (!pisid) /* Simply compute the size */ 00871 { 00872 TRACE("only size requested, returning TRUE\n"); 00873 return TRUE; 00874 } 00875 00876 if (StringSid[0] == 'S' && StringSid[1] == '-') /* S-R-I-S-S */ 00877 { 00878 DWORD i = 0, identAuth; 00879 DWORD csubauth = ((*cBytes - GetSidLengthRequired(0)) / sizeof(DWORD)); 00880 00881 StringSid += 2; /* Advance to Revision */ 00882 pisid->Revision = atoiW(StringSid); 00883 00884 if (pisid->Revision != SDDL_REVISION) 00885 { 00886 TRACE("Revision %d is unknown\n", pisid->Revision); 00887 goto lend; /* ERROR_INVALID_SID */ 00888 } 00889 if (csubauth == 0) 00890 { 00891 TRACE("SubAuthorityCount is 0\n"); 00892 goto lend; /* ERROR_INVALID_SID */ 00893 } 00894 00895 pisid->SubAuthorityCount = csubauth; 00896 00897 /* Advance to identifier authority */ 00898 while (*StringSid && *StringSid != '-') 00899 StringSid++; 00900 if (*StringSid == '-') 00901 StringSid++; 00902 00903 /* MS' implementation can't handle values greater than 2^32 - 1, so 00904 * we don't either; assume most significant bytes are always 0 00905 */ 00906 pisid->IdentifierAuthority.Value[0] = 0; 00907 pisid->IdentifierAuthority.Value[1] = 0; 00908 identAuth = atoiW(StringSid); 00909 pisid->IdentifierAuthority.Value[5] = identAuth & 0xff; 00910 pisid->IdentifierAuthority.Value[4] = (identAuth & 0xff00) >> 8; 00911 pisid->IdentifierAuthority.Value[3] = (identAuth & 0xff0000) >> 16; 00912 pisid->IdentifierAuthority.Value[2] = (identAuth & 0xff000000) >> 24; 00913 00914 /* Advance to first sub authority */ 00915 while (*StringSid && *StringSid != '-') 00916 StringSid++; 00917 if (*StringSid == '-') 00918 StringSid++; 00919 00920 while (*StringSid) 00921 { 00922 pisid->SubAuthority[i++] = atoiW(StringSid); 00923 00924 while (*StringSid && *StringSid != '-') 00925 StringSid++; 00926 if (*StringSid == '-') 00927 StringSid++; 00928 } 00929 00930 if (i != pisid->SubAuthorityCount) 00931 goto lend; /* ERROR_INVALID_SID */ 00932 00933 bret = TRUE; 00934 } 00935 else /* String constant format - Only available in winxp and above */ 00936 { 00937 unsigned int i; 00938 pisid->Revision = SDDL_REVISION; 00939 00940 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++) 00941 if (!strncmpW(WellKnownSids[i].wstr, StringSid, 2)) 00942 { 00943 DWORD j; 00944 pisid->SubAuthorityCount = WellKnownSids[i].Sid.SubAuthorityCount; 00945 pisid->IdentifierAuthority = WellKnownSids[i].Sid.IdentifierAuthority; 00946 for (j = 0; j < WellKnownSids[i].Sid.SubAuthorityCount; j++) 00947 pisid->SubAuthority[j] = WellKnownSids[i].Sid.SubAuthority[j]; 00948 bret = TRUE; 00949 } 00950 00951 if (!bret) 00952 FIXME("String constant not supported: %s\n", debugstr_wn(StringSid, 2)); 00953 } 00954 00955 lend: 00956 if (!bret) 00957 SetLastError(ERROR_INVALID_SID); 00958 00959 TRACE("returning %s\n", bret ? "TRUE" : "FALSE"); 00960 return bret; 00961 } 00962 00963 /****************************************************************************** 00964 * ParseAclStringFlags 00965 */ 00966 static DWORD ParseAclStringFlags(LPCWSTR* StringAcl) 00967 { 00968 DWORD flags = 0; 00969 LPCWSTR szAcl = *StringAcl; 00970 00971 while (*szAcl != '(') 00972 { 00973 if (*szAcl == 'P') 00974 { 00975 flags |= SE_DACL_PROTECTED; 00976 } 00977 else if (*szAcl == 'A') 00978 { 00979 szAcl++; 00980 if (*szAcl == 'R') 00981 flags |= SE_DACL_AUTO_INHERIT_REQ; 00982 else if (*szAcl == 'I') 00983 flags |= SE_DACL_AUTO_INHERITED; 00984 } 00985 szAcl++; 00986 } 00987 00988 *StringAcl = szAcl; 00989 return flags; 00990 } 00991 00992 /****************************************************************************** 00993 * ParseAceStringType 00994 */ 00995 static const ACEFLAG AceType[] = 00996 { 00997 { SDDL_ALARM, SYSTEM_ALARM_ACE_TYPE }, 00998 { SDDL_AUDIT, SYSTEM_AUDIT_ACE_TYPE }, 00999 { SDDL_ACCESS_ALLOWED, ACCESS_ALLOWED_ACE_TYPE }, 01000 { SDDL_ACCESS_DENIED, ACCESS_DENIED_ACE_TYPE }, 01001 /* 01002 { SDDL_OBJECT_ACCESS_ALLOWED, ACCESS_ALLOWED_OBJECT_ACE_TYPE }, 01003 { SDDL_OBJECT_ACCESS_DENIED, ACCESS_DENIED_OBJECT_ACE_TYPE }, 01004 { SDDL_OBJECT_ALARM, SYSTEM_ALARM_OBJECT_ACE_TYPE }, 01005 { SDDL_OBJECT_AUDIT, SYSTEM_AUDIT_OBJECT_ACE_TYPE }, 01006 */ 01007 { NULL, 0 }, 01008 }; 01009 01010 static BYTE ParseAceStringType(LPCWSTR* StringAcl) 01011 { 01012 UINT len = 0; 01013 LPCWSTR szAcl = *StringAcl; 01014 const ACEFLAG *lpaf = AceType; 01015 01016 while (lpaf->wstr && 01017 (len = strlenW(lpaf->wstr)) && 01018 strncmpW(lpaf->wstr, szAcl, len)) 01019 lpaf++; 01020 01021 if (!lpaf->wstr) 01022 return 0; 01023 01024 *StringAcl += len; 01025 return lpaf->value; 01026 } 01027 01028 01029 /****************************************************************************** 01030 * ParseAceStringFlags 01031 */ 01032 static const ACEFLAG AceFlags[] = 01033 { 01034 { SDDL_CONTAINER_INHERIT, CONTAINER_INHERIT_ACE }, 01035 { SDDL_AUDIT_FAILURE, FAILED_ACCESS_ACE_FLAG }, 01036 { SDDL_INHERITED, INHERITED_ACE }, 01037 { SDDL_INHERIT_ONLY, INHERIT_ONLY_ACE }, 01038 { SDDL_NO_PROPAGATE, NO_PROPAGATE_INHERIT_ACE }, 01039 { SDDL_OBJECT_INHERIT, OBJECT_INHERIT_ACE }, 01040 { SDDL_AUDIT_SUCCESS, SUCCESSFUL_ACCESS_ACE_FLAG }, 01041 { NULL, 0 }, 01042 }; 01043 01044 static BYTE ParseAceStringFlags(LPCWSTR* StringAcl) 01045 { 01046 UINT len = 0; 01047 BYTE flags = 0; 01048 LPCWSTR szAcl = *StringAcl; 01049 01050 while (*szAcl != ';') 01051 { 01052 const ACEFLAG *lpaf = AceFlags; 01053 01054 while (lpaf->wstr && 01055 (len = strlenW(lpaf->wstr)) && 01056 strncmpW(lpaf->wstr, szAcl, len)) 01057 lpaf++; 01058 01059 if (!lpaf->wstr) 01060 return 0; 01061 01062 flags |= lpaf->value; 01063 szAcl += len; 01064 } 01065 01066 *StringAcl = szAcl; 01067 return flags; 01068 } 01069 01070 01071 /****************************************************************************** 01072 * ParseAceStringRights 01073 */ 01074 static DWORD ParseAceStringRights(LPCWSTR* StringAcl) 01075 { 01076 UINT len = 0; 01077 DWORD rights = 0; 01078 LPCWSTR szAcl = *StringAcl; 01079 01080 if ((*szAcl == '0') && (*(szAcl + 1) == 'x')) 01081 { 01082 LPCWSTR p = szAcl; 01083 01084 while (*p && *p != ';') 01085 p++; 01086 01087 if (p - szAcl <= 10 /* 8 hex digits + "0x" */ ) 01088 { 01089 rights = strtoulW(szAcl, NULL, 16); 01090 szAcl = p; 01091 } 01092 else 01093 WARN("Invalid rights string format: %s\n", debugstr_wn(szAcl, p - szAcl)); 01094 } 01095 else 01096 { 01097 while (*szAcl != ';') 01098 { 01099 const ACEFLAG *lpaf = AceRights; 01100 01101 while (lpaf->wstr && 01102 (len = strlenW(lpaf->wstr)) && 01103 strncmpW(lpaf->wstr, szAcl, len)) 01104 { 01105 lpaf++; 01106 } 01107 01108 if (!lpaf->wstr) 01109 return 0; 01110 01111 rights |= lpaf->value; 01112 szAcl += len; 01113 } 01114 } 01115 01116 *StringAcl = szAcl; 01117 return rights; 01118 } 01119 01120 01121 /****************************************************************************** 01122 * ParseStringAclToAcl 01123 * 01124 * dacl_flags(string_ace1)(string_ace2)... (string_acen) 01125 */ 01126 static BOOL ParseStringAclToAcl(LPCWSTR StringAcl, LPDWORD lpdwFlags, 01127 PACL pAcl, LPDWORD cBytes) 01128 { 01129 DWORD val; 01130 DWORD sidlen; 01131 DWORD length = sizeof(ACL); 01132 DWORD acesize = 0; 01133 DWORD acecount = 0; 01134 PACCESS_ALLOWED_ACE pAce = NULL; /* pointer to current ACE */ 01135 01136 TRACE("%s\n", debugstr_w(StringAcl)); 01137 01138 if (!StringAcl) 01139 return FALSE; 01140 01141 if (pAcl) /* pAce is only useful if we're setting values */ 01142 pAce = (PACCESS_ALLOWED_ACE) (pAcl + 1); 01143 01144 /* Parse ACL flags */ 01145 *lpdwFlags = ParseAclStringFlags(&StringAcl); 01146 01147 /* Parse ACE */ 01148 while (*StringAcl == '(') 01149 { 01150 StringAcl++; 01151 01152 /* Parse ACE type */ 01153 val = ParseAceStringType(&StringAcl); 01154 if (pAce) 01155 pAce->Header.AceType = (BYTE) val; 01156 if (*StringAcl != ';') 01157 goto lerr; 01158 StringAcl++; 01159 01160 /* Parse ACE flags */ 01161 val = ParseAceStringFlags(&StringAcl); 01162 if (pAce) 01163 pAce->Header.AceFlags = (BYTE) val; 01164 if (*StringAcl != ';') 01165 goto lerr; 01166 StringAcl++; 01167 01168 /* Parse ACE rights */ 01169 val = ParseAceStringRights(&StringAcl); 01170 if (pAce) 01171 pAce->Mask = val; 01172 if (*StringAcl != ';') 01173 goto lerr; 01174 StringAcl++; 01175 01176 /* Parse ACE object guid */ 01177 if (*StringAcl != ';') 01178 { 01179 FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n"); 01180 goto lerr; 01181 } 01182 StringAcl++; 01183 01184 /* Parse ACE inherit object guid */ 01185 if (*StringAcl != ';') 01186 { 01187 FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n"); 01188 goto lerr; 01189 } 01190 StringAcl++; 01191 01192 /* Parse ACE account sid */ 01193 if (ParseStringSidToSid(StringAcl, pAce ? &pAce->SidStart : NULL, &sidlen)) 01194 { 01195 while (*StringAcl && *StringAcl != ')') 01196 StringAcl++; 01197 } 01198 01199 if (*StringAcl != ')') 01200 goto lerr; 01201 StringAcl++; 01202 01203 acesize = sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + sidlen; 01204 length += acesize; 01205 if (pAce) 01206 { 01207 pAce->Header.AceSize = acesize; 01208 pAce = (PACCESS_ALLOWED_ACE)((LPBYTE)pAce + acesize); 01209 } 01210 acecount++; 01211 } 01212 01213 *cBytes = length; 01214 01215 if (length > 0xffff) 01216 { 01217 ERR("ACL too large\n"); 01218 goto lerr; 01219 } 01220 01221 if (pAcl) 01222 { 01223 pAcl->AclRevision = ACL_REVISION; 01224 pAcl->Sbz1 = 0; 01225 pAcl->AclSize = length; 01226 pAcl->AceCount = acecount++; 01227 pAcl->Sbz2 = 0; 01228 } 01229 return TRUE; 01230 01231 lerr: 01232 SetLastError(ERROR_INVALID_ACL); 01233 WARN("Invalid ACE string format\n"); 01234 return FALSE; 01235 } 01236 01237 01238 /****************************************************************************** 01239 * ParseStringSecurityDescriptorToSecurityDescriptor 01240 */ 01241 static BOOL ParseStringSecurityDescriptorToSecurityDescriptor( 01242 LPCWSTR StringSecurityDescriptor, 01243 SECURITY_DESCRIPTOR_RELATIVE* SecurityDescriptor, 01244 LPDWORD cBytes) 01245 { 01246 BOOL bret = FALSE; 01247 WCHAR toktype; 01248 WCHAR tok[MAX_PATH]; 01249 LPCWSTR lptoken; 01250 LPBYTE lpNext = NULL; 01251 DWORD len; 01252 01253 *cBytes = sizeof(SECURITY_DESCRIPTOR); 01254 01255 if (SecurityDescriptor) 01256 lpNext = (LPBYTE)(SecurityDescriptor + 1); 01257 01258 while (*StringSecurityDescriptor) 01259 { 01260 toktype = *StringSecurityDescriptor; 01261 01262 /* Expect char identifier followed by ':' */ 01263 StringSecurityDescriptor++; 01264 if (*StringSecurityDescriptor != ':') 01265 { 01266 SetLastError(ERROR_INVALID_PARAMETER); 01267 goto lend; 01268 } 01269 StringSecurityDescriptor++; 01270 01271 /* Extract token */ 01272 lptoken = StringSecurityDescriptor; 01273 while (*lptoken && *lptoken != ':') 01274 lptoken++; 01275 01276 if (*lptoken) 01277 lptoken--; 01278 01279 len = lptoken - StringSecurityDescriptor; 01280 memcpy( tok, StringSecurityDescriptor, len * sizeof(WCHAR) ); 01281 tok[len] = 0; 01282 01283 switch (toktype) 01284 { 01285 case 'O': 01286 { 01287 DWORD bytes; 01288 01289 if (!ParseStringSidToSid(tok, lpNext, &bytes)) 01290 goto lend; 01291 01292 if (SecurityDescriptor) 01293 { 01294 SecurityDescriptor->Owner = lpNext - (LPBYTE)SecurityDescriptor; 01295 lpNext += bytes; /* Advance to next token */ 01296 } 01297 01298 *cBytes += bytes; 01299 01300 break; 01301 } 01302 01303 case 'G': 01304 { 01305 DWORD bytes; 01306 01307 if (!ParseStringSidToSid(tok, lpNext, &bytes)) 01308 goto lend; 01309 01310 if (SecurityDescriptor) 01311 { 01312 SecurityDescriptor->Group = lpNext - (LPBYTE)SecurityDescriptor; 01313 lpNext += bytes; /* Advance to next token */ 01314 } 01315 01316 *cBytes += bytes; 01317 01318 break; 01319 } 01320 01321 case 'D': 01322 { 01323 DWORD flags; 01324 DWORD bytes; 01325 01326 if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes)) 01327 goto lend; 01328 01329 if (SecurityDescriptor) 01330 { 01331 SecurityDescriptor->Control |= SE_DACL_PRESENT | flags; 01332 SecurityDescriptor->Dacl = lpNext - (LPBYTE)SecurityDescriptor; 01333 lpNext += bytes; /* Advance to next token */ 01334 } 01335 01336 *cBytes += bytes; 01337 01338 break; 01339 } 01340 01341 case 'S': 01342 { 01343 DWORD flags; 01344 DWORD bytes; 01345 01346 if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes)) 01347 goto lend; 01348 01349 if (SecurityDescriptor) 01350 { 01351 SecurityDescriptor->Control |= SE_SACL_PRESENT | flags; 01352 SecurityDescriptor->Sacl = lpNext - (LPBYTE)SecurityDescriptor; 01353 lpNext += bytes; /* Advance to next token */ 01354 } 01355 01356 *cBytes += bytes; 01357 01358 break; 01359 } 01360 01361 default: 01362 FIXME("Unknown token\n"); 01363 SetLastError(ERROR_INVALID_PARAMETER); 01364 goto lend; 01365 } 01366 01367 StringSecurityDescriptor = lptoken; 01368 } 01369 01370 bret = TRUE; 01371 01372 lend: 01373 return bret; 01374 } 01375 01376 01377 /****************************************************************************** 01378 * ConvertStringSecurityDescriptorToSecurityDescriptorW [ADVAPI32.@] 01379 * @implemented 01380 */ 01381 BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorW( 01382 LPCWSTR StringSecurityDescriptor, 01383 DWORD StringSDRevision, 01384 PSECURITY_DESCRIPTOR* SecurityDescriptor, 01385 PULONG SecurityDescriptorSize) 01386 { 01387 DWORD cBytes; 01388 SECURITY_DESCRIPTOR* psd; 01389 BOOL bret = FALSE; 01390 01391 TRACE("%s\n", debugstr_w(StringSecurityDescriptor)); 01392 01393 if (GetVersion() & 0x80000000) 01394 { 01395 SetLastError(ERROR_CALL_NOT_IMPLEMENTED); 01396 goto lend; 01397 } 01398 else if (!StringSecurityDescriptor || !SecurityDescriptor) 01399 { 01400 SetLastError(ERROR_INVALID_PARAMETER); 01401 goto lend; 01402 } 01403 else if (StringSDRevision != SID_REVISION) 01404 { 01405 SetLastError(ERROR_UNKNOWN_REVISION); 01406 goto lend; 01407 } 01408 01409 /* Compute security descriptor length */ 01410 if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor, 01411 NULL, &cBytes)) 01412 goto lend; 01413 01414 psd = *SecurityDescriptor = LocalAlloc(GMEM_ZEROINIT, cBytes); 01415 if (!psd) goto lend; 01416 01417 psd->Revision = SID_REVISION; 01418 psd->Control |= SE_SELF_RELATIVE; 01419 01420 if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor, 01421 (SECURITY_DESCRIPTOR_RELATIVE *)psd, &cBytes)) 01422 { 01423 LocalFree(psd); 01424 goto lend; 01425 } 01426 01427 if (SecurityDescriptorSize) 01428 *SecurityDescriptorSize = cBytes; 01429 01430 bret = TRUE; 01431 01432 lend: 01433 TRACE(" ret=%d\n", bret); 01434 return bret; 01435 } 01436 01437 01438 /* Winehq cvs 20050916 */ 01439 /****************************************************************************** 01440 * ConvertStringSecurityDescriptorToSecurityDescriptorA [ADVAPI32.@] 01441 * @implemented 01442 */ 01443 BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorA( 01444 LPCSTR StringSecurityDescriptor, 01445 DWORD StringSDRevision, 01446 PSECURITY_DESCRIPTOR* SecurityDescriptor, 01447 PULONG SecurityDescriptorSize) 01448 { 01449 UINT len; 01450 BOOL ret = FALSE; 01451 LPWSTR StringSecurityDescriptorW; 01452 01453 len = MultiByteToWideChar(CP_ACP, 0, StringSecurityDescriptor, -1, NULL, 0); 01454 StringSecurityDescriptorW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); 01455 01456 if (StringSecurityDescriptorW) 01457 { 01458 MultiByteToWideChar(CP_ACP, 0, StringSecurityDescriptor, -1, StringSecurityDescriptorW, len); 01459 01460 ret = ConvertStringSecurityDescriptorToSecurityDescriptorW(StringSecurityDescriptorW, 01461 StringSDRevision, SecurityDescriptor, 01462 SecurityDescriptorSize); 01463 HeapFree(GetProcessHeap(), 0, StringSecurityDescriptorW); 01464 } 01465 01466 return ret; 01467 } 01468 01469 /* 01470 * @implemented 01471 */ 01472 BOOL WINAPI 01473 EqualPrefixSid(PSID pSid1, 01474 PSID pSid2) 01475 { 01476 return RtlEqualPrefixSid (pSid1, pSid2); 01477 } 01478 01479 01480 /* 01481 * @implemented 01482 */ 01483 BOOL WINAPI 01484 EqualSid(PSID pSid1, 01485 PSID pSid2) 01486 { 01487 return RtlEqualSid (pSid1, pSid2); 01488 } 01489 01490 01491 /* 01492 * @implemented 01493 * 01494 * RETURNS 01495 * Docs says this function does NOT return a value 01496 * even thou it's defined to return a PVOID... 01497 */ 01498 PVOID WINAPI 01499 FreeSid(PSID pSid) 01500 { 01501 return RtlFreeSid(pSid); 01502 } 01503 01504 01505 /* 01506 * @implemented 01507 */ 01508 DWORD WINAPI 01509 GetLengthSid(PSID pSid) 01510 { 01511 return (DWORD)RtlLengthSid(pSid); 01512 } 01513 01514 01515 /* 01516 * @implemented 01517 */ 01518 PSID_IDENTIFIER_AUTHORITY WINAPI 01519 GetSidIdentifierAuthority(PSID pSid) 01520 { 01521 return RtlIdentifierAuthoritySid(pSid); 01522 } 01523 01524 01525 /* 01526 * @implemented 01527 */ 01528 DWORD WINAPI 01529 GetSidLengthRequired(UCHAR nSubAuthorityCount) 01530 { 01531 return (DWORD)RtlLengthRequiredSid(nSubAuthorityCount); 01532 } 01533 01534 01535 /* 01536 * @implemented 01537 */ 01538 PDWORD WINAPI 01539 GetSidSubAuthority(PSID pSid, 01540 DWORD nSubAuthority) 01541 { 01542 return (PDWORD)RtlSubAuthoritySid(pSid, nSubAuthority); 01543 } 01544 01545 01546 /* 01547 * @implemented 01548 */ 01549 PUCHAR WINAPI 01550 GetSidSubAuthorityCount(PSID pSid) 01551 { 01552 return RtlSubAuthorityCountSid(pSid); 01553 } 01554 01555 01556 /* 01557 * @implemented 01558 */ 01559 BOOL WINAPI 01560 InitializeSid(PSID Sid, 01561 PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority, 01562 BYTE nSubAuthorityCount) 01563 { 01564 NTSTATUS Status; 01565 01566 Status = RtlInitializeSid(Sid, 01567 pIdentifierAuthority, 01568 nSubAuthorityCount); 01569 if (!NT_SUCCESS(Status)) 01570 { 01571 SetLastError(RtlNtStatusToDosError(Status)); 01572 return FALSE; 01573 } 01574 01575 return TRUE; 01576 } 01577 01578 01579 /* 01580 * @implemented 01581 */ 01582 BOOL WINAPI 01583 IsValidSid(PSID pSid) 01584 { 01585 return (BOOL)RtlValidSid(pSid); 01586 } 01587 01588 01589 /* 01590 * @implemented 01591 */ 01592 BOOL WINAPI 01593 ConvertSidToStringSidW(PSID Sid, 01594 LPWSTR *StringSid) 01595 { 01596 NTSTATUS Status; 01597 UNICODE_STRING UnicodeString; 01598 WCHAR FixedBuffer[64]; 01599 01600 if (!RtlValidSid(Sid)) 01601 { 01602 SetLastError(ERROR_INVALID_SID); 01603 return FALSE; 01604 } 01605 01606 UnicodeString.Length = 0; 01607 UnicodeString.MaximumLength = sizeof(FixedBuffer); 01608 UnicodeString.Buffer = FixedBuffer; 01609 Status = RtlConvertSidToUnicodeString(&UnicodeString, Sid, FALSE); 01610 if (STATUS_BUFFER_TOO_SMALL == Status) 01611 { 01612 Status = RtlConvertSidToUnicodeString(&UnicodeString, Sid, TRUE); 01613 } 01614 01615 if (!NT_SUCCESS(Status)) 01616 { 01617 SetLastError(RtlNtStatusToDosError(Status)); 01618 return FALSE; 01619 } 01620 01621 *StringSid = LocalAlloc(LMEM_FIXED, UnicodeString.Length + sizeof(WCHAR)); 01622 if (NULL == *StringSid) 01623 { 01624 if (UnicodeString.Buffer != FixedBuffer) 01625 { 01626 RtlFreeUnicodeString(&UnicodeString); 01627 } 01628 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 01629 return FALSE; 01630 } 01631 01632 MoveMemory(*StringSid, UnicodeString.Buffer, UnicodeString.Length); 01633 ZeroMemory((PCHAR) *StringSid + UnicodeString.Length, sizeof(WCHAR)); 01634 if (UnicodeString.Buffer != FixedBuffer) 01635 { 01636 RtlFreeUnicodeString(&UnicodeString); 01637 } 01638 01639 return TRUE; 01640 } 01641 01642 01643 /* 01644 * @implemented 01645 */ 01646 BOOL WINAPI 01647 ConvertSidToStringSidA(PSID Sid, 01648 LPSTR *StringSid) 01649 { 01650 LPWSTR StringSidW; 01651 int Len; 01652 01653 if (!ConvertSidToStringSidW(Sid, &StringSidW)) 01654 { 01655 return FALSE; 01656 } 01657 01658 Len = WideCharToMultiByte(CP_ACP, 0, StringSidW, -1, NULL, 0, NULL, NULL); 01659 if (Len <= 0) 01660 { 01661 LocalFree(StringSidW); 01662 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 01663 return FALSE; 01664 } 01665 01666 *StringSid = LocalAlloc(LMEM_FIXED, Len); 01667 if (NULL == *StringSid) 01668 { 01669 LocalFree(StringSidW); 01670 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 01671 return FALSE; 01672 } 01673 01674 if (!WideCharToMultiByte(CP_ACP, 0, StringSidW, -1, *StringSid, Len, NULL, NULL)) 01675 { 01676 LocalFree(StringSid); 01677 LocalFree(StringSidW); 01678 return FALSE; 01679 } 01680 01681 LocalFree(StringSidW); 01682 01683 return TRUE; 01684 } 01685 01686 01687 /* 01688 * @unimplemented 01689 */ 01690 BOOL WINAPI 01691 EqualDomainSid(IN PSID pSid1, 01692 IN PSID pSid2, 01693 OUT BOOL* pfEqual) 01694 { 01695 UNIMPLEMENTED; 01696 return FALSE; 01697 } 01698 01699 01700 /* 01701 * @unimplemented 01702 */ 01703 BOOL WINAPI 01704 GetWindowsAccountDomainSid(IN PSID pSid, 01705 OUT PSID ppDomainSid, 01706 IN OUT DWORD* cbSid) 01707 { 01708 UNIMPLEMENTED; 01709 return FALSE; 01710 } 01711 01712 01713 /* 01714 * @unimplemented 01715 */ 01716 BOOL WINAPI 01717 CreateWellKnownSid(IN WELL_KNOWN_SID_TYPE WellKnownSidType, 01718 IN PSID DomainSid OPTIONAL, 01719 OUT PSID pSid, 01720 IN OUT DWORD* cbSid) 01721 { 01722 unsigned int i; 01723 TRACE("(%d, %s, %p, %p)\n", WellKnownSidType, debugstr_sid(DomainSid), pSid, cbSid); 01724 01725 if (cbSid == NULL || (DomainSid && !IsValidSid(DomainSid))) 01726 { 01727 SetLastError(ERROR_INVALID_PARAMETER); 01728 return FALSE; 01729 } 01730 01731 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++) { 01732 if (WellKnownSids[i].Type == WellKnownSidType) { 01733 DWORD length = GetSidLengthRequired(WellKnownSids[i].Sid.SubAuthorityCount); 01734 01735 if (*cbSid < length) 01736 { 01737 *cbSid = length; 01738 SetLastError(ERROR_INSUFFICIENT_BUFFER); 01739 return FALSE; 01740 } 01741 if (!pSid) 01742 { 01743 SetLastError(ERROR_INVALID_PARAMETER); 01744 return FALSE; 01745 } 01746 CopyMemory(pSid, &WellKnownSids[i].Sid.Revision, length); 01747 *cbSid = length; 01748 return TRUE; 01749 } 01750 } 01751 01752 if (DomainSid == NULL || *GetSidSubAuthorityCount(DomainSid) == SID_MAX_SUB_AUTHORITIES) 01753 { 01754 SetLastError(ERROR_INVALID_PARAMETER); 01755 return FALSE; 01756 } 01757 01758 for (i = 0; i < sizeof(WellKnownRids)/sizeof(WellKnownRids[0]); i++) 01759 if (WellKnownRids[i].Type == WellKnownSidType) { 01760 UCHAR domain_subauth = *GetSidSubAuthorityCount(DomainSid); 01761 DWORD domain_sid_length = GetSidLengthRequired(domain_subauth); 01762 DWORD output_sid_length = GetSidLengthRequired(domain_subauth + 1); 01763 01764 if (*cbSid < output_sid_length) 01765 { 01766 *cbSid = output_sid_length; 01767 SetLastError(ERROR_INSUFFICIENT_BUFFER); 01768 return FALSE; 01769 } 01770 if (!pSid) 01771 { 01772 SetLastError(ERROR_INVALID_PARAMETER); 01773 return FALSE; 01774 } 01775 CopyMemory(pSid, DomainSid, domain_sid_length); 01776 (*GetSidSubAuthorityCount(pSid))++; 01777 (*GetSidSubAuthority(pSid, domain_subauth)) = WellKnownRids[i].Rid; 01778 *cbSid = output_sid_length; 01779 return TRUE; 01780 } 01781 01782 SetLastError(ERROR_INVALID_PARAMETER); 01783 return FALSE; 01784 } 01785 01786 01787 /* 01788 * @unimplemented 01789 */ 01790 BOOL WINAPI 01791 IsWellKnownSid(IN PSID pSid, 01792 IN WELL_KNOWN_SID_TYPE WellKnownSidType) 01793 { 01794 unsigned int i; 01795 TRACE("(%s, %d)\n", debugstr_sid(pSid), WellKnownSidType); 01796 01797 for (i = 0; i < sizeof(WellKnownSids) / sizeof(WellKnownSids[0]); i++) 01798 { 01799 if (WellKnownSids[i].Type == WellKnownSidType) 01800 { 01801 if (EqualSid(pSid, (PSID)(&WellKnownSids[i].Sid.Revision))) 01802 return TRUE; 01803 } 01804 } 01805 01806 return FALSE; 01807 } 01808 01809 01810 /* 01811 * @implemented 01812 */ 01813 BOOL WINAPI 01814 ConvertStringSidToSidA(IN LPCSTR StringSid, 01815 OUT PSID* sid) 01816 { 01817 BOOL bRetVal = FALSE; 01818 01819 TRACE("%s, %p\n", debugstr_a(StringSid), sid); 01820 if (GetVersion() & 0x80000000) 01821 SetLastError(ERROR_CALL_NOT_IMPLEMENTED); 01822 else if (!StringSid || !sid) 01823 SetLastError(ERROR_INVALID_PARAMETER); 01824 else 01825 { 01826 UINT len = MultiByteToWideChar(CP_ACP, 0, StringSid, -1, NULL, 0); 01827 LPWSTR wStringSid = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); 01828 MultiByteToWideChar(CP_ACP, 0, StringSid, - 1, wStringSid, len); 01829 bRetVal = ConvertStringSidToSidW(wStringSid, sid); 01830 HeapFree(GetProcessHeap(), 0, wStringSid); 01831 } 01832 return bRetVal; 01833 } 01834 01835 01836 static const RECORD SidTable[] = 01837 { 01838 { SDDL_ACCOUNT_OPERATORS, WinBuiltinAccountOperatorsSid }, 01839 { SDDL_ALIAS_PREW2KCOMPACC, WinBuiltinPreWindows2000CompatibleAccessSid }, 01840 { SDDL_ANONYMOUS, WinAnonymousSid }, 01841 { SDDL_AUTHENTICATED_USERS, WinAuthenticatedUserSid }, 01842 { SDDL_BUILTIN_ADMINISTRATORS, WinBuiltinAdministratorsSid }, 01843 { SDDL_BUILTIN_GUESTS, WinBuiltinGuestsSid }, 01844 { SDDL_BACKUP_OPERATORS, WinBuiltinBackupOperatorsSid }, 01845 { SDDL_BUILTIN_USERS, WinBuiltinUsersSid }, 01846 { SDDL_CERT_SERV_ADMINISTRATORS, WinAccountCertAdminsSid /* FIXME: DOMAIN_GROUP_RID_CERT_ADMINS */ }, 01847 { SDDL_CREATOR_GROUP, WinCreatorGroupSid }, 01848 { SDDL_CREATOR_OWNER, WinCreatorOwnerSid }, 01849 { SDDL_DOMAIN_ADMINISTRATORS, WinAccountDomainAdminsSid /* FIXME: DOMAIN_GROUP_RID_ADMINS */ }, 01850 { SDDL_DOMAIN_COMPUTERS, WinAccountComputersSid /* FIXME: DOMAIN_GROUP_RID_COMPUTERS */ }, 01851 { SDDL_DOMAIN_DOMAIN_CONTROLLERS, WinAccountControllersSid /* FIXME: DOMAIN_GROUP_RID_CONTROLLERS */ }, 01852 { SDDL_DOMAIN_GUESTS, WinAccountDomainGuestsSid /* FIXME: DOMAIN_GROUP_RID_GUESTS */ }, 01853 { SDDL_DOMAIN_USERS, WinAccountDomainUsersSid /* FIXME: DOMAIN_GROUP_RID_USERS */ }, 01854 { SDDL_ENTERPRISE_ADMINS, WinAccountEnterpriseAdminsSid /* FIXME: DOMAIN_GROUP_RID_ENTERPRISE_ADMINS */ }, 01855 { SDDL_ENTERPRISE_DOMAIN_CONTROLLERS, WinLogonIdsSid /* FIXME: SECURITY_SERVER_LOGON_RID */ }, 01856 { SDDL_EVERYONE, WinWorldSid }, 01857 { SDDL_GROUP_POLICY_ADMINS, WinAccountPolicyAdminsSid /* FIXME: DOMAIN_GROUP_RID_POLICY_ADMINS */ }, 01858 { SDDL_INTERACTIVE, WinInteractiveSid }, 01859 { SDDL_LOCAL_ADMIN, WinAccountAdministratorSid /* FIXME: DOMAIN_USER_RID_ADMIN */ }, 01860 { SDDL_LOCAL_GUEST, WinAccountGuestSid /* FIXME: DOMAIN_USER_RID_GUEST */ }, 01861 { SDDL_LOCAL_SERVICE, WinLocalServiceSid }, 01862 { SDDL_LOCAL_SYSTEM, WinLocalSystemSid }, 01863 { SDDL_NETWORK, WinNetworkSid }, 01864 { SDDL_NETWORK_CONFIGURATION_OPS, WinBuiltinNetworkConfigurationOperatorsSid }, 01865 { SDDL_NETWORK_SERVICE, WinNetworkServiceSid }, 01866 { SDDL_PRINTER_OPERATORS, WinBuiltinPrintOperatorsSid }, 01867 { SDDL_PERSONAL_SELF, WinSelfSid }, 01868 { SDDL_POWER_USERS, WinBuiltinPowerUsersSid }, 01869 { SDDL_RAS_SERVERS, WinAccountRasAndIasServersSid /* FIXME: DOMAIN_ALIAS_RID_RAS_SERVERS */ }, 01870 { SDDL_REMOTE_DESKTOP, WinBuiltinRemoteDesktopUsersSid }, 01871 { SDDL_REPLICATOR, WinBuiltinReplicatorSid }, 01872 { SDDL_RESTRICTED_CODE, WinRestrictedCodeSid }, 01873 { SDDL_SCHEMA_ADMINISTRATORS, WinAccountSchemaAdminsSid /* FIXME: DOMAIN_GROUP_RID_SCHEMA_ADMINS */ }, 01874 { SDDL_SERVER_OPERATORS, WinBuiltinSystemOperatorsSid }, 01875 { SDDL_SERVICE, WinServiceSid }, 01876 { NULL, 0 }, 01877 }; 01878 01879 /* 01880 * @implemented 01881 */ 01882 BOOL WINAPI 01883 ConvertStringSidToSidW(IN LPCWSTR StringSid, 01884 OUT PSID* sid) 01885 { 01886 DWORD size; 01887 DWORD i, cBytes, identAuth, csubauth; 01888 BOOL ret; 01889 SID* pisid; 01890 01891 TRACE("%s %p\n", debugstr_w(StringSid), sid); 01892 01893 if (!StringSid) 01894 { 01895 SetLastError(ERROR_INVALID_SID); 01896 return FALSE; 01897 } 01898 for (i = 0; i < sizeof(SidTable) / sizeof(SidTable[0]) - 1; i++) 01899 { 01900 if (wcscmp(StringSid, SidTable[i].key) == 0) 01901 { 01902 WELL_KNOWN_SID_TYPE knownSid = (WELL_KNOWN_SID_TYPE)SidTable[i].value; 01903 size = SECURITY_MAX_SID_SIZE; 01904 *sid = LocalAlloc(0, size); 01905 if (!*sid) 01906 { 01907 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 01908 return FALSE; 01909 } 01910 ret = CreateWellKnownSid( 01911 knownSid, 01912 NULL, 01913 *sid, 01914 &size); 01915 if (!ret) 01916 { 01917 SetLastError(ERROR_INVALID_SID); 01918 LocalFree(*sid); 01919 } 01920 return ret; 01921 } 01922 } 01923 01924 /* That's probably a string S-R-I-S-S... */ 01925 if (StringSid[0] != 'S' || StringSid[1] != '-') 01926 { 01927 SetLastError(ERROR_INVALID_SID); 01928 return FALSE; 01929 } 01930 01931 cBytes = ComputeStringSidSize(StringSid); 01932 pisid = (SID*)LocalAlloc( 0, cBytes ); 01933 if (!pisid) 01934 { 01935 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 01936 return FALSE; 01937 } 01938 i = 0; 01939 ret = FALSE; 01940 csubauth = ((cBytes - GetSidLengthRequired(0)) / sizeof(DWORD)); 01941 01942 StringSid += 2; /* Advance to Revision */ 01943 pisid->Revision = atoiW(StringSid); 01944 01945 if (pisid->Revision != SDDL_REVISION) 01946 { 01947 TRACE("Revision %d is unknown\n", pisid->Revision); 01948 goto lend; /* ERROR_INVALID_SID */ 01949 } 01950 if (csubauth == 0) 01951 { 01952 TRACE("SubAuthorityCount is 0\n"); 01953 goto lend; /* ERROR_INVALID_SID */ 01954 } 01955 01956 pisid->SubAuthorityCount = csubauth; 01957 01958 /* Advance to identifier authority */ 01959 while (*StringSid && *StringSid != '-') 01960 StringSid++; 01961 if (*StringSid == '-') 01962 StringSid++; 01963 01964 /* MS' implementation can't handle values greater than 2^32 - 1, so 01965 * we don't either; assume most significant bytes are always 0 01966 */ 01967 pisid->IdentifierAuthority.Value[0] = 0; 01968 pisid->IdentifierAuthority.Value[1] = 0; 01969 identAuth = atoiW(StringSid); 01970 pisid->IdentifierAuthority.Value[5] = identAuth & 0xff; 01971 pisid->IdentifierAuthority.Value[4] = (identAuth & 0xff00) >> 8; 01972 pisid->IdentifierAuthority.Value[3] = (identAuth & 0xff0000) >> 16; 01973 pisid->IdentifierAuthority.Value[2] = (identAuth & 0xff000000) >> 24; 01974 01975 /* Advance to first sub authority */ 01976 while (*StringSid && *StringSid != '-') 01977 StringSid++; 01978 if (*StringSid == '-') 01979 StringSid++; 01980 01981 while (*StringSid) 01982 { 01983 pisid->SubAuthority[i++] = atoiW(StringSid); 01984 01985 while (*StringSid && *StringSid != '-') 01986 StringSid++; 01987 if (*StringSid == '-') 01988 StringSid++; 01989 } 01990 01991 if (i != pisid->SubAuthorityCount) 01992 goto lend; /* ERROR_INVALID_SID */ 01993 01994 *sid = pisid; 01995 ret = TRUE; 01996 01997 lend: 01998 if (!ret) 01999 { 02000 LocalFree(pisid); 02001 SetLastError(ERROR_INVALID_SID); 02002 } 02003 02004 TRACE("returning %s\n", ret ? "TRUE" : "FALSE"); 02005 return ret; 02006 } 02007 02008 02009 /* EOF */ Generated on Sun May 27 2012 04:22:44 for ReactOS by
1.7.6.1
|