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/wine/security.c
17 WINE_DEFAULT_DEBUG_CHANNEL(advapi
);
19 static DWORD
ComputeStringSidSize(LPCWSTR StringSid
);
20 static BOOL
ParseStringSidToSid(LPCWSTR StringSid
, PSID pSid
, LPDWORD cBytes
);
22 #define MAX_GUID_STRING_LEN 39
25 AddAuditAccessAceEx(PACL pAcl
,
40 typedef struct _MAX_SID
42 /* same fields as struct _SID */
44 BYTE SubAuthorityCount
;
45 SID_IDENTIFIER_AUTHORITY IdentifierAuthority
;
46 DWORD SubAuthority
[SID_MAX_SUB_AUTHORITIES
];
49 typedef struct WELLKNOWNSID
52 WELL_KNOWN_SID_TYPE Type
;
56 typedef struct _ACEFLAG
60 } ACEFLAG
, *LPACEFLAG
;
62 static const WELLKNOWNSID WellKnownSids
[] =
64 { {0,0}, WinNullSid
, { SID_REVISION
, 1, { SECURITY_NULL_SID_AUTHORITY
}, { SECURITY_NULL_RID
} } },
65 { {'W','D'}, WinWorldSid
, { SID_REVISION
, 1, { SECURITY_WORLD_SID_AUTHORITY
}, { SECURITY_WORLD_RID
} } },
66 { {0,0}, WinLocalSid
, { SID_REVISION
, 1, { SECURITY_LOCAL_SID_AUTHORITY
}, { SECURITY_LOCAL_RID
} } },
67 { {'C','O'}, WinCreatorOwnerSid
, { SID_REVISION
, 1, { SECURITY_CREATOR_SID_AUTHORITY
}, { SECURITY_CREATOR_OWNER_RID
} } },
68 { {'C','G'}, WinCreatorGroupSid
, { SID_REVISION
, 1, { SECURITY_CREATOR_SID_AUTHORITY
}, { SECURITY_CREATOR_GROUP_RID
} } },
69 { {0,0}, WinCreatorOwnerServerSid
, { SID_REVISION
, 1, { SECURITY_CREATOR_SID_AUTHORITY
}, { SECURITY_CREATOR_OWNER_SERVER_RID
} } },
70 { {0,0}, WinCreatorGroupServerSid
, { SID_REVISION
, 1, { SECURITY_CREATOR_SID_AUTHORITY
}, { SECURITY_CREATOR_GROUP_SERVER_RID
} } },
71 { {0,0}, WinNtAuthoritySid
, { SID_REVISION
, 0, { SECURITY_NT_AUTHORITY
}, { SECURITY_NULL_RID
} } },
72 { {0,0}, WinDialupSid
, { SID_REVISION
, 1, { SECURITY_NT_AUTHORITY
}, { SECURITY_DIALUP_RID
} } },
73 { {'N','U'}, WinNetworkSid
, { SID_REVISION
, 1, { SECURITY_NT_AUTHORITY
}, { SECURITY_NETWORK_RID
} } },
74 { {0,0}, WinBatchSid
, { SID_REVISION
, 1, { SECURITY_NT_AUTHORITY
}, { SECURITY_BATCH_RID
} } },
75 { {'I','U'}, WinInteractiveSid
, { SID_REVISION
, 1, { SECURITY_NT_AUTHORITY
}, { SECURITY_INTERACTIVE_RID
} } },
76 { {'S','U'}, WinServiceSid
, { SID_REVISION
, 1, { SECURITY_NT_AUTHORITY
}, { SECURITY_SERVICE_RID
} } },
77 { {'A','N'}, WinAnonymousSid
, { SID_REVISION
, 1, { SECURITY_NT_AUTHORITY
}, { SECURITY_ANONYMOUS_LOGON_RID
} } },
78 { {0,0}, WinProxySid
, { SID_REVISION
, 1, { SECURITY_NT_AUTHORITY
}, { SECURITY_PROXY_RID
} } },
79 { {'E','D'}, WinEnterpriseControllersSid
, { SID_REVISION
, 1, { SECURITY_NT_AUTHORITY
}, { SECURITY_ENTERPRISE_CONTROLLERS_RID
} } },
80 { {'P','S'}, WinSelfSid
, { SID_REVISION
, 1, { SECURITY_NT_AUTHORITY
}, { SECURITY_PRINCIPAL_SELF_RID
} } },
81 { {'A','U'}, WinAuthenticatedUserSid
, { SID_REVISION
, 1, { SECURITY_NT_AUTHORITY
}, { SECURITY_AUTHENTICATED_USER_RID
} } },
82 { {'R','C'}, WinRestrictedCodeSid
, { SID_REVISION
, 1, { SECURITY_NT_AUTHORITY
}, { SECURITY_RESTRICTED_CODE_RID
} } },
83 { {0,0}, WinTerminalServerSid
, { SID_REVISION
, 1, { SECURITY_NT_AUTHORITY
}, { SECURITY_TERMINAL_SERVER_RID
} } },
84 { {0,0}, WinRemoteLogonIdSid
, { SID_REVISION
, 1, { SECURITY_NT_AUTHORITY
}, { SECURITY_REMOTE_LOGON_RID
} } },
85 { {'S','Y'}, WinLocalSystemSid
, { SID_REVISION
, 1, { SECURITY_NT_AUTHORITY
}, { SECURITY_LOCAL_SYSTEM_RID
} } },
86 { {'L','S'}, WinLocalServiceSid
, { SID_REVISION
, 1, { SECURITY_NT_AUTHORITY
}, { SECURITY_LOCAL_SERVICE_RID
} } },
87 { {'N','S'}, WinNetworkServiceSid
, { SID_REVISION
, 1, { SECURITY_NT_AUTHORITY
}, { SECURITY_NETWORK_SERVICE_RID
} } },
88 { {0,0}, WinBuiltinDomainSid
, { SID_REVISION
, 1, { SECURITY_NT_AUTHORITY
}, { SECURITY_BUILTIN_DOMAIN_RID
} } },
89 { {'B','A'}, WinBuiltinAdministratorsSid
, { SID_REVISION
, 2, { SECURITY_NT_AUTHORITY
}, { SECURITY_BUILTIN_DOMAIN_RID
, DOMAIN_ALIAS_RID_ADMINS
} } },
90 { {'B','U'}, WinBuiltinUsersSid
, { SID_REVISION
, 2, { SECURITY_NT_AUTHORITY
}, { SECURITY_BUILTIN_DOMAIN_RID
, DOMAIN_ALIAS_RID_USERS
} } },
91 { {'B','G'}, WinBuiltinGuestsSid
, { SID_REVISION
, 2, { SECURITY_NT_AUTHORITY
}, { SECURITY_BUILTIN_DOMAIN_RID
, DOMAIN_ALIAS_RID_GUESTS
} } },
92 { {'P','U'}, WinBuiltinPowerUsersSid
, { SID_REVISION
, 2, { SECURITY_NT_AUTHORITY
}, { SECURITY_BUILTIN_DOMAIN_RID
, DOMAIN_ALIAS_RID_POWER_USERS
} } },
93 { {'A','O'}, WinBuiltinAccountOperatorsSid
, { SID_REVISION
, 2, { SECURITY_NT_AUTHORITY
}, { SECURITY_BUILTIN_DOMAIN_RID
, DOMAIN_ALIAS_RID_ACCOUNT_OPS
} } },
94 { {'S','O'}, WinBuiltinSystemOperatorsSid
, { SID_REVISION
, 2, { SECURITY_NT_AUTHORITY
}, { SECURITY_BUILTIN_DOMAIN_RID
, DOMAIN_ALIAS_RID_SYSTEM_OPS
} } },
95 { {'P','O'}, WinBuiltinPrintOperatorsSid
, { SID_REVISION
, 2, { SECURITY_NT_AUTHORITY
}, { SECURITY_BUILTIN_DOMAIN_RID
, DOMAIN_ALIAS_RID_PRINT_OPS
} } },
96 { {'B','O'}, WinBuiltinBackupOperatorsSid
, { SID_REVISION
, 2, { SECURITY_NT_AUTHORITY
}, { SECURITY_BUILTIN_DOMAIN_RID
, DOMAIN_ALIAS_RID_BACKUP_OPS
} } },
97 { {'R','E'}, WinBuiltinReplicatorSid
, { SID_REVISION
, 2, { SECURITY_NT_AUTHORITY
}, { SECURITY_BUILTIN_DOMAIN_RID
, DOMAIN_ALIAS_RID_REPLICATOR
} } },
98 { {'R','U'}, WinBuiltinPreWindows2000CompatibleAccessSid
, { SID_REVISION
, 2, { SECURITY_NT_AUTHORITY
}, { SECURITY_BUILTIN_DOMAIN_RID
, DOMAIN_ALIAS_RID_PREW2KCOMPACCESS
} } },
99 { {'R','D'}, WinBuiltinRemoteDesktopUsersSid
, { SID_REVISION
, 2, { SECURITY_NT_AUTHORITY
}, { SECURITY_BUILTIN_DOMAIN_RID
, DOMAIN_ALIAS_RID_REMOTE_DESKTOP_USERS
} } },
100 { {'N','O'}, WinBuiltinNetworkConfigurationOperatorsSid
, { SID_REVISION
, 2, { SECURITY_NT_AUTHORITY
}, { SECURITY_BUILTIN_DOMAIN_RID
, DOMAIN_ALIAS_RID_NETWORK_CONFIGURATION_OPS
} } },
101 { {0,0}, WinNTLMAuthenticationSid
, { SID_REVISION
, 2, { SECURITY_NT_AUTHORITY
}, { SECURITY_PACKAGE_BASE_RID
, SECURITY_PACKAGE_NTLM_RID
} } },
102 { {0,0}, WinDigestAuthenticationSid
, { SID_REVISION
, 2, { SECURITY_NT_AUTHORITY
}, { SECURITY_PACKAGE_BASE_RID
, SECURITY_PACKAGE_DIGEST_RID
} } },
103 { {0,0}, WinSChannelAuthenticationSid
, { SID_REVISION
, 2, { SECURITY_NT_AUTHORITY
}, { SECURITY_PACKAGE_BASE_RID
, SECURITY_PACKAGE_SCHANNEL_RID
} } },
104 { {0,0}, WinThisOrganizationSid
, { SID_REVISION
, 1, { SECURITY_NT_AUTHORITY
}, { SECURITY_THIS_ORGANIZATION_RID
} } },
105 { {0,0}, WinOtherOrganizationSid
, { SID_REVISION
, 1, { SECURITY_NT_AUTHORITY
}, { SECURITY_OTHER_ORGANIZATION_RID
} } },
106 { {0,0}, WinBuiltinIncomingForestTrustBuildersSid
, { SID_REVISION
, 2, { SECURITY_NT_AUTHORITY
}, { SECURITY_BUILTIN_DOMAIN_RID
, DOMAIN_ALIAS_RID_INCOMING_FOREST_TRUST_BUILDERS
} } },
107 { {0,0}, WinBuiltinPerfMonitoringUsersSid
, { SID_REVISION
, 2, { SECURITY_NT_AUTHORITY
}, { SECURITY_BUILTIN_DOMAIN_RID
, DOMAIN_ALIAS_RID_MONITORING_USERS
} } },
108 { {0,0}, WinBuiltinPerfLoggingUsersSid
, { SID_REVISION
, 2, { SECURITY_NT_AUTHORITY
}, { SECURITY_BUILTIN_DOMAIN_RID
, DOMAIN_ALIAS_RID_LOGGING_USERS
} } },
109 { {0,0}, WinBuiltinAuthorizationAccessSid
, { SID_REVISION
, 2, { SECURITY_NT_AUTHORITY
}, { SECURITY_BUILTIN_DOMAIN_RID
, DOMAIN_ALIAS_RID_AUTHORIZATIONACCESS
} } },
110 { {0,0}, WinBuiltinTerminalServerLicenseServersSid
, { SID_REVISION
, 2, { SECURITY_NT_AUTHORITY
}, { SECURITY_BUILTIN_DOMAIN_RID
, DOMAIN_ALIAS_RID_TS_LICENSE_SERVERS
} } },
111 { {0,0}, WinBuiltinDCOMUsersSid
, { SID_REVISION
, 2, { SECURITY_NT_AUTHORITY
}, { SECURITY_BUILTIN_DOMAIN_RID
, DOMAIN_ALIAS_RID_DCOM_USERS
} } },
112 { {'L','W'}, WinLowLabelSid
, { SID_REVISION
, 1, { SECURITY_MANDATORY_LABEL_AUTHORITY
}, { SECURITY_MANDATORY_LOW_RID
} } },
113 { {'M','E'}, WinMediumLabelSid
, { SID_REVISION
, 1, { SECURITY_MANDATORY_LABEL_AUTHORITY
}, { SECURITY_MANDATORY_MEDIUM_RID
} } },
114 { {'H','I'}, WinHighLabelSid
, { SID_REVISION
, 1, { SECURITY_MANDATORY_LABEL_AUTHORITY
}, { SECURITY_MANDATORY_HIGH_RID
} } },
115 { {'S','I'}, WinSystemLabelSid
, { SID_REVISION
, 1, { SECURITY_MANDATORY_LABEL_AUTHORITY
}, { SECURITY_MANDATORY_SYSTEM_RID
} } },
118 typedef struct WELLKNOWNRID
120 WELL_KNOWN_SID_TYPE Type
;
124 static const WELLKNOWNRID WellKnownRids
[] = {
125 { WinAccountAdministratorSid
, DOMAIN_USER_RID_ADMIN
},
126 { WinAccountGuestSid
, DOMAIN_USER_RID_GUEST
},
127 { WinAccountKrbtgtSid
, DOMAIN_USER_RID_KRBTGT
},
128 { WinAccountDomainAdminsSid
, DOMAIN_GROUP_RID_ADMINS
},
129 { WinAccountDomainUsersSid
, DOMAIN_GROUP_RID_USERS
},
130 { WinAccountDomainGuestsSid
, DOMAIN_GROUP_RID_GUESTS
},
131 { WinAccountComputersSid
, DOMAIN_GROUP_RID_COMPUTERS
},
132 { WinAccountControllersSid
, DOMAIN_GROUP_RID_CONTROLLERS
},
133 { WinAccountCertAdminsSid
, DOMAIN_GROUP_RID_CERT_ADMINS
},
134 { WinAccountSchemaAdminsSid
, DOMAIN_GROUP_RID_SCHEMA_ADMINS
},
135 { WinAccountEnterpriseAdminsSid
, DOMAIN_GROUP_RID_ENTERPRISE_ADMINS
},
136 { WinAccountPolicyAdminsSid
, DOMAIN_GROUP_RID_POLICY_ADMINS
},
137 { WinAccountRasAndIasServersSid
, DOMAIN_ALIAS_RID_RAS_SERVERS
},
140 static const SID sidWorld
= { SID_REVISION
, 1, { SECURITY_WORLD_SID_AUTHORITY
} , { SECURITY_WORLD_RID
} };
145 static const WCHAR SDDL_ACCESS_ALLOWED
[] = {'A',0};
146 static const WCHAR SDDL_ACCESS_DENIED
[] = {'D',0};
147 static const WCHAR SDDL_OBJECT_ACCESS_ALLOWED
[] = {'O','A',0};
148 static const WCHAR SDDL_OBJECT_ACCESS_DENIED
[] = {'O','D',0};
149 static const WCHAR SDDL_AUDIT
[] = {'A','U',0};
150 static const WCHAR SDDL_ALARM
[] = {'A','L',0};
151 static const WCHAR SDDL_OBJECT_AUDIT
[] = {'O','U',0};
152 static const WCHAR SDDL_OBJECT_ALARM
[] = {'O','L',0};
157 #define ADS_RIGHT_DS_CREATE_CHILD 0x0001
158 #define ADS_RIGHT_DS_DELETE_CHILD 0x0002
159 #define ADS_RIGHT_ACTRL_DS_LIST 0x0004
160 #define ADS_RIGHT_DS_SELF 0x0008
161 #define ADS_RIGHT_DS_READ_PROP 0x0010
162 #define ADS_RIGHT_DS_WRITE_PROP 0x0020
163 #define ADS_RIGHT_DS_DELETE_TREE 0x0040
164 #define ADS_RIGHT_DS_LIST_OBJECT 0x0080
165 #define ADS_RIGHT_DS_CONTROL_ACCESS 0x0100
170 static const WCHAR SDDL_CONTAINER_INHERIT
[] = {'C','I',0};
171 static const WCHAR SDDL_OBJECT_INHERIT
[] = {'O','I',0};
172 static const WCHAR SDDL_NO_PROPAGATE
[] = {'N','P',0};
173 static const WCHAR SDDL_INHERIT_ONLY
[] = {'I','O',0};
174 static const WCHAR SDDL_INHERITED
[] = {'I','D',0};
175 static const WCHAR SDDL_AUDIT_SUCCESS
[] = {'S','A',0};
176 static const WCHAR SDDL_AUDIT_FAILURE
[] = {'F','A',0};
178 static const char * debugstr_sid(PSID sid
)
181 SID
* psid
= (SID
*)sid
;
186 auth
= psid
->IdentifierAuthority
.Value
[5] +
187 (psid
->IdentifierAuthority
.Value
[4] << 8) +
188 (psid
->IdentifierAuthority
.Value
[3] << 16) +
189 (psid
->IdentifierAuthority
.Value
[2] << 24);
191 switch (psid
->SubAuthorityCount
) {
193 return wine_dbg_sprintf("S-%d-%d", psid
->Revision
, auth
);
195 return wine_dbg_sprintf("S-%d-%d-%lu", psid
->Revision
, auth
,
196 psid
->SubAuthority
[0]);
198 return wine_dbg_sprintf("S-%d-%d-%lu-%lu", psid
->Revision
, auth
,
199 psid
->SubAuthority
[0], psid
->SubAuthority
[1]);
201 return wine_dbg_sprintf("S-%d-%d-%lu-%lu-%lu", psid
->Revision
, auth
,
202 psid
->SubAuthority
[0], psid
->SubAuthority
[1], psid
->SubAuthority
[2]);
204 return wine_dbg_sprintf("S-%d-%d-%lu-%lu-%lu-%lu", psid
->Revision
, auth
,
205 psid
->SubAuthority
[0], psid
->SubAuthority
[1], psid
->SubAuthority
[2],
206 psid
->SubAuthority
[3]);
208 return wine_dbg_sprintf("S-%d-%d-%lu-%lu-%lu-%lu-%lu", psid
->Revision
, auth
,
209 psid
->SubAuthority
[0], psid
->SubAuthority
[1], psid
->SubAuthority
[2],
210 psid
->SubAuthority
[3], psid
->SubAuthority
[4]);
212 return wine_dbg_sprintf("S-%d-%d-%lu-%lu-%lu-%lu-%lu-%lu", psid
->Revision
, auth
,
213 psid
->SubAuthority
[3], psid
->SubAuthority
[1], psid
->SubAuthority
[2],
214 psid
->SubAuthority
[0], psid
->SubAuthority
[4], psid
->SubAuthority
[5]);
216 return wine_dbg_sprintf("S-%d-%d-%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]);
221 return wine_dbg_sprintf("S-%d-%d-%lu-%lu-%lu-%lu-%lu-%lu-%lu-%lu", psid
->Revision
, auth
,
222 psid
->SubAuthority
[0], psid
->SubAuthority
[1], psid
->SubAuthority
[2],
223 psid
->SubAuthority
[3], psid
->SubAuthority
[4], psid
->SubAuthority
[5],
224 psid
->SubAuthority
[6], psid
->SubAuthority
[7]);
229 static const ACEFLAG AceRights
[] =
231 { SDDL_GENERIC_ALL
, GENERIC_ALL
},
232 { SDDL_GENERIC_READ
, GENERIC_READ
},
233 { SDDL_GENERIC_WRITE
, GENERIC_WRITE
},
234 { SDDL_GENERIC_EXECUTE
, GENERIC_EXECUTE
},
236 { SDDL_READ_CONTROL
, READ_CONTROL
},
237 { SDDL_STANDARD_DELETE
, DELETE
},
238 { SDDL_WRITE_DAC
, WRITE_DAC
},
239 { SDDL_WRITE_OWNER
, WRITE_OWNER
},
241 { SDDL_READ_PROPERTY
, ADS_RIGHT_DS_READ_PROP
},
242 { SDDL_WRITE_PROPERTY
, ADS_RIGHT_DS_WRITE_PROP
},
243 { SDDL_CREATE_CHILD
, ADS_RIGHT_DS_CREATE_CHILD
},
244 { SDDL_DELETE_CHILD
, ADS_RIGHT_DS_DELETE_CHILD
},
245 { SDDL_LIST_CHILDREN
, ADS_RIGHT_ACTRL_DS_LIST
},
246 { SDDL_SELF_WRITE
, ADS_RIGHT_DS_SELF
},
247 { SDDL_LIST_OBJECT
, ADS_RIGHT_DS_LIST_OBJECT
},
248 { SDDL_DELETE_TREE
, ADS_RIGHT_DS_DELETE_TREE
},
249 { SDDL_CONTROL_ACCESS
, ADS_RIGHT_DS_CONTROL_ACCESS
},
251 { SDDL_FILE_ALL
, FILE_ALL_ACCESS
},
252 { SDDL_FILE_READ
, FILE_GENERIC_READ
},
253 { SDDL_FILE_WRITE
, FILE_GENERIC_WRITE
},
254 { SDDL_FILE_EXECUTE
, FILE_GENERIC_EXECUTE
},
256 { SDDL_KEY_ALL
, KEY_ALL_ACCESS
},
257 { SDDL_KEY_READ
, KEY_READ
},
258 { SDDL_KEY_WRITE
, KEY_WRITE
},
259 { SDDL_KEY_EXECUTE
, KEY_EXECUTE
},
263 /* set last error code from NT status and get the proper boolean return value */
264 /* used for functions that are a simple wrapper around the corresponding ntdll API */
265 static __inline BOOL
set_ntstatus( NTSTATUS status
)
267 if (status
) SetLastError( RtlNtStatusToDosError( status
));
271 static const RECORD SidTable
[] =
273 { SDDL_ACCOUNT_OPERATORS
, WinBuiltinAccountOperatorsSid
},
274 { SDDL_ALIAS_PREW2KCOMPACC
, WinBuiltinPreWindows2000CompatibleAccessSid
},
275 { SDDL_ANONYMOUS
, WinAnonymousSid
},
276 { SDDL_AUTHENTICATED_USERS
, WinAuthenticatedUserSid
},
277 { SDDL_BUILTIN_ADMINISTRATORS
, WinBuiltinAdministratorsSid
},
278 { SDDL_BUILTIN_GUESTS
, WinBuiltinGuestsSid
},
279 { SDDL_BACKUP_OPERATORS
, WinBuiltinBackupOperatorsSid
},
280 { SDDL_BUILTIN_USERS
, WinBuiltinUsersSid
},
281 { SDDL_CERT_SERV_ADMINISTRATORS
, WinAccountCertAdminsSid
/* FIXME: DOMAIN_GROUP_RID_CERT_ADMINS */ },
282 { SDDL_CREATOR_GROUP
, WinCreatorGroupSid
},
283 { SDDL_CREATOR_OWNER
, WinCreatorOwnerSid
},
284 { SDDL_DOMAIN_ADMINISTRATORS
, WinAccountDomainAdminsSid
/* FIXME: DOMAIN_GROUP_RID_ADMINS */ },
285 { SDDL_DOMAIN_COMPUTERS
, WinAccountComputersSid
/* FIXME: DOMAIN_GROUP_RID_COMPUTERS */ },
286 { SDDL_DOMAIN_DOMAIN_CONTROLLERS
, WinAccountControllersSid
/* FIXME: DOMAIN_GROUP_RID_CONTROLLERS */ },
287 { SDDL_DOMAIN_GUESTS
, WinAccountDomainGuestsSid
/* FIXME: DOMAIN_GROUP_RID_GUESTS */ },
288 { SDDL_DOMAIN_USERS
, WinAccountDomainUsersSid
/* FIXME: DOMAIN_GROUP_RID_USERS */ },
289 { SDDL_ENTERPRISE_ADMINS
, WinAccountEnterpriseAdminsSid
/* FIXME: DOMAIN_GROUP_RID_ENTERPRISE_ADMINS */ },
290 { SDDL_ENTERPRISE_DOMAIN_CONTROLLERS
, WinEnterpriseControllersSid
},
291 { SDDL_EVERYONE
, WinWorldSid
},
292 { SDDL_GROUP_POLICY_ADMINS
, WinAccountPolicyAdminsSid
/* FIXME: DOMAIN_GROUP_RID_POLICY_ADMINS */ },
293 { SDDL_INTERACTIVE
, WinInteractiveSid
},
294 { SDDL_LOCAL_ADMIN
, WinAccountAdministratorSid
/* FIXME: DOMAIN_USER_RID_ADMIN */ },
295 { SDDL_LOCAL_GUEST
, WinAccountGuestSid
/* FIXME: DOMAIN_USER_RID_GUEST */ },
296 { SDDL_LOCAL_SERVICE
, WinLocalServiceSid
},
297 { SDDL_LOCAL_SYSTEM
, WinLocalSystemSid
},
298 { SDDL_NETWORK
, WinNetworkSid
},
299 { SDDL_NETWORK_CONFIGURATION_OPS
, WinBuiltinNetworkConfigurationOperatorsSid
},
300 { SDDL_NETWORK_SERVICE
, WinNetworkServiceSid
},
301 { SDDL_PRINTER_OPERATORS
, WinBuiltinPrintOperatorsSid
},
302 { SDDL_PERSONAL_SELF
, WinSelfSid
},
303 { SDDL_POWER_USERS
, WinBuiltinPowerUsersSid
},
304 { SDDL_RAS_SERVERS
, WinAccountRasAndIasServersSid
/* FIXME: DOMAIN_ALIAS_RID_RAS_SERVERS */ },
305 { SDDL_REMOTE_DESKTOP
, WinBuiltinRemoteDesktopUsersSid
},
306 { SDDL_REPLICATOR
, WinBuiltinReplicatorSid
},
307 { SDDL_RESTRICTED_CODE
, WinRestrictedCodeSid
},
308 { SDDL_SCHEMA_ADMINISTRATORS
, WinAccountSchemaAdminsSid
/* FIXME: DOMAIN_GROUP_RID_SCHEMA_ADMINS */ },
309 { SDDL_SERVER_OPERATORS
, WinBuiltinSystemOperatorsSid
},
310 { SDDL_SERVICE
, WinServiceSid
},
314 /* Exported functions */
320 OpenProcessToken(HANDLE ProcessHandle
,
326 TRACE("%p, %x, %p.\n", ProcessHandle
, DesiredAccess
, TokenHandle
);
328 Status
= NtOpenProcessToken(ProcessHandle
,
331 if (!NT_SUCCESS(Status
))
333 ERR("NtOpenProcessToken failed! Status %08x.\n", Status
);
334 SetLastError(RtlNtStatusToDosError(Status
));
338 TRACE("Returning token %p.\n", *TokenHandle
);
347 OpenThreadToken(HANDLE ThreadHandle
,
354 Status
= NtOpenThreadToken(ThreadHandle
,
358 if (!NT_SUCCESS(Status
))
360 SetLastError(RtlNtStatusToDosError(Status
));
371 AdjustTokenGroups(HANDLE TokenHandle
,
373 PTOKEN_GROUPS NewState
,
375 PTOKEN_GROUPS PreviousState
,
380 Status
= NtAdjustGroupsToken(TokenHandle
,
385 (PULONG
)ReturnLength
);
386 if (!NT_SUCCESS(Status
))
388 SetLastError(RtlNtStatusToDosError(Status
));
399 AdjustTokenPrivileges(HANDLE TokenHandle
,
400 BOOL DisableAllPrivileges
,
401 PTOKEN_PRIVILEGES NewState
,
403 PTOKEN_PRIVILEGES PreviousState
,
408 Status
= NtAdjustPrivilegesToken(TokenHandle
,
409 DisableAllPrivileges
,
413 (PULONG
)ReturnLength
);
414 if (STATUS_NOT_ALL_ASSIGNED
== Status
)
416 SetLastError(ERROR_NOT_ALL_ASSIGNED
);
420 if (!NT_SUCCESS(Status
))
422 SetLastError(RtlNtStatusToDosError(Status
));
426 /* AdjustTokenPrivileges is documented to do this */
427 SetLastError(ERROR_SUCCESS
);
436 GetTokenInformation(HANDLE TokenHandle
,
437 TOKEN_INFORMATION_CLASS TokenInformationClass
,
438 LPVOID TokenInformation
,
439 DWORD TokenInformationLength
,
444 Status
= NtQueryInformationToken(TokenHandle
,
445 TokenInformationClass
,
447 TokenInformationLength
,
448 (PULONG
)ReturnLength
);
449 if (!NT_SUCCESS(Status
))
451 SetLastError(RtlNtStatusToDosError(Status
));
462 SetTokenInformation(HANDLE TokenHandle
,
463 TOKEN_INFORMATION_CLASS TokenInformationClass
,
464 LPVOID TokenInformation
,
465 DWORD TokenInformationLength
)
469 Status
= NtSetInformationToken(TokenHandle
,
470 TokenInformationClass
,
472 TokenInformationLength
);
473 if (!NT_SUCCESS(Status
))
475 SetLastError(RtlNtStatusToDosError(Status
));
486 SetThreadToken(IN PHANDLE ThreadHandle OPTIONAL
,
487 IN HANDLE TokenHandle
)
492 hThread
= (ThreadHandle
!= NULL
) ? *ThreadHandle
: NtCurrentThread();
494 Status
= NtSetInformationThread(hThread
,
495 ThreadImpersonationToken
,
498 if (!NT_SUCCESS(Status
))
500 SetLastError(RtlNtStatusToDosError(Status
));
508 CreateRestrictedToken(HANDLE TokenHandle
,
510 DWORD DisableSidCount
,
511 PSID_AND_ATTRIBUTES pSidAndAttributes
,
512 DWORD DeletePrivilegeCount
,
513 PLUID_AND_ATTRIBUTES pLUIDAndAttributes
,
514 DWORD RestrictedSidCount
,
515 PSID_AND_ATTRIBUTES pSIDAndAttributes
,
516 PHANDLE NewTokenHandle
)
526 AllocateAndInitializeSid(PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority
,
527 BYTE nSubAuthorityCount
,
528 DWORD dwSubAuthority0
,
529 DWORD dwSubAuthority1
,
530 DWORD dwSubAuthority2
,
531 DWORD dwSubAuthority3
,
532 DWORD dwSubAuthority4
,
533 DWORD dwSubAuthority5
,
534 DWORD dwSubAuthority6
,
535 DWORD dwSubAuthority7
,
540 Status
= RtlAllocateAndInitializeSid(pIdentifierAuthority
,
551 if (!NT_SUCCESS(Status
))
553 SetLastError(RtlNtStatusToDosError(Status
));
564 * Docs says this function does NOT return a value
565 * even thou it's defined to return a PVOID...
571 return RtlFreeSid(pSid
);
578 CopySid(DWORD nDestinationSidLength
,
579 PSID pDestinationSid
,
584 Status
= RtlCopySid(nDestinationSidLength
,
587 if (!NT_SUCCESS (Status
))
589 SetLastError(RtlNtStatusToDosError(Status
));
601 CreateWellKnownSid(IN WELL_KNOWN_SID_TYPE WellKnownSidType
,
602 IN PSID DomainSid OPTIONAL
,
607 TRACE("(%d, %s, %p, %p)\n", WellKnownSidType
, debugstr_sid(DomainSid
), pSid
, cbSid
);
609 if (cbSid
== NULL
|| (DomainSid
&& !IsValidSid(DomainSid
)))
611 SetLastError(ERROR_INVALID_PARAMETER
);
615 for (i
= 0; i
< sizeof(WellKnownSids
)/sizeof(WellKnownSids
[0]); i
++) {
616 if (WellKnownSids
[i
].Type
== WellKnownSidType
) {
617 DWORD length
= GetSidLengthRequired(WellKnownSids
[i
].Sid
.SubAuthorityCount
);
622 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
627 SetLastError(ERROR_INVALID_PARAMETER
);
630 CopyMemory(pSid
, &WellKnownSids
[i
].Sid
.Revision
, length
);
636 if (DomainSid
== NULL
|| *GetSidSubAuthorityCount(DomainSid
) == SID_MAX_SUB_AUTHORITIES
)
638 SetLastError(ERROR_INVALID_PARAMETER
);
642 for (i
= 0; i
< sizeof(WellKnownRids
)/sizeof(WellKnownRids
[0]); i
++)
643 if (WellKnownRids
[i
].Type
== WellKnownSidType
) {
644 UCHAR domain_subauth
= *GetSidSubAuthorityCount(DomainSid
);
645 DWORD domain_sid_length
= GetSidLengthRequired(domain_subauth
);
646 DWORD output_sid_length
= GetSidLengthRequired(domain_subauth
+ 1);
648 if (*cbSid
< output_sid_length
)
650 *cbSid
= output_sid_length
;
651 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
656 SetLastError(ERROR_INVALID_PARAMETER
);
659 CopyMemory(pSid
, DomainSid
, domain_sid_length
);
660 (*GetSidSubAuthorityCount(pSid
))++;
661 (*GetSidSubAuthority(pSid
, domain_subauth
)) = WellKnownRids
[i
].Rid
;
662 *cbSid
= output_sid_length
;
666 SetLastError(ERROR_INVALID_PARAMETER
);
675 IsWellKnownSid(IN PSID pSid
,
676 IN WELL_KNOWN_SID_TYPE WellKnownSidType
)
679 TRACE("(%s, %d)\n", debugstr_sid(pSid
), WellKnownSidType
);
681 for (i
= 0; i
< sizeof(WellKnownSids
) / sizeof(WellKnownSids
[0]); i
++)
683 if (WellKnownSids
[i
].Type
== WellKnownSidType
)
685 if (EqualSid(pSid
, (PSID
)(&WellKnownSids
[i
].Sid
.Revision
)))
698 IsValidSid(PSID pSid
)
700 return (BOOL
)RtlValidSid(pSid
);
711 SetLastError(ERROR_SUCCESS
);
712 return RtlEqualSid (pSid1
, pSid2
);
720 EqualPrefixSid(PSID pSid1
,
723 return RtlEqualPrefixSid (pSid1
, pSid2
);
731 GetSidLengthRequired(UCHAR nSubAuthorityCount
)
733 return (DWORD
)RtlLengthRequiredSid(nSubAuthorityCount
);
741 InitializeSid(PSID Sid
,
742 PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority
,
743 BYTE nSubAuthorityCount
)
747 Status
= RtlInitializeSid(Sid
,
748 pIdentifierAuthority
,
750 if (!NT_SUCCESS(Status
))
752 SetLastError(RtlNtStatusToDosError(Status
));
762 PSID_IDENTIFIER_AUTHORITY
764 GetSidIdentifierAuthority(PSID pSid
)
766 return RtlIdentifierAuthoritySid(pSid
);
774 GetSidSubAuthority(PSID pSid
,
777 SetLastError(ERROR_SUCCESS
);
778 return (PDWORD
)RtlSubAuthoritySid(pSid
, nSubAuthority
);
786 GetSidSubAuthorityCount(PSID pSid
)
788 SetLastError(ERROR_SUCCESS
);
789 return RtlSubAuthorityCountSid(pSid
);
797 GetLengthSid(PSID pSid
)
799 return (DWORD
)RtlLengthSid(pSid
);
806 AllocateLocallyUniqueId(PLUID Luid
)
810 Status
= NtAllocateLocallyUniqueId (Luid
);
811 if (!NT_SUCCESS (Status
))
813 SetLastError(RtlNtStatusToDosError(Status
));
825 AccessCheck(IN PSECURITY_DESCRIPTOR pSecurityDescriptor
,
826 IN HANDLE ClientToken
,
827 IN DWORD DesiredAccess
,
828 IN PGENERIC_MAPPING GenericMapping
,
829 OUT PPRIVILEGE_SET PrivilegeSet OPTIONAL
,
830 IN OUT LPDWORD PrivilegeSetLength
,
831 OUT LPDWORD GrantedAccess
,
832 OUT LPBOOL AccessStatus
)
835 NTSTATUS NtAccessStatus
;
837 /* Do the access check */
838 Status
= NtAccessCheck(pSecurityDescriptor
,
843 (PULONG
)PrivilegeSetLength
,
844 (PACCESS_MASK
)GrantedAccess
,
847 /* See if the access check operation succeeded */
848 if (!NT_SUCCESS(Status
))
851 SetLastError(RtlNtStatusToDosError(Status
));
855 /* Now check the access status */
856 if (!NT_SUCCESS(NtAccessStatus
))
859 SetLastError(RtlNtStatusToDosError(NtAccessStatus
));
860 *AccessStatus
= FALSE
;
865 *AccessStatus
= TRUE
;
868 /* Check succeeded */
875 BOOL WINAPI
AccessCheckByType(
876 PSECURITY_DESCRIPTOR pSecurityDescriptor
,
877 PSID PrincipalSelfSid
,
880 POBJECT_TYPE_LIST ObjectTypeList
,
881 DWORD ObjectTypeListLength
,
882 PGENERIC_MAPPING GenericMapping
,
883 PPRIVILEGE_SET PrivilegeSet
,
884 LPDWORD PrivilegeSetLength
,
885 LPDWORD GrantedAccess
,
890 *AccessStatus
= TRUE
;
892 return !*AccessStatus
;
895 /**********************************************************************
896 * PrivilegeCheck EXPORTED
901 PrivilegeCheck(HANDLE ClientToken
,
902 PPRIVILEGE_SET RequiredPrivileges
,
908 Status
= NtPrivilegeCheck(ClientToken
,
911 if (!NT_SUCCESS(Status
))
913 SetLastError(RtlNtStatusToDosError(Status
));
917 *pfResult
= (BOOL
)Result
;
922 /******************************************************************************
923 * ParseAclStringFlags
925 static DWORD
ParseAclStringFlags(LPCWSTR
* StringAcl
)
928 LPCWSTR szAcl
= *StringAcl
;
930 while (*szAcl
!= '(')
934 flags
|= SE_DACL_PROTECTED
;
936 else if (*szAcl
== 'A')
940 flags
|= SE_DACL_AUTO_INHERIT_REQ
;
941 else if (*szAcl
== 'I')
942 flags
|= SE_DACL_AUTO_INHERITED
;
951 /******************************************************************************
954 static const ACEFLAG AceType
[] =
956 { SDDL_ALARM
, SYSTEM_ALARM_ACE_TYPE
},
957 { SDDL_AUDIT
, SYSTEM_AUDIT_ACE_TYPE
},
958 { SDDL_ACCESS_ALLOWED
, ACCESS_ALLOWED_ACE_TYPE
},
959 { SDDL_ACCESS_DENIED
, ACCESS_DENIED_ACE_TYPE
},
961 { SDDL_OBJECT_ACCESS_ALLOWED, ACCESS_ALLOWED_OBJECT_ACE_TYPE },
962 { SDDL_OBJECT_ACCESS_DENIED, ACCESS_DENIED_OBJECT_ACE_TYPE },
963 { SDDL_OBJECT_ALARM, SYSTEM_ALARM_OBJECT_ACE_TYPE },
964 { SDDL_OBJECT_AUDIT, SYSTEM_AUDIT_OBJECT_ACE_TYPE },
969 static BYTE
ParseAceStringType(LPCWSTR
* StringAcl
)
972 LPCWSTR szAcl
= *StringAcl
;
973 const ACEFLAG
*lpaf
= AceType
;
976 (len
= strlenW(lpaf
->wstr
)) &&
977 strncmpW(lpaf
->wstr
, szAcl
, len
))
988 /******************************************************************************
989 * ParseAceStringFlags
991 static const ACEFLAG AceFlags
[] =
993 { SDDL_CONTAINER_INHERIT
, CONTAINER_INHERIT_ACE
},
994 { SDDL_AUDIT_FAILURE
, FAILED_ACCESS_ACE_FLAG
},
995 { SDDL_INHERITED
, INHERITED_ACE
},
996 { SDDL_INHERIT_ONLY
, INHERIT_ONLY_ACE
},
997 { SDDL_NO_PROPAGATE
, NO_PROPAGATE_INHERIT_ACE
},
998 { SDDL_OBJECT_INHERIT
, OBJECT_INHERIT_ACE
},
999 { SDDL_AUDIT_SUCCESS
, SUCCESSFUL_ACCESS_ACE_FLAG
},
1003 static BYTE
ParseAceStringFlags(LPCWSTR
* StringAcl
)
1007 LPCWSTR szAcl
= *StringAcl
;
1009 while (*szAcl
!= ';')
1011 const ACEFLAG
*lpaf
= AceFlags
;
1013 while (lpaf
->wstr
&&
1014 (len
= strlenW(lpaf
->wstr
)) &&
1015 strncmpW(lpaf
->wstr
, szAcl
, len
))
1021 flags
|= lpaf
->value
;
1030 /******************************************************************************
1031 * ParseAceStringRights
1033 static DWORD
ParseAceStringRights(LPCWSTR
* StringAcl
)
1037 LPCWSTR szAcl
= *StringAcl
;
1039 if ((*szAcl
== '0') && (*(szAcl
+ 1) == 'x'))
1043 while (*p
&& *p
!= ';')
1046 if (p
- szAcl
<= 10 /* 8 hex digits + "0x" */ )
1048 rights
= strtoulW(szAcl
, NULL
, 16);
1052 WARN("Invalid rights string format: %s\n", debugstr_wn(szAcl
, p
- szAcl
));
1056 while (*szAcl
!= ';')
1058 const ACEFLAG
*lpaf
= AceRights
;
1060 while (lpaf
->wstr
&&
1061 (len
= strlenW(lpaf
->wstr
)) &&
1062 strncmpW(lpaf
->wstr
, szAcl
, len
))
1070 rights
|= lpaf
->value
;
1080 /******************************************************************************
1081 * ParseStringAclToAcl
1083 * dacl_flags(string_ace1)(string_ace2)... (string_acen)
1086 ParseStringAclToAcl(LPCWSTR StringAcl
,
1093 DWORD length
= sizeof(ACL
);
1096 PACCESS_ALLOWED_ACE pAce
= NULL
; /* pointer to current ACE */
1098 TRACE("%s\n", debugstr_w(StringAcl
));
1103 if (pAcl
) /* pAce is only useful if we're setting values */
1104 pAce
= (PACCESS_ALLOWED_ACE
) (pAcl
+ 1);
1106 /* Parse ACL flags */
1107 *lpdwFlags
= ParseAclStringFlags(&StringAcl
);
1110 while (*StringAcl
== '(')
1114 /* Parse ACE type */
1115 val
= ParseAceStringType(&StringAcl
);
1117 pAce
->Header
.AceType
= (BYTE
) val
;
1118 if (*StringAcl
!= ';')
1122 /* Parse ACE flags */
1123 val
= ParseAceStringFlags(&StringAcl
);
1125 pAce
->Header
.AceFlags
= (BYTE
) val
;
1126 if (*StringAcl
!= ';')
1130 /* Parse ACE rights */
1131 val
= ParseAceStringRights(&StringAcl
);
1134 if (*StringAcl
!= ';')
1138 /* Parse ACE object guid */
1139 if (*StringAcl
!= ';')
1141 FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
1146 /* Parse ACE inherit object guid */
1147 if (*StringAcl
!= ';')
1149 FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
1154 /* Parse ACE account sid */
1155 if (ParseStringSidToSid(StringAcl
, pAce
? &pAce
->SidStart
: NULL
, &sidlen
))
1157 while (*StringAcl
&& *StringAcl
!= ')')
1161 if (*StringAcl
!= ')')
1165 acesize
= sizeof(ACCESS_ALLOWED_ACE
) - sizeof(DWORD
) + sidlen
;
1169 pAce
->Header
.AceSize
= acesize
;
1170 pAce
= (PACCESS_ALLOWED_ACE
)((LPBYTE
)pAce
+ acesize
);
1177 if (length
> 0xffff)
1179 ERR("ACL too large\n");
1185 pAcl
->AclRevision
= ACL_REVISION
;
1187 pAcl
->AclSize
= length
;
1188 pAcl
->AceCount
= acecount
++;
1194 SetLastError(ERROR_INVALID_ACL
);
1195 WARN("Invalid ACE string format\n");
1200 /******************************************************************************
1201 * ParseStringSecurityDescriptorToSecurityDescriptor
1204 ParseStringSecurityDescriptorToSecurityDescriptor(LPCWSTR StringSecurityDescriptor
,
1205 SECURITY_DESCRIPTOR_RELATIVE
* SecurityDescriptor
,
1210 WCHAR tok
[MAX_PATH
];
1212 LPBYTE lpNext
= NULL
;
1215 *cBytes
= sizeof(SECURITY_DESCRIPTOR
);
1217 if (SecurityDescriptor
)
1218 lpNext
= (LPBYTE
)(SecurityDescriptor
+ 1);
1220 while (*StringSecurityDescriptor
)
1222 toktype
= *StringSecurityDescriptor
;
1224 /* Expect char identifier followed by ':' */
1225 StringSecurityDescriptor
++;
1226 if (*StringSecurityDescriptor
!= ':')
1228 SetLastError(ERROR_INVALID_PARAMETER
);
1231 StringSecurityDescriptor
++;
1234 lptoken
= StringSecurityDescriptor
;
1235 while (*lptoken
&& *lptoken
!= ':')
1241 len
= lptoken
- StringSecurityDescriptor
;
1242 memcpy( tok
, StringSecurityDescriptor
, len
* sizeof(WCHAR
) );
1251 if (!ParseStringSidToSid(tok
, lpNext
, &bytes
))
1254 if (SecurityDescriptor
)
1256 SecurityDescriptor
->Owner
= lpNext
- (LPBYTE
)SecurityDescriptor
;
1257 lpNext
+= bytes
; /* Advance to next token */
1269 if (!ParseStringSidToSid(tok
, lpNext
, &bytes
))
1272 if (SecurityDescriptor
)
1274 SecurityDescriptor
->Group
= lpNext
- (LPBYTE
)SecurityDescriptor
;
1275 lpNext
+= bytes
; /* Advance to next token */
1288 if (!ParseStringAclToAcl(tok
, &flags
, (PACL
)lpNext
, &bytes
))
1291 if (SecurityDescriptor
)
1293 SecurityDescriptor
->Control
|= SE_DACL_PRESENT
| flags
;
1294 SecurityDescriptor
->Dacl
= lpNext
- (LPBYTE
)SecurityDescriptor
;
1295 lpNext
+= bytes
; /* Advance to next token */
1308 if (!ParseStringAclToAcl(tok
, &flags
, (PACL
)lpNext
, &bytes
))
1311 if (SecurityDescriptor
)
1313 SecurityDescriptor
->Control
|= SE_SACL_PRESENT
| flags
;
1314 SecurityDescriptor
->Sacl
= lpNext
- (LPBYTE
)SecurityDescriptor
;
1315 lpNext
+= bytes
; /* Advance to next token */
1324 FIXME("Unknown token\n");
1325 SetLastError(ERROR_INVALID_PARAMETER
);
1329 StringSecurityDescriptor
= lptoken
;
1338 /* Winehq cvs 20050916 */
1339 /******************************************************************************
1340 * ConvertStringSecurityDescriptorToSecurityDescriptorA [ADVAPI32.@]
1345 ConvertStringSecurityDescriptorToSecurityDescriptorA(LPCSTR StringSecurityDescriptor
,
1346 DWORD StringSDRevision
,
1347 PSECURITY_DESCRIPTOR
* SecurityDescriptor
,
1348 PULONG SecurityDescriptorSize
)
1352 LPWSTR StringSecurityDescriptorW
;
1354 len
= MultiByteToWideChar(CP_ACP
, 0, StringSecurityDescriptor
, -1, NULL
, 0);
1355 StringSecurityDescriptorW
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
1357 if (StringSecurityDescriptorW
)
1359 MultiByteToWideChar(CP_ACP
, 0, StringSecurityDescriptor
, -1, StringSecurityDescriptorW
, len
);
1361 ret
= ConvertStringSecurityDescriptorToSecurityDescriptorW(StringSecurityDescriptorW
,
1362 StringSDRevision
, SecurityDescriptor
,
1363 SecurityDescriptorSize
);
1364 HeapFree(GetProcessHeap(), 0, StringSecurityDescriptorW
);
1370 /******************************************************************************
1371 * ConvertStringSecurityDescriptorToSecurityDescriptorW [ADVAPI32.@]
1375 ConvertStringSecurityDescriptorToSecurityDescriptorW(LPCWSTR StringSecurityDescriptor
,
1376 DWORD StringSDRevision
,
1377 PSECURITY_DESCRIPTOR
* SecurityDescriptor
,
1378 PULONG SecurityDescriptorSize
)
1381 SECURITY_DESCRIPTOR
* psd
;
1384 TRACE("%s\n", debugstr_w(StringSecurityDescriptor
));
1386 if (GetVersion() & 0x80000000)
1388 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1391 else if (!StringSecurityDescriptor
|| !SecurityDescriptor
)
1393 SetLastError(ERROR_INVALID_PARAMETER
);
1396 else if (StringSDRevision
!= SID_REVISION
)
1398 SetLastError(ERROR_UNKNOWN_REVISION
);
1402 /* Compute security descriptor length */
1403 if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor
,
1407 psd
= *SecurityDescriptor
= LocalAlloc(GMEM_ZEROINIT
, cBytes
);
1408 if (!psd
) goto lend
;
1410 psd
->Revision
= SID_REVISION
;
1411 psd
->Control
|= SE_SELF_RELATIVE
;
1413 if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor
,
1414 (SECURITY_DESCRIPTOR_RELATIVE
*)psd
, &cBytes
))
1420 if (SecurityDescriptorSize
)
1421 *SecurityDescriptorSize
= cBytes
;
1426 TRACE(" ret=%d\n", bret
);
1430 static void DumpString(LPCWSTR string
, int cch
, WCHAR
**pwptr
, ULONG
*plen
)
1433 cch
= strlenW(string
);
1440 memcpy(*pwptr
, string
, sizeof(WCHAR
)*cch
);
1445 static BOOL
DumpSidNumeric(PSID psid
, WCHAR
**pwptr
, ULONG
*plen
)
1448 WCHAR fmt
[] = { 'S','-','%','u','-','%','d',0 };
1449 WCHAR subauthfmt
[] = { '-','%','u',0 };
1453 if( !IsValidSid( psid
) || pisid
->Revision
!= SDDL_REVISION
)
1455 SetLastError(ERROR_INVALID_SID
);
1459 if (pisid
->IdentifierAuthority
.Value
[0] ||
1460 pisid
->IdentifierAuthority
.Value
[1])
1462 FIXME("not matching MS' bugs\n");
1463 SetLastError(ERROR_INVALID_SID
);
1467 sprintfW( buf
, fmt
, pisid
->Revision
,
1469 MAKEWORD( pisid
->IdentifierAuthority
.Value
[5],
1470 pisid
->IdentifierAuthority
.Value
[4] ),
1471 MAKEWORD( pisid
->IdentifierAuthority
.Value
[3],
1472 pisid
->IdentifierAuthority
.Value
[2] )
1474 DumpString(buf
, -1, pwptr
, plen
);
1476 for( i
=0; i
<pisid
->SubAuthorityCount
; i
++ )
1478 sprintfW( buf
, subauthfmt
, pisid
->SubAuthority
[i
] );
1479 DumpString(buf
, -1, pwptr
, plen
);
1484 static BOOL
DumpSid(PSID psid
, WCHAR
**pwptr
, ULONG
*plen
)
1487 for (i
= 0; i
< sizeof(WellKnownSids
) / sizeof(WellKnownSids
[0]); i
++)
1489 if (WellKnownSids
[i
].wstr
[0] && EqualSid(psid
, (PSID
)&(WellKnownSids
[i
].Sid
.Revision
)))
1491 DumpString(WellKnownSids
[i
].wstr
, 2, pwptr
, plen
);
1496 return DumpSidNumeric(psid
, pwptr
, plen
);
1499 static const LPCWSTR AceRightBitNames
[32] = {
1500 SDDL_CREATE_CHILD
, /* 0 */
1504 SDDL_READ_PROPERTY
, /* 4 */
1505 SDDL_WRITE_PROPERTY
,
1508 SDDL_CONTROL_ACCESS
, /* 8 */
1516 SDDL_STANDARD_DELETE
, /* 16 */
1528 SDDL_GENERIC_ALL
, /* 28 */
1529 SDDL_GENERIC_EXECUTE
,
1534 static void DumpRights(DWORD mask
, WCHAR
**pwptr
, ULONG
*plen
)
1536 static const WCHAR fmtW
[] = {'0','x','%','x',0};
1543 /* first check if the right have name */
1544 for (i
= 0; i
< sizeof(AceRights
)/sizeof(AceRights
[0]); i
++)
1546 if (AceRights
[i
].wstr
== NULL
)
1548 if (mask
== AceRights
[i
].value
)
1550 DumpString(AceRights
[i
].wstr
, -1, pwptr
, plen
);
1555 /* then check if it can be built from bit names */
1556 for (i
= 0; i
< 32; i
++)
1558 if ((mask
& (1 << i
)) && (AceRightBitNames
[i
] == NULL
))
1560 /* can't be built from bit names */
1561 sprintfW(buf
, fmtW
, mask
);
1562 DumpString(buf
, -1, pwptr
, plen
);
1567 /* build from bit names */
1568 for (i
= 0; i
< 32; i
++)
1569 if (mask
& (1 << i
))
1570 DumpString(AceRightBitNames
[i
], -1, pwptr
, plen
);
1573 static BOOL
DumpAce(LPVOID pace
, WCHAR
**pwptr
, ULONG
*plen
)
1575 ACCESS_ALLOWED_ACE
*piace
; /* all the supported ACEs have the same memory layout */
1576 static const WCHAR openbr
= '(';
1577 static const WCHAR closebr
= ')';
1578 static const WCHAR semicolon
= ';';
1580 if (((PACE_HEADER
)pace
)->AceType
> SYSTEM_ALARM_ACE_TYPE
|| ((PACE_HEADER
)pace
)->AceSize
< sizeof(ACCESS_ALLOWED_ACE
))
1582 SetLastError(ERROR_INVALID_ACL
);
1587 DumpString(&openbr
, 1, pwptr
, plen
);
1588 switch (piace
->Header
.AceType
)
1590 case ACCESS_ALLOWED_ACE_TYPE
:
1591 DumpString(SDDL_ACCESS_ALLOWED
, -1, pwptr
, plen
);
1593 case ACCESS_DENIED_ACE_TYPE
:
1594 DumpString(SDDL_ACCESS_DENIED
, -1, pwptr
, plen
);
1596 case SYSTEM_AUDIT_ACE_TYPE
:
1597 DumpString(SDDL_AUDIT
, -1, pwptr
, plen
);
1599 case SYSTEM_ALARM_ACE_TYPE
:
1600 DumpString(SDDL_ALARM
, -1, pwptr
, plen
);
1603 DumpString(&semicolon
, 1, pwptr
, plen
);
1605 if (piace
->Header
.AceFlags
& OBJECT_INHERIT_ACE
)
1606 DumpString(SDDL_OBJECT_INHERIT
, -1, pwptr
, plen
);
1607 if (piace
->Header
.AceFlags
& CONTAINER_INHERIT_ACE
)
1608 DumpString(SDDL_CONTAINER_INHERIT
, -1, pwptr
, plen
);
1609 if (piace
->Header
.AceFlags
& NO_PROPAGATE_INHERIT_ACE
)
1610 DumpString(SDDL_NO_PROPAGATE
, -1, pwptr
, plen
);
1611 if (piace
->Header
.AceFlags
& INHERIT_ONLY_ACE
)
1612 DumpString(SDDL_INHERIT_ONLY
, -1, pwptr
, plen
);
1613 if (piace
->Header
.AceFlags
& INHERITED_ACE
)
1614 DumpString(SDDL_INHERITED
, -1, pwptr
, plen
);
1615 if (piace
->Header
.AceFlags
& SUCCESSFUL_ACCESS_ACE_FLAG
)
1616 DumpString(SDDL_AUDIT_SUCCESS
, -1, pwptr
, plen
);
1617 if (piace
->Header
.AceFlags
& FAILED_ACCESS_ACE_FLAG
)
1618 DumpString(SDDL_AUDIT_FAILURE
, -1, pwptr
, plen
);
1619 DumpString(&semicolon
, 1, pwptr
, plen
);
1620 DumpRights(piace
->Mask
, pwptr
, plen
);
1621 DumpString(&semicolon
, 1, pwptr
, plen
);
1622 /* objects not supported */
1623 DumpString(&semicolon
, 1, pwptr
, plen
);
1624 /* objects not supported */
1625 DumpString(&semicolon
, 1, pwptr
, plen
);
1626 if (!DumpSid((PSID
)&piace
->SidStart
, pwptr
, plen
))
1628 DumpString(&closebr
, 1, pwptr
, plen
);
1632 static BOOL
DumpAcl(PACL pacl
, WCHAR
**pwptr
, ULONG
*plen
, BOOL
protected, BOOL autoInheritReq
, BOOL autoInherited
)
1638 DumpString(SDDL_PROTECTED
, -1, pwptr
, plen
);
1640 DumpString(SDDL_AUTO_INHERIT_REQ
, -1, pwptr
, plen
);
1642 DumpString(SDDL_AUTO_INHERITED
, -1, pwptr
, plen
);
1647 if (!IsValidAcl(pacl
))
1650 count
= pacl
->AceCount
;
1651 for (i
= 0; i
< count
; i
++)
1654 if (!GetAce(pacl
, i
, &ace
))
1656 if (!DumpAce(ace
, pwptr
, plen
))
1663 static BOOL
DumpOwner(PSECURITY_DESCRIPTOR SecurityDescriptor
, WCHAR
**pwptr
, ULONG
*plen
)
1665 static const WCHAR prefix
[] = {'O',':',0};
1669 if (!GetSecurityDescriptorOwner(SecurityDescriptor
, &psid
, &bDefaulted
))
1675 DumpString(prefix
, -1, pwptr
, plen
);
1676 if (!DumpSid(psid
, pwptr
, plen
))
1681 static BOOL
DumpGroup(PSECURITY_DESCRIPTOR SecurityDescriptor
, WCHAR
**pwptr
, ULONG
*plen
)
1683 static const WCHAR prefix
[] = {'G',':',0};
1687 if (!GetSecurityDescriptorGroup(SecurityDescriptor
, &psid
, &bDefaulted
))
1693 DumpString(prefix
, -1, pwptr
, plen
);
1694 if (!DumpSid(psid
, pwptr
, plen
))
1699 static BOOL
DumpDacl(PSECURITY_DESCRIPTOR SecurityDescriptor
, WCHAR
**pwptr
, ULONG
*plen
)
1701 static const WCHAR dacl
[] = {'D',':',0};
1702 SECURITY_DESCRIPTOR_CONTROL control
;
1703 BOOL present
, defaulted
;
1707 if (!GetSecurityDescriptorDacl(SecurityDescriptor
, &present
, &pacl
, &defaulted
))
1710 if (!GetSecurityDescriptorControl(SecurityDescriptor
, &control
, &revision
))
1716 DumpString(dacl
, 2, pwptr
, plen
);
1717 if (!DumpAcl(pacl
, pwptr
, plen
, control
& SE_DACL_PROTECTED
, control
& SE_DACL_AUTO_INHERIT_REQ
, control
& SE_DACL_AUTO_INHERITED
))
1722 static BOOL
DumpSacl(PSECURITY_DESCRIPTOR SecurityDescriptor
, WCHAR
**pwptr
, ULONG
*plen
)
1724 static const WCHAR sacl
[] = {'S',':',0};
1725 SECURITY_DESCRIPTOR_CONTROL control
;
1726 BOOL present
, defaulted
;
1730 if (!GetSecurityDescriptorSacl(SecurityDescriptor
, &present
, &pacl
, &defaulted
))
1733 if (!GetSecurityDescriptorControl(SecurityDescriptor
, &control
, &revision
))
1739 DumpString(sacl
, 2, pwptr
, plen
);
1740 if (!DumpAcl(pacl
, pwptr
, plen
, control
& SE_SACL_PROTECTED
, control
& SE_SACL_AUTO_INHERIT_REQ
, control
& SE_SACL_AUTO_INHERITED
))
1745 /******************************************************************************
1746 * ConvertSecurityDescriptorToStringSecurityDescriptorW [ADVAPI32.@]
1750 ConvertSecurityDescriptorToStringSecurityDescriptorW(PSECURITY_DESCRIPTOR SecurityDescriptor
,
1752 SECURITY_INFORMATION SecurityInformation
,
1753 LPWSTR
*OutputString
,
1759 if (SDRevision
!= SDDL_REVISION_1
)
1761 ERR("Program requested unknown SDDL revision %d\n", SDRevision
);
1762 SetLastError(ERROR_UNKNOWN_REVISION
);
1767 if (SecurityInformation
& OWNER_SECURITY_INFORMATION
)
1768 if (!DumpOwner(SecurityDescriptor
, NULL
, &len
))
1770 if (SecurityInformation
& GROUP_SECURITY_INFORMATION
)
1771 if (!DumpGroup(SecurityDescriptor
, NULL
, &len
))
1773 if (SecurityInformation
& DACL_SECURITY_INFORMATION
)
1774 if (!DumpDacl(SecurityDescriptor
, NULL
, &len
))
1776 if (SecurityInformation
& SACL_SECURITY_INFORMATION
)
1777 if (!DumpSacl(SecurityDescriptor
, NULL
, &len
))
1780 wstr
= wptr
= LocalAlloc(0, (len
+ 1)*sizeof(WCHAR
));
1784 if (SecurityInformation
& OWNER_SECURITY_INFORMATION
)
1785 if (!DumpOwner(SecurityDescriptor
, &wptr
, NULL
))
1787 if (SecurityInformation
& GROUP_SECURITY_INFORMATION
)
1788 if (!DumpGroup(SecurityDescriptor
, &wptr
, NULL
))
1790 if (SecurityInformation
& DACL_SECURITY_INFORMATION
)
1791 if (!DumpDacl(SecurityDescriptor
, &wptr
, NULL
))
1793 if (SecurityInformation
& SACL_SECURITY_INFORMATION
)
1794 if (!DumpSacl(SecurityDescriptor
, &wptr
, NULL
))
1798 TRACE("ret: %s, %d\n", wine_dbgstr_w(wstr
), len
);
1799 *OutputString
= wstr
;
1801 *OutputLen
= strlenW(*OutputString
)+1;
1805 /******************************************************************************
1806 * ConvertSecurityDescriptorToStringSecurityDescriptorA [ADVAPI32.@]
1810 ConvertSecurityDescriptorToStringSecurityDescriptorA(PSECURITY_DESCRIPTOR SecurityDescriptor
,
1812 SECURITY_INFORMATION Information
,
1813 LPSTR
*OutputString
,
1819 if (ConvertSecurityDescriptorToStringSecurityDescriptorW(SecurityDescriptor
, SDRevision
, Information
, &wstr
, &len
))
1823 lenA
= WideCharToMultiByte(CP_ACP
, 0, wstr
, len
, NULL
, 0, NULL
, NULL
);
1824 *OutputString
= HeapAlloc(GetProcessHeap(), 0, lenA
);
1825 if (*OutputString
== NULL
)
1831 WideCharToMultiByte(CP_ACP
, 0, wstr
, len
, *OutputString
, lenA
, NULL
, NULL
);
1834 if (OutputLen
!= NULL
)
1840 *OutputString
= NULL
;
1852 ConvertStringSidToSidW(IN LPCWSTR StringSid
,
1856 DWORD i
, cBytes
, identAuth
, csubauth
;
1860 TRACE("%s %p\n", debugstr_w(StringSid
), sid
);
1864 SetLastError(ERROR_INVALID_SID
);
1868 for (i
= 0; i
< sizeof(SidTable
) / sizeof(SidTable
[0]) - 1; i
++)
1870 if (wcscmp(StringSid
, SidTable
[i
].key
) == 0)
1872 WELL_KNOWN_SID_TYPE knownSid
= (WELL_KNOWN_SID_TYPE
)SidTable
[i
].value
;
1873 size
= SECURITY_MAX_SID_SIZE
;
1874 *sid
= LocalAlloc(0, size
);
1877 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
1880 ret
= CreateWellKnownSid(knownSid
,
1886 SetLastError(ERROR_INVALID_SID
);
1893 /* That's probably a string S-R-I-S-S... */
1894 if (StringSid
[0] != 'S' || StringSid
[1] != '-')
1896 SetLastError(ERROR_INVALID_SID
);
1900 cBytes
= ComputeStringSidSize(StringSid
);
1901 pisid
= (SID
*)LocalAlloc( 0, cBytes
);
1904 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
1909 csubauth
= ((cBytes
- GetSidLengthRequired(0)) / sizeof(DWORD
));
1911 StringSid
+= 2; /* Advance to Revision */
1912 pisid
->Revision
= atoiW(StringSid
);
1914 if (pisid
->Revision
!= SDDL_REVISION
)
1916 TRACE("Revision %d is unknown\n", pisid
->Revision
);
1917 goto lend
; /* ERROR_INVALID_SID */
1921 TRACE("SubAuthorityCount is 0\n");
1922 goto lend
; /* ERROR_INVALID_SID */
1925 pisid
->SubAuthorityCount
= csubauth
;
1927 /* Advance to identifier authority */
1928 while (*StringSid
&& *StringSid
!= '-')
1930 if (*StringSid
== '-')
1933 /* MS' implementation can't handle values greater than 2^32 - 1, so
1934 * we don't either; assume most significant bytes are always 0
1936 pisid
->IdentifierAuthority
.Value
[0] = 0;
1937 pisid
->IdentifierAuthority
.Value
[1] = 0;
1938 identAuth
= atoiW(StringSid
);
1939 pisid
->IdentifierAuthority
.Value
[5] = identAuth
& 0xff;
1940 pisid
->IdentifierAuthority
.Value
[4] = (identAuth
& 0xff00) >> 8;
1941 pisid
->IdentifierAuthority
.Value
[3] = (identAuth
& 0xff0000) >> 16;
1942 pisid
->IdentifierAuthority
.Value
[2] = (identAuth
& 0xff000000) >> 24;
1944 /* Advance to first sub authority */
1945 while (*StringSid
&& *StringSid
!= '-')
1947 if (*StringSid
== '-')
1952 pisid
->SubAuthority
[i
++] = atoiW(StringSid
);
1954 while (*StringSid
&& *StringSid
!= '-')
1956 if (*StringSid
== '-')
1960 if (i
!= pisid
->SubAuthorityCount
)
1961 goto lend
; /* ERROR_INVALID_SID */
1970 SetLastError(ERROR_INVALID_SID
);
1973 TRACE("returning %s\n", ret
? "TRUE" : "FALSE");
1982 ConvertStringSidToSidA(IN LPCSTR StringSid
,
1985 BOOL bRetVal
= FALSE
;
1987 TRACE("%s, %p\n", debugstr_a(StringSid
), sid
);
1988 if (GetVersion() & 0x80000000)
1989 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1990 else if (!StringSid
|| !sid
)
1991 SetLastError(ERROR_INVALID_PARAMETER
);
1994 UINT len
= MultiByteToWideChar(CP_ACP
, 0, StringSid
, -1, NULL
, 0);
1995 LPWSTR wStringSid
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
1996 if (wStringSid
== NULL
)
1998 MultiByteToWideChar(CP_ACP
, 0, StringSid
, - 1, wStringSid
, len
);
1999 bRetVal
= ConvertStringSidToSidW(wStringSid
, sid
);
2000 HeapFree(GetProcessHeap(), 0, wStringSid
);
2010 ConvertSidToStringSidW(PSID Sid
,
2014 UNICODE_STRING UnicodeString
;
2015 WCHAR FixedBuffer
[64];
2017 if (!RtlValidSid(Sid
))
2019 SetLastError(ERROR_INVALID_SID
);
2023 UnicodeString
.Length
= 0;
2024 UnicodeString
.MaximumLength
= sizeof(FixedBuffer
);
2025 UnicodeString
.Buffer
= FixedBuffer
;
2026 Status
= RtlConvertSidToUnicodeString(&UnicodeString
, Sid
, FALSE
);
2027 if (STATUS_BUFFER_TOO_SMALL
== Status
)
2029 Status
= RtlConvertSidToUnicodeString(&UnicodeString
, Sid
, TRUE
);
2032 if (!NT_SUCCESS(Status
))
2034 SetLastError(RtlNtStatusToDosError(Status
));
2038 *StringSid
= LocalAlloc(LMEM_FIXED
, UnicodeString
.Length
+ sizeof(WCHAR
));
2039 if (NULL
== *StringSid
)
2041 if (UnicodeString
.Buffer
!= FixedBuffer
)
2043 RtlFreeUnicodeString(&UnicodeString
);
2045 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
2049 MoveMemory(*StringSid
, UnicodeString
.Buffer
, UnicodeString
.Length
);
2050 ZeroMemory((PCHAR
) *StringSid
+ UnicodeString
.Length
, sizeof(WCHAR
));
2051 if (UnicodeString
.Buffer
!= FixedBuffer
)
2053 RtlFreeUnicodeString(&UnicodeString
);
2064 ConvertSidToStringSidA(PSID Sid
,
2070 if (!ConvertSidToStringSidW(Sid
, &StringSidW
))
2075 Len
= WideCharToMultiByte(CP_ACP
, 0, StringSidW
, -1, NULL
, 0, NULL
, NULL
);
2078 LocalFree(StringSidW
);
2079 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
2083 *StringSid
= LocalAlloc(LMEM_FIXED
, Len
);
2084 if (NULL
== *StringSid
)
2086 LocalFree(StringSidW
);
2087 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
2091 if (!WideCharToMultiByte(CP_ACP
, 0, StringSidW
, -1, *StringSid
, Len
, NULL
, NULL
))
2093 LocalFree(StringSid
);
2094 LocalFree(StringSidW
);
2098 LocalFree(StringSidW
);
2105 CreateProcessWithTokenW(IN HANDLE hToken
,
2106 IN DWORD dwLogonFlags
,
2107 IN LPCWSTR lpApplicationName OPTIONAL
,
2108 IN OUT LPWSTR lpCommandLine OPTIONAL
,
2109 IN DWORD dwCreationFlags
,
2110 IN LPVOID lpEnvironment OPTIONAL
,
2111 IN LPCWSTR lpCurrentDirectory OPTIONAL
,
2112 IN LPSTARTUPINFOW lpStartupInfo
,
2113 OUT LPPROCESS_INFORMATION lpProcessInfo
)
2123 DuplicateTokenEx(IN HANDLE ExistingTokenHandle
,
2124 IN DWORD dwDesiredAccess
,
2125 IN LPSECURITY_ATTRIBUTES lpTokenAttributes OPTIONAL
,
2126 IN SECURITY_IMPERSONATION_LEVEL ImpersonationLevel
,
2127 IN TOKEN_TYPE TokenType
,
2128 OUT PHANDLE DuplicateTokenHandle
)
2130 OBJECT_ATTRIBUTES ObjectAttributes
;
2132 SECURITY_QUALITY_OF_SERVICE Sqos
;
2134 TRACE("%p 0x%08x 0x%08x 0x%08x %p\n", ExistingTokenHandle
, dwDesiredAccess
,
2135 ImpersonationLevel
, TokenType
, DuplicateTokenHandle
);
2137 Sqos
.Length
= sizeof(SECURITY_QUALITY_OF_SERVICE
);
2138 Sqos
.ImpersonationLevel
= ImpersonationLevel
;
2139 Sqos
.ContextTrackingMode
= 0;
2140 Sqos
.EffectiveOnly
= FALSE
;
2142 if (lpTokenAttributes
!= NULL
)
2144 InitializeObjectAttributes(&ObjectAttributes
,
2146 lpTokenAttributes
->bInheritHandle
? OBJ_INHERIT
: 0,
2148 lpTokenAttributes
->lpSecurityDescriptor
);
2152 InitializeObjectAttributes(&ObjectAttributes
,
2159 ObjectAttributes
.SecurityQualityOfService
= &Sqos
;
2161 Status
= NtDuplicateToken(ExistingTokenHandle
,
2166 DuplicateTokenHandle
);
2167 if (!NT_SUCCESS(Status
))
2169 ERR("NtDuplicateToken failed: Status %08x\n", Status
);
2170 SetLastError(RtlNtStatusToDosError(Status
));
2174 TRACE("Returning token %p.\n", *DuplicateTokenHandle
);
2183 DuplicateToken(IN HANDLE ExistingTokenHandle
,
2184 IN SECURITY_IMPERSONATION_LEVEL ImpersonationLevel
,
2185 OUT PHANDLE DuplicateTokenHandle
)
2187 return DuplicateTokenEx(ExistingTokenHandle
,
2188 TOKEN_IMPERSONATE
| TOKEN_QUERY
,
2192 DuplicateTokenHandle
);
2195 /******************************************************************************
2196 * ComputeStringSidSize
2198 static DWORD
ComputeStringSidSize(LPCWSTR StringSid
)
2200 if (StringSid
[0] == 'S' && StringSid
[1] == '-') /* S-R-I(-S)+ */
2205 if (*StringSid
== '-')
2211 return GetSidLengthRequired(ctok
- 2);
2213 else /* String constant format - Only available in winxp and above */
2217 for (i
= 0; i
< sizeof(WellKnownSids
)/sizeof(WellKnownSids
[0]); i
++)
2218 if (!strncmpW(WellKnownSids
[i
].wstr
, StringSid
, 2))
2219 return GetSidLengthRequired(WellKnownSids
[i
].Sid
.SubAuthorityCount
);
2222 return GetSidLengthRequired(0);
2225 /******************************************************************************
2226 * ParseStringSidToSid
2228 static BOOL
ParseStringSidToSid(LPCWSTR StringSid
, PSID pSid
, LPDWORD cBytes
)
2233 TRACE("%s, %p, %p\n", debugstr_w(StringSid
), pSid
, cBytes
);
2236 SetLastError(ERROR_INVALID_PARAMETER
);
2237 TRACE("StringSid is NULL, returning FALSE\n");
2241 while (*StringSid
== ' ')
2244 *cBytes
= ComputeStringSidSize(StringSid
);
2245 if (!pisid
) /* Simply compute the size */
2247 TRACE("only size requested, returning TRUE\n");
2251 if (StringSid
[0] == 'S' && StringSid
[1] == '-') /* S-R-I-S-S */
2253 DWORD i
= 0, identAuth
;
2254 DWORD csubauth
= ((*cBytes
- GetSidLengthRequired(0)) / sizeof(DWORD
));
2256 StringSid
+= 2; /* Advance to Revision */
2257 pisid
->Revision
= atoiW(StringSid
);
2259 if (pisid
->Revision
!= SDDL_REVISION
)
2261 TRACE("Revision %d is unknown\n", pisid
->Revision
);
2262 goto lend
; /* ERROR_INVALID_SID */
2266 TRACE("SubAuthorityCount is 0\n");
2267 goto lend
; /* ERROR_INVALID_SID */
2270 pisid
->SubAuthorityCount
= csubauth
;
2272 /* Advance to identifier authority */
2273 while (*StringSid
&& *StringSid
!= '-')
2275 if (*StringSid
== '-')
2278 /* MS' implementation can't handle values greater than 2^32 - 1, so
2279 * we don't either; assume most significant bytes are always 0
2281 pisid
->IdentifierAuthority
.Value
[0] = 0;
2282 pisid
->IdentifierAuthority
.Value
[1] = 0;
2283 identAuth
= atoiW(StringSid
);
2284 pisid
->IdentifierAuthority
.Value
[5] = identAuth
& 0xff;
2285 pisid
->IdentifierAuthority
.Value
[4] = (identAuth
& 0xff00) >> 8;
2286 pisid
->IdentifierAuthority
.Value
[3] = (identAuth
& 0xff0000) >> 16;
2287 pisid
->IdentifierAuthority
.Value
[2] = (identAuth
& 0xff000000) >> 24;
2289 /* Advance to first sub authority */
2290 while (*StringSid
&& *StringSid
!= '-')
2292 if (*StringSid
== '-')
2297 pisid
->SubAuthority
[i
++] = atoiW(StringSid
);
2299 while (*StringSid
&& *StringSid
!= '-')
2301 if (*StringSid
== '-')
2305 if (i
!= pisid
->SubAuthorityCount
)
2306 goto lend
; /* ERROR_INVALID_SID */
2310 else /* String constant format - Only available in winxp and above */
2313 pisid
->Revision
= SDDL_REVISION
;
2315 for (i
= 0; i
< sizeof(WellKnownSids
)/sizeof(WellKnownSids
[0]); i
++)
2316 if (!strncmpW(WellKnownSids
[i
].wstr
, StringSid
, 2))
2319 pisid
->SubAuthorityCount
= WellKnownSids
[i
].Sid
.SubAuthorityCount
;
2320 pisid
->IdentifierAuthority
= WellKnownSids
[i
].Sid
.IdentifierAuthority
;
2321 for (j
= 0; j
< WellKnownSids
[i
].Sid
.SubAuthorityCount
; j
++)
2322 pisid
->SubAuthority
[j
] = WellKnownSids
[i
].Sid
.SubAuthority
[j
];
2327 FIXME("String constant not supported: %s\n", debugstr_wn(StringSid
, 2));
2332 SetLastError(ERROR_INVALID_SID
);
2334 TRACE("returning %s\n", bret
? "TRUE" : "FALSE");
2343 GetWindowsAccountDomainSid(IN PSID pSid
,
2344 OUT PSID ppDomainSid
,
2345 IN OUT DWORD
* cbSid
)
2356 EqualDomainSid(IN PSID pSid1
,