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