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
} } },
113 typedef struct WELLKNOWNRID
115 WELL_KNOWN_SID_TYPE Type
;
119 static const WELLKNOWNRID WellKnownRids
[] = {
120 { WinAccountAdministratorSid
, DOMAIN_USER_RID_ADMIN
},
121 { WinAccountGuestSid
, DOMAIN_USER_RID_GUEST
},
122 { WinAccountKrbtgtSid
, DOMAIN_USER_RID_KRBTGT
},
123 { WinAccountDomainAdminsSid
, DOMAIN_GROUP_RID_ADMINS
},
124 { WinAccountDomainUsersSid
, DOMAIN_GROUP_RID_USERS
},
125 { WinAccountDomainGuestsSid
, DOMAIN_GROUP_RID_GUESTS
},
126 { WinAccountComputersSid
, DOMAIN_GROUP_RID_COMPUTERS
},
127 { WinAccountControllersSid
, DOMAIN_GROUP_RID_CONTROLLERS
},
128 { WinAccountCertAdminsSid
, DOMAIN_GROUP_RID_CERT_ADMINS
},
129 { WinAccountSchemaAdminsSid
, DOMAIN_GROUP_RID_SCHEMA_ADMINS
},
130 { WinAccountEnterpriseAdminsSid
, DOMAIN_GROUP_RID_ENTERPRISE_ADMINS
},
131 { WinAccountPolicyAdminsSid
, DOMAIN_GROUP_RID_POLICY_ADMINS
},
132 { WinAccountRasAndIasServersSid
, DOMAIN_ALIAS_RID_RAS_SERVERS
},
135 static const SID sidWorld
= { SID_REVISION
, 1, { SECURITY_WORLD_SID_AUTHORITY
} , { SECURITY_WORLD_RID
} };
140 static const WCHAR SDDL_ACCESS_ALLOWED
[] = {'A',0};
141 static const WCHAR SDDL_ACCESS_DENIED
[] = {'D',0};
142 static const WCHAR SDDL_OBJECT_ACCESS_ALLOWED
[] = {'O','A',0};
143 static const WCHAR SDDL_OBJECT_ACCESS_DENIED
[] = {'O','D',0};
144 static const WCHAR SDDL_AUDIT
[] = {'A','U',0};
145 static const WCHAR SDDL_ALARM
[] = {'A','L',0};
146 static const WCHAR SDDL_OBJECT_AUDIT
[] = {'O','U',0};
147 static const WCHAR SDDL_OBJECT_ALARM
[] = {'O','L',0};
152 #define ADS_RIGHT_DS_CREATE_CHILD 0x0001
153 #define ADS_RIGHT_DS_DELETE_CHILD 0x0002
154 #define ADS_RIGHT_ACTRL_DS_LIST 0x0004
155 #define ADS_RIGHT_DS_SELF 0x0008
156 #define ADS_RIGHT_DS_READ_PROP 0x0010
157 #define ADS_RIGHT_DS_WRITE_PROP 0x0020
158 #define ADS_RIGHT_DS_DELETE_TREE 0x0040
159 #define ADS_RIGHT_DS_LIST_OBJECT 0x0080
160 #define ADS_RIGHT_DS_CONTROL_ACCESS 0x0100
165 static const WCHAR SDDL_CONTAINER_INHERIT
[] = {'C','I',0};
166 static const WCHAR SDDL_OBJECT_INHERIT
[] = {'O','I',0};
167 static const WCHAR SDDL_NO_PROPAGATE
[] = {'N','P',0};
168 static const WCHAR SDDL_INHERIT_ONLY
[] = {'I','O',0};
169 static const WCHAR SDDL_INHERITED
[] = {'I','D',0};
170 static const WCHAR SDDL_AUDIT_SUCCESS
[] = {'S','A',0};
171 static const WCHAR SDDL_AUDIT_FAILURE
[] = {'F','A',0};
173 static const char * debugstr_sid(PSID sid
)
176 SID
* psid
= (SID
*)sid
;
181 auth
= psid
->IdentifierAuthority
.Value
[5] +
182 (psid
->IdentifierAuthority
.Value
[4] << 8) +
183 (psid
->IdentifierAuthority
.Value
[3] << 16) +
184 (psid
->IdentifierAuthority
.Value
[2] << 24);
186 switch (psid
->SubAuthorityCount
) {
188 return wine_dbg_sprintf("S-%d-%d", psid
->Revision
, auth
);
190 return wine_dbg_sprintf("S-%d-%d-%lu", psid
->Revision
, auth
,
191 psid
->SubAuthority
[0]);
193 return wine_dbg_sprintf("S-%d-%d-%lu-%lu", psid
->Revision
, auth
,
194 psid
->SubAuthority
[0], psid
->SubAuthority
[1]);
196 return wine_dbg_sprintf("S-%d-%d-%lu-%lu-%lu", psid
->Revision
, auth
,
197 psid
->SubAuthority
[0], psid
->SubAuthority
[1], psid
->SubAuthority
[2]);
199 return wine_dbg_sprintf("S-%d-%d-%lu-%lu-%lu-%lu", psid
->Revision
, auth
,
200 psid
->SubAuthority
[0], psid
->SubAuthority
[1], psid
->SubAuthority
[2],
201 psid
->SubAuthority
[3]);
203 return wine_dbg_sprintf("S-%d-%d-%lu-%lu-%lu-%lu-%lu", psid
->Revision
, auth
,
204 psid
->SubAuthority
[0], psid
->SubAuthority
[1], psid
->SubAuthority
[2],
205 psid
->SubAuthority
[3], psid
->SubAuthority
[4]);
207 return wine_dbg_sprintf("S-%d-%d-%lu-%lu-%lu-%lu-%lu-%lu", psid
->Revision
, auth
,
208 psid
->SubAuthority
[3], psid
->SubAuthority
[1], psid
->SubAuthority
[2],
209 psid
->SubAuthority
[0], psid
->SubAuthority
[4], psid
->SubAuthority
[5]);
211 return wine_dbg_sprintf("S-%d-%d-%lu-%lu-%lu-%lu-%lu-%lu-%lu", psid
->Revision
, auth
,
212 psid
->SubAuthority
[0], psid
->SubAuthority
[1], psid
->SubAuthority
[2],
213 psid
->SubAuthority
[3], psid
->SubAuthority
[4], psid
->SubAuthority
[5],
214 psid
->SubAuthority
[6]);
216 return wine_dbg_sprintf("S-%d-%d-%lu-%lu-%lu-%lu-%lu-%lu-%lu-%lu", psid
->Revision
, auth
,
217 psid
->SubAuthority
[0], psid
->SubAuthority
[1], psid
->SubAuthority
[2],
218 psid
->SubAuthority
[3], psid
->SubAuthority
[4], psid
->SubAuthority
[5],
219 psid
->SubAuthority
[6], psid
->SubAuthority
[7]);
224 static const ACEFLAG AceRights
[] =
226 { SDDL_GENERIC_ALL
, GENERIC_ALL
},
227 { SDDL_GENERIC_READ
, GENERIC_READ
},
228 { SDDL_GENERIC_WRITE
, GENERIC_WRITE
},
229 { SDDL_GENERIC_EXECUTE
, GENERIC_EXECUTE
},
231 { SDDL_READ_CONTROL
, READ_CONTROL
},
232 { SDDL_STANDARD_DELETE
, DELETE
},
233 { SDDL_WRITE_DAC
, WRITE_DAC
},
234 { SDDL_WRITE_OWNER
, WRITE_OWNER
},
236 { SDDL_READ_PROPERTY
, ADS_RIGHT_DS_READ_PROP
},
237 { SDDL_WRITE_PROPERTY
, ADS_RIGHT_DS_WRITE_PROP
},
238 { SDDL_CREATE_CHILD
, ADS_RIGHT_DS_CREATE_CHILD
},
239 { SDDL_DELETE_CHILD
, ADS_RIGHT_DS_DELETE_CHILD
},
240 { SDDL_LIST_CHILDREN
, ADS_RIGHT_ACTRL_DS_LIST
},
241 { SDDL_SELF_WRITE
, ADS_RIGHT_DS_SELF
},
242 { SDDL_LIST_OBJECT
, ADS_RIGHT_DS_LIST_OBJECT
},
243 { SDDL_DELETE_TREE
, ADS_RIGHT_DS_DELETE_TREE
},
244 { SDDL_CONTROL_ACCESS
, ADS_RIGHT_DS_CONTROL_ACCESS
},
246 { SDDL_FILE_ALL
, FILE_ALL_ACCESS
},
247 { SDDL_FILE_READ
, FILE_GENERIC_READ
},
248 { SDDL_FILE_WRITE
, FILE_GENERIC_WRITE
},
249 { SDDL_FILE_EXECUTE
, FILE_GENERIC_EXECUTE
},
251 { SDDL_KEY_ALL
, KEY_ALL_ACCESS
},
252 { SDDL_KEY_READ
, KEY_READ
},
253 { SDDL_KEY_WRITE
, KEY_WRITE
},
254 { SDDL_KEY_EXECUTE
, KEY_EXECUTE
},
258 static const LPCWSTR AceRightBitNames
[32] = {
259 SDDL_CREATE_CHILD
, /* 0 */
263 SDDL_READ_PROPERTY
, /* 4 */
267 SDDL_CONTROL_ACCESS
, /* 8 */
275 SDDL_STANDARD_DELETE
, /* 16 */
287 SDDL_GENERIC_ALL
, /* 28 */
288 SDDL_GENERIC_EXECUTE
,
294 /* set last error code from NT status and get the proper boolean return value */
295 /* used for functions that are a simple wrapper around the corresponding ntdll API */
296 static __inline BOOL
set_ntstatus( NTSTATUS status
)
298 if (status
) SetLastError( RtlNtStatusToDosError( status
));
304 IN
const RECORD
* Table
,
306 OUT SIZE_T
* pKeyLength
,
309 const RECORD
* pRecord
= Table
;
310 while (pRecord
->key
!= NULL
)
312 if (wcsncmp(pRecord
->key
, Key
, wcslen(pRecord
->key
)) == 0)
314 *pKeyLength
= wcslen(pRecord
->key
);
315 *pItem
= pRecord
->value
;
320 SetLastError(ERROR_INVALID_PARAMETER
);
330 WCHAR str
[SDDL_ALIAS_SIZE
+ 1];
336 wcsncpy(str
, Buffer
, SDDL_ALIAS_SIZE
);
337 for (i
= SDDL_ALIAS_SIZE
; i
> 0; i
--)
339 str
[i
] = UNICODE_NULL
;
340 if (ConvertStringSidToSidW(str
, pSid
))
347 end
= wcschr(Buffer
, SDDL_ACE_ENDC
);
350 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
353 strSid
= (LPWSTR
)LocalAlloc(0, (end
- Buffer
) * sizeof(WCHAR
) + sizeof(UNICODE_NULL
));
356 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
359 wcsncpy(strSid
, Buffer
, end
- Buffer
+ 1);
360 strSid
[end
- Buffer
] = UNICODE_NULL
;
361 *pLength
= end
- Buffer
;
362 ret
= ConvertStringSidToSidW(strSid
, pSid
);
367 static const RECORD DaclFlagTable
[] =
369 { SDDL_PROTECTED
, SE_DACL_PROTECTED
},
370 { SDDL_AUTO_INHERIT_REQ
, SE_DACL_AUTO_INHERIT_REQ
},
371 { SDDL_AUTO_INHERITED
, SE_DACL_AUTO_INHERITED
},
375 static const RECORD SaclFlagTable
[] =
377 { SDDL_PROTECTED
, SE_SACL_PROTECTED
},
378 { SDDL_AUTO_INHERIT_REQ
, SE_SACL_AUTO_INHERIT_REQ
},
379 { SDDL_AUTO_INHERITED
, SE_SACL_AUTO_INHERITED
},
383 static const RECORD AceFlagTable
[] =
385 { SDDL_CONTAINER_INHERIT
, CONTAINER_INHERIT_ACE
},
386 { SDDL_OBJECT_INHERIT
, OBJECT_INHERIT_ACE
},
387 { SDDL_NO_PROPAGATE
, NO_PROPAGATE_INHERIT_ACE
},
388 { SDDL_INHERIT_ONLY
, INHERIT_ONLY_ACE
},
389 { SDDL_INHERITED
, INHERITED_ACE
},
390 { SDDL_AUDIT_SUCCESS
, SUCCESSFUL_ACCESS_ACE_FLAG
},
391 { SDDL_AUDIT_FAILURE
, FAILED_ACCESS_ACE_FLAG
},
398 IN
const RECORD
* FlagTable
,
403 LPCWSTR ptr
= Buffer
;
404 SIZE_T PartialLength
;
408 while (*ptr
!= LimitChar
)
410 if (!FindKeyInTable(FlagTable
, ptr
, &PartialLength
, &Flag
))
413 ptr
+= PartialLength
;
415 *pLength
= ptr
- Buffer
;
419 static const RECORD AccessMaskTable
[] =
421 { SDDL_GENERIC_ALL
, GENERIC_ALL
},
422 { SDDL_GENERIC_READ
, GENERIC_READ
},
423 { SDDL_GENERIC_WRITE
, GENERIC_WRITE
},
424 { SDDL_GENERIC_EXECUTE
, GENERIC_EXECUTE
},
425 { SDDL_READ_CONTROL
, READ_CONTROL
},
426 { SDDL_STANDARD_DELETE
, DELETE
},
427 { SDDL_WRITE_DAC
, WRITE_DAC
},
428 { SDDL_WRITE_OWNER
, WRITE_OWNER
},
429 { SDDL_READ_PROPERTY
, ADS_RIGHT_DS_READ_PROP
},
430 { SDDL_WRITE_PROPERTY
, ADS_RIGHT_DS_WRITE_PROP
},
431 { SDDL_CREATE_CHILD
, ADS_RIGHT_DS_CREATE_CHILD
},
432 { SDDL_DELETE_CHILD
, ADS_RIGHT_DS_DELETE_CHILD
},
433 { SDDL_LIST_CHILDREN
, ADS_RIGHT_ACTRL_DS_LIST
},
434 { SDDL_SELF_WRITE
, ADS_RIGHT_DS_SELF
},
435 { SDDL_LIST_OBJECT
, ADS_RIGHT_DS_LIST_OBJECT
},
436 { SDDL_DELETE_TREE
, ADS_RIGHT_DS_DELETE_TREE
},
437 { SDDL_CONTROL_ACCESS
, ADS_RIGHT_DS_CONTROL_ACCESS
},
438 { SDDL_FILE_ALL
, FILE_ALL_ACCESS
},
439 { SDDL_FILE_READ
, FILE_GENERIC_READ
},
440 { SDDL_FILE_WRITE
, FILE_GENERIC_WRITE
},
441 { SDDL_FILE_EXECUTE
, FILE_GENERIC_EXECUTE
},
442 { SDDL_KEY_ALL
, KEY_ALL_ACCESS
},
443 { SDDL_KEY_READ
, KEY_READ
},
444 { SDDL_KEY_WRITE
, KEY_WRITE
},
445 { SDDL_KEY_EXECUTE
, KEY_EXECUTE
},
450 ParseAccessMaskString(
452 OUT DWORD
* pAccessMask
,
455 LPCWSTR szAcl
= Buffer
;
459 if ((*szAcl
== '0') && (*(szAcl
+ 1) == 'x'))
463 while (*p
&& *p
!= ';')
466 if (p
- szAcl
<= 10 /* 8 hex digits + "0x" */ )
468 *pAccessMask
= strtoulW(szAcl
, NULL
, 16);
469 ptr
= wcschr(Buffer
, SDDL_SEPERATORC
);
472 *pLength
= ptr
- Buffer
;
479 RetVal
= ParseFlagsString(Buffer
, AccessMaskTable
, SDDL_SEPERATORC
, pAccessMask
, pLength
);
489 OUT BOOL
* pIsGuidValid
,
492 WCHAR GuidStr
[MAX_GUID_STRING_LEN
+ 1];
495 end
= wcschr(Buffer
, SDDL_SEPERATORC
);
498 SetLastError(ERROR_INVALID_PARAMETER
);
502 *pLength
= end
- Buffer
;
503 *pIsGuidValid
= (end
!= Buffer
);
507 if (end
- Buffer
> MAX_GUID_STRING_LEN
- 1)
509 SetLastError(ERROR_INVALID_PARAMETER
);
512 GuidStr
[end
- Buffer
] = UNICODE_NULL
;
513 wcsncpy(GuidStr
, Buffer
, end
- Buffer
);
514 if (RPC_S_OK
!= UuidFromStringW((unsigned short*)&GuidStr
, pGuid
))
516 SetLastError(ERROR_INVALID_PARAMETER
);
522 static const RECORD AceTypeTable
[] =
524 { SDDL_OBJECT_ACCESS_ALLOWED
, ACCESS_ALLOWED_OBJECT_ACE_TYPE
},
525 { SDDL_OBJECT_ACCESS_DENIED
, ACCESS_DENIED_OBJECT_ACE_TYPE
},
526 { SDDL_AUDIT
, SYSTEM_AUDIT_ACE_TYPE
},
527 { SDDL_ALARM
, SYSTEM_ALARM_ACE_TYPE
},
528 { SDDL_OBJECT_AUDIT
, SYSTEM_AUDIT_OBJECT_ACE_TYPE
},
529 { SDDL_OBJECT_ALARM
, SYSTEM_ALARM_OBJECT_ACE_TYPE
},
530 { SDDL_ACCESS_ALLOWED
, ACCESS_ALLOWED_ACE_TYPE
},
531 { SDDL_ACCESS_DENIED
, ACCESS_DENIED_ACE_TYPE
},
541 LPCWSTR ptr
= Buffer
;
542 SIZE_T PartialLength
;
543 DWORD aceType
, aceFlags
, accessMask
;
544 GUID object
, inheritObject
;
545 BOOL objectValid
, inheritObjectValid
;
549 if (*ptr
!= SDDL_ACE_BEGINC
)
551 SetLastError(ERROR_INVALID_PARAMETER
);
554 ptr
++; /* Skip SDDL_ACE_BEGINC */
556 if (!FindKeyInTable(AceTypeTable
, ptr
, &PartialLength
, &aceType
))
558 ptr
+= PartialLength
;
560 if (*ptr
!= SDDL_SEPERATORC
)
562 SetLastError(ERROR_INVALID_PARAMETER
);
565 ptr
++; /* Skip SDDL_SEPERATORC */
567 if (!ParseFlagsString(ptr
, AceFlagTable
, SDDL_SEPERATORC
, &aceFlags
, &PartialLength
))
569 ptr
+= PartialLength
+ 1;
571 if (!ParseAccessMaskString(ptr
, &accessMask
, &PartialLength
))
573 ptr
+= PartialLength
+ 1;
575 if (!ParseGuidString(ptr
, &object
, &objectValid
, &PartialLength
))
577 ptr
+= PartialLength
+ 1;
579 if (!ParseGuidString(ptr
, &inheritObject
, &inheritObjectValid
, &PartialLength
))
581 ptr
+= PartialLength
+ 1;
583 if (!ParseSidString(ptr
, &sid
, &PartialLength
))
585 ptr
+= PartialLength
;
586 if (*ptr
!= SDDL_ACE_ENDC
)
588 SetLastError(ERROR_INVALID_PARAMETER
);
591 ptr
++; /* Skip SDDL_ACE_ENDC */
592 *pLength
= ptr
- Buffer
;
596 case ACCESS_ALLOWED_ACE_TYPE
:
597 ret
= AddAccessAllowedAceEx(
604 case ACCESS_ALLOWED_OBJECT_ACE_TYPE
:
605 ret
= AddAccessAllowedObjectAce(
610 objectValid
? &object
: NULL
,
611 inheritObjectValid
? &inheritObject
: NULL
,
614 case ACCESS_DENIED_ACE_TYPE
:
615 ret
= AddAccessDeniedAceEx(
622 case ACCESS_DENIED_OBJECT_ACE_TYPE
:
623 ret
= AddAccessDeniedObjectAce(
628 objectValid
? &object
: NULL
,
629 inheritObjectValid
? &inheritObject
: NULL
,
632 case SYSTEM_AUDIT_ACE_TYPE
:
633 ret
= AddAuditAccessAceEx(
642 case SYSTEM_AUDIT_OBJECT_ACE_TYPE
:
643 ret
= AddAuditAccessObjectAce(
648 objectValid
? &object
: NULL
,
649 inheritObjectValid
? &inheritObject
: NULL
,
654 case SYSTEM_ALARM_ACE_TYPE
:
655 case SYSTEM_ALARM_OBJECT_ACE_TYPE
:
658 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
666 /* Exported functions */
672 AllocateLocallyUniqueId(PLUID Luid
)
676 Status
= NtAllocateLocallyUniqueId (Luid
);
677 if (!NT_SUCCESS (Status
))
679 SetLastError(RtlNtStatusToDosError(Status
));
691 AllocateAndInitializeSid(PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority
,
692 BYTE nSubAuthorityCount
,
693 DWORD dwSubAuthority0
,
694 DWORD dwSubAuthority1
,
695 DWORD dwSubAuthority2
,
696 DWORD dwSubAuthority3
,
697 DWORD dwSubAuthority4
,
698 DWORD dwSubAuthority5
,
699 DWORD dwSubAuthority6
,
700 DWORD dwSubAuthority7
,
705 Status
= RtlAllocateAndInitializeSid(pIdentifierAuthority
,
716 if (!NT_SUCCESS(Status
))
718 SetLastError(RtlNtStatusToDosError(Status
));
730 CopySid(DWORD nDestinationSidLength
,
731 PSID pDestinationSid
,
736 Status
= RtlCopySid(nDestinationSidLength
,
739 if (!NT_SUCCESS (Status
))
741 SetLastError(RtlNtStatusToDosError(Status
));
748 static void DumpString(LPCWSTR string
, int cch
, WCHAR
**pwptr
, ULONG
*plen
)
751 cch
= strlenW(string
);
758 memcpy(*pwptr
, string
, sizeof(WCHAR
)*cch
);
763 static BOOL
DumpSidNumeric(PSID psid
, WCHAR
**pwptr
, ULONG
*plen
)
766 WCHAR fmt
[] = { 'S','-','%','u','-','%','d',0 };
767 WCHAR subauthfmt
[] = { '-','%','u',0 };
771 if( !IsValidSid( psid
) || pisid
->Revision
!= SDDL_REVISION
)
773 SetLastError(ERROR_INVALID_SID
);
777 if (pisid
->IdentifierAuthority
.Value
[0] ||
778 pisid
->IdentifierAuthority
.Value
[1])
780 FIXME("not matching MS' bugs\n");
781 SetLastError(ERROR_INVALID_SID
);
785 sprintfW( buf
, fmt
, pisid
->Revision
,
787 MAKEWORD( pisid
->IdentifierAuthority
.Value
[5],
788 pisid
->IdentifierAuthority
.Value
[4] ),
789 MAKEWORD( pisid
->IdentifierAuthority
.Value
[3],
790 pisid
->IdentifierAuthority
.Value
[2] )
792 DumpString(buf
, -1, pwptr
, plen
);
794 for( i
=0; i
<pisid
->SubAuthorityCount
; i
++ )
796 sprintfW( buf
, subauthfmt
, pisid
->SubAuthority
[i
] );
797 DumpString(buf
, -1, pwptr
, plen
);
802 static BOOL
DumpSid(PSID psid
, WCHAR
**pwptr
, ULONG
*plen
)
805 for (i
= 0; i
< sizeof(WellKnownSids
) / sizeof(WellKnownSids
[0]); i
++)
807 if (WellKnownSids
[i
].wstr
[0] && EqualSid(psid
, (PSID
)&(WellKnownSids
[i
].Sid
.Revision
)))
809 DumpString(WellKnownSids
[i
].wstr
, 2, pwptr
, plen
);
814 return DumpSidNumeric(psid
, pwptr
, plen
);
817 static void DumpRights(DWORD mask
, WCHAR
**pwptr
, ULONG
*plen
)
819 static const WCHAR fmtW
[] = {'0','x','%','x',0};
826 /* first check if the right have name */
827 for (i
= 0; i
< sizeof(AceRights
)/sizeof(AceRights
[0]); i
++)
829 if (AceRights
[i
].wstr
== NULL
)
831 if (mask
== AceRights
[i
].value
)
833 DumpString(AceRights
[i
].wstr
, -1, pwptr
, plen
);
838 /* then check if it can be built from bit names */
839 for (i
= 0; i
< 32; i
++)
841 if ((mask
& (1 << i
)) && (AceRightBitNames
[i
] == NULL
))
843 /* can't be built from bit names */
844 sprintfW(buf
, fmtW
, mask
);
845 DumpString(buf
, -1, pwptr
, plen
);
850 /* build from bit names */
851 for (i
= 0; i
< 32; i
++)
853 DumpString(AceRightBitNames
[i
], -1, pwptr
, plen
);
856 static BOOL
DumpAce(LPVOID pace
, WCHAR
**pwptr
, ULONG
*plen
)
858 ACCESS_ALLOWED_ACE
*piace
; /* all the supported ACEs have the same memory layout */
859 static const WCHAR openbr
= '(';
860 static const WCHAR closebr
= ')';
861 static const WCHAR semicolon
= ';';
863 if (((PACE_HEADER
)pace
)->AceType
> SYSTEM_ALARM_ACE_TYPE
|| ((PACE_HEADER
)pace
)->AceSize
< sizeof(ACCESS_ALLOWED_ACE
))
865 SetLastError(ERROR_INVALID_ACL
);
869 piace
= (ACCESS_ALLOWED_ACE
*)pace
;
870 DumpString(&openbr
, 1, pwptr
, plen
);
871 switch (piace
->Header
.AceType
)
873 case ACCESS_ALLOWED_ACE_TYPE
:
874 DumpString(SDDL_ACCESS_ALLOWED
, -1, pwptr
, plen
);
876 case ACCESS_DENIED_ACE_TYPE
:
877 DumpString(SDDL_ACCESS_DENIED
, -1, pwptr
, plen
);
879 case SYSTEM_AUDIT_ACE_TYPE
:
880 DumpString(SDDL_AUDIT
, -1, pwptr
, plen
);
882 case SYSTEM_ALARM_ACE_TYPE
:
883 DumpString(SDDL_ALARM
, -1, pwptr
, plen
);
886 DumpString(&semicolon
, 1, pwptr
, plen
);
888 if (piace
->Header
.AceFlags
& OBJECT_INHERIT_ACE
)
889 DumpString(SDDL_OBJECT_INHERIT
, -1, pwptr
, plen
);
890 if (piace
->Header
.AceFlags
& CONTAINER_INHERIT_ACE
)
891 DumpString(SDDL_CONTAINER_INHERIT
, -1, pwptr
, plen
);
892 if (piace
->Header
.AceFlags
& NO_PROPAGATE_INHERIT_ACE
)
893 DumpString(SDDL_NO_PROPAGATE
, -1, pwptr
, plen
);
894 if (piace
->Header
.AceFlags
& INHERIT_ONLY_ACE
)
895 DumpString(SDDL_INHERIT_ONLY
, -1, pwptr
, plen
);
896 if (piace
->Header
.AceFlags
& INHERITED_ACE
)
897 DumpString(SDDL_INHERITED
, -1, pwptr
, plen
);
898 if (piace
->Header
.AceFlags
& SUCCESSFUL_ACCESS_ACE_FLAG
)
899 DumpString(SDDL_AUDIT_SUCCESS
, -1, pwptr
, plen
);
900 if (piace
->Header
.AceFlags
& FAILED_ACCESS_ACE_FLAG
)
901 DumpString(SDDL_AUDIT_FAILURE
, -1, pwptr
, plen
);
902 DumpString(&semicolon
, 1, pwptr
, plen
);
903 DumpRights(piace
->Mask
, pwptr
, plen
);
904 DumpString(&semicolon
, 1, pwptr
, plen
);
905 /* objects not supported */
906 DumpString(&semicolon
, 1, pwptr
, plen
);
907 /* objects not supported */
908 DumpString(&semicolon
, 1, pwptr
, plen
);
909 if (!DumpSid((PSID
)&piace
->SidStart
, pwptr
, plen
))
911 DumpString(&closebr
, 1, pwptr
, plen
);
915 static BOOL
DumpAcl(PACL pacl
, WCHAR
**pwptr
, ULONG
*plen
, BOOL
protected, BOOL autoInheritReq
, BOOL autoInherited
)
921 DumpString(SDDL_PROTECTED
, -1, pwptr
, plen
);
923 DumpString(SDDL_AUTO_INHERIT_REQ
, -1, pwptr
, plen
);
925 DumpString(SDDL_AUTO_INHERITED
, -1, pwptr
, plen
);
930 if (!IsValidAcl(pacl
))
933 count
= pacl
->AceCount
;
934 for (i
= 0; i
< count
; i
++)
937 if (!GetAce(pacl
, i
, &ace
))
939 if (!DumpAce(ace
, pwptr
, plen
))
946 static BOOL
DumpOwner(PSECURITY_DESCRIPTOR SecurityDescriptor
, WCHAR
**pwptr
, ULONG
*plen
)
948 static const WCHAR prefix
[] = {'O',':',0};
952 if (!GetSecurityDescriptorOwner(SecurityDescriptor
, &psid
, &bDefaulted
))
958 DumpString(prefix
, -1, pwptr
, plen
);
959 if (!DumpSid(psid
, pwptr
, plen
))
964 static BOOL
DumpGroup(PSECURITY_DESCRIPTOR SecurityDescriptor
, WCHAR
**pwptr
, ULONG
*plen
)
966 static const WCHAR prefix
[] = {'G',':',0};
970 if (!GetSecurityDescriptorGroup(SecurityDescriptor
, &psid
, &bDefaulted
))
976 DumpString(prefix
, -1, pwptr
, plen
);
977 if (!DumpSid(psid
, pwptr
, plen
))
982 static BOOL
DumpDacl(PSECURITY_DESCRIPTOR SecurityDescriptor
, WCHAR
**pwptr
, ULONG
*plen
)
984 static const WCHAR dacl
[] = {'D',':',0};
985 SECURITY_DESCRIPTOR_CONTROL control
;
986 BOOL present
, defaulted
;
990 if (!GetSecurityDescriptorDacl(SecurityDescriptor
, &present
, &pacl
, &defaulted
))
993 if (!GetSecurityDescriptorControl(SecurityDescriptor
, &control
, &revision
))
999 DumpString(dacl
, 2, pwptr
, plen
);
1000 if (!DumpAcl(pacl
, pwptr
, plen
, control
& SE_DACL_PROTECTED
, control
& SE_DACL_AUTO_INHERIT_REQ
, control
& SE_DACL_AUTO_INHERITED
))
1005 static BOOL
DumpSacl(PSECURITY_DESCRIPTOR SecurityDescriptor
, WCHAR
**pwptr
, ULONG
*plen
)
1007 static const WCHAR sacl
[] = {'S',':',0};
1008 SECURITY_DESCRIPTOR_CONTROL control
;
1009 BOOL present
, defaulted
;
1013 if (!GetSecurityDescriptorSacl(SecurityDescriptor
, &present
, &pacl
, &defaulted
))
1016 if (!GetSecurityDescriptorControl(SecurityDescriptor
, &control
, &revision
))
1022 DumpString(sacl
, 2, pwptr
, plen
);
1023 if (!DumpAcl(pacl
, pwptr
, plen
, control
& SE_SACL_PROTECTED
, control
& SE_SACL_AUTO_INHERIT_REQ
, control
& SE_SACL_AUTO_INHERITED
))
1028 /******************************************************************************
1029 * ConvertSecurityDescriptorToStringSecurityDescriptorW [ADVAPI32.@]
1033 ConvertSecurityDescriptorToStringSecurityDescriptorW(PSECURITY_DESCRIPTOR SecurityDescriptor
,
1035 SECURITY_INFORMATION SecurityInformation
,
1036 LPWSTR
*OutputString
,
1042 if (SDRevision
!= SDDL_REVISION_1
)
1044 ERR("Pogram requested unknown SDDL revision %d\n", SDRevision
);
1045 SetLastError(ERROR_UNKNOWN_REVISION
);
1050 if (SecurityInformation
& OWNER_SECURITY_INFORMATION
)
1051 if (!DumpOwner(SecurityDescriptor
, NULL
, &len
))
1053 if (SecurityInformation
& GROUP_SECURITY_INFORMATION
)
1054 if (!DumpGroup(SecurityDescriptor
, NULL
, &len
))
1056 if (SecurityInformation
& DACL_SECURITY_INFORMATION
)
1057 if (!DumpDacl(SecurityDescriptor
, NULL
, &len
))
1059 if (SecurityInformation
& SACL_SECURITY_INFORMATION
)
1060 if (!DumpSacl(SecurityDescriptor
, NULL
, &len
))
1063 wstr
= wptr
= LocalAlloc(0, (len
+ 1)*sizeof(WCHAR
));
1064 if (SecurityInformation
& OWNER_SECURITY_INFORMATION
)
1065 if (!DumpOwner(SecurityDescriptor
, &wptr
, NULL
))
1067 if (SecurityInformation
& GROUP_SECURITY_INFORMATION
)
1068 if (!DumpGroup(SecurityDescriptor
, &wptr
, NULL
))
1070 if (SecurityInformation
& DACL_SECURITY_INFORMATION
)
1071 if (!DumpDacl(SecurityDescriptor
, &wptr
, NULL
))
1073 if (SecurityInformation
& SACL_SECURITY_INFORMATION
)
1074 if (!DumpSacl(SecurityDescriptor
, &wptr
, NULL
))
1078 TRACE("ret: %s, %d\n", wine_dbgstr_w(wstr
), len
);
1079 *OutputString
= wstr
;
1081 *OutputLen
= strlenW(*OutputString
)+1;
1086 /******************************************************************************
1087 * ConvertSecurityDescriptorToStringSecurityDescriptorA [ADVAPI32.@]
1091 ConvertSecurityDescriptorToStringSecurityDescriptorA(PSECURITY_DESCRIPTOR SecurityDescriptor
,
1093 SECURITY_INFORMATION Information
,
1094 LPSTR
*OutputString
,
1099 if (ConvertSecurityDescriptorToStringSecurityDescriptorW(SecurityDescriptor
, SDRevision
, Information
, &wstr
, &len
))
1103 lenA
= WideCharToMultiByte(CP_ACP
, 0, wstr
, len
, NULL
, 0, NULL
, NULL
);
1104 *OutputString
= HeapAlloc(GetProcessHeap(), 0, lenA
);
1105 WideCharToMultiByte(CP_ACP
, 0, wstr
, len
, *OutputString
, lenA
, NULL
, NULL
);
1108 if (OutputLen
!= NULL
)
1114 *OutputString
= NULL
;
1121 /******************************************************************************
1122 * ConvertStringSecurityDescriptorToSecurityDescriptorW [ADVAPI32.@]
1126 ConvertStringSecurityDescriptorToSecurityDescriptorW(
1127 IN LPCWSTR StringSecurityDescriptor
,
1128 IN DWORD StringSDRevision
,
1129 OUT PSECURITY_DESCRIPTOR
* SecurityDescriptor
,
1130 OUT PULONG SecurityDescriptorSize
)
1132 PSECURITY_DESCRIPTOR sd
= NULL
;
1135 if (!StringSecurityDescriptor
|| !SecurityDescriptor
)
1136 SetLastError(ERROR_INVALID_PARAMETER
);
1137 else if (StringSDRevision
!= SDDL_REVISION_1
)
1138 SetLastError(ERROR_INVALID_PARAMETER
);
1141 LPCWSTR ptr
= StringSecurityDescriptor
;
1142 DWORD numberOfAces
= 0;
1143 DWORD relativeSdSize
;
1145 PSECURITY_DESCRIPTOR relativeSd
= NULL
;
1148 BOOL present
, dummy
;
1149 /* An easy way to know how much space we need for an ACL is to count
1150 * the number of ACEs and say that we have 1 SID by ACE
1152 ptr
= wcschr(StringSecurityDescriptor
, SDDL_ACE_BEGINC
);
1156 ptr
= wcschr(ptr
+ 1, SDDL_ACE_BEGINC
);
1158 MaxAclSize
= sizeof(ACL
) + numberOfAces
*
1159 (sizeof(ACCESS_ALLOWED_OBJECT_ACE
) + SECURITY_MAX_SID_SIZE
);
1161 sd
= (SECURITY_DESCRIPTOR
*)LocalAlloc(0, sizeof(SECURITY_DESCRIPTOR
));
1164 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
1167 ret
= InitializeSecurityDescriptor(sd
, SECURITY_DESCRIPTOR_REVISION
);
1171 /* Now, really parse the string */
1172 ptr
= StringSecurityDescriptor
;
1175 if (ptr
[1] != SDDL_DELIMINATORC
)
1177 SetLastError(ERROR_INVALID_PARAMETER
);
1190 ret
= ParseSidString(ptr
, &pSid
, &Length
);
1194 ret
= SetSecurityDescriptorOwner(sd
, pSid
, FALSE
);
1196 ret
= SetSecurityDescriptorGroup(sd
, pSid
, FALSE
);
1210 BOOL isDacl
= (ptr
[-2] == 'D');
1213 ret
= ParseFlagsString(ptr
, DaclFlagTable
, SDDL_ACE_BEGINC
, &aclFlags
, &Length
);
1215 ret
= ParseFlagsString(ptr
, SaclFlagTable
, SDDL_ACE_BEGINC
, &aclFlags
, &Length
);
1218 pAcl
= (PACL
)LocalAlloc(0, MaxAclSize
);
1221 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
1225 if (!InitializeAcl(pAcl
, (DWORD
)MaxAclSize
, ACL_REVISION_DS
))
1232 ret
= SetSecurityDescriptorControl(
1234 (SECURITY_DESCRIPTOR_CONTROL
)aclFlags
,
1235 (SECURITY_DESCRIPTOR_CONTROL
)aclFlags
);
1243 while (*ptr
== SDDL_ACE_BEGINC
)
1245 ret
= ParseAceString(ptr
, pAcl
, &Length
);
1254 ret
= SetSecurityDescriptorDacl(sd
, TRUE
, pAcl
, FALSE
);
1256 ret
= SetSecurityDescriptorSacl(sd
, TRUE
, pAcl
, FALSE
);
1266 SetLastError(ERROR_INVALID_PARAMETER
);
1277 LocalFree(relativeSd
);
1278 relativeSd
= LocalAlloc(0, relativeSdSize
);
1281 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
1284 ret
= MakeSelfRelativeSD(sd
, relativeSd
, &relativeSdSize
);
1285 if (ret
|| GetLastError() != ERROR_INSUFFICIENT_BUFFER
)
1288 if (SecurityDescriptorSize
)
1289 *SecurityDescriptorSize
= relativeSdSize
;
1290 *SecurityDescriptor
= relativeSd
;
1293 if (GetSecurityDescriptorOwner(sd
, &pSid
, &dummy
))
1295 if (GetSecurityDescriptorGroup(sd
, &pSid
, &dummy
))
1297 if (GetSecurityDescriptorDacl(sd
, &present
, &pAcl
, &dummy
) && present
)
1299 if (GetSecurityDescriptorSacl(sd
, &present
, &pAcl
, &dummy
) && present
)
1307 /* Winehq cvs 20050916 */
1308 /******************************************************************************
1309 * ConvertStringSecurityDescriptorToSecurityDescriptorA [ADVAPI32.@]
1312 BOOL WINAPI
ConvertStringSecurityDescriptorToSecurityDescriptorA(
1313 LPCSTR StringSecurityDescriptor
,
1314 DWORD StringSDRevision
,
1315 PSECURITY_DESCRIPTOR
* SecurityDescriptor
,
1316 PULONG SecurityDescriptorSize
)
1320 LPWSTR StringSecurityDescriptorW
;
1322 len
= MultiByteToWideChar(CP_ACP
, 0, StringSecurityDescriptor
, -1, NULL
, 0);
1323 StringSecurityDescriptorW
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
1325 if (StringSecurityDescriptorW
)
1327 MultiByteToWideChar(CP_ACP
, 0, StringSecurityDescriptor
, -1, StringSecurityDescriptorW
, len
);
1329 ret
= ConvertStringSecurityDescriptorToSecurityDescriptorW(StringSecurityDescriptorW
,
1330 StringSDRevision
, SecurityDescriptor
,
1331 SecurityDescriptorSize
);
1332 HeapFree(GetProcessHeap(), 0, StringSecurityDescriptorW
);
1342 EqualPrefixSid(PSID pSid1
,
1345 return RtlEqualPrefixSid (pSid1
, pSid2
);
1353 EqualSid(PSID pSid1
,
1356 return RtlEqualSid (pSid1
, pSid2
);
1364 * Docs says this function does NOT return a value
1365 * even thou it's defined to return a PVOID...
1370 return RtlFreeSid(pSid
);
1378 GetLengthSid(PSID pSid
)
1380 return (DWORD
)RtlLengthSid(pSid
);
1387 PSID_IDENTIFIER_AUTHORITY WINAPI
1388 GetSidIdentifierAuthority(PSID pSid
)
1390 return RtlIdentifierAuthoritySid(pSid
);
1398 GetSidLengthRequired(UCHAR nSubAuthorityCount
)
1400 return (DWORD
)RtlLengthRequiredSid(nSubAuthorityCount
);
1408 GetSidSubAuthority(PSID pSid
,
1409 DWORD nSubAuthority
)
1411 return (PDWORD
)RtlSubAuthoritySid(pSid
, nSubAuthority
);
1419 GetSidSubAuthorityCount(PSID pSid
)
1421 return RtlSubAuthorityCountSid(pSid
);
1429 InitializeSid(PSID Sid
,
1430 PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority
,
1431 BYTE nSubAuthorityCount
)
1435 Status
= RtlInitializeSid(Sid
,
1436 pIdentifierAuthority
,
1437 nSubAuthorityCount
);
1438 if (!NT_SUCCESS(Status
))
1440 SetLastError(RtlNtStatusToDosError(Status
));
1452 IsValidSid(PSID pSid
)
1454 return (BOOL
)RtlValidSid(pSid
);
1462 ConvertSidToStringSidW(PSID Sid
,
1466 UNICODE_STRING UnicodeString
;
1467 WCHAR FixedBuffer
[64];
1469 if (!RtlValidSid(Sid
))
1471 SetLastError(ERROR_INVALID_SID
);
1475 UnicodeString
.Length
= 0;
1476 UnicodeString
.MaximumLength
= sizeof(FixedBuffer
);
1477 UnicodeString
.Buffer
= FixedBuffer
;
1478 Status
= RtlConvertSidToUnicodeString(&UnicodeString
, Sid
, FALSE
);
1479 if (STATUS_BUFFER_TOO_SMALL
== Status
)
1481 Status
= RtlConvertSidToUnicodeString(&UnicodeString
, Sid
, TRUE
);
1484 if (!NT_SUCCESS(Status
))
1486 SetLastError(RtlNtStatusToDosError(Status
));
1490 *StringSid
= LocalAlloc(LMEM_FIXED
, UnicodeString
.Length
+ sizeof(WCHAR
));
1491 if (NULL
== *StringSid
)
1493 if (UnicodeString
.Buffer
!= FixedBuffer
)
1495 RtlFreeUnicodeString(&UnicodeString
);
1497 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
1501 MoveMemory(*StringSid
, UnicodeString
.Buffer
, UnicodeString
.Length
);
1502 ZeroMemory((PCHAR
) *StringSid
+ UnicodeString
.Length
, sizeof(WCHAR
));
1503 if (UnicodeString
.Buffer
!= FixedBuffer
)
1505 RtlFreeUnicodeString(&UnicodeString
);
1516 ConvertSidToStringSidA(PSID Sid
,
1522 if (!ConvertSidToStringSidW(Sid
, &StringSidW
))
1527 Len
= WideCharToMultiByte(CP_ACP
, 0, StringSidW
, -1, NULL
, 0, NULL
, NULL
);
1530 LocalFree(StringSidW
);
1531 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
1535 *StringSid
= LocalAlloc(LMEM_FIXED
, Len
);
1536 if (NULL
== *StringSid
)
1538 LocalFree(StringSidW
);
1539 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
1543 if (!WideCharToMultiByte(CP_ACP
, 0, StringSidW
, -1, *StringSid
, Len
, NULL
, NULL
))
1545 LocalFree(StringSid
);
1546 LocalFree(StringSidW
);
1550 LocalFree(StringSidW
);
1560 EqualDomainSid(IN PSID pSid1
,
1573 GetWindowsAccountDomainSid(IN PSID pSid
,
1574 OUT PSID ppDomainSid
,
1575 IN OUT DWORD
* cbSid
)
1586 CreateWellKnownSid(IN WELL_KNOWN_SID_TYPE WellKnownSidType
,
1587 IN PSID DomainSid OPTIONAL
,
1589 IN OUT DWORD
* cbSid
)
1592 TRACE("(%d, %s, %p, %p)\n", WellKnownSidType
, debugstr_sid(DomainSid
), pSid
, cbSid
);
1594 if (cbSid
== NULL
|| pSid
== NULL
|| (DomainSid
&& !IsValidSid(DomainSid
))) {
1595 SetLastError(ERROR_INVALID_PARAMETER
);
1599 for (i
= 0; i
< sizeof(WellKnownSids
)/sizeof(WellKnownSids
[0]); i
++) {
1600 if (WellKnownSids
[i
].Type
== WellKnownSidType
) {
1601 DWORD length
= GetSidLengthRequired(WellKnownSids
[i
].Sid
.SubAuthorityCount
);
1603 if (*cbSid
< length
) {
1604 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
1608 CopyMemory(pSid
, &WellKnownSids
[i
].Sid
.Revision
, length
);
1614 if (DomainSid
== NULL
|| *GetSidSubAuthorityCount(DomainSid
) == SID_MAX_SUB_AUTHORITIES
)
1616 SetLastError(ERROR_INVALID_PARAMETER
);
1620 for (i
= 0; i
< sizeof(WellKnownRids
)/sizeof(WellKnownRids
[0]); i
++)
1621 if (WellKnownRids
[i
].Type
== WellKnownSidType
) {
1622 UCHAR domain_subauth
= *GetSidSubAuthorityCount(DomainSid
);
1623 DWORD domain_sid_length
= GetSidLengthRequired(domain_subauth
);
1624 DWORD output_sid_length
= GetSidLengthRequired(domain_subauth
+ 1);
1626 if (*cbSid
< output_sid_length
) {
1627 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
1631 CopyMemory(pSid
, DomainSid
, domain_sid_length
);
1632 (*GetSidSubAuthorityCount(pSid
))++;
1633 (*GetSidSubAuthority(pSid
, domain_subauth
)) = WellKnownRids
[i
].Rid
;
1634 *cbSid
= output_sid_length
;
1638 SetLastError(ERROR_INVALID_PARAMETER
);
1647 IsWellKnownSid(IN PSID pSid
,
1648 IN WELL_KNOWN_SID_TYPE WellKnownSidType
)
1651 TRACE("(%s, %d)\n", debugstr_sid(pSid
), WellKnownSidType
);
1653 for (i
= 0; i
< sizeof(WellKnownSids
) / sizeof(WellKnownSids
[0]); i
++)
1655 if (WellKnownSids
[i
].Type
== WellKnownSidType
)
1657 if (EqualSid(pSid
, (PSID
)((ULONG_PTR
)&WellKnownSids
[i
].Sid
.Revision
)))
1670 ConvertStringSidToSidA(IN LPCSTR StringSid
,
1673 BOOL bRetVal
= FALSE
;
1675 if (!StringSid
|| !sid
)
1676 SetLastError(ERROR_INVALID_PARAMETER
);
1679 UINT len
= MultiByteToWideChar(CP_ACP
, 0, StringSid
, -1, NULL
, 0);
1680 LPWSTR wStringSid
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
1681 MultiByteToWideChar(CP_ACP
, 0, StringSid
, - 1, wStringSid
, len
);
1682 bRetVal
= ConvertStringSidToSidW(wStringSid
, sid
);
1683 HeapFree(GetProcessHeap(), 0, wStringSid
);
1689 /******************************************************************************
1690 * ComputeStringSidSize
1692 static DWORD
ComputeStringSidSize(LPCWSTR StringSid
)
1694 if (StringSid
[0] == 'S' && StringSid
[1] == '-') /* S-R-I(-S)+ */
1699 if (*StringSid
== '-')
1705 return GetSidLengthRequired(ctok
- 2);
1707 else /* String constant format - Only available in winxp and above */
1711 for (i
= 0; i
< sizeof(WellKnownSids
)/sizeof(WellKnownSids
[0]); i
++)
1712 if (!strncmpW(WellKnownSids
[i
].wstr
, StringSid
, 2))
1713 return GetSidLengthRequired(WellKnownSids
[i
].Sid
.SubAuthorityCount
);
1716 return GetSidLengthRequired(0);
1719 static const RECORD SidTable
[] =
1721 { SDDL_ACCOUNT_OPERATORS
, WinBuiltinAccountOperatorsSid
},
1722 { SDDL_ALIAS_PREW2KCOMPACC
, WinBuiltinPreWindows2000CompatibleAccessSid
},
1723 { SDDL_ANONYMOUS
, WinAnonymousSid
},
1724 { SDDL_AUTHENTICATED_USERS
, WinAuthenticatedUserSid
},
1725 { SDDL_BUILTIN_ADMINISTRATORS
, WinBuiltinAdministratorsSid
},
1726 { SDDL_BUILTIN_GUESTS
, WinBuiltinGuestsSid
},
1727 { SDDL_BACKUP_OPERATORS
, WinBuiltinBackupOperatorsSid
},
1728 { SDDL_BUILTIN_USERS
, WinBuiltinUsersSid
},
1729 { SDDL_CERT_SERV_ADMINISTRATORS
, WinAccountCertAdminsSid
/* FIXME: DOMAIN_GROUP_RID_CERT_ADMINS */ },
1730 { SDDL_CREATOR_GROUP
, WinCreatorGroupSid
},
1731 { SDDL_CREATOR_OWNER
, WinCreatorOwnerSid
},
1732 { SDDL_DOMAIN_ADMINISTRATORS
, WinAccountDomainAdminsSid
/* FIXME: DOMAIN_GROUP_RID_ADMINS */ },
1733 { SDDL_DOMAIN_COMPUTERS
, WinAccountComputersSid
/* FIXME: DOMAIN_GROUP_RID_COMPUTERS */ },
1734 { SDDL_DOMAIN_DOMAIN_CONTROLLERS
, WinAccountControllersSid
/* FIXME: DOMAIN_GROUP_RID_CONTROLLERS */ },
1735 { SDDL_DOMAIN_GUESTS
, WinAccountDomainGuestsSid
/* FIXME: DOMAIN_GROUP_RID_GUESTS */ },
1736 { SDDL_DOMAIN_USERS
, WinAccountDomainUsersSid
/* FIXME: DOMAIN_GROUP_RID_USERS */ },
1737 { SDDL_ENTERPRISE_ADMINS
, WinAccountEnterpriseAdminsSid
/* FIXME: DOMAIN_GROUP_RID_ENTERPRISE_ADMINS */ },
1738 { SDDL_ENTERPRISE_DOMAIN_CONTROLLERS
, WinLogonIdsSid
/* FIXME: SECURITY_SERVER_LOGON_RID */ },
1739 { SDDL_EVERYONE
, WinWorldSid
},
1740 { SDDL_GROUP_POLICY_ADMINS
, WinAccountPolicyAdminsSid
/* FIXME: DOMAIN_GROUP_RID_POLICY_ADMINS */ },
1741 { SDDL_INTERACTIVE
, WinInteractiveSid
},
1742 { SDDL_LOCAL_ADMIN
, WinAccountAdministratorSid
/* FIXME: DOMAIN_USER_RID_ADMIN */ },
1743 { SDDL_LOCAL_GUEST
, WinAccountGuestSid
/* FIXME: DOMAIN_USER_RID_GUEST */ },
1744 { SDDL_LOCAL_SERVICE
, WinLocalServiceSid
},
1745 { SDDL_LOCAL_SYSTEM
, WinLocalSystemSid
},
1746 { SDDL_NETWORK
, WinNetworkSid
},
1747 { SDDL_NETWORK_CONFIGURATION_OPS
, WinBuiltinNetworkConfigurationOperatorsSid
},
1748 { SDDL_NETWORK_SERVICE
, WinNetworkServiceSid
},
1749 { SDDL_PRINTER_OPERATORS
, WinBuiltinPrintOperatorsSid
},
1750 { SDDL_PERSONAL_SELF
, WinSelfSid
},
1751 { SDDL_POWER_USERS
, WinBuiltinPowerUsersSid
},
1752 { SDDL_RAS_SERVERS
, WinAccountRasAndIasServersSid
/* FIXME: DOMAIN_ALIAS_RID_RAS_SERVERS */ },
1753 { SDDL_REMOTE_DESKTOP
, WinBuiltinRemoteDesktopUsersSid
},
1754 { SDDL_REPLICATOR
, WinBuiltinReplicatorSid
},
1755 { SDDL_RESTRICTED_CODE
, WinRestrictedCodeSid
},
1756 { SDDL_SCHEMA_ADMINISTRATORS
, WinAccountSchemaAdminsSid
/* FIXME: DOMAIN_GROUP_RID_SCHEMA_ADMINS */ },
1757 { SDDL_SERVER_OPERATORS
, WinBuiltinSystemOperatorsSid
},
1758 { SDDL_SERVICE
, WinServiceSid
},
1766 ConvertStringSidToSidW(IN LPCWSTR StringSid
,
1770 DWORD i
, cBytes
, identAuth
, csubauth
;
1774 TRACE("%s %p\n", debugstr_w(StringSid
), sid
);
1778 SetLastError(ERROR_INVALID_SID
);
1781 for (i
= 0; i
< sizeof(SidTable
) / sizeof(SidTable
[0]) - 1; i
++)
1783 if (wcscmp(StringSid
, SidTable
[i
].key
) == 0)
1785 WELL_KNOWN_SID_TYPE knownSid
= (WELL_KNOWN_SID_TYPE
)SidTable
[i
].value
;
1786 size
= SECURITY_MAX_SID_SIZE
;
1787 *sid
= LocalAlloc(0, size
);
1790 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
1793 ret
= CreateWellKnownSid(
1800 SetLastError(ERROR_INVALID_SID
);
1807 /* That's probably a string S-R-I-S-S... */
1808 if (StringSid
[0] != 'S' || StringSid
[1] != '-')
1810 SetLastError(ERROR_INVALID_SID
);
1814 cBytes
= ComputeStringSidSize(StringSid
);
1815 pisid
= (SID
*)LocalAlloc( 0, cBytes
);
1818 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
1823 csubauth
= ((cBytes
- GetSidLengthRequired(0)) / sizeof(DWORD
));
1825 StringSid
+= 2; /* Advance to Revision */
1826 pisid
->Revision
= atoiW(StringSid
);
1828 if (pisid
->Revision
!= SDDL_REVISION
)
1830 TRACE("Revision %d is unknown\n", pisid
->Revision
);
1831 goto lend
; /* ERROR_INVALID_SID */
1835 TRACE("SubAuthorityCount is 0\n");
1836 goto lend
; /* ERROR_INVALID_SID */
1839 pisid
->SubAuthorityCount
= csubauth
;
1841 /* Advance to identifier authority */
1842 while (*StringSid
&& *StringSid
!= '-')
1844 if (*StringSid
== '-')
1847 /* MS' implementation can't handle values greater than 2^32 - 1, so
1848 * we don't either; assume most significant bytes are always 0
1850 pisid
->IdentifierAuthority
.Value
[0] = 0;
1851 pisid
->IdentifierAuthority
.Value
[1] = 0;
1852 identAuth
= atoiW(StringSid
);
1853 pisid
->IdentifierAuthority
.Value
[5] = identAuth
& 0xff;
1854 pisid
->IdentifierAuthority
.Value
[4] = (identAuth
& 0xff00) >> 8;
1855 pisid
->IdentifierAuthority
.Value
[3] = (identAuth
& 0xff0000) >> 16;
1856 pisid
->IdentifierAuthority
.Value
[2] = (identAuth
& 0xff000000) >> 24;
1858 /* Advance to first sub authority */
1859 while (*StringSid
&& *StringSid
!= '-')
1861 if (*StringSid
== '-')
1864 pisid
->SubAuthority
[i
] = atoiW(StringSid
);
1868 while (*StringSid
&& *StringSid
!= '-')
1870 if (*StringSid
== '-')
1873 pisid
->SubAuthority
[++i
] = atoiW(StringSid
);
1876 if (i
!= pisid
->SubAuthorityCount
)
1877 goto lend
; /* ERROR_INVALID_SID */
1884 SetLastError(ERROR_INVALID_SID
);
1886 TRACE("returning %s\n", ret
? "TRUE" : "FALSE");