~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Wine Cross Reference
wine/dlls/advapi32/security.c

Version: ~ [ wine-1.1.33 ] ~ [ wine-1.1.32 ] ~ [ wine-1.1.31 ] ~ [ wine-1.1.30 ] ~ [ wine-1.1.29 ] ~ [ wine-1.1.28 ] ~ [ wine-1.1.27 ] ~ [ wine-1.1.26 ] ~ [ wine-1.1.25 ] ~ [ wine-1.1.24 ] ~ [ wine-1.1.23 ] ~ [ wine-1.1.22 ] ~ [ wine-1.1.21 ] ~ [ wine-1.1.20 ] ~ [ wine-1.1.19 ] ~ [ wine-1.1.18 ] ~ [ wine-1.1.17 ] ~ [ wine-1.1.16 ] ~ [ wine-1.1.15 ] ~ [ wine-1.1.14 ] ~ [ wine-1.1.13 ] ~ [ wine-1.1.12 ] ~ [ wine-1.1.11 ] ~ [ wine-1.1.10 ] ~ [ wine-1.1.9 ] ~ [ wine-1.1.8 ] ~ [ wine-1.1.7 ] ~ [ wine-1.0.1 ] ~ [ wine-1.1.6 ] ~ [ wine-1.1.5 ] ~ [ wine-1.1.4 ] ~ [ wine-1.1.3 ] ~ [ wine-1.1.2 ] ~ [ wine-1.1.1 ] ~ [ wine-1.1.0 ] ~ [ wine-1.0 ] ~

  1 /*
  2  * Copyright 1999, 2000 Juergen Schmied <juergen.schmied@debitel.net>
  3  * Copyright 2003 CodeWeavers Inc. (Ulrich Czekalla)
  4  * Copyright 2006 Robert Reif
  5  *
  6  * This library is free software; you can redistribute it and/or
  7  * modify it under the terms of the GNU Lesser General Public
  8  * License as published by the Free Software Foundation; either
  9  * version 2.1 of the License, or (at your option) any later version.
 10  *
 11  * This library is distributed in the hope that it will be useful,
 12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 14  * Lesser General Public License for more details.
 15  *
 16  * You should have received a copy of the GNU Lesser General Public
 17  * License along with this library; if not, write to the Free Software
 18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 19  *
 20  */
 21 
 22 #include <stdarg.h>
 23 #include <string.h>
 24 
 25 #include "ntstatus.h"
 26 #define WIN32_NO_STATUS
 27 #include "windef.h"
 28 #include "winbase.h"
 29 #include "winerror.h"
 30 #include "winreg.h"
 31 #include "winsafer.h"
 32 #include "winternl.h"
 33 #include "winioctl.h"
 34 #include "ntsecapi.h"
 35 #include "accctrl.h"
 36 #include "sddl.h"
 37 #include "winsvc.h"
 38 #include "aclapi.h"
 39 #include "objbase.h"
 40 #include "iads.h"
 41 #include "advapi32_misc.h"
 42 #include "lmcons.h"
 43 
 44 #include "wine/debug.h"
 45 #include "wine/unicode.h"
 46 
 47 WINE_DEFAULT_DEBUG_CHANNEL(advapi);
 48 
 49 static BOOL ParseStringSidToSid(LPCWSTR StringSid, PSID pSid, LPDWORD cBytes);
 50 static BOOL ParseStringAclToAcl(LPCWSTR StringAcl, LPDWORD lpdwFlags, 
 51     PACL pAcl, LPDWORD cBytes);
 52 static BYTE ParseAceStringFlags(LPCWSTR* StringAcl);
 53 static BYTE ParseAceStringType(LPCWSTR* StringAcl);
 54 static DWORD ParseAceStringRights(LPCWSTR* StringAcl);
 55 static BOOL ParseStringSecurityDescriptorToSecurityDescriptor(
 56     LPCWSTR StringSecurityDescriptor,
 57     SECURITY_DESCRIPTOR* SecurityDescriptor,
 58     LPDWORD cBytes);
 59 static DWORD ParseAclStringFlags(LPCWSTR* StringAcl);
 60 
 61 typedef struct _ACEFLAG
 62 {
 63    LPCWSTR wstr;
 64    DWORD value;
 65 } ACEFLAG, *LPACEFLAG;
 66 
 67 typedef struct _MAX_SID
 68 {
 69     /* same fields as struct _SID */
 70     BYTE Revision;
 71     BYTE SubAuthorityCount;
 72     SID_IDENTIFIER_AUTHORITY IdentifierAuthority;
 73     DWORD SubAuthority[SID_MAX_SUB_AUTHORITIES];
 74 } MAX_SID;
 75 
 76 typedef struct WELLKNOWNSID
 77 {
 78     WCHAR wstr[2];
 79     WELL_KNOWN_SID_TYPE Type;
 80     MAX_SID Sid;
 81 } WELLKNOWNSID;
 82 
 83 static const WELLKNOWNSID WellKnownSids[] =
 84 {
 85     { {0,0}, WinNullSid, { SID_REVISION, 1, { SECURITY_NULL_SID_AUTHORITY }, { SECURITY_NULL_RID } } },
 86     { {'W','D'}, WinWorldSid, { SID_REVISION, 1, { SECURITY_WORLD_SID_AUTHORITY }, { SECURITY_WORLD_RID } } },
 87     { {0,0}, WinLocalSid, { SID_REVISION, 1, { SECURITY_LOCAL_SID_AUTHORITY }, { SECURITY_LOCAL_RID } } },
 88     { {'C','O'}, WinCreatorOwnerSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_OWNER_RID } } },
 89     { {'C','G'}, WinCreatorGroupSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_GROUP_RID } } },
 90     { {0,0}, WinCreatorOwnerServerSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_OWNER_SERVER_RID } } },
 91     { {0,0}, WinCreatorGroupServerSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_GROUP_SERVER_RID } } },
 92     { {0,0}, WinNtAuthoritySid, { SID_REVISION, 0, { SECURITY_NT_AUTHORITY }, { SECURITY_NULL_RID } } },
 93     { {0,0}, WinDialupSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_DIALUP_RID } } },
 94     { {'N','U'}, WinNetworkSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_NETWORK_RID } } },
 95     { {0,0}, WinBatchSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_BATCH_RID } } },
 96     { {'I','U'}, WinInteractiveSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_INTERACTIVE_RID } } },
 97     { {'S','U'}, WinServiceSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_SERVICE_RID } } },
 98     { {'A','N'}, WinAnonymousSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_ANONYMOUS_LOGON_RID } } },
 99     { {0,0}, WinProxySid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_PROXY_RID } } },
100     { {'E','D'}, WinEnterpriseControllersSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_ENTERPRISE_CONTROLLERS_RID } } },
101     { {'P','S'}, WinSelfSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_PRINCIPAL_SELF_RID } } },
102     { {'A','U'}, WinAuthenticatedUserSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_AUTHENTICATED_USER_RID } } },
103     { {'R','C'}, WinRestrictedCodeSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_RESTRICTED_CODE_RID } } },
104     { {0,0}, WinTerminalServerSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_TERMINAL_SERVER_RID } } },
105     { {0,0}, WinRemoteLogonIdSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_REMOTE_LOGON_RID } } },
106     { {'S','Y'}, WinLocalSystemSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_LOCAL_SYSTEM_RID } } },
107     { {'L','S'}, WinLocalServiceSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_LOCAL_SERVICE_RID } } },
108     { {'N','S'}, WinNetworkServiceSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_NETWORK_SERVICE_RID } } },
109     { {0,0}, WinBuiltinDomainSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID } } },
110     { {'B','A'}, WinBuiltinAdministratorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS } } },
111     { {'B','U'}, WinBuiltinUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_USERS } } },
112     { {'B','G'}, WinBuiltinGuestsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_GUESTS } } },
113     { {'P','U'}, WinBuiltinPowerUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_POWER_USERS } } },
114     { {'A','O'}, WinBuiltinAccountOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ACCOUNT_OPS } } },
115     { {'S','O'}, WinBuiltinSystemOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_SYSTEM_OPS } } },
116     { {'P','O'}, WinBuiltinPrintOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_PRINT_OPS } } },
117     { {'B','O'}, WinBuiltinBackupOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_BACKUP_OPS } } },
118     { {'R','E'}, WinBuiltinReplicatorSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_REPLICATOR } } },
119     { {'R','U'}, WinBuiltinPreWindows2000CompatibleAccessSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_PREW2KCOMPACCESS } } },
120     { {'R','D'}, WinBuiltinRemoteDesktopUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_REMOTE_DESKTOP_USERS } } },
121     { {'N','O'}, WinBuiltinNetworkConfigurationOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_NETWORK_CONFIGURATION_OPS } } },
122     { {0,0}, WinNTLMAuthenticationSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_PACKAGE_BASE_RID, SECURITY_PACKAGE_NTLM_RID } } },
123     { {0,0}, WinDigestAuthenticationSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_PACKAGE_BASE_RID, SECURITY_PACKAGE_DIGEST_RID } } },
124     { {0,0}, WinSChannelAuthenticationSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_PACKAGE_BASE_RID, SECURITY_PACKAGE_SCHANNEL_RID } } },
125     { {0,0}, WinThisOrganizationSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_THIS_ORGANIZATION_RID } } },
126     { {0,0}, WinOtherOrganizationSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_OTHER_ORGANIZATION_RID } } },
127     { {0,0}, WinBuiltinIncomingForestTrustBuildersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_INCOMING_FOREST_TRUST_BUILDERS  } } },
128     { {0,0}, WinBuiltinPerfMonitoringUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_MONITORING_USERS } } },
129     { {0,0}, WinBuiltinPerfLoggingUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_LOGGING_USERS } } },
130     { {0,0}, WinBuiltinAuthorizationAccessSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_AUTHORIZATIONACCESS } } },
131     { {0,0}, WinBuiltinTerminalServerLicenseServersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_TS_LICENSE_SERVERS } } },
132     { {0,0}, WinBuiltinDCOMUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_DCOM_USERS } } },
133 };
134 
135 /* these SIDs must be constructed as relative to some domain - only the RID is well-known */
136 typedef struct WELLKNOWNRID
137 {
138     WELL_KNOWN_SID_TYPE Type;
139     DWORD Rid;
140 } WELLKNOWNRID;
141 
142 static const WELLKNOWNRID WellKnownRids[] = {
143     { WinAccountAdministratorSid,    DOMAIN_USER_RID_ADMIN },
144     { WinAccountGuestSid,            DOMAIN_USER_RID_GUEST },
145     { WinAccountKrbtgtSid,           DOMAIN_USER_RID_KRBTGT },
146     { WinAccountDomainAdminsSid,     DOMAIN_GROUP_RID_ADMINS },
147     { WinAccountDomainUsersSid,      DOMAIN_GROUP_RID_USERS },
148     { WinAccountDomainGuestsSid,     DOMAIN_GROUP_RID_GUESTS },
149     { WinAccountComputersSid,        DOMAIN_GROUP_RID_COMPUTERS },
150     { WinAccountControllersSid,      DOMAIN_GROUP_RID_CONTROLLERS },
151     { WinAccountCertAdminsSid,       DOMAIN_GROUP_RID_CERT_ADMINS },
152     { WinAccountSchemaAdminsSid,     DOMAIN_GROUP_RID_SCHEMA_ADMINS },
153     { WinAccountEnterpriseAdminsSid, DOMAIN_GROUP_RID_ENTERPRISE_ADMINS },
154     { WinAccountPolicyAdminsSid,     DOMAIN_GROUP_RID_POLICY_ADMINS },
155     { WinAccountRasAndIasServersSid, DOMAIN_ALIAS_RID_RAS_SERVERS },
156 };
157 
158 
159 static SID const sidWorld = { SID_REVISION, 1, { SECURITY_WORLD_SID_AUTHORITY} , { SECURITY_WORLD_RID } };
160 
161 typedef struct _AccountSid {
162     WELL_KNOWN_SID_TYPE type;
163     LPCWSTR account;
164     LPCWSTR domain;
165     SID_NAME_USE name_use;
166 } AccountSid;
167 
168 static const WCHAR Account_Operators[] = { 'A','c','c','o','u','n','t',' ','O','p','e','r','a','t','o','r','s',0 };
169 static const WCHAR Administrator[] = {'A','d','m','i','n','i','s','t','r','a','t','o','r',0 };
170 static const WCHAR Administrators[] = { 'A','d','m','i','n','i','s','t','r','a','t','o','r','s',0 };
171 static const WCHAR ANONYMOUS_LOGON[] = { 'A','N','O','N','Y','M','O','U','S',' ','L','O','G','O','N',0 };
172 static const WCHAR Authenticated_Users[] = { 'A','u','t','h','e','n','t','i','c','a','t','e','d',' ','U','s','e','r','s',0 };
173 static const WCHAR Backup_Operators[] = { 'B','a','c','k','u','p',' ','O','p','e','r','a','t','o','r','s',0 };
174 static const WCHAR BATCH[] = { 'B','A','T','C','H',0 };
175 static const WCHAR Blank[] = { 0 };
176 static const WCHAR BUILTIN[] = { 'B','U','I','L','T','I','N',0 };
177 static const WCHAR Cert_Publishers[] = { 'C','e','r','t',' ','P','u','b','l','i','s','h','e','r','s',0 };
178 static const WCHAR CREATOR_GROUP[] = { 'C','R','E','A','T','O','R',' ','G','R','O','U','P',0 };
179 static const WCHAR CREATOR_GROUP_SERVER[] = { 'C','R','E','A','T','O','R',' ','G','R','O','U','P',' ','S','E','R','V','E','R',0 };
180 static const WCHAR CREATOR_OWNER[] = { 'C','R','E','A','T','O','R',' ','O','W','N','E','R',0 };
181 static const WCHAR CREATOR_OWNER_SERVER[] = { 'C','R','E','A','T','O','R',' ','O','W','N','E','R',' ','S','E','R','V','E','R',0 };
182 static const WCHAR DIALUP[] = { 'D','I','A','L','U','P',0 };
183 static const WCHAR Digest_Authentication[] = { 'D','i','g','e','s','t',' ','A','u','t','h','e','n','t','i','c','a','t','i','o','n',0 };
184 static const WCHAR DOMAIN[] = {'D','O','M','A','I','N',0};
185 static const WCHAR Domain_Admins[] = { 'D','o','m','a','i','n',' ','A','d','m','i','n','s',0 };
186 static const WCHAR Domain_Computers[] = { 'D','o','m','a','i','n',' ','C','o','m','p','u','t','e','r','s',0 };
187 static const WCHAR Domain_Controllers[] = { 'D','o','m','a','i','n',' ','C','o','n','t','r','o','l','l','e','r','s',0 };
188 static const WCHAR Domain_Guests[] = { 'D','o','m','a','i','n',' ','G','u','e','s','t','s',0 };
189 static const WCHAR Domain_Users[] = { 'D','o','m','a','i','n',' ','U','s','e','r','s',0 };
190 static const WCHAR Enterprise_Admins[] = { 'E','n','t','e','r','p','r','i','s','e',' ','A','d','m','i','n','s',0 };
191 static const WCHAR ENTERPRISE_DOMAIN_CONTROLLERS[] = { 'E','N','T','E','R','P','R','I','S','E',' ','D','O','M','A','I','N',' ','C','O','N','T','R','O','L','L','E','R','S',0 };
192 static const WCHAR Everyone[] = { 'E','v','e','r','y','o','n','e',0 };
193 static const WCHAR Group_Policy_Creator_Owners[] = { 'G','r','o','u','p',' ','P','o','l','i','c','y',' ','C','r','e','a','t','o','r',' ','O','w','n','e','r','s',0 };
194 static const WCHAR Guest[] = { 'G','u','e','s','t',0 };
195 static const WCHAR Guests[] = { 'G','u','e','s','t','s',0 };
196 static const WCHAR INTERACTIVE[] = { 'I','N','T','E','R','A','C','T','I','V','E',0 };
197 static const WCHAR LOCAL[] = { 'L','O','C','A','L',0 };
198 static const WCHAR LOCAL_SERVICE[] = { 'L','O','C','A','L',' ','S','E','R','V','I','C','E',0 };
199 static const WCHAR NETWORK[] = { 'N','E','T','W','O','R','K',0 };
200 static const WCHAR Network_Configuration_Operators[] = { 'N','e','t','w','o','r','k',' ','C','o','n','f','i','g','u','r','a','t','i','o','n',' ','O','p','e','r','a','t','o','r','s',0 };
201 static const WCHAR NETWORK_SERVICE[] = { 'N','E','T','W','O','R','K',' ','S','E','R','V','I','C','E',0 };
202 static const WCHAR NT_AUTHORITY[] = { 'N','T',' ','A','U','T','H','O','R','I','T','Y',0 };
203 static const WCHAR NT_Pseudo_Domain[] = { 'N','T',' ','P','s','e','u','d','o',' ','D','o','m','a','i','n',0 };
204 static const WCHAR NTML_Authentication[] = { 'N','T','M','L',' ','A','u','t','h','e','n','t','i','c','a','t','i','o','n',0 };
205 static const WCHAR NULL_SID[] = { 'N','U','L','L',' ','S','I','D',0 };
206 static const WCHAR Other_Organization[] = { 'O','t','h','e','r',' ','O','r','g','a','n','i','z','a','t','i','o','n',0 };
207 static const WCHAR Performance_Log_Users[] = { 'P','e','r','f','o','r','m','a','n','c','e',' ','L','o','g',' ','U','s','e','r','s',0 };
208 static const WCHAR Performance_Monitor_Users[] = { 'P','e','r','f','o','r','m','a','n','c','e',' ','M','o','n','i','t','o','r',' ','U','s','e','r','s',0 };
209 static const WCHAR Power_Users[] = { 'P','o','w','e','r',' ','U','s','e','r','s',0 };
210 static const WCHAR Pre_Windows_2000_Compatible_Access[] = { 'P','r','e','-','W','i','n','d','o','w','s',' ','2','','','',' ','C','o','m','p','a','t','i','b','l','e',' ','A','c','c','e','s','s',0 };
211 static const WCHAR Print_Operators[] = { 'P','r','i','n','t',' ','O','p','e','r','a','t','o','r','s',0 };
212 static const WCHAR PROXY[] = { 'P','R','O','X','Y',0 };
213 static const WCHAR RAS_and_IAS_Servers[] = { 'R','A','S',' ','a','n','d',' ','I','A','S',' ','S','e','r','v','e','r','s',0 };
214 static const WCHAR Remote_Desktop_Users[] = { 'R','e','m','o','t','e',' ','D','e','s','k','t','o','p',' ','U','s','e','r','s',0 };
215 static const WCHAR REMOTE_INTERACTIVE_LOGON[] = { 'R','E','M','O','T','E',' ','I','N','T','E','R','A','C','T','I','V','E',' ','L','O','G','O','N',0 };
216 static const WCHAR Replicators[] = { 'R','e','p','l','i','c','a','t','o','r','s',0 };
217 static const WCHAR RESTRICTED[] = { 'R','E','S','T','R','I','C','T','E','D',0 };
218 static const WCHAR SChannel_Authentication[] = { 'S','C','h','a','n','n','e','l',' ','A','u','t','h','e','n','t','i','c','a','t','i','o','n',0 };
219 static const WCHAR Schema_Admins[] = { 'S','c','h','e','m','a',' ','A','d','m','i','n','s',0 };
220 static const WCHAR SELF[] = { 'S','E','L','F',0 };
221 static const WCHAR Server_Operators[] = { 'S','e','r','v','e','r',' ','O','p','e','r','a','t','o','r','s',0 };
222 static const WCHAR SERVICE[] = { 'S','E','R','V','I','C','E',0 };
223 static const WCHAR SYSTEM[] = { 'S','Y','S','T','E','M',0 };
224 static const WCHAR TERMINAL_SERVER_USER[] = { 'T','E','R','M','I','N','A','L',' ','S','E','R','V','E','R',' ','U','S','E','R',0 };
225 static const WCHAR This_Organization[] = { 'T','h','i','s',' ','O','r','g','a','n','i','z','a','t','i','o','n',0 };
226 static const WCHAR Users[] = { 'U','s','e','r','s',0 };
227 
228 static const AccountSid ACCOUNT_SIDS[] = {
229     { WinNullSid, NULL_SID, Blank, SidTypeWellKnownGroup },
230     { WinWorldSid, Everyone, Blank, SidTypeWellKnownGroup },
231     { WinLocalSid, LOCAL, Blank, SidTypeWellKnownGroup },
232     { WinCreatorOwnerSid, CREATOR_OWNER, Blank, SidTypeWellKnownGroup },
233     { WinCreatorGroupSid, CREATOR_GROUP, Blank, SidTypeWellKnownGroup },
234     { WinCreatorOwnerServerSid, CREATOR_OWNER_SERVER, Blank, SidTypeWellKnownGroup },
235     { WinCreatorGroupServerSid, CREATOR_GROUP_SERVER, Blank, SidTypeWellKnownGroup },
236     { WinNtAuthoritySid, NT_Pseudo_Domain, NT_Pseudo_Domain, SidTypeDomain },
237     { WinDialupSid, DIALUP, NT_AUTHORITY, SidTypeWellKnownGroup },
238     { WinNetworkSid, NETWORK, NT_AUTHORITY, SidTypeWellKnownGroup },
239     { WinBatchSid, BATCH, NT_AUTHORITY, SidTypeWellKnownGroup },
240     { WinInteractiveSid, INTERACTIVE, NT_AUTHORITY, SidTypeWellKnownGroup },
241     { WinServiceSid, SERVICE, NT_AUTHORITY, SidTypeWellKnownGroup },
242     { WinAnonymousSid, ANONYMOUS_LOGON, NT_AUTHORITY, SidTypeWellKnownGroup },
243     { WinProxySid, PROXY, NT_AUTHORITY, SidTypeWellKnownGroup },
244     { WinEnterpriseControllersSid, ENTERPRISE_DOMAIN_CONTROLLERS, NT_AUTHORITY, SidTypeWellKnownGroup },
245     { WinSelfSid, SELF, NT_AUTHORITY, SidTypeWellKnownGroup },
246     { WinAuthenticatedUserSid, Authenticated_Users, NT_AUTHORITY, SidTypeWellKnownGroup },
247     { WinRestrictedCodeSid, RESTRICTED, NT_AUTHORITY, SidTypeWellKnownGroup },
248     { WinTerminalServerSid, TERMINAL_SERVER_USER, NT_AUTHORITY, SidTypeWellKnownGroup },
249     { WinRemoteLogonIdSid, REMOTE_INTERACTIVE_LOGON, NT_AUTHORITY, SidTypeWellKnownGroup },
250     { WinLocalSystemSid, SYSTEM, NT_AUTHORITY, SidTypeWellKnownGroup },
251     { WinLocalServiceSid, LOCAL_SERVICE, NT_AUTHORITY, SidTypeWellKnownGroup },
252     { WinNetworkServiceSid, NETWORK_SERVICE, NT_AUTHORITY, SidTypeWellKnownGroup },
253     { WinBuiltinDomainSid, BUILTIN, BUILTIN, SidTypeDomain },
254     { WinBuiltinAdministratorsSid, Administrators, BUILTIN, SidTypeAlias },
255     { WinBuiltinUsersSid, Users, BUILTIN, SidTypeAlias },
256     { WinBuiltinGuestsSid, Guests, BUILTIN, SidTypeAlias },
257     { WinBuiltinPowerUsersSid, Power_Users, BUILTIN, SidTypeAlias },
258     { WinBuiltinAccountOperatorsSid, Account_Operators, BUILTIN, SidTypeAlias },
259     { WinBuiltinSystemOperatorsSid, Server_Operators, BUILTIN, SidTypeAlias },
260     { WinBuiltinPrintOperatorsSid, Print_Operators, BUILTIN, SidTypeAlias },
261     { WinBuiltinBackupOperatorsSid, Backup_Operators, BUILTIN, SidTypeAlias },
262     { WinBuiltinReplicatorSid, Replicators, BUILTIN, SidTypeAlias },
263     { WinBuiltinPreWindows2000CompatibleAccessSid, Pre_Windows_2000_Compatible_Access, BUILTIN, SidTypeAlias },
264     { WinBuiltinRemoteDesktopUsersSid, Remote_Desktop_Users, BUILTIN, SidTypeAlias },
265     { WinBuiltinNetworkConfigurationOperatorsSid, Network_Configuration_Operators, BUILTIN, SidTypeAlias },
266     { WinNTLMAuthenticationSid, NTML_Authentication, NT_AUTHORITY, SidTypeWellKnownGroup },
267     { WinDigestAuthenticationSid, Digest_Authentication, NT_AUTHORITY, SidTypeWellKnownGroup },
268     { WinSChannelAuthenticationSid, SChannel_Authentication, NT_AUTHORITY, SidTypeWellKnownGroup },
269     { WinThisOrganizationSid, This_Organization, NT_AUTHORITY, SidTypeWellKnownGroup },
270     { WinOtherOrganizationSid, Other_Organization, NT_AUTHORITY, SidTypeWellKnownGroup },
271     { WinBuiltinPerfMonitoringUsersSid, Performance_Monitor_Users, BUILTIN, SidTypeAlias },
272     { WinBuiltinPerfLoggingUsersSid, Performance_Log_Users, BUILTIN, SidTypeAlias },
273 };
274 /*
275  * ACE access rights
276  */
277 static const WCHAR SDDL_READ_CONTROL[]     = {'R','C',0};
278 static const WCHAR SDDL_WRITE_DAC[]        = {'W','D',0};
279 static const WCHAR SDDL_WRITE_OWNER[]      = {'W','O',0};
280 static const WCHAR SDDL_STANDARD_DELETE[]  = {'S','D',0};
281 
282 static const WCHAR SDDL_READ_PROPERTY[]    = {'R','P',0};
283 static const WCHAR SDDL_WRITE_PROPERTY[]   = {'W','P',0};
284 static const WCHAR SDDL_CREATE_CHILD[]     = {'C','C',0};
285 static const WCHAR SDDL_DELETE_CHILD[]     = {'D','C',0};
286 static const WCHAR SDDL_LIST_CHILDREN[]    = {'L','C',0};
287 static const WCHAR SDDL_SELF_WRITE[]       = {'S','W',0};
288 static const WCHAR SDDL_LIST_OBJECT[]      = {'L','O',0};
289 static const WCHAR SDDL_DELETE_TREE[]      = {'D','T',0};
290 static const WCHAR SDDL_CONTROL_ACCESS[]   = {'C','R',0};
291 
292 static const WCHAR SDDL_FILE_ALL[]         = {'F','A',0};
293 static const WCHAR SDDL_FILE_READ[]        = {'F','R',0};
294 static const WCHAR SDDL_FILE_WRITE[]       = {'F','W',0};
295 static const WCHAR SDDL_FILE_EXECUTE[]     = {'F','X',0};
296 
297 static const WCHAR SDDL_KEY_ALL[]          = {'K','A',0};
298 static const WCHAR SDDL_KEY_READ[]         = {'K','R',0};
299 static const WCHAR SDDL_KEY_WRITE[]        = {'K','W',0};
300 static const WCHAR SDDL_KEY_EXECUTE[]      = {'K','X',0};
301 
302 static const WCHAR SDDL_GENERIC_ALL[]      = {'G','A',0};
303 static const WCHAR SDDL_GENERIC_READ[]     = {'G','R',0};
304 static const WCHAR SDDL_GENERIC_WRITE[]    = {'G','W',0};
305 static const WCHAR SDDL_GENERIC_EXECUTE[]  = {'G','X',0};
306 
307 /*
308  * ACL flags
309  */
310 static const WCHAR SDDL_PROTECTED[]             = {'P',0};
311 static const WCHAR SDDL_AUTO_INHERIT_REQ[]      = {'A','R',0};
312 static const WCHAR SDDL_AUTO_INHERITED[]        = {'A','I',0};
313 
314 /*
315  * ACE types
316  */
317 static const WCHAR SDDL_ACCESS_ALLOWED[]        = {'A',0};
318 static const WCHAR SDDL_ACCESS_DENIED[]         = {'D',0};
319 static const WCHAR SDDL_OBJECT_ACCESS_ALLOWED[] = {'O','A',0};
320 static const WCHAR SDDL_OBJECT_ACCESS_DENIED[]  = {'O','D',0};
321 static const WCHAR SDDL_AUDIT[]                 = {'A','U',0};
322 static const WCHAR SDDL_ALARM[]                 = {'A','L',0};
323 static const WCHAR SDDL_OBJECT_AUDIT[]          = {'O','U',0};
324 static const WCHAR SDDL_OBJECT_ALARMp[]         = {'O','L',0};
325 
326 /*
327  * ACE flags
328  */
329 static const WCHAR SDDL_CONTAINER_INHERIT[]  = {'C','I',0};
330 static const WCHAR SDDL_OBJECT_INHERIT[]     = {'O','I',0};
331 static const WCHAR SDDL_NO_PROPAGATE[]       = {'N','P',0};
332 static const WCHAR SDDL_INHERIT_ONLY[]       = {'I','O',0};
333 static const WCHAR SDDL_INHERITED[]          = {'I','D',0};
334 static const WCHAR SDDL_AUDIT_SUCCESS[]      = {'S','A',0};
335 static const WCHAR SDDL_AUDIT_FAILURE[]      = {'F','A',0};
336 
337 const char * debugstr_sid(PSID sid)
338 {
339     int auth = 0;
340     SID * psid = (SID *)sid;
341 
342     if (psid == NULL)
343         return "(null)";
344 
345     auth = psid->IdentifierAuthority.Value[5] +
346            (psid->IdentifierAuthority.Value[4] << 8) +
347            (psid->IdentifierAuthority.Value[3] << 16) +
348            (psid->IdentifierAuthority.Value[2] << 24);
349 
350     switch (psid->SubAuthorityCount) {
351     case 0:
352         return wine_dbg_sprintf("S-%d-%d", psid->Revision, auth);
353     case 1:
354         return wine_dbg_sprintf("S-%d-%d-%u", psid->Revision, auth,
355             psid->SubAuthority[0]);
356     case 2:
357         return wine_dbg_sprintf("S-%d-%d-%u-%u", psid->Revision, auth,
358             psid->SubAuthority[0], psid->SubAuthority[1]);
359     case 3:
360         return wine_dbg_sprintf("S-%d-%d-%u-%u-%u", psid->Revision, auth,
361             psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2]);
362     case 4:
363         return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u", psid->Revision, auth,
364             psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
365             psid->SubAuthority[3]);
366     case 5:
367         return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u", psid->Revision, auth,
368             psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
369             psid->SubAuthority[3], psid->SubAuthority[4]);
370     case 6:
371         return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u-%u", psid->Revision, auth,
372             psid->SubAuthority[3], psid->SubAuthority[1], psid->SubAuthority[2],
373             psid->SubAuthority[0], psid->SubAuthority[4], psid->SubAuthority[5]);
374     case 7:
375         return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u-%u-%u", psid->Revision, auth,
376             psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
377             psid->SubAuthority[3], psid->SubAuthority[4], psid->SubAuthority[5],
378             psid->SubAuthority[6]);
379     case 8:
380         return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u-%u-%u-%u", psid->Revision, auth,
381             psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
382             psid->SubAuthority[3], psid->SubAuthority[4], psid->SubAuthority[5],
383             psid->SubAuthority[6], psid->SubAuthority[7]);
384     }
385     return "(too-big)";
386 }
387 
388 /* set last error code from NT status and get the proper boolean return value */
389 /* used for functions that are a simple wrapper around the corresponding ntdll API */
390 static inline BOOL set_ntstatus( NTSTATUS status )
391 {
392     if (status) SetLastError( RtlNtStatusToDosError( status ));
393     return !status;
394 }
395 
396 #define WINE_SIZE_OF_WORLD_ACCESS_ACL   (sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE) + sizeof(sidWorld) - sizeof(DWORD))
397 
398 static void GetWorldAccessACL(PACL pACL)
399 {
400     PACCESS_ALLOWED_ACE pACE = (PACCESS_ALLOWED_ACE) (pACL + 1);
401 
402     pACL->AclRevision = ACL_REVISION;
403     pACL->Sbz1 = 0;
404     pACL->AclSize = WINE_SIZE_OF_WORLD_ACCESS_ACL;
405     pACL->AceCount = 1;
406     pACL->Sbz2 = 0;
407 
408     pACE->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
409     pACE->Header.AceFlags = CONTAINER_INHERIT_ACE;
410     pACE->Header.AceSize = sizeof(ACCESS_ALLOWED_ACE) + sizeof(sidWorld) - sizeof(DWORD);
411     pACE->Mask = 0xf3ffffff; /* Everything except reserved bits */
412     memcpy(&pACE->SidStart, &sidWorld, sizeof(sidWorld));
413 }
414 
415 /************************************************************
416  *                ADVAPI_IsLocalComputer
417  *
418  * Checks whether the server name indicates local machine.
419  */
420 BOOL ADVAPI_IsLocalComputer(LPCWSTR ServerName)
421 {
422     DWORD dwSize = MAX_COMPUTERNAME_LENGTH + 1;
423     BOOL Result;
424     LPWSTR buf;
425 
426     if (!ServerName || !ServerName[0])
427         return TRUE;
428 
429     buf = HeapAlloc(GetProcessHeap(), 0, dwSize * sizeof(WCHAR));
430     Result = GetComputerNameW(buf,  &dwSize);
431     if (Result && (ServerName[0] == '\\') && (ServerName[1] == '\\'))
432         ServerName += 2;
433     Result = Result && !lstrcmpW(ServerName, buf);
434     HeapFree(GetProcessHeap(), 0, buf);
435 
436     return Result;
437 }
438 
439 /************************************************************
440  *                ADVAPI_GetComputerSid
441  *
442  * Reads the computer SID from the registry.
443  */
444 BOOL ADVAPI_GetComputerSid(PSID sid)
445 {
446     HKEY key;
447     LONG ret;
448     BOOL retval = FALSE;
449     static const WCHAR Account[] = { 'S','E','C','U','R','I','T','Y','\\','S','A','M','\\','D','o','m','a','i','n','s','\\','A','c','c','o','u','n','t',0 };
450     static const WCHAR V[] = { 'V',0 };
451 
452     if ((ret = RegOpenKeyExW(HKEY_LOCAL_MACHINE, Account, 0,
453         KEY_READ, &key)) == ERROR_SUCCESS)
454     {
455         DWORD size = 0;
456         ret = RegQueryValueExW(key, V, NULL, NULL, NULL, &size);
457         if (ret == ERROR_MORE_DATA || ret == ERROR_SUCCESS)
458         {
459             BYTE * data = HeapAlloc(GetProcessHeap(), 0, size);
460             if (data)
461             {
462                 if ((ret = RegQueryValueExW(key, V, NULL, NULL,
463                      data, &size)) == ERROR_SUCCESS)
464                 {
465                     /* the SID is in the last 24 bytes of the binary data */
466                     CopyMemory(sid, &data[size-24], 24);
467                     retval = TRUE;
468                 }
469                 HeapFree(GetProcessHeap(), 0, data);
470             }
471         }
472         RegCloseKey(key);
473     }
474 
475     if(retval == TRUE) return retval;
476 
477     /* create a new random SID */
478     if (RegCreateKeyExW(HKEY_LOCAL_MACHINE, Account,
479         0, NULL, 0, KEY_ALL_ACCESS, NULL, &key, NULL) == ERROR_SUCCESS)
480     {
481         PSID new_sid;
482         SID_IDENTIFIER_AUTHORITY identifierAuthority = {SECURITY_NT_AUTHORITY};
483         DWORD id[3];
484 
485         if (RtlGenRandom(id, sizeof(id)))
486         {
487             if (AllocateAndInitializeSid(&identifierAuthority, 4, SECURITY_NT_NON_UNIQUE, id[0], id[1], id[2], 0, 0, 0, 0, &new_sid))
488             {
489                 if (RegSetValueExW(key, V, 0, REG_BINARY, new_sid, GetLengthSid(new_sid)) == ERROR_SUCCESS)
490                     retval = CopySid(GetLengthSid(new_sid), sid, new_sid);
491 
492                 FreeSid(new_sid);
493             }
494         }
495         RegCloseKey(key);
496     }
497 
498     return retval;
499 }
500 
501 /*      ##############################
502         ######  TOKEN FUNCTIONS ######
503         ##############################
504 */
505 
506 /******************************************************************************
507  * OpenProcessToken                     [ADVAPI32.@]
508  * Opens the access token associated with a process handle.
509  *
510  * PARAMS
511  *   ProcessHandle [I] Handle to process
512  *   DesiredAccess [I] Desired access to process
513  *   TokenHandle   [O] Pointer to handle of open access token
514  *
515  * RETURNS
516  *  Success: TRUE. TokenHandle contains the access token.
517  *  Failure: FALSE.
518  *
519  * NOTES
520  *  See NtOpenProcessToken.
521  */
522 BOOL WINAPI
523 OpenProcessToken( HANDLE ProcessHandle, DWORD DesiredAccess,
524                   HANDLE *TokenHandle )
525 {
526         return set_ntstatus(NtOpenProcessToken( ProcessHandle, DesiredAccess, TokenHandle ));
527 }
528 
529 /******************************************************************************
530  * OpenThreadToken [ADVAPI32.@]
531  *
532  * Opens the access token associated with a thread handle.
533  *
534  * PARAMS
535  *   ThreadHandle  [I] Handle to process
536  *   DesiredAccess [I] Desired access to the thread
537  *   OpenAsSelf    [I] ???
538  *   TokenHandle   [O] Destination for the token handle
539  *
540  * RETURNS
541  *  Success: TRUE. TokenHandle contains the access token.
542  *  Failure: FALSE.
543  *
544  * NOTES
545  *  See NtOpenThreadToken.
546  */
547 BOOL WINAPI
548 OpenThreadToken( HANDLE ThreadHandle, DWORD DesiredAccess,
549                  BOOL OpenAsSelf, HANDLE *TokenHandle)
550 {
551         return set_ntstatus( NtOpenThreadToken(ThreadHandle, DesiredAccess, OpenAsSelf, TokenHandle));
552 }
553 
554 BOOL WINAPI
555 AdjustTokenGroups( HANDLE TokenHandle, BOOL ResetToDefault, PTOKEN_GROUPS NewState,
556                    DWORD BufferLength, PTOKEN_GROUPS PreviousState, PDWORD ReturnLength )
557 {
558     return set_ntstatus( NtAdjustGroupsToken(TokenHandle, ResetToDefault, NewState, BufferLength,
559                                              PreviousState, ReturnLength));
560 }
561 
562 /******************************************************************************
563  * AdjustTokenPrivileges [ADVAPI32.@]
564  *
565  * Adjust the privileges of an open token handle.
566  * 
567  * PARAMS
568  *  TokenHandle          [I]   Handle from OpenProcessToken() or OpenThreadToken() 
569  *  DisableAllPrivileges [I]   TRUE=Remove all privileges, FALSE=Use NewState
570  *  NewState             [I]   Desired new privileges of the token
571  *  BufferLength         [I]   Length of NewState
572  *  PreviousState        [O]   Destination for the previous state
573  *  ReturnLength         [I/O] Size of PreviousState
574  *
575  *
576  * RETURNS
577  *  Success: TRUE. Privileges are set to NewState and PreviousState is updated.
578  *  Failure: FALSE.
579  *
580  * NOTES
581  *  See NtAdjustPrivilegesToken.
582  */
583 BOOL WINAPI
584 AdjustTokenPrivileges( HANDLE TokenHandle, BOOL DisableAllPrivileges,
585                        PTOKEN_PRIVILEGES NewState, DWORD BufferLength,
586                        PTOKEN_PRIVILEGES PreviousState, PDWORD ReturnLength )
587 {
588     NTSTATUS status;
589 
590     TRACE("\n");
591     
592     status = NtAdjustPrivilegesToken(TokenHandle, DisableAllPrivileges,
593                                                      NewState, BufferLength, PreviousState,
594                                                      ReturnLength);
595     SetLastError( RtlNtStatusToDosError( status ));
596     if ((status == STATUS_SUCCESS) || (status == STATUS_NOT_ALL_ASSIGNED))
597         return TRUE;
598     else
599         return FALSE;
600 }
601 
602 /******************************************************************************
603  * CheckTokenMembership [ADVAPI32.@]
604  *
605  * Determine if an access token is a member of a SID.
606  * 
607  * PARAMS
608  *   TokenHandle [I] Handle from OpenProcessToken() or OpenThreadToken()
609  *   SidToCheck  [I] SID that possibly contains the token
610  *   IsMember    [O] Destination for result.
611  *
612  * RETURNS
613  *  Success: TRUE. IsMember is TRUE if TokenHandle is a member, FALSE otherwise.
614  *  Failure: FALSE.
615  */
616 BOOL WINAPI
617 CheckTokenMembership( HANDLE TokenHandle, PSID SidToCheck,
618                       PBOOL IsMember )
619 {
620   FIXME("(%p %p %p) stub!\n", TokenHandle, SidToCheck, IsMember);
621 
622   *IsMember = TRUE;
623   return(TRUE);
624 }
625 
626 /******************************************************************************
627  * GetTokenInformation [ADVAPI32.@]
628  *
629  * Get a type of information about an access token.
630  *
631  * PARAMS
632  *   token           [I] Handle from OpenProcessToken() or OpenThreadToken()
633  *   tokeninfoclass  [I] A TOKEN_INFORMATION_CLASS from "winnt.h"
634  *   tokeninfo       [O] Destination for token information
635  *   tokeninfolength [I] Length of tokeninfo
636  *   retlen          [O] Destination for returned token information length
637  *
638  * RETURNS
639  *  Success: TRUE. tokeninfo contains retlen bytes of token information
640  *  Failure: FALSE.
641  *
642  * NOTES
643  *  See NtQueryInformationToken.
644  */
645 BOOL WINAPI
646 GetTokenInformation( HANDLE token, TOKEN_INFORMATION_CLASS tokeninfoclass,
647                      LPVOID tokeninfo, DWORD tokeninfolength, LPDWORD retlen )
648 {
649     TRACE("(%p, %s, %p, %d, %p):\n",
650           token,
651           (tokeninfoclass == TokenUser) ? "TokenUser" :
652           (tokeninfoclass == TokenGroups) ? "TokenGroups" :
653           (tokeninfoclass == TokenPrivileges) ? "TokenPrivileges" :
654           (tokeninfoclass == TokenOwner) ? "TokenOwner" :
655           (tokeninfoclass == TokenPrimaryGroup) ? "TokenPrimaryGroup" :
656           (tokeninfoclass == TokenDefaultDacl) ? "TokenDefaultDacl" :
657           (tokeninfoclass == TokenSource) ? "TokenSource" :
658           (tokeninfoclass == TokenType) ? "TokenType" :
659           (tokeninfoclass == TokenImpersonationLevel) ? "TokenImpersonationLevel" :
660           (tokeninfoclass == TokenStatistics) ? "TokenStatistics" :
661           (tokeninfoclass == TokenRestrictedSids) ? "TokenRestrictedSids" :
662           (tokeninfoclass == TokenSessionId) ? "TokenSessionId" :
663           (tokeninfoclass == TokenGroupsAndPrivileges) ? "TokenGroupsAndPrivileges" :
664           (tokeninfoclass == TokenSessionReference) ? "TokenSessionReference" :
665           (tokeninfoclass == TokenSandBoxInert) ? "TokenSandBoxInert" :
666           "Unknown",
667           tokeninfo, tokeninfolength, retlen);
668     return set_ntstatus( NtQueryInformationToken( token, tokeninfoclass, tokeninfo,
669                                                   tokeninfolength, retlen));
670 }
671 
672 /******************************************************************************
673  * SetTokenInformation [ADVAPI32.@]
674  *
675  * Set information for an access token.
676  *
677  * PARAMS
678  *   token           [I] Handle from OpenProcessToken() or OpenThreadToken()
679  *   tokeninfoclass  [I] A TOKEN_INFORMATION_CLASS from "winnt.h"
680  *   tokeninfo       [I] Token information to set
681  *   tokeninfolength [I] Length of tokeninfo
682  *
683  * RETURNS
684  *  Success: TRUE. The information for the token is set to tokeninfo.
685  *  Failure: FALSE.
686  */
687 BOOL WINAPI
688 SetTokenInformation( HANDLE token, TOKEN_INFORMATION_CLASS tokeninfoclass,
689                      LPVOID tokeninfo, DWORD tokeninfolength )
690 {
691     TRACE("(%p, %s, %p, %d): stub\n",
692           token,
693           (tokeninfoclass == TokenUser) ? "TokenUser" :
694           (tokeninfoclass == TokenGroups) ? "TokenGroups" :
695           (tokeninfoclass == TokenPrivileges) ? "TokenPrivileges" :
696           (tokeninfoclass == TokenOwner) ? "TokenOwner" :
697           (tokeninfoclass == TokenPrimaryGroup) ? "TokenPrimaryGroup" :
698           (tokeninfoclass == TokenDefaultDacl) ? "TokenDefaultDacl" :
699           (tokeninfoclass == TokenSource) ? "TokenSource" :
700           (tokeninfoclass == TokenType) ? "TokenType" :
701           (tokeninfoclass == TokenImpersonationLevel) ? "TokenImpersonationLevel" :
702           (tokeninfoclass == TokenStatistics) ? "TokenStatistics" :
703           (tokeninfoclass == TokenRestrictedSids) ? "TokenRestrictedSids" :
704           (tokeninfoclass == TokenSessionId) ? "TokenSessionId" :
705           (tokeninfoclass == TokenGroupsAndPrivileges) ? "TokenGroupsAndPrivileges" :
706           (tokeninfoclass == TokenSessionReference) ? "TokenSessionReference" :
707           (tokeninfoclass == TokenSandBoxInert) ? "TokenSandBoxInert" :
708           "Unknown",
709           tokeninfo, tokeninfolength);
710 
711     return set_ntstatus( NtSetInformationToken( token, tokeninfoclass, tokeninfo, tokeninfolength ));
712 }
713 
714 /*************************************************************************
715  * SetThreadToken [ADVAPI32.@]
716  *
717  * Assigns an 'impersonation token' to a thread so it can assume the
718  * security privileges of another thread or process.  Can also remove
719  * a previously assigned token. 
720  *
721  * PARAMS
722  *   thread          [O] Handle to thread to set the token for
723  *   token           [I] Token to set
724  *
725  * RETURNS
726  *  Success: TRUE. The threads access token is set to token
727  *  Failure: FALSE.
728  *
729  * NOTES
730  *  Only supported on NT or higher. On Win9X this function does nothing.
731  *  See SetTokenInformation.
732  */
733 BOOL WINAPI SetThreadToken(PHANDLE thread, HANDLE token)
734 {
735     return set_ntstatus( NtSetInformationThread( thread ? *thread : GetCurrentThread(),
736                                                  ThreadImpersonationToken, &token, sizeof token ));
737 }
738 
739 /*************************************************************************
740  * CreateRestrictedToken [ADVAPI32.@]
741  *
742  * Create a new more restricted token from an existing token.
743  *
744  * PARAMS
745  *   baseToken       [I] Token to base the new restricted token on
746  *   flags           [I] Options
747  *   nDisableSids    [I] Length of disableSids array
748  *   disableSids     [I] Array of SIDs to disable in the new token
749  *   nDeletePrivs    [I] Length of deletePrivs array
750  *   deletePrivs     [I] Array of privileges to delete in the new token
751  *   nRestrictSids   [I] Length of restrictSids array
752  *   restrictSids    [I] Array of SIDs to restrict in the new token
753  *   newToken        [O] Address where the new token is stored
754  *
755  * RETURNS
756  *  Success: TRUE
757  *  Failure: FALSE
758  */
759 BOOL WINAPI CreateRestrictedToken(
760     HANDLE baseToken,
761     DWORD flags,
762     DWORD nDisableSids,
763     PSID_AND_ATTRIBUTES disableSids,
764     DWORD nDeletePrivs,
765     PLUID_AND_ATTRIBUTES deletePrivs,
766     DWORD nRestrictSids,
767     PSID_AND_ATTRIBUTES restrictSids,
768     PHANDLE newToken)
769 {
770     FIXME("(%p, 0x%x, %u, %p, %u, %p, %u, %p, %p): stub\n",
771           baseToken, flags, nDisableSids, disableSids,
772           nDeletePrivs, deletePrivs,
773           nRestrictSids, restrictSids,
774           newToken);
775     SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
776     return FALSE;
777 }
778 
779 /*      ##############################
780         ######  SID FUNCTIONS   ######
781         ##############################
782 */
783 
784 /******************************************************************************
785  * AllocateAndInitializeSid [ADVAPI32.@]
786  *
787  * PARAMS
788  *   pIdentifierAuthority []
789  *   nSubAuthorityCount   []
790  *   nSubAuthority0       []
791  *   nSubAuthority1       []
792  *   nSubAuthority2       []
793  *   nSubAuthority3       []
794  *   nSubAuthority4       []
795  *   nSubAuthority5       []
796  *   nSubAuthority6       []
797  *   nSubAuthority7       []
798  *   pSid                 []
799  */
800 BOOL WINAPI
801 AllocateAndInitializeSid( PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
802                           BYTE nSubAuthorityCount,
803                           DWORD nSubAuthority0, DWORD nSubAuthority1,
804                           DWORD nSubAuthority2, DWORD nSubAuthority3,
805                           DWORD nSubAuthority4, DWORD nSubAuthority5,
806                           DWORD nSubAuthority6, DWORD nSubAuthority7,
807                           PSID *pSid )
808 {
809     return set_ntstatus( RtlAllocateAndInitializeSid(
810                              pIdentifierAuthority, nSubAuthorityCount,
811                              nSubAuthority0, nSubAuthority1, nSubAuthority2, nSubAuthority3,
812                              nSubAuthority4, nSubAuthority5, nSubAuthority6, nSubAuthority7,
813                              pSid ));
814 }
815 
816 /******************************************************************************
817  * FreeSid [ADVAPI32.@]
818  *
819  * PARAMS
820  *   pSid []
821  */
822 PVOID WINAPI
823 FreeSid( PSID pSid )
824 {
825         RtlFreeSid(pSid);
826         return NULL; /* is documented like this */
827 }
828 
829 /******************************************************************************
830  * CopySid [ADVAPI32.@]
831  *
832  * PARAMS
833  *   nDestinationSidLength []
834  *   pDestinationSid       []
835  *   pSourceSid            []
836  */
837 BOOL WINAPI
838 CopySid( DWORD nDestinationSidLength, PSID pDestinationSid, PSID pSourceSid )
839 {
840         return RtlCopySid(nDestinationSidLength, pDestinationSid, pSourceSid);
841 }
842 
843 /******************************************************************************
844  * CreateWellKnownSid [ADVAPI32.@]
845  */
846 BOOL WINAPI
847 CreateWellKnownSid( WELL_KNOWN_SID_TYPE WellKnownSidType,
848                     PSID DomainSid,
849                     PSID pSid,
850                     DWORD* cbSid)
851 {
852     unsigned int i;
853     TRACE("(%d, %s, %p, %p)\n", WellKnownSidType, debugstr_sid(DomainSid), pSid, cbSid);
854 
855     if (cbSid == NULL || pSid == NULL || (DomainSid && !IsValidSid(DomainSid))) {
856         SetLastError(ERROR_INVALID_PARAMETER);
857         return FALSE;
858     }
859 
860     for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++) {
861         if (WellKnownSids[i].Type == WellKnownSidType) {
862             DWORD length = GetSidLengthRequired(WellKnownSids[i].Sid.SubAuthorityCount);
863 
864             if (*cbSid < length) {
865                 SetLastError(ERROR_INSUFFICIENT_BUFFER);
866                 return FALSE;
867             }
868 
869             CopyMemory(pSid, &WellKnownSids[i].Sid.Revision, length);
870             *cbSid = length;
871             return TRUE;
872         }
873     }
874 
875     if (DomainSid == NULL || *GetSidSubAuthorityCount(DomainSid) == SID_MAX_SUB_AUTHORITIES)
876     {
877         SetLastError(ERROR_INVALID_PARAMETER);
878         return FALSE;
879     }
880 
881     for (i = 0; i < sizeof(WellKnownRids)/sizeof(WellKnownRids[0]); i++)
882         if (WellKnownRids[i].Type == WellKnownSidType) {
883             UCHAR domain_subauth = *GetSidSubAuthorityCount(DomainSid);
884             DWORD domain_sid_length = GetSidLengthRequired(domain_subauth);
885             DWORD output_sid_length = GetSidLengthRequired(domain_subauth + 1);
886 
887             if (*cbSid < output_sid_length) {
888                 SetLastError(ERROR_INSUFFICIENT_BUFFER);
889                 return FALSE;
890             }
891 
892             CopyMemory(pSid, DomainSid, domain_sid_length);
893             (*GetSidSubAuthorityCount(pSid))++;
894             (*GetSidSubAuthority(pSid, domain_subauth)) = WellKnownRids[i].Rid;
895             *cbSid = output_sid_length;
896             return TRUE;
897         }
898 
899     SetLastError(ERROR_INVALID_PARAMETER);
900     return FALSE;
901 }
902 
903 /******************************************************************************
904  * IsWellKnownSid [ADVAPI32.@]
905  */
906 BOOL WINAPI
907 IsWellKnownSid( PSID pSid, WELL_KNOWN_SID_TYPE WellKnownSidType )
908 {
909     unsigned int i;
910     TRACE("(%s, %d)\n", debugstr_sid(pSid), WellKnownSidType);
911 
912     for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
913         if (WellKnownSids[i].Type == WellKnownSidType)
914             if (EqualSid(pSid, (PSID)&(WellKnownSids[i].Sid.Revision)))
915                 return TRUE;
916 
917     return FALSE;
918 }
919 
920 BOOL WINAPI
921 IsTokenRestricted( HANDLE TokenHandle )
922 {
923     TOKEN_GROUPS *groups;
924     DWORD size;
925     NTSTATUS status;
926     BOOL restricted;
927 
928     TRACE("(%p)\n", TokenHandle);
929  
930     status = NtQueryInformationToken(TokenHandle, TokenRestrictedSids, NULL, 0, &size);
931     if (status != STATUS_BUFFER_TOO_SMALL)
932         return FALSE;
933  
934     groups = HeapAlloc(GetProcessHeap(), 0, size);
935     if (!groups)
936     {
937         SetLastError(ERROR_OUTOFMEMORY);
938         return FALSE;
939     }
940  
941     status = NtQueryInformationToken(TokenHandle, TokenRestrictedSids, groups, size, &size);
942     if (status != STATUS_SUCCESS)
943     {
944         HeapFree(GetProcessHeap(), 0, groups);
945         return set_ntstatus(status);
946     }
947  
948     if (groups->GroupCount)
949         restricted = TRUE;
950     else
951         restricted = FALSE;
952      
953     HeapFree(GetProcessHeap(), 0, groups);
954  
955     return restricted;
956 }
957 
958 /******************************************************************************
959  * IsValidSid [ADVAPI32.@]
960  *
961  * PARAMS
962  *   pSid []
963  */
964 BOOL WINAPI
965 IsValidSid( PSID pSid )
966 {
967         return RtlValidSid( pSid );
968 }
969 
970 /******************************************************************************
971  * EqualSid [ADVAPI32.@]
972  *
973  * PARAMS
974  *   pSid1 []
975  *   pSid2 []
976  */
977 BOOL WINAPI
978 EqualSid( PSID pSid1, PSID pSid2 )
979 {
980         return RtlEqualSid( pSid1, pSid2 );
981 }
982 
983 /******************************************************************************
984  * EqualPrefixSid [ADVAPI32.@]
985  */
986 BOOL WINAPI EqualPrefixSid (PSID pSid1, PSID pSid2)
987 {
988         return RtlEqualPrefixSid(pSid1, pSid2);
989 }
990 
991 /******************************************************************************
992  * GetSidLengthRequired [ADVAPI32.@]
993  *
994  * PARAMS
995  *   nSubAuthorityCount []
996  */
997 DWORD WINAPI
998 GetSidLengthRequired( BYTE nSubAuthorityCount )
999 {
1000         return RtlLengthRequiredSid(nSubAuthorityCount);
1001 }
1002 
1003 /******************************************************************************
1004  * InitializeSid [ADVAPI32.@]
1005  *
1006  * PARAMS
1007  *   pIdentifierAuthority []
1008  */
1009 BOOL WINAPI
1010 InitializeSid (
1011         PSID pSid,
1012         PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
1013         BYTE nSubAuthorityCount)
1014 {
1015         return RtlInitializeSid(pSid, pIdentifierAuthority, nSubAuthorityCount);
1016 }
1017 
1018 DWORD WINAPI
1019 GetEffectiveRightsFromAclA( PACL pacl, PTRUSTEEA pTrustee, PACCESS_MASK pAccessRights )
1020 {
1021     FIXME("%p %p %p - stub\n", pacl, pTrustee, pAccessRights);
1022 
1023     return 1;
1024 }
1025 
1026 DWORD WINAPI
1027 GetEffectiveRightsFromAclW( PACL pacl, PTRUSTEEW pTrustee, PACCESS_MASK pAccessRights )
1028 {
1029     FIXME("%p %p %p - stub\n", pacl, pTrustee, pAccessRights);
1030 
1031     return 1;
1032 }
1033 
1034 /******************************************************************************
1035  * GetSidIdentifierAuthority [ADVAPI32.@]
1036  *
1037  * PARAMS
1038  *   pSid []
1039  */
1040 PSID_IDENTIFIER_AUTHORITY WINAPI
1041 GetSidIdentifierAuthority( PSID pSid )
1042 {
1043         return RtlIdentifierAuthoritySid(pSid);
1044 }
1045 
1046 /******************************************************************************
1047  * GetSidSubAuthority [ADVAPI32.@]
1048  *
1049  * PARAMS
1050  *   pSid          []
1051  *   nSubAuthority []
1052  */
1053 PDWORD WINAPI
1054 GetSidSubAuthority( PSID pSid, DWORD nSubAuthority )
1055 {
1056         return RtlSubAuthoritySid(pSid, nSubAuthority);
1057 }
1058 
1059 /******************************************************************************
1060  * GetSidSubAuthorityCount [ADVAPI32.@]
1061  *
1062  * PARAMS
1063  *   pSid []
1064  */
1065 PUCHAR WINAPI
1066 GetSidSubAuthorityCount (PSID pSid)
1067 {
1068         return RtlSubAuthorityCountSid(pSid);
1069 }
1070 
1071 /******************************************************************************
1072  * GetLengthSid [ADVAPI32.@]
1073  *
1074  * PARAMS
1075  *   pSid []
1076  */
1077 DWORD WINAPI
1078 GetLengthSid (PSID pSid)
1079 {
1080         return RtlLengthSid(pSid);
1081 }
1082 
1083 /*      ##############################################
1084         ######  SECURITY DESCRIPTOR FUNCTIONS   ######
1085         ##############################################
1086 */
1087 
1088  /****************************************************************************** 
1089  * BuildSecurityDescriptorA [ADVAPI32.@]
1090  *
1091  * Builds a SD from 
1092  *
1093  * PARAMS
1094  *  pOwner                [I]
1095  *  pGroup                [I]
1096  *  cCountOfAccessEntries [I]
1097  *  pListOfAccessEntries  [I]
1098  *  cCountOfAuditEntries  [I]
1099  *  pListofAuditEntries   [I]
1100  *  pOldSD                [I]
1101  *  lpdwBufferLength      [I/O]
1102  *  pNewSD                [O]
1103  *
1104  * RETURNS
1105  *  Success: ERROR_SUCCESS
1106  *  Failure: nonzero error code from Winerror.h
1107  */
1108 DWORD WINAPI BuildSecurityDescriptorA(
1109     IN PTRUSTEEA pOwner,
1110     IN PTRUSTEEA pGroup,
1111     IN ULONG cCountOfAccessEntries,
1112     IN PEXPLICIT_ACCESSA pListOfAccessEntries,
1113     IN ULONG cCountOfAuditEntries,
1114     IN PEXPLICIT_ACCESSA pListofAuditEntries,
1115     IN PSECURITY_DESCRIPTOR pOldSD,
1116     IN OUT PULONG lpdwBufferLength,
1117     OUT PSECURITY_DESCRIPTOR* pNewSD)
1118 { 
1119     FIXME("(%p,%p,%d,%p,%d,%p,%p,%p,%p) stub!\n",pOwner,pGroup,
1120           cCountOfAccessEntries,pListOfAccessEntries,cCountOfAuditEntries,
1121           pListofAuditEntries,pOldSD,lpdwBufferLength,pNewSD);
1122  
1123     return ERROR_CALL_NOT_IMPLEMENTED;
1124 } 
1125  
1126 /******************************************************************************
1127  * BuildSecurityDescriptorW [ADVAPI32.@]
1128  *
1129  * See BuildSecurityDescriptorA.
1130  */
1131 DWORD WINAPI BuildSecurityDescriptorW(
1132     IN PTRUSTEEW pOwner,
1133     IN PTRUSTEEW pGroup,
1134     IN ULONG cCountOfAccessEntries,
1135     IN PEXPLICIT_ACCESSW pListOfAccessEntries,
1136     IN ULONG cCountOfAuditEntries,
1137     IN PEXPLICIT_ACCESSW pListofAuditEntries,
1138     IN PSECURITY_DESCRIPTOR pOldSD,
1139     IN OUT PULONG lpdwBufferLength,
1140     OUT PSECURITY_DESCRIPTOR* pNewSD)
1141 { 
1142     FIXME("(%p,%p,%d,%p,%d,%p,%p,%p,%p) stub!\n",pOwner,pGroup,
1143           cCountOfAccessEntries,pListOfAccessEntries,cCountOfAuditEntries,
1144           pListofAuditEntries,pOldSD,lpdwBufferLength,pNewSD);
1145  
1146     return ERROR_CALL_NOT_IMPLEMENTED;
1147 } 
1148 
1149 /******************************************************************************
1150  * InitializeSecurityDescriptor [ADVAPI32.@]
1151  *
1152  * PARAMS
1153  *   pDescr   []
1154  *   revision []
1155  */
1156 BOOL WINAPI
1157 InitializeSecurityDescriptor( PSECURITY_DESCRIPTOR pDescr, DWORD revision )
1158 {
1159         return set_ntstatus( RtlCreateSecurityDescriptor(pDescr, revision ));
1160 }
1161 
1162 
1163 /******************************************************************************
1164  * MakeAbsoluteSD [ADVAPI32.@]
1165  */
1166 BOOL WINAPI MakeAbsoluteSD (
1167         IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,
1168         OUT PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor,
1169         OUT LPDWORD lpdwAbsoluteSecurityDescriptorSize,
1170         OUT PACL pDacl,
1171         OUT LPDWORD lpdwDaclSize,
1172         OUT PACL pSacl,
1173         OUT LPDWORD lpdwSaclSize,
1174         OUT PSID pOwner,
1175         OUT LPDWORD lpdwOwnerSize,
1176         OUT PSID pPrimaryGroup,
1177         OUT LPDWORD lpdwPrimaryGroupSize)
1178 {
1179     return set_ntstatus( RtlSelfRelativeToAbsoluteSD(pSelfRelativeSecurityDescriptor,
1180                                                      pAbsoluteSecurityDescriptor,
1181                                                      lpdwAbsoluteSecurityDescriptorSize,
1182                                                      pDacl, lpdwDaclSize, pSacl, lpdwSaclSize,
1183                                                      pOwner, lpdwOwnerSize,
1184                                                      pPrimaryGroup, lpdwPrimaryGroupSize));
1185 }
1186 
1187 /******************************************************************************
1188  * GetKernelObjectSecurity [ADVAPI32.@]
1189  */
1190 BOOL WINAPI GetKernelObjectSecurity(
1191         HANDLE Handle,
1192         SECURITY_INFORMATION RequestedInformation,
1193         PSECURITY_DESCRIPTOR pSecurityDescriptor,
1194         DWORD nLength,
1195         LPDWORD lpnLengthNeeded )
1196 {
1197     TRACE("(%p,0x%08x,%p,0x%08x,%p)\n", Handle, RequestedInformation,
1198           pSecurityDescriptor, nLength, lpnLengthNeeded);
1199 
1200     return set_ntstatus( NtQuerySecurityObject(Handle, RequestedInformation, pSecurityDescriptor,
1201                                                nLength, lpnLengthNeeded ));
1202 }
1203 
1204 /******************************************************************************
1205  * GetPrivateObjectSecurity [ADVAPI32.@]
1206  */
1207 BOOL WINAPI GetPrivateObjectSecurity(
1208         PSECURITY_DESCRIPTOR ObjectDescriptor,
1209         SECURITY_INFORMATION SecurityInformation,
1210         PSECURITY_DESCRIPTOR ResultantDescriptor,
1211         DWORD DescriptorLength,
1212         PDWORD ReturnLength )
1213 {
1214     SECURITY_DESCRIPTOR desc;
1215     BOOL defaulted, present;
1216     PACL pacl;
1217     PSID psid;
1218 
1219     TRACE("(%p,0x%08x,%p,0x%08x,%p)\n", ObjectDescriptor, SecurityInformation,
1220           ResultantDescriptor, DescriptorLength, ReturnLength);
1221 
1222     if (!InitializeSecurityDescriptor(&desc, SECURITY_DESCRIPTOR_REVISION))
1223         return FALSE;
1224 
1225     if (SecurityInformation & OWNER_SECURITY_INFORMATION)
1226     {
1227         if (!GetSecurityDescriptorOwner(ObjectDescriptor, &psid, &defaulted))
1228             return FALSE;
1229         SetSecurityDescriptorOwner(&desc, psid, defaulted);
1230     }
1231 
1232     if (SecurityInformation & GROUP_SECURITY_INFORMATION)
1233     {
1234         if (!GetSecurityDescriptorGroup(ObjectDescriptor, &psid, &defaulted))
1235             return FALSE;
1236         SetSecurityDescriptorGroup(&desc, psid, defaulted);
1237     }
1238 
1239     if (SecurityInformation & DACL_SECURITY_INFORMATION)
1240     {
1241         if (!GetSecurityDescriptorDacl(ObjectDescriptor, &present, &pacl, &defaulted))
1242             return FALSE;
1243         SetSecurityDescriptorDacl(&desc, present, pacl, defaulted);
1244     }
1245 
1246     if (SecurityInformation & SACL_SECURITY_INFORMATION)
1247     {
1248         if (!GetSecurityDescriptorSacl(ObjectDescriptor, &present, &pacl, &defaulted))
1249             return FALSE;
1250         SetSecurityDescriptorSacl(&desc, present, pacl, defaulted);
1251     }
1252 
1253     *ReturnLength = DescriptorLength;
1254     return MakeSelfRelativeSD(&desc, ResultantDescriptor, ReturnLength);
1255 }
1256 
1257 /******************************************************************************
1258  * GetSecurityDescriptorLength [ADVAPI32.@]
1259  */
1260 DWORD WINAPI GetSecurityDescriptorLength( PSECURITY_DESCRIPTOR pDescr)
1261 {
1262         return RtlLengthSecurityDescriptor(pDescr);
1263 }
1264 
1265 /******************************************************************************
1266  * GetSecurityDescriptorOwner [ADVAPI32.@]
1267  *
1268  * PARAMS
1269  *   pOwner            []
1270  *   lpbOwnerDefaulted []
1271  */
1272 BOOL WINAPI
1273 GetSecurityDescriptorOwner( PSECURITY_DESCRIPTOR pDescr, PSID *pOwner,
1274                             LPBOOL lpbOwnerDefaulted )
1275 {
1276     BOOLEAN defaulted;
1277     BOOL ret = set_ntstatus( RtlGetOwnerSecurityDescriptor( pDescr, pOwner, &defaulted ));
1278     *lpbOwnerDefaulted = defaulted;
1279     return ret;
1280 }
1281 
1282 /******************************************************************************
1283  * SetSecurityDescriptorOwner [ADVAPI32.@]
1284  *
1285  * PARAMS
1286  */
1287 BOOL WINAPI SetSecurityDescriptorOwner( PSECURITY_DESCRIPTOR pSecurityDescriptor,
1288                                    PSID pOwner, BOOL bOwnerDefaulted)
1289 {
1290     return set_ntstatus( RtlSetOwnerSecurityDescriptor(pSecurityDescriptor, pOwner, bOwnerDefaulted));
1291 }
1292 /******************************************************************************
1293  * GetSecurityDescriptorGroup                   [ADVAPI32.@]
1294  */
1295 BOOL WINAPI GetSecurityDescriptorGroup(
1296         PSECURITY_DESCRIPTOR SecurityDescriptor,
1297         PSID *Group,
1298         LPBOOL GroupDefaulted)
1299 {
1300     BOOLEAN defaulted;
1301     BOOL ret = set_ntstatus( RtlGetGroupSecurityDescriptor(SecurityDescriptor, Group, &defaulted ));
1302     *GroupDefaulted = defaulted;
1303     return ret;
1304 }
1305 /******************************************************************************
1306  * SetSecurityDescriptorGroup [ADVAPI32.@]
1307  */
1308 BOOL WINAPI SetSecurityDescriptorGroup ( PSECURITY_DESCRIPTOR SecurityDescriptor,
1309                                            PSID Group, BOOL GroupDefaulted)
1310 {
1311     return set_ntstatus( RtlSetGroupSecurityDescriptor( SecurityDescriptor, Group, GroupDefaulted));
1312 }
1313 
1314 /******************************************************************************
1315  * IsValidSecurityDescriptor [ADVAPI32.@]
1316  *
1317  * PARAMS
1318  *   lpsecdesc []
1319  */
1320 BOOL WINAPI
1321 IsValidSecurityDescriptor( PSECURITY_DESCRIPTOR SecurityDescriptor )
1322 {
1323     return set_ntstatus( RtlValidSecurityDescriptor(SecurityDescriptor));
1324 }
1325 
1326 /******************************************************************************
1327  *  GetSecurityDescriptorDacl                   [ADVAPI32.@]
1328  */
1329 BOOL WINAPI GetSecurityDescriptorDacl(
1330         IN PSECURITY_DESCRIPTOR pSecurityDescriptor,
1331         OUT LPBOOL lpbDaclPresent,
1332         OUT PACL *pDacl,
1333         OUT LPBOOL lpbDaclDefaulted)
1334 {
1335     BOOLEAN present, defaulted;
1336     BOOL ret = set_ntstatus( RtlGetDaclSecurityDescriptor(pSecurityDescriptor, &present, pDacl, &defaulted));
1337     *lpbDaclPresent = present;
1338     *lpbDaclDefaulted = defaulted;
1339     return ret;
1340 }
1341 
1342 /******************************************************************************
1343  *  SetSecurityDescriptorDacl                   [ADVAPI32.@]
1344  */
1345 BOOL WINAPI
1346 SetSecurityDescriptorDacl (
1347         PSECURITY_DESCRIPTOR lpsd,
1348         BOOL daclpresent,
1349         PACL dacl,
1350         BOOL dacldefaulted )
1351 {
1352     return set_ntstatus( RtlSetDaclSecurityDescriptor (lpsd, daclpresent, dacl, dacldefaulted ) );
1353 }
1354 /******************************************************************************
1355  *  GetSecurityDescriptorSacl                   [ADVAPI32.@]
1356  */
1357 BOOL WINAPI GetSecurityDescriptorSacl(
1358         IN PSECURITY_DESCRIPTOR lpsd,
1359         OUT LPBOOL lpbSaclPresent,
1360         OUT PACL *pSacl,
1361         OUT LPBOOL lpbSaclDefaulted)
1362 {
1363     BOOLEAN present, defaulted;
1364     BOOL ret = set_ntstatus( RtlGetSaclSecurityDescriptor(lpsd, &present, pSacl, &defaulted) );
1365     *lpbSaclPresent = present;
1366     *lpbSaclDefaulted = defaulted;
1367     return ret;
1368 }
1369 
1370 /**************************************************************************
1371  * SetSecurityDescriptorSacl                    [ADVAPI32.@]
1372  */
1373 BOOL WINAPI SetSecurityDescriptorSacl (
1374         PSECURITY_DESCRIPTOR lpsd,
1375         BOOL saclpresent,
1376         PACL lpsacl,
1377         BOOL sacldefaulted)
1378 {
1379     return set_ntstatus (RtlSetSaclSecurityDescriptor(lpsd, saclpresent, lpsacl, sacldefaulted));
1380 }
1381 /******************************************************************************
1382  * MakeSelfRelativeSD [ADVAPI32.@]
1383  *
1384  * PARAMS
1385  *   lpabssecdesc  []
1386  *   lpselfsecdesc []
1387  *   lpbuflen      []
1388  */
1389 BOOL WINAPI
1390 MakeSelfRelativeSD(
1391         IN PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor,
1392         IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,
1393         IN OUT LPDWORD lpdwBufferLength)
1394 {
1395     return set_ntstatus( RtlMakeSelfRelativeSD( pAbsoluteSecurityDescriptor,
1396                                                 pSelfRelativeSecurityDescriptor, lpdwBufferLength));
1397 }
1398 
1399 /******************************************************************************
1400  * GetSecurityDescriptorControl                 [ADVAPI32.@]
1401  */
1402 
1403 BOOL WINAPI GetSecurityDescriptorControl ( PSECURITY_DESCRIPTOR  pSecurityDescriptor,
1404                  PSECURITY_DESCRIPTOR_CONTROL pControl, LPDWORD lpdwRevision)
1405 {
1406     return set_ntstatus( RtlGetControlSecurityDescriptor(pSecurityDescriptor,pControl,lpdwRevision));
1407 }
1408 
1409 /******************************************************************************
1410  * SetSecurityDescriptorControl                 [ADVAPI32.@]
1411  */
1412 BOOL WINAPI SetSecurityDescriptorControl( PSECURITY_DESCRIPTOR pSecurityDescriptor,
1413   SECURITY_DESCRIPTOR_CONTROL ControlBitsOfInterest,
1414   SECURITY_DESCRIPTOR_CONTROL ControlBitsToSet )
1415 {
1416     return set_ntstatus( RtlSetControlSecurityDescriptor(
1417         pSecurityDescriptor, ControlBitsOfInterest, ControlBitsToSet ) );
1418 }
1419 
1420 /*      ##############################
1421         ######  ACL FUNCTIONS   ######
1422         ##############################
1423 */
1424 
1425 /*************************************************************************
1426  * InitializeAcl [ADVAPI32.@]
1427  */
1428 BOOL WINAPI InitializeAcl(PACL acl, DWORD size, DWORD rev)
1429 {
1430     return set_ntstatus( RtlCreateAcl(acl, size, rev));
1431 }
1432 
1433 BOOL WINAPI ImpersonateNamedPipeClient( HANDLE hNamedPipe )
1434 {
1435     IO_STATUS_BLOCK io_block;
1436 
1437     TRACE("(%p)\n", hNamedPipe);
1438 
1439     return set_ntstatus( NtFsControlFile(hNamedPipe, NULL, NULL, NULL,
1440                          &io_block, FSCTL_PIPE_IMPERSONATE, NULL, 0, NULL, 0) );
1441 }
1442 
1443 /******************************************************************************
1444  *  AddAccessAllowedAce [ADVAPI32.@]
1445  */
1446 BOOL WINAPI AddAccessAllowedAce(
1447         IN OUT PACL pAcl,
1448         IN DWORD dwAceRevision,
1449         IN DWORD AccessMask,
1450         IN PSID pSid)
1451 {
1452     return set_ntstatus(RtlAddAccessAllowedAce(pAcl, dwAceRevision, AccessMask, pSid));
1453 }
1454 
1455 /******************************************************************************
1456  *  AddAccessAllowedAceEx [ADVAPI32.@]
1457  */
1458 BOOL WINAPI AddAccessAllowedAceEx(
1459         IN OUT PACL pAcl,
1460         IN DWORD dwAceRevision,
1461         IN DWORD AceFlags,
1462         IN DWORD AccessMask,
1463         IN PSID pSid)
1464 {
1465     return set_ntstatus(RtlAddAccessAllowedAceEx(pAcl, dwAceRevision, AceFlags, AccessMask, pSid));
1466 }
1467 
1468 /******************************************************************************
1469  *  AddAccessDeniedAce [ADVAPI32.@]
1470  */
1471 BOOL WINAPI AddAccessDeniedAce(
1472         IN OUT PACL pAcl,
1473         IN DWORD dwAceRevision,
1474         IN DWORD AccessMask,
1475         IN PSID pSid)
1476 {
1477     return set_ntstatus(RtlAddAccessDeniedAce(pAcl, dwAceRevision, AccessMask, pSid));
1478 }
1479 
1480 /******************************************************************************
1481  *  AddAccessDeniedAceEx [ADVAPI32.@]
1482  */
1483 BOOL WINAPI AddAccessDeniedAceEx(
1484         IN OUT PACL pAcl,
1485         IN DWORD dwAceRevision,
1486         IN DWORD AceFlags,
1487         IN DWORD AccessMask,
1488         IN PSID pSid)
1489 {
1490     return set_ntstatus(RtlAddAccessDeniedAceEx(pAcl, dwAceRevision, AceFlags, AccessMask, pSid));
1491 }
1492 
1493 /******************************************************************************
1494  *  AddAce [ADVAPI32.@]
1495  */
1496 BOOL WINAPI AddAce(
1497         IN OUT PACL pAcl,
1498         IN DWORD dwAceRevision,
1499         IN DWORD dwStartingAceIndex,
1500         LPVOID pAceList,
1501         DWORD nAceListLength)
1502 {
1503     return set_ntstatus(RtlAddAce(pAcl, dwAceRevision, dwStartingAceIndex, pAceList, nAceListLength));
1504 }
1505 
1506 /******************************************************************************
1507  * DeleteAce [ADVAPI32.@]
1508  */
1509 BOOL WINAPI DeleteAce(PACL pAcl, DWORD dwAceIndex)
1510 {
1511     return set_ntstatus(RtlDeleteAce(pAcl, dwAceIndex));
1512 }
1513 
1514 /******************************************************************************
1515  *  FindFirstFreeAce [ADVAPI32.@]
1516  */
1517 BOOL WINAPI FindFirstFreeAce(IN PACL pAcl, LPVOID * pAce)
1518 {
1519         return RtlFirstFreeAce(pAcl, (PACE_HEADER *)pAce);
1520 }
1521 
1522 /******************************************************************************
1523  * GetAce [ADVAPI32.@]
1524  */
1525 BOOL WINAPI GetAce(PACL pAcl,DWORD dwAceIndex,LPVOID *pAce )
1526 {
1527     return set_ntstatus(RtlGetAce(pAcl, dwAceIndex, pAce));
1528 }
1529 
1530 /******************************************************************************
1531  * GetAclInformation [ADVAPI32.@]
1532  */
1533 BOOL WINAPI GetAclInformation(
1534   PACL pAcl,
1535   LPVOID pAclInformation,
1536   DWORD nAclInformationLength,
1537   ACL_INFORMATION_CLASS dwAclInformationClass)
1538 {
1539     return set_ntstatus(RtlQueryInformationAcl(pAcl, pAclInformation,
1540                                                nAclInformationLength, dwAclInformationClass));
1541 }
1542 
1543 /******************************************************************************
1544  *  IsValidAcl [ADVAPI32.@]
1545  */
1546 BOOL WINAPI IsValidAcl(IN PACL pAcl)
1547 {
1548         return RtlValidAcl(pAcl);
1549 }
1550 
1551 /*      ##############################
1552         ######  MISC FUNCTIONS  ######
1553         ##############################
1554 */
1555 
1556 /******************************************************************************
1557  * AllocateLocallyUniqueId [ADVAPI32.@]
1558  *
1559  * PARAMS
1560  *   lpLuid []
1561  */
1562 BOOL WINAPI AllocateLocallyUniqueId( PLUID lpLuid )
1563 {
1564     return set_ntstatus(NtAllocateLocallyUniqueId(lpLuid));
1565 }
1566 
1567 static const WCHAR SE_CREATE_TOKEN_NAME_W[] =
1568  { 'S','e','C','r','e','a','t','e','T','o','k','e','n','P','r','i','v','i','l','e','g','e',0 };
1569 static const WCHAR SE_ASSIGNPRIMARYTOKEN_NAME_W[] =
1570  { 'S','e','A','s','s','i','g','n','P','r','i','m','a','r','y','T','o','k','e','n','P','r','i','v','i','l','e','g','e',0 };
1571 static const WCHAR SE_LOCK_MEMORY_NAME_W[] =
1572  { 'S','e','L','o','c','k','M','e','m','o','r','y','P','r','i','v','i','l','e','g','e',0 };
1573 static const WCHAR SE_INCREASE_QUOTA_NAME_W[] =
1574  { 'S','e','I','n','c','r','e','a','s','e','Q','u','o','t','a','P','r','i','v','i','l','e','g','e',0 };
1575 static const WCHAR SE_MACHINE_ACCOUNT_NAME_W[] =
1576  { 'S','e','M','a','c','h','i','n','e','A','c','c','o','u','n','t','P','r','i','v','i','l','e','g','e',0 };
1577 static const WCHAR SE_TCB_NAME_W[] =
1578  { 'S','e','T','c','b','P','r','i','v','i','l','e','g','e',0 };
1579 static const WCHAR SE_SECURITY_NAME_W[] =
1580  { 'S','e','S','e','c','u','r','i','t','y','P','r','i','v','i','l','e','g','e',0 };
1581 static const WCHAR SE_TAKE_OWNERSHIP_NAME_W[] =
1582  { 'S','e','T','a','k','e','O','w','n','e','r','s','h','i','p','P','r','i','v','i','l','e','g','e',0 };
1583 static const WCHAR SE_LOAD_DRIVER_NAME_W[] =
1584  { 'S','e','L','o','a','d','D','r','i','v','e','r','P','r','i','v','i','l','e','g','e',0 };
1585 static const WCHAR SE_SYSTEM_PROFILE_NAME_W[] =
1586  { 'S','e','S','y','s','t','e','m','P','r','o','f','i','l','e','P','r','i','v','i','l','e','g','e',0 };
1587 static const WCHAR SE_SYSTEMTIME_NAME_W[] =
1588  { 'S','e','S','y','s','t','e','m','t','i','m','e','P','r','i','v','i','l','e','g','e',0 };
1589 static const WCHAR SE_PROF_SINGLE_PROCESS_NAME_W[] =
1590  { 'S','e','P','r','o','f','i','l','e','S','i','n','g','l','e','P','r','o','c','e','s','s','P','r','i','v','i','l','e','g','e',0 };
1591 static const WCHAR SE_INC_BASE_PRIORITY_NAME_W[] =
1592  { 'S','e','I','n','c','r','e','a','s','e','B','a','s','e','P','r','i','o','r','i','t','y','P','r','i','v','i','l','e','g','e',0 };
1593 static const WCHAR SE_CREATE_PAGEFILE_NAME_W[] =
1594  { 'S','e','C','r','e','a','t','e','P','a','g','e','f','i','l','e','P','r','i','v','i','l','e','g','e',0 };
1595 static const WCHAR SE_CREATE_PERMANENT_NAME_W[] =
1596  { 'S','e','C','r','e','a','t','e','P','e','r','m','a','n','e','n','t','P','r','i','v','i','l','e','g','e',0 };
1597 static const WCHAR SE_BACKUP_NAME_W[] =
1598  { 'S','e','B','a','c','k','u','p','P','r','i','v','i','l','e','g','e',0 };
1599 static const WCHAR SE_RESTORE_NAME_W[] =
1600  { 'S','e','R','e','s','t','o','r','e','P','r','i','v','i','l','e','g','e',0 };
1601 static const WCHAR SE_SHUTDOWN_NAME_W[] =
1602  { 'S','e','S','h','u','t','d','o','w','n','P','r','i','v','i','l','e','g','e',0 };
1603 static const WCHAR SE_DEBUG_NAME_W[] =
1604  { 'S','e','D','e','b','u','g','P','r','i','v','i','l','e','g','e',0 };
1605 static const WCHAR SE_AUDIT_NAME_W[] =
1606  { 'S','e','A','u','d','i','t','P','r','i','v','i','l','e','g','e',0 };
1607 static const WCHAR SE_SYSTEM_ENVIRONMENT_NAME_W[] =
1608  { 'S','e','S','y','s','t','e','m','E','n','v','i','r','o','n','m','e','n','t','P','r','i','v','i','l','e','g','e',0 };
1609 static const WCHAR SE_CHANGE_NOTIFY_NAME_W[] =
1610  { 'S','e','C','h','a','n','g','e','N','o','t','i','f','y','P','r','i','v','i','l','e','g','e',0 };
1611 static const WCHAR SE_REMOTE_SHUTDOWN_NAME_W[] =
1612  { 'S','e','R','e','m','o','t','e','S','h','u','t','d','o','w','n','P','r','i','v','i','l','e','g','e',0 };
1613 static const WCHAR SE_UNDOCK_NAME_W[] =
1614  { 'S','e','U','n','d','o','c','k','P','r','i','v','i','l','e','g','e',0 };
1615 static const WCHAR SE_SYNC_AGENT_NAME_W[] =
1616  { 'S','e','S','y','n','c','A','g','e','n','t','P','r','i','v','i','l','e','g','e',0 };
1617 static const WCHAR SE_ENABLE_DELEGATION_NAME_W[] =
1618  { 'S','e','E','n','a','b','l','e','D','e','l','e','g','a','t','i','o','n','P','r','i','v','i','l','e','g','e',0 };
1619 static const WCHAR SE_MANAGE_VOLUME_NAME_W[] =
1620  { 'S','e','M','a','n','a','g','e','V','o','l','u','m','e','P','r','i','v','i','l','e','g','e',0 };
1621 static const WCHAR SE_IMPERSONATE_NAME_W[] =
1622  { 'S','e','I','m','p','e','r','s','o','n','a','t','e','P','r','i','v','i','l','e','g','e',0 };
1623 static const WCHAR SE_CREATE_GLOBAL_NAME_W[] =
1624  { 'S','e','C','r','e','a','t','e','G','l','o','b','a','l','P','r','i','v','i','l','e','g','e',0 };
1625 
1626 static const WCHAR * const WellKnownPrivNames[SE_MAX_WELL_KNOWN_PRIVILEGE + 1] =
1627 {
1628     NULL,
1629     NULL,
1630     SE_CREATE_TOKEN_NAME_W,
1631     SE_ASSIGNPRIMARYTOKEN_NAME_W,
1632     SE_LOCK_MEMORY_NAME_W,
1633     SE_INCREASE_QUOTA_NAME_W,
1634     SE_MACHINE_ACCOUNT_NAME_W,
1635     SE_TCB_NAME_W,
1636     SE_SECURITY_NAME_W,
1637     SE_TAKE_OWNERSHIP_NAME_W,
1638     SE_LOAD_DRIVER_NAME_W,
1639     SE_SYSTEM_PROFILE_NAME_W,
1640     SE_SYSTEMTIME_NAME_W,
1641     SE_PROF_SINGLE_PROCESS_NAME_W,
1642     SE_INC_BASE_PRIORITY_NAME_W,
1643     SE_CREATE_PAGEFILE_NAME_W,
1644     SE_CREATE_PERMANENT_NAME_W,
1645     SE_BACKUP_NAME_W,
1646     SE_RESTORE_NAME_W,
1647     SE_SHUTDOWN_NAME_W,
1648     SE_DEBUG_NAME_W,
1649     SE_AUDIT_NAME_W,
1650     SE_SYSTEM_ENVIRONMENT_NAME_W,
1651     SE_CHANGE_NOTIFY_NAME_W,
1652     SE_REMOTE_SHUTDOWN_NAME_W,
1653     SE_UNDOCK_NAME_W,
1654     SE_SYNC_AGENT_NAME_W,
1655     SE_ENABLE_DELEGATION_NAME_W,
1656     SE_MANAGE_VOLUME_NAME_W,
1657     SE_IMPERSONATE_NAME_W,
1658     SE_CREATE_GLOBAL_NAME_W,
1659 };
1660 
1661 /******************************************************************************
1662  * LookupPrivilegeValueW                        [ADVAPI32.@]
1663  *
1664  * See LookupPrivilegeValueA.
1665  */
1666 BOOL WINAPI
1667 LookupPrivilegeValueW( LPCWSTR lpSystemName, LPCWSTR lpName, PLUID lpLuid )
1668 {
1669     UINT i;
1670 
1671     TRACE("%s,%s,%p\n",debugstr_w(lpSystemName), debugstr_w(lpName), lpLuid);
1672 
1673     if (!ADVAPI_IsLocalComputer(lpSystemName))
1674     {
1675         SetLastError(RPC_S_SERVER_UNAVAILABLE);
1676         return FALSE;
1677     }
1678     if (!lpName)
1679     {
1680         SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1681         return FALSE;
1682     }
1683     for( i=SE_MIN_WELL_KNOWN_PRIVILEGE; i<=SE_MAX_WELL_KNOWN_PRIVILEGE; i++ )
1684     {
1685         if( !WellKnownPrivNames[i] )
1686             continue;
1687         if( strcmpiW( WellKnownPrivNames[i], lpName) )
1688             continue;
1689         lpLuid->LowPart = i;
1690         lpLuid->HighPart = 0;
1691         TRACE( "%s -> %08x-%08x\n",debugstr_w( lpSystemName ),
1692                lpLuid->HighPart, lpLuid->LowPart );
1693         return TRUE;
1694     }
1695     SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1696     return FALSE;
1697 }
1698 
1699 /******************************************************************************
1700  * LookupPrivilegeValueA                        [ADVAPI32.@]
1701  *
1702  * Retrieves LUID used on a system to represent the privilege name.
1703  *
1704  * PARAMS
1705  *  lpSystemName [I] Name of the system
1706  *  lpName       [I] Name of the privilege
1707  *  lpLuid       [O] Destination for the resulting LUID
1708  *
1709  * RETURNS
1710  *  Success: TRUE. lpLuid contains the requested LUID.
1711  *  Failure: FALSE.
1712  */
1713 BOOL WINAPI
1714 LookupPrivilegeValueA( LPCSTR lpSystemName, LPCSTR lpName, PLUID lpLuid )
1715 {
1716     UNICODE_STRING lpSystemNameW;
1717     UNICODE_STRING lpNameW;
1718     BOOL ret;
1719 
1720     RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW, lpSystemName);
1721     RtlCreateUnicodeStringFromAsciiz(&lpNameW,lpName);
1722     ret = LookupPrivilegeValueW(lpSystemNameW.Buffer, lpNameW.Buffer, lpLuid);
1723     RtlFreeUnicodeString(&lpNameW);
1724     RtlFreeUnicodeString(&lpSystemNameW);
1725     return ret;
1726 }
1727 
1728 BOOL WINAPI LookupPrivilegeDisplayNameA( LPCSTR lpSystemName, LPCSTR lpName, LPSTR lpDisplayName,
1729                                          LPDWORD cchDisplayName, LPDWORD lpLanguageId )
1730 {
1731     FIXME("%s %s %s %p %p - stub\n", debugstr_a(lpSystemName), debugstr_a(lpName),
1732           debugstr_a(lpDisplayName), cchDisplayName, lpLanguageId);
1733 
1734     return FALSE;
1735 }
1736 
1737 BOOL WINAPI LookupPrivilegeDisplayNameW( LPCWSTR lpSystemName, LPCWSTR lpName, LPWSTR lpDisplayName,
1738                                          LPDWORD cchDisplayName, LPDWORD lpLanguageId )
1739 {
1740     FIXME("%s %s %s %p %p - stub\n", debugstr_w(lpSystemName), debugstr_w(lpName),
1741           debugstr_w(lpDisplayName), cchDisplayName, lpLanguageId);
1742 
1743     return FALSE;
1744 }
1745 
1746 /******************************************************************************
1747  * LookupPrivilegeNameA                 [ADVAPI32.@]
1748  *
1749  * See LookupPrivilegeNameW.
1750  */
1751 BOOL WINAPI
1752 LookupPrivilegeNameA( LPCSTR lpSystemName, PLUID lpLuid, LPSTR lpName,
1753  LPDWORD cchName)
1754 {
1755     UNICODE_STRING lpSystemNameW;
1756     BOOL ret;
1757     DWORD wLen = 0;
1758 
1759     TRACE("%s %p %p %p\n", debugstr_a(lpSystemName), lpLuid, lpName, cchName);
1760 
1761     RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW, lpSystemName);
1762     ret = LookupPrivilegeNameW(lpSystemNameW.Buffer, lpLuid, NULL, &wLen);
1763     if (!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
1764     {
1765         LPWSTR lpNameW = HeapAlloc(GetProcessHeap(), 0, wLen * sizeof(WCHAR));
1766 
1767         ret = LookupPrivilegeNameW(lpSystemNameW.Buffer, lpLuid, lpNameW,
1768          &wLen);
1769         if (ret)
1770         {
1771             /* Windows crashes if cchName is NULL, so will I */
1772             unsigned int len = WideCharToMultiByte(CP_ACP, 0, lpNameW, -1, lpName,
1773              *cchName, NULL, NULL);
1774 
1775             if (len == 0)
1776             {
1777                 /* WideCharToMultiByte failed */
1778                 ret = FALSE;
1779             }
1780             else if (len > *cchName)
1781             {
1782                 *cchName = len;
1783                 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1784                 ret = FALSE;
1785             }
1786             else
1787             {
1788                 /* WideCharToMultiByte succeeded, output length needs to be
1789                  * length not including NULL terminator
1790                  */
1791                 *cchName = len - 1;
1792             }
1793         }
1794         HeapFree(GetProcessHeap(), 0, lpNameW);
1795     }
1796     RtlFreeUnicodeString(&lpSystemNameW);
1797     return ret;
1798 }
1799 
1800 /******************************************************************************
1801  * LookupPrivilegeNameW                 [ADVAPI32.@]
1802  *
1803  * Retrieves the privilege name referred to by the LUID lpLuid.
1804  *
1805  * PARAMS
1806  *  lpSystemName [I]   Name of the system
1807  *  lpLuid       [I]   Privilege value
1808  *  lpName       [O]   Name of the privilege
1809  *  cchName      [I/O] Number of characters in lpName.
1810  *
1811  * RETURNS
1812  *  Success: TRUE. lpName contains the name of the privilege whose value is
1813  *  *lpLuid.
1814  *  Failure: FALSE.
1815  *
1816  * REMARKS
1817  *  Only well-known privilege names (those defined in winnt.h) can be retrieved
1818  *  using this function.
1819  *  If the length of lpName is too small, on return *cchName will contain the
1820  *  number of WCHARs needed to contain the privilege, including the NULL
1821  *  terminator, and GetLastError will return ERROR_INSUFFICIENT_BUFFER.
1822  *  On success, *cchName will contain the number of characters stored in
1823  *  lpName, NOT including the NULL terminator.
1824  */
1825 BOOL WINAPI
1826 LookupPrivilegeNameW( LPCWSTR lpSystemName, PLUID lpLuid, LPWSTR lpName,
1827  LPDWORD cchName)
1828 {
1829     size_t privNameLen;
1830 
1831     TRACE("%s,%p,%p,%p\n",debugstr_w(lpSystemName), lpLuid, lpName, cchName);
1832 
1833     if (!ADVAPI_IsLocalComputer(lpSystemName))
1834     {
1835         SetLastError(RPC_S_SERVER_UNAVAILABLE);
1836         return FALSE;
1837     }
1838     if (lpLuid->HighPart || (lpLuid->LowPart < SE_MIN_WELL_KNOWN_PRIVILEGE ||
1839      lpLuid->LowPart > SE_MAX_WELL_KNOWN_PRIVILEGE))
1840     {
1841         SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1842         return FALSE;
1843     }
1844     privNameLen = strlenW(WellKnownPrivNames[lpLuid->LowPart]);
1845     /* Windows crashes if cchName is NULL, so will I */
1846     if (*cchName <= privNameLen)
1847     {
1848         *cchName = privNameLen + 1;
1849         SetLastError(ERROR_INSUFFICIENT_BUFFER);
1850         return FALSE;
1851     }
1852     else
1853     {
1854         strcpyW(lpName, WellKnownPrivNames[lpLuid->LowPart]);
1855         *cchName = privNameLen;
1856         return TRUE;
1857     }
1858 }
1859 
1860 /******************************************************************************
1861  * GetFileSecurityA [ADVAPI32.@]
1862  *
1863  * Obtains Specified information about the security of a file or directory.
1864  *
1865  * PARAMS
1866  *  lpFileName           [I] Name of the file to get info for
1867  *  RequestedInformation [I] SE_ flags from "winnt.h"
1868  *  pSecurityDescriptor  [O] Destination for security information
1869  *  nLength              [I] Length of pSecurityDescriptor
1870  *  lpnLengthNeeded      [O] Destination for length of returned security information
1871  *
1872  * RETURNS
1873  *  Success: TRUE. pSecurityDescriptor contains the requested information.
1874  *  Failure: FALSE. lpnLengthNeeded contains the required space to return the info. 
1875  *
1876  * NOTES
1877  *  The information returned is constrained by the callers access rights and
1878  *  privileges.
1879  */
1880 BOOL WINAPI
1881 GetFileSecurityA( LPCSTR lpFileName,
1882                     SECURITY_INFORMATION RequestedInformation,
1883                     PSECURITY_DESCRIPTOR pSecurityDescriptor,
1884                     DWORD nLength, LPDWORD lpnLengthNeeded )
1885 {
1886     DWORD len;
1887     BOOL r;
1888     LPWSTR name = NULL;
1889 
1890     if( lpFileName )
1891     {
1892         len = MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, NULL, 0 );
1893         name = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
1894         MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, name, len );
1895     }
1896 
1897     r = GetFileSecurityW( name, RequestedInformation, pSecurityDescriptor,
1898                           nLength, lpnLengthNeeded );
1899     HeapFree( GetProcessHeap(), 0, name );
1900 
1901     return r;
1902 }
1903 
1904 /******************************************************************************
1905  * GetFileSecurityW [ADVAPI32.@]
1906  *
1907  * See GetFileSecurityA.
1908  */
1909 BOOL WINAPI
1910 GetFileSecurityW( LPCWSTR lpFileName,
1911                     SECURITY_INFORMATION RequestedInformation,
1912                     PSECURITY_DESCRIPTOR pSecurityDescriptor,
1913                     DWORD nLength, LPDWORD lpnLengthNeeded )
1914 {
1915     HANDLE hfile;
1916     NTSTATUS status;
1917     DWORD access = 0;
1918 
1919     TRACE("(%s,%d,%p,%d,%p)\n", debugstr_w(lpFileName),
1920           RequestedInformation, pSecurityDescriptor,
1921           nLength, lpnLengthNeeded);
1922 
1923     if (RequestedInformation & (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|
1924                                 DACL_SECURITY_INFORMATION))
1925         access |= READ_CONTROL;
1926     if (RequestedInformation & SACL_SECURITY_INFORMATION)
1927         access |= ACCESS_SYSTEM_SECURITY;
1928 
1929     hfile = CreateFileW( lpFileName, access, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
1930                          NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0 );
1931     if ( hfile == INVALID_HANDLE_VALUE )
1932         return FALSE;
1933 
1934     status = NtQuerySecurityObject( hfile, RequestedInformation, pSecurityDescriptor,
1935                                     nLength, lpnLengthNeeded );
1936     CloseHandle( hfile );
1937     return set_ntstatus( status );
1938 }
1939 
1940 
1941 /******************************************************************************
1942  * LookupAccountSidA [ADVAPI32.@]
1943  */
1944 BOOL WINAPI
1945 LookupAccountSidA(
1946         IN LPCSTR system,
1947         IN PSID sid,
1948         OUT LPSTR account,
1949         IN OUT LPDWORD accountSize,
1950         OUT LPSTR domain,
1951         IN OUT LPDWORD domainSize,
1952         OUT PSID_NAME_USE name_use )
1953 {
1954     DWORD len;
1955     BOOL r;
1956     LPWSTR systemW = NULL;
1957     LPWSTR accountW = NULL;
1958     LPWSTR domainW = NULL;
1959     DWORD accountSizeW = *accountSize;
1960     DWORD domainSizeW = *domainSize;
1961 
1962     if (system) {
1963         len = MultiByteToWideChar( CP_ACP, 0, system, -1, NULL, 0 );
1964         systemW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
1965         MultiByteToWideChar( CP_ACP, 0, system, -1, systemW, len );
1966     }
1967     if (account)
1968         accountW = HeapAlloc( GetProcessHeap(), 0, accountSizeW * sizeof(WCHAR) );
1969     if (domain)
1970         domainW = HeapAlloc( GetProcessHeap(), 0, domainSizeW * sizeof(WCHAR) );
1971 
1972     r = LookupAccountSidW( systemW, sid, accountW, &accountSizeW, domainW, &domainSizeW, name_use );
1973 
1974     if (r) {
1975         if (accountW && *accountSize) {
1976             len = WideCharToMultiByte( CP_ACP, 0, accountW, -1, NULL, 0, NULL, NULL );
1977             WideCharToMultiByte( CP_ACP, 0, accountW, -1, account, len, NULL, NULL );
1978             *accountSize = len;
1979         } else
1980             *accountSize = accountSizeW + 1;
1981 
1982         if (domainW && *domainSize) {
1983             len = WideCharToMultiByte( CP_ACP, 0, domainW, -1, NULL, 0, NULL, NULL );
1984             WideCharToMultiByte( CP_ACP, 0, domainW, -1, domain, len, NULL, NULL );
1985             *domainSize = len;
1986         } else
1987             *domainSize = domainSizeW + 1;
1988     }
1989 
1990     HeapFree( GetProcessHeap(), 0, systemW );
1991     HeapFree( GetProcessHeap(), 0, accountW );
1992     HeapFree( GetProcessHeap(), 0, domainW );
1993 
1994     return r;
1995 }
1996 
1997 /******************************************************************************
1998  * LookupAccountSidW [ADVAPI32.@]
1999  *
2000  * PARAMS
2001  *   system      []
2002  *   sid         []
2003  *   account     []
2004  *   accountSize []
2005  *   domain      []
2006  *   domainSize  []
2007  *   name_use    []
2008  */
2009 
2010 BOOL WINAPI
2011 LookupAccountSidW(
2012         IN LPCWSTR system,
2013         IN PSID sid,
2014         OUT LPWSTR account,
2015         IN OUT LPDWORD accountSize,
2016         OUT LPWSTR domain,
2017         IN OUT LPDWORD domainSize,
2018         OUT PSID_NAME_USE name_use )
2019 {
2020     unsigned int i, j;
2021     const WCHAR * ac = NULL;
2022     const WCHAR * dm = NULL;
2023     SID_NAME_USE use = 0;
2024     LPWSTR computer_name = NULL;
2025     LPWSTR account_name = NULL;
2026 
2027     TRACE("(%s,sid=%s,%p,%p(%u),%p,%p(%u),%p)\n",
2028           debugstr_w(system),debugstr_sid(sid),
2029           account,accountSize,accountSize?*accountSize:0,
2030           domain,domainSize,domainSize?*domainSize:0,
2031           name_use);
2032 
2033     if (!ADVAPI_IsLocalComputer(system)) {
2034         FIXME("Only local computer supported!\n");
2035         SetLastError(RPC_S_SERVER_UNAVAILABLE);
2036         return FALSE;
2037     }
2038 
2039     /* check the well known SIDs first */
2040     for (i = 0; i <= 60; i++) {
2041         if (IsWellKnownSid(sid, i)) {
2042             for (j = 0; j < (sizeof(ACCOUNT_SIDS) / sizeof(ACCOUNT_SIDS[0])); j++) {
2043                 if (ACCOUNT_SIDS[j].type == i) {
2044                     ac = ACCOUNT_SIDS[j].account;
2045                     dm = ACCOUNT_SIDS[j].domain;
2046                     use = ACCOUNT_SIDS[j].name_use;
2047                 }
2048             }
2049             break;
2050         }
2051     }
2052 
2053     if (dm == NULL) {
2054         MAX_SID local;
2055 
2056         /* check for the local computer next */
2057         if (ADVAPI_GetComputerSid(&local)) {
2058             DWORD size = MAX_COMPUTERNAME_LENGTH + 1;
2059             BOOL result;
2060 
2061             computer_name = HeapAlloc(GetProcessHeap(), 0, size * sizeof(WCHAR));
2062             result = GetComputerNameW(computer_name,  &size);
2063 
2064             if (result) {
2065                 if (EqualSid(sid, &local)) {
2066                     dm = computer_name;
2067                     ac = Blank;
2068                     use = 3;
2069                 } else {
2070                     local.SubAuthorityCount++;
2071 
2072                     if (EqualPrefixSid(sid, &local)) {
2073                         dm = computer_name;
2074                         use = 1;
2075                         switch (((MAX_SID *)sid)->SubAuthority[4]) {
2076                         case DOMAIN_USER_RID_ADMIN:
2077                             ac = Administrator;
2078                             break;
2079                         case DOMAIN_USER_RID_GUEST:
2080                             ac = Guest;
2081                             break;
2082                         case DOMAIN_GROUP_RID_ADMINS:
2083                             ac = Domain_Admins;
2084                             break;
2085                         case DOMAIN_GROUP_RID_USERS:
2086                             ac = Domain_Users;
2087                             break;
2088                         case DOMAIN_GROUP_RID_GUESTS:
2089                             ac = Domain_Guests;
2090                             break;
2091                         case DOMAIN_GROUP_RID_COMPUTERS:
2092                             ac = Domain_Computers;
2093                             break;
2094                         case DOMAIN_GROUP_RID_CONTROLLERS:
2095                             ac = Domain_Controllers;
2096                             break;
2097                         case DOMAIN_GROUP_RID_CERT_ADMINS:
2098                             ac = Cert_Publishers;
2099                             break;
2100                         case DOMAIN_GROUP_RID_SCHEMA_ADMINS:
2101                             ac = Schema_Admins;
2102                             break;
2103                         case DOMAIN_GROUP_RID_ENTERPRISE_ADMINS:
2104                             ac = Enterprise_Admins;
2105                             break;
2106                         case DOMAIN_GROUP_RID_POLICY_ADMINS:
2107                             ac = Group_Policy_Creator_Owners;
2108                             break;
2109                         case DOMAIN_ALIAS_RID_RAS_SERVERS:
2110                             ac = RAS_and_IAS_Servers;
2111                             break;
2112                         case 1000:      /* first user account */
2113                             size = UNLEN + 1;
2114                             account_name = HeapAlloc(
2115                                 GetProcessHeap(), 0, size * sizeof(WCHAR));
2116                             if (GetUserNameW(account_name, &size))
2117                                 ac = account_name;
2118                             else
2119                                 dm = NULL;
2120 
2121                             break;
2122                         default:
2123                             dm = NULL;
2124                             break;
2125                         }
2126                     }
2127                 }
2128             }
2129         }
2130     }
2131 
2132     if (dm) {
2133         DWORD ac_len = lstrlenW(ac);
2134         DWORD dm_len = lstrlenW(dm);
2135         BOOL status = TRUE;
2136 
2137         if (*accountSize > ac_len) {
2138             if (account)
2139                 lstrcpyW(account, ac);
2140         }
2141         if (*domainSize > dm_len) {
2142             if (domain)
2143                 lstrcpyW(domain, dm);
2144         }
2145         if (((*accountSize != 0) && (*accountSize < ac_len)) ||
2146             ((*domainSize != 0) && (*domainSize < dm_len))) {
2147             SetLastError(ERROR_INSUFFICIENT_BUFFER);
2148             status = FALSE;
2149         }
2150         if (*domainSize)
2151             *domainSize = dm_len;
2152         else
2153             *domainSize = dm_len + 1;
2154         if (*accountSize)
2155             *accountSize = ac_len;
2156         else
2157             *accountSize = ac_len + 1;
2158         *name_use = use;
2159         HeapFree(GetProcessHeap(), 0, account_name);
2160         HeapFree(GetProcessHeap(), 0, computer_name);
2161         return status;
2162     }
2163 
2164     HeapFree(GetProcessHeap(), 0, account_name);
2165     HeapFree(GetProcessHeap(), 0, computer_name);
2166     SetLastError(ERROR_NONE_MAPPED);
2167     return FALSE;
2168 }
2169 
2170 /******************************************************************************
2171  * SetFileSecurityA [ADVAPI32.@]
2172  *
2173  * See SetFileSecurityW.
2174  */
2175 BOOL WINAPI SetFileSecurityA( LPCSTR lpFileName,
2176                                 SECURITY_INFORMATION RequestedInformation,
2177                                 PSECURITY_DESCRIPTOR pSecurityDescriptor)
2178 {
2179     DWORD len;
2180     BOOL r;
2181     LPWSTR name = NULL;
2182 
2183     if( lpFileName )
2184     {
2185         len = MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, NULL, 0 );
2186         name = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
2187         MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, name, len );
2188     }
2189 
2190     r = SetFileSecurityW( name, RequestedInformation, pSecurityDescriptor );
2191     HeapFree( GetProcessHeap(), 0, name );
2192 
2193     return r;
2194 }
2195 
2196 /******************************************************************************
2197  * SetFileSecurityW [ADVAPI32.@]
2198  *
2199  * Sets the security of a file or directory.
2200  *
2201  * PARAMS
2202  *   lpFileName           []
2203  *   RequestedInformation []
2204  *   pSecurityDescriptor  []
2205  *
2206  * RETURNS
2207  *  Success: TRUE.
2208  *  Failure: FALSE.
2209  */
2210 BOOL WINAPI
2211 SetFileSecurityW( LPCWSTR lpFileName,
2212                     SECURITY_INFORMATION RequestedInformation,
2213                     PSECURITY_DESCRIPTOR pSecurityDescriptor )
2214 {
2215     HANDLE file;
2216     DWORD access = 0;
2217     NTSTATUS status;
2218 
2219     TRACE("(%s, 0x%x, %p)\n", debugstr_w(lpFileName), RequestedInformation,
2220           pSecurityDescriptor );
2221 
2222     if (RequestedInformation & OWNER_SECURITY_INFORMATION ||
2223         RequestedInformation & GROUP_SECURITY_INFORMATION)
2224         access |= WRITE_OWNER;
2225     if (RequestedInformation & SACL_SECURITY_INFORMATION)
2226         access |= ACCESS_SYSTEM_SECURITY;
2227     if (RequestedInformation & DACL_SECURITY_INFORMATION)
2228         access |= WRITE_DAC;
2229 
2230     file = CreateFileW( lpFileName, access, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
2231                         NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL );
2232     if (file == INVALID_HANDLE_VALUE)
2233         return FALSE;
2234 
2235     status = NtSetSecurityObject( file, RequestedInformation, pSecurityDescriptor );
2236     CloseHandle( file );
2237     return set_ntstatus( status );
2238 }
2239 
2240 /******************************************************************************
2241  * QueryWindows31FilesMigration [ADVAPI32.@]
2242  *
2243  * PARAMS
2244  *   x1 []
2245  */
2246 BOOL WINAPI
2247 QueryWindows31FilesMigration( DWORD x1 )
2248 {
2249         FIXME("(%d):stub\n",x1);
2250         return TRUE;
2251 }
2252 
2253 /******************************************************************************
2254  * SynchronizeWindows31FilesAndWindowsNTRegistry [ADVAPI32.@]
2255  *
2256  * PARAMS
2257  *   x1 []
2258  *   x2 []
2259  *   x3 []
2260  *   x4 []
2261  */
2262 BOOL WINAPI
2263 SynchronizeWindows31FilesAndWindowsNTRegistry( DWORD x1, DWORD x2, DWORD x3,
2264                                                DWORD x4 )
2265 {
2266         FIXME("(0x%08x,0x%08x,0x%08x,0x%08x):stub\n",x1,x2,x3,x4);
2267         return TRUE;
2268 }
2269 
2270 /******************************************************************************
2271  * NotifyBootConfigStatus [ADVAPI32.@]
2272  *
2273  * PARAMS
2274  *   x1 []
2275  */
2276 BOOL WINAPI
2277 NotifyBootConfigStatus( BOOL x1 )
2278 {
2279         FIXME("(0x%08d):stub\n",x1);
2280         return 1;
2281 }
2282 
2283 /******************************************************************************
2284  * RevertToSelf [ADVAPI32.@]
2285  *
2286  * Ends the impersonation of a user.
2287  *
2288  * PARAMS
2289  *   void []
2290  *
2291  * RETURNS
2292  *  Success: TRUE.
2293  *  Failure: FALSE.
2294  */
2295 BOOL WINAPI
2296 RevertToSelf( void )
2297 {
2298     HANDLE Token = NULL;
2299     return set_ntstatus( NtSetInformationThread( GetCurrentThread(),
2300         ThreadImpersonationToken, &Token, sizeof(Token) ) );
2301 }
2302 
2303 /******************************************************************************
2304  * ImpersonateSelf [ADVAPI32.@]
2305  *
2306  * Makes an impersonation token that represents the process user and assigns
2307  * to the current thread.
2308  *
2309  * PARAMS
2310  *  ImpersonationLevel [I] Level at which to impersonate.
2311  *
2312  * RETURNS
2313  *  Success: TRUE.
2314  *  Failure: FALSE.
2315  */
2316 BOOL WINAPI
2317 ImpersonateSelf(SECURITY_IMPERSONATION_LEVEL ImpersonationLevel)
2318 {
2319     return set_ntstatus( RtlImpersonateSelf( ImpersonationLevel ) );
2320 }
2321 
2322 /******************************************************************************
2323  * ImpersonateLoggedOnUser [ADVAPI32.@]
2324  */
2325 BOOL WINAPI ImpersonateLoggedOnUser(HANDLE hToken)
2326 {
2327     DWORD size;
2328     NTSTATUS Status;
2329     HANDLE ImpersonationToken;
2330     TOKEN_TYPE Type;
2331     static BOOL warn = TRUE;
2332 
2333     if (warn)
2334     {
2335         FIXME( "(%p)\n", hToken );
2336         warn = FALSE;
2337     }
2338     if (!GetTokenInformation( hToken, TokenType, &Type,
2339                               sizeof(TOKEN_TYPE), &size ))
2340         return FALSE;
2341 
2342     if (Type == TokenPrimary)
2343     {
2344         OBJECT_ATTRIBUTES ObjectAttributes;
2345 
2346         InitializeObjectAttributes( &ObjectAttributes, NULL, 0, NULL, NULL );
2347 
2348         Status = NtDuplicateToken( hToken,
2349                                    TOKEN_IMPERSONATE | TOKEN_QUERY,
2350                                    &ObjectAttributes,
2351                                    SecurityImpersonation,
2352                                    TokenImpersonation,
2353                                    &ImpersonationToken );
2354         if (Status != STATUS_SUCCESS)
2355         {
2356             ERR( "NtDuplicateToken failed with error 0x%08x\n", Status );
2357             SetLastError( RtlNtStatusToDosError( Status ) );
2358             return FALSE;
2359         }
2360     }
2361     else
2362         ImpersonationToken = hToken;
2363 
2364     Status = NtSetInformationThread( GetCurrentThread(),
2365                                      ThreadImpersonationToken,
2366                                      &ImpersonationToken,
2367                                      sizeof(ImpersonationToken) );
2368 
2369     if (Type == TokenPrimary)
2370         NtClose( ImpersonationToken );
2371 
2372     if (Status != STATUS_SUCCESS)
2373     {
2374         ERR( "NtSetInformationThread failed with error 0x%08x\n", Status );
2375         SetLastError( RtlNtStatusToDosError( Status ) );
2376         return FALSE;
2377     }
2378 
2379     return TRUE;
2380 }
2381 
2382 /******************************************************************************
2383  * AccessCheck [ADVAPI32.@]
2384  */
2385 BOOL WINAPI
2386 AccessCheck(
2387         PSECURITY_DESCRIPTOR SecurityDescriptor,
2388         HANDLE ClientToken,
2389         DWORD DesiredAccess,
2390         PGENERIC_MAPPING GenericMapping,
2391         PPRIVILEGE_SET PrivilegeSet,
2392         LPDWORD PrivilegeSetLength,
2393         LPDWORD GrantedAccess,
2394         LPBOOL AccessStatus)
2395 {
2396     NTSTATUS access_status;
2397     BOOL ret = set_ntstatus( NtAccessCheck(SecurityDescriptor, ClientToken, DesiredAccess,
2398                                            GenericMapping, PrivilegeSet, PrivilegeSetLength,
2399                                            GrantedAccess, &access_status) );
2400     if (ret) *AccessStatus = set_ntstatus( access_status );
2401     return ret;
2402 }
2403 
2404 
2405 /******************************************************************************
2406  * AccessCheckByType [ADVAPI32.@]
2407  */
2408 BOOL WINAPI AccessCheckByType(
2409     PSECURITY_DESCRIPTOR pSecurityDescriptor, 
2410     PSID PrincipalSelfSid,
2411     HANDLE ClientToken, 
2412     DWORD DesiredAccess, 
2413     POBJECT_TYPE_LIST ObjectTypeList,
2414     DWORD ObjectTypeListLength,
2415     PGENERIC_MAPPING GenericMapping,
2416     PPRIVILEGE_SET PrivilegeSet,
2417     LPDWORD PrivilegeSetLength, 
2418     LPDWORD GrantedAccess,
2419     LPBOOL AccessStatus)
2420 {
2421         FIXME("stub\n");
2422 
2423         *AccessStatus = TRUE;
2424 
2425         return !*AccessStatus;
2426 }
2427 
2428 /******************************************************************************
2429  * MapGenericMask [ADVAPI32.@]
2430  *
2431  * Maps generic access rights into specific access rights according to the
2432  * supplied mapping.
2433  *
2434  * PARAMS
2435  *  AccessMask     [I/O] Access rights.
2436  *  GenericMapping [I] The mapping between generic and specific rights.
2437  *
2438  * RETURNS
2439  *  Nothing.
2440  */
2441 VOID WINAPI MapGenericMask( PDWORD AccessMask, PGENERIC_MAPPING GenericMapping )
2442 {
2443     RtlMapGenericMask( AccessMask, GenericMapping );
2444 }
2445 
2446 /*************************************************************************
2447  * SetKernelObjectSecurity [ADVAPI32.@]
2448  */
2449 BOOL WINAPI SetKernelObjectSecurity (
2450         IN HANDLE Handle,
2451         IN SECURITY_INFORMATION SecurityInformation,
2452         IN PSECURITY_DESCRIPTOR SecurityDescriptor )
2453 {
2454     return set_ntstatus (NtSetSecurityObject (Handle, SecurityInformation, SecurityDescriptor));
2455 }
2456 
2457 
2458 /******************************************************************************
2459  *  AddAuditAccessAce [ADVAPI32.@]
2460  */
2461 BOOL WINAPI AddAuditAccessAce(
2462     IN OUT PACL pAcl, 
2463     IN DWORD dwAceRevision, 
2464     IN DWORD dwAccessMask, 
2465     IN PSID pSid, 
2466     IN BOOL bAuditSuccess, 
2467     IN BOOL bAuditFailure) 
2468 {
2469     return set_ntstatus( RtlAddAuditAccessAce(pAcl, dwAceRevision, dwAccessMask, pSid, 
2470                                               bAuditSuccess, bAuditFailure) ); 
2471 }
2472 
2473 /******************************************************************************
2474  *  AddAuditAccessAce [ADVAPI32.@]
2475  */
2476 BOOL WINAPI AddAuditAccessAceEx(
2477     IN OUT PACL pAcl,
2478     IN DWORD dwAceRevision,
2479     IN DWORD dwAceFlags,
2480     IN DWORD dwAccessMask,
2481     IN PSID pSid,
2482     IN BOOL bAuditSuccess,
2483     IN BOOL bAuditFailure)
2484 {
2485     return set_ntstatus( RtlAddAuditAccessAceEx(pAcl, dwAceRevision, dwAceFlags, dwAccessMask, pSid,
2486                                               bAuditSuccess, bAuditFailure) );
2487 }
2488 
2489 /******************************************************************************
2490  * LookupAccountNameA [ADVAPI32.@]
2491  */
2492 BOOL WINAPI
2493 LookupAccountNameA(
2494         IN LPCSTR system,
2495         IN LPCSTR account,
2496         OUT PSID sid,
2497         OUT LPDWORD cbSid,
2498         LPSTR ReferencedDomainName,
2499         IN OUT LPDWORD cbReferencedDomainName,
2500         OUT PSID_NAME_USE name_use )
2501 {
2502     BOOL ret;
2503     UNICODE_STRING lpSystemW;
2504     UNICODE_STRING lpAccountW;
2505     LPWSTR lpReferencedDomainNameW = NULL;
2506 
2507     RtlCreateUnicodeStringFromAsciiz(&lpSystemW, system);
2508     RtlCreateUnicodeStringFromAsciiz(&lpAccountW, account);
2509 
2510     if (ReferencedDomainName)
2511         lpReferencedDomainNameW = HeapAlloc(GetProcessHeap(), 0, *cbReferencedDomainName * sizeof(WCHAR));
2512 
2513     ret = LookupAccountNameW(lpSystemW.Buffer, lpAccountW.Buffer, sid, cbSid, lpReferencedDomainNameW,
2514         cbReferencedDomainName, name_use);
2515 
2516     if (ret && lpReferencedDomainNameW)
2517     {
2518         WideCharToMultiByte(CP_ACP, 0, lpReferencedDomainNameW, -1,
2519             ReferencedDomainName, *cbReferencedDomainName+1, NULL, NULL);
2520     }
2521 
2522     RtlFreeUnicodeString(&lpSystemW);
2523     RtlFreeUnicodeString(&lpAccountW);
2524     HeapFree(GetProcessHeap(), 0, lpReferencedDomainNameW);
2525 
2526     return ret;
2527 }
2528 
2529 /******************************************************************************
2530  * LookupAccountNameW [ADVAPI32.@]
2531  */
2532 BOOL WINAPI LookupAccountNameW( LPCWSTR lpSystemName, LPCWSTR lpAccountName, PSID Sid,
2533                                 LPDWORD cbSid, LPWSTR ReferencedDomainName,
2534                                 LPDWORD cchReferencedDomainName, PSID_NAME_USE peUse )
2535 {
2536     /* Default implementation: Always return a default SID */
2537     SID_IDENTIFIER_AUTHORITY identifierAuthority = {SECURITY_NT_AUTHORITY};
2538     BOOL ret;
2539     PSID pSid;
2540     static const WCHAR dm[] = {'D','O','M','A','I','N',0};
2541     unsigned int i;
2542     DWORD nameLen;
2543     LPWSTR userName = NULL;
2544     LPCWSTR domainName;
2545 
2546     FIXME("%s %s %p %p %p %p %p - stub\n", debugstr_w(lpSystemName), debugstr_w(lpAccountName),
2547           Sid, cbSid, ReferencedDomainName, cchReferencedDomainName, peUse);
2548 
2549     if (!ADVAPI_IsLocalComputer(lpSystemName))
2550     {
2551         SetLastError(RPC_S_SERVER_UNAVAILABLE);
2552         return FALSE;
2553     }
2554 
2555     if (!lpAccountName || !strcmpW(lpAccountName, Blank))
2556     {
2557         lpAccountName = BUILTIN;
2558     }
2559 
2560     /* Check well known SIDs first */
2561 
2562     for (i = 0; i < (sizeof(ACCOUNT_SIDS) / sizeof(ACCOUNT_SIDS[0])); i++)
2563     {
2564         if (!strcmpW(lpAccountName, ACCOUNT_SIDS[i].account))
2565         {
2566             DWORD sidLen = SECURITY_MAX_SID_SIZE;
2567 
2568             pSid = HeapAlloc(GetProcessHeap(), 0, sidLen);
2569 
2570             ret = CreateWellKnownSid(ACCOUNT_SIDS[i].type, NULL, pSid, &sidLen);
2571 
2572             if (ret)
2573             {
2574                 if (*cbSid < sidLen)
2575                 {
2576                     SetLastError(ERROR_INSUFFICIENT_BUFFER);
2577                     ret = FALSE;
2578                 }
2579                 else if (Sid)
2580                 {
2581                     CopySid(*cbSid, Sid, pSid);
2582                 }
2583 
2584                 *cbSid = sidLen;
2585             }
2586 
2587             domainName = ACCOUNT_SIDS[i].domain;
2588             nameLen = strlenW(domainName);
2589 
2590             if (*cchReferencedDomainName <= nameLen || !ret)
2591             {
2592                 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2593                 nameLen += 1;
2594                 ret = FALSE;
2595             }
2596             else if (ReferencedDomainName && domainName)
2597             {
2598                 strcpyW(ReferencedDomainName, domainName);
2599             }
2600 
2601             *cchReferencedDomainName = nameLen;
2602 
2603             if (ret)
2604             {
2605                 *peUse = ACCOUNT_SIDS[i].name_use;
2606             }
2607 
2608             HeapFree(GetProcessHeap(), 0, pSid);
2609 
2610             return ret;
2611         }
2612     }
2613 
2614     /* Let the current Unix user id masquerade as first Windows user account */
2615 
2616     nameLen = UNLEN + 1;
2617 
2618     userName = HeapAlloc(GetProcessHeap(), 0, nameLen);
2619 
2620     ret = GetUserNameW(userName, &nameLen);
2621 
2622     if (ret && strcmpW(lpAccountName, userName) != 0)
2623     {
2624         SetLastError(ERROR_NONE_MAPPED);
2625         ret = FALSE;
2626     }
2627 
2628     HeapFree(GetProcessHeap(), 0, userName);
2629 
2630     if (!ret)
2631     {
2632         return ret;
2633     }
2634 
2635     ret = AllocateAndInitializeSid(&identifierAuthority,
2636         2,
2637         SECURITY_BUILTIN_DOMAIN_RID,
2638         DOMAIN_ALIAS_RID_ADMINS,
2639         0, 0, 0, 0, 0, 0,
2640         &pSid);
2641 
2642     if (!ret)
2643        return FALSE;
2644 
2645     if (!RtlValidSid(pSid))
2646     {
2647        FreeSid(pSid);
2648        return FALSE;
2649     }
2650 
2651     if (Sid != NULL && (*cbSid >= GetLengthSid(pSid)))
2652        CopySid(*cbSid, Sid, pSid);
2653     if (*cbSid < GetLengthSid(pSid))
2654     {
2655        SetLastError(ERROR_INSUFFICIENT_BUFFER);
2656        ret = FALSE;
2657     }
2658     *cbSid = GetLengthSid(pSid);
2659 
2660     domainName = dm;
2661     nameLen = strlenW(domainName);
2662 
2663     if (*cchReferencedDomainName <= nameLen || !ret)
2664     {
2665         SetLastError(ERROR_INSUFFICIENT_BUFFER);
2666         nameLen += 1;
2667         ret = FALSE;
2668     }
2669     else if (ReferencedDomainName)
2670     {
2671         strcpyW(ReferencedDomainName, domainName);
2672     }
2673 
2674     *cchReferencedDomainName = nameLen;
2675 
2676     if (ret)
2677     {
2678         *peUse = SidTypeUser;
2679     }
2680 
2681     FreeSid(pSid);
2682 
2683     return ret;
2684 }
2685 
2686 /******************************************************************************
2687  * PrivilegeCheck [ADVAPI32.@]
2688  */
2689 BOOL WINAPI PrivilegeCheck( HANDLE ClientToken, PPRIVILEGE_SET RequiredPrivileges, LPBOOL pfResult)
2690 {
2691     BOOL ret;
2692     BOOLEAN Result;
2693 
2694     TRACE("%p %p %p\n", ClientToken, RequiredPrivileges, pfResult);
2695 
2696     ret = set_ntstatus (NtPrivilegeCheck (ClientToken, RequiredPrivileges, &Result));
2697     if (ret)
2698         *pfResult = Result;
2699     return ret;
2700 }
2701 
2702 /******************************************************************************
2703  * AccessCheckAndAuditAlarmA [ADVAPI32.@]
2704  */
2705 BOOL WINAPI AccessCheckAndAuditAlarmA(LPCSTR Subsystem, LPVOID HandleId, LPSTR ObjectTypeName,
2706   LPSTR ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD DesiredAccess,
2707   PGENERIC_MAPPING GenericMapping, BOOL ObjectCreation, LPDWORD GrantedAccess,
2708   LPBOOL AccessStatus, LPBOOL pfGenerateOnClose)
2709 {
2710         FIXME("stub (%s,%p,%s,%s,%p,%08x,%p,%x,%p,%p,%p)\n", debugstr_a(Subsystem),
2711                 HandleId, debugstr_a(ObjectTypeName), debugstr_a(ObjectName),
2712                 SecurityDescriptor, DesiredAccess, GenericMapping,
2713                 ObjectCreation, GrantedAccess, AccessStatus, pfGenerateOnClose);
2714         return TRUE;
2715 }
2716 
2717 /******************************************************************************
2718  * AccessCheckAndAuditAlarmW [ADVAPI32.@]
2719  */
2720 BOOL WINAPI AccessCheckAndAuditAlarmW(LPCWSTR Subsystem, LPVOID HandleId, LPWSTR ObjectTypeName,
2721   LPWSTR ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD DesiredAccess,
2722   PGENERIC_MAPPING GenericMapping, BOOL ObjectCreation, LPDWORD GrantedAccess,
2723   LPBOOL AccessStatus, LPBOOL pfGenerateOnClose)
2724 {
2725         FIXME("stub (%s,%p,%s,%s,%p,%08x,%p,%x,%p,%p,%p)\n", debugstr_w(Subsystem),
2726                 HandleId, debugstr_w(ObjectTypeName), debugstr_w(ObjectName),
2727                 SecurityDescriptor, DesiredAccess, GenericMapping,
2728                 ObjectCreation, GrantedAccess, AccessStatus, pfGenerateOnClose);
2729         return TRUE;
2730 }
2731 
2732 BOOL WINAPI ObjectCloseAuditAlarmA(LPCSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
2733 {
2734     FIXME("stub (%s,%p,%x)\n", debugstr_a(SubsystemName), HandleId, GenerateOnClose);
2735 
2736     return TRUE;
2737 }
2738 
2739 BOOL WINAPI ObjectCloseAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
2740 {
2741     FIXME("stub (%s,%p,%x)\n", debugstr_w(SubsystemName), HandleId, GenerateOnClose);
2742 
2743     return TRUE;
2744 }
2745 
2746 BOOL WINAPI ObjectDeleteAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
2747 {
2748     FIXME("stub (%s,%p,%x)\n", debugstr_w(SubsystemName), HandleId, GenerateOnClose);
2749 
2750     return TRUE;
2751 }
2752 
2753 BOOL WINAPI ObjectOpenAuditAlarmA(LPCSTR SubsystemName, LPVOID HandleId, LPSTR ObjectTypeName,
2754   LPSTR ObjectName, PSECURITY_DESCRIPTOR pSecurityDescriptor, HANDLE ClientToken, DWORD DesiredAccess,
2755   DWORD GrantedAccess, PPRIVILEGE_SET Privileges, BOOL ObjectCreation, BOOL AccessGranted,
2756   LPBOOL GenerateOnClose)
2757 {
2758         FIXME("stub (%s,%p,%s,%s,%p,%p,0x%08x,0x%08x,%p,%x,%x,%p)\n", debugstr_a(SubsystemName),
2759                 HandleId, debugstr_a(ObjectTypeName), debugstr_a(ObjectName), pSecurityDescriptor,
2760         ClientToken, DesiredAccess, GrantedAccess, Privileges, ObjectCreation, AccessGranted,
2761         GenerateOnClose);
2762 
2763     return TRUE;
2764 }
2765 
2766 BOOL WINAPI ObjectOpenAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, LPWSTR ObjectTypeName,
2767   LPWSTR ObjectName, PSECURITY_DESCRIPTOR pSecurityDescriptor, HANDLE ClientToken, DWORD DesiredAccess,
2768   DWORD GrantedAccess, PPRIVILEGE_SET Privileges, BOOL ObjectCreation, BOOL AccessGranted,
2769   LPBOOL GenerateOnClose)
2770 {
2771     FIXME("stub (%s,%p,%s,%s,%p,%p,0x%08x,0x%08x,%p,%x,%x,%p)\n", debugstr_w(SubsystemName),
2772         HandleId, debugstr_w(ObjectTypeName), debugstr_w(ObjectName), pSecurityDescriptor,
2773         ClientToken, DesiredAccess, GrantedAccess, Privileges, ObjectCreation, AccessGranted,
2774         GenerateOnClose);
2775 
2776     return TRUE;
2777 }
2778 
2779 BOOL WINAPI ObjectPrivilegeAuditAlarmA( LPCSTR SubsystemName, LPVOID HandleId, HANDLE ClientToken,
2780   DWORD DesiredAccess, PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2781 {
2782     FIXME("stub (%s,%p,%p,0x%08x,%p,%x)\n", debugstr_a(SubsystemName), HandleId, ClientToken,
2783           DesiredAccess, Privileges, AccessGranted);
2784 
2785     return TRUE;
2786 }
2787 
2788 BOOL WINAPI ObjectPrivilegeAuditAlarmW( LPCWSTR SubsystemName, LPVOID HandleId, HANDLE ClientToken,
2789   DWORD DesiredAccess, PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2790 {
2791     FIXME("stub (%s,%p,%p,0x%08x,%p,%x)\n", debugstr_w(SubsystemName), HandleId, ClientToken,
2792           DesiredAccess, Privileges, AccessGranted);
2793 
2794     return TRUE;
2795 }
2796 
2797 BOOL WINAPI PrivilegedServiceAuditAlarmA( LPCSTR SubsystemName, LPCSTR ServiceName, HANDLE ClientToken,
2798                                    PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2799 {
2800     FIXME("stub (%s,%s,%p,%p,%x)\n", debugstr_a(SubsystemName), debugstr_a(ServiceName),
2801           ClientToken, Privileges, AccessGranted);
2802 
2803     return TRUE;
2804 }
2805 
2806 BOOL WINAPI PrivilegedServiceAuditAlarmW( LPCWSTR SubsystemName, LPCWSTR ServiceName, HANDLE ClientToken,
2807                                    PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2808 {
2809     FIXME("stub %s,%s,%p,%p,%x)\n", debugstr_w(SubsystemName), debugstr_w(ServiceName),
2810           ClientToken, Privileges, AccessGranted);
2811 
2812     return TRUE;
2813 }
2814 
2815 /******************************************************************************
2816  * GetSecurityInfo [ADVAPI32.@]
2817  *
2818  * Retrieves a copy of the security descriptor associated with an object.
2819  *
2820  * PARAMS
2821  *  hObject              [I] A handle for the object.
2822  *  ObjectType           [I] The type of object.
2823  *  SecurityInfo         [I] A bitmask indicating what info to retrieve.
2824  *  ppsidOwner           [O] If non-null, receives a pointer to the owner SID.
2825  *  ppsidGroup           [O] If non-null, receives a pointer to the group SID.
2826  *  ppDacl               [O] If non-null, receives a pointer to the DACL.
2827  *  ppSacl               [O] If non-null, receives a pointer to the SACL.
2828  *  ppSecurityDescriptor [O] Receives a pointer to the security descriptor,
2829  *                           which must be freed with LocalFree.
2830  *
2831  * RETURNS
2832  *  ERROR_SUCCESS if all's well, and a WIN32 error code otherwise.
2833  */
2834 DWORD WINAPI GetSecurityInfo(
2835     HANDLE hObject, SE_OBJECT_TYPE ObjectType,
2836     SECURITY_INFORMATION SecurityInfo, PSID *ppsidOwner,
2837     PSID *ppsidGroup, PACL *ppDacl, PACL *ppSacl,
2838     PSECURITY_DESCRIPTOR *ppSecurityDescriptor
2839 )
2840 {
2841     PSECURITY_DESCRIPTOR sd;
2842     NTSTATUS status;
2843     ULONG n1, n2;
2844     BOOL present, defaulted;
2845 
2846     status = NtQuerySecurityObject(hObject, SecurityInfo, NULL, 0, &n1);
2847     if (status != STATUS_BUFFER_TOO_SMALL && status != STATUS_SUCCESS)
2848         return RtlNtStatusToDosError(status);
2849 
2850     sd = LocalAlloc(0, n1);
2851     if (!sd)
2852         return ERROR_NOT_ENOUGH_MEMORY;
2853 
2854     status = NtQuerySecurityObject(hObject, SecurityInfo, sd, n1, &n2);
2855     if (status != STATUS_SUCCESS)
2856     {
2857         LocalFree(sd);
2858         return RtlNtStatusToDosError(status);
2859     }
2860 
2861     if (ppsidOwner)
2862     {
2863         *ppsidOwner = NULL;
2864         GetSecurityDescriptorOwner(sd, ppsidOwner, &defaulted);
2865     }
2866     if (ppsidGroup)
2867     {
2868         *ppsidGroup = NULL;
2869         GetSecurityDescriptorGroup(sd, ppsidGroup, &defaulted);
2870     }
2871     if (ppDacl)
2872     {
2873         *ppDacl = NULL;
2874         GetSecurityDescriptorDacl(sd, &present, ppDacl, &defaulted);
2875     }
2876     if (ppSacl)
2877     {
2878         *ppSacl = NULL;
2879         GetSecurityDescriptorSacl(sd, &present, ppSacl, &defaulted);
2880     }
2881     if (ppSecurityDescriptor)
2882         *ppSecurityDescriptor = sd;
2883 
2884     return ERROR_SUCCESS;
2885 }
2886 
2887 /******************************************************************************
2888  * GetSecurityInfoExW [ADVAPI32.@]
2889  */
2890 DWORD WINAPI GetSecurityInfoExW(
2891         HANDLE hObject, SE_OBJECT_TYPE ObjectType, 
2892         SECURITY_INFORMATION SecurityInfo, LPCWSTR lpProvider,
2893         LPCWSTR lpProperty, PACTRL_ACCESSW *ppAccessList, 
2894         PACTRL_AUDITW *ppAuditList, LPWSTR *lppOwner, LPWSTR *lppGroup
2895 )
2896 {
2897   FIXME("stub!\n");
2898   return ERROR_BAD_PROVIDER; 
2899 }
2900 
2901 /******************************************************************************
2902  * BuildExplicitAccessWithNameA [ADVAPI32.@]
2903  */
2904 VOID WINAPI BuildExplicitAccessWithNameA( PEXPLICIT_ACCESSA pExplicitAccess,
2905                                           LPSTR pTrusteeName, DWORD AccessPermissions,
2906                                           ACCESS_MODE AccessMode, DWORD Inheritance )
2907 {
2908     TRACE("%p %s 0x%08x 0x%08x 0x%08x\n", pExplicitAccess, debugstr_a(pTrusteeName),
2909           AccessPermissions, AccessMode, Inheritance);
2910 
2911     pExplicitAccess->grfAccessPermissions = AccessPermissions;
2912     pExplicitAccess->grfAccessMode = AccessMode;
2913     pExplicitAccess->grfInheritance = Inheritance;
2914 
2915     pExplicitAccess->Trustee.pMultipleTrustee = NULL;
2916     pExplicitAccess->Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2917     pExplicitAccess->Trustee.TrusteeForm = TRUSTEE_IS_NAME;
2918     pExplicitAccess->Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
2919     pExplicitAccess->Trustee.ptstrName = pTrusteeName;
2920 }
2921 
2922 /******************************************************************************
2923  * BuildExplicitAccessWithNameW [ADVAPI32.@]
2924  */
2925 VOID WINAPI BuildExplicitAccessWithNameW( PEXPLICIT_ACCESSW pExplicitAccess,
2926                                           LPWSTR pTrusteeName, DWORD AccessPermissions,
2927                                           ACCESS_MODE AccessMode, DWORD Inheritance )
2928 {
2929     TRACE("%p %s 0x%08x 0x%08x 0x%08x\n", pExplicitAccess, debugstr_w(pTrusteeName),
2930           AccessPermissions, AccessMode, Inheritance);
2931 
2932     pExplicitAccess->grfAccessPermissions = AccessPermissions;
2933     pExplicitAccess->grfAccessMode = AccessMode;
2934     pExplicitAccess->grfInheritance = Inheritance;
2935 
2936     pExplicitAccess->Trustee.pMultipleTrustee = NULL;
2937     pExplicitAccess->Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2938     pExplicitAccess->Trustee.TrusteeForm = TRUSTEE_IS_NAME;
2939     pExplicitAccess->Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
2940     pExplicitAccess->Trustee.ptstrName = pTrusteeName;
2941 }
2942 
2943 /******************************************************************************
2944  * BuildTrusteeWithObjectsAndNameA [ADVAPI32.@]
2945  */
2946 VOID WINAPI BuildTrusteeWithObjectsAndNameA( PTRUSTEEA pTrustee, POBJECTS_AND_NAME_A pObjName,
2947                                              SE_OBJECT_TYPE ObjectType, LPSTR ObjectTypeName,
2948                                              LPSTR InheritedObjectTypeName, LPSTR Name )
2949 {
2950     DWORD ObjectsPresent = 0;
2951 
2952     TRACE("%p %p 0x%08x %p %p %s\n", pTrustee, pObjName,
2953           ObjectType, ObjectTypeName, InheritedObjectTypeName, debugstr_a(Name));
2954 
2955     /* Fill the OBJECTS_AND_NAME structure */
2956     pObjName->ObjectType = ObjectType;
2957     if (ObjectTypeName != NULL)
2958     {
2959         ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
2960     }
2961 
2962     pObjName->InheritedObjectTypeName = InheritedObjectTypeName;
2963     if (InheritedObjectTypeName != NULL)
2964     {
2965         ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
2966     }
2967 
2968     pObjName->ObjectsPresent = ObjectsPresent;
2969     pObjName->ptstrName = Name;
2970 
2971     /* Fill the TRUSTEE structure */
2972     pTrustee->pMultipleTrustee = NULL;
2973     pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2974     pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_NAME;
2975     pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2976     pTrustee->ptstrName = (LPSTR)pObjName;
2977 }
2978 
2979 /******************************************************************************
2980  * BuildTrusteeWithObjectsAndNameW [ADVAPI32.@]
2981  */
2982 VOID WINAPI BuildTrusteeWithObjectsAndNameW( PTRUSTEEW pTrustee, POBJECTS_AND_NAME_W pObjName,
2983                                              SE_OBJECT_TYPE ObjectType, LPWSTR ObjectTypeName,
2984                                              LPWSTR InheritedObjectTypeName, LPWSTR Name )
2985 {
2986     DWORD ObjectsPresent = 0;
2987 
2988     TRACE("%p %p 0x%08x %p %p %s\n", pTrustee, pObjName,
2989           ObjectType, ObjectTypeName, InheritedObjectTypeName, debugstr_w(Name));
2990 
2991     /* Fill the OBJECTS_AND_NAME structure */
2992     pObjName->ObjectType = ObjectType;
2993     if (ObjectTypeName != NULL)
2994     {
2995         ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
2996     }
2997 
2998     pObjName->InheritedObjectTypeName = InheritedObjectTypeName;
2999     if (InheritedObjectTypeName != NULL)
3000     {
3001         ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3002     }
3003 
3004     pObjName->ObjectsPresent = ObjectsPresent;
3005     pObjName->ptstrName = Name;
3006 
3007     /* Fill the TRUSTEE structure */
3008     pTrustee->pMultipleTrustee = NULL;
3009     pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3010     pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_NAME;
3011     pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3012     pTrustee->ptstrName = (LPWSTR)pObjName;
3013 }
3014 
3015 /******************************************************************************
3016  * BuildTrusteeWithObjectsAndSidA [ADVAPI32.@]
3017  */
3018 VOID WINAPI BuildTrusteeWithObjectsAndSidA( PTRUSTEEA pTrustee, POBJECTS_AND_SID pObjSid,
3019                                             GUID* pObjectGuid, GUID* pInheritedObjectGuid, PSID pSid )
3020 {
3021     DWORD ObjectsPresent = 0;
3022 
3023     TRACE("%p %p %p %p %p\n", pTrustee, pObjSid, pObjectGuid, pInheritedObjectGuid, pSid);
3024 
3025     /* Fill the OBJECTS_AND_SID structure */
3026     if (pObjectGuid != NULL)
3027     {
3028         pObjSid->ObjectTypeGuid = *pObjectGuid;
3029         ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
3030     }
3031     else
3032     {
3033         ZeroMemory(&pObjSid->ObjectTypeGuid,
3034                    sizeof(GUID));
3035     }
3036 
3037     if (pInheritedObjectGuid != NULL)
3038     {
3039         pObjSid->InheritedObjectTypeGuid = *pInheritedObjectGuid;
3040         ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3041     }
3042     else
3043     {
3044         ZeroMemory(&pObjSid->InheritedObjectTypeGuid,
3045                    sizeof(GUID));
3046     }
3047 
3048     pObjSid->ObjectsPresent = ObjectsPresent;
3049     pObjSid->pSid = pSid;
3050 
3051     /* Fill the TRUSTEE structure */
3052     pTrustee->pMultipleTrustee = NULL;
3053     pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3054     pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_SID;
3055     pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3056     pTrustee->ptstrName = (LPSTR) pObjSid;
3057 }
3058 
3059 /******************************************************************************
3060  * BuildTrusteeWithObjectsAndSidW [ADVAPI32.@]
3061  */
3062 VOID WINAPI BuildTrusteeWithObjectsAndSidW( PTRUSTEEW pTrustee, POBJECTS_AND_SID pObjSid,
3063                                             GUID* pObjectGuid, GUID* pInheritedObjectGuid, PSID pSid )
3064 {
3065     DWORD ObjectsPresent = 0;
3066 
3067     TRACE("%p %p %p %p %p\n", pTrustee, pObjSid, pObjectGuid, pInheritedObjectGuid, pSid);
3068 
3069     /* Fill the OBJECTS_AND_SID structure */
3070     if (pObjectGuid != NULL)
3071     {
3072         pObjSid->ObjectTypeGuid = *pObjectGuid;
3073         ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
3074     }
3075     else
3076     {
3077         ZeroMemory(&pObjSid->ObjectTypeGuid,
3078                    sizeof(GUID));
3079     }
3080 
3081     if (pInheritedObjectGuid != NULL)
3082     {
3083         pObjSid->InheritedObjectTypeGuid = *pInheritedObjectGuid;
3084         ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3085     }
3086     else
3087     {
3088         ZeroMemory(&pObjSid->InheritedObjectTypeGuid,
3089                    sizeof(GUID));
3090     }
3091 
3092     pObjSid->ObjectsPresent = ObjectsPresent;
3093     pObjSid->pSid = pSid;
3094 
3095     /* Fill the TRUSTEE structure */
3096     pTrustee->pMultipleTrustee = NULL;
3097     pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3098     pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_SID;
3099     pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3100     pTrustee->ptstrName = (LPWSTR) pObjSid;
3101 }
3102 
3103 /******************************************************************************
3104  * BuildTrusteeWithSidA [ADVAPI32.@]
3105  */
3106 VOID WINAPI BuildTrusteeWithSidA(PTRUSTEEA pTrustee, PSID pSid)
3107 {
3108     TRACE("%p %p\n", pTrustee, pSid);
3109 
3110     pTrustee->pMultipleTrustee = NULL;
3111     pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3112     pTrustee->TrusteeForm = TRUSTEE_IS_SID;
3113     pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3114     pTrustee->ptstrName = (LPSTR) pSid;
3115 }
3116 
3117 /******************************************************************************
3118  * BuildTrusteeWithSidW [ADVAPI32.@]
3119  */
3120 VOID WINAPI BuildTrusteeWithSidW(PTRUSTEEW pTrustee, PSID pSid)
3121 {
3122     TRACE("%p %p\n", pTrustee, pSid);
3123 
3124     pTrustee->pMultipleTrustee = NULL;
3125     pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3126     pTrustee->TrusteeForm = TRUSTEE_IS_SID;
3127     pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3128     pTrustee->ptstrName = (LPWSTR) pSid;
3129 }
3130 
3131 /******************************************************************************
3132  * BuildTrusteeWithNameA [ADVAPI32.@]
3133  */
3134 VOID WINAPI BuildTrusteeWithNameA(PTRUSTEEA pTrustee, LPSTR name)
3135 {
3136     TRACE("%p %s\n", pTrustee, debugstr_a(name) );
3137 
3138     pTrustee->pMultipleTrustee = NULL;
3139     pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3140     pTrustee->TrusteeForm = TRUSTEE_IS_NAME;
3141     pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3142     pTrustee->ptstrName = name;
3143 }
3144 
3145 /******************************************************************************
3146  * BuildTrusteeWithNameW [ADVAPI32.@]
3147  */
3148 VOID WINAPI BuildTrusteeWithNameW(PTRUSTEEW pTrustee, LPWSTR name)
3149 {
3150     TRACE("%p %s\n", pTrustee, debugstr_w(name) );
3151 
3152     pTrustee->pMultipleTrustee = NULL;
3153     pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3154     pTrustee->TrusteeForm = TRUSTEE_IS_NAME;
3155     pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3156     pTrustee->ptstrName = name;
3157 }
3158 
3159 /****************************************************************************** 
3160  * GetTrusteeFormA [ADVAPI32.@] 
3161  */ 
3162 TRUSTEE_FORM WINAPI GetTrusteeFormA(PTRUSTEEA pTrustee) 
3163 {  
3164     TRACE("(%p)\n", pTrustee); 
3165   
3166     if (!pTrustee) 
3167         return TRUSTEE_BAD_FORM; 
3168   
3169     return pTrustee->TrusteeForm; 
3170 }  
3171   
3172 /****************************************************************************** 
3173  * GetTrusteeFormW [ADVAPI32.@] 
3174  */ 
3175 TRUSTEE_FORM WINAPI GetTrusteeFormW(PTRUSTEEW pTrustee) 
3176 {  
3177     TRACE("(%p)\n", pTrustee); 
3178   
3179     if (!pTrustee) 
3180         return TRUSTEE_BAD_FORM; 
3181   
3182     return pTrustee->TrusteeForm; 
3183 }  
3184   
3185 /****************************************************************************** 
3186  * GetTrusteeNameA [ADVAPI32.@] 
3187  */ 
3188 LPSTR WINAPI GetTrusteeNameA(PTRUSTEEA pTrustee) 
3189 {  
3190     TRACE("(%p)\n", pTrustee); 
3191   
3192     if (!pTrustee) 
3193         return NULL; 
3194   
3195     return pTrustee->ptstrName; 
3196 }  
3197   
3198 /****************************************************************************** 
3199  * GetTrusteeNameW [ADVAPI32.@] 
3200  */ 
3201 LPWSTR WINAPI GetTrusteeNameW(PTRUSTEEW pTrustee) 
3202 {  
3203     TRACE("(%p)\n", pTrustee); 
3204   
3205     if (!pTrustee) 
3206         return NULL; 
3207   
3208     return pTrustee->ptstrName; 
3209 }  
3210   
3211 /****************************************************************************** 
3212  * GetTrusteeTypeA [ADVAPI32.@] 
3213  */ 
3214 TRUSTEE_TYPE WINAPI GetTrusteeTypeA(PTRUSTEEA pTrustee) 
3215 {  
3216     TRACE("(%p)\n", pTrustee); 
3217   
3218     if (!pTrustee) 
3219         return TRUSTEE_IS_UNKNOWN; 
3220   
3221     return pTrustee->TrusteeType; 
3222 }  
3223   
3224 /****************************************************************************** 
3225  * GetTrusteeTypeW [ADVAPI32.@] 
3226  */ 
3227 TRUSTEE_TYPE WINAPI GetTrusteeTypeW(PTRUSTEEW pTrustee) 
3228 {  
3229     TRACE("(%p)\n", pTrustee); 
3230   
3231     if (!pTrustee) 
3232         return TRUSTEE_IS_UNKNOWN; 
3233   
3234     return pTrustee->TrusteeType; 
3235 } 
3236  
3237 BOOL WINAPI SetAclInformation( PACL pAcl, LPVOID pAclInformation,
3238                                DWORD nAclInformationLength,
3239                                ACL_INFORMATION_CLASS dwAclInformationClass )
3240 {
3241     FIXME("%p %p 0x%08x 0x%08x - stub\n", pAcl, pAclInformation,
3242           nAclInformationLength, dwAclInformationClass);
3243 
3244     return TRUE;
3245 }
3246 
3247 /******************************************************************************
3248  * SetEntriesInAclA [ADVAPI32.@]
3249  */
3250 DWORD WINAPI SetEntriesInAclA( ULONG count, PEXPLICIT_ACCESSA pEntries,
3251                                PACL OldAcl, PACL* NewAcl )
3252 {
3253     FIXME("%d %p %p %p\n",count,pEntries,OldAcl,NewAcl);
3254     if (NewAcl)
3255          *NewAcl = NULL;
3256     return ERROR_SUCCESS;
3257 }
3258 
3259 /******************************************************************************
3260  * SetEntriesInAclW [ADVAPI32.@]
3261  */
3262 DWORD WINAPI SetEntriesInAclW( ULONG count, PEXPLICIT_ACCESSW pEntries,
3263                                PACL OldAcl, PACL* NewAcl )
3264 {
3265     ULONG i;
3266     PSID *ppsid;
3267     DWORD ret = ERROR_SUCCESS;
3268     DWORD acl_size = sizeof(ACL);
3269     NTSTATUS status;
3270 
3271     TRACE("%d %p %p %p\n", count, pEntries, OldAcl, NewAcl);
3272 
3273     *NewAcl = NULL;
3274 
3275     if (!count && !OldAcl)
3276         return ERROR_SUCCESS;
3277 
3278     /* allocate array of maximum sized sids allowed */
3279     ppsid = HeapAlloc(