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 LPWSTR
SERV_dup( LPCSTR str
)
246 len
= MultiByteToWideChar( CP_ACP
, 0, str
, -1, NULL
, 0 );
247 wstr
= heap_alloc( len
*sizeof (WCHAR
) );
248 MultiByteToWideChar( CP_ACP
, 0, str
, -1, wstr
, len
);
252 /************************************************************
253 * ADVAPI_IsLocalComputer
255 * Checks whether the server name indicates local machine.
257 BOOL
ADVAPI_IsLocalComputer(LPCWSTR ServerName
)
259 DWORD dwSize
= MAX_COMPUTERNAME_LENGTH
+ 1;
263 if (!ServerName
|| !ServerName
[0])
266 buf
= heap_alloc(dwSize
* sizeof(WCHAR
));
267 Result
= GetComputerNameW(buf
, &dwSize
);
268 if (Result
&& (ServerName
[0] == '\\') && (ServerName
[1] == '\\'))
270 Result
= Result
&& !lstrcmpW(ServerName
, buf
);
276 /************************************************************
277 * ADVAPI_GetComputerSid
279 BOOL
ADVAPI_GetComputerSid(PSID sid
)
281 static const struct /* same fields as struct SID */
284 BYTE SubAuthorityCount
;
285 SID_IDENTIFIER_AUTHORITY IdentifierAuthority
;
286 DWORD SubAuthority
[4];
288 { SID_REVISION
, 4, { SECURITY_NT_AUTHORITY
}, { SECURITY_NT_NON_UNIQUE
, 0, 0, 0 } };
290 memcpy( sid
, &computer_sid
, sizeof(computer_sid
) );
294 /* Exported functions */
300 OpenProcessToken(HANDLE ProcessHandle
,
306 TRACE("%p, %x, %p.\n", ProcessHandle
, DesiredAccess
, TokenHandle
);
308 Status
= NtOpenProcessToken(ProcessHandle
,
311 if (!NT_SUCCESS(Status
))
313 ERR("NtOpenProcessToken failed! Status %08x.\n", Status
);
314 SetLastError(RtlNtStatusToDosError(Status
));
318 TRACE("Returning token %p.\n", *TokenHandle
);
323 /******************************************************************************
324 * OpenThreadToken [ADVAPI32.@]
326 * Opens the access token associated with a thread handle.
329 * ThreadHandle [I] Handle to process
330 * DesiredAccess [I] Desired access to the thread
332 * TokenHandle [O] Destination for the token handle
335 * Success: TRUE. TokenHandle contains the access token.
339 * See NtOpenThreadToken.
342 OpenThreadToken( HANDLE ThreadHandle
, DWORD DesiredAccess
,
343 BOOL OpenAsSelf
, HANDLE
*TokenHandle
)
345 return set_ntstatus( NtOpenThreadToken(ThreadHandle
, DesiredAccess
, OpenAsSelf
, TokenHandle
));
352 AdjustTokenGroups(HANDLE TokenHandle
,
354 PTOKEN_GROUPS NewState
,
356 PTOKEN_GROUPS PreviousState
,
361 Status
= NtAdjustGroupsToken(TokenHandle
,
366 (PULONG
)ReturnLength
);
367 if (!NT_SUCCESS(Status
))
369 SetLastError(RtlNtStatusToDosError(Status
));
380 AdjustTokenPrivileges(HANDLE TokenHandle
,
381 BOOL DisableAllPrivileges
,
382 PTOKEN_PRIVILEGES NewState
,
384 PTOKEN_PRIVILEGES PreviousState
,
389 Status
= NtAdjustPrivilegesToken(TokenHandle
,
390 DisableAllPrivileges
,
394 (PULONG
)ReturnLength
);
395 if (STATUS_NOT_ALL_ASSIGNED
== Status
)
397 SetLastError(ERROR_NOT_ALL_ASSIGNED
);
401 if (!NT_SUCCESS(Status
))
403 SetLastError(RtlNtStatusToDosError(Status
));
407 /* AdjustTokenPrivileges is documented to do this */
408 SetLastError(ERROR_SUCCESS
);
417 GetTokenInformation(HANDLE TokenHandle
,
418 TOKEN_INFORMATION_CLASS TokenInformationClass
,
419 LPVOID TokenInformation
,
420 DWORD TokenInformationLength
,
425 Status
= NtQueryInformationToken(TokenHandle
,
426 TokenInformationClass
,
428 TokenInformationLength
,
429 (PULONG
)ReturnLength
);
430 if (!NT_SUCCESS(Status
))
432 SetLastError(RtlNtStatusToDosError(Status
));
443 SetTokenInformation(HANDLE TokenHandle
,
444 TOKEN_INFORMATION_CLASS TokenInformationClass
,
445 LPVOID TokenInformation
,
446 DWORD TokenInformationLength
)
450 Status
= NtSetInformationToken(TokenHandle
,
451 TokenInformationClass
,
453 TokenInformationLength
);
454 if (!NT_SUCCESS(Status
))
456 SetLastError(RtlNtStatusToDosError(Status
));
467 SetThreadToken(IN PHANDLE ThreadHandle OPTIONAL
,
468 IN HANDLE TokenHandle
)
473 hThread
= (ThreadHandle
!= NULL
) ? *ThreadHandle
: NtCurrentThread();
475 Status
= NtSetInformationThread(hThread
,
476 ThreadImpersonationToken
,
479 if (!NT_SUCCESS(Status
))
481 SetLastError(RtlNtStatusToDosError(Status
));
488 /*************************************************************************
489 * CreateRestrictedToken [ADVAPI32.@]
491 * Create a new more restricted token from an existing token.
494 * baseToken [I] Token to base the new restricted token on
496 * nDisableSids [I] Length of disableSids array
497 * disableSids [I] Array of SIDs to disable in the new token
498 * nDeletePrivs [I] Length of deletePrivs array
499 * deletePrivs [I] Array of privileges to delete in the new token
500 * nRestrictSids [I] Length of restrictSids array
501 * restrictSids [I] Array of SIDs to restrict in the new token
502 * newToken [O] Address where the new token is stored
508 BOOL WINAPI
CreateRestrictedToken(
512 PSID_AND_ATTRIBUTES disableSids
,
514 PLUID_AND_ATTRIBUTES deletePrivs
,
516 PSID_AND_ATTRIBUTES restrictSids
,
520 SECURITY_IMPERSONATION_LEVEL level
= TokenImpersonationLevel
;
523 FIXME("(%p, 0x%x, %u, %p, %u, %p, %u, %p, %p): stub\n",
524 baseToken
, flags
, nDisableSids
, disableSids
,
525 nDeletePrivs
, deletePrivs
,
526 nRestrictSids
, restrictSids
,
530 if (!GetTokenInformation( baseToken
, TokenType
, &type
, size
, &size
)) return FALSE
;
531 if (type
== TokenImpersonation
)
533 size
= sizeof(level
);
534 if (!GetTokenInformation( baseToken
, TokenImpersonationLevel
, &level
, size
, &size
))
537 return DuplicateTokenEx( baseToken
, MAXIMUM_ALLOWED
, NULL
, level
, type
, newToken
);
540 /******************************************************************************
541 * AllocateAndInitializeSid [ADVAPI32.@]
544 * pIdentifierAuthority []
545 * nSubAuthorityCount []
557 AllocateAndInitializeSid( PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority
,
558 BYTE nSubAuthorityCount
,
559 DWORD nSubAuthority0
, DWORD nSubAuthority1
,
560 DWORD nSubAuthority2
, DWORD nSubAuthority3
,
561 DWORD nSubAuthority4
, DWORD nSubAuthority5
,
562 DWORD nSubAuthority6
, DWORD nSubAuthority7
,
565 return set_ntstatus( RtlAllocateAndInitializeSid(
566 pIdentifierAuthority
, nSubAuthorityCount
,
567 nSubAuthority0
, nSubAuthority1
, nSubAuthority2
, nSubAuthority3
,
568 nSubAuthority4
, nSubAuthority5
, nSubAuthority6
, nSubAuthority7
,
576 * Docs says this function does NOT return a value
577 * even thou it's defined to return a PVOID...
583 return RtlFreeSid(pSid
);
586 /******************************************************************************
587 * CopySid [ADVAPI32.@]
590 * nDestinationSidLength []
595 CopySid( DWORD nDestinationSidLength
, PSID pDestinationSid
, PSID pSourceSid
)
597 return set_ntstatus(RtlCopySid(nDestinationSidLength
, pDestinationSid
, pSourceSid
));
605 CreateWellKnownSid(IN WELL_KNOWN_SID_TYPE WellKnownSidType
,
606 IN PSID DomainSid OPTIONAL
,
611 TRACE("(%d, %s, %p, %p)\n", WellKnownSidType
, debugstr_sid(DomainSid
), pSid
, cbSid
);
613 if (cbSid
== NULL
|| (DomainSid
&& !IsValidSid(DomainSid
)))
615 SetLastError(ERROR_INVALID_PARAMETER
);
619 for (i
= 0; i
< sizeof(WellKnownSids
)/sizeof(WellKnownSids
[0]); i
++) {
620 if (WellKnownSids
[i
].Type
== WellKnownSidType
) {
621 DWORD length
= GetSidLengthRequired(WellKnownSids
[i
].Sid
.SubAuthorityCount
);
626 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
631 SetLastError(ERROR_INVALID_PARAMETER
);
634 CopyMemory(pSid
, &WellKnownSids
[i
].Sid
.Revision
, length
);
640 if (DomainSid
== NULL
|| *GetSidSubAuthorityCount(DomainSid
) == SID_MAX_SUB_AUTHORITIES
)
642 SetLastError(ERROR_INVALID_PARAMETER
);
646 for (i
= 0; i
< sizeof(WellKnownRids
)/sizeof(WellKnownRids
[0]); i
++)
647 if (WellKnownRids
[i
].Type
== WellKnownSidType
) {
648 UCHAR domain_subauth
= *GetSidSubAuthorityCount(DomainSid
);
649 DWORD domain_sid_length
= GetSidLengthRequired(domain_subauth
);
650 DWORD output_sid_length
= GetSidLengthRequired(domain_subauth
+ 1);
652 if (*cbSid
< output_sid_length
)
654 *cbSid
= output_sid_length
;
655 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
660 SetLastError(ERROR_INVALID_PARAMETER
);
663 CopyMemory(pSid
, DomainSid
, domain_sid_length
);
664 (*GetSidSubAuthorityCount(pSid
))++;
665 (*GetSidSubAuthority(pSid
, domain_subauth
)) = WellKnownRids
[i
].Rid
;
666 *cbSid
= output_sid_length
;
670 SetLastError(ERROR_INVALID_PARAMETER
);
679 IsWellKnownSid(IN PSID pSid
,
680 IN WELL_KNOWN_SID_TYPE WellKnownSidType
)
683 TRACE("(%s, %d)\n", debugstr_sid(pSid
), WellKnownSidType
);
685 for (i
= 0; i
< sizeof(WellKnownSids
) / sizeof(WellKnownSids
[0]); i
++)
687 if (WellKnownSids
[i
].Type
== WellKnownSidType
)
689 if (EqualSid(pSid
, (PSID
)(&WellKnownSids
[i
].Sid
.Revision
)))
702 IsValidSid(PSID pSid
)
704 return (BOOL
)RtlValidSid(pSid
);
715 SetLastError(ERROR_SUCCESS
);
716 return RtlEqualSid (pSid1
, pSid2
);
724 EqualPrefixSid(PSID pSid1
,
727 return RtlEqualPrefixSid (pSid1
, pSid2
);
735 GetSidLengthRequired(UCHAR nSubAuthorityCount
)
737 return (DWORD
)RtlLengthRequiredSid(nSubAuthorityCount
);
745 InitializeSid(PSID Sid
,
746 PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority
,
747 BYTE nSubAuthorityCount
)
751 Status
= RtlInitializeSid(Sid
,
752 pIdentifierAuthority
,
754 if (!NT_SUCCESS(Status
))
756 SetLastError(RtlNtStatusToDosError(Status
));
766 PSID_IDENTIFIER_AUTHORITY
768 GetSidIdentifierAuthority(PSID pSid
)
770 return RtlIdentifierAuthoritySid(pSid
);
778 GetSidSubAuthority(PSID pSid
,
781 SetLastError(ERROR_SUCCESS
);
782 return (PDWORD
)RtlSubAuthoritySid(pSid
, nSubAuthority
);
790 GetSidSubAuthorityCount(PSID pSid
)
792 SetLastError(ERROR_SUCCESS
);
793 return RtlSubAuthorityCountSid(pSid
);
801 GetLengthSid(PSID pSid
)
803 return (DWORD
)RtlLengthSid(pSid
);
811 InitializeSecurityDescriptor(PSECURITY_DESCRIPTOR pSecurityDescriptor
,
816 Status
= RtlCreateSecurityDescriptor(pSecurityDescriptor
,
818 if (!NT_SUCCESS(Status
))
820 SetLastError(RtlNtStatusToDosError(Status
));
832 MakeAbsoluteSD(PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor
,
833 PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor
,
834 LPDWORD lpdwAbsoluteSecurityDescriptorSize
,
836 LPDWORD lpdwDaclSize
,
838 LPDWORD lpdwSaclSize
,
840 LPDWORD lpdwOwnerSize
,
842 LPDWORD lpdwPrimaryGroupSize
)
846 Status
= RtlSelfRelativeToAbsoluteSD(pSelfRelativeSecurityDescriptor
,
847 pAbsoluteSecurityDescriptor
,
848 lpdwAbsoluteSecurityDescriptorSize
,
856 lpdwPrimaryGroupSize
);
857 if (!NT_SUCCESS(Status
))
859 SetLastError(RtlNtStatusToDosError(Status
));
866 /******************************************************************************
867 * GetKernelObjectSecurity [ADVAPI32.@]
869 BOOL WINAPI
GetKernelObjectSecurity(
871 SECURITY_INFORMATION RequestedInformation
,
872 PSECURITY_DESCRIPTOR pSecurityDescriptor
,
874 LPDWORD lpnLengthNeeded
)
876 TRACE("(%p,0x%08x,%p,0x%08x,%p)\n", Handle
, RequestedInformation
,
877 pSecurityDescriptor
, nLength
, lpnLengthNeeded
);
879 return set_ntstatus( NtQuerySecurityObject(Handle
, RequestedInformation
, pSecurityDescriptor
,
880 nLength
, lpnLengthNeeded
));
888 InitializeAcl(PACL pAcl
,
894 Status
= RtlCreateAcl(pAcl
,
897 if (!NT_SUCCESS(Status
))
899 SetLastError(RtlNtStatusToDosError(Status
));
906 BOOL WINAPI
ImpersonateNamedPipeClient( HANDLE hNamedPipe
)
908 IO_STATUS_BLOCK io_block
;
910 TRACE("(%p)\n", hNamedPipe
);
912 return set_ntstatus( NtFsControlFile(hNamedPipe
, NULL
, NULL
, NULL
,
913 &io_block
, FSCTL_PIPE_IMPERSONATE
, NULL
, 0, NULL
, 0) );
921 AddAccessAllowedAce(PACL pAcl
,
928 Status
= RtlAddAccessAllowedAce(pAcl
,
932 if (!NT_SUCCESS(Status
))
934 SetLastError(RtlNtStatusToDosError(Status
));
945 AddAccessAllowedAceEx(PACL pAcl
,
953 Status
= RtlAddAccessAllowedAceEx(pAcl
,
958 if (!NT_SUCCESS(Status
))
960 SetLastError(RtlNtStatusToDosError(Status
));
972 AddAccessDeniedAce(PACL pAcl
,
979 Status
= RtlAddAccessDeniedAce(pAcl
,
983 if (!NT_SUCCESS(Status
))
985 SetLastError(RtlNtStatusToDosError(Status
));
996 AddAccessDeniedAceEx(PACL pAcl
,
1004 Status
= RtlAddAccessDeniedAceEx(pAcl
,
1009 if (!NT_SUCCESS(Status
))
1011 SetLastError(RtlNtStatusToDosError(Status
));
1024 DWORD dwAceRevision
,
1025 DWORD dwStartingAceIndex
,
1027 DWORD nAceListLength
)
1031 Status
= RtlAddAce(pAcl
,
1036 if (!NT_SUCCESS(Status
))
1038 SetLastError(RtlNtStatusToDosError(Status
));
1045 /******************************************************************************
1046 * DeleteAce [ADVAPI32.@]
1048 BOOL WINAPI
DeleteAce(PACL pAcl
, DWORD dwAceIndex
)
1050 return set_ntstatus(RtlDeleteAce(pAcl
, dwAceIndex
));
1058 FindFirstFreeAce(PACL pAcl
,
1061 return RtlFirstFreeAce(pAcl
,
1065 /******************************************************************************
1066 * GetAce [ADVAPI32.@]
1068 BOOL WINAPI
GetAce(PACL pAcl
,DWORD dwAceIndex
,LPVOID
*pAce
)
1070 return set_ntstatus(RtlGetAce(pAcl
, dwAceIndex
, pAce
));
1073 /******************************************************************************
1074 * GetAclInformation [ADVAPI32.@]
1076 BOOL WINAPI
GetAclInformation(
1078 LPVOID pAclInformation
,
1079 DWORD nAclInformationLength
,
1080 ACL_INFORMATION_CLASS dwAclInformationClass
)
1082 return set_ntstatus(RtlQueryInformationAcl(pAcl
, pAclInformation
,
1083 nAclInformationLength
, dwAclInformationClass
));
1091 IsValidAcl(PACL pAcl
)
1093 return RtlValidAcl (pAcl
);
1100 AllocateLocallyUniqueId(PLUID Luid
)
1104 Status
= NtAllocateLocallyUniqueId (Luid
);
1105 if (!NT_SUCCESS (Status
))
1107 SetLastError(RtlNtStatusToDosError(Status
));
1114 /**********************************************************************
1115 * LookupPrivilegeDisplayNameA EXPORTED
1121 LookupPrivilegeDisplayNameA(LPCSTR lpSystemName
,
1123 LPSTR lpDisplayName
,
1124 LPDWORD cbDisplayName
,
1125 LPDWORD lpLanguageId
)
1127 FIXME("%s() not implemented!\n", __FUNCTION__
);
1128 SetLastError (ERROR_CALL_NOT_IMPLEMENTED
);
1133 /**********************************************************************
1134 * LookupPrivilegeDisplayNameW EXPORTED
1140 LookupPrivilegeDisplayNameW(LPCWSTR lpSystemName
,
1142 LPWSTR lpDisplayName
,
1143 LPDWORD cbDisplayName
,
1144 LPDWORD lpLanguageId
)
1146 FIXME("%s() not implemented!\n", __FUNCTION__
);
1147 SetLastError (ERROR_CALL_NOT_IMPLEMENTED
);
1151 /**********************************************************************
1152 * LookupPrivilegeNameA EXPORTED
1158 LookupPrivilegeNameA(LPCSTR lpSystemName
,
1163 UNICODE_STRING lpSystemNameW
;
1167 TRACE("%s %p %p %p\n", debugstr_a(lpSystemName
), lpLuid
, lpName
, cchName
);
1169 RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW
, lpSystemName
);
1170 ret
= LookupPrivilegeNameW(lpSystemNameW
.Buffer
, lpLuid
, NULL
, &wLen
);
1171 if (!ret
&& GetLastError() == ERROR_INSUFFICIENT_BUFFER
)
1173 LPWSTR lpNameW
= HeapAlloc(GetProcessHeap(), 0, wLen
* sizeof(WCHAR
));
1175 ret
= LookupPrivilegeNameW(lpSystemNameW
.Buffer
, lpLuid
, lpNameW
,
1179 /* Windows crashes if cchName is NULL, so will I */
1180 unsigned int len
= WideCharToMultiByte(CP_ACP
, 0, lpNameW
, -1, lpName
,
1181 *cchName
, NULL
, NULL
);
1185 /* WideCharToMultiByte failed */
1188 else if (len
> *cchName
)
1191 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
1196 /* WideCharToMultiByte succeeded, output length needs to be
1197 * length not including NULL terminator
1202 HeapFree(GetProcessHeap(), 0, lpNameW
);
1204 RtlFreeUnicodeString(&lpSystemNameW
);
1208 /******************************************************************************
1209 * GetFileSecurityA [ADVAPI32.@]
1211 * Obtains Specified information about the security of a file or directory.
1214 * lpFileName [I] Name of the file to get info for
1215 * RequestedInformation [I] SE_ flags from "winnt.h"
1216 * pSecurityDescriptor [O] Destination for security information
1217 * nLength [I] Length of pSecurityDescriptor
1218 * lpnLengthNeeded [O] Destination for length of returned security information
1221 * Success: TRUE. pSecurityDescriptor contains the requested information.
1222 * Failure: FALSE. lpnLengthNeeded contains the required space to return the info.
1225 * The information returned is constrained by the callers access rights and
1232 GetFileSecurityA(LPCSTR lpFileName
,
1233 SECURITY_INFORMATION RequestedInformation
,
1234 PSECURITY_DESCRIPTOR pSecurityDescriptor
,
1236 LPDWORD lpnLengthNeeded
)
1238 UNICODE_STRING FileName
;
1241 if (!RtlCreateUnicodeStringFromAsciiz(&FileName
, lpFileName
))
1243 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
1247 bResult
= GetFileSecurityW(FileName
.Buffer
,
1248 RequestedInformation
,
1249 pSecurityDescriptor
,
1253 RtlFreeUnicodeString(&FileName
);
1263 GetFileSecurityW(LPCWSTR lpFileName
,
1264 SECURITY_INFORMATION RequestedInformation
,
1265 PSECURITY_DESCRIPTOR pSecurityDescriptor
,
1267 LPDWORD lpnLengthNeeded
)
1269 OBJECT_ATTRIBUTES ObjectAttributes
;
1270 IO_STATUS_BLOCK StatusBlock
;
1271 UNICODE_STRING FileName
;
1272 ULONG AccessMask
= 0;
1276 TRACE("GetFileSecurityW() called\n");
1278 QuerySecurityAccessMask(RequestedInformation
, &AccessMask
);
1280 if (!RtlDosPathNameToNtPathName_U(lpFileName
,
1285 ERR("Invalid path\n");
1286 SetLastError(ERROR_INVALID_NAME
);
1290 InitializeObjectAttributes(&ObjectAttributes
,
1292 OBJ_CASE_INSENSITIVE
,
1296 Status
= NtOpenFile(&FileHandle
,
1300 FILE_SHARE_READ
| FILE_SHARE_WRITE
| FILE_SHARE_DELETE
,
1303 RtlFreeHeap(RtlGetProcessHeap(),
1307 if (!NT_SUCCESS(Status
))
1309 ERR("NtOpenFile() failed (Status %lx)\n", Status
);
1310 SetLastError(RtlNtStatusToDosError(Status
));
1314 Status
= NtQuerySecurityObject(FileHandle
,
1315 RequestedInformation
,
1316 pSecurityDescriptor
,
1319 NtClose(FileHandle
);
1320 if (!NT_SUCCESS(Status
))
1322 ERR("NtQuerySecurityObject() failed (Status %lx)\n", Status
);
1323 SetLastError(RtlNtStatusToDosError(Status
));
1330 /******************************************************************************
1331 * SetFileSecurityA [ADVAPI32.@]
1332 * Sets the security of a file or directory
1338 SetFileSecurityA(LPCSTR lpFileName
,
1339 SECURITY_INFORMATION SecurityInformation
,
1340 PSECURITY_DESCRIPTOR pSecurityDescriptor
)
1342 UNICODE_STRING FileName
;
1345 if (!RtlCreateUnicodeStringFromAsciiz(&FileName
, lpFileName
))
1347 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
1351 bResult
= SetFileSecurityW(FileName
.Buffer
,
1352 SecurityInformation
,
1353 pSecurityDescriptor
);
1355 RtlFreeUnicodeString(&FileName
);
1360 /******************************************************************************
1361 * SetFileSecurityW [ADVAPI32.@]
1362 * Sets the security of a file or directory
1368 SetFileSecurityW(LPCWSTR lpFileName
,
1369 SECURITY_INFORMATION SecurityInformation
,
1370 PSECURITY_DESCRIPTOR pSecurityDescriptor
)
1372 OBJECT_ATTRIBUTES ObjectAttributes
;
1373 IO_STATUS_BLOCK StatusBlock
;
1374 UNICODE_STRING FileName
;
1375 ULONG AccessMask
= 0;
1379 TRACE("SetFileSecurityW() called\n");
1381 SetSecurityAccessMask(SecurityInformation
, &AccessMask
);
1383 if (!RtlDosPathNameToNtPathName_U(lpFileName
,
1388 ERR("Invalid path\n");
1389 SetLastError(ERROR_INVALID_NAME
);
1393 InitializeObjectAttributes(&ObjectAttributes
,
1395 OBJ_CASE_INSENSITIVE
,
1399 Status
= NtOpenFile(&FileHandle
,
1403 FILE_SHARE_READ
| FILE_SHARE_WRITE
| FILE_SHARE_DELETE
,
1406 RtlFreeHeap(RtlGetProcessHeap(),
1410 if (!NT_SUCCESS(Status
))
1412 ERR("NtOpenFile() failed (Status %lx)\n", Status
);
1413 SetLastError(RtlNtStatusToDosError(Status
));
1417 Status
= NtSetSecurityObject(FileHandle
,
1418 SecurityInformation
,
1419 pSecurityDescriptor
);
1420 NtClose(FileHandle
);
1422 if (!NT_SUCCESS(Status
))
1424 ERR("NtSetSecurityObject() failed (Status %lx)\n", Status
);
1425 SetLastError(RtlNtStatusToDosError(Status
));
1432 /******************************************************************************
1433 * QueryWindows31FilesMigration [ADVAPI32.@]
1439 QueryWindows31FilesMigration( DWORD x1
)
1441 FIXME("(%d):stub\n",x1
);
1445 /******************************************************************************
1446 * SynchronizeWindows31FilesAndWindowsNTRegistry [ADVAPI32.@]
1455 SynchronizeWindows31FilesAndWindowsNTRegistry( DWORD x1
, DWORD x2
, DWORD x3
,
1458 FIXME("(0x%08x,0x%08x,0x%08x,0x%08x):stub\n",x1
,x2
,x3
,x4
);
1470 HANDLE Token
= NULL
;
1472 Status
= NtSetInformationThread(NtCurrentThread(),
1473 ThreadImpersonationToken
,
1476 if (!NT_SUCCESS(Status
))
1478 SetLastError(RtlNtStatusToDosError(Status
));
1490 ImpersonateSelf(SECURITY_IMPERSONATION_LEVEL ImpersonationLevel
)
1494 Status
= RtlImpersonateSelf(ImpersonationLevel
);
1495 if (!NT_SUCCESS(Status
))
1497 SetLastError(RtlNtStatusToDosError(Status
));
1509 AccessCheck(IN PSECURITY_DESCRIPTOR pSecurityDescriptor
,
1510 IN HANDLE ClientToken
,
1511 IN DWORD DesiredAccess
,
1512 IN PGENERIC_MAPPING GenericMapping
,
1513 OUT PPRIVILEGE_SET PrivilegeSet OPTIONAL
,
1514 IN OUT LPDWORD PrivilegeSetLength
,
1515 OUT LPDWORD GrantedAccess
,
1516 OUT LPBOOL AccessStatus
)
1519 NTSTATUS NtAccessStatus
;
1521 /* Do the access check */
1522 Status
= NtAccessCheck(pSecurityDescriptor
,
1527 (PULONG
)PrivilegeSetLength
,
1528 (PACCESS_MASK
)GrantedAccess
,
1531 /* See if the access check operation succeeded */
1532 if (!NT_SUCCESS(Status
))
1535 SetLastError(RtlNtStatusToDosError(Status
));
1539 /* Now check the access status */
1540 if (!NT_SUCCESS(NtAccessStatus
))
1543 SetLastError(RtlNtStatusToDosError(NtAccessStatus
));
1544 *AccessStatus
= FALSE
;
1548 /* Access granted */
1549 *AccessStatus
= TRUE
;
1552 /* Check succeeded */
1559 BOOL WINAPI
AccessCheckByType(
1560 PSECURITY_DESCRIPTOR pSecurityDescriptor
,
1561 PSID PrincipalSelfSid
,
1563 DWORD DesiredAccess
,
1564 POBJECT_TYPE_LIST ObjectTypeList
,
1565 DWORD ObjectTypeListLength
,
1566 PGENERIC_MAPPING GenericMapping
,
1567 PPRIVILEGE_SET PrivilegeSet
,
1568 LPDWORD PrivilegeSetLength
,
1569 LPDWORD GrantedAccess
,
1570 LPBOOL AccessStatus
)
1574 *AccessStatus
= TRUE
;
1576 return !*AccessStatus
;
1584 SetKernelObjectSecurity(HANDLE Handle
,
1585 SECURITY_INFORMATION SecurityInformation
,
1586 PSECURITY_DESCRIPTOR SecurityDescriptor
)
1590 Status
= NtSetSecurityObject(Handle
,
1591 SecurityInformation
,
1592 SecurityDescriptor
);
1593 if (!NT_SUCCESS(Status
))
1595 SetLastError(RtlNtStatusToDosError(Status
));
1607 AddAuditAccessAce(PACL pAcl
,
1608 DWORD dwAceRevision
,
1616 Status
= RtlAddAuditAccessAce(pAcl
,
1622 if (!NT_SUCCESS(Status
))
1624 SetLastError(RtlNtStatusToDosError(Status
));
1635 AddAuditAccessAceEx(PACL pAcl
,
1636 DWORD dwAceRevision
,
1645 Status
= RtlAddAuditAccessAceEx(pAcl
,
1652 if (!NT_SUCCESS(Status
))
1654 SetLastError(RtlNtStatusToDosError(Status
));
1661 /******************************************************************************
1662 * LookupAccountNameA [ADVAPI32.@]
1668 LookupAccountNameA(LPCSTR SystemName
,
1672 LPSTR ReferencedDomainName
,
1673 LPDWORD hReferencedDomainNameLength
,
1674 PSID_NAME_USE SidNameUse
)
1677 UNICODE_STRING lpSystemW
;
1678 UNICODE_STRING lpAccountW
;
1679 LPWSTR lpReferencedDomainNameW
= NULL
;
1681 RtlCreateUnicodeStringFromAsciiz(&lpSystemW
, SystemName
);
1682 RtlCreateUnicodeStringFromAsciiz(&lpAccountW
, AccountName
);
1684 if (ReferencedDomainName
)
1685 lpReferencedDomainNameW
= HeapAlloc(GetProcessHeap(),
1687 *hReferencedDomainNameLength
* sizeof(WCHAR
));
1689 ret
= LookupAccountNameW(lpSystemW
.Buffer
,
1693 lpReferencedDomainNameW
,
1694 hReferencedDomainNameLength
,
1697 if (ret
&& lpReferencedDomainNameW
)
1699 WideCharToMultiByte(CP_ACP
,
1701 lpReferencedDomainNameW
,
1702 *hReferencedDomainNameLength
+ 1,
1703 ReferencedDomainName
,
1704 *hReferencedDomainNameLength
+ 1,
1709 RtlFreeUnicodeString(&lpSystemW
);
1710 RtlFreeUnicodeString(&lpAccountW
);
1711 HeapFree(GetProcessHeap(), 0, lpReferencedDomainNameW
);
1716 /**********************************************************************
1717 * PrivilegeCheck EXPORTED
1722 PrivilegeCheck(HANDLE ClientToken
,
1723 PPRIVILEGE_SET RequiredPrivileges
,
1729 Status
= NtPrivilegeCheck(ClientToken
,
1732 if (!NT_SUCCESS(Status
))
1734 SetLastError(RtlNtStatusToDosError(Status
));
1738 *pfResult
= (BOOL
)Result
;
1743 /******************************************************************************
1744 * GetSecurityInfoExW EXPORTED
1748 GetSecurityInfoExA(HANDLE hObject
,
1749 SE_OBJECT_TYPE ObjectType
,
1750 SECURITY_INFORMATION SecurityInfo
,
1753 PACTRL_ACCESSA
*ppAccessList
,
1754 PACTRL_AUDITA
*ppAuditList
,
1758 FIXME("%s() not implemented!\n", __FUNCTION__
);
1759 return ERROR_BAD_PROVIDER
;
1763 /******************************************************************************
1764 * GetSecurityInfoExW EXPORTED
1768 GetSecurityInfoExW(HANDLE hObject
,
1769 SE_OBJECT_TYPE ObjectType
,
1770 SECURITY_INFORMATION SecurityInfo
,
1773 PACTRL_ACCESSW
*ppAccessList
,
1774 PACTRL_AUDITW
*ppAuditList
,
1778 FIXME("%s() not implemented!\n", __FUNCTION__
);
1779 return ERROR_BAD_PROVIDER
;
1782 /******************************************************************************
1783 * BuildExplicitAccessWithNameA [ADVAPI32.@]
1786 BuildExplicitAccessWithNameA(PEXPLICIT_ACCESSA pExplicitAccess
,
1788 DWORD AccessPermissions
,
1789 ACCESS_MODE AccessMode
,
1792 pExplicitAccess
->grfAccessPermissions
= AccessPermissions
;
1793 pExplicitAccess
->grfAccessMode
= AccessMode
;
1794 pExplicitAccess
->grfInheritance
= Inheritance
;
1796 pExplicitAccess
->Trustee
.pMultipleTrustee
= NULL
;
1797 pExplicitAccess
->Trustee
.MultipleTrusteeOperation
= NO_MULTIPLE_TRUSTEE
;
1798 pExplicitAccess
->Trustee
.TrusteeForm
= TRUSTEE_IS_NAME
;
1799 pExplicitAccess
->Trustee
.TrusteeType
= TRUSTEE_IS_UNKNOWN
;
1800 pExplicitAccess
->Trustee
.ptstrName
= pTrusteeName
;
1804 /******************************************************************************
1805 * BuildExplicitAccessWithNameW [ADVAPI32.@]
1808 BuildExplicitAccessWithNameW(PEXPLICIT_ACCESSW pExplicitAccess
,
1809 LPWSTR pTrusteeName
,
1810 DWORD AccessPermissions
,
1811 ACCESS_MODE AccessMode
,
1814 pExplicitAccess
->grfAccessPermissions
= AccessPermissions
;
1815 pExplicitAccess
->grfAccessMode
= AccessMode
;
1816 pExplicitAccess
->grfInheritance
= Inheritance
;
1818 pExplicitAccess
->Trustee
.pMultipleTrustee
= NULL
;
1819 pExplicitAccess
->Trustee
.MultipleTrusteeOperation
= NO_MULTIPLE_TRUSTEE
;
1820 pExplicitAccess
->Trustee
.TrusteeForm
= TRUSTEE_IS_NAME
;
1821 pExplicitAccess
->Trustee
.TrusteeType
= TRUSTEE_IS_UNKNOWN
;
1822 pExplicitAccess
->Trustee
.ptstrName
= pTrusteeName
;
1825 /******************************************************************************
1826 * BuildTrusteeWithObjectsAndNameA [ADVAPI32.@]
1828 VOID WINAPI
BuildTrusteeWithObjectsAndNameA( PTRUSTEEA pTrustee
, POBJECTS_AND_NAME_A pObjName
,
1829 SE_OBJECT_TYPE ObjectType
, LPSTR ObjectTypeName
,
1830 LPSTR InheritedObjectTypeName
, LPSTR Name
)
1832 DWORD ObjectsPresent
= 0;
1834 TRACE("%p %p 0x%08x %p %p %s\n", pTrustee
, pObjName
,
1835 ObjectType
, ObjectTypeName
, InheritedObjectTypeName
, debugstr_a(Name
));
1837 /* Fill the OBJECTS_AND_NAME structure */
1838 pObjName
->ObjectType
= ObjectType
;
1839 if (ObjectTypeName
!= NULL
)
1841 ObjectsPresent
|= ACE_OBJECT_TYPE_PRESENT
;
1844 pObjName
->InheritedObjectTypeName
= InheritedObjectTypeName
;
1845 if (InheritedObjectTypeName
!= NULL
)
1847 ObjectsPresent
|= ACE_INHERITED_OBJECT_TYPE_PRESENT
;
1850 pObjName
->ObjectsPresent
= ObjectsPresent
;
1851 pObjName
->ptstrName
= Name
;
1853 /* Fill the TRUSTEE structure */
1854 pTrustee
->pMultipleTrustee
= NULL
;
1855 pTrustee
->MultipleTrusteeOperation
= NO_MULTIPLE_TRUSTEE
;
1856 pTrustee
->TrusteeForm
= TRUSTEE_IS_OBJECTS_AND_NAME
;
1857 pTrustee
->TrusteeType
= TRUSTEE_IS_UNKNOWN
;
1858 pTrustee
->ptstrName
= (LPSTR
)pObjName
;
1861 /******************************************************************************
1862 * BuildTrusteeWithObjectsAndNameW [ADVAPI32.@]
1864 VOID WINAPI
BuildTrusteeWithObjectsAndNameW( PTRUSTEEW pTrustee
, POBJECTS_AND_NAME_W pObjName
,
1865 SE_OBJECT_TYPE ObjectType
, LPWSTR ObjectTypeName
,
1866 LPWSTR InheritedObjectTypeName
, LPWSTR Name
)
1868 DWORD ObjectsPresent
= 0;
1870 TRACE("%p %p 0x%08x %p %p %s\n", pTrustee
, pObjName
,
1871 ObjectType
, ObjectTypeName
, InheritedObjectTypeName
, debugstr_w(Name
));
1873 /* Fill the OBJECTS_AND_NAME structure */
1874 pObjName
->ObjectType
= ObjectType
;
1875 if (ObjectTypeName
!= NULL
)
1877 ObjectsPresent
|= ACE_OBJECT_TYPE_PRESENT
;
1880 pObjName
->InheritedObjectTypeName
= InheritedObjectTypeName
;
1881 if (InheritedObjectTypeName
!= NULL
)
1883 ObjectsPresent
|= ACE_INHERITED_OBJECT_TYPE_PRESENT
;
1886 pObjName
->ObjectsPresent
= ObjectsPresent
;
1887 pObjName
->ptstrName
= Name
;
1889 /* Fill the TRUSTEE structure */
1890 pTrustee
->pMultipleTrustee
= NULL
;
1891 pTrustee
->MultipleTrusteeOperation
= NO_MULTIPLE_TRUSTEE
;
1892 pTrustee
->TrusteeForm
= TRUSTEE_IS_OBJECTS_AND_NAME
;
1893 pTrustee
->TrusteeType
= TRUSTEE_IS_UNKNOWN
;
1894 pTrustee
->ptstrName
= (LPWSTR
)pObjName
;
1897 /******************************************************************************
1898 * BuildTrusteeWithObjectsAndSidA [ADVAPI32.@]
1901 BuildTrusteeWithObjectsAndSidA(PTRUSTEEA pTrustee
,
1902 POBJECTS_AND_SID pObjSid
,
1904 GUID
*pInheritedObjectGuid
,
1907 DWORD ObjectsPresent
= 0;
1909 TRACE("%p %p %p %p %p\n", pTrustee
, pObjSid
, pObjectGuid
, pInheritedObjectGuid
, pSid
);
1911 /* Fill the OBJECTS_AND_SID structure */
1912 if (pObjectGuid
!= NULL
)
1914 pObjSid
->ObjectTypeGuid
= *pObjectGuid
;
1915 ObjectsPresent
|= ACE_OBJECT_TYPE_PRESENT
;
1919 ZeroMemory(&pObjSid
->ObjectTypeGuid
,
1923 if (pInheritedObjectGuid
!= NULL
)
1925 pObjSid
->InheritedObjectTypeGuid
= *pInheritedObjectGuid
;
1926 ObjectsPresent
|= ACE_INHERITED_OBJECT_TYPE_PRESENT
;
1930 ZeroMemory(&pObjSid
->InheritedObjectTypeGuid
,
1934 pObjSid
->ObjectsPresent
= ObjectsPresent
;
1935 pObjSid
->pSid
= pSid
;
1937 /* Fill the TRUSTEE structure */
1938 pTrustee
->pMultipleTrustee
= NULL
;
1939 pTrustee
->MultipleTrusteeOperation
= NO_MULTIPLE_TRUSTEE
;
1940 pTrustee
->TrusteeForm
= TRUSTEE_IS_OBJECTS_AND_SID
;
1941 pTrustee
->TrusteeType
= TRUSTEE_IS_UNKNOWN
;
1942 pTrustee
->ptstrName
= (LPSTR
) pObjSid
;
1946 /******************************************************************************
1947 * BuildTrusteeWithObjectsAndSidW [ADVAPI32.@]
1950 BuildTrusteeWithObjectsAndSidW(PTRUSTEEW pTrustee
,
1951 POBJECTS_AND_SID pObjSid
,
1953 GUID
*pInheritedObjectGuid
,
1956 DWORD ObjectsPresent
= 0;
1958 TRACE("%p %p %p %p %p\n", pTrustee
, pObjSid
, pObjectGuid
, pInheritedObjectGuid
, pSid
);
1960 /* Fill the OBJECTS_AND_SID structure */
1961 if (pObjectGuid
!= NULL
)
1963 pObjSid
->ObjectTypeGuid
= *pObjectGuid
;
1964 ObjectsPresent
|= ACE_OBJECT_TYPE_PRESENT
;
1968 ZeroMemory(&pObjSid
->ObjectTypeGuid
,
1972 if (pInheritedObjectGuid
!= NULL
)
1974 pObjSid
->InheritedObjectTypeGuid
= *pInheritedObjectGuid
;
1975 ObjectsPresent
|= ACE_INHERITED_OBJECT_TYPE_PRESENT
;
1979 ZeroMemory(&pObjSid
->InheritedObjectTypeGuid
,
1983 pObjSid
->ObjectsPresent
= ObjectsPresent
;
1984 pObjSid
->pSid
= pSid
;
1986 /* Fill the TRUSTEE structure */
1987 pTrustee
->pMultipleTrustee
= NULL
;
1988 pTrustee
->MultipleTrusteeOperation
= NO_MULTIPLE_TRUSTEE
;
1989 pTrustee
->TrusteeForm
= TRUSTEE_IS_OBJECTS_AND_SID
;
1990 pTrustee
->TrusteeType
= TRUSTEE_IS_UNKNOWN
;
1991 pTrustee
->ptstrName
= (LPWSTR
) pObjSid
;
1994 /******************************************************************************
1995 * BuildTrusteeWithSidA [ADVAPI32.@]
1998 BuildTrusteeWithSidA(PTRUSTEE_A pTrustee
,
2001 TRACE("%p %p\n", pTrustee
, pSid
);
2003 pTrustee
->pMultipleTrustee
= NULL
;
2004 pTrustee
->MultipleTrusteeOperation
= NO_MULTIPLE_TRUSTEE
;
2005 pTrustee
->TrusteeForm
= TRUSTEE_IS_SID
;
2006 pTrustee
->TrusteeType
= TRUSTEE_IS_UNKNOWN
;
2007 pTrustee
->ptstrName
= (LPSTR
) pSid
;
2011 /******************************************************************************
2012 * BuildTrusteeWithSidW [ADVAPI32.@]
2015 BuildTrusteeWithSidW(PTRUSTEE_W pTrustee
,
2018 TRACE("%p %p\n", pTrustee
, pSid
);
2020 pTrustee
->pMultipleTrustee
= NULL
;
2021 pTrustee
->MultipleTrusteeOperation
= NO_MULTIPLE_TRUSTEE
;
2022 pTrustee
->TrusteeForm
= TRUSTEE_IS_SID
;
2023 pTrustee
->TrusteeType
= TRUSTEE_IS_UNKNOWN
;
2024 pTrustee
->ptstrName
= (LPWSTR
) pSid
;
2027 /******************************************************************************
2028 * BuildTrusteeWithNameA [ADVAPI32.@]
2031 BuildTrusteeWithNameA(PTRUSTEE_A pTrustee
,
2034 TRACE("%p %s\n", pTrustee
, name
);
2036 pTrustee
->pMultipleTrustee
= NULL
;
2037 pTrustee
->MultipleTrusteeOperation
= NO_MULTIPLE_TRUSTEE
;
2038 pTrustee
->TrusteeForm
= TRUSTEE_IS_NAME
;
2039 pTrustee
->TrusteeType
= TRUSTEE_IS_UNKNOWN
;
2040 pTrustee
->ptstrName
= name
;
2043 /******************************************************************************
2044 * BuildTrusteeWithNameW [ADVAPI32.@]
2047 BuildTrusteeWithNameW(PTRUSTEE_W pTrustee
,
2050 TRACE("%p %s\n", pTrustee
, name
);
2052 pTrustee
->pMultipleTrustee
= NULL
;
2053 pTrustee
->MultipleTrusteeOperation
= NO_MULTIPLE_TRUSTEE
;
2054 pTrustee
->TrusteeForm
= TRUSTEE_IS_NAME
;
2055 pTrustee
->TrusteeType
= TRUSTEE_IS_UNKNOWN
;
2056 pTrustee
->ptstrName
= name
;
2059 /******************************************************************************
2060 * GetTrusteeFormW [ADVAPI32.@]
2063 GetTrusteeFormA(PTRUSTEE_A pTrustee
)
2065 return pTrustee
->TrusteeForm
;
2069 /******************************************************************************
2070 * GetTrusteeFormW [ADVAPI32.@]
2073 GetTrusteeFormW(PTRUSTEE_W pTrustee
)
2075 return pTrustee
->TrusteeForm
;
2078 /******************************************************************************
2079 * GetTrusteeNameA [ADVAPI32.@]
2082 GetTrusteeNameA(PTRUSTEE_A pTrustee
)
2084 return pTrustee
->ptstrName
;
2088 /******************************************************************************
2089 * GetTrusteeNameW [ADVAPI32.@]
2092 GetTrusteeNameW(PTRUSTEE_W pTrustee
)
2094 return pTrustee
->ptstrName
;
2097 /******************************************************************************
2098 * GetTrusteeTypeA [ADVAPI32.@]
2101 GetTrusteeTypeA(PTRUSTEE_A pTrustee
)
2103 return pTrustee
->TrusteeType
;
2106 /******************************************************************************
2107 * GetTrusteeTypeW [ADVAPI32.@]
2110 GetTrusteeTypeW(PTRUSTEE_W pTrustee
)
2112 return pTrustee
->TrusteeType
;
2120 SetAclInformation(PACL pAcl
,
2121 LPVOID pAclInformation
,
2122 DWORD nAclInformationLength
,
2123 ACL_INFORMATION_CLASS dwAclInformationClass
)
2127 Status
= RtlSetInformationAcl(pAcl
,
2129 nAclInformationLength
,
2130 dwAclInformationClass
);
2131 if (!NT_SUCCESS(Status
))
2133 SetLastError(RtlNtStatusToDosError(Status
));
2140 /**********************************************************************
2141 * SetNamedSecurityInfoA EXPORTED
2147 SetNamedSecurityInfoA(LPSTR pObjectName
,
2148 SE_OBJECT_TYPE ObjectType
,
2149 SECURITY_INFORMATION SecurityInfo
,
2155 UNICODE_STRING ObjectName
;
2158 if (!RtlCreateUnicodeStringFromAsciiz(&ObjectName
, pObjectName
))
2160 return ERROR_NOT_ENOUGH_MEMORY
;
2163 Ret
= SetNamedSecurityInfoW(ObjectName
.Buffer
,
2171 RtlFreeUnicodeString(&ObjectName
);
2181 AreAllAccessesGranted(DWORD GrantedAccess
,
2182 DWORD DesiredAccess
)
2184 return (BOOL
)RtlAreAllAccessesGranted(GrantedAccess
,
2193 AreAnyAccessesGranted(DWORD GrantedAccess
,
2194 DWORD DesiredAccess
)
2196 return (BOOL
)RtlAreAnyAccessesGranted(GrantedAccess
,
2200 /******************************************************************************
2201 * ParseAclStringFlags
2203 static DWORD
ParseAclStringFlags(LPCWSTR
* StringAcl
)
2206 LPCWSTR szAcl
= *StringAcl
;
2208 while (*szAcl
!= '(')
2212 flags
|= SE_DACL_PROTECTED
;
2214 else if (*szAcl
== 'A')
2218 flags
|= SE_DACL_AUTO_INHERIT_REQ
;
2219 else if (*szAcl
== 'I')
2220 flags
|= SE_DACL_AUTO_INHERITED
;
2229 /******************************************************************************
2230 * ParseAceStringType
2232 static const ACEFLAG AceType
[] =
2234 { SDDL_ALARM
, SYSTEM_ALARM_ACE_TYPE
},
2235 { SDDL_AUDIT
, SYSTEM_AUDIT_ACE_TYPE
},
2236 { SDDL_ACCESS_ALLOWED
, ACCESS_ALLOWED_ACE_TYPE
},
2237 { SDDL_ACCESS_DENIED
, ACCESS_DENIED_ACE_TYPE
},
2239 { SDDL_OBJECT_ACCESS_ALLOWED, ACCESS_ALLOWED_OBJECT_ACE_TYPE },
2240 { SDDL_OBJECT_ACCESS_DENIED, ACCESS_DENIED_OBJECT_ACE_TYPE },
2241 { SDDL_OBJECT_ALARM, SYSTEM_ALARM_OBJECT_ACE_TYPE },
2242 { SDDL_OBJECT_AUDIT, SYSTEM_AUDIT_OBJECT_ACE_TYPE },
2247 static BYTE
ParseAceStringType(LPCWSTR
* StringAcl
)
2250 LPCWSTR szAcl
= *StringAcl
;
2251 const ACEFLAG
*lpaf
= AceType
;
2253 while (*szAcl
== ' ')
2256 while (lpaf
->wstr
&&
2257 (len
= strlenW(lpaf
->wstr
)) &&
2258 strncmpW(lpaf
->wstr
, szAcl
, len
))
2264 *StringAcl
= szAcl
+ len
;
2269 /******************************************************************************
2270 * ParseAceStringFlags
2272 static const ACEFLAG AceFlags
[] =
2274 { SDDL_CONTAINER_INHERIT
, CONTAINER_INHERIT_ACE
},
2275 { SDDL_AUDIT_FAILURE
, FAILED_ACCESS_ACE_FLAG
},
2276 { SDDL_INHERITED
, INHERITED_ACE
},
2277 { SDDL_INHERIT_ONLY
, INHERIT_ONLY_ACE
},
2278 { SDDL_NO_PROPAGATE
, NO_PROPAGATE_INHERIT_ACE
},
2279 { SDDL_OBJECT_INHERIT
, OBJECT_INHERIT_ACE
},
2280 { SDDL_AUDIT_SUCCESS
, SUCCESSFUL_ACCESS_ACE_FLAG
},
2284 static BYTE
ParseAceStringFlags(LPCWSTR
* StringAcl
)
2288 LPCWSTR szAcl
= *StringAcl
;
2290 while (*szAcl
== ' ')
2293 while (*szAcl
!= ';')
2295 const ACEFLAG
*lpaf
= AceFlags
;
2297 while (lpaf
->wstr
&&
2298 (len
= strlenW(lpaf
->wstr
)) &&
2299 strncmpW(lpaf
->wstr
, szAcl
, len
))
2305 flags
|= lpaf
->value
;
2314 /******************************************************************************
2315 * ParseAceStringRights
2317 static const ACEFLAG AceRights
[] =
2319 { SDDL_GENERIC_ALL
, GENERIC_ALL
},
2320 { SDDL_GENERIC_READ
, GENERIC_READ
},
2321 { SDDL_GENERIC_WRITE
, GENERIC_WRITE
},
2322 { SDDL_GENERIC_EXECUTE
, GENERIC_EXECUTE
},
2324 { SDDL_READ_CONTROL
, READ_CONTROL
},
2325 { SDDL_STANDARD_DELETE
, DELETE
},
2326 { SDDL_WRITE_DAC
, WRITE_DAC
},
2327 { SDDL_WRITE_OWNER
, WRITE_OWNER
},
2329 { SDDL_READ_PROPERTY
, ADS_RIGHT_DS_READ_PROP
},
2330 { SDDL_WRITE_PROPERTY
, ADS_RIGHT_DS_WRITE_PROP
},
2331 { SDDL_CREATE_CHILD
, ADS_RIGHT_DS_CREATE_CHILD
},
2332 { SDDL_DELETE_CHILD
, ADS_RIGHT_DS_DELETE_CHILD
},
2333 { SDDL_LIST_CHILDREN
, ADS_RIGHT_ACTRL_DS_LIST
},
2334 { SDDL_SELF_WRITE
, ADS_RIGHT_DS_SELF
},
2335 { SDDL_LIST_OBJECT
, ADS_RIGHT_DS_LIST_OBJECT
},
2336 { SDDL_DELETE_TREE
, ADS_RIGHT_DS_DELETE_TREE
},
2337 { SDDL_CONTROL_ACCESS
, ADS_RIGHT_DS_CONTROL_ACCESS
},
2339 { SDDL_FILE_ALL
, FILE_ALL_ACCESS
},
2340 { SDDL_FILE_READ
, FILE_GENERIC_READ
},
2341 { SDDL_FILE_WRITE
, FILE_GENERIC_WRITE
},
2342 { SDDL_FILE_EXECUTE
, FILE_GENERIC_EXECUTE
},
2344 { SDDL_KEY_ALL
, KEY_ALL_ACCESS
},
2345 { SDDL_KEY_READ
, KEY_READ
},
2346 { SDDL_KEY_WRITE
, KEY_WRITE
},
2347 { SDDL_KEY_EXECUTE
, KEY_EXECUTE
},
2351 static DWORD
ParseAceStringRights(LPCWSTR
* StringAcl
)
2355 LPCWSTR szAcl
= *StringAcl
;
2357 while (*szAcl
== ' ')
2360 if ((*szAcl
== '0') && (*(szAcl
+ 1) == 'x'))
2364 while (*p
&& *p
!= ';')
2367 if (p
- szAcl
<= 10 /* 8 hex digits + "0x" */ )
2369 rights
= strtoulW(szAcl
, NULL
, 16);
2373 WARN("Invalid rights string format: %s\n", debugstr_wn(szAcl
, p
- szAcl
));
2377 while (*szAcl
!= ';')
2379 const ACEFLAG
*lpaf
= AceRights
;
2381 while (lpaf
->wstr
&&
2382 (len
= strlenW(lpaf
->wstr
)) &&
2383 strncmpW(lpaf
->wstr
, szAcl
, len
))
2391 rights
|= lpaf
->value
;
2401 /******************************************************************************
2402 * ParseStringAclToAcl
2404 * dacl_flags(string_ace1)(string_ace2)... (string_acen)
2406 static BOOL
ParseStringAclToAcl(LPCWSTR StringAcl
, LPDWORD lpdwFlags
,
2407 PACL pAcl
, LPDWORD cBytes
)
2411 DWORD length
= sizeof(ACL
);
2414 PACCESS_ALLOWED_ACE pAce
= NULL
; /* pointer to current ACE */
2415 DWORD error
= ERROR_INVALID_ACL
;
2417 TRACE("%s\n", debugstr_w(StringAcl
));
2422 if (pAcl
) /* pAce is only useful if we're setting values */
2423 pAce
= (PACCESS_ALLOWED_ACE
) (pAcl
+ 1);
2425 /* Parse ACL flags */
2426 *lpdwFlags
= ParseAclStringFlags(&StringAcl
);
2429 while (*StringAcl
== '(')
2433 /* Parse ACE type */
2434 val
= ParseAceStringType(&StringAcl
);
2436 pAce
->Header
.AceType
= (BYTE
) val
;
2437 if (*StringAcl
!= ';')
2439 error
= RPC_S_INVALID_STRING_UUID
;
2444 /* Parse ACE flags */
2445 val
= ParseAceStringFlags(&StringAcl
);
2447 pAce
->Header
.AceFlags
= (BYTE
) val
;
2448 if (*StringAcl
!= ';')
2452 /* Parse ACE rights */
2453 val
= ParseAceStringRights(&StringAcl
);
2456 if (*StringAcl
!= ';')
2460 /* Parse ACE object guid */
2461 while (*StringAcl
== ' ')
2463 if (*StringAcl
!= ';')
2465 FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
2470 /* Parse ACE inherit object guid */
2471 while (*StringAcl
== ' ')
2473 if (*StringAcl
!= ';')
2475 FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
2480 /* Parse ACE account sid */
2481 if (ParseStringSidToSid(StringAcl
, pAce
? &pAce
->SidStart
: NULL
, &sidlen
))
2483 while (*StringAcl
&& *StringAcl
!= ')')
2487 if (*StringAcl
!= ')')
2491 acesize
= sizeof(ACCESS_ALLOWED_ACE
) - sizeof(DWORD
) + sidlen
;
2495 pAce
->Header
.AceSize
= acesize
;
2496 pAce
= (PACCESS_ALLOWED_ACE
)((LPBYTE
)pAce
+ acesize
);
2503 if (length
> 0xffff)
2505 ERR("ACL too large\n");
2511 pAcl
->AclRevision
= ACL_REVISION
;
2513 pAcl
->AclSize
= length
;
2514 pAcl
->AceCount
= acecount
++;
2520 SetLastError(error
);
2521 WARN("Invalid ACE string format\n");
2526 /******************************************************************************
2527 * ParseStringSecurityDescriptorToSecurityDescriptor
2529 static BOOL
ParseStringSecurityDescriptorToSecurityDescriptor(
2530 LPCWSTR StringSecurityDescriptor
,
2531 SECURITY_DESCRIPTOR_RELATIVE
* SecurityDescriptor
,
2536 WCHAR tok
[MAX_PATH
];
2538 LPBYTE lpNext
= NULL
;
2541 *cBytes
= sizeof(SECURITY_DESCRIPTOR
);
2543 if (SecurityDescriptor
)
2544 lpNext
= (LPBYTE
)(SecurityDescriptor
+ 1);
2546 while (*StringSecurityDescriptor
== ' ')
2547 StringSecurityDescriptor
++;
2549 while (*StringSecurityDescriptor
)
2551 toktype
= *StringSecurityDescriptor
;
2553 /* Expect char identifier followed by ':' */
2554 StringSecurityDescriptor
++;
2555 if (*StringSecurityDescriptor
!= ':')
2557 SetLastError(ERROR_INVALID_PARAMETER
);
2560 StringSecurityDescriptor
++;
2563 lptoken
= StringSecurityDescriptor
;
2564 while (*lptoken
&& *lptoken
!= ':')
2570 len
= lptoken
- StringSecurityDescriptor
;
2571 memcpy( tok
, StringSecurityDescriptor
, len
* sizeof(WCHAR
) );
2580 if (!ParseStringSidToSid(tok
, lpNext
, &bytes
))
2583 if (SecurityDescriptor
)
2585 SecurityDescriptor
->Owner
= lpNext
- (LPBYTE
)SecurityDescriptor
;
2586 lpNext
+= bytes
; /* Advance to next token */
2598 if (!ParseStringSidToSid(tok
, lpNext
, &bytes
))
2601 if (SecurityDescriptor
)
2603 SecurityDescriptor
->Group
= lpNext
- (LPBYTE
)SecurityDescriptor
;
2604 lpNext
+= bytes
; /* Advance to next token */
2617 if (!ParseStringAclToAcl(tok
, &flags
, (PACL
)lpNext
, &bytes
))
2620 if (SecurityDescriptor
)
2622 SecurityDescriptor
->Control
|= SE_DACL_PRESENT
| flags
;
2623 SecurityDescriptor
->Dacl
= lpNext
- (LPBYTE
)SecurityDescriptor
;
2624 lpNext
+= bytes
; /* Advance to next token */
2637 if (!ParseStringAclToAcl(tok
, &flags
, (PACL
)lpNext
, &bytes
))
2640 if (SecurityDescriptor
)
2642 SecurityDescriptor
->Control
|= SE_SACL_PRESENT
| flags
;
2643 SecurityDescriptor
->Sacl
= lpNext
- (LPBYTE
)SecurityDescriptor
;
2644 lpNext
+= bytes
; /* Advance to next token */
2653 FIXME("Unknown token\n");
2654 SetLastError(ERROR_INVALID_PARAMETER
);
2658 StringSecurityDescriptor
= lptoken
;
2667 /* Winehq cvs 20050916 */
2668 /******************************************************************************
2669 * ConvertStringSecurityDescriptorToSecurityDescriptorA [ADVAPI32.@]
2674 ConvertStringSecurityDescriptorToSecurityDescriptorA(LPCSTR StringSecurityDescriptor
,
2675 DWORD StringSDRevision
,
2676 PSECURITY_DESCRIPTOR
* SecurityDescriptor
,
2677 PULONG SecurityDescriptorSize
)
2681 LPWSTR StringSecurityDescriptorW
;
2683 len
= MultiByteToWideChar(CP_ACP
, 0, StringSecurityDescriptor
, -1, NULL
, 0);
2684 StringSecurityDescriptorW
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
2686 if (StringSecurityDescriptorW
)
2688 MultiByteToWideChar(CP_ACP
, 0, StringSecurityDescriptor
, -1, StringSecurityDescriptorW
, len
);
2690 ret
= ConvertStringSecurityDescriptorToSecurityDescriptorW(StringSecurityDescriptorW
,
2691 StringSDRevision
, SecurityDescriptor
,
2692 SecurityDescriptorSize
);
2693 HeapFree(GetProcessHeap(), 0, StringSecurityDescriptorW
);
2699 /******************************************************************************
2700 * ConvertStringSecurityDescriptorToSecurityDescriptorW [ADVAPI32.@]
2704 ConvertStringSecurityDescriptorToSecurityDescriptorW(LPCWSTR StringSecurityDescriptor
,
2705 DWORD StringSDRevision
,
2706 PSECURITY_DESCRIPTOR
* SecurityDescriptor
,
2707 PULONG SecurityDescriptorSize
)
2710 SECURITY_DESCRIPTOR
* psd
;
2713 TRACE("%s\n", debugstr_w(StringSecurityDescriptor
));
2715 if (GetVersion() & 0x80000000)
2717 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
2720 else if (!StringSecurityDescriptor
|| !SecurityDescriptor
)
2722 SetLastError(ERROR_INVALID_PARAMETER
);
2725 else if (StringSDRevision
!= SID_REVISION
)
2727 SetLastError(ERROR_UNKNOWN_REVISION
);
2731 /* Compute security descriptor length */
2732 if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor
,
2736 psd
= *SecurityDescriptor
= LocalAlloc(GMEM_ZEROINIT
, cBytes
);
2737 if (!psd
) goto lend
;
2739 psd
->Revision
= SID_REVISION
;
2740 psd
->Control
|= SE_SELF_RELATIVE
;
2742 if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor
,
2743 (SECURITY_DESCRIPTOR_RELATIVE
*)psd
, &cBytes
))
2749 if (SecurityDescriptorSize
)
2750 *SecurityDescriptorSize
= cBytes
;
2755 TRACE(" ret=%d\n", bret
);
2759 static void DumpString(LPCWSTR string
, int cch
, WCHAR
**pwptr
, ULONG
*plen
)
2762 cch
= strlenW(string
);
2769 memcpy(*pwptr
, string
, sizeof(WCHAR
)*cch
);
2774 static BOOL
DumpSidNumeric(PSID psid
, WCHAR
**pwptr
, ULONG
*plen
)
2777 WCHAR fmt
[] = { 'S','-','%','u','-','%','d',0 };
2778 WCHAR subauthfmt
[] = { '-','%','u',0 };
2782 if( !IsValidSid( psid
) || pisid
->Revision
!= SDDL_REVISION
)
2784 SetLastError(ERROR_INVALID_SID
);
2788 if (pisid
->IdentifierAuthority
.Value
[0] ||
2789 pisid
->IdentifierAuthority
.Value
[1])
2791 FIXME("not matching MS' bugs\n");
2792 SetLastError(ERROR_INVALID_SID
);
2796 sprintfW( buf
, fmt
, pisid
->Revision
,
2798 MAKEWORD( pisid
->IdentifierAuthority
.Value
[5],
2799 pisid
->IdentifierAuthority
.Value
[4] ),
2800 MAKEWORD( pisid
->IdentifierAuthority
.Value
[3],
2801 pisid
->IdentifierAuthority
.Value
[2] )
2803 DumpString(buf
, -1, pwptr
, plen
);
2805 for( i
=0; i
<pisid
->SubAuthorityCount
; i
++ )
2807 sprintfW( buf
, subauthfmt
, pisid
->SubAuthority
[i
] );
2808 DumpString(buf
, -1, pwptr
, plen
);
2813 static BOOL
DumpSid(PSID psid
, WCHAR
**pwptr
, ULONG
*plen
)
2816 for (i
= 0; i
< sizeof(WellKnownSids
) / sizeof(WellKnownSids
[0]); i
++)
2818 if (WellKnownSids
[i
].wstr
[0] && EqualSid(psid
, (PSID
)&(WellKnownSids
[i
].Sid
.Revision
)))
2820 DumpString(WellKnownSids
[i
].wstr
, 2, pwptr
, plen
);
2825 return DumpSidNumeric(psid
, pwptr
, plen
);
2828 static const LPCWSTR AceRightBitNames
[32] = {
2829 SDDL_CREATE_CHILD
, /* 0 */
2833 SDDL_READ_PROPERTY
, /* 4 */
2834 SDDL_WRITE_PROPERTY
,
2837 SDDL_CONTROL_ACCESS
, /* 8 */
2845 SDDL_STANDARD_DELETE
, /* 16 */
2857 SDDL_GENERIC_ALL
, /* 28 */
2858 SDDL_GENERIC_EXECUTE
,
2863 static void DumpRights(DWORD mask
, WCHAR
**pwptr
, ULONG
*plen
)
2865 static const WCHAR fmtW
[] = {'0','x','%','x',0};
2872 /* first check if the right have name */
2873 for (i
= 0; i
< sizeof(AceRights
)/sizeof(AceRights
[0]); i
++)
2875 if (AceRights
[i
].wstr
== NULL
)
2877 if (mask
== AceRights
[i
].value
)
2879 DumpString(AceRights
[i
].wstr
, -1, pwptr
, plen
);
2884 /* then check if it can be built from bit names */
2885 for (i
= 0; i
< 32; i
++)
2887 if ((mask
& (1 << i
)) && (AceRightBitNames
[i
] == NULL
))
2889 /* can't be built from bit names */
2890 sprintfW(buf
, fmtW
, mask
);
2891 DumpString(buf
, -1, pwptr
, plen
);
2896 /* build from bit names */
2897 for (i
= 0; i
< 32; i
++)
2898 if (mask
& (1 << i
))
2899 DumpString(AceRightBitNames
[i
], -1, pwptr
, plen
);
2902 static BOOL
DumpAce(LPVOID pace
, WCHAR
**pwptr
, ULONG
*plen
)
2904 ACCESS_ALLOWED_ACE
*piace
; /* all the supported ACEs have the same memory layout */
2905 static const WCHAR openbr
= '(';
2906 static const WCHAR closebr
= ')';
2907 static const WCHAR semicolon
= ';';
2909 if (((PACE_HEADER
)pace
)->AceType
> SYSTEM_ALARM_ACE_TYPE
|| ((PACE_HEADER
)pace
)->AceSize
< sizeof(ACCESS_ALLOWED_ACE
))
2911 SetLastError(ERROR_INVALID_ACL
);
2916 DumpString(&openbr
, 1, pwptr
, plen
);
2917 switch (piace
->Header
.AceType
)
2919 case ACCESS_ALLOWED_ACE_TYPE
:
2920 DumpString(SDDL_ACCESS_ALLOWED
, -1, pwptr
, plen
);
2922 case ACCESS_DENIED_ACE_TYPE
:
2923 DumpString(SDDL_ACCESS_DENIED
, -1, pwptr
, plen
);
2925 case SYSTEM_AUDIT_ACE_TYPE
:
2926 DumpString(SDDL_AUDIT
, -1, pwptr
, plen
);
2928 case SYSTEM_ALARM_ACE_TYPE
:
2929 DumpString(SDDL_ALARM
, -1, pwptr
, plen
);
2932 DumpString(&semicolon
, 1, pwptr
, plen
);
2934 if (piace
->Header
.AceFlags
& OBJECT_INHERIT_ACE
)
2935 DumpString(SDDL_OBJECT_INHERIT
, -1, pwptr
, plen
);
2936 if (piace
->Header
.AceFlags
& CONTAINER_INHERIT_ACE
)
2937 DumpString(SDDL_CONTAINER_INHERIT
, -1, pwptr
, plen
);
2938 if (piace
->Header
.AceFlags
& NO_PROPAGATE_INHERIT_ACE
)
2939 DumpString(SDDL_NO_PROPAGATE
, -1, pwptr
, plen
);
2940 if (piace
->Header
.AceFlags
& INHERIT_ONLY_ACE
)
2941 DumpString(SDDL_INHERIT_ONLY
, -1, pwptr
, plen
);
2942 if (piace
->Header
.AceFlags
& INHERITED_ACE
)
2943 DumpString(SDDL_INHERITED
, -1, pwptr
, plen
);
2944 if (piace
->Header
.AceFlags
& SUCCESSFUL_ACCESS_ACE_FLAG
)
2945 DumpString(SDDL_AUDIT_SUCCESS
, -1, pwptr
, plen
);
2946 if (piace
->Header
.AceFlags
& FAILED_ACCESS_ACE_FLAG
)
2947 DumpString(SDDL_AUDIT_FAILURE
, -1, pwptr
, plen
);
2948 DumpString(&semicolon
, 1, pwptr
, plen
);
2949 DumpRights(piace
->Mask
, pwptr
, plen
);
2950 DumpString(&semicolon
, 1, pwptr
, plen
);
2951 /* objects not supported */
2952 DumpString(&semicolon
, 1, pwptr
, plen
);
2953 /* objects not supported */
2954 DumpString(&semicolon
, 1, pwptr
, plen
);
2955 if (!DumpSid((PSID
)&piace
->SidStart
, pwptr
, plen
))
2957 DumpString(&closebr
, 1, pwptr
, plen
);
2961 static BOOL
DumpAcl(PACL pacl
, WCHAR
**pwptr
, ULONG
*plen
, BOOL
protected, BOOL autoInheritReq
, BOOL autoInherited
)
2967 DumpString(SDDL_PROTECTED
, -1, pwptr
, plen
);
2969 DumpString(SDDL_AUTO_INHERIT_REQ
, -1, pwptr
, plen
);
2971 DumpString(SDDL_AUTO_INHERITED
, -1, pwptr
, plen
);
2976 if (!IsValidAcl(pacl
))
2979 count
= pacl
->AceCount
;
2980 for (i
= 0; i
< count
; i
++)
2983 if (!GetAce(pacl
, i
, &ace
))
2985 if (!DumpAce(ace
, pwptr
, plen
))
2992 static BOOL
DumpOwner(PSECURITY_DESCRIPTOR SecurityDescriptor
, WCHAR
**pwptr
, ULONG
*plen
)
2994 static const WCHAR prefix
[] = {'O',':',0};
2998 if (!GetSecurityDescriptorOwner(SecurityDescriptor
, &psid
, &bDefaulted
))
3004 DumpString(prefix
, -1, pwptr
, plen
);
3005 if (!DumpSid(psid
, pwptr
, plen
))
3010 static BOOL
DumpGroup(PSECURITY_DESCRIPTOR SecurityDescriptor
, WCHAR
**pwptr
, ULONG
*plen
)
3012 static const WCHAR prefix
[] = {'G',':',0};
3016 if (!GetSecurityDescriptorGroup(SecurityDescriptor
, &psid
, &bDefaulted
))
3022 DumpString(prefix
, -1, pwptr
, plen
);
3023 if (!DumpSid(psid
, pwptr
, plen
))
3028 static BOOL
DumpDacl(PSECURITY_DESCRIPTOR SecurityDescriptor
, WCHAR
**pwptr
, ULONG
*plen
)
3030 static const WCHAR dacl
[] = {'D',':',0};
3031 SECURITY_DESCRIPTOR_CONTROL control
;
3032 BOOL present
, defaulted
;
3036 if (!GetSecurityDescriptorDacl(SecurityDescriptor
, &present
, &pacl
, &defaulted
))
3039 if (!GetSecurityDescriptorControl(SecurityDescriptor
, &control
, &revision
))
3045 DumpString(dacl
, 2, pwptr
, plen
);
3046 if (!DumpAcl(pacl
, pwptr
, plen
, control
& SE_DACL_PROTECTED
, control
& SE_DACL_AUTO_INHERIT_REQ
, control
& SE_DACL_AUTO_INHERITED
))
3051 static BOOL
DumpSacl(PSECURITY_DESCRIPTOR SecurityDescriptor
, WCHAR
**pwptr
, ULONG
*plen
)
3053 static const WCHAR sacl
[] = {'S',':',0};
3054 SECURITY_DESCRIPTOR_CONTROL control
;
3055 BOOL present
, defaulted
;
3059 if (!GetSecurityDescriptorSacl(SecurityDescriptor
, &present
, &pacl
, &defaulted
))
3062 if (!GetSecurityDescriptorControl(SecurityDescriptor
, &control
, &revision
))
3068 DumpString(sacl
, 2, pwptr
, plen
);
3069 if (!DumpAcl(pacl
, pwptr
, plen
, control
& SE_SACL_PROTECTED
, control
& SE_SACL_AUTO_INHERIT_REQ
, control
& SE_SACL_AUTO_INHERITED
))
3074 /******************************************************************************
3075 * ConvertSecurityDescriptorToStringSecurityDescriptorW [ADVAPI32.@]
3079 ConvertSecurityDescriptorToStringSecurityDescriptorW(PSECURITY_DESCRIPTOR SecurityDescriptor
,
3081 SECURITY_INFORMATION SecurityInformation
,
3082 LPWSTR
*OutputString
,
3088 if (SDRevision
!= SDDL_REVISION_1
)
3090 ERR("Program requested unknown SDDL revision %d\n", SDRevision
);
3091 SetLastError(ERROR_UNKNOWN_REVISION
);
3096 if (SecurityInformation
& OWNER_SECURITY_INFORMATION
)
3097 if (!DumpOwner(SecurityDescriptor
, NULL
, &len
))
3099 if (SecurityInformation
& GROUP_SECURITY_INFORMATION
)
3100 if (!DumpGroup(SecurityDescriptor
, NULL
, &len
))
3102 if (SecurityInformation
& DACL_SECURITY_INFORMATION
)
3103 if (!DumpDacl(SecurityDescriptor
, NULL
, &len
))
3105 if (SecurityInformation
& SACL_SECURITY_INFORMATION
)
3106 if (!DumpSacl(SecurityDescriptor
, NULL
, &len
))
3109 wstr
= wptr
= LocalAlloc(0, (len
+ 1)*sizeof(WCHAR
));
3113 if (SecurityInformation
& OWNER_SECURITY_INFORMATION
)
3114 if (!DumpOwner(SecurityDescriptor
, &wptr
, NULL
))
3116 if (SecurityInformation
& GROUP_SECURITY_INFORMATION
)
3117 if (!DumpGroup(SecurityDescriptor
, &wptr
, NULL
))
3119 if (SecurityInformation
& DACL_SECURITY_INFORMATION
)
3120 if (!DumpDacl(SecurityDescriptor
, &wptr
, NULL
))
3122 if (SecurityInformation
& SACL_SECURITY_INFORMATION
)
3123 if (!DumpSacl(SecurityDescriptor
, &wptr
, NULL
))
3127 TRACE("ret: %s, %d\n", wine_dbgstr_w(wstr
), len
);
3128 *OutputString
= wstr
;
3130 *OutputLen
= strlenW(*OutputString
)+1;
3134 /******************************************************************************
3135 * ConvertSecurityDescriptorToStringSecurityDescriptorA [ADVAPI32.@]
3139 ConvertSecurityDescriptorToStringSecurityDescriptorA(PSECURITY_DESCRIPTOR SecurityDescriptor
,
3141 SECURITY_INFORMATION Information
,
3142 LPSTR
*OutputString
,
3148 if (ConvertSecurityDescriptorToStringSecurityDescriptorW(SecurityDescriptor
, SDRevision
, Information
, &wstr
, &len
))
3152 lenA
= WideCharToMultiByte(CP_ACP
, 0, wstr
, len
, NULL
, 0, NULL
, NULL
);
3153 *OutputString
= HeapAlloc(GetProcessHeap(), 0, lenA
);
3154 if (*OutputString
== NULL
)
3160 WideCharToMultiByte(CP_ACP
, 0, wstr
, len
, *OutputString
, lenA
, NULL
, NULL
);
3163 if (OutputLen
!= NULL
)
3169 *OutputString
= NULL
;
3176 /******************************************************************************
3177 * ConvertStringSidToSidW [ADVAPI32.@]
3179 BOOL WINAPI
ConvertStringSidToSidW(LPCWSTR StringSid
, PSID
* Sid
)
3184 TRACE("%s, %p\n", debugstr_w(StringSid
), Sid
);
3185 if (GetVersion() & 0x80000000)
3186 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
3187 else if (!StringSid
|| !Sid
)
3188 SetLastError(ERROR_INVALID_PARAMETER
);
3189 else if (ParseStringSidToSid(StringSid
, NULL
, &cBytes
))
3191 PSID pSid
= *Sid
= LocalAlloc(0, cBytes
);
3193 bret
= ParseStringSidToSid(StringSid
, pSid
, &cBytes
);
3200 /******************************************************************************
3201 * ConvertStringSidToSidA [ADVAPI32.@]
3203 BOOL WINAPI
ConvertStringSidToSidA(LPCSTR StringSid
, PSID
* Sid
)
3207 TRACE("%s, %p\n", debugstr_a(StringSid
), Sid
);
3208 if (GetVersion() & 0x80000000)
3209 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
3210 else if (!StringSid
|| !Sid
)
3211 SetLastError(ERROR_INVALID_PARAMETER
);
3214 WCHAR
*wStringSid
= SERV_dup(StringSid
);
3215 bret
= ConvertStringSidToSidW(wStringSid
, Sid
);
3216 heap_free(wStringSid
);
3226 ConvertSidToStringSidW(PSID Sid
,
3230 UNICODE_STRING UnicodeString
;
3231 WCHAR FixedBuffer
[64];
3233 if (!RtlValidSid(Sid
))
3235 SetLastError(ERROR_INVALID_SID
);
3239 UnicodeString
.Length
= 0;
3240 UnicodeString
.MaximumLength
= sizeof(FixedBuffer
);
3241 UnicodeString
.Buffer
= FixedBuffer
;
3242 Status
= RtlConvertSidToUnicodeString(&UnicodeString
, Sid
, FALSE
);
3243 if (STATUS_BUFFER_TOO_SMALL
== Status
)
3245 Status
= RtlConvertSidToUnicodeString(&UnicodeString
, Sid
, TRUE
);
3248 if (!NT_SUCCESS(Status
))
3250 SetLastError(RtlNtStatusToDosError(Status
));
3254 *StringSid
= LocalAlloc(LMEM_FIXED
, UnicodeString
.Length
+ sizeof(WCHAR
));
3255 if (NULL
== *StringSid
)
3257 if (UnicodeString
.Buffer
!= FixedBuffer
)
3259 RtlFreeUnicodeString(&UnicodeString
);
3261 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
3265 MoveMemory(*StringSid
, UnicodeString
.Buffer
, UnicodeString
.Length
);
3266 ZeroMemory((PCHAR
) *StringSid
+ UnicodeString
.Length
, sizeof(WCHAR
));
3267 if (UnicodeString
.Buffer
!= FixedBuffer
)
3269 RtlFreeUnicodeString(&UnicodeString
);
3280 ConvertSidToStringSidA(PSID Sid
,
3286 if (!ConvertSidToStringSidW(Sid
, &StringSidW
))
3291 Len
= WideCharToMultiByte(CP_ACP
, 0, StringSidW
, -1, NULL
, 0, NULL
, NULL
);
3294 LocalFree(StringSidW
);
3295 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
3299 *StringSid
= LocalAlloc(LMEM_FIXED
, Len
);
3300 if (NULL
== *StringSid
)
3302 LocalFree(StringSidW
);
3303 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
3307 if (!WideCharToMultiByte(CP_ACP
, 0, StringSidW
, -1, *StringSid
, Len
, NULL
, NULL
))
3309 LocalFree(StringSid
);
3310 LocalFree(StringSidW
);
3314 LocalFree(StringSidW
);
3323 CreateProcessWithLogonW(LPCWSTR lpUsername
,
3327 LPCWSTR lpApplicationName
,
3328 LPWSTR lpCommandLine
,
3329 DWORD dwCreationFlags
,
3330 LPVOID lpEnvironment
,
3331 LPCWSTR lpCurrentDirectory
,
3332 LPSTARTUPINFOW lpStartupInfo
,
3333 LPPROCESS_INFORMATION lpProcessInformation
)
3335 FIXME("%s %s %s 0x%08x %s %s 0x%08x %p %s %p %p stub\n", debugstr_w(lpUsername
), debugstr_w(lpDomain
),
3336 debugstr_w(lpPassword
), dwLogonFlags
, debugstr_w(lpApplicationName
),
3337 debugstr_w(lpCommandLine
), dwCreationFlags
, lpEnvironment
, debugstr_w(lpCurrentDirectory
),
3338 lpStartupInfo
, lpProcessInformation
);
3345 CreateProcessWithTokenW(IN HANDLE hToken
,
3346 IN DWORD dwLogonFlags
,
3347 IN LPCWSTR lpApplicationName OPTIONAL
,
3348 IN OUT LPWSTR lpCommandLine OPTIONAL
,
3349 IN DWORD dwCreationFlags
,
3350 IN LPVOID lpEnvironment OPTIONAL
,
3351 IN LPCWSTR lpCurrentDirectory OPTIONAL
,
3352 IN LPSTARTUPINFOW lpStartupInfo
,
3353 OUT LPPROCESS_INFORMATION lpProcessInfo
)
3363 DuplicateTokenEx(IN HANDLE ExistingTokenHandle
,
3364 IN DWORD dwDesiredAccess
,
3365 IN LPSECURITY_ATTRIBUTES lpTokenAttributes OPTIONAL
,
3366 IN SECURITY_IMPERSONATION_LEVEL ImpersonationLevel
,
3367 IN TOKEN_TYPE TokenType
,
3368 OUT PHANDLE DuplicateTokenHandle
)
3370 OBJECT_ATTRIBUTES ObjectAttributes
;
3372 SECURITY_QUALITY_OF_SERVICE Sqos
;
3374 TRACE("%p 0x%08x 0x%08x 0x%08x %p\n", ExistingTokenHandle
, dwDesiredAccess
,
3375 ImpersonationLevel
, TokenType
, DuplicateTokenHandle
);
3377 Sqos
.Length
= sizeof(SECURITY_QUALITY_OF_SERVICE
);
3378 Sqos
.ImpersonationLevel
= ImpersonationLevel
;
3379 Sqos
.ContextTrackingMode
= 0;
3380 Sqos
.EffectiveOnly
= FALSE
;
3382 if (lpTokenAttributes
!= NULL
)
3384 InitializeObjectAttributes(&ObjectAttributes
,
3386 lpTokenAttributes
->bInheritHandle
? OBJ_INHERIT
: 0,
3388 lpTokenAttributes
->lpSecurityDescriptor
);
3392 InitializeObjectAttributes(&ObjectAttributes
,
3399 ObjectAttributes
.SecurityQualityOfService
= &Sqos
;
3401 Status
= NtDuplicateToken(ExistingTokenHandle
,
3406 DuplicateTokenHandle
);
3407 if (!NT_SUCCESS(Status
))
3409 ERR("NtDuplicateToken failed: Status %08x\n", Status
);
3410 SetLastError(RtlNtStatusToDosError(Status
));
3414 TRACE("Returning token %p.\n", *DuplicateTokenHandle
);
3423 DuplicateToken(IN HANDLE ExistingTokenHandle
,
3424 IN SECURITY_IMPERSONATION_LEVEL ImpersonationLevel
,
3425 OUT PHANDLE DuplicateTokenHandle
)
3427 return DuplicateTokenEx(ExistingTokenHandle
,
3428 TOKEN_IMPERSONATE
| TOKEN_QUERY
,
3432 DuplicateTokenHandle
);
3435 /******************************************************************************
3436 * ComputeStringSidSize
3438 static DWORD
ComputeStringSidSize(LPCWSTR StringSid
)
3440 if (StringSid
[0] == 'S' && StringSid
[1] == '-') /* S-R-I(-S)+ */
3445 if (*StringSid
== '-')
3451 return GetSidLengthRequired(ctok
- 2);
3453 else /* String constant format - Only available in winxp and above */
3457 for (i
= 0; i
< sizeof(WellKnownSids
)/sizeof(WellKnownSids
[0]); i
++)
3458 if (!strncmpW(WellKnownSids
[i
].wstr
, StringSid
, 2))
3459 return GetSidLengthRequired(WellKnownSids
[i
].Sid
.SubAuthorityCount
);
3461 for (i
= 0; i
< sizeof(WellKnownRids
)/sizeof(WellKnownRids
[0]); i
++)
3462 if (!strncmpW(WellKnownRids
[i
].wstr
, StringSid
, 2))
3465 ADVAPI_GetComputerSid(&local
);
3466 return GetSidLengthRequired(*GetSidSubAuthorityCount(&local
) + 1);
3471 return GetSidLengthRequired(0);
3474 /******************************************************************************
3475 * ParseStringSidToSid
3477 static BOOL
ParseStringSidToSid(LPCWSTR StringSid
, PSID pSid
, LPDWORD cBytes
)
3482 TRACE("%s, %p, %p\n", debugstr_w(StringSid
), pSid
, cBytes
);
3485 SetLastError(ERROR_INVALID_PARAMETER
);
3486 TRACE("StringSid is NULL, returning FALSE\n");
3490 while (*StringSid
== ' ')
3494 goto lend
; /* ERROR_INVALID_SID */
3496 *cBytes
= ComputeStringSidSize(StringSid
);
3497 if (!pisid
) /* Simply compute the size */
3499 TRACE("only size requested, returning TRUE with %d\n", *cBytes
);
3503 if (StringSid
[0] == 'S' && StringSid
[1] == '-') /* S-R-I-S-S */
3505 DWORD i
= 0, identAuth
;
3506 DWORD csubauth
= ((*cBytes
- GetSidLengthRequired(0)) / sizeof(DWORD
));
3508 StringSid
+= 2; /* Advance to Revision */
3509 pisid
->Revision
= atoiW(StringSid
);
3511 if (pisid
->Revision
!= SDDL_REVISION
)
3513 TRACE("Revision %d is unknown\n", pisid
->Revision
);
3514 goto lend
; /* ERROR_INVALID_SID */
3518 TRACE("SubAuthorityCount is 0\n");
3519 goto lend
; /* ERROR_INVALID_SID */
3522 pisid
->SubAuthorityCount
= csubauth
;
3524 /* Advance to identifier authority */
3525 while (*StringSid
&& *StringSid
!= '-')
3527 if (*StringSid
== '-')
3530 /* MS' implementation can't handle values greater than 2^32 - 1, so
3531 * we don't either; assume most significant bytes are always 0
3533 pisid
->IdentifierAuthority
.Value
[0] = 0;
3534 pisid
->IdentifierAuthority
.Value
[1] = 0;
3535 identAuth
= atoiW(StringSid
);
3536 pisid
->IdentifierAuthority
.Value
[5] = identAuth
& 0xff;
3537 pisid
->IdentifierAuthority
.Value
[4] = (identAuth
& 0xff00) >> 8;
3538 pisid
->IdentifierAuthority
.Value
[3] = (identAuth
& 0xff0000) >> 16;
3539 pisid
->IdentifierAuthority
.Value
[2] = (identAuth
& 0xff000000) >> 24;
3541 /* Advance to first sub authority */
3542 while (*StringSid
&& *StringSid
!= '-')
3544 if (*StringSid
== '-')
3549 pisid
->SubAuthority
[i
++] = atoiW(StringSid
);
3551 while (*StringSid
&& *StringSid
!= '-')
3553 if (*StringSid
== '-')
3557 if (i
!= pisid
->SubAuthorityCount
)
3558 goto lend
; /* ERROR_INVALID_SID */
3562 else /* String constant format - Only available in winxp and above */
3565 pisid
->Revision
= SDDL_REVISION
;
3567 for (i
= 0; i
< sizeof(WellKnownSids
)/sizeof(WellKnownSids
[0]); i
++)
3568 if (!strncmpW(WellKnownSids
[i
].wstr
, StringSid
, 2))
3571 pisid
->SubAuthorityCount
= WellKnownSids
[i
].Sid
.SubAuthorityCount
;
3572 pisid
->IdentifierAuthority
= WellKnownSids
[i
].Sid
.IdentifierAuthority
;
3573 for (j
= 0; j
< WellKnownSids
[i
].Sid
.SubAuthorityCount
; j
++)
3574 pisid
->SubAuthority
[j
] = WellKnownSids
[i
].Sid
.SubAuthority
[j
];
3578 for (i
= 0; i
< sizeof(WellKnownRids
)/sizeof(WellKnownRids
[0]); i
++)
3579 if (!strncmpW(WellKnownRids
[i
].wstr
, StringSid
, 2))
3581 ADVAPI_GetComputerSid(pisid
);
3582 pisid
->SubAuthority
[pisid
->SubAuthorityCount
] = WellKnownRids
[i
].Rid
;
3583 pisid
->SubAuthorityCount
++;
3588 FIXME("String constant not supported: %s\n", debugstr_wn(StringSid
, 2));
3593 SetLastError(ERROR_INVALID_SID
);
3595 TRACE("returning %s\n", bret
? "TRUE" : "FALSE");
3599 /**********************************************************************
3600 * GetNamedSecurityInfoA EXPORTED
3606 GetNamedSecurityInfoA(LPSTR pObjectName
,
3607 SE_OBJECT_TYPE ObjectType
,
3608 SECURITY_INFORMATION SecurityInfo
,
3613 PSECURITY_DESCRIPTOR
*ppSecurityDescriptor
)
3619 TRACE("%s %d %d %p %p %p %p %p\n", pObjectName
, ObjectType
, SecurityInfo
,
3620 ppsidOwner
, ppsidGroup
, ppDacl
, ppSacl
, ppSecurityDescriptor
);
3624 len
= MultiByteToWideChar( CP_ACP
, 0, pObjectName
, -1, NULL
, 0 );
3625 wstr
= HeapAlloc( GetProcessHeap(), 0, len
*sizeof(WCHAR
));
3626 MultiByteToWideChar( CP_ACP
, 0, pObjectName
, -1, wstr
, len
);
3629 r
= GetNamedSecurityInfoW( wstr
, ObjectType
, SecurityInfo
, ppsidOwner
,
3630 ppsidGroup
, ppDacl
, ppSacl
, ppSecurityDescriptor
);
3632 HeapFree( GetProcessHeap(), 0, wstr
);
3642 GetWindowsAccountDomainSid(IN PSID pSid
,
3643 OUT PSID ppDomainSid
,
3644 IN OUT DWORD
* cbSid
)
3655 EqualDomainSid(IN PSID pSid1
,