2 * COPYRIGHT: See COPYING in the top level directory
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
9 * PROJECT: ReactOS system libraries
10 * FILE: dll/win32/advapi32/sec/sid.c
11 * PURPOSE: Security ID functions
16 #include <wine/debug.h>
17 #include <wine/unicode.h>
19 WINE_DEFAULT_DEBUG_CHANNEL(advapi
);
21 #define MAX_GUID_STRING_LEN 39
24 AddAuditAccessAceEx(PACL pAcl
,
39 typedef struct _MAX_SID
41 /* same fields as struct _SID */
43 BYTE SubAuthorityCount
;
44 SID_IDENTIFIER_AUTHORITY IdentifierAuthority
;
45 DWORD SubAuthority
[SID_MAX_SUB_AUTHORITIES
];
48 typedef struct WELLKNOWNSID
51 WELL_KNOWN_SID_TYPE Type
;
55 typedef struct _ACEFLAG
59 } ACEFLAG
, *LPACEFLAG
;
61 static const WELLKNOWNSID WellKnownSids
[] =
63 { {0,0}, WinNullSid
, { SID_REVISION
, 1, { SECURITY_NULL_SID_AUTHORITY
}, { SECURITY_NULL_RID
} } },
64 { {'W','D'}, WinWorldSid
, { SID_REVISION
, 1, { SECURITY_WORLD_SID_AUTHORITY
}, { SECURITY_WORLD_RID
} } },
65 { {0,0}, WinLocalSid
, { SID_REVISION
, 1, { SECURITY_LOCAL_SID_AUTHORITY
}, { SECURITY_LOCAL_RID
} } },
66 { {'C','O'}, WinCreatorOwnerSid
, { SID_REVISION
, 1, { SECURITY_CREATOR_SID_AUTHORITY
}, { SECURITY_CREATOR_OWNER_RID
} } },
67 { {'C','G'}, WinCreatorGroupSid
, { SID_REVISION
, 1, { SECURITY_CREATOR_SID_AUTHORITY
}, { SECURITY_CREATOR_GROUP_RID
} } },
68 { {0,0}, WinCreatorOwnerServerSid
, { SID_REVISION
, 1, { SECURITY_CREATOR_SID_AUTHORITY
}, { SECURITY_CREATOR_OWNER_SERVER_RID
} } },
69 { {0,0}, WinCreatorGroupServerSid
, { SID_REVISION
, 1, { SECURITY_CREATOR_SID_AUTHORITY
}, { SECURITY_CREATOR_GROUP_SERVER_RID
} } },
70 { {0,0}, WinNtAuthoritySid
, { SID_REVISION
, 0, { SECURITY_NT_AUTHORITY
}, { SECURITY_NULL_RID
} } },
71 { {0,0}, WinDialupSid
, { SID_REVISION
, 1, { SECURITY_NT_AUTHORITY
}, { SECURITY_DIALUP_RID
} } },
72 { {'N','U'}, WinNetworkSid
, { SID_REVISION
, 1, { SECURITY_NT_AUTHORITY
}, { SECURITY_NETWORK_RID
} } },
73 { {0,0}, WinBatchSid
, { SID_REVISION
, 1, { SECURITY_NT_AUTHORITY
}, { SECURITY_BATCH_RID
} } },
74 { {'I','U'}, WinInteractiveSid
, { SID_REVISION
, 1, { SECURITY_NT_AUTHORITY
}, { SECURITY_INTERACTIVE_RID
} } },
75 { {'S','U'}, WinServiceSid
, { SID_REVISION
, 1, { SECURITY_NT_AUTHORITY
}, { SECURITY_SERVICE_RID
} } },
76 { {'A','N'}, WinAnonymousSid
, { SID_REVISION
, 1, { SECURITY_NT_AUTHORITY
}, { SECURITY_ANONYMOUS_LOGON_RID
} } },
77 { {0,0}, WinProxySid
, { SID_REVISION
, 1, { SECURITY_NT_AUTHORITY
}, { SECURITY_PROXY_RID
} } },
78 { {'E','D'}, WinEnterpriseControllersSid
, { SID_REVISION
, 1, { SECURITY_NT_AUTHORITY
}, { SECURITY_ENTERPRISE_CONTROLLERS_RID
} } },
79 { {'P','S'}, WinSelfSid
, { SID_REVISION
, 1, { SECURITY_NT_AUTHORITY
}, { SECURITY_PRINCIPAL_SELF_RID
} } },
80 { {'A','U'}, WinAuthenticatedUserSid
, { SID_REVISION
, 1, { SECURITY_NT_AUTHORITY
}, { SECURITY_AUTHENTICATED_USER_RID
} } },
81 { {'R','C'}, WinRestrictedCodeSid
, { SID_REVISION
, 1, { SECURITY_NT_AUTHORITY
}, { SECURITY_RESTRICTED_CODE_RID
} } },
82 { {0,0}, WinTerminalServerSid
, { SID_REVISION
, 1, { SECURITY_NT_AUTHORITY
}, { SECURITY_TERMINAL_SERVER_RID
} } },
83 { {0,0}, WinRemoteLogonIdSid
, { SID_REVISION
, 1, { SECURITY_NT_AUTHORITY
}, { SECURITY_REMOTE_LOGON_RID
} } },
84 { {'S','Y'}, WinLocalSystemSid
, { SID_REVISION
, 1, { SECURITY_NT_AUTHORITY
}, { SECURITY_LOCAL_SYSTEM_RID
} } },
85 { {'L','S'}, WinLocalServiceSid
, { SID_REVISION
, 1, { SECURITY_NT_AUTHORITY
}, { SECURITY_LOCAL_SERVICE_RID
} } },
86 { {'N','S'}, WinNetworkServiceSid
, { SID_REVISION
, 1, { SECURITY_NT_AUTHORITY
}, { SECURITY_NETWORK_SERVICE_RID
} } },
87 { {0,0}, WinBuiltinDomainSid
, { SID_REVISION
, 1, { SECURITY_NT_AUTHORITY
}, { SECURITY_BUILTIN_DOMAIN_RID
} } },
88 { {'B','A'}, WinBuiltinAdministratorsSid
, { SID_REVISION
, 2, { SECURITY_NT_AUTHORITY
}, { SECURITY_BUILTIN_DOMAIN_RID
, DOMAIN_ALIAS_RID_ADMINS
} } },
89 { {'B','U'}, WinBuiltinUsersSid
, { SID_REVISION
, 2, { SECURITY_NT_AUTHORITY
}, { SECURITY_BUILTIN_DOMAIN_RID
, DOMAIN_ALIAS_RID_USERS
} } },
90 { {'B','G'}, WinBuiltinGuestsSid
, { SID_REVISION
, 2, { SECURITY_NT_AUTHORITY
}, { SECURITY_BUILTIN_DOMAIN_RID
, DOMAIN_ALIAS_RID_GUESTS
} } },
91 { {'P','U'}, WinBuiltinPowerUsersSid
, { SID_REVISION
, 2, { SECURITY_NT_AUTHORITY
}, { SECURITY_BUILTIN_DOMAIN_RID
, DOMAIN_ALIAS_RID_POWER_USERS
} } },
92 { {'A','O'}, WinBuiltinAccountOperatorsSid
, { SID_REVISION
, 2, { SECURITY_NT_AUTHORITY
}, { SECURITY_BUILTIN_DOMAIN_RID
, DOMAIN_ALIAS_RID_ACCOUNT_OPS
} } },
93 { {'S','O'}, WinBuiltinSystemOperatorsSid
, { SID_REVISION
, 2, { SECURITY_NT_AUTHORITY
}, { SECURITY_BUILTIN_DOMAIN_RID
, DOMAIN_ALIAS_RID_SYSTEM_OPS
} } },
94 { {'P','O'}, WinBuiltinPrintOperatorsSid
, { SID_REVISION
, 2, { SECURITY_NT_AUTHORITY
}, { SECURITY_BUILTIN_DOMAIN_RID
, DOMAIN_ALIAS_RID_PRINT_OPS
} } },
95 { {'B','O'}, WinBuiltinBackupOperatorsSid
, { SID_REVISION
, 2, { SECURITY_NT_AUTHORITY
}, { SECURITY_BUILTIN_DOMAIN_RID
, DOMAIN_ALIAS_RID_BACKUP_OPS
} } },
96 { {'R','E'}, WinBuiltinReplicatorSid
, { SID_REVISION
, 2, { SECURITY_NT_AUTHORITY
}, { SECURITY_BUILTIN_DOMAIN_RID
, DOMAIN_ALIAS_RID_REPLICATOR
} } },
97 { {'R','U'}, WinBuiltinPreWindows2000CompatibleAccessSid
, { SID_REVISION
, 2, { SECURITY_NT_AUTHORITY
}, { SECURITY_BUILTIN_DOMAIN_RID
, DOMAIN_ALIAS_RID_PREW2KCOMPACCESS
} } },
98 { {'R','D'}, WinBuiltinRemoteDesktopUsersSid
, { SID_REVISION
, 2, { SECURITY_NT_AUTHORITY
}, { SECURITY_BUILTIN_DOMAIN_RID
, DOMAIN_ALIAS_RID_REMOTE_DESKTOP_USERS
} } },
99 { {'N','O'}, WinBuiltinNetworkConfigurationOperatorsSid
, { SID_REVISION
, 2, { SECURITY_NT_AUTHORITY
}, { SECURITY_BUILTIN_DOMAIN_RID
, DOMAIN_ALIAS_RID_NETWORK_CONFIGURATION_OPS
} } },
100 { {0,0}, WinNTLMAuthenticationSid
, { SID_REVISION
, 2, { SECURITY_NT_AUTHORITY
}, { SECURITY_PACKAGE_BASE_RID
, SECURITY_PACKAGE_NTLM_RID
} } },
101 { {0,0}, WinDigestAuthenticationSid
, { SID_REVISION
, 2, { SECURITY_NT_AUTHORITY
}, { SECURITY_PACKAGE_BASE_RID
, SECURITY_PACKAGE_DIGEST_RID
} } },
102 { {0,0}, WinSChannelAuthenticationSid
, { SID_REVISION
, 2, { SECURITY_NT_AUTHORITY
}, { SECURITY_PACKAGE_BASE_RID
, SECURITY_PACKAGE_SCHANNEL_RID
} } },
103 { {0,0}, WinThisOrganizationSid
, { SID_REVISION
, 1, { SECURITY_NT_AUTHORITY
}, { SECURITY_THIS_ORGANIZATION_RID
} } },
104 { {0,0}, WinOtherOrganizationSid
, { SID_REVISION
, 1, { SECURITY_NT_AUTHORITY
}, { SECURITY_OTHER_ORGANIZATION_RID
} } },
105 { {0,0}, WinBuiltinIncomingForestTrustBuildersSid
, { SID_REVISION
, 2, { SECURITY_NT_AUTHORITY
}, { SECURITY_BUILTIN_DOMAIN_RID
, DOMAIN_ALIAS_RID_INCOMING_FOREST_TRUST_BUILDERS
} } },
106 { {0,0}, WinBuiltinPerfMonitoringUsersSid
, { SID_REVISION
, 2, { SECURITY_NT_AUTHORITY
}, { SECURITY_BUILTIN_DOMAIN_RID
, DOMAIN_ALIAS_RID_MONITORING_USERS
} } },
107 { {0,0}, WinBuiltinPerfLoggingUsersSid
, { SID_REVISION
, 2, { SECURITY_NT_AUTHORITY
}, { SECURITY_BUILTIN_DOMAIN_RID
, DOMAIN_ALIAS_RID_LOGGING_USERS
} } },
108 { {0,0}, WinBuiltinAuthorizationAccessSid
, { SID_REVISION
, 2, { SECURITY_NT_AUTHORITY
}, { SECURITY_BUILTIN_DOMAIN_RID
, DOMAIN_ALIAS_RID_AUTHORIZATIONACCESS
} } },
109 { {0,0}, WinBuiltinTerminalServerLicenseServersSid
, { SID_REVISION
, 2, { SECURITY_NT_AUTHORITY
}, { SECURITY_BUILTIN_DOMAIN_RID
, DOMAIN_ALIAS_RID_TS_LICENSE_SERVERS
} } },
110 { {0,0}, WinBuiltinDCOMUsersSid
, { SID_REVISION
, 2, { SECURITY_NT_AUTHORITY
}, { SECURITY_BUILTIN_DOMAIN_RID
, DOMAIN_ALIAS_RID_DCOM_USERS
} } },
111 { {'L','W'}, WinLowLabelSid
, { SID_REVISION
, 1, { SECURITY_MANDATORY_LABEL_AUTHORITY
}, { SECURITY_MANDATORY_LOW_RID
} } },
112 { {'M','E'}, WinMediumLabelSid
, { SID_REVISION
, 1, { SECURITY_MANDATORY_LABEL_AUTHORITY
}, { SECURITY_MANDATORY_MEDIUM_RID
} } },
113 { {'H','I'}, WinHighLabelSid
, { SID_REVISION
, 1, { SECURITY_MANDATORY_LABEL_AUTHORITY
}, { SECURITY_MANDATORY_HIGH_RID
} } },
114 { {'S','I'}, WinSystemLabelSid
, { SID_REVISION
, 1, { SECURITY_MANDATORY_LABEL_AUTHORITY
}, { SECURITY_MANDATORY_SYSTEM_RID
} } },
117 typedef struct WELLKNOWNRID
119 WELL_KNOWN_SID_TYPE Type
;
123 static const WELLKNOWNRID WellKnownRids
[] = {
124 { WinAccountAdministratorSid
, DOMAIN_USER_RID_ADMIN
},
125 { WinAccountGuestSid
, DOMAIN_USER_RID_GUEST
},
126 { WinAccountKrbtgtSid
, DOMAIN_USER_RID_KRBTGT
},
127 { WinAccountDomainAdminsSid
, DOMAIN_GROUP_RID_ADMINS
},
128 { WinAccountDomainUsersSid
, DOMAIN_GROUP_RID_USERS
},
129 { WinAccountDomainGuestsSid
, DOMAIN_GROUP_RID_GUESTS
},
130 { WinAccountComputersSid
, DOMAIN_GROUP_RID_COMPUTERS
},
131 { WinAccountControllersSid
, DOMAIN_GROUP_RID_CONTROLLERS
},
132 { WinAccountCertAdminsSid
, DOMAIN_GROUP_RID_CERT_ADMINS
},
133 { WinAccountSchemaAdminsSid
, DOMAIN_GROUP_RID_SCHEMA_ADMINS
},
134 { WinAccountEnterpriseAdminsSid
, DOMAIN_GROUP_RID_ENTERPRISE_ADMINS
},
135 { WinAccountPolicyAdminsSid
, DOMAIN_GROUP_RID_POLICY_ADMINS
},
136 { WinAccountRasAndIasServersSid
, DOMAIN_ALIAS_RID_RAS_SERVERS
},
139 static const SID sidWorld
= { SID_REVISION
, 1, { SECURITY_WORLD_SID_AUTHORITY
} , { SECURITY_WORLD_RID
} };
144 static const WCHAR SDDL_ACCESS_ALLOWED
[] = {'A',0};
145 static const WCHAR SDDL_ACCESS_DENIED
[] = {'D',0};
146 static const WCHAR SDDL_OBJECT_ACCESS_ALLOWED
[] = {'O','A',0};
147 static const WCHAR SDDL_OBJECT_ACCESS_DENIED
[] = {'O','D',0};
148 static const WCHAR SDDL_AUDIT
[] = {'A','U',0};
149 static const WCHAR SDDL_ALARM
[] = {'A','L',0};
150 static const WCHAR SDDL_OBJECT_AUDIT
[] = {'O','U',0};
151 static const WCHAR SDDL_OBJECT_ALARM
[] = {'O','L',0};
156 #define ADS_RIGHT_DS_CREATE_CHILD 0x0001
157 #define ADS_RIGHT_DS_DELETE_CHILD 0x0002
158 #define ADS_RIGHT_ACTRL_DS_LIST 0x0004
159 #define ADS_RIGHT_DS_SELF 0x0008
160 #define ADS_RIGHT_DS_READ_PROP 0x0010
161 #define ADS_RIGHT_DS_WRITE_PROP 0x0020
162 #define ADS_RIGHT_DS_DELETE_TREE 0x0040
163 #define ADS_RIGHT_DS_LIST_OBJECT 0x0080
164 #define ADS_RIGHT_DS_CONTROL_ACCESS 0x0100
169 static const WCHAR SDDL_CONTAINER_INHERIT
[] = {'C','I',0};
170 static const WCHAR SDDL_OBJECT_INHERIT
[] = {'O','I',0};
171 static const WCHAR SDDL_NO_PROPAGATE
[] = {'N','P',0};
172 static const WCHAR SDDL_INHERIT_ONLY
[] = {'I','O',0};
173 static const WCHAR SDDL_INHERITED
[] = {'I','D',0};
174 static const WCHAR SDDL_AUDIT_SUCCESS
[] = {'S','A',0};
175 static const WCHAR SDDL_AUDIT_FAILURE
[] = {'F','A',0};
177 static const char * debugstr_sid(PSID sid
)
180 SID
* psid
= (SID
*)sid
;
185 auth
= psid
->IdentifierAuthority
.Value
[5] +
186 (psid
->IdentifierAuthority
.Value
[4] << 8) +
187 (psid
->IdentifierAuthority
.Value
[3] << 16) +
188 (psid
->IdentifierAuthority
.Value
[2] << 24);
190 switch (psid
->SubAuthorityCount
) {
192 return wine_dbg_sprintf("S-%d-%d", psid
->Revision
, auth
);
194 return wine_dbg_sprintf("S-%d-%d-%lu", psid
->Revision
, auth
,
195 psid
->SubAuthority
[0]);
197 return wine_dbg_sprintf("S-%d-%d-%lu-%lu", psid
->Revision
, auth
,
198 psid
->SubAuthority
[0], psid
->SubAuthority
[1]);
200 return wine_dbg_sprintf("S-%d-%d-%lu-%lu-%lu", psid
->Revision
, auth
,
201 psid
->SubAuthority
[0], psid
->SubAuthority
[1], psid
->SubAuthority
[2]);
203 return wine_dbg_sprintf("S-%d-%d-%lu-%lu-%lu-%lu", psid
->Revision
, auth
,
204 psid
->SubAuthority
[0], psid
->SubAuthority
[1], psid
->SubAuthority
[2],
205 psid
->SubAuthority
[3]);
207 return wine_dbg_sprintf("S-%d-%d-%lu-%lu-%lu-%lu-%lu", psid
->Revision
, auth
,
208 psid
->SubAuthority
[0], psid
->SubAuthority
[1], psid
->SubAuthority
[2],
209 psid
->SubAuthority
[3], psid
->SubAuthority
[4]);
211 return wine_dbg_sprintf("S-%d-%d-%lu-%lu-%lu-%lu-%lu-%lu", psid
->Revision
, auth
,
212 psid
->SubAuthority
[3], psid
->SubAuthority
[1], psid
->SubAuthority
[2],
213 psid
->SubAuthority
[0], psid
->SubAuthority
[4], psid
->SubAuthority
[5]);
215 return wine_dbg_sprintf("S-%d-%d-%lu-%lu-%lu-%lu-%lu-%lu-%lu", psid
->Revision
, auth
,
216 psid
->SubAuthority
[0], psid
->SubAuthority
[1], psid
->SubAuthority
[2],
217 psid
->SubAuthority
[3], psid
->SubAuthority
[4], psid
->SubAuthority
[5],
218 psid
->SubAuthority
[6]);
220 return wine_dbg_sprintf("S-%d-%d-%lu-%lu-%lu-%lu-%lu-%lu-%lu-%lu", psid
->Revision
, auth
,
221 psid
->SubAuthority
[0], psid
->SubAuthority
[1], psid
->SubAuthority
[2],
222 psid
->SubAuthority
[3], psid
->SubAuthority
[4], psid
->SubAuthority
[5],
223 psid
->SubAuthority
[6], psid
->SubAuthority
[7]);
228 static const ACEFLAG AceRights
[] =
230 { SDDL_GENERIC_ALL
, GENERIC_ALL
},
231 { SDDL_GENERIC_READ
, GENERIC_READ
},
232 { SDDL_GENERIC_WRITE
, GENERIC_WRITE
},
233 { SDDL_GENERIC_EXECUTE
, GENERIC_EXECUTE
},
235 { SDDL_READ_CONTROL
, READ_CONTROL
},
236 { SDDL_STANDARD_DELETE
, DELETE
},
237 { SDDL_WRITE_DAC
, WRITE_DAC
},
238 { SDDL_WRITE_OWNER
, WRITE_OWNER
},
240 { SDDL_READ_PROPERTY
, ADS_RIGHT_DS_READ_PROP
},
241 { SDDL_WRITE_PROPERTY
, ADS_RIGHT_DS_WRITE_PROP
},
242 { SDDL_CREATE_CHILD
, ADS_RIGHT_DS_CREATE_CHILD
},
243 { SDDL_DELETE_CHILD
, ADS_RIGHT_DS_DELETE_CHILD
},
244 { SDDL_LIST_CHILDREN
, ADS_RIGHT_ACTRL_DS_LIST
},
245 { SDDL_SELF_WRITE
, ADS_RIGHT_DS_SELF
},
246 { SDDL_LIST_OBJECT
, ADS_RIGHT_DS_LIST_OBJECT
},
247 { SDDL_DELETE_TREE
, ADS_RIGHT_DS_DELETE_TREE
},
248 { SDDL_CONTROL_ACCESS
, ADS_RIGHT_DS_CONTROL_ACCESS
},
250 { SDDL_FILE_ALL
, FILE_ALL_ACCESS
},
251 { SDDL_FILE_READ
, FILE_GENERIC_READ
},
252 { SDDL_FILE_WRITE
, FILE_GENERIC_WRITE
},
253 { SDDL_FILE_EXECUTE
, FILE_GENERIC_EXECUTE
},
255 { SDDL_KEY_ALL
, KEY_ALL_ACCESS
},
256 { SDDL_KEY_READ
, KEY_READ
},
257 { SDDL_KEY_WRITE
, KEY_WRITE
},
258 { SDDL_KEY_EXECUTE
, KEY_EXECUTE
},
262 static const LPCWSTR AceRightBitNames
[32] = {
263 SDDL_CREATE_CHILD
, /* 0 */
267 SDDL_READ_PROPERTY
, /* 4 */
271 SDDL_CONTROL_ACCESS
, /* 8 */
279 SDDL_STANDARD_DELETE
, /* 16 */
291 SDDL_GENERIC_ALL
, /* 28 */
292 SDDL_GENERIC_EXECUTE
,
298 /* set last error code from NT status and get the proper boolean return value */
299 /* used for functions that are a simple wrapper around the corresponding ntdll API */
300 static __inline BOOL
set_ntstatus( NTSTATUS status
)
302 if (status
) SetLastError( RtlNtStatusToDosError( status
));
306 /************************************************************
307 * ADVAPI_GetComputerSid
309 * Reads the computer SID from the registry.
311 BOOL
ADVAPI_GetComputerSid(PSID sid
)
316 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 };
317 static const WCHAR V
[] = { 'V',0 };
319 if ((ret
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
, Account
, 0,
320 KEY_READ
, &key
)) == ERROR_SUCCESS
)
323 ret
= RegQueryValueExW(key
, V
, NULL
, NULL
, NULL
, &size
);
324 if (ret
== ERROR_MORE_DATA
|| ret
== ERROR_SUCCESS
)
326 BYTE
* data
= HeapAlloc(GetProcessHeap(), 0, size
);
329 if ((ret
= RegQueryValueExW(key
, V
, NULL
, NULL
,
330 data
, &size
)) == ERROR_SUCCESS
)
332 /* the SID is in the last 24 bytes of the binary data */
333 CopyMemory(sid
, &data
[size
-24], 24);
336 HeapFree(GetProcessHeap(), 0, data
);
342 if(retval
== TRUE
) return retval
;
344 /* create a new random SID */
345 if (RegCreateKeyExW(HKEY_LOCAL_MACHINE
, Account
,
346 0, NULL
, 0, KEY_ALL_ACCESS
, NULL
, &key
, NULL
) == ERROR_SUCCESS
)
349 SID_IDENTIFIER_AUTHORITY identifierAuthority
= {SECURITY_NT_AUTHORITY
};
352 if (RtlGenRandom(id
, sizeof(id
)))
354 if (AllocateAndInitializeSid(&identifierAuthority
, 4, SECURITY_NT_NON_UNIQUE
, id
[0], id
[1], id
[2], 0, 0, 0, 0, &new_sid
))
356 if (RegSetValueExW(key
, V
, 0, REG_BINARY
, new_sid
, GetLengthSid(new_sid
)) == ERROR_SUCCESS
)
357 retval
= CopySid(GetLengthSid(new_sid
), sid
, new_sid
);
368 /* Exported functions */
374 AllocateLocallyUniqueId(PLUID Luid
)
378 Status
= NtAllocateLocallyUniqueId (Luid
);
379 if (!NT_SUCCESS (Status
))
381 SetLastError(RtlNtStatusToDosError(Status
));
393 AllocateAndInitializeSid(PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority
,
394 BYTE nSubAuthorityCount
,
395 DWORD dwSubAuthority0
,
396 DWORD dwSubAuthority1
,
397 DWORD dwSubAuthority2
,
398 DWORD dwSubAuthority3
,
399 DWORD dwSubAuthority4
,
400 DWORD dwSubAuthority5
,
401 DWORD dwSubAuthority6
,
402 DWORD dwSubAuthority7
,
407 Status
= RtlAllocateAndInitializeSid(pIdentifierAuthority
,
418 if (!NT_SUCCESS(Status
))
420 SetLastError(RtlNtStatusToDosError(Status
));
432 CopySid(DWORD nDestinationSidLength
,
433 PSID pDestinationSid
,
438 Status
= RtlCopySid(nDestinationSidLength
,
441 if (!NT_SUCCESS (Status
))
443 SetLastError(RtlNtStatusToDosError(Status
));
450 static void DumpString(LPCWSTR string
, int cch
, WCHAR
**pwptr
, ULONG
*plen
)
453 cch
= strlenW(string
);
460 memcpy(*pwptr
, string
, sizeof(WCHAR
)*cch
);
465 static BOOL
DumpSidNumeric(PSID psid
, WCHAR
**pwptr
, ULONG
*plen
)
468 WCHAR fmt
[] = { 'S','-','%','u','-','%','d',0 };
469 WCHAR subauthfmt
[] = { '-','%','u',0 };
473 if( !IsValidSid( psid
) || pisid
->Revision
!= SDDL_REVISION
)
475 SetLastError(ERROR_INVALID_SID
);
479 if (pisid
->IdentifierAuthority
.Value
[0] ||
480 pisid
->IdentifierAuthority
.Value
[1])
482 FIXME("not matching MS' bugs\n");
483 SetLastError(ERROR_INVALID_SID
);
487 sprintfW( buf
, fmt
, pisid
->Revision
,
489 MAKEWORD( pisid
->IdentifierAuthority
.Value
[5],
490 pisid
->IdentifierAuthority
.Value
[4] ),
491 MAKEWORD( pisid
->IdentifierAuthority
.Value
[3],
492 pisid
->IdentifierAuthority
.Value
[2] )
494 DumpString(buf
, -1, pwptr
, plen
);
496 for( i
=0; i
<pisid
->SubAuthorityCount
; i
++ )
498 sprintfW( buf
, subauthfmt
, pisid
->SubAuthority
[i
] );
499 DumpString(buf
, -1, pwptr
, plen
);
504 static BOOL
DumpSid(PSID psid
, WCHAR
**pwptr
, ULONG
*plen
)
507 for (i
= 0; i
< sizeof(WellKnownSids
) / sizeof(WellKnownSids
[0]); i
++)
509 if (WellKnownSids
[i
].wstr
[0] && EqualSid(psid
, (PSID
)&(WellKnownSids
[i
].Sid
.Revision
)))
511 DumpString(WellKnownSids
[i
].wstr
, 2, pwptr
, plen
);
516 return DumpSidNumeric(psid
, pwptr
, plen
);
519 static void DumpRights(DWORD mask
, WCHAR
**pwptr
, ULONG
*plen
)
521 static const WCHAR fmtW
[] = {'0','x','%','x',0};
528 /* first check if the right have name */
529 for (i
= 0; i
< sizeof(AceRights
)/sizeof(AceRights
[0]); i
++)
531 if (AceRights
[i
].wstr
== NULL
)
533 if (mask
== AceRights
[i
].value
)
535 DumpString(AceRights
[i
].wstr
, -1, pwptr
, plen
);
540 /* then check if it can be built from bit names */
541 for (i
= 0; i
< 32; i
++)
543 if ((mask
& (1 << i
)) && (AceRightBitNames
[i
] == NULL
))
545 /* can't be built from bit names */
546 sprintfW(buf
, fmtW
, mask
);
547 DumpString(buf
, -1, pwptr
, plen
);
552 /* build from bit names */
553 for (i
= 0; i
< 32; i
++)
555 DumpString(AceRightBitNames
[i
], -1, pwptr
, plen
);
558 static BOOL
DumpAce(LPVOID pace
, WCHAR
**pwptr
, ULONG
*plen
)
560 ACCESS_ALLOWED_ACE
*piace
; /* all the supported ACEs have the same memory layout */
561 static const WCHAR openbr
= '(';
562 static const WCHAR closebr
= ')';
563 static const WCHAR semicolon
= ';';
565 if (((PACE_HEADER
)pace
)->AceType
> SYSTEM_ALARM_ACE_TYPE
|| ((PACE_HEADER
)pace
)->AceSize
< sizeof(ACCESS_ALLOWED_ACE
))
567 SetLastError(ERROR_INVALID_ACL
);
572 DumpString(&openbr
, 1, pwptr
, plen
);
573 switch (piace
->Header
.AceType
)
575 case ACCESS_ALLOWED_ACE_TYPE
:
576 DumpString(SDDL_ACCESS_ALLOWED
, -1, pwptr
, plen
);
578 case ACCESS_DENIED_ACE_TYPE
:
579 DumpString(SDDL_ACCESS_DENIED
, -1, pwptr
, plen
);
581 case SYSTEM_AUDIT_ACE_TYPE
:
582 DumpString(SDDL_AUDIT
, -1, pwptr
, plen
);
584 case SYSTEM_ALARM_ACE_TYPE
:
585 DumpString(SDDL_ALARM
, -1, pwptr
, plen
);
588 DumpString(&semicolon
, 1, pwptr
, plen
);
590 if (piace
->Header
.AceFlags
& OBJECT_INHERIT_ACE
)
591 DumpString(SDDL_OBJECT_INHERIT
, -1, pwptr
, plen
);
592 if (piace
->Header
.AceFlags
& CONTAINER_INHERIT_ACE
)
593 DumpString(SDDL_CONTAINER_INHERIT
, -1, pwptr
, plen
);
594 if (piace
->Header
.AceFlags
& NO_PROPAGATE_INHERIT_ACE
)
595 DumpString(SDDL_NO_PROPAGATE
, -1, pwptr
, plen
);
596 if (piace
->Header
.AceFlags
& INHERIT_ONLY_ACE
)
597 DumpString(SDDL_INHERIT_ONLY
, -1, pwptr
, plen
);
598 if (piace
->Header
.AceFlags
& INHERITED_ACE
)
599 DumpString(SDDL_INHERITED
, -1, pwptr
, plen
);
600 if (piace
->Header
.AceFlags
& SUCCESSFUL_ACCESS_ACE_FLAG
)
601 DumpString(SDDL_AUDIT_SUCCESS
, -1, pwptr
, plen
);
602 if (piace
->Header
.AceFlags
& FAILED_ACCESS_ACE_FLAG
)
603 DumpString(SDDL_AUDIT_FAILURE
, -1, pwptr
, plen
);
604 DumpString(&semicolon
, 1, pwptr
, plen
);
605 DumpRights(piace
->Mask
, pwptr
, plen
);
606 DumpString(&semicolon
, 1, pwptr
, plen
);
607 /* objects not supported */
608 DumpString(&semicolon
, 1, pwptr
, plen
);
609 /* objects not supported */
610 DumpString(&semicolon
, 1, pwptr
, plen
);
611 if (!DumpSid((PSID
)&piace
->SidStart
, pwptr
, plen
))
613 DumpString(&closebr
, 1, pwptr
, plen
);
617 static BOOL
DumpAcl(PACL pacl
, WCHAR
**pwptr
, ULONG
*plen
, BOOL
protected, BOOL autoInheritReq
, BOOL autoInherited
)
623 DumpString(SDDL_PROTECTED
, -1, pwptr
, plen
);
625 DumpString(SDDL_AUTO_INHERIT_REQ
, -1, pwptr
, plen
);
627 DumpString(SDDL_AUTO_INHERITED
, -1, pwptr
, plen
);
632 if (!IsValidAcl(pacl
))
635 count
= pacl
->AceCount
;
636 for (i
= 0; i
< count
; i
++)
639 if (!GetAce(pacl
, i
, &ace
))
641 if (!DumpAce(ace
, pwptr
, plen
))
648 static BOOL
DumpOwner(PSECURITY_DESCRIPTOR SecurityDescriptor
, WCHAR
**pwptr
, ULONG
*plen
)
650 static const WCHAR prefix
[] = {'O',':',0};
654 if (!GetSecurityDescriptorOwner(SecurityDescriptor
, &psid
, &bDefaulted
))
660 DumpString(prefix
, -1, pwptr
, plen
);
661 if (!DumpSid(psid
, pwptr
, plen
))
666 static BOOL
DumpGroup(PSECURITY_DESCRIPTOR SecurityDescriptor
, WCHAR
**pwptr
, ULONG
*plen
)
668 static const WCHAR prefix
[] = {'G',':',0};
672 if (!GetSecurityDescriptorGroup(SecurityDescriptor
, &psid
, &bDefaulted
))
678 DumpString(prefix
, -1, pwptr
, plen
);
679 if (!DumpSid(psid
, pwptr
, plen
))
684 static BOOL
DumpDacl(PSECURITY_DESCRIPTOR SecurityDescriptor
, WCHAR
**pwptr
, ULONG
*plen
)
686 static const WCHAR dacl
[] = {'D',':',0};
687 SECURITY_DESCRIPTOR_CONTROL control
;
688 BOOL present
, defaulted
;
692 if (!GetSecurityDescriptorDacl(SecurityDescriptor
, &present
, &pacl
, &defaulted
))
695 if (!GetSecurityDescriptorControl(SecurityDescriptor
, &control
, &revision
))
701 DumpString(dacl
, 2, pwptr
, plen
);
702 if (!DumpAcl(pacl
, pwptr
, plen
, control
& SE_DACL_PROTECTED
, control
& SE_DACL_AUTO_INHERIT_REQ
, control
& SE_DACL_AUTO_INHERITED
))
707 static BOOL
DumpSacl(PSECURITY_DESCRIPTOR SecurityDescriptor
, WCHAR
**pwptr
, ULONG
*plen
)
709 static const WCHAR sacl
[] = {'S',':',0};
710 SECURITY_DESCRIPTOR_CONTROL control
;
711 BOOL present
, defaulted
;
715 if (!GetSecurityDescriptorSacl(SecurityDescriptor
, &present
, &pacl
, &defaulted
))
718 if (!GetSecurityDescriptorControl(SecurityDescriptor
, &control
, &revision
))
724 DumpString(sacl
, 2, pwptr
, plen
);
725 if (!DumpAcl(pacl
, pwptr
, plen
, control
& SE_SACL_PROTECTED
, control
& SE_SACL_AUTO_INHERIT_REQ
, control
& SE_SACL_AUTO_INHERITED
))
730 /******************************************************************************
731 * ConvertSecurityDescriptorToStringSecurityDescriptorW [ADVAPI32.@]
735 ConvertSecurityDescriptorToStringSecurityDescriptorW(PSECURITY_DESCRIPTOR SecurityDescriptor
,
737 SECURITY_INFORMATION SecurityInformation
,
738 LPWSTR
*OutputString
,
744 if (SDRevision
!= SDDL_REVISION_1
)
746 ERR("Pogram requested unknown SDDL revision %d\n", SDRevision
);
747 SetLastError(ERROR_UNKNOWN_REVISION
);
752 if (SecurityInformation
& OWNER_SECURITY_INFORMATION
)
753 if (!DumpOwner(SecurityDescriptor
, NULL
, &len
))
755 if (SecurityInformation
& GROUP_SECURITY_INFORMATION
)
756 if (!DumpGroup(SecurityDescriptor
, NULL
, &len
))
758 if (SecurityInformation
& DACL_SECURITY_INFORMATION
)
759 if (!DumpDacl(SecurityDescriptor
, NULL
, &len
))
761 if (SecurityInformation
& SACL_SECURITY_INFORMATION
)
762 if (!DumpSacl(SecurityDescriptor
, NULL
, &len
))
765 wstr
= wptr
= LocalAlloc(0, (len
+ 1)*sizeof(WCHAR
));
766 if (SecurityInformation
& OWNER_SECURITY_INFORMATION
)
767 if (!DumpOwner(SecurityDescriptor
, &wptr
, NULL
))
769 if (SecurityInformation
& GROUP_SECURITY_INFORMATION
)
770 if (!DumpGroup(SecurityDescriptor
, &wptr
, NULL
))
772 if (SecurityInformation
& DACL_SECURITY_INFORMATION
)
773 if (!DumpDacl(SecurityDescriptor
, &wptr
, NULL
))
775 if (SecurityInformation
& SACL_SECURITY_INFORMATION
)
776 if (!DumpSacl(SecurityDescriptor
, &wptr
, NULL
))
780 TRACE("ret: %s, %d\n", wine_dbgstr_w(wstr
), len
);
781 *OutputString
= wstr
;
783 *OutputLen
= strlenW(*OutputString
)+1;
788 /******************************************************************************
789 * ConvertSecurityDescriptorToStringSecurityDescriptorA [ADVAPI32.@]
793 ConvertSecurityDescriptorToStringSecurityDescriptorA(PSECURITY_DESCRIPTOR SecurityDescriptor
,
795 SECURITY_INFORMATION Information
,
801 if (ConvertSecurityDescriptorToStringSecurityDescriptorW(SecurityDescriptor
, SDRevision
, Information
, &wstr
, &len
))
805 lenA
= WideCharToMultiByte(CP_ACP
, 0, wstr
, len
, NULL
, 0, NULL
, NULL
);
806 *OutputString
= HeapAlloc(GetProcessHeap(), 0, lenA
);
807 WideCharToMultiByte(CP_ACP
, 0, wstr
, len
, *OutputString
, lenA
, NULL
, NULL
);
810 if (OutputLen
!= NULL
)
816 *OutputString
= NULL
;
824 /******************************************************************************
825 * ComputeStringSidSize
827 static DWORD
ComputeStringSidSize(LPCWSTR StringSid
)
829 if (StringSid
[0] == 'S' && StringSid
[1] == '-') /* S-R-I(-S)+ */
834 if (*StringSid
== '-')
840 return GetSidLengthRequired(ctok
- 2);
842 else /* String constant format - Only available in winxp and above */
846 for (i
= 0; i
< sizeof(WellKnownSids
)/sizeof(WellKnownSids
[0]); i
++)
847 if (!strncmpW(WellKnownSids
[i
].wstr
, StringSid
, 2))
848 return GetSidLengthRequired(WellKnownSids
[i
].Sid
.SubAuthorityCount
);
851 return GetSidLengthRequired(0);
854 /******************************************************************************
855 * ParseStringSidToSid
857 static BOOL
ParseStringSidToSid(LPCWSTR StringSid
, PSID pSid
, LPDWORD cBytes
)
862 TRACE("%s, %p, %p\n", debugstr_w(StringSid
), pSid
, cBytes
);
865 SetLastError(ERROR_INVALID_PARAMETER
);
866 TRACE("StringSid is NULL, returning FALSE\n");
870 while (*StringSid
== ' ')
873 *cBytes
= ComputeStringSidSize(StringSid
);
874 if (!pisid
) /* Simply compute the size */
876 TRACE("only size requested, returning TRUE\n");
880 if (StringSid
[0] == 'S' && StringSid
[1] == '-') /* S-R-I-S-S */
882 DWORD i
= 0, identAuth
;
883 DWORD csubauth
= ((*cBytes
- GetSidLengthRequired(0)) / sizeof(DWORD
));
885 StringSid
+= 2; /* Advance to Revision */
886 pisid
->Revision
= atoiW(StringSid
);
888 if (pisid
->Revision
!= SDDL_REVISION
)
890 TRACE("Revision %d is unknown\n", pisid
->Revision
);
891 goto lend
; /* ERROR_INVALID_SID */
895 TRACE("SubAuthorityCount is 0\n");
896 goto lend
; /* ERROR_INVALID_SID */
899 pisid
->SubAuthorityCount
= csubauth
;
901 /* Advance to identifier authority */
902 while (*StringSid
&& *StringSid
!= '-')
904 if (*StringSid
== '-')
907 /* MS' implementation can't handle values greater than 2^32 - 1, so
908 * we don't either; assume most significant bytes are always 0
910 pisid
->IdentifierAuthority
.Value
[0] = 0;
911 pisid
->IdentifierAuthority
.Value
[1] = 0;
912 identAuth
= atoiW(StringSid
);
913 pisid
->IdentifierAuthority
.Value
[5] = identAuth
& 0xff;
914 pisid
->IdentifierAuthority
.Value
[4] = (identAuth
& 0xff00) >> 8;
915 pisid
->IdentifierAuthority
.Value
[3] = (identAuth
& 0xff0000) >> 16;
916 pisid
->IdentifierAuthority
.Value
[2] = (identAuth
& 0xff000000) >> 24;
918 /* Advance to first sub authority */
919 while (*StringSid
&& *StringSid
!= '-')
921 if (*StringSid
== '-')
926 pisid
->SubAuthority
[i
++] = atoiW(StringSid
);
928 while (*StringSid
&& *StringSid
!= '-')
930 if (*StringSid
== '-')
934 if (i
!= pisid
->SubAuthorityCount
)
935 goto lend
; /* ERROR_INVALID_SID */
939 else /* String constant format - Only available in winxp and above */
942 pisid
->Revision
= SDDL_REVISION
;
944 for (i
= 0; i
< sizeof(WellKnownSids
)/sizeof(WellKnownSids
[0]); i
++)
945 if (!strncmpW(WellKnownSids
[i
].wstr
, StringSid
, 2))
948 pisid
->SubAuthorityCount
= WellKnownSids
[i
].Sid
.SubAuthorityCount
;
949 pisid
->IdentifierAuthority
= WellKnownSids
[i
].Sid
.IdentifierAuthority
;
950 for (j
= 0; j
< WellKnownSids
[i
].Sid
.SubAuthorityCount
; j
++)
951 pisid
->SubAuthority
[j
] = WellKnownSids
[i
].Sid
.SubAuthority
[j
];
956 FIXME("String constant not supported: %s\n", debugstr_wn(StringSid
, 2));
961 SetLastError(ERROR_INVALID_SID
);
963 TRACE("returning %s\n", bret
? "TRUE" : "FALSE");
967 /******************************************************************************
968 * ParseAclStringFlags
970 static DWORD
ParseAclStringFlags(LPCWSTR
* StringAcl
)
973 LPCWSTR szAcl
= *StringAcl
;
975 while (*szAcl
!= '(')
979 flags
|= SE_DACL_PROTECTED
;
981 else if (*szAcl
== 'A')
985 flags
|= SE_DACL_AUTO_INHERIT_REQ
;
986 else if (*szAcl
== 'I')
987 flags
|= SE_DACL_AUTO_INHERITED
;
996 /******************************************************************************
999 static const ACEFLAG AceType
[] =
1001 { SDDL_ALARM
, SYSTEM_ALARM_ACE_TYPE
},
1002 { SDDL_AUDIT
, SYSTEM_AUDIT_ACE_TYPE
},
1003 { SDDL_ACCESS_ALLOWED
, ACCESS_ALLOWED_ACE_TYPE
},
1004 { SDDL_ACCESS_DENIED
, ACCESS_DENIED_ACE_TYPE
},
1006 { SDDL_OBJECT_ACCESS_ALLOWED, ACCESS_ALLOWED_OBJECT_ACE_TYPE },
1007 { SDDL_OBJECT_ACCESS_DENIED, ACCESS_DENIED_OBJECT_ACE_TYPE },
1008 { SDDL_OBJECT_ALARM, SYSTEM_ALARM_OBJECT_ACE_TYPE },
1009 { SDDL_OBJECT_AUDIT, SYSTEM_AUDIT_OBJECT_ACE_TYPE },
1014 static BYTE
ParseAceStringType(LPCWSTR
* StringAcl
)
1017 LPCWSTR szAcl
= *StringAcl
;
1018 const ACEFLAG
*lpaf
= AceType
;
1020 while (lpaf
->wstr
&&
1021 (len
= strlenW(lpaf
->wstr
)) &&
1022 strncmpW(lpaf
->wstr
, szAcl
, len
))
1033 /******************************************************************************
1034 * ParseAceStringFlags
1036 static const ACEFLAG AceFlags
[] =
1038 { SDDL_CONTAINER_INHERIT
, CONTAINER_INHERIT_ACE
},
1039 { SDDL_AUDIT_FAILURE
, FAILED_ACCESS_ACE_FLAG
},
1040 { SDDL_INHERITED
, INHERITED_ACE
},
1041 { SDDL_INHERIT_ONLY
, INHERIT_ONLY_ACE
},
1042 { SDDL_NO_PROPAGATE
, NO_PROPAGATE_INHERIT_ACE
},
1043 { SDDL_OBJECT_INHERIT
, OBJECT_INHERIT_ACE
},
1044 { SDDL_AUDIT_SUCCESS
, SUCCESSFUL_ACCESS_ACE_FLAG
},
1048 static BYTE
ParseAceStringFlags(LPCWSTR
* StringAcl
)
1052 LPCWSTR szAcl
= *StringAcl
;
1054 while (*szAcl
!= ';')
1056 const ACEFLAG
*lpaf
= AceFlags
;
1058 while (lpaf
->wstr
&&
1059 (len
= strlenW(lpaf
->wstr
)) &&
1060 strncmpW(lpaf
->wstr
, szAcl
, len
))
1066 flags
|= lpaf
->value
;
1075 /******************************************************************************
1076 * ParseAceStringRights
1078 static DWORD
ParseAceStringRights(LPCWSTR
* StringAcl
)
1082 LPCWSTR szAcl
= *StringAcl
;
1084 if ((*szAcl
== '0') && (*(szAcl
+ 1) == 'x'))
1088 while (*p
&& *p
!= ';')
1091 if (p
- szAcl
<= 10 /* 8 hex digits + "0x" */ )
1093 rights
= strtoulW(szAcl
, NULL
, 16);
1097 WARN("Invalid rights string format: %s\n", debugstr_wn(szAcl
, p
- szAcl
));
1101 while (*szAcl
!= ';')
1103 const ACEFLAG
*lpaf
= AceRights
;
1105 while (lpaf
->wstr
&&
1106 (len
= strlenW(lpaf
->wstr
)) &&
1107 strncmpW(lpaf
->wstr
, szAcl
, len
))
1115 rights
|= lpaf
->value
;
1125 /******************************************************************************
1126 * ParseStringAclToAcl
1128 * dacl_flags(string_ace1)(string_ace2)... (string_acen)
1130 static BOOL
ParseStringAclToAcl(LPCWSTR StringAcl
, LPDWORD lpdwFlags
,
1131 PACL pAcl
, LPDWORD cBytes
)
1135 DWORD length
= sizeof(ACL
);
1138 PACCESS_ALLOWED_ACE pAce
= NULL
; /* pointer to current ACE */
1140 TRACE("%s\n", debugstr_w(StringAcl
));
1145 if (pAcl
) /* pAce is only useful if we're setting values */
1146 pAce
= (PACCESS_ALLOWED_ACE
) (pAcl
+ 1);
1148 /* Parse ACL flags */
1149 *lpdwFlags
= ParseAclStringFlags(&StringAcl
);
1152 while (*StringAcl
== '(')
1156 /* Parse ACE type */
1157 val
= ParseAceStringType(&StringAcl
);
1159 pAce
->Header
.AceType
= (BYTE
) val
;
1160 if (*StringAcl
!= ';')
1164 /* Parse ACE flags */
1165 val
= ParseAceStringFlags(&StringAcl
);
1167 pAce
->Header
.AceFlags
= (BYTE
) val
;
1168 if (*StringAcl
!= ';')
1172 /* Parse ACE rights */
1173 val
= ParseAceStringRights(&StringAcl
);
1176 if (*StringAcl
!= ';')
1180 /* Parse ACE object guid */
1181 if (*StringAcl
!= ';')
1183 FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
1188 /* Parse ACE inherit object guid */
1189 if (*StringAcl
!= ';')
1191 FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
1196 /* Parse ACE account sid */
1197 if (ParseStringSidToSid(StringAcl
, pAce
? &pAce
->SidStart
: NULL
, &sidlen
))
1199 while (*StringAcl
&& *StringAcl
!= ')')
1203 if (*StringAcl
!= ')')
1207 acesize
= sizeof(ACCESS_ALLOWED_ACE
) - sizeof(DWORD
) + sidlen
;
1211 pAce
->Header
.AceSize
= acesize
;
1212 pAce
= (PACCESS_ALLOWED_ACE
)((LPBYTE
)pAce
+ acesize
);
1219 if (length
> 0xffff)
1221 ERR("ACL too large\n");
1227 pAcl
->AclRevision
= ACL_REVISION
;
1229 pAcl
->AclSize
= length
;
1230 pAcl
->AceCount
= acecount
++;
1236 SetLastError(ERROR_INVALID_ACL
);
1237 WARN("Invalid ACE string format\n");
1242 /******************************************************************************
1243 * ParseStringSecurityDescriptorToSecurityDescriptor
1245 static BOOL
ParseStringSecurityDescriptorToSecurityDescriptor(
1246 LPCWSTR StringSecurityDescriptor
,
1247 SECURITY_DESCRIPTOR_RELATIVE
* SecurityDescriptor
,
1252 WCHAR tok
[MAX_PATH
];
1254 LPBYTE lpNext
= NULL
;
1257 *cBytes
= sizeof(SECURITY_DESCRIPTOR
);
1259 if (SecurityDescriptor
)
1260 lpNext
= (LPBYTE
)(SecurityDescriptor
+ 1);
1262 while (*StringSecurityDescriptor
)
1264 toktype
= *StringSecurityDescriptor
;
1266 /* Expect char identifier followed by ':' */
1267 StringSecurityDescriptor
++;
1268 if (*StringSecurityDescriptor
!= ':')
1270 SetLastError(ERROR_INVALID_PARAMETER
);
1273 StringSecurityDescriptor
++;
1276 lptoken
= StringSecurityDescriptor
;
1277 while (*lptoken
&& *lptoken
!= ':')
1283 len
= lptoken
- StringSecurityDescriptor
;
1284 memcpy( tok
, StringSecurityDescriptor
, len
* sizeof(WCHAR
) );
1293 if (!ParseStringSidToSid(tok
, lpNext
, &bytes
))
1296 if (SecurityDescriptor
)
1298 SecurityDescriptor
->Owner
= lpNext
- (LPBYTE
)SecurityDescriptor
;
1299 lpNext
+= bytes
; /* Advance to next token */
1311 if (!ParseStringSidToSid(tok
, lpNext
, &bytes
))
1314 if (SecurityDescriptor
)
1316 SecurityDescriptor
->Group
= lpNext
- (LPBYTE
)SecurityDescriptor
;
1317 lpNext
+= bytes
; /* Advance to next token */
1330 if (!ParseStringAclToAcl(tok
, &flags
, (PACL
)lpNext
, &bytes
))
1333 if (SecurityDescriptor
)
1335 SecurityDescriptor
->Control
|= SE_DACL_PRESENT
| flags
;
1336 SecurityDescriptor
->Dacl
= lpNext
- (LPBYTE
)SecurityDescriptor
;
1337 lpNext
+= bytes
; /* Advance to next token */
1350 if (!ParseStringAclToAcl(tok
, &flags
, (PACL
)lpNext
, &bytes
))
1353 if (SecurityDescriptor
)
1355 SecurityDescriptor
->Control
|= SE_SACL_PRESENT
| flags
;
1356 SecurityDescriptor
->Sacl
= lpNext
- (LPBYTE
)SecurityDescriptor
;
1357 lpNext
+= bytes
; /* Advance to next token */
1366 FIXME("Unknown token\n");
1367 SetLastError(ERROR_INVALID_PARAMETER
);
1371 StringSecurityDescriptor
= lptoken
;
1381 /******************************************************************************
1382 * ConvertStringSecurityDescriptorToSecurityDescriptorW [ADVAPI32.@]
1385 BOOL WINAPI
ConvertStringSecurityDescriptorToSecurityDescriptorW(
1386 LPCWSTR StringSecurityDescriptor
,
1387 DWORD StringSDRevision
,
1388 PSECURITY_DESCRIPTOR
* SecurityDescriptor
,
1389 PULONG SecurityDescriptorSize
)
1392 SECURITY_DESCRIPTOR
* psd
;
1395 TRACE("%s\n", debugstr_w(StringSecurityDescriptor
));
1397 if (GetVersion() & 0x80000000)
1399 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1402 else if (!StringSecurityDescriptor
|| !SecurityDescriptor
)
1404 SetLastError(ERROR_INVALID_PARAMETER
);
1407 else if (StringSDRevision
!= SID_REVISION
)
1409 SetLastError(ERROR_UNKNOWN_REVISION
);
1413 /* Compute security descriptor length */
1414 if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor
,
1418 psd
= *SecurityDescriptor
= LocalAlloc(GMEM_ZEROINIT
, cBytes
);
1419 if (!psd
) goto lend
;
1421 psd
->Revision
= SID_REVISION
;
1422 psd
->Control
|= SE_SELF_RELATIVE
;
1424 if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor
,
1425 (SECURITY_DESCRIPTOR_RELATIVE
*)psd
, &cBytes
))
1431 if (SecurityDescriptorSize
)
1432 *SecurityDescriptorSize
= cBytes
;
1437 TRACE(" ret=%d\n", bret
);
1442 /* Winehq cvs 20050916 */
1443 /******************************************************************************
1444 * ConvertStringSecurityDescriptorToSecurityDescriptorA [ADVAPI32.@]
1447 BOOL WINAPI
ConvertStringSecurityDescriptorToSecurityDescriptorA(
1448 LPCSTR StringSecurityDescriptor
,
1449 DWORD StringSDRevision
,
1450 PSECURITY_DESCRIPTOR
* SecurityDescriptor
,
1451 PULONG SecurityDescriptorSize
)
1455 LPWSTR StringSecurityDescriptorW
;
1457 len
= MultiByteToWideChar(CP_ACP
, 0, StringSecurityDescriptor
, -1, NULL
, 0);
1458 StringSecurityDescriptorW
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
1460 if (StringSecurityDescriptorW
)
1462 MultiByteToWideChar(CP_ACP
, 0, StringSecurityDescriptor
, -1, StringSecurityDescriptorW
, len
);
1464 ret
= ConvertStringSecurityDescriptorToSecurityDescriptorW(StringSecurityDescriptorW
,
1465 StringSDRevision
, SecurityDescriptor
,
1466 SecurityDescriptorSize
);
1467 HeapFree(GetProcessHeap(), 0, StringSecurityDescriptorW
);
1477 EqualPrefixSid(PSID pSid1
,
1480 return RtlEqualPrefixSid (pSid1
, pSid2
);
1488 EqualSid(PSID pSid1
,
1491 return RtlEqualSid (pSid1
, pSid2
);
1499 * Docs says this function does NOT return a value
1500 * even thou it's defined to return a PVOID...
1505 return RtlFreeSid(pSid
);
1513 GetLengthSid(PSID pSid
)
1515 return (DWORD
)RtlLengthSid(pSid
);
1522 PSID_IDENTIFIER_AUTHORITY WINAPI
1523 GetSidIdentifierAuthority(PSID pSid
)
1525 return RtlIdentifierAuthoritySid(pSid
);
1533 GetSidLengthRequired(UCHAR nSubAuthorityCount
)
1535 return (DWORD
)RtlLengthRequiredSid(nSubAuthorityCount
);
1543 GetSidSubAuthority(PSID pSid
,
1544 DWORD nSubAuthority
)
1546 return (PDWORD
)RtlSubAuthoritySid(pSid
, nSubAuthority
);
1554 GetSidSubAuthorityCount(PSID pSid
)
1556 return RtlSubAuthorityCountSid(pSid
);
1564 InitializeSid(PSID Sid
,
1565 PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority
,
1566 BYTE nSubAuthorityCount
)
1570 Status
= RtlInitializeSid(Sid
,
1571 pIdentifierAuthority
,
1572 nSubAuthorityCount
);
1573 if (!NT_SUCCESS(Status
))
1575 SetLastError(RtlNtStatusToDosError(Status
));
1587 IsValidSid(PSID pSid
)
1589 return (BOOL
)RtlValidSid(pSid
);
1597 ConvertSidToStringSidW(PSID Sid
,
1601 UNICODE_STRING UnicodeString
;
1602 WCHAR FixedBuffer
[64];
1604 if (!RtlValidSid(Sid
))
1606 SetLastError(ERROR_INVALID_SID
);
1610 UnicodeString
.Length
= 0;
1611 UnicodeString
.MaximumLength
= sizeof(FixedBuffer
);
1612 UnicodeString
.Buffer
= FixedBuffer
;
1613 Status
= RtlConvertSidToUnicodeString(&UnicodeString
, Sid
, FALSE
);
1614 if (STATUS_BUFFER_TOO_SMALL
== Status
)
1616 Status
= RtlConvertSidToUnicodeString(&UnicodeString
, Sid
, TRUE
);
1619 if (!NT_SUCCESS(Status
))
1621 SetLastError(RtlNtStatusToDosError(Status
));
1625 *StringSid
= LocalAlloc(LMEM_FIXED
, UnicodeString
.Length
+ sizeof(WCHAR
));
1626 if (NULL
== *StringSid
)
1628 if (UnicodeString
.Buffer
!= FixedBuffer
)
1630 RtlFreeUnicodeString(&UnicodeString
);
1632 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
1636 MoveMemory(*StringSid
, UnicodeString
.Buffer
, UnicodeString
.Length
);
1637 ZeroMemory((PCHAR
) *StringSid
+ UnicodeString
.Length
, sizeof(WCHAR
));
1638 if (UnicodeString
.Buffer
!= FixedBuffer
)
1640 RtlFreeUnicodeString(&UnicodeString
);
1651 ConvertSidToStringSidA(PSID Sid
,
1657 if (!ConvertSidToStringSidW(Sid
, &StringSidW
))
1662 Len
= WideCharToMultiByte(CP_ACP
, 0, StringSidW
, -1, NULL
, 0, NULL
, NULL
);
1665 LocalFree(StringSidW
);
1666 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
1670 *StringSid
= LocalAlloc(LMEM_FIXED
, Len
);
1671 if (NULL
== *StringSid
)
1673 LocalFree(StringSidW
);
1674 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
1678 if (!WideCharToMultiByte(CP_ACP
, 0, StringSidW
, -1, *StringSid
, Len
, NULL
, NULL
))
1680 LocalFree(StringSid
);
1681 LocalFree(StringSidW
);
1685 LocalFree(StringSidW
);
1695 EqualDomainSid(IN PSID pSid1
,
1708 GetWindowsAccountDomainSid(IN PSID pSid
,
1709 OUT PSID ppDomainSid
,
1710 IN OUT DWORD
* cbSid
)
1721 CreateWellKnownSid(IN WELL_KNOWN_SID_TYPE WellKnownSidType
,
1722 IN PSID DomainSid OPTIONAL
,
1724 IN OUT DWORD
* cbSid
)
1727 TRACE("(%d, %s, %p, %p)\n", WellKnownSidType
, debugstr_sid(DomainSid
), pSid
, cbSid
);
1729 if (cbSid
== NULL
|| (DomainSid
&& !IsValidSid(DomainSid
)))
1731 SetLastError(ERROR_INVALID_PARAMETER
);
1735 for (i
= 0; i
< sizeof(WellKnownSids
)/sizeof(WellKnownSids
[0]); i
++) {
1736 if (WellKnownSids
[i
].Type
== WellKnownSidType
) {
1737 DWORD length
= GetSidLengthRequired(WellKnownSids
[i
].Sid
.SubAuthorityCount
);
1739 if (*cbSid
< length
)
1742 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
1747 SetLastError(ERROR_INVALID_PARAMETER
);
1750 CopyMemory(pSid
, &WellKnownSids
[i
].Sid
.Revision
, length
);
1756 if (DomainSid
== NULL
|| *GetSidSubAuthorityCount(DomainSid
) == SID_MAX_SUB_AUTHORITIES
)
1758 SetLastError(ERROR_INVALID_PARAMETER
);
1762 for (i
= 0; i
< sizeof(WellKnownRids
)/sizeof(WellKnownRids
[0]); i
++)
1763 if (WellKnownRids
[i
].Type
== WellKnownSidType
) {
1764 UCHAR domain_subauth
= *GetSidSubAuthorityCount(DomainSid
);
1765 DWORD domain_sid_length
= GetSidLengthRequired(domain_subauth
);
1766 DWORD output_sid_length
= GetSidLengthRequired(domain_subauth
+ 1);
1768 if (*cbSid
< output_sid_length
)
1770 *cbSid
= output_sid_length
;
1771 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
1776 SetLastError(ERROR_INVALID_PARAMETER
);
1779 CopyMemory(pSid
, DomainSid
, domain_sid_length
);
1780 (*GetSidSubAuthorityCount(pSid
))++;
1781 (*GetSidSubAuthority(pSid
, domain_subauth
)) = WellKnownRids
[i
].Rid
;
1782 *cbSid
= output_sid_length
;
1786 SetLastError(ERROR_INVALID_PARAMETER
);
1795 IsWellKnownSid(IN PSID pSid
,
1796 IN WELL_KNOWN_SID_TYPE WellKnownSidType
)
1799 TRACE("(%s, %d)\n", debugstr_sid(pSid
), WellKnownSidType
);
1801 for (i
= 0; i
< sizeof(WellKnownSids
) / sizeof(WellKnownSids
[0]); i
++)
1803 if (WellKnownSids
[i
].Type
== WellKnownSidType
)
1805 if (EqualSid(pSid
, (PSID
)(&WellKnownSids
[i
].Sid
.Revision
)))
1818 ConvertStringSidToSidA(IN LPCSTR StringSid
,
1821 BOOL bRetVal
= FALSE
;
1823 TRACE("%s, %p\n", debugstr_a(StringSid
), sid
);
1824 if (GetVersion() & 0x80000000)
1825 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1826 else if (!StringSid
|| !sid
)
1827 SetLastError(ERROR_INVALID_PARAMETER
);
1830 UINT len
= MultiByteToWideChar(CP_ACP
, 0, StringSid
, -1, NULL
, 0);
1831 LPWSTR wStringSid
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
1832 MultiByteToWideChar(CP_ACP
, 0, StringSid
, - 1, wStringSid
, len
);
1833 bRetVal
= ConvertStringSidToSidW(wStringSid
, sid
);
1834 HeapFree(GetProcessHeap(), 0, wStringSid
);
1840 static const RECORD SidTable
[] =
1842 { SDDL_ACCOUNT_OPERATORS
, WinBuiltinAccountOperatorsSid
},
1843 { SDDL_ALIAS_PREW2KCOMPACC
, WinBuiltinPreWindows2000CompatibleAccessSid
},
1844 { SDDL_ANONYMOUS
, WinAnonymousSid
},
1845 { SDDL_AUTHENTICATED_USERS
, WinAuthenticatedUserSid
},
1846 { SDDL_BUILTIN_ADMINISTRATORS
, WinBuiltinAdministratorsSid
},
1847 { SDDL_BUILTIN_GUESTS
, WinBuiltinGuestsSid
},
1848 { SDDL_BACKUP_OPERATORS
, WinBuiltinBackupOperatorsSid
},
1849 { SDDL_BUILTIN_USERS
, WinBuiltinUsersSid
},
1850 { SDDL_CERT_SERV_ADMINISTRATORS
, WinAccountCertAdminsSid
/* FIXME: DOMAIN_GROUP_RID_CERT_ADMINS */ },
1851 { SDDL_CREATOR_GROUP
, WinCreatorGroupSid
},
1852 { SDDL_CREATOR_OWNER
, WinCreatorOwnerSid
},
1853 { SDDL_DOMAIN_ADMINISTRATORS
, WinAccountDomainAdminsSid
/* FIXME: DOMAIN_GROUP_RID_ADMINS */ },
1854 { SDDL_DOMAIN_COMPUTERS
, WinAccountComputersSid
/* FIXME: DOMAIN_GROUP_RID_COMPUTERS */ },
1855 { SDDL_DOMAIN_DOMAIN_CONTROLLERS
, WinAccountControllersSid
/* FIXME: DOMAIN_GROUP_RID_CONTROLLERS */ },
1856 { SDDL_DOMAIN_GUESTS
, WinAccountDomainGuestsSid
/* FIXME: DOMAIN_GROUP_RID_GUESTS */ },
1857 { SDDL_DOMAIN_USERS
, WinAccountDomainUsersSid
/* FIXME: DOMAIN_GROUP_RID_USERS */ },
1858 { SDDL_ENTERPRISE_ADMINS
, WinAccountEnterpriseAdminsSid
/* FIXME: DOMAIN_GROUP_RID_ENTERPRISE_ADMINS */ },
1859 { SDDL_ENTERPRISE_DOMAIN_CONTROLLERS
, WinLogonIdsSid
/* FIXME: SECURITY_SERVER_LOGON_RID */ },
1860 { SDDL_EVERYONE
, WinWorldSid
},
1861 { SDDL_GROUP_POLICY_ADMINS
, WinAccountPolicyAdminsSid
/* FIXME: DOMAIN_GROUP_RID_POLICY_ADMINS */ },
1862 { SDDL_INTERACTIVE
, WinInteractiveSid
},
1863 { SDDL_LOCAL_ADMIN
, WinAccountAdministratorSid
/* FIXME: DOMAIN_USER_RID_ADMIN */ },
1864 { SDDL_LOCAL_GUEST
, WinAccountGuestSid
/* FIXME: DOMAIN_USER_RID_GUEST */ },
1865 { SDDL_LOCAL_SERVICE
, WinLocalServiceSid
},
1866 { SDDL_LOCAL_SYSTEM
, WinLocalSystemSid
},
1867 { SDDL_NETWORK
, WinNetworkSid
},
1868 { SDDL_NETWORK_CONFIGURATION_OPS
, WinBuiltinNetworkConfigurationOperatorsSid
},
1869 { SDDL_NETWORK_SERVICE
, WinNetworkServiceSid
},
1870 { SDDL_PRINTER_OPERATORS
, WinBuiltinPrintOperatorsSid
},
1871 { SDDL_PERSONAL_SELF
, WinSelfSid
},
1872 { SDDL_POWER_USERS
, WinBuiltinPowerUsersSid
},
1873 { SDDL_RAS_SERVERS
, WinAccountRasAndIasServersSid
/* FIXME: DOMAIN_ALIAS_RID_RAS_SERVERS */ },
1874 { SDDL_REMOTE_DESKTOP
, WinBuiltinRemoteDesktopUsersSid
},
1875 { SDDL_REPLICATOR
, WinBuiltinReplicatorSid
},
1876 { SDDL_RESTRICTED_CODE
, WinRestrictedCodeSid
},
1877 { SDDL_SCHEMA_ADMINISTRATORS
, WinAccountSchemaAdminsSid
/* FIXME: DOMAIN_GROUP_RID_SCHEMA_ADMINS */ },
1878 { SDDL_SERVER_OPERATORS
, WinBuiltinSystemOperatorsSid
},
1879 { SDDL_SERVICE
, WinServiceSid
},
1887 ConvertStringSidToSidW(IN LPCWSTR StringSid
,
1891 DWORD i
, cBytes
, identAuth
, csubauth
;
1895 TRACE("%s %p\n", debugstr_w(StringSid
), sid
);
1899 SetLastError(ERROR_INVALID_SID
);
1902 for (i
= 0; i
< sizeof(SidTable
) / sizeof(SidTable
[0]) - 1; i
++)
1904 if (wcscmp(StringSid
, SidTable
[i
].key
) == 0)
1906 WELL_KNOWN_SID_TYPE knownSid
= (WELL_KNOWN_SID_TYPE
)SidTable
[i
].value
;
1907 size
= SECURITY_MAX_SID_SIZE
;
1908 *sid
= LocalAlloc(0, size
);
1911 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
1914 ret
= CreateWellKnownSid(
1921 SetLastError(ERROR_INVALID_SID
);
1928 /* That's probably a string S-R-I-S-S... */
1929 if (StringSid
[0] != 'S' || StringSid
[1] != '-')
1931 SetLastError(ERROR_INVALID_SID
);
1935 cBytes
= ComputeStringSidSize(StringSid
);
1936 pisid
= (SID
*)LocalAlloc( 0, cBytes
);
1939 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
1944 csubauth
= ((cBytes
- GetSidLengthRequired(0)) / sizeof(DWORD
));
1946 StringSid
+= 2; /* Advance to Revision */
1947 pisid
->Revision
= atoiW(StringSid
);
1949 if (pisid
->Revision
!= SDDL_REVISION
)
1951 TRACE("Revision %d is unknown\n", pisid
->Revision
);
1952 goto lend
; /* ERROR_INVALID_SID */
1956 TRACE("SubAuthorityCount is 0\n");
1957 goto lend
; /* ERROR_INVALID_SID */
1960 pisid
->SubAuthorityCount
= csubauth
;
1962 /* Advance to identifier authority */
1963 while (*StringSid
&& *StringSid
!= '-')
1965 if (*StringSid
== '-')
1968 /* MS' implementation can't handle values greater than 2^32 - 1, so
1969 * we don't either; assume most significant bytes are always 0
1971 pisid
->IdentifierAuthority
.Value
[0] = 0;
1972 pisid
->IdentifierAuthority
.Value
[1] = 0;
1973 identAuth
= atoiW(StringSid
);
1974 pisid
->IdentifierAuthority
.Value
[5] = identAuth
& 0xff;
1975 pisid
->IdentifierAuthority
.Value
[4] = (identAuth
& 0xff00) >> 8;
1976 pisid
->IdentifierAuthority
.Value
[3] = (identAuth
& 0xff0000) >> 16;
1977 pisid
->IdentifierAuthority
.Value
[2] = (identAuth
& 0xff000000) >> 24;
1979 /* Advance to first sub authority */
1980 while (*StringSid
&& *StringSid
!= '-')
1982 if (*StringSid
== '-')
1985 pisid
->SubAuthority
[i
] = atoiW(StringSid
);
1989 while (*StringSid
&& *StringSid
!= '-')
1991 if (*StringSid
== '-')
1994 pisid
->SubAuthority
[++i
] = atoiW(StringSid
);
1997 if (i
!= pisid
->SubAuthorityCount
)
1998 goto lend
; /* ERROR_INVALID_SID */
2005 SetLastError(ERROR_INVALID_SID
);
2007 TRACE("returning %s\n", ret
? "TRUE" : "FALSE");