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 { {'D','A'}, WinAccountDomainAdminsSid
, DOMAIN_GROUP_RID_ADMINS
},
112 { {'D','U'}, WinAccountDomainUsersSid
, DOMAIN_GROUP_RID_USERS
},
113 { {'D','G'}, WinAccountDomainGuestsSid
, DOMAIN_GROUP_RID_GUESTS
},
114 { {'D','C'}, WinAccountComputersSid
, DOMAIN_GROUP_RID_COMPUTERS
},
115 { {'D','D'}, WinAccountControllersSid
, DOMAIN_GROUP_RID_CONTROLLERS
},
116 { {'C','A'}, WinAccountCertAdminsSid
, DOMAIN_GROUP_RID_CERT_ADMINS
},
117 { {'S','A'}, WinAccountSchemaAdminsSid
, DOMAIN_GROUP_RID_SCHEMA_ADMINS
},
118 { {'E','A'}, WinAccountEnterpriseAdminsSid
, DOMAIN_GROUP_RID_ENTERPRISE_ADMINS
},
119 { {'P','A'}, WinAccountPolicyAdminsSid
, DOMAIN_GROUP_RID_POLICY_ADMINS
},
120 { {'R','S'}, WinAccountRasAndIasServersSid
, DOMAIN_ALIAS_RID_RAS_SERVERS
},
123 static const SID sidWorld
= { SID_REVISION
, 1, { SECURITY_WORLD_SID_AUTHORITY
} , { SECURITY_WORLD_RID
} };
125 static const WCHAR SDDL_NO_READ_UP
[] = {'N','R',0};
126 static const WCHAR SDDL_NO_WRITE_UP
[] = {'N','W',0};
127 static const WCHAR SDDL_NO_EXECUTE_UP
[] = {'N','X',0};
132 static const WCHAR SDDL_ACCESS_ALLOWED
[] = {'A',0};
133 static const WCHAR SDDL_ACCESS_DENIED
[] = {'D',0};
134 static const WCHAR SDDL_OBJECT_ACCESS_ALLOWED
[] = {'O','A',0};
135 static const WCHAR SDDL_OBJECT_ACCESS_DENIED
[] = {'O','D',0};
136 static const WCHAR SDDL_AUDIT
[] = {'A','U',0};
137 static const WCHAR SDDL_ALARM
[] = {'A','L',0};
138 static const WCHAR SDDL_MANDATORY_LABEL
[] = {'M','L',0};
139 static const WCHAR SDDL_OBJECT_AUDIT
[] = {'O','U',0};
140 static const WCHAR SDDL_OBJECT_ALARM
[] = {'O','L',0};
145 #define ADS_RIGHT_DS_CREATE_CHILD 0x0001
146 #define ADS_RIGHT_DS_DELETE_CHILD 0x0002
147 #define ADS_RIGHT_ACTRL_DS_LIST 0x0004
148 #define ADS_RIGHT_DS_SELF 0x0008
149 #define ADS_RIGHT_DS_READ_PROP 0x0010
150 #define ADS_RIGHT_DS_WRITE_PROP 0x0020
151 #define ADS_RIGHT_DS_DELETE_TREE 0x0040
152 #define ADS_RIGHT_DS_LIST_OBJECT 0x0080
153 #define ADS_RIGHT_DS_CONTROL_ACCESS 0x0100
158 static const WCHAR SDDL_CONTAINER_INHERIT
[] = {'C','I',0};
159 static const WCHAR SDDL_OBJECT_INHERIT
[] = {'O','I',0};
160 static const WCHAR SDDL_NO_PROPAGATE
[] = {'N','P',0};
161 static const WCHAR SDDL_INHERIT_ONLY
[] = {'I','O',0};
162 static const WCHAR SDDL_INHERITED
[] = {'I','D',0};
163 static const WCHAR SDDL_AUDIT_SUCCESS
[] = {'S','A',0};
164 static const WCHAR SDDL_AUDIT_FAILURE
[] = {'F','A',0};
166 static const char * debugstr_sid(PSID sid
)
169 SID
* psid
= (SID
*)sid
;
174 auth
= psid
->IdentifierAuthority
.Value
[5] +
175 (psid
->IdentifierAuthority
.Value
[4] << 8) +
176 (psid
->IdentifierAuthority
.Value
[3] << 16) +
177 (psid
->IdentifierAuthority
.Value
[2] << 24);
179 switch (psid
->SubAuthorityCount
) {
181 return wine_dbg_sprintf("S-%d-%d", psid
->Revision
, auth
);
183 return wine_dbg_sprintf("S-%d-%d-%lu", psid
->Revision
, auth
,
184 psid
->SubAuthority
[0]);
186 return wine_dbg_sprintf("S-%d-%d-%lu-%lu", psid
->Revision
, auth
,
187 psid
->SubAuthority
[0], psid
->SubAuthority
[1]);
189 return wine_dbg_sprintf("S-%d-%d-%lu-%lu-%lu", psid
->Revision
, auth
,
190 psid
->SubAuthority
[0], psid
->SubAuthority
[1], psid
->SubAuthority
[2]);
192 return wine_dbg_sprintf("S-%d-%d-%lu-%lu-%lu-%lu", psid
->Revision
, auth
,
193 psid
->SubAuthority
[0], psid
->SubAuthority
[1], psid
->SubAuthority
[2],
194 psid
->SubAuthority
[3]);
196 return wine_dbg_sprintf("S-%d-%d-%lu-%lu-%lu-%lu-%lu", psid
->Revision
, auth
,
197 psid
->SubAuthority
[0], psid
->SubAuthority
[1], psid
->SubAuthority
[2],
198 psid
->SubAuthority
[3], psid
->SubAuthority
[4]);
200 return wine_dbg_sprintf("S-%d-%d-%lu-%lu-%lu-%lu-%lu-%lu", psid
->Revision
, auth
,
201 psid
->SubAuthority
[3], psid
->SubAuthority
[1], psid
->SubAuthority
[2],
202 psid
->SubAuthority
[0], psid
->SubAuthority
[4], psid
->SubAuthority
[5]);
204 return wine_dbg_sprintf("S-%d-%d-%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]);
209 return wine_dbg_sprintf("S-%d-%d-%lu-%lu-%lu-%lu-%lu-%lu-%lu-%lu", psid
->Revision
, auth
,
210 psid
->SubAuthority
[0], psid
->SubAuthority
[1], psid
->SubAuthority
[2],
211 psid
->SubAuthority
[3], psid
->SubAuthority
[4], psid
->SubAuthority
[5],
212 psid
->SubAuthority
[6], psid
->SubAuthority
[7]);
217 /* set last error code from NT status and get the proper boolean return value */
218 /* used for functions that are a simple wrapper around the corresponding ntdll API */
219 static __inline BOOL
set_ntstatus( NTSTATUS status
)
221 if (!NT_SUCCESS(status
)) SetLastError( RtlNtStatusToDosError( status
));
222 return NT_SUCCESS(status
);
225 static LPWSTR
SERV_dup( LPCSTR str
)
232 len
= MultiByteToWideChar( CP_ACP
, 0, str
, -1, NULL
, 0 );
233 wstr
= heap_alloc( len
*sizeof (WCHAR
) );
234 MultiByteToWideChar( CP_ACP
, 0, str
, -1, wstr
, len
);
238 /************************************************************
239 * ADVAPI_IsLocalComputer
241 * Checks whether the server name indicates local machine.
243 BOOL
ADVAPI_IsLocalComputer(LPCWSTR ServerName
)
245 DWORD dwSize
= MAX_COMPUTERNAME_LENGTH
+ 1;
249 if (!ServerName
|| !ServerName
[0])
252 buf
= heap_alloc(dwSize
* sizeof(WCHAR
));
253 Result
= GetComputerNameW(buf
, &dwSize
);
254 if (Result
&& (ServerName
[0] == '\\') && (ServerName
[1] == '\\'))
256 Result
= Result
&& !lstrcmpW(ServerName
, buf
);
262 /************************************************************
263 * ADVAPI_GetComputerSid
265 BOOL
ADVAPI_GetComputerSid(PSID sid
)
267 static const struct /* same fields as struct SID */
270 BYTE SubAuthorityCount
;
271 SID_IDENTIFIER_AUTHORITY IdentifierAuthority
;
272 DWORD SubAuthority
[4];
274 { SID_REVISION
, 4, { SECURITY_NT_AUTHORITY
}, { SECURITY_NT_NON_UNIQUE
, 0, 0, 0 } };
276 memcpy( sid
, &computer_sid
, sizeof(computer_sid
) );
280 /* Exported functions */
286 OpenProcessToken(HANDLE ProcessHandle
,
292 TRACE("%p, %x, %p.\n", ProcessHandle
, DesiredAccess
, TokenHandle
);
294 Status
= NtOpenProcessToken(ProcessHandle
,
297 if (!NT_SUCCESS(Status
))
299 ERR("NtOpenProcessToken failed! Status %08x.\n", Status
);
300 SetLastError(RtlNtStatusToDosError(Status
));
304 TRACE("Returning token %p.\n", *TokenHandle
);
309 /******************************************************************************
310 * OpenThreadToken [ADVAPI32.@]
312 * Opens the access token associated with a thread handle.
315 * ThreadHandle [I] Handle to process
316 * DesiredAccess [I] Desired access to the thread
318 * TokenHandle [O] Destination for the token handle
321 * Success: TRUE. TokenHandle contains the access token.
325 * See NtOpenThreadToken.
328 OpenThreadToken( HANDLE ThreadHandle
, DWORD DesiredAccess
,
329 BOOL OpenAsSelf
, HANDLE
*TokenHandle
)
331 return set_ntstatus( NtOpenThreadToken(ThreadHandle
, DesiredAccess
, OpenAsSelf
, TokenHandle
));
338 AdjustTokenGroups(HANDLE TokenHandle
,
340 PTOKEN_GROUPS NewState
,
342 PTOKEN_GROUPS PreviousState
,
347 Status
= NtAdjustGroupsToken(TokenHandle
,
352 (PULONG
)ReturnLength
);
353 if (!NT_SUCCESS(Status
))
355 SetLastError(RtlNtStatusToDosError(Status
));
366 AdjustTokenPrivileges(HANDLE TokenHandle
,
367 BOOL DisableAllPrivileges
,
368 PTOKEN_PRIVILEGES NewState
,
370 PTOKEN_PRIVILEGES PreviousState
,
375 Status
= NtAdjustPrivilegesToken(TokenHandle
,
376 DisableAllPrivileges
,
380 (PULONG
)ReturnLength
);
381 if (STATUS_NOT_ALL_ASSIGNED
== Status
)
383 SetLastError(ERROR_NOT_ALL_ASSIGNED
);
387 if (!NT_SUCCESS(Status
))
389 SetLastError(RtlNtStatusToDosError(Status
));
393 /* AdjustTokenPrivileges is documented to do this */
394 SetLastError(ERROR_SUCCESS
);
403 GetTokenInformation(HANDLE TokenHandle
,
404 TOKEN_INFORMATION_CLASS TokenInformationClass
,
405 LPVOID TokenInformation
,
406 DWORD TokenInformationLength
,
411 Status
= NtQueryInformationToken(TokenHandle
,
412 TokenInformationClass
,
414 TokenInformationLength
,
415 (PULONG
)ReturnLength
);
416 if (!NT_SUCCESS(Status
))
418 SetLastError(RtlNtStatusToDosError(Status
));
429 SetTokenInformation(HANDLE TokenHandle
,
430 TOKEN_INFORMATION_CLASS TokenInformationClass
,
431 LPVOID TokenInformation
,
432 DWORD TokenInformationLength
)
436 Status
= NtSetInformationToken(TokenHandle
,
437 TokenInformationClass
,
439 TokenInformationLength
);
440 if (!NT_SUCCESS(Status
))
442 SetLastError(RtlNtStatusToDosError(Status
));
453 SetThreadToken(IN PHANDLE ThreadHandle OPTIONAL
,
454 IN HANDLE TokenHandle
)
459 hThread
= (ThreadHandle
!= NULL
) ? *ThreadHandle
: NtCurrentThread();
461 Status
= NtSetInformationThread(hThread
,
462 ThreadImpersonationToken
,
465 if (!NT_SUCCESS(Status
))
467 SetLastError(RtlNtStatusToDosError(Status
));
474 /*************************************************************************
475 * CreateRestrictedToken [ADVAPI32.@]
477 * Create a new more restricted token from an existing token.
480 * baseToken [I] Token to base the new restricted token on
482 * nDisableSids [I] Length of disableSids array
483 * disableSids [I] Array of SIDs to disable in the new token
484 * nDeletePrivs [I] Length of deletePrivs array
485 * deletePrivs [I] Array of privileges to delete in the new token
486 * nRestrictSids [I] Length of restrictSids array
487 * restrictSids [I] Array of SIDs to restrict in the new token
488 * newToken [O] Address where the new token is stored
494 BOOL WINAPI
CreateRestrictedToken(
498 PSID_AND_ATTRIBUTES disableSids
,
500 PLUID_AND_ATTRIBUTES deletePrivs
,
502 PSID_AND_ATTRIBUTES restrictSids
,
506 SECURITY_IMPERSONATION_LEVEL level
= SecurityAnonymous
;
509 FIXME("(%p, 0x%x, %u, %p, %u, %p, %u, %p, %p): stub\n",
510 baseToken
, flags
, nDisableSids
, disableSids
,
511 nDeletePrivs
, deletePrivs
,
512 nRestrictSids
, restrictSids
,
516 if (!GetTokenInformation( baseToken
, TokenType
, &type
, size
, &size
)) return FALSE
;
517 if (type
== TokenImpersonation
)
519 size
= sizeof(level
);
520 if (!GetTokenInformation( baseToken
, TokenImpersonationLevel
, &level
, size
, &size
))
523 return DuplicateTokenEx( baseToken
, MAXIMUM_ALLOWED
, NULL
, level
, type
, newToken
);
526 /******************************************************************************
527 * AllocateAndInitializeSid [ADVAPI32.@]
530 * pIdentifierAuthority []
531 * nSubAuthorityCount []
543 AllocateAndInitializeSid( PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority
,
544 BYTE nSubAuthorityCount
,
545 DWORD nSubAuthority0
, DWORD nSubAuthority1
,
546 DWORD nSubAuthority2
, DWORD nSubAuthority3
,
547 DWORD nSubAuthority4
, DWORD nSubAuthority5
,
548 DWORD nSubAuthority6
, DWORD nSubAuthority7
,
551 return set_ntstatus( RtlAllocateAndInitializeSid(
552 pIdentifierAuthority
, nSubAuthorityCount
,
553 nSubAuthority0
, nSubAuthority1
, nSubAuthority2
, nSubAuthority3
,
554 nSubAuthority4
, nSubAuthority5
, nSubAuthority6
, nSubAuthority7
,
562 * Docs says this function does NOT return a value
563 * even thou it's defined to return a PVOID...
569 return RtlFreeSid(pSid
);
572 /******************************************************************************
573 * CopySid [ADVAPI32.@]
576 * nDestinationSidLength []
581 CopySid( DWORD nDestinationSidLength
, PSID pDestinationSid
, PSID pSourceSid
)
583 return set_ntstatus(RtlCopySid(nDestinationSidLength
, pDestinationSid
, pSourceSid
));
591 CreateWellKnownSid(IN WELL_KNOWN_SID_TYPE WellKnownSidType
,
592 IN PSID DomainSid OPTIONAL
,
597 TRACE("(%d, %s, %p, %p)\n", WellKnownSidType
, debugstr_sid(DomainSid
), pSid
, cbSid
);
599 if (cbSid
== NULL
|| (DomainSid
&& !IsValidSid(DomainSid
)))
601 SetLastError(ERROR_INVALID_PARAMETER
);
605 for (i
= 0; i
< sizeof(WellKnownSids
)/sizeof(WellKnownSids
[0]); i
++) {
606 if (WellKnownSids
[i
].Type
== WellKnownSidType
) {
607 DWORD length
= GetSidLengthRequired(WellKnownSids
[i
].Sid
.SubAuthorityCount
);
612 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
617 SetLastError(ERROR_INVALID_PARAMETER
);
620 CopyMemory(pSid
, &WellKnownSids
[i
].Sid
.Revision
, length
);
626 if (DomainSid
== NULL
|| *GetSidSubAuthorityCount(DomainSid
) == SID_MAX_SUB_AUTHORITIES
)
628 SetLastError(ERROR_INVALID_PARAMETER
);
632 for (i
= 0; i
< sizeof(WellKnownRids
)/sizeof(WellKnownRids
[0]); i
++)
633 if (WellKnownRids
[i
].Type
== WellKnownSidType
) {
634 UCHAR domain_subauth
= *GetSidSubAuthorityCount(DomainSid
);
635 DWORD domain_sid_length
= GetSidLengthRequired(domain_subauth
);
636 DWORD output_sid_length
= GetSidLengthRequired(domain_subauth
+ 1);
638 if (*cbSid
< output_sid_length
)
640 *cbSid
= output_sid_length
;
641 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
646 SetLastError(ERROR_INVALID_PARAMETER
);
649 CopyMemory(pSid
, DomainSid
, domain_sid_length
);
650 (*GetSidSubAuthorityCount(pSid
))++;
651 (*GetSidSubAuthority(pSid
, domain_subauth
)) = WellKnownRids
[i
].Rid
;
652 *cbSid
= output_sid_length
;
656 SetLastError(ERROR_INVALID_PARAMETER
);
665 IsWellKnownSid(IN PSID pSid
,
666 IN WELL_KNOWN_SID_TYPE WellKnownSidType
)
669 TRACE("(%s, %d)\n", debugstr_sid(pSid
), WellKnownSidType
);
671 for (i
= 0; i
< sizeof(WellKnownSids
) / sizeof(WellKnownSids
[0]); i
++)
673 if (WellKnownSids
[i
].Type
== WellKnownSidType
)
675 if (EqualSid(pSid
, (PSID
)(&WellKnownSids
[i
].Sid
.Revision
)))
688 IsValidSid(PSID pSid
)
690 return (BOOL
)RtlValidSid(pSid
);
701 SetLastError(ERROR_SUCCESS
);
702 return RtlEqualSid (pSid1
, pSid2
);
710 EqualPrefixSid(PSID pSid1
,
713 return RtlEqualPrefixSid (pSid1
, pSid2
);
721 GetSidLengthRequired(UCHAR nSubAuthorityCount
)
723 return (DWORD
)RtlLengthRequiredSid(nSubAuthorityCount
);
731 InitializeSid(PSID Sid
,
732 PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority
,
733 BYTE nSubAuthorityCount
)
737 Status
= RtlInitializeSid(Sid
,
738 pIdentifierAuthority
,
740 if (!NT_SUCCESS(Status
))
742 SetLastError(RtlNtStatusToDosError(Status
));
752 PSID_IDENTIFIER_AUTHORITY
754 GetSidIdentifierAuthority(PSID pSid
)
756 return RtlIdentifierAuthoritySid(pSid
);
764 GetSidSubAuthority(PSID pSid
,
767 SetLastError(ERROR_SUCCESS
);
768 return (PDWORD
)RtlSubAuthoritySid(pSid
, nSubAuthority
);
776 GetSidSubAuthorityCount(PSID pSid
)
778 SetLastError(ERROR_SUCCESS
);
779 return RtlSubAuthorityCountSid(pSid
);
787 GetLengthSid(PSID pSid
)
789 return (DWORD
)RtlLengthSid(pSid
);
797 InitializeSecurityDescriptor(PSECURITY_DESCRIPTOR pSecurityDescriptor
,
802 Status
= RtlCreateSecurityDescriptor(pSecurityDescriptor
,
804 if (!NT_SUCCESS(Status
))
806 SetLastError(RtlNtStatusToDosError(Status
));
818 MakeAbsoluteSD(PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor
,
819 PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor
,
820 LPDWORD lpdwAbsoluteSecurityDescriptorSize
,
822 LPDWORD lpdwDaclSize
,
824 LPDWORD lpdwSaclSize
,
826 LPDWORD lpdwOwnerSize
,
828 LPDWORD lpdwPrimaryGroupSize
)
832 Status
= RtlSelfRelativeToAbsoluteSD(pSelfRelativeSecurityDescriptor
,
833 pAbsoluteSecurityDescriptor
,
834 lpdwAbsoluteSecurityDescriptorSize
,
842 lpdwPrimaryGroupSize
);
843 if (!NT_SUCCESS(Status
))
845 SetLastError(RtlNtStatusToDosError(Status
));
852 /******************************************************************************
853 * GetKernelObjectSecurity [ADVAPI32.@]
855 BOOL WINAPI
GetKernelObjectSecurity(
857 SECURITY_INFORMATION RequestedInformation
,
858 PSECURITY_DESCRIPTOR pSecurityDescriptor
,
860 LPDWORD lpnLengthNeeded
)
862 TRACE("(%p,0x%08x,%p,0x%08x,%p)\n", Handle
, RequestedInformation
,
863 pSecurityDescriptor
, nLength
, lpnLengthNeeded
);
865 return set_ntstatus( NtQuerySecurityObject(Handle
, RequestedInformation
, pSecurityDescriptor
,
866 nLength
, lpnLengthNeeded
));
874 InitializeAcl(PACL pAcl
,
880 Status
= RtlCreateAcl(pAcl
,
883 if (!NT_SUCCESS(Status
))
885 SetLastError(RtlNtStatusToDosError(Status
));
892 BOOL WINAPI
ImpersonateNamedPipeClient( HANDLE hNamedPipe
)
894 IO_STATUS_BLOCK io_block
;
896 TRACE("(%p)\n", hNamedPipe
);
898 return set_ntstatus( NtFsControlFile(hNamedPipe
, NULL
, NULL
, NULL
,
899 &io_block
, FSCTL_PIPE_IMPERSONATE
, NULL
, 0, NULL
, 0) );
907 AddAccessAllowedAce(PACL pAcl
,
914 Status
= RtlAddAccessAllowedAce(pAcl
,
918 if (!NT_SUCCESS(Status
))
920 SetLastError(RtlNtStatusToDosError(Status
));
931 AddAccessAllowedAceEx(PACL pAcl
,
939 Status
= RtlAddAccessAllowedAceEx(pAcl
,
944 if (!NT_SUCCESS(Status
))
946 SetLastError(RtlNtStatusToDosError(Status
));
958 AddAccessDeniedAce(PACL pAcl
,
965 Status
= RtlAddAccessDeniedAce(pAcl
,
969 if (!NT_SUCCESS(Status
))
971 SetLastError(RtlNtStatusToDosError(Status
));
982 AddAccessDeniedAceEx(PACL pAcl
,
990 Status
= RtlAddAccessDeniedAceEx(pAcl
,
995 if (!NT_SUCCESS(Status
))
997 SetLastError(RtlNtStatusToDosError(Status
));
1010 DWORD dwAceRevision
,
1011 DWORD dwStartingAceIndex
,
1013 DWORD nAceListLength
)
1017 Status
= RtlAddAce(pAcl
,
1022 if (!NT_SUCCESS(Status
))
1024 SetLastError(RtlNtStatusToDosError(Status
));
1031 /******************************************************************************
1032 * DeleteAce [ADVAPI32.@]
1034 BOOL WINAPI
DeleteAce(PACL pAcl
, DWORD dwAceIndex
)
1036 return set_ntstatus(RtlDeleteAce(pAcl
, dwAceIndex
));
1044 FindFirstFreeAce(PACL pAcl
,
1047 return RtlFirstFreeAce(pAcl
,
1051 /******************************************************************************
1052 * GetAce [ADVAPI32.@]
1054 BOOL WINAPI
GetAce(PACL pAcl
,DWORD dwAceIndex
,LPVOID
*pAce
)
1056 return set_ntstatus(RtlGetAce(pAcl
, dwAceIndex
, pAce
));
1059 /******************************************************************************
1060 * GetAclInformation [ADVAPI32.@]
1062 BOOL WINAPI
GetAclInformation(
1064 LPVOID pAclInformation
,
1065 DWORD nAclInformationLength
,
1066 ACL_INFORMATION_CLASS dwAclInformationClass
)
1068 return set_ntstatus(RtlQueryInformationAcl(pAcl
, pAclInformation
,
1069 nAclInformationLength
, dwAclInformationClass
));
1077 IsValidAcl(PACL pAcl
)
1079 return RtlValidAcl (pAcl
);
1086 AllocateLocallyUniqueId(PLUID Luid
)
1090 Status
= NtAllocateLocallyUniqueId (Luid
);
1091 if (!NT_SUCCESS (Status
))
1093 SetLastError(RtlNtStatusToDosError(Status
));
1100 /**********************************************************************
1101 * LookupPrivilegeDisplayNameA EXPORTED
1107 LookupPrivilegeDisplayNameA(LPCSTR lpSystemName
,
1109 LPSTR lpDisplayName
,
1110 LPDWORD cchDisplayName
,
1111 LPDWORD lpLanguageId
)
1113 UNICODE_STRING lpSystemNameW
;
1114 UNICODE_STRING lpNameW
;
1118 TRACE("%s %s %p %p %p\n", debugstr_a(lpSystemName
), debugstr_a(lpName
), lpName
, cchDisplayName
, lpLanguageId
);
1120 RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW
, lpSystemName
);
1121 RtlCreateUnicodeStringFromAsciiz(&lpNameW
, lpName
);
1122 ret
= LookupPrivilegeDisplayNameW(lpSystemNameW
.Buffer
, lpNameW
.Buffer
, NULL
, &wLen
, lpLanguageId
);
1123 if (!ret
&& GetLastError() == ERROR_INSUFFICIENT_BUFFER
)
1125 LPWSTR lpDisplayNameW
= HeapAlloc(GetProcessHeap(), 0, wLen
* sizeof(WCHAR
));
1127 ret
= LookupPrivilegeDisplayNameW(lpSystemNameW
.Buffer
, lpNameW
.Buffer
, lpDisplayNameW
,
1128 &wLen
, lpLanguageId
);
1131 unsigned int len
= WideCharToMultiByte(CP_ACP
, 0, lpDisplayNameW
, -1, lpDisplayName
,
1132 *cchDisplayName
, NULL
, NULL
);
1136 /* WideCharToMultiByte failed */
1139 else if (len
> *cchDisplayName
)
1141 *cchDisplayName
= len
;
1142 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
1147 /* WideCharToMultiByte succeeded, output length needs to be
1148 * length not including NULL terminator
1150 *cchDisplayName
= len
- 1;
1153 HeapFree(GetProcessHeap(), 0, lpDisplayNameW
);
1155 RtlFreeUnicodeString(&lpSystemNameW
);
1156 RtlFreeUnicodeString(&lpNameW
);
1160 /**********************************************************************
1161 * LookupPrivilegeNameA EXPORTED
1167 LookupPrivilegeNameA(LPCSTR lpSystemName
,
1172 UNICODE_STRING lpSystemNameW
;
1176 TRACE("%s %p %p %p\n", debugstr_a(lpSystemName
), lpLuid
, lpName
, cchName
);
1178 RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW
, lpSystemName
);
1179 ret
= LookupPrivilegeNameW(lpSystemNameW
.Buffer
, lpLuid
, NULL
, &wLen
);
1180 if (!ret
&& GetLastError() == ERROR_INSUFFICIENT_BUFFER
)
1182 LPWSTR lpNameW
= HeapAlloc(GetProcessHeap(), 0, wLen
* sizeof(WCHAR
));
1184 ret
= LookupPrivilegeNameW(lpSystemNameW
.Buffer
, lpLuid
, lpNameW
,
1188 /* Windows crashes if cchName is NULL, so will I */
1189 unsigned int len
= WideCharToMultiByte(CP_ACP
, 0, lpNameW
, -1, lpName
,
1190 *cchName
, NULL
, NULL
);
1194 /* WideCharToMultiByte failed */
1197 else if (len
> *cchName
)
1200 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
1205 /* WideCharToMultiByte succeeded, output length needs to be
1206 * length not including NULL terminator
1211 HeapFree(GetProcessHeap(), 0, lpNameW
);
1213 RtlFreeUnicodeString(&lpSystemNameW
);
1217 /******************************************************************************
1218 * GetFileSecurityA [ADVAPI32.@]
1220 * Obtains Specified information about the security of a file or directory.
1223 * lpFileName [I] Name of the file to get info for
1224 * RequestedInformation [I] SE_ flags from "winnt.h"
1225 * pSecurityDescriptor [O] Destination for security information
1226 * nLength [I] Length of pSecurityDescriptor
1227 * lpnLengthNeeded [O] Destination for length of returned security information
1230 * Success: TRUE. pSecurityDescriptor contains the requested information.
1231 * Failure: FALSE. lpnLengthNeeded contains the required space to return the info.
1234 * The information returned is constrained by the callers access rights and
1241 GetFileSecurityA(LPCSTR lpFileName
,
1242 SECURITY_INFORMATION RequestedInformation
,
1243 PSECURITY_DESCRIPTOR pSecurityDescriptor
,
1245 LPDWORD lpnLengthNeeded
)
1247 UNICODE_STRING FileName
;
1250 if (!RtlCreateUnicodeStringFromAsciiz(&FileName
, lpFileName
))
1252 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
1256 bResult
= GetFileSecurityW(FileName
.Buffer
,
1257 RequestedInformation
,
1258 pSecurityDescriptor
,
1262 RtlFreeUnicodeString(&FileName
);
1272 GetFileSecurityW(LPCWSTR lpFileName
,
1273 SECURITY_INFORMATION RequestedInformation
,
1274 PSECURITY_DESCRIPTOR pSecurityDescriptor
,
1276 LPDWORD lpnLengthNeeded
)
1278 OBJECT_ATTRIBUTES ObjectAttributes
;
1279 IO_STATUS_BLOCK StatusBlock
;
1280 UNICODE_STRING FileName
;
1281 ULONG AccessMask
= 0;
1285 TRACE("GetFileSecurityW() called\n");
1287 QuerySecurityAccessMask(RequestedInformation
, &AccessMask
);
1289 if (!RtlDosPathNameToNtPathName_U(lpFileName
,
1294 ERR("Invalid path\n");
1295 SetLastError(ERROR_INVALID_NAME
);
1299 InitializeObjectAttributes(&ObjectAttributes
,
1301 OBJ_CASE_INSENSITIVE
,
1305 Status
= NtOpenFile(&FileHandle
,
1309 FILE_SHARE_READ
| FILE_SHARE_WRITE
| FILE_SHARE_DELETE
,
1312 RtlFreeHeap(RtlGetProcessHeap(),
1316 if (!NT_SUCCESS(Status
))
1318 ERR("NtOpenFile() failed (Status %lx)\n", Status
);
1319 SetLastError(RtlNtStatusToDosError(Status
));
1323 Status
= NtQuerySecurityObject(FileHandle
,
1324 RequestedInformation
,
1325 pSecurityDescriptor
,
1328 NtClose(FileHandle
);
1329 if (!NT_SUCCESS(Status
))
1331 ERR("NtQuerySecurityObject() failed (Status %lx)\n", Status
);
1332 SetLastError(RtlNtStatusToDosError(Status
));
1339 /******************************************************************************
1340 * SetFileSecurityA [ADVAPI32.@]
1341 * Sets the security of a file or directory
1347 SetFileSecurityA(LPCSTR lpFileName
,
1348 SECURITY_INFORMATION SecurityInformation
,
1349 PSECURITY_DESCRIPTOR pSecurityDescriptor
)
1351 UNICODE_STRING FileName
;
1354 if (!RtlCreateUnicodeStringFromAsciiz(&FileName
, lpFileName
))
1356 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
1360 bResult
= SetFileSecurityW(FileName
.Buffer
,
1361 SecurityInformation
,
1362 pSecurityDescriptor
);
1364 RtlFreeUnicodeString(&FileName
);
1369 /******************************************************************************
1370 * SetFileSecurityW [ADVAPI32.@]
1371 * Sets the security of a file or directory
1377 SetFileSecurityW(LPCWSTR lpFileName
,
1378 SECURITY_INFORMATION SecurityInformation
,
1379 PSECURITY_DESCRIPTOR pSecurityDescriptor
)
1381 OBJECT_ATTRIBUTES ObjectAttributes
;
1382 IO_STATUS_BLOCK StatusBlock
;
1383 UNICODE_STRING FileName
;
1384 ULONG AccessMask
= 0;
1388 TRACE("SetFileSecurityW() called\n");
1390 SetSecurityAccessMask(SecurityInformation
, &AccessMask
);
1392 if (!RtlDosPathNameToNtPathName_U(lpFileName
,
1397 ERR("Invalid path\n");
1398 SetLastError(ERROR_INVALID_NAME
);
1402 InitializeObjectAttributes(&ObjectAttributes
,
1404 OBJ_CASE_INSENSITIVE
,
1408 Status
= NtOpenFile(&FileHandle
,
1412 FILE_SHARE_READ
| FILE_SHARE_WRITE
| FILE_SHARE_DELETE
,
1415 RtlFreeHeap(RtlGetProcessHeap(),
1419 if (!NT_SUCCESS(Status
))
1421 ERR("NtOpenFile() failed (Status %lx)\n", Status
);
1422 SetLastError(RtlNtStatusToDosError(Status
));
1426 Status
= NtSetSecurityObject(FileHandle
,
1427 SecurityInformation
,
1428 pSecurityDescriptor
);
1429 NtClose(FileHandle
);
1431 if (!NT_SUCCESS(Status
))
1433 ERR("NtSetSecurityObject() failed (Status %lx)\n", Status
);
1434 SetLastError(RtlNtStatusToDosError(Status
));
1441 /******************************************************************************
1442 * QueryWindows31FilesMigration [ADVAPI32.@]
1448 QueryWindows31FilesMigration( DWORD x1
)
1450 FIXME("(%d):stub\n",x1
);
1454 /******************************************************************************
1455 * SynchronizeWindows31FilesAndWindowsNTRegistry [ADVAPI32.@]
1464 SynchronizeWindows31FilesAndWindowsNTRegistry( DWORD x1
, DWORD x2
, DWORD x3
,
1467 FIXME("(0x%08x,0x%08x,0x%08x,0x%08x):stub\n",x1
,x2
,x3
,x4
);
1479 HANDLE Token
= NULL
;
1481 Status
= NtSetInformationThread(NtCurrentThread(),
1482 ThreadImpersonationToken
,
1485 if (!NT_SUCCESS(Status
))
1487 SetLastError(RtlNtStatusToDosError(Status
));
1499 ImpersonateSelf(SECURITY_IMPERSONATION_LEVEL ImpersonationLevel
)
1503 Status
= RtlImpersonateSelf(ImpersonationLevel
);
1504 if (!NT_SUCCESS(Status
))
1506 SetLastError(RtlNtStatusToDosError(Status
));
1518 AccessCheck(IN PSECURITY_DESCRIPTOR pSecurityDescriptor
,
1519 IN HANDLE ClientToken
,
1520 IN DWORD DesiredAccess
,
1521 IN PGENERIC_MAPPING GenericMapping
,
1522 OUT PPRIVILEGE_SET PrivilegeSet OPTIONAL
,
1523 IN OUT LPDWORD PrivilegeSetLength
,
1524 OUT LPDWORD GrantedAccess
,
1525 OUT LPBOOL AccessStatus
)
1528 NTSTATUS NtAccessStatus
;
1530 /* Do the access check */
1531 Status
= NtAccessCheck(pSecurityDescriptor
,
1536 (PULONG
)PrivilegeSetLength
,
1537 (PACCESS_MASK
)GrantedAccess
,
1540 /* See if the access check operation succeeded */
1541 if (!NT_SUCCESS(Status
))
1544 SetLastError(RtlNtStatusToDosError(Status
));
1548 /* Now check the access status */
1549 if (!NT_SUCCESS(NtAccessStatus
))
1552 SetLastError(RtlNtStatusToDosError(NtAccessStatus
));
1553 *AccessStatus
= FALSE
;
1557 /* Access granted */
1558 *AccessStatus
= TRUE
;
1561 /* Check succeeded */
1568 BOOL WINAPI
AccessCheckByType(
1569 PSECURITY_DESCRIPTOR pSecurityDescriptor
,
1570 PSID PrincipalSelfSid
,
1572 DWORD DesiredAccess
,
1573 POBJECT_TYPE_LIST ObjectTypeList
,
1574 DWORD ObjectTypeListLength
,
1575 PGENERIC_MAPPING GenericMapping
,
1576 PPRIVILEGE_SET PrivilegeSet
,
1577 LPDWORD PrivilegeSetLength
,
1578 LPDWORD GrantedAccess
,
1579 LPBOOL AccessStatus
)
1583 *AccessStatus
= TRUE
;
1585 return !*AccessStatus
;
1593 SetKernelObjectSecurity(HANDLE Handle
,
1594 SECURITY_INFORMATION SecurityInformation
,
1595 PSECURITY_DESCRIPTOR SecurityDescriptor
)
1599 Status
= NtSetSecurityObject(Handle
,
1600 SecurityInformation
,
1601 SecurityDescriptor
);
1602 if (!NT_SUCCESS(Status
))
1604 SetLastError(RtlNtStatusToDosError(Status
));
1616 AddAuditAccessAce(PACL pAcl
,
1617 DWORD dwAceRevision
,
1625 Status
= RtlAddAuditAccessAce(pAcl
,
1631 if (!NT_SUCCESS(Status
))
1633 SetLastError(RtlNtStatusToDosError(Status
));
1644 AddAuditAccessAceEx(PACL pAcl
,
1645 DWORD dwAceRevision
,
1654 Status
= RtlAddAuditAccessAceEx(pAcl
,
1661 if (!NT_SUCCESS(Status
))
1663 SetLastError(RtlNtStatusToDosError(Status
));
1670 /******************************************************************************
1671 * LookupAccountNameA [ADVAPI32.@]
1677 LookupAccountNameA(LPCSTR SystemName
,
1681 LPSTR ReferencedDomainName
,
1682 LPDWORD hReferencedDomainNameLength
,
1683 PSID_NAME_USE SidNameUse
)
1686 UNICODE_STRING lpSystemW
;
1687 UNICODE_STRING lpAccountW
;
1688 LPWSTR lpReferencedDomainNameW
= NULL
;
1690 RtlCreateUnicodeStringFromAsciiz(&lpSystemW
, SystemName
);
1691 RtlCreateUnicodeStringFromAsciiz(&lpAccountW
, AccountName
);
1693 if (ReferencedDomainName
)
1694 lpReferencedDomainNameW
= HeapAlloc(GetProcessHeap(),
1696 *hReferencedDomainNameLength
* sizeof(WCHAR
));
1698 ret
= LookupAccountNameW(lpSystemW
.Buffer
,
1702 lpReferencedDomainNameW
,
1703 hReferencedDomainNameLength
,
1706 if (ret
&& lpReferencedDomainNameW
)
1708 WideCharToMultiByte(CP_ACP
,
1710 lpReferencedDomainNameW
,
1711 *hReferencedDomainNameLength
+ 1,
1712 ReferencedDomainName
,
1713 *hReferencedDomainNameLength
+ 1,
1718 RtlFreeUnicodeString(&lpSystemW
);
1719 RtlFreeUnicodeString(&lpAccountW
);
1720 HeapFree(GetProcessHeap(), 0, lpReferencedDomainNameW
);
1725 /**********************************************************************
1726 * PrivilegeCheck EXPORTED
1731 PrivilegeCheck(HANDLE ClientToken
,
1732 PPRIVILEGE_SET RequiredPrivileges
,
1738 Status
= NtPrivilegeCheck(ClientToken
,
1741 if (!NT_SUCCESS(Status
))
1743 SetLastError(RtlNtStatusToDosError(Status
));
1747 *pfResult
= (BOOL
)Result
;
1752 /******************************************************************************
1753 * GetSecurityInfoExW EXPORTED
1757 GetSecurityInfoExA(HANDLE hObject
,
1758 SE_OBJECT_TYPE ObjectType
,
1759 SECURITY_INFORMATION SecurityInfo
,
1762 PACTRL_ACCESSA
*ppAccessList
,
1763 PACTRL_AUDITA
*ppAuditList
,
1767 FIXME("%s() not implemented!\n", __FUNCTION__
);
1768 return ERROR_BAD_PROVIDER
;
1772 /******************************************************************************
1773 * GetSecurityInfoExW EXPORTED
1777 GetSecurityInfoExW(HANDLE hObject
,
1778 SE_OBJECT_TYPE ObjectType
,
1779 SECURITY_INFORMATION SecurityInfo
,
1782 PACTRL_ACCESSW
*ppAccessList
,
1783 PACTRL_AUDITW
*ppAuditList
,
1787 FIXME("%s() not implemented!\n", __FUNCTION__
);
1788 return ERROR_BAD_PROVIDER
;
1791 /******************************************************************************
1792 * BuildExplicitAccessWithNameA [ADVAPI32.@]
1795 BuildExplicitAccessWithNameA(PEXPLICIT_ACCESSA pExplicitAccess
,
1797 DWORD AccessPermissions
,
1798 ACCESS_MODE AccessMode
,
1801 pExplicitAccess
->grfAccessPermissions
= AccessPermissions
;
1802 pExplicitAccess
->grfAccessMode
= AccessMode
;
1803 pExplicitAccess
->grfInheritance
= Inheritance
;
1805 pExplicitAccess
->Trustee
.pMultipleTrustee
= NULL
;
1806 pExplicitAccess
->Trustee
.MultipleTrusteeOperation
= NO_MULTIPLE_TRUSTEE
;
1807 pExplicitAccess
->Trustee
.TrusteeForm
= TRUSTEE_IS_NAME
;
1808 pExplicitAccess
->Trustee
.TrusteeType
= TRUSTEE_IS_UNKNOWN
;
1809 pExplicitAccess
->Trustee
.ptstrName
= pTrusteeName
;
1813 /******************************************************************************
1814 * BuildExplicitAccessWithNameW [ADVAPI32.@]
1817 BuildExplicitAccessWithNameW(PEXPLICIT_ACCESSW pExplicitAccess
,
1818 LPWSTR pTrusteeName
,
1819 DWORD AccessPermissions
,
1820 ACCESS_MODE AccessMode
,
1823 pExplicitAccess
->grfAccessPermissions
= AccessPermissions
;
1824 pExplicitAccess
->grfAccessMode
= AccessMode
;
1825 pExplicitAccess
->grfInheritance
= Inheritance
;
1827 pExplicitAccess
->Trustee
.pMultipleTrustee
= NULL
;
1828 pExplicitAccess
->Trustee
.MultipleTrusteeOperation
= NO_MULTIPLE_TRUSTEE
;
1829 pExplicitAccess
->Trustee
.TrusteeForm
= TRUSTEE_IS_NAME
;
1830 pExplicitAccess
->Trustee
.TrusteeType
= TRUSTEE_IS_UNKNOWN
;
1831 pExplicitAccess
->Trustee
.ptstrName
= pTrusteeName
;
1834 /******************************************************************************
1835 * BuildTrusteeWithObjectsAndNameA [ADVAPI32.@]
1837 VOID WINAPI
BuildTrusteeWithObjectsAndNameA( PTRUSTEEA pTrustee
, POBJECTS_AND_NAME_A pObjName
,
1838 SE_OBJECT_TYPE ObjectType
, LPSTR ObjectTypeName
,
1839 LPSTR InheritedObjectTypeName
, LPSTR Name
)
1841 DWORD ObjectsPresent
= 0;
1843 TRACE("%p %p 0x%08x %p %p %s\n", pTrustee
, pObjName
,
1844 ObjectType
, ObjectTypeName
, InheritedObjectTypeName
, debugstr_a(Name
));
1846 /* Fill the OBJECTS_AND_NAME structure */
1847 pObjName
->ObjectType
= ObjectType
;
1848 if (ObjectTypeName
!= NULL
)
1850 ObjectsPresent
|= ACE_OBJECT_TYPE_PRESENT
;
1853 pObjName
->InheritedObjectTypeName
= InheritedObjectTypeName
;
1854 if (InheritedObjectTypeName
!= NULL
)
1856 ObjectsPresent
|= ACE_INHERITED_OBJECT_TYPE_PRESENT
;
1859 pObjName
->ObjectsPresent
= ObjectsPresent
;
1860 pObjName
->ptstrName
= Name
;
1862 /* Fill the TRUSTEE structure */
1863 pTrustee
->pMultipleTrustee
= NULL
;
1864 pTrustee
->MultipleTrusteeOperation
= NO_MULTIPLE_TRUSTEE
;
1865 pTrustee
->TrusteeForm
= TRUSTEE_IS_OBJECTS_AND_NAME
;
1866 pTrustee
->TrusteeType
= TRUSTEE_IS_UNKNOWN
;
1867 pTrustee
->ptstrName
= (LPSTR
)pObjName
;
1870 /******************************************************************************
1871 * BuildTrusteeWithObjectsAndNameW [ADVAPI32.@]
1873 VOID WINAPI
BuildTrusteeWithObjectsAndNameW( PTRUSTEEW pTrustee
, POBJECTS_AND_NAME_W pObjName
,
1874 SE_OBJECT_TYPE ObjectType
, LPWSTR ObjectTypeName
,
1875 LPWSTR InheritedObjectTypeName
, LPWSTR Name
)
1877 DWORD ObjectsPresent
= 0;
1879 TRACE("%p %p 0x%08x %p %p %s\n", pTrustee
, pObjName
,
1880 ObjectType
, ObjectTypeName
, InheritedObjectTypeName
, debugstr_w(Name
));
1882 /* Fill the OBJECTS_AND_NAME structure */
1883 pObjName
->ObjectType
= ObjectType
;
1884 if (ObjectTypeName
!= NULL
)
1886 ObjectsPresent
|= ACE_OBJECT_TYPE_PRESENT
;
1889 pObjName
->InheritedObjectTypeName
= InheritedObjectTypeName
;
1890 if (InheritedObjectTypeName
!= NULL
)
1892 ObjectsPresent
|= ACE_INHERITED_OBJECT_TYPE_PRESENT
;
1895 pObjName
->ObjectsPresent
= ObjectsPresent
;
1896 pObjName
->ptstrName
= Name
;
1898 /* Fill the TRUSTEE structure */
1899 pTrustee
->pMultipleTrustee
= NULL
;
1900 pTrustee
->MultipleTrusteeOperation
= NO_MULTIPLE_TRUSTEE
;
1901 pTrustee
->TrusteeForm
= TRUSTEE_IS_OBJECTS_AND_NAME
;
1902 pTrustee
->TrusteeType
= TRUSTEE_IS_UNKNOWN
;
1903 pTrustee
->ptstrName
= (LPWSTR
)pObjName
;
1906 /******************************************************************************
1907 * BuildTrusteeWithObjectsAndSidA [ADVAPI32.@]
1910 BuildTrusteeWithObjectsAndSidA(PTRUSTEEA pTrustee
,
1911 POBJECTS_AND_SID pObjSid
,
1913 GUID
*pInheritedObjectGuid
,
1916 DWORD ObjectsPresent
= 0;
1918 TRACE("%p %p %p %p %p\n", pTrustee
, pObjSid
, pObjectGuid
, pInheritedObjectGuid
, pSid
);
1920 /* Fill the OBJECTS_AND_SID structure */
1921 if (pObjectGuid
!= NULL
)
1923 pObjSid
->ObjectTypeGuid
= *pObjectGuid
;
1924 ObjectsPresent
|= ACE_OBJECT_TYPE_PRESENT
;
1928 ZeroMemory(&pObjSid
->ObjectTypeGuid
,
1932 if (pInheritedObjectGuid
!= NULL
)
1934 pObjSid
->InheritedObjectTypeGuid
= *pInheritedObjectGuid
;
1935 ObjectsPresent
|= ACE_INHERITED_OBJECT_TYPE_PRESENT
;
1939 ZeroMemory(&pObjSid
->InheritedObjectTypeGuid
,
1943 pObjSid
->ObjectsPresent
= ObjectsPresent
;
1944 pObjSid
->pSid
= pSid
;
1946 /* Fill the TRUSTEE structure */
1947 pTrustee
->pMultipleTrustee
= NULL
;
1948 pTrustee
->MultipleTrusteeOperation
= NO_MULTIPLE_TRUSTEE
;
1949 pTrustee
->TrusteeForm
= TRUSTEE_IS_OBJECTS_AND_SID
;
1950 pTrustee
->TrusteeType
= TRUSTEE_IS_UNKNOWN
;
1951 pTrustee
->ptstrName
= (LPSTR
) pObjSid
;
1955 /******************************************************************************
1956 * BuildTrusteeWithObjectsAndSidW [ADVAPI32.@]
1959 BuildTrusteeWithObjectsAndSidW(PTRUSTEEW pTrustee
,
1960 POBJECTS_AND_SID pObjSid
,
1962 GUID
*pInheritedObjectGuid
,
1965 DWORD ObjectsPresent
= 0;
1967 TRACE("%p %p %p %p %p\n", pTrustee
, pObjSid
, pObjectGuid
, pInheritedObjectGuid
, pSid
);
1969 /* Fill the OBJECTS_AND_SID structure */
1970 if (pObjectGuid
!= NULL
)
1972 pObjSid
->ObjectTypeGuid
= *pObjectGuid
;
1973 ObjectsPresent
|= ACE_OBJECT_TYPE_PRESENT
;
1977 ZeroMemory(&pObjSid
->ObjectTypeGuid
,
1981 if (pInheritedObjectGuid
!= NULL
)
1983 pObjSid
->InheritedObjectTypeGuid
= *pInheritedObjectGuid
;
1984 ObjectsPresent
|= ACE_INHERITED_OBJECT_TYPE_PRESENT
;
1988 ZeroMemory(&pObjSid
->InheritedObjectTypeGuid
,
1992 pObjSid
->ObjectsPresent
= ObjectsPresent
;
1993 pObjSid
->pSid
= pSid
;
1995 /* Fill the TRUSTEE structure */
1996 pTrustee
->pMultipleTrustee
= NULL
;
1997 pTrustee
->MultipleTrusteeOperation
= NO_MULTIPLE_TRUSTEE
;
1998 pTrustee
->TrusteeForm
= TRUSTEE_IS_OBJECTS_AND_SID
;
1999 pTrustee
->TrusteeType
= TRUSTEE_IS_UNKNOWN
;
2000 pTrustee
->ptstrName
= (LPWSTR
) pObjSid
;
2003 /******************************************************************************
2004 * BuildTrusteeWithSidA [ADVAPI32.@]
2007 BuildTrusteeWithSidA(PTRUSTEE_A pTrustee
,
2010 TRACE("%p %p\n", pTrustee
, pSid
);
2012 pTrustee
->pMultipleTrustee
= NULL
;
2013 pTrustee
->MultipleTrusteeOperation
= NO_MULTIPLE_TRUSTEE
;
2014 pTrustee
->TrusteeForm
= TRUSTEE_IS_SID
;
2015 pTrustee
->TrusteeType
= TRUSTEE_IS_UNKNOWN
;
2016 pTrustee
->ptstrName
= (LPSTR
) pSid
;
2020 /******************************************************************************
2021 * BuildTrusteeWithSidW [ADVAPI32.@]
2024 BuildTrusteeWithSidW(PTRUSTEE_W pTrustee
,
2027 TRACE("%p %p\n", pTrustee
, pSid
);
2029 pTrustee
->pMultipleTrustee
= NULL
;
2030 pTrustee
->MultipleTrusteeOperation
= NO_MULTIPLE_TRUSTEE
;
2031 pTrustee
->TrusteeForm
= TRUSTEE_IS_SID
;
2032 pTrustee
->TrusteeType
= TRUSTEE_IS_UNKNOWN
;
2033 pTrustee
->ptstrName
= (LPWSTR
) pSid
;
2036 /******************************************************************************
2037 * BuildTrusteeWithNameA [ADVAPI32.@]
2040 BuildTrusteeWithNameA(PTRUSTEE_A pTrustee
,
2043 TRACE("%p %s\n", pTrustee
, name
);
2045 pTrustee
->pMultipleTrustee
= NULL
;
2046 pTrustee
->MultipleTrusteeOperation
= NO_MULTIPLE_TRUSTEE
;
2047 pTrustee
->TrusteeForm
= TRUSTEE_IS_NAME
;
2048 pTrustee
->TrusteeType
= TRUSTEE_IS_UNKNOWN
;
2049 pTrustee
->ptstrName
= name
;
2052 /******************************************************************************
2053 * BuildTrusteeWithNameW [ADVAPI32.@]
2056 BuildTrusteeWithNameW(PTRUSTEE_W pTrustee
,
2059 TRACE("%p %s\n", pTrustee
, name
);
2061 pTrustee
->pMultipleTrustee
= NULL
;
2062 pTrustee
->MultipleTrusteeOperation
= NO_MULTIPLE_TRUSTEE
;
2063 pTrustee
->TrusteeForm
= TRUSTEE_IS_NAME
;
2064 pTrustee
->TrusteeType
= TRUSTEE_IS_UNKNOWN
;
2065 pTrustee
->ptstrName
= name
;
2068 /******************************************************************************
2069 * GetTrusteeFormA [ADVAPI32.@]
2071 TRUSTEE_FORM WINAPI
GetTrusteeFormA(PTRUSTEEA pTrustee
)
2073 TRACE("(%p)\n", pTrustee
);
2076 return TRUSTEE_BAD_FORM
;
2078 return pTrustee
->TrusteeForm
;
2081 /******************************************************************************
2082 * GetTrusteeFormW [ADVAPI32.@]
2084 TRUSTEE_FORM WINAPI
GetTrusteeFormW(PTRUSTEEW pTrustee
)
2086 TRACE("(%p)\n", pTrustee
);
2089 return TRUSTEE_BAD_FORM
;
2091 return pTrustee
->TrusteeForm
;
2094 /******************************************************************************
2095 * GetTrusteeNameA [ADVAPI32.@]
2098 GetTrusteeNameA(PTRUSTEE_A pTrustee
)
2100 return pTrustee
->ptstrName
;
2104 /******************************************************************************
2105 * GetTrusteeNameW [ADVAPI32.@]
2108 GetTrusteeNameW(PTRUSTEE_W pTrustee
)
2110 return pTrustee
->ptstrName
;
2113 /******************************************************************************
2114 * GetTrusteeTypeA [ADVAPI32.@]
2117 GetTrusteeTypeA(PTRUSTEE_A pTrustee
)
2119 return pTrustee
->TrusteeType
;
2122 /******************************************************************************
2123 * GetTrusteeTypeW [ADVAPI32.@]
2126 GetTrusteeTypeW(PTRUSTEE_W pTrustee
)
2128 return pTrustee
->TrusteeType
;
2136 SetAclInformation(PACL pAcl
,
2137 LPVOID pAclInformation
,
2138 DWORD nAclInformationLength
,
2139 ACL_INFORMATION_CLASS dwAclInformationClass
)
2143 Status
= RtlSetInformationAcl(pAcl
,
2145 nAclInformationLength
,
2146 dwAclInformationClass
);
2147 if (!NT_SUCCESS(Status
))
2149 SetLastError(RtlNtStatusToDosError(Status
));
2156 /**********************************************************************
2157 * SetNamedSecurityInfoA EXPORTED
2163 SetNamedSecurityInfoA(LPSTR pObjectName
,
2164 SE_OBJECT_TYPE ObjectType
,
2165 SECURITY_INFORMATION SecurityInfo
,
2171 UNICODE_STRING ObjectName
;
2174 if (!RtlCreateUnicodeStringFromAsciiz(&ObjectName
, pObjectName
))
2176 return ERROR_NOT_ENOUGH_MEMORY
;
2179 Ret
= SetNamedSecurityInfoW(ObjectName
.Buffer
,
2187 RtlFreeUnicodeString(&ObjectName
);
2197 AreAllAccessesGranted(DWORD GrantedAccess
,
2198 DWORD DesiredAccess
)
2200 return (BOOL
)RtlAreAllAccessesGranted(GrantedAccess
,
2209 AreAnyAccessesGranted(DWORD GrantedAccess
,
2210 DWORD DesiredAccess
)
2212 return (BOOL
)RtlAreAnyAccessesGranted(GrantedAccess
,
2216 /******************************************************************************
2217 * ParseAclStringFlags
2219 static DWORD
ParseAclStringFlags(LPCWSTR
* StringAcl
)
2222 LPCWSTR szAcl
= *StringAcl
;
2224 while (*szAcl
!= '(')
2228 flags
|= SE_DACL_PROTECTED
;
2230 else if (*szAcl
== 'A')
2234 flags
|= SE_DACL_AUTO_INHERIT_REQ
;
2235 else if (*szAcl
== 'I')
2236 flags
|= SE_DACL_AUTO_INHERITED
;
2245 /******************************************************************************
2246 * ParseAceStringType
2248 static const ACEFLAG AceType
[] =
2250 { SDDL_ALARM
, SYSTEM_ALARM_ACE_TYPE
},
2251 { SDDL_AUDIT
, SYSTEM_AUDIT_ACE_TYPE
},
2252 { SDDL_ACCESS_ALLOWED
, ACCESS_ALLOWED_ACE_TYPE
},
2253 { SDDL_ACCESS_DENIED
, ACCESS_DENIED_ACE_TYPE
},
2254 { SDDL_MANDATORY_LABEL
,SYSTEM_MANDATORY_LABEL_ACE_TYPE
},
2256 { SDDL_OBJECT_ACCESS_ALLOWED, ACCESS_ALLOWED_OBJECT_ACE_TYPE },
2257 { SDDL_OBJECT_ACCESS_DENIED, ACCESS_DENIED_OBJECT_ACE_TYPE },
2258 { SDDL_OBJECT_ALARM, SYSTEM_ALARM_OBJECT_ACE_TYPE },
2259 { SDDL_OBJECT_AUDIT, SYSTEM_AUDIT_OBJECT_ACE_TYPE },
2264 static BYTE
ParseAceStringType(LPCWSTR
* StringAcl
)
2267 LPCWSTR szAcl
= *StringAcl
;
2268 const ACEFLAG
*lpaf
= AceType
;
2270 while (*szAcl
== ' ')
2273 while (lpaf
->wstr
&&
2274 (len
= strlenW(lpaf
->wstr
)) &&
2275 strncmpW(lpaf
->wstr
, szAcl
, len
))
2281 *StringAcl
= szAcl
+ len
;
2286 /******************************************************************************
2287 * ParseAceStringFlags
2289 static const ACEFLAG AceFlags
[] =
2291 { SDDL_CONTAINER_INHERIT
, CONTAINER_INHERIT_ACE
},
2292 { SDDL_AUDIT_FAILURE
, FAILED_ACCESS_ACE_FLAG
},
2293 { SDDL_INHERITED
, INHERITED_ACE
},
2294 { SDDL_INHERIT_ONLY
, INHERIT_ONLY_ACE
},
2295 { SDDL_NO_PROPAGATE
, NO_PROPAGATE_INHERIT_ACE
},
2296 { SDDL_OBJECT_INHERIT
, OBJECT_INHERIT_ACE
},
2297 { SDDL_AUDIT_SUCCESS
, SUCCESSFUL_ACCESS_ACE_FLAG
},
2301 static BYTE
ParseAceStringFlags(LPCWSTR
* StringAcl
)
2305 LPCWSTR szAcl
= *StringAcl
;
2307 while (*szAcl
== ' ')
2310 while (*szAcl
!= ';')
2312 const ACEFLAG
*lpaf
= AceFlags
;
2314 while (lpaf
->wstr
&&
2315 (len
= strlenW(lpaf
->wstr
)) &&
2316 strncmpW(lpaf
->wstr
, szAcl
, len
))
2322 flags
|= lpaf
->value
;
2331 /******************************************************************************
2332 * ParseAceStringRights
2334 static const ACEFLAG AceRights
[] =
2336 { SDDL_GENERIC_ALL
, GENERIC_ALL
},
2337 { SDDL_GENERIC_READ
, GENERIC_READ
},
2338 { SDDL_GENERIC_WRITE
, GENERIC_WRITE
},
2339 { SDDL_GENERIC_EXECUTE
, GENERIC_EXECUTE
},
2341 { SDDL_READ_CONTROL
, READ_CONTROL
},
2342 { SDDL_STANDARD_DELETE
, DELETE
},
2343 { SDDL_WRITE_DAC
, WRITE_DAC
},
2344 { SDDL_WRITE_OWNER
, WRITE_OWNER
},
2346 { SDDL_READ_PROPERTY
, ADS_RIGHT_DS_READ_PROP
},
2347 { SDDL_WRITE_PROPERTY
, ADS_RIGHT_DS_WRITE_PROP
},
2348 { SDDL_CREATE_CHILD
, ADS_RIGHT_DS_CREATE_CHILD
},
2349 { SDDL_DELETE_CHILD
, ADS_RIGHT_DS_DELETE_CHILD
},
2350 { SDDL_LIST_CHILDREN
, ADS_RIGHT_ACTRL_DS_LIST
},
2351 { SDDL_SELF_WRITE
, ADS_RIGHT_DS_SELF
},
2352 { SDDL_LIST_OBJECT
, ADS_RIGHT_DS_LIST_OBJECT
},
2353 { SDDL_DELETE_TREE
, ADS_RIGHT_DS_DELETE_TREE
},
2354 { SDDL_CONTROL_ACCESS
, ADS_RIGHT_DS_CONTROL_ACCESS
},
2356 { SDDL_FILE_ALL
, FILE_ALL_ACCESS
},
2357 { SDDL_FILE_READ
, FILE_GENERIC_READ
},
2358 { SDDL_FILE_WRITE
, FILE_GENERIC_WRITE
},
2359 { SDDL_FILE_EXECUTE
, FILE_GENERIC_EXECUTE
},
2361 { SDDL_KEY_ALL
, KEY_ALL_ACCESS
},
2362 { SDDL_KEY_READ
, KEY_READ
},
2363 { SDDL_KEY_WRITE
, KEY_WRITE
},
2364 { SDDL_KEY_EXECUTE
, KEY_EXECUTE
},
2366 { SDDL_NO_READ_UP
, SYSTEM_MANDATORY_LABEL_NO_READ_UP
},
2367 { SDDL_NO_WRITE_UP
, SYSTEM_MANDATORY_LABEL_NO_WRITE_UP
},
2368 { SDDL_NO_EXECUTE_UP
, SYSTEM_MANDATORY_LABEL_NO_EXECUTE_UP
},
2372 static DWORD
ParseAceStringRights(LPCWSTR
* StringAcl
)
2376 LPCWSTR szAcl
= *StringAcl
;
2378 while (*szAcl
== ' ')
2381 if ((*szAcl
== '0') && (*(szAcl
+ 1) == 'x'))
2385 while (*p
&& *p
!= ';')
2388 if (p
- szAcl
<= 10 /* 8 hex digits + "0x" */ )
2390 rights
= strtoulW(szAcl
, NULL
, 16);
2394 WARN("Invalid rights string format: %s\n", debugstr_wn(szAcl
, p
- szAcl
));
2398 while (*szAcl
!= ';')
2400 const ACEFLAG
*lpaf
= AceRights
;
2402 while (lpaf
->wstr
&&
2403 (len
= strlenW(lpaf
->wstr
)) &&
2404 strncmpW(lpaf
->wstr
, szAcl
, len
))
2412 rights
|= lpaf
->value
;
2422 /******************************************************************************
2423 * ParseStringAclToAcl
2425 * dacl_flags(string_ace1)(string_ace2)... (string_acen)
2427 static BOOL
ParseStringAclToAcl(LPCWSTR StringAcl
, LPDWORD lpdwFlags
,
2428 PACL pAcl
, LPDWORD cBytes
)
2432 DWORD length
= sizeof(ACL
);
2435 PACCESS_ALLOWED_ACE pAce
= NULL
; /* pointer to current ACE */
2436 DWORD error
= ERROR_INVALID_ACL
;
2438 TRACE("%s\n", debugstr_w(StringAcl
));
2443 if (pAcl
) /* pAce is only useful if we're setting values */
2444 pAce
= (PACCESS_ALLOWED_ACE
) (pAcl
+ 1);
2446 /* Parse ACL flags */
2447 *lpdwFlags
= ParseAclStringFlags(&StringAcl
);
2450 while (*StringAcl
== '(')
2454 /* Parse ACE type */
2455 val
= ParseAceStringType(&StringAcl
);
2457 pAce
->Header
.AceType
= (BYTE
) val
;
2458 if (*StringAcl
!= ';')
2460 error
= RPC_S_INVALID_STRING_UUID
;
2465 /* Parse ACE flags */
2466 val
= ParseAceStringFlags(&StringAcl
);
2468 pAce
->Header
.AceFlags
= (BYTE
) val
;
2469 if (*StringAcl
!= ';')
2473 /* Parse ACE rights */
2474 val
= ParseAceStringRights(&StringAcl
);
2477 if (*StringAcl
!= ';')
2481 /* Parse ACE object guid */
2482 while (*StringAcl
== ' ')
2484 if (*StringAcl
!= ';')
2486 FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
2491 /* Parse ACE inherit object guid */
2492 while (*StringAcl
== ' ')
2494 if (*StringAcl
!= ';')
2496 FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
2501 /* Parse ACE account sid */
2502 if (ParseStringSidToSid(StringAcl
, pAce
? &pAce
->SidStart
: NULL
, &sidlen
))
2504 while (*StringAcl
&& *StringAcl
!= ')')
2508 if (*StringAcl
!= ')')
2512 acesize
= sizeof(ACCESS_ALLOWED_ACE
) - sizeof(DWORD
) + sidlen
;
2516 pAce
->Header
.AceSize
= acesize
;
2517 pAce
= (PACCESS_ALLOWED_ACE
)((LPBYTE
)pAce
+ acesize
);
2524 if (length
> 0xffff)
2526 ERR("ACL too large\n");
2532 pAcl
->AclRevision
= ACL_REVISION
;
2534 pAcl
->AclSize
= length
;
2535 pAcl
->AceCount
= acecount
++;
2541 SetLastError(error
);
2542 WARN("Invalid ACE string format\n");
2547 /******************************************************************************
2548 * ParseStringSecurityDescriptorToSecurityDescriptor
2550 static BOOL
ParseStringSecurityDescriptorToSecurityDescriptor(
2551 LPCWSTR StringSecurityDescriptor
,
2552 SECURITY_DESCRIPTOR_RELATIVE
* SecurityDescriptor
,
2559 LPBYTE lpNext
= NULL
;
2562 *cBytes
= sizeof(SECURITY_DESCRIPTOR
);
2564 tok
= heap_alloc( (lstrlenW(StringSecurityDescriptor
) + 1) * sizeof(WCHAR
));
2566 if (SecurityDescriptor
)
2567 lpNext
= (LPBYTE
)(SecurityDescriptor
+ 1);
2569 while (*StringSecurityDescriptor
== ' ')
2570 StringSecurityDescriptor
++;
2572 while (*StringSecurityDescriptor
)
2574 toktype
= *StringSecurityDescriptor
;
2576 /* Expect char identifier followed by ':' */
2577 StringSecurityDescriptor
++;
2578 if (*StringSecurityDescriptor
!= ':')
2580 SetLastError(ERROR_INVALID_PARAMETER
);
2583 StringSecurityDescriptor
++;
2586 lptoken
= StringSecurityDescriptor
;
2587 while (*lptoken
&& *lptoken
!= ':')
2593 len
= lptoken
- StringSecurityDescriptor
;
2594 memcpy( tok
, StringSecurityDescriptor
, len
* sizeof(WCHAR
) );
2603 if (!ParseStringSidToSid(tok
, lpNext
, &bytes
))
2606 if (SecurityDescriptor
)
2608 SecurityDescriptor
->Owner
= lpNext
- (LPBYTE
)SecurityDescriptor
;
2609 lpNext
+= bytes
; /* Advance to next token */
2621 if (!ParseStringSidToSid(tok
, lpNext
, &bytes
))
2624 if (SecurityDescriptor
)
2626 SecurityDescriptor
->Group
= lpNext
- (LPBYTE
)SecurityDescriptor
;
2627 lpNext
+= bytes
; /* Advance to next token */
2640 if (!ParseStringAclToAcl(tok
, &flags
, (PACL
)lpNext
, &bytes
))
2643 if (SecurityDescriptor
)
2645 SecurityDescriptor
->Control
|= SE_DACL_PRESENT
| flags
;
2646 SecurityDescriptor
->Dacl
= lpNext
- (LPBYTE
)SecurityDescriptor
;
2647 lpNext
+= bytes
; /* Advance to next token */
2660 if (!ParseStringAclToAcl(tok
, &flags
, (PACL
)lpNext
, &bytes
))
2663 if (SecurityDescriptor
)
2665 SecurityDescriptor
->Control
|= SE_SACL_PRESENT
| flags
;
2666 SecurityDescriptor
->Sacl
= lpNext
- (LPBYTE
)SecurityDescriptor
;
2667 lpNext
+= bytes
; /* Advance to next token */
2676 FIXME("Unknown token\n");
2677 SetLastError(ERROR_INVALID_PARAMETER
);
2681 StringSecurityDescriptor
= lptoken
;
2691 /* Winehq cvs 20050916 */
2692 /******************************************************************************
2693 * ConvertStringSecurityDescriptorToSecurityDescriptorA [ADVAPI32.@]
2698 ConvertStringSecurityDescriptorToSecurityDescriptorA(LPCSTR StringSecurityDescriptor
,
2699 DWORD StringSDRevision
,
2700 PSECURITY_DESCRIPTOR
* SecurityDescriptor
,
2701 PULONG SecurityDescriptorSize
)
2705 LPWSTR StringSecurityDescriptorW
;
2707 len
= MultiByteToWideChar(CP_ACP
, 0, StringSecurityDescriptor
, -1, NULL
, 0);
2708 StringSecurityDescriptorW
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
2710 if (StringSecurityDescriptorW
)
2712 MultiByteToWideChar(CP_ACP
, 0, StringSecurityDescriptor
, -1, StringSecurityDescriptorW
, len
);
2714 ret
= ConvertStringSecurityDescriptorToSecurityDescriptorW(StringSecurityDescriptorW
,
2715 StringSDRevision
, SecurityDescriptor
,
2716 SecurityDescriptorSize
);
2717 HeapFree(GetProcessHeap(), 0, StringSecurityDescriptorW
);
2723 /******************************************************************************
2724 * ConvertStringSecurityDescriptorToSecurityDescriptorW [ADVAPI32.@]
2728 ConvertStringSecurityDescriptorToSecurityDescriptorW(LPCWSTR StringSecurityDescriptor
,
2729 DWORD StringSDRevision
,
2730 PSECURITY_DESCRIPTOR
* SecurityDescriptor
,
2731 PULONG SecurityDescriptorSize
)
2734 SECURITY_DESCRIPTOR
* psd
;
2737 TRACE("%s\n", debugstr_w(StringSecurityDescriptor
));
2739 if (GetVersion() & 0x80000000)
2741 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
2744 else if (!StringSecurityDescriptor
|| !SecurityDescriptor
)
2746 SetLastError(ERROR_INVALID_PARAMETER
);
2749 else if (StringSDRevision
!= SID_REVISION
)
2751 SetLastError(ERROR_UNKNOWN_REVISION
);
2755 /* Compute security descriptor length */
2756 if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor
,
2760 psd
= *SecurityDescriptor
= LocalAlloc(GMEM_ZEROINIT
, cBytes
);
2761 if (!psd
) goto lend
;
2763 psd
->Revision
= SID_REVISION
;
2764 psd
->Control
|= SE_SELF_RELATIVE
;
2766 if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor
,
2767 (SECURITY_DESCRIPTOR_RELATIVE
*)psd
, &cBytes
))
2773 if (SecurityDescriptorSize
)
2774 *SecurityDescriptorSize
= cBytes
;
2779 TRACE(" ret=%d\n", bret
);
2783 static void DumpString(LPCWSTR string
, int cch
, WCHAR
**pwptr
, ULONG
*plen
)
2786 cch
= strlenW(string
);
2793 memcpy(*pwptr
, string
, sizeof(WCHAR
)*cch
);
2798 static BOOL
DumpSidNumeric(PSID psid
, WCHAR
**pwptr
, ULONG
*plen
)
2801 WCHAR fmt
[] = { 'S','-','%','u','-','%','d',0 };
2802 WCHAR subauthfmt
[] = { '-','%','u',0 };
2806 if( !IsValidSid( psid
) || pisid
->Revision
!= SDDL_REVISION
)
2808 SetLastError(ERROR_INVALID_SID
);
2812 if (pisid
->IdentifierAuthority
.Value
[0] ||
2813 pisid
->IdentifierAuthority
.Value
[1])
2815 FIXME("not matching MS' bugs\n");
2816 SetLastError(ERROR_INVALID_SID
);
2820 sprintfW( buf
, fmt
, pisid
->Revision
,
2822 MAKEWORD( pisid
->IdentifierAuthority
.Value
[5],
2823 pisid
->IdentifierAuthority
.Value
[4] ),
2824 MAKEWORD( pisid
->IdentifierAuthority
.Value
[3],
2825 pisid
->IdentifierAuthority
.Value
[2] )
2827 DumpString(buf
, -1, pwptr
, plen
);
2829 for( i
=0; i
<pisid
->SubAuthorityCount
; i
++ )
2831 sprintfW( buf
, subauthfmt
, pisid
->SubAuthority
[i
] );
2832 DumpString(buf
, -1, pwptr
, plen
);
2837 static BOOL
DumpSid(PSID psid
, WCHAR
**pwptr
, ULONG
*plen
)
2840 for (i
= 0; i
< sizeof(WellKnownSids
) / sizeof(WellKnownSids
[0]); i
++)
2842 if (WellKnownSids
[i
].wstr
[0] && EqualSid(psid
, (PSID
)&(WellKnownSids
[i
].Sid
.Revision
)))
2844 DumpString(WellKnownSids
[i
].wstr
, 2, pwptr
, plen
);
2849 return DumpSidNumeric(psid
, pwptr
, plen
);
2852 static const LPCWSTR AceRightBitNames
[32] = {
2853 SDDL_CREATE_CHILD
, /* 0 */
2857 SDDL_READ_PROPERTY
, /* 4 */
2858 SDDL_WRITE_PROPERTY
,
2861 SDDL_CONTROL_ACCESS
, /* 8 */
2869 SDDL_STANDARD_DELETE
, /* 16 */
2881 SDDL_GENERIC_ALL
, /* 28 */
2882 SDDL_GENERIC_EXECUTE
,
2887 static void DumpRights(DWORD mask
, WCHAR
**pwptr
, ULONG
*plen
)
2889 static const WCHAR fmtW
[] = {'0','x','%','x',0};
2896 /* first check if the right have name */
2897 for (i
= 0; i
< sizeof(AceRights
)/sizeof(AceRights
[0]); i
++)
2899 if (AceRights
[i
].wstr
== NULL
)
2901 if (mask
== AceRights
[i
].value
)
2903 DumpString(AceRights
[i
].wstr
, -1, pwptr
, plen
);
2908 /* then check if it can be built from bit names */
2909 for (i
= 0; i
< 32; i
++)
2911 if ((mask
& (1 << i
)) && (AceRightBitNames
[i
] == NULL
))
2913 /* can't be built from bit names */
2914 sprintfW(buf
, fmtW
, mask
);
2915 DumpString(buf
, -1, pwptr
, plen
);
2920 /* build from bit names */
2921 for (i
= 0; i
< 32; i
++)
2922 if (mask
& (1 << i
))
2923 DumpString(AceRightBitNames
[i
], -1, pwptr
, plen
);
2926 static BOOL
DumpAce(LPVOID pace
, WCHAR
**pwptr
, ULONG
*plen
)
2928 ACCESS_ALLOWED_ACE
*piace
; /* all the supported ACEs have the same memory layout */
2929 static const WCHAR openbr
= '(';
2930 static const WCHAR closebr
= ')';
2931 static const WCHAR semicolon
= ';';
2933 if (((PACE_HEADER
)pace
)->AceType
> SYSTEM_ALARM_ACE_TYPE
|| ((PACE_HEADER
)pace
)->AceSize
< sizeof(ACCESS_ALLOWED_ACE
))
2935 SetLastError(ERROR_INVALID_ACL
);
2940 DumpString(&openbr
, 1, pwptr
, plen
);
2941 switch (piace
->Header
.AceType
)
2943 case ACCESS_ALLOWED_ACE_TYPE
:
2944 DumpString(SDDL_ACCESS_ALLOWED
, -1, pwptr
, plen
);
2946 case ACCESS_DENIED_ACE_TYPE
:
2947 DumpString(SDDL_ACCESS_DENIED
, -1, pwptr
, plen
);
2949 case SYSTEM_AUDIT_ACE_TYPE
:
2950 DumpString(SDDL_AUDIT
, -1, pwptr
, plen
);
2952 case SYSTEM_ALARM_ACE_TYPE
:
2953 DumpString(SDDL_ALARM
, -1, pwptr
, plen
);
2956 DumpString(&semicolon
, 1, pwptr
, plen
);
2958 if (piace
->Header
.AceFlags
& OBJECT_INHERIT_ACE
)
2959 DumpString(SDDL_OBJECT_INHERIT
, -1, pwptr
, plen
);
2960 if (piace
->Header
.AceFlags
& CONTAINER_INHERIT_ACE
)
2961 DumpString(SDDL_CONTAINER_INHERIT
, -1, pwptr
, plen
);
2962 if (piace
->Header
.AceFlags
& NO_PROPAGATE_INHERIT_ACE
)
2963 DumpString(SDDL_NO_PROPAGATE
, -1, pwptr
, plen
);
2964 if (piace
->Header
.AceFlags
& INHERIT_ONLY_ACE
)
2965 DumpString(SDDL_INHERIT_ONLY
, -1, pwptr
, plen
);
2966 if (piace
->Header
.AceFlags
& INHERITED_ACE
)
2967 DumpString(SDDL_INHERITED
, -1, pwptr
, plen
);
2968 if (piace
->Header
.AceFlags
& SUCCESSFUL_ACCESS_ACE_FLAG
)
2969 DumpString(SDDL_AUDIT_SUCCESS
, -1, pwptr
, plen
);
2970 if (piace
->Header
.AceFlags
& FAILED_ACCESS_ACE_FLAG
)
2971 DumpString(SDDL_AUDIT_FAILURE
, -1, pwptr
, plen
);
2972 DumpString(&semicolon
, 1, pwptr
, plen
);
2973 DumpRights(piace
->Mask
, pwptr
, plen
);
2974 DumpString(&semicolon
, 1, pwptr
, plen
);
2975 /* objects not supported */
2976 DumpString(&semicolon
, 1, pwptr
, plen
);
2977 /* objects not supported */
2978 DumpString(&semicolon
, 1, pwptr
, plen
);
2979 if (!DumpSid((PSID
)&piace
->SidStart
, pwptr
, plen
))
2981 DumpString(&closebr
, 1, pwptr
, plen
);
2985 static BOOL
DumpAcl(PACL pacl
, WCHAR
**pwptr
, ULONG
*plen
, BOOL
protected, BOOL autoInheritReq
, BOOL autoInherited
)
2991 DumpString(SDDL_PROTECTED
, -1, pwptr
, plen
);
2993 DumpString(SDDL_AUTO_INHERIT_REQ
, -1, pwptr
, plen
);
2995 DumpString(SDDL_AUTO_INHERITED
, -1, pwptr
, plen
);
3000 if (!IsValidAcl(pacl
))
3003 count
= pacl
->AceCount
;
3004 for (i
= 0; i
< count
; i
++)
3007 if (!GetAce(pacl
, i
, &ace
))
3009 if (!DumpAce(ace
, pwptr
, plen
))
3016 static BOOL
DumpOwner(PSECURITY_DESCRIPTOR SecurityDescriptor
, WCHAR
**pwptr
, ULONG
*plen
)
3018 static const WCHAR prefix
[] = {'O',':',0};
3022 if (!GetSecurityDescriptorOwner(SecurityDescriptor
, &psid
, &bDefaulted
))
3028 DumpString(prefix
, -1, pwptr
, plen
);
3029 if (!DumpSid(psid
, pwptr
, plen
))
3034 static BOOL
DumpGroup(PSECURITY_DESCRIPTOR SecurityDescriptor
, WCHAR
**pwptr
, ULONG
*plen
)
3036 static const WCHAR prefix
[] = {'G',':',0};
3040 if (!GetSecurityDescriptorGroup(SecurityDescriptor
, &psid
, &bDefaulted
))
3046 DumpString(prefix
, -1, pwptr
, plen
);
3047 if (!DumpSid(psid
, pwptr
, plen
))
3052 static BOOL
DumpDacl(PSECURITY_DESCRIPTOR SecurityDescriptor
, WCHAR
**pwptr
, ULONG
*plen
)
3054 static const WCHAR dacl
[] = {'D',':',0};
3055 SECURITY_DESCRIPTOR_CONTROL control
;
3056 BOOL present
, defaulted
;
3060 if (!GetSecurityDescriptorDacl(SecurityDescriptor
, &present
, &pacl
, &defaulted
))
3063 if (!GetSecurityDescriptorControl(SecurityDescriptor
, &control
, &revision
))
3069 DumpString(dacl
, 2, pwptr
, plen
);
3070 if (!DumpAcl(pacl
, pwptr
, plen
, control
& SE_DACL_PROTECTED
, control
& SE_DACL_AUTO_INHERIT_REQ
, control
& SE_DACL_AUTO_INHERITED
))
3075 static BOOL
DumpSacl(PSECURITY_DESCRIPTOR SecurityDescriptor
, WCHAR
**pwptr
, ULONG
*plen
)
3077 static const WCHAR sacl
[] = {'S',':',0};
3078 SECURITY_DESCRIPTOR_CONTROL control
;
3079 BOOL present
, defaulted
;
3083 if (!GetSecurityDescriptorSacl(SecurityDescriptor
, &present
, &pacl
, &defaulted
))
3086 if (!GetSecurityDescriptorControl(SecurityDescriptor
, &control
, &revision
))
3092 DumpString(sacl
, 2, pwptr
, plen
);
3093 if (!DumpAcl(pacl
, pwptr
, plen
, control
& SE_SACL_PROTECTED
, control
& SE_SACL_AUTO_INHERIT_REQ
, control
& SE_SACL_AUTO_INHERITED
))
3098 /******************************************************************************
3099 * ConvertSecurityDescriptorToStringSecurityDescriptorW [ADVAPI32.@]
3101 BOOL WINAPI
ConvertSecurityDescriptorToStringSecurityDescriptorW(PSECURITY_DESCRIPTOR SecurityDescriptor
, DWORD SDRevision
, SECURITY_INFORMATION RequestedInformation
, LPWSTR
*OutputString
, PULONG OutputLen
)
3106 if (SDRevision
!= SDDL_REVISION_1
)
3108 ERR("Program requested unknown SDDL revision %d\n", SDRevision
);
3109 SetLastError(ERROR_UNKNOWN_REVISION
);
3114 if (RequestedInformation
& OWNER_SECURITY_INFORMATION
)
3115 if (!DumpOwner(SecurityDescriptor
, NULL
, &len
))
3117 if (RequestedInformation
& GROUP_SECURITY_INFORMATION
)
3118 if (!DumpGroup(SecurityDescriptor
, NULL
, &len
))
3120 if (RequestedInformation
& DACL_SECURITY_INFORMATION
)
3121 if (!DumpDacl(SecurityDescriptor
, NULL
, &len
))
3123 if (RequestedInformation
& SACL_SECURITY_INFORMATION
)
3124 if (!DumpSacl(SecurityDescriptor
, NULL
, &len
))
3127 wstr
= wptr
= LocalAlloc(0, (len
+ 1)*sizeof(WCHAR
));
3133 if (RequestedInformation
& OWNER_SECURITY_INFORMATION
)
3134 if (!DumpOwner(SecurityDescriptor
, &wptr
, NULL
)) {
3138 if (RequestedInformation
& GROUP_SECURITY_INFORMATION
)
3139 if (!DumpGroup(SecurityDescriptor
, &wptr
, NULL
)) {
3143 if (RequestedInformation
& DACL_SECURITY_INFORMATION
)
3144 if (!DumpDacl(SecurityDescriptor
, &wptr
, NULL
)) {
3148 if (RequestedInformation
& SACL_SECURITY_INFORMATION
)
3149 if (!DumpSacl(SecurityDescriptor
, &wptr
, NULL
)) {
3155 TRACE("ret: %s, %d\n", wine_dbgstr_w(wstr
), len
);
3156 *OutputString
= wstr
;
3158 *OutputLen
= strlenW(*OutputString
)+1;
3162 /******************************************************************************
3163 * ConvertSecurityDescriptorToStringSecurityDescriptorA [ADVAPI32.@]
3165 BOOL WINAPI
ConvertSecurityDescriptorToStringSecurityDescriptorA(PSECURITY_DESCRIPTOR SecurityDescriptor
, DWORD SDRevision
, SECURITY_INFORMATION Information
, LPSTR
*OutputString
, PULONG OutputLen
)
3169 if (ConvertSecurityDescriptorToStringSecurityDescriptorW(SecurityDescriptor
, SDRevision
, Information
, &wstr
, &len
))
3173 lenA
= WideCharToMultiByte(CP_ACP
, 0, wstr
, len
, NULL
, 0, NULL
, NULL
);
3174 *OutputString
= heap_alloc(lenA
);
3176 if (*OutputString
== NULL
)
3183 WideCharToMultiByte(CP_ACP
, 0, wstr
, len
, *OutputString
, lenA
, NULL
, NULL
);
3186 if (OutputLen
!= NULL
)
3192 *OutputString
= NULL
;
3199 /******************************************************************************
3200 * ConvertStringSidToSidW [ADVAPI32.@]
3202 BOOL WINAPI
ConvertStringSidToSidW(LPCWSTR StringSid
, PSID
* Sid
)
3207 TRACE("%s, %p\n", debugstr_w(StringSid
), Sid
);
3208 if (GetVersion() & 0x80000000)
3209 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
3210 else if (!StringSid
|| !Sid
)
3211 SetLastError(ERROR_INVALID_PARAMETER
);
3212 else if (ParseStringSidToSid(StringSid
, NULL
, &cBytes
))
3214 PSID pSid
= *Sid
= LocalAlloc(0, cBytes
);
3216 bret
= ParseStringSidToSid(StringSid
, pSid
, &cBytes
);
3223 /******************************************************************************
3224 * ConvertStringSidToSidA [ADVAPI32.@]
3226 BOOL WINAPI
ConvertStringSidToSidA(LPCSTR StringSid
, PSID
* Sid
)
3230 TRACE("%s, %p\n", debugstr_a(StringSid
), Sid
);
3231 if (GetVersion() & 0x80000000)
3232 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
3233 else if (!StringSid
|| !Sid
)
3234 SetLastError(ERROR_INVALID_PARAMETER
);
3237 WCHAR
*wStringSid
= SERV_dup(StringSid
);
3238 bret
= ConvertStringSidToSidW(wStringSid
, Sid
);
3239 heap_free(wStringSid
);
3249 ConvertSidToStringSidW(PSID Sid
,
3253 UNICODE_STRING UnicodeString
;
3254 WCHAR FixedBuffer
[64];
3256 if (!RtlValidSid(Sid
))
3258 SetLastError(ERROR_INVALID_SID
);
3262 UnicodeString
.Length
= 0;
3263 UnicodeString
.MaximumLength
= sizeof(FixedBuffer
);
3264 UnicodeString
.Buffer
= FixedBuffer
;
3265 Status
= RtlConvertSidToUnicodeString(&UnicodeString
, Sid
, FALSE
);
3266 if (STATUS_BUFFER_TOO_SMALL
== Status
)
3268 Status
= RtlConvertSidToUnicodeString(&UnicodeString
, Sid
, TRUE
);
3271 if (!NT_SUCCESS(Status
))
3273 SetLastError(RtlNtStatusToDosError(Status
));
3277 *StringSid
= LocalAlloc(LMEM_FIXED
, UnicodeString
.Length
+ sizeof(WCHAR
));
3278 if (NULL
== *StringSid
)
3280 if (UnicodeString
.Buffer
!= FixedBuffer
)
3282 RtlFreeUnicodeString(&UnicodeString
);
3284 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
3288 MoveMemory(*StringSid
, UnicodeString
.Buffer
, UnicodeString
.Length
);
3289 ZeroMemory((PCHAR
) *StringSid
+ UnicodeString
.Length
, sizeof(WCHAR
));
3290 if (UnicodeString
.Buffer
!= FixedBuffer
)
3292 RtlFreeUnicodeString(&UnicodeString
);
3303 ConvertSidToStringSidA(PSID Sid
,
3309 if (!ConvertSidToStringSidW(Sid
, &StringSidW
))
3314 Len
= WideCharToMultiByte(CP_ACP
, 0, StringSidW
, -1, NULL
, 0, NULL
, NULL
);
3317 LocalFree(StringSidW
);
3318 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
3322 *StringSid
= LocalAlloc(LMEM_FIXED
, Len
);
3323 if (NULL
== *StringSid
)
3325 LocalFree(StringSidW
);
3326 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
3330 if (!WideCharToMultiByte(CP_ACP
, 0, StringSidW
, -1, *StringSid
, Len
, NULL
, NULL
))
3332 LocalFree(StringSid
);
3333 LocalFree(StringSidW
);
3337 LocalFree(StringSidW
);
3346 CreateProcessWithLogonW(LPCWSTR lpUsername
,
3350 LPCWSTR lpApplicationName
,
3351 LPWSTR lpCommandLine
,
3352 DWORD dwCreationFlags
,
3353 LPVOID lpEnvironment
,
3354 LPCWSTR lpCurrentDirectory
,
3355 LPSTARTUPINFOW lpStartupInfo
,
3356 LPPROCESS_INFORMATION lpProcessInformation
)
3358 FIXME("%s %s %s 0x%08x %s %s 0x%08x %p %s %p %p stub\n", debugstr_w(lpUsername
), debugstr_w(lpDomain
),
3359 debugstr_w(lpPassword
), dwLogonFlags
, debugstr_w(lpApplicationName
),
3360 debugstr_w(lpCommandLine
), dwCreationFlags
, lpEnvironment
, debugstr_w(lpCurrentDirectory
),
3361 lpStartupInfo
, lpProcessInformation
);
3366 BOOL WINAPI
CreateProcessWithTokenW(HANDLE token
, DWORD logon_flags
, LPCWSTR application_name
, LPWSTR command_line
,
3367 DWORD creation_flags
, void *environment
, LPCWSTR current_directory
, STARTUPINFOW
*startup_info
,
3368 PROCESS_INFORMATION
*process_information
)
3370 FIXME("%p 0x%08x %s %s 0x%08x %p %s %p %p - semi-stub\n", token
,
3371 logon_flags
, debugstr_w(application_name
), debugstr_w(command_line
),
3372 creation_flags
, environment
, debugstr_w(current_directory
),
3373 startup_info
, process_information
);
3375 /* FIXME: check if handles should be inherited */
3376 return CreateProcessW( application_name
, command_line
, NULL
, NULL
, FALSE
, creation_flags
, environment
,
3377 current_directory
, startup_info
, process_information
);
3384 DuplicateTokenEx(IN HANDLE ExistingTokenHandle
,
3385 IN DWORD dwDesiredAccess
,
3386 IN LPSECURITY_ATTRIBUTES lpTokenAttributes OPTIONAL
,
3387 IN SECURITY_IMPERSONATION_LEVEL ImpersonationLevel
,
3388 IN TOKEN_TYPE TokenType
,
3389 OUT PHANDLE DuplicateTokenHandle
)
3391 OBJECT_ATTRIBUTES ObjectAttributes
;
3393 SECURITY_QUALITY_OF_SERVICE Sqos
;
3395 TRACE("%p 0x%08x 0x%08x 0x%08x %p\n", ExistingTokenHandle
, dwDesiredAccess
,
3396 ImpersonationLevel
, TokenType
, DuplicateTokenHandle
);
3398 Sqos
.Length
= sizeof(SECURITY_QUALITY_OF_SERVICE
);
3399 Sqos
.ImpersonationLevel
= ImpersonationLevel
;
3400 Sqos
.ContextTrackingMode
= 0;
3401 Sqos
.EffectiveOnly
= FALSE
;
3403 if (lpTokenAttributes
!= NULL
)
3405 InitializeObjectAttributes(&ObjectAttributes
,
3407 lpTokenAttributes
->bInheritHandle
? OBJ_INHERIT
: 0,
3409 lpTokenAttributes
->lpSecurityDescriptor
);
3413 InitializeObjectAttributes(&ObjectAttributes
,
3420 ObjectAttributes
.SecurityQualityOfService
= &Sqos
;
3422 Status
= NtDuplicateToken(ExistingTokenHandle
,
3427 DuplicateTokenHandle
);
3428 if (!NT_SUCCESS(Status
))
3430 ERR("NtDuplicateToken failed: Status %08x\n", Status
);
3431 SetLastError(RtlNtStatusToDosError(Status
));
3435 TRACE("Returning token %p.\n", *DuplicateTokenHandle
);
3444 DuplicateToken(IN HANDLE ExistingTokenHandle
,
3445 IN SECURITY_IMPERSONATION_LEVEL ImpersonationLevel
,
3446 OUT PHANDLE DuplicateTokenHandle
)
3448 return DuplicateTokenEx(ExistingTokenHandle
,
3449 TOKEN_IMPERSONATE
| TOKEN_QUERY
,
3453 DuplicateTokenHandle
);
3456 /******************************************************************************
3457 * ComputeStringSidSize
3459 static DWORD
ComputeStringSidSize(LPCWSTR StringSid
)
3461 if (StringSid
[0] == 'S' && StringSid
[1] == '-') /* S-R-I(-S)+ */
3466 if (*StringSid
== '-')
3472 return GetSidLengthRequired(ctok
- 2);
3474 else /* String constant format - Only available in winxp and above */
3478 for (i
= 0; i
< sizeof(WellKnownSids
)/sizeof(WellKnownSids
[0]); i
++)
3479 if (!strncmpW(WellKnownSids
[i
].wstr
, StringSid
, 2))
3480 return GetSidLengthRequired(WellKnownSids
[i
].Sid
.SubAuthorityCount
);
3482 for (i
= 0; i
< sizeof(WellKnownRids
)/sizeof(WellKnownRids
[0]); i
++)
3483 if (!strncmpW(WellKnownRids
[i
].wstr
, StringSid
, 2))
3486 ADVAPI_GetComputerSid(&local
);
3487 return GetSidLengthRequired(*GetSidSubAuthorityCount(&local
) + 1);
3492 return GetSidLengthRequired(0);
3495 /******************************************************************************
3496 * ParseStringSidToSid
3498 static BOOL
ParseStringSidToSid(LPCWSTR StringSid
, PSID pSid
, LPDWORD cBytes
)
3503 TRACE("%s, %p, %p\n", debugstr_w(StringSid
), pSid
, cBytes
);
3506 SetLastError(ERROR_INVALID_PARAMETER
);
3507 TRACE("StringSid is NULL, returning FALSE\n");
3511 while (*StringSid
== ' ')
3515 goto lend
; /* ERROR_INVALID_SID */
3517 *cBytes
= ComputeStringSidSize(StringSid
);
3518 if (!pisid
) /* Simply compute the size */
3520 TRACE("only size requested, returning TRUE with %d\n", *cBytes
);
3524 if (StringSid
[0] == 'S' && StringSid
[1] == '-') /* S-R-I-S-S */
3526 DWORD i
= 0, identAuth
;
3527 DWORD csubauth
= ((*cBytes
- GetSidLengthRequired(0)) / sizeof(DWORD
));
3529 StringSid
+= 2; /* Advance to Revision */
3530 pisid
->Revision
= atoiW(StringSid
);
3532 if (pisid
->Revision
!= SDDL_REVISION
)
3534 TRACE("Revision %d is unknown\n", pisid
->Revision
);
3535 goto lend
; /* ERROR_INVALID_SID */
3539 TRACE("SubAuthorityCount is 0\n");
3540 goto lend
; /* ERROR_INVALID_SID */
3543 pisid
->SubAuthorityCount
= csubauth
;
3545 /* Advance to identifier authority */
3546 while (*StringSid
&& *StringSid
!= '-')
3548 if (*StringSid
== '-')
3551 /* MS' implementation can't handle values greater than 2^32 - 1, so
3552 * we don't either; assume most significant bytes are always 0
3554 pisid
->IdentifierAuthority
.Value
[0] = 0;
3555 pisid
->IdentifierAuthority
.Value
[1] = 0;
3556 identAuth
= atoiW(StringSid
);
3557 pisid
->IdentifierAuthority
.Value
[5] = identAuth
& 0xff;
3558 pisid
->IdentifierAuthority
.Value
[4] = (identAuth
& 0xff00) >> 8;
3559 pisid
->IdentifierAuthority
.Value
[3] = (identAuth
& 0xff0000) >> 16;
3560 pisid
->IdentifierAuthority
.Value
[2] = (identAuth
& 0xff000000) >> 24;
3562 /* Advance to first sub authority */
3563 while (*StringSid
&& *StringSid
!= '-')
3565 if (*StringSid
== '-')
3570 pisid
->SubAuthority
[i
++] = atoiW(StringSid
);
3572 while (*StringSid
&& *StringSid
!= '-')
3574 if (*StringSid
== '-')
3578 if (i
!= pisid
->SubAuthorityCount
)
3579 goto lend
; /* ERROR_INVALID_SID */
3583 else /* String constant format - Only available in winxp and above */
3586 pisid
->Revision
= SDDL_REVISION
;
3588 for (i
= 0; i
< sizeof(WellKnownSids
)/sizeof(WellKnownSids
[0]); i
++)
3589 if (!strncmpW(WellKnownSids
[i
].wstr
, StringSid
, 2))
3592 pisid
->SubAuthorityCount
= WellKnownSids
[i
].Sid
.SubAuthorityCount
;
3593 pisid
->IdentifierAuthority
= WellKnownSids
[i
].Sid
.IdentifierAuthority
;
3594 for (j
= 0; j
< WellKnownSids
[i
].Sid
.SubAuthorityCount
; j
++)
3595 pisid
->SubAuthority
[j
] = WellKnownSids
[i
].Sid
.SubAuthority
[j
];
3599 for (i
= 0; i
< sizeof(WellKnownRids
)/sizeof(WellKnownRids
[0]); i
++)
3600 if (!strncmpW(WellKnownRids
[i
].wstr
, StringSid
, 2))
3602 ADVAPI_GetComputerSid(pisid
);
3603 pisid
->SubAuthority
[pisid
->SubAuthorityCount
] = WellKnownRids
[i
].Rid
;
3604 pisid
->SubAuthorityCount
++;
3609 FIXME("String constant not supported: %s\n", debugstr_wn(StringSid
, 2));
3614 SetLastError(ERROR_INVALID_SID
);
3616 TRACE("returning %s\n", bret
? "TRUE" : "FALSE");
3620 /**********************************************************************
3621 * GetNamedSecurityInfoA EXPORTED
3627 GetNamedSecurityInfoA(LPSTR pObjectName
,
3628 SE_OBJECT_TYPE ObjectType
,
3629 SECURITY_INFORMATION SecurityInfo
,
3634 PSECURITY_DESCRIPTOR
*ppSecurityDescriptor
)
3640 TRACE("%s %d %d %p %p %p %p %p\n", pObjectName
, ObjectType
, SecurityInfo
,
3641 ppsidOwner
, ppsidGroup
, ppDacl
, ppSacl
, ppSecurityDescriptor
);
3645 len
= MultiByteToWideChar( CP_ACP
, 0, pObjectName
, -1, NULL
, 0 );
3646 wstr
= HeapAlloc( GetProcessHeap(), 0, len
*sizeof(WCHAR
));
3647 MultiByteToWideChar( CP_ACP
, 0, pObjectName
, -1, wstr
, len
);
3650 r
= GetNamedSecurityInfoW( wstr
, ObjectType
, SecurityInfo
, ppsidOwner
,
3651 ppsidGroup
, ppDacl
, ppSacl
, ppSecurityDescriptor
);
3653 HeapFree( GetProcessHeap(), 0, wstr
);
3658 /******************************************************************************
3659 * GetWindowsAccountDomainSid [ADVAPI32.@]
3661 BOOL WINAPI
GetWindowsAccountDomainSid( PSID sid
, PSID domain_sid
, DWORD
*size
)
3663 SID_IDENTIFIER_AUTHORITY domain_ident
= { SECURITY_NT_AUTHORITY
};
3664 DWORD required_size
;
3667 FIXME( "(%p %p %p): semi-stub\n", sid
, domain_sid
, size
);
3669 if (!sid
|| !IsValidSid( sid
))
3671 SetLastError( ERROR_INVALID_SID
);
3677 SetLastError( ERROR_INVALID_PARAMETER
);
3681 if (*GetSidSubAuthorityCount( sid
) < 4)
3683 SetLastError( ERROR_INVALID_SID
);
3687 required_size
= GetSidLengthRequired( 4 );
3688 if (*size
< required_size
|| !domain_sid
)
3690 *size
= required_size
;
3691 SetLastError( domain_sid
? ERROR_INSUFFICIENT_BUFFER
:
3692 ERROR_INVALID_PARAMETER
);
3696 InitializeSid( domain_sid
, &domain_ident
, 4 );
3697 for (i
= 0; i
< 4; i
++)
3698 *GetSidSubAuthority( domain_sid
, i
) = *GetSidSubAuthority( sid
, i
);
3700 *size
= required_size
;
3709 EqualDomainSid(IN PSID pSid1
,