~ [ 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_RELATIVE* 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 || (DomainSid && !IsValidSid(DomainSid)))
863     {
864         SetLastError(ERROR_INVALID_PARAMETER);
865         return FALSE;
866     }
867 
868     for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++) {
869         if (WellKnownSids[i].Type == WellKnownSidType) {
870             DWORD length = GetSidLengthRequired(WellKnownSids[i].Sid.SubAuthorityCount);
871 
872             if (*cbSid < length)
873             {
874                 *cbSid = length;
875                 SetLastError(ERROR_INSUFFICIENT_BUFFER);
876                 return FALSE;
877             }
878             if (!pSid)
879             {
880                 SetLastError(ERROR_INVALID_PARAMETER);
881                 return FALSE;
882             }
883             CopyMemory(pSid, &WellKnownSids[i].Sid.Revision, length);
884             *cbSid = length;
885             return TRUE;
886         }
887     }
888 
889     if (DomainSid == NULL || *GetSidSubAuthorityCount(DomainSid) == SID_MAX_SUB_AUTHORITIES)
890     {
891         SetLastError(ERROR_INVALID_PARAMETER);
892         return FALSE;
893     }
894 
895     for (i = 0; i < sizeof(WellKnownRids)/sizeof(WellKnownRids[0]); i++)
896         if (WellKnownRids[i].Type == WellKnownSidType) {
897             UCHAR domain_subauth = *GetSidSubAuthorityCount(DomainSid);
898             DWORD domain_sid_length = GetSidLengthRequired(domain_subauth);
899             DWORD output_sid_length = GetSidLengthRequired(domain_subauth + 1);
900 
901             if (*cbSid < output_sid_length)
902             {
903                 *cbSid = output_sid_length;
904                 SetLastError(ERROR_INSUFFICIENT_BUFFER);
905                 return FALSE;
906             }
907             if (!pSid)
908             {
909                 SetLastError(ERROR_INVALID_PARAMETER);
910                 return FALSE;
911             }
912             CopyMemory(pSid, DomainSid, domain_sid_length);
913             (*GetSidSubAuthorityCount(pSid))++;
914             (*GetSidSubAuthority(pSid, domain_subauth)) = WellKnownRids[i].Rid;
915             *cbSid = output_sid_length;
916             return TRUE;
917         }
918 
919     SetLastError(ERROR_INVALID_PARAMETER);
920     return FALSE;
921 }
922 
923 /******************************************************************************
924  * IsWellKnownSid [ADVAPI32.@]
925  */
926 BOOL WINAPI
927 IsWellKnownSid( PSID pSid, WELL_KNOWN_SID_TYPE WellKnownSidType )
928 {
929     unsigned int i;
930     TRACE("(%s, %d)\n", debugstr_sid(pSid), WellKnownSidType);
931 
932     for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
933         if (WellKnownSids[i].Type == WellKnownSidType)
934             if (EqualSid(pSid, (PSID)&(WellKnownSids[i].Sid.Revision)))
935                 return TRUE;
936 
937     return FALSE;
938 }
939 
940 BOOL WINAPI
941 IsTokenRestricted( HANDLE TokenHandle )
942 {
943     TOKEN_GROUPS *groups;
944     DWORD size;
945     NTSTATUS status;
946     BOOL restricted;
947 
948     TRACE("(%p)\n", TokenHandle);
949  
950     status = NtQueryInformationToken(TokenHandle, TokenRestrictedSids, NULL, 0, &size);
951     if (status != STATUS_BUFFER_TOO_SMALL)
952         return FALSE;
953  
954     groups = HeapAlloc(GetProcessHeap(), 0, size);
955     if (!groups)
956     {
957         SetLastError(ERROR_OUTOFMEMORY);
958         return FALSE;
959     }
960  
961     status = NtQueryInformationToken(TokenHandle, TokenRestrictedSids, groups, size, &size);
962     if (status != STATUS_SUCCESS)
963     {
964         HeapFree(GetProcessHeap(), 0, groups);
965         return set_ntstatus(status);
966     }
967  
968     if (groups->GroupCount)
969         restricted = TRUE;
970     else
971         restricted = FALSE;
972      
973     HeapFree(GetProcessHeap(), 0, groups);
974  
975     return restricted;
976 }
977 
978 /******************************************************************************
979  * IsValidSid [ADVAPI32.@]
980  *
981  * PARAMS
982  *   pSid []
983  */
984 BOOL WINAPI
985 IsValidSid( PSID pSid )
986 {
987         return RtlValidSid( pSid );
988 }
989 
990 /******************************************************************************
991  * EqualSid [ADVAPI32.@]
992  *
993  * PARAMS
994  *   pSid1 []
995  *   pSid2 []
996  */
997 BOOL WINAPI
998 EqualSid( PSID pSid1, PSID pSid2 )
999 {
1000         return RtlEqualSid( pSid1, pSid2 );
1001 }
1002 
1003 /******************************************************************************
1004  * EqualPrefixSid [ADVAPI32.@]
1005  */
1006 BOOL WINAPI EqualPrefixSid (PSID pSid1, PSID pSid2)
1007 {
1008         return RtlEqualPrefixSid(pSid1, pSid2);
1009 }
1010 
1011 /******************************************************************************
1012  * GetSidLengthRequired [ADVAPI32.@]
1013  *
1014  * PARAMS
1015  *   nSubAuthorityCount []
1016  */
1017 DWORD WINAPI
1018 GetSidLengthRequired( BYTE nSubAuthorityCount )
1019 {
1020         return RtlLengthRequiredSid(nSubAuthorityCount);
1021 }
1022 
1023 /******************************************************************************
1024  * InitializeSid [ADVAPI32.@]
1025  *
1026  * PARAMS
1027  *   pIdentifierAuthority []
1028  */
1029 BOOL WINAPI
1030 InitializeSid (
1031         PSID pSid,
1032         PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
1033         BYTE nSubAuthorityCount)
1034 {
1035         return RtlInitializeSid(pSid, pIdentifierAuthority, nSubAuthorityCount);
1036 }
1037 
1038 DWORD WINAPI
1039 GetEffectiveRightsFromAclA( PACL pacl, PTRUSTEEA pTrustee, PACCESS_MASK pAccessRights )
1040 {
1041     FIXME("%p %p %p - stub\n", pacl, pTrustee, pAccessRights);
1042 
1043     return 1;
1044 }
1045 
1046 DWORD WINAPI
1047 GetEffectiveRightsFromAclW( PACL pacl, PTRUSTEEW pTrustee, PACCESS_MASK pAccessRights )
1048 {
1049     FIXME("%p %p %p - stub\n", pacl, pTrustee, pAccessRights);
1050 
1051     return 1;
1052 }
1053 
1054 /******************************************************************************
1055  * GetSidIdentifierAuthority [ADVAPI32.@]
1056  *
1057  * PARAMS
1058  *   pSid []
1059  */
1060 PSID_IDENTIFIER_AUTHORITY WINAPI
1061 GetSidIdentifierAuthority( PSID pSid )
1062 {
1063         return RtlIdentifierAuthoritySid(pSid);
1064 }
1065 
1066 /******************************************************************************
1067  * GetSidSubAuthority [ADVAPI32.@]
1068  *
1069  * PARAMS
1070  *   pSid          []
1071  *   nSubAuthority []
1072  */
1073 PDWORD WINAPI
1074 GetSidSubAuthority( PSID pSid, DWORD nSubAuthority )
1075 {
1076         SetLastError(ERROR_SUCCESS);
1077         return RtlSubAuthoritySid(pSid, nSubAuthority);
1078 }
1079 
1080 /******************************************************************************
1081  * GetSidSubAuthorityCount [ADVAPI32.@]
1082  *
1083  * PARAMS
1084  *   pSid []
1085  */
1086 PUCHAR WINAPI
1087 GetSidSubAuthorityCount (PSID pSid)
1088 {
1089         SetLastError(ERROR_SUCCESS);
1090         return RtlSubAuthorityCountSid(pSid);
1091 }
1092 
1093 /******************************************************************************
1094  * GetLengthSid [ADVAPI32.@]
1095  *
1096  * PARAMS
1097  *   pSid []
1098  */
1099 DWORD WINAPI
1100 GetLengthSid (PSID pSid)
1101 {
1102         return RtlLengthSid(pSid);
1103 }
1104 
1105 /*      ##############################################
1106         ######  SECURITY DESCRIPTOR FUNCTIONS   ######
1107         ##############################################
1108 */
1109 
1110  /****************************************************************************** 
1111  * BuildSecurityDescriptorA [ADVAPI32.@]
1112  *
1113  * Builds a SD from 
1114  *
1115  * PARAMS
1116  *  pOwner                [I]
1117  *  pGroup                [I]
1118  *  cCountOfAccessEntries [I]
1119  *  pListOfAccessEntries  [I]
1120  *  cCountOfAuditEntries  [I]
1121  *  pListofAuditEntries   [I]
1122  *  pOldSD                [I]
1123  *  lpdwBufferLength      [I/O]
1124  *  pNewSD                [O]
1125  *
1126  * RETURNS
1127  *  Success: ERROR_SUCCESS
1128  *  Failure: nonzero error code from Winerror.h
1129  */
1130 DWORD WINAPI BuildSecurityDescriptorA(
1131     IN PTRUSTEEA pOwner,
1132     IN PTRUSTEEA pGroup,
1133     IN ULONG cCountOfAccessEntries,
1134     IN PEXPLICIT_ACCESSA pListOfAccessEntries,
1135     IN ULONG cCountOfAuditEntries,
1136     IN PEXPLICIT_ACCESSA pListofAuditEntries,
1137     IN PSECURITY_DESCRIPTOR pOldSD,
1138     IN OUT PULONG lpdwBufferLength,
1139     OUT PSECURITY_DESCRIPTOR* pNewSD)
1140 { 
1141     FIXME("(%p,%p,%d,%p,%d,%p,%p,%p,%p) stub!\n",pOwner,pGroup,
1142           cCountOfAccessEntries,pListOfAccessEntries,cCountOfAuditEntries,
1143           pListofAuditEntries,pOldSD,lpdwBufferLength,pNewSD);
1144  
1145     return ERROR_CALL_NOT_IMPLEMENTED;
1146 } 
1147  
1148 /******************************************************************************
1149  * BuildSecurityDescriptorW [ADVAPI32.@]
1150  *
1151  * See BuildSecurityDescriptorA.
1152  */
1153 DWORD WINAPI BuildSecurityDescriptorW(
1154     IN PTRUSTEEW pOwner,
1155     IN PTRUSTEEW pGroup,
1156     IN ULONG cCountOfAccessEntries,
1157     IN PEXPLICIT_ACCESSW pListOfAccessEntries,
1158     IN ULONG cCountOfAuditEntries,
1159     IN PEXPLICIT_ACCESSW pListofAuditEntries,
1160     IN PSECURITY_DESCRIPTOR pOldSD,
1161     IN OUT PULONG lpdwBufferLength,
1162     OUT PSECURITY_DESCRIPTOR* pNewSD)
1163 { 
1164     FIXME("(%p,%p,%d,%p,%d,%p,%p,%p,%p) stub!\n",pOwner,pGroup,
1165           cCountOfAccessEntries,pListOfAccessEntries,cCountOfAuditEntries,
1166           pListofAuditEntries,pOldSD,lpdwBufferLength,pNewSD);
1167  
1168     return ERROR_CALL_NOT_IMPLEMENTED;
1169 } 
1170 
1171 /******************************************************************************
1172  * InitializeSecurityDescriptor [ADVAPI32.@]
1173  *
1174  * PARAMS
1175  *   pDescr   []
1176  *   revision []
1177  */
1178 BOOL WINAPI
1179 InitializeSecurityDescriptor( PSECURITY_DESCRIPTOR pDescr, DWORD revision )
1180 {
1181         return set_ntstatus( RtlCreateSecurityDescriptor(pDescr, revision ));
1182 }
1183 
1184 
1185 /******************************************************************************
1186  * MakeAbsoluteSD [ADVAPI32.@]
1187  */
1188 BOOL WINAPI MakeAbsoluteSD (
1189         IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,
1190         OUT PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor,
1191         OUT LPDWORD lpdwAbsoluteSecurityDescriptorSize,
1192         OUT PACL pDacl,
1193         OUT LPDWORD lpdwDaclSize,
1194         OUT PACL pSacl,
1195         OUT LPDWORD lpdwSaclSize,
1196         OUT PSID pOwner,
1197         OUT LPDWORD lpdwOwnerSize,
1198         OUT PSID pPrimaryGroup,
1199         OUT LPDWORD lpdwPrimaryGroupSize)
1200 {
1201     return set_ntstatus( RtlSelfRelativeToAbsoluteSD(pSelfRelativeSecurityDescriptor,
1202                                                      pAbsoluteSecurityDescriptor,
1203                                                      lpdwAbsoluteSecurityDescriptorSize,
1204                                                      pDacl, lpdwDaclSize, pSacl, lpdwSaclSize,
1205                                                      pOwner, lpdwOwnerSize,
1206                                                      pPrimaryGroup, lpdwPrimaryGroupSize));
1207 }
1208 
1209 /******************************************************************************
1210  * GetKernelObjectSecurity [ADVAPI32.@]
1211  */
1212 BOOL WINAPI GetKernelObjectSecurity(
1213         HANDLE Handle,
1214         SECURITY_INFORMATION RequestedInformation,
1215         PSECURITY_DESCRIPTOR pSecurityDescriptor,
1216         DWORD nLength,
1217         LPDWORD lpnLengthNeeded )
1218 {
1219     TRACE("(%p,0x%08x,%p,0x%08x,%p)\n", Handle, RequestedInformation,
1220           pSecurityDescriptor, nLength, lpnLengthNeeded);
1221 
1222     return set_ntstatus( NtQuerySecurityObject(Handle, RequestedInformation, pSecurityDescriptor,
1223                                                nLength, lpnLengthNeeded ));
1224 }
1225 
1226 /******************************************************************************
1227  * GetPrivateObjectSecurity [ADVAPI32.@]
1228  */
1229 BOOL WINAPI GetPrivateObjectSecurity(
1230         PSECURITY_DESCRIPTOR ObjectDescriptor,
1231         SECURITY_INFORMATION SecurityInformation,
1232         PSECURITY_DESCRIPTOR ResultantDescriptor,
1233         DWORD DescriptorLength,
1234         PDWORD ReturnLength )
1235 {
1236     SECURITY_DESCRIPTOR desc;
1237     BOOL defaulted, present;
1238     PACL pacl;
1239     PSID psid;
1240 
1241     TRACE("(%p,0x%08x,%p,0x%08x,%p)\n", ObjectDescriptor, SecurityInformation,
1242           ResultantDescriptor, DescriptorLength, ReturnLength);
1243 
1244     if (!InitializeSecurityDescriptor(&desc, SECURITY_DESCRIPTOR_REVISION))
1245         return FALSE;
1246 
1247     if (SecurityInformation & OWNER_SECURITY_INFORMATION)
1248     {
1249         if (!GetSecurityDescriptorOwner(ObjectDescriptor, &psid, &defaulted))
1250             return FALSE;
1251         SetSecurityDescriptorOwner(&desc, psid, defaulted);
1252     }
1253 
1254     if (SecurityInformation & GROUP_SECURITY_INFORMATION)
1255     {
1256         if (!GetSecurityDescriptorGroup(ObjectDescriptor, &psid, &defaulted))
1257             return FALSE;
1258         SetSecurityDescriptorGroup(&desc, psid, defaulted);
1259     }
1260 
1261     if (SecurityInformation & DACL_SECURITY_INFORMATION)
1262     {
1263         if (!GetSecurityDescriptorDacl(ObjectDescriptor, &present, &pacl, &defaulted))
1264             return FALSE;
1265         SetSecurityDescriptorDacl(&desc, present, pacl, defaulted);
1266     }
1267 
1268     if (SecurityInformation & SACL_SECURITY_INFORMATION)
1269     {
1270         if (!GetSecurityDescriptorSacl(ObjectDescriptor, &present, &pacl, &defaulted))
1271             return FALSE;
1272         SetSecurityDescriptorSacl(&desc, present, pacl, defaulted);
1273     }
1274 
1275     *ReturnLength = DescriptorLength;
1276     return MakeSelfRelativeSD(&desc, ResultantDescriptor, ReturnLength);
1277 }
1278 
1279 /******************************************************************************
1280  * GetSecurityDescriptorLength [ADVAPI32.@]
1281  */
1282 DWORD WINAPI GetSecurityDescriptorLength( PSECURITY_DESCRIPTOR pDescr)
1283 {
1284         return RtlLengthSecurityDescriptor(pDescr);
1285 }
1286 
1287 /******************************************************************************
1288  * GetSecurityDescriptorOwner [ADVAPI32.@]
1289  *
1290  * PARAMS
1291  *   pOwner            []
1292  *   lpbOwnerDefaulted []
1293  */
1294 BOOL WINAPI
1295 GetSecurityDescriptorOwner( PSECURITY_DESCRIPTOR pDescr, PSID *pOwner,
1296                             LPBOOL lpbOwnerDefaulted )
1297 {
1298     BOOLEAN defaulted;
1299     BOOL ret = set_ntstatus( RtlGetOwnerSecurityDescriptor( pDescr, pOwner, &defaulted ));
1300     *lpbOwnerDefaulted = defaulted;
1301     return ret;
1302 }
1303 
1304 /******************************************************************************
1305  * SetSecurityDescriptorOwner [ADVAPI32.@]
1306  *
1307  * PARAMS
1308  */
1309 BOOL WINAPI SetSecurityDescriptorOwner( PSECURITY_DESCRIPTOR pSecurityDescriptor,
1310                                    PSID pOwner, BOOL bOwnerDefaulted)
1311 {
1312     return set_ntstatus( RtlSetOwnerSecurityDescriptor(pSecurityDescriptor, pOwner, bOwnerDefaulted));
1313 }
1314 /******************************************************************************
1315  * GetSecurityDescriptorGroup                   [ADVAPI32.@]
1316  */
1317 BOOL WINAPI GetSecurityDescriptorGroup(
1318         PSECURITY_DESCRIPTOR SecurityDescriptor,
1319         PSID *Group,
1320         LPBOOL GroupDefaulted)
1321 {
1322     BOOLEAN defaulted;
1323     BOOL ret = set_ntstatus( RtlGetGroupSecurityDescriptor(SecurityDescriptor, Group, &defaulted ));
1324     *GroupDefaulted = defaulted;
1325     return ret;
1326 }
1327 /******************************************************************************
1328  * SetSecurityDescriptorGroup [ADVAPI32.@]
1329  */
1330 BOOL WINAPI SetSecurityDescriptorGroup ( PSECURITY_DESCRIPTOR SecurityDescriptor,
1331                                            PSID Group, BOOL GroupDefaulted)
1332 {
1333     return set_ntstatus( RtlSetGroupSecurityDescriptor( SecurityDescriptor, Group, GroupDefaulted));
1334 }
1335 
1336 /******************************************************************************
1337  * IsValidSecurityDescriptor [ADVAPI32.@]
1338  *
1339  * PARAMS
1340  *   lpsecdesc []
1341  */
1342 BOOL WINAPI
1343 IsValidSecurityDescriptor( PSECURITY_DESCRIPTOR SecurityDescriptor )
1344 {
1345     return set_ntstatus( RtlValidSecurityDescriptor(SecurityDescriptor));
1346 }
1347 
1348 /******************************************************************************
1349  *  GetSecurityDescriptorDacl                   [ADVAPI32.@]
1350  */
1351 BOOL WINAPI GetSecurityDescriptorDacl(
1352         IN PSECURITY_DESCRIPTOR pSecurityDescriptor,
1353         OUT LPBOOL lpbDaclPresent,
1354         OUT PACL *pDacl,
1355         OUT LPBOOL lpbDaclDefaulted)
1356 {
1357     BOOLEAN present, defaulted;
1358     BOOL ret = set_ntstatus( RtlGetDaclSecurityDescriptor(pSecurityDescriptor, &present, pDacl, &defaulted));
1359     *lpbDaclPresent = present;
1360     *lpbDaclDefaulted = defaulted;
1361     return ret;
1362 }
1363 
1364 /******************************************************************************
1365  *  SetSecurityDescriptorDacl                   [ADVAPI32.@]
1366  */
1367 BOOL WINAPI
1368 SetSecurityDescriptorDacl (
1369         PSECURITY_DESCRIPTOR lpsd,
1370         BOOL daclpresent,
1371         PACL dacl,
1372         BOOL dacldefaulted )
1373 {
1374     return set_ntstatus( RtlSetDaclSecurityDescriptor (lpsd, daclpresent, dacl, dacldefaulted ) );
1375 }
1376 /******************************************************************************
1377  *  GetSecurityDescriptorSacl                   [ADVAPI32.@]
1378  */
1379 BOOL WINAPI GetSecurityDescriptorSacl(
1380         IN PSECURITY_DESCRIPTOR lpsd,
1381         OUT LPBOOL lpbSaclPresent,
1382         OUT PACL *pSacl,
1383         OUT LPBOOL lpbSaclDefaulted)
1384 {
1385     BOOLEAN present, defaulted;
1386     BOOL ret = set_ntstatus( RtlGetSaclSecurityDescriptor(lpsd, &present, pSacl, &defaulted) );
1387     *lpbSaclPresent = present;
1388     *lpbSaclDefaulted = defaulted;
1389     return ret;
1390 }
1391 
1392 /**************************************************************************
1393  * SetSecurityDescriptorSacl                    [ADVAPI32.@]
1394  */
1395 BOOL WINAPI SetSecurityDescriptorSacl (
1396         PSECURITY_DESCRIPTOR lpsd,
1397         BOOL saclpresent,
1398         PACL lpsacl,
1399         BOOL sacldefaulted)
1400 {
1401     return set_ntstatus (RtlSetSaclSecurityDescriptor(lpsd, saclpresent, lpsacl, sacldefaulted));
1402 }
1403 /******************************************************************************
1404  * MakeSelfRelativeSD [ADVAPI32.@]
1405  *
1406  * PARAMS
1407  *   lpabssecdesc  []
1408  *   lpselfsecdesc []
1409  *   lpbuflen      []
1410  */
1411 BOOL WINAPI
1412 MakeSelfRelativeSD(
1413         IN PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor,
1414         IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,
1415         IN OUT LPDWORD lpdwBufferLength)
1416 {
1417     return set_ntstatus( RtlMakeSelfRelativeSD( pAbsoluteSecurityDescriptor,
1418                                                 pSelfRelativeSecurityDescriptor, lpdwBufferLength));
1419 }
1420 
1421 /******************************************************************************
1422  * GetSecurityDescriptorControl                 [ADVAPI32.@]
1423  */
1424 
1425 BOOL WINAPI GetSecurityDescriptorControl ( PSECURITY_DESCRIPTOR  pSecurityDescriptor,
1426                  PSECURITY_DESCRIPTOR_CONTROL pControl, LPDWORD lpdwRevision)
1427 {
1428     return set_ntstatus( RtlGetControlSecurityDescriptor(pSecurityDescriptor,pControl,lpdwRevision));
1429 }
1430 
1431 /******************************************************************************
1432  * SetSecurityDescriptorControl                 [ADVAPI32.@]
1433  */
1434 BOOL WINAPI SetSecurityDescriptorControl( PSECURITY_DESCRIPTOR pSecurityDescriptor,
1435   SECURITY_DESCRIPTOR_CONTROL ControlBitsOfInterest,
1436   SECURITY_DESCRIPTOR_CONTROL ControlBitsToSet )
1437 {
1438     return set_ntstatus( RtlSetControlSecurityDescriptor(
1439         pSecurityDescriptor, ControlBitsOfInterest, ControlBitsToSet ) );
1440 }
1441 
1442 /*      ##############################
1443         ######  ACL FUNCTIONS   ######
1444         ##############################
1445 */
1446 
1447 /*************************************************************************
1448  * InitializeAcl [ADVAPI32.@]
1449  */
1450 BOOL WINAPI InitializeAcl(PACL acl, DWORD size, DWORD rev)
1451 {
1452     return set_ntstatus( RtlCreateAcl(acl, size, rev));
1453 }
1454 
1455 BOOL WINAPI ImpersonateNamedPipeClient( HANDLE hNamedPipe )
1456 {
1457     IO_STATUS_BLOCK io_block;
1458 
1459     TRACE("(%p)\n", hNamedPipe);
1460 
1461     return set_ntstatus( NtFsControlFile(hNamedPipe, NULL, NULL, NULL,
1462                          &io_block, FSCTL_PIPE_IMPERSONATE, NULL, 0, NULL, 0) );
1463 }
1464 
1465 /******************************************************************************
1466  *  AddAccessAllowedAce [ADVAPI32.@]
1467  */
1468 BOOL WINAPI AddAccessAllowedAce(
1469         IN OUT PACL pAcl,
1470         IN DWORD dwAceRevision,
1471         IN DWORD AccessMask,
1472         IN PSID pSid)
1473 {
1474     return set_ntstatus(RtlAddAccessAllowedAce(pAcl, dwAceRevision, AccessMask, pSid));
1475 }
1476 
1477 /******************************************************************************
1478  *  AddAccessAllowedAceEx [ADVAPI32.@]
1479  */
1480 BOOL WINAPI AddAccessAllowedAceEx(
1481         IN OUT PACL pAcl,
1482         IN DWORD dwAceRevision,
1483         IN DWORD AceFlags,
1484         IN DWORD AccessMask,
1485         IN PSID pSid)
1486 {
1487     return set_ntstatus(RtlAddAccessAllowedAceEx(pAcl, dwAceRevision, AceFlags, AccessMask, pSid));
1488 }
1489 
1490 /******************************************************************************
1491  *  AddAccessDeniedAce [ADVAPI32.@]
1492  */
1493 BOOL WINAPI AddAccessDeniedAce(
1494         IN OUT PACL pAcl,
1495         IN DWORD dwAceRevision,
1496         IN DWORD AccessMask,
1497         IN PSID pSid)
1498 {
1499     return set_ntstatus(RtlAddAccessDeniedAce(pAcl, dwAceRevision, AccessMask, pSid));
1500 }
1501 
1502 /******************************************************************************
1503  *  AddAccessDeniedAceEx [ADVAPI32.@]
1504  */
1505 BOOL WINAPI AddAccessDeniedAceEx(
1506         IN OUT PACL pAcl,
1507         IN DWORD dwAceRevision,
1508         IN DWORD AceFlags,
1509         IN DWORD AccessMask,
1510         IN PSID pSid)
1511 {
1512     return set_ntstatus(RtlAddAccessDeniedAceEx(pAcl, dwAceRevision, AceFlags, AccessMask, pSid));
1513 }
1514 
1515 /******************************************************************************
1516  *  AddAce [ADVAPI32.@]
1517  */
1518 BOOL WINAPI AddAce(
1519         IN OUT PACL pAcl,
1520         IN DWORD dwAceRevision,
1521         IN DWORD dwStartingAceIndex,
1522         LPVOID pAceList,
1523         DWORD nAceListLength)
1524 {
1525     return set_ntstatus(RtlAddAce(pAcl, dwAceRevision, dwStartingAceIndex, pAceList, nAceListLength));
1526 }
1527 
1528 /******************************************************************************
1529  * DeleteAce [ADVAPI32.@]
1530  */
1531 BOOL WINAPI DeleteAce(PACL pAcl, DWORD dwAceIndex)
1532 {
1533     return set_ntstatus(RtlDeleteAce(pAcl, dwAceIndex));
1534 }
1535 
1536 /******************************************************************************
1537  *  FindFirstFreeAce [ADVAPI32.@]
1538  */
1539 BOOL WINAPI FindFirstFreeAce(IN PACL pAcl, LPVOID * pAce)
1540 {
1541         return RtlFirstFreeAce(pAcl, (PACE_HEADER *)pAce);
1542 }
1543 
1544 /******************************************************************************
1545  * GetAce [ADVAPI32.@]
1546  */
1547 BOOL WINAPI GetAce(PACL pAcl,DWORD dwAceIndex,LPVOID *pAce )
1548 {
1549     return set_ntstatus(RtlGetAce(pAcl, dwAceIndex, pAce));
1550 }
1551 
1552 /******************************************************************************
1553  * GetAclInformation [ADVAPI32.@]
1554  */
1555 BOOL WINAPI GetAclInformation(
1556   PACL pAcl,
1557   LPVOID pAclInformation,
1558   DWORD nAclInformationLength,
1559   ACL_INFORMATION_CLASS dwAclInformationClass)
1560 {
1561     return set_ntstatus(RtlQueryInformationAcl(pAcl, pAclInformation,
1562                                                nAclInformationLength, dwAclInformationClass));
1563 }
1564 
1565 /******************************************************************************
1566  *  IsValidAcl [ADVAPI32.@]
1567  */
1568 BOOL WINAPI IsValidAcl(IN PACL pAcl)
1569 {
1570         return RtlValidAcl(pAcl);
1571 }
1572 
1573 /*      ##############################
1574         ######  MISC FUNCTIONS  ######
1575         ##############################
1576 */
1577 
1578 /******************************************************************************
1579  * AllocateLocallyUniqueId [ADVAPI32.@]
1580  *
1581  * PARAMS
1582  *   lpLuid []
1583  */
1584 BOOL WINAPI AllocateLocallyUniqueId( PLUID lpLuid )
1585 {
1586     return set_ntstatus(NtAllocateLocallyUniqueId(lpLuid));
1587 }
1588 
1589 static const WCHAR SE_CREATE_TOKEN_NAME_W[] =
1590  { 'S','e','C','r','e','a','t','e','T','o','k','e','n','P','r','i','v','i','l','e','g','e',0 };
1591 static const WCHAR SE_ASSIGNPRIMARYTOKEN_NAME_W[] =
1592  { '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 };
1593 static const WCHAR SE_LOCK_MEMORY_NAME_W[] =
1594  { 'S','e','L','o','c','k','M','e','m','o','r','y','P','r','i','v','i','l','e','g','e',0 };
1595 static const WCHAR SE_INCREASE_QUOTA_NAME_W[] =
1596  { '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 };
1597 static const WCHAR SE_MACHINE_ACCOUNT_NAME_W[] =
1598  { '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 };
1599 static const WCHAR SE_TCB_NAME_W[] =
1600  { 'S','e','T','c','b','P','r','i','v','i','l','e','g','e',0 };
1601 static const WCHAR SE_SECURITY_NAME_W[] =
1602  { 'S','e','S','e','c','u','r','i','t','y','P','r','i','v','i','l','e','g','e',0 };
1603 static const WCHAR SE_TAKE_OWNERSHIP_NAME_W[] =
1604  { '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 };
1605 static const WCHAR SE_LOAD_DRIVER_NAME_W[] =
1606  { 'S','e','L','o','a','d','D','r','i','v','e','r','P','r','i','v','i','l','e','g','e',0 };
1607 static const WCHAR SE_SYSTEM_PROFILE_NAME_W[] =
1608  { '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 };
1609 static const WCHAR SE_SYSTEMTIME_NAME_W[] =
1610  { 'S','e','S','y','s','t','e','m','t','i','m','e','P','r','i','v','i','l','e','g','e',0 };
1611 static const WCHAR SE_PROF_SINGLE_PROCESS_NAME_W[] =
1612  { '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 };
1613 static const WCHAR SE_INC_BASE_PRIORITY_NAME_W[] =
1614  { '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 };
1615 static const WCHAR SE_CREATE_PAGEFILE_NAME_W[] =
1616  { '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 };
1617 static const WCHAR SE_CREATE_PERMANENT_NAME_W[] =
1618  { '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 };
1619 static const WCHAR SE_BACKUP_NAME_W[] =
1620  { 'S','e','B','a','c','k','u','p','P','r','i','v','i','l','e','g','e',0 };
1621 static const WCHAR SE_RESTORE_NAME_W[] =
1622  { 'S','e','R','e','s','t','o','r','e','P','r','i','v','i','l','e','g','e',0 };
1623 static const WCHAR SE_SHUTDOWN_NAME_W[] =
1624  { 'S','e','S','h','u','t','d','o','w','n','P','r','i','v','i','l','e','g','e',0 };
1625 static const WCHAR SE_DEBUG_NAME_W[] =
1626  { 'S','e','D','e','b','u','g','P','r','i','v','i','l','e','g','e',0 };
1627 static const WCHAR SE_AUDIT_NAME_W[] =
1628  { 'S','e','A','u','d','i','t','P','r','i','v','i','l','e','g','e',0 };
1629 static const WCHAR SE_SYSTEM_ENVIRONMENT_NAME_W[] =
1630  { '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 };
1631 static const WCHAR SE_CHANGE_NOTIFY_NAME_W[] =
1632  { 'S','e','C','h','a','n','g','e','N','o','t','i','f','y','P','r','i','v','i','l','e','g','e',0 };
1633 static const WCHAR SE_REMOTE_SHUTDOWN_NAME_W[] =
1634  { '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 };
1635 static const WCHAR SE_UNDOCK_NAME_W[] =
1636  { 'S','e','U','n','d','o','c','k','P','r','i','v','i','l','e','g','e',0 };
1637 static const WCHAR SE_SYNC_AGENT_NAME_W[] =
1638  { 'S','e','S','y','n','c','A','g','e','n','t','P','r','i','v','i','l','e','g','e',0 };
1639 static const WCHAR SE_ENABLE_DELEGATION_NAME_W[] =
1640  { '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 };
1641 static const WCHAR SE_MANAGE_VOLUME_NAME_W[] =
1642  { 'S','e','M','a','n','a','g','e','V','o','l','u','m','e','P','r','i','v','i','l','e','g','e',0 };
1643 static const WCHAR SE_IMPERSONATE_NAME_W[] =
1644  { 'S','e','I','m','p','e','r','s','o','n','a','t','e','P','r','i','v','i','l','e','g','e',0 };
1645 static const WCHAR SE_CREATE_GLOBAL_NAME_W[] =
1646  { 'S','e','C','r','e','a','t','e','G','l','o','b','a','l','P','r','i','v','i','l','e','g','e',0 };
1647 
1648 static const WCHAR * const WellKnownPrivNames[SE_MAX_WELL_KNOWN_PRIVILEGE + 1] =
1649 {
1650     NULL,
1651     NULL,
1652     SE_CREATE_TOKEN_NAME_W,
1653     SE_ASSIGNPRIMARYTOKEN_NAME_W,
1654     SE_LOCK_MEMORY_NAME_W,
1655     SE_INCREASE_QUOTA_NAME_W,
1656     SE_MACHINE_ACCOUNT_NAME_W,
1657     SE_TCB_NAME_W,
1658     SE_SECURITY_NAME_W,
1659     SE_TAKE_OWNERSHIP_NAME_W,
1660     SE_LOAD_DRIVER_NAME_W,
1661     SE_SYSTEM_PROFILE_NAME_W,
1662     SE_SYSTEMTIME_NAME_W,
1663     SE_PROF_SINGLE_PROCESS_NAME_W,
1664     SE_INC_BASE_PRIORITY_NAME_W,
1665     SE_CREATE_PAGEFILE_NAME_W,
1666     SE_CREATE_PERMANENT_NAME_W,
1667     SE_BACKUP_NAME_W,
1668     SE_RESTORE_NAME_W,
1669     SE_SHUTDOWN_NAME_W,
1670     SE_DEBUG_NAME_W,
1671     SE_AUDIT_NAME_W,
1672     SE_SYSTEM_ENVIRONMENT_NAME_W,
1673     SE_CHANGE_NOTIFY_NAME_W,
1674     SE_REMOTE_SHUTDOWN_NAME_W,
1675     SE_UNDOCK_NAME_W,
1676     SE_SYNC_AGENT_NAME_W,
1677     SE_ENABLE_DELEGATION_NAME_W,
1678     SE_MANAGE_VOLUME_NAME_W,
1679     SE_IMPERSONATE_NAME_W,
1680     SE_CREATE_GLOBAL_NAME_W,
1681 };
1682 
1683 /******************************************************************************
1684  * LookupPrivilegeValueW                        [ADVAPI32.@]
1685  *
1686  * See LookupPrivilegeValueA.
1687  */
1688 BOOL WINAPI
1689 LookupPrivilegeValueW( LPCWSTR lpSystemName, LPCWSTR lpName, PLUID lpLuid )
1690 {
1691     UINT i;
1692 
1693     TRACE("%s,%s,%p\n",debugstr_w(lpSystemName), debugstr_w(lpName), lpLuid);
1694 
1695     if (!ADVAPI_IsLocalComputer(lpSystemName))
1696     {
1697         SetLastError(RPC_S_SERVER_UNAVAILABLE);
1698         return FALSE;
1699     }
1700     if (!lpName)
1701     {
1702         SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1703         return FALSE;
1704     }
1705     for( i=SE_MIN_WELL_KNOWN_PRIVILEGE; i<=SE_MAX_WELL_KNOWN_PRIVILEGE; i++ )
1706     {
1707         if( !WellKnownPrivNames[i] )
1708             continue;
1709         if( strcmpiW( WellKnownPrivNames[i], lpName) )
1710             continue;
1711         lpLuid->LowPart = i;
1712         lpLuid->HighPart = 0;
1713         TRACE( "%s -> %08x-%08x\n",debugstr_w( lpSystemName ),
1714                lpLuid->HighPart, lpLuid->LowPart );
1715         return TRUE;
1716     }
1717     SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1718     return FALSE;
1719 }
1720 
1721 /******************************************************************************
1722  * LookupPrivilegeValueA                        [ADVAPI32.@]
1723  *
1724  * Retrieves LUID used on a system to represent the privilege name.
1725  *
1726  * PARAMS
1727  *  lpSystemName [I] Name of the system
1728  *  lpName       [I] Name of the privilege
1729  *  lpLuid       [O] Destination for the resulting LUID
1730  *
1731  * RETURNS
1732  *  Success: TRUE. lpLuid contains the requested LUID.
1733  *  Failure: FALSE.
1734  */
1735 BOOL WINAPI
1736 LookupPrivilegeValueA( LPCSTR lpSystemName, LPCSTR lpName, PLUID lpLuid )
1737 {
1738     UNICODE_STRING lpSystemNameW;
1739     UNICODE_STRING lpNameW;
1740     BOOL ret;
1741 
1742     RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW, lpSystemName);
1743     RtlCreateUnicodeStringFromAsciiz(&lpNameW,lpName);
1744     ret = LookupPrivilegeValueW(lpSystemNameW.Buffer, lpNameW.Buffer, lpLuid);
1745     RtlFreeUnicodeString(&lpNameW);
1746     RtlFreeUnicodeString(&lpSystemNameW);
1747     return ret;
1748 }
1749 
1750 BOOL WINAPI LookupPrivilegeDisplayNameA( LPCSTR lpSystemName, LPCSTR lpName, LPSTR lpDisplayName,
1751                                          LPDWORD cchDisplayName, LPDWORD lpLanguageId )
1752 {
1753     FIXME("%s %s %s %p %p - stub\n", debugstr_a(lpSystemName), debugstr_a(lpName),
1754           debugstr_a(lpDisplayName), cchDisplayName, lpLanguageId);
1755 
1756     return FALSE;
1757 }
1758 
1759 BOOL WINAPI LookupPrivilegeDisplayNameW( LPCWSTR lpSystemName, LPCWSTR lpName, LPWSTR lpDisplayName,
1760                                          LPDWORD cchDisplayName, LPDWORD lpLanguageId )
1761 {
1762     FIXME("%s %s %s %p %p - stub\n", debugstr_w(lpSystemName), debugstr_w(lpName),
1763           debugstr_w(lpDisplayName), cchDisplayName, lpLanguageId);
1764 
1765     return FALSE;
1766 }
1767 
1768 /******************************************************************************
1769  * LookupPrivilegeNameA                 [ADVAPI32.@]
1770  *
1771  * See LookupPrivilegeNameW.
1772  */
1773 BOOL WINAPI
1774 LookupPrivilegeNameA( LPCSTR lpSystemName, PLUID lpLuid, LPSTR lpName,
1775  LPDWORD cchName)
1776 {
1777     UNICODE_STRING lpSystemNameW;
1778     BOOL ret;
1779     DWORD wLen = 0;
1780 
1781     TRACE("%s %p %p %p\n", debugstr_a(lpSystemName), lpLuid, lpName, cchName);
1782 
1783     RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW, lpSystemName);
1784     ret = LookupPrivilegeNameW(lpSystemNameW.Buffer, lpLuid, NULL, &wLen);
1785     if (!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
1786     {
1787         LPWSTR lpNameW = HeapAlloc(GetProcessHeap(), 0, wLen * sizeof(WCHAR));
1788 
1789         ret = LookupPrivilegeNameW(lpSystemNameW.Buffer, lpLuid, lpNameW,
1790          &wLen);
1791         if (ret)
1792         {
1793             /* Windows crashes if cchName is NULL, so will I */
1794             unsigned int len = WideCharToMultiByte(CP_ACP, 0, lpNameW, -1, lpName,
1795              *cchName, NULL, NULL);
1796 
1797             if (len == 0)
1798             {
1799                 /* WideCharToMultiByte failed */
1800                 ret = FALSE;
1801             }
1802             else if (len > *cchName)
1803             {
1804                 *cchName = len;
1805                 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1806                 ret = FALSE;
1807             }
1808             else
1809             {
1810                 /* WideCharToMultiByte succeeded, output length needs to be
1811                  * length not including NULL terminator
1812                  */
1813                 *cchName = len - 1;
1814             }
1815         }
1816         HeapFree(GetProcessHeap(), 0, lpNameW);
1817     }
1818     RtlFreeUnicodeString(&lpSystemNameW);
1819     return ret;
1820 }
1821 
1822 /******************************************************************************
1823  * LookupPrivilegeNameW                 [ADVAPI32.@]
1824  *
1825  * Retrieves the privilege name referred to by the LUID lpLuid.
1826  *
1827  * PARAMS
1828  *  lpSystemName [I]   Name of the system
1829  *  lpLuid       [I]   Privilege value
1830  *  lpName       [O]   Name of the privilege
1831  *  cchName      [I/O] Number of characters in lpName.
1832  *
1833  * RETURNS
1834  *  Success: TRUE. lpName contains the name of the privilege whose value is
1835  *  *lpLuid.
1836  *  Failure: FALSE.
1837  *
1838  * REMARKS
1839  *  Only well-known privilege names (those defined in winnt.h) can be retrieved
1840  *  using this function.
1841  *  If the length of lpName is too small, on return *cchName will contain the
1842  *  number of WCHARs needed to contain the privilege, including the NULL
1843  *  terminator, and GetLastError will return ERROR_INSUFFICIENT_BUFFER.
1844  *  On success, *cchName will contain the number of characters stored in
1845  *  lpName, NOT including the NULL terminator.
1846  */
1847 BOOL WINAPI
1848 LookupPrivilegeNameW( LPCWSTR lpSystemName, PLUID lpLuid, LPWSTR lpName,
1849  LPDWORD cchName)
1850 {
1851     size_t privNameLen;
1852 
1853     TRACE("%s,%p,%p,%p\n",debugstr_w(lpSystemName), lpLuid, lpName, cchName);
1854 
1855     if (!ADVAPI_IsLocalComputer(lpSystemName))
1856     {
1857         SetLastError(RPC_S_SERVER_UNAVAILABLE);
1858         return FALSE;
1859     }
1860     if (lpLuid->HighPart || (lpLuid->LowPart < SE_MIN_WELL_KNOWN_PRIVILEGE ||
1861      lpLuid->LowPart > SE_MAX_WELL_KNOWN_PRIVILEGE))
1862     {
1863         SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1864         return FALSE;
1865     }
1866     privNameLen = strlenW(WellKnownPrivNames[lpLuid->LowPart]);
1867     /* Windows crashes if cchName is NULL, so will I */
1868     if (*cchName <= privNameLen)
1869     {
1870         *cchName = privNameLen + 1;
1871         SetLastError(ERROR_INSUFFICIENT_BUFFER);
1872         return FALSE;
1873     }
1874     else
1875     {
1876         strcpyW(lpName, WellKnownPrivNames[lpLuid->LowPart]);
1877         *cchName = privNameLen;
1878         return TRUE;
1879     }
1880 }
1881 
1882 /******************************************************************************
1883  * GetFileSecurityA [ADVAPI32.@]
1884  *
1885  * Obtains Specified information about the security of a file or directory.
1886  *
1887  * PARAMS
1888  *  lpFileName           [I] Name of the file to get info for
1889  *  RequestedInformation [I] SE_ flags from "winnt.h"
1890  *  pSecurityDescriptor  [O] Destination for security information
1891  *  nLength              [I] Length of pSecurityDescriptor
1892  *  lpnLengthNeeded      [O] Destination for length of returned security information
1893  *
1894  * RETURNS
1895  *  Success: TRUE. pSecurityDescriptor contains the requested information.
1896  *  Failure: FALSE. lpnLengthNeeded contains the required space to return the info. 
1897  *
1898  * NOTES
1899  *  The information returned is constrained by the callers access rights and
1900  *  privileges.
1901  */
1902 BOOL WINAPI
1903 GetFileSecurityA( LPCSTR lpFileName,
1904                     SECURITY_INFORMATION RequestedInformation,
1905                     PSECURITY_DESCRIPTOR pSecurityDescriptor,
1906                     DWORD nLength, LPDWORD lpnLengthNeeded )
1907 {
1908     DWORD len;
1909     BOOL r;
1910     LPWSTR name = NULL;
1911 
1912     if( lpFileName )
1913     {
1914         len = MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, NULL, 0 );
1915         name = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
1916         MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, name, len );
1917     }
1918 
1919     r = GetFileSecurityW( name, RequestedInformation, pSecurityDescriptor,
1920                           nLength, lpnLengthNeeded );
1921     HeapFree( GetProcessHeap(), 0, name );
1922 
1923     return r;
1924 }
1925 
1926 /******************************************************************************
1927  * GetFileSecurityW [ADVAPI32.@]
1928  *
1929  * See GetFileSecurityA.
1930  */
1931 BOOL WINAPI
1932 GetFileSecurityW( LPCWSTR lpFileName,
1933                     SECURITY_INFORMATION RequestedInformation,
1934                     PSECURITY_DESCRIPTOR pSecurityDescriptor,
1935                     DWORD nLength, LPDWORD lpnLengthNeeded )
1936 {
1937     HANDLE hfile;
1938     NTSTATUS status;
1939     DWORD access = 0;
1940 
1941     TRACE("(%s,%d,%p,%d,%p)\n", debugstr_w(lpFileName),
1942           RequestedInformation, pSecurityDescriptor,
1943           nLength, lpnLengthNeeded);
1944 
1945     if (RequestedInformation & (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|
1946                                 DACL_SECURITY_INFORMATION))
1947         access |= READ_CONTROL;
1948     if (RequestedInformation & SACL_SECURITY_INFORMATION)
1949         access |= ACCESS_SYSTEM_SECURITY;
1950 
1951     hfile = CreateFileW( lpFileName, access, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
1952                          NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0 );
1953     if ( hfile == INVALID_HANDLE_VALUE )
1954         return FALSE;
1955 
1956     status = NtQuerySecurityObject( hfile, RequestedInformation, pSecurityDescriptor,
1957                                     nLength, lpnLengthNeeded );
1958     CloseHandle( hfile );
1959     return set_ntstatus( status );
1960 }
1961 
1962 
1963 /******************************************************************************
1964  * LookupAccountSidA [ADVAPI32.@]
1965  */
1966 BOOL WINAPI
1967 LookupAccountSidA(
1968         IN LPCSTR system,
1969         IN PSID sid,
1970         OUT LPSTR account,
1971         IN OUT LPDWORD accountSize,
1972         OUT LPSTR domain,
1973         IN OUT LPDWORD domainSize,
1974         OUT PSID_NAME_USE name_use )
1975 {
1976     DWORD len;
1977     BOOL r;
1978     LPWSTR systemW = NULL;
1979     LPWSTR accountW = NULL;
1980     LPWSTR domainW = NULL;
1981     DWORD accountSizeW = *accountSize;
1982     DWORD domainSizeW = *domainSize;
1983 
1984     if (system) {
1985         len = MultiByteToWideChar( CP_ACP, 0, system, -1, NULL, 0 );
1986         systemW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
1987         MultiByteToWideChar( CP_ACP, 0, system, -1, systemW, len );
1988     }
1989     if (account)
1990         accountW = HeapAlloc( GetProcessHeap(), 0, accountSizeW * sizeof(WCHAR) );
1991     if (domain)
1992         domainW = HeapAlloc( GetProcessHeap(), 0, domainSizeW * sizeof(WCHAR) );
1993 
1994     r = LookupAccountSidW( systemW, sid, accountW, &accountSizeW, domainW, &domainSizeW, name_use );
1995 
1996     if (r) {
1997         if (accountW && *accountSize) {
1998             len = WideCharToMultiByte( CP_ACP, 0, accountW, -1, NULL, 0, NULL, NULL );
1999             WideCharToMultiByte( CP_ACP, 0, accountW, -1, account, len, NULL, NULL );
2000             *accountSize = len;
2001         } else
2002             *accountSize = accountSizeW + 1;
2003 
2004         if (domainW && *domainSize) {
2005             len = WideCharToMultiByte( CP_ACP, 0, domainW, -1, NULL, 0, NULL, NULL );
2006             WideCharToMultiByte( CP_ACP, 0, domainW, -1, domain, len, NULL, NULL );
2007             *domainSize = len;
2008         } else
2009             *domainSize = domainSizeW + 1;
2010     }
2011 
2012     HeapFree( GetProcessHeap(), 0, systemW );
2013     HeapFree( GetProcessHeap(), 0, accountW );
2014     HeapFree( GetProcessHeap(), 0, domainW );
2015 
2016     return r;
2017 }
2018 
2019 /******************************************************************************
2020  * LookupAccountSidW [ADVAPI32.@]
2021  *
2022  * PARAMS
2023  *   system      []
2024  *   sid         []
2025  *   account     []
2026  *   accountSize []
2027  *   domain      []
2028  *   domainSize  []
2029  *   name_use    []
2030  */
2031 
2032 BOOL WINAPI
2033 LookupAccountSidW(
2034         IN LPCWSTR system,
2035         IN PSID sid,
2036         OUT LPWSTR account,
2037         IN OUT LPDWORD accountSize,
2038         OUT LPWSTR domain,
2039         IN OUT LPDWORD domainSize,
2040         OUT PSID_NAME_USE name_use )
2041 {
2042     unsigned int i, j;
2043     const WCHAR * ac = NULL;
2044     const WCHAR * dm = NULL;
2045     SID_NAME_USE use = 0;
2046     LPWSTR computer_name = NULL;
2047     LPWSTR account_name = NULL;
2048 
2049     TRACE("(%s,sid=%s,%p,%p(%u),%p,%p(%u),%p)\n",
2050           debugstr_w(system),debugstr_sid(sid),
2051           account,accountSize,accountSize?*accountSize:0,
2052           domain,domainSize,domainSize?*domainSize:0,
2053           name_use);
2054 
2055     if (!ADVAPI_IsLocalComputer(system)) {
2056         FIXME("Only local computer supported!\n");
2057         SetLastError(RPC_S_SERVER_UNAVAILABLE);
2058         return FALSE;
2059     }
2060 
2061     /* check the well known SIDs first */
2062     for (i = 0; i <= 60; i++) {
2063         if (IsWellKnownSid(sid, i)) {
2064             for (j = 0; j < (sizeof(ACCOUNT_SIDS) / sizeof(ACCOUNT_SIDS[0])); j++) {
2065                 if (ACCOUNT_SIDS[j].type == i) {
2066                     ac = ACCOUNT_SIDS[j].account;
2067                     dm = ACCOUNT_SIDS[j].domain;
2068                     use = ACCOUNT_SIDS[j].name_use;
2069                 }
2070             }
2071             break;
2072         }
2073     }
2074 
2075     if (dm == NULL) {
2076         MAX_SID local;
2077 
2078         /* check for the local computer next */
2079         if (ADVAPI_GetComputerSid(&local)) {
2080             DWORD size = MAX_COMPUTERNAME_LENGTH + 1;
2081             BOOL result;
2082 
2083             computer_name = HeapAlloc(GetProcessHeap(), 0, size * sizeof(WCHAR));
2084             result = GetComputerNameW(computer_name,  &size);
2085 
2086             if (result) {
2087                 if (EqualSid(sid, &local)) {
2088                     dm = computer_name;
2089                     ac = Blank;
2090                     use = 3;
2091                 } else {
2092                     local.SubAuthorityCount++;
2093 
2094                     if (EqualPrefixSid(sid, &local)) {
2095                         dm = computer_name;
2096                         use = 1;
2097                         switch (((MAX_SID *)sid)->SubAuthority[4]) {
2098                         case DOMAIN_USER_RID_ADMIN:
2099                             ac = Administrator;
2100                             break;
2101                         case DOMAIN_USER_RID_GUEST:
2102                             ac = Guest;
2103                             break;
2104                         case DOMAIN_GROUP_RID_ADMINS:
2105                             ac = Domain_Admins;
2106                             break;
2107                         case DOMAIN_GROUP_RID_USERS:
2108                             ac = Domain_Users;
2109                             break;
2110                         case DOMAIN_GROUP_RID_GUESTS:
2111                             ac = Domain_Guests;
2112                             break;
2113                         case DOMAIN_GROUP_RID_COMPUTERS:
2114                             ac = Domain_Computers;
2115                             break;
2116                         case DOMAIN_GROUP_RID_CONTROLLERS:
2117                             ac = Domain_Controllers;
2118                             break;
2119                         case DOMAIN_GROUP_RID_CERT_ADMINS:
2120                             ac = Cert_Publishers;
2121                             break;
2122                         case DOMAIN_GROUP_RID_SCHEMA_ADMINS:
2123                             ac = Schema_Admins;
2124                             break;
2125                         case DOMAIN_GROUP_RID_ENTERPRISE_ADMINS:
2126                             ac = Enterprise_Admins;
2127                             break;
2128                         case DOMAIN_GROUP_RID_POLICY_ADMINS:
2129                             ac = Group_Policy_Creator_Owners;
2130                             break;
2131                         case DOMAIN_ALIAS_RID_RAS_SERVERS:
2132                             ac = RAS_and_IAS_Servers;
2133                             break;
2134                         case 1000:      /* first user account */
2135                             size = UNLEN + 1;
2136                             account_name = HeapAlloc(
2137                                 GetProcessHeap(), 0, size * sizeof(WCHAR));
2138                             if (GetUserNameW(account_name, &size))
2139                                 ac = account_name;
2140                             else
2141                                 dm = NULL;
2142 
2143                             break;
2144                         default:
2145                             dm = NULL;
2146                             break;
2147                         }
2148                     }
2149                 }
2150             }
2151         }
2152     }
2153 
2154     if (dm) {
2155         DWORD ac_len = lstrlenW(ac);
2156         DWORD dm_len = lstrlenW(dm);
2157         BOOL status = TRUE;
2158 
2159         if (*accountSize > ac_len) {
2160             if (account)
2161                 lstrcpyW(account, ac);
2162         }
2163         if (*domainSize > dm_len) {
2164             if (domain)
2165                 lstrcpyW(domain, dm);
2166         }
2167         if (((*accountSize != 0) && (*accountSize < ac_len)) ||
2168             ((*domainSize != 0) && (*domainSize < dm_len))) {
2169             SetLastError(ERROR_INSUFFICIENT_BUFFER);
2170             status = FALSE;
2171         }
2172         if (*domainSize)
2173             *domainSize = dm_len;
2174         else
2175             *domainSize = dm_len + 1;
2176         if (*accountSize)
2177             *accountSize = ac_len;
2178         else
2179             *accountSize = ac_len + 1;
2180         *name_use = use;
2181         HeapFree(GetProcessHeap(), 0, account_name);
2182         HeapFree(GetProcessHeap(), 0, computer_name);
2183         return status;
2184     }
2185 
2186     HeapFree(GetProcessHeap(), 0, account_name);
2187     HeapFree(GetProcessHeap(), 0, computer_name);
2188     SetLastError(ERROR_NONE_MAPPED);
2189     return FALSE;
2190 }
2191 
2192 /******************************************************************************
2193  * SetFileSecurityA [ADVAPI32.@]
2194  *
2195  * See SetFileSecurityW.
2196  */
2197 BOOL WINAPI SetFileSecurityA( LPCSTR lpFileName,
2198                                 SECURITY_INFORMATION RequestedInformation,
2199                                 PSECURITY_DESCRIPTOR pSecurityDescriptor)
2200 {
2201     DWORD len;
2202     BOOL r;
2203     LPWSTR name = NULL;
2204 
2205     if( lpFileName )
2206     {
2207         len = MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, NULL, 0 );
2208         name = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
2209         MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, name, len );
2210     }
2211 
2212     r = SetFileSecurityW( name, RequestedInformation, pSecurityDescriptor );
2213     HeapFree( GetProcessHeap(), 0, name );
2214 
2215     return r;
2216 }
2217 
2218 /******************************************************************************
2219  * SetFileSecurityW [ADVAPI32.@]
2220  *
2221  * Sets the security of a file or directory.
2222  *
2223  * PARAMS
2224  *   lpFileName           []
2225  *   RequestedInformation []
2226  *   pSecurityDescriptor  []
2227  *
2228  * RETURNS
2229  *  Success: TRUE.
2230  *  Failure: FALSE.
2231  */
2232 BOOL WINAPI
2233 SetFileSecurityW( LPCWSTR lpFileName,
2234                     SECURITY_INFORMATION RequestedInformation,
2235                     PSECURITY_DESCRIPTOR pSecurityDescriptor )
2236 {
2237     HANDLE file;
2238     DWORD access = 0;
2239     NTSTATUS status;
2240 
2241     TRACE("(%s, 0x%x, %p)\n", debugstr_w(lpFileName), RequestedInformation,
2242           pSecurityDescriptor );
2243 
2244     if (RequestedInformation & OWNER_SECURITY_INFORMATION ||
2245         RequestedInformation & GROUP_SECURITY_INFORMATION)
2246         access |= WRITE_OWNER;
2247     if (RequestedInformation & SACL_SECURITY_INFORMATION)
2248         access |= ACCESS_SYSTEM_SECURITY;
2249     if (RequestedInformation & DACL_SECURITY_INFORMATION)
2250         access |= WRITE_DAC;
2251 
2252     file = CreateFileW( lpFileName, access, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
2253                         NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL );
2254     if (file == INVALID_HANDLE_VALUE)
2255         return FALSE;
2256 
2257     status = NtSetSecurityObject( file, RequestedInformation, pSecurityDescriptor );
2258     CloseHandle( file );
2259     return set_ntstatus( status );
2260 }
2261 
2262 /******************************************************************************
2263  * QueryWindows31FilesMigration [ADVAPI32.@]
2264  *
2265  * PARAMS
2266  *   x1 []
2267  */
2268 BOOL WINAPI
2269 QueryWindows31FilesMigration( DWORD x1 )
2270 {
2271         FIXME("(%d):stub\n",x1);
2272         return TRUE;
2273 }
2274 
2275 /******************************************************************************
2276  * SynchronizeWindows31FilesAndWindowsNTRegistry [ADVAPI32.@]
2277  *
2278  * PARAMS
2279  *   x1 []
2280  *   x2 []
2281  *   x3 []
2282  *   x4 []
2283  */
2284 BOOL WINAPI
2285 SynchronizeWindows31FilesAndWindowsNTRegistry( DWORD x1, DWORD x2, DWORD x3,
2286                                                DWORD x4 )
2287 {
2288         FIXME("(0x%08x,0x%08x,0x%08x,0x%08x):stub\n",x1,x2,x3,x4);
2289         return TRUE;
2290 }
2291 
2292 /******************************************************************************
2293  * NotifyBootConfigStatus [ADVAPI32.@]
2294  *
2295  * PARAMS
2296  *   x1 []
2297  */
2298 BOOL WINAPI
2299 NotifyBootConfigStatus( BOOL x1 )
2300 {
2301         FIXME("(0x%08d):stub\n",x1);
2302         return 1;
2303 }
2304 
2305 /******************************************************************************
2306  * RevertToSelf [ADVAPI32.@]
2307  *
2308  * Ends the impersonation of a user.
2309  *
2310  * PARAMS
2311  *   void []
2312  *
2313  * RETURNS
2314  *  Success: TRUE.
2315  *  Failure: FALSE.
2316  */
2317 BOOL WINAPI
2318 RevertToSelf( void )
2319 {
2320     HANDLE Token = NULL;
2321     return set_ntstatus( NtSetInformationThread( GetCurrentThread(),
2322         ThreadImpersonationToken, &Token, sizeof(Token) ) );
2323 }
2324 
2325 /******************************************************************************
2326  * ImpersonateSelf [ADVAPI32.@]
2327  *
2328  * Makes an impersonation token that represents the process user and assigns
2329  * to the current thread.
2330  *
2331  * PARAMS
2332  *  ImpersonationLevel [I] Level at which to impersonate.
2333  *
2334  * RETURNS
2335  *  Success: TRUE.
2336  *  Failure: FALSE.
2337  */
2338 BOOL WINAPI
2339 ImpersonateSelf(SECURITY_IMPERSONATION_LEVEL ImpersonationLevel)
2340 {
2341     return set_ntstatus( RtlImpersonateSelf( ImpersonationLevel ) );
2342 }
2343 
2344 /******************************************************************************
2345  * ImpersonateLoggedOnUser [ADVAPI32.@]
2346  */
2347 BOOL WINAPI ImpersonateLoggedOnUser(HANDLE hToken)
2348 {
2349     DWORD size;
2350     NTSTATUS Status;
2351     HANDLE ImpersonationToken;
2352     TOKEN_TYPE Type;
2353     static BOOL warn = TRUE;
2354 
2355     if (warn)
2356     {
2357         FIXME( "(%p)\n", hToken );
2358         warn = FALSE;
2359     }
2360     if (!GetTokenInformation( hToken, TokenType, &Type,
2361                               sizeof(TOKEN_TYPE), &size ))
2362         return FALSE;
2363 
2364     if (Type == TokenPrimary)
2365     {
2366         OBJECT_ATTRIBUTES ObjectAttributes;
2367 
2368         InitializeObjectAttributes( &ObjectAttributes, NULL, 0, NULL, NULL );
2369 
2370         Status = NtDuplicateToken( hToken,
2371                                    TOKEN_IMPERSONATE | TOKEN_QUERY,
2372                                    &ObjectAttributes,
2373                                    SecurityImpersonation,
2374                                    TokenImpersonation,
2375                                    &ImpersonationToken );
2376         if (Status != STATUS_SUCCESS)
2377         {
2378             ERR( "NtDuplicateToken failed with error 0x%08x\n", Status );
2379             SetLastError( RtlNtStatusToDosError( Status ) );
2380             return FALSE;
2381         }
2382     }
2383     else
2384         ImpersonationToken = hToken;
2385 
2386     Status = NtSetInformationThread( GetCurrentThread(),
2387                                      ThreadImpersonationToken,
2388                                      &ImpersonationToken,
2389                                      sizeof(ImpersonationToken) );
2390 
2391     if (Type == TokenPrimary)
2392         NtClose( ImpersonationToken );
2393 
2394     if (Status != STATUS_SUCCESS)
2395     {
2396         ERR( "NtSetInformationThread failed with error 0x%08x\n", Status );
2397         SetLastError( RtlNtStatusToDosError( Status ) );
2398         return FALSE;
2399     }
2400 
2401     return TRUE;
2402 }
2403 
2404 /******************************************************************************
2405  * AccessCheck [ADVAPI32.@]
2406  */
2407 BOOL WINAPI
2408 AccessCheck(
2409         PSECURITY_DESCRIPTOR SecurityDescriptor,
2410         HANDLE ClientToken,
2411         DWORD DesiredAccess,
2412         PGENERIC_MAPPING GenericMapping,
2413         PPRIVILEGE_SET PrivilegeSet,
2414         LPDWORD PrivilegeSetLength,
2415         LPDWORD GrantedAccess,
2416         LPBOOL AccessStatus)
2417 {
2418     NTSTATUS access_status;
2419     BOOL ret = set_ntstatus( NtAccessCheck(SecurityDescriptor, ClientToken, DesiredAccess,
2420                                            GenericMapping, PrivilegeSet, PrivilegeSetLength,
2421                                            GrantedAccess, &access_status) );
2422     if (ret) *AccessStatus = set_ntstatus( access_status );
2423     return ret;
2424 }
2425 
2426 
2427 /******************************************************************************
2428  * AccessCheckByType [ADVAPI32.@]
2429  */
2430 BOOL WINAPI AccessCheckByType(
2431     PSECURITY_DESCRIPTOR pSecurityDescriptor, 
2432     PSID PrincipalSelfSid,
2433     HANDLE ClientToken, 
2434     DWORD DesiredAccess, 
2435     POBJECT_TYPE_LIST ObjectTypeList,
2436     DWORD ObjectTypeListLength,
2437     PGENERIC_MAPPING GenericMapping,
2438     PPRIVILEGE_SET PrivilegeSet,
2439     LPDWORD PrivilegeSetLength, 
2440     LPDWORD GrantedAccess,
2441     LPBOOL AccessStatus)
2442 {
2443         FIXME("stub\n");
2444 
2445         *AccessStatus = TRUE;
2446 
2447         return !*AccessStatus;
2448 }
2449 
2450 /******************************************************************************
2451  * MapGenericMask [ADVAPI32.@]
2452  *
2453  * Maps generic access rights into specific access rights according to the
2454  * supplied mapping.
2455  *
2456  * PARAMS
2457  *  AccessMask     [I/O] Access rights.
2458  *  GenericMapping [I] The mapping between generic and specific rights.
2459  *
2460  * RETURNS
2461  *  Nothing.
2462  */
2463 VOID WINAPI MapGenericMask( PDWORD AccessMask, PGENERIC_MAPPING GenericMapping )
2464 {
2465     RtlMapGenericMask( AccessMask, GenericMapping );
2466 }
2467 
2468 /*************************************************************************
2469  * SetKernelObjectSecurity [ADVAPI32.@]
2470  */
2471 BOOL WINAPI SetKernelObjectSecurity (
2472         IN HANDLE Handle,
2473         IN SECURITY_INFORMATION SecurityInformation,
2474         IN PSECURITY_DESCRIPTOR SecurityDescriptor )
2475 {
2476     return set_ntstatus (NtSetSecurityObject (Handle, SecurityInformation, SecurityDescriptor));
2477 }
2478 
2479 
2480 /******************************************************************************
2481  *  AddAuditAccessAce [ADVAPI32.@]
2482  */
2483 BOOL WINAPI AddAuditAccessAce(
2484     IN OUT PACL pAcl, 
2485     IN DWORD dwAceRevision, 
2486     IN DWORD dwAccessMask, 
2487     IN PSID pSid, 
2488     IN BOOL bAuditSuccess, 
2489     IN BOOL bAuditFailure) 
2490 {
2491     return set_ntstatus( RtlAddAuditAccessAce(pAcl, dwAceRevision, dwAccessMask, pSid, 
2492                                               bAuditSuccess, bAuditFailure) ); 
2493 }
2494 
2495 /******************************************************************************
2496  *  AddAuditAccessAce [ADVAPI32.@]
2497  */
2498 BOOL WINAPI AddAuditAccessAceEx(
2499     IN OUT PACL pAcl,
2500     IN DWORD dwAceRevision,
2501     IN DWORD dwAceFlags,
2502     IN DWORD dwAccessMask,
2503     IN PSID pSid,
2504     IN BOOL bAuditSuccess,
2505     IN BOOL bAuditFailure)
2506 {
2507     return set_ntstatus( RtlAddAuditAccessAceEx(pAcl, dwAceRevision, dwAceFlags, dwAccessMask, pSid,
2508                                               bAuditSuccess, bAuditFailure) );
2509 }
2510 
2511 /******************************************************************************
2512  * LookupAccountNameA [ADVAPI32.@]
2513  */
2514 BOOL WINAPI
2515 LookupAccountNameA(
2516         IN LPCSTR system,
2517         IN LPCSTR account,
2518         OUT PSID sid,
2519         OUT LPDWORD cbSid,
2520         LPSTR ReferencedDomainName,
2521         IN OUT LPDWORD cbReferencedDomainName,
2522         OUT PSID_NAME_USE name_use )
2523 {
2524     BOOL ret;
2525     UNICODE_STRING lpSystemW;
2526     UNICODE_STRING lpAccountW;
2527     LPWSTR lpReferencedDomainNameW = NULL;
2528 
2529     RtlCreateUnicodeStringFromAsciiz(&lpSystemW, system);
2530     RtlCreateUnicodeStringFromAsciiz(&lpAccountW, account);
2531 
2532     if (ReferencedDomainName)
2533         lpReferencedDomainNameW = HeapAlloc(GetProcessHeap(), 0, *cbReferencedDomainName * sizeof(WCHAR));
2534 
2535     ret = LookupAccountNameW(lpSystemW.Buffer, lpAccountW.Buffer, sid, cbSid, lpReferencedDomainNameW,
2536         cbReferencedDomainName, name_use);
2537 
2538     if (ret && lpReferencedDomainNameW)
2539     {
2540         WideCharToMultiByte(CP_ACP, 0, lpReferencedDomainNameW, -1,
2541             ReferencedDomainName, *cbReferencedDomainName+1, NULL, NULL);
2542     }
2543 
2544     RtlFreeUnicodeString(&lpSystemW);
2545     RtlFreeUnicodeString(&lpAccountW);
2546     HeapFree(GetProcessHeap(), 0, lpReferencedDomainNameW);
2547 
2548     return ret;
2549 }
2550 
2551 /******************************************************************************
2552  * lookup_user_account_name
2553  */
2554 static BOOL lookup_user_account_name(PSID Sid, PDWORD cbSid, LPWSTR ReferencedDomainName,
2555                                      LPDWORD cchReferencedDomainName, PSID_NAME_USE peUse )
2556 {
2557     /* Default implementation: Always return a default SID */
2558     SID_IDENTIFIER_AUTHORITY identifierAuthority = {SECURITY_NT_AUTHORITY};
2559     BOOL ret;
2560     PSID pSid;
2561     static const WCHAR dm[] = {'D','O','M','A','I','N',0};
2562     DWORD nameLen;
2563     LPCWSTR domainName;
2564 
2565     ret = AllocateAndInitializeSid(&identifierAuthority,
2566         2,
2567         SECURITY_BUILTIN_DOMAIN_RID,
2568         DOMAIN_ALIAS_RID_ADMINS,
2569         0, 0, 0, 0, 0, 0,
2570         &pSid);
2571 
2572     if (!ret)
2573        return FALSE;
2574 
2575     if (!RtlValidSid(pSid))
2576     {
2577        FreeSid(pSid);
2578        return FALSE;
2579     }
2580 
2581     if (Sid != NULL && (*cbSid >= GetLengthSid(pSid)))
2582        CopySid(*cbSid, Sid, pSid);
2583     if (*cbSid < GetLengthSid(pSid))
2584     {
2585        SetLastError(ERROR_INSUFFICIENT_BUFFER);
2586        ret = FALSE;
2587     }
2588     *cbSid = GetLengthSid(pSid);
2589 
2590     domainName = dm;
2591     nameLen = strlenW(domainName);
2592 
2593     if (*cchReferencedDomainName <= nameLen || !ret)
2594     {
2595         SetLastError(ERROR_INSUFFICIENT_BUFFER);
2596         nameLen += 1;
2597         ret = FALSE;
2598     }
2599     else if (ReferencedDomainName)
2600         strcpyW(ReferencedDomainName, domainName);
2601 
2602     *cchReferencedDomainName = nameLen;
2603 
2604     if (ret)
2605         *peUse = SidTypeUser;
2606 
2607     FreeSid(pSid);
2608 
2609     return ret;
2610 }
2611 
2612 /******************************************************************************
2613  * lookup_computer_account_name
2614  */
2615 static BOOL lookup_computer_account_name(PSID Sid, PDWORD cbSid, LPWSTR ReferencedDomainName,
2616                                          LPDWORD cchReferencedDomainName, PSID_NAME_USE peUse )
2617 {
2618     MAX_SID local;
2619     BOOL ret;
2620     static const WCHAR dm[] = {'D','O','M','A','I','N',0};
2621     DWORD nameLen;
2622     LPCWSTR domainName;
2623 
2624     if ((ret = ADVAPI_GetComputerSid(&local)))
2625     {
2626         if (Sid != NULL && (*cbSid >= GetLengthSid(&local)))
2627            CopySid(*cbSid, Sid, &local);
2628         if (*cbSid < GetLengthSid(&local))
2629         {
2630            SetLastError(ERROR_INSUFFICIENT_BUFFER);
2631            ret = FALSE;
2632         }
2633         *cbSid = GetLengthSid(&local);
2634     }
2635 
2636     domainName = dm;
2637     nameLen = strlenW(domainName);
2638 
2639     if (*cchReferencedDomainName <= nameLen || !ret)
2640     {
2641         SetLastError(ERROR_INSUFFICIENT_BUFFER);
2642         nameLen += 1;
2643         ret = FALSE;
2644     }
2645     else if (ReferencedDomainName)
2646         strcpyW(ReferencedDomainName, domainName);
2647 
2648     *cchReferencedDomainName = nameLen;
2649 
2650     if (ret)
2651         *peUse = SidTypeDomain;
2652 
2653     return ret;
2654 }
2655 
2656 /******************************************************************************
2657  * LookupAccountNameW [ADVAPI32.@]
2658  */
2659 BOOL WINAPI LookupAccountNameW( LPCWSTR lpSystemName, LPCWSTR lpAccountName, PSID Sid,
2660                                 LPDWORD cbSid, LPWSTR ReferencedDomainName,
2661                                 LPDWORD cchReferencedDomainName, PSID_NAME_USE peUse )
2662 {
2663     BOOL ret;
2664     PSID pSid;
2665     unsigned int i;
2666     DWORD nameLen;
2667     LPWSTR userName = NULL;
2668     LPCWSTR domainName;
2669     LPCWSTR lpAccountNamePtr;
2670     LPCWSTR lpDomainNamePtr = NULL;
2671 
2672     FIXME("%s %s %p %p %p %p %p - stub\n", debugstr_w(lpSystemName), debugstr_w(lpAccountName),
2673           Sid, cbSid, ReferencedDomainName, cchReferencedDomainName, peUse);
2674 
2675     if (!ADVAPI_IsLocalComputer(lpSystemName))
2676     {
2677         SetLastError(RPC_S_SERVER_UNAVAILABLE);
2678         return FALSE;
2679     }
2680 
2681     if (!lpAccountName || !strcmpW(lpAccountName, Blank))
2682     {
2683         lpAccountName = BUILTIN;
2684     }
2685 
2686     /* Check well known SIDs first */
2687     if ((lpAccountNamePtr = strrchrW(lpAccountName,'\\')))
2688     {
2689         lpAccountNamePtr++;
2690         lpDomainNamePtr = lpAccountName;
2691     }
2692     else
2693         lpAccountNamePtr = lpAccountName;
2694 
2695     for (i = 0; i < (sizeof(ACCOUNT_SIDS) / sizeof(ACCOUNT_SIDS[0])); i++)
2696     {
2697         /* check domain first */
2698         if (lpDomainNamePtr && (strncmpiW(lpDomainNamePtr, ACCOUNT_SIDS[i].domain, strlenW(ACCOUNT_SIDS[i].domain)) || lpDomainNamePtr[strlenW(ACCOUNT_SIDS[i].domain)]!='\\'))
2699             continue;
2700 
2701         if (!strcmpiW(lpAccountNamePtr, ACCOUNT_SIDS[i].account) ||
2702             (ACCOUNT_SIDS[i].alias && !strcmpiW(lpAccountNamePtr, ACCOUNT_SIDS[i].alias)))
2703         {
2704             DWORD sidLen = SECURITY_MAX_SID_SIZE;
2705 
2706             pSid = HeapAlloc(GetProcessHeap(), 0, sidLen);
2707 
2708             ret = CreateWellKnownSid(ACCOUNT_SIDS[i].type, NULL, pSid, &sidLen);
2709 
2710             if (ret)
2711             {
2712                 if (*cbSid < sidLen)
2713                 {
2714                     SetLastError(ERROR_INSUFFICIENT_BUFFER);
2715                     ret = FALSE;
2716                 }
2717                 else if (Sid)
2718                 {
2719                     CopySid(*cbSid, Sid, pSid);
2720                 }
2721 
2722                 *cbSid = sidLen;
2723             }
2724 
2725             domainName = ACCOUNT_SIDS[i].domain;
2726             nameLen = strlenW(domainName);
2727 
2728             if (*cchReferencedDomainName <= nameLen || !ret)
2729             {
2730                 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2731                 nameLen += 1;
2732                 ret = FALSE;
2733             }
2734             else if (ReferencedDomainName)
2735             {
2736                 strcpyW(ReferencedDomainName, domainName);
2737             }
2738 
2739             *cchReferencedDomainName = nameLen;
2740 
2741             if (ret)
2742             {
2743                 *peUse = ACCOUNT_SIDS[i].name_use;
2744             }
2745 
2746             HeapFree(GetProcessHeap(), 0, pSid);
2747 
2748             return ret;
2749         }
2750     }
2751 
2752     /* Let the current Unix user id masquerade as first Windows user account */
2753 
2754     nameLen = UNLEN + 1;
2755 
2756     userName = HeapAlloc(GetProcessHeap(), 0, nameLen*sizeof(WCHAR));
2757 
2758     if (lpDomainNamePtr)
2759     {
2760         /* check to make sure this account is on this computer */
2761         if (GetComputerNameW(userName, &nameLen) && strcmpW(lpDomainNamePtr, userName))
2762         {
2763             SetLastError(ERROR_NONE_MAPPED);
2764             ret = FALSE;
2765         }
2766         nameLen = UNLEN + 1;
2767     }
2768 
2769     if (GetUserNameW(userName, &nameLen) && !strcmpW(lpAccountNamePtr, userName))
2770         ret = lookup_user_account_name(Sid, cbSid, ReferencedDomainName,
2771                                        cchReferencedDomainName, peUse);
2772     else
2773     {
2774         nameLen = UNLEN + 1;
2775         if (GetComputerNameW(userName, &nameLen) && !strcmpW(lpAccountNamePtr, userName))
2776             ret = lookup_computer_account_name(Sid, cbSid, ReferencedDomainName,
2777                                                cchReferencedDomainName, peUse);
2778         else
2779         {
2780             SetLastError(ERROR_NONE_MAPPED);
2781             ret = FALSE;
2782         }
2783     }
2784 
2785     HeapFree(GetProcessHeap(), 0, userName);
2786 
2787     return ret;
2788 }
2789 
2790 /******************************************************************************
2791  * PrivilegeCheck [ADVAPI32.@]
2792  */
2793 BOOL WINAPI PrivilegeCheck( HANDLE ClientToken, PPRIVILEGE_SET RequiredPrivileges, LPBOOL pfResult)
2794 {
2795     BOOL ret;
2796     BOOLEAN Result;
2797 
2798     TRACE("%p %p %p\n", ClientToken, RequiredPrivileges, pfResult);
2799 
2800     ret = set_ntstatus (NtPrivilegeCheck (ClientToken, RequiredPrivileges, &Result));
2801     if (ret)
2802         *pfResult = Result;
2803     return ret;
2804 }
2805 
2806 /******************************************************************************
2807  * AccessCheckAndAuditAlarmA [ADVAPI32.@]
2808  */
2809 BOOL WINAPI AccessCheckAndAuditAlarmA(LPCSTR Subsystem, LPVOID HandleId, LPSTR ObjectTypeName,
2810   LPSTR ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD DesiredAccess,
2811   PGENERIC_MAPPING GenericMapping, BOOL ObjectCreation, LPDWORD GrantedAccess,
2812   LPBOOL AccessStatus, LPBOOL pfGenerateOnClose)
2813 {
2814         FIXME("stub (%s,%p,%s,%s,%p,%08x,%p,%x,%p,%p,%p)\n", debugstr_a(Subsystem),
2815                 HandleId, debugstr_a(ObjectTypeName), debugstr_a(ObjectName),
2816                 SecurityDescriptor, DesiredAccess, GenericMapping,
2817                 ObjectCreation, GrantedAccess, AccessStatus, pfGenerateOnClose);
2818         return TRUE;
2819 }
2820 
2821 /******************************************************************************
2822  * AccessCheckAndAuditAlarmW [ADVAPI32.@]
2823  */
2824 BOOL WINAPI AccessCheckAndAuditAlarmW(LPCWSTR Subsystem, LPVOID HandleId, LPWSTR ObjectTypeName,
2825   LPWSTR ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD DesiredAccess,
2826   PGENERIC_MAPPING GenericMapping, BOOL ObjectCreation, LPDWORD GrantedAccess,
2827   LPBOOL AccessStatus, LPBOOL pfGenerateOnClose)
2828 {
2829         FIXME("stub (%s,%p,%s,%s,%p,%08x,%p,%x,%p,%p,%p)\n", debugstr_w(Subsystem),
2830                 HandleId, debugstr_w(ObjectTypeName), debugstr_w(ObjectName),
2831                 SecurityDescriptor, DesiredAccess, GenericMapping,
2832                 ObjectCreation, GrantedAccess, AccessStatus, pfGenerateOnClose);
2833         return TRUE;
2834 }
2835 
2836 BOOL WINAPI ObjectCloseAuditAlarmA(LPCSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
2837 {
2838     FIXME("stub (%s,%p,%x)\n", debugstr_a(SubsystemName), HandleId, GenerateOnClose);
2839 
2840     return TRUE;
2841 }
2842 
2843 BOOL WINAPI ObjectCloseAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
2844 {
2845     FIXME("stub (%s,%p,%x)\n", debugstr_w(SubsystemName), HandleId, GenerateOnClose);
2846 
2847     return TRUE;
2848 }
2849 
2850 BOOL WINAPI ObjectDeleteAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
2851 {
2852     FIXME("stub (%s,%p,%x)\n", debugstr_w(SubsystemName), HandleId, GenerateOnClose);
2853 
2854     return TRUE;
2855 }
2856 
2857 BOOL WINAPI ObjectOpenAuditAlarmA(LPCSTR SubsystemName, LPVOID HandleId, LPSTR ObjectTypeName,
2858   LPSTR ObjectName, PSECURITY_DESCRIPTOR pSecurityDescriptor, HANDLE ClientToken, DWORD DesiredAccess,
2859   DWORD GrantedAccess, PPRIVILEGE_SET Privileges, BOOL ObjectCreation, BOOL AccessGranted,
2860   LPBOOL GenerateOnClose)
2861 {
2862         FIXME("stub (%s,%p,%s,%s,%p,%p,0x%08x,0x%08x,%p,%x,%x,%p)\n", debugstr_a(SubsystemName),
2863                 HandleId, debugstr_a(ObjectTypeName), debugstr_a(ObjectName), pSecurityDescriptor,
2864         ClientToken, DesiredAccess, GrantedAccess, Privileges, ObjectCreation, AccessGranted,
2865         GenerateOnClose);
2866 
2867     return TRUE;
2868 }
2869 
2870 BOOL WINAPI ObjectOpenAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, LPWSTR ObjectTypeName,
2871   LPWSTR ObjectName, PSECURITY_DESCRIPTOR pSecurityDescriptor, HANDLE ClientToken, DWORD DesiredAccess,
2872   DWORD GrantedAccess, PPRIVILEGE_SET Privileges, BOOL ObjectCreation, BOOL AccessGranted,
2873   LPBOOL GenerateOnClose)
2874 {
2875     FIXME("stub (%s,%p,%s,%s,%p,%p,0x%08x,0x%08x,%p,%x,%x,%p)\n", debugstr_w(SubsystemName),
2876         HandleId, debugstr_w(ObjectTypeName), debugstr_w(ObjectName), pSecurityDescriptor,
2877         ClientToken, DesiredAccess, GrantedAccess, Privileges, ObjectCreation, AccessGranted,
2878         GenerateOnClose);
2879 
2880     return TRUE;
2881 }
2882 
2883 BOOL WINAPI ObjectPrivilegeAuditAlarmA( LPCSTR SubsystemName, LPVOID HandleId, HANDLE ClientToken,
2884   DWORD DesiredAccess, PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2885 {
2886     FIXME("stub (%s,%p,%p,0x%08x,%p,%x)\n", debugstr_a(SubsystemName), HandleId, ClientToken,
2887           DesiredAccess, Privileges, AccessGranted);
2888 
2889     return TRUE;
2890 }
2891 
2892 BOOL WINAPI ObjectPrivilegeAuditAlarmW( LPCWSTR SubsystemName, LPVOID HandleId, HANDLE ClientToken,
2893   DWORD DesiredAccess, PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2894 {
2895     FIXME("stub (%s,%p,%p,0x%08x,%p,%x)\n", debugstr_w(SubsystemName), HandleId, ClientToken,
2896           DesiredAccess, Privileges, AccessGranted);
2897 
2898     return TRUE;
2899 }
2900 
2901 BOOL WINAPI PrivilegedServiceAuditAlarmA( LPCSTR SubsystemName, LPCSTR ServiceName, HANDLE ClientToken,
2902                                    PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2903 {
2904     FIXME("stub (%s,%s,%p,%p,%x)\n", debugstr_a(SubsystemName), debugstr_a(ServiceName),
2905           ClientToken, Privileges, AccessGranted);
2906 
2907     return TRUE;
2908 }
2909 
2910 BOOL WINAPI PrivilegedServiceAuditAlarmW( LPCWSTR SubsystemName, LPCWSTR ServiceName, HANDLE ClientToken,
2911                                    PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2912 {
2913     FIXME("stub %s,%s,%p,%p,%x)\n", debugstr_w(SubsystemName), debugstr_w(ServiceName),
2914           ClientToken, Privileges, AccessGranted);
2915 
2916     return TRUE;
2917 }
2918 
2919 /******************************************************************************
2920  * GetSecurityInfo [ADVAPI32.@]
2921  *
2922  * Retrieves a copy of the security descriptor associated with an object.
2923  *
2924  * PARAMS
2925  *  hObject              [I] A handle for the object.
2926  *  ObjectType           [I] The type of object.
2927  *  SecurityInfo         [I] A bitmask indicating what info to retrieve.
2928  *  ppsidOwner           [O] If non-null, receives a pointer to the owner SID.
2929  *  ppsidGroup           [O] If non-null, receives a pointer to the group SID.
2930  *  ppDacl               [O] If non-null, receives a pointer to the DACL.
2931  *  ppSacl               [O] If non-null, receives a pointer to the SACL.
2932  *  ppSecurityDescriptor [O] Receives a pointer to the security descriptor,
2933  *                           which must be freed with LocalFree.
2934  *
2935  * RETURNS
2936  *  ERROR_SUCCESS if all's well, and a WIN32 error code otherwise.
2937  */
2938 DWORD WINAPI GetSecurityInfo(
2939     HANDLE hObject, SE_OBJECT_TYPE ObjectType,
2940     SECURITY_INFORMATION SecurityInfo, PSID *ppsidOwner,
2941     PSID *ppsidGroup, PACL *ppDacl, PACL *ppSacl,
2942     PSECURITY_DESCRIPTOR *ppSecurityDescriptor
2943 )
2944 {
2945     PSECURITY_DESCRIPTOR sd;
2946     NTSTATUS status;
2947     ULONG n1, n2;
2948     BOOL present, defaulted;
2949 
2950     status = NtQuerySecurityObject(hObject, SecurityInfo, NULL, 0, &n1);
2951     if (status != STATUS_BUFFER_TOO_SMALL && status != STATUS_SUCCESS)
2952         return RtlNtStatusToDosError(status);
2953 
2954     sd = LocalAlloc(0, n1);
2955     if (!sd)
2956         return ERROR_NOT_ENOUGH_MEMORY;
2957 
2958     status = NtQuerySecurityObject(hObject, SecurityInfo, sd, n1, &n2);
2959     if (status != STATUS_SUCCESS)
2960     {
2961         LocalFree(sd);
2962         return RtlNtStatusToDosError(status);
2963     }
2964 
2965     if (ppsidOwner)
2966     {
2967         *ppsidOwner = NULL;
2968         GetSecurityDescriptorOwner(sd, ppsidOwner, &defaulted);
2969     }
2970     if (ppsidGroup)
2971     {
2972         *ppsidGroup = NULL;
2973         GetSecurityDescriptorGroup(sd, ppsidGroup, &defaulted);
2974     }
2975     if (ppDacl)
2976     {
2977         *ppDacl = NULL;
2978         GetSecurityDescriptorDacl(sd, &present, ppDacl, &defaulted);
2979     }
2980     if (ppSacl)
2981     {
2982         *ppSacl = NULL;
2983         GetSecurityDescriptorSacl(sd, &present, ppSacl, &defaulted);
2984     }
2985     if (ppSecurityDescriptor)
2986         *ppSecurityDescriptor = sd;
2987 
2988     return ERROR_SUCCESS;
2989 }
2990 
2991 /******************************************************************************
2992  * GetSecurityInfoExA [ADVAPI32.@]
2993  */
2994 DWORD WINAPI GetSecurityInfoExA(
2995         HANDLE hObject, SE_OBJECT_TYPE ObjectType,
2996         SECURITY_INFORMATION SecurityInfo, LPCSTR lpProvider,
2997         LPCSTR lpProperty, PACTRL_ACCESSA *ppAccessList,
2998         PACTRL_AUDITA *ppAuditList, LPSTR *lppOwner, LPSTR *lppGroup
2999 )
3000 {
3001   FIXME("stub!\n");
3002   return ERROR_BAD_PROVIDER;
3003 }
3004 
3005 /******************************************************************************
3006  * GetSecurityInfoExW [ADVAPI32.@]
3007  */
3008 DWORD WINAPI GetSecurityInfoExW(
3009         HANDLE hObject, SE_OBJECT_TYPE ObjectType, 
3010         SECURITY_INFORMATION SecurityInfo, LPCWSTR lpProvider,
3011         LPCWSTR lpProperty, PACTRL_ACCESSW *ppAccessList, 
3012         PACTRL_AUDITW *ppAuditList, LPWSTR *lppOwner, LPWSTR *lppGroup
3013 )
3014 {
3015   FIXME("stub!\n");
3016   return ERROR_BAD_PROVIDER; 
3017 }
3018 
3019 /******************************************************************************
3020  * BuildExplicitAccessWithNameA [ADVAPI32.@]
3021  */
3022 VOID WINAPI BuildExplicitAccessWithNameA( PEXPLICIT_ACCESSA pExplicitAccess,
3023                                           LPSTR pTrusteeName, DWORD AccessPermissions,
3024                                           ACCESS_MODE AccessMode, DWORD Inheritance )
3025 {
3026     TRACE("%p %s 0x%08x 0x%08x 0x%08x\n", pExplicitAccess, debugstr_a(pTrusteeName),
3027           AccessPermissions, AccessMode, Inheritance);
3028 
3029     pExplicitAccess->grfAccessPermissions = AccessPermissions;
3030     pExplicitAccess->grfAccessMode = AccessMode;
3031     pExplicitAccess->grfInheritance = Inheritance;
3032 
3033     pExplicitAccess->Trustee.pMultipleTrustee = NULL;
3034     pExplicitAccess->Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3035     pExplicitAccess->Trustee.TrusteeForm = TRUSTEE_IS_NAME;
3036     pExplicitAccess->Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
3037     pExplicitAccess->Trustee.ptstrName = pTrusteeName;
3038 }
3039 
3040 /******************************************************************************
3041  * BuildExplicitAccessWithNameW [ADVAPI32.@]
3042  */
3043 VOID WINAPI BuildExplicitAccessWithNameW( PEXPLICIT_ACCESSW pExplicitAccess,
3044                                           LPWSTR pTrusteeName, DWORD AccessPermissions,
3045                                           ACCESS_MODE AccessMode, DWORD Inheritance )
3046 {
3047     TRACE("%p %s 0x%08x 0x%08x 0x%08x\n", pExplicitAccess, debugstr_w(pTrusteeName),
3048           AccessPermissions, AccessMode, Inheritance);
3049 
3050     pExplicitAccess->grfAccessPermissions = AccessPermissions;
3051     pExplicitAccess->grfAccessMode = AccessMode;
3052     pExplicitAccess->grfInheritance = Inheritance;
3053 
3054     pExplicitAccess->Trustee.pMultipleTrustee = NULL;
3055     pExplicitAccess->Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3056     pExplicitAccess->Trustee.TrusteeForm = TRUSTEE_IS_NAME;
3057     pExplicitAccess->Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
3058     pExplicitAccess->Trustee.ptstrName = pTrusteeName;
3059 }
3060 
3061 /******************************************************************************
3062  * BuildTrusteeWithObjectsAndNameA [ADVAPI32.@]
3063  */
3064 VOID WINAPI BuildTrusteeWithObjectsAndNameA( PTRUSTEEA pTrustee, POBJECTS_AND_NAME_A pObjName,
3065                                              SE_OBJECT_TYPE ObjectType, LPSTR ObjectTypeName,
3066                                              LPSTR InheritedObjectTypeName, LPSTR Name )
3067 {
3068     DWORD ObjectsPresent = 0;
3069 
3070     TRACE("%p %p 0x%08x %p %p %s\n", pTrustee, pObjName,
3071           ObjectType, ObjectTypeName, InheritedObjectTypeName, debugstr_a(Name));
3072 
3073     /* Fill the OBJECTS_AND_NAME structure */
3074     pObjName->ObjectType = ObjectType;
3075     if (ObjectTypeName != NULL)
3076     {
3077         ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
3078     }
3079 
3080     pObjName->InheritedObjectTypeName = InheritedObjectTypeName;
3081     if (InheritedObjectTypeName != NULL)
3082     {
3083         ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3084     }
3085 
3086     pObjName->ObjectsPresent = ObjectsPresent;
3087     pObjName->ptstrName = Name;
3088 
3089     /* Fill the TRUSTEE structure */
3090     pTrustee->pMultipleTrustee = NULL;
3091     pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3092     pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_NAME;
3093     pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3094     pTrustee->ptstrName = (LPSTR)pObjName;
3095 }
3096 
3097 /******************************************************************************
3098  * BuildTrusteeWithObjectsAndNameW [ADVAPI32.@]
3099  */
3100 VOID WINAPI BuildTrusteeWithObjectsAndNameW( PTRUSTEEW pTrustee, POBJECTS_AND_NAME_W pObjName,
3101                                              SE_OBJECT_TYPE ObjectType, LPWSTR ObjectTypeName,
3102                                              LPWSTR InheritedObjectTypeName, LPWSTR Name )
3103 {
3104     DWORD ObjectsPresent = 0;
3105 
3106     TRACE("%p %p 0x%08x %p %p %s\n", pTrustee, pObjName,
3107           ObjectType, ObjectTypeName, InheritedObjectTypeName, debugstr_w(Name));
3108 
3109     /* Fill the OBJECTS_AND_NAME structure */
3110     pObjName->ObjectType = ObjectType;
3111     if (ObjectTypeName != NULL)
3112     {
3113         ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
3114     }
3115 
3116     pObjName->InheritedObjectTypeName = InheritedObjectTypeName;
3117     if (InheritedObjectTypeName != NULL)
3118     {
3119         ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3120     }
3121 
3122     pObjName->ObjectsPresent = ObjectsPresent;
3123     pObjName->ptstrName = Name;
3124 
3125     /* Fill the TRUSTEE structure */
3126     pTrustee->pMultipleTrustee = NULL;
3127     pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3128     pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_NAME;
3129     pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3130     pTrustee->ptstrName = (LPWSTR)pObjName;
3131 }
3132 
3133 /******************************************************************************
3134  * BuildTrusteeWithObjectsAndSidA [ADVAPI32.@]
3135  */
3136 VOID WINAPI BuildTrusteeWithObjectsAndSidA( PTRUSTEEA pTrustee, POBJECTS_AND_SID pObjSid,
3137                                             GUID* pObjectGuid, GUID* pInheritedObjectGuid, PSID pSid )
3138 {
3139     DWORD ObjectsPresent = 0;
3140 
3141     TRACE("%p %p %p %p %p\n", pTrustee, pObjSid, pObjectGuid, pInheritedObjectGuid, pSid);
3142 
3143     /* Fill the OBJECTS_AND_SID structure */
3144     if (pObjectGuid != NULL)
3145     {
3146         pObjSid->ObjectTypeGuid = *pObjectGuid;
3147         ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
3148     }
3149     else
3150     {
3151         ZeroMemory(&pObjSid->ObjectTypeGuid,
3152                    sizeof(GUID));
3153     }
3154 
3155     if (pInheritedObjectGuid != NULL)
3156     {
3157         pObjSid->InheritedObjectTypeGuid = *pInheritedObjectGuid;
3158         ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3159     }
3160     else
3161     {
3162         ZeroMemory(&pObjSid->InheritedObjectTypeGuid,
3163                    sizeof(GUID));
3164     }
3165 
3166     pObjSid->ObjectsPresent = ObjectsPresent;
3167     pObjSid->pSid = pSid;
3168 
3169     /* Fill the TRUSTEE structure */
3170     pTrustee->pMultipleTrustee = NULL;
3171     pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3172     pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_SID;
3173     pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3174     pTrustee->ptstrName = (LPSTR) pObjSid;
3175 }
3176 
3177 /******************************************************************************
3178  * BuildTrusteeWithObjectsAndSidW [ADVAPI32.@]
3179  */
3180 VOID WINAPI BuildTrusteeWithObjectsAndSidW( PTRUSTEEW pTrustee, POBJECTS_AND_SID pObjSid,
3181                                             GUID* pObjectGuid, GUID* pInheritedObjectGuid, PSID pSid )
3182 {
3183     DWORD ObjectsPresent = 0;
3184 
3185     TRACE("%p %p %p %p %p\n", pTrustee, pObjSid, pObjectGuid, pInheritedObjectGuid, pSid);
3186 
3187     /* Fill the OBJECTS_AND_SID structure */
3188     if (pObjectGuid != NULL)
3189     {
3190         pObjSid->ObjectTypeGuid = *pObjectGuid;
3191         ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
3192     }
3193     else
3194     {
3195         ZeroMemory(&pObjSid->ObjectTypeGuid,
3196                    sizeof(GUID));
3197     }
3198 
3199     if (pInheritedObjectGuid != NULL)
3200     {
3201         pObjSid->InheritedObjectTypeGuid = *pInheritedObjectGuid;
3202         ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3203     }
3204     else
3205     {
3206         ZeroMemory(&pObjSid->InheritedObjectTypeGuid,
3207                    sizeof(GUID));
3208     }
3209 
3210     pObjSid->ObjectsPresent = ObjectsPresent;
3211     pObjSid->pSid = pSid;
3212 
3213     /* Fill the TRUSTEE structu