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 /* set last error code from NT status and get the proper boolean return value */
230 /* used for functions that are a simple wrapper around the corresponding ntdll API */
231 static __inline BOOL
set_ntstatus( NTSTATUS status
)
233 if (!NT_SUCCESS(status
)) SetLastError( RtlNtStatusToDosError( status
));
234 return NT_SUCCESS(status
);
237 static const RECORD SidTable
[] =
239 { SDDL_ACCOUNT_OPERATORS
, WinBuiltinAccountOperatorsSid
},
240 { SDDL_ALIAS_PREW2KCOMPACC
, WinBuiltinPreWindows2000CompatibleAccessSid
},
241 { SDDL_ANONYMOUS
, WinAnonymousSid
},
242 { SDDL_AUTHENTICATED_USERS
, WinAuthenticatedUserSid
},
243 { SDDL_BUILTIN_ADMINISTRATORS
, WinBuiltinAdministratorsSid
},
244 { SDDL_BUILTIN_GUESTS
, WinBuiltinGuestsSid
},
245 { SDDL_BACKUP_OPERATORS
, WinBuiltinBackupOperatorsSid
},
246 { SDDL_BUILTIN_USERS
, WinBuiltinUsersSid
},
247 { SDDL_CERT_SERV_ADMINISTRATORS
, WinAccountCertAdminsSid
/* FIXME: DOMAIN_GROUP_RID_CERT_ADMINS */ },
248 { SDDL_CREATOR_GROUP
, WinCreatorGroupSid
},
249 { SDDL_CREATOR_OWNER
, WinCreatorOwnerSid
},
250 { SDDL_DOMAIN_ADMINISTRATORS
, WinAccountDomainAdminsSid
/* FIXME: DOMAIN_GROUP_RID_ADMINS */ },
251 { SDDL_DOMAIN_COMPUTERS
, WinAccountComputersSid
/* FIXME: DOMAIN_GROUP_RID_COMPUTERS */ },
252 { SDDL_DOMAIN_DOMAIN_CONTROLLERS
, WinAccountControllersSid
/* FIXME: DOMAIN_GROUP_RID_CONTROLLERS */ },
253 { SDDL_DOMAIN_GUESTS
, WinAccountDomainGuestsSid
/* FIXME: DOMAIN_GROUP_RID_GUESTS */ },
254 { SDDL_DOMAIN_USERS
, WinAccountDomainUsersSid
/* FIXME: DOMAIN_GROUP_RID_USERS */ },
255 { SDDL_ENTERPRISE_ADMINS
, WinAccountEnterpriseAdminsSid
/* FIXME: DOMAIN_GROUP_RID_ENTERPRISE_ADMINS */ },
256 { SDDL_ENTERPRISE_DOMAIN_CONTROLLERS
, WinEnterpriseControllersSid
},
257 { SDDL_EVERYONE
, WinWorldSid
},
258 { SDDL_GROUP_POLICY_ADMINS
, WinAccountPolicyAdminsSid
/* FIXME: DOMAIN_GROUP_RID_POLICY_ADMINS */ },
259 { SDDL_INTERACTIVE
, WinInteractiveSid
},
260 { SDDL_LOCAL_ADMIN
, WinAccountAdministratorSid
/* FIXME: DOMAIN_USER_RID_ADMIN */ },
261 { SDDL_LOCAL_GUEST
, WinAccountGuestSid
/* FIXME: DOMAIN_USER_RID_GUEST */ },
262 { SDDL_LOCAL_SERVICE
, WinLocalServiceSid
},
263 { SDDL_LOCAL_SYSTEM
, WinLocalSystemSid
},
264 { SDDL_NETWORK
, WinNetworkSid
},
265 { SDDL_NETWORK_CONFIGURATION_OPS
, WinBuiltinNetworkConfigurationOperatorsSid
},
266 { SDDL_NETWORK_SERVICE
, WinNetworkServiceSid
},
267 { SDDL_PRINTER_OPERATORS
, WinBuiltinPrintOperatorsSid
},
268 { SDDL_PERSONAL_SELF
, WinSelfSid
},
269 { SDDL_POWER_USERS
, WinBuiltinPowerUsersSid
},
270 { SDDL_RAS_SERVERS
, WinAccountRasAndIasServersSid
/* FIXME: DOMAIN_ALIAS_RID_RAS_SERVERS */ },
271 { SDDL_REMOTE_DESKTOP
, WinBuiltinRemoteDesktopUsersSid
},
272 { SDDL_REPLICATOR
, WinBuiltinReplicatorSid
},
273 { SDDL_RESTRICTED_CODE
, WinRestrictedCodeSid
},
274 { SDDL_SCHEMA_ADMINISTRATORS
, WinAccountSchemaAdminsSid
/* FIXME: DOMAIN_GROUP_RID_SCHEMA_ADMINS */ },
275 { SDDL_SERVER_OPERATORS
, WinBuiltinSystemOperatorsSid
},
276 { SDDL_SERVICE
, WinServiceSid
},
280 /************************************************************
281 * ADVAPI_IsLocalComputer
283 * Checks whether the server name indicates local machine.
285 BOOL
ADVAPI_IsLocalComputer(LPCWSTR ServerName
)
287 DWORD dwSize
= MAX_COMPUTERNAME_LENGTH
+ 1;
291 if (!ServerName
|| !ServerName
[0])
294 buf
= heap_alloc(dwSize
* sizeof(WCHAR
));
295 Result
= GetComputerNameW(buf
, &dwSize
);
296 if (Result
&& (ServerName
[0] == '\\') && (ServerName
[1] == '\\'))
298 Result
= Result
&& !lstrcmpW(ServerName
, buf
);
304 /* Exported functions */
310 OpenProcessToken(HANDLE ProcessHandle
,
316 TRACE("%p, %x, %p.\n", ProcessHandle
, DesiredAccess
, TokenHandle
);
318 Status
= NtOpenProcessToken(ProcessHandle
,
321 if (!NT_SUCCESS(Status
))
323 ERR("NtOpenProcessToken failed! Status %08x.\n", Status
);
324 SetLastError(RtlNtStatusToDosError(Status
));
328 TRACE("Returning token %p.\n", *TokenHandle
);
333 /******************************************************************************
334 * OpenThreadToken [ADVAPI32.@]
336 * Opens the access token associated with a thread handle.
339 * ThreadHandle [I] Handle to process
340 * DesiredAccess [I] Desired access to the thread
342 * TokenHandle [O] Destination for the token handle
345 * Success: TRUE. TokenHandle contains the access token.
349 * See NtOpenThreadToken.
352 OpenThreadToken( HANDLE ThreadHandle
, DWORD DesiredAccess
,
353 BOOL OpenAsSelf
, HANDLE
*TokenHandle
)
355 return set_ntstatus( NtOpenThreadToken(ThreadHandle
, DesiredAccess
, OpenAsSelf
, TokenHandle
));
362 AdjustTokenGroups(HANDLE TokenHandle
,
364 PTOKEN_GROUPS NewState
,
366 PTOKEN_GROUPS PreviousState
,
371 Status
= NtAdjustGroupsToken(TokenHandle
,
376 (PULONG
)ReturnLength
);
377 if (!NT_SUCCESS(Status
))
379 SetLastError(RtlNtStatusToDosError(Status
));
390 AdjustTokenPrivileges(HANDLE TokenHandle
,
391 BOOL DisableAllPrivileges
,
392 PTOKEN_PRIVILEGES NewState
,
394 PTOKEN_PRIVILEGES PreviousState
,
399 Status
= NtAdjustPrivilegesToken(TokenHandle
,
400 DisableAllPrivileges
,
404 (PULONG
)ReturnLength
);
405 if (STATUS_NOT_ALL_ASSIGNED
== Status
)
407 SetLastError(ERROR_NOT_ALL_ASSIGNED
);
411 if (!NT_SUCCESS(Status
))
413 SetLastError(RtlNtStatusToDosError(Status
));
417 /* AdjustTokenPrivileges is documented to do this */
418 SetLastError(ERROR_SUCCESS
);
427 GetTokenInformation(HANDLE TokenHandle
,
428 TOKEN_INFORMATION_CLASS TokenInformationClass
,
429 LPVOID TokenInformation
,
430 DWORD TokenInformationLength
,
435 Status
= NtQueryInformationToken(TokenHandle
,
436 TokenInformationClass
,
438 TokenInformationLength
,
439 (PULONG
)ReturnLength
);
440 if (!NT_SUCCESS(Status
))
442 SetLastError(RtlNtStatusToDosError(Status
));
453 SetTokenInformation(HANDLE TokenHandle
,
454 TOKEN_INFORMATION_CLASS TokenInformationClass
,
455 LPVOID TokenInformation
,
456 DWORD TokenInformationLength
)
460 Status
= NtSetInformationToken(TokenHandle
,
461 TokenInformationClass
,
463 TokenInformationLength
);
464 if (!NT_SUCCESS(Status
))
466 SetLastError(RtlNtStatusToDosError(Status
));
477 SetThreadToken(IN PHANDLE ThreadHandle OPTIONAL
,
478 IN HANDLE TokenHandle
)
483 hThread
= (ThreadHandle
!= NULL
) ? *ThreadHandle
: NtCurrentThread();
485 Status
= NtSetInformationThread(hThread
,
486 ThreadImpersonationToken
,
489 if (!NT_SUCCESS(Status
))
491 SetLastError(RtlNtStatusToDosError(Status
));
498 /*************************************************************************
499 * CreateRestrictedToken [ADVAPI32.@]
501 * Create a new more restricted token from an existing token.
504 * baseToken [I] Token to base the new restricted token on
506 * nDisableSids [I] Length of disableSids array
507 * disableSids [I] Array of SIDs to disable in the new token
508 * nDeletePrivs [I] Length of deletePrivs array
509 * deletePrivs [I] Array of privileges to delete in the new token
510 * nRestrictSids [I] Length of restrictSids array
511 * restrictSids [I] Array of SIDs to restrict in the new token
512 * newToken [O] Address where the new token is stored
518 BOOL WINAPI
CreateRestrictedToken(
522 PSID_AND_ATTRIBUTES disableSids
,
524 PLUID_AND_ATTRIBUTES deletePrivs
,
526 PSID_AND_ATTRIBUTES restrictSids
,
530 SECURITY_IMPERSONATION_LEVEL level
= TokenImpersonationLevel
;
533 FIXME("(%p, 0x%x, %u, %p, %u, %p, %u, %p, %p): stub\n",
534 baseToken
, flags
, nDisableSids
, disableSids
,
535 nDeletePrivs
, deletePrivs
,
536 nRestrictSids
, restrictSids
,
540 if (!GetTokenInformation( baseToken
, TokenType
, &type
, size
, &size
)) return FALSE
;
541 if (type
== TokenImpersonation
)
543 size
= sizeof(level
);
544 if (!GetTokenInformation( baseToken
, TokenImpersonationLevel
, &level
, size
, &size
))
547 return DuplicateTokenEx( baseToken
, MAXIMUM_ALLOWED
, NULL
, level
, type
, newToken
);
550 /******************************************************************************
551 * AllocateAndInitializeSid [ADVAPI32.@]
554 * pIdentifierAuthority []
555 * nSubAuthorityCount []
567 AllocateAndInitializeSid( PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority
,
568 BYTE nSubAuthorityCount
,
569 DWORD nSubAuthority0
, DWORD nSubAuthority1
,
570 DWORD nSubAuthority2
, DWORD nSubAuthority3
,
571 DWORD nSubAuthority4
, DWORD nSubAuthority5
,
572 DWORD nSubAuthority6
, DWORD nSubAuthority7
,
575 return set_ntstatus( RtlAllocateAndInitializeSid(
576 pIdentifierAuthority
, nSubAuthorityCount
,
577 nSubAuthority0
, nSubAuthority1
, nSubAuthority2
, nSubAuthority3
,
578 nSubAuthority4
, nSubAuthority5
, nSubAuthority6
, nSubAuthority7
,
586 * Docs says this function does NOT return a value
587 * even thou it's defined to return a PVOID...
593 return RtlFreeSid(pSid
);
596 /******************************************************************************
597 * CopySid [ADVAPI32.@]
600 * nDestinationSidLength []
605 CopySid( DWORD nDestinationSidLength
, PSID pDestinationSid
, PSID pSourceSid
)
607 return set_ntstatus(RtlCopySid(nDestinationSidLength
, pDestinationSid
, pSourceSid
));
615 CreateWellKnownSid(IN WELL_KNOWN_SID_TYPE WellKnownSidType
,
616 IN PSID DomainSid OPTIONAL
,
621 TRACE("(%d, %s, %p, %p)\n", WellKnownSidType
, debugstr_sid(DomainSid
), pSid
, cbSid
);
623 if (cbSid
== NULL
|| (DomainSid
&& !IsValidSid(DomainSid
)))
625 SetLastError(ERROR_INVALID_PARAMETER
);
629 for (i
= 0; i
< sizeof(WellKnownSids
)/sizeof(WellKnownSids
[0]); i
++) {
630 if (WellKnownSids
[i
].Type
== WellKnownSidType
) {
631 DWORD length
= GetSidLengthRequired(WellKnownSids
[i
].Sid
.SubAuthorityCount
);
636 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
641 SetLastError(ERROR_INVALID_PARAMETER
);
644 CopyMemory(pSid
, &WellKnownSids
[i
].Sid
.Revision
, length
);
650 if (DomainSid
== NULL
|| *GetSidSubAuthorityCount(DomainSid
) == SID_MAX_SUB_AUTHORITIES
)
652 SetLastError(ERROR_INVALID_PARAMETER
);
656 for (i
= 0; i
< sizeof(WellKnownRids
)/sizeof(WellKnownRids
[0]); i
++)
657 if (WellKnownRids
[i
].Type
== WellKnownSidType
) {
658 UCHAR domain_subauth
= *GetSidSubAuthorityCount(DomainSid
);
659 DWORD domain_sid_length
= GetSidLengthRequired(domain_subauth
);
660 DWORD output_sid_length
= GetSidLengthRequired(domain_subauth
+ 1);
662 if (*cbSid
< output_sid_length
)
664 *cbSid
= output_sid_length
;
665 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
670 SetLastError(ERROR_INVALID_PARAMETER
);
673 CopyMemory(pSid
, DomainSid
, domain_sid_length
);
674 (*GetSidSubAuthorityCount(pSid
))++;
675 (*GetSidSubAuthority(pSid
, domain_subauth
)) = WellKnownRids
[i
].Rid
;
676 *cbSid
= output_sid_length
;
680 SetLastError(ERROR_INVALID_PARAMETER
);
689 IsWellKnownSid(IN PSID pSid
,
690 IN WELL_KNOWN_SID_TYPE WellKnownSidType
)
693 TRACE("(%s, %d)\n", debugstr_sid(pSid
), WellKnownSidType
);
695 for (i
= 0; i
< sizeof(WellKnownSids
) / sizeof(WellKnownSids
[0]); i
++)
697 if (WellKnownSids
[i
].Type
== WellKnownSidType
)
699 if (EqualSid(pSid
, (PSID
)(&WellKnownSids
[i
].Sid
.Revision
)))
712 IsValidSid(PSID pSid
)
714 return (BOOL
)RtlValidSid(pSid
);
725 SetLastError(ERROR_SUCCESS
);
726 return RtlEqualSid (pSid1
, pSid2
);
734 EqualPrefixSid(PSID pSid1
,
737 return RtlEqualPrefixSid (pSid1
, pSid2
);
745 GetSidLengthRequired(UCHAR nSubAuthorityCount
)
747 return (DWORD
)RtlLengthRequiredSid(nSubAuthorityCount
);
755 InitializeSid(PSID Sid
,
756 PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority
,
757 BYTE nSubAuthorityCount
)
761 Status
= RtlInitializeSid(Sid
,
762 pIdentifierAuthority
,
764 if (!NT_SUCCESS(Status
))
766 SetLastError(RtlNtStatusToDosError(Status
));
776 PSID_IDENTIFIER_AUTHORITY
778 GetSidIdentifierAuthority(PSID pSid
)
780 return RtlIdentifierAuthoritySid(pSid
);
788 GetSidSubAuthority(PSID pSid
,
791 SetLastError(ERROR_SUCCESS
);
792 return (PDWORD
)RtlSubAuthoritySid(pSid
, nSubAuthority
);
800 GetSidSubAuthorityCount(PSID pSid
)
802 SetLastError(ERROR_SUCCESS
);
803 return RtlSubAuthorityCountSid(pSid
);
811 GetLengthSid(PSID pSid
)
813 return (DWORD
)RtlLengthSid(pSid
);
821 InitializeSecurityDescriptor(PSECURITY_DESCRIPTOR pSecurityDescriptor
,
826 Status
= RtlCreateSecurityDescriptor(pSecurityDescriptor
,
828 if (!NT_SUCCESS(Status
))
830 SetLastError(RtlNtStatusToDosError(Status
));
842 MakeAbsoluteSD(PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor
,
843 PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor
,
844 LPDWORD lpdwAbsoluteSecurityDescriptorSize
,
846 LPDWORD lpdwDaclSize
,
848 LPDWORD lpdwSaclSize
,
850 LPDWORD lpdwOwnerSize
,
852 LPDWORD lpdwPrimaryGroupSize
)
856 Status
= RtlSelfRelativeToAbsoluteSD(pSelfRelativeSecurityDescriptor
,
857 pAbsoluteSecurityDescriptor
,
858 lpdwAbsoluteSecurityDescriptorSize
,
866 lpdwPrimaryGroupSize
);
867 if (!NT_SUCCESS(Status
))
869 SetLastError(RtlNtStatusToDosError(Status
));
876 /******************************************************************************
877 * GetKernelObjectSecurity [ADVAPI32.@]
879 BOOL WINAPI
GetKernelObjectSecurity(
881 SECURITY_INFORMATION RequestedInformation
,
882 PSECURITY_DESCRIPTOR pSecurityDescriptor
,
884 LPDWORD lpnLengthNeeded
)
886 TRACE("(%p,0x%08x,%p,0x%08x,%p)\n", Handle
, RequestedInformation
,
887 pSecurityDescriptor
, nLength
, lpnLengthNeeded
);
889 return set_ntstatus( NtQuerySecurityObject(Handle
, RequestedInformation
, pSecurityDescriptor
,
890 nLength
, lpnLengthNeeded
));
898 InitializeAcl(PACL pAcl
,
904 Status
= RtlCreateAcl(pAcl
,
907 if (!NT_SUCCESS(Status
))
909 SetLastError(RtlNtStatusToDosError(Status
));
916 BOOL WINAPI
ImpersonateNamedPipeClient( HANDLE hNamedPipe
)
918 IO_STATUS_BLOCK io_block
;
920 TRACE("(%p)\n", hNamedPipe
);
922 return set_ntstatus( NtFsControlFile(hNamedPipe
, NULL
, NULL
, NULL
,
923 &io_block
, FSCTL_PIPE_IMPERSONATE
, NULL
, 0, NULL
, 0) );
931 AddAccessAllowedAce(PACL pAcl
,
938 Status
= RtlAddAccessAllowedAce(pAcl
,
942 if (!NT_SUCCESS(Status
))
944 SetLastError(RtlNtStatusToDosError(Status
));
955 AddAccessAllowedAceEx(PACL pAcl
,
963 Status
= RtlAddAccessAllowedAceEx(pAcl
,
968 if (!NT_SUCCESS(Status
))
970 SetLastError(RtlNtStatusToDosError(Status
));
982 AddAccessDeniedAce(PACL pAcl
,
989 Status
= RtlAddAccessDeniedAce(pAcl
,
993 if (!NT_SUCCESS(Status
))
995 SetLastError(RtlNtStatusToDosError(Status
));
1006 AddAccessDeniedAceEx(PACL pAcl
,
1007 DWORD dwAceRevision
,
1014 Status
= RtlAddAccessDeniedAceEx(pAcl
,
1019 if (!NT_SUCCESS(Status
))
1021 SetLastError(RtlNtStatusToDosError(Status
));
1034 DWORD dwAceRevision
,
1035 DWORD dwStartingAceIndex
,
1037 DWORD nAceListLength
)
1041 Status
= RtlAddAce(pAcl
,
1046 if (!NT_SUCCESS(Status
))
1048 SetLastError(RtlNtStatusToDosError(Status
));
1060 DeleteAce(PACL pAcl
,
1065 Status
= RtlDeleteAce(pAcl
,
1067 if (!NT_SUCCESS(Status
))
1069 SetLastError(RtlNtStatusToDosError(Status
));
1081 FindFirstFreeAce(PACL pAcl
,
1084 return RtlFirstFreeAce(pAcl
,
1100 Status
= RtlGetAce(pAcl
,
1103 if (!NT_SUCCESS(Status
))
1105 SetLastError(RtlNtStatusToDosError(Status
));
1117 GetAclInformation(PACL pAcl
,
1118 LPVOID pAclInformation
,
1119 DWORD nAclInformationLength
,
1120 ACL_INFORMATION_CLASS dwAclInformationClass
)
1124 Status
= RtlQueryInformationAcl(pAcl
,
1126 nAclInformationLength
,
1127 dwAclInformationClass
);
1128 if (!NT_SUCCESS(Status
))
1130 SetLastError(RtlNtStatusToDosError(Status
));
1142 IsValidAcl(PACL pAcl
)
1144 return RtlValidAcl (pAcl
);
1151 AllocateLocallyUniqueId(PLUID Luid
)
1155 Status
= NtAllocateLocallyUniqueId (Luid
);
1156 if (!NT_SUCCESS (Status
))
1158 SetLastError(RtlNtStatusToDosError(Status
));
1165 /**********************************************************************
1166 * LookupPrivilegeDisplayNameA EXPORTED
1172 LookupPrivilegeDisplayNameA(LPCSTR lpSystemName
,
1174 LPSTR lpDisplayName
,
1175 LPDWORD cbDisplayName
,
1176 LPDWORD lpLanguageId
)
1178 FIXME("%s() not implemented!\n", __FUNCTION__
);
1179 SetLastError (ERROR_CALL_NOT_IMPLEMENTED
);
1184 /**********************************************************************
1185 * LookupPrivilegeDisplayNameW EXPORTED
1191 LookupPrivilegeDisplayNameW(LPCWSTR lpSystemName
,
1193 LPWSTR lpDisplayName
,
1194 LPDWORD cbDisplayName
,
1195 LPDWORD lpLanguageId
)
1197 FIXME("%s() not implemented!\n", __FUNCTION__
);
1198 SetLastError (ERROR_CALL_NOT_IMPLEMENTED
);
1202 /**********************************************************************
1203 * LookupPrivilegeNameA EXPORTED
1209 LookupPrivilegeNameA(LPCSTR lpSystemName
,
1214 UNICODE_STRING lpSystemNameW
;
1218 TRACE("%s %p %p %p\n", debugstr_a(lpSystemName
), lpLuid
, lpName
, cchName
);
1220 RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW
, lpSystemName
);
1221 ret
= LookupPrivilegeNameW(lpSystemNameW
.Buffer
, lpLuid
, NULL
, &wLen
);
1222 if (!ret
&& GetLastError() == ERROR_INSUFFICIENT_BUFFER
)
1224 LPWSTR lpNameW
= HeapAlloc(GetProcessHeap(), 0, wLen
* sizeof(WCHAR
));
1226 ret
= LookupPrivilegeNameW(lpSystemNameW
.Buffer
, lpLuid
, lpNameW
,
1230 /* Windows crashes if cchName is NULL, so will I */
1231 unsigned int len
= WideCharToMultiByte(CP_ACP
, 0, lpNameW
, -1, lpName
,
1232 *cchName
, NULL
, NULL
);
1236 /* WideCharToMultiByte failed */
1239 else if (len
> *cchName
)
1242 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
1247 /* WideCharToMultiByte succeeded, output length needs to be
1248 * length not including NULL terminator
1253 HeapFree(GetProcessHeap(), 0, lpNameW
);
1255 RtlFreeUnicodeString(&lpSystemNameW
);
1259 /******************************************************************************
1260 * GetFileSecurityA [ADVAPI32.@]
1262 * Obtains Specified information about the security of a file or directory.
1265 * lpFileName [I] Name of the file to get info for
1266 * RequestedInformation [I] SE_ flags from "winnt.h"
1267 * pSecurityDescriptor [O] Destination for security information
1268 * nLength [I] Length of pSecurityDescriptor
1269 * lpnLengthNeeded [O] Destination for length of returned security information
1272 * Success: TRUE. pSecurityDescriptor contains the requested information.
1273 * Failure: FALSE. lpnLengthNeeded contains the required space to return the info.
1276 * The information returned is constrained by the callers access rights and
1283 GetFileSecurityA(LPCSTR lpFileName
,
1284 SECURITY_INFORMATION RequestedInformation
,
1285 PSECURITY_DESCRIPTOR pSecurityDescriptor
,
1287 LPDWORD lpnLengthNeeded
)
1289 UNICODE_STRING FileName
;
1292 if (!RtlCreateUnicodeStringFromAsciiz(&FileName
, lpFileName
))
1294 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
1298 bResult
= GetFileSecurityW(FileName
.Buffer
,
1299 RequestedInformation
,
1300 pSecurityDescriptor
,
1304 RtlFreeUnicodeString(&FileName
);
1314 GetFileSecurityW(LPCWSTR lpFileName
,
1315 SECURITY_INFORMATION RequestedInformation
,
1316 PSECURITY_DESCRIPTOR pSecurityDescriptor
,
1318 LPDWORD lpnLengthNeeded
)
1320 OBJECT_ATTRIBUTES ObjectAttributes
;
1321 IO_STATUS_BLOCK StatusBlock
;
1322 UNICODE_STRING FileName
;
1323 ULONG AccessMask
= 0;
1327 TRACE("GetFileSecurityW() called\n");
1329 QuerySecurityAccessMask(RequestedInformation
, &AccessMask
);
1331 if (!RtlDosPathNameToNtPathName_U(lpFileName
,
1336 ERR("Invalid path\n");
1337 SetLastError(ERROR_INVALID_NAME
);
1341 InitializeObjectAttributes(&ObjectAttributes
,
1343 OBJ_CASE_INSENSITIVE
,
1347 Status
= NtOpenFile(&FileHandle
,
1351 FILE_SHARE_READ
| FILE_SHARE_WRITE
| FILE_SHARE_DELETE
,
1354 RtlFreeHeap(RtlGetProcessHeap(),
1358 if (!NT_SUCCESS(Status
))
1360 ERR("NtOpenFile() failed (Status %lx)\n", Status
);
1361 SetLastError(RtlNtStatusToDosError(Status
));
1365 Status
= NtQuerySecurityObject(FileHandle
,
1366 RequestedInformation
,
1367 pSecurityDescriptor
,
1370 NtClose(FileHandle
);
1371 if (!NT_SUCCESS(Status
))
1373 ERR("NtQuerySecurityObject() failed (Status %lx)\n", Status
);
1374 SetLastError(RtlNtStatusToDosError(Status
));
1381 /******************************************************************************
1382 * SetFileSecurityA [ADVAPI32.@]
1383 * Sets the security of a file or directory
1389 SetFileSecurityA(LPCSTR lpFileName
,
1390 SECURITY_INFORMATION SecurityInformation
,
1391 PSECURITY_DESCRIPTOR pSecurityDescriptor
)
1393 UNICODE_STRING FileName
;
1396 if (!RtlCreateUnicodeStringFromAsciiz(&FileName
, lpFileName
))
1398 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
1402 bResult
= SetFileSecurityW(FileName
.Buffer
,
1403 SecurityInformation
,
1404 pSecurityDescriptor
);
1406 RtlFreeUnicodeString(&FileName
);
1411 /******************************************************************************
1412 * SetFileSecurityW [ADVAPI32.@]
1413 * Sets the security of a file or directory
1419 SetFileSecurityW(LPCWSTR lpFileName
,
1420 SECURITY_INFORMATION SecurityInformation
,
1421 PSECURITY_DESCRIPTOR pSecurityDescriptor
)
1423 OBJECT_ATTRIBUTES ObjectAttributes
;
1424 IO_STATUS_BLOCK StatusBlock
;
1425 UNICODE_STRING FileName
;
1426 ULONG AccessMask
= 0;
1430 TRACE("SetFileSecurityW() called\n");
1432 SetSecurityAccessMask(SecurityInformation
, &AccessMask
);
1434 if (!RtlDosPathNameToNtPathName_U(lpFileName
,
1439 ERR("Invalid path\n");
1440 SetLastError(ERROR_INVALID_NAME
);
1444 InitializeObjectAttributes(&ObjectAttributes
,
1446 OBJ_CASE_INSENSITIVE
,
1450 Status
= NtOpenFile(&FileHandle
,
1454 FILE_SHARE_READ
| FILE_SHARE_WRITE
| FILE_SHARE_DELETE
,
1457 RtlFreeHeap(RtlGetProcessHeap(),
1461 if (!NT_SUCCESS(Status
))
1463 ERR("NtOpenFile() failed (Status %lx)\n", Status
);
1464 SetLastError(RtlNtStatusToDosError(Status
));
1468 Status
= NtSetSecurityObject(FileHandle
,
1469 SecurityInformation
,
1470 pSecurityDescriptor
);
1471 NtClose(FileHandle
);
1473 if (!NT_SUCCESS(Status
))
1475 ERR("NtSetSecurityObject() failed (Status %lx)\n", Status
);
1476 SetLastError(RtlNtStatusToDosError(Status
));
1483 /******************************************************************************
1484 * QueryWindows31FilesMigration [ADVAPI32.@]
1490 QueryWindows31FilesMigration( DWORD x1
)
1492 FIXME("(%d):stub\n",x1
);
1496 /******************************************************************************
1497 * SynchronizeWindows31FilesAndWindowsNTRegistry [ADVAPI32.@]
1506 SynchronizeWindows31FilesAndWindowsNTRegistry( DWORD x1
, DWORD x2
, DWORD x3
,
1509 FIXME("(0x%08x,0x%08x,0x%08x,0x%08x):stub\n",x1
,x2
,x3
,x4
);
1521 HANDLE Token
= NULL
;
1523 Status
= NtSetInformationThread(NtCurrentThread(),
1524 ThreadImpersonationToken
,
1527 if (!NT_SUCCESS(Status
))
1529 SetLastError(RtlNtStatusToDosError(Status
));
1541 ImpersonateSelf(SECURITY_IMPERSONATION_LEVEL ImpersonationLevel
)
1545 Status
= RtlImpersonateSelf(ImpersonationLevel
);
1546 if (!NT_SUCCESS(Status
))
1548 SetLastError(RtlNtStatusToDosError(Status
));
1560 AccessCheck(IN PSECURITY_DESCRIPTOR pSecurityDescriptor
,
1561 IN HANDLE ClientToken
,
1562 IN DWORD DesiredAccess
,
1563 IN PGENERIC_MAPPING GenericMapping
,
1564 OUT PPRIVILEGE_SET PrivilegeSet OPTIONAL
,
1565 IN OUT LPDWORD PrivilegeSetLength
,
1566 OUT LPDWORD GrantedAccess
,
1567 OUT LPBOOL AccessStatus
)
1570 NTSTATUS NtAccessStatus
;
1572 /* Do the access check */
1573 Status
= NtAccessCheck(pSecurityDescriptor
,
1578 (PULONG
)PrivilegeSetLength
,
1579 (PACCESS_MASK
)GrantedAccess
,
1582 /* See if the access check operation succeeded */
1583 if (!NT_SUCCESS(Status
))
1586 SetLastError(RtlNtStatusToDosError(Status
));
1590 /* Now check the access status */
1591 if (!NT_SUCCESS(NtAccessStatus
))
1594 SetLastError(RtlNtStatusToDosError(NtAccessStatus
));
1595 *AccessStatus
= FALSE
;
1599 /* Access granted */
1600 *AccessStatus
= TRUE
;
1603 /* Check succeeded */
1610 BOOL WINAPI
AccessCheckByType(
1611 PSECURITY_DESCRIPTOR pSecurityDescriptor
,
1612 PSID PrincipalSelfSid
,
1614 DWORD DesiredAccess
,
1615 POBJECT_TYPE_LIST ObjectTypeList
,
1616 DWORD ObjectTypeListLength
,
1617 PGENERIC_MAPPING GenericMapping
,
1618 PPRIVILEGE_SET PrivilegeSet
,
1619 LPDWORD PrivilegeSetLength
,
1620 LPDWORD GrantedAccess
,
1621 LPBOOL AccessStatus
)
1625 *AccessStatus
= TRUE
;
1627 return !*AccessStatus
;
1635 SetKernelObjectSecurity(HANDLE Handle
,
1636 SECURITY_INFORMATION SecurityInformation
,
1637 PSECURITY_DESCRIPTOR SecurityDescriptor
)
1641 Status
= NtSetSecurityObject(Handle
,
1642 SecurityInformation
,
1643 SecurityDescriptor
);
1644 if (!NT_SUCCESS(Status
))
1646 SetLastError(RtlNtStatusToDosError(Status
));
1658 AddAuditAccessAce(PACL pAcl
,
1659 DWORD dwAceRevision
,
1667 Status
= RtlAddAuditAccessAce(pAcl
,
1673 if (!NT_SUCCESS(Status
))
1675 SetLastError(RtlNtStatusToDosError(Status
));
1686 AddAuditAccessAceEx(PACL pAcl
,
1687 DWORD dwAceRevision
,
1696 Status
= RtlAddAuditAccessAceEx(pAcl
,
1703 if (!NT_SUCCESS(Status
))
1705 SetLastError(RtlNtStatusToDosError(Status
));
1712 /******************************************************************************
1713 * LookupAccountNameA [ADVAPI32.@]
1719 LookupAccountNameA(LPCSTR SystemName
,
1723 LPSTR ReferencedDomainName
,
1724 LPDWORD hReferencedDomainNameLength
,
1725 PSID_NAME_USE SidNameUse
)
1728 UNICODE_STRING lpSystemW
;
1729 UNICODE_STRING lpAccountW
;
1730 LPWSTR lpReferencedDomainNameW
= NULL
;
1732 RtlCreateUnicodeStringFromAsciiz(&lpSystemW
, SystemName
);
1733 RtlCreateUnicodeStringFromAsciiz(&lpAccountW
, AccountName
);
1735 if (ReferencedDomainName
)
1736 lpReferencedDomainNameW
= HeapAlloc(GetProcessHeap(),
1738 *hReferencedDomainNameLength
* sizeof(WCHAR
));
1740 ret
= LookupAccountNameW(lpSystemW
.Buffer
,
1744 lpReferencedDomainNameW
,
1745 hReferencedDomainNameLength
,
1748 if (ret
&& lpReferencedDomainNameW
)
1750 WideCharToMultiByte(CP_ACP
,
1752 lpReferencedDomainNameW
,
1753 *hReferencedDomainNameLength
+ 1,
1754 ReferencedDomainName
,
1755 *hReferencedDomainNameLength
+ 1,
1760 RtlFreeUnicodeString(&lpSystemW
);
1761 RtlFreeUnicodeString(&lpAccountW
);
1762 HeapFree(GetProcessHeap(), 0, lpReferencedDomainNameW
);
1767 /**********************************************************************
1768 * PrivilegeCheck EXPORTED
1773 PrivilegeCheck(HANDLE ClientToken
,
1774 PPRIVILEGE_SET RequiredPrivileges
,
1780 Status
= NtPrivilegeCheck(ClientToken
,
1783 if (!NT_SUCCESS(Status
))
1785 SetLastError(RtlNtStatusToDosError(Status
));
1789 *pfResult
= (BOOL
)Result
;
1794 /******************************************************************************
1795 * GetSecurityInfoExW EXPORTED
1799 GetSecurityInfoExA(HANDLE hObject
,
1800 SE_OBJECT_TYPE ObjectType
,
1801 SECURITY_INFORMATION SecurityInfo
,
1804 PACTRL_ACCESSA
*ppAccessList
,
1805 PACTRL_AUDITA
*ppAuditList
,
1809 FIXME("%s() not implemented!\n", __FUNCTION__
);
1810 return ERROR_BAD_PROVIDER
;
1814 /******************************************************************************
1815 * GetSecurityInfoExW EXPORTED
1819 GetSecurityInfoExW(HANDLE hObject
,
1820 SE_OBJECT_TYPE ObjectType
,
1821 SECURITY_INFORMATION SecurityInfo
,
1824 PACTRL_ACCESSW
*ppAccessList
,
1825 PACTRL_AUDITW
*ppAuditList
,
1829 FIXME("%s() not implemented!\n", __FUNCTION__
);
1830 return ERROR_BAD_PROVIDER
;
1833 /******************************************************************************
1834 * BuildExplicitAccessWithNameA [ADVAPI32.@]
1837 BuildExplicitAccessWithNameA(PEXPLICIT_ACCESSA pExplicitAccess
,
1839 DWORD AccessPermissions
,
1840 ACCESS_MODE AccessMode
,
1843 pExplicitAccess
->grfAccessPermissions
= AccessPermissions
;
1844 pExplicitAccess
->grfAccessMode
= AccessMode
;
1845 pExplicitAccess
->grfInheritance
= Inheritance
;
1847 pExplicitAccess
->Trustee
.pMultipleTrustee
= NULL
;
1848 pExplicitAccess
->Trustee
.MultipleTrusteeOperation
= NO_MULTIPLE_TRUSTEE
;
1849 pExplicitAccess
->Trustee
.TrusteeForm
= TRUSTEE_IS_NAME
;
1850 pExplicitAccess
->Trustee
.TrusteeType
= TRUSTEE_IS_UNKNOWN
;
1851 pExplicitAccess
->Trustee
.ptstrName
= pTrusteeName
;
1855 /******************************************************************************
1856 * BuildExplicitAccessWithNameW [ADVAPI32.@]
1859 BuildExplicitAccessWithNameW(PEXPLICIT_ACCESSW pExplicitAccess
,
1860 LPWSTR pTrusteeName
,
1861 DWORD AccessPermissions
,
1862 ACCESS_MODE AccessMode
,
1865 pExplicitAccess
->grfAccessPermissions
= AccessPermissions
;
1866 pExplicitAccess
->grfAccessMode
= AccessMode
;
1867 pExplicitAccess
->grfInheritance
= Inheritance
;
1869 pExplicitAccess
->Trustee
.pMultipleTrustee
= NULL
;
1870 pExplicitAccess
->Trustee
.MultipleTrusteeOperation
= NO_MULTIPLE_TRUSTEE
;
1871 pExplicitAccess
->Trustee
.TrusteeForm
= TRUSTEE_IS_NAME
;
1872 pExplicitAccess
->Trustee
.TrusteeType
= TRUSTEE_IS_UNKNOWN
;
1873 pExplicitAccess
->Trustee
.ptstrName
= pTrusteeName
;
1876 /******************************************************************************
1877 * BuildTrusteeWithObjectsAndNameA [ADVAPI32.@]
1879 VOID WINAPI
BuildTrusteeWithObjectsAndNameA( PTRUSTEEA pTrustee
, POBJECTS_AND_NAME_A pObjName
,
1880 SE_OBJECT_TYPE ObjectType
, LPSTR ObjectTypeName
,
1881 LPSTR InheritedObjectTypeName
, LPSTR Name
)
1883 DWORD ObjectsPresent
= 0;
1885 TRACE("%p %p 0x%08x %p %p %s\n", pTrustee
, pObjName
,
1886 ObjectType
, ObjectTypeName
, InheritedObjectTypeName
, debugstr_a(Name
));
1888 /* Fill the OBJECTS_AND_NAME structure */
1889 pObjName
->ObjectType
= ObjectType
;
1890 if (ObjectTypeName
!= NULL
)
1892 ObjectsPresent
|= ACE_OBJECT_TYPE_PRESENT
;
1895 pObjName
->InheritedObjectTypeName
= InheritedObjectTypeName
;
1896 if (InheritedObjectTypeName
!= NULL
)
1898 ObjectsPresent
|= ACE_INHERITED_OBJECT_TYPE_PRESENT
;
1901 pObjName
->ObjectsPresent
= ObjectsPresent
;
1902 pObjName
->ptstrName
= Name
;
1904 /* Fill the TRUSTEE structure */
1905 pTrustee
->pMultipleTrustee
= NULL
;
1906 pTrustee
->MultipleTrusteeOperation
= NO_MULTIPLE_TRUSTEE
;
1907 pTrustee
->TrusteeForm
= TRUSTEE_IS_OBJECTS_AND_NAME
;
1908 pTrustee
->TrusteeType
= TRUSTEE_IS_UNKNOWN
;
1909 pTrustee
->ptstrName
= (LPSTR
)pObjName
;
1912 /******************************************************************************
1913 * BuildTrusteeWithObjectsAndNameW [ADVAPI32.@]
1915 VOID WINAPI
BuildTrusteeWithObjectsAndNameW( PTRUSTEEW pTrustee
, POBJECTS_AND_NAME_W pObjName
,
1916 SE_OBJECT_TYPE ObjectType
, LPWSTR ObjectTypeName
,
1917 LPWSTR InheritedObjectTypeName
, LPWSTR Name
)
1919 DWORD ObjectsPresent
= 0;
1921 TRACE("%p %p 0x%08x %p %p %s\n", pTrustee
, pObjName
,
1922 ObjectType
, ObjectTypeName
, InheritedObjectTypeName
, debugstr_w(Name
));
1924 /* Fill the OBJECTS_AND_NAME structure */
1925 pObjName
->ObjectType
= ObjectType
;
1926 if (ObjectTypeName
!= NULL
)
1928 ObjectsPresent
|= ACE_OBJECT_TYPE_PRESENT
;
1931 pObjName
->InheritedObjectTypeName
= InheritedObjectTypeName
;
1932 if (InheritedObjectTypeName
!= NULL
)
1934 ObjectsPresent
|= ACE_INHERITED_OBJECT_TYPE_PRESENT
;
1937 pObjName
->ObjectsPresent
= ObjectsPresent
;
1938 pObjName
->ptstrName
= Name
;
1940 /* Fill the TRUSTEE structure */
1941 pTrustee
->pMultipleTrustee
= NULL
;
1942 pTrustee
->MultipleTrusteeOperation
= NO_MULTIPLE_TRUSTEE
;
1943 pTrustee
->TrusteeForm
= TRUSTEE_IS_OBJECTS_AND_NAME
;
1944 pTrustee
->TrusteeType
= TRUSTEE_IS_UNKNOWN
;
1945 pTrustee
->ptstrName
= (LPWSTR
)pObjName
;
1948 /******************************************************************************
1949 * BuildTrusteeWithObjectsAndSidA [ADVAPI32.@]
1952 BuildTrusteeWithObjectsAndSidA(PTRUSTEEA pTrustee
,
1953 POBJECTS_AND_SID pObjSid
,
1955 GUID
*pInheritedObjectGuid
,
1958 DWORD ObjectsPresent
= 0;
1960 TRACE("%p %p %p %p %p\n", pTrustee
, pObjSid
, pObjectGuid
, pInheritedObjectGuid
, pSid
);
1962 /* Fill the OBJECTS_AND_SID structure */
1963 if (pObjectGuid
!= NULL
)
1965 pObjSid
->ObjectTypeGuid
= *pObjectGuid
;
1966 ObjectsPresent
|= ACE_OBJECT_TYPE_PRESENT
;
1970 ZeroMemory(&pObjSid
->ObjectTypeGuid
,
1974 if (pInheritedObjectGuid
!= NULL
)
1976 pObjSid
->InheritedObjectTypeGuid
= *pInheritedObjectGuid
;
1977 ObjectsPresent
|= ACE_INHERITED_OBJECT_TYPE_PRESENT
;
1981 ZeroMemory(&pObjSid
->InheritedObjectTypeGuid
,
1985 pObjSid
->ObjectsPresent
= ObjectsPresent
;
1986 pObjSid
->pSid
= pSid
;
1988 /* Fill the TRUSTEE structure */
1989 pTrustee
->pMultipleTrustee
= NULL
;
1990 pTrustee
->MultipleTrusteeOperation
= NO_MULTIPLE_TRUSTEE
;
1991 pTrustee
->TrusteeForm
= TRUSTEE_IS_OBJECTS_AND_SID
;
1992 pTrustee
->TrusteeType
= TRUSTEE_IS_UNKNOWN
;
1993 pTrustee
->ptstrName
= (LPSTR
) pObjSid
;
1997 /******************************************************************************
1998 * BuildTrusteeWithObjectsAndSidW [ADVAPI32.@]
2001 BuildTrusteeWithObjectsAndSidW(PTRUSTEEW pTrustee
,
2002 POBJECTS_AND_SID pObjSid
,
2004 GUID
*pInheritedObjectGuid
,
2007 DWORD ObjectsPresent
= 0;
2009 TRACE("%p %p %p %p %p\n", pTrustee
, pObjSid
, pObjectGuid
, pInheritedObjectGuid
, pSid
);
2011 /* Fill the OBJECTS_AND_SID structure */
2012 if (pObjectGuid
!= NULL
)
2014 pObjSid
->ObjectTypeGuid
= *pObjectGuid
;
2015 ObjectsPresent
|= ACE_OBJECT_TYPE_PRESENT
;
2019 ZeroMemory(&pObjSid
->ObjectTypeGuid
,
2023 if (pInheritedObjectGuid
!= NULL
)
2025 pObjSid
->InheritedObjectTypeGuid
= *pInheritedObjectGuid
;
2026 ObjectsPresent
|= ACE_INHERITED_OBJECT_TYPE_PRESENT
;
2030 ZeroMemory(&pObjSid
->InheritedObjectTypeGuid
,
2034 pObjSid
->ObjectsPresent
= ObjectsPresent
;
2035 pObjSid
->pSid
= pSid
;
2037 /* Fill the TRUSTEE structure */
2038 pTrustee
->pMultipleTrustee
= NULL
;
2039 pTrustee
->MultipleTrusteeOperation
= NO_MULTIPLE_TRUSTEE
;
2040 pTrustee
->TrusteeForm
= TRUSTEE_IS_OBJECTS_AND_SID
;
2041 pTrustee
->TrusteeType
= TRUSTEE_IS_UNKNOWN
;
2042 pTrustee
->ptstrName
= (LPWSTR
) pObjSid
;
2045 /******************************************************************************
2046 * BuildTrusteeWithSidA [ADVAPI32.@]
2049 BuildTrusteeWithSidA(PTRUSTEE_A pTrustee
,
2052 TRACE("%p %p\n", pTrustee
, pSid
);
2054 pTrustee
->pMultipleTrustee
= NULL
;
2055 pTrustee
->MultipleTrusteeOperation
= NO_MULTIPLE_TRUSTEE
;
2056 pTrustee
->TrusteeForm
= TRUSTEE_IS_SID
;
2057 pTrustee
->TrusteeType
= TRUSTEE_IS_UNKNOWN
;
2058 pTrustee
->ptstrName
= (LPSTR
) pSid
;
2062 /******************************************************************************
2063 * BuildTrusteeWithSidW [ADVAPI32.@]
2066 BuildTrusteeWithSidW(PTRUSTEE_W pTrustee
,
2069 TRACE("%p %p\n", pTrustee
, pSid
);
2071 pTrustee
->pMultipleTrustee
= NULL
;
2072 pTrustee
->MultipleTrusteeOperation
= NO_MULTIPLE_TRUSTEE
;
2073 pTrustee
->TrusteeForm
= TRUSTEE_IS_SID
;
2074 pTrustee
->TrusteeType
= TRUSTEE_IS_UNKNOWN
;
2075 pTrustee
->ptstrName
= (LPWSTR
) pSid
;
2078 /******************************************************************************
2079 * BuildTrusteeWithNameA [ADVAPI32.@]
2082 BuildTrusteeWithNameA(PTRUSTEE_A pTrustee
,
2085 TRACE("%p %s\n", pTrustee
, name
);
2087 pTrustee
->pMultipleTrustee
= NULL
;
2088 pTrustee
->MultipleTrusteeOperation
= NO_MULTIPLE_TRUSTEE
;
2089 pTrustee
->TrusteeForm
= TRUSTEE_IS_NAME
;
2090 pTrustee
->TrusteeType
= TRUSTEE_IS_UNKNOWN
;
2091 pTrustee
->ptstrName
= name
;
2094 /******************************************************************************
2095 * BuildTrusteeWithNameW [ADVAPI32.@]
2098 BuildTrusteeWithNameW(PTRUSTEE_W pTrustee
,
2101 TRACE("%p %s\n", pTrustee
, name
);
2103 pTrustee
->pMultipleTrustee
= NULL
;
2104 pTrustee
->MultipleTrusteeOperation
= NO_MULTIPLE_TRUSTEE
;
2105 pTrustee
->TrusteeForm
= TRUSTEE_IS_NAME
;
2106 pTrustee
->TrusteeType
= TRUSTEE_IS_UNKNOWN
;
2107 pTrustee
->ptstrName
= name
;
2110 /******************************************************************************
2111 * GetTrusteeFormW [ADVAPI32.@]
2114 GetTrusteeFormA(PTRUSTEE_A pTrustee
)
2116 return pTrustee
->TrusteeForm
;
2120 /******************************************************************************
2121 * GetTrusteeFormW [ADVAPI32.@]
2124 GetTrusteeFormW(PTRUSTEE_W pTrustee
)
2126 return pTrustee
->TrusteeForm
;
2129 /******************************************************************************
2130 * GetTrusteeNameA [ADVAPI32.@]
2133 GetTrusteeNameA(PTRUSTEE_A pTrustee
)
2135 return pTrustee
->ptstrName
;
2139 /******************************************************************************
2140 * GetTrusteeNameW [ADVAPI32.@]
2143 GetTrusteeNameW(PTRUSTEE_W pTrustee
)
2145 return pTrustee
->ptstrName
;
2148 /******************************************************************************
2149 * GetTrusteeTypeA [ADVAPI32.@]
2152 GetTrusteeTypeA(PTRUSTEE_A pTrustee
)
2154 return pTrustee
->TrusteeType
;
2157 /******************************************************************************
2158 * GetTrusteeTypeW [ADVAPI32.@]
2161 GetTrusteeTypeW(PTRUSTEE_W pTrustee
)
2163 return pTrustee
->TrusteeType
;
2171 SetAclInformation(PACL pAcl
,
2172 LPVOID pAclInformation
,
2173 DWORD nAclInformationLength
,
2174 ACL_INFORMATION_CLASS dwAclInformationClass
)
2178 Status
= RtlSetInformationAcl(pAcl
,
2180 nAclInformationLength
,
2181 dwAclInformationClass
);
2182 if (!NT_SUCCESS(Status
))
2184 SetLastError(RtlNtStatusToDosError(Status
));
2191 /**********************************************************************
2192 * SetNamedSecurityInfoA EXPORTED
2198 SetNamedSecurityInfoA(LPSTR pObjectName
,
2199 SE_OBJECT_TYPE ObjectType
,
2200 SECURITY_INFORMATION SecurityInfo
,
2206 UNICODE_STRING ObjectName
;
2209 if (!RtlCreateUnicodeStringFromAsciiz(&ObjectName
, pObjectName
))
2211 return ERROR_NOT_ENOUGH_MEMORY
;
2214 Ret
= SetNamedSecurityInfoW(ObjectName
.Buffer
,
2222 RtlFreeUnicodeString(&ObjectName
);
2232 AreAllAccessesGranted(DWORD GrantedAccess
,
2233 DWORD DesiredAccess
)
2235 return (BOOL
)RtlAreAllAccessesGranted(GrantedAccess
,
2244 AreAnyAccessesGranted(DWORD GrantedAccess
,
2245 DWORD DesiredAccess
)
2247 return (BOOL
)RtlAreAnyAccessesGranted(GrantedAccess
,
2251 /******************************************************************************
2252 * ParseAclStringFlags
2254 static DWORD
ParseAclStringFlags(LPCWSTR
* StringAcl
)
2257 LPCWSTR szAcl
= *StringAcl
;
2259 while (*szAcl
!= '(')
2263 flags
|= SE_DACL_PROTECTED
;
2265 else if (*szAcl
== 'A')
2269 flags
|= SE_DACL_AUTO_INHERIT_REQ
;
2270 else if (*szAcl
== 'I')
2271 flags
|= SE_DACL_AUTO_INHERITED
;
2280 /******************************************************************************
2281 * ParseAceStringType
2283 static const ACEFLAG AceType
[] =
2285 { SDDL_ALARM
, SYSTEM_ALARM_ACE_TYPE
},
2286 { SDDL_AUDIT
, SYSTEM_AUDIT_ACE_TYPE
},
2287 { SDDL_ACCESS_ALLOWED
, ACCESS_ALLOWED_ACE_TYPE
},
2288 { SDDL_ACCESS_DENIED
, ACCESS_DENIED_ACE_TYPE
},
2290 { SDDL_OBJECT_ACCESS_ALLOWED, ACCESS_ALLOWED_OBJECT_ACE_TYPE },
2291 { SDDL_OBJECT_ACCESS_DENIED, ACCESS_DENIED_OBJECT_ACE_TYPE },
2292 { SDDL_OBJECT_ALARM, SYSTEM_ALARM_OBJECT_ACE_TYPE },
2293 { SDDL_OBJECT_AUDIT, SYSTEM_AUDIT_OBJECT_ACE_TYPE },
2298 static BYTE
ParseAceStringType(LPCWSTR
* StringAcl
)
2301 LPCWSTR szAcl
= *StringAcl
;
2302 const ACEFLAG
*lpaf
= AceType
;
2304 while (*szAcl
== ' ')
2307 while (lpaf
->wstr
&&
2308 (len
= strlenW(lpaf
->wstr
)) &&
2309 strncmpW(lpaf
->wstr
, szAcl
, len
))
2315 *StringAcl
= szAcl
+ len
;
2320 /******************************************************************************
2321 * ParseAceStringFlags
2323 static const ACEFLAG AceFlags
[] =
2325 { SDDL_CONTAINER_INHERIT
, CONTAINER_INHERIT_ACE
},
2326 { SDDL_AUDIT_FAILURE
, FAILED_ACCESS_ACE_FLAG
},
2327 { SDDL_INHERITED
, INHERITED_ACE
},
2328 { SDDL_INHERIT_ONLY
, INHERIT_ONLY_ACE
},
2329 { SDDL_NO_PROPAGATE
, NO_PROPAGATE_INHERIT_ACE
},
2330 { SDDL_OBJECT_INHERIT
, OBJECT_INHERIT_ACE
},
2331 { SDDL_AUDIT_SUCCESS
, SUCCESSFUL_ACCESS_ACE_FLAG
},
2335 static BYTE
ParseAceStringFlags(LPCWSTR
* StringAcl
)
2339 LPCWSTR szAcl
= *StringAcl
;
2341 while (*szAcl
== ' ')
2344 while (*szAcl
!= ';')
2346 const ACEFLAG
*lpaf
= AceFlags
;
2348 while (lpaf
->wstr
&&
2349 (len
= strlenW(lpaf
->wstr
)) &&
2350 strncmpW(lpaf
->wstr
, szAcl
, len
))
2356 flags
|= lpaf
->value
;
2365 /******************************************************************************
2366 * ParseAceStringRights
2368 static const ACEFLAG AceRights
[] =
2370 { SDDL_GENERIC_ALL
, GENERIC_ALL
},
2371 { SDDL_GENERIC_READ
, GENERIC_READ
},
2372 { SDDL_GENERIC_WRITE
, GENERIC_WRITE
},
2373 { SDDL_GENERIC_EXECUTE
, GENERIC_EXECUTE
},
2375 { SDDL_READ_CONTROL
, READ_CONTROL
},
2376 { SDDL_STANDARD_DELETE
, DELETE
},
2377 { SDDL_WRITE_DAC
, WRITE_DAC
},
2378 { SDDL_WRITE_OWNER
, WRITE_OWNER
},
2380 { SDDL_READ_PROPERTY
, ADS_RIGHT_DS_READ_PROP
},
2381 { SDDL_WRITE_PROPERTY
, ADS_RIGHT_DS_WRITE_PROP
},
2382 { SDDL_CREATE_CHILD
, ADS_RIGHT_DS_CREATE_CHILD
},
2383 { SDDL_DELETE_CHILD
, ADS_RIGHT_DS_DELETE_CHILD
},
2384 { SDDL_LIST_CHILDREN
, ADS_RIGHT_ACTRL_DS_LIST
},
2385 { SDDL_SELF_WRITE
, ADS_RIGHT_DS_SELF
},
2386 { SDDL_LIST_OBJECT
, ADS_RIGHT_DS_LIST_OBJECT
},
2387 { SDDL_DELETE_TREE
, ADS_RIGHT_DS_DELETE_TREE
},
2388 { SDDL_CONTROL_ACCESS
, ADS_RIGHT_DS_CONTROL_ACCESS
},
2390 { SDDL_FILE_ALL
, FILE_ALL_ACCESS
},
2391 { SDDL_FILE_READ
, FILE_GENERIC_READ
},
2392 { SDDL_FILE_WRITE
, FILE_GENERIC_WRITE
},
2393 { SDDL_FILE_EXECUTE
, FILE_GENERIC_EXECUTE
},
2395 { SDDL_KEY_ALL
, KEY_ALL_ACCESS
},
2396 { SDDL_KEY_READ
, KEY_READ
},
2397 { SDDL_KEY_WRITE
, KEY_WRITE
},
2398 { SDDL_KEY_EXECUTE
, KEY_EXECUTE
},
2402 static DWORD
ParseAceStringRights(LPCWSTR
* StringAcl
)
2406 LPCWSTR szAcl
= *StringAcl
;
2408 while (*szAcl
== ' ')
2411 if ((*szAcl
== '0') && (*(szAcl
+ 1) == 'x'))
2415 while (*p
&& *p
!= ';')
2418 if (p
- szAcl
<= 10 /* 8 hex digits + "0x" */ )
2420 rights
= strtoulW(szAcl
, NULL
, 16);
2424 WARN("Invalid rights string format: %s\n", debugstr_wn(szAcl
, p
- szAcl
));
2428 while (*szAcl
!= ';')
2430 const ACEFLAG
*lpaf
= AceRights
;
2432 while (lpaf
->wstr
&&
2433 (len
= strlenW(lpaf
->wstr
)) &&
2434 strncmpW(lpaf
->wstr
, szAcl
, len
))
2442 rights
|= lpaf
->value
;
2452 /******************************************************************************
2453 * ParseStringAclToAcl
2455 * dacl_flags(string_ace1)(string_ace2)... (string_acen)
2457 static BOOL
ParseStringAclToAcl(LPCWSTR StringAcl
, LPDWORD lpdwFlags
,
2458 PACL pAcl
, LPDWORD cBytes
)
2462 DWORD length
= sizeof(ACL
);
2465 PACCESS_ALLOWED_ACE pAce
= NULL
; /* pointer to current ACE */
2466 DWORD error
= ERROR_INVALID_ACL
;
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
!= ';')
2490 error
= RPC_S_INVALID_STRING_UUID
;
2495 /* Parse ACE flags */
2496 val
= ParseAceStringFlags(&StringAcl
);
2498 pAce
->Header
.AceFlags
= (BYTE
) val
;
2499 if (*StringAcl
!= ';')
2503 /* Parse ACE rights */
2504 val
= ParseAceStringRights(&StringAcl
);
2507 if (*StringAcl
!= ';')
2511 /* Parse ACE object guid */
2512 while (*StringAcl
== ' ')
2514 if (*StringAcl
!= ';')
2516 FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
2521 /* Parse ACE inherit object guid */
2522 while (*StringAcl
== ' ')
2524 if (*StringAcl
!= ';')
2526 FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
2531 /* Parse ACE account sid */
2532 if (ParseStringSidToSid(StringAcl
, pAce
? &pAce
->SidStart
: NULL
, &sidlen
))
2534 while (*StringAcl
&& *StringAcl
!= ')')
2538 if (*StringAcl
!= ')')
2542 acesize
= sizeof(ACCESS_ALLOWED_ACE
) - sizeof(DWORD
) + sidlen
;
2546 pAce
->Header
.AceSize
= acesize
;
2547 pAce
= (PACCESS_ALLOWED_ACE
)((LPBYTE
)pAce
+ acesize
);
2554 if (length
> 0xffff)
2556 ERR("ACL too large\n");
2562 pAcl
->AclRevision
= ACL_REVISION
;
2564 pAcl
->AclSize
= length
;
2565 pAcl
->AceCount
= acecount
++;
2571 SetLastError(error
);
2572 WARN("Invalid ACE string format\n");
2577 /******************************************************************************
2578 * ParseStringSecurityDescriptorToSecurityDescriptor
2580 static BOOL
ParseStringSecurityDescriptorToSecurityDescriptor(
2581 LPCWSTR StringSecurityDescriptor
,
2582 SECURITY_DESCRIPTOR_RELATIVE
* SecurityDescriptor
,
2587 WCHAR tok
[MAX_PATH
];
2589 LPBYTE lpNext
= NULL
;
2592 *cBytes
= sizeof(SECURITY_DESCRIPTOR
);
2594 if (SecurityDescriptor
)
2595 lpNext
= (LPBYTE
)(SecurityDescriptor
+ 1);
2597 while (*StringSecurityDescriptor
== ' ')
2598 StringSecurityDescriptor
++;
2600 while (*StringSecurityDescriptor
)
2602 toktype
= *StringSecurityDescriptor
;
2604 /* Expect char identifier followed by ':' */
2605 StringSecurityDescriptor
++;
2606 if (*StringSecurityDescriptor
!= ':')
2608 SetLastError(ERROR_INVALID_PARAMETER
);
2611 StringSecurityDescriptor
++;
2614 lptoken
= StringSecurityDescriptor
;
2615 while (*lptoken
&& *lptoken
!= ':')
2621 len
= lptoken
- StringSecurityDescriptor
;
2622 memcpy( tok
, StringSecurityDescriptor
, len
* sizeof(WCHAR
) );
2631 if (!ParseStringSidToSid(tok
, lpNext
, &bytes
))
2634 if (SecurityDescriptor
)
2636 SecurityDescriptor
->Owner
= lpNext
- (LPBYTE
)SecurityDescriptor
;
2637 lpNext
+= bytes
; /* Advance to next token */
2649 if (!ParseStringSidToSid(tok
, lpNext
, &bytes
))
2652 if (SecurityDescriptor
)
2654 SecurityDescriptor
->Group
= lpNext
- (LPBYTE
)SecurityDescriptor
;
2655 lpNext
+= bytes
; /* Advance to next token */
2668 if (!ParseStringAclToAcl(tok
, &flags
, (PACL
)lpNext
, &bytes
))
2671 if (SecurityDescriptor
)
2673 SecurityDescriptor
->Control
|= SE_DACL_PRESENT
| flags
;
2674 SecurityDescriptor
->Dacl
= lpNext
- (LPBYTE
)SecurityDescriptor
;
2675 lpNext
+= bytes
; /* Advance to next token */
2688 if (!ParseStringAclToAcl(tok
, &flags
, (PACL
)lpNext
, &bytes
))
2691 if (SecurityDescriptor
)
2693 SecurityDescriptor
->Control
|= SE_SACL_PRESENT
| flags
;
2694 SecurityDescriptor
->Sacl
= lpNext
- (LPBYTE
)SecurityDescriptor
;
2695 lpNext
+= bytes
; /* Advance to next token */
2704 FIXME("Unknown token\n");
2705 SetLastError(ERROR_INVALID_PARAMETER
);
2709 StringSecurityDescriptor
= lptoken
;
2718 /* Winehq cvs 20050916 */
2719 /******************************************************************************
2720 * ConvertStringSecurityDescriptorToSecurityDescriptorA [ADVAPI32.@]
2725 ConvertStringSecurityDescriptorToSecurityDescriptorA(LPCSTR StringSecurityDescriptor
,
2726 DWORD StringSDRevision
,
2727 PSECURITY_DESCRIPTOR
* SecurityDescriptor
,
2728 PULONG SecurityDescriptorSize
)
2732 LPWSTR StringSecurityDescriptorW
;
2734 len
= MultiByteToWideChar(CP_ACP
, 0, StringSecurityDescriptor
, -1, NULL
, 0);
2735 StringSecurityDescriptorW
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
2737 if (StringSecurityDescriptorW
)
2739 MultiByteToWideChar(CP_ACP
, 0, StringSecurityDescriptor
, -1, StringSecurityDescriptorW
, len
);
2741 ret
= ConvertStringSecurityDescriptorToSecurityDescriptorW(StringSecurityDescriptorW
,
2742 StringSDRevision
, SecurityDescriptor
,
2743 SecurityDescriptorSize
);
2744 HeapFree(GetProcessHeap(), 0, StringSecurityDescriptorW
);
2750 /******************************************************************************
2751 * ConvertStringSecurityDescriptorToSecurityDescriptorW [ADVAPI32.@]
2755 ConvertStringSecurityDescriptorToSecurityDescriptorW(LPCWSTR StringSecurityDescriptor
,
2756 DWORD StringSDRevision
,
2757 PSECURITY_DESCRIPTOR
* SecurityDescriptor
,
2758 PULONG SecurityDescriptorSize
)
2761 SECURITY_DESCRIPTOR
* psd
;
2764 TRACE("%s\n", debugstr_w(StringSecurityDescriptor
));
2766 if (GetVersion() & 0x80000000)
2768 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
2771 else if (!StringSecurityDescriptor
|| !SecurityDescriptor
)
2773 SetLastError(ERROR_INVALID_PARAMETER
);
2776 else if (StringSDRevision
!= SID_REVISION
)
2778 SetLastError(ERROR_UNKNOWN_REVISION
);
2782 /* Compute security descriptor length */
2783 if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor
,
2787 psd
= *SecurityDescriptor
= LocalAlloc(GMEM_ZEROINIT
, cBytes
);
2788 if (!psd
) goto lend
;
2790 psd
->Revision
= SID_REVISION
;
2791 psd
->Control
|= SE_SELF_RELATIVE
;
2793 if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor
,
2794 (SECURITY_DESCRIPTOR_RELATIVE
*)psd
, &cBytes
))
2800 if (SecurityDescriptorSize
)
2801 *SecurityDescriptorSize
= cBytes
;
2806 TRACE(" ret=%d\n", bret
);
2810 static void DumpString(LPCWSTR string
, int cch
, WCHAR
**pwptr
, ULONG
*plen
)
2813 cch
= strlenW(string
);
2820 memcpy(*pwptr
, string
, sizeof(WCHAR
)*cch
);
2825 static BOOL
DumpSidNumeric(PSID psid
, WCHAR
**pwptr
, ULONG
*plen
)
2828 WCHAR fmt
[] = { 'S','-','%','u','-','%','d',0 };
2829 WCHAR subauthfmt
[] = { '-','%','u',0 };
2833 if( !IsValidSid( psid
) || pisid
->Revision
!= SDDL_REVISION
)
2835 SetLastError(ERROR_INVALID_SID
);
2839 if (pisid
->IdentifierAuthority
.Value
[0] ||
2840 pisid
->IdentifierAuthority
.Value
[1])
2842 FIXME("not matching MS' bugs\n");
2843 SetLastError(ERROR_INVALID_SID
);
2847 sprintfW( buf
, fmt
, pisid
->Revision
,
2849 MAKEWORD( pisid
->IdentifierAuthority
.Value
[5],
2850 pisid
->IdentifierAuthority
.Value
[4] ),
2851 MAKEWORD( pisid
->IdentifierAuthority
.Value
[3],
2852 pisid
->IdentifierAuthority
.Value
[2] )
2854 DumpString(buf
, -1, pwptr
, plen
);
2856 for( i
=0; i
<pisid
->SubAuthorityCount
; i
++ )
2858 sprintfW( buf
, subauthfmt
, pisid
->SubAuthority
[i
] );
2859 DumpString(buf
, -1, pwptr
, plen
);
2864 static BOOL
DumpSid(PSID psid
, WCHAR
**pwptr
, ULONG
*plen
)
2867 for (i
= 0; i
< sizeof(WellKnownSids
) / sizeof(WellKnownSids
[0]); i
++)
2869 if (WellKnownSids
[i
].wstr
[0] && EqualSid(psid
, (PSID
)&(WellKnownSids
[i
].Sid
.Revision
)))
2871 DumpString(WellKnownSids
[i
].wstr
, 2, pwptr
, plen
);
2876 return DumpSidNumeric(psid
, pwptr
, plen
);
2879 static const LPCWSTR AceRightBitNames
[32] = {
2880 SDDL_CREATE_CHILD
, /* 0 */
2884 SDDL_READ_PROPERTY
, /* 4 */
2885 SDDL_WRITE_PROPERTY
,
2888 SDDL_CONTROL_ACCESS
, /* 8 */
2896 SDDL_STANDARD_DELETE
, /* 16 */
2908 SDDL_GENERIC_ALL
, /* 28 */
2909 SDDL_GENERIC_EXECUTE
,
2914 static void DumpRights(DWORD mask
, WCHAR
**pwptr
, ULONG
*plen
)
2916 static const WCHAR fmtW
[] = {'0','x','%','x',0};
2923 /* first check if the right have name */
2924 for (i
= 0; i
< sizeof(AceRights
)/sizeof(AceRights
[0]); i
++)
2926 if (AceRights
[i
].wstr
== NULL
)
2928 if (mask
== AceRights
[i
].value
)
2930 DumpString(AceRights
[i
].wstr
, -1, pwptr
, plen
);
2935 /* then check if it can be built from bit names */
2936 for (i
= 0; i
< 32; i
++)
2938 if ((mask
& (1 << i
)) && (AceRightBitNames
[i
] == NULL
))
2940 /* can't be built from bit names */
2941 sprintfW(buf
, fmtW
, mask
);
2942 DumpString(buf
, -1, pwptr
, plen
);
2947 /* build from bit names */
2948 for (i
= 0; i
< 32; i
++)
2949 if (mask
& (1 << i
))
2950 DumpString(AceRightBitNames
[i
], -1, pwptr
, plen
);
2953 static BOOL
DumpAce(LPVOID pace
, WCHAR
**pwptr
, ULONG
*plen
)
2955 ACCESS_ALLOWED_ACE
*piace
; /* all the supported ACEs have the same memory layout */
2956 static const WCHAR openbr
= '(';
2957 static const WCHAR closebr
= ')';
2958 static const WCHAR semicolon
= ';';
2960 if (((PACE_HEADER
)pace
)->AceType
> SYSTEM_ALARM_ACE_TYPE
|| ((PACE_HEADER
)pace
)->AceSize
< sizeof(ACCESS_ALLOWED_ACE
))
2962 SetLastError(ERROR_INVALID_ACL
);
2967 DumpString(&openbr
, 1, pwptr
, plen
);
2968 switch (piace
->Header
.AceType
)
2970 case ACCESS_ALLOWED_ACE_TYPE
:
2971 DumpString(SDDL_ACCESS_ALLOWED
, -1, pwptr
, plen
);
2973 case ACCESS_DENIED_ACE_TYPE
:
2974 DumpString(SDDL_ACCESS_DENIED
, -1, pwptr
, plen
);
2976 case SYSTEM_AUDIT_ACE_TYPE
:
2977 DumpString(SDDL_AUDIT
, -1, pwptr
, plen
);
2979 case SYSTEM_ALARM_ACE_TYPE
:
2980 DumpString(SDDL_ALARM
, -1, pwptr
, plen
);
2983 DumpString(&semicolon
, 1, pwptr
, plen
);
2985 if (piace
->Header
.AceFlags
& OBJECT_INHERIT_ACE
)
2986 DumpString(SDDL_OBJECT_INHERIT
, -1, pwptr
, plen
);
2987 if (piace
->Header
.AceFlags
& CONTAINER_INHERIT_ACE
)
2988 DumpString(SDDL_CONTAINER_INHERIT
, -1, pwptr
, plen
);
2989 if (piace
->Header
.AceFlags
& NO_PROPAGATE_INHERIT_ACE
)
2990 DumpString(SDDL_NO_PROPAGATE
, -1, pwptr
, plen
);
2991 if (piace
->Header
.AceFlags
& INHERIT_ONLY_ACE
)
2992 DumpString(SDDL_INHERIT_ONLY
, -1, pwptr
, plen
);
2993 if (piace
->Header
.AceFlags
& INHERITED_ACE
)
2994 DumpString(SDDL_INHERITED
, -1, pwptr
, plen
);
2995 if (piace
->Header
.AceFlags
& SUCCESSFUL_ACCESS_ACE_FLAG
)
2996 DumpString(SDDL_AUDIT_SUCCESS
, -1, pwptr
, plen
);
2997 if (piace
->Header
.AceFlags
& FAILED_ACCESS_ACE_FLAG
)
2998 DumpString(SDDL_AUDIT_FAILURE
, -1, pwptr
, plen
);
2999 DumpString(&semicolon
, 1, pwptr
, plen
);
3000 DumpRights(piace
->Mask
, pwptr
, plen
);
3001 DumpString(&semicolon
, 1, pwptr
, plen
);
3002 /* objects not supported */
3003 DumpString(&semicolon
, 1, pwptr
, plen
);
3004 /* objects not supported */
3005 DumpString(&semicolon
, 1, pwptr
, plen
);
3006 if (!DumpSid((PSID
)&piace
->SidStart
, pwptr
, plen
))
3008 DumpString(&closebr
, 1, pwptr
, plen
);
3012 static BOOL
DumpAcl(PACL pacl
, WCHAR
**pwptr
, ULONG
*plen
, BOOL
protected, BOOL autoInheritReq
, BOOL autoInherited
)
3018 DumpString(SDDL_PROTECTED
, -1, pwptr
, plen
);
3020 DumpString(SDDL_AUTO_INHERIT_REQ
, -1, pwptr
, plen
);
3022 DumpString(SDDL_AUTO_INHERITED
, -1, pwptr
, plen
);
3027 if (!IsValidAcl(pacl
))
3030 count
= pacl
->AceCount
;
3031 for (i
= 0; i
< count
; i
++)
3034 if (!GetAce(pacl
, i
, &ace
))
3036 if (!DumpAce(ace
, pwptr
, plen
))
3043 static BOOL
DumpOwner(PSECURITY_DESCRIPTOR SecurityDescriptor
, WCHAR
**pwptr
, ULONG
*plen
)
3045 static const WCHAR prefix
[] = {'O',':',0};
3049 if (!GetSecurityDescriptorOwner(SecurityDescriptor
, &psid
, &bDefaulted
))
3055 DumpString(prefix
, -1, pwptr
, plen
);
3056 if (!DumpSid(psid
, pwptr
, plen
))
3061 static BOOL
DumpGroup(PSECURITY_DESCRIPTOR SecurityDescriptor
, WCHAR
**pwptr
, ULONG
*plen
)
3063 static const WCHAR prefix
[] = {'G',':',0};
3067 if (!GetSecurityDescriptorGroup(SecurityDescriptor
, &psid
, &bDefaulted
))
3073 DumpString(prefix
, -1, pwptr
, plen
);
3074 if (!DumpSid(psid
, pwptr
, plen
))
3079 static BOOL
DumpDacl(PSECURITY_DESCRIPTOR SecurityDescriptor
, WCHAR
**pwptr
, ULONG
*plen
)
3081 static const WCHAR dacl
[] = {'D',':',0};
3082 SECURITY_DESCRIPTOR_CONTROL control
;
3083 BOOL present
, defaulted
;
3087 if (!GetSecurityDescriptorDacl(SecurityDescriptor
, &present
, &pacl
, &defaulted
))
3090 if (!GetSecurityDescriptorControl(SecurityDescriptor
, &control
, &revision
))
3096 DumpString(dacl
, 2, pwptr
, plen
);
3097 if (!DumpAcl(pacl
, pwptr
, plen
, control
& SE_DACL_PROTECTED
, control
& SE_DACL_AUTO_INHERIT_REQ
, control
& SE_DACL_AUTO_INHERITED
))
3102 static BOOL
DumpSacl(PSECURITY_DESCRIPTOR SecurityDescriptor
, WCHAR
**pwptr
, ULONG
*plen
)
3104 static const WCHAR sacl
[] = {'S',':',0};
3105 SECURITY_DESCRIPTOR_CONTROL control
;
3106 BOOL present
, defaulted
;
3110 if (!GetSecurityDescriptorSacl(SecurityDescriptor
, &present
, &pacl
, &defaulted
))
3113 if (!GetSecurityDescriptorControl(SecurityDescriptor
, &control
, &revision
))
3119 DumpString(sacl
, 2, pwptr
, plen
);
3120 if (!DumpAcl(pacl
, pwptr
, plen
, control
& SE_SACL_PROTECTED
, control
& SE_SACL_AUTO_INHERIT_REQ
, control
& SE_SACL_AUTO_INHERITED
))
3125 /******************************************************************************
3126 * ConvertSecurityDescriptorToStringSecurityDescriptorW [ADVAPI32.@]
3130 ConvertSecurityDescriptorToStringSecurityDescriptorW(PSECURITY_DESCRIPTOR SecurityDescriptor
,
3132 SECURITY_INFORMATION SecurityInformation
,
3133 LPWSTR
*OutputString
,
3139 if (SDRevision
!= SDDL_REVISION_1
)
3141 ERR("Program requested unknown SDDL revision %d\n", SDRevision
);
3142 SetLastError(ERROR_UNKNOWN_REVISION
);
3147 if (SecurityInformation
& OWNER_SECURITY_INFORMATION
)
3148 if (!DumpOwner(SecurityDescriptor
, NULL
, &len
))
3150 if (SecurityInformation
& GROUP_SECURITY_INFORMATION
)
3151 if (!DumpGroup(SecurityDescriptor
, NULL
, &len
))
3153 if (SecurityInformation
& DACL_SECURITY_INFORMATION
)
3154 if (!DumpDacl(SecurityDescriptor
, NULL
, &len
))
3156 if (SecurityInformation
& SACL_SECURITY_INFORMATION
)
3157 if (!DumpSacl(SecurityDescriptor
, NULL
, &len
))
3160 wstr
= wptr
= LocalAlloc(0, (len
+ 1)*sizeof(WCHAR
));
3164 if (SecurityInformation
& OWNER_SECURITY_INFORMATION
)
3165 if (!DumpOwner(SecurityDescriptor
, &wptr
, NULL
))
3167 if (SecurityInformation
& GROUP_SECURITY_INFORMATION
)
3168 if (!DumpGroup(SecurityDescriptor
, &wptr
, NULL
))
3170 if (SecurityInformation
& DACL_SECURITY_INFORMATION
)
3171 if (!DumpDacl(SecurityDescriptor
, &wptr
, NULL
))
3173 if (SecurityInformation
& SACL_SECURITY_INFORMATION
)
3174 if (!DumpSacl(SecurityDescriptor
, &wptr
, NULL
))
3178 TRACE("ret: %s, %d\n", wine_dbgstr_w(wstr
), len
);
3179 *OutputString
= wstr
;
3181 *OutputLen
= strlenW(*OutputString
)+1;
3185 /******************************************************************************
3186 * ConvertSecurityDescriptorToStringSecurityDescriptorA [ADVAPI32.@]
3190 ConvertSecurityDescriptorToStringSecurityDescriptorA(PSECURITY_DESCRIPTOR SecurityDescriptor
,
3192 SECURITY_INFORMATION Information
,
3193 LPSTR
*OutputString
,
3199 if (ConvertSecurityDescriptorToStringSecurityDescriptorW(SecurityDescriptor
, SDRevision
, Information
, &wstr
, &len
))
3203 lenA
= WideCharToMultiByte(CP_ACP
, 0, wstr
, len
, NULL
, 0, NULL
, NULL
);
3204 *OutputString
= HeapAlloc(GetProcessHeap(), 0, lenA
);
3205 if (*OutputString
== NULL
)
3211 WideCharToMultiByte(CP_ACP
, 0, wstr
, len
, *OutputString
, lenA
, NULL
, NULL
);
3214 if (OutputLen
!= NULL
)
3220 *OutputString
= NULL
;
3232 ConvertStringSidToSidW(IN LPCWSTR StringSid
,
3236 DWORD i
, cBytes
, identAuth
, csubauth
;
3240 TRACE("%s %p\n", debugstr_w(StringSid
), sid
);
3244 SetLastError(ERROR_INVALID_SID
);
3248 for (i
= 0; i
< sizeof(SidTable
) / sizeof(SidTable
[0]) - 1; i
++)
3250 if (wcscmp(StringSid
, SidTable
[i
].key
) == 0)
3252 WELL_KNOWN_SID_TYPE knownSid
= (WELL_KNOWN_SID_TYPE
)SidTable
[i
].value
;
3253 size
= SECURITY_MAX_SID_SIZE
;
3254 *sid
= LocalAlloc(0, size
);
3257 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
3260 ret
= CreateWellKnownSid(knownSid
,
3266 SetLastError(ERROR_INVALID_SID
);
3273 /* That's probably a string S-R-I-S-S... */
3274 if (StringSid
[0] != 'S' || StringSid
[1] != '-')
3276 SetLastError(ERROR_INVALID_SID
);
3280 cBytes
= ComputeStringSidSize(StringSid
);
3281 pisid
= (SID
*)LocalAlloc( 0, cBytes
);
3284 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
3289 csubauth
= ((cBytes
- GetSidLengthRequired(0)) / sizeof(DWORD
));
3291 StringSid
+= 2; /* Advance to Revision */
3292 pisid
->Revision
= atoiW(StringSid
);
3294 if (pisid
->Revision
!= SDDL_REVISION
)
3296 TRACE("Revision %d is unknown\n", pisid
->Revision
);
3297 goto lend
; /* ERROR_INVALID_SID */
3301 TRACE("SubAuthorityCount is 0\n");
3302 goto lend
; /* ERROR_INVALID_SID */
3305 pisid
->SubAuthorityCount
= csubauth
;
3307 /* Advance to identifier authority */
3308 while (*StringSid
&& *StringSid
!= '-')
3310 if (*StringSid
== '-')
3313 /* MS' implementation can't handle values greater than 2^32 - 1, so
3314 * we don't either; assume most significant bytes are always 0
3316 pisid
->IdentifierAuthority
.Value
[0] = 0;
3317 pisid
->IdentifierAuthority
.Value
[1] = 0;
3318 identAuth
= atoiW(StringSid
);
3319 pisid
->IdentifierAuthority
.Value
[5] = identAuth
& 0xff;
3320 pisid
->IdentifierAuthority
.Value
[4] = (identAuth
& 0xff00) >> 8;
3321 pisid
->IdentifierAuthority
.Value
[3] = (identAuth
& 0xff0000) >> 16;
3322 pisid
->IdentifierAuthority
.Value
[2] = (identAuth
& 0xff000000) >> 24;
3324 /* Advance to first sub authority */
3325 while (*StringSid
&& *StringSid
!= '-')
3327 if (*StringSid
== '-')
3332 pisid
->SubAuthority
[i
++] = atoiW(StringSid
);
3334 while (*StringSid
&& *StringSid
!= '-')
3336 if (*StringSid
== '-')
3340 if (i
!= pisid
->SubAuthorityCount
)
3341 goto lend
; /* ERROR_INVALID_SID */
3350 SetLastError(ERROR_INVALID_SID
);
3353 TRACE("returning %s\n", ret
? "TRUE" : "FALSE");
3362 ConvertStringSidToSidA(IN LPCSTR StringSid
,
3365 BOOL bRetVal
= FALSE
;
3367 TRACE("%s, %p\n", debugstr_a(StringSid
), sid
);
3368 if (GetVersion() & 0x80000000)
3369 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
3370 else if (!StringSid
|| !sid
)
3371 SetLastError(ERROR_INVALID_PARAMETER
);
3374 UINT len
= MultiByteToWideChar(CP_ACP
, 0, StringSid
, -1, NULL
, 0);
3375 LPWSTR wStringSid
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
3376 if (wStringSid
== NULL
)
3378 MultiByteToWideChar(CP_ACP
, 0, StringSid
, - 1, wStringSid
, len
);
3379 bRetVal
= ConvertStringSidToSidW(wStringSid
, sid
);
3380 HeapFree(GetProcessHeap(), 0, wStringSid
);
3390 ConvertSidToStringSidW(PSID Sid
,
3394 UNICODE_STRING UnicodeString
;
3395 WCHAR FixedBuffer
[64];
3397 if (!RtlValidSid(Sid
))
3399 SetLastError(ERROR_INVALID_SID
);
3403 UnicodeString
.Length
= 0;
3404 UnicodeString
.MaximumLength
= sizeof(FixedBuffer
);
3405 UnicodeString
.Buffer
= FixedBuffer
;
3406 Status
= RtlConvertSidToUnicodeString(&UnicodeString
, Sid
, FALSE
);
3407 if (STATUS_BUFFER_TOO_SMALL
== Status
)
3409 Status
= RtlConvertSidToUnicodeString(&UnicodeString
, Sid
, TRUE
);
3412 if (!NT_SUCCESS(Status
))
3414 SetLastError(RtlNtStatusToDosError(Status
));
3418 *StringSid
= LocalAlloc(LMEM_FIXED
, UnicodeString
.Length
+ sizeof(WCHAR
));
3419 if (NULL
== *StringSid
)
3421 if (UnicodeString
.Buffer
!= FixedBuffer
)
3423 RtlFreeUnicodeString(&UnicodeString
);
3425 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
3429 MoveMemory(*StringSid
, UnicodeString
.Buffer
, UnicodeString
.Length
);
3430 ZeroMemory((PCHAR
) *StringSid
+ UnicodeString
.Length
, sizeof(WCHAR
));
3431 if (UnicodeString
.Buffer
!= FixedBuffer
)
3433 RtlFreeUnicodeString(&UnicodeString
);
3444 ConvertSidToStringSidA(PSID Sid
,
3450 if (!ConvertSidToStringSidW(Sid
, &StringSidW
))
3455 Len
= WideCharToMultiByte(CP_ACP
, 0, StringSidW
, -1, NULL
, 0, NULL
, NULL
);
3458 LocalFree(StringSidW
);
3459 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
3463 *StringSid
= LocalAlloc(LMEM_FIXED
, Len
);
3464 if (NULL
== *StringSid
)
3466 LocalFree(StringSidW
);
3467 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
3471 if (!WideCharToMultiByte(CP_ACP
, 0, StringSidW
, -1, *StringSid
, Len
, NULL
, NULL
))
3473 LocalFree(StringSid
);
3474 LocalFree(StringSidW
);
3478 LocalFree(StringSidW
);
3487 CreateProcessWithLogonW(LPCWSTR lpUsername
,
3491 LPCWSTR lpApplicationName
,
3492 LPWSTR lpCommandLine
,
3493 DWORD dwCreationFlags
,
3494 LPVOID lpEnvironment
,
3495 LPCWSTR lpCurrentDirectory
,
3496 LPSTARTUPINFOW lpStartupInfo
,
3497 LPPROCESS_INFORMATION lpProcessInformation
)
3499 FIXME("%s %s %s 0x%08x %s %s 0x%08x %p %s %p %p stub\n", debugstr_w(lpUsername
), debugstr_w(lpDomain
),
3500 debugstr_w(lpPassword
), dwLogonFlags
, debugstr_w(lpApplicationName
),
3501 debugstr_w(lpCommandLine
), dwCreationFlags
, lpEnvironment
, debugstr_w(lpCurrentDirectory
),
3502 lpStartupInfo
, lpProcessInformation
);
3509 CreateProcessWithTokenW(IN HANDLE hToken
,
3510 IN DWORD dwLogonFlags
,
3511 IN LPCWSTR lpApplicationName OPTIONAL
,
3512 IN OUT LPWSTR lpCommandLine OPTIONAL
,
3513 IN DWORD dwCreationFlags
,
3514 IN LPVOID lpEnvironment OPTIONAL
,
3515 IN LPCWSTR lpCurrentDirectory OPTIONAL
,
3516 IN LPSTARTUPINFOW lpStartupInfo
,
3517 OUT LPPROCESS_INFORMATION lpProcessInfo
)
3527 DuplicateTokenEx(IN HANDLE ExistingTokenHandle
,
3528 IN DWORD dwDesiredAccess
,
3529 IN LPSECURITY_ATTRIBUTES lpTokenAttributes OPTIONAL
,
3530 IN SECURITY_IMPERSONATION_LEVEL ImpersonationLevel
,
3531 IN TOKEN_TYPE TokenType
,
3532 OUT PHANDLE DuplicateTokenHandle
)
3534 OBJECT_ATTRIBUTES ObjectAttributes
;
3536 SECURITY_QUALITY_OF_SERVICE Sqos
;
3538 TRACE("%p 0x%08x 0x%08x 0x%08x %p\n", ExistingTokenHandle
, dwDesiredAccess
,
3539 ImpersonationLevel
, TokenType
, DuplicateTokenHandle
);
3541 Sqos
.Length
= sizeof(SECURITY_QUALITY_OF_SERVICE
);
3542 Sqos
.ImpersonationLevel
= ImpersonationLevel
;
3543 Sqos
.ContextTrackingMode
= 0;
3544 Sqos
.EffectiveOnly
= FALSE
;
3546 if (lpTokenAttributes
!= NULL
)
3548 InitializeObjectAttributes(&ObjectAttributes
,
3550 lpTokenAttributes
->bInheritHandle
? OBJ_INHERIT
: 0,
3552 lpTokenAttributes
->lpSecurityDescriptor
);
3556 InitializeObjectAttributes(&ObjectAttributes
,
3563 ObjectAttributes
.SecurityQualityOfService
= &Sqos
;
3565 Status
= NtDuplicateToken(ExistingTokenHandle
,
3570 DuplicateTokenHandle
);
3571 if (!NT_SUCCESS(Status
))
3573 ERR("NtDuplicateToken failed: Status %08x\n", Status
);
3574 SetLastError(RtlNtStatusToDosError(Status
));
3578 TRACE("Returning token %p.\n", *DuplicateTokenHandle
);
3587 DuplicateToken(IN HANDLE ExistingTokenHandle
,
3588 IN SECURITY_IMPERSONATION_LEVEL ImpersonationLevel
,
3589 OUT PHANDLE DuplicateTokenHandle
)
3591 return DuplicateTokenEx(ExistingTokenHandle
,
3592 TOKEN_IMPERSONATE
| TOKEN_QUERY
,
3596 DuplicateTokenHandle
);
3599 /******************************************************************************
3600 * ComputeStringSidSize
3602 static DWORD
ComputeStringSidSize(LPCWSTR StringSid
)
3604 if (StringSid
[0] == 'S' && StringSid
[1] == '-') /* S-R-I(-S)+ */
3609 if (*StringSid
== '-')
3615 return GetSidLengthRequired(ctok
- 2);
3617 else /* String constant format - Only available in winxp and above */
3621 for (i
= 0; i
< sizeof(WellKnownSids
)/sizeof(WellKnownSids
[0]); i
++)
3622 if (!strncmpW(WellKnownSids
[i
].wstr
, StringSid
, 2))
3623 return GetSidLengthRequired(WellKnownSids
[i
].Sid
.SubAuthorityCount
);
3626 return GetSidLengthRequired(0);
3629 /******************************************************************************
3630 * ParseStringSidToSid
3632 static BOOL
ParseStringSidToSid(LPCWSTR StringSid
, PSID pSid
, LPDWORD cBytes
)
3637 TRACE("%s, %p, %p\n", debugstr_w(StringSid
), pSid
, cBytes
);
3640 SetLastError(ERROR_INVALID_PARAMETER
);
3641 TRACE("StringSid is NULL, returning FALSE\n");
3645 while (*StringSid
== ' ')
3648 *cBytes
= ComputeStringSidSize(StringSid
);
3649 if (!pisid
) /* Simply compute the size */
3651 TRACE("only size requested, returning TRUE\n");
3655 if (StringSid
[0] == 'S' && StringSid
[1] == '-') /* S-R-I-S-S */
3657 DWORD i
= 0, identAuth
;
3658 DWORD csubauth
= ((*cBytes
- GetSidLengthRequired(0)) / sizeof(DWORD
));
3660 StringSid
+= 2; /* Advance to Revision */
3661 pisid
->Revision
= atoiW(StringSid
);
3663 if (pisid
->Revision
!= SDDL_REVISION
)
3665 TRACE("Revision %d is unknown\n", pisid
->Revision
);
3666 goto lend
; /* ERROR_INVALID_SID */
3670 TRACE("SubAuthorityCount is 0\n");
3671 goto lend
; /* ERROR_INVALID_SID */
3674 pisid
->SubAuthorityCount
= csubauth
;
3676 /* Advance to identifier authority */
3677 while (*StringSid
&& *StringSid
!= '-')
3679 if (*StringSid
== '-')
3682 /* MS' implementation can't handle values greater than 2^32 - 1, so
3683 * we don't either; assume most significant bytes are always 0
3685 pisid
->IdentifierAuthority
.Value
[0] = 0;
3686 pisid
->IdentifierAuthority
.Value
[1] = 0;
3687 identAuth
= atoiW(StringSid
);
3688 pisid
->IdentifierAuthority
.Value
[5] = identAuth
& 0xff;
3689 pisid
->IdentifierAuthority
.Value
[4] = (identAuth
& 0xff00) >> 8;
3690 pisid
->IdentifierAuthority
.Value
[3] = (identAuth
& 0xff0000) >> 16;
3691 pisid
->IdentifierAuthority
.Value
[2] = (identAuth
& 0xff000000) >> 24;
3693 /* Advance to first sub authority */
3694 while (*StringSid
&& *StringSid
!= '-')
3696 if (*StringSid
== '-')
3701 pisid
->SubAuthority
[i
++] = atoiW(StringSid
);
3703 while (*StringSid
&& *StringSid
!= '-')
3705 if (*StringSid
== '-')
3709 if (i
!= pisid
->SubAuthorityCount
)
3710 goto lend
; /* ERROR_INVALID_SID */
3714 else /* String constant format - Only available in winxp and above */
3717 pisid
->Revision
= SDDL_REVISION
;
3719 for (i
= 0; i
< sizeof(WellKnownSids
)/sizeof(WellKnownSids
[0]); i
++)
3720 if (!strncmpW(WellKnownSids
[i
].wstr
, StringSid
, 2))
3723 pisid
->SubAuthorityCount
= WellKnownSids
[i
].Sid
.SubAuthorityCount
;
3724 pisid
->IdentifierAuthority
= WellKnownSids
[i
].Sid
.IdentifierAuthority
;
3725 for (j
= 0; j
< WellKnownSids
[i
].Sid
.SubAuthorityCount
; j
++)
3726 pisid
->SubAuthority
[j
] = WellKnownSids
[i
].Sid
.SubAuthority
[j
];
3731 FIXME("String constant not supported: %s\n", debugstr_wn(StringSid
, 2));
3736 SetLastError(ERROR_INVALID_SID
);
3738 TRACE("returning %s\n", bret
? "TRUE" : "FALSE");
3742 /**********************************************************************
3743 * GetNamedSecurityInfoA EXPORTED
3749 GetNamedSecurityInfoA(LPSTR pObjectName
,
3750 SE_OBJECT_TYPE ObjectType
,
3751 SECURITY_INFORMATION SecurityInfo
,
3756 PSECURITY_DESCRIPTOR
*ppSecurityDescriptor
)
3762 TRACE("%s %d %d %p %p %p %p %p\n", pObjectName
, ObjectType
, SecurityInfo
,
3763 ppsidOwner
, ppsidGroup
, ppDacl
, ppSacl
, ppSecurityDescriptor
);
3767 len
= MultiByteToWideChar( CP_ACP
, 0, pObjectName
, -1, NULL
, 0 );
3768 wstr
= HeapAlloc( GetProcessHeap(), 0, len
*sizeof(WCHAR
));
3769 MultiByteToWideChar( CP_ACP
, 0, pObjectName
, -1, wstr
, len
);
3772 r
= GetNamedSecurityInfoW( wstr
, ObjectType
, SecurityInfo
, ppsidOwner
,
3773 ppsidGroup
, ppDacl
, ppSacl
, ppSecurityDescriptor
);
3775 HeapFree( GetProcessHeap(), 0, wstr
);
3785 GetWindowsAccountDomainSid(IN PSID pSid
,
3786 OUT PSID ppDomainSid
,
3787 IN OUT DWORD
* cbSid
)
3798 EqualDomainSid(IN PSID pSid1
,