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 (!NT_SUCCESS(status
)) SetLastError( RtlNtStatusToDosError( status
));
268 return NT_SUCCESS(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 /************************************************************
315 * ADVAPI_IsLocalComputer
317 * Checks whether the server name indicates local machine.
319 BOOL
ADVAPI_IsLocalComputer(LPCWSTR ServerName
)
321 DWORD dwSize
= MAX_COMPUTERNAME_LENGTH
+ 1;
325 if (!ServerName
|| !ServerName
[0])
328 buf
= heap_alloc(dwSize
* sizeof(WCHAR
));
329 Result
= GetComputerNameW(buf
, &dwSize
);
330 if (Result
&& (ServerName
[0] == '\\') && (ServerName
[1] == '\\'))
332 Result
= Result
&& !lstrcmpW(ServerName
, buf
);
338 /* Exported functions */
344 OpenProcessToken(HANDLE ProcessHandle
,
350 TRACE("%p, %x, %p.\n", ProcessHandle
, DesiredAccess
, TokenHandle
);
352 Status
= NtOpenProcessToken(ProcessHandle
,
355 if (!NT_SUCCESS(Status
))
357 ERR("NtOpenProcessToken failed! Status %08x.\n", Status
);
358 SetLastError(RtlNtStatusToDosError(Status
));
362 TRACE("Returning token %p.\n", *TokenHandle
);
371 OpenThreadToken(HANDLE ThreadHandle
,
378 Status
= NtOpenThreadToken(ThreadHandle
,
382 if (!NT_SUCCESS(Status
))
384 SetLastError(RtlNtStatusToDosError(Status
));
395 AdjustTokenGroups(HANDLE TokenHandle
,
397 PTOKEN_GROUPS NewState
,
399 PTOKEN_GROUPS PreviousState
,
404 Status
= NtAdjustGroupsToken(TokenHandle
,
409 (PULONG
)ReturnLength
);
410 if (!NT_SUCCESS(Status
))
412 SetLastError(RtlNtStatusToDosError(Status
));
423 AdjustTokenPrivileges(HANDLE TokenHandle
,
424 BOOL DisableAllPrivileges
,
425 PTOKEN_PRIVILEGES NewState
,
427 PTOKEN_PRIVILEGES PreviousState
,
432 Status
= NtAdjustPrivilegesToken(TokenHandle
,
433 DisableAllPrivileges
,
437 (PULONG
)ReturnLength
);
438 if (STATUS_NOT_ALL_ASSIGNED
== Status
)
440 SetLastError(ERROR_NOT_ALL_ASSIGNED
);
444 if (!NT_SUCCESS(Status
))
446 SetLastError(RtlNtStatusToDosError(Status
));
450 /* AdjustTokenPrivileges is documented to do this */
451 SetLastError(ERROR_SUCCESS
);
460 GetTokenInformation(HANDLE TokenHandle
,
461 TOKEN_INFORMATION_CLASS TokenInformationClass
,
462 LPVOID TokenInformation
,
463 DWORD TokenInformationLength
,
468 Status
= NtQueryInformationToken(TokenHandle
,
469 TokenInformationClass
,
471 TokenInformationLength
,
472 (PULONG
)ReturnLength
);
473 if (!NT_SUCCESS(Status
))
475 SetLastError(RtlNtStatusToDosError(Status
));
486 SetTokenInformation(HANDLE TokenHandle
,
487 TOKEN_INFORMATION_CLASS TokenInformationClass
,
488 LPVOID TokenInformation
,
489 DWORD TokenInformationLength
)
493 Status
= NtSetInformationToken(TokenHandle
,
494 TokenInformationClass
,
496 TokenInformationLength
);
497 if (!NT_SUCCESS(Status
))
499 SetLastError(RtlNtStatusToDosError(Status
));
510 SetThreadToken(IN PHANDLE ThreadHandle OPTIONAL
,
511 IN HANDLE TokenHandle
)
516 hThread
= (ThreadHandle
!= NULL
) ? *ThreadHandle
: NtCurrentThread();
518 Status
= NtSetInformationThread(hThread
,
519 ThreadImpersonationToken
,
522 if (!NT_SUCCESS(Status
))
524 SetLastError(RtlNtStatusToDosError(Status
));
531 /*************************************************************************
532 * CreateRestrictedToken [ADVAPI32.@]
534 * Create a new more restricted token from an existing token.
537 * baseToken [I] Token to base the new restricted token on
539 * nDisableSids [I] Length of disableSids array
540 * disableSids [I] Array of SIDs to disable in the new token
541 * nDeletePrivs [I] Length of deletePrivs array
542 * deletePrivs [I] Array of privileges to delete in the new token
543 * nRestrictSids [I] Length of restrictSids array
544 * restrictSids [I] Array of SIDs to restrict in the new token
545 * newToken [O] Address where the new token is stored
551 BOOL WINAPI
CreateRestrictedToken(
555 PSID_AND_ATTRIBUTES disableSids
,
557 PLUID_AND_ATTRIBUTES deletePrivs
,
559 PSID_AND_ATTRIBUTES restrictSids
,
563 SECURITY_IMPERSONATION_LEVEL level
= TokenImpersonationLevel
;
566 FIXME("(%p, 0x%x, %u, %p, %u, %p, %u, %p, %p): stub\n",
567 baseToken
, flags
, nDisableSids
, disableSids
,
568 nDeletePrivs
, deletePrivs
,
569 nRestrictSids
, restrictSids
,
573 if (!GetTokenInformation( baseToken
, TokenType
, &type
, size
, &size
)) return FALSE
;
574 if (type
== TokenImpersonation
)
576 size
= sizeof(level
);
577 if (!GetTokenInformation( baseToken
, TokenImpersonationLevel
, &level
, size
, &size
))
580 return DuplicateTokenEx( baseToken
, MAXIMUM_ALLOWED
, NULL
, level
, type
, newToken
);
583 /******************************************************************************
584 * AllocateAndInitializeSid [ADVAPI32.@]
587 * pIdentifierAuthority []
588 * nSubAuthorityCount []
600 AllocateAndInitializeSid( PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority
,
601 BYTE nSubAuthorityCount
,
602 DWORD nSubAuthority0
, DWORD nSubAuthority1
,
603 DWORD nSubAuthority2
, DWORD nSubAuthority3
,
604 DWORD nSubAuthority4
, DWORD nSubAuthority5
,
605 DWORD nSubAuthority6
, DWORD nSubAuthority7
,
608 return set_ntstatus( RtlAllocateAndInitializeSid(
609 pIdentifierAuthority
, nSubAuthorityCount
,
610 nSubAuthority0
, nSubAuthority1
, nSubAuthority2
, nSubAuthority3
,
611 nSubAuthority4
, nSubAuthority5
, nSubAuthority6
, nSubAuthority7
,
619 * Docs says this function does NOT return a value
620 * even thou it's defined to return a PVOID...
626 return RtlFreeSid(pSid
);
633 CopySid(DWORD nDestinationSidLength
,
634 PSID pDestinationSid
,
639 Status
= RtlCopySid(nDestinationSidLength
,
642 if (!NT_SUCCESS (Status
))
644 SetLastError(RtlNtStatusToDosError(Status
));
656 CreateWellKnownSid(IN WELL_KNOWN_SID_TYPE WellKnownSidType
,
657 IN PSID DomainSid OPTIONAL
,
662 TRACE("(%d, %s, %p, %p)\n", WellKnownSidType
, debugstr_sid(DomainSid
), pSid
, cbSid
);
664 if (cbSid
== NULL
|| (DomainSid
&& !IsValidSid(DomainSid
)))
666 SetLastError(ERROR_INVALID_PARAMETER
);
670 for (i
= 0; i
< sizeof(WellKnownSids
)/sizeof(WellKnownSids
[0]); i
++) {
671 if (WellKnownSids
[i
].Type
== WellKnownSidType
) {
672 DWORD length
= GetSidLengthRequired(WellKnownSids
[i
].Sid
.SubAuthorityCount
);
677 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
682 SetLastError(ERROR_INVALID_PARAMETER
);
685 CopyMemory(pSid
, &WellKnownSids
[i
].Sid
.Revision
, length
);
691 if (DomainSid
== NULL
|| *GetSidSubAuthorityCount(DomainSid
) == SID_MAX_SUB_AUTHORITIES
)
693 SetLastError(ERROR_INVALID_PARAMETER
);
697 for (i
= 0; i
< sizeof(WellKnownRids
)/sizeof(WellKnownRids
[0]); i
++)
698 if (WellKnownRids
[i
].Type
== WellKnownSidType
) {
699 UCHAR domain_subauth
= *GetSidSubAuthorityCount(DomainSid
);
700 DWORD domain_sid_length
= GetSidLengthRequired(domain_subauth
);
701 DWORD output_sid_length
= GetSidLengthRequired(domain_subauth
+ 1);
703 if (*cbSid
< output_sid_length
)
705 *cbSid
= output_sid_length
;
706 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
711 SetLastError(ERROR_INVALID_PARAMETER
);
714 CopyMemory(pSid
, DomainSid
, domain_sid_length
);
715 (*GetSidSubAuthorityCount(pSid
))++;
716 (*GetSidSubAuthority(pSid
, domain_subauth
)) = WellKnownRids
[i
].Rid
;
717 *cbSid
= output_sid_length
;
721 SetLastError(ERROR_INVALID_PARAMETER
);
730 IsWellKnownSid(IN PSID pSid
,
731 IN WELL_KNOWN_SID_TYPE WellKnownSidType
)
734 TRACE("(%s, %d)\n", debugstr_sid(pSid
), WellKnownSidType
);
736 for (i
= 0; i
< sizeof(WellKnownSids
) / sizeof(WellKnownSids
[0]); i
++)
738 if (WellKnownSids
[i
].Type
== WellKnownSidType
)
740 if (EqualSid(pSid
, (PSID
)(&WellKnownSids
[i
].Sid
.Revision
)))
753 IsValidSid(PSID pSid
)
755 return (BOOL
)RtlValidSid(pSid
);
766 SetLastError(ERROR_SUCCESS
);
767 return RtlEqualSid (pSid1
, pSid2
);
775 EqualPrefixSid(PSID pSid1
,
778 return RtlEqualPrefixSid (pSid1
, pSid2
);
786 GetSidLengthRequired(UCHAR nSubAuthorityCount
)
788 return (DWORD
)RtlLengthRequiredSid(nSubAuthorityCount
);
796 InitializeSid(PSID Sid
,
797 PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority
,
798 BYTE nSubAuthorityCount
)
802 Status
= RtlInitializeSid(Sid
,
803 pIdentifierAuthority
,
805 if (!NT_SUCCESS(Status
))
807 SetLastError(RtlNtStatusToDosError(Status
));
817 PSID_IDENTIFIER_AUTHORITY
819 GetSidIdentifierAuthority(PSID pSid
)
821 return RtlIdentifierAuthoritySid(pSid
);
829 GetSidSubAuthority(PSID pSid
,
832 SetLastError(ERROR_SUCCESS
);
833 return (PDWORD
)RtlSubAuthoritySid(pSid
, nSubAuthority
);
841 GetSidSubAuthorityCount(PSID pSid
)
843 SetLastError(ERROR_SUCCESS
);
844 return RtlSubAuthorityCountSid(pSid
);
852 GetLengthSid(PSID pSid
)
854 return (DWORD
)RtlLengthSid(pSid
);
862 InitializeSecurityDescriptor(PSECURITY_DESCRIPTOR pSecurityDescriptor
,
867 Status
= RtlCreateSecurityDescriptor(pSecurityDescriptor
,
869 if (!NT_SUCCESS(Status
))
871 SetLastError(RtlNtStatusToDosError(Status
));
883 MakeAbsoluteSD(PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor
,
884 PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor
,
885 LPDWORD lpdwAbsoluteSecurityDescriptorSize
,
887 LPDWORD lpdwDaclSize
,
889 LPDWORD lpdwSaclSize
,
891 LPDWORD lpdwOwnerSize
,
893 LPDWORD lpdwPrimaryGroupSize
)
897 Status
= RtlSelfRelativeToAbsoluteSD(pSelfRelativeSecurityDescriptor
,
898 pAbsoluteSecurityDescriptor
,
899 lpdwAbsoluteSecurityDescriptorSize
,
907 lpdwPrimaryGroupSize
);
908 if (!NT_SUCCESS(Status
))
910 SetLastError(RtlNtStatusToDosError(Status
));
917 /******************************************************************************
918 * GetKernelObjectSecurity [ADVAPI32.@]
920 BOOL WINAPI
GetKernelObjectSecurity(
922 SECURITY_INFORMATION RequestedInformation
,
923 PSECURITY_DESCRIPTOR pSecurityDescriptor
,
925 LPDWORD lpnLengthNeeded
)
927 TRACE("(%p,0x%08x,%p,0x%08x,%p)\n", Handle
, RequestedInformation
,
928 pSecurityDescriptor
, nLength
, lpnLengthNeeded
);
930 return set_ntstatus( NtQuerySecurityObject(Handle
, RequestedInformation
, pSecurityDescriptor
,
931 nLength
, lpnLengthNeeded
));
939 InitializeAcl(PACL pAcl
,
945 Status
= RtlCreateAcl(pAcl
,
948 if (!NT_SUCCESS(Status
))
950 SetLastError(RtlNtStatusToDosError(Status
));
957 BOOL WINAPI
ImpersonateNamedPipeClient( HANDLE hNamedPipe
)
959 IO_STATUS_BLOCK io_block
;
961 TRACE("(%p)\n", hNamedPipe
);
963 return set_ntstatus( NtFsControlFile(hNamedPipe
, NULL
, NULL
, NULL
,
964 &io_block
, FSCTL_PIPE_IMPERSONATE
, NULL
, 0, NULL
, 0) );
972 AddAccessAllowedAce(PACL pAcl
,
979 Status
= RtlAddAccessAllowedAce(pAcl
,
983 if (!NT_SUCCESS(Status
))
985 SetLastError(RtlNtStatusToDosError(Status
));
996 AddAccessAllowedAceEx(PACL pAcl
,
1004 Status
= RtlAddAccessAllowedAceEx(pAcl
,
1009 if (!NT_SUCCESS(Status
))
1011 SetLastError(RtlNtStatusToDosError(Status
));
1023 AddAccessDeniedAce(PACL pAcl
,
1024 DWORD dwAceRevision
,
1030 Status
= RtlAddAccessDeniedAce(pAcl
,
1034 if (!NT_SUCCESS(Status
))
1036 SetLastError(RtlNtStatusToDosError(Status
));
1047 AddAccessDeniedAceEx(PACL pAcl
,
1048 DWORD dwAceRevision
,
1055 Status
= RtlAddAccessDeniedAceEx(pAcl
,
1060 if (!NT_SUCCESS(Status
))
1062 SetLastError(RtlNtStatusToDosError(Status
));
1075 DWORD dwAceRevision
,
1076 DWORD dwStartingAceIndex
,
1078 DWORD nAceListLength
)
1082 Status
= RtlAddAce(pAcl
,
1087 if (!NT_SUCCESS(Status
))
1089 SetLastError(RtlNtStatusToDosError(Status
));
1101 DeleteAce(PACL pAcl
,
1106 Status
= RtlDeleteAce(pAcl
,
1108 if (!NT_SUCCESS(Status
))
1110 SetLastError(RtlNtStatusToDosError(Status
));
1122 FindFirstFreeAce(PACL pAcl
,
1125 return RtlFirstFreeAce(pAcl
,
1141 Status
= RtlGetAce(pAcl
,
1144 if (!NT_SUCCESS(Status
))
1146 SetLastError(RtlNtStatusToDosError(Status
));
1158 GetAclInformation(PACL pAcl
,
1159 LPVOID pAclInformation
,
1160 DWORD nAclInformationLength
,
1161 ACL_INFORMATION_CLASS dwAclInformationClass
)
1165 Status
= RtlQueryInformationAcl(pAcl
,
1167 nAclInformationLength
,
1168 dwAclInformationClass
);
1169 if (!NT_SUCCESS(Status
))
1171 SetLastError(RtlNtStatusToDosError(Status
));
1183 IsValidAcl(PACL pAcl
)
1185 return RtlValidAcl (pAcl
);
1192 AllocateLocallyUniqueId(PLUID Luid
)
1196 Status
= NtAllocateLocallyUniqueId (Luid
);
1197 if (!NT_SUCCESS (Status
))
1199 SetLastError(RtlNtStatusToDosError(Status
));
1206 /**********************************************************************
1207 * LookupPrivilegeDisplayNameA EXPORTED
1213 LookupPrivilegeDisplayNameA(LPCSTR lpSystemName
,
1215 LPSTR lpDisplayName
,
1216 LPDWORD cbDisplayName
,
1217 LPDWORD lpLanguageId
)
1219 FIXME("%s() not implemented!\n", __FUNCTION__
);
1220 SetLastError (ERROR_CALL_NOT_IMPLEMENTED
);
1225 /**********************************************************************
1226 * LookupPrivilegeDisplayNameW EXPORTED
1232 LookupPrivilegeDisplayNameW(LPCWSTR lpSystemName
,
1234 LPWSTR lpDisplayName
,
1235 LPDWORD cbDisplayName
,
1236 LPDWORD lpLanguageId
)
1238 FIXME("%s() not implemented!\n", __FUNCTION__
);
1239 SetLastError (ERROR_CALL_NOT_IMPLEMENTED
);
1243 /**********************************************************************
1244 * LookupPrivilegeNameA EXPORTED
1250 LookupPrivilegeNameA(LPCSTR lpSystemName
,
1255 UNICODE_STRING lpSystemNameW
;
1259 TRACE("%s %p %p %p\n", debugstr_a(lpSystemName
), lpLuid
, lpName
, cchName
);
1261 RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW
, lpSystemName
);
1262 ret
= LookupPrivilegeNameW(lpSystemNameW
.Buffer
, lpLuid
, NULL
, &wLen
);
1263 if (!ret
&& GetLastError() == ERROR_INSUFFICIENT_BUFFER
)
1265 LPWSTR lpNameW
= HeapAlloc(GetProcessHeap(), 0, wLen
* sizeof(WCHAR
));
1267 ret
= LookupPrivilegeNameW(lpSystemNameW
.Buffer
, lpLuid
, lpNameW
,
1271 /* Windows crashes if cchName is NULL, so will I */
1272 unsigned int len
= WideCharToMultiByte(CP_ACP
, 0, lpNameW
, -1, lpName
,
1273 *cchName
, NULL
, NULL
);
1277 /* WideCharToMultiByte failed */
1280 else if (len
> *cchName
)
1283 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
1288 /* WideCharToMultiByte succeeded, output length needs to be
1289 * length not including NULL terminator
1294 HeapFree(GetProcessHeap(), 0, lpNameW
);
1296 RtlFreeUnicodeString(&lpSystemNameW
);
1300 /******************************************************************************
1301 * GetFileSecurityA [ADVAPI32.@]
1303 * Obtains Specified information about the security of a file or directory.
1306 * lpFileName [I] Name of the file to get info for
1307 * RequestedInformation [I] SE_ flags from "winnt.h"
1308 * pSecurityDescriptor [O] Destination for security information
1309 * nLength [I] Length of pSecurityDescriptor
1310 * lpnLengthNeeded [O] Destination for length of returned security information
1313 * Success: TRUE. pSecurityDescriptor contains the requested information.
1314 * Failure: FALSE. lpnLengthNeeded contains the required space to return the info.
1317 * The information returned is constrained by the callers access rights and
1324 GetFileSecurityA(LPCSTR lpFileName
,
1325 SECURITY_INFORMATION RequestedInformation
,
1326 PSECURITY_DESCRIPTOR pSecurityDescriptor
,
1328 LPDWORD lpnLengthNeeded
)
1330 UNICODE_STRING FileName
;
1333 if (!RtlCreateUnicodeStringFromAsciiz(&FileName
, lpFileName
))
1335 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
1339 bResult
= GetFileSecurityW(FileName
.Buffer
,
1340 RequestedInformation
,
1341 pSecurityDescriptor
,
1345 RtlFreeUnicodeString(&FileName
);
1355 GetFileSecurityW(LPCWSTR lpFileName
,
1356 SECURITY_INFORMATION RequestedInformation
,
1357 PSECURITY_DESCRIPTOR pSecurityDescriptor
,
1359 LPDWORD lpnLengthNeeded
)
1361 OBJECT_ATTRIBUTES ObjectAttributes
;
1362 IO_STATUS_BLOCK StatusBlock
;
1363 UNICODE_STRING FileName
;
1364 ULONG AccessMask
= 0;
1368 TRACE("GetFileSecurityW() called\n");
1370 QuerySecurityAccessMask(RequestedInformation
, &AccessMask
);
1372 if (!RtlDosPathNameToNtPathName_U(lpFileName
,
1377 ERR("Invalid path\n");
1378 SetLastError(ERROR_INVALID_NAME
);
1382 InitializeObjectAttributes(&ObjectAttributes
,
1384 OBJ_CASE_INSENSITIVE
,
1388 Status
= NtOpenFile(&FileHandle
,
1392 FILE_SHARE_READ
| FILE_SHARE_WRITE
| FILE_SHARE_DELETE
,
1395 RtlFreeHeap(RtlGetProcessHeap(),
1399 if (!NT_SUCCESS(Status
))
1401 ERR("NtOpenFile() failed (Status %lx)\n", Status
);
1402 SetLastError(RtlNtStatusToDosError(Status
));
1406 Status
= NtQuerySecurityObject(FileHandle
,
1407 RequestedInformation
,
1408 pSecurityDescriptor
,
1411 NtClose(FileHandle
);
1412 if (!NT_SUCCESS(Status
))
1414 ERR("NtQuerySecurityObject() failed (Status %lx)\n", Status
);
1415 SetLastError(RtlNtStatusToDosError(Status
));
1422 /******************************************************************************
1423 * SetFileSecurityA [ADVAPI32.@]
1424 * Sets the security of a file or directory
1430 SetFileSecurityA(LPCSTR lpFileName
,
1431 SECURITY_INFORMATION SecurityInformation
,
1432 PSECURITY_DESCRIPTOR pSecurityDescriptor
)
1434 UNICODE_STRING FileName
;
1437 if (!RtlCreateUnicodeStringFromAsciiz(&FileName
, lpFileName
))
1439 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
1443 bResult
= SetFileSecurityW(FileName
.Buffer
,
1444 SecurityInformation
,
1445 pSecurityDescriptor
);
1447 RtlFreeUnicodeString(&FileName
);
1452 /******************************************************************************
1453 * SetFileSecurityW [ADVAPI32.@]
1454 * Sets the security of a file or directory
1460 SetFileSecurityW(LPCWSTR lpFileName
,
1461 SECURITY_INFORMATION SecurityInformation
,
1462 PSECURITY_DESCRIPTOR pSecurityDescriptor
)
1464 OBJECT_ATTRIBUTES ObjectAttributes
;
1465 IO_STATUS_BLOCK StatusBlock
;
1466 UNICODE_STRING FileName
;
1467 ULONG AccessMask
= 0;
1471 TRACE("SetFileSecurityW() called\n");
1473 SetSecurityAccessMask(SecurityInformation
, &AccessMask
);
1475 if (!RtlDosPathNameToNtPathName_U(lpFileName
,
1480 ERR("Invalid path\n");
1481 SetLastError(ERROR_INVALID_NAME
);
1485 InitializeObjectAttributes(&ObjectAttributes
,
1487 OBJ_CASE_INSENSITIVE
,
1491 Status
= NtOpenFile(&FileHandle
,
1495 FILE_SHARE_READ
| FILE_SHARE_WRITE
| FILE_SHARE_DELETE
,
1498 RtlFreeHeap(RtlGetProcessHeap(),
1502 if (!NT_SUCCESS(Status
))
1504 ERR("NtOpenFile() failed (Status %lx)\n", Status
);
1505 SetLastError(RtlNtStatusToDosError(Status
));
1509 Status
= NtSetSecurityObject(FileHandle
,
1510 SecurityInformation
,
1511 pSecurityDescriptor
);
1512 NtClose(FileHandle
);
1514 if (!NT_SUCCESS(Status
))
1516 ERR("NtSetSecurityObject() failed (Status %lx)\n", Status
);
1517 SetLastError(RtlNtStatusToDosError(Status
));
1524 /******************************************************************************
1525 * QueryWindows31FilesMigration [ADVAPI32.@]
1531 QueryWindows31FilesMigration( DWORD x1
)
1533 FIXME("(%d):stub\n",x1
);
1537 /******************************************************************************
1538 * SynchronizeWindows31FilesAndWindowsNTRegistry [ADVAPI32.@]
1547 SynchronizeWindows31FilesAndWindowsNTRegistry( DWORD x1
, DWORD x2
, DWORD x3
,
1550 FIXME("(0x%08x,0x%08x,0x%08x,0x%08x):stub\n",x1
,x2
,x3
,x4
);
1562 HANDLE Token
= NULL
;
1564 Status
= NtSetInformationThread(NtCurrentThread(),
1565 ThreadImpersonationToken
,
1568 if (!NT_SUCCESS(Status
))
1570 SetLastError(RtlNtStatusToDosError(Status
));
1582 ImpersonateSelf(SECURITY_IMPERSONATION_LEVEL ImpersonationLevel
)
1586 Status
= RtlImpersonateSelf(ImpersonationLevel
);
1587 if (!NT_SUCCESS(Status
))
1589 SetLastError(RtlNtStatusToDosError(Status
));
1601 AccessCheck(IN PSECURITY_DESCRIPTOR pSecurityDescriptor
,
1602 IN HANDLE ClientToken
,
1603 IN DWORD DesiredAccess
,
1604 IN PGENERIC_MAPPING GenericMapping
,
1605 OUT PPRIVILEGE_SET PrivilegeSet OPTIONAL
,
1606 IN OUT LPDWORD PrivilegeSetLength
,
1607 OUT LPDWORD GrantedAccess
,
1608 OUT LPBOOL AccessStatus
)
1611 NTSTATUS NtAccessStatus
;
1613 /* Do the access check */
1614 Status
= NtAccessCheck(pSecurityDescriptor
,
1619 (PULONG
)PrivilegeSetLength
,
1620 (PACCESS_MASK
)GrantedAccess
,
1623 /* See if the access check operation succeeded */
1624 if (!NT_SUCCESS(Status
))
1627 SetLastError(RtlNtStatusToDosError(Status
));
1631 /* Now check the access status */
1632 if (!NT_SUCCESS(NtAccessStatus
))
1635 SetLastError(RtlNtStatusToDosError(NtAccessStatus
));
1636 *AccessStatus
= FALSE
;
1640 /* Access granted */
1641 *AccessStatus
= TRUE
;
1644 /* Check succeeded */
1651 BOOL WINAPI
AccessCheckByType(
1652 PSECURITY_DESCRIPTOR pSecurityDescriptor
,
1653 PSID PrincipalSelfSid
,
1655 DWORD DesiredAccess
,
1656 POBJECT_TYPE_LIST ObjectTypeList
,
1657 DWORD ObjectTypeListLength
,
1658 PGENERIC_MAPPING GenericMapping
,
1659 PPRIVILEGE_SET PrivilegeSet
,
1660 LPDWORD PrivilegeSetLength
,
1661 LPDWORD GrantedAccess
,
1662 LPBOOL AccessStatus
)
1666 *AccessStatus
= TRUE
;
1668 return !*AccessStatus
;
1676 SetKernelObjectSecurity(HANDLE Handle
,
1677 SECURITY_INFORMATION SecurityInformation
,
1678 PSECURITY_DESCRIPTOR SecurityDescriptor
)
1682 Status
= NtSetSecurityObject(Handle
,
1683 SecurityInformation
,
1684 SecurityDescriptor
);
1685 if (!NT_SUCCESS(Status
))
1687 SetLastError(RtlNtStatusToDosError(Status
));
1699 AddAuditAccessAce(PACL pAcl
,
1700 DWORD dwAceRevision
,
1708 Status
= RtlAddAuditAccessAce(pAcl
,
1714 if (!NT_SUCCESS(Status
))
1716 SetLastError(RtlNtStatusToDosError(Status
));
1727 AddAuditAccessAceEx(PACL pAcl
,
1728 DWORD dwAceRevision
,
1737 Status
= RtlAddAuditAccessAceEx(pAcl
,
1744 if (!NT_SUCCESS(Status
))
1746 SetLastError(RtlNtStatusToDosError(Status
));
1753 /******************************************************************************
1754 * LookupAccountNameA [ADVAPI32.@]
1760 LookupAccountNameA(LPCSTR SystemName
,
1764 LPSTR ReferencedDomainName
,
1765 LPDWORD hReferencedDomainNameLength
,
1766 PSID_NAME_USE SidNameUse
)
1769 UNICODE_STRING lpSystemW
;
1770 UNICODE_STRING lpAccountW
;
1771 LPWSTR lpReferencedDomainNameW
= NULL
;
1773 RtlCreateUnicodeStringFromAsciiz(&lpSystemW
, SystemName
);
1774 RtlCreateUnicodeStringFromAsciiz(&lpAccountW
, AccountName
);
1776 if (ReferencedDomainName
)
1777 lpReferencedDomainNameW
= HeapAlloc(GetProcessHeap(),
1779 *hReferencedDomainNameLength
* sizeof(WCHAR
));
1781 ret
= LookupAccountNameW(lpSystemW
.Buffer
,
1785 lpReferencedDomainNameW
,
1786 hReferencedDomainNameLength
,
1789 if (ret
&& lpReferencedDomainNameW
)
1791 WideCharToMultiByte(CP_ACP
,
1793 lpReferencedDomainNameW
,
1794 *hReferencedDomainNameLength
+ 1,
1795 ReferencedDomainName
,
1796 *hReferencedDomainNameLength
+ 1,
1801 RtlFreeUnicodeString(&lpSystemW
);
1802 RtlFreeUnicodeString(&lpAccountW
);
1803 HeapFree(GetProcessHeap(), 0, lpReferencedDomainNameW
);
1808 /**********************************************************************
1809 * PrivilegeCheck EXPORTED
1814 PrivilegeCheck(HANDLE ClientToken
,
1815 PPRIVILEGE_SET RequiredPrivileges
,
1821 Status
= NtPrivilegeCheck(ClientToken
,
1824 if (!NT_SUCCESS(Status
))
1826 SetLastError(RtlNtStatusToDosError(Status
));
1830 *pfResult
= (BOOL
)Result
;
1835 /******************************************************************************
1836 * GetSecurityInfoExW EXPORTED
1840 GetSecurityInfoExA(HANDLE hObject
,
1841 SE_OBJECT_TYPE ObjectType
,
1842 SECURITY_INFORMATION SecurityInfo
,
1845 PACTRL_ACCESSA
*ppAccessList
,
1846 PACTRL_AUDITA
*ppAuditList
,
1850 FIXME("%s() not implemented!\n", __FUNCTION__
);
1851 return ERROR_BAD_PROVIDER
;
1855 /******************************************************************************
1856 * GetSecurityInfoExW EXPORTED
1860 GetSecurityInfoExW(HANDLE hObject
,
1861 SE_OBJECT_TYPE ObjectType
,
1862 SECURITY_INFORMATION SecurityInfo
,
1865 PACTRL_ACCESSW
*ppAccessList
,
1866 PACTRL_AUDITW
*ppAuditList
,
1870 FIXME("%s() not implemented!\n", __FUNCTION__
);
1871 return ERROR_BAD_PROVIDER
;
1874 /******************************************************************************
1875 * BuildExplicitAccessWithNameA [ADVAPI32.@]
1878 BuildExplicitAccessWithNameA(PEXPLICIT_ACCESSA pExplicitAccess
,
1880 DWORD AccessPermissions
,
1881 ACCESS_MODE AccessMode
,
1884 pExplicitAccess
->grfAccessPermissions
= AccessPermissions
;
1885 pExplicitAccess
->grfAccessMode
= AccessMode
;
1886 pExplicitAccess
->grfInheritance
= Inheritance
;
1888 pExplicitAccess
->Trustee
.pMultipleTrustee
= NULL
;
1889 pExplicitAccess
->Trustee
.MultipleTrusteeOperation
= NO_MULTIPLE_TRUSTEE
;
1890 pExplicitAccess
->Trustee
.TrusteeForm
= TRUSTEE_IS_NAME
;
1891 pExplicitAccess
->Trustee
.TrusteeType
= TRUSTEE_IS_UNKNOWN
;
1892 pExplicitAccess
->Trustee
.ptstrName
= pTrusteeName
;
1896 /******************************************************************************
1897 * BuildExplicitAccessWithNameW [ADVAPI32.@]
1900 BuildExplicitAccessWithNameW(PEXPLICIT_ACCESSW pExplicitAccess
,
1901 LPWSTR pTrusteeName
,
1902 DWORD AccessPermissions
,
1903 ACCESS_MODE AccessMode
,
1906 pExplicitAccess
->grfAccessPermissions
= AccessPermissions
;
1907 pExplicitAccess
->grfAccessMode
= AccessMode
;
1908 pExplicitAccess
->grfInheritance
= Inheritance
;
1910 pExplicitAccess
->Trustee
.pMultipleTrustee
= NULL
;
1911 pExplicitAccess
->Trustee
.MultipleTrusteeOperation
= NO_MULTIPLE_TRUSTEE
;
1912 pExplicitAccess
->Trustee
.TrusteeForm
= TRUSTEE_IS_NAME
;
1913 pExplicitAccess
->Trustee
.TrusteeType
= TRUSTEE_IS_UNKNOWN
;
1914 pExplicitAccess
->Trustee
.ptstrName
= pTrusteeName
;
1917 /******************************************************************************
1918 * BuildTrusteeWithObjectsAndNameA [ADVAPI32.@]
1920 VOID WINAPI
BuildTrusteeWithObjectsAndNameA( PTRUSTEEA pTrustee
, POBJECTS_AND_NAME_A pObjName
,
1921 SE_OBJECT_TYPE ObjectType
, LPSTR ObjectTypeName
,
1922 LPSTR InheritedObjectTypeName
, LPSTR Name
)
1924 DWORD ObjectsPresent
= 0;
1926 TRACE("%p %p 0x%08x %p %p %s\n", pTrustee
, pObjName
,
1927 ObjectType
, ObjectTypeName
, InheritedObjectTypeName
, debugstr_a(Name
));
1929 /* Fill the OBJECTS_AND_NAME structure */
1930 pObjName
->ObjectType
= ObjectType
;
1931 if (ObjectTypeName
!= NULL
)
1933 ObjectsPresent
|= ACE_OBJECT_TYPE_PRESENT
;
1936 pObjName
->InheritedObjectTypeName
= InheritedObjectTypeName
;
1937 if (InheritedObjectTypeName
!= NULL
)
1939 ObjectsPresent
|= ACE_INHERITED_OBJECT_TYPE_PRESENT
;
1942 pObjName
->ObjectsPresent
= ObjectsPresent
;
1943 pObjName
->ptstrName
= Name
;
1945 /* Fill the TRUSTEE structure */
1946 pTrustee
->pMultipleTrustee
= NULL
;
1947 pTrustee
->MultipleTrusteeOperation
= NO_MULTIPLE_TRUSTEE
;
1948 pTrustee
->TrusteeForm
= TRUSTEE_IS_OBJECTS_AND_NAME
;
1949 pTrustee
->TrusteeType
= TRUSTEE_IS_UNKNOWN
;
1950 pTrustee
->ptstrName
= (LPSTR
)pObjName
;
1953 /******************************************************************************
1954 * BuildTrusteeWithObjectsAndNameW [ADVAPI32.@]
1956 VOID WINAPI
BuildTrusteeWithObjectsAndNameW( PTRUSTEEW pTrustee
, POBJECTS_AND_NAME_W pObjName
,
1957 SE_OBJECT_TYPE ObjectType
, LPWSTR ObjectTypeName
,
1958 LPWSTR InheritedObjectTypeName
, LPWSTR Name
)
1960 DWORD ObjectsPresent
= 0;
1962 TRACE("%p %p 0x%08x %p %p %s\n", pTrustee
, pObjName
,
1963 ObjectType
, ObjectTypeName
, InheritedObjectTypeName
, debugstr_w(Name
));
1965 /* Fill the OBJECTS_AND_NAME structure */
1966 pObjName
->ObjectType
= ObjectType
;
1967 if (ObjectTypeName
!= NULL
)
1969 ObjectsPresent
|= ACE_OBJECT_TYPE_PRESENT
;
1972 pObjName
->InheritedObjectTypeName
= InheritedObjectTypeName
;
1973 if (InheritedObjectTypeName
!= NULL
)
1975 ObjectsPresent
|= ACE_INHERITED_OBJECT_TYPE_PRESENT
;
1978 pObjName
->ObjectsPresent
= ObjectsPresent
;
1979 pObjName
->ptstrName
= Name
;
1981 /* Fill the TRUSTEE structure */
1982 pTrustee
->pMultipleTrustee
= NULL
;
1983 pTrustee
->MultipleTrusteeOperation
= NO_MULTIPLE_TRUSTEE
;
1984 pTrustee
->TrusteeForm
= TRUSTEE_IS_OBJECTS_AND_NAME
;
1985 pTrustee
->TrusteeType
= TRUSTEE_IS_UNKNOWN
;
1986 pTrustee
->ptstrName
= (LPWSTR
)pObjName
;
1989 /******************************************************************************
1990 * BuildTrusteeWithObjectsAndSidA [ADVAPI32.@]
1993 BuildTrusteeWithObjectsAndSidA(PTRUSTEEA pTrustee
,
1994 POBJECTS_AND_SID pObjSid
,
1996 GUID
*pInheritedObjectGuid
,
1999 DWORD ObjectsPresent
= 0;
2001 TRACE("%p %p %p %p %p\n", pTrustee
, pObjSid
, pObjectGuid
, pInheritedObjectGuid
, pSid
);
2003 /* Fill the OBJECTS_AND_SID structure */
2004 if (pObjectGuid
!= NULL
)
2006 pObjSid
->ObjectTypeGuid
= *pObjectGuid
;
2007 ObjectsPresent
|= ACE_OBJECT_TYPE_PRESENT
;
2011 ZeroMemory(&pObjSid
->ObjectTypeGuid
,
2015 if (pInheritedObjectGuid
!= NULL
)
2017 pObjSid
->InheritedObjectTypeGuid
= *pInheritedObjectGuid
;
2018 ObjectsPresent
|= ACE_INHERITED_OBJECT_TYPE_PRESENT
;
2022 ZeroMemory(&pObjSid
->InheritedObjectTypeGuid
,
2026 pObjSid
->ObjectsPresent
= ObjectsPresent
;
2027 pObjSid
->pSid
= pSid
;
2029 /* Fill the TRUSTEE structure */
2030 pTrustee
->pMultipleTrustee
= NULL
;
2031 pTrustee
->MultipleTrusteeOperation
= NO_MULTIPLE_TRUSTEE
;
2032 pTrustee
->TrusteeForm
= TRUSTEE_IS_OBJECTS_AND_SID
;
2033 pTrustee
->TrusteeType
= TRUSTEE_IS_UNKNOWN
;
2034 pTrustee
->ptstrName
= (LPSTR
) pObjSid
;
2038 /******************************************************************************
2039 * BuildTrusteeWithObjectsAndSidW [ADVAPI32.@]
2042 BuildTrusteeWithObjectsAndSidW(PTRUSTEEW pTrustee
,
2043 POBJECTS_AND_SID pObjSid
,
2045 GUID
*pInheritedObjectGuid
,
2048 DWORD ObjectsPresent
= 0;
2050 TRACE("%p %p %p %p %p\n", pTrustee
, pObjSid
, pObjectGuid
, pInheritedObjectGuid
, pSid
);
2052 /* Fill the OBJECTS_AND_SID structure */
2053 if (pObjectGuid
!= NULL
)
2055 pObjSid
->ObjectTypeGuid
= *pObjectGuid
;
2056 ObjectsPresent
|= ACE_OBJECT_TYPE_PRESENT
;
2060 ZeroMemory(&pObjSid
->ObjectTypeGuid
,
2064 if (pInheritedObjectGuid
!= NULL
)
2066 pObjSid
->InheritedObjectTypeGuid
= *pInheritedObjectGuid
;
2067 ObjectsPresent
|= ACE_INHERITED_OBJECT_TYPE_PRESENT
;
2071 ZeroMemory(&pObjSid
->InheritedObjectTypeGuid
,
2075 pObjSid
->ObjectsPresent
= ObjectsPresent
;
2076 pObjSid
->pSid
= pSid
;
2078 /* Fill the TRUSTEE structure */
2079 pTrustee
->pMultipleTrustee
= NULL
;
2080 pTrustee
->MultipleTrusteeOperation
= NO_MULTIPLE_TRUSTEE
;
2081 pTrustee
->TrusteeForm
= TRUSTEE_IS_OBJECTS_AND_SID
;
2082 pTrustee
->TrusteeType
= TRUSTEE_IS_UNKNOWN
;
2083 pTrustee
->ptstrName
= (LPWSTR
) pObjSid
;
2086 /******************************************************************************
2087 * BuildTrusteeWithSidA [ADVAPI32.@]
2090 BuildTrusteeWithSidA(PTRUSTEE_A pTrustee
,
2093 TRACE("%p %p\n", pTrustee
, pSid
);
2095 pTrustee
->pMultipleTrustee
= NULL
;
2096 pTrustee
->MultipleTrusteeOperation
= NO_MULTIPLE_TRUSTEE
;
2097 pTrustee
->TrusteeForm
= TRUSTEE_IS_SID
;
2098 pTrustee
->TrusteeType
= TRUSTEE_IS_UNKNOWN
;
2099 pTrustee
->ptstrName
= (LPSTR
) pSid
;
2103 /******************************************************************************
2104 * BuildTrusteeWithSidW [ADVAPI32.@]
2107 BuildTrusteeWithSidW(PTRUSTEE_W pTrustee
,
2110 TRACE("%p %p\n", pTrustee
, pSid
);
2112 pTrustee
->pMultipleTrustee
= NULL
;
2113 pTrustee
->MultipleTrusteeOperation
= NO_MULTIPLE_TRUSTEE
;
2114 pTrustee
->TrusteeForm
= TRUSTEE_IS_SID
;
2115 pTrustee
->TrusteeType
= TRUSTEE_IS_UNKNOWN
;
2116 pTrustee
->ptstrName
= (LPWSTR
) pSid
;
2119 /******************************************************************************
2120 * BuildTrusteeWithNameA [ADVAPI32.@]
2123 BuildTrusteeWithNameA(PTRUSTEE_A pTrustee
,
2126 TRACE("%p %s\n", pTrustee
, name
);
2128 pTrustee
->pMultipleTrustee
= NULL
;
2129 pTrustee
->MultipleTrusteeOperation
= NO_MULTIPLE_TRUSTEE
;
2130 pTrustee
->TrusteeForm
= TRUSTEE_IS_NAME
;
2131 pTrustee
->TrusteeType
= TRUSTEE_IS_UNKNOWN
;
2132 pTrustee
->ptstrName
= name
;
2135 /******************************************************************************
2136 * BuildTrusteeWithNameW [ADVAPI32.@]
2139 BuildTrusteeWithNameW(PTRUSTEE_W pTrustee
,
2142 TRACE("%p %s\n", pTrustee
, name
);
2144 pTrustee
->pMultipleTrustee
= NULL
;
2145 pTrustee
->MultipleTrusteeOperation
= NO_MULTIPLE_TRUSTEE
;
2146 pTrustee
->TrusteeForm
= TRUSTEE_IS_NAME
;
2147 pTrustee
->TrusteeType
= TRUSTEE_IS_UNKNOWN
;
2148 pTrustee
->ptstrName
= name
;
2151 /******************************************************************************
2152 * GetTrusteeFormW [ADVAPI32.@]
2155 GetTrusteeFormA(PTRUSTEE_A pTrustee
)
2157 return pTrustee
->TrusteeForm
;
2161 /******************************************************************************
2162 * GetTrusteeFormW [ADVAPI32.@]
2165 GetTrusteeFormW(PTRUSTEE_W pTrustee
)
2167 return pTrustee
->TrusteeForm
;
2170 /******************************************************************************
2171 * GetTrusteeNameA [ADVAPI32.@]
2174 GetTrusteeNameA(PTRUSTEE_A pTrustee
)
2176 return pTrustee
->ptstrName
;
2180 /******************************************************************************
2181 * GetTrusteeNameW [ADVAPI32.@]
2184 GetTrusteeNameW(PTRUSTEE_W pTrustee
)
2186 return pTrustee
->ptstrName
;
2189 /******************************************************************************
2190 * GetTrusteeTypeA [ADVAPI32.@]
2193 GetTrusteeTypeA(PTRUSTEE_A pTrustee
)
2195 return pTrustee
->TrusteeType
;
2198 /******************************************************************************
2199 * GetTrusteeTypeW [ADVAPI32.@]
2202 GetTrusteeTypeW(PTRUSTEE_W pTrustee
)
2204 return pTrustee
->TrusteeType
;
2212 SetAclInformation(PACL pAcl
,
2213 LPVOID pAclInformation
,
2214 DWORD nAclInformationLength
,
2215 ACL_INFORMATION_CLASS dwAclInformationClass
)
2219 Status
= RtlSetInformationAcl(pAcl
,
2221 nAclInformationLength
,
2222 dwAclInformationClass
);
2223 if (!NT_SUCCESS(Status
))
2225 SetLastError(RtlNtStatusToDosError(Status
));
2232 /**********************************************************************
2233 * SetNamedSecurityInfoA EXPORTED
2239 SetNamedSecurityInfoA(LPSTR pObjectName
,
2240 SE_OBJECT_TYPE ObjectType
,
2241 SECURITY_INFORMATION SecurityInfo
,
2247 UNICODE_STRING ObjectName
;
2250 if (!RtlCreateUnicodeStringFromAsciiz(&ObjectName
, pObjectName
))
2252 return ERROR_NOT_ENOUGH_MEMORY
;
2255 Ret
= SetNamedSecurityInfoW(ObjectName
.Buffer
,
2263 RtlFreeUnicodeString(&ObjectName
);
2273 AreAllAccessesGranted(DWORD GrantedAccess
,
2274 DWORD DesiredAccess
)
2276 return (BOOL
)RtlAreAllAccessesGranted(GrantedAccess
,
2285 AreAnyAccessesGranted(DWORD GrantedAccess
,
2286 DWORD DesiredAccess
)
2288 return (BOOL
)RtlAreAnyAccessesGranted(GrantedAccess
,
2292 /******************************************************************************
2293 * ParseAclStringFlags
2295 static DWORD
ParseAclStringFlags(LPCWSTR
* StringAcl
)
2298 LPCWSTR szAcl
= *StringAcl
;
2300 while (*szAcl
!= '(')
2304 flags
|= SE_DACL_PROTECTED
;
2306 else if (*szAcl
== 'A')
2310 flags
|= SE_DACL_AUTO_INHERIT_REQ
;
2311 else if (*szAcl
== 'I')
2312 flags
|= SE_DACL_AUTO_INHERITED
;
2321 /******************************************************************************
2322 * ParseAceStringType
2324 static const ACEFLAG AceType
[] =
2326 { SDDL_ALARM
, SYSTEM_ALARM_ACE_TYPE
},
2327 { SDDL_AUDIT
, SYSTEM_AUDIT_ACE_TYPE
},
2328 { SDDL_ACCESS_ALLOWED
, ACCESS_ALLOWED_ACE_TYPE
},
2329 { SDDL_ACCESS_DENIED
, ACCESS_DENIED_ACE_TYPE
},
2331 { SDDL_OBJECT_ACCESS_ALLOWED, ACCESS_ALLOWED_OBJECT_ACE_TYPE },
2332 { SDDL_OBJECT_ACCESS_DENIED, ACCESS_DENIED_OBJECT_ACE_TYPE },
2333 { SDDL_OBJECT_ALARM, SYSTEM_ALARM_OBJECT_ACE_TYPE },
2334 { SDDL_OBJECT_AUDIT, SYSTEM_AUDIT_OBJECT_ACE_TYPE },
2339 static BYTE
ParseAceStringType(LPCWSTR
* StringAcl
)
2342 LPCWSTR szAcl
= *StringAcl
;
2343 const ACEFLAG
*lpaf
= AceType
;
2345 while (lpaf
->wstr
&&
2346 (len
= strlenW(lpaf
->wstr
)) &&
2347 strncmpW(lpaf
->wstr
, szAcl
, len
))
2358 /******************************************************************************
2359 * ParseAceStringFlags
2361 static const ACEFLAG AceFlags
[] =
2363 { SDDL_CONTAINER_INHERIT
, CONTAINER_INHERIT_ACE
},
2364 { SDDL_AUDIT_FAILURE
, FAILED_ACCESS_ACE_FLAG
},
2365 { SDDL_INHERITED
, INHERITED_ACE
},
2366 { SDDL_INHERIT_ONLY
, INHERIT_ONLY_ACE
},
2367 { SDDL_NO_PROPAGATE
, NO_PROPAGATE_INHERIT_ACE
},
2368 { SDDL_OBJECT_INHERIT
, OBJECT_INHERIT_ACE
},
2369 { SDDL_AUDIT_SUCCESS
, SUCCESSFUL_ACCESS_ACE_FLAG
},
2373 static BYTE
ParseAceStringFlags(LPCWSTR
* StringAcl
)
2377 LPCWSTR szAcl
= *StringAcl
;
2379 while (*szAcl
!= ';')
2381 const ACEFLAG
*lpaf
= AceFlags
;
2383 while (lpaf
->wstr
&&
2384 (len
= strlenW(lpaf
->wstr
)) &&
2385 strncmpW(lpaf
->wstr
, szAcl
, len
))
2391 flags
|= lpaf
->value
;
2400 /******************************************************************************
2401 * ParseAceStringRights
2403 static DWORD
ParseAceStringRights(LPCWSTR
* StringAcl
)
2407 LPCWSTR szAcl
= *StringAcl
;
2409 if ((*szAcl
== '0') && (*(szAcl
+ 1) == 'x'))
2413 while (*p
&& *p
!= ';')
2416 if (p
- szAcl
<= 10 /* 8 hex digits + "0x" */ )
2418 rights
= strtoulW(szAcl
, NULL
, 16);
2422 WARN("Invalid rights string format: %s\n", debugstr_wn(szAcl
, p
- szAcl
));
2426 while (*szAcl
!= ';')
2428 const ACEFLAG
*lpaf
= AceRights
;
2430 while (lpaf
->wstr
&&
2431 (len
= strlenW(lpaf
->wstr
)) &&
2432 strncmpW(lpaf
->wstr
, szAcl
, len
))
2440 rights
|= lpaf
->value
;
2450 /******************************************************************************
2451 * ParseStringAclToAcl
2453 * dacl_flags(string_ace1)(string_ace2)... (string_acen)
2456 ParseStringAclToAcl(LPCWSTR StringAcl
,
2463 DWORD length
= sizeof(ACL
);
2466 PACCESS_ALLOWED_ACE pAce
= NULL
; /* pointer to current ACE */
2468 TRACE("%s\n", debugstr_w(StringAcl
));
2473 if (pAcl
) /* pAce is only useful if we're setting values */
2474 pAce
= (PACCESS_ALLOWED_ACE
) (pAcl
+ 1);
2476 /* Parse ACL flags */
2477 *lpdwFlags
= ParseAclStringFlags(&StringAcl
);
2480 while (*StringAcl
== '(')
2484 /* Parse ACE type */
2485 val
= ParseAceStringType(&StringAcl
);
2487 pAce
->Header
.AceType
= (BYTE
) val
;
2488 if (*StringAcl
!= ';')
2492 /* Parse ACE flags */
2493 val
= ParseAceStringFlags(&StringAcl
);
2495 pAce
->Header
.AceFlags
= (BYTE
) val
;
2496 if (*StringAcl
!= ';')
2500 /* Parse ACE rights */
2501 val
= ParseAceStringRights(&StringAcl
);
2504 if (*StringAcl
!= ';')
2508 /* Parse ACE object guid */
2509 if (*StringAcl
!= ';')
2511 FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
2516 /* Parse ACE inherit object guid */
2517 if (*StringAcl
!= ';')
2519 FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
2524 /* Parse ACE account sid */
2525 if (ParseStringSidToSid(StringAcl
, pAce
? &pAce
->SidStart
: NULL
, &sidlen
))
2527 while (*StringAcl
&& *StringAcl
!= ')')
2531 if (*StringAcl
!= ')')
2535 acesize
= sizeof(ACCESS_ALLOWED_ACE
) - sizeof(DWORD
) + sidlen
;
2539 pAce
->Header
.AceSize
= acesize
;
2540 pAce
= (PACCESS_ALLOWED_ACE
)((LPBYTE
)pAce
+ acesize
);
2547 if (length
> 0xffff)
2549 ERR("ACL too large\n");
2555 pAcl
->AclRevision
= ACL_REVISION
;
2557 pAcl
->AclSize
= length
;
2558 pAcl
->AceCount
= acecount
++;
2564 SetLastError(ERROR_INVALID_ACL
);
2565 WARN("Invalid ACE string format\n");
2570 /******************************************************************************
2571 * ParseStringSecurityDescriptorToSecurityDescriptor
2574 ParseStringSecurityDescriptorToSecurityDescriptor(LPCWSTR StringSecurityDescriptor
,
2575 SECURITY_DESCRIPTOR_RELATIVE
* SecurityDescriptor
,
2580 WCHAR tok
[MAX_PATH
];
2582 LPBYTE lpNext
= NULL
;
2585 *cBytes
= sizeof(SECURITY_DESCRIPTOR
);
2587 if (SecurityDescriptor
)
2588 lpNext
= (LPBYTE
)(SecurityDescriptor
+ 1);
2590 while (*StringSecurityDescriptor
)
2592 toktype
= *StringSecurityDescriptor
;
2594 /* Expect char identifier followed by ':' */
2595 StringSecurityDescriptor
++;
2596 if (*StringSecurityDescriptor
!= ':')
2598 SetLastError(ERROR_INVALID_PARAMETER
);
2601 StringSecurityDescriptor
++;
2604 lptoken
= StringSecurityDescriptor
;
2605 while (*lptoken
&& *lptoken
!= ':')
2611 len
= lptoken
- StringSecurityDescriptor
;
2612 memcpy( tok
, StringSecurityDescriptor
, len
* sizeof(WCHAR
) );
2621 if (!ParseStringSidToSid(tok
, lpNext
, &bytes
))
2624 if (SecurityDescriptor
)
2626 SecurityDescriptor
->Owner
= lpNext
- (LPBYTE
)SecurityDescriptor
;
2627 lpNext
+= bytes
; /* Advance to next token */
2639 if (!ParseStringSidToSid(tok
, lpNext
, &bytes
))
2642 if (SecurityDescriptor
)
2644 SecurityDescriptor
->Group
= lpNext
- (LPBYTE
)SecurityDescriptor
;
2645 lpNext
+= bytes
; /* Advance to next token */
2658 if (!ParseStringAclToAcl(tok
, &flags
, (PACL
)lpNext
, &bytes
))
2661 if (SecurityDescriptor
)
2663 SecurityDescriptor
->Control
|= SE_DACL_PRESENT
| flags
;
2664 SecurityDescriptor
->Dacl
= lpNext
- (LPBYTE
)SecurityDescriptor
;
2665 lpNext
+= bytes
; /* Advance to next token */
2678 if (!ParseStringAclToAcl(tok
, &flags
, (PACL
)lpNext
, &bytes
))
2681 if (SecurityDescriptor
)
2683 SecurityDescriptor
->Control
|= SE_SACL_PRESENT
| flags
;
2684 SecurityDescriptor
->Sacl
= lpNext
- (LPBYTE
)SecurityDescriptor
;
2685 lpNext
+= bytes
; /* Advance to next token */
2694 FIXME("Unknown token\n");
2695 SetLastError(ERROR_INVALID_PARAMETER
);
2699 StringSecurityDescriptor
= lptoken
;
2708 /* Winehq cvs 20050916 */
2709 /******************************************************************************
2710 * ConvertStringSecurityDescriptorToSecurityDescriptorA [ADVAPI32.@]
2715 ConvertStringSecurityDescriptorToSecurityDescriptorA(LPCSTR StringSecurityDescriptor
,
2716 DWORD StringSDRevision
,
2717 PSECURITY_DESCRIPTOR
* SecurityDescriptor
,
2718 PULONG SecurityDescriptorSize
)
2722 LPWSTR StringSecurityDescriptorW
;
2724 len
= MultiByteToWideChar(CP_ACP
, 0, StringSecurityDescriptor
, -1, NULL
, 0);
2725 StringSecurityDescriptorW
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
2727 if (StringSecurityDescriptorW
)
2729 MultiByteToWideChar(CP_ACP
, 0, StringSecurityDescriptor
, -1, StringSecurityDescriptorW
, len
);
2731 ret
= ConvertStringSecurityDescriptorToSecurityDescriptorW(StringSecurityDescriptorW
,
2732 StringSDRevision
, SecurityDescriptor
,
2733 SecurityDescriptorSize
);
2734 HeapFree(GetProcessHeap(), 0, StringSecurityDescriptorW
);
2740 /******************************************************************************
2741 * ConvertStringSecurityDescriptorToSecurityDescriptorW [ADVAPI32.@]
2745 ConvertStringSecurityDescriptorToSecurityDescriptorW(LPCWSTR StringSecurityDescriptor
,
2746 DWORD StringSDRevision
,
2747 PSECURITY_DESCRIPTOR
* SecurityDescriptor
,
2748 PULONG SecurityDescriptorSize
)
2751 SECURITY_DESCRIPTOR
* psd
;
2754 TRACE("%s\n", debugstr_w(StringSecurityDescriptor
));
2756 if (GetVersion() & 0x80000000)
2758 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
2761 else if (!StringSecurityDescriptor
|| !SecurityDescriptor
)
2763 SetLastError(ERROR_INVALID_PARAMETER
);
2766 else if (StringSDRevision
!= SID_REVISION
)
2768 SetLastError(ERROR_UNKNOWN_REVISION
);
2772 /* Compute security descriptor length */
2773 if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor
,
2777 psd
= *SecurityDescriptor
= LocalAlloc(GMEM_ZEROINIT
, cBytes
);
2778 if (!psd
) goto lend
;
2780 psd
->Revision
= SID_REVISION
;
2781 psd
->Control
|= SE_SELF_RELATIVE
;
2783 if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor
,
2784 (SECURITY_DESCRIPTOR_RELATIVE
*)psd
, &cBytes
))
2790 if (SecurityDescriptorSize
)
2791 *SecurityDescriptorSize
= cBytes
;
2796 TRACE(" ret=%d\n", bret
);
2800 static void DumpString(LPCWSTR string
, int cch
, WCHAR
**pwptr
, ULONG
*plen
)
2803 cch
= strlenW(string
);
2810 memcpy(*pwptr
, string
, sizeof(WCHAR
)*cch
);
2815 static BOOL
DumpSidNumeric(PSID psid
, WCHAR
**pwptr
, ULONG
*plen
)
2818 WCHAR fmt
[] = { 'S','-','%','u','-','%','d',0 };
2819 WCHAR subauthfmt
[] = { '-','%','u',0 };
2823 if( !IsValidSid( psid
) || pisid
->Revision
!= SDDL_REVISION
)
2825 SetLastError(ERROR_INVALID_SID
);
2829 if (pisid
->IdentifierAuthority
.Value
[0] ||
2830 pisid
->IdentifierAuthority
.Value
[1])
2832 FIXME("not matching MS' bugs\n");
2833 SetLastError(ERROR_INVALID_SID
);
2837 sprintfW( buf
, fmt
, pisid
->Revision
,
2839 MAKEWORD( pisid
->IdentifierAuthority
.Value
[5],
2840 pisid
->IdentifierAuthority
.Value
[4] ),
2841 MAKEWORD( pisid
->IdentifierAuthority
.Value
[3],
2842 pisid
->IdentifierAuthority
.Value
[2] )
2844 DumpString(buf
, -1, pwptr
, plen
);
2846 for( i
=0; i
<pisid
->SubAuthorityCount
; i
++ )
2848 sprintfW( buf
, subauthfmt
, pisid
->SubAuthority
[i
] );
2849 DumpString(buf
, -1, pwptr
, plen
);
2854 static BOOL
DumpSid(PSID psid
, WCHAR
**pwptr
, ULONG
*plen
)
2857 for (i
= 0; i
< sizeof(WellKnownSids
) / sizeof(WellKnownSids
[0]); i
++)
2859 if (WellKnownSids
[i
].wstr
[0] && EqualSid(psid
, (PSID
)&(WellKnownSids
[i
].Sid
.Revision
)))
2861 DumpString(WellKnownSids
[i
].wstr
, 2, pwptr
, plen
);
2866 return DumpSidNumeric(psid
, pwptr
, plen
);
2869 static const LPCWSTR AceRightBitNames
[32] = {
2870 SDDL_CREATE_CHILD
, /* 0 */
2874 SDDL_READ_PROPERTY
, /* 4 */
2875 SDDL_WRITE_PROPERTY
,
2878 SDDL_CONTROL_ACCESS
, /* 8 */
2886 SDDL_STANDARD_DELETE
, /* 16 */
2898 SDDL_GENERIC_ALL
, /* 28 */
2899 SDDL_GENERIC_EXECUTE
,
2904 static void DumpRights(DWORD mask
, WCHAR
**pwptr
, ULONG
*plen
)
2906 static const WCHAR fmtW
[] = {'0','x','%','x',0};
2913 /* first check if the right have name */
2914 for (i
= 0; i
< sizeof(AceRights
)/sizeof(AceRights
[0]); i
++)
2916 if (AceRights
[i
].wstr
== NULL
)
2918 if (mask
== AceRights
[i
].value
)
2920 DumpString(AceRights
[i
].wstr
, -1, pwptr
, plen
);
2925 /* then check if it can be built from bit names */
2926 for (i
= 0; i
< 32; i
++)
2928 if ((mask
& (1 << i
)) && (AceRightBitNames
[i
] == NULL
))
2930 /* can't be built from bit names */
2931 sprintfW(buf
, fmtW
, mask
);
2932 DumpString(buf
, -1, pwptr
, plen
);
2937 /* build from bit names */
2938 for (i
= 0; i
< 32; i
++)
2939 if (mask
& (1 << i
))
2940 DumpString(AceRightBitNames
[i
], -1, pwptr
, plen
);
2943 static BOOL
DumpAce(LPVOID pace
, WCHAR
**pwptr
, ULONG
*plen
)
2945 ACCESS_ALLOWED_ACE
*piace
; /* all the supported ACEs have the same memory layout */
2946 static const WCHAR openbr
= '(';
2947 static const WCHAR closebr
= ')';
2948 static const WCHAR semicolon
= ';';
2950 if (((PACE_HEADER
)pace
)->AceType
> SYSTEM_ALARM_ACE_TYPE
|| ((PACE_HEADER
)pace
)->AceSize
< sizeof(ACCESS_ALLOWED_ACE
))
2952 SetLastError(ERROR_INVALID_ACL
);
2957 DumpString(&openbr
, 1, pwptr
, plen
);
2958 switch (piace
->Header
.AceType
)
2960 case ACCESS_ALLOWED_ACE_TYPE
:
2961 DumpString(SDDL_ACCESS_ALLOWED
, -1, pwptr
, plen
);
2963 case ACCESS_DENIED_ACE_TYPE
:
2964 DumpString(SDDL_ACCESS_DENIED
, -1, pwptr
, plen
);
2966 case SYSTEM_AUDIT_ACE_TYPE
:
2967 DumpString(SDDL_AUDIT
, -1, pwptr
, plen
);
2969 case SYSTEM_ALARM_ACE_TYPE
:
2970 DumpString(SDDL_ALARM
, -1, pwptr
, plen
);
2973 DumpString(&semicolon
, 1, pwptr
, plen
);
2975 if (piace
->Header
.AceFlags
& OBJECT_INHERIT_ACE
)
2976 DumpString(SDDL_OBJECT_INHERIT
, -1, pwptr
, plen
);
2977 if (piace
->Header
.AceFlags
& CONTAINER_INHERIT_ACE
)
2978 DumpString(SDDL_CONTAINER_INHERIT
, -1, pwptr
, plen
);
2979 if (piace
->Header
.AceFlags
& NO_PROPAGATE_INHERIT_ACE
)
2980 DumpString(SDDL_NO_PROPAGATE
, -1, pwptr
, plen
);
2981 if (piace
->Header
.AceFlags
& INHERIT_ONLY_ACE
)
2982 DumpString(SDDL_INHERIT_ONLY
, -1, pwptr
, plen
);
2983 if (piace
->Header
.AceFlags
& INHERITED_ACE
)
2984 DumpString(SDDL_INHERITED
, -1, pwptr
, plen
);
2985 if (piace
->Header
.AceFlags
& SUCCESSFUL_ACCESS_ACE_FLAG
)
2986 DumpString(SDDL_AUDIT_SUCCESS
, -1, pwptr
, plen
);
2987 if (piace
->Header
.AceFlags
& FAILED_ACCESS_ACE_FLAG
)
2988 DumpString(SDDL_AUDIT_FAILURE
, -1, pwptr
, plen
);
2989 DumpString(&semicolon
, 1, pwptr
, plen
);
2990 DumpRights(piace
->Mask
, pwptr
, plen
);
2991 DumpString(&semicolon
, 1, pwptr
, plen
);
2992 /* objects not supported */
2993 DumpString(&semicolon
, 1, pwptr
, plen
);
2994 /* objects not supported */
2995 DumpString(&semicolon
, 1, pwptr
, plen
);
2996 if (!DumpSid((PSID
)&piace
->SidStart
, pwptr
, plen
))
2998 DumpString(&closebr
, 1, pwptr
, plen
);
3002 static BOOL
DumpAcl(PACL pacl
, WCHAR
**pwptr
, ULONG
*plen
, BOOL
protected, BOOL autoInheritReq
, BOOL autoInherited
)
3008 DumpString(SDDL_PROTECTED
, -1, pwptr
, plen
);
3010 DumpString(SDDL_AUTO_INHERIT_REQ
, -1, pwptr
, plen
);
3012 DumpString(SDDL_AUTO_INHERITED
, -1, pwptr
, plen
);
3017 if (!IsValidAcl(pacl
))
3020 count
= pacl
->AceCount
;
3021 for (i
= 0; i
< count
; i
++)
3024 if (!GetAce(pacl
, i
, &ace
))
3026 if (!DumpAce(ace
, pwptr
, plen
))
3033 static BOOL
DumpOwner(PSECURITY_DESCRIPTOR SecurityDescriptor
, WCHAR
**pwptr
, ULONG
*plen
)
3035 static const WCHAR prefix
[] = {'O',':',0};
3039 if (!GetSecurityDescriptorOwner(SecurityDescriptor
, &psid
, &bDefaulted
))
3045 DumpString(prefix
, -1, pwptr
, plen
);
3046 if (!DumpSid(psid
, pwptr
, plen
))
3051 static BOOL
DumpGroup(PSECURITY_DESCRIPTOR SecurityDescriptor
, WCHAR
**pwptr
, ULONG
*plen
)
3053 static const WCHAR prefix
[] = {'G',':',0};
3057 if (!GetSecurityDescriptorGroup(SecurityDescriptor
, &psid
, &bDefaulted
))
3063 DumpString(prefix
, -1, pwptr
, plen
);
3064 if (!DumpSid(psid
, pwptr
, plen
))
3069 static BOOL
DumpDacl(PSECURITY_DESCRIPTOR SecurityDescriptor
, WCHAR
**pwptr
, ULONG
*plen
)
3071 static const WCHAR dacl
[] = {'D',':',0};
3072 SECURITY_DESCRIPTOR_CONTROL control
;
3073 BOOL present
, defaulted
;
3077 if (!GetSecurityDescriptorDacl(SecurityDescriptor
, &present
, &pacl
, &defaulted
))
3080 if (!GetSecurityDescriptorControl(SecurityDescriptor
, &control
, &revision
))
3086 DumpString(dacl
, 2, pwptr
, plen
);
3087 if (!DumpAcl(pacl
, pwptr
, plen
, control
& SE_DACL_PROTECTED
, control
& SE_DACL_AUTO_INHERIT_REQ
, control
& SE_DACL_AUTO_INHERITED
))
3092 static BOOL
DumpSacl(PSECURITY_DESCRIPTOR SecurityDescriptor
, WCHAR
**pwptr
, ULONG
*plen
)
3094 static const WCHAR sacl
[] = {'S',':',0};
3095 SECURITY_DESCRIPTOR_CONTROL control
;
3096 BOOL present
, defaulted
;
3100 if (!GetSecurityDescriptorSacl(SecurityDescriptor
, &present
, &pacl
, &defaulted
))
3103 if (!GetSecurityDescriptorControl(SecurityDescriptor
, &control
, &revision
))
3109 DumpString(sacl
, 2, pwptr
, plen
);
3110 if (!DumpAcl(pacl
, pwptr
, plen
, control
& SE_SACL_PROTECTED
, control
& SE_SACL_AUTO_INHERIT_REQ
, control
& SE_SACL_AUTO_INHERITED
))
3115 /******************************************************************************
3116 * ConvertSecurityDescriptorToStringSecurityDescriptorW [ADVAPI32.@]
3120 ConvertSecurityDescriptorToStringSecurityDescriptorW(PSECURITY_DESCRIPTOR SecurityDescriptor
,
3122 SECURITY_INFORMATION SecurityInformation
,
3123 LPWSTR
*OutputString
,
3129 if (SDRevision
!= SDDL_REVISION_1
)
3131 ERR("Program requested unknown SDDL revision %d\n", SDRevision
);
3132 SetLastError(ERROR_UNKNOWN_REVISION
);
3137 if (SecurityInformation
& OWNER_SECURITY_INFORMATION
)
3138 if (!DumpOwner(SecurityDescriptor
, NULL
, &len
))
3140 if (SecurityInformation
& GROUP_SECURITY_INFORMATION
)
3141 if (!DumpGroup(SecurityDescriptor
, NULL
, &len
))
3143 if (SecurityInformation
& DACL_SECURITY_INFORMATION
)
3144 if (!DumpDacl(SecurityDescriptor
, NULL
, &len
))
3146 if (SecurityInformation
& SACL_SECURITY_INFORMATION
)
3147 if (!DumpSacl(SecurityDescriptor
, NULL
, &len
))
3150 wstr
= wptr
= LocalAlloc(0, (len
+ 1)*sizeof(WCHAR
));
3154 if (SecurityInformation
& OWNER_SECURITY_INFORMATION
)
3155 if (!DumpOwner(SecurityDescriptor
, &wptr
, NULL
))
3157 if (SecurityInformation
& GROUP_SECURITY_INFORMATION
)
3158 if (!DumpGroup(SecurityDescriptor
, &wptr
, NULL
))
3160 if (SecurityInformation
& DACL_SECURITY_INFORMATION
)
3161 if (!DumpDacl(SecurityDescriptor
, &wptr
, NULL
))
3163 if (SecurityInformation
& SACL_SECURITY_INFORMATION
)
3164 if (!DumpSacl(SecurityDescriptor
, &wptr
, NULL
))
3168 TRACE("ret: %s, %d\n", wine_dbgstr_w(wstr
), len
);
3169 *OutputString
= wstr
;
3171 *OutputLen
= strlenW(*OutputString
)+1;
3175 /******************************************************************************
3176 * ConvertSecurityDescriptorToStringSecurityDescriptorA [ADVAPI32.@]
3180 ConvertSecurityDescriptorToStringSecurityDescriptorA(PSECURITY_DESCRIPTOR SecurityDescriptor
,
3182 SECURITY_INFORMATION Information
,
3183 LPSTR
*OutputString
,
3189 if (ConvertSecurityDescriptorToStringSecurityDescriptorW(SecurityDescriptor
, SDRevision
, Information
, &wstr
, &len
))
3193 lenA
= WideCharToMultiByte(CP_ACP
, 0, wstr
, len
, NULL
, 0, NULL
, NULL
);
3194 *OutputString
= HeapAlloc(GetProcessHeap(), 0, lenA
);
3195 if (*OutputString
== NULL
)
3201 WideCharToMultiByte(CP_ACP
, 0, wstr
, len
, *OutputString
, lenA
, NULL
, NULL
);
3204 if (OutputLen
!= NULL
)
3210 *OutputString
= NULL
;
3222 ConvertStringSidToSidW(IN LPCWSTR StringSid
,
3226 DWORD i
, cBytes
, identAuth
, csubauth
;
3230 TRACE("%s %p\n", debugstr_w(StringSid
), sid
);
3234 SetLastError(ERROR_INVALID_SID
);
3238 for (i
= 0; i
< sizeof(SidTable
) / sizeof(SidTable
[0]) - 1; i
++)
3240 if (wcscmp(StringSid
, SidTable
[i
].key
) == 0)
3242 WELL_KNOWN_SID_TYPE knownSid
= (WELL_KNOWN_SID_TYPE
)SidTable
[i
].value
;
3243 size
= SECURITY_MAX_SID_SIZE
;
3244 *sid
= LocalAlloc(0, size
);
3247 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
3250 ret
= CreateWellKnownSid(knownSid
,
3256 SetLastError(ERROR_INVALID_SID
);
3263 /* That's probably a string S-R-I-S-S... */
3264 if (StringSid
[0] != 'S' || StringSid
[1] != '-')
3266 SetLastError(ERROR_INVALID_SID
);
3270 cBytes
= ComputeStringSidSize(StringSid
);
3271 pisid
= (SID
*)LocalAlloc( 0, cBytes
);
3274 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
3279 csubauth
= ((cBytes
- GetSidLengthRequired(0)) / sizeof(DWORD
));
3281 StringSid
+= 2; /* Advance to Revision */
3282 pisid
->Revision
= atoiW(StringSid
);
3284 if (pisid
->Revision
!= SDDL_REVISION
)
3286 TRACE("Revision %d is unknown\n", pisid
->Revision
);
3287 goto lend
; /* ERROR_INVALID_SID */
3291 TRACE("SubAuthorityCount is 0\n");
3292 goto lend
; /* ERROR_INVALID_SID */
3295 pisid
->SubAuthorityCount
= csubauth
;
3297 /* Advance to identifier authority */
3298 while (*StringSid
&& *StringSid
!= '-')
3300 if (*StringSid
== '-')
3303 /* MS' implementation can't handle values greater than 2^32 - 1, so
3304 * we don't either; assume most significant bytes are always 0
3306 pisid
->IdentifierAuthority
.Value
[0] = 0;
3307 pisid
->IdentifierAuthority
.Value
[1] = 0;
3308 identAuth
= atoiW(StringSid
);
3309 pisid
->IdentifierAuthority
.Value
[5] = identAuth
& 0xff;
3310 pisid
->IdentifierAuthority
.Value
[4] = (identAuth
& 0xff00) >> 8;
3311 pisid
->IdentifierAuthority
.Value
[3] = (identAuth
& 0xff0000) >> 16;
3312 pisid
->IdentifierAuthority
.Value
[2] = (identAuth
& 0xff000000) >> 24;
3314 /* Advance to first sub authority */
3315 while (*StringSid
&& *StringSid
!= '-')
3317 if (*StringSid
== '-')
3322 pisid
->SubAuthority
[i
++] = atoiW(StringSid
);
3324 while (*StringSid
&& *StringSid
!= '-')
3326 if (*StringSid
== '-')
3330 if (i
!= pisid
->SubAuthorityCount
)
3331 goto lend
; /* ERROR_INVALID_SID */
3340 SetLastError(ERROR_INVALID_SID
);
3343 TRACE("returning %s\n", ret
? "TRUE" : "FALSE");
3352 ConvertStringSidToSidA(IN LPCSTR StringSid
,
3355 BOOL bRetVal
= FALSE
;
3357 TRACE("%s, %p\n", debugstr_a(StringSid
), sid
);
3358 if (GetVersion() & 0x80000000)
3359 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
3360 else if (!StringSid
|| !sid
)
3361 SetLastError(ERROR_INVALID_PARAMETER
);
3364 UINT len
= MultiByteToWideChar(CP_ACP
, 0, StringSid
, -1, NULL
, 0);
3365 LPWSTR wStringSid
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
3366 if (wStringSid
== NULL
)
3368 MultiByteToWideChar(CP_ACP
, 0, StringSid
, - 1, wStringSid
, len
);
3369 bRetVal
= ConvertStringSidToSidW(wStringSid
, sid
);
3370 HeapFree(GetProcessHeap(), 0, wStringSid
);
3380 ConvertSidToStringSidW(PSID Sid
,
3384 UNICODE_STRING UnicodeString
;
3385 WCHAR FixedBuffer
[64];
3387 if (!RtlValidSid(Sid
))
3389 SetLastError(ERROR_INVALID_SID
);
3393 UnicodeString
.Length
= 0;
3394 UnicodeString
.MaximumLength
= sizeof(FixedBuffer
);
3395 UnicodeString
.Buffer
= FixedBuffer
;
3396 Status
= RtlConvertSidToUnicodeString(&UnicodeString
, Sid
, FALSE
);
3397 if (STATUS_BUFFER_TOO_SMALL
== Status
)
3399 Status
= RtlConvertSidToUnicodeString(&UnicodeString
, Sid
, TRUE
);
3402 if (!NT_SUCCESS(Status
))
3404 SetLastError(RtlNtStatusToDosError(Status
));
3408 *StringSid
= LocalAlloc(LMEM_FIXED
, UnicodeString
.Length
+ sizeof(WCHAR
));
3409 if (NULL
== *StringSid
)
3411 if (UnicodeString
.Buffer
!= FixedBuffer
)
3413 RtlFreeUnicodeString(&UnicodeString
);
3415 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
3419 MoveMemory(*StringSid
, UnicodeString
.Buffer
, UnicodeString
.Length
);
3420 ZeroMemory((PCHAR
) *StringSid
+ UnicodeString
.Length
, sizeof(WCHAR
));
3421 if (UnicodeString
.Buffer
!= FixedBuffer
)
3423 RtlFreeUnicodeString(&UnicodeString
);
3434 ConvertSidToStringSidA(PSID Sid
,
3440 if (!ConvertSidToStringSidW(Sid
, &StringSidW
))
3445 Len
= WideCharToMultiByte(CP_ACP
, 0, StringSidW
, -1, NULL
, 0, NULL
, NULL
);
3448 LocalFree(StringSidW
);
3449 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
3453 *StringSid
= LocalAlloc(LMEM_FIXED
, Len
);
3454 if (NULL
== *StringSid
)
3456 LocalFree(StringSidW
);
3457 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
3461 if (!WideCharToMultiByte(CP_ACP
, 0, StringSidW
, -1, *StringSid
, Len
, NULL
, NULL
))
3463 LocalFree(StringSid
);
3464 LocalFree(StringSidW
);
3468 LocalFree(StringSidW
);
3477 CreateProcessWithLogonW(LPCWSTR lpUsername
,
3481 LPCWSTR lpApplicationName
,
3482 LPWSTR lpCommandLine
,
3483 DWORD dwCreationFlags
,
3484 LPVOID lpEnvironment
,
3485 LPCWSTR lpCurrentDirectory
,
3486 LPSTARTUPINFOW lpStartupInfo
,
3487 LPPROCESS_INFORMATION lpProcessInformation
)
3489 FIXME("%s %s %s 0x%08x %s %s 0x%08x %p %s %p %p stub\n", debugstr_w(lpUsername
), debugstr_w(lpDomain
),
3490 debugstr_w(lpPassword
), dwLogonFlags
, debugstr_w(lpApplicationName
),
3491 debugstr_w(lpCommandLine
), dwCreationFlags
, lpEnvironment
, debugstr_w(lpCurrentDirectory
),
3492 lpStartupInfo
, lpProcessInformation
);
3499 CreateProcessWithTokenW(IN HANDLE hToken
,
3500 IN DWORD dwLogonFlags
,
3501 IN LPCWSTR lpApplicationName OPTIONAL
,
3502 IN OUT LPWSTR lpCommandLine OPTIONAL
,
3503 IN DWORD dwCreationFlags
,
3504 IN LPVOID lpEnvironment OPTIONAL
,
3505 IN LPCWSTR lpCurrentDirectory OPTIONAL
,
3506 IN LPSTARTUPINFOW lpStartupInfo
,
3507 OUT LPPROCESS_INFORMATION lpProcessInfo
)
3517 DuplicateTokenEx(IN HANDLE ExistingTokenHandle
,
3518 IN DWORD dwDesiredAccess
,
3519 IN LPSECURITY_ATTRIBUTES lpTokenAttributes OPTIONAL
,
3520 IN SECURITY_IMPERSONATION_LEVEL ImpersonationLevel
,
3521 IN TOKEN_TYPE TokenType
,
3522 OUT PHANDLE DuplicateTokenHandle
)
3524 OBJECT_ATTRIBUTES ObjectAttributes
;
3526 SECURITY_QUALITY_OF_SERVICE Sqos
;
3528 TRACE("%p 0x%08x 0x%08x 0x%08x %p\n", ExistingTokenHandle
, dwDesiredAccess
,
3529 ImpersonationLevel
, TokenType
, DuplicateTokenHandle
);
3531 Sqos
.Length
= sizeof(SECURITY_QUALITY_OF_SERVICE
);
3532 Sqos
.ImpersonationLevel
= ImpersonationLevel
;
3533 Sqos
.ContextTrackingMode
= 0;
3534 Sqos
.EffectiveOnly
= FALSE
;
3536 if (lpTokenAttributes
!= NULL
)
3538 InitializeObjectAttributes(&ObjectAttributes
,
3540 lpTokenAttributes
->bInheritHandle
? OBJ_INHERIT
: 0,
3542 lpTokenAttributes
->lpSecurityDescriptor
);
3546 InitializeObjectAttributes(&ObjectAttributes
,
3553 ObjectAttributes
.SecurityQualityOfService
= &Sqos
;
3555 Status
= NtDuplicateToken(ExistingTokenHandle
,
3560 DuplicateTokenHandle
);
3561 if (!NT_SUCCESS(Status
))
3563 ERR("NtDuplicateToken failed: Status %08x\n", Status
);
3564 SetLastError(RtlNtStatusToDosError(Status
));
3568 TRACE("Returning token %p.\n", *DuplicateTokenHandle
);
3577 DuplicateToken(IN HANDLE ExistingTokenHandle
,
3578 IN SECURITY_IMPERSONATION_LEVEL ImpersonationLevel
,
3579 OUT PHANDLE DuplicateTokenHandle
)
3581 return DuplicateTokenEx(ExistingTokenHandle
,
3582 TOKEN_IMPERSONATE
| TOKEN_QUERY
,
3586 DuplicateTokenHandle
);
3589 /******************************************************************************
3590 * ComputeStringSidSize
3592 static DWORD
ComputeStringSidSize(LPCWSTR StringSid
)
3594 if (StringSid
[0] == 'S' && StringSid
[1] == '-') /* S-R-I(-S)+ */
3599 if (*StringSid
== '-')
3605 return GetSidLengthRequired(ctok
- 2);
3607 else /* String constant format - Only available in winxp and above */
3611 for (i
= 0; i
< sizeof(WellKnownSids
)/sizeof(WellKnownSids
[0]); i
++)
3612 if (!strncmpW(WellKnownSids
[i
].wstr
, StringSid
, 2))
3613 return GetSidLengthRequired(WellKnownSids
[i
].Sid
.SubAuthorityCount
);
3616 return GetSidLengthRequired(0);
3619 /******************************************************************************
3620 * ParseStringSidToSid
3622 static BOOL
ParseStringSidToSid(LPCWSTR StringSid
, PSID pSid
, LPDWORD cBytes
)
3627 TRACE("%s, %p, %p\n", debugstr_w(StringSid
), pSid
, cBytes
);
3630 SetLastError(ERROR_INVALID_PARAMETER
);
3631 TRACE("StringSid is NULL, returning FALSE\n");
3635 while (*StringSid
== ' ')
3638 *cBytes
= ComputeStringSidSize(StringSid
);
3639 if (!pisid
) /* Simply compute the size */
3641 TRACE("only size requested, returning TRUE\n");
3645 if (StringSid
[0] == 'S' && StringSid
[1] == '-') /* S-R-I-S-S */
3647 DWORD i
= 0, identAuth
;
3648 DWORD csubauth
= ((*cBytes
- GetSidLengthRequired(0)) / sizeof(DWORD
));
3650 StringSid
+= 2; /* Advance to Revision */
3651 pisid
->Revision
= atoiW(StringSid
);
3653 if (pisid
->Revision
!= SDDL_REVISION
)
3655 TRACE("Revision %d is unknown\n", pisid
->Revision
);
3656 goto lend
; /* ERROR_INVALID_SID */
3660 TRACE("SubAuthorityCount is 0\n");
3661 goto lend
; /* ERROR_INVALID_SID */
3664 pisid
->SubAuthorityCount
= csubauth
;
3666 /* Advance to identifier authority */
3667 while (*StringSid
&& *StringSid
!= '-')
3669 if (*StringSid
== '-')
3672 /* MS' implementation can't handle values greater than 2^32 - 1, so
3673 * we don't either; assume most significant bytes are always 0
3675 pisid
->IdentifierAuthority
.Value
[0] = 0;
3676 pisid
->IdentifierAuthority
.Value
[1] = 0;
3677 identAuth
= atoiW(StringSid
);
3678 pisid
->IdentifierAuthority
.Value
[5] = identAuth
& 0xff;
3679 pisid
->IdentifierAuthority
.Value
[4] = (identAuth
& 0xff00) >> 8;
3680 pisid
->IdentifierAuthority
.Value
[3] = (identAuth
& 0xff0000) >> 16;
3681 pisid
->IdentifierAuthority
.Value
[2] = (identAuth
& 0xff000000) >> 24;
3683 /* Advance to first sub authority */
3684 while (*StringSid
&& *StringSid
!= '-')
3686 if (*StringSid
== '-')
3691 pisid
->SubAuthority
[i
++] = atoiW(StringSid
);
3693 while (*StringSid
&& *StringSid
!= '-')
3695 if (*StringSid
== '-')
3699 if (i
!= pisid
->SubAuthorityCount
)
3700 goto lend
; /* ERROR_INVALID_SID */
3704 else /* String constant format - Only available in winxp and above */
3707 pisid
->Revision
= SDDL_REVISION
;
3709 for (i
= 0; i
< sizeof(WellKnownSids
)/sizeof(WellKnownSids
[0]); i
++)
3710 if (!strncmpW(WellKnownSids
[i
].wstr
, StringSid
, 2))
3713 pisid
->SubAuthorityCount
= WellKnownSids
[i
].Sid
.SubAuthorityCount
;
3714 pisid
->IdentifierAuthority
= WellKnownSids
[i
].Sid
.IdentifierAuthority
;
3715 for (j
= 0; j
< WellKnownSids
[i
].Sid
.SubAuthorityCount
; j
++)
3716 pisid
->SubAuthority
[j
] = WellKnownSids
[i
].Sid
.SubAuthority
[j
];
3721 FIXME("String constant not supported: %s\n", debugstr_wn(StringSid
, 2));
3726 SetLastError(ERROR_INVALID_SID
);
3728 TRACE("returning %s\n", bret
? "TRUE" : "FALSE");
3732 /**********************************************************************
3733 * GetNamedSecurityInfoA EXPORTED
3739 GetNamedSecurityInfoA(LPSTR pObjectName
,
3740 SE_OBJECT_TYPE ObjectType
,
3741 SECURITY_INFORMATION SecurityInfo
,
3746 PSECURITY_DESCRIPTOR
*ppSecurityDescriptor
)
3752 TRACE("%s %d %d %p %p %p %p %p\n", pObjectName
, ObjectType
, SecurityInfo
,
3753 ppsidOwner
, ppsidGroup
, ppDacl
, ppSacl
, ppSecurityDescriptor
);
3757 len
= MultiByteToWideChar( CP_ACP
, 0, pObjectName
, -1, NULL
, 0 );
3758 wstr
= HeapAlloc( GetProcessHeap(), 0, len
*sizeof(WCHAR
));
3759 MultiByteToWideChar( CP_ACP
, 0, pObjectName
, -1, wstr
, len
);
3762 r
= GetNamedSecurityInfoW( wstr
, ObjectType
, SecurityInfo
, ppsidOwner
,
3763 ppsidGroup
, ppDacl
, ppSacl
, ppSecurityDescriptor
);
3765 HeapFree( GetProcessHeap(), 0, wstr
);
3775 GetWindowsAccountDomainSid(IN PSID pSid
,
3776 OUT PSID ppDomainSid
,
3777 IN OUT DWORD
* cbSid
)
3788 EqualDomainSid(IN PSID pSid1
,