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 /* these SIDs must be constructed as relative to some domain - only the RID is well-known */
119 typedef struct WELLKNOWNRID
122 WELL_KNOWN_SID_TYPE Type
;
126 static const WELLKNOWNRID WellKnownRids
[] = {
127 { {'L','A'}, WinAccountAdministratorSid
, DOMAIN_USER_RID_ADMIN
},
128 { {'L','G'}, WinAccountGuestSid
, DOMAIN_USER_RID_GUEST
},
129 { {0,0}, WinAccountKrbtgtSid
, DOMAIN_USER_RID_KRBTGT
},
130 { {0,0}, WinAccountDomainAdminsSid
, DOMAIN_GROUP_RID_ADMINS
},
131 { {0,0}, WinAccountDomainUsersSid
, DOMAIN_GROUP_RID_USERS
},
132 { {0,0}, WinAccountDomainGuestsSid
, DOMAIN_GROUP_RID_GUESTS
},
133 { {0,0}, WinAccountComputersSid
, DOMAIN_GROUP_RID_COMPUTERS
},
134 { {0,0}, WinAccountControllersSid
, DOMAIN_GROUP_RID_CONTROLLERS
},
135 { {0,0}, WinAccountCertAdminsSid
, DOMAIN_GROUP_RID_CERT_ADMINS
},
136 { {0,0}, WinAccountSchemaAdminsSid
, DOMAIN_GROUP_RID_SCHEMA_ADMINS
},
137 { {0,0}, WinAccountEnterpriseAdminsSid
, DOMAIN_GROUP_RID_ENTERPRISE_ADMINS
},
138 { {0,0}, WinAccountPolicyAdminsSid
, DOMAIN_GROUP_RID_POLICY_ADMINS
},
139 { {0,0}, WinAccountRasAndIasServersSid
, DOMAIN_ALIAS_RID_RAS_SERVERS
},
142 static const SID sidWorld
= { SID_REVISION
, 1, { SECURITY_WORLD_SID_AUTHORITY
} , { SECURITY_WORLD_RID
} };
147 static const WCHAR SDDL_ACCESS_ALLOWED
[] = {'A',0};
148 static const WCHAR SDDL_ACCESS_DENIED
[] = {'D',0};
149 static const WCHAR SDDL_OBJECT_ACCESS_ALLOWED
[] = {'O','A',0};
150 static const WCHAR SDDL_OBJECT_ACCESS_DENIED
[] = {'O','D',0};
151 static const WCHAR SDDL_AUDIT
[] = {'A','U',0};
152 static const WCHAR SDDL_ALARM
[] = {'A','L',0};
153 static const WCHAR SDDL_OBJECT_AUDIT
[] = {'O','U',0};
154 static const WCHAR SDDL_OBJECT_ALARM
[] = {'O','L',0};
159 #define ADS_RIGHT_DS_CREATE_CHILD 0x0001
160 #define ADS_RIGHT_DS_DELETE_CHILD 0x0002
161 #define ADS_RIGHT_ACTRL_DS_LIST 0x0004
162 #define ADS_RIGHT_DS_SELF 0x0008
163 #define ADS_RIGHT_DS_READ_PROP 0x0010
164 #define ADS_RIGHT_DS_WRITE_PROP 0x0020
165 #define ADS_RIGHT_DS_DELETE_TREE 0x0040
166 #define ADS_RIGHT_DS_LIST_OBJECT 0x0080
167 #define ADS_RIGHT_DS_CONTROL_ACCESS 0x0100
172 static const WCHAR SDDL_CONTAINER_INHERIT
[] = {'C','I',0};
173 static const WCHAR SDDL_OBJECT_INHERIT
[] = {'O','I',0};
174 static const WCHAR SDDL_NO_PROPAGATE
[] = {'N','P',0};
175 static const WCHAR SDDL_INHERIT_ONLY
[] = {'I','O',0};
176 static const WCHAR SDDL_INHERITED
[] = {'I','D',0};
177 static const WCHAR SDDL_AUDIT_SUCCESS
[] = {'S','A',0};
178 static const WCHAR SDDL_AUDIT_FAILURE
[] = {'F','A',0};
180 static const char * debugstr_sid(PSID sid
)
183 SID
* psid
= (SID
*)sid
;
188 auth
= psid
->IdentifierAuthority
.Value
[5] +
189 (psid
->IdentifierAuthority
.Value
[4] << 8) +
190 (psid
->IdentifierAuthority
.Value
[3] << 16) +
191 (psid
->IdentifierAuthority
.Value
[2] << 24);
193 switch (psid
->SubAuthorityCount
) {
195 return wine_dbg_sprintf("S-%d-%d", psid
->Revision
, auth
);
197 return wine_dbg_sprintf("S-%d-%d-%lu", psid
->Revision
, auth
,
198 psid
->SubAuthority
[0]);
200 return wine_dbg_sprintf("S-%d-%d-%lu-%lu", psid
->Revision
, auth
,
201 psid
->SubAuthority
[0], psid
->SubAuthority
[1]);
203 return wine_dbg_sprintf("S-%d-%d-%lu-%lu-%lu", psid
->Revision
, auth
,
204 psid
->SubAuthority
[0], psid
->SubAuthority
[1], psid
->SubAuthority
[2]);
206 return wine_dbg_sprintf("S-%d-%d-%lu-%lu-%lu-%lu", psid
->Revision
, auth
,
207 psid
->SubAuthority
[0], psid
->SubAuthority
[1], psid
->SubAuthority
[2],
208 psid
->SubAuthority
[3]);
210 return wine_dbg_sprintf("S-%d-%d-%lu-%lu-%lu-%lu-%lu", psid
->Revision
, auth
,
211 psid
->SubAuthority
[0], psid
->SubAuthority
[1], psid
->SubAuthority
[2],
212 psid
->SubAuthority
[3], psid
->SubAuthority
[4]);
214 return wine_dbg_sprintf("S-%d-%d-%lu-%lu-%lu-%lu-%lu-%lu", psid
->Revision
, auth
,
215 psid
->SubAuthority
[3], psid
->SubAuthority
[1], psid
->SubAuthority
[2],
216 psid
->SubAuthority
[0], psid
->SubAuthority
[4], psid
->SubAuthority
[5]);
218 return wine_dbg_sprintf("S-%d-%d-%lu-%lu-%lu-%lu-%lu-%lu-%lu", psid
->Revision
, auth
,
219 psid
->SubAuthority
[0], psid
->SubAuthority
[1], psid
->SubAuthority
[2],
220 psid
->SubAuthority
[3], psid
->SubAuthority
[4], psid
->SubAuthority
[5],
221 psid
->SubAuthority
[6]);
223 return wine_dbg_sprintf("S-%d-%d-%lu-%lu-%lu-%lu-%lu-%lu-%lu-%lu", psid
->Revision
, auth
,
224 psid
->SubAuthority
[0], psid
->SubAuthority
[1], psid
->SubAuthority
[2],
225 psid
->SubAuthority
[3], psid
->SubAuthority
[4], psid
->SubAuthority
[5],
226 psid
->SubAuthority
[6], psid
->SubAuthority
[7]);
231 /* set last error code from NT status and get the proper boolean return value */
232 /* used for functions that are a simple wrapper around the corresponding ntdll API */
233 static __inline BOOL
set_ntstatus( NTSTATUS status
)
235 if (!NT_SUCCESS(status
)) SetLastError( RtlNtStatusToDosError( status
));
236 return NT_SUCCESS(status
);
239 static const RECORD SidTable
[] =
241 { SDDL_ACCOUNT_OPERATORS
, WinBuiltinAccountOperatorsSid
},
242 { SDDL_ALIAS_PREW2KCOMPACC
, WinBuiltinPreWindows2000CompatibleAccessSid
},
243 { SDDL_ANONYMOUS
, WinAnonymousSid
},
244 { SDDL_AUTHENTICATED_USERS
, WinAuthenticatedUserSid
},
245 { SDDL_BUILTIN_ADMINISTRATORS
, WinBuiltinAdministratorsSid
},
246 { SDDL_BUILTIN_GUESTS
, WinBuiltinGuestsSid
},
247 { SDDL_BACKUP_OPERATORS
, WinBuiltinBackupOperatorsSid
},
248 { SDDL_BUILTIN_USERS
, WinBuiltinUsersSid
},
249 { SDDL_CERT_SERV_ADMINISTRATORS
, WinAccountCertAdminsSid
/* FIXME: DOMAIN_GROUP_RID_CERT_ADMINS */ },
250 { SDDL_CREATOR_GROUP
, WinCreatorGroupSid
},
251 { SDDL_CREATOR_OWNER
, WinCreatorOwnerSid
},
252 { SDDL_DOMAIN_ADMINISTRATORS
, WinAccountDomainAdminsSid
/* FIXME: DOMAIN_GROUP_RID_ADMINS */ },
253 { SDDL_DOMAIN_COMPUTERS
, WinAccountComputersSid
/* FIXME: DOMAIN_GROUP_RID_COMPUTERS */ },
254 { SDDL_DOMAIN_DOMAIN_CONTROLLERS
, WinAccountControllersSid
/* FIXME: DOMAIN_GROUP_RID_CONTROLLERS */ },
255 { SDDL_DOMAIN_GUESTS
, WinAccountDomainGuestsSid
/* FIXME: DOMAIN_GROUP_RID_GUESTS */ },
256 { SDDL_DOMAIN_USERS
, WinAccountDomainUsersSid
/* FIXME: DOMAIN_GROUP_RID_USERS */ },
257 { SDDL_ENTERPRISE_ADMINS
, WinAccountEnterpriseAdminsSid
/* FIXME: DOMAIN_GROUP_RID_ENTERPRISE_ADMINS */ },
258 { SDDL_ENTERPRISE_DOMAIN_CONTROLLERS
, WinEnterpriseControllersSid
},
259 { SDDL_EVERYONE
, WinWorldSid
},
260 { SDDL_GROUP_POLICY_ADMINS
, WinAccountPolicyAdminsSid
/* FIXME: DOMAIN_GROUP_RID_POLICY_ADMINS */ },
261 { SDDL_INTERACTIVE
, WinInteractiveSid
},
262 { SDDL_LOCAL_ADMIN
, WinAccountAdministratorSid
/* FIXME: DOMAIN_USER_RID_ADMIN */ },
263 { SDDL_LOCAL_GUEST
, WinAccountGuestSid
/* FIXME: DOMAIN_USER_RID_GUEST */ },
264 { SDDL_LOCAL_SERVICE
, WinLocalServiceSid
},
265 { SDDL_LOCAL_SYSTEM
, WinLocalSystemSid
},
266 { SDDL_NETWORK
, WinNetworkSid
},
267 { SDDL_NETWORK_CONFIGURATION_OPS
, WinBuiltinNetworkConfigurationOperatorsSid
},
268 { SDDL_NETWORK_SERVICE
, WinNetworkServiceSid
},
269 { SDDL_PRINTER_OPERATORS
, WinBuiltinPrintOperatorsSid
},
270 { SDDL_PERSONAL_SELF
, WinSelfSid
},
271 { SDDL_POWER_USERS
, WinBuiltinPowerUsersSid
},
272 { SDDL_RAS_SERVERS
, WinAccountRasAndIasServersSid
/* FIXME: DOMAIN_ALIAS_RID_RAS_SERVERS */ },
273 { SDDL_REMOTE_DESKTOP
, WinBuiltinRemoteDesktopUsersSid
},
274 { SDDL_REPLICATOR
, WinBuiltinReplicatorSid
},
275 { SDDL_RESTRICTED_CODE
, WinRestrictedCodeSid
},
276 { SDDL_SCHEMA_ADMINISTRATORS
, WinAccountSchemaAdminsSid
/* FIXME: DOMAIN_GROUP_RID_SCHEMA_ADMINS */ },
277 { SDDL_SERVER_OPERATORS
, WinBuiltinSystemOperatorsSid
},
278 { SDDL_SERVICE
, WinServiceSid
},
282 /************************************************************
283 * ADVAPI_IsLocalComputer
285 * Checks whether the server name indicates local machine.
287 BOOL
ADVAPI_IsLocalComputer(LPCWSTR ServerName
)
289 DWORD dwSize
= MAX_COMPUTERNAME_LENGTH
+ 1;
293 if (!ServerName
|| !ServerName
[0])
296 buf
= heap_alloc(dwSize
* sizeof(WCHAR
));
297 Result
= GetComputerNameW(buf
, &dwSize
);
298 if (Result
&& (ServerName
[0] == '\\') && (ServerName
[1] == '\\'))
300 Result
= Result
&& !lstrcmpW(ServerName
, buf
);
306 /************************************************************
307 * ADVAPI_GetComputerSid
309 BOOL
ADVAPI_GetComputerSid(PSID sid
)
311 static const struct /* same fields as struct SID */
314 BYTE SubAuthorityCount
;
315 SID_IDENTIFIER_AUTHORITY IdentifierAuthority
;
316 DWORD SubAuthority
[4];
318 { SID_REVISION
, 4, { SECURITY_NT_AUTHORITY
}, { SECURITY_NT_NON_UNIQUE
, 0, 0, 0 } };
320 memcpy( sid
, &computer_sid
, sizeof(computer_sid
) );
324 /* Exported functions */
330 OpenProcessToken(HANDLE ProcessHandle
,
336 TRACE("%p, %x, %p.\n", ProcessHandle
, DesiredAccess
, TokenHandle
);
338 Status
= NtOpenProcessToken(ProcessHandle
,
341 if (!NT_SUCCESS(Status
))
343 ERR("NtOpenProcessToken failed! Status %08x.\n", Status
);
344 SetLastError(RtlNtStatusToDosError(Status
));
348 TRACE("Returning token %p.\n", *TokenHandle
);
353 /******************************************************************************
354 * OpenThreadToken [ADVAPI32.@]
356 * Opens the access token associated with a thread handle.
359 * ThreadHandle [I] Handle to process
360 * DesiredAccess [I] Desired access to the thread
362 * TokenHandle [O] Destination for the token handle
365 * Success: TRUE. TokenHandle contains the access token.
369 * See NtOpenThreadToken.
372 OpenThreadToken( HANDLE ThreadHandle
, DWORD DesiredAccess
,
373 BOOL OpenAsSelf
, HANDLE
*TokenHandle
)
375 return set_ntstatus( NtOpenThreadToken(ThreadHandle
, DesiredAccess
, OpenAsSelf
, TokenHandle
));
382 AdjustTokenGroups(HANDLE TokenHandle
,
384 PTOKEN_GROUPS NewState
,
386 PTOKEN_GROUPS PreviousState
,
391 Status
= NtAdjustGroupsToken(TokenHandle
,
396 (PULONG
)ReturnLength
);
397 if (!NT_SUCCESS(Status
))
399 SetLastError(RtlNtStatusToDosError(Status
));
410 AdjustTokenPrivileges(HANDLE TokenHandle
,
411 BOOL DisableAllPrivileges
,
412 PTOKEN_PRIVILEGES NewState
,
414 PTOKEN_PRIVILEGES PreviousState
,
419 Status
= NtAdjustPrivilegesToken(TokenHandle
,
420 DisableAllPrivileges
,
424 (PULONG
)ReturnLength
);
425 if (STATUS_NOT_ALL_ASSIGNED
== Status
)
427 SetLastError(ERROR_NOT_ALL_ASSIGNED
);
431 if (!NT_SUCCESS(Status
))
433 SetLastError(RtlNtStatusToDosError(Status
));
437 /* AdjustTokenPrivileges is documented to do this */
438 SetLastError(ERROR_SUCCESS
);
447 GetTokenInformation(HANDLE TokenHandle
,
448 TOKEN_INFORMATION_CLASS TokenInformationClass
,
449 LPVOID TokenInformation
,
450 DWORD TokenInformationLength
,
455 Status
= NtQueryInformationToken(TokenHandle
,
456 TokenInformationClass
,
458 TokenInformationLength
,
459 (PULONG
)ReturnLength
);
460 if (!NT_SUCCESS(Status
))
462 SetLastError(RtlNtStatusToDosError(Status
));
473 SetTokenInformation(HANDLE TokenHandle
,
474 TOKEN_INFORMATION_CLASS TokenInformationClass
,
475 LPVOID TokenInformation
,
476 DWORD TokenInformationLength
)
480 Status
= NtSetInformationToken(TokenHandle
,
481 TokenInformationClass
,
483 TokenInformationLength
);
484 if (!NT_SUCCESS(Status
))
486 SetLastError(RtlNtStatusToDosError(Status
));
497 SetThreadToken(IN PHANDLE ThreadHandle OPTIONAL
,
498 IN HANDLE TokenHandle
)
503 hThread
= (ThreadHandle
!= NULL
) ? *ThreadHandle
: NtCurrentThread();
505 Status
= NtSetInformationThread(hThread
,
506 ThreadImpersonationToken
,
509 if (!NT_SUCCESS(Status
))
511 SetLastError(RtlNtStatusToDosError(Status
));
518 /*************************************************************************
519 * CreateRestrictedToken [ADVAPI32.@]
521 * Create a new more restricted token from an existing token.
524 * baseToken [I] Token to base the new restricted token on
526 * nDisableSids [I] Length of disableSids array
527 * disableSids [I] Array of SIDs to disable in the new token
528 * nDeletePrivs [I] Length of deletePrivs array
529 * deletePrivs [I] Array of privileges to delete in the new token
530 * nRestrictSids [I] Length of restrictSids array
531 * restrictSids [I] Array of SIDs to restrict in the new token
532 * newToken [O] Address where the new token is stored
538 BOOL WINAPI
CreateRestrictedToken(
542 PSID_AND_ATTRIBUTES disableSids
,
544 PLUID_AND_ATTRIBUTES deletePrivs
,
546 PSID_AND_ATTRIBUTES restrictSids
,
550 SECURITY_IMPERSONATION_LEVEL level
= TokenImpersonationLevel
;
553 FIXME("(%p, 0x%x, %u, %p, %u, %p, %u, %p, %p): stub\n",
554 baseToken
, flags
, nDisableSids
, disableSids
,
555 nDeletePrivs
, deletePrivs
,
556 nRestrictSids
, restrictSids
,
560 if (!GetTokenInformation( baseToken
, TokenType
, &type
, size
, &size
)) return FALSE
;
561 if (type
== TokenImpersonation
)
563 size
= sizeof(level
);
564 if (!GetTokenInformation( baseToken
, TokenImpersonationLevel
, &level
, size
, &size
))
567 return DuplicateTokenEx( baseToken
, MAXIMUM_ALLOWED
, NULL
, level
, type
, newToken
);
570 /******************************************************************************
571 * AllocateAndInitializeSid [ADVAPI32.@]
574 * pIdentifierAuthority []
575 * nSubAuthorityCount []
587 AllocateAndInitializeSid( PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority
,
588 BYTE nSubAuthorityCount
,
589 DWORD nSubAuthority0
, DWORD nSubAuthority1
,
590 DWORD nSubAuthority2
, DWORD nSubAuthority3
,
591 DWORD nSubAuthority4
, DWORD nSubAuthority5
,
592 DWORD nSubAuthority6
, DWORD nSubAuthority7
,
595 return set_ntstatus( RtlAllocateAndInitializeSid(
596 pIdentifierAuthority
, nSubAuthorityCount
,
597 nSubAuthority0
, nSubAuthority1
, nSubAuthority2
, nSubAuthority3
,
598 nSubAuthority4
, nSubAuthority5
, nSubAuthority6
, nSubAuthority7
,
606 * Docs says this function does NOT return a value
607 * even thou it's defined to return a PVOID...
613 return RtlFreeSid(pSid
);
616 /******************************************************************************
617 * CopySid [ADVAPI32.@]
620 * nDestinationSidLength []
625 CopySid( DWORD nDestinationSidLength
, PSID pDestinationSid
, PSID pSourceSid
)
627 return set_ntstatus(RtlCopySid(nDestinationSidLength
, pDestinationSid
, pSourceSid
));
635 CreateWellKnownSid(IN WELL_KNOWN_SID_TYPE WellKnownSidType
,
636 IN PSID DomainSid OPTIONAL
,
641 TRACE("(%d, %s, %p, %p)\n", WellKnownSidType
, debugstr_sid(DomainSid
), pSid
, cbSid
);
643 if (cbSid
== NULL
|| (DomainSid
&& !IsValidSid(DomainSid
)))
645 SetLastError(ERROR_INVALID_PARAMETER
);
649 for (i
= 0; i
< sizeof(WellKnownSids
)/sizeof(WellKnownSids
[0]); i
++) {
650 if (WellKnownSids
[i
].Type
== WellKnownSidType
) {
651 DWORD length
= GetSidLengthRequired(WellKnownSids
[i
].Sid
.SubAuthorityCount
);
656 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
661 SetLastError(ERROR_INVALID_PARAMETER
);
664 CopyMemory(pSid
, &WellKnownSids
[i
].Sid
.Revision
, length
);
670 if (DomainSid
== NULL
|| *GetSidSubAuthorityCount(DomainSid
) == SID_MAX_SUB_AUTHORITIES
)
672 SetLastError(ERROR_INVALID_PARAMETER
);
676 for (i
= 0; i
< sizeof(WellKnownRids
)/sizeof(WellKnownRids
[0]); i
++)
677 if (WellKnownRids
[i
].Type
== WellKnownSidType
) {
678 UCHAR domain_subauth
= *GetSidSubAuthorityCount(DomainSid
);
679 DWORD domain_sid_length
= GetSidLengthRequired(domain_subauth
);
680 DWORD output_sid_length
= GetSidLengthRequired(domain_subauth
+ 1);
682 if (*cbSid
< output_sid_length
)
684 *cbSid
= output_sid_length
;
685 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
690 SetLastError(ERROR_INVALID_PARAMETER
);
693 CopyMemory(pSid
, DomainSid
, domain_sid_length
);
694 (*GetSidSubAuthorityCount(pSid
))++;
695 (*GetSidSubAuthority(pSid
, domain_subauth
)) = WellKnownRids
[i
].Rid
;
696 *cbSid
= output_sid_length
;
700 SetLastError(ERROR_INVALID_PARAMETER
);
709 IsWellKnownSid(IN PSID pSid
,
710 IN WELL_KNOWN_SID_TYPE WellKnownSidType
)
713 TRACE("(%s, %d)\n", debugstr_sid(pSid
), WellKnownSidType
);
715 for (i
= 0; i
< sizeof(WellKnownSids
) / sizeof(WellKnownSids
[0]); i
++)
717 if (WellKnownSids
[i
].Type
== WellKnownSidType
)
719 if (EqualSid(pSid
, (PSID
)(&WellKnownSids
[i
].Sid
.Revision
)))
732 IsValidSid(PSID pSid
)
734 return (BOOL
)RtlValidSid(pSid
);
745 SetLastError(ERROR_SUCCESS
);
746 return RtlEqualSid (pSid1
, pSid2
);
754 EqualPrefixSid(PSID pSid1
,
757 return RtlEqualPrefixSid (pSid1
, pSid2
);
765 GetSidLengthRequired(UCHAR nSubAuthorityCount
)
767 return (DWORD
)RtlLengthRequiredSid(nSubAuthorityCount
);
775 InitializeSid(PSID Sid
,
776 PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority
,
777 BYTE nSubAuthorityCount
)
781 Status
= RtlInitializeSid(Sid
,
782 pIdentifierAuthority
,
784 if (!NT_SUCCESS(Status
))
786 SetLastError(RtlNtStatusToDosError(Status
));
796 PSID_IDENTIFIER_AUTHORITY
798 GetSidIdentifierAuthority(PSID pSid
)
800 return RtlIdentifierAuthoritySid(pSid
);
808 GetSidSubAuthority(PSID pSid
,
811 SetLastError(ERROR_SUCCESS
);
812 return (PDWORD
)RtlSubAuthoritySid(pSid
, nSubAuthority
);
820 GetSidSubAuthorityCount(PSID pSid
)
822 SetLastError(ERROR_SUCCESS
);
823 return RtlSubAuthorityCountSid(pSid
);
831 GetLengthSid(PSID pSid
)
833 return (DWORD
)RtlLengthSid(pSid
);
841 InitializeSecurityDescriptor(PSECURITY_DESCRIPTOR pSecurityDescriptor
,
846 Status
= RtlCreateSecurityDescriptor(pSecurityDescriptor
,
848 if (!NT_SUCCESS(Status
))
850 SetLastError(RtlNtStatusToDosError(Status
));
862 MakeAbsoluteSD(PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor
,
863 PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor
,
864 LPDWORD lpdwAbsoluteSecurityDescriptorSize
,
866 LPDWORD lpdwDaclSize
,
868 LPDWORD lpdwSaclSize
,
870 LPDWORD lpdwOwnerSize
,
872 LPDWORD lpdwPrimaryGroupSize
)
876 Status
= RtlSelfRelativeToAbsoluteSD(pSelfRelativeSecurityDescriptor
,
877 pAbsoluteSecurityDescriptor
,
878 lpdwAbsoluteSecurityDescriptorSize
,
886 lpdwPrimaryGroupSize
);
887 if (!NT_SUCCESS(Status
))
889 SetLastError(RtlNtStatusToDosError(Status
));
896 /******************************************************************************
897 * GetKernelObjectSecurity [ADVAPI32.@]
899 BOOL WINAPI
GetKernelObjectSecurity(
901 SECURITY_INFORMATION RequestedInformation
,
902 PSECURITY_DESCRIPTOR pSecurityDescriptor
,
904 LPDWORD lpnLengthNeeded
)
906 TRACE("(%p,0x%08x,%p,0x%08x,%p)\n", Handle
, RequestedInformation
,
907 pSecurityDescriptor
, nLength
, lpnLengthNeeded
);
909 return set_ntstatus( NtQuerySecurityObject(Handle
, RequestedInformation
, pSecurityDescriptor
,
910 nLength
, lpnLengthNeeded
));
918 InitializeAcl(PACL pAcl
,
924 Status
= RtlCreateAcl(pAcl
,
927 if (!NT_SUCCESS(Status
))
929 SetLastError(RtlNtStatusToDosError(Status
));
936 BOOL WINAPI
ImpersonateNamedPipeClient( HANDLE hNamedPipe
)
938 IO_STATUS_BLOCK io_block
;
940 TRACE("(%p)\n", hNamedPipe
);
942 return set_ntstatus( NtFsControlFile(hNamedPipe
, NULL
, NULL
, NULL
,
943 &io_block
, FSCTL_PIPE_IMPERSONATE
, NULL
, 0, NULL
, 0) );
951 AddAccessAllowedAce(PACL pAcl
,
958 Status
= RtlAddAccessAllowedAce(pAcl
,
962 if (!NT_SUCCESS(Status
))
964 SetLastError(RtlNtStatusToDosError(Status
));
975 AddAccessAllowedAceEx(PACL pAcl
,
983 Status
= RtlAddAccessAllowedAceEx(pAcl
,
988 if (!NT_SUCCESS(Status
))
990 SetLastError(RtlNtStatusToDosError(Status
));
1002 AddAccessDeniedAce(PACL pAcl
,
1003 DWORD dwAceRevision
,
1009 Status
= RtlAddAccessDeniedAce(pAcl
,
1013 if (!NT_SUCCESS(Status
))
1015 SetLastError(RtlNtStatusToDosError(Status
));
1026 AddAccessDeniedAceEx(PACL pAcl
,
1027 DWORD dwAceRevision
,
1034 Status
= RtlAddAccessDeniedAceEx(pAcl
,
1039 if (!NT_SUCCESS(Status
))
1041 SetLastError(RtlNtStatusToDosError(Status
));
1054 DWORD dwAceRevision
,
1055 DWORD dwStartingAceIndex
,
1057 DWORD nAceListLength
)
1061 Status
= RtlAddAce(pAcl
,
1066 if (!NT_SUCCESS(Status
))
1068 SetLastError(RtlNtStatusToDosError(Status
));
1075 /******************************************************************************
1076 * DeleteAce [ADVAPI32.@]
1078 BOOL WINAPI
DeleteAce(PACL pAcl
, DWORD dwAceIndex
)
1080 return set_ntstatus(RtlDeleteAce(pAcl
, dwAceIndex
));
1088 FindFirstFreeAce(PACL pAcl
,
1091 return RtlFirstFreeAce(pAcl
,
1095 /******************************************************************************
1096 * GetAce [ADVAPI32.@]
1098 BOOL WINAPI
GetAce(PACL pAcl
,DWORD dwAceIndex
,LPVOID
*pAce
)
1100 return set_ntstatus(RtlGetAce(pAcl
, dwAceIndex
, pAce
));
1108 GetAclInformation(PACL pAcl
,
1109 LPVOID pAclInformation
,
1110 DWORD nAclInformationLength
,
1111 ACL_INFORMATION_CLASS dwAclInformationClass
)
1115 Status
= RtlQueryInformationAcl(pAcl
,
1117 nAclInformationLength
,
1118 dwAclInformationClass
);
1119 if (!NT_SUCCESS(Status
))
1121 SetLastError(RtlNtStatusToDosError(Status
));
1133 IsValidAcl(PACL pAcl
)
1135 return RtlValidAcl (pAcl
);
1142 AllocateLocallyUniqueId(PLUID Luid
)
1146 Status
= NtAllocateLocallyUniqueId (Luid
);
1147 if (!NT_SUCCESS (Status
))
1149 SetLastError(RtlNtStatusToDosError(Status
));
1156 /**********************************************************************
1157 * LookupPrivilegeDisplayNameA EXPORTED
1163 LookupPrivilegeDisplayNameA(LPCSTR lpSystemName
,
1165 LPSTR lpDisplayName
,
1166 LPDWORD cbDisplayName
,
1167 LPDWORD lpLanguageId
)
1169 FIXME("%s() not implemented!\n", __FUNCTION__
);
1170 SetLastError (ERROR_CALL_NOT_IMPLEMENTED
);
1175 /**********************************************************************
1176 * LookupPrivilegeDisplayNameW EXPORTED
1182 LookupPrivilegeDisplayNameW(LPCWSTR lpSystemName
,
1184 LPWSTR lpDisplayName
,
1185 LPDWORD cbDisplayName
,
1186 LPDWORD lpLanguageId
)
1188 FIXME("%s() not implemented!\n", __FUNCTION__
);
1189 SetLastError (ERROR_CALL_NOT_IMPLEMENTED
);
1193 /**********************************************************************
1194 * LookupPrivilegeNameA EXPORTED
1200 LookupPrivilegeNameA(LPCSTR lpSystemName
,
1205 UNICODE_STRING lpSystemNameW
;
1209 TRACE("%s %p %p %p\n", debugstr_a(lpSystemName
), lpLuid
, lpName
, cchName
);
1211 RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW
, lpSystemName
);
1212 ret
= LookupPrivilegeNameW(lpSystemNameW
.Buffer
, lpLuid
, NULL
, &wLen
);
1213 if (!ret
&& GetLastError() == ERROR_INSUFFICIENT_BUFFER
)
1215 LPWSTR lpNameW
= HeapAlloc(GetProcessHeap(), 0, wLen
* sizeof(WCHAR
));
1217 ret
= LookupPrivilegeNameW(lpSystemNameW
.Buffer
, lpLuid
, lpNameW
,
1221 /* Windows crashes if cchName is NULL, so will I */
1222 unsigned int len
= WideCharToMultiByte(CP_ACP
, 0, lpNameW
, -1, lpName
,
1223 *cchName
, NULL
, NULL
);
1227 /* WideCharToMultiByte failed */
1230 else if (len
> *cchName
)
1233 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
1238 /* WideCharToMultiByte succeeded, output length needs to be
1239 * length not including NULL terminator
1244 HeapFree(GetProcessHeap(), 0, lpNameW
);
1246 RtlFreeUnicodeString(&lpSystemNameW
);
1250 /******************************************************************************
1251 * GetFileSecurityA [ADVAPI32.@]
1253 * Obtains Specified information about the security of a file or directory.
1256 * lpFileName [I] Name of the file to get info for
1257 * RequestedInformation [I] SE_ flags from "winnt.h"
1258 * pSecurityDescriptor [O] Destination for security information
1259 * nLength [I] Length of pSecurityDescriptor
1260 * lpnLengthNeeded [O] Destination for length of returned security information
1263 * Success: TRUE. pSecurityDescriptor contains the requested information.
1264 * Failure: FALSE. lpnLengthNeeded contains the required space to return the info.
1267 * The information returned is constrained by the callers access rights and
1274 GetFileSecurityA(LPCSTR lpFileName
,
1275 SECURITY_INFORMATION RequestedInformation
,
1276 PSECURITY_DESCRIPTOR pSecurityDescriptor
,
1278 LPDWORD lpnLengthNeeded
)
1280 UNICODE_STRING FileName
;
1283 if (!RtlCreateUnicodeStringFromAsciiz(&FileName
, lpFileName
))
1285 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
1289 bResult
= GetFileSecurityW(FileName
.Buffer
,
1290 RequestedInformation
,
1291 pSecurityDescriptor
,
1295 RtlFreeUnicodeString(&FileName
);
1305 GetFileSecurityW(LPCWSTR lpFileName
,
1306 SECURITY_INFORMATION RequestedInformation
,
1307 PSECURITY_DESCRIPTOR pSecurityDescriptor
,
1309 LPDWORD lpnLengthNeeded
)
1311 OBJECT_ATTRIBUTES ObjectAttributes
;
1312 IO_STATUS_BLOCK StatusBlock
;
1313 UNICODE_STRING FileName
;
1314 ULONG AccessMask
= 0;
1318 TRACE("GetFileSecurityW() called\n");
1320 QuerySecurityAccessMask(RequestedInformation
, &AccessMask
);
1322 if (!RtlDosPathNameToNtPathName_U(lpFileName
,
1327 ERR("Invalid path\n");
1328 SetLastError(ERROR_INVALID_NAME
);
1332 InitializeObjectAttributes(&ObjectAttributes
,
1334 OBJ_CASE_INSENSITIVE
,
1338 Status
= NtOpenFile(&FileHandle
,
1342 FILE_SHARE_READ
| FILE_SHARE_WRITE
| FILE_SHARE_DELETE
,
1345 RtlFreeHeap(RtlGetProcessHeap(),
1349 if (!NT_SUCCESS(Status
))
1351 ERR("NtOpenFile() failed (Status %lx)\n", Status
);
1352 SetLastError(RtlNtStatusToDosError(Status
));
1356 Status
= NtQuerySecurityObject(FileHandle
,
1357 RequestedInformation
,
1358 pSecurityDescriptor
,
1361 NtClose(FileHandle
);
1362 if (!NT_SUCCESS(Status
))
1364 ERR("NtQuerySecurityObject() failed (Status %lx)\n", Status
);
1365 SetLastError(RtlNtStatusToDosError(Status
));
1372 /******************************************************************************
1373 * SetFileSecurityA [ADVAPI32.@]
1374 * Sets the security of a file or directory
1380 SetFileSecurityA(LPCSTR lpFileName
,
1381 SECURITY_INFORMATION SecurityInformation
,
1382 PSECURITY_DESCRIPTOR pSecurityDescriptor
)
1384 UNICODE_STRING FileName
;
1387 if (!RtlCreateUnicodeStringFromAsciiz(&FileName
, lpFileName
))
1389 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
1393 bResult
= SetFileSecurityW(FileName
.Buffer
,
1394 SecurityInformation
,
1395 pSecurityDescriptor
);
1397 RtlFreeUnicodeString(&FileName
);
1402 /******************************************************************************
1403 * SetFileSecurityW [ADVAPI32.@]
1404 * Sets the security of a file or directory
1410 SetFileSecurityW(LPCWSTR lpFileName
,
1411 SECURITY_INFORMATION SecurityInformation
,
1412 PSECURITY_DESCRIPTOR pSecurityDescriptor
)
1414 OBJECT_ATTRIBUTES ObjectAttributes
;
1415 IO_STATUS_BLOCK StatusBlock
;
1416 UNICODE_STRING FileName
;
1417 ULONG AccessMask
= 0;
1421 TRACE("SetFileSecurityW() called\n");
1423 SetSecurityAccessMask(SecurityInformation
, &AccessMask
);
1425 if (!RtlDosPathNameToNtPathName_U(lpFileName
,
1430 ERR("Invalid path\n");
1431 SetLastError(ERROR_INVALID_NAME
);
1435 InitializeObjectAttributes(&ObjectAttributes
,
1437 OBJ_CASE_INSENSITIVE
,
1441 Status
= NtOpenFile(&FileHandle
,
1445 FILE_SHARE_READ
| FILE_SHARE_WRITE
| FILE_SHARE_DELETE
,
1448 RtlFreeHeap(RtlGetProcessHeap(),
1452 if (!NT_SUCCESS(Status
))
1454 ERR("NtOpenFile() failed (Status %lx)\n", Status
);
1455 SetLastError(RtlNtStatusToDosError(Status
));
1459 Status
= NtSetSecurityObject(FileHandle
,
1460 SecurityInformation
,
1461 pSecurityDescriptor
);
1462 NtClose(FileHandle
);
1464 if (!NT_SUCCESS(Status
))
1466 ERR("NtSetSecurityObject() failed (Status %lx)\n", Status
);
1467 SetLastError(RtlNtStatusToDosError(Status
));
1474 /******************************************************************************
1475 * QueryWindows31FilesMigration [ADVAPI32.@]
1481 QueryWindows31FilesMigration( DWORD x1
)
1483 FIXME("(%d):stub\n",x1
);
1487 /******************************************************************************
1488 * SynchronizeWindows31FilesAndWindowsNTRegistry [ADVAPI32.@]
1497 SynchronizeWindows31FilesAndWindowsNTRegistry( DWORD x1
, DWORD x2
, DWORD x3
,
1500 FIXME("(0x%08x,0x%08x,0x%08x,0x%08x):stub\n",x1
,x2
,x3
,x4
);
1512 HANDLE Token
= NULL
;
1514 Status
= NtSetInformationThread(NtCurrentThread(),
1515 ThreadImpersonationToken
,
1518 if (!NT_SUCCESS(Status
))
1520 SetLastError(RtlNtStatusToDosError(Status
));
1532 ImpersonateSelf(SECURITY_IMPERSONATION_LEVEL ImpersonationLevel
)
1536 Status
= RtlImpersonateSelf(ImpersonationLevel
);
1537 if (!NT_SUCCESS(Status
))
1539 SetLastError(RtlNtStatusToDosError(Status
));
1551 AccessCheck(IN PSECURITY_DESCRIPTOR pSecurityDescriptor
,
1552 IN HANDLE ClientToken
,
1553 IN DWORD DesiredAccess
,
1554 IN PGENERIC_MAPPING GenericMapping
,
1555 OUT PPRIVILEGE_SET PrivilegeSet OPTIONAL
,
1556 IN OUT LPDWORD PrivilegeSetLength
,
1557 OUT LPDWORD GrantedAccess
,
1558 OUT LPBOOL AccessStatus
)
1561 NTSTATUS NtAccessStatus
;
1563 /* Do the access check */
1564 Status
= NtAccessCheck(pSecurityDescriptor
,
1569 (PULONG
)PrivilegeSetLength
,
1570 (PACCESS_MASK
)GrantedAccess
,
1573 /* See if the access check operation succeeded */
1574 if (!NT_SUCCESS(Status
))
1577 SetLastError(RtlNtStatusToDosError(Status
));
1581 /* Now check the access status */
1582 if (!NT_SUCCESS(NtAccessStatus
))
1585 SetLastError(RtlNtStatusToDosError(NtAccessStatus
));
1586 *AccessStatus
= FALSE
;
1590 /* Access granted */
1591 *AccessStatus
= TRUE
;
1594 /* Check succeeded */
1601 BOOL WINAPI
AccessCheckByType(
1602 PSECURITY_DESCRIPTOR pSecurityDescriptor
,
1603 PSID PrincipalSelfSid
,
1605 DWORD DesiredAccess
,
1606 POBJECT_TYPE_LIST ObjectTypeList
,
1607 DWORD ObjectTypeListLength
,
1608 PGENERIC_MAPPING GenericMapping
,
1609 PPRIVILEGE_SET PrivilegeSet
,
1610 LPDWORD PrivilegeSetLength
,
1611 LPDWORD GrantedAccess
,
1612 LPBOOL AccessStatus
)
1616 *AccessStatus
= TRUE
;
1618 return !*AccessStatus
;
1626 SetKernelObjectSecurity(HANDLE Handle
,
1627 SECURITY_INFORMATION SecurityInformation
,
1628 PSECURITY_DESCRIPTOR SecurityDescriptor
)
1632 Status
= NtSetSecurityObject(Handle
,
1633 SecurityInformation
,
1634 SecurityDescriptor
);
1635 if (!NT_SUCCESS(Status
))
1637 SetLastError(RtlNtStatusToDosError(Status
));
1649 AddAuditAccessAce(PACL pAcl
,
1650 DWORD dwAceRevision
,
1658 Status
= RtlAddAuditAccessAce(pAcl
,
1664 if (!NT_SUCCESS(Status
))
1666 SetLastError(RtlNtStatusToDosError(Status
));
1677 AddAuditAccessAceEx(PACL pAcl
,
1678 DWORD dwAceRevision
,
1687 Status
= RtlAddAuditAccessAceEx(pAcl
,
1694 if (!NT_SUCCESS(Status
))
1696 SetLastError(RtlNtStatusToDosError(Status
));
1703 /******************************************************************************
1704 * LookupAccountNameA [ADVAPI32.@]
1710 LookupAccountNameA(LPCSTR SystemName
,
1714 LPSTR ReferencedDomainName
,
1715 LPDWORD hReferencedDomainNameLength
,
1716 PSID_NAME_USE SidNameUse
)
1719 UNICODE_STRING lpSystemW
;
1720 UNICODE_STRING lpAccountW
;
1721 LPWSTR lpReferencedDomainNameW
= NULL
;
1723 RtlCreateUnicodeStringFromAsciiz(&lpSystemW
, SystemName
);
1724 RtlCreateUnicodeStringFromAsciiz(&lpAccountW
, AccountName
);
1726 if (ReferencedDomainName
)
1727 lpReferencedDomainNameW
= HeapAlloc(GetProcessHeap(),
1729 *hReferencedDomainNameLength
* sizeof(WCHAR
));
1731 ret
= LookupAccountNameW(lpSystemW
.Buffer
,
1735 lpReferencedDomainNameW
,
1736 hReferencedDomainNameLength
,
1739 if (ret
&& lpReferencedDomainNameW
)
1741 WideCharToMultiByte(CP_ACP
,
1743 lpReferencedDomainNameW
,
1744 *hReferencedDomainNameLength
+ 1,
1745 ReferencedDomainName
,
1746 *hReferencedDomainNameLength
+ 1,
1751 RtlFreeUnicodeString(&lpSystemW
);
1752 RtlFreeUnicodeString(&lpAccountW
);
1753 HeapFree(GetProcessHeap(), 0, lpReferencedDomainNameW
);
1758 /**********************************************************************
1759 * PrivilegeCheck EXPORTED
1764 PrivilegeCheck(HANDLE ClientToken
,
1765 PPRIVILEGE_SET RequiredPrivileges
,
1771 Status
= NtPrivilegeCheck(ClientToken
,
1774 if (!NT_SUCCESS(Status
))
1776 SetLastError(RtlNtStatusToDosError(Status
));
1780 *pfResult
= (BOOL
)Result
;
1785 /******************************************************************************
1786 * GetSecurityInfoExW EXPORTED
1790 GetSecurityInfoExA(HANDLE hObject
,
1791 SE_OBJECT_TYPE ObjectType
,
1792 SECURITY_INFORMATION SecurityInfo
,
1795 PACTRL_ACCESSA
*ppAccessList
,
1796 PACTRL_AUDITA
*ppAuditList
,
1800 FIXME("%s() not implemented!\n", __FUNCTION__
);
1801 return ERROR_BAD_PROVIDER
;
1805 /******************************************************************************
1806 * GetSecurityInfoExW EXPORTED
1810 GetSecurityInfoExW(HANDLE hObject
,
1811 SE_OBJECT_TYPE ObjectType
,
1812 SECURITY_INFORMATION SecurityInfo
,
1815 PACTRL_ACCESSW
*ppAccessList
,
1816 PACTRL_AUDITW
*ppAuditList
,
1820 FIXME("%s() not implemented!\n", __FUNCTION__
);
1821 return ERROR_BAD_PROVIDER
;
1824 /******************************************************************************
1825 * BuildExplicitAccessWithNameA [ADVAPI32.@]
1828 BuildExplicitAccessWithNameA(PEXPLICIT_ACCESSA pExplicitAccess
,
1830 DWORD AccessPermissions
,
1831 ACCESS_MODE AccessMode
,
1834 pExplicitAccess
->grfAccessPermissions
= AccessPermissions
;
1835 pExplicitAccess
->grfAccessMode
= AccessMode
;
1836 pExplicitAccess
->grfInheritance
= Inheritance
;
1838 pExplicitAccess
->Trustee
.pMultipleTrustee
= NULL
;
1839 pExplicitAccess
->Trustee
.MultipleTrusteeOperation
= NO_MULTIPLE_TRUSTEE
;
1840 pExplicitAccess
->Trustee
.TrusteeForm
= TRUSTEE_IS_NAME
;
1841 pExplicitAccess
->Trustee
.TrusteeType
= TRUSTEE_IS_UNKNOWN
;
1842 pExplicitAccess
->Trustee
.ptstrName
= pTrusteeName
;
1846 /******************************************************************************
1847 * BuildExplicitAccessWithNameW [ADVAPI32.@]
1850 BuildExplicitAccessWithNameW(PEXPLICIT_ACCESSW pExplicitAccess
,
1851 LPWSTR pTrusteeName
,
1852 DWORD AccessPermissions
,
1853 ACCESS_MODE AccessMode
,
1856 pExplicitAccess
->grfAccessPermissions
= AccessPermissions
;
1857 pExplicitAccess
->grfAccessMode
= AccessMode
;
1858 pExplicitAccess
->grfInheritance
= Inheritance
;
1860 pExplicitAccess
->Trustee
.pMultipleTrustee
= NULL
;
1861 pExplicitAccess
->Trustee
.MultipleTrusteeOperation
= NO_MULTIPLE_TRUSTEE
;
1862 pExplicitAccess
->Trustee
.TrusteeForm
= TRUSTEE_IS_NAME
;
1863 pExplicitAccess
->Trustee
.TrusteeType
= TRUSTEE_IS_UNKNOWN
;
1864 pExplicitAccess
->Trustee
.ptstrName
= pTrusteeName
;
1867 /******************************************************************************
1868 * BuildTrusteeWithObjectsAndNameA [ADVAPI32.@]
1870 VOID WINAPI
BuildTrusteeWithObjectsAndNameA( PTRUSTEEA pTrustee
, POBJECTS_AND_NAME_A pObjName
,
1871 SE_OBJECT_TYPE ObjectType
, LPSTR ObjectTypeName
,
1872 LPSTR InheritedObjectTypeName
, LPSTR Name
)
1874 DWORD ObjectsPresent
= 0;
1876 TRACE("%p %p 0x%08x %p %p %s\n", pTrustee
, pObjName
,
1877 ObjectType
, ObjectTypeName
, InheritedObjectTypeName
, debugstr_a(Name
));
1879 /* Fill the OBJECTS_AND_NAME structure */
1880 pObjName
->ObjectType
= ObjectType
;
1881 if (ObjectTypeName
!= NULL
)
1883 ObjectsPresent
|= ACE_OBJECT_TYPE_PRESENT
;
1886 pObjName
->InheritedObjectTypeName
= InheritedObjectTypeName
;
1887 if (InheritedObjectTypeName
!= NULL
)
1889 ObjectsPresent
|= ACE_INHERITED_OBJECT_TYPE_PRESENT
;
1892 pObjName
->ObjectsPresent
= ObjectsPresent
;
1893 pObjName
->ptstrName
= Name
;
1895 /* Fill the TRUSTEE structure */
1896 pTrustee
->pMultipleTrustee
= NULL
;
1897 pTrustee
->MultipleTrusteeOperation
= NO_MULTIPLE_TRUSTEE
;
1898 pTrustee
->TrusteeForm
= TRUSTEE_IS_OBJECTS_AND_NAME
;
1899 pTrustee
->TrusteeType
= TRUSTEE_IS_UNKNOWN
;
1900 pTrustee
->ptstrName
= (LPSTR
)pObjName
;
1903 /******************************************************************************
1904 * BuildTrusteeWithObjectsAndNameW [ADVAPI32.@]
1906 VOID WINAPI
BuildTrusteeWithObjectsAndNameW( PTRUSTEEW pTrustee
, POBJECTS_AND_NAME_W pObjName
,
1907 SE_OBJECT_TYPE ObjectType
, LPWSTR ObjectTypeName
,
1908 LPWSTR InheritedObjectTypeName
, LPWSTR Name
)
1910 DWORD ObjectsPresent
= 0;
1912 TRACE("%p %p 0x%08x %p %p %s\n", pTrustee
, pObjName
,
1913 ObjectType
, ObjectTypeName
, InheritedObjectTypeName
, debugstr_w(Name
));
1915 /* Fill the OBJECTS_AND_NAME structure */
1916 pObjName
->ObjectType
= ObjectType
;
1917 if (ObjectTypeName
!= NULL
)
1919 ObjectsPresent
|= ACE_OBJECT_TYPE_PRESENT
;
1922 pObjName
->InheritedObjectTypeName
= InheritedObjectTypeName
;
1923 if (InheritedObjectTypeName
!= NULL
)
1925 ObjectsPresent
|= ACE_INHERITED_OBJECT_TYPE_PRESENT
;
1928 pObjName
->ObjectsPresent
= ObjectsPresent
;
1929 pObjName
->ptstrName
= Name
;
1931 /* Fill the TRUSTEE structure */
1932 pTrustee
->pMultipleTrustee
= NULL
;
1933 pTrustee
->MultipleTrusteeOperation
= NO_MULTIPLE_TRUSTEE
;
1934 pTrustee
->TrusteeForm
= TRUSTEE_IS_OBJECTS_AND_NAME
;
1935 pTrustee
->TrusteeType
= TRUSTEE_IS_UNKNOWN
;
1936 pTrustee
->ptstrName
= (LPWSTR
)pObjName
;
1939 /******************************************************************************
1940 * BuildTrusteeWithObjectsAndSidA [ADVAPI32.@]
1943 BuildTrusteeWithObjectsAndSidA(PTRUSTEEA pTrustee
,
1944 POBJECTS_AND_SID pObjSid
,
1946 GUID
*pInheritedObjectGuid
,
1949 DWORD ObjectsPresent
= 0;
1951 TRACE("%p %p %p %p %p\n", pTrustee
, pObjSid
, pObjectGuid
, pInheritedObjectGuid
, pSid
);
1953 /* Fill the OBJECTS_AND_SID structure */
1954 if (pObjectGuid
!= NULL
)
1956 pObjSid
->ObjectTypeGuid
= *pObjectGuid
;
1957 ObjectsPresent
|= ACE_OBJECT_TYPE_PRESENT
;
1961 ZeroMemory(&pObjSid
->ObjectTypeGuid
,
1965 if (pInheritedObjectGuid
!= NULL
)
1967 pObjSid
->InheritedObjectTypeGuid
= *pInheritedObjectGuid
;
1968 ObjectsPresent
|= ACE_INHERITED_OBJECT_TYPE_PRESENT
;
1972 ZeroMemory(&pObjSid
->InheritedObjectTypeGuid
,
1976 pObjSid
->ObjectsPresent
= ObjectsPresent
;
1977 pObjSid
->pSid
= pSid
;
1979 /* Fill the TRUSTEE structure */
1980 pTrustee
->pMultipleTrustee
= NULL
;
1981 pTrustee
->MultipleTrusteeOperation
= NO_MULTIPLE_TRUSTEE
;
1982 pTrustee
->TrusteeForm
= TRUSTEE_IS_OBJECTS_AND_SID
;
1983 pTrustee
->TrusteeType
= TRUSTEE_IS_UNKNOWN
;
1984 pTrustee
->ptstrName
= (LPSTR
) pObjSid
;
1988 /******************************************************************************
1989 * BuildTrusteeWithObjectsAndSidW [ADVAPI32.@]
1992 BuildTrusteeWithObjectsAndSidW(PTRUSTEEW pTrustee
,
1993 POBJECTS_AND_SID pObjSid
,
1995 GUID
*pInheritedObjectGuid
,
1998 DWORD ObjectsPresent
= 0;
2000 TRACE("%p %p %p %p %p\n", pTrustee
, pObjSid
, pObjectGuid
, pInheritedObjectGuid
, pSid
);
2002 /* Fill the OBJECTS_AND_SID structure */
2003 if (pObjectGuid
!= NULL
)
2005 pObjSid
->ObjectTypeGuid
= *pObjectGuid
;
2006 ObjectsPresent
|= ACE_OBJECT_TYPE_PRESENT
;
2010 ZeroMemory(&pObjSid
->ObjectTypeGuid
,
2014 if (pInheritedObjectGuid
!= NULL
)
2016 pObjSid
->InheritedObjectTypeGuid
= *pInheritedObjectGuid
;
2017 ObjectsPresent
|= ACE_INHERITED_OBJECT_TYPE_PRESENT
;
2021 ZeroMemory(&pObjSid
->InheritedObjectTypeGuid
,
2025 pObjSid
->ObjectsPresent
= ObjectsPresent
;
2026 pObjSid
->pSid
= pSid
;
2028 /* Fill the TRUSTEE structure */
2029 pTrustee
->pMultipleTrustee
= NULL
;
2030 pTrustee
->MultipleTrusteeOperation
= NO_MULTIPLE_TRUSTEE
;
2031 pTrustee
->TrusteeForm
= TRUSTEE_IS_OBJECTS_AND_SID
;
2032 pTrustee
->TrusteeType
= TRUSTEE_IS_UNKNOWN
;
2033 pTrustee
->ptstrName
= (LPWSTR
) pObjSid
;
2036 /******************************************************************************
2037 * BuildTrusteeWithSidA [ADVAPI32.@]
2040 BuildTrusteeWithSidA(PTRUSTEE_A pTrustee
,
2043 TRACE("%p %p\n", pTrustee
, pSid
);
2045 pTrustee
->pMultipleTrustee
= NULL
;
2046 pTrustee
->MultipleTrusteeOperation
= NO_MULTIPLE_TRUSTEE
;
2047 pTrustee
->TrusteeForm
= TRUSTEE_IS_SID
;
2048 pTrustee
->TrusteeType
= TRUSTEE_IS_UNKNOWN
;
2049 pTrustee
->ptstrName
= (LPSTR
) pSid
;
2053 /******************************************************************************
2054 * BuildTrusteeWithSidW [ADVAPI32.@]
2057 BuildTrusteeWithSidW(PTRUSTEE_W pTrustee
,
2060 TRACE("%p %p\n", pTrustee
, pSid
);
2062 pTrustee
->pMultipleTrustee
= NULL
;
2063 pTrustee
->MultipleTrusteeOperation
= NO_MULTIPLE_TRUSTEE
;
2064 pTrustee
->TrusteeForm
= TRUSTEE_IS_SID
;
2065 pTrustee
->TrusteeType
= TRUSTEE_IS_UNKNOWN
;
2066 pTrustee
->ptstrName
= (LPWSTR
) pSid
;
2069 /******************************************************************************
2070 * BuildTrusteeWithNameA [ADVAPI32.@]
2073 BuildTrusteeWithNameA(PTRUSTEE_A pTrustee
,
2076 TRACE("%p %s\n", pTrustee
, name
);
2078 pTrustee
->pMultipleTrustee
= NULL
;
2079 pTrustee
->MultipleTrusteeOperation
= NO_MULTIPLE_TRUSTEE
;
2080 pTrustee
->TrusteeForm
= TRUSTEE_IS_NAME
;
2081 pTrustee
->TrusteeType
= TRUSTEE_IS_UNKNOWN
;
2082 pTrustee
->ptstrName
= name
;
2085 /******************************************************************************
2086 * BuildTrusteeWithNameW [ADVAPI32.@]
2089 BuildTrusteeWithNameW(PTRUSTEE_W pTrustee
,
2092 TRACE("%p %s\n", pTrustee
, name
);
2094 pTrustee
->pMultipleTrustee
= NULL
;
2095 pTrustee
->MultipleTrusteeOperation
= NO_MULTIPLE_TRUSTEE
;
2096 pTrustee
->TrusteeForm
= TRUSTEE_IS_NAME
;
2097 pTrustee
->TrusteeType
= TRUSTEE_IS_UNKNOWN
;
2098 pTrustee
->ptstrName
= name
;
2101 /******************************************************************************
2102 * GetTrusteeFormW [ADVAPI32.@]
2105 GetTrusteeFormA(PTRUSTEE_A pTrustee
)
2107 return pTrustee
->TrusteeForm
;
2111 /******************************************************************************
2112 * GetTrusteeFormW [ADVAPI32.@]
2115 GetTrusteeFormW(PTRUSTEE_W pTrustee
)
2117 return pTrustee
->TrusteeForm
;
2120 /******************************************************************************
2121 * GetTrusteeNameA [ADVAPI32.@]
2124 GetTrusteeNameA(PTRUSTEE_A pTrustee
)
2126 return pTrustee
->ptstrName
;
2130 /******************************************************************************
2131 * GetTrusteeNameW [ADVAPI32.@]
2134 GetTrusteeNameW(PTRUSTEE_W pTrustee
)
2136 return pTrustee
->ptstrName
;
2139 /******************************************************************************
2140 * GetTrusteeTypeA [ADVAPI32.@]
2143 GetTrusteeTypeA(PTRUSTEE_A pTrustee
)
2145 return pTrustee
->TrusteeType
;
2148 /******************************************************************************
2149 * GetTrusteeTypeW [ADVAPI32.@]
2152 GetTrusteeTypeW(PTRUSTEE_W pTrustee
)
2154 return pTrustee
->TrusteeType
;
2162 SetAclInformation(PACL pAcl
,
2163 LPVOID pAclInformation
,
2164 DWORD nAclInformationLength
,
2165 ACL_INFORMATION_CLASS dwAclInformationClass
)
2169 Status
= RtlSetInformationAcl(pAcl
,
2171 nAclInformationLength
,
2172 dwAclInformationClass
);
2173 if (!NT_SUCCESS(Status
))
2175 SetLastError(RtlNtStatusToDosError(Status
));
2182 /**********************************************************************
2183 * SetNamedSecurityInfoA EXPORTED
2189 SetNamedSecurityInfoA(LPSTR pObjectName
,
2190 SE_OBJECT_TYPE ObjectType
,
2191 SECURITY_INFORMATION SecurityInfo
,
2197 UNICODE_STRING ObjectName
;
2200 if (!RtlCreateUnicodeStringFromAsciiz(&ObjectName
, pObjectName
))
2202 return ERROR_NOT_ENOUGH_MEMORY
;
2205 Ret
= SetNamedSecurityInfoW(ObjectName
.Buffer
,
2213 RtlFreeUnicodeString(&ObjectName
);
2223 AreAllAccessesGranted(DWORD GrantedAccess
,
2224 DWORD DesiredAccess
)
2226 return (BOOL
)RtlAreAllAccessesGranted(GrantedAccess
,
2235 AreAnyAccessesGranted(DWORD GrantedAccess
,
2236 DWORD DesiredAccess
)
2238 return (BOOL
)RtlAreAnyAccessesGranted(GrantedAccess
,
2242 /******************************************************************************
2243 * ParseAclStringFlags
2245 static DWORD
ParseAclStringFlags(LPCWSTR
* StringAcl
)
2248 LPCWSTR szAcl
= *StringAcl
;
2250 while (*szAcl
!= '(')
2254 flags
|= SE_DACL_PROTECTED
;
2256 else if (*szAcl
== 'A')
2260 flags
|= SE_DACL_AUTO_INHERIT_REQ
;
2261 else if (*szAcl
== 'I')
2262 flags
|= SE_DACL_AUTO_INHERITED
;
2271 /******************************************************************************
2272 * ParseAceStringType
2274 static const ACEFLAG AceType
[] =
2276 { SDDL_ALARM
, SYSTEM_ALARM_ACE_TYPE
},
2277 { SDDL_AUDIT
, SYSTEM_AUDIT_ACE_TYPE
},
2278 { SDDL_ACCESS_ALLOWED
, ACCESS_ALLOWED_ACE_TYPE
},
2279 { SDDL_ACCESS_DENIED
, ACCESS_DENIED_ACE_TYPE
},
2281 { SDDL_OBJECT_ACCESS_ALLOWED, ACCESS_ALLOWED_OBJECT_ACE_TYPE },
2282 { SDDL_OBJECT_ACCESS_DENIED, ACCESS_DENIED_OBJECT_ACE_TYPE },
2283 { SDDL_OBJECT_ALARM, SYSTEM_ALARM_OBJECT_ACE_TYPE },
2284 { SDDL_OBJECT_AUDIT, SYSTEM_AUDIT_OBJECT_ACE_TYPE },
2289 static BYTE
ParseAceStringType(LPCWSTR
* StringAcl
)
2292 LPCWSTR szAcl
= *StringAcl
;
2293 const ACEFLAG
*lpaf
= AceType
;
2295 while (*szAcl
== ' ')
2298 while (lpaf
->wstr
&&
2299 (len
= strlenW(lpaf
->wstr
)) &&
2300 strncmpW(lpaf
->wstr
, szAcl
, len
))
2306 *StringAcl
= szAcl
+ len
;
2311 /******************************************************************************
2312 * ParseAceStringFlags
2314 static const ACEFLAG AceFlags
[] =
2316 { SDDL_CONTAINER_INHERIT
, CONTAINER_INHERIT_ACE
},
2317 { SDDL_AUDIT_FAILURE
, FAILED_ACCESS_ACE_FLAG
},
2318 { SDDL_INHERITED
, INHERITED_ACE
},
2319 { SDDL_INHERIT_ONLY
, INHERIT_ONLY_ACE
},
2320 { SDDL_NO_PROPAGATE
, NO_PROPAGATE_INHERIT_ACE
},
2321 { SDDL_OBJECT_INHERIT
, OBJECT_INHERIT_ACE
},
2322 { SDDL_AUDIT_SUCCESS
, SUCCESSFUL_ACCESS_ACE_FLAG
},
2326 static BYTE
ParseAceStringFlags(LPCWSTR
* StringAcl
)
2330 LPCWSTR szAcl
= *StringAcl
;
2332 while (*szAcl
== ' ')
2335 while (*szAcl
!= ';')
2337 const ACEFLAG
*lpaf
= AceFlags
;
2339 while (lpaf
->wstr
&&
2340 (len
= strlenW(lpaf
->wstr
)) &&
2341 strncmpW(lpaf
->wstr
, szAcl
, len
))
2347 flags
|= lpaf
->value
;
2356 /******************************************************************************
2357 * ParseAceStringRights
2359 static const ACEFLAG AceRights
[] =
2361 { SDDL_GENERIC_ALL
, GENERIC_ALL
},
2362 { SDDL_GENERIC_READ
, GENERIC_READ
},
2363 { SDDL_GENERIC_WRITE
, GENERIC_WRITE
},
2364 { SDDL_GENERIC_EXECUTE
, GENERIC_EXECUTE
},
2366 { SDDL_READ_CONTROL
, READ_CONTROL
},
2367 { SDDL_STANDARD_DELETE
, DELETE
},
2368 { SDDL_WRITE_DAC
, WRITE_DAC
},
2369 { SDDL_WRITE_OWNER
, WRITE_OWNER
},
2371 { SDDL_READ_PROPERTY
, ADS_RIGHT_DS_READ_PROP
},
2372 { SDDL_WRITE_PROPERTY
, ADS_RIGHT_DS_WRITE_PROP
},
2373 { SDDL_CREATE_CHILD
, ADS_RIGHT_DS_CREATE_CHILD
},
2374 { SDDL_DELETE_CHILD
, ADS_RIGHT_DS_DELETE_CHILD
},
2375 { SDDL_LIST_CHILDREN
, ADS_RIGHT_ACTRL_DS_LIST
},
2376 { SDDL_SELF_WRITE
, ADS_RIGHT_DS_SELF
},
2377 { SDDL_LIST_OBJECT
, ADS_RIGHT_DS_LIST_OBJECT
},
2378 { SDDL_DELETE_TREE
, ADS_RIGHT_DS_DELETE_TREE
},
2379 { SDDL_CONTROL_ACCESS
, ADS_RIGHT_DS_CONTROL_ACCESS
},
2381 { SDDL_FILE_ALL
, FILE_ALL_ACCESS
},
2382 { SDDL_FILE_READ
, FILE_GENERIC_READ
},
2383 { SDDL_FILE_WRITE
, FILE_GENERIC_WRITE
},
2384 { SDDL_FILE_EXECUTE
, FILE_GENERIC_EXECUTE
},
2386 { SDDL_KEY_ALL
, KEY_ALL_ACCESS
},
2387 { SDDL_KEY_READ
, KEY_READ
},
2388 { SDDL_KEY_WRITE
, KEY_WRITE
},
2389 { SDDL_KEY_EXECUTE
, KEY_EXECUTE
},
2393 static DWORD
ParseAceStringRights(LPCWSTR
* StringAcl
)
2397 LPCWSTR szAcl
= *StringAcl
;
2399 while (*szAcl
== ' ')
2402 if ((*szAcl
== '0') && (*(szAcl
+ 1) == 'x'))
2406 while (*p
&& *p
!= ';')
2409 if (p
- szAcl
<= 10 /* 8 hex digits + "0x" */ )
2411 rights
= strtoulW(szAcl
, NULL
, 16);
2415 WARN("Invalid rights string format: %s\n", debugstr_wn(szAcl
, p
- szAcl
));
2419 while (*szAcl
!= ';')
2421 const ACEFLAG
*lpaf
= AceRights
;
2423 while (lpaf
->wstr
&&
2424 (len
= strlenW(lpaf
->wstr
)) &&
2425 strncmpW(lpaf
->wstr
, szAcl
, len
))
2433 rights
|= lpaf
->value
;
2443 /******************************************************************************
2444 * ParseStringAclToAcl
2446 * dacl_flags(string_ace1)(string_ace2)... (string_acen)
2448 static BOOL
ParseStringAclToAcl(LPCWSTR StringAcl
, LPDWORD lpdwFlags
,
2449 PACL pAcl
, LPDWORD cBytes
)
2453 DWORD length
= sizeof(ACL
);
2456 PACCESS_ALLOWED_ACE pAce
= NULL
; /* pointer to current ACE */
2457 DWORD error
= ERROR_INVALID_ACL
;
2459 TRACE("%s\n", debugstr_w(StringAcl
));
2464 if (pAcl
) /* pAce is only useful if we're setting values */
2465 pAce
= (PACCESS_ALLOWED_ACE
) (pAcl
+ 1);
2467 /* Parse ACL flags */
2468 *lpdwFlags
= ParseAclStringFlags(&StringAcl
);
2471 while (*StringAcl
== '(')
2475 /* Parse ACE type */
2476 val
= ParseAceStringType(&StringAcl
);
2478 pAce
->Header
.AceType
= (BYTE
) val
;
2479 if (*StringAcl
!= ';')
2481 error
= RPC_S_INVALID_STRING_UUID
;
2486 /* Parse ACE flags */
2487 val
= ParseAceStringFlags(&StringAcl
);
2489 pAce
->Header
.AceFlags
= (BYTE
) val
;
2490 if (*StringAcl
!= ';')
2494 /* Parse ACE rights */
2495 val
= ParseAceStringRights(&StringAcl
);
2498 if (*StringAcl
!= ';')
2502 /* Parse ACE object guid */
2503 while (*StringAcl
== ' ')
2505 if (*StringAcl
!= ';')
2507 FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
2512 /* Parse ACE inherit object guid */
2513 while (*StringAcl
== ' ')
2515 if (*StringAcl
!= ';')
2517 FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
2522 /* Parse ACE account sid */
2523 if (ParseStringSidToSid(StringAcl
, pAce
? &pAce
->SidStart
: NULL
, &sidlen
))
2525 while (*StringAcl
&& *StringAcl
!= ')')
2529 if (*StringAcl
!= ')')
2533 acesize
= sizeof(ACCESS_ALLOWED_ACE
) - sizeof(DWORD
) + sidlen
;
2537 pAce
->Header
.AceSize
= acesize
;
2538 pAce
= (PACCESS_ALLOWED_ACE
)((LPBYTE
)pAce
+ acesize
);
2545 if (length
> 0xffff)
2547 ERR("ACL too large\n");
2553 pAcl
->AclRevision
= ACL_REVISION
;
2555 pAcl
->AclSize
= length
;
2556 pAcl
->AceCount
= acecount
++;
2562 SetLastError(error
);
2563 WARN("Invalid ACE string format\n");
2568 /******************************************************************************
2569 * ParseStringSecurityDescriptorToSecurityDescriptor
2571 static BOOL
ParseStringSecurityDescriptorToSecurityDescriptor(
2572 LPCWSTR StringSecurityDescriptor
,
2573 SECURITY_DESCRIPTOR_RELATIVE
* SecurityDescriptor
,
2578 WCHAR tok
[MAX_PATH
];
2580 LPBYTE lpNext
= NULL
;
2583 *cBytes
= sizeof(SECURITY_DESCRIPTOR
);
2585 if (SecurityDescriptor
)
2586 lpNext
= (LPBYTE
)(SecurityDescriptor
+ 1);
2588 while (*StringSecurityDescriptor
== ' ')
2589 StringSecurityDescriptor
++;
2591 while (*StringSecurityDescriptor
)
2593 toktype
= *StringSecurityDescriptor
;
2595 /* Expect char identifier followed by ':' */
2596 StringSecurityDescriptor
++;
2597 if (*StringSecurityDescriptor
!= ':')
2599 SetLastError(ERROR_INVALID_PARAMETER
);
2602 StringSecurityDescriptor
++;
2605 lptoken
= StringSecurityDescriptor
;
2606 while (*lptoken
&& *lptoken
!= ':')
2612 len
= lptoken
- StringSecurityDescriptor
;
2613 memcpy( tok
, StringSecurityDescriptor
, len
* sizeof(WCHAR
) );
2622 if (!ParseStringSidToSid(tok
, lpNext
, &bytes
))
2625 if (SecurityDescriptor
)
2627 SecurityDescriptor
->Owner
= lpNext
- (LPBYTE
)SecurityDescriptor
;
2628 lpNext
+= bytes
; /* Advance to next token */
2640 if (!ParseStringSidToSid(tok
, lpNext
, &bytes
))
2643 if (SecurityDescriptor
)
2645 SecurityDescriptor
->Group
= lpNext
- (LPBYTE
)SecurityDescriptor
;
2646 lpNext
+= bytes
; /* Advance to next token */
2659 if (!ParseStringAclToAcl(tok
, &flags
, (PACL
)lpNext
, &bytes
))
2662 if (SecurityDescriptor
)
2664 SecurityDescriptor
->Control
|= SE_DACL_PRESENT
| flags
;
2665 SecurityDescriptor
->Dacl
= lpNext
- (LPBYTE
)SecurityDescriptor
;
2666 lpNext
+= bytes
; /* Advance to next token */
2679 if (!ParseStringAclToAcl(tok
, &flags
, (PACL
)lpNext
, &bytes
))
2682 if (SecurityDescriptor
)
2684 SecurityDescriptor
->Control
|= SE_SACL_PRESENT
| flags
;
2685 SecurityDescriptor
->Sacl
= lpNext
- (LPBYTE
)SecurityDescriptor
;
2686 lpNext
+= bytes
; /* Advance to next token */
2695 FIXME("Unknown token\n");
2696 SetLastError(ERROR_INVALID_PARAMETER
);
2700 StringSecurityDescriptor
= lptoken
;
2709 /* Winehq cvs 20050916 */
2710 /******************************************************************************
2711 * ConvertStringSecurityDescriptorToSecurityDescriptorA [ADVAPI32.@]
2716 ConvertStringSecurityDescriptorToSecurityDescriptorA(LPCSTR StringSecurityDescriptor
,
2717 DWORD StringSDRevision
,
2718 PSECURITY_DESCRIPTOR
* SecurityDescriptor
,
2719 PULONG SecurityDescriptorSize
)
2723 LPWSTR StringSecurityDescriptorW
;
2725 len
= MultiByteToWideChar(CP_ACP
, 0, StringSecurityDescriptor
, -1, NULL
, 0);
2726 StringSecurityDescriptorW
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
2728 if (StringSecurityDescriptorW
)
2730 MultiByteToWideChar(CP_ACP
, 0, StringSecurityDescriptor
, -1, StringSecurityDescriptorW
, len
);
2732 ret
= ConvertStringSecurityDescriptorToSecurityDescriptorW(StringSecurityDescriptorW
,
2733 StringSDRevision
, SecurityDescriptor
,
2734 SecurityDescriptorSize
);
2735 HeapFree(GetProcessHeap(), 0, StringSecurityDescriptorW
);
2741 /******************************************************************************
2742 * ConvertStringSecurityDescriptorToSecurityDescriptorW [ADVAPI32.@]
2746 ConvertStringSecurityDescriptorToSecurityDescriptorW(LPCWSTR StringSecurityDescriptor
,
2747 DWORD StringSDRevision
,
2748 PSECURITY_DESCRIPTOR
* SecurityDescriptor
,
2749 PULONG SecurityDescriptorSize
)
2752 SECURITY_DESCRIPTOR
* psd
;
2755 TRACE("%s\n", debugstr_w(StringSecurityDescriptor
));
2757 if (GetVersion() & 0x80000000)
2759 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
2762 else if (!StringSecurityDescriptor
|| !SecurityDescriptor
)
2764 SetLastError(ERROR_INVALID_PARAMETER
);
2767 else if (StringSDRevision
!= SID_REVISION
)
2769 SetLastError(ERROR_UNKNOWN_REVISION
);
2773 /* Compute security descriptor length */
2774 if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor
,
2778 psd
= *SecurityDescriptor
= LocalAlloc(GMEM_ZEROINIT
, cBytes
);
2779 if (!psd
) goto lend
;
2781 psd
->Revision
= SID_REVISION
;
2782 psd
->Control
|= SE_SELF_RELATIVE
;
2784 if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor
,
2785 (SECURITY_DESCRIPTOR_RELATIVE
*)psd
, &cBytes
))
2791 if (SecurityDescriptorSize
)
2792 *SecurityDescriptorSize
= cBytes
;
2797 TRACE(" ret=%d\n", bret
);
2801 static void DumpString(LPCWSTR string
, int cch
, WCHAR
**pwptr
, ULONG
*plen
)
2804 cch
= strlenW(string
);
2811 memcpy(*pwptr
, string
, sizeof(WCHAR
)*cch
);
2816 static BOOL
DumpSidNumeric(PSID psid
, WCHAR
**pwptr
, ULONG
*plen
)
2819 WCHAR fmt
[] = { 'S','-','%','u','-','%','d',0 };
2820 WCHAR subauthfmt
[] = { '-','%','u',0 };
2824 if( !IsValidSid( psid
) || pisid
->Revision
!= SDDL_REVISION
)
2826 SetLastError(ERROR_INVALID_SID
);
2830 if (pisid
->IdentifierAuthority
.Value
[0] ||
2831 pisid
->IdentifierAuthority
.Value
[1])
2833 FIXME("not matching MS' bugs\n");
2834 SetLastError(ERROR_INVALID_SID
);
2838 sprintfW( buf
, fmt
, pisid
->Revision
,
2840 MAKEWORD( pisid
->IdentifierAuthority
.Value
[5],
2841 pisid
->IdentifierAuthority
.Value
[4] ),
2842 MAKEWORD( pisid
->IdentifierAuthority
.Value
[3],
2843 pisid
->IdentifierAuthority
.Value
[2] )
2845 DumpString(buf
, -1, pwptr
, plen
);
2847 for( i
=0; i
<pisid
->SubAuthorityCount
; i
++ )
2849 sprintfW( buf
, subauthfmt
, pisid
->SubAuthority
[i
] );
2850 DumpString(buf
, -1, pwptr
, plen
);
2855 static BOOL
DumpSid(PSID psid
, WCHAR
**pwptr
, ULONG
*plen
)
2858 for (i
= 0; i
< sizeof(WellKnownSids
) / sizeof(WellKnownSids
[0]); i
++)
2860 if (WellKnownSids
[i
].wstr
[0] && EqualSid(psid
, (PSID
)&(WellKnownSids
[i
].Sid
.Revision
)))
2862 DumpString(WellKnownSids
[i
].wstr
, 2, pwptr
, plen
);
2867 return DumpSidNumeric(psid
, pwptr
, plen
);
2870 static const LPCWSTR AceRightBitNames
[32] = {
2871 SDDL_CREATE_CHILD
, /* 0 */
2875 SDDL_READ_PROPERTY
, /* 4 */
2876 SDDL_WRITE_PROPERTY
,
2879 SDDL_CONTROL_ACCESS
, /* 8 */
2887 SDDL_STANDARD_DELETE
, /* 16 */
2899 SDDL_GENERIC_ALL
, /* 28 */
2900 SDDL_GENERIC_EXECUTE
,
2905 static void DumpRights(DWORD mask
, WCHAR
**pwptr
, ULONG
*plen
)
2907 static const WCHAR fmtW
[] = {'0','x','%','x',0};
2914 /* first check if the right have name */
2915 for (i
= 0; i
< sizeof(AceRights
)/sizeof(AceRights
[0]); i
++)
2917 if (AceRights
[i
].wstr
== NULL
)
2919 if (mask
== AceRights
[i
].value
)
2921 DumpString(AceRights
[i
].wstr
, -1, pwptr
, plen
);
2926 /* then check if it can be built from bit names */
2927 for (i
= 0; i
< 32; i
++)
2929 if ((mask
& (1 << i
)) && (AceRightBitNames
[i
] == NULL
))
2931 /* can't be built from bit names */
2932 sprintfW(buf
, fmtW
, mask
);
2933 DumpString(buf
, -1, pwptr
, plen
);
2938 /* build from bit names */
2939 for (i
= 0; i
< 32; i
++)
2940 if (mask
& (1 << i
))
2941 DumpString(AceRightBitNames
[i
], -1, pwptr
, plen
);
2944 static BOOL
DumpAce(LPVOID pace
, WCHAR
**pwptr
, ULONG
*plen
)
2946 ACCESS_ALLOWED_ACE
*piace
; /* all the supported ACEs have the same memory layout */
2947 static const WCHAR openbr
= '(';
2948 static const WCHAR closebr
= ')';
2949 static const WCHAR semicolon
= ';';
2951 if (((PACE_HEADER
)pace
)->AceType
> SYSTEM_ALARM_ACE_TYPE
|| ((PACE_HEADER
)pace
)->AceSize
< sizeof(ACCESS_ALLOWED_ACE
))
2953 SetLastError(ERROR_INVALID_ACL
);
2958 DumpString(&openbr
, 1, pwptr
, plen
);
2959 switch (piace
->Header
.AceType
)
2961 case ACCESS_ALLOWED_ACE_TYPE
:
2962 DumpString(SDDL_ACCESS_ALLOWED
, -1, pwptr
, plen
);
2964 case ACCESS_DENIED_ACE_TYPE
:
2965 DumpString(SDDL_ACCESS_DENIED
, -1, pwptr
, plen
);
2967 case SYSTEM_AUDIT_ACE_TYPE
:
2968 DumpString(SDDL_AUDIT
, -1, pwptr
, plen
);
2970 case SYSTEM_ALARM_ACE_TYPE
:
2971 DumpString(SDDL_ALARM
, -1, pwptr
, plen
);
2974 DumpString(&semicolon
, 1, pwptr
, plen
);
2976 if (piace
->Header
.AceFlags
& OBJECT_INHERIT_ACE
)
2977 DumpString(SDDL_OBJECT_INHERIT
, -1, pwptr
, plen
);
2978 if (piace
->Header
.AceFlags
& CONTAINER_INHERIT_ACE
)
2979 DumpString(SDDL_CONTAINER_INHERIT
, -1, pwptr
, plen
);
2980 if (piace
->Header
.AceFlags
& NO_PROPAGATE_INHERIT_ACE
)
2981 DumpString(SDDL_NO_PROPAGATE
, -1, pwptr
, plen
);
2982 if (piace
->Header
.AceFlags
& INHERIT_ONLY_ACE
)
2983 DumpString(SDDL_INHERIT_ONLY
, -1, pwptr
, plen
);
2984 if (piace
->Header
.AceFlags
& INHERITED_ACE
)
2985 DumpString(SDDL_INHERITED
, -1, pwptr
, plen
);
2986 if (piace
->Header
.AceFlags
& SUCCESSFUL_ACCESS_ACE_FLAG
)
2987 DumpString(SDDL_AUDIT_SUCCESS
, -1, pwptr
, plen
);
2988 if (piace
->Header
.AceFlags
& FAILED_ACCESS_ACE_FLAG
)
2989 DumpString(SDDL_AUDIT_FAILURE
, -1, pwptr
, plen
);
2990 DumpString(&semicolon
, 1, pwptr
, plen
);
2991 DumpRights(piace
->Mask
, pwptr
, plen
);
2992 DumpString(&semicolon
, 1, pwptr
, plen
);
2993 /* objects not supported */
2994 DumpString(&semicolon
, 1, pwptr
, plen
);
2995 /* objects not supported */
2996 DumpString(&semicolon
, 1, pwptr
, plen
);
2997 if (!DumpSid((PSID
)&piace
->SidStart
, pwptr
, plen
))
2999 DumpString(&closebr
, 1, pwptr
, plen
);
3003 static BOOL
DumpAcl(PACL pacl
, WCHAR
**pwptr
, ULONG
*plen
, BOOL
protected, BOOL autoInheritReq
, BOOL autoInherited
)
3009 DumpString(SDDL_PROTECTED
, -1, pwptr
, plen
);
3011 DumpString(SDDL_AUTO_INHERIT_REQ
, -1, pwptr
, plen
);
3013 DumpString(SDDL_AUTO_INHERITED
, -1, pwptr
, plen
);
3018 if (!IsValidAcl(pacl
))
3021 count
= pacl
->AceCount
;
3022 for (i
= 0; i
< count
; i
++)
3025 if (!GetAce(pacl
, i
, &ace
))
3027 if (!DumpAce(ace
, pwptr
, plen
))
3034 static BOOL
DumpOwner(PSECURITY_DESCRIPTOR SecurityDescriptor
, WCHAR
**pwptr
, ULONG
*plen
)
3036 static const WCHAR prefix
[] = {'O',':',0};
3040 if (!GetSecurityDescriptorOwner(SecurityDescriptor
, &psid
, &bDefaulted
))
3046 DumpString(prefix
, -1, pwptr
, plen
);
3047 if (!DumpSid(psid
, pwptr
, plen
))
3052 static BOOL
DumpGroup(PSECURITY_DESCRIPTOR SecurityDescriptor
, WCHAR
**pwptr
, ULONG
*plen
)
3054 static const WCHAR prefix
[] = {'G',':',0};
3058 if (!GetSecurityDescriptorGroup(SecurityDescriptor
, &psid
, &bDefaulted
))
3064 DumpString(prefix
, -1, pwptr
, plen
);
3065 if (!DumpSid(psid
, pwptr
, plen
))
3070 static BOOL
DumpDacl(PSECURITY_DESCRIPTOR SecurityDescriptor
, WCHAR
**pwptr
, ULONG
*plen
)
3072 static const WCHAR dacl
[] = {'D',':',0};
3073 SECURITY_DESCRIPTOR_CONTROL control
;
3074 BOOL present
, defaulted
;
3078 if (!GetSecurityDescriptorDacl(SecurityDescriptor
, &present
, &pacl
, &defaulted
))
3081 if (!GetSecurityDescriptorControl(SecurityDescriptor
, &control
, &revision
))
3087 DumpString(dacl
, 2, pwptr
, plen
);
3088 if (!DumpAcl(pacl
, pwptr
, plen
, control
& SE_DACL_PROTECTED
, control
& SE_DACL_AUTO_INHERIT_REQ
, control
& SE_DACL_AUTO_INHERITED
))
3093 static BOOL
DumpSacl(PSECURITY_DESCRIPTOR SecurityDescriptor
, WCHAR
**pwptr
, ULONG
*plen
)
3095 static const WCHAR sacl
[] = {'S',':',0};
3096 SECURITY_DESCRIPTOR_CONTROL control
;
3097 BOOL present
, defaulted
;
3101 if (!GetSecurityDescriptorSacl(SecurityDescriptor
, &present
, &pacl
, &defaulted
))
3104 if (!GetSecurityDescriptorControl(SecurityDescriptor
, &control
, &revision
))
3110 DumpString(sacl
, 2, pwptr
, plen
);
3111 if (!DumpAcl(pacl
, pwptr
, plen
, control
& SE_SACL_PROTECTED
, control
& SE_SACL_AUTO_INHERIT_REQ
, control
& SE_SACL_AUTO_INHERITED
))
3116 /******************************************************************************
3117 * ConvertSecurityDescriptorToStringSecurityDescriptorW [ADVAPI32.@]
3121 ConvertSecurityDescriptorToStringSecurityDescriptorW(PSECURITY_DESCRIPTOR SecurityDescriptor
,
3123 SECURITY_INFORMATION SecurityInformation
,
3124 LPWSTR
*OutputString
,
3130 if (SDRevision
!= SDDL_REVISION_1
)
3132 ERR("Program requested unknown SDDL revision %d\n", SDRevision
);
3133 SetLastError(ERROR_UNKNOWN_REVISION
);
3138 if (SecurityInformation
& OWNER_SECURITY_INFORMATION
)
3139 if (!DumpOwner(SecurityDescriptor
, NULL
, &len
))
3141 if (SecurityInformation
& GROUP_SECURITY_INFORMATION
)
3142 if (!DumpGroup(SecurityDescriptor
, NULL
, &len
))
3144 if (SecurityInformation
& DACL_SECURITY_INFORMATION
)
3145 if (!DumpDacl(SecurityDescriptor
, NULL
, &len
))
3147 if (SecurityInformation
& SACL_SECURITY_INFORMATION
)
3148 if (!DumpSacl(SecurityDescriptor
, NULL
, &len
))
3151 wstr
= wptr
= LocalAlloc(0, (len
+ 1)*sizeof(WCHAR
));
3155 if (SecurityInformation
& OWNER_SECURITY_INFORMATION
)
3156 if (!DumpOwner(SecurityDescriptor
, &wptr
, NULL
))
3158 if (SecurityInformation
& GROUP_SECURITY_INFORMATION
)
3159 if (!DumpGroup(SecurityDescriptor
, &wptr
, NULL
))
3161 if (SecurityInformation
& DACL_SECURITY_INFORMATION
)
3162 if (!DumpDacl(SecurityDescriptor
, &wptr
, NULL
))
3164 if (SecurityInformation
& SACL_SECURITY_INFORMATION
)
3165 if (!DumpSacl(SecurityDescriptor
, &wptr
, NULL
))
3169 TRACE("ret: %s, %d\n", wine_dbgstr_w(wstr
), len
);
3170 *OutputString
= wstr
;
3172 *OutputLen
= strlenW(*OutputString
)+1;
3176 /******************************************************************************
3177 * ConvertSecurityDescriptorToStringSecurityDescriptorA [ADVAPI32.@]
3181 ConvertSecurityDescriptorToStringSecurityDescriptorA(PSECURITY_DESCRIPTOR SecurityDescriptor
,
3183 SECURITY_INFORMATION Information
,
3184 LPSTR
*OutputString
,
3190 if (ConvertSecurityDescriptorToStringSecurityDescriptorW(SecurityDescriptor
, SDRevision
, Information
, &wstr
, &len
))
3194 lenA
= WideCharToMultiByte(CP_ACP
, 0, wstr
, len
, NULL
, 0, NULL
, NULL
);
3195 *OutputString
= HeapAlloc(GetProcessHeap(), 0, lenA
);
3196 if (*OutputString
== NULL
)
3202 WideCharToMultiByte(CP_ACP
, 0, wstr
, len
, *OutputString
, lenA
, NULL
, NULL
);
3205 if (OutputLen
!= NULL
)
3211 *OutputString
= NULL
;
3223 ConvertStringSidToSidW(IN LPCWSTR StringSid
,
3227 DWORD i
, cBytes
, identAuth
, csubauth
;
3231 TRACE("%s %p\n", debugstr_w(StringSid
), sid
);
3235 SetLastError(ERROR_INVALID_SID
);
3239 for (i
= 0; i
< sizeof(SidTable
) / sizeof(SidTable
[0]) - 1; i
++)
3241 if (wcscmp(StringSid
, SidTable
[i
].key
) == 0)
3243 WELL_KNOWN_SID_TYPE knownSid
= (WELL_KNOWN_SID_TYPE
)SidTable
[i
].value
;
3244 size
= SECURITY_MAX_SID_SIZE
;
3245 *sid
= LocalAlloc(0, size
);
3248 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
3251 ret
= CreateWellKnownSid(knownSid
,
3257 SetLastError(ERROR_INVALID_SID
);
3264 /* That's probably a string S-R-I-S-S... */
3265 if (StringSid
[0] != 'S' || StringSid
[1] != '-')
3267 SetLastError(ERROR_INVALID_SID
);
3271 cBytes
= ComputeStringSidSize(StringSid
);
3272 pisid
= (SID
*)LocalAlloc( 0, cBytes
);
3275 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
3280 csubauth
= ((cBytes
- GetSidLengthRequired(0)) / sizeof(DWORD
));
3282 StringSid
+= 2; /* Advance to Revision */
3283 pisid
->Revision
= atoiW(StringSid
);
3285 if (pisid
->Revision
!= SDDL_REVISION
)
3287 TRACE("Revision %d is unknown\n", pisid
->Revision
);
3288 goto lend
; /* ERROR_INVALID_SID */
3292 TRACE("SubAuthorityCount is 0\n");
3293 goto lend
; /* ERROR_INVALID_SID */
3296 pisid
->SubAuthorityCount
= csubauth
;
3298 /* Advance to identifier authority */
3299 while (*StringSid
&& *StringSid
!= '-')
3301 if (*StringSid
== '-')
3304 /* MS' implementation can't handle values greater than 2^32 - 1, so
3305 * we don't either; assume most significant bytes are always 0
3307 pisid
->IdentifierAuthority
.Value
[0] = 0;
3308 pisid
->IdentifierAuthority
.Value
[1] = 0;
3309 identAuth
= atoiW(StringSid
);
3310 pisid
->IdentifierAuthority
.Value
[5] = identAuth
& 0xff;
3311 pisid
->IdentifierAuthority
.Value
[4] = (identAuth
& 0xff00) >> 8;
3312 pisid
->IdentifierAuthority
.Value
[3] = (identAuth
& 0xff0000) >> 16;
3313 pisid
->IdentifierAuthority
.Value
[2] = (identAuth
& 0xff000000) >> 24;
3315 /* Advance to first sub authority */
3316 while (*StringSid
&& *StringSid
!= '-')
3318 if (*StringSid
== '-')
3323 pisid
->SubAuthority
[i
++] = atoiW(StringSid
);
3325 while (*StringSid
&& *StringSid
!= '-')
3327 if (*StringSid
== '-')
3331 if (i
!= pisid
->SubAuthorityCount
)
3332 goto lend
; /* ERROR_INVALID_SID */
3341 SetLastError(ERROR_INVALID_SID
);
3344 TRACE("returning %s\n", ret
? "TRUE" : "FALSE");
3353 ConvertStringSidToSidA(IN LPCSTR StringSid
,
3356 BOOL bRetVal
= FALSE
;
3358 TRACE("%s, %p\n", debugstr_a(StringSid
), sid
);
3359 if (GetVersion() & 0x80000000)
3360 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
3361 else if (!StringSid
|| !sid
)
3362 SetLastError(ERROR_INVALID_PARAMETER
);
3365 UINT len
= MultiByteToWideChar(CP_ACP
, 0, StringSid
, -1, NULL
, 0);
3366 LPWSTR wStringSid
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
3367 if (wStringSid
== NULL
)
3369 MultiByteToWideChar(CP_ACP
, 0, StringSid
, - 1, wStringSid
, len
);
3370 bRetVal
= ConvertStringSidToSidW(wStringSid
, sid
);
3371 HeapFree(GetProcessHeap(), 0, wStringSid
);
3381 ConvertSidToStringSidW(PSID Sid
,
3385 UNICODE_STRING UnicodeString
;
3386 WCHAR FixedBuffer
[64];
3388 if (!RtlValidSid(Sid
))
3390 SetLastError(ERROR_INVALID_SID
);
3394 UnicodeString
.Length
= 0;
3395 UnicodeString
.MaximumLength
= sizeof(FixedBuffer
);
3396 UnicodeString
.Buffer
= FixedBuffer
;
3397 Status
= RtlConvertSidToUnicodeString(&UnicodeString
, Sid
, FALSE
);
3398 if (STATUS_BUFFER_TOO_SMALL
== Status
)
3400 Status
= RtlConvertSidToUnicodeString(&UnicodeString
, Sid
, TRUE
);
3403 if (!NT_SUCCESS(Status
))
3405 SetLastError(RtlNtStatusToDosError(Status
));
3409 *StringSid
= LocalAlloc(LMEM_FIXED
, UnicodeString
.Length
+ sizeof(WCHAR
));
3410 if (NULL
== *StringSid
)
3412 if (UnicodeString
.Buffer
!= FixedBuffer
)
3414 RtlFreeUnicodeString(&UnicodeString
);
3416 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
3420 MoveMemory(*StringSid
, UnicodeString
.Buffer
, UnicodeString
.Length
);
3421 ZeroMemory((PCHAR
) *StringSid
+ UnicodeString
.Length
, sizeof(WCHAR
));
3422 if (UnicodeString
.Buffer
!= FixedBuffer
)
3424 RtlFreeUnicodeString(&UnicodeString
);
3435 ConvertSidToStringSidA(PSID Sid
,
3441 if (!ConvertSidToStringSidW(Sid
, &StringSidW
))
3446 Len
= WideCharToMultiByte(CP_ACP
, 0, StringSidW
, -1, NULL
, 0, NULL
, NULL
);
3449 LocalFree(StringSidW
);
3450 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
3454 *StringSid
= LocalAlloc(LMEM_FIXED
, Len
);
3455 if (NULL
== *StringSid
)
3457 LocalFree(StringSidW
);
3458 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
3462 if (!WideCharToMultiByte(CP_ACP
, 0, StringSidW
, -1, *StringSid
, Len
, NULL
, NULL
))
3464 LocalFree(StringSid
);
3465 LocalFree(StringSidW
);
3469 LocalFree(StringSidW
);
3478 CreateProcessWithLogonW(LPCWSTR lpUsername
,
3482 LPCWSTR lpApplicationName
,
3483 LPWSTR lpCommandLine
,
3484 DWORD dwCreationFlags
,
3485 LPVOID lpEnvironment
,
3486 LPCWSTR lpCurrentDirectory
,
3487 LPSTARTUPINFOW lpStartupInfo
,
3488 LPPROCESS_INFORMATION lpProcessInformation
)
3490 FIXME("%s %s %s 0x%08x %s %s 0x%08x %p %s %p %p stub\n", debugstr_w(lpUsername
), debugstr_w(lpDomain
),
3491 debugstr_w(lpPassword
), dwLogonFlags
, debugstr_w(lpApplicationName
),
3492 debugstr_w(lpCommandLine
), dwCreationFlags
, lpEnvironment
, debugstr_w(lpCurrentDirectory
),
3493 lpStartupInfo
, lpProcessInformation
);
3500 CreateProcessWithTokenW(IN HANDLE hToken
,
3501 IN DWORD dwLogonFlags
,
3502 IN LPCWSTR lpApplicationName OPTIONAL
,
3503 IN OUT LPWSTR lpCommandLine OPTIONAL
,
3504 IN DWORD dwCreationFlags
,
3505 IN LPVOID lpEnvironment OPTIONAL
,
3506 IN LPCWSTR lpCurrentDirectory OPTIONAL
,
3507 IN LPSTARTUPINFOW lpStartupInfo
,
3508 OUT LPPROCESS_INFORMATION lpProcessInfo
)
3518 DuplicateTokenEx(IN HANDLE ExistingTokenHandle
,
3519 IN DWORD dwDesiredAccess
,
3520 IN LPSECURITY_ATTRIBUTES lpTokenAttributes OPTIONAL
,
3521 IN SECURITY_IMPERSONATION_LEVEL ImpersonationLevel
,
3522 IN TOKEN_TYPE TokenType
,
3523 OUT PHANDLE DuplicateTokenHandle
)
3525 OBJECT_ATTRIBUTES ObjectAttributes
;
3527 SECURITY_QUALITY_OF_SERVICE Sqos
;
3529 TRACE("%p 0x%08x 0x%08x 0x%08x %p\n", ExistingTokenHandle
, dwDesiredAccess
,
3530 ImpersonationLevel
, TokenType
, DuplicateTokenHandle
);
3532 Sqos
.Length
= sizeof(SECURITY_QUALITY_OF_SERVICE
);
3533 Sqos
.ImpersonationLevel
= ImpersonationLevel
;
3534 Sqos
.ContextTrackingMode
= 0;
3535 Sqos
.EffectiveOnly
= FALSE
;
3537 if (lpTokenAttributes
!= NULL
)
3539 InitializeObjectAttributes(&ObjectAttributes
,
3541 lpTokenAttributes
->bInheritHandle
? OBJ_INHERIT
: 0,
3543 lpTokenAttributes
->lpSecurityDescriptor
);
3547 InitializeObjectAttributes(&ObjectAttributes
,
3554 ObjectAttributes
.SecurityQualityOfService
= &Sqos
;
3556 Status
= NtDuplicateToken(ExistingTokenHandle
,
3561 DuplicateTokenHandle
);
3562 if (!NT_SUCCESS(Status
))
3564 ERR("NtDuplicateToken failed: Status %08x\n", Status
);
3565 SetLastError(RtlNtStatusToDosError(Status
));
3569 TRACE("Returning token %p.\n", *DuplicateTokenHandle
);
3578 DuplicateToken(IN HANDLE ExistingTokenHandle
,
3579 IN SECURITY_IMPERSONATION_LEVEL ImpersonationLevel
,
3580 OUT PHANDLE DuplicateTokenHandle
)
3582 return DuplicateTokenEx(ExistingTokenHandle
,
3583 TOKEN_IMPERSONATE
| TOKEN_QUERY
,
3587 DuplicateTokenHandle
);
3590 /******************************************************************************
3591 * ComputeStringSidSize
3593 static DWORD
ComputeStringSidSize(LPCWSTR StringSid
)
3595 if (StringSid
[0] == 'S' && StringSid
[1] == '-') /* S-R-I(-S)+ */
3600 if (*StringSid
== '-')
3606 return GetSidLengthRequired(ctok
- 2);
3608 else /* String constant format - Only available in winxp and above */
3612 for (i
= 0; i
< sizeof(WellKnownSids
)/sizeof(WellKnownSids
[0]); i
++)
3613 if (!strncmpW(WellKnownSids
[i
].wstr
, StringSid
, 2))
3614 return GetSidLengthRequired(WellKnownSids
[i
].Sid
.SubAuthorityCount
);
3616 for (i
= 0; i
< sizeof(WellKnownRids
)/sizeof(WellKnownRids
[0]); i
++)
3617 if (!strncmpW(WellKnownRids
[i
].wstr
, StringSid
, 2))
3620 ADVAPI_GetComputerSid(&local
);
3621 return GetSidLengthRequired(*GetSidSubAuthorityCount(&local
) + 1);
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 with %d\n", *cBytes
);
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
];
3730 for (i
= 0; i
< sizeof(WellKnownRids
)/sizeof(WellKnownRids
[0]); i
++)
3731 if (!strncmpW(WellKnownRids
[i
].wstr
, StringSid
, 2))
3733 ADVAPI_GetComputerSid(pisid
);
3734 pisid
->SubAuthority
[pisid
->SubAuthorityCount
] = WellKnownRids
[i
].Rid
;
3735 pisid
->SubAuthorityCount
++;
3740 FIXME("String constant not supported: %s\n", debugstr_wn(StringSid
, 2));
3745 SetLastError(ERROR_INVALID_SID
);
3747 TRACE("returning %s\n", bret
? "TRUE" : "FALSE");
3751 /**********************************************************************
3752 * GetNamedSecurityInfoA EXPORTED
3758 GetNamedSecurityInfoA(LPSTR pObjectName
,
3759 SE_OBJECT_TYPE ObjectType
,
3760 SECURITY_INFORMATION SecurityInfo
,
3765 PSECURITY_DESCRIPTOR
*ppSecurityDescriptor
)
3771 TRACE("%s %d %d %p %p %p %p %p\n", pObjectName
, ObjectType
, SecurityInfo
,
3772 ppsidOwner
, ppsidGroup
, ppDacl
, ppSacl
, ppSecurityDescriptor
);
3776 len
= MultiByteToWideChar( CP_ACP
, 0, pObjectName
, -1, NULL
, 0 );
3777 wstr
= HeapAlloc( GetProcessHeap(), 0, len
*sizeof(WCHAR
));
3778 MultiByteToWideChar( CP_ACP
, 0, pObjectName
, -1, wstr
, len
);
3781 r
= GetNamedSecurityInfoW( wstr
, ObjectType
, SecurityInfo
, ppsidOwner
,
3782 ppsidGroup
, ppDacl
, ppSacl
, ppSecurityDescriptor
);
3784 HeapFree( GetProcessHeap(), 0, wstr
);
3794 GetWindowsAccountDomainSid(IN PSID pSid
,
3795 OUT PSID ppDomainSid
,
3796 IN OUT DWORD
* cbSid
)
3807 EqualDomainSid(IN PSID pSid1
,