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 BOOL
ParseStringSidToSid(LPCWSTR StringSid
, PSID pSid
, LPDWORD cBytes
);
21 typedef struct _ACEFLAG
25 } ACEFLAG
, *LPACEFLAG
;
27 typedef struct _MAX_SID
29 /* same fields as struct _SID */
31 BYTE SubAuthorityCount
;
32 SID_IDENTIFIER_AUTHORITY IdentifierAuthority
;
33 DWORD SubAuthority
[SID_MAX_SUB_AUTHORITIES
];
36 typedef struct WELLKNOWNSID
39 WELL_KNOWN_SID_TYPE Type
;
43 static const WELLKNOWNSID WellKnownSids
[] =
45 { {0,0}, WinNullSid
, { SID_REVISION
, 1, { SECURITY_NULL_SID_AUTHORITY
}, { SECURITY_NULL_RID
} } },
46 { {'W','D'}, WinWorldSid
, { SID_REVISION
, 1, { SECURITY_WORLD_SID_AUTHORITY
}, { SECURITY_WORLD_RID
} } },
47 { {0,0}, WinLocalSid
, { SID_REVISION
, 1, { SECURITY_LOCAL_SID_AUTHORITY
}, { SECURITY_LOCAL_RID
} } },
48 { {'C','O'}, WinCreatorOwnerSid
, { SID_REVISION
, 1, { SECURITY_CREATOR_SID_AUTHORITY
}, { SECURITY_CREATOR_OWNER_RID
} } },
49 { {'C','G'}, WinCreatorGroupSid
, { SID_REVISION
, 1, { SECURITY_CREATOR_SID_AUTHORITY
}, { SECURITY_CREATOR_GROUP_RID
} } },
50 { {0,0}, WinCreatorOwnerServerSid
, { SID_REVISION
, 1, { SECURITY_CREATOR_SID_AUTHORITY
}, { SECURITY_CREATOR_OWNER_SERVER_RID
} } },
51 { {0,0}, WinCreatorGroupServerSid
, { SID_REVISION
, 1, { SECURITY_CREATOR_SID_AUTHORITY
}, { SECURITY_CREATOR_GROUP_SERVER_RID
} } },
52 { {0,0}, WinNtAuthoritySid
, { SID_REVISION
, 0, { SECURITY_NT_AUTHORITY
}, { SECURITY_NULL_RID
} } },
53 { {0,0}, WinDialupSid
, { SID_REVISION
, 1, { SECURITY_NT_AUTHORITY
}, { SECURITY_DIALUP_RID
} } },
54 { {'N','U'}, WinNetworkSid
, { SID_REVISION
, 1, { SECURITY_NT_AUTHORITY
}, { SECURITY_NETWORK_RID
} } },
55 { {0,0}, WinBatchSid
, { SID_REVISION
, 1, { SECURITY_NT_AUTHORITY
}, { SECURITY_BATCH_RID
} } },
56 { {'I','U'}, WinInteractiveSid
, { SID_REVISION
, 1, { SECURITY_NT_AUTHORITY
}, { SECURITY_INTERACTIVE_RID
} } },
57 { {'S','U'}, WinServiceSid
, { SID_REVISION
, 1, { SECURITY_NT_AUTHORITY
}, { SECURITY_SERVICE_RID
} } },
58 { {'A','N'}, WinAnonymousSid
, { SID_REVISION
, 1, { SECURITY_NT_AUTHORITY
}, { SECURITY_ANONYMOUS_LOGON_RID
} } },
59 { {0,0}, WinProxySid
, { SID_REVISION
, 1, { SECURITY_NT_AUTHORITY
}, { SECURITY_PROXY_RID
} } },
60 { {'E','D'}, WinEnterpriseControllersSid
, { SID_REVISION
, 1, { SECURITY_NT_AUTHORITY
}, { SECURITY_ENTERPRISE_CONTROLLERS_RID
} } },
61 { {'P','S'}, WinSelfSid
, { SID_REVISION
, 1, { SECURITY_NT_AUTHORITY
}, { SECURITY_PRINCIPAL_SELF_RID
} } },
62 { {'A','U'}, WinAuthenticatedUserSid
, { SID_REVISION
, 1, { SECURITY_NT_AUTHORITY
}, { SECURITY_AUTHENTICATED_USER_RID
} } },
63 { {'R','C'}, WinRestrictedCodeSid
, { SID_REVISION
, 1, { SECURITY_NT_AUTHORITY
}, { SECURITY_RESTRICTED_CODE_RID
} } },
64 { {0,0}, WinTerminalServerSid
, { SID_REVISION
, 1, { SECURITY_NT_AUTHORITY
}, { SECURITY_TERMINAL_SERVER_RID
} } },
65 { {0,0}, WinRemoteLogonIdSid
, { SID_REVISION
, 1, { SECURITY_NT_AUTHORITY
}, { SECURITY_REMOTE_LOGON_RID
} } },
66 { {'S','Y'}, WinLocalSystemSid
, { SID_REVISION
, 1, { SECURITY_NT_AUTHORITY
}, { SECURITY_LOCAL_SYSTEM_RID
} } },
67 { {'L','S'}, WinLocalServiceSid
, { SID_REVISION
, 1, { SECURITY_NT_AUTHORITY
}, { SECURITY_LOCAL_SERVICE_RID
} } },
68 { {'N','S'}, WinNetworkServiceSid
, { SID_REVISION
, 1, { SECURITY_NT_AUTHORITY
}, { SECURITY_NETWORK_SERVICE_RID
} } },
69 { {0,0}, WinBuiltinDomainSid
, { SID_REVISION
, 1, { SECURITY_NT_AUTHORITY
}, { SECURITY_BUILTIN_DOMAIN_RID
} } },
70 { {'B','A'}, WinBuiltinAdministratorsSid
, { SID_REVISION
, 2, { SECURITY_NT_AUTHORITY
}, { SECURITY_BUILTIN_DOMAIN_RID
, DOMAIN_ALIAS_RID_ADMINS
} } },
71 { {'B','U'}, WinBuiltinUsersSid
, { SID_REVISION
, 2, { SECURITY_NT_AUTHORITY
}, { SECURITY_BUILTIN_DOMAIN_RID
, DOMAIN_ALIAS_RID_USERS
} } },
72 { {'B','G'}, WinBuiltinGuestsSid
, { SID_REVISION
, 2, { SECURITY_NT_AUTHORITY
}, { SECURITY_BUILTIN_DOMAIN_RID
, DOMAIN_ALIAS_RID_GUESTS
} } },
73 { {'P','U'}, WinBuiltinPowerUsersSid
, { SID_REVISION
, 2, { SECURITY_NT_AUTHORITY
}, { SECURITY_BUILTIN_DOMAIN_RID
, DOMAIN_ALIAS_RID_POWER_USERS
} } },
74 { {'A','O'}, WinBuiltinAccountOperatorsSid
, { SID_REVISION
, 2, { SECURITY_NT_AUTHORITY
}, { SECURITY_BUILTIN_DOMAIN_RID
, DOMAIN_ALIAS_RID_ACCOUNT_OPS
} } },
75 { {'S','O'}, WinBuiltinSystemOperatorsSid
, { SID_REVISION
, 2, { SECURITY_NT_AUTHORITY
}, { SECURITY_BUILTIN_DOMAIN_RID
, DOMAIN_ALIAS_RID_SYSTEM_OPS
} } },
76 { {'P','O'}, WinBuiltinPrintOperatorsSid
, { SID_REVISION
, 2, { SECURITY_NT_AUTHORITY
}, { SECURITY_BUILTIN_DOMAIN_RID
, DOMAIN_ALIAS_RID_PRINT_OPS
} } },
77 { {'B','O'}, WinBuiltinBackupOperatorsSid
, { SID_REVISION
, 2, { SECURITY_NT_AUTHORITY
}, { SECURITY_BUILTIN_DOMAIN_RID
, DOMAIN_ALIAS_RID_BACKUP_OPS
} } },
78 { {'R','E'}, WinBuiltinReplicatorSid
, { SID_REVISION
, 2, { SECURITY_NT_AUTHORITY
}, { SECURITY_BUILTIN_DOMAIN_RID
, DOMAIN_ALIAS_RID_REPLICATOR
} } },
79 { {'R','U'}, WinBuiltinPreWindows2000CompatibleAccessSid
, { SID_REVISION
, 2, { SECURITY_NT_AUTHORITY
}, { SECURITY_BUILTIN_DOMAIN_RID
, DOMAIN_ALIAS_RID_PREW2KCOMPACCESS
} } },
80 { {'R','D'}, WinBuiltinRemoteDesktopUsersSid
, { SID_REVISION
, 2, { SECURITY_NT_AUTHORITY
}, { SECURITY_BUILTIN_DOMAIN_RID
, DOMAIN_ALIAS_RID_REMOTE_DESKTOP_USERS
} } },
81 { {'N','O'}, WinBuiltinNetworkConfigurationOperatorsSid
, { SID_REVISION
, 2, { SECURITY_NT_AUTHORITY
}, { SECURITY_BUILTIN_DOMAIN_RID
, DOMAIN_ALIAS_RID_NETWORK_CONFIGURATION_OPS
} } },
82 { {0,0}, WinNTLMAuthenticationSid
, { SID_REVISION
, 2, { SECURITY_NT_AUTHORITY
}, { SECURITY_PACKAGE_BASE_RID
, SECURITY_PACKAGE_NTLM_RID
} } },
83 { {0,0}, WinDigestAuthenticationSid
, { SID_REVISION
, 2, { SECURITY_NT_AUTHORITY
}, { SECURITY_PACKAGE_BASE_RID
, SECURITY_PACKAGE_DIGEST_RID
} } },
84 { {0,0}, WinSChannelAuthenticationSid
, { SID_REVISION
, 2, { SECURITY_NT_AUTHORITY
}, { SECURITY_PACKAGE_BASE_RID
, SECURITY_PACKAGE_SCHANNEL_RID
} } },
85 { {0,0}, WinThisOrganizationSid
, { SID_REVISION
, 1, { SECURITY_NT_AUTHORITY
}, { SECURITY_THIS_ORGANIZATION_RID
} } },
86 { {0,0}, WinOtherOrganizationSid
, { SID_REVISION
, 1, { SECURITY_NT_AUTHORITY
}, { SECURITY_OTHER_ORGANIZATION_RID
} } },
87 { {0,0}, WinBuiltinIncomingForestTrustBuildersSid
, { SID_REVISION
, 2, { SECURITY_NT_AUTHORITY
}, { SECURITY_BUILTIN_DOMAIN_RID
, DOMAIN_ALIAS_RID_INCOMING_FOREST_TRUST_BUILDERS
} } },
88 { {0,0}, WinBuiltinPerfMonitoringUsersSid
, { SID_REVISION
, 2, { SECURITY_NT_AUTHORITY
}, { SECURITY_BUILTIN_DOMAIN_RID
, DOMAIN_ALIAS_RID_MONITORING_USERS
} } },
89 { {0,0}, WinBuiltinPerfLoggingUsersSid
, { SID_REVISION
, 2, { SECURITY_NT_AUTHORITY
}, { SECURITY_BUILTIN_DOMAIN_RID
, DOMAIN_ALIAS_RID_LOGGING_USERS
} } },
90 { {0,0}, WinBuiltinAuthorizationAccessSid
, { SID_REVISION
, 2, { SECURITY_NT_AUTHORITY
}, { SECURITY_BUILTIN_DOMAIN_RID
, DOMAIN_ALIAS_RID_AUTHORIZATIONACCESS
} } },
91 { {0,0}, WinBuiltinTerminalServerLicenseServersSid
, { SID_REVISION
, 2, { SECURITY_NT_AUTHORITY
}, { SECURITY_BUILTIN_DOMAIN_RID
, DOMAIN_ALIAS_RID_TS_LICENSE_SERVERS
} } },
92 { {0,0}, WinBuiltinDCOMUsersSid
, { SID_REVISION
, 2, { SECURITY_NT_AUTHORITY
}, { SECURITY_BUILTIN_DOMAIN_RID
, DOMAIN_ALIAS_RID_DCOM_USERS
} } },
93 { {'L','W'}, WinLowLabelSid
, { SID_REVISION
, 1, { SECURITY_MANDATORY_LABEL_AUTHORITY
}, { SECURITY_MANDATORY_LOW_RID
} } },
94 { {'M','E'}, WinMediumLabelSid
, { SID_REVISION
, 1, { SECURITY_MANDATORY_LABEL_AUTHORITY
}, { SECURITY_MANDATORY_MEDIUM_RID
} } },
95 { {'H','I'}, WinHighLabelSid
, { SID_REVISION
, 1, { SECURITY_MANDATORY_LABEL_AUTHORITY
}, { SECURITY_MANDATORY_HIGH_RID
} } },
96 { {'S','I'}, WinSystemLabelSid
, { SID_REVISION
, 1, { SECURITY_MANDATORY_LABEL_AUTHORITY
}, { SECURITY_MANDATORY_SYSTEM_RID
} } },
99 /* these SIDs must be constructed as relative to some domain - only the RID is well-known */
100 typedef struct WELLKNOWNRID
103 WELL_KNOWN_SID_TYPE Type
;
107 static const WELLKNOWNRID WellKnownRids
[] = {
108 { {'L','A'}, WinAccountAdministratorSid
, DOMAIN_USER_RID_ADMIN
},
109 { {'L','G'}, WinAccountGuestSid
, DOMAIN_USER_RID_GUEST
},
110 { {0,0}, WinAccountKrbtgtSid
, DOMAIN_USER_RID_KRBTGT
},
111 { {0,0}, WinAccountDomainAdminsSid
, DOMAIN_GROUP_RID_ADMINS
},
112 { {0,0}, WinAccountDomainUsersSid
, DOMAIN_GROUP_RID_USERS
},
113 { {0,0}, WinAccountDomainGuestsSid
, DOMAIN_GROUP_RID_GUESTS
},
114 { {0,0}, WinAccountComputersSid
, DOMAIN_GROUP_RID_COMPUTERS
},
115 { {0,0}, WinAccountControllersSid
, DOMAIN_GROUP_RID_CONTROLLERS
},
116 { {0,0}, WinAccountCertAdminsSid
, DOMAIN_GROUP_RID_CERT_ADMINS
},
117 { {0,0}, WinAccountSchemaAdminsSid
, DOMAIN_GROUP_RID_SCHEMA_ADMINS
},
118 { {0,0}, WinAccountEnterpriseAdminsSid
, DOMAIN_GROUP_RID_ENTERPRISE_ADMINS
},
119 { {0,0}, WinAccountPolicyAdminsSid
, DOMAIN_GROUP_RID_POLICY_ADMINS
},
120 { {0,0}, WinAccountRasAndIasServersSid
, DOMAIN_ALIAS_RID_RAS_SERVERS
},
123 static const SID sidWorld
= { SID_REVISION
, 1, { SECURITY_WORLD_SID_AUTHORITY
} , { SECURITY_WORLD_RID
} };
128 static const WCHAR SDDL_ACCESS_ALLOWED
[] = {'A',0};
129 static const WCHAR SDDL_ACCESS_DENIED
[] = {'D',0};
130 static const WCHAR SDDL_OBJECT_ACCESS_ALLOWED
[] = {'O','A',0};
131 static const WCHAR SDDL_OBJECT_ACCESS_DENIED
[] = {'O','D',0};
132 static const WCHAR SDDL_AUDIT
[] = {'A','U',0};
133 static const WCHAR SDDL_ALARM
[] = {'A','L',0};
134 static const WCHAR SDDL_OBJECT_AUDIT
[] = {'O','U',0};
135 static const WCHAR SDDL_OBJECT_ALARM
[] = {'O','L',0};
140 #define ADS_RIGHT_DS_CREATE_CHILD 0x0001
141 #define ADS_RIGHT_DS_DELETE_CHILD 0x0002
142 #define ADS_RIGHT_ACTRL_DS_LIST 0x0004
143 #define ADS_RIGHT_DS_SELF 0x0008
144 #define ADS_RIGHT_DS_READ_PROP 0x0010
145 #define ADS_RIGHT_DS_WRITE_PROP 0x0020
146 #define ADS_RIGHT_DS_DELETE_TREE 0x0040
147 #define ADS_RIGHT_DS_LIST_OBJECT 0x0080
148 #define ADS_RIGHT_DS_CONTROL_ACCESS 0x0100
153 static const WCHAR SDDL_CONTAINER_INHERIT
[] = {'C','I',0};
154 static const WCHAR SDDL_OBJECT_INHERIT
[] = {'O','I',0};
155 static const WCHAR SDDL_NO_PROPAGATE
[] = {'N','P',0};
156 static const WCHAR SDDL_INHERIT_ONLY
[] = {'I','O',0};
157 static const WCHAR SDDL_INHERITED
[] = {'I','D',0};
158 static const WCHAR SDDL_AUDIT_SUCCESS
[] = {'S','A',0};
159 static const WCHAR SDDL_AUDIT_FAILURE
[] = {'F','A',0};
161 static const char * debugstr_sid(PSID sid
)
164 SID
* psid
= (SID
*)sid
;
169 auth
= psid
->IdentifierAuthority
.Value
[5] +
170 (psid
->IdentifierAuthority
.Value
[4] << 8) +
171 (psid
->IdentifierAuthority
.Value
[3] << 16) +
172 (psid
->IdentifierAuthority
.Value
[2] << 24);
174 switch (psid
->SubAuthorityCount
) {
176 return wine_dbg_sprintf("S-%d-%d", psid
->Revision
, auth
);
178 return wine_dbg_sprintf("S-%d-%d-%lu", psid
->Revision
, auth
,
179 psid
->SubAuthority
[0]);
181 return wine_dbg_sprintf("S-%d-%d-%lu-%lu", psid
->Revision
, auth
,
182 psid
->SubAuthority
[0], psid
->SubAuthority
[1]);
184 return wine_dbg_sprintf("S-%d-%d-%lu-%lu-%lu", psid
->Revision
, auth
,
185 psid
->SubAuthority
[0], psid
->SubAuthority
[1], psid
->SubAuthority
[2]);
187 return wine_dbg_sprintf("S-%d-%d-%lu-%lu-%lu-%lu", psid
->Revision
, auth
,
188 psid
->SubAuthority
[0], psid
->SubAuthority
[1], psid
->SubAuthority
[2],
189 psid
->SubAuthority
[3]);
191 return wine_dbg_sprintf("S-%d-%d-%lu-%lu-%lu-%lu-%lu", psid
->Revision
, auth
,
192 psid
->SubAuthority
[0], psid
->SubAuthority
[1], psid
->SubAuthority
[2],
193 psid
->SubAuthority
[3], psid
->SubAuthority
[4]);
195 return wine_dbg_sprintf("S-%d-%d-%lu-%lu-%lu-%lu-%lu-%lu", psid
->Revision
, auth
,
196 psid
->SubAuthority
[3], psid
->SubAuthority
[1], psid
->SubAuthority
[2],
197 psid
->SubAuthority
[0], psid
->SubAuthority
[4], psid
->SubAuthority
[5]);
199 return wine_dbg_sprintf("S-%d-%d-%lu-%lu-%lu-%lu-%lu-%lu-%lu", psid
->Revision
, auth
,
200 psid
->SubAuthority
[0], psid
->SubAuthority
[1], psid
->SubAuthority
[2],
201 psid
->SubAuthority
[3], psid
->SubAuthority
[4], psid
->SubAuthority
[5],
202 psid
->SubAuthority
[6]);
204 return wine_dbg_sprintf("S-%d-%d-%lu-%lu-%lu-%lu-%lu-%lu-%lu-%lu", psid
->Revision
, auth
,
205 psid
->SubAuthority
[0], psid
->SubAuthority
[1], psid
->SubAuthority
[2],
206 psid
->SubAuthority
[3], psid
->SubAuthority
[4], psid
->SubAuthority
[5],
207 psid
->SubAuthority
[6], psid
->SubAuthority
[7]);
212 /* set last error code from NT status and get the proper boolean return value */
213 /* used for functions that are a simple wrapper around the corresponding ntdll API */
214 static __inline BOOL
set_ntstatus( NTSTATUS status
)
216 if (!NT_SUCCESS(status
)) SetLastError( RtlNtStatusToDosError( status
));
217 return NT_SUCCESS(status
);
220 static LPWSTR
SERV_dup( LPCSTR str
)
227 len
= MultiByteToWideChar( CP_ACP
, 0, str
, -1, NULL
, 0 );
228 wstr
= heap_alloc( len
*sizeof (WCHAR
) );
229 MultiByteToWideChar( CP_ACP
, 0, str
, -1, wstr
, len
);
233 /************************************************************
234 * ADVAPI_IsLocalComputer
236 * Checks whether the server name indicates local machine.
238 BOOL
ADVAPI_IsLocalComputer(LPCWSTR ServerName
)
240 DWORD dwSize
= MAX_COMPUTERNAME_LENGTH
+ 1;
244 if (!ServerName
|| !ServerName
[0])
247 buf
= heap_alloc(dwSize
* sizeof(WCHAR
));
248 Result
= GetComputerNameW(buf
, &dwSize
);
249 if (Result
&& (ServerName
[0] == '\\') && (ServerName
[1] == '\\'))
251 Result
= Result
&& !lstrcmpW(ServerName
, buf
);
257 /************************************************************
258 * ADVAPI_GetComputerSid
260 BOOL
ADVAPI_GetComputerSid(PSID sid
)
262 static const struct /* same fields as struct SID */
265 BYTE SubAuthorityCount
;
266 SID_IDENTIFIER_AUTHORITY IdentifierAuthority
;
267 DWORD SubAuthority
[4];
269 { SID_REVISION
, 4, { SECURITY_NT_AUTHORITY
}, { SECURITY_NT_NON_UNIQUE
, 0, 0, 0 } };
271 memcpy( sid
, &computer_sid
, sizeof(computer_sid
) );
275 /* Exported functions */
281 OpenProcessToken(HANDLE ProcessHandle
,
287 TRACE("%p, %x, %p.\n", ProcessHandle
, DesiredAccess
, TokenHandle
);
289 Status
= NtOpenProcessToken(ProcessHandle
,
292 if (!NT_SUCCESS(Status
))
294 ERR("NtOpenProcessToken failed! Status %08x.\n", Status
);
295 SetLastError(RtlNtStatusToDosError(Status
));
299 TRACE("Returning token %p.\n", *TokenHandle
);
304 /******************************************************************************
305 * OpenThreadToken [ADVAPI32.@]
307 * Opens the access token associated with a thread handle.
310 * ThreadHandle [I] Handle to process
311 * DesiredAccess [I] Desired access to the thread
313 * TokenHandle [O] Destination for the token handle
316 * Success: TRUE. TokenHandle contains the access token.
320 * See NtOpenThreadToken.
323 OpenThreadToken( HANDLE ThreadHandle
, DWORD DesiredAccess
,
324 BOOL OpenAsSelf
, HANDLE
*TokenHandle
)
326 return set_ntstatus( NtOpenThreadToken(ThreadHandle
, DesiredAccess
, OpenAsSelf
, TokenHandle
));
333 AdjustTokenGroups(HANDLE TokenHandle
,
335 PTOKEN_GROUPS NewState
,
337 PTOKEN_GROUPS PreviousState
,
342 Status
= NtAdjustGroupsToken(TokenHandle
,
347 (PULONG
)ReturnLength
);
348 if (!NT_SUCCESS(Status
))
350 SetLastError(RtlNtStatusToDosError(Status
));
361 AdjustTokenPrivileges(HANDLE TokenHandle
,
362 BOOL DisableAllPrivileges
,
363 PTOKEN_PRIVILEGES NewState
,
365 PTOKEN_PRIVILEGES PreviousState
,
370 Status
= NtAdjustPrivilegesToken(TokenHandle
,
371 DisableAllPrivileges
,
375 (PULONG
)ReturnLength
);
376 if (STATUS_NOT_ALL_ASSIGNED
== Status
)
378 SetLastError(ERROR_NOT_ALL_ASSIGNED
);
382 if (!NT_SUCCESS(Status
))
384 SetLastError(RtlNtStatusToDosError(Status
));
388 /* AdjustTokenPrivileges is documented to do this */
389 SetLastError(ERROR_SUCCESS
);
398 GetTokenInformation(HANDLE TokenHandle
,
399 TOKEN_INFORMATION_CLASS TokenInformationClass
,
400 LPVOID TokenInformation
,
401 DWORD TokenInformationLength
,
406 Status
= NtQueryInformationToken(TokenHandle
,
407 TokenInformationClass
,
409 TokenInformationLength
,
410 (PULONG
)ReturnLength
);
411 if (!NT_SUCCESS(Status
))
413 SetLastError(RtlNtStatusToDosError(Status
));
424 SetTokenInformation(HANDLE TokenHandle
,
425 TOKEN_INFORMATION_CLASS TokenInformationClass
,
426 LPVOID TokenInformation
,
427 DWORD TokenInformationLength
)
431 Status
= NtSetInformationToken(TokenHandle
,
432 TokenInformationClass
,
434 TokenInformationLength
);
435 if (!NT_SUCCESS(Status
))
437 SetLastError(RtlNtStatusToDosError(Status
));
448 SetThreadToken(IN PHANDLE ThreadHandle OPTIONAL
,
449 IN HANDLE TokenHandle
)
454 hThread
= (ThreadHandle
!= NULL
) ? *ThreadHandle
: NtCurrentThread();
456 Status
= NtSetInformationThread(hThread
,
457 ThreadImpersonationToken
,
460 if (!NT_SUCCESS(Status
))
462 SetLastError(RtlNtStatusToDosError(Status
));
469 /*************************************************************************
470 * CreateRestrictedToken [ADVAPI32.@]
472 * Create a new more restricted token from an existing token.
475 * baseToken [I] Token to base the new restricted token on
477 * nDisableSids [I] Length of disableSids array
478 * disableSids [I] Array of SIDs to disable in the new token
479 * nDeletePrivs [I] Length of deletePrivs array
480 * deletePrivs [I] Array of privileges to delete in the new token
481 * nRestrictSids [I] Length of restrictSids array
482 * restrictSids [I] Array of SIDs to restrict in the new token
483 * newToken [O] Address where the new token is stored
489 BOOL WINAPI
CreateRestrictedToken(
493 PSID_AND_ATTRIBUTES disableSids
,
495 PLUID_AND_ATTRIBUTES deletePrivs
,
497 PSID_AND_ATTRIBUTES restrictSids
,
501 SECURITY_IMPERSONATION_LEVEL level
= TokenImpersonationLevel
;
504 FIXME("(%p, 0x%x, %u, %p, %u, %p, %u, %p, %p): stub\n",
505 baseToken
, flags
, nDisableSids
, disableSids
,
506 nDeletePrivs
, deletePrivs
,
507 nRestrictSids
, restrictSids
,
511 if (!GetTokenInformation( baseToken
, TokenType
, &type
, size
, &size
)) return FALSE
;
512 if (type
== TokenImpersonation
)
514 size
= sizeof(level
);
515 if (!GetTokenInformation( baseToken
, TokenImpersonationLevel
, &level
, size
, &size
))
518 return DuplicateTokenEx( baseToken
, MAXIMUM_ALLOWED
, NULL
, level
, type
, newToken
);
521 /******************************************************************************
522 * AllocateAndInitializeSid [ADVAPI32.@]
525 * pIdentifierAuthority []
526 * nSubAuthorityCount []
538 AllocateAndInitializeSid( PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority
,
539 BYTE nSubAuthorityCount
,
540 DWORD nSubAuthority0
, DWORD nSubAuthority1
,
541 DWORD nSubAuthority2
, DWORD nSubAuthority3
,
542 DWORD nSubAuthority4
, DWORD nSubAuthority5
,
543 DWORD nSubAuthority6
, DWORD nSubAuthority7
,
546 return set_ntstatus( RtlAllocateAndInitializeSid(
547 pIdentifierAuthority
, nSubAuthorityCount
,
548 nSubAuthority0
, nSubAuthority1
, nSubAuthority2
, nSubAuthority3
,
549 nSubAuthority4
, nSubAuthority5
, nSubAuthority6
, nSubAuthority7
,
557 * Docs says this function does NOT return a value
558 * even thou it's defined to return a PVOID...
564 return RtlFreeSid(pSid
);
567 /******************************************************************************
568 * CopySid [ADVAPI32.@]
571 * nDestinationSidLength []
576 CopySid( DWORD nDestinationSidLength
, PSID pDestinationSid
, PSID pSourceSid
)
578 return set_ntstatus(RtlCopySid(nDestinationSidLength
, pDestinationSid
, pSourceSid
));
586 CreateWellKnownSid(IN WELL_KNOWN_SID_TYPE WellKnownSidType
,
587 IN PSID DomainSid OPTIONAL
,
592 TRACE("(%d, %s, %p, %p)\n", WellKnownSidType
, debugstr_sid(DomainSid
), pSid
, cbSid
);
594 if (cbSid
== NULL
|| (DomainSid
&& !IsValidSid(DomainSid
)))
596 SetLastError(ERROR_INVALID_PARAMETER
);
600 for (i
= 0; i
< sizeof(WellKnownSids
)/sizeof(WellKnownSids
[0]); i
++) {
601 if (WellKnownSids
[i
].Type
== WellKnownSidType
) {
602 DWORD length
= GetSidLengthRequired(WellKnownSids
[i
].Sid
.SubAuthorityCount
);
607 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
612 SetLastError(ERROR_INVALID_PARAMETER
);
615 CopyMemory(pSid
, &WellKnownSids
[i
].Sid
.Revision
, length
);
621 if (DomainSid
== NULL
|| *GetSidSubAuthorityCount(DomainSid
) == SID_MAX_SUB_AUTHORITIES
)
623 SetLastError(ERROR_INVALID_PARAMETER
);
627 for (i
= 0; i
< sizeof(WellKnownRids
)/sizeof(WellKnownRids
[0]); i
++)
628 if (WellKnownRids
[i
].Type
== WellKnownSidType
) {
629 UCHAR domain_subauth
= *GetSidSubAuthorityCount(DomainSid
);
630 DWORD domain_sid_length
= GetSidLengthRequired(domain_subauth
);
631 DWORD output_sid_length
= GetSidLengthRequired(domain_subauth
+ 1);
633 if (*cbSid
< output_sid_length
)
635 *cbSid
= output_sid_length
;
636 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
641 SetLastError(ERROR_INVALID_PARAMETER
);
644 CopyMemory(pSid
, DomainSid
, domain_sid_length
);
645 (*GetSidSubAuthorityCount(pSid
))++;
646 (*GetSidSubAuthority(pSid
, domain_subauth
)) = WellKnownRids
[i
].Rid
;
647 *cbSid
= output_sid_length
;
651 SetLastError(ERROR_INVALID_PARAMETER
);
660 IsWellKnownSid(IN PSID pSid
,
661 IN WELL_KNOWN_SID_TYPE WellKnownSidType
)
664 TRACE("(%s, %d)\n", debugstr_sid(pSid
), WellKnownSidType
);
666 for (i
= 0; i
< sizeof(WellKnownSids
) / sizeof(WellKnownSids
[0]); i
++)
668 if (WellKnownSids
[i
].Type
== WellKnownSidType
)
670 if (EqualSid(pSid
, (PSID
)(&WellKnownSids
[i
].Sid
.Revision
)))
683 IsValidSid(PSID pSid
)
685 return (BOOL
)RtlValidSid(pSid
);
696 SetLastError(ERROR_SUCCESS
);
697 return RtlEqualSid (pSid1
, pSid2
);
705 EqualPrefixSid(PSID pSid1
,
708 return RtlEqualPrefixSid (pSid1
, pSid2
);
716 GetSidLengthRequired(UCHAR nSubAuthorityCount
)
718 return (DWORD
)RtlLengthRequiredSid(nSubAuthorityCount
);
726 InitializeSid(PSID Sid
,
727 PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority
,
728 BYTE nSubAuthorityCount
)
732 Status
= RtlInitializeSid(Sid
,
733 pIdentifierAuthority
,
735 if (!NT_SUCCESS(Status
))
737 SetLastError(RtlNtStatusToDosError(Status
));
747 PSID_IDENTIFIER_AUTHORITY
749 GetSidIdentifierAuthority(PSID pSid
)
751 return RtlIdentifierAuthoritySid(pSid
);
759 GetSidSubAuthority(PSID pSid
,
762 SetLastError(ERROR_SUCCESS
);
763 return (PDWORD
)RtlSubAuthoritySid(pSid
, nSubAuthority
);
771 GetSidSubAuthorityCount(PSID pSid
)
773 SetLastError(ERROR_SUCCESS
);
774 return RtlSubAuthorityCountSid(pSid
);
782 GetLengthSid(PSID pSid
)
784 return (DWORD
)RtlLengthSid(pSid
);
792 InitializeSecurityDescriptor(PSECURITY_DESCRIPTOR pSecurityDescriptor
,
797 Status
= RtlCreateSecurityDescriptor(pSecurityDescriptor
,
799 if (!NT_SUCCESS(Status
))
801 SetLastError(RtlNtStatusToDosError(Status
));
813 MakeAbsoluteSD(PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor
,
814 PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor
,
815 LPDWORD lpdwAbsoluteSecurityDescriptorSize
,
817 LPDWORD lpdwDaclSize
,
819 LPDWORD lpdwSaclSize
,
821 LPDWORD lpdwOwnerSize
,
823 LPDWORD lpdwPrimaryGroupSize
)
827 Status
= RtlSelfRelativeToAbsoluteSD(pSelfRelativeSecurityDescriptor
,
828 pAbsoluteSecurityDescriptor
,
829 lpdwAbsoluteSecurityDescriptorSize
,
837 lpdwPrimaryGroupSize
);
838 if (!NT_SUCCESS(Status
))
840 SetLastError(RtlNtStatusToDosError(Status
));
847 /******************************************************************************
848 * GetKernelObjectSecurity [ADVAPI32.@]
850 BOOL WINAPI
GetKernelObjectSecurity(
852 SECURITY_INFORMATION RequestedInformation
,
853 PSECURITY_DESCRIPTOR pSecurityDescriptor
,
855 LPDWORD lpnLengthNeeded
)
857 TRACE("(%p,0x%08x,%p,0x%08x,%p)\n", Handle
, RequestedInformation
,
858 pSecurityDescriptor
, nLength
, lpnLengthNeeded
);
860 return set_ntstatus( NtQuerySecurityObject(Handle
, RequestedInformation
, pSecurityDescriptor
,
861 nLength
, lpnLengthNeeded
));
869 InitializeAcl(PACL pAcl
,
875 Status
= RtlCreateAcl(pAcl
,
878 if (!NT_SUCCESS(Status
))
880 SetLastError(RtlNtStatusToDosError(Status
));
887 BOOL WINAPI
ImpersonateNamedPipeClient( HANDLE hNamedPipe
)
889 IO_STATUS_BLOCK io_block
;
891 TRACE("(%p)\n", hNamedPipe
);
893 return set_ntstatus( NtFsControlFile(hNamedPipe
, NULL
, NULL
, NULL
,
894 &io_block
, FSCTL_PIPE_IMPERSONATE
, NULL
, 0, NULL
, 0) );
902 AddAccessAllowedAce(PACL pAcl
,
909 Status
= RtlAddAccessAllowedAce(pAcl
,
913 if (!NT_SUCCESS(Status
))
915 SetLastError(RtlNtStatusToDosError(Status
));
926 AddAccessAllowedAceEx(PACL pAcl
,
934 Status
= RtlAddAccessAllowedAceEx(pAcl
,
939 if (!NT_SUCCESS(Status
))
941 SetLastError(RtlNtStatusToDosError(Status
));
953 AddAccessDeniedAce(PACL pAcl
,
960 Status
= RtlAddAccessDeniedAce(pAcl
,
964 if (!NT_SUCCESS(Status
))
966 SetLastError(RtlNtStatusToDosError(Status
));
977 AddAccessDeniedAceEx(PACL pAcl
,
985 Status
= RtlAddAccessDeniedAceEx(pAcl
,
990 if (!NT_SUCCESS(Status
))
992 SetLastError(RtlNtStatusToDosError(Status
));
1005 DWORD dwAceRevision
,
1006 DWORD dwStartingAceIndex
,
1008 DWORD nAceListLength
)
1012 Status
= RtlAddAce(pAcl
,
1017 if (!NT_SUCCESS(Status
))
1019 SetLastError(RtlNtStatusToDosError(Status
));
1026 /******************************************************************************
1027 * DeleteAce [ADVAPI32.@]
1029 BOOL WINAPI
DeleteAce(PACL pAcl
, DWORD dwAceIndex
)
1031 return set_ntstatus(RtlDeleteAce(pAcl
, dwAceIndex
));
1039 FindFirstFreeAce(PACL pAcl
,
1042 return RtlFirstFreeAce(pAcl
,
1046 /******************************************************************************
1047 * GetAce [ADVAPI32.@]
1049 BOOL WINAPI
GetAce(PACL pAcl
,DWORD dwAceIndex
,LPVOID
*pAce
)
1051 return set_ntstatus(RtlGetAce(pAcl
, dwAceIndex
, pAce
));
1054 /******************************************************************************
1055 * GetAclInformation [ADVAPI32.@]
1057 BOOL WINAPI
GetAclInformation(
1059 LPVOID pAclInformation
,
1060 DWORD nAclInformationLength
,
1061 ACL_INFORMATION_CLASS dwAclInformationClass
)
1063 return set_ntstatus(RtlQueryInformationAcl(pAcl
, pAclInformation
,
1064 nAclInformationLength
, dwAclInformationClass
));
1072 IsValidAcl(PACL pAcl
)
1074 return RtlValidAcl (pAcl
);
1081 AllocateLocallyUniqueId(PLUID Luid
)
1085 Status
= NtAllocateLocallyUniqueId (Luid
);
1086 if (!NT_SUCCESS (Status
))
1088 SetLastError(RtlNtStatusToDosError(Status
));
1095 /**********************************************************************
1096 * LookupPrivilegeDisplayNameA EXPORTED
1102 LookupPrivilegeDisplayNameA(LPCSTR lpSystemName
,
1104 LPSTR lpDisplayName
,
1105 LPDWORD cbDisplayName
,
1106 LPDWORD lpLanguageId
)
1108 FIXME("%s() not implemented!\n", __FUNCTION__
);
1109 SetLastError (ERROR_CALL_NOT_IMPLEMENTED
);
1114 /**********************************************************************
1115 * LookupPrivilegeDisplayNameW EXPORTED
1121 LookupPrivilegeDisplayNameW(LPCWSTR lpSystemName
,
1123 LPWSTR lpDisplayName
,
1124 LPDWORD cbDisplayName
,
1125 LPDWORD lpLanguageId
)
1127 FIXME("%s() not implemented!\n", __FUNCTION__
);
1128 SetLastError (ERROR_CALL_NOT_IMPLEMENTED
);
1132 /**********************************************************************
1133 * LookupPrivilegeNameA EXPORTED
1139 LookupPrivilegeNameA(LPCSTR lpSystemName
,
1144 UNICODE_STRING lpSystemNameW
;
1148 TRACE("%s %p %p %p\n", debugstr_a(lpSystemName
), lpLuid
, lpName
, cchName
);
1150 RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW
, lpSystemName
);
1151 ret
= LookupPrivilegeNameW(lpSystemNameW
.Buffer
, lpLuid
, NULL
, &wLen
);
1152 if (!ret
&& GetLastError() == ERROR_INSUFFICIENT_BUFFER
)
1154 LPWSTR lpNameW
= HeapAlloc(GetProcessHeap(), 0, wLen
* sizeof(WCHAR
));
1156 ret
= LookupPrivilegeNameW(lpSystemNameW
.Buffer
, lpLuid
, lpNameW
,
1160 /* Windows crashes if cchName is NULL, so will I */
1161 unsigned int len
= WideCharToMultiByte(CP_ACP
, 0, lpNameW
, -1, lpName
,
1162 *cchName
, NULL
, NULL
);
1166 /* WideCharToMultiByte failed */
1169 else if (len
> *cchName
)
1172 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
1177 /* WideCharToMultiByte succeeded, output length needs to be
1178 * length not including NULL terminator
1183 HeapFree(GetProcessHeap(), 0, lpNameW
);
1185 RtlFreeUnicodeString(&lpSystemNameW
);
1189 /******************************************************************************
1190 * GetFileSecurityA [ADVAPI32.@]
1192 * Obtains Specified information about the security of a file or directory.
1195 * lpFileName [I] Name of the file to get info for
1196 * RequestedInformation [I] SE_ flags from "winnt.h"
1197 * pSecurityDescriptor [O] Destination for security information
1198 * nLength [I] Length of pSecurityDescriptor
1199 * lpnLengthNeeded [O] Destination for length of returned security information
1202 * Success: TRUE. pSecurityDescriptor contains the requested information.
1203 * Failure: FALSE. lpnLengthNeeded contains the required space to return the info.
1206 * The information returned is constrained by the callers access rights and
1213 GetFileSecurityA(LPCSTR lpFileName
,
1214 SECURITY_INFORMATION RequestedInformation
,
1215 PSECURITY_DESCRIPTOR pSecurityDescriptor
,
1217 LPDWORD lpnLengthNeeded
)
1219 UNICODE_STRING FileName
;
1222 if (!RtlCreateUnicodeStringFromAsciiz(&FileName
, lpFileName
))
1224 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
1228 bResult
= GetFileSecurityW(FileName
.Buffer
,
1229 RequestedInformation
,
1230 pSecurityDescriptor
,
1234 RtlFreeUnicodeString(&FileName
);
1244 GetFileSecurityW(LPCWSTR lpFileName
,
1245 SECURITY_INFORMATION RequestedInformation
,
1246 PSECURITY_DESCRIPTOR pSecurityDescriptor
,
1248 LPDWORD lpnLengthNeeded
)
1250 OBJECT_ATTRIBUTES ObjectAttributes
;
1251 IO_STATUS_BLOCK StatusBlock
;
1252 UNICODE_STRING FileName
;
1253 ULONG AccessMask
= 0;
1257 TRACE("GetFileSecurityW() called\n");
1259 QuerySecurityAccessMask(RequestedInformation
, &AccessMask
);
1261 if (!RtlDosPathNameToNtPathName_U(lpFileName
,
1266 ERR("Invalid path\n");
1267 SetLastError(ERROR_INVALID_NAME
);
1271 InitializeObjectAttributes(&ObjectAttributes
,
1273 OBJ_CASE_INSENSITIVE
,
1277 Status
= NtOpenFile(&FileHandle
,
1281 FILE_SHARE_READ
| FILE_SHARE_WRITE
| FILE_SHARE_DELETE
,
1284 RtlFreeHeap(RtlGetProcessHeap(),
1288 if (!NT_SUCCESS(Status
))
1290 ERR("NtOpenFile() failed (Status %lx)\n", Status
);
1291 SetLastError(RtlNtStatusToDosError(Status
));
1295 Status
= NtQuerySecurityObject(FileHandle
,
1296 RequestedInformation
,
1297 pSecurityDescriptor
,
1300 NtClose(FileHandle
);
1301 if (!NT_SUCCESS(Status
))
1303 ERR("NtQuerySecurityObject() failed (Status %lx)\n", Status
);
1304 SetLastError(RtlNtStatusToDosError(Status
));
1311 /******************************************************************************
1312 * SetFileSecurityA [ADVAPI32.@]
1313 * Sets the security of a file or directory
1319 SetFileSecurityA(LPCSTR lpFileName
,
1320 SECURITY_INFORMATION SecurityInformation
,
1321 PSECURITY_DESCRIPTOR pSecurityDescriptor
)
1323 UNICODE_STRING FileName
;
1326 if (!RtlCreateUnicodeStringFromAsciiz(&FileName
, lpFileName
))
1328 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
1332 bResult
= SetFileSecurityW(FileName
.Buffer
,
1333 SecurityInformation
,
1334 pSecurityDescriptor
);
1336 RtlFreeUnicodeString(&FileName
);
1341 /******************************************************************************
1342 * SetFileSecurityW [ADVAPI32.@]
1343 * Sets the security of a file or directory
1349 SetFileSecurityW(LPCWSTR lpFileName
,
1350 SECURITY_INFORMATION SecurityInformation
,
1351 PSECURITY_DESCRIPTOR pSecurityDescriptor
)
1353 OBJECT_ATTRIBUTES ObjectAttributes
;
1354 IO_STATUS_BLOCK StatusBlock
;
1355 UNICODE_STRING FileName
;
1356 ULONG AccessMask
= 0;
1360 TRACE("SetFileSecurityW() called\n");
1362 SetSecurityAccessMask(SecurityInformation
, &AccessMask
);
1364 if (!RtlDosPathNameToNtPathName_U(lpFileName
,
1369 ERR("Invalid path\n");
1370 SetLastError(ERROR_INVALID_NAME
);
1374 InitializeObjectAttributes(&ObjectAttributes
,
1376 OBJ_CASE_INSENSITIVE
,
1380 Status
= NtOpenFile(&FileHandle
,
1384 FILE_SHARE_READ
| FILE_SHARE_WRITE
| FILE_SHARE_DELETE
,
1387 RtlFreeHeap(RtlGetProcessHeap(),
1391 if (!NT_SUCCESS(Status
))
1393 ERR("NtOpenFile() failed (Status %lx)\n", Status
);
1394 SetLastError(RtlNtStatusToDosError(Status
));
1398 Status
= NtSetSecurityObject(FileHandle
,
1399 SecurityInformation
,
1400 pSecurityDescriptor
);
1401 NtClose(FileHandle
);
1403 if (!NT_SUCCESS(Status
))
1405 ERR("NtSetSecurityObject() failed (Status %lx)\n", Status
);
1406 SetLastError(RtlNtStatusToDosError(Status
));
1413 /******************************************************************************
1414 * QueryWindows31FilesMigration [ADVAPI32.@]
1420 QueryWindows31FilesMigration( DWORD x1
)
1422 FIXME("(%d):stub\n",x1
);
1426 /******************************************************************************
1427 * SynchronizeWindows31FilesAndWindowsNTRegistry [ADVAPI32.@]
1436 SynchronizeWindows31FilesAndWindowsNTRegistry( DWORD x1
, DWORD x2
, DWORD x3
,
1439 FIXME("(0x%08x,0x%08x,0x%08x,0x%08x):stub\n",x1
,x2
,x3
,x4
);
1451 HANDLE Token
= NULL
;
1453 Status
= NtSetInformationThread(NtCurrentThread(),
1454 ThreadImpersonationToken
,
1457 if (!NT_SUCCESS(Status
))
1459 SetLastError(RtlNtStatusToDosError(Status
));
1471 ImpersonateSelf(SECURITY_IMPERSONATION_LEVEL ImpersonationLevel
)
1475 Status
= RtlImpersonateSelf(ImpersonationLevel
);
1476 if (!NT_SUCCESS(Status
))
1478 SetLastError(RtlNtStatusToDosError(Status
));
1490 AccessCheck(IN PSECURITY_DESCRIPTOR pSecurityDescriptor
,
1491 IN HANDLE ClientToken
,
1492 IN DWORD DesiredAccess
,
1493 IN PGENERIC_MAPPING GenericMapping
,
1494 OUT PPRIVILEGE_SET PrivilegeSet OPTIONAL
,
1495 IN OUT LPDWORD PrivilegeSetLength
,
1496 OUT LPDWORD GrantedAccess
,
1497 OUT LPBOOL AccessStatus
)
1500 NTSTATUS NtAccessStatus
;
1502 /* Do the access check */
1503 Status
= NtAccessCheck(pSecurityDescriptor
,
1508 (PULONG
)PrivilegeSetLength
,
1509 (PACCESS_MASK
)GrantedAccess
,
1512 /* See if the access check operation succeeded */
1513 if (!NT_SUCCESS(Status
))
1516 SetLastError(RtlNtStatusToDosError(Status
));
1520 /* Now check the access status */
1521 if (!NT_SUCCESS(NtAccessStatus
))
1524 SetLastError(RtlNtStatusToDosError(NtAccessStatus
));
1525 *AccessStatus
= FALSE
;
1529 /* Access granted */
1530 *AccessStatus
= TRUE
;
1533 /* Check succeeded */
1540 BOOL WINAPI
AccessCheckByType(
1541 PSECURITY_DESCRIPTOR pSecurityDescriptor
,
1542 PSID PrincipalSelfSid
,
1544 DWORD DesiredAccess
,
1545 POBJECT_TYPE_LIST ObjectTypeList
,
1546 DWORD ObjectTypeListLength
,
1547 PGENERIC_MAPPING GenericMapping
,
1548 PPRIVILEGE_SET PrivilegeSet
,
1549 LPDWORD PrivilegeSetLength
,
1550 LPDWORD GrantedAccess
,
1551 LPBOOL AccessStatus
)
1555 *AccessStatus
= TRUE
;
1557 return !*AccessStatus
;
1565 SetKernelObjectSecurity(HANDLE Handle
,
1566 SECURITY_INFORMATION SecurityInformation
,
1567 PSECURITY_DESCRIPTOR SecurityDescriptor
)
1571 Status
= NtSetSecurityObject(Handle
,
1572 SecurityInformation
,
1573 SecurityDescriptor
);
1574 if (!NT_SUCCESS(Status
))
1576 SetLastError(RtlNtStatusToDosError(Status
));
1588 AddAuditAccessAce(PACL pAcl
,
1589 DWORD dwAceRevision
,
1597 Status
= RtlAddAuditAccessAce(pAcl
,
1603 if (!NT_SUCCESS(Status
))
1605 SetLastError(RtlNtStatusToDosError(Status
));
1616 AddAuditAccessAceEx(PACL pAcl
,
1617 DWORD dwAceRevision
,
1626 Status
= RtlAddAuditAccessAceEx(pAcl
,
1633 if (!NT_SUCCESS(Status
))
1635 SetLastError(RtlNtStatusToDosError(Status
));
1642 /******************************************************************************
1643 * LookupAccountNameA [ADVAPI32.@]
1649 LookupAccountNameA(LPCSTR SystemName
,
1653 LPSTR ReferencedDomainName
,
1654 LPDWORD hReferencedDomainNameLength
,
1655 PSID_NAME_USE SidNameUse
)
1658 UNICODE_STRING lpSystemW
;
1659 UNICODE_STRING lpAccountW
;
1660 LPWSTR lpReferencedDomainNameW
= NULL
;
1662 RtlCreateUnicodeStringFromAsciiz(&lpSystemW
, SystemName
);
1663 RtlCreateUnicodeStringFromAsciiz(&lpAccountW
, AccountName
);
1665 if (ReferencedDomainName
)
1666 lpReferencedDomainNameW
= HeapAlloc(GetProcessHeap(),
1668 *hReferencedDomainNameLength
* sizeof(WCHAR
));
1670 ret
= LookupAccountNameW(lpSystemW
.Buffer
,
1674 lpReferencedDomainNameW
,
1675 hReferencedDomainNameLength
,
1678 if (ret
&& lpReferencedDomainNameW
)
1680 WideCharToMultiByte(CP_ACP
,
1682 lpReferencedDomainNameW
,
1683 *hReferencedDomainNameLength
+ 1,
1684 ReferencedDomainName
,
1685 *hReferencedDomainNameLength
+ 1,
1690 RtlFreeUnicodeString(&lpSystemW
);
1691 RtlFreeUnicodeString(&lpAccountW
);
1692 HeapFree(GetProcessHeap(), 0, lpReferencedDomainNameW
);
1697 /**********************************************************************
1698 * PrivilegeCheck EXPORTED
1703 PrivilegeCheck(HANDLE ClientToken
,
1704 PPRIVILEGE_SET RequiredPrivileges
,
1710 Status
= NtPrivilegeCheck(ClientToken
,
1713 if (!NT_SUCCESS(Status
))
1715 SetLastError(RtlNtStatusToDosError(Status
));
1719 *pfResult
= (BOOL
)Result
;
1724 /******************************************************************************
1725 * GetSecurityInfoExW EXPORTED
1729 GetSecurityInfoExA(HANDLE hObject
,
1730 SE_OBJECT_TYPE ObjectType
,
1731 SECURITY_INFORMATION SecurityInfo
,
1734 PACTRL_ACCESSA
*ppAccessList
,
1735 PACTRL_AUDITA
*ppAuditList
,
1739 FIXME("%s() not implemented!\n", __FUNCTION__
);
1740 return ERROR_BAD_PROVIDER
;
1744 /******************************************************************************
1745 * GetSecurityInfoExW EXPORTED
1749 GetSecurityInfoExW(HANDLE hObject
,
1750 SE_OBJECT_TYPE ObjectType
,
1751 SECURITY_INFORMATION SecurityInfo
,
1754 PACTRL_ACCESSW
*ppAccessList
,
1755 PACTRL_AUDITW
*ppAuditList
,
1759 FIXME("%s() not implemented!\n", __FUNCTION__
);
1760 return ERROR_BAD_PROVIDER
;
1763 /******************************************************************************
1764 * BuildExplicitAccessWithNameA [ADVAPI32.@]
1767 BuildExplicitAccessWithNameA(PEXPLICIT_ACCESSA pExplicitAccess
,
1769 DWORD AccessPermissions
,
1770 ACCESS_MODE AccessMode
,
1773 pExplicitAccess
->grfAccessPermissions
= AccessPermissions
;
1774 pExplicitAccess
->grfAccessMode
= AccessMode
;
1775 pExplicitAccess
->grfInheritance
= Inheritance
;
1777 pExplicitAccess
->Trustee
.pMultipleTrustee
= NULL
;
1778 pExplicitAccess
->Trustee
.MultipleTrusteeOperation
= NO_MULTIPLE_TRUSTEE
;
1779 pExplicitAccess
->Trustee
.TrusteeForm
= TRUSTEE_IS_NAME
;
1780 pExplicitAccess
->Trustee
.TrusteeType
= TRUSTEE_IS_UNKNOWN
;
1781 pExplicitAccess
->Trustee
.ptstrName
= pTrusteeName
;
1785 /******************************************************************************
1786 * BuildExplicitAccessWithNameW [ADVAPI32.@]
1789 BuildExplicitAccessWithNameW(PEXPLICIT_ACCESSW pExplicitAccess
,
1790 LPWSTR pTrusteeName
,
1791 DWORD AccessPermissions
,
1792 ACCESS_MODE AccessMode
,
1795 pExplicitAccess
->grfAccessPermissions
= AccessPermissions
;
1796 pExplicitAccess
->grfAccessMode
= AccessMode
;
1797 pExplicitAccess
->grfInheritance
= Inheritance
;
1799 pExplicitAccess
->Trustee
.pMultipleTrustee
= NULL
;
1800 pExplicitAccess
->Trustee
.MultipleTrusteeOperation
= NO_MULTIPLE_TRUSTEE
;
1801 pExplicitAccess
->Trustee
.TrusteeForm
= TRUSTEE_IS_NAME
;
1802 pExplicitAccess
->Trustee
.TrusteeType
= TRUSTEE_IS_UNKNOWN
;
1803 pExplicitAccess
->Trustee
.ptstrName
= pTrusteeName
;
1806 /******************************************************************************
1807 * BuildTrusteeWithObjectsAndNameA [ADVAPI32.@]
1809 VOID WINAPI
BuildTrusteeWithObjectsAndNameA( PTRUSTEEA pTrustee
, POBJECTS_AND_NAME_A pObjName
,
1810 SE_OBJECT_TYPE ObjectType
, LPSTR ObjectTypeName
,
1811 LPSTR InheritedObjectTypeName
, LPSTR Name
)
1813 DWORD ObjectsPresent
= 0;
1815 TRACE("%p %p 0x%08x %p %p %s\n", pTrustee
, pObjName
,
1816 ObjectType
, ObjectTypeName
, InheritedObjectTypeName
, debugstr_a(Name
));
1818 /* Fill the OBJECTS_AND_NAME structure */
1819 pObjName
->ObjectType
= ObjectType
;
1820 if (ObjectTypeName
!= NULL
)
1822 ObjectsPresent
|= ACE_OBJECT_TYPE_PRESENT
;
1825 pObjName
->InheritedObjectTypeName
= InheritedObjectTypeName
;
1826 if (InheritedObjectTypeName
!= NULL
)
1828 ObjectsPresent
|= ACE_INHERITED_OBJECT_TYPE_PRESENT
;
1831 pObjName
->ObjectsPresent
= ObjectsPresent
;
1832 pObjName
->ptstrName
= Name
;
1834 /* Fill the TRUSTEE structure */
1835 pTrustee
->pMultipleTrustee
= NULL
;
1836 pTrustee
->MultipleTrusteeOperation
= NO_MULTIPLE_TRUSTEE
;
1837 pTrustee
->TrusteeForm
= TRUSTEE_IS_OBJECTS_AND_NAME
;
1838 pTrustee
->TrusteeType
= TRUSTEE_IS_UNKNOWN
;
1839 pTrustee
->ptstrName
= (LPSTR
)pObjName
;
1842 /******************************************************************************
1843 * BuildTrusteeWithObjectsAndNameW [ADVAPI32.@]
1845 VOID WINAPI
BuildTrusteeWithObjectsAndNameW( PTRUSTEEW pTrustee
, POBJECTS_AND_NAME_W pObjName
,
1846 SE_OBJECT_TYPE ObjectType
, LPWSTR ObjectTypeName
,
1847 LPWSTR InheritedObjectTypeName
, LPWSTR Name
)
1849 DWORD ObjectsPresent
= 0;
1851 TRACE("%p %p 0x%08x %p %p %s\n", pTrustee
, pObjName
,
1852 ObjectType
, ObjectTypeName
, InheritedObjectTypeName
, debugstr_w(Name
));
1854 /* Fill the OBJECTS_AND_NAME structure */
1855 pObjName
->ObjectType
= ObjectType
;
1856 if (ObjectTypeName
!= NULL
)
1858 ObjectsPresent
|= ACE_OBJECT_TYPE_PRESENT
;
1861 pObjName
->InheritedObjectTypeName
= InheritedObjectTypeName
;
1862 if (InheritedObjectTypeName
!= NULL
)
1864 ObjectsPresent
|= ACE_INHERITED_OBJECT_TYPE_PRESENT
;
1867 pObjName
->ObjectsPresent
= ObjectsPresent
;
1868 pObjName
->ptstrName
= Name
;
1870 /* Fill the TRUSTEE structure */
1871 pTrustee
->pMultipleTrustee
= NULL
;
1872 pTrustee
->MultipleTrusteeOperation
= NO_MULTIPLE_TRUSTEE
;
1873 pTrustee
->TrusteeForm
= TRUSTEE_IS_OBJECTS_AND_NAME
;
1874 pTrustee
->TrusteeType
= TRUSTEE_IS_UNKNOWN
;
1875 pTrustee
->ptstrName
= (LPWSTR
)pObjName
;
1878 /******************************************************************************
1879 * BuildTrusteeWithObjectsAndSidA [ADVAPI32.@]
1882 BuildTrusteeWithObjectsAndSidA(PTRUSTEEA pTrustee
,
1883 POBJECTS_AND_SID pObjSid
,
1885 GUID
*pInheritedObjectGuid
,
1888 DWORD ObjectsPresent
= 0;
1890 TRACE("%p %p %p %p %p\n", pTrustee
, pObjSid
, pObjectGuid
, pInheritedObjectGuid
, pSid
);
1892 /* Fill the OBJECTS_AND_SID structure */
1893 if (pObjectGuid
!= NULL
)
1895 pObjSid
->ObjectTypeGuid
= *pObjectGuid
;
1896 ObjectsPresent
|= ACE_OBJECT_TYPE_PRESENT
;
1900 ZeroMemory(&pObjSid
->ObjectTypeGuid
,
1904 if (pInheritedObjectGuid
!= NULL
)
1906 pObjSid
->InheritedObjectTypeGuid
= *pInheritedObjectGuid
;
1907 ObjectsPresent
|= ACE_INHERITED_OBJECT_TYPE_PRESENT
;
1911 ZeroMemory(&pObjSid
->InheritedObjectTypeGuid
,
1915 pObjSid
->ObjectsPresent
= ObjectsPresent
;
1916 pObjSid
->pSid
= pSid
;
1918 /* Fill the TRUSTEE structure */
1919 pTrustee
->pMultipleTrustee
= NULL
;
1920 pTrustee
->MultipleTrusteeOperation
= NO_MULTIPLE_TRUSTEE
;
1921 pTrustee
->TrusteeForm
= TRUSTEE_IS_OBJECTS_AND_SID
;
1922 pTrustee
->TrusteeType
= TRUSTEE_IS_UNKNOWN
;
1923 pTrustee
->ptstrName
= (LPSTR
) pObjSid
;
1927 /******************************************************************************
1928 * BuildTrusteeWithObjectsAndSidW [ADVAPI32.@]
1931 BuildTrusteeWithObjectsAndSidW(PTRUSTEEW pTrustee
,
1932 POBJECTS_AND_SID pObjSid
,
1934 GUID
*pInheritedObjectGuid
,
1937 DWORD ObjectsPresent
= 0;
1939 TRACE("%p %p %p %p %p\n", pTrustee
, pObjSid
, pObjectGuid
, pInheritedObjectGuid
, pSid
);
1941 /* Fill the OBJECTS_AND_SID structure */
1942 if (pObjectGuid
!= NULL
)
1944 pObjSid
->ObjectTypeGuid
= *pObjectGuid
;
1945 ObjectsPresent
|= ACE_OBJECT_TYPE_PRESENT
;
1949 ZeroMemory(&pObjSid
->ObjectTypeGuid
,
1953 if (pInheritedObjectGuid
!= NULL
)
1955 pObjSid
->InheritedObjectTypeGuid
= *pInheritedObjectGuid
;
1956 ObjectsPresent
|= ACE_INHERITED_OBJECT_TYPE_PRESENT
;
1960 ZeroMemory(&pObjSid
->InheritedObjectTypeGuid
,
1964 pObjSid
->ObjectsPresent
= ObjectsPresent
;
1965 pObjSid
->pSid
= pSid
;
1967 /* Fill the TRUSTEE structure */
1968 pTrustee
->pMultipleTrustee
= NULL
;
1969 pTrustee
->MultipleTrusteeOperation
= NO_MULTIPLE_TRUSTEE
;
1970 pTrustee
->TrusteeForm
= TRUSTEE_IS_OBJECTS_AND_SID
;
1971 pTrustee
->TrusteeType
= TRUSTEE_IS_UNKNOWN
;
1972 pTrustee
->ptstrName
= (LPWSTR
) pObjSid
;
1975 /******************************************************************************
1976 * BuildTrusteeWithSidA [ADVAPI32.@]
1979 BuildTrusteeWithSidA(PTRUSTEE_A pTrustee
,
1982 TRACE("%p %p\n", pTrustee
, pSid
);
1984 pTrustee
->pMultipleTrustee
= NULL
;
1985 pTrustee
->MultipleTrusteeOperation
= NO_MULTIPLE_TRUSTEE
;
1986 pTrustee
->TrusteeForm
= TRUSTEE_IS_SID
;
1987 pTrustee
->TrusteeType
= TRUSTEE_IS_UNKNOWN
;
1988 pTrustee
->ptstrName
= (LPSTR
) pSid
;
1992 /******************************************************************************
1993 * BuildTrusteeWithSidW [ADVAPI32.@]
1996 BuildTrusteeWithSidW(PTRUSTEE_W pTrustee
,
1999 TRACE("%p %p\n", pTrustee
, pSid
);
2001 pTrustee
->pMultipleTrustee
= NULL
;
2002 pTrustee
->MultipleTrusteeOperation
= NO_MULTIPLE_TRUSTEE
;
2003 pTrustee
->TrusteeForm
= TRUSTEE_IS_SID
;
2004 pTrustee
->TrusteeType
= TRUSTEE_IS_UNKNOWN
;
2005 pTrustee
->ptstrName
= (LPWSTR
) pSid
;
2008 /******************************************************************************
2009 * BuildTrusteeWithNameA [ADVAPI32.@]
2012 BuildTrusteeWithNameA(PTRUSTEE_A pTrustee
,
2015 TRACE("%p %s\n", pTrustee
, name
);
2017 pTrustee
->pMultipleTrustee
= NULL
;
2018 pTrustee
->MultipleTrusteeOperation
= NO_MULTIPLE_TRUSTEE
;
2019 pTrustee
->TrusteeForm
= TRUSTEE_IS_NAME
;
2020 pTrustee
->TrusteeType
= TRUSTEE_IS_UNKNOWN
;
2021 pTrustee
->ptstrName
= name
;
2024 /******************************************************************************
2025 * BuildTrusteeWithNameW [ADVAPI32.@]
2028 BuildTrusteeWithNameW(PTRUSTEE_W pTrustee
,
2031 TRACE("%p %s\n", pTrustee
, name
);
2033 pTrustee
->pMultipleTrustee
= NULL
;
2034 pTrustee
->MultipleTrusteeOperation
= NO_MULTIPLE_TRUSTEE
;
2035 pTrustee
->TrusteeForm
= TRUSTEE_IS_NAME
;
2036 pTrustee
->TrusteeType
= TRUSTEE_IS_UNKNOWN
;
2037 pTrustee
->ptstrName
= name
;
2040 /******************************************************************************
2041 * GetTrusteeFormA [ADVAPI32.@]
2043 TRUSTEE_FORM WINAPI
GetTrusteeFormA(PTRUSTEEA pTrustee
)
2045 TRACE("(%p)\n", pTrustee
);
2048 return TRUSTEE_BAD_FORM
;
2050 return pTrustee
->TrusteeForm
;
2053 /******************************************************************************
2054 * GetTrusteeFormW [ADVAPI32.@]
2056 TRUSTEE_FORM WINAPI
GetTrusteeFormW(PTRUSTEEW pTrustee
)
2058 TRACE("(%p)\n", pTrustee
);
2061 return TRUSTEE_BAD_FORM
;
2063 return pTrustee
->TrusteeForm
;
2066 /******************************************************************************
2067 * GetTrusteeNameA [ADVAPI32.@]
2070 GetTrusteeNameA(PTRUSTEE_A pTrustee
)
2072 return pTrustee
->ptstrName
;
2076 /******************************************************************************
2077 * GetTrusteeNameW [ADVAPI32.@]
2080 GetTrusteeNameW(PTRUSTEE_W pTrustee
)
2082 return pTrustee
->ptstrName
;
2085 /******************************************************************************
2086 * GetTrusteeTypeA [ADVAPI32.@]
2089 GetTrusteeTypeA(PTRUSTEE_A pTrustee
)
2091 return pTrustee
->TrusteeType
;
2094 /******************************************************************************
2095 * GetTrusteeTypeW [ADVAPI32.@]
2098 GetTrusteeTypeW(PTRUSTEE_W pTrustee
)
2100 return pTrustee
->TrusteeType
;
2108 SetAclInformation(PACL pAcl
,
2109 LPVOID pAclInformation
,
2110 DWORD nAclInformationLength
,
2111 ACL_INFORMATION_CLASS dwAclInformationClass
)
2115 Status
= RtlSetInformationAcl(pAcl
,
2117 nAclInformationLength
,
2118 dwAclInformationClass
);
2119 if (!NT_SUCCESS(Status
))
2121 SetLastError(RtlNtStatusToDosError(Status
));
2128 /**********************************************************************
2129 * SetNamedSecurityInfoA EXPORTED
2135 SetNamedSecurityInfoA(LPSTR pObjectName
,
2136 SE_OBJECT_TYPE ObjectType
,
2137 SECURITY_INFORMATION SecurityInfo
,
2143 UNICODE_STRING ObjectName
;
2146 if (!RtlCreateUnicodeStringFromAsciiz(&ObjectName
, pObjectName
))
2148 return ERROR_NOT_ENOUGH_MEMORY
;
2151 Ret
= SetNamedSecurityInfoW(ObjectName
.Buffer
,
2159 RtlFreeUnicodeString(&ObjectName
);
2169 AreAllAccessesGranted(DWORD GrantedAccess
,
2170 DWORD DesiredAccess
)
2172 return (BOOL
)RtlAreAllAccessesGranted(GrantedAccess
,
2181 AreAnyAccessesGranted(DWORD GrantedAccess
,
2182 DWORD DesiredAccess
)
2184 return (BOOL
)RtlAreAnyAccessesGranted(GrantedAccess
,
2188 /******************************************************************************
2189 * ParseAclStringFlags
2191 static DWORD
ParseAclStringFlags(LPCWSTR
* StringAcl
)
2194 LPCWSTR szAcl
= *StringAcl
;
2196 while (*szAcl
!= '(')
2200 flags
|= SE_DACL_PROTECTED
;
2202 else if (*szAcl
== 'A')
2206 flags
|= SE_DACL_AUTO_INHERIT_REQ
;
2207 else if (*szAcl
== 'I')
2208 flags
|= SE_DACL_AUTO_INHERITED
;
2217 /******************************************************************************
2218 * ParseAceStringType
2220 static const ACEFLAG AceType
[] =
2222 { SDDL_ALARM
, SYSTEM_ALARM_ACE_TYPE
},
2223 { SDDL_AUDIT
, SYSTEM_AUDIT_ACE_TYPE
},
2224 { SDDL_ACCESS_ALLOWED
, ACCESS_ALLOWED_ACE_TYPE
},
2225 { SDDL_ACCESS_DENIED
, ACCESS_DENIED_ACE_TYPE
},
2227 { SDDL_OBJECT_ACCESS_ALLOWED, ACCESS_ALLOWED_OBJECT_ACE_TYPE },
2228 { SDDL_OBJECT_ACCESS_DENIED, ACCESS_DENIED_OBJECT_ACE_TYPE },
2229 { SDDL_OBJECT_ALARM, SYSTEM_ALARM_OBJECT_ACE_TYPE },
2230 { SDDL_OBJECT_AUDIT, SYSTEM_AUDIT_OBJECT_ACE_TYPE },
2235 static BYTE
ParseAceStringType(LPCWSTR
* StringAcl
)
2238 LPCWSTR szAcl
= *StringAcl
;
2239 const ACEFLAG
*lpaf
= AceType
;
2241 while (*szAcl
== ' ')
2244 while (lpaf
->wstr
&&
2245 (len
= strlenW(lpaf
->wstr
)) &&
2246 strncmpW(lpaf
->wstr
, szAcl
, len
))
2252 *StringAcl
= szAcl
+ len
;
2257 /******************************************************************************
2258 * ParseAceStringFlags
2260 static const ACEFLAG AceFlags
[] =
2262 { SDDL_CONTAINER_INHERIT
, CONTAINER_INHERIT_ACE
},
2263 { SDDL_AUDIT_FAILURE
, FAILED_ACCESS_ACE_FLAG
},
2264 { SDDL_INHERITED
, INHERITED_ACE
},
2265 { SDDL_INHERIT_ONLY
, INHERIT_ONLY_ACE
},
2266 { SDDL_NO_PROPAGATE
, NO_PROPAGATE_INHERIT_ACE
},
2267 { SDDL_OBJECT_INHERIT
, OBJECT_INHERIT_ACE
},
2268 { SDDL_AUDIT_SUCCESS
, SUCCESSFUL_ACCESS_ACE_FLAG
},
2272 static BYTE
ParseAceStringFlags(LPCWSTR
* StringAcl
)
2276 LPCWSTR szAcl
= *StringAcl
;
2278 while (*szAcl
== ' ')
2281 while (*szAcl
!= ';')
2283 const ACEFLAG
*lpaf
= AceFlags
;
2285 while (lpaf
->wstr
&&
2286 (len
= strlenW(lpaf
->wstr
)) &&
2287 strncmpW(lpaf
->wstr
, szAcl
, len
))
2293 flags
|= lpaf
->value
;
2302 /******************************************************************************
2303 * ParseAceStringRights
2305 static const ACEFLAG AceRights
[] =
2307 { SDDL_GENERIC_ALL
, GENERIC_ALL
},
2308 { SDDL_GENERIC_READ
, GENERIC_READ
},
2309 { SDDL_GENERIC_WRITE
, GENERIC_WRITE
},
2310 { SDDL_GENERIC_EXECUTE
, GENERIC_EXECUTE
},
2312 { SDDL_READ_CONTROL
, READ_CONTROL
},
2313 { SDDL_STANDARD_DELETE
, DELETE
},
2314 { SDDL_WRITE_DAC
, WRITE_DAC
},
2315 { SDDL_WRITE_OWNER
, WRITE_OWNER
},
2317 { SDDL_READ_PROPERTY
, ADS_RIGHT_DS_READ_PROP
},
2318 { SDDL_WRITE_PROPERTY
, ADS_RIGHT_DS_WRITE_PROP
},
2319 { SDDL_CREATE_CHILD
, ADS_RIGHT_DS_CREATE_CHILD
},
2320 { SDDL_DELETE_CHILD
, ADS_RIGHT_DS_DELETE_CHILD
},
2321 { SDDL_LIST_CHILDREN
, ADS_RIGHT_ACTRL_DS_LIST
},
2322 { SDDL_SELF_WRITE
, ADS_RIGHT_DS_SELF
},
2323 { SDDL_LIST_OBJECT
, ADS_RIGHT_DS_LIST_OBJECT
},
2324 { SDDL_DELETE_TREE
, ADS_RIGHT_DS_DELETE_TREE
},
2325 { SDDL_CONTROL_ACCESS
, ADS_RIGHT_DS_CONTROL_ACCESS
},
2327 { SDDL_FILE_ALL
, FILE_ALL_ACCESS
},
2328 { SDDL_FILE_READ
, FILE_GENERIC_READ
},
2329 { SDDL_FILE_WRITE
, FILE_GENERIC_WRITE
},
2330 { SDDL_FILE_EXECUTE
, FILE_GENERIC_EXECUTE
},
2332 { SDDL_KEY_ALL
, KEY_ALL_ACCESS
},
2333 { SDDL_KEY_READ
, KEY_READ
},
2334 { SDDL_KEY_WRITE
, KEY_WRITE
},
2335 { SDDL_KEY_EXECUTE
, KEY_EXECUTE
},
2339 static DWORD
ParseAceStringRights(LPCWSTR
* StringAcl
)
2343 LPCWSTR szAcl
= *StringAcl
;
2345 while (*szAcl
== ' ')
2348 if ((*szAcl
== '0') && (*(szAcl
+ 1) == 'x'))
2352 while (*p
&& *p
!= ';')
2355 if (p
- szAcl
<= 10 /* 8 hex digits + "0x" */ )
2357 rights
= strtoulW(szAcl
, NULL
, 16);
2361 WARN("Invalid rights string format: %s\n", debugstr_wn(szAcl
, p
- szAcl
));
2365 while (*szAcl
!= ';')
2367 const ACEFLAG
*lpaf
= AceRights
;
2369 while (lpaf
->wstr
&&
2370 (len
= strlenW(lpaf
->wstr
)) &&
2371 strncmpW(lpaf
->wstr
, szAcl
, len
))
2379 rights
|= lpaf
->value
;
2389 /******************************************************************************
2390 * ParseStringAclToAcl
2392 * dacl_flags(string_ace1)(string_ace2)... (string_acen)
2394 static BOOL
ParseStringAclToAcl(LPCWSTR StringAcl
, LPDWORD lpdwFlags
,
2395 PACL pAcl
, LPDWORD cBytes
)
2399 DWORD length
= sizeof(ACL
);
2402 PACCESS_ALLOWED_ACE pAce
= NULL
; /* pointer to current ACE */
2403 DWORD error
= ERROR_INVALID_ACL
;
2405 TRACE("%s\n", debugstr_w(StringAcl
));
2410 if (pAcl
) /* pAce is only useful if we're setting values */
2411 pAce
= (PACCESS_ALLOWED_ACE
) (pAcl
+ 1);
2413 /* Parse ACL flags */
2414 *lpdwFlags
= ParseAclStringFlags(&StringAcl
);
2417 while (*StringAcl
== '(')
2421 /* Parse ACE type */
2422 val
= ParseAceStringType(&StringAcl
);
2424 pAce
->Header
.AceType
= (BYTE
) val
;
2425 if (*StringAcl
!= ';')
2427 error
= RPC_S_INVALID_STRING_UUID
;
2432 /* Parse ACE flags */
2433 val
= ParseAceStringFlags(&StringAcl
);
2435 pAce
->Header
.AceFlags
= (BYTE
) val
;
2436 if (*StringAcl
!= ';')
2440 /* Parse ACE rights */
2441 val
= ParseAceStringRights(&StringAcl
);
2444 if (*StringAcl
!= ';')
2448 /* Parse ACE object guid */
2449 while (*StringAcl
== ' ')
2451 if (*StringAcl
!= ';')
2453 FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
2458 /* Parse ACE inherit object guid */
2459 while (*StringAcl
== ' ')
2461 if (*StringAcl
!= ';')
2463 FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
2468 /* Parse ACE account sid */
2469 if (ParseStringSidToSid(StringAcl
, pAce
? &pAce
->SidStart
: NULL
, &sidlen
))
2471 while (*StringAcl
&& *StringAcl
!= ')')
2475 if (*StringAcl
!= ')')
2479 acesize
= sizeof(ACCESS_ALLOWED_ACE
) - sizeof(DWORD
) + sidlen
;
2483 pAce
->Header
.AceSize
= acesize
;
2484 pAce
= (PACCESS_ALLOWED_ACE
)((LPBYTE
)pAce
+ acesize
);
2491 if (length
> 0xffff)
2493 ERR("ACL too large\n");
2499 pAcl
->AclRevision
= ACL_REVISION
;
2501 pAcl
->AclSize
= length
;
2502 pAcl
->AceCount
= acecount
++;
2508 SetLastError(error
);
2509 WARN("Invalid ACE string format\n");
2514 /******************************************************************************
2515 * ParseStringSecurityDescriptorToSecurityDescriptor
2517 static BOOL
ParseStringSecurityDescriptorToSecurityDescriptor(
2518 LPCWSTR StringSecurityDescriptor
,
2519 SECURITY_DESCRIPTOR_RELATIVE
* SecurityDescriptor
,
2524 WCHAR tok
[MAX_PATH
];
2526 LPBYTE lpNext
= NULL
;
2529 *cBytes
= sizeof(SECURITY_DESCRIPTOR
);
2531 if (SecurityDescriptor
)
2532 lpNext
= (LPBYTE
)(SecurityDescriptor
+ 1);
2534 while (*StringSecurityDescriptor
== ' ')
2535 StringSecurityDescriptor
++;
2537 while (*StringSecurityDescriptor
)
2539 toktype
= *StringSecurityDescriptor
;
2541 /* Expect char identifier followed by ':' */
2542 StringSecurityDescriptor
++;
2543 if (*StringSecurityDescriptor
!= ':')
2545 SetLastError(ERROR_INVALID_PARAMETER
);
2548 StringSecurityDescriptor
++;
2551 lptoken
= StringSecurityDescriptor
;
2552 while (*lptoken
&& *lptoken
!= ':')
2558 len
= lptoken
- StringSecurityDescriptor
;
2559 memcpy( tok
, StringSecurityDescriptor
, len
* sizeof(WCHAR
) );
2568 if (!ParseStringSidToSid(tok
, lpNext
, &bytes
))
2571 if (SecurityDescriptor
)
2573 SecurityDescriptor
->Owner
= lpNext
- (LPBYTE
)SecurityDescriptor
;
2574 lpNext
+= bytes
; /* Advance to next token */
2586 if (!ParseStringSidToSid(tok
, lpNext
, &bytes
))
2589 if (SecurityDescriptor
)
2591 SecurityDescriptor
->Group
= lpNext
- (LPBYTE
)SecurityDescriptor
;
2592 lpNext
+= bytes
; /* Advance to next token */
2605 if (!ParseStringAclToAcl(tok
, &flags
, (PACL
)lpNext
, &bytes
))
2608 if (SecurityDescriptor
)
2610 SecurityDescriptor
->Control
|= SE_DACL_PRESENT
| flags
;
2611 SecurityDescriptor
->Dacl
= lpNext
- (LPBYTE
)SecurityDescriptor
;
2612 lpNext
+= bytes
; /* Advance to next token */
2625 if (!ParseStringAclToAcl(tok
, &flags
, (PACL
)lpNext
, &bytes
))
2628 if (SecurityDescriptor
)
2630 SecurityDescriptor
->Control
|= SE_SACL_PRESENT
| flags
;
2631 SecurityDescriptor
->Sacl
= lpNext
- (LPBYTE
)SecurityDescriptor
;
2632 lpNext
+= bytes
; /* Advance to next token */
2641 FIXME("Unknown token\n");
2642 SetLastError(ERROR_INVALID_PARAMETER
);
2646 StringSecurityDescriptor
= lptoken
;
2655 /* Winehq cvs 20050916 */
2656 /******************************************************************************
2657 * ConvertStringSecurityDescriptorToSecurityDescriptorA [ADVAPI32.@]
2662 ConvertStringSecurityDescriptorToSecurityDescriptorA(LPCSTR StringSecurityDescriptor
,
2663 DWORD StringSDRevision
,
2664 PSECURITY_DESCRIPTOR
* SecurityDescriptor
,
2665 PULONG SecurityDescriptorSize
)
2669 LPWSTR StringSecurityDescriptorW
;
2671 len
= MultiByteToWideChar(CP_ACP
, 0, StringSecurityDescriptor
, -1, NULL
, 0);
2672 StringSecurityDescriptorW
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
2674 if (StringSecurityDescriptorW
)
2676 MultiByteToWideChar(CP_ACP
, 0, StringSecurityDescriptor
, -1, StringSecurityDescriptorW
, len
);
2678 ret
= ConvertStringSecurityDescriptorToSecurityDescriptorW(StringSecurityDescriptorW
,
2679 StringSDRevision
, SecurityDescriptor
,
2680 SecurityDescriptorSize
);
2681 HeapFree(GetProcessHeap(), 0, StringSecurityDescriptorW
);
2687 /******************************************************************************
2688 * ConvertStringSecurityDescriptorToSecurityDescriptorW [ADVAPI32.@]
2692 ConvertStringSecurityDescriptorToSecurityDescriptorW(LPCWSTR StringSecurityDescriptor
,
2693 DWORD StringSDRevision
,
2694 PSECURITY_DESCRIPTOR
* SecurityDescriptor
,
2695 PULONG SecurityDescriptorSize
)
2698 SECURITY_DESCRIPTOR
* psd
;
2701 TRACE("%s\n", debugstr_w(StringSecurityDescriptor
));
2703 if (GetVersion() & 0x80000000)
2705 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
2708 else if (!StringSecurityDescriptor
|| !SecurityDescriptor
)
2710 SetLastError(ERROR_INVALID_PARAMETER
);
2713 else if (StringSDRevision
!= SID_REVISION
)
2715 SetLastError(ERROR_UNKNOWN_REVISION
);
2719 /* Compute security descriptor length */
2720 if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor
,
2724 psd
= *SecurityDescriptor
= LocalAlloc(GMEM_ZEROINIT
, cBytes
);
2725 if (!psd
) goto lend
;
2727 psd
->Revision
= SID_REVISION
;
2728 psd
->Control
|= SE_SELF_RELATIVE
;
2730 if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor
,
2731 (SECURITY_DESCRIPTOR_RELATIVE
*)psd
, &cBytes
))
2737 if (SecurityDescriptorSize
)
2738 *SecurityDescriptorSize
= cBytes
;
2743 TRACE(" ret=%d\n", bret
);
2747 static void DumpString(LPCWSTR string
, int cch
, WCHAR
**pwptr
, ULONG
*plen
)
2750 cch
= strlenW(string
);
2757 memcpy(*pwptr
, string
, sizeof(WCHAR
)*cch
);
2762 static BOOL
DumpSidNumeric(PSID psid
, WCHAR
**pwptr
, ULONG
*plen
)
2765 WCHAR fmt
[] = { 'S','-','%','u','-','%','d',0 };
2766 WCHAR subauthfmt
[] = { '-','%','u',0 };
2770 if( !IsValidSid( psid
) || pisid
->Revision
!= SDDL_REVISION
)
2772 SetLastError(ERROR_INVALID_SID
);
2776 if (pisid
->IdentifierAuthority
.Value
[0] ||
2777 pisid
->IdentifierAuthority
.Value
[1])
2779 FIXME("not matching MS' bugs\n");
2780 SetLastError(ERROR_INVALID_SID
);
2784 sprintfW( buf
, fmt
, pisid
->Revision
,
2786 MAKEWORD( pisid
->IdentifierAuthority
.Value
[5],
2787 pisid
->IdentifierAuthority
.Value
[4] ),
2788 MAKEWORD( pisid
->IdentifierAuthority
.Value
[3],
2789 pisid
->IdentifierAuthority
.Value
[2] )
2791 DumpString(buf
, -1, pwptr
, plen
);
2793 for( i
=0; i
<pisid
->SubAuthorityCount
; i
++ )
2795 sprintfW( buf
, subauthfmt
, pisid
->SubAuthority
[i
] );
2796 DumpString(buf
, -1, pwptr
, plen
);
2801 static BOOL
DumpSid(PSID psid
, WCHAR
**pwptr
, ULONG
*plen
)
2804 for (i
= 0; i
< sizeof(WellKnownSids
) / sizeof(WellKnownSids
[0]); i
++)
2806 if (WellKnownSids
[i
].wstr
[0] && EqualSid(psid
, (PSID
)&(WellKnownSids
[i
].Sid
.Revision
)))
2808 DumpString(WellKnownSids
[i
].wstr
, 2, pwptr
, plen
);
2813 return DumpSidNumeric(psid
, pwptr
, plen
);
2816 static const LPCWSTR AceRightBitNames
[32] = {
2817 SDDL_CREATE_CHILD
, /* 0 */
2821 SDDL_READ_PROPERTY
, /* 4 */
2822 SDDL_WRITE_PROPERTY
,
2825 SDDL_CONTROL_ACCESS
, /* 8 */
2833 SDDL_STANDARD_DELETE
, /* 16 */
2845 SDDL_GENERIC_ALL
, /* 28 */
2846 SDDL_GENERIC_EXECUTE
,
2851 static void DumpRights(DWORD mask
, WCHAR
**pwptr
, ULONG
*plen
)
2853 static const WCHAR fmtW
[] = {'0','x','%','x',0};
2860 /* first check if the right have name */
2861 for (i
= 0; i
< sizeof(AceRights
)/sizeof(AceRights
[0]); i
++)
2863 if (AceRights
[i
].wstr
== NULL
)
2865 if (mask
== AceRights
[i
].value
)
2867 DumpString(AceRights
[i
].wstr
, -1, pwptr
, plen
);
2872 /* then check if it can be built from bit names */
2873 for (i
= 0; i
< 32; i
++)
2875 if ((mask
& (1 << i
)) && (AceRightBitNames
[i
] == NULL
))
2877 /* can't be built from bit names */
2878 sprintfW(buf
, fmtW
, mask
);
2879 DumpString(buf
, -1, pwptr
, plen
);
2884 /* build from bit names */
2885 for (i
= 0; i
< 32; i
++)
2886 if (mask
& (1 << i
))
2887 DumpString(AceRightBitNames
[i
], -1, pwptr
, plen
);
2890 static BOOL
DumpAce(LPVOID pace
, WCHAR
**pwptr
, ULONG
*plen
)
2892 ACCESS_ALLOWED_ACE
*piace
; /* all the supported ACEs have the same memory layout */
2893 static const WCHAR openbr
= '(';
2894 static const WCHAR closebr
= ')';
2895 static const WCHAR semicolon
= ';';
2897 if (((PACE_HEADER
)pace
)->AceType
> SYSTEM_ALARM_ACE_TYPE
|| ((PACE_HEADER
)pace
)->AceSize
< sizeof(ACCESS_ALLOWED_ACE
))
2899 SetLastError(ERROR_INVALID_ACL
);
2904 DumpString(&openbr
, 1, pwptr
, plen
);
2905 switch (piace
->Header
.AceType
)
2907 case ACCESS_ALLOWED_ACE_TYPE
:
2908 DumpString(SDDL_ACCESS_ALLOWED
, -1, pwptr
, plen
);
2910 case ACCESS_DENIED_ACE_TYPE
:
2911 DumpString(SDDL_ACCESS_DENIED
, -1, pwptr
, plen
);
2913 case SYSTEM_AUDIT_ACE_TYPE
:
2914 DumpString(SDDL_AUDIT
, -1, pwptr
, plen
);
2916 case SYSTEM_ALARM_ACE_TYPE
:
2917 DumpString(SDDL_ALARM
, -1, pwptr
, plen
);
2920 DumpString(&semicolon
, 1, pwptr
, plen
);
2922 if (piace
->Header
.AceFlags
& OBJECT_INHERIT_ACE
)
2923 DumpString(SDDL_OBJECT_INHERIT
, -1, pwptr
, plen
);
2924 if (piace
->Header
.AceFlags
& CONTAINER_INHERIT_ACE
)
2925 DumpString(SDDL_CONTAINER_INHERIT
, -1, pwptr
, plen
);
2926 if (piace
->Header
.AceFlags
& NO_PROPAGATE_INHERIT_ACE
)
2927 DumpString(SDDL_NO_PROPAGATE
, -1, pwptr
, plen
);
2928 if (piace
->Header
.AceFlags
& INHERIT_ONLY_ACE
)
2929 DumpString(SDDL_INHERIT_ONLY
, -1, pwptr
, plen
);
2930 if (piace
->Header
.AceFlags
& INHERITED_ACE
)
2931 DumpString(SDDL_INHERITED
, -1, pwptr
, plen
);
2932 if (piace
->Header
.AceFlags
& SUCCESSFUL_ACCESS_ACE_FLAG
)
2933 DumpString(SDDL_AUDIT_SUCCESS
, -1, pwptr
, plen
);
2934 if (piace
->Header
.AceFlags
& FAILED_ACCESS_ACE_FLAG
)
2935 DumpString(SDDL_AUDIT_FAILURE
, -1, pwptr
, plen
);
2936 DumpString(&semicolon
, 1, pwptr
, plen
);
2937 DumpRights(piace
->Mask
, pwptr
, plen
);
2938 DumpString(&semicolon
, 1, pwptr
, plen
);
2939 /* objects not supported */
2940 DumpString(&semicolon
, 1, pwptr
, plen
);
2941 /* objects not supported */
2942 DumpString(&semicolon
, 1, pwptr
, plen
);
2943 if (!DumpSid((PSID
)&piace
->SidStart
, pwptr
, plen
))
2945 DumpString(&closebr
, 1, pwptr
, plen
);
2949 static BOOL
DumpAcl(PACL pacl
, WCHAR
**pwptr
, ULONG
*plen
, BOOL
protected, BOOL autoInheritReq
, BOOL autoInherited
)
2955 DumpString(SDDL_PROTECTED
, -1, pwptr
, plen
);
2957 DumpString(SDDL_AUTO_INHERIT_REQ
, -1, pwptr
, plen
);
2959 DumpString(SDDL_AUTO_INHERITED
, -1, pwptr
, plen
);
2964 if (!IsValidAcl(pacl
))
2967 count
= pacl
->AceCount
;
2968 for (i
= 0; i
< count
; i
++)
2971 if (!GetAce(pacl
, i
, &ace
))
2973 if (!DumpAce(ace
, pwptr
, plen
))
2980 static BOOL
DumpOwner(PSECURITY_DESCRIPTOR SecurityDescriptor
, WCHAR
**pwptr
, ULONG
*plen
)
2982 static const WCHAR prefix
[] = {'O',':',0};
2986 if (!GetSecurityDescriptorOwner(SecurityDescriptor
, &psid
, &bDefaulted
))
2992 DumpString(prefix
, -1, pwptr
, plen
);
2993 if (!DumpSid(psid
, pwptr
, plen
))
2998 static BOOL
DumpGroup(PSECURITY_DESCRIPTOR SecurityDescriptor
, WCHAR
**pwptr
, ULONG
*plen
)
3000 static const WCHAR prefix
[] = {'G',':',0};
3004 if (!GetSecurityDescriptorGroup(SecurityDescriptor
, &psid
, &bDefaulted
))
3010 DumpString(prefix
, -1, pwptr
, plen
);
3011 if (!DumpSid(psid
, pwptr
, plen
))
3016 static BOOL
DumpDacl(PSECURITY_DESCRIPTOR SecurityDescriptor
, WCHAR
**pwptr
, ULONG
*plen
)
3018 static const WCHAR dacl
[] = {'D',':',0};
3019 SECURITY_DESCRIPTOR_CONTROL control
;
3020 BOOL present
, defaulted
;
3024 if (!GetSecurityDescriptorDacl(SecurityDescriptor
, &present
, &pacl
, &defaulted
))
3027 if (!GetSecurityDescriptorControl(SecurityDescriptor
, &control
, &revision
))
3033 DumpString(dacl
, 2, pwptr
, plen
);
3034 if (!DumpAcl(pacl
, pwptr
, plen
, control
& SE_DACL_PROTECTED
, control
& SE_DACL_AUTO_INHERIT_REQ
, control
& SE_DACL_AUTO_INHERITED
))
3039 static BOOL
DumpSacl(PSECURITY_DESCRIPTOR SecurityDescriptor
, WCHAR
**pwptr
, ULONG
*plen
)
3041 static const WCHAR sacl
[] = {'S',':',0};
3042 SECURITY_DESCRIPTOR_CONTROL control
;
3043 BOOL present
, defaulted
;
3047 if (!GetSecurityDescriptorSacl(SecurityDescriptor
, &present
, &pacl
, &defaulted
))
3050 if (!GetSecurityDescriptorControl(SecurityDescriptor
, &control
, &revision
))
3056 DumpString(sacl
, 2, pwptr
, plen
);
3057 if (!DumpAcl(pacl
, pwptr
, plen
, control
& SE_SACL_PROTECTED
, control
& SE_SACL_AUTO_INHERIT_REQ
, control
& SE_SACL_AUTO_INHERITED
))
3062 /******************************************************************************
3063 * ConvertSecurityDescriptorToStringSecurityDescriptorW [ADVAPI32.@]
3067 ConvertSecurityDescriptorToStringSecurityDescriptorW(PSECURITY_DESCRIPTOR SecurityDescriptor
,
3069 SECURITY_INFORMATION SecurityInformation
,
3070 LPWSTR
*OutputString
,
3076 if (SDRevision
!= SDDL_REVISION_1
)
3078 ERR("Program requested unknown SDDL revision %d\n", SDRevision
);
3079 SetLastError(ERROR_UNKNOWN_REVISION
);
3084 if (SecurityInformation
& OWNER_SECURITY_INFORMATION
)
3085 if (!DumpOwner(SecurityDescriptor
, NULL
, &len
))
3087 if (SecurityInformation
& GROUP_SECURITY_INFORMATION
)
3088 if (!DumpGroup(SecurityDescriptor
, NULL
, &len
))
3090 if (SecurityInformation
& DACL_SECURITY_INFORMATION
)
3091 if (!DumpDacl(SecurityDescriptor
, NULL
, &len
))
3093 if (SecurityInformation
& SACL_SECURITY_INFORMATION
)
3094 if (!DumpSacl(SecurityDescriptor
, NULL
, &len
))
3097 wstr
= wptr
= LocalAlloc(0, (len
+ 1)*sizeof(WCHAR
));
3101 if (SecurityInformation
& OWNER_SECURITY_INFORMATION
)
3102 if (!DumpOwner(SecurityDescriptor
, &wptr
, NULL
))
3104 if (SecurityInformation
& GROUP_SECURITY_INFORMATION
)
3105 if (!DumpGroup(SecurityDescriptor
, &wptr
, NULL
))
3107 if (SecurityInformation
& DACL_SECURITY_INFORMATION
)
3108 if (!DumpDacl(SecurityDescriptor
, &wptr
, NULL
))
3110 if (SecurityInformation
& SACL_SECURITY_INFORMATION
)
3111 if (!DumpSacl(SecurityDescriptor
, &wptr
, NULL
))
3115 TRACE("ret: %s, %d\n", wine_dbgstr_w(wstr
), len
);
3116 *OutputString
= wstr
;
3118 *OutputLen
= strlenW(*OutputString
)+1;
3122 /******************************************************************************
3123 * ConvertSecurityDescriptorToStringSecurityDescriptorA [ADVAPI32.@]
3127 ConvertSecurityDescriptorToStringSecurityDescriptorA(PSECURITY_DESCRIPTOR SecurityDescriptor
,
3129 SECURITY_INFORMATION Information
,
3130 LPSTR
*OutputString
,
3136 if (ConvertSecurityDescriptorToStringSecurityDescriptorW(SecurityDescriptor
, SDRevision
, Information
, &wstr
, &len
))
3140 lenA
= WideCharToMultiByte(CP_ACP
, 0, wstr
, len
, NULL
, 0, NULL
, NULL
);
3141 *OutputString
= HeapAlloc(GetProcessHeap(), 0, lenA
);
3142 if (*OutputString
== NULL
)
3148 WideCharToMultiByte(CP_ACP
, 0, wstr
, len
, *OutputString
, lenA
, NULL
, NULL
);
3151 if (OutputLen
!= NULL
)
3157 *OutputString
= NULL
;
3164 /******************************************************************************
3165 * ConvertStringSidToSidW [ADVAPI32.@]
3167 BOOL WINAPI
ConvertStringSidToSidW(LPCWSTR StringSid
, PSID
* Sid
)
3172 TRACE("%s, %p\n", debugstr_w(StringSid
), Sid
);
3173 if (GetVersion() & 0x80000000)
3174 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
3175 else if (!StringSid
|| !Sid
)
3176 SetLastError(ERROR_INVALID_PARAMETER
);
3177 else if (ParseStringSidToSid(StringSid
, NULL
, &cBytes
))
3179 PSID pSid
= *Sid
= LocalAlloc(0, cBytes
);
3181 bret
= ParseStringSidToSid(StringSid
, pSid
, &cBytes
);
3188 /******************************************************************************
3189 * ConvertStringSidToSidA [ADVAPI32.@]
3191 BOOL WINAPI
ConvertStringSidToSidA(LPCSTR StringSid
, PSID
* Sid
)
3195 TRACE("%s, %p\n", debugstr_a(StringSid
), Sid
);
3196 if (GetVersion() & 0x80000000)
3197 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
3198 else if (!StringSid
|| !Sid
)
3199 SetLastError(ERROR_INVALID_PARAMETER
);
3202 WCHAR
*wStringSid
= SERV_dup(StringSid
);
3203 bret
= ConvertStringSidToSidW(wStringSid
, Sid
);
3204 heap_free(wStringSid
);
3214 ConvertSidToStringSidW(PSID Sid
,
3218 UNICODE_STRING UnicodeString
;
3219 WCHAR FixedBuffer
[64];
3221 if (!RtlValidSid(Sid
))
3223 SetLastError(ERROR_INVALID_SID
);
3227 UnicodeString
.Length
= 0;
3228 UnicodeString
.MaximumLength
= sizeof(FixedBuffer
);
3229 UnicodeString
.Buffer
= FixedBuffer
;
3230 Status
= RtlConvertSidToUnicodeString(&UnicodeString
, Sid
, FALSE
);
3231 if (STATUS_BUFFER_TOO_SMALL
== Status
)
3233 Status
= RtlConvertSidToUnicodeString(&UnicodeString
, Sid
, TRUE
);
3236 if (!NT_SUCCESS(Status
))
3238 SetLastError(RtlNtStatusToDosError(Status
));
3242 *StringSid
= LocalAlloc(LMEM_FIXED
, UnicodeString
.Length
+ sizeof(WCHAR
));
3243 if (NULL
== *StringSid
)
3245 if (UnicodeString
.Buffer
!= FixedBuffer
)
3247 RtlFreeUnicodeString(&UnicodeString
);
3249 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
3253 MoveMemory(*StringSid
, UnicodeString
.Buffer
, UnicodeString
.Length
);
3254 ZeroMemory((PCHAR
) *StringSid
+ UnicodeString
.Length
, sizeof(WCHAR
));
3255 if (UnicodeString
.Buffer
!= FixedBuffer
)
3257 RtlFreeUnicodeString(&UnicodeString
);
3268 ConvertSidToStringSidA(PSID Sid
,
3274 if (!ConvertSidToStringSidW(Sid
, &StringSidW
))
3279 Len
= WideCharToMultiByte(CP_ACP
, 0, StringSidW
, -1, NULL
, 0, NULL
, NULL
);
3282 LocalFree(StringSidW
);
3283 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
3287 *StringSid
= LocalAlloc(LMEM_FIXED
, Len
);
3288 if (NULL
== *StringSid
)
3290 LocalFree(StringSidW
);
3291 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
3295 if (!WideCharToMultiByte(CP_ACP
, 0, StringSidW
, -1, *StringSid
, Len
, NULL
, NULL
))
3297 LocalFree(StringSid
);
3298 LocalFree(StringSidW
);
3302 LocalFree(StringSidW
);
3311 CreateProcessWithLogonW(LPCWSTR lpUsername
,
3315 LPCWSTR lpApplicationName
,
3316 LPWSTR lpCommandLine
,
3317 DWORD dwCreationFlags
,
3318 LPVOID lpEnvironment
,
3319 LPCWSTR lpCurrentDirectory
,
3320 LPSTARTUPINFOW lpStartupInfo
,
3321 LPPROCESS_INFORMATION lpProcessInformation
)
3323 FIXME("%s %s %s 0x%08x %s %s 0x%08x %p %s %p %p stub\n", debugstr_w(lpUsername
), debugstr_w(lpDomain
),
3324 debugstr_w(lpPassword
), dwLogonFlags
, debugstr_w(lpApplicationName
),
3325 debugstr_w(lpCommandLine
), dwCreationFlags
, lpEnvironment
, debugstr_w(lpCurrentDirectory
),
3326 lpStartupInfo
, lpProcessInformation
);
3331 BOOL WINAPI
CreateProcessWithTokenW(HANDLE token
, DWORD logon_flags
, LPCWSTR application_name
, LPWSTR command_line
,
3332 DWORD creation_flags
, void *environment
, LPCWSTR current_directory
, STARTUPINFOW
*startup_info
,
3333 PROCESS_INFORMATION
*process_information
)
3335 FIXME("%p 0x%08x %s %s 0x%08x %p %s %p %p - semi-stub\n", token
,
3336 logon_flags
, debugstr_w(application_name
), debugstr_w(command_line
),
3337 creation_flags
, environment
, debugstr_w(current_directory
),
3338 startup_info
, process_information
);
3340 /* FIXME: check if handles should be inherited */
3341 return CreateProcessW( application_name
, command_line
, NULL
, NULL
, FALSE
, creation_flags
, environment
,
3342 current_directory
, startup_info
, process_information
);
3349 DuplicateTokenEx(IN HANDLE ExistingTokenHandle
,
3350 IN DWORD dwDesiredAccess
,
3351 IN LPSECURITY_ATTRIBUTES lpTokenAttributes OPTIONAL
,
3352 IN SECURITY_IMPERSONATION_LEVEL ImpersonationLevel
,
3353 IN TOKEN_TYPE TokenType
,
3354 OUT PHANDLE DuplicateTokenHandle
)
3356 OBJECT_ATTRIBUTES ObjectAttributes
;
3358 SECURITY_QUALITY_OF_SERVICE Sqos
;
3360 TRACE("%p 0x%08x 0x%08x 0x%08x %p\n", ExistingTokenHandle
, dwDesiredAccess
,
3361 ImpersonationLevel
, TokenType
, DuplicateTokenHandle
);
3363 Sqos
.Length
= sizeof(SECURITY_QUALITY_OF_SERVICE
);
3364 Sqos
.ImpersonationLevel
= ImpersonationLevel
;
3365 Sqos
.ContextTrackingMode
= 0;
3366 Sqos
.EffectiveOnly
= FALSE
;
3368 if (lpTokenAttributes
!= NULL
)
3370 InitializeObjectAttributes(&ObjectAttributes
,
3372 lpTokenAttributes
->bInheritHandle
? OBJ_INHERIT
: 0,
3374 lpTokenAttributes
->lpSecurityDescriptor
);
3378 InitializeObjectAttributes(&ObjectAttributes
,
3385 ObjectAttributes
.SecurityQualityOfService
= &Sqos
;
3387 Status
= NtDuplicateToken(ExistingTokenHandle
,
3392 DuplicateTokenHandle
);
3393 if (!NT_SUCCESS(Status
))
3395 ERR("NtDuplicateToken failed: Status %08x\n", Status
);
3396 SetLastError(RtlNtStatusToDosError(Status
));
3400 TRACE("Returning token %p.\n", *DuplicateTokenHandle
);
3409 DuplicateToken(IN HANDLE ExistingTokenHandle
,
3410 IN SECURITY_IMPERSONATION_LEVEL ImpersonationLevel
,
3411 OUT PHANDLE DuplicateTokenHandle
)
3413 return DuplicateTokenEx(ExistingTokenHandle
,
3414 TOKEN_IMPERSONATE
| TOKEN_QUERY
,
3418 DuplicateTokenHandle
);
3421 /******************************************************************************
3422 * ComputeStringSidSize
3424 static DWORD
ComputeStringSidSize(LPCWSTR StringSid
)
3426 if (StringSid
[0] == 'S' && StringSid
[1] == '-') /* S-R-I(-S)+ */
3431 if (*StringSid
== '-')
3437 return GetSidLengthRequired(ctok
- 2);
3439 else /* String constant format - Only available in winxp and above */
3443 for (i
= 0; i
< sizeof(WellKnownSids
)/sizeof(WellKnownSids
[0]); i
++)
3444 if (!strncmpW(WellKnownSids
[i
].wstr
, StringSid
, 2))
3445 return GetSidLengthRequired(WellKnownSids
[i
].Sid
.SubAuthorityCount
);
3447 for (i
= 0; i
< sizeof(WellKnownRids
)/sizeof(WellKnownRids
[0]); i
++)
3448 if (!strncmpW(WellKnownRids
[i
].wstr
, StringSid
, 2))
3451 ADVAPI_GetComputerSid(&local
);
3452 return GetSidLengthRequired(*GetSidSubAuthorityCount(&local
) + 1);
3457 return GetSidLengthRequired(0);
3460 /******************************************************************************
3461 * ParseStringSidToSid
3463 static BOOL
ParseStringSidToSid(LPCWSTR StringSid
, PSID pSid
, LPDWORD cBytes
)
3468 TRACE("%s, %p, %p\n", debugstr_w(StringSid
), pSid
, cBytes
);
3471 SetLastError(ERROR_INVALID_PARAMETER
);
3472 TRACE("StringSid is NULL, returning FALSE\n");
3476 while (*StringSid
== ' ')
3480 goto lend
; /* ERROR_INVALID_SID */
3482 *cBytes
= ComputeStringSidSize(StringSid
);
3483 if (!pisid
) /* Simply compute the size */
3485 TRACE("only size requested, returning TRUE with %d\n", *cBytes
);
3489 if (StringSid
[0] == 'S' && StringSid
[1] == '-') /* S-R-I-S-S */
3491 DWORD i
= 0, identAuth
;
3492 DWORD csubauth
= ((*cBytes
- GetSidLengthRequired(0)) / sizeof(DWORD
));
3494 StringSid
+= 2; /* Advance to Revision */
3495 pisid
->Revision
= atoiW(StringSid
);
3497 if (pisid
->Revision
!= SDDL_REVISION
)
3499 TRACE("Revision %d is unknown\n", pisid
->Revision
);
3500 goto lend
; /* ERROR_INVALID_SID */
3504 TRACE("SubAuthorityCount is 0\n");
3505 goto lend
; /* ERROR_INVALID_SID */
3508 pisid
->SubAuthorityCount
= csubauth
;
3510 /* Advance to identifier authority */
3511 while (*StringSid
&& *StringSid
!= '-')
3513 if (*StringSid
== '-')
3516 /* MS' implementation can't handle values greater than 2^32 - 1, so
3517 * we don't either; assume most significant bytes are always 0
3519 pisid
->IdentifierAuthority
.Value
[0] = 0;
3520 pisid
->IdentifierAuthority
.Value
[1] = 0;
3521 identAuth
= atoiW(StringSid
);
3522 pisid
->IdentifierAuthority
.Value
[5] = identAuth
& 0xff;
3523 pisid
->IdentifierAuthority
.Value
[4] = (identAuth
& 0xff00) >> 8;
3524 pisid
->IdentifierAuthority
.Value
[3] = (identAuth
& 0xff0000) >> 16;
3525 pisid
->IdentifierAuthority
.Value
[2] = (identAuth
& 0xff000000) >> 24;
3527 /* Advance to first sub authority */
3528 while (*StringSid
&& *StringSid
!= '-')
3530 if (*StringSid
== '-')
3535 pisid
->SubAuthority
[i
++] = atoiW(StringSid
);
3537 while (*StringSid
&& *StringSid
!= '-')
3539 if (*StringSid
== '-')
3543 if (i
!= pisid
->SubAuthorityCount
)
3544 goto lend
; /* ERROR_INVALID_SID */
3548 else /* String constant format - Only available in winxp and above */
3551 pisid
->Revision
= SDDL_REVISION
;
3553 for (i
= 0; i
< sizeof(WellKnownSids
)/sizeof(WellKnownSids
[0]); i
++)
3554 if (!strncmpW(WellKnownSids
[i
].wstr
, StringSid
, 2))
3557 pisid
->SubAuthorityCount
= WellKnownSids
[i
].Sid
.SubAuthorityCount
;
3558 pisid
->IdentifierAuthority
= WellKnownSids
[i
].Sid
.IdentifierAuthority
;
3559 for (j
= 0; j
< WellKnownSids
[i
].Sid
.SubAuthorityCount
; j
++)
3560 pisid
->SubAuthority
[j
] = WellKnownSids
[i
].Sid
.SubAuthority
[j
];
3564 for (i
= 0; i
< sizeof(WellKnownRids
)/sizeof(WellKnownRids
[0]); i
++)
3565 if (!strncmpW(WellKnownRids
[i
].wstr
, StringSid
, 2))
3567 ADVAPI_GetComputerSid(pisid
);
3568 pisid
->SubAuthority
[pisid
->SubAuthorityCount
] = WellKnownRids
[i
].Rid
;
3569 pisid
->SubAuthorityCount
++;
3574 FIXME("String constant not supported: %s\n", debugstr_wn(StringSid
, 2));
3579 SetLastError(ERROR_INVALID_SID
);
3581 TRACE("returning %s\n", bret
? "TRUE" : "FALSE");
3585 /**********************************************************************
3586 * GetNamedSecurityInfoA EXPORTED
3592 GetNamedSecurityInfoA(LPSTR pObjectName
,
3593 SE_OBJECT_TYPE ObjectType
,
3594 SECURITY_INFORMATION SecurityInfo
,
3599 PSECURITY_DESCRIPTOR
*ppSecurityDescriptor
)
3605 TRACE("%s %d %d %p %p %p %p %p\n", pObjectName
, ObjectType
, SecurityInfo
,
3606 ppsidOwner
, ppsidGroup
, ppDacl
, ppSacl
, ppSecurityDescriptor
);
3610 len
= MultiByteToWideChar( CP_ACP
, 0, pObjectName
, -1, NULL
, 0 );
3611 wstr
= HeapAlloc( GetProcessHeap(), 0, len
*sizeof(WCHAR
));
3612 MultiByteToWideChar( CP_ACP
, 0, pObjectName
, -1, wstr
, len
);
3615 r
= GetNamedSecurityInfoW( wstr
, ObjectType
, SecurityInfo
, ppsidOwner
,
3616 ppsidGroup
, ppDacl
, ppSacl
, ppSecurityDescriptor
);
3618 HeapFree( GetProcessHeap(), 0, wstr
);
3628 GetWindowsAccountDomainSid(IN PSID pSid
,
3629 OUT PSID ppDomainSid
,
3630 IN OUT DWORD
* cbSid
)
3641 EqualDomainSid(IN PSID pSid1
,