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
},
124 static const SID sidWorld
= { SID_REVISION
, 1, { SECURITY_WORLD_SID_AUTHORITY
} , { SECURITY_WORLD_RID
} };
127 static const WCHAR SDDL_NO_READ_UP
[] = {'N','R',0};
128 static const WCHAR SDDL_NO_WRITE_UP
[] = {'N','W',0};
129 static const WCHAR SDDL_NO_EXECUTE_UP
[] = {'N','X',0};
134 static const WCHAR SDDL_ACCESS_ALLOWED
[] = {'A',0};
135 static const WCHAR SDDL_ACCESS_DENIED
[] = {'D',0};
137 static const WCHAR SDDL_OBJECT_ACCESS_ALLOWED
[] = {'O','A',0};
138 static const WCHAR SDDL_OBJECT_ACCESS_DENIED
[] = {'O','D',0};
140 static const WCHAR SDDL_AUDIT
[] = {'A','U',0};
141 static const WCHAR SDDL_ALARM
[] = {'A','L',0};
142 static const WCHAR SDDL_MANDATORY_LABEL
[] = {'M','L',0};
144 static const WCHAR SDDL_OBJECT_AUDIT
[] = {'O','U',0};
145 static const WCHAR SDDL_OBJECT_ALARM
[] = {'O','L',0};
151 #define ADS_RIGHT_DS_CREATE_CHILD 0x0001
152 #define ADS_RIGHT_DS_DELETE_CHILD 0x0002
153 #define ADS_RIGHT_ACTRL_DS_LIST 0x0004
154 #define ADS_RIGHT_DS_SELF 0x0008
155 #define ADS_RIGHT_DS_READ_PROP 0x0010
156 #define ADS_RIGHT_DS_WRITE_PROP 0x0020
157 #define ADS_RIGHT_DS_DELETE_TREE 0x0040
158 #define ADS_RIGHT_DS_LIST_OBJECT 0x0080
159 #define ADS_RIGHT_DS_CONTROL_ACCESS 0x0100
164 static const WCHAR SDDL_CONTAINER_INHERIT
[] = {'C','I',0};
165 static const WCHAR SDDL_OBJECT_INHERIT
[] = {'O','I',0};
166 static const WCHAR SDDL_NO_PROPAGATE
[] = {'N','P',0};
167 static const WCHAR SDDL_INHERIT_ONLY
[] = {'I','O',0};
168 static const WCHAR SDDL_INHERITED
[] = {'I','D',0};
169 static const WCHAR SDDL_AUDIT_SUCCESS
[] = {'S','A',0};
170 static const WCHAR SDDL_AUDIT_FAILURE
[] = {'F','A',0};
172 static const char * debugstr_sid(PSID sid
)
175 SID
* psid
= (SID
*)sid
;
180 auth
= psid
->IdentifierAuthority
.Value
[5] +
181 (psid
->IdentifierAuthority
.Value
[4] << 8) +
182 (psid
->IdentifierAuthority
.Value
[3] << 16) +
183 (psid
->IdentifierAuthority
.Value
[2] << 24);
185 switch (psid
->SubAuthorityCount
) {
187 return wine_dbg_sprintf("S-%d-%d", psid
->Revision
, auth
);
189 return wine_dbg_sprintf("S-%d-%d-%lu", psid
->Revision
, auth
,
190 psid
->SubAuthority
[0]);
192 return wine_dbg_sprintf("S-%d-%d-%lu-%lu", psid
->Revision
, auth
,
193 psid
->SubAuthority
[0], psid
->SubAuthority
[1]);
195 return wine_dbg_sprintf("S-%d-%d-%lu-%lu-%lu", psid
->Revision
, auth
,
196 psid
->SubAuthority
[0], psid
->SubAuthority
[1], psid
->SubAuthority
[2]);
198 return wine_dbg_sprintf("S-%d-%d-%lu-%lu-%lu-%lu", psid
->Revision
, auth
,
199 psid
->SubAuthority
[0], psid
->SubAuthority
[1], psid
->SubAuthority
[2],
200 psid
->SubAuthority
[3]);
202 return wine_dbg_sprintf("S-%d-%d-%lu-%lu-%lu-%lu-%lu", psid
->Revision
, auth
,
203 psid
->SubAuthority
[0], psid
->SubAuthority
[1], psid
->SubAuthority
[2],
204 psid
->SubAuthority
[3], psid
->SubAuthority
[4]);
206 return wine_dbg_sprintf("S-%d-%d-%lu-%lu-%lu-%lu-%lu-%lu", psid
->Revision
, auth
,
207 psid
->SubAuthority
[3], psid
->SubAuthority
[1], psid
->SubAuthority
[2],
208 psid
->SubAuthority
[0], psid
->SubAuthority
[4], psid
->SubAuthority
[5]);
210 return wine_dbg_sprintf("S-%d-%d-%lu-%lu-%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], psid
->SubAuthority
[5],
213 psid
->SubAuthority
[6]);
215 return wine_dbg_sprintf("S-%d-%d-%lu-%lu-%lu-%lu-%lu-%lu-%lu-%lu", psid
->Revision
, auth
,
216 psid
->SubAuthority
[0], psid
->SubAuthority
[1], psid
->SubAuthority
[2],
217 psid
->SubAuthority
[3], psid
->SubAuthority
[4], psid
->SubAuthority
[5],
218 psid
->SubAuthority
[6], psid
->SubAuthority
[7]);
223 /* set last error code from NT status and get the proper boolean return value */
224 /* used for functions that are a simple wrapper around the corresponding ntdll API */
225 static __inline BOOL
set_ntstatus( NTSTATUS status
)
227 if (!NT_SUCCESS(status
)) SetLastError( RtlNtStatusToDosError( status
));
228 return NT_SUCCESS(status
);
231 static LPWSTR
SERV_dup( LPCSTR str
)
238 len
= MultiByteToWideChar( CP_ACP
, 0, str
, -1, NULL
, 0 );
239 wstr
= heap_alloc( len
*sizeof (WCHAR
) );
240 MultiByteToWideChar( CP_ACP
, 0, str
, -1, wstr
, len
);
244 /************************************************************
245 * ADVAPI_IsLocalComputer
247 * Checks whether the server name indicates local machine.
249 BOOL
ADVAPI_IsLocalComputer(LPCWSTR ServerName
)
251 DWORD dwSize
= MAX_COMPUTERNAME_LENGTH
+ 1;
255 if (!ServerName
|| !ServerName
[0])
258 buf
= heap_alloc(dwSize
* sizeof(WCHAR
));
259 Result
= GetComputerNameW(buf
, &dwSize
);
260 if (Result
&& (ServerName
[0] == '\\') && (ServerName
[1] == '\\'))
262 Result
= Result
&& !lstrcmpW(ServerName
, buf
);
268 /************************************************************
269 * ADVAPI_GetComputerSid
271 BOOL
ADVAPI_GetComputerSid(PSID sid
)
273 static const struct /* same fields as struct SID */
276 BYTE SubAuthorityCount
;
277 SID_IDENTIFIER_AUTHORITY IdentifierAuthority
;
278 DWORD SubAuthority
[4];
280 { SID_REVISION
, 4, { SECURITY_NT_AUTHORITY
}, { SECURITY_NT_NON_UNIQUE
, 0, 0, 0 } };
282 memcpy( sid
, &computer_sid
, sizeof(computer_sid
) );
286 /* Exported functions */
292 OpenProcessToken(HANDLE ProcessHandle
,
298 TRACE("%p, %x, %p.\n", ProcessHandle
, DesiredAccess
, TokenHandle
);
300 Status
= NtOpenProcessToken(ProcessHandle
,
303 if (!NT_SUCCESS(Status
))
305 ERR("NtOpenProcessToken failed! Status %08x.\n", Status
);
306 SetLastError(RtlNtStatusToDosError(Status
));
310 TRACE("Returning token %p.\n", *TokenHandle
);
315 /******************************************************************************
316 * OpenThreadToken [ADVAPI32.@]
318 * Opens the access token associated with a thread handle.
321 * ThreadHandle [I] Handle to process
322 * DesiredAccess [I] Desired access to the thread
324 * TokenHandle [O] Destination for the token handle
327 * Success: TRUE. TokenHandle contains the access token.
331 * See NtOpenThreadToken.
334 OpenThreadToken( HANDLE ThreadHandle
, DWORD DesiredAccess
,
335 BOOL OpenAsSelf
, HANDLE
*TokenHandle
)
337 return set_ntstatus( NtOpenThreadToken(ThreadHandle
, DesiredAccess
, OpenAsSelf
, TokenHandle
));
344 AdjustTokenGroups(HANDLE TokenHandle
,
346 PTOKEN_GROUPS NewState
,
348 PTOKEN_GROUPS PreviousState
,
353 Status
= NtAdjustGroupsToken(TokenHandle
,
358 (PULONG
)ReturnLength
);
359 if (!NT_SUCCESS(Status
))
361 SetLastError(RtlNtStatusToDosError(Status
));
372 AdjustTokenPrivileges(HANDLE TokenHandle
,
373 BOOL DisableAllPrivileges
,
374 PTOKEN_PRIVILEGES NewState
,
376 PTOKEN_PRIVILEGES PreviousState
,
381 Status
= NtAdjustPrivilegesToken(TokenHandle
,
382 DisableAllPrivileges
,
386 (PULONG
)ReturnLength
);
387 if (STATUS_NOT_ALL_ASSIGNED
== Status
)
389 SetLastError(ERROR_NOT_ALL_ASSIGNED
);
393 if (!NT_SUCCESS(Status
))
395 SetLastError(RtlNtStatusToDosError(Status
));
399 /* AdjustTokenPrivileges is documented to do this */
400 SetLastError(ERROR_SUCCESS
);
409 GetTokenInformation(HANDLE TokenHandle
,
410 TOKEN_INFORMATION_CLASS TokenInformationClass
,
411 LPVOID TokenInformation
,
412 DWORD TokenInformationLength
,
417 Status
= NtQueryInformationToken(TokenHandle
,
418 TokenInformationClass
,
420 TokenInformationLength
,
421 (PULONG
)ReturnLength
);
422 if (!NT_SUCCESS(Status
))
424 SetLastError(RtlNtStatusToDosError(Status
));
435 SetTokenInformation(HANDLE TokenHandle
,
436 TOKEN_INFORMATION_CLASS TokenInformationClass
,
437 LPVOID TokenInformation
,
438 DWORD TokenInformationLength
)
442 Status
= NtSetInformationToken(TokenHandle
,
443 TokenInformationClass
,
445 TokenInformationLength
);
446 if (!NT_SUCCESS(Status
))
448 SetLastError(RtlNtStatusToDosError(Status
));
459 SetThreadToken(IN PHANDLE ThreadHandle OPTIONAL
,
460 IN HANDLE TokenHandle
)
465 hThread
= (ThreadHandle
!= NULL
) ? *ThreadHandle
: NtCurrentThread();
467 Status
= NtSetInformationThread(hThread
,
468 ThreadImpersonationToken
,
471 if (!NT_SUCCESS(Status
))
473 SetLastError(RtlNtStatusToDosError(Status
));
480 /*************************************************************************
481 * CreateRestrictedToken [ADVAPI32.@]
483 * Create a new more restricted token from an existing token.
486 * baseToken [I] Token to base the new restricted token on
488 * nDisableSids [I] Length of disableSids array
489 * disableSids [I] Array of SIDs to disable in the new token
490 * nDeletePrivs [I] Length of deletePrivs array
491 * deletePrivs [I] Array of privileges to delete in the new token
492 * nRestrictSids [I] Length of restrictSids array
493 * restrictSids [I] Array of SIDs to restrict in the new token
494 * newToken [O] Address where the new token is stored
500 BOOL WINAPI
CreateRestrictedToken(
504 PSID_AND_ATTRIBUTES disableSids
,
506 PLUID_AND_ATTRIBUTES deletePrivs
,
508 PSID_AND_ATTRIBUTES restrictSids
,
512 SECURITY_IMPERSONATION_LEVEL level
= SecurityAnonymous
;
515 FIXME("(%p, 0x%x, %u, %p, %u, %p, %u, %p, %p): stub\n",
516 baseToken
, flags
, nDisableSids
, disableSids
,
517 nDeletePrivs
, deletePrivs
,
518 nRestrictSids
, restrictSids
,
522 if (!GetTokenInformation( baseToken
, TokenType
, &type
, size
, &size
)) return FALSE
;
523 if (type
== TokenImpersonation
)
525 size
= sizeof(level
);
526 if (!GetTokenInformation( baseToken
, TokenImpersonationLevel
, &level
, size
, &size
))
529 return DuplicateTokenEx( baseToken
, MAXIMUM_ALLOWED
, NULL
, level
, type
, newToken
);
532 /******************************************************************************
533 * AllocateAndInitializeSid [ADVAPI32.@]
536 * pIdentifierAuthority []
537 * nSubAuthorityCount []
549 AllocateAndInitializeSid( PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority
,
550 BYTE nSubAuthorityCount
,
551 DWORD nSubAuthority0
, DWORD nSubAuthority1
,
552 DWORD nSubAuthority2
, DWORD nSubAuthority3
,
553 DWORD nSubAuthority4
, DWORD nSubAuthority5
,
554 DWORD nSubAuthority6
, DWORD nSubAuthority7
,
557 return set_ntstatus( RtlAllocateAndInitializeSid(
558 pIdentifierAuthority
, nSubAuthorityCount
,
559 nSubAuthority0
, nSubAuthority1
, nSubAuthority2
, nSubAuthority3
,
560 nSubAuthority4
, nSubAuthority5
, nSubAuthority6
, nSubAuthority7
,
568 * Docs says this function does NOT return a value
569 * even thou it's defined to return a PVOID...
575 return RtlFreeSid(pSid
);
578 /******************************************************************************
579 * CopySid [ADVAPI32.@]
582 * nDestinationSidLength []
587 CopySid( DWORD nDestinationSidLength
, PSID pDestinationSid
, PSID pSourceSid
)
589 return set_ntstatus(RtlCopySid(nDestinationSidLength
, pDestinationSid
, pSourceSid
));
597 CreateWellKnownSid(IN WELL_KNOWN_SID_TYPE WellKnownSidType
,
598 IN PSID DomainSid OPTIONAL
,
603 TRACE("(%d, %s, %p, %p)\n", WellKnownSidType
, debugstr_sid(DomainSid
), pSid
, cbSid
);
605 if (cbSid
== NULL
|| (DomainSid
&& !IsValidSid(DomainSid
)))
607 SetLastError(ERROR_INVALID_PARAMETER
);
611 for (i
= 0; i
< sizeof(WellKnownSids
)/sizeof(WellKnownSids
[0]); i
++) {
612 if (WellKnownSids
[i
].Type
== WellKnownSidType
) {
613 DWORD length
= GetSidLengthRequired(WellKnownSids
[i
].Sid
.SubAuthorityCount
);
618 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
623 SetLastError(ERROR_INVALID_PARAMETER
);
626 CopyMemory(pSid
, &WellKnownSids
[i
].Sid
.Revision
, length
);
632 if (DomainSid
== NULL
|| *GetSidSubAuthorityCount(DomainSid
) == SID_MAX_SUB_AUTHORITIES
)
634 SetLastError(ERROR_INVALID_PARAMETER
);
638 for (i
= 0; i
< sizeof(WellKnownRids
)/sizeof(WellKnownRids
[0]); i
++)
639 if (WellKnownRids
[i
].Type
== WellKnownSidType
) {
640 UCHAR domain_subauth
= *GetSidSubAuthorityCount(DomainSid
);
641 DWORD domain_sid_length
= GetSidLengthRequired(domain_subauth
);
642 DWORD output_sid_length
= GetSidLengthRequired(domain_subauth
+ 1);
644 if (*cbSid
< output_sid_length
)
646 *cbSid
= output_sid_length
;
647 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
652 SetLastError(ERROR_INVALID_PARAMETER
);
655 CopyMemory(pSid
, DomainSid
, domain_sid_length
);
656 (*GetSidSubAuthorityCount(pSid
))++;
657 (*GetSidSubAuthority(pSid
, domain_subauth
)) = WellKnownRids
[i
].Rid
;
658 *cbSid
= output_sid_length
;
662 SetLastError(ERROR_INVALID_PARAMETER
);
671 IsWellKnownSid(IN PSID pSid
,
672 IN WELL_KNOWN_SID_TYPE WellKnownSidType
)
675 TRACE("(%s, %d)\n", debugstr_sid(pSid
), WellKnownSidType
);
677 for (i
= 0; i
< sizeof(WellKnownSids
) / sizeof(WellKnownSids
[0]); i
++)
679 if (WellKnownSids
[i
].Type
== WellKnownSidType
)
681 if (EqualSid(pSid
, (PSID
)(&WellKnownSids
[i
].Sid
.Revision
)))
694 IsValidSid(PSID pSid
)
696 return (BOOL
)RtlValidSid(pSid
);
707 SetLastError(ERROR_SUCCESS
);
708 return RtlEqualSid (pSid1
, pSid2
);
716 EqualPrefixSid(PSID pSid1
,
719 return RtlEqualPrefixSid (pSid1
, pSid2
);
727 GetSidLengthRequired(UCHAR nSubAuthorityCount
)
729 return (DWORD
)RtlLengthRequiredSid(nSubAuthorityCount
);
737 InitializeSid(PSID Sid
,
738 PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority
,
739 BYTE nSubAuthorityCount
)
743 Status
= RtlInitializeSid(Sid
,
744 pIdentifierAuthority
,
746 if (!NT_SUCCESS(Status
))
748 SetLastError(RtlNtStatusToDosError(Status
));
758 PSID_IDENTIFIER_AUTHORITY
760 GetSidIdentifierAuthority(PSID pSid
)
762 SetLastError(ERROR_SUCCESS
);
763 return RtlIdentifierAuthoritySid(pSid
);
771 GetSidSubAuthority(PSID pSid
,
774 SetLastError(ERROR_SUCCESS
);
775 return (PDWORD
)RtlSubAuthoritySid(pSid
, nSubAuthority
);
783 GetSidSubAuthorityCount(PSID pSid
)
785 SetLastError(ERROR_SUCCESS
);
786 return RtlSubAuthorityCountSid(pSid
);
794 GetLengthSid(PSID pSid
)
796 return (DWORD
)RtlLengthSid(pSid
);
804 InitializeSecurityDescriptor(PSECURITY_DESCRIPTOR pSecurityDescriptor
,
809 Status
= RtlCreateSecurityDescriptor(pSecurityDescriptor
,
811 if (!NT_SUCCESS(Status
))
813 SetLastError(RtlNtStatusToDosError(Status
));
825 MakeAbsoluteSD(PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor
,
826 PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor
,
827 LPDWORD lpdwAbsoluteSecurityDescriptorSize
,
829 LPDWORD lpdwDaclSize
,
831 LPDWORD lpdwSaclSize
,
833 LPDWORD lpdwOwnerSize
,
835 LPDWORD lpdwPrimaryGroupSize
)
839 Status
= RtlSelfRelativeToAbsoluteSD(pSelfRelativeSecurityDescriptor
,
840 pAbsoluteSecurityDescriptor
,
841 lpdwAbsoluteSecurityDescriptorSize
,
849 lpdwPrimaryGroupSize
);
850 if (!NT_SUCCESS(Status
))
852 SetLastError(RtlNtStatusToDosError(Status
));
859 /******************************************************************************
860 * GetKernelObjectSecurity [ADVAPI32.@]
862 BOOL WINAPI
GetKernelObjectSecurity(
864 SECURITY_INFORMATION RequestedInformation
,
865 PSECURITY_DESCRIPTOR pSecurityDescriptor
,
867 LPDWORD lpnLengthNeeded
)
869 TRACE("(%p,0x%08x,%p,0x%08x,%p)\n", Handle
, RequestedInformation
,
870 pSecurityDescriptor
, nLength
, lpnLengthNeeded
);
872 return set_ntstatus( NtQuerySecurityObject(Handle
, RequestedInformation
, pSecurityDescriptor
,
873 nLength
, lpnLengthNeeded
));
881 InitializeAcl(PACL pAcl
,
887 Status
= RtlCreateAcl(pAcl
,
890 if (!NT_SUCCESS(Status
))
892 SetLastError(RtlNtStatusToDosError(Status
));
899 BOOL WINAPI
ImpersonateNamedPipeClient( HANDLE hNamedPipe
)
901 IO_STATUS_BLOCK io_block
;
903 TRACE("(%p)\n", hNamedPipe
);
905 return set_ntstatus( NtFsControlFile(hNamedPipe
, NULL
, NULL
, NULL
,
906 &io_block
, FSCTL_PIPE_IMPERSONATE
, NULL
, 0, NULL
, 0) );
914 AddAccessAllowedAce(PACL pAcl
,
921 Status
= RtlAddAccessAllowedAce(pAcl
,
925 if (!NT_SUCCESS(Status
))
927 SetLastError(RtlNtStatusToDosError(Status
));
938 AddAccessAllowedAceEx(PACL pAcl
,
946 Status
= RtlAddAccessAllowedAceEx(pAcl
,
951 if (!NT_SUCCESS(Status
))
953 SetLastError(RtlNtStatusToDosError(Status
));
965 AddAccessDeniedAce(PACL pAcl
,
972 Status
= RtlAddAccessDeniedAce(pAcl
,
976 if (!NT_SUCCESS(Status
))
978 SetLastError(RtlNtStatusToDosError(Status
));
989 AddAccessDeniedAceEx(PACL pAcl
,
997 Status
= RtlAddAccessDeniedAceEx(pAcl
,
1002 if (!NT_SUCCESS(Status
))
1004 SetLastError(RtlNtStatusToDosError(Status
));
1017 DWORD dwAceRevision
,
1018 DWORD dwStartingAceIndex
,
1020 DWORD nAceListLength
)
1024 Status
= RtlAddAce(pAcl
,
1029 if (!NT_SUCCESS(Status
))
1031 SetLastError(RtlNtStatusToDosError(Status
));
1038 /******************************************************************************
1039 * DeleteAce [ADVAPI32.@]
1041 BOOL WINAPI
DeleteAce(PACL pAcl
, DWORD dwAceIndex
)
1043 return set_ntstatus(RtlDeleteAce(pAcl
, dwAceIndex
));
1051 FindFirstFreeAce(PACL pAcl
,
1054 return RtlFirstFreeAce(pAcl
,
1058 /******************************************************************************
1059 * GetAce [ADVAPI32.@]
1061 BOOL WINAPI
GetAce(PACL pAcl
,DWORD dwAceIndex
,LPVOID
*pAce
)
1063 return set_ntstatus(RtlGetAce(pAcl
, dwAceIndex
, pAce
));
1066 /******************************************************************************
1067 * GetAclInformation [ADVAPI32.@]
1069 BOOL WINAPI
GetAclInformation(
1071 LPVOID pAclInformation
,
1072 DWORD nAclInformationLength
,
1073 ACL_INFORMATION_CLASS dwAclInformationClass
)
1075 return set_ntstatus(RtlQueryInformationAcl(pAcl
, pAclInformation
,
1076 nAclInformationLength
, dwAclInformationClass
));
1084 IsValidAcl(PACL pAcl
)
1086 return RtlValidAcl (pAcl
);
1093 AllocateLocallyUniqueId(PLUID Luid
)
1097 Status
= NtAllocateLocallyUniqueId (Luid
);
1098 if (!NT_SUCCESS (Status
))
1100 SetLastError(RtlNtStatusToDosError(Status
));
1107 /**********************************************************************
1108 * LookupPrivilegeDisplayNameA EXPORTED
1114 LookupPrivilegeDisplayNameA(LPCSTR lpSystemName
,
1116 LPSTR lpDisplayName
,
1117 LPDWORD cchDisplayName
,
1118 LPDWORD lpLanguageId
)
1120 UNICODE_STRING lpSystemNameW
;
1121 UNICODE_STRING lpNameW
;
1125 TRACE("%s %s %p %p %p\n", debugstr_a(lpSystemName
), debugstr_a(lpName
), lpName
, cchDisplayName
, lpLanguageId
);
1127 RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW
, lpSystemName
);
1128 RtlCreateUnicodeStringFromAsciiz(&lpNameW
, lpName
);
1129 ret
= LookupPrivilegeDisplayNameW(lpSystemNameW
.Buffer
, lpNameW
.Buffer
, NULL
, &wLen
, lpLanguageId
);
1130 if (!ret
&& GetLastError() == ERROR_INSUFFICIENT_BUFFER
)
1132 LPWSTR lpDisplayNameW
= HeapAlloc(GetProcessHeap(), 0, wLen
* sizeof(WCHAR
));
1134 ret
= LookupPrivilegeDisplayNameW(lpSystemNameW
.Buffer
, lpNameW
.Buffer
, lpDisplayNameW
,
1135 &wLen
, lpLanguageId
);
1138 unsigned int len
= WideCharToMultiByte(CP_ACP
, 0, lpDisplayNameW
, -1, lpDisplayName
,
1139 *cchDisplayName
, NULL
, NULL
);
1143 /* WideCharToMultiByte failed */
1146 else if (len
> *cchDisplayName
)
1148 *cchDisplayName
= len
;
1149 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
1154 /* WideCharToMultiByte succeeded, output length needs to be
1155 * length not including NULL terminator
1157 *cchDisplayName
= len
- 1;
1160 HeapFree(GetProcessHeap(), 0, lpDisplayNameW
);
1162 RtlFreeUnicodeString(&lpSystemNameW
);
1163 RtlFreeUnicodeString(&lpNameW
);
1167 /**********************************************************************
1168 * LookupPrivilegeNameA EXPORTED
1174 LookupPrivilegeNameA(LPCSTR lpSystemName
,
1179 UNICODE_STRING lpSystemNameW
;
1183 TRACE("%s %p %p %p\n", debugstr_a(lpSystemName
), lpLuid
, lpName
, cchName
);
1185 RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW
, lpSystemName
);
1186 ret
= LookupPrivilegeNameW(lpSystemNameW
.Buffer
, lpLuid
, NULL
, &wLen
);
1187 if (!ret
&& GetLastError() == ERROR_INSUFFICIENT_BUFFER
)
1189 LPWSTR lpNameW
= HeapAlloc(GetProcessHeap(), 0, wLen
* sizeof(WCHAR
));
1191 ret
= LookupPrivilegeNameW(lpSystemNameW
.Buffer
, lpLuid
, lpNameW
,
1195 /* Windows crashes if cchName is NULL, so will I */
1196 unsigned int len
= WideCharToMultiByte(CP_ACP
, 0, lpNameW
, -1, lpName
,
1197 *cchName
, NULL
, NULL
);
1201 /* WideCharToMultiByte failed */
1204 else if (len
> *cchName
)
1207 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
1212 /* WideCharToMultiByte succeeded, output length needs to be
1213 * length not including NULL terminator
1218 HeapFree(GetProcessHeap(), 0, lpNameW
);
1220 RtlFreeUnicodeString(&lpSystemNameW
);
1224 /******************************************************************************
1225 * GetFileSecurityA [ADVAPI32.@]
1227 * Obtains Specified information about the security of a file or directory.
1230 * lpFileName [I] Name of the file to get info for
1231 * RequestedInformation [I] SE_ flags from "winnt.h"
1232 * pSecurityDescriptor [O] Destination for security information
1233 * nLength [I] Length of pSecurityDescriptor
1234 * lpnLengthNeeded [O] Destination for length of returned security information
1237 * Success: TRUE. pSecurityDescriptor contains the requested information.
1238 * Failure: FALSE. lpnLengthNeeded contains the required space to return the info.
1241 * The information returned is constrained by the callers access rights and
1248 GetFileSecurityA(LPCSTR lpFileName
,
1249 SECURITY_INFORMATION RequestedInformation
,
1250 PSECURITY_DESCRIPTOR pSecurityDescriptor
,
1252 LPDWORD lpnLengthNeeded
)
1254 UNICODE_STRING FileName
;
1257 if (!RtlCreateUnicodeStringFromAsciiz(&FileName
, lpFileName
))
1259 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
1263 bResult
= GetFileSecurityW(FileName
.Buffer
,
1264 RequestedInformation
,
1265 pSecurityDescriptor
,
1269 RtlFreeUnicodeString(&FileName
);
1279 GetFileSecurityW(LPCWSTR lpFileName
,
1280 SECURITY_INFORMATION RequestedInformation
,
1281 PSECURITY_DESCRIPTOR pSecurityDescriptor
,
1283 LPDWORD lpnLengthNeeded
)
1285 OBJECT_ATTRIBUTES ObjectAttributes
;
1286 IO_STATUS_BLOCK StatusBlock
;
1287 UNICODE_STRING FileName
;
1288 ULONG AccessMask
= 0;
1292 TRACE("GetFileSecurityW() called\n");
1294 QuerySecurityAccessMask(RequestedInformation
, &AccessMask
);
1296 if (!RtlDosPathNameToNtPathName_U(lpFileName
,
1301 ERR("Invalid path\n");
1302 SetLastError(ERROR_INVALID_NAME
);
1306 InitializeObjectAttributes(&ObjectAttributes
,
1308 OBJ_CASE_INSENSITIVE
,
1312 Status
= NtOpenFile(&FileHandle
,
1316 FILE_SHARE_READ
| FILE_SHARE_WRITE
| FILE_SHARE_DELETE
,
1319 RtlFreeHeap(RtlGetProcessHeap(),
1323 if (!NT_SUCCESS(Status
))
1325 ERR("NtOpenFile() failed (Status %lx)\n", Status
);
1326 SetLastError(RtlNtStatusToDosError(Status
));
1330 Status
= NtQuerySecurityObject(FileHandle
,
1331 RequestedInformation
,
1332 pSecurityDescriptor
,
1335 NtClose(FileHandle
);
1336 if (!NT_SUCCESS(Status
))
1338 ERR("NtQuerySecurityObject() failed (Status %lx)\n", Status
);
1339 SetLastError(RtlNtStatusToDosError(Status
));
1346 /******************************************************************************
1347 * SetFileSecurityA [ADVAPI32.@]
1348 * Sets the security of a file or directory
1354 SetFileSecurityA(LPCSTR lpFileName
,
1355 SECURITY_INFORMATION SecurityInformation
,
1356 PSECURITY_DESCRIPTOR pSecurityDescriptor
)
1358 UNICODE_STRING FileName
;
1361 if (!RtlCreateUnicodeStringFromAsciiz(&FileName
, lpFileName
))
1363 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
1367 bResult
= SetFileSecurityW(FileName
.Buffer
,
1368 SecurityInformation
,
1369 pSecurityDescriptor
);
1371 RtlFreeUnicodeString(&FileName
);
1376 /******************************************************************************
1377 * SetFileSecurityW [ADVAPI32.@]
1378 * Sets the security of a file or directory
1384 SetFileSecurityW(LPCWSTR lpFileName
,
1385 SECURITY_INFORMATION SecurityInformation
,
1386 PSECURITY_DESCRIPTOR pSecurityDescriptor
)
1388 OBJECT_ATTRIBUTES ObjectAttributes
;
1389 IO_STATUS_BLOCK StatusBlock
;
1390 UNICODE_STRING FileName
;
1391 ULONG AccessMask
= 0;
1395 TRACE("SetFileSecurityW() called\n");
1397 SetSecurityAccessMask(SecurityInformation
, &AccessMask
);
1399 if (!RtlDosPathNameToNtPathName_U(lpFileName
,
1404 ERR("Invalid path\n");
1405 SetLastError(ERROR_INVALID_NAME
);
1409 InitializeObjectAttributes(&ObjectAttributes
,
1411 OBJ_CASE_INSENSITIVE
,
1415 Status
= NtOpenFile(&FileHandle
,
1419 FILE_SHARE_READ
| FILE_SHARE_WRITE
| FILE_SHARE_DELETE
,
1422 RtlFreeHeap(RtlGetProcessHeap(),
1426 if (!NT_SUCCESS(Status
))
1428 ERR("NtOpenFile() failed (Status %lx)\n", Status
);
1429 SetLastError(RtlNtStatusToDosError(Status
));
1433 Status
= NtSetSecurityObject(FileHandle
,
1434 SecurityInformation
,
1435 pSecurityDescriptor
);
1436 NtClose(FileHandle
);
1438 if (!NT_SUCCESS(Status
))
1440 ERR("NtSetSecurityObject() failed (Status %lx)\n", Status
);
1441 SetLastError(RtlNtStatusToDosError(Status
));
1448 /******************************************************************************
1449 * QueryWindows31FilesMigration [ADVAPI32.@]
1455 QueryWindows31FilesMigration( DWORD x1
)
1457 FIXME("(%d):stub\n",x1
);
1461 /******************************************************************************
1462 * SynchronizeWindows31FilesAndWindowsNTRegistry [ADVAPI32.@]
1471 SynchronizeWindows31FilesAndWindowsNTRegistry( DWORD x1
, DWORD x2
, DWORD x3
,
1474 FIXME("(0x%08x,0x%08x,0x%08x,0x%08x):stub\n",x1
,x2
,x3
,x4
);
1486 HANDLE Token
= NULL
;
1488 Status
= NtSetInformationThread(NtCurrentThread(),
1489 ThreadImpersonationToken
,
1492 if (!NT_SUCCESS(Status
))
1494 SetLastError(RtlNtStatusToDosError(Status
));
1506 ImpersonateSelf(SECURITY_IMPERSONATION_LEVEL ImpersonationLevel
)
1510 Status
= RtlImpersonateSelf(ImpersonationLevel
);
1511 if (!NT_SUCCESS(Status
))
1513 SetLastError(RtlNtStatusToDosError(Status
));
1525 AccessCheck(IN PSECURITY_DESCRIPTOR pSecurityDescriptor
,
1526 IN HANDLE ClientToken
,
1527 IN DWORD DesiredAccess
,
1528 IN PGENERIC_MAPPING GenericMapping
,
1529 OUT PPRIVILEGE_SET PrivilegeSet OPTIONAL
,
1530 IN OUT LPDWORD PrivilegeSetLength
,
1531 OUT LPDWORD GrantedAccess
,
1532 OUT LPBOOL AccessStatus
)
1535 NTSTATUS NtAccessStatus
;
1537 /* Do the access check */
1538 Status
= NtAccessCheck(pSecurityDescriptor
,
1543 (PULONG
)PrivilegeSetLength
,
1544 (PACCESS_MASK
)GrantedAccess
,
1547 /* See if the access check operation succeeded */
1548 if (!NT_SUCCESS(Status
))
1551 SetLastError(RtlNtStatusToDosError(Status
));
1555 /* Now check the access status */
1556 if (!NT_SUCCESS(NtAccessStatus
))
1559 SetLastError(RtlNtStatusToDosError(NtAccessStatus
));
1560 *AccessStatus
= FALSE
;
1564 /* Access granted */
1565 *AccessStatus
= TRUE
;
1568 /* Check succeeded */
1575 BOOL WINAPI
AccessCheckByType(
1576 PSECURITY_DESCRIPTOR pSecurityDescriptor
,
1577 PSID PrincipalSelfSid
,
1579 DWORD DesiredAccess
,
1580 POBJECT_TYPE_LIST ObjectTypeList
,
1581 DWORD ObjectTypeListLength
,
1582 PGENERIC_MAPPING GenericMapping
,
1583 PPRIVILEGE_SET PrivilegeSet
,
1584 LPDWORD PrivilegeSetLength
,
1585 LPDWORD GrantedAccess
,
1586 LPBOOL AccessStatus
)
1590 *AccessStatus
= TRUE
;
1592 return !*AccessStatus
;
1600 SetKernelObjectSecurity(HANDLE Handle
,
1601 SECURITY_INFORMATION SecurityInformation
,
1602 PSECURITY_DESCRIPTOR SecurityDescriptor
)
1606 Status
= NtSetSecurityObject(Handle
,
1607 SecurityInformation
,
1608 SecurityDescriptor
);
1609 if (!NT_SUCCESS(Status
))
1611 SetLastError(RtlNtStatusToDosError(Status
));
1623 AddAuditAccessAce(PACL pAcl
,
1624 DWORD dwAceRevision
,
1632 Status
= RtlAddAuditAccessAce(pAcl
,
1638 if (!NT_SUCCESS(Status
))
1640 SetLastError(RtlNtStatusToDosError(Status
));
1651 AddAuditAccessAceEx(PACL pAcl
,
1652 DWORD dwAceRevision
,
1661 Status
= RtlAddAuditAccessAceEx(pAcl
,
1668 if (!NT_SUCCESS(Status
))
1670 SetLastError(RtlNtStatusToDosError(Status
));
1677 /******************************************************************************
1678 * LookupAccountNameA [ADVAPI32.@]
1684 LookupAccountNameA(LPCSTR SystemName
,
1688 LPSTR ReferencedDomainName
,
1689 LPDWORD hReferencedDomainNameLength
,
1690 PSID_NAME_USE SidNameUse
)
1693 UNICODE_STRING lpSystemW
;
1694 UNICODE_STRING lpAccountW
;
1695 LPWSTR lpReferencedDomainNameW
= NULL
;
1697 RtlCreateUnicodeStringFromAsciiz(&lpSystemW
, SystemName
);
1698 RtlCreateUnicodeStringFromAsciiz(&lpAccountW
, AccountName
);
1700 if (ReferencedDomainName
)
1701 lpReferencedDomainNameW
= HeapAlloc(GetProcessHeap(),
1703 *hReferencedDomainNameLength
* sizeof(WCHAR
));
1705 ret
= LookupAccountNameW(lpSystemW
.Buffer
,
1709 lpReferencedDomainNameW
,
1710 hReferencedDomainNameLength
,
1713 if (ret
&& lpReferencedDomainNameW
)
1715 WideCharToMultiByte(CP_ACP
,
1717 lpReferencedDomainNameW
,
1718 *hReferencedDomainNameLength
+ 1,
1719 ReferencedDomainName
,
1720 *hReferencedDomainNameLength
+ 1,
1725 RtlFreeUnicodeString(&lpSystemW
);
1726 RtlFreeUnicodeString(&lpAccountW
);
1727 HeapFree(GetProcessHeap(), 0, lpReferencedDomainNameW
);
1732 /**********************************************************************
1733 * PrivilegeCheck EXPORTED
1738 PrivilegeCheck(HANDLE ClientToken
,
1739 PPRIVILEGE_SET RequiredPrivileges
,
1745 Status
= NtPrivilegeCheck(ClientToken
,
1748 if (!NT_SUCCESS(Status
))
1750 SetLastError(RtlNtStatusToDosError(Status
));
1754 *pfResult
= (BOOL
)Result
;
1759 /******************************************************************************
1760 * GetSecurityInfoExW EXPORTED
1764 GetSecurityInfoExA(HANDLE hObject
,
1765 SE_OBJECT_TYPE ObjectType
,
1766 SECURITY_INFORMATION SecurityInfo
,
1769 PACTRL_ACCESSA
*ppAccessList
,
1770 PACTRL_AUDITA
*ppAuditList
,
1774 FIXME("%s() not implemented!\n", __FUNCTION__
);
1775 return ERROR_BAD_PROVIDER
;
1779 /******************************************************************************
1780 * GetSecurityInfoExW EXPORTED
1784 GetSecurityInfoExW(HANDLE hObject
,
1785 SE_OBJECT_TYPE ObjectType
,
1786 SECURITY_INFORMATION SecurityInfo
,
1789 PACTRL_ACCESSW
*ppAccessList
,
1790 PACTRL_AUDITW
*ppAuditList
,
1794 FIXME("%s() not implemented!\n", __FUNCTION__
);
1795 return ERROR_BAD_PROVIDER
;
1798 /******************************************************************************
1799 * BuildExplicitAccessWithNameA [ADVAPI32.@]
1802 BuildExplicitAccessWithNameA(PEXPLICIT_ACCESSA pExplicitAccess
,
1804 DWORD AccessPermissions
,
1805 ACCESS_MODE AccessMode
,
1808 pExplicitAccess
->grfAccessPermissions
= AccessPermissions
;
1809 pExplicitAccess
->grfAccessMode
= AccessMode
;
1810 pExplicitAccess
->grfInheritance
= Inheritance
;
1812 pExplicitAccess
->Trustee
.pMultipleTrustee
= NULL
;
1813 pExplicitAccess
->Trustee
.MultipleTrusteeOperation
= NO_MULTIPLE_TRUSTEE
;
1814 pExplicitAccess
->Trustee
.TrusteeForm
= TRUSTEE_IS_NAME
;
1815 pExplicitAccess
->Trustee
.TrusteeType
= TRUSTEE_IS_UNKNOWN
;
1816 pExplicitAccess
->Trustee
.ptstrName
= pTrusteeName
;
1820 /******************************************************************************
1821 * BuildExplicitAccessWithNameW [ADVAPI32.@]
1824 BuildExplicitAccessWithNameW(PEXPLICIT_ACCESSW pExplicitAccess
,
1825 LPWSTR pTrusteeName
,
1826 DWORD AccessPermissions
,
1827 ACCESS_MODE AccessMode
,
1830 pExplicitAccess
->grfAccessPermissions
= AccessPermissions
;
1831 pExplicitAccess
->grfAccessMode
= AccessMode
;
1832 pExplicitAccess
->grfInheritance
= Inheritance
;
1834 pExplicitAccess
->Trustee
.pMultipleTrustee
= NULL
;
1835 pExplicitAccess
->Trustee
.MultipleTrusteeOperation
= NO_MULTIPLE_TRUSTEE
;
1836 pExplicitAccess
->Trustee
.TrusteeForm
= TRUSTEE_IS_NAME
;
1837 pExplicitAccess
->Trustee
.TrusteeType
= TRUSTEE_IS_UNKNOWN
;
1838 pExplicitAccess
->Trustee
.ptstrName
= pTrusteeName
;
1841 /******************************************************************************
1842 * BuildTrusteeWithObjectsAndNameA [ADVAPI32.@]
1844 VOID WINAPI
BuildTrusteeWithObjectsAndNameA( PTRUSTEEA pTrustee
, POBJECTS_AND_NAME_A pObjName
,
1845 SE_OBJECT_TYPE ObjectType
, LPSTR ObjectTypeName
,
1846 LPSTR InheritedObjectTypeName
, LPSTR Name
)
1848 DWORD ObjectsPresent
= 0;
1850 TRACE("%p %p 0x%08x %p %p %s\n", pTrustee
, pObjName
,
1851 ObjectType
, ObjectTypeName
, InheritedObjectTypeName
, debugstr_a(Name
));
1853 /* Fill the OBJECTS_AND_NAME structure */
1854 pObjName
->ObjectType
= ObjectType
;
1855 if (ObjectTypeName
!= NULL
)
1857 ObjectsPresent
|= ACE_OBJECT_TYPE_PRESENT
;
1860 pObjName
->InheritedObjectTypeName
= InheritedObjectTypeName
;
1861 if (InheritedObjectTypeName
!= NULL
)
1863 ObjectsPresent
|= ACE_INHERITED_OBJECT_TYPE_PRESENT
;
1866 pObjName
->ObjectsPresent
= ObjectsPresent
;
1867 pObjName
->ptstrName
= Name
;
1869 /* Fill the TRUSTEE structure */
1870 pTrustee
->pMultipleTrustee
= NULL
;
1871 pTrustee
->MultipleTrusteeOperation
= NO_MULTIPLE_TRUSTEE
;
1872 pTrustee
->TrusteeForm
= TRUSTEE_IS_OBJECTS_AND_NAME
;
1873 pTrustee
->TrusteeType
= TRUSTEE_IS_UNKNOWN
;
1874 pTrustee
->ptstrName
= (LPSTR
)pObjName
;
1877 /******************************************************************************
1878 * BuildTrusteeWithObjectsAndNameW [ADVAPI32.@]
1880 VOID WINAPI
BuildTrusteeWithObjectsAndNameW( PTRUSTEEW pTrustee
, POBJECTS_AND_NAME_W pObjName
,
1881 SE_OBJECT_TYPE ObjectType
, LPWSTR ObjectTypeName
,
1882 LPWSTR InheritedObjectTypeName
, LPWSTR Name
)
1884 DWORD ObjectsPresent
= 0;
1886 TRACE("%p %p 0x%08x %p %p %s\n", pTrustee
, pObjName
,
1887 ObjectType
, ObjectTypeName
, InheritedObjectTypeName
, debugstr_w(Name
));
1889 /* Fill the OBJECTS_AND_NAME structure */
1890 pObjName
->ObjectType
= ObjectType
;
1891 if (ObjectTypeName
!= NULL
)
1893 ObjectsPresent
|= ACE_OBJECT_TYPE_PRESENT
;
1896 pObjName
->InheritedObjectTypeName
= InheritedObjectTypeName
;
1897 if (InheritedObjectTypeName
!= NULL
)
1899 ObjectsPresent
|= ACE_INHERITED_OBJECT_TYPE_PRESENT
;
1902 pObjName
->ObjectsPresent
= ObjectsPresent
;
1903 pObjName
->ptstrName
= Name
;
1905 /* Fill the TRUSTEE structure */
1906 pTrustee
->pMultipleTrustee
= NULL
;
1907 pTrustee
->MultipleTrusteeOperation
= NO_MULTIPLE_TRUSTEE
;
1908 pTrustee
->TrusteeForm
= TRUSTEE_IS_OBJECTS_AND_NAME
;
1909 pTrustee
->TrusteeType
= TRUSTEE_IS_UNKNOWN
;
1910 pTrustee
->ptstrName
= (LPWSTR
)pObjName
;
1913 /******************************************************************************
1914 * BuildTrusteeWithObjectsAndSidA [ADVAPI32.@]
1917 BuildTrusteeWithObjectsAndSidA(PTRUSTEEA pTrustee
,
1918 POBJECTS_AND_SID pObjSid
,
1920 GUID
*pInheritedObjectGuid
,
1923 DWORD ObjectsPresent
= 0;
1925 TRACE("%p %p %p %p %p\n", pTrustee
, pObjSid
, pObjectGuid
, pInheritedObjectGuid
, pSid
);
1927 /* Fill the OBJECTS_AND_SID structure */
1928 if (pObjectGuid
!= NULL
)
1930 pObjSid
->ObjectTypeGuid
= *pObjectGuid
;
1931 ObjectsPresent
|= ACE_OBJECT_TYPE_PRESENT
;
1935 ZeroMemory(&pObjSid
->ObjectTypeGuid
,
1939 if (pInheritedObjectGuid
!= NULL
)
1941 pObjSid
->InheritedObjectTypeGuid
= *pInheritedObjectGuid
;
1942 ObjectsPresent
|= ACE_INHERITED_OBJECT_TYPE_PRESENT
;
1946 ZeroMemory(&pObjSid
->InheritedObjectTypeGuid
,
1950 pObjSid
->ObjectsPresent
= ObjectsPresent
;
1951 pObjSid
->pSid
= pSid
;
1953 /* Fill the TRUSTEE structure */
1954 pTrustee
->pMultipleTrustee
= NULL
;
1955 pTrustee
->MultipleTrusteeOperation
= NO_MULTIPLE_TRUSTEE
;
1956 pTrustee
->TrusteeForm
= TRUSTEE_IS_OBJECTS_AND_SID
;
1957 pTrustee
->TrusteeType
= TRUSTEE_IS_UNKNOWN
;
1958 pTrustee
->ptstrName
= (LPSTR
) pObjSid
;
1962 /******************************************************************************
1963 * BuildTrusteeWithObjectsAndSidW [ADVAPI32.@]
1966 BuildTrusteeWithObjectsAndSidW(PTRUSTEEW pTrustee
,
1967 POBJECTS_AND_SID pObjSid
,
1969 GUID
*pInheritedObjectGuid
,
1972 DWORD ObjectsPresent
= 0;
1974 TRACE("%p %p %p %p %p\n", pTrustee
, pObjSid
, pObjectGuid
, pInheritedObjectGuid
, pSid
);
1976 /* Fill the OBJECTS_AND_SID structure */
1977 if (pObjectGuid
!= NULL
)
1979 pObjSid
->ObjectTypeGuid
= *pObjectGuid
;
1980 ObjectsPresent
|= ACE_OBJECT_TYPE_PRESENT
;
1984 ZeroMemory(&pObjSid
->ObjectTypeGuid
,
1988 if (pInheritedObjectGuid
!= NULL
)
1990 pObjSid
->InheritedObjectTypeGuid
= *pInheritedObjectGuid
;
1991 ObjectsPresent
|= ACE_INHERITED_OBJECT_TYPE_PRESENT
;
1995 ZeroMemory(&pObjSid
->InheritedObjectTypeGuid
,
1999 pObjSid
->ObjectsPresent
= ObjectsPresent
;
2000 pObjSid
->pSid
= pSid
;
2002 /* Fill the TRUSTEE structure */
2003 pTrustee
->pMultipleTrustee
= NULL
;
2004 pTrustee
->MultipleTrusteeOperation
= NO_MULTIPLE_TRUSTEE
;
2005 pTrustee
->TrusteeForm
= TRUSTEE_IS_OBJECTS_AND_SID
;
2006 pTrustee
->TrusteeType
= TRUSTEE_IS_UNKNOWN
;
2007 pTrustee
->ptstrName
= (LPWSTR
) pObjSid
;
2010 /******************************************************************************
2011 * BuildTrusteeWithSidA [ADVAPI32.@]
2014 BuildTrusteeWithSidA(PTRUSTEE_A pTrustee
,
2017 TRACE("%p %p\n", pTrustee
, pSid
);
2019 pTrustee
->pMultipleTrustee
= NULL
;
2020 pTrustee
->MultipleTrusteeOperation
= NO_MULTIPLE_TRUSTEE
;
2021 pTrustee
->TrusteeForm
= TRUSTEE_IS_SID
;
2022 pTrustee
->TrusteeType
= TRUSTEE_IS_UNKNOWN
;
2023 pTrustee
->ptstrName
= (LPSTR
) pSid
;
2027 /******************************************************************************
2028 * BuildTrusteeWithSidW [ADVAPI32.@]
2031 BuildTrusteeWithSidW(PTRUSTEE_W pTrustee
,
2034 TRACE("%p %p\n", pTrustee
, pSid
);
2036 pTrustee
->pMultipleTrustee
= NULL
;
2037 pTrustee
->MultipleTrusteeOperation
= NO_MULTIPLE_TRUSTEE
;
2038 pTrustee
->TrusteeForm
= TRUSTEE_IS_SID
;
2039 pTrustee
->TrusteeType
= TRUSTEE_IS_UNKNOWN
;
2040 pTrustee
->ptstrName
= (LPWSTR
) pSid
;
2043 /******************************************************************************
2044 * BuildTrusteeWithNameA [ADVAPI32.@]
2047 BuildTrusteeWithNameA(PTRUSTEE_A 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 * BuildTrusteeWithNameW [ADVAPI32.@]
2063 BuildTrusteeWithNameW(PTRUSTEE_W pTrustee
,
2066 TRACE("%p %s\n", pTrustee
, name
);
2068 pTrustee
->pMultipleTrustee
= NULL
;
2069 pTrustee
->MultipleTrusteeOperation
= NO_MULTIPLE_TRUSTEE
;
2070 pTrustee
->TrusteeForm
= TRUSTEE_IS_NAME
;
2071 pTrustee
->TrusteeType
= TRUSTEE_IS_UNKNOWN
;
2072 pTrustee
->ptstrName
= name
;
2075 /******************************************************************************
2076 * GetTrusteeFormA [ADVAPI32.@]
2078 TRUSTEE_FORM WINAPI
GetTrusteeFormA(PTRUSTEEA pTrustee
)
2080 TRACE("(%p)\n", pTrustee
);
2083 return TRUSTEE_BAD_FORM
;
2085 return pTrustee
->TrusteeForm
;
2088 /******************************************************************************
2089 * GetTrusteeFormW [ADVAPI32.@]
2091 TRUSTEE_FORM WINAPI
GetTrusteeFormW(PTRUSTEEW pTrustee
)
2093 TRACE("(%p)\n", pTrustee
);
2096 return TRUSTEE_BAD_FORM
;
2098 return pTrustee
->TrusteeForm
;
2101 /******************************************************************************
2102 * GetTrusteeNameA [ADVAPI32.@]
2105 GetTrusteeNameA(PTRUSTEE_A pTrustee
)
2107 return pTrustee
->ptstrName
;
2111 /******************************************************************************
2112 * GetTrusteeNameW [ADVAPI32.@]
2115 GetTrusteeNameW(PTRUSTEE_W pTrustee
)
2117 return pTrustee
->ptstrName
;
2120 /******************************************************************************
2121 * GetTrusteeTypeA [ADVAPI32.@]
2124 GetTrusteeTypeA(PTRUSTEE_A pTrustee
)
2126 return pTrustee
->TrusteeType
;
2129 /******************************************************************************
2130 * GetTrusteeTypeW [ADVAPI32.@]
2133 GetTrusteeTypeW(PTRUSTEE_W pTrustee
)
2135 return pTrustee
->TrusteeType
;
2143 SetAclInformation(PACL pAcl
,
2144 LPVOID pAclInformation
,
2145 DWORD nAclInformationLength
,
2146 ACL_INFORMATION_CLASS dwAclInformationClass
)
2150 Status
= RtlSetInformationAcl(pAcl
,
2152 nAclInformationLength
,
2153 dwAclInformationClass
);
2154 if (!NT_SUCCESS(Status
))
2156 SetLastError(RtlNtStatusToDosError(Status
));
2163 /**********************************************************************
2164 * SetNamedSecurityInfoA EXPORTED
2170 SetNamedSecurityInfoA(LPSTR pObjectName
,
2171 SE_OBJECT_TYPE ObjectType
,
2172 SECURITY_INFORMATION SecurityInfo
,
2178 UNICODE_STRING ObjectName
;
2181 if (!RtlCreateUnicodeStringFromAsciiz(&ObjectName
, pObjectName
))
2183 return ERROR_NOT_ENOUGH_MEMORY
;
2186 Ret
= SetNamedSecurityInfoW(ObjectName
.Buffer
,
2194 RtlFreeUnicodeString(&ObjectName
);
2204 AreAllAccessesGranted(DWORD GrantedAccess
,
2205 DWORD DesiredAccess
)
2207 return (BOOL
)RtlAreAllAccessesGranted(GrantedAccess
,
2216 AreAnyAccessesGranted(DWORD GrantedAccess
,
2217 DWORD DesiredAccess
)
2219 return (BOOL
)RtlAreAnyAccessesGranted(GrantedAccess
,
2223 /******************************************************************************
2224 * ParseAclStringFlags
2226 static DWORD
ParseAclStringFlags(LPCWSTR
* StringAcl
)
2229 LPCWSTR szAcl
= *StringAcl
;
2231 while (*szAcl
&& *szAcl
!= '(')
2235 flags
|= SE_DACL_PROTECTED
;
2237 else if (*szAcl
== 'A')
2241 flags
|= SE_DACL_AUTO_INHERIT_REQ
;
2242 else if (*szAcl
== 'I')
2243 flags
|= SE_DACL_AUTO_INHERITED
;
2252 /******************************************************************************
2253 * ParseAceStringType
2255 static const ACEFLAG AceType
[] =
2257 { SDDL_ALARM
, SYSTEM_ALARM_ACE_TYPE
},
2258 { SDDL_AUDIT
, SYSTEM_AUDIT_ACE_TYPE
},
2259 { SDDL_ACCESS_ALLOWED
, ACCESS_ALLOWED_ACE_TYPE
},
2260 { SDDL_ACCESS_DENIED
, ACCESS_DENIED_ACE_TYPE
},
2261 { SDDL_MANDATORY_LABEL
,SYSTEM_MANDATORY_LABEL_ACE_TYPE
},
2263 { SDDL_OBJECT_ACCESS_ALLOWED, ACCESS_ALLOWED_OBJECT_ACE_TYPE },
2264 { SDDL_OBJECT_ACCESS_DENIED, ACCESS_DENIED_OBJECT_ACE_TYPE },
2265 { SDDL_OBJECT_ALARM, SYSTEM_ALARM_OBJECT_ACE_TYPE },
2266 { SDDL_OBJECT_AUDIT, SYSTEM_AUDIT_OBJECT_ACE_TYPE },
2271 static BYTE
ParseAceStringType(LPCWSTR
* StringAcl
)
2274 LPCWSTR szAcl
= *StringAcl
;
2275 const ACEFLAG
*lpaf
= AceType
;
2277 while (*szAcl
== ' ')
2280 while (lpaf
->wstr
&&
2281 (len
= strlenW(lpaf
->wstr
)) &&
2282 strncmpW(lpaf
->wstr
, szAcl
, len
))
2288 *StringAcl
= szAcl
+ len
;
2293 /******************************************************************************
2294 * ParseAceStringFlags
2296 static const ACEFLAG AceFlags
[] =
2298 { SDDL_CONTAINER_INHERIT
, CONTAINER_INHERIT_ACE
},
2299 { SDDL_AUDIT_FAILURE
, FAILED_ACCESS_ACE_FLAG
},
2300 { SDDL_INHERITED
, INHERITED_ACE
},
2301 { SDDL_INHERIT_ONLY
, INHERIT_ONLY_ACE
},
2302 { SDDL_NO_PROPAGATE
, NO_PROPAGATE_INHERIT_ACE
},
2303 { SDDL_OBJECT_INHERIT
, OBJECT_INHERIT_ACE
},
2304 { SDDL_AUDIT_SUCCESS
, SUCCESSFUL_ACCESS_ACE_FLAG
},
2308 static BYTE
ParseAceStringFlags(LPCWSTR
* StringAcl
)
2312 LPCWSTR szAcl
= *StringAcl
;
2314 while (*szAcl
== ' ')
2317 while (*szAcl
!= ';')
2319 const ACEFLAG
*lpaf
= AceFlags
;
2321 while (lpaf
->wstr
&&
2322 (len
= strlenW(lpaf
->wstr
)) &&
2323 strncmpW(lpaf
->wstr
, szAcl
, len
))
2329 flags
|= lpaf
->value
;
2338 /******************************************************************************
2339 * ParseAceStringRights
2341 static const ACEFLAG AceRights
[] =
2343 { SDDL_GENERIC_ALL
, GENERIC_ALL
},
2344 { SDDL_GENERIC_READ
, GENERIC_READ
},
2345 { SDDL_GENERIC_WRITE
, GENERIC_WRITE
},
2346 { SDDL_GENERIC_EXECUTE
, GENERIC_EXECUTE
},
2348 { SDDL_READ_CONTROL
, READ_CONTROL
},
2349 { SDDL_STANDARD_DELETE
, DELETE
},
2350 { SDDL_WRITE_DAC
, WRITE_DAC
},
2351 { SDDL_WRITE_OWNER
, WRITE_OWNER
},
2353 { SDDL_READ_PROPERTY
, ADS_RIGHT_DS_READ_PROP
},
2354 { SDDL_WRITE_PROPERTY
, ADS_RIGHT_DS_WRITE_PROP
},
2355 { SDDL_CREATE_CHILD
, ADS_RIGHT_DS_CREATE_CHILD
},
2356 { SDDL_DELETE_CHILD
, ADS_RIGHT_DS_DELETE_CHILD
},
2357 { SDDL_LIST_CHILDREN
, ADS_RIGHT_ACTRL_DS_LIST
},
2358 { SDDL_SELF_WRITE
, ADS_RIGHT_DS_SELF
},
2359 { SDDL_LIST_OBJECT
, ADS_RIGHT_DS_LIST_OBJECT
},
2360 { SDDL_DELETE_TREE
, ADS_RIGHT_DS_DELETE_TREE
},
2361 { SDDL_CONTROL_ACCESS
, ADS_RIGHT_DS_CONTROL_ACCESS
},
2363 { SDDL_FILE_ALL
, FILE_ALL_ACCESS
},
2364 { SDDL_FILE_READ
, FILE_GENERIC_READ
},
2365 { SDDL_FILE_WRITE
, FILE_GENERIC_WRITE
},
2366 { SDDL_FILE_EXECUTE
, FILE_GENERIC_EXECUTE
},
2368 { SDDL_KEY_ALL
, KEY_ALL_ACCESS
},
2369 { SDDL_KEY_READ
, KEY_READ
},
2370 { SDDL_KEY_WRITE
, KEY_WRITE
},
2371 { SDDL_KEY_EXECUTE
, KEY_EXECUTE
},
2373 { SDDL_NO_READ_UP
, SYSTEM_MANDATORY_LABEL_NO_READ_UP
},
2374 { SDDL_NO_WRITE_UP
, SYSTEM_MANDATORY_LABEL_NO_WRITE_UP
},
2375 { SDDL_NO_EXECUTE_UP
, SYSTEM_MANDATORY_LABEL_NO_EXECUTE_UP
},
2379 static DWORD
ParseAceStringRights(LPCWSTR
* StringAcl
)
2383 LPCWSTR szAcl
= *StringAcl
;
2385 while (*szAcl
== ' ')
2388 if ((*szAcl
== '0') && (*(szAcl
+ 1) == 'x'))
2392 while (*p
&& *p
!= ';')
2395 if (p
- szAcl
<= 10 /* 8 hex digits + "0x" */ )
2397 rights
= strtoulW(szAcl
, NULL
, 16);
2401 WARN("Invalid rights string format: %s\n", debugstr_wn(szAcl
, p
- szAcl
));
2405 while (*szAcl
!= ';')
2407 const ACEFLAG
*lpaf
= AceRights
;
2409 while (lpaf
->wstr
&&
2410 (len
= strlenW(lpaf
->wstr
)) &&
2411 strncmpW(lpaf
->wstr
, szAcl
, len
))
2419 rights
|= lpaf
->value
;
2429 /******************************************************************************
2430 * ParseStringAclToAcl
2432 * dacl_flags(string_ace1)(string_ace2)... (string_acen)
2434 static BOOL
ParseStringAclToAcl(LPCWSTR StringAcl
, LPDWORD lpdwFlags
,
2435 PACL pAcl
, LPDWORD cBytes
)
2439 DWORD length
= sizeof(ACL
);
2442 PACCESS_ALLOWED_ACE pAce
= NULL
; /* pointer to current ACE */
2443 DWORD error
= ERROR_INVALID_ACL
;
2445 TRACE("%s\n", debugstr_w(StringAcl
));
2450 if (pAcl
) /* pAce is only useful if we're setting values */
2451 pAce
= (PACCESS_ALLOWED_ACE
) (pAcl
+ 1);
2453 /* Parse ACL flags */
2454 *lpdwFlags
= ParseAclStringFlags(&StringAcl
);
2457 while (*StringAcl
== '(')
2461 /* Parse ACE type */
2462 val
= ParseAceStringType(&StringAcl
);
2464 pAce
->Header
.AceType
= (BYTE
) val
;
2465 if (*StringAcl
!= ';')
2467 error
= RPC_S_INVALID_STRING_UUID
;
2472 /* Parse ACE flags */
2473 val
= ParseAceStringFlags(&StringAcl
);
2475 pAce
->Header
.AceFlags
= (BYTE
) val
;
2476 if (*StringAcl
!= ';')
2480 /* Parse ACE rights */
2481 val
= ParseAceStringRights(&StringAcl
);
2484 if (*StringAcl
!= ';')
2488 /* Parse ACE object guid */
2489 while (*StringAcl
== ' ')
2491 if (*StringAcl
!= ';')
2493 FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
2498 /* Parse ACE inherit object guid */
2499 while (*StringAcl
== ' ')
2501 if (*StringAcl
!= ';')
2503 FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
2508 /* Parse ACE account sid */
2509 if (ParseStringSidToSid(StringAcl
, pAce
? &pAce
->SidStart
: NULL
, &sidlen
))
2511 while (*StringAcl
&& *StringAcl
!= ')')
2515 if (*StringAcl
!= ')')
2519 acesize
= sizeof(ACCESS_ALLOWED_ACE
) - sizeof(DWORD
) + sidlen
;
2523 pAce
->Header
.AceSize
= acesize
;
2524 pAce
= (PACCESS_ALLOWED_ACE
)((LPBYTE
)pAce
+ acesize
);
2531 if (length
> 0xffff)
2533 ERR("ACL too large\n");
2539 pAcl
->AclRevision
= ACL_REVISION
;
2541 pAcl
->AclSize
= length
;
2542 pAcl
->AceCount
= acecount
;
2548 SetLastError(error
);
2549 WARN("Invalid ACE string format\n");
2553 /******************************************************************************
2554 * ParseStringSecurityDescriptorToSecurityDescriptor
2556 static BOOL
ParseStringSecurityDescriptorToSecurityDescriptor(
2557 LPCWSTR StringSecurityDescriptor
,
2558 SECURITY_DESCRIPTOR_RELATIVE
* SecurityDescriptor
,
2565 LPBYTE lpNext
= NULL
;
2568 *cBytes
= sizeof(SECURITY_DESCRIPTOR_RELATIVE
);
2570 tok
= heap_alloc( (lstrlenW(StringSecurityDescriptor
) + 1) * sizeof(WCHAR
));
2572 if (SecurityDescriptor
)
2573 lpNext
= (LPBYTE
)(SecurityDescriptor
+ 1);
2575 while (*StringSecurityDescriptor
== ' ')
2576 StringSecurityDescriptor
++;
2578 while (*StringSecurityDescriptor
)
2580 toktype
= *StringSecurityDescriptor
;
2582 /* Expect char identifier followed by ':' */
2583 StringSecurityDescriptor
++;
2584 if (*StringSecurityDescriptor
!= ':')
2586 SetLastError(ERROR_INVALID_PARAMETER
);
2589 StringSecurityDescriptor
++;
2592 lptoken
= StringSecurityDescriptor
;
2593 while (*lptoken
&& *lptoken
!= ':')
2599 len
= lptoken
- StringSecurityDescriptor
;
2600 memcpy( tok
, StringSecurityDescriptor
, len
* sizeof(WCHAR
) );
2609 if (!ParseStringSidToSid(tok
, lpNext
, &bytes
))
2612 if (SecurityDescriptor
)
2614 SecurityDescriptor
->Owner
= lpNext
- (LPBYTE
)SecurityDescriptor
;
2615 lpNext
+= bytes
; /* Advance to next token */
2627 if (!ParseStringSidToSid(tok
, lpNext
, &bytes
))
2630 if (SecurityDescriptor
)
2632 SecurityDescriptor
->Group
= lpNext
- (LPBYTE
)SecurityDescriptor
;
2633 lpNext
+= bytes
; /* Advance to next token */
2646 if (!ParseStringAclToAcl(tok
, &flags
, (PACL
)lpNext
, &bytes
))
2649 if (SecurityDescriptor
)
2651 SecurityDescriptor
->Control
|= SE_DACL_PRESENT
| flags
;
2652 SecurityDescriptor
->Dacl
= lpNext
- (LPBYTE
)SecurityDescriptor
;
2653 lpNext
+= bytes
; /* Advance to next token */
2666 if (!ParseStringAclToAcl(tok
, &flags
, (PACL
)lpNext
, &bytes
))
2669 if (SecurityDescriptor
)
2671 SecurityDescriptor
->Control
|= SE_SACL_PRESENT
| flags
;
2672 SecurityDescriptor
->Sacl
= lpNext
- (LPBYTE
)SecurityDescriptor
;
2673 lpNext
+= bytes
; /* Advance to next token */
2682 FIXME("Unknown token\n");
2683 SetLastError(ERROR_INVALID_PARAMETER
);
2687 StringSecurityDescriptor
= lptoken
;
2697 /* Winehq cvs 20050916 */
2698 /******************************************************************************
2699 * ConvertStringSecurityDescriptorToSecurityDescriptorA [ADVAPI32.@]
2704 ConvertStringSecurityDescriptorToSecurityDescriptorA(LPCSTR StringSecurityDescriptor
,
2705 DWORD StringSDRevision
,
2706 PSECURITY_DESCRIPTOR
* SecurityDescriptor
,
2707 PULONG SecurityDescriptorSize
)
2711 LPWSTR StringSecurityDescriptorW
;
2713 len
= MultiByteToWideChar(CP_ACP
, 0, StringSecurityDescriptor
, -1, NULL
, 0);
2714 StringSecurityDescriptorW
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
2716 if (StringSecurityDescriptorW
)
2718 MultiByteToWideChar(CP_ACP
, 0, StringSecurityDescriptor
, -1, StringSecurityDescriptorW
, len
);
2720 ret
= ConvertStringSecurityDescriptorToSecurityDescriptorW(StringSecurityDescriptorW
,
2721 StringSDRevision
, SecurityDescriptor
,
2722 SecurityDescriptorSize
);
2723 HeapFree(GetProcessHeap(), 0, StringSecurityDescriptorW
);
2729 /******************************************************************************
2730 * ConvertStringSecurityDescriptorToSecurityDescriptorW [ADVAPI32.@]
2734 ConvertStringSecurityDescriptorToSecurityDescriptorW(LPCWSTR StringSecurityDescriptor
,
2735 DWORD StringSDRevision
,
2736 PSECURITY_DESCRIPTOR
* SecurityDescriptor
,
2737 PULONG SecurityDescriptorSize
)
2740 SECURITY_DESCRIPTOR
* psd
;
2743 TRACE("%s\n", debugstr_w(StringSecurityDescriptor
));
2745 if (GetVersion() & 0x80000000)
2747 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
2750 else if (!StringSecurityDescriptor
|| !SecurityDescriptor
)
2752 SetLastError(ERROR_INVALID_PARAMETER
);
2755 else if (StringSDRevision
!= SID_REVISION
)
2757 SetLastError(ERROR_UNKNOWN_REVISION
);
2761 /* Compute security descriptor length */
2762 if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor
,
2766 psd
= *SecurityDescriptor
= LocalAlloc(GMEM_ZEROINIT
, cBytes
);
2767 if (!psd
) goto lend
;
2769 psd
->Revision
= SID_REVISION
;
2770 psd
->Control
|= SE_SELF_RELATIVE
;
2772 if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor
,
2773 (SECURITY_DESCRIPTOR_RELATIVE
*)psd
, &cBytes
))
2779 if (SecurityDescriptorSize
)
2780 *SecurityDescriptorSize
= cBytes
;
2785 TRACE(" ret=%d\n", bret
);
2789 static void DumpString(LPCWSTR string
, int cch
, WCHAR
**pwptr
, ULONG
*plen
)
2792 cch
= strlenW(string
);
2799 memcpy(*pwptr
, string
, sizeof(WCHAR
)*cch
);
2804 static BOOL
DumpSidNumeric(PSID psid
, WCHAR
**pwptr
, ULONG
*plen
)
2807 WCHAR fmt
[] = { 'S','-','%','u','-','%','d',0 };
2808 WCHAR subauthfmt
[] = { '-','%','u',0 };
2812 if( !IsValidSid( psid
) || pisid
->Revision
!= SDDL_REVISION
)
2814 SetLastError(ERROR_INVALID_SID
);
2818 if (pisid
->IdentifierAuthority
.Value
[0] ||
2819 pisid
->IdentifierAuthority
.Value
[1])
2821 FIXME("not matching MS' bugs\n");
2822 SetLastError(ERROR_INVALID_SID
);
2826 sprintfW( buf
, fmt
, pisid
->Revision
,
2828 MAKEWORD( pisid
->IdentifierAuthority
.Value
[5],
2829 pisid
->IdentifierAuthority
.Value
[4] ),
2830 MAKEWORD( pisid
->IdentifierAuthority
.Value
[3],
2831 pisid
->IdentifierAuthority
.Value
[2] )
2833 DumpString(buf
, -1, pwptr
, plen
);
2835 for( i
=0; i
<pisid
->SubAuthorityCount
; i
++ )
2837 sprintfW( buf
, subauthfmt
, pisid
->SubAuthority
[i
] );
2838 DumpString(buf
, -1, pwptr
, plen
);
2843 static BOOL
DumpSid(PSID psid
, WCHAR
**pwptr
, ULONG
*plen
)
2846 for (i
= 0; i
< sizeof(WellKnownSids
) / sizeof(WellKnownSids
[0]); i
++)
2848 if (WellKnownSids
[i
].wstr
[0] && EqualSid(psid
, (PSID
)&(WellKnownSids
[i
].Sid
.Revision
)))
2850 DumpString(WellKnownSids
[i
].wstr
, 2, pwptr
, plen
);
2855 return DumpSidNumeric(psid
, pwptr
, plen
);
2858 static const LPCWSTR AceRightBitNames
[32] = {
2859 SDDL_CREATE_CHILD
, /* 0 */
2863 SDDL_READ_PROPERTY
, /* 4 */
2864 SDDL_WRITE_PROPERTY
,
2867 SDDL_CONTROL_ACCESS
, /* 8 */
2875 SDDL_STANDARD_DELETE
, /* 16 */
2887 SDDL_GENERIC_ALL
, /* 28 */
2888 SDDL_GENERIC_EXECUTE
,
2893 static void DumpRights(DWORD mask
, WCHAR
**pwptr
, ULONG
*plen
)
2895 static const WCHAR fmtW
[] = {'0','x','%','x',0};
2902 /* first check if the right have name */
2903 for (i
= 0; i
< sizeof(AceRights
)/sizeof(AceRights
[0]); i
++)
2905 if (AceRights
[i
].wstr
== NULL
)
2907 if (mask
== AceRights
[i
].value
)
2909 DumpString(AceRights
[i
].wstr
, -1, pwptr
, plen
);
2914 /* then check if it can be built from bit names */
2915 for (i
= 0; i
< 32; i
++)
2917 if ((mask
& (1 << i
)) && (AceRightBitNames
[i
] == NULL
))
2919 /* can't be built from bit names */
2920 sprintfW(buf
, fmtW
, mask
);
2921 DumpString(buf
, -1, pwptr
, plen
);
2926 /* build from bit names */
2927 for (i
= 0; i
< 32; i
++)
2928 if (mask
& (1 << i
))
2929 DumpString(AceRightBitNames
[i
], -1, pwptr
, plen
);
2932 static BOOL
DumpAce(LPVOID pace
, WCHAR
**pwptr
, ULONG
*plen
)
2934 ACCESS_ALLOWED_ACE
*piace
; /* all the supported ACEs have the same memory layout */
2935 static const WCHAR openbr
= '(';
2936 static const WCHAR closebr
= ')';
2937 static const WCHAR semicolon
= ';';
2939 if (((PACE_HEADER
)pace
)->AceType
> SYSTEM_ALARM_ACE_TYPE
|| ((PACE_HEADER
)pace
)->AceSize
< sizeof(ACCESS_ALLOWED_ACE
))
2941 SetLastError(ERROR_INVALID_ACL
);
2946 DumpString(&openbr
, 1, pwptr
, plen
);
2947 switch (piace
->Header
.AceType
)
2949 case ACCESS_ALLOWED_ACE_TYPE
:
2950 DumpString(SDDL_ACCESS_ALLOWED
, -1, pwptr
, plen
);
2952 case ACCESS_DENIED_ACE_TYPE
:
2953 DumpString(SDDL_ACCESS_DENIED
, -1, pwptr
, plen
);
2955 case SYSTEM_AUDIT_ACE_TYPE
:
2956 DumpString(SDDL_AUDIT
, -1, pwptr
, plen
);
2958 case SYSTEM_ALARM_ACE_TYPE
:
2959 DumpString(SDDL_ALARM
, -1, pwptr
, plen
);
2962 DumpString(&semicolon
, 1, pwptr
, plen
);
2964 if (piace
->Header
.AceFlags
& OBJECT_INHERIT_ACE
)
2965 DumpString(SDDL_OBJECT_INHERIT
, -1, pwptr
, plen
);
2966 if (piace
->Header
.AceFlags
& CONTAINER_INHERIT_ACE
)
2967 DumpString(SDDL_CONTAINER_INHERIT
, -1, pwptr
, plen
);
2968 if (piace
->Header
.AceFlags
& NO_PROPAGATE_INHERIT_ACE
)
2969 DumpString(SDDL_NO_PROPAGATE
, -1, pwptr
, plen
);
2970 if (piace
->Header
.AceFlags
& INHERIT_ONLY_ACE
)
2971 DumpString(SDDL_INHERIT_ONLY
, -1, pwptr
, plen
);
2972 if (piace
->Header
.AceFlags
& INHERITED_ACE
)
2973 DumpString(SDDL_INHERITED
, -1, pwptr
, plen
);
2974 if (piace
->Header
.AceFlags
& SUCCESSFUL_ACCESS_ACE_FLAG
)
2975 DumpString(SDDL_AUDIT_SUCCESS
, -1, pwptr
, plen
);
2976 if (piace
->Header
.AceFlags
& FAILED_ACCESS_ACE_FLAG
)
2977 DumpString(SDDL_AUDIT_FAILURE
, -1, pwptr
, plen
);
2978 DumpString(&semicolon
, 1, pwptr
, plen
);
2979 DumpRights(piace
->Mask
, pwptr
, plen
);
2980 DumpString(&semicolon
, 1, pwptr
, plen
);
2981 /* objects not supported */
2982 DumpString(&semicolon
, 1, pwptr
, plen
);
2983 /* objects not supported */
2984 DumpString(&semicolon
, 1, pwptr
, plen
);
2985 if (!DumpSid((PSID
)&piace
->SidStart
, pwptr
, plen
))
2987 DumpString(&closebr
, 1, pwptr
, plen
);
2991 static BOOL
DumpAcl(PACL pacl
, WCHAR
**pwptr
, ULONG
*plen
, BOOL
protected, BOOL autoInheritReq
, BOOL autoInherited
)
2997 DumpString(SDDL_PROTECTED
, -1, pwptr
, plen
);
2999 DumpString(SDDL_AUTO_INHERIT_REQ
, -1, pwptr
, plen
);
3001 DumpString(SDDL_AUTO_INHERITED
, -1, pwptr
, plen
);
3006 if (!IsValidAcl(pacl
))
3009 count
= pacl
->AceCount
;
3010 for (i
= 0; i
< count
; i
++)
3013 if (!GetAce(pacl
, i
, &ace
))
3015 if (!DumpAce(ace
, pwptr
, plen
))
3022 static BOOL
DumpOwner(PSECURITY_DESCRIPTOR SecurityDescriptor
, WCHAR
**pwptr
, ULONG
*plen
)
3024 static const WCHAR prefix
[] = {'O',':',0};
3028 if (!GetSecurityDescriptorOwner(SecurityDescriptor
, &psid
, &bDefaulted
))
3034 DumpString(prefix
, -1, pwptr
, plen
);
3035 if (!DumpSid(psid
, pwptr
, plen
))
3040 static BOOL
DumpGroup(PSECURITY_DESCRIPTOR SecurityDescriptor
, WCHAR
**pwptr
, ULONG
*plen
)
3042 static const WCHAR prefix
[] = {'G',':',0};
3046 if (!GetSecurityDescriptorGroup(SecurityDescriptor
, &psid
, &bDefaulted
))
3052 DumpString(prefix
, -1, pwptr
, plen
);
3053 if (!DumpSid(psid
, pwptr
, plen
))
3058 static BOOL
DumpDacl(PSECURITY_DESCRIPTOR SecurityDescriptor
, WCHAR
**pwptr
, ULONG
*plen
)
3060 static const WCHAR dacl
[] = {'D',':',0};
3061 SECURITY_DESCRIPTOR_CONTROL control
;
3062 BOOL present
, defaulted
;
3066 if (!GetSecurityDescriptorDacl(SecurityDescriptor
, &present
, &pacl
, &defaulted
))
3069 if (!GetSecurityDescriptorControl(SecurityDescriptor
, &control
, &revision
))
3075 DumpString(dacl
, 2, pwptr
, plen
);
3076 if (!DumpAcl(pacl
, pwptr
, plen
, control
& SE_DACL_PROTECTED
, control
& SE_DACL_AUTO_INHERIT_REQ
, control
& SE_DACL_AUTO_INHERITED
))
3081 static BOOL
DumpSacl(PSECURITY_DESCRIPTOR SecurityDescriptor
, WCHAR
**pwptr
, ULONG
*plen
)
3083 static const WCHAR sacl
[] = {'S',':',0};
3084 SECURITY_DESCRIPTOR_CONTROL control
;
3085 BOOL present
, defaulted
;
3089 if (!GetSecurityDescriptorSacl(SecurityDescriptor
, &present
, &pacl
, &defaulted
))
3092 if (!GetSecurityDescriptorControl(SecurityDescriptor
, &control
, &revision
))
3098 DumpString(sacl
, 2, pwptr
, plen
);
3099 if (!DumpAcl(pacl
, pwptr
, plen
, control
& SE_SACL_PROTECTED
, control
& SE_SACL_AUTO_INHERIT_REQ
, control
& SE_SACL_AUTO_INHERITED
))
3104 /******************************************************************************
3105 * ConvertSecurityDescriptorToStringSecurityDescriptorW [ADVAPI32.@]
3107 BOOL WINAPI
ConvertSecurityDescriptorToStringSecurityDescriptorW(PSECURITY_DESCRIPTOR SecurityDescriptor
, DWORD SDRevision
, SECURITY_INFORMATION RequestedInformation
, LPWSTR
*OutputString
, PULONG OutputLen
)
3112 if (SDRevision
!= SDDL_REVISION_1
)
3114 ERR("Program requested unknown SDDL revision %d\n", SDRevision
);
3115 SetLastError(ERROR_UNKNOWN_REVISION
);
3120 if (RequestedInformation
& OWNER_SECURITY_INFORMATION
)
3121 if (!DumpOwner(SecurityDescriptor
, NULL
, &len
))
3123 if (RequestedInformation
& GROUP_SECURITY_INFORMATION
)
3124 if (!DumpGroup(SecurityDescriptor
, NULL
, &len
))
3126 if (RequestedInformation
& DACL_SECURITY_INFORMATION
)
3127 if (!DumpDacl(SecurityDescriptor
, NULL
, &len
))
3129 if (RequestedInformation
& SACL_SECURITY_INFORMATION
)
3130 if (!DumpSacl(SecurityDescriptor
, NULL
, &len
))
3133 wstr
= wptr
= LocalAlloc(0, (len
+ 1)*sizeof(WCHAR
));
3139 if (RequestedInformation
& OWNER_SECURITY_INFORMATION
)
3140 if (!DumpOwner(SecurityDescriptor
, &wptr
, NULL
)) {
3144 if (RequestedInformation
& GROUP_SECURITY_INFORMATION
)
3145 if (!DumpGroup(SecurityDescriptor
, &wptr
, NULL
)) {
3149 if (RequestedInformation
& DACL_SECURITY_INFORMATION
)
3150 if (!DumpDacl(SecurityDescriptor
, &wptr
, NULL
)) {
3154 if (RequestedInformation
& SACL_SECURITY_INFORMATION
)
3155 if (!DumpSacl(SecurityDescriptor
, &wptr
, NULL
)) {
3161 TRACE("ret: %s, %d\n", wine_dbgstr_w(wstr
), len
);
3162 *OutputString
= wstr
;
3164 *OutputLen
= strlenW(*OutputString
)+1;
3168 /******************************************************************************
3169 * ConvertSecurityDescriptorToStringSecurityDescriptorA [ADVAPI32.@]
3171 BOOL WINAPI
ConvertSecurityDescriptorToStringSecurityDescriptorA(PSECURITY_DESCRIPTOR SecurityDescriptor
, DWORD SDRevision
, SECURITY_INFORMATION Information
, LPSTR
*OutputString
, PULONG OutputLen
)
3175 if (ConvertSecurityDescriptorToStringSecurityDescriptorW(SecurityDescriptor
, SDRevision
, Information
, &wstr
, &len
))
3179 lenA
= WideCharToMultiByte(CP_ACP
, 0, wstr
, len
, NULL
, 0, NULL
, NULL
);
3180 *OutputString
= heap_alloc(lenA
);
3182 if (*OutputString
== NULL
)
3189 WideCharToMultiByte(CP_ACP
, 0, wstr
, len
, *OutputString
, lenA
, NULL
, NULL
);
3192 if (OutputLen
!= NULL
)
3198 *OutputString
= NULL
;
3205 /******************************************************************************
3206 * ConvertStringSidToSidW [ADVAPI32.@]
3208 BOOL WINAPI
ConvertStringSidToSidW(LPCWSTR StringSid
, PSID
* Sid
)
3213 TRACE("%s, %p\n", debugstr_w(StringSid
), Sid
);
3214 if (GetVersion() & 0x80000000)
3215 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
3216 else if (!StringSid
|| !Sid
)
3217 SetLastError(ERROR_INVALID_PARAMETER
);
3218 else if (ParseStringSidToSid(StringSid
, NULL
, &cBytes
))
3220 PSID pSid
= *Sid
= LocalAlloc(0, cBytes
);
3222 bret
= ParseStringSidToSid(StringSid
, pSid
, &cBytes
);
3229 /******************************************************************************
3230 * ConvertStringSidToSidA [ADVAPI32.@]
3232 BOOL WINAPI
ConvertStringSidToSidA(LPCSTR StringSid
, PSID
* Sid
)
3236 TRACE("%s, %p\n", debugstr_a(StringSid
), Sid
);
3237 if (GetVersion() & 0x80000000)
3238 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
3239 else if (!StringSid
|| !Sid
)
3240 SetLastError(ERROR_INVALID_PARAMETER
);
3243 WCHAR
*wStringSid
= SERV_dup(StringSid
);
3244 bret
= ConvertStringSidToSidW(wStringSid
, Sid
);
3245 heap_free(wStringSid
);
3255 ConvertSidToStringSidW(PSID Sid
,
3259 UNICODE_STRING UnicodeString
;
3260 WCHAR FixedBuffer
[64];
3262 if (!RtlValidSid(Sid
))
3264 SetLastError(ERROR_INVALID_SID
);
3268 UnicodeString
.Length
= 0;
3269 UnicodeString
.MaximumLength
= sizeof(FixedBuffer
);
3270 UnicodeString
.Buffer
= FixedBuffer
;
3271 Status
= RtlConvertSidToUnicodeString(&UnicodeString
, Sid
, FALSE
);
3272 if (STATUS_BUFFER_TOO_SMALL
== Status
)
3274 Status
= RtlConvertSidToUnicodeString(&UnicodeString
, Sid
, TRUE
);
3277 if (!NT_SUCCESS(Status
))
3279 SetLastError(RtlNtStatusToDosError(Status
));
3283 *StringSid
= LocalAlloc(LMEM_FIXED
, UnicodeString
.Length
+ sizeof(WCHAR
));
3284 if (NULL
== *StringSid
)
3286 if (UnicodeString
.Buffer
!= FixedBuffer
)
3288 RtlFreeUnicodeString(&UnicodeString
);
3290 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
3294 MoveMemory(*StringSid
, UnicodeString
.Buffer
, UnicodeString
.Length
);
3295 ZeroMemory((PCHAR
) *StringSid
+ UnicodeString
.Length
, sizeof(WCHAR
));
3296 if (UnicodeString
.Buffer
!= FixedBuffer
)
3298 RtlFreeUnicodeString(&UnicodeString
);
3309 ConvertSidToStringSidA(PSID Sid
,
3315 if (!ConvertSidToStringSidW(Sid
, &StringSidW
))
3320 Len
= WideCharToMultiByte(CP_ACP
, 0, StringSidW
, -1, NULL
, 0, NULL
, NULL
);
3323 LocalFree(StringSidW
);
3324 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
3328 *StringSid
= LocalAlloc(LMEM_FIXED
, Len
);
3329 if (NULL
== *StringSid
)
3331 LocalFree(StringSidW
);
3332 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
3336 if (!WideCharToMultiByte(CP_ACP
, 0, StringSidW
, -1, *StringSid
, Len
, NULL
, NULL
))
3338 LocalFree(StringSid
);
3339 LocalFree(StringSidW
);
3343 LocalFree(StringSidW
);
3352 CreateProcessWithLogonW(LPCWSTR lpUsername
,
3356 LPCWSTR lpApplicationName
,
3357 LPWSTR lpCommandLine
,
3358 DWORD dwCreationFlags
,
3359 LPVOID lpEnvironment
,
3360 LPCWSTR lpCurrentDirectory
,
3361 LPSTARTUPINFOW lpStartupInfo
,
3362 LPPROCESS_INFORMATION lpProcessInformation
)
3364 FIXME("%s %s %s 0x%08x %s %s 0x%08x %p %s %p %p stub\n", debugstr_w(lpUsername
), debugstr_w(lpDomain
),
3365 debugstr_w(lpPassword
), dwLogonFlags
, debugstr_w(lpApplicationName
),
3366 debugstr_w(lpCommandLine
), dwCreationFlags
, lpEnvironment
, debugstr_w(lpCurrentDirectory
),
3367 lpStartupInfo
, lpProcessInformation
);
3372 BOOL WINAPI
CreateProcessWithTokenW(HANDLE token
, DWORD logon_flags
, LPCWSTR application_name
, LPWSTR command_line
,
3373 DWORD creation_flags
, void *environment
, LPCWSTR current_directory
, STARTUPINFOW
*startup_info
,
3374 PROCESS_INFORMATION
*process_information
)
3376 FIXME("%p 0x%08x %s %s 0x%08x %p %s %p %p - semi-stub\n", token
,
3377 logon_flags
, debugstr_w(application_name
), debugstr_w(command_line
),
3378 creation_flags
, environment
, debugstr_w(current_directory
),
3379 startup_info
, process_information
);
3381 /* FIXME: check if handles should be inherited */
3382 return CreateProcessW( application_name
, command_line
, NULL
, NULL
, FALSE
, creation_flags
, environment
,
3383 current_directory
, startup_info
, process_information
);
3390 DuplicateTokenEx(IN HANDLE ExistingTokenHandle
,
3391 IN DWORD dwDesiredAccess
,
3392 IN LPSECURITY_ATTRIBUTES lpTokenAttributes OPTIONAL
,
3393 IN SECURITY_IMPERSONATION_LEVEL ImpersonationLevel
,
3394 IN TOKEN_TYPE TokenType
,
3395 OUT PHANDLE DuplicateTokenHandle
)
3397 OBJECT_ATTRIBUTES ObjectAttributes
;
3399 SECURITY_QUALITY_OF_SERVICE Sqos
;
3401 TRACE("%p 0x%08x 0x%08x 0x%08x %p\n", ExistingTokenHandle
, dwDesiredAccess
,
3402 ImpersonationLevel
, TokenType
, DuplicateTokenHandle
);
3404 Sqos
.Length
= sizeof(SECURITY_QUALITY_OF_SERVICE
);
3405 Sqos
.ImpersonationLevel
= ImpersonationLevel
;
3406 Sqos
.ContextTrackingMode
= 0;
3407 Sqos
.EffectiveOnly
= FALSE
;
3409 if (lpTokenAttributes
!= NULL
)
3411 InitializeObjectAttributes(&ObjectAttributes
,
3413 lpTokenAttributes
->bInheritHandle
? OBJ_INHERIT
: 0,
3415 lpTokenAttributes
->lpSecurityDescriptor
);
3419 InitializeObjectAttributes(&ObjectAttributes
,
3426 ObjectAttributes
.SecurityQualityOfService
= &Sqos
;
3428 Status
= NtDuplicateToken(ExistingTokenHandle
,
3433 DuplicateTokenHandle
);
3434 if (!NT_SUCCESS(Status
))
3436 ERR("NtDuplicateToken failed: Status %08x\n", Status
);
3437 SetLastError(RtlNtStatusToDosError(Status
));
3441 TRACE("Returning token %p.\n", *DuplicateTokenHandle
);
3450 DuplicateToken(IN HANDLE ExistingTokenHandle
,
3451 IN SECURITY_IMPERSONATION_LEVEL ImpersonationLevel
,
3452 OUT PHANDLE DuplicateTokenHandle
)
3454 return DuplicateTokenEx(ExistingTokenHandle
,
3455 TOKEN_IMPERSONATE
| TOKEN_QUERY
,
3459 DuplicateTokenHandle
);
3462 /******************************************************************************
3463 * ComputeStringSidSize
3465 static DWORD
ComputeStringSidSize(LPCWSTR StringSid
)
3467 if (StringSid
[0] == 'S' && StringSid
[1] == '-') /* S-R-I(-S)+ */
3472 if (*StringSid
== '-')
3478 return GetSidLengthRequired(ctok
- 2);
3480 else /* String constant format - Only available in winxp and above */
3484 for (i
= 0; i
< sizeof(WellKnownSids
)/sizeof(WellKnownSids
[0]); i
++)
3485 if (!strncmpW(WellKnownSids
[i
].wstr
, StringSid
, 2))
3486 return GetSidLengthRequired(WellKnownSids
[i
].Sid
.SubAuthorityCount
);
3488 for (i
= 0; i
< sizeof(WellKnownRids
)/sizeof(WellKnownRids
[0]); i
++)
3489 if (!strncmpW(WellKnownRids
[i
].wstr
, StringSid
, 2))
3492 ADVAPI_GetComputerSid(&local
);
3493 return GetSidLengthRequired(*GetSidSubAuthorityCount(&local
) + 1);
3498 return GetSidLengthRequired(0);
3501 /******************************************************************************
3502 * ParseStringSidToSid
3504 static BOOL
ParseStringSidToSid(LPCWSTR StringSid
, PSID pSid
, LPDWORD cBytes
)
3509 TRACE("%s, %p, %p\n", debugstr_w(StringSid
), pSid
, cBytes
);
3512 SetLastError(ERROR_INVALID_PARAMETER
);
3513 TRACE("StringSid is NULL, returning FALSE\n");
3517 while (*StringSid
== ' ')
3521 goto lend
; /* ERROR_INVALID_SID */
3523 *cBytes
= ComputeStringSidSize(StringSid
);
3524 if (!pisid
) /* Simply compute the size */
3526 TRACE("only size requested, returning TRUE with %d\n", *cBytes
);
3530 if (StringSid
[0] == 'S' && StringSid
[1] == '-') /* S-R-I-S-S */
3532 DWORD i
= 0, identAuth
;
3533 DWORD csubauth
= ((*cBytes
- GetSidLengthRequired(0)) / sizeof(DWORD
));
3535 StringSid
+= 2; /* Advance to Revision */
3536 pisid
->Revision
= atoiW(StringSid
);
3538 if (pisid
->Revision
!= SDDL_REVISION
)
3540 TRACE("Revision %d is unknown\n", pisid
->Revision
);
3541 goto lend
; /* ERROR_INVALID_SID */
3545 TRACE("SubAuthorityCount is 0\n");
3546 goto lend
; /* ERROR_INVALID_SID */
3549 pisid
->SubAuthorityCount
= csubauth
;
3551 /* Advance to identifier authority */
3552 while (*StringSid
&& *StringSid
!= '-')
3554 if (*StringSid
== '-')
3557 /* MS' implementation can't handle values greater than 2^32 - 1, so
3558 * we don't either; assume most significant bytes are always 0
3560 pisid
->IdentifierAuthority
.Value
[0] = 0;
3561 pisid
->IdentifierAuthority
.Value
[1] = 0;
3562 identAuth
= atoiW(StringSid
);
3563 pisid
->IdentifierAuthority
.Value
[5] = identAuth
& 0xff;
3564 pisid
->IdentifierAuthority
.Value
[4] = (identAuth
& 0xff00) >> 8;
3565 pisid
->IdentifierAuthority
.Value
[3] = (identAuth
& 0xff0000) >> 16;
3566 pisid
->IdentifierAuthority
.Value
[2] = (identAuth
& 0xff000000) >> 24;
3568 /* Advance to first sub authority */
3569 while (*StringSid
&& *StringSid
!= '-')
3571 if (*StringSid
== '-')
3576 pisid
->SubAuthority
[i
++] = atoiW(StringSid
);
3578 while (*StringSid
&& *StringSid
!= '-')
3580 if (*StringSid
== '-')
3584 if (i
!= pisid
->SubAuthorityCount
)
3585 goto lend
; /* ERROR_INVALID_SID */
3589 else /* String constant format - Only available in winxp and above */
3592 pisid
->Revision
= SDDL_REVISION
;
3594 for (i
= 0; i
< sizeof(WellKnownSids
)/sizeof(WellKnownSids
[0]); i
++)
3595 if (!strncmpW(WellKnownSids
[i
].wstr
, StringSid
, 2))
3598 pisid
->SubAuthorityCount
= WellKnownSids
[i
].Sid
.SubAuthorityCount
;
3599 pisid
->IdentifierAuthority
= WellKnownSids
[i
].Sid
.IdentifierAuthority
;
3600 for (j
= 0; j
< WellKnownSids
[i
].Sid
.SubAuthorityCount
; j
++)
3601 pisid
->SubAuthority
[j
] = WellKnownSids
[i
].Sid
.SubAuthority
[j
];
3605 for (i
= 0; i
< sizeof(WellKnownRids
)/sizeof(WellKnownRids
[0]); i
++)
3606 if (!strncmpW(WellKnownRids
[i
].wstr
, StringSid
, 2))
3608 ADVAPI_GetComputerSid(pisid
);
3609 pisid
->SubAuthority
[pisid
->SubAuthorityCount
] = WellKnownRids
[i
].Rid
;
3610 pisid
->SubAuthorityCount
++;
3615 FIXME("String constant not supported: %s\n", debugstr_wn(StringSid
, 2));
3620 SetLastError(ERROR_INVALID_SID
);
3622 TRACE("returning %s\n", bret
? "TRUE" : "FALSE");
3626 /**********************************************************************
3627 * GetNamedSecurityInfoA EXPORTED
3633 GetNamedSecurityInfoA(LPSTR pObjectName
,
3634 SE_OBJECT_TYPE ObjectType
,
3635 SECURITY_INFORMATION SecurityInfo
,
3640 PSECURITY_DESCRIPTOR
*ppSecurityDescriptor
)
3646 TRACE("%s %d %d %p %p %p %p %p\n", pObjectName
, ObjectType
, SecurityInfo
,
3647 ppsidOwner
, ppsidGroup
, ppDacl
, ppSacl
, ppSecurityDescriptor
);
3651 len
= MultiByteToWideChar( CP_ACP
, 0, pObjectName
, -1, NULL
, 0 );
3652 wstr
= HeapAlloc( GetProcessHeap(), 0, len
*sizeof(WCHAR
));
3653 MultiByteToWideChar( CP_ACP
, 0, pObjectName
, -1, wstr
, len
);
3656 r
= GetNamedSecurityInfoW( wstr
, ObjectType
, SecurityInfo
, ppsidOwner
,
3657 ppsidGroup
, ppDacl
, ppSacl
, ppSecurityDescriptor
);
3659 HeapFree( GetProcessHeap(), 0, wstr
);
3664 /******************************************************************************
3665 * GetWindowsAccountDomainSid [ADVAPI32.@]
3667 BOOL WINAPI
GetWindowsAccountDomainSid( PSID sid
, PSID domain_sid
, DWORD
*size
)
3669 SID_IDENTIFIER_AUTHORITY domain_ident
= { SECURITY_NT_AUTHORITY
};
3670 DWORD required_size
;
3673 FIXME( "(%p %p %p): semi-stub\n", sid
, domain_sid
, size
);
3675 if (!sid
|| !IsValidSid( sid
))
3677 SetLastError( ERROR_INVALID_SID
);
3683 SetLastError( ERROR_INVALID_PARAMETER
);
3687 if (*GetSidSubAuthorityCount( sid
) < 4)
3689 SetLastError( ERROR_INVALID_SID
);
3693 required_size
= GetSidLengthRequired( 4 );
3694 if (*size
< required_size
|| !domain_sid
)
3696 *size
= required_size
;
3697 SetLastError( domain_sid
? ERROR_INSUFFICIENT_BUFFER
:
3698 ERROR_INVALID_PARAMETER
);
3702 InitializeSid( domain_sid
, &domain_ident
, 4 );
3703 for (i
= 0; i
< 4; i
++)
3704 *GetSidSubAuthority( domain_sid
, i
) = *GetSidSubAuthority( sid
, i
);
3706 *size
= required_size
;
3715 EqualDomainSid(IN PSID pSid1
,