2 * Copyright 1999, 2000 Juergen Schmied <juergen.schmied@debitel.net>
3 * Copyright 2003 CodeWeavers Inc. (Ulrich Czekalla)
4 * Copyright 2006 Robert Reif
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.
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.
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
28 #define WIN32_NO_STATUS
42 #include "advapi32_misc.h"
45 #include "wine/debug.h"
46 #include "wine/unicode.h"
48 WINE_DEFAULT_DEBUG_CHANNEL(advapi
);
50 static BOOL
ParseStringSidToSid(LPCWSTR StringSid
, PSID pSid
, LPDWORD cBytes
);
51 static DWORD
trustee_to_sid(DWORD nDestinationSidLength
, PSID pDestinationSid
, PTRUSTEEW pTrustee
);
53 typedef struct _ACEFLAG
57 } ACEFLAG
, *LPACEFLAG
;
59 typedef struct _MAX_SID
61 /* same fields as struct _SID */
63 BYTE SubAuthorityCount
;
64 SID_IDENTIFIER_AUTHORITY IdentifierAuthority
;
65 DWORD SubAuthority
[SID_MAX_SUB_AUTHORITIES
];
68 typedef struct WELLKNOWNSID
71 WELL_KNOWN_SID_TYPE Type
;
75 static const WELLKNOWNSID WellKnownSids
[] =
77 { {0,0}, WinNullSid
, { SID_REVISION
, 1, { SECURITY_NULL_SID_AUTHORITY
}, { SECURITY_NULL_RID
} } },
78 { {'W','D'}, WinWorldSid
, { SID_REVISION
, 1, { SECURITY_WORLD_SID_AUTHORITY
}, { SECURITY_WORLD_RID
} } },
79 { {0,0}, WinLocalSid
, { SID_REVISION
, 1, { SECURITY_LOCAL_SID_AUTHORITY
}, { SECURITY_LOCAL_RID
} } },
80 { {'C','O'}, WinCreatorOwnerSid
, { SID_REVISION
, 1, { SECURITY_CREATOR_SID_AUTHORITY
}, { SECURITY_CREATOR_OWNER_RID
} } },
81 { {'C','G'}, WinCreatorGroupSid
, { SID_REVISION
, 1, { SECURITY_CREATOR_SID_AUTHORITY
}, { SECURITY_CREATOR_GROUP_RID
} } },
82 { {'O','W'}, WinCreatorOwnerRightsSid
, { SID_REVISION
, 1, { SECURITY_CREATOR_SID_AUTHORITY
}, { SECURITY_CREATOR_OWNER_RIGHTS_RID
} } },
83 { {0,0}, WinCreatorOwnerServerSid
, { SID_REVISION
, 1, { SECURITY_CREATOR_SID_AUTHORITY
}, { SECURITY_CREATOR_OWNER_SERVER_RID
} } },
84 { {0,0}, WinCreatorGroupServerSid
, { SID_REVISION
, 1, { SECURITY_CREATOR_SID_AUTHORITY
}, { SECURITY_CREATOR_GROUP_SERVER_RID
} } },
85 { {0,0}, WinNtAuthoritySid
, { SID_REVISION
, 0, { SECURITY_NT_AUTHORITY
}, { SECURITY_NULL_RID
} } },
86 { {0,0}, WinDialupSid
, { SID_REVISION
, 1, { SECURITY_NT_AUTHORITY
}, { SECURITY_DIALUP_RID
} } },
87 { {'N','U'}, WinNetworkSid
, { SID_REVISION
, 1, { SECURITY_NT_AUTHORITY
}, { SECURITY_NETWORK_RID
} } },
88 { {0,0}, WinBatchSid
, { SID_REVISION
, 1, { SECURITY_NT_AUTHORITY
}, { SECURITY_BATCH_RID
} } },
89 { {'I','U'}, WinInteractiveSid
, { SID_REVISION
, 1, { SECURITY_NT_AUTHORITY
}, { SECURITY_INTERACTIVE_RID
} } },
90 { {'S','U'}, WinServiceSid
, { SID_REVISION
, 1, { SECURITY_NT_AUTHORITY
}, { SECURITY_SERVICE_RID
} } },
91 { {'A','N'}, WinAnonymousSid
, { SID_REVISION
, 1, { SECURITY_NT_AUTHORITY
}, { SECURITY_ANONYMOUS_LOGON_RID
} } },
92 { {0,0}, WinProxySid
, { SID_REVISION
, 1, { SECURITY_NT_AUTHORITY
}, { SECURITY_PROXY_RID
} } },
93 { {'E','D'}, WinEnterpriseControllersSid
, { SID_REVISION
, 1, { SECURITY_NT_AUTHORITY
}, { SECURITY_ENTERPRISE_CONTROLLERS_RID
} } },
94 { {'P','S'}, WinSelfSid
, { SID_REVISION
, 1, { SECURITY_NT_AUTHORITY
}, { SECURITY_PRINCIPAL_SELF_RID
} } },
95 { {'A','U'}, WinAuthenticatedUserSid
, { SID_REVISION
, 1, { SECURITY_NT_AUTHORITY
}, { SECURITY_AUTHENTICATED_USER_RID
} } },
96 { {'R','C'}, WinRestrictedCodeSid
, { SID_REVISION
, 1, { SECURITY_NT_AUTHORITY
}, { SECURITY_RESTRICTED_CODE_RID
} } },
97 { {0,0}, WinTerminalServerSid
, { SID_REVISION
, 1, { SECURITY_NT_AUTHORITY
}, { SECURITY_TERMINAL_SERVER_RID
} } },
98 { {0,0}, WinRemoteLogonIdSid
, { SID_REVISION
, 1, { SECURITY_NT_AUTHORITY
}, { SECURITY_REMOTE_LOGON_RID
} } },
99 { {0,0}, WinLogonIdsSid
, { SID_REVISION
, SECURITY_LOGON_IDS_RID_COUNT
, { SECURITY_NT_AUTHORITY
}, { SECURITY_LOGON_IDS_RID
} } },
100 { {'S','Y'}, WinLocalSystemSid
, { SID_REVISION
, 1, { SECURITY_NT_AUTHORITY
}, { SECURITY_LOCAL_SYSTEM_RID
} } },
101 { {'L','S'}, WinLocalServiceSid
, { SID_REVISION
, 1, { SECURITY_NT_AUTHORITY
}, { SECURITY_LOCAL_SERVICE_RID
} } },
102 { {'N','S'}, WinNetworkServiceSid
, { SID_REVISION
, 1, { SECURITY_NT_AUTHORITY
}, { SECURITY_NETWORK_SERVICE_RID
} } },
103 { {0,0}, WinBuiltinDomainSid
, { SID_REVISION
, 1, { SECURITY_NT_AUTHORITY
}, { SECURITY_BUILTIN_DOMAIN_RID
} } },
104 { {'B','A'}, WinBuiltinAdministratorsSid
, { SID_REVISION
, 2, { SECURITY_NT_AUTHORITY
}, { SECURITY_BUILTIN_DOMAIN_RID
, DOMAIN_ALIAS_RID_ADMINS
} } },
105 { {'B','U'}, WinBuiltinUsersSid
, { SID_REVISION
, 2, { SECURITY_NT_AUTHORITY
}, { SECURITY_BUILTIN_DOMAIN_RID
, DOMAIN_ALIAS_RID_USERS
} } },
106 { {'B','G'}, WinBuiltinGuestsSid
, { SID_REVISION
, 2, { SECURITY_NT_AUTHORITY
}, { SECURITY_BUILTIN_DOMAIN_RID
, DOMAIN_ALIAS_RID_GUESTS
} } },
107 { {'P','U'}, WinBuiltinPowerUsersSid
, { SID_REVISION
, 2, { SECURITY_NT_AUTHORITY
}, { SECURITY_BUILTIN_DOMAIN_RID
, DOMAIN_ALIAS_RID_POWER_USERS
} } },
108 { {'A','O'}, WinBuiltinAccountOperatorsSid
, { SID_REVISION
, 2, { SECURITY_NT_AUTHORITY
}, { SECURITY_BUILTIN_DOMAIN_RID
, DOMAIN_ALIAS_RID_ACCOUNT_OPS
} } },
109 { {'S','O'}, WinBuiltinSystemOperatorsSid
, { SID_REVISION
, 2, { SECURITY_NT_AUTHORITY
}, { SECURITY_BUILTIN_DOMAIN_RID
, DOMAIN_ALIAS_RID_SYSTEM_OPS
} } },
110 { {'P','O'}, WinBuiltinPrintOperatorsSid
, { SID_REVISION
, 2, { SECURITY_NT_AUTHORITY
}, { SECURITY_BUILTIN_DOMAIN_RID
, DOMAIN_ALIAS_RID_PRINT_OPS
} } },
111 { {'B','O'}, WinBuiltinBackupOperatorsSid
, { SID_REVISION
, 2, { SECURITY_NT_AUTHORITY
}, { SECURITY_BUILTIN_DOMAIN_RID
, DOMAIN_ALIAS_RID_BACKUP_OPS
} } },
112 { {'R','E'}, WinBuiltinReplicatorSid
, { SID_REVISION
, 2, { SECURITY_NT_AUTHORITY
}, { SECURITY_BUILTIN_DOMAIN_RID
, DOMAIN_ALIAS_RID_REPLICATOR
} } },
113 { {'R','U'}, WinBuiltinPreWindows2000CompatibleAccessSid
, { SID_REVISION
, 2, { SECURITY_NT_AUTHORITY
}, { SECURITY_BUILTIN_DOMAIN_RID
, DOMAIN_ALIAS_RID_PREW2KCOMPACCESS
} } },
114 { {'R','D'}, WinBuiltinRemoteDesktopUsersSid
, { SID_REVISION
, 2, { SECURITY_NT_AUTHORITY
}, { SECURITY_BUILTIN_DOMAIN_RID
, DOMAIN_ALIAS_RID_REMOTE_DESKTOP_USERS
} } },
115 { {'N','O'}, WinBuiltinNetworkConfigurationOperatorsSid
, { SID_REVISION
, 2, { SECURITY_NT_AUTHORITY
}, { SECURITY_BUILTIN_DOMAIN_RID
, DOMAIN_ALIAS_RID_NETWORK_CONFIGURATION_OPS
} } },
116 { {0,0}, WinNTLMAuthenticationSid
, { SID_REVISION
, 2, { SECURITY_NT_AUTHORITY
}, { SECURITY_PACKAGE_BASE_RID
, SECURITY_PACKAGE_NTLM_RID
} } },
117 { {0,0}, WinDigestAuthenticationSid
, { SID_REVISION
, 2, { SECURITY_NT_AUTHORITY
}, { SECURITY_PACKAGE_BASE_RID
, SECURITY_PACKAGE_DIGEST_RID
} } },
118 { {0,0}, WinSChannelAuthenticationSid
, { SID_REVISION
, 2, { SECURITY_NT_AUTHORITY
}, { SECURITY_PACKAGE_BASE_RID
, SECURITY_PACKAGE_SCHANNEL_RID
} } },
119 { {0,0}, WinThisOrganizationSid
, { SID_REVISION
, 1, { SECURITY_NT_AUTHORITY
}, { SECURITY_THIS_ORGANIZATION_RID
} } },
120 { {0,0}, WinOtherOrganizationSid
, { SID_REVISION
, 1, { SECURITY_NT_AUTHORITY
}, { SECURITY_OTHER_ORGANIZATION_RID
} } },
121 { {0,0}, WinBuiltinIncomingForestTrustBuildersSid
, { SID_REVISION
, 2, { SECURITY_NT_AUTHORITY
}, { SECURITY_BUILTIN_DOMAIN_RID
, DOMAIN_ALIAS_RID_INCOMING_FOREST_TRUST_BUILDERS
} } },
122 { {0,0}, WinBuiltinPerfMonitoringUsersSid
, { SID_REVISION
, 2, { SECURITY_NT_AUTHORITY
}, { SECURITY_BUILTIN_DOMAIN_RID
, DOMAIN_ALIAS_RID_MONITORING_USERS
} } },
123 { {0,0}, WinBuiltinPerfLoggingUsersSid
, { SID_REVISION
, 2, { SECURITY_NT_AUTHORITY
}, { SECURITY_BUILTIN_DOMAIN_RID
, DOMAIN_ALIAS_RID_LOGGING_USERS
} } },
124 { {0,0}, WinBuiltinAuthorizationAccessSid
, { SID_REVISION
, 2, { SECURITY_NT_AUTHORITY
}, { SECURITY_BUILTIN_DOMAIN_RID
, DOMAIN_ALIAS_RID_AUTHORIZATIONACCESS
} } },
125 { {0,0}, WinBuiltinTerminalServerLicenseServersSid
, { SID_REVISION
, 2, { SECURITY_NT_AUTHORITY
}, { SECURITY_BUILTIN_DOMAIN_RID
, DOMAIN_ALIAS_RID_TS_LICENSE_SERVERS
} } },
126 { {0,0}, WinBuiltinDCOMUsersSid
, { SID_REVISION
, 2, { SECURITY_NT_AUTHORITY
}, { SECURITY_BUILTIN_DOMAIN_RID
, DOMAIN_ALIAS_RID_DCOM_USERS
} } },
127 { {'L','W'}, WinLowLabelSid
, { SID_REVISION
, 1, { SECURITY_MANDATORY_LABEL_AUTHORITY
}, { SECURITY_MANDATORY_LOW_RID
} } },
128 { {'M','E'}, WinMediumLabelSid
, { SID_REVISION
, 1, { SECURITY_MANDATORY_LABEL_AUTHORITY
}, { SECURITY_MANDATORY_MEDIUM_RID
} } },
129 { {'H','I'}, WinHighLabelSid
, { SID_REVISION
, 1, { SECURITY_MANDATORY_LABEL_AUTHORITY
}, { SECURITY_MANDATORY_HIGH_RID
} } },
130 { {'S','I'}, WinSystemLabelSid
, { SID_REVISION
, 1, { SECURITY_MANDATORY_LABEL_AUTHORITY
}, { SECURITY_MANDATORY_SYSTEM_RID
} } },
131 { {'A','C'}, WinBuiltinAnyPackageSid
, { SID_REVISION
, 2, { SECURITY_APP_PACKAGE_AUTHORITY
}, { SECURITY_APP_PACKAGE_BASE_RID
, SECURITY_BUILTIN_PACKAGE_ANY_PACKAGE
} } },
134 /* these SIDs must be constructed as relative to some domain - only the RID is well-known */
135 typedef struct WELLKNOWNRID
138 WELL_KNOWN_SID_TYPE Type
;
142 static const WELLKNOWNRID WellKnownRids
[] = {
143 { {'L','A'}, WinAccountAdministratorSid
, DOMAIN_USER_RID_ADMIN
},
144 { {'L','G'}, WinAccountGuestSid
, DOMAIN_USER_RID_GUEST
},
145 { {0,0}, WinAccountKrbtgtSid
, DOMAIN_USER_RID_KRBTGT
},
146 { {'D','A'}, WinAccountDomainAdminsSid
, DOMAIN_GROUP_RID_ADMINS
},
147 { {'D','U'}, WinAccountDomainUsersSid
, DOMAIN_GROUP_RID_USERS
},
148 { {'D','G'}, WinAccountDomainGuestsSid
, DOMAIN_GROUP_RID_GUESTS
},
149 { {'D','C'}, WinAccountComputersSid
, DOMAIN_GROUP_RID_COMPUTERS
},
150 { {'D','D'}, WinAccountControllersSid
, DOMAIN_GROUP_RID_CONTROLLERS
},
151 { {'C','A'}, WinAccountCertAdminsSid
, DOMAIN_GROUP_RID_CERT_ADMINS
},
152 { {'S','A'}, WinAccountSchemaAdminsSid
, DOMAIN_GROUP_RID_SCHEMA_ADMINS
},
153 { {'E','A'}, WinAccountEnterpriseAdminsSid
, DOMAIN_GROUP_RID_ENTERPRISE_ADMINS
},
154 { {'P','A'}, WinAccountPolicyAdminsSid
, DOMAIN_GROUP_RID_POLICY_ADMINS
},
155 { {'R','S'}, WinAccountRasAndIasServersSid
, DOMAIN_ALIAS_RID_RAS_SERVERS
},
159 typedef struct _AccountSid
{
160 WELL_KNOWN_SID_TYPE type
;
163 SID_NAME_USE name_use
;
167 static const WCHAR Account_Operators
[] = { 'A','c','c','o','u','n','t',' ','O','p','e','r','a','t','o','r','s',0 };
168 static const WCHAR Administrator
[] = {'A','d','m','i','n','i','s','t','r','a','t','o','r',0 };
169 static const WCHAR Administrators
[] = { 'A','d','m','i','n','i','s','t','r','a','t','o','r','s',0 };
170 static const WCHAR ALL_APPLICATION_PACKAGES
[] = { 'A','L','L',' ','A','P','P','L','I','C','A','T','I','O','N',' ','P','A','C','K','A','G','E','S',0 };
171 static const WCHAR ANONYMOUS_LOGON
[] = { 'A','N','O','N','Y','M','O','U','S',' ','L','O','G','O','N',0 };
172 static const WCHAR APPLICATION_PACKAGE_AUTHORITY
[] = { 'A','P','P','L','I','C','A','T','I','O','N',' ','P','A','C','K','A','G','E',' ','A','U','T','H','O','R','I','T','Y',0 };
173 static const WCHAR Authenticated_Users
[] = { 'A','u','t','h','e','n','t','i','c','a','t','e','d',' ','U','s','e','r','s',0 };
174 static const WCHAR Backup_Operators
[] = { 'B','a','c','k','u','p',' ','O','p','e','r','a','t','o','r','s',0 };
175 static const WCHAR BATCH
[] = { 'B','A','T','C','H',0 };
176 static const WCHAR Blank
[] = { 0 };
177 static const WCHAR BUILTIN
[] = { 'B','U','I','L','T','I','N',0 };
178 static const WCHAR Cert_Publishers
[] = { 'C','e','r','t',' ','P','u','b','l','i','s','h','e','r','s',0 };
179 static const WCHAR CREATOR_GROUP
[] = { 'C','R','E','A','T','O','R',' ','G','R','O','U','P',0 };
180 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 };
181 static const WCHAR CREATOR_OWNER
[] = { 'C','R','E','A','T','O','R',' ','O','W','N','E','R',0 };
182 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 };
183 static const WCHAR CURRENT_USER
[] = { 'C','U','R','R','E','N','T','_','U','S','E','R',0 };
184 static const WCHAR DIALUP
[] = { 'D','I','A','L','U','P',0 };
185 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 };
186 static const WCHAR Domain_Admins
[] = { 'D','o','m','a','i','n',' ','A','d','m','i','n','s',0 };
187 static const WCHAR Domain_Computers
[] = { 'D','o','m','a','i','n',' ','C','o','m','p','u','t','e','r','s',0 };
188 static const WCHAR Domain_Controllers
[] = { 'D','o','m','a','i','n',' ','C','o','n','t','r','o','l','l','e','r','s',0 };
189 static const WCHAR Domain_Guests
[] = { 'D','o','m','a','i','n',' ','G','u','e','s','t','s',0 };
190 static const WCHAR None
[] = { 'N','o','n','e',0 };
191 static const WCHAR Enterprise_Admins
[] = { 'E','n','t','e','r','p','r','i','s','e',' ','A','d','m','i','n','s',0 };
192 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 };
193 static const WCHAR Everyone
[] = { 'E','v','e','r','y','o','n','e',0 };
194 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 };
195 static const WCHAR Guest
[] = { 'G','u','e','s','t',0 };
196 static const WCHAR Guests
[] = { 'G','u','e','s','t','s',0 };
197 static const WCHAR INTERACTIVE
[] = { 'I','N','T','E','R','A','C','T','I','V','E',0 };
198 static const WCHAR LOCAL
[] = { 'L','O','C','A','L',0 };
199 static const WCHAR LOCAL_SERVICE
[] = { 'L','O','C','A','L',' ','S','E','R','V','I','C','E',0 };
200 static const WCHAR LOCAL_SERVICE2
[] = { 'L','O','C','A','L','S','E','R','V','I','C','E',0 };
201 static const WCHAR NETWORK
[] = { 'N','E','T','W','O','R','K',0 };
202 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 };
203 static const WCHAR NETWORK_SERVICE
[] = { 'N','E','T','W','O','R','K',' ','S','E','R','V','I','C','E',0 };
204 static const WCHAR NETWORK_SERVICE2
[] = { 'N','E','T','W','O','R','K','S','E','R','V','I','C','E',0 };
205 static const WCHAR NT_AUTHORITY
[] = { 'N','T',' ','A','U','T','H','O','R','I','T','Y',0 };
206 static const WCHAR NT_Pseudo_Domain
[] = { 'N','T',' ','P','s','e','u','d','o',' ','D','o','m','a','i','n',0 };
207 static const WCHAR NTML_Authentication
[] = { 'N','T','M','L',' ','A','u','t','h','e','n','t','i','c','a','t','i','o','n',0 };
208 static const WCHAR NULL_SID
[] = { 'N','U','L','L',' ','S','I','D',0 };
209 static const WCHAR Other_Organization
[] = { 'O','t','h','e','r',' ','O','r','g','a','n','i','z','a','t','i','o','n',0 };
210 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 };
211 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 };
212 static const WCHAR Power_Users
[] = { 'P','o','w','e','r',' ','U','s','e','r','s',0 };
213 static const WCHAR Pre_Windows_2000_Compatible_Access
[] = { 'P','r','e','-','W','i','n','d','o','w','s',' ','2','0','0','0',' ','C','o','m','p','a','t','i','b','l','e',' ','A','c','c','e','s','s',0 };
214 static const WCHAR Print_Operators
[] = { 'P','r','i','n','t',' ','O','p','e','r','a','t','o','r','s',0 };
215 static const WCHAR PROXY
[] = { 'P','R','O','X','Y',0 };
216 static const WCHAR RAS_and_IAS_Servers
[] = { 'R','A','S',' ','a','n','d',' ','I','A','S',' ','S','e','r','v','e','r','s',0 };
217 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 };
218 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 };
219 static const WCHAR Replicators
[] = { 'R','e','p','l','i','c','a','t','o','r','s',0 };
220 static const WCHAR RESTRICTED
[] = { 'R','E','S','T','R','I','C','T','E','D',0 };
221 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 };
222 static const WCHAR Schema_Admins
[] = { 'S','c','h','e','m','a',' ','A','d','m','i','n','s',0 };
223 static const WCHAR SELF
[] = { 'S','E','L','F',0 };
224 static const WCHAR Server_Operators
[] = { 'S','e','r','v','e','r',' ','O','p','e','r','a','t','o','r','s',0 };
225 static const WCHAR SERVICE
[] = { 'S','E','R','V','I','C','E',0 };
226 static const WCHAR SYSTEM
[] = { 'S','Y','S','T','E','M',0 };
227 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 };
228 static const WCHAR This_Organization
[] = { 'T','h','i','s',' ','O','r','g','a','n','i','z','a','t','i','o','n',0 };
229 static const WCHAR Users
[] = { 'U','s','e','r','s',0 };
231 static const AccountSid ACCOUNT_SIDS
[] = {
232 { WinNullSid
, NULL_SID
, Blank
, SidTypeWellKnownGroup
},
233 { WinWorldSid
, Everyone
, Blank
, SidTypeWellKnownGroup
},
234 { WinLocalSid
, LOCAL
, Blank
, SidTypeWellKnownGroup
},
235 { WinCreatorOwnerSid
, CREATOR_OWNER
, Blank
, SidTypeWellKnownGroup
},
236 { WinCreatorGroupSid
, CREATOR_GROUP
, Blank
, SidTypeWellKnownGroup
},
237 { WinCreatorOwnerServerSid
, CREATOR_OWNER_SERVER
, Blank
, SidTypeWellKnownGroup
},
238 { WinCreatorGroupServerSid
, CREATOR_GROUP_SERVER
, Blank
, SidTypeWellKnownGroup
},
239 { WinNtAuthoritySid
, NT_Pseudo_Domain
, NT_Pseudo_Domain
, SidTypeDomain
},
240 { WinDialupSid
, DIALUP
, NT_AUTHORITY
, SidTypeWellKnownGroup
},
241 { WinNetworkSid
, NETWORK
, NT_AUTHORITY
, SidTypeWellKnownGroup
},
242 { WinBatchSid
, BATCH
, NT_AUTHORITY
, SidTypeWellKnownGroup
},
243 { WinInteractiveSid
, INTERACTIVE
, NT_AUTHORITY
, SidTypeWellKnownGroup
},
244 { WinServiceSid
, SERVICE
, NT_AUTHORITY
, SidTypeWellKnownGroup
},
245 { WinAnonymousSid
, ANONYMOUS_LOGON
, NT_AUTHORITY
, SidTypeWellKnownGroup
},
246 { WinProxySid
, PROXY
, NT_AUTHORITY
, SidTypeWellKnownGroup
},
247 { WinEnterpriseControllersSid
, ENTERPRISE_DOMAIN_CONTROLLERS
, NT_AUTHORITY
, SidTypeWellKnownGroup
},
248 { WinSelfSid
, SELF
, NT_AUTHORITY
, SidTypeWellKnownGroup
},
249 { WinAuthenticatedUserSid
, Authenticated_Users
, NT_AUTHORITY
, SidTypeWellKnownGroup
},
250 { WinRestrictedCodeSid
, RESTRICTED
, NT_AUTHORITY
, SidTypeWellKnownGroup
},
251 { WinTerminalServerSid
, TERMINAL_SERVER_USER
, NT_AUTHORITY
, SidTypeWellKnownGroup
},
252 { WinRemoteLogonIdSid
, REMOTE_INTERACTIVE_LOGON
, NT_AUTHORITY
, SidTypeWellKnownGroup
},
253 { WinLocalSystemSid
, SYSTEM
, NT_AUTHORITY
, SidTypeWellKnownGroup
},
254 { WinLocalServiceSid
, LOCAL_SERVICE
, NT_AUTHORITY
, SidTypeWellKnownGroup
, LOCAL_SERVICE2
},
255 { WinNetworkServiceSid
, NETWORK_SERVICE
, NT_AUTHORITY
, SidTypeWellKnownGroup
, NETWORK_SERVICE2
},
256 { WinBuiltinDomainSid
, BUILTIN
, BUILTIN
, SidTypeDomain
},
257 { WinBuiltinAdministratorsSid
, Administrators
, BUILTIN
, SidTypeAlias
},
258 { WinBuiltinUsersSid
, Users
, BUILTIN
, SidTypeAlias
},
259 { WinBuiltinGuestsSid
, Guests
, BUILTIN
, SidTypeAlias
},
260 { WinBuiltinPowerUsersSid
, Power_Users
, BUILTIN
, SidTypeAlias
},
261 { WinBuiltinAccountOperatorsSid
, Account_Operators
, BUILTIN
, SidTypeAlias
},
262 { WinBuiltinSystemOperatorsSid
, Server_Operators
, BUILTIN
, SidTypeAlias
},
263 { WinBuiltinPrintOperatorsSid
, Print_Operators
, BUILTIN
, SidTypeAlias
},
264 { WinBuiltinBackupOperatorsSid
, Backup_Operators
, BUILTIN
, SidTypeAlias
},
265 { WinBuiltinReplicatorSid
, Replicators
, BUILTIN
, SidTypeAlias
},
266 { WinBuiltinPreWindows2000CompatibleAccessSid
, Pre_Windows_2000_Compatible_Access
, BUILTIN
, SidTypeAlias
},
267 { WinBuiltinRemoteDesktopUsersSid
, Remote_Desktop_Users
, BUILTIN
, SidTypeAlias
},
268 { WinBuiltinNetworkConfigurationOperatorsSid
, Network_Configuration_Operators
, BUILTIN
, SidTypeAlias
},
269 { WinNTLMAuthenticationSid
, NTML_Authentication
, NT_AUTHORITY
, SidTypeWellKnownGroup
},
270 { WinDigestAuthenticationSid
, Digest_Authentication
, NT_AUTHORITY
, SidTypeWellKnownGroup
},
271 { WinSChannelAuthenticationSid
, SChannel_Authentication
, NT_AUTHORITY
, SidTypeWellKnownGroup
},
272 { WinThisOrganizationSid
, This_Organization
, NT_AUTHORITY
, SidTypeWellKnownGroup
},
273 { WinOtherOrganizationSid
, Other_Organization
, NT_AUTHORITY
, SidTypeWellKnownGroup
},
274 { WinBuiltinPerfMonitoringUsersSid
, Performance_Monitor_Users
, BUILTIN
, SidTypeAlias
},
275 { WinBuiltinPerfLoggingUsersSid
, Performance_Log_Users
, BUILTIN
, SidTypeAlias
},
276 { WinBuiltinAnyPackageSid
, ALL_APPLICATION_PACKAGES
, APPLICATION_PACKAGE_AUTHORITY
, SidTypeWellKnownGroup
},
281 static const WCHAR SDDL_READ_CONTROL
[] = {'R','C',0};
282 static const WCHAR SDDL_WRITE_DAC
[] = {'W','D',0};
283 static const WCHAR SDDL_WRITE_OWNER
[] = {'W','O',0};
284 static const WCHAR SDDL_STANDARD_DELETE
[] = {'S','D',0};
286 static const WCHAR SDDL_READ_PROPERTY
[] = {'R','P',0};
287 static const WCHAR SDDL_WRITE_PROPERTY
[] = {'W','P',0};
288 static const WCHAR SDDL_CREATE_CHILD
[] = {'C','C',0};
289 static const WCHAR SDDL_DELETE_CHILD
[] = {'D','C',0};
290 static const WCHAR SDDL_LIST_CHILDREN
[] = {'L','C',0};
291 static const WCHAR SDDL_SELF_WRITE
[] = {'S','W',0};
292 static const WCHAR SDDL_LIST_OBJECT
[] = {'L','O',0};
293 static const WCHAR SDDL_DELETE_TREE
[] = {'D','T',0};
294 static const WCHAR SDDL_CONTROL_ACCESS
[] = {'C','R',0};
296 static const WCHAR SDDL_FILE_ALL
[] = {'F','A',0};
297 static const WCHAR SDDL_FILE_READ
[] = {'F','R',0};
298 static const WCHAR SDDL_FILE_WRITE
[] = {'F','W',0};
299 static const WCHAR SDDL_FILE_EXECUTE
[] = {'F','X',0};
301 static const WCHAR SDDL_KEY_ALL
[] = {'K','A',0};
302 static const WCHAR SDDL_KEY_READ
[] = {'K','R',0};
303 static const WCHAR SDDL_KEY_WRITE
[] = {'K','W',0};
304 static const WCHAR SDDL_KEY_EXECUTE
[] = {'K','X',0};
306 static const WCHAR SDDL_GENERIC_ALL
[] = {'G','A',0};
307 static const WCHAR SDDL_GENERIC_READ
[] = {'G','R',0};
308 static const WCHAR SDDL_GENERIC_WRITE
[] = {'G','W',0};
309 static const WCHAR SDDL_GENERIC_EXECUTE
[] = {'G','X',0};
311 static const WCHAR SDDL_NO_READ_UP
[] = {'N','R',0};
312 static const WCHAR SDDL_NO_WRITE_UP
[] = {'N','W',0};
313 static const WCHAR SDDL_NO_EXECUTE_UP
[] = {'N','X',0};
318 static const WCHAR SDDL_PROTECTED
[] = {'P',0};
319 static const WCHAR SDDL_AUTO_INHERIT_REQ
[] = {'A','R',0};
320 static const WCHAR SDDL_AUTO_INHERITED
[] = {'A','I',0};
325 static const WCHAR SDDL_ACCESS_ALLOWED
[] = {'A',0};
326 static const WCHAR SDDL_ACCESS_DENIED
[] = {'D',0};
327 static const WCHAR SDDL_AUDIT
[] = {'A','U',0};
328 static const WCHAR SDDL_ALARM
[] = {'A','L',0};
329 static const WCHAR SDDL_MANDATORY_LABEL
[] = {'M','L',0};
334 static const WCHAR SDDL_CONTAINER_INHERIT
[] = {'C','I',0};
335 static const WCHAR SDDL_OBJECT_INHERIT
[] = {'O','I',0};
336 static const WCHAR SDDL_NO_PROPAGATE
[] = {'N','P',0};
337 static const WCHAR SDDL_INHERIT_ONLY
[] = {'I','O',0};
338 static const WCHAR SDDL_INHERITED
[] = {'I','D',0};
339 static const WCHAR SDDL_AUDIT_SUCCESS
[] = {'S','A',0};
340 static const WCHAR SDDL_AUDIT_FAILURE
[] = {'F','A',0};
342 const char * debugstr_sid(PSID sid
)
350 auth
= psid
->IdentifierAuthority
.Value
[5] +
351 (psid
->IdentifierAuthority
.Value
[4] << 8) +
352 (psid
->IdentifierAuthority
.Value
[3] << 16) +
353 (psid
->IdentifierAuthority
.Value
[2] << 24);
355 switch (psid
->SubAuthorityCount
) {
357 return wine_dbg_sprintf("S-%d-%d", psid
->Revision
, auth
);
359 return wine_dbg_sprintf("S-%d-%d-%u", psid
->Revision
, auth
,
360 psid
->SubAuthority
[0]);
362 return wine_dbg_sprintf("S-%d-%d-%u-%u", psid
->Revision
, auth
,
363 psid
->SubAuthority
[0], psid
->SubAuthority
[1]);
365 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u", psid
->Revision
, auth
,
366 psid
->SubAuthority
[0], psid
->SubAuthority
[1], psid
->SubAuthority
[2]);
368 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u", psid
->Revision
, auth
,
369 psid
->SubAuthority
[0], psid
->SubAuthority
[1], psid
->SubAuthority
[2],
370 psid
->SubAuthority
[3]);
372 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u", psid
->Revision
, auth
,
373 psid
->SubAuthority
[0], psid
->SubAuthority
[1], psid
->SubAuthority
[2],
374 psid
->SubAuthority
[3], psid
->SubAuthority
[4]);
376 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u-%u", psid
->Revision
, auth
,
377 psid
->SubAuthority
[3], psid
->SubAuthority
[1], psid
->SubAuthority
[2],
378 psid
->SubAuthority
[0], psid
->SubAuthority
[4], psid
->SubAuthority
[5]);
380 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u-%u-%u", psid
->Revision
, auth
,
381 psid
->SubAuthority
[0], psid
->SubAuthority
[1], psid
->SubAuthority
[2],
382 psid
->SubAuthority
[3], psid
->SubAuthority
[4], psid
->SubAuthority
[5],
383 psid
->SubAuthority
[6]);
385 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u-%u-%u-%u", psid
->Revision
, auth
,
386 psid
->SubAuthority
[0], psid
->SubAuthority
[1], psid
->SubAuthority
[2],
387 psid
->SubAuthority
[3], psid
->SubAuthority
[4], psid
->SubAuthority
[5],
388 psid
->SubAuthority
[6], psid
->SubAuthority
[7]);
393 /* helper function for SE_FILE_OBJECT objects in [Get|Set]NamedSecurityInfo */
394 static inline DWORD
get_security_file( LPCWSTR full_file_name
, DWORD access
, HANDLE
*file
)
396 UNICODE_STRING file_nameW
;
397 OBJECT_ATTRIBUTES attr
;
401 if (!RtlDosPathNameToNtPathName_U( full_file_name
, &file_nameW
, NULL
, NULL
))
402 return ERROR_PATH_NOT_FOUND
;
403 attr
.Length
= sizeof(attr
);
404 attr
.RootDirectory
= 0;
405 attr
.Attributes
= OBJ_CASE_INSENSITIVE
;
406 attr
.ObjectName
= &file_nameW
;
407 attr
.SecurityDescriptor
= NULL
;
408 status
= NtCreateFile( file
, access
|SYNCHRONIZE
, &attr
, &io
, NULL
, FILE_FLAG_BACKUP_SEMANTICS
,
409 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
, FILE_OPEN
,
410 FILE_OPEN_FOR_BACKUP_INTENT
, NULL
, 0 );
411 RtlFreeUnicodeString( &file_nameW
);
412 return RtlNtStatusToDosError( status
);
415 /* helper function for SE_SERVICE objects in [Get|Set]NamedSecurityInfo */
416 static inline DWORD
get_security_service( LPWSTR full_service_name
, DWORD access
, HANDLE
*service
)
418 SC_HANDLE manager
= 0;
421 err
= SERV_OpenSCManagerW( NULL
, NULL
, access
, (SC_HANDLE
*)&manager
);
422 if (err
== ERROR_SUCCESS
)
424 err
= SERV_OpenServiceW( manager
, full_service_name
, access
, (SC_HANDLE
*)service
);
425 CloseServiceHandle( manager
);
430 /* helper function for SE_REGISTRY_KEY objects in [Get|Set]NamedSecurityInfo */
431 static inline DWORD
get_security_regkey( LPWSTR full_key_name
, DWORD access
, HANDLE
*key
)
433 static const WCHAR classes_rootW
[] = {'C','L','A','S','S','E','S','_','R','O','O','T',0};
434 static const WCHAR current_userW
[] = {'C','U','R','R','E','N','T','_','U','S','E','R',0};
435 static const WCHAR machineW
[] = {'M','A','C','H','I','N','E',0};
436 static const WCHAR usersW
[] = {'U','S','E','R','S',0};
437 LPWSTR p
= strchrW(full_key_name
, '\\');
438 int len
= p
-full_key_name
;
441 if (!p
) return ERROR_INVALID_PARAMETER
;
442 if (strncmpW( full_key_name
, classes_rootW
, len
) == 0)
443 hParent
= HKEY_CLASSES_ROOT
;
444 else if (strncmpW( full_key_name
, current_userW
, len
) == 0)
445 hParent
= HKEY_CURRENT_USER
;
446 else if (strncmpW( full_key_name
, machineW
, len
) == 0)
447 hParent
= HKEY_LOCAL_MACHINE
;
448 else if (strncmpW( full_key_name
, usersW
, len
) == 0)
449 hParent
= HKEY_USERS
;
451 return ERROR_INVALID_PARAMETER
;
452 return RegOpenKeyExW( hParent
, p
+1, 0, access
, (HKEY
*)key
);
456 /************************************************************
457 * ADVAPI_IsLocalComputer
459 * Checks whether the server name indicates local machine.
461 BOOL
ADVAPI_IsLocalComputer(LPCWSTR ServerName
)
463 DWORD dwSize
= MAX_COMPUTERNAME_LENGTH
+ 1;
467 if (!ServerName
|| !ServerName
[0])
470 buf
= heap_alloc(dwSize
* sizeof(WCHAR
));
471 Result
= GetComputerNameW(buf
, &dwSize
);
472 if (Result
&& (ServerName
[0] == '\\') && (ServerName
[1] == '\\'))
474 Result
= Result
&& !lstrcmpW(ServerName
, buf
);
480 /************************************************************
481 * ADVAPI_GetComputerSid
483 BOOL
ADVAPI_GetComputerSid(PSID sid
)
485 static const struct /* same fields as struct SID */
488 BYTE SubAuthorityCount
;
489 SID_IDENTIFIER_AUTHORITY IdentifierAuthority
;
490 DWORD SubAuthority
[4];
492 { SID_REVISION
, 4, { SECURITY_NT_AUTHORITY
}, { SECURITY_NT_NON_UNIQUE
, 0, 0, 0 } };
494 memcpy( sid
, &computer_sid
, sizeof(computer_sid
) );
499 GetEffectiveRightsFromAclA( PACL pacl
, PTRUSTEEA pTrustee
, PACCESS_MASK pAccessRights
)
501 FIXME("%p %p %p - stub\n", pacl
, pTrustee
, pAccessRights
);
503 *pAccessRights
= STANDARD_RIGHTS_ALL
| SPECIFIC_RIGHTS_ALL
;
508 GetEffectiveRightsFromAclW( PACL pacl
, PTRUSTEEW pTrustee
, PACCESS_MASK pAccessRights
)
510 FIXME("%p %p %p - stub\n", pacl
, pTrustee
, pAccessRights
);
515 /* ##############################################
516 ###### SECURITY DESCRIPTOR FUNCTIONS ######
517 ##############################################
520 /******************************************************************************
521 * BuildSecurityDescriptorA [ADVAPI32.@]
528 * cCountOfAccessEntries [I]
529 * pListOfAccessEntries [I]
530 * cCountOfAuditEntries [I]
531 * pListofAuditEntries [I]
533 * lpdwBufferLength [I/O]
537 * Success: ERROR_SUCCESS
538 * Failure: nonzero error code from Winerror.h
540 DWORD WINAPI
BuildSecurityDescriptorA(
543 IN ULONG cCountOfAccessEntries
,
544 IN PEXPLICIT_ACCESSA pListOfAccessEntries
,
545 IN ULONG cCountOfAuditEntries
,
546 IN PEXPLICIT_ACCESSA pListofAuditEntries
,
547 IN PSECURITY_DESCRIPTOR pOldSD
,
548 IN OUT PULONG lpdwBufferLength
,
549 OUT PSECURITY_DESCRIPTOR
* pNewSD
)
551 FIXME("(%p,%p,%d,%p,%d,%p,%p,%p,%p) stub!\n",pOwner
,pGroup
,
552 cCountOfAccessEntries
,pListOfAccessEntries
,cCountOfAuditEntries
,
553 pListofAuditEntries
,pOldSD
,lpdwBufferLength
,pNewSD
);
555 return ERROR_CALL_NOT_IMPLEMENTED
;
558 /******************************************************************************
559 * BuildSecurityDescriptorW [ADVAPI32.@]
561 * See BuildSecurityDescriptorA.
563 DWORD WINAPI
BuildSecurityDescriptorW(
566 IN ULONG cCountOfAccessEntries
,
567 IN PEXPLICIT_ACCESSW pListOfAccessEntries
,
568 IN ULONG cCountOfAuditEntries
,
569 IN PEXPLICIT_ACCESSW pListOfAuditEntries
,
570 IN PSECURITY_DESCRIPTOR pOldSD
,
571 IN OUT PULONG lpdwBufferLength
,
572 OUT PSECURITY_DESCRIPTOR
* pNewSD
)
574 SECURITY_DESCRIPTOR desc
;
576 DWORD ret
= ERROR_SUCCESS
;
578 TRACE("(%p,%p,%d,%p,%d,%p,%p,%p,%p)\n", pOwner
, pGroup
,
579 cCountOfAccessEntries
, pListOfAccessEntries
, cCountOfAuditEntries
,
580 pListOfAuditEntries
, pOldSD
, lpdwBufferLength
, pNewSD
);
584 SECURITY_DESCRIPTOR_CONTROL control
;
585 DWORD desc_size
, dacl_size
= 0, sacl_size
= 0, owner_size
= 0, group_size
= 0;
586 PACL dacl
= NULL
, sacl
= NULL
;
587 PSID owner
= NULL
, group
= NULL
;
590 if ((status
= RtlGetControlSecurityDescriptor( pOldSD
, &control
, &revision
)) != STATUS_SUCCESS
)
591 return RtlNtStatusToDosError( status
);
592 if (!(control
& SE_SELF_RELATIVE
))
593 return ERROR_INVALID_SECURITY_DESCR
;
595 desc_size
= sizeof(desc
);
596 status
= RtlSelfRelativeToAbsoluteSD( pOldSD
, &desc
, &desc_size
, dacl
, &dacl_size
, sacl
, &sacl_size
,
597 owner
, &owner_size
, group
, &group_size
);
598 if (status
== STATUS_BUFFER_TOO_SMALL
)
601 dacl
= LocalAlloc( LMEM_FIXED
, dacl_size
);
603 sacl
= LocalAlloc( LMEM_FIXED
, sacl_size
);
605 owner
= LocalAlloc( LMEM_FIXED
, owner_size
);
607 group
= LocalAlloc( LMEM_FIXED
, group_size
);
609 desc_size
= sizeof(desc
);
610 status
= RtlSelfRelativeToAbsoluteSD( pOldSD
, &desc
, &desc_size
, dacl
, &dacl_size
, sacl
, &sacl_size
,
611 owner
, &owner_size
, group
, &group_size
);
613 if (status
!= STATUS_SUCCESS
)
619 return RtlNtStatusToDosError( status
);
624 if ((status
= RtlCreateSecurityDescriptor( &desc
, SECURITY_DESCRIPTOR_REVISION
)) != STATUS_SUCCESS
)
625 return RtlNtStatusToDosError( status
);
630 LocalFree( desc
.Owner
);
631 desc
.Owner
= LocalAlloc( LMEM_FIXED
, sizeof(MAX_SID
) );
632 if ((ret
= trustee_to_sid( sizeof(MAX_SID
), desc
.Owner
, pOwner
)))
638 LocalFree( desc
.Group
);
639 desc
.Group
= LocalAlloc( LMEM_FIXED
, sizeof(MAX_SID
) );
640 if ((ret
= trustee_to_sid( sizeof(MAX_SID
), desc
.Group
, pGroup
)))
644 if (pListOfAccessEntries
)
648 if ((ret
= SetEntriesInAclW( cCountOfAccessEntries
, pListOfAccessEntries
, desc
.Dacl
, &new_dacl
)))
651 LocalFree( desc
.Dacl
);
652 desc
.Dacl
= new_dacl
;
653 desc
.Control
|= SE_DACL_PRESENT
;
656 if (pListOfAuditEntries
)
660 if ((ret
= SetEntriesInAclW( cCountOfAuditEntries
, pListOfAuditEntries
, desc
.Sacl
, &new_sacl
)))
663 LocalFree( desc
.Sacl
);
664 desc
.Sacl
= new_sacl
;
665 desc
.Control
|= SE_SACL_PRESENT
;
668 *lpdwBufferLength
= RtlLengthSecurityDescriptor( &desc
);
669 *pNewSD
= LocalAlloc( LMEM_FIXED
, *lpdwBufferLength
);
671 if ((status
= RtlMakeSelfRelativeSD( &desc
, *pNewSD
, lpdwBufferLength
)) != STATUS_SUCCESS
)
673 ret
= RtlNtStatusToDosError( status
);
674 LocalFree( *pNewSD
);
679 /* free absolute descriptor */
680 LocalFree( desc
.Owner
);
681 LocalFree( desc
.Group
);
682 LocalFree( desc
.Sacl
);
683 LocalFree( desc
.Dacl
);
688 static const WCHAR SE_CREATE_TOKEN_NAME_W
[] =
689 { 'S','e','C','r','e','a','t','e','T','o','k','e','n','P','r','i','v','i','l','e','g','e',0 };
690 static const WCHAR SE_ASSIGNPRIMARYTOKEN_NAME_W
[] =
691 { '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 };
692 static const WCHAR SE_LOCK_MEMORY_NAME_W
[] =
693 { 'S','e','L','o','c','k','M','e','m','o','r','y','P','r','i','v','i','l','e','g','e',0 };
694 static const WCHAR SE_INCREASE_QUOTA_NAME_W
[] =
695 { '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 };
696 static const WCHAR SE_MACHINE_ACCOUNT_NAME_W
[] =
697 { '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 };
698 static const WCHAR SE_TCB_NAME_W
[] =
699 { 'S','e','T','c','b','P','r','i','v','i','l','e','g','e',0 };
700 static const WCHAR SE_SECURITY_NAME_W
[] =
701 { 'S','e','S','e','c','u','r','i','t','y','P','r','i','v','i','l','e','g','e',0 };
702 static const WCHAR SE_TAKE_OWNERSHIP_NAME_W
[] =
703 { '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 };
704 static const WCHAR SE_LOAD_DRIVER_NAME_W
[] =
705 { 'S','e','L','o','a','d','D','r','i','v','e','r','P','r','i','v','i','l','e','g','e',0 };
706 static const WCHAR SE_SYSTEM_PROFILE_NAME_W
[] =
707 { '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 };
708 static const WCHAR SE_SYSTEMTIME_NAME_W
[] =
709 { 'S','e','S','y','s','t','e','m','t','i','m','e','P','r','i','v','i','l','e','g','e',0 };
710 static const WCHAR SE_PROF_SINGLE_PROCESS_NAME_W
[] =
711 { '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 };
712 static const WCHAR SE_INC_BASE_PRIORITY_NAME_W
[] =
713 { '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 };
714 static const WCHAR SE_CREATE_PAGEFILE_NAME_W
[] =
715 { '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 };
716 static const WCHAR SE_CREATE_PERMANENT_NAME_W
[] =
717 { '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 };
718 static const WCHAR SE_BACKUP_NAME_W
[] =
719 { 'S','e','B','a','c','k','u','p','P','r','i','v','i','l','e','g','e',0 };
720 static const WCHAR SE_RESTORE_NAME_W
[] =
721 { 'S','e','R','e','s','t','o','r','e','P','r','i','v','i','l','e','g','e',0 };
722 static const WCHAR SE_SHUTDOWN_NAME_W
[] =
723 { 'S','e','S','h','u','t','d','o','w','n','P','r','i','v','i','l','e','g','e',0 };
724 static const WCHAR SE_DEBUG_NAME_W
[] =
725 { 'S','e','D','e','b','u','g','P','r','i','v','i','l','e','g','e',0 };
726 static const WCHAR SE_AUDIT_NAME_W
[] =
727 { 'S','e','A','u','d','i','t','P','r','i','v','i','l','e','g','e',0 };
728 static const WCHAR SE_SYSTEM_ENVIRONMENT_NAME_W
[] =
729 { '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 };
730 static const WCHAR SE_CHANGE_NOTIFY_NAME_W
[] =
731 { 'S','e','C','h','a','n','g','e','N','o','t','i','f','y','P','r','i','v','i','l','e','g','e',0 };
732 static const WCHAR SE_REMOTE_SHUTDOWN_NAME_W
[] =
733 { '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 };
734 static const WCHAR SE_UNDOCK_NAME_W
[] =
735 { 'S','e','U','n','d','o','c','k','P','r','i','v','i','l','e','g','e',0 };
736 static const WCHAR SE_SYNC_AGENT_NAME_W
[] =
737 { 'S','e','S','y','n','c','A','g','e','n','t','P','r','i','v','i','l','e','g','e',0 };
738 static const WCHAR SE_ENABLE_DELEGATION_NAME_W
[] =
739 { '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 };
740 static const WCHAR SE_MANAGE_VOLUME_NAME_W
[] =
741 { 'S','e','M','a','n','a','g','e','V','o','l','u','m','e','P','r','i','v','i','l','e','g','e',0 };
742 static const WCHAR SE_IMPERSONATE_NAME_W
[] =
743 { 'S','e','I','m','p','e','r','s','o','n','a','t','e','P','r','i','v','i','l','e','g','e',0 };
744 static const WCHAR SE_CREATE_GLOBAL_NAME_W
[] =
745 { 'S','e','C','r','e','a','t','e','G','l','o','b','a','l','P','r','i','v','i','l','e','g','e',0 };
747 static const WCHAR
* const WellKnownPrivNames
[SE_MAX_WELL_KNOWN_PRIVILEGE
+ 1] =
751 SE_CREATE_TOKEN_NAME_W
,
752 SE_ASSIGNPRIMARYTOKEN_NAME_W
,
753 SE_LOCK_MEMORY_NAME_W
,
754 SE_INCREASE_QUOTA_NAME_W
,
755 SE_MACHINE_ACCOUNT_NAME_W
,
758 SE_TAKE_OWNERSHIP_NAME_W
,
759 SE_LOAD_DRIVER_NAME_W
,
760 SE_SYSTEM_PROFILE_NAME_W
,
761 SE_SYSTEMTIME_NAME_W
,
762 SE_PROF_SINGLE_PROCESS_NAME_W
,
763 SE_INC_BASE_PRIORITY_NAME_W
,
764 SE_CREATE_PAGEFILE_NAME_W
,
765 SE_CREATE_PERMANENT_NAME_W
,
771 SE_SYSTEM_ENVIRONMENT_NAME_W
,
772 SE_CHANGE_NOTIFY_NAME_W
,
773 SE_REMOTE_SHUTDOWN_NAME_W
,
775 SE_SYNC_AGENT_NAME_W
,
776 SE_ENABLE_DELEGATION_NAME_W
,
777 SE_MANAGE_VOLUME_NAME_W
,
778 SE_IMPERSONATE_NAME_W
,
779 SE_CREATE_GLOBAL_NAME_W
,
782 const WCHAR
*get_wellknown_privilege_name(const LUID
*luid
)
784 if (luid
->HighPart
|| luid
->LowPart
< SE_MIN_WELL_KNOWN_PRIVILEGE
||
785 luid
->LowPart
> SE_MAX_WELL_KNOWN_PRIVILEGE
|| !WellKnownPrivNames
[luid
->LowPart
])
788 return WellKnownPrivNames
[luid
->LowPart
];
791 /******************************************************************************
792 * LookupPrivilegeValueW [ADVAPI32.@]
794 * See LookupPrivilegeValueA.
797 LookupPrivilegeValueW( LPCWSTR lpSystemName
, LPCWSTR lpName
, PLUID lpLuid
)
801 TRACE("%s,%s,%p\n",debugstr_w(lpSystemName
), debugstr_w(lpName
), lpLuid
);
803 if (!ADVAPI_IsLocalComputer(lpSystemName
))
805 SetLastError(RPC_S_SERVER_UNAVAILABLE
);
810 SetLastError(ERROR_NO_SUCH_PRIVILEGE
);
813 for( i
=SE_MIN_WELL_KNOWN_PRIVILEGE
; i
<=SE_MAX_WELL_KNOWN_PRIVILEGE
; i
++ )
815 if( !WellKnownPrivNames
[i
] )
817 if( strcmpiW( WellKnownPrivNames
[i
], lpName
) )
820 lpLuid
->HighPart
= 0;
821 TRACE( "%s -> %08x-%08x\n",debugstr_w( lpSystemName
),
822 lpLuid
->HighPart
, lpLuid
->LowPart
);
825 SetLastError(ERROR_NO_SUCH_PRIVILEGE
);
829 /******************************************************************************
830 * LookupPrivilegeValueA [ADVAPI32.@]
832 * Retrieves LUID used on a system to represent the privilege name.
835 * lpSystemName [I] Name of the system
836 * lpName [I] Name of the privilege
837 * lpLuid [O] Destination for the resulting LUID
840 * Success: TRUE. lpLuid contains the requested LUID.
844 LookupPrivilegeValueA( LPCSTR lpSystemName
, LPCSTR lpName
, PLUID lpLuid
)
846 UNICODE_STRING lpSystemNameW
;
847 UNICODE_STRING lpNameW
;
850 RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW
, lpSystemName
);
851 RtlCreateUnicodeStringFromAsciiz(&lpNameW
,lpName
);
852 ret
= LookupPrivilegeValueW(lpSystemNameW
.Buffer
, lpNameW
.Buffer
, lpLuid
);
853 RtlFreeUnicodeString(&lpNameW
);
854 RtlFreeUnicodeString(&lpSystemNameW
);
858 BOOL WINAPI
LookupPrivilegeDisplayNameA( LPCSTR lpSystemName
, LPCSTR lpName
, LPSTR lpDisplayName
,
859 LPDWORD cchDisplayName
, LPDWORD lpLanguageId
)
861 FIXME("%s %s %s %p %p - stub\n", debugstr_a(lpSystemName
), debugstr_a(lpName
),
862 debugstr_a(lpDisplayName
), cchDisplayName
, lpLanguageId
);
867 BOOL WINAPI
LookupPrivilegeDisplayNameW( LPCWSTR lpSystemName
, LPCWSTR lpName
, LPWSTR lpDisplayName
,
868 LPDWORD cchDisplayName
, LPDWORD lpLanguageId
)
870 FIXME("%s %s %s %p %p - stub\n", debugstr_w(lpSystemName
), debugstr_w(lpName
),
871 debugstr_w(lpDisplayName
), cchDisplayName
, lpLanguageId
);
876 /******************************************************************************
877 * LookupPrivilegeNameA [ADVAPI32.@]
879 * See LookupPrivilegeNameW.
882 LookupPrivilegeNameA( LPCSTR lpSystemName
, PLUID lpLuid
, LPSTR lpName
,
885 UNICODE_STRING lpSystemNameW
;
889 TRACE("%s %p %p %p\n", debugstr_a(lpSystemName
), lpLuid
, lpName
, cchName
);
891 RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW
, lpSystemName
);
892 ret
= LookupPrivilegeNameW(lpSystemNameW
.Buffer
, lpLuid
, NULL
, &wLen
);
893 if (!ret
&& GetLastError() == ERROR_INSUFFICIENT_BUFFER
)
895 LPWSTR lpNameW
= heap_alloc(wLen
* sizeof(WCHAR
));
897 ret
= LookupPrivilegeNameW(lpSystemNameW
.Buffer
, lpLuid
, lpNameW
,
901 /* Windows crashes if cchName is NULL, so will I */
902 unsigned int len
= WideCharToMultiByte(CP_ACP
, 0, lpNameW
, -1, lpName
,
903 *cchName
, NULL
, NULL
);
907 /* WideCharToMultiByte failed */
910 else if (len
> *cchName
)
913 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
918 /* WideCharToMultiByte succeeded, output length needs to be
919 * length not including NULL terminator
926 RtlFreeUnicodeString(&lpSystemNameW
);
930 /******************************************************************************
931 * LookupPrivilegeNameW [ADVAPI32.@]
933 * Retrieves the privilege name referred to by the LUID lpLuid.
936 * lpSystemName [I] Name of the system
937 * lpLuid [I] Privilege value
938 * lpName [O] Name of the privilege
939 * cchName [I/O] Number of characters in lpName.
942 * Success: TRUE. lpName contains the name of the privilege whose value is
947 * Only well-known privilege names (those defined in winnt.h) can be retrieved
948 * using this function.
949 * If the length of lpName is too small, on return *cchName will contain the
950 * number of WCHARs needed to contain the privilege, including the NULL
951 * terminator, and GetLastError will return ERROR_INSUFFICIENT_BUFFER.
952 * On success, *cchName will contain the number of characters stored in
953 * lpName, NOT including the NULL terminator.
956 LookupPrivilegeNameW( LPCWSTR lpSystemName
, PLUID lpLuid
, LPWSTR lpName
,
961 TRACE("%s,%p,%p,%p\n",debugstr_w(lpSystemName
), lpLuid
, lpName
, cchName
);
963 if (!ADVAPI_IsLocalComputer(lpSystemName
))
965 SetLastError(RPC_S_SERVER_UNAVAILABLE
);
968 if (lpLuid
->HighPart
|| (lpLuid
->LowPart
< SE_MIN_WELL_KNOWN_PRIVILEGE
||
969 lpLuid
->LowPart
> SE_MAX_WELL_KNOWN_PRIVILEGE
))
971 SetLastError(ERROR_NO_SUCH_PRIVILEGE
);
974 privNameLen
= strlenW(WellKnownPrivNames
[lpLuid
->LowPart
]);
975 /* Windows crashes if cchName is NULL, so will I */
976 if (*cchName
<= privNameLen
)
978 *cchName
= privNameLen
+ 1;
979 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
984 strcpyW(lpName
, WellKnownPrivNames
[lpLuid
->LowPart
]);
985 *cchName
= privNameLen
;
990 /******************************************************************************
991 * GetFileSecurityA [ADVAPI32.@]
993 * Obtains Specified information about the security of a file or directory.
996 * lpFileName [I] Name of the file to get info for
997 * RequestedInformation [I] SE_ flags from "winnt.h"
998 * pSecurityDescriptor [O] Destination for security information
999 * nLength [I] Length of pSecurityDescriptor
1000 * lpnLengthNeeded [O] Destination for length of returned security information
1003 * Success: TRUE. pSecurityDescriptor contains the requested information.
1004 * Failure: FALSE. lpnLengthNeeded contains the required space to return the info.
1007 * The information returned is constrained by the callers access rights and
1011 GetFileSecurityA( LPCSTR lpFileName
,
1012 SECURITY_INFORMATION RequestedInformation
,
1013 PSECURITY_DESCRIPTOR pSecurityDescriptor
,
1014 DWORD nLength
, LPDWORD lpnLengthNeeded
)
1019 name
= SERV_dup(lpFileName
);
1020 r
= GetFileSecurityW( name
, RequestedInformation
, pSecurityDescriptor
,
1021 nLength
, lpnLengthNeeded
);
1027 /******************************************************************************
1028 * LookupAccountSidA [ADVAPI32.@]
1035 IN OUT LPDWORD accountSize
,
1037 IN OUT LPDWORD domainSize
,
1038 OUT PSID_NAME_USE name_use
)
1043 LPWSTR accountW
= NULL
;
1044 LPWSTR domainW
= NULL
;
1045 DWORD accountSizeW
= *accountSize
;
1046 DWORD domainSizeW
= *domainSize
;
1048 systemW
= SERV_dup(system
);
1050 accountW
= heap_alloc( accountSizeW
* sizeof(WCHAR
) );
1052 domainW
= heap_alloc( domainSizeW
* sizeof(WCHAR
) );
1054 r
= LookupAccountSidW( systemW
, sid
, accountW
, &accountSizeW
, domainW
, &domainSizeW
, name_use
);
1057 if (accountW
&& *accountSize
) {
1058 len
= WideCharToMultiByte( CP_ACP
, 0, accountW
, -1, NULL
, 0, NULL
, NULL
);
1059 WideCharToMultiByte( CP_ACP
, 0, accountW
, -1, account
, len
, NULL
, NULL
);
1062 *accountSize
= accountSizeW
+ 1;
1064 if (domainW
&& *domainSize
) {
1065 len
= WideCharToMultiByte( CP_ACP
, 0, domainW
, -1, NULL
, 0, NULL
, NULL
);
1066 WideCharToMultiByte( CP_ACP
, 0, domainW
, -1, domain
, len
, NULL
, NULL
);
1069 *domainSize
= domainSizeW
+ 1;
1073 *accountSize
= accountSizeW
+ 1;
1074 *domainSize
= domainSizeW
+ 1;
1077 heap_free( systemW
);
1078 heap_free( accountW
);
1079 heap_free( domainW
);
1084 /******************************************************************************
1085 * LookupAccountSidLocalA [ADVAPI32.@]
1088 LookupAccountSidLocalA(
1091 LPDWORD accountSize
,
1094 PSID_NAME_USE name_use
)
1096 return LookupAccountSidA(NULL
, sid
, account
, accountSize
, domain
, domainSize
, name_use
);
1099 /******************************************************************************
1100 * LookupAccountSidW [ADVAPI32.@]
1117 IN OUT LPDWORD accountSize
,
1119 IN OUT LPDWORD domainSize
,
1120 OUT PSID_NAME_USE name_use
)
1123 const WCHAR
* ac
= NULL
;
1124 const WCHAR
* dm
= NULL
;
1125 SID_NAME_USE use
= 0;
1126 LPWSTR computer_name
= NULL
;
1127 LPWSTR account_name
= NULL
;
1129 TRACE("(%s,sid=%s,%p,%p(%u),%p,%p(%u),%p)\n",
1130 debugstr_w(system
),debugstr_sid(sid
),
1131 account
,accountSize
,accountSize
?*accountSize
:0,
1132 domain
,domainSize
,domainSize
?*domainSize
:0,
1135 if (!ADVAPI_IsLocalComputer(system
)) {
1136 FIXME("Only local computer supported!\n");
1137 SetLastError(RPC_S_SERVER_UNAVAILABLE
);
1141 /* check the well known SIDs first */
1142 for (i
= 0; i
<= WinAccountProtectedUsersSid
; i
++) {
1143 if (IsWellKnownSid(sid
, i
)) {
1144 for (j
= 0; j
< ARRAY_SIZE(ACCOUNT_SIDS
); j
++) {
1145 if (ACCOUNT_SIDS
[j
].type
== i
) {
1146 ac
= ACCOUNT_SIDS
[j
].account
;
1147 dm
= ACCOUNT_SIDS
[j
].domain
;
1148 use
= ACCOUNT_SIDS
[j
].name_use
;
1158 /* check for the local computer next */
1159 if (ADVAPI_GetComputerSid(&local
)) {
1160 DWORD size
= MAX_COMPUTERNAME_LENGTH
+ 1;
1163 computer_name
= heap_alloc(size
* sizeof(WCHAR
));
1164 result
= GetComputerNameW(computer_name
, &size
);
1167 if (EqualSid(sid
, &local
)) {
1172 local
.SubAuthorityCount
++;
1174 if (EqualPrefixSid(sid
, &local
)) {
1177 switch (((MAX_SID
*)sid
)->SubAuthority
[4]) {
1178 case DOMAIN_USER_RID_ADMIN
:
1181 case DOMAIN_USER_RID_GUEST
:
1184 case DOMAIN_GROUP_RID_ADMINS
:
1187 case DOMAIN_GROUP_RID_USERS
:
1191 case DOMAIN_GROUP_RID_GUESTS
:
1194 case DOMAIN_GROUP_RID_COMPUTERS
:
1195 ac
= Domain_Computers
;
1197 case DOMAIN_GROUP_RID_CONTROLLERS
:
1198 ac
= Domain_Controllers
;
1200 case DOMAIN_GROUP_RID_CERT_ADMINS
:
1201 ac
= Cert_Publishers
;
1203 case DOMAIN_GROUP_RID_SCHEMA_ADMINS
:
1206 case DOMAIN_GROUP_RID_ENTERPRISE_ADMINS
:
1207 ac
= Enterprise_Admins
;
1209 case DOMAIN_GROUP_RID_POLICY_ADMINS
:
1210 ac
= Group_Policy_Creator_Owners
;
1212 case DOMAIN_ALIAS_RID_RAS_SERVERS
:
1213 ac
= RAS_and_IAS_Servers
;
1215 case 1000: /* first user account */
1217 account_name
= heap_alloc(size
* sizeof(WCHAR
));
1218 if (GetUserNameW(account_name
, &size
))
1235 DWORD ac_len
= lstrlenW(ac
);
1236 DWORD dm_len
= lstrlenW(dm
);
1239 if (*accountSize
> ac_len
) {
1241 lstrcpyW(account
, ac
);
1243 if (*domainSize
> dm_len
) {
1245 lstrcpyW(domain
, dm
);
1247 if ((*accountSize
&& *accountSize
< ac_len
) ||
1248 (!account
&& !*accountSize
&& ac_len
) ||
1249 (*domainSize
&& *domainSize
< dm_len
) ||
1250 (!domain
&& !*domainSize
&& dm_len
))
1252 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
1256 *domainSize
= dm_len
;
1258 *domainSize
= dm_len
+ 1;
1260 *accountSize
= ac_len
;
1262 *accountSize
= ac_len
+ 1;
1264 heap_free(account_name
);
1265 heap_free(computer_name
);
1266 if (status
) *name_use
= use
;
1270 heap_free(account_name
);
1271 heap_free(computer_name
);
1272 SetLastError(ERROR_NONE_MAPPED
);
1276 /******************************************************************************
1277 * LookupAccountSidLocalW [ADVAPI32.@]
1280 LookupAccountSidLocalW(
1283 LPDWORD accountSize
,
1286 PSID_NAME_USE name_use
)
1288 return LookupAccountSidW(NULL
, sid
, account
, accountSize
, domain
, domainSize
, name_use
);
1291 /******************************************************************************
1292 * SetFileSecurityA [ADVAPI32.@]
1294 * See SetFileSecurityW.
1296 BOOL WINAPI
SetFileSecurityA( LPCSTR lpFileName
,
1297 SECURITY_INFORMATION RequestedInformation
,
1298 PSECURITY_DESCRIPTOR pSecurityDescriptor
)
1303 name
= SERV_dup(lpFileName
);
1304 r
= SetFileSecurityW( name
, RequestedInformation
, pSecurityDescriptor
);
1310 /******************************************************************************
1311 * QueryWindows31FilesMigration [ADVAPI32.@]
1317 QueryWindows31FilesMigration( DWORD x1
)
1319 FIXME("(%d):stub\n",x1
);
1323 /******************************************************************************
1324 * SynchronizeWindows31FilesAndWindowsNTRegistry [ADVAPI32.@]
1333 SynchronizeWindows31FilesAndWindowsNTRegistry( DWORD x1
, DWORD x2
, DWORD x3
,
1336 FIXME("(0x%08x,0x%08x,0x%08x,0x%08x):stub\n",x1
,x2
,x3
,x4
);
1340 /******************************************************************************
1341 * NotifyBootConfigStatus [ADVAPI32.@]
1347 NotifyBootConfigStatus( BOOL x1
)
1349 FIXME("(0x%08d):stub\n",x1
);
1353 /******************************************************************************
1354 * LookupAccountNameA [ADVAPI32.@]
1362 LPSTR ReferencedDomainName
,
1363 IN OUT LPDWORD cbReferencedDomainName
,
1364 OUT PSID_NAME_USE name_use
)
1367 UNICODE_STRING lpSystemW
;
1368 UNICODE_STRING lpAccountW
;
1369 LPWSTR lpReferencedDomainNameW
= NULL
;
1371 RtlCreateUnicodeStringFromAsciiz(&lpSystemW
, system
);
1372 RtlCreateUnicodeStringFromAsciiz(&lpAccountW
, account
);
1374 if (ReferencedDomainName
)
1375 lpReferencedDomainNameW
= heap_alloc(*cbReferencedDomainName
* sizeof(WCHAR
));
1377 ret
= LookupAccountNameW(lpSystemW
.Buffer
, lpAccountW
.Buffer
, sid
, cbSid
, lpReferencedDomainNameW
,
1378 cbReferencedDomainName
, name_use
);
1380 if (ret
&& lpReferencedDomainNameW
)
1382 WideCharToMultiByte(CP_ACP
, 0, lpReferencedDomainNameW
, -1,
1383 ReferencedDomainName
, *cbReferencedDomainName
+1, NULL
, NULL
);
1386 RtlFreeUnicodeString(&lpSystemW
);
1387 RtlFreeUnicodeString(&lpAccountW
);
1388 heap_free(lpReferencedDomainNameW
);
1393 /******************************************************************************
1394 * lookup_user_account_name
1396 static BOOL
lookup_user_account_name(PSID Sid
, PDWORD cbSid
, LPWSTR ReferencedDomainName
,
1397 LPDWORD cchReferencedDomainName
, PSID_NAME_USE peUse
)
1399 char buffer
[sizeof(TOKEN_USER
) + sizeof(SID
) + sizeof(DWORD
)*SID_MAX_SUB_AUTHORITIES
];
1400 DWORD len
= sizeof(buffer
);
1404 WCHAR domainName
[MAX_COMPUTERNAME_LENGTH
+ 1];
1407 if (!OpenThreadToken(GetCurrentThread(), TOKEN_READ
, TRUE
, &token
))
1409 if (GetLastError() != ERROR_NO_TOKEN
) return FALSE
;
1410 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_READ
, &token
)) return FALSE
;
1413 ret
= GetTokenInformation(token
, TokenUser
, buffer
, len
, &len
);
1414 CloseHandle( token
);
1416 if (!ret
) return FALSE
;
1418 pSid
= ((TOKEN_USER
*)buffer
)->User
.Sid
;
1420 if (Sid
!= NULL
&& (*cbSid
>= GetLengthSid(pSid
)))
1421 CopySid(*cbSid
, Sid
, pSid
);
1422 if (*cbSid
< GetLengthSid(pSid
))
1424 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
1427 *cbSid
= GetLengthSid(pSid
);
1429 nameLen
= MAX_COMPUTERNAME_LENGTH
+ 1;
1430 if (!GetComputerNameW(domainName
, &nameLen
))
1435 if (*cchReferencedDomainName
<= nameLen
|| !ret
)
1437 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
1441 else if (ReferencedDomainName
)
1442 strcpyW(ReferencedDomainName
, domainName
);
1444 *cchReferencedDomainName
= nameLen
;
1447 *peUse
= SidTypeUser
;
1452 /******************************************************************************
1453 * lookup_computer_account_name
1455 static BOOL
lookup_computer_account_name(PSID Sid
, PDWORD cbSid
, LPWSTR ReferencedDomainName
,
1456 LPDWORD cchReferencedDomainName
, PSID_NAME_USE peUse
)
1460 WCHAR domainName
[MAX_COMPUTERNAME_LENGTH
+ 1];
1463 if ((ret
= ADVAPI_GetComputerSid(&local
)))
1465 if (Sid
!= NULL
&& (*cbSid
>= GetLengthSid(&local
)))
1466 CopySid(*cbSid
, Sid
, &local
);
1467 if (*cbSid
< GetLengthSid(&local
))
1469 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
1472 *cbSid
= GetLengthSid(&local
);
1475 nameLen
= MAX_COMPUTERNAME_LENGTH
+ 1;
1476 if (!GetComputerNameW(domainName
, &nameLen
))
1481 if (*cchReferencedDomainName
<= nameLen
|| !ret
)
1483 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
1487 else if (ReferencedDomainName
)
1488 strcpyW(ReferencedDomainName
, domainName
);
1490 *cchReferencedDomainName
= nameLen
;
1493 *peUse
= SidTypeDomain
;
1498 static void split_domain_account( const LSA_UNICODE_STRING
*str
, LSA_UNICODE_STRING
*account
,
1499 LSA_UNICODE_STRING
*domain
)
1501 WCHAR
*p
= str
->Buffer
+ str
->Length
/ sizeof(WCHAR
) - 1;
1503 while (p
> str
->Buffer
&& *p
!= '\\') p
--;
1507 domain
->Buffer
= str
->Buffer
;
1508 domain
->Length
= (p
- str
->Buffer
) * sizeof(WCHAR
);
1510 account
->Buffer
= p
+ 1;
1511 account
->Length
= str
->Length
- ((p
- str
->Buffer
+ 1) * sizeof(WCHAR
));
1515 domain
->Buffer
= NULL
;
1518 account
->Buffer
= str
->Buffer
;
1519 account
->Length
= str
->Length
;
1523 static BOOL
match_domain( ULONG idx
, const LSA_UNICODE_STRING
*domain
)
1525 ULONG len
= strlenW( ACCOUNT_SIDS
[idx
].domain
);
1527 if (len
== domain
->Length
/ sizeof(WCHAR
) && !strncmpiW( domain
->Buffer
, ACCOUNT_SIDS
[idx
].domain
, len
))
1533 static BOOL
match_account( ULONG idx
, const LSA_UNICODE_STRING
*account
)
1535 ULONG len
= strlenW( ACCOUNT_SIDS
[idx
].account
);
1537 if (len
== account
->Length
/ sizeof(WCHAR
) && !strncmpiW( account
->Buffer
, ACCOUNT_SIDS
[idx
].account
, len
))
1540 if (ACCOUNT_SIDS
[idx
].alias
)
1542 len
= strlenW( ACCOUNT_SIDS
[idx
].alias
);
1543 if (len
== account
->Length
/ sizeof(WCHAR
) && !strncmpiW( account
->Buffer
, ACCOUNT_SIDS
[idx
].alias
, len
))
1550 * Helper function for LookupAccountNameW
1552 BOOL
lookup_local_wellknown_name( const LSA_UNICODE_STRING
*account_and_domain
,
1553 PSID Sid
, LPDWORD cbSid
,
1554 LPWSTR ReferencedDomainName
,
1555 LPDWORD cchReferencedDomainName
,
1556 PSID_NAME_USE peUse
, BOOL
*handled
)
1559 LSA_UNICODE_STRING account
, domain
;
1564 split_domain_account( account_and_domain
, &account
, &domain
);
1566 for (i
= 0; i
< ARRAY_SIZE(ACCOUNT_SIDS
); i
++)
1568 /* check domain first */
1569 if (domain
.Buffer
&& !match_domain( i
, &domain
)) continue;
1571 if (match_account( i
, &account
))
1573 DWORD len
, sidLen
= SECURITY_MAX_SID_SIZE
;
1575 if (!(pSid
= heap_alloc( sidLen
))) return FALSE
;
1577 if ((ret
= CreateWellKnownSid( ACCOUNT_SIDS
[i
].type
, NULL
, pSid
, &sidLen
)))
1579 if (*cbSid
< sidLen
)
1581 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
1586 CopySid(*cbSid
, Sid
, pSid
);
1591 len
= strlenW( ACCOUNT_SIDS
[i
].domain
);
1592 if (*cchReferencedDomainName
<= len
|| !ret
)
1594 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
1598 else if (ReferencedDomainName
)
1600 strcpyW( ReferencedDomainName
, ACCOUNT_SIDS
[i
].domain
);
1603 *cchReferencedDomainName
= len
;
1605 *peUse
= ACCOUNT_SIDS
[i
].name_use
;
1615 BOOL
lookup_local_user_name( const LSA_UNICODE_STRING
*account_and_domain
,
1616 PSID Sid
, LPDWORD cbSid
,
1617 LPWSTR ReferencedDomainName
,
1618 LPDWORD cchReferencedDomainName
,
1619 PSID_NAME_USE peUse
, BOOL
*handled
)
1622 LPWSTR userName
= NULL
;
1623 LSA_UNICODE_STRING account
, domain
;
1627 split_domain_account( account_and_domain
, &account
, &domain
);
1629 /* Let the current Unix user id masquerade as first Windows user account */
1631 nameLen
= UNLEN
+ 1;
1632 if (!(userName
= heap_alloc( nameLen
* sizeof(WCHAR
) ))) return FALSE
;
1636 /* check to make sure this account is on this computer */
1637 if (GetComputerNameW( userName
, &nameLen
) &&
1638 (domain
.Length
/ sizeof(WCHAR
) != nameLen
|| strncmpW( domain
.Buffer
, userName
, nameLen
)))
1640 SetLastError(ERROR_NONE_MAPPED
);
1643 nameLen
= UNLEN
+ 1;
1646 if (GetUserNameW( userName
, &nameLen
) &&
1647 account
.Length
/ sizeof(WCHAR
) == nameLen
- 1 && !strncmpW( account
.Buffer
, userName
, nameLen
- 1 ))
1649 ret
= lookup_user_account_name( Sid
, cbSid
, ReferencedDomainName
, cchReferencedDomainName
, peUse
);
1654 nameLen
= UNLEN
+ 1;
1655 if (GetComputerNameW( userName
, &nameLen
) &&
1656 account
.Length
/ sizeof(WCHAR
) == nameLen
&& !strncmpW( account
.Buffer
, userName
, nameLen
))
1658 ret
= lookup_computer_account_name( Sid
, cbSid
, ReferencedDomainName
, cchReferencedDomainName
, peUse
);
1663 heap_free(userName
);
1667 /******************************************************************************
1668 * LookupAccountNameW [ADVAPI32.@]
1670 BOOL WINAPI
LookupAccountNameW( LPCWSTR lpSystemName
, LPCWSTR lpAccountName
, PSID Sid
,
1671 LPDWORD cbSid
, LPWSTR ReferencedDomainName
,
1672 LPDWORD cchReferencedDomainName
, PSID_NAME_USE peUse
)
1675 LSA_UNICODE_STRING account
;
1677 TRACE("%s %s %p %p %p %p %p\n", debugstr_w(lpSystemName
), debugstr_w(lpAccountName
),
1678 Sid
, cbSid
, ReferencedDomainName
, cchReferencedDomainName
, peUse
);
1680 if (!ADVAPI_IsLocalComputer( lpSystemName
))
1682 FIXME("remote computer not supported\n");
1683 SetLastError( RPC_S_SERVER_UNAVAILABLE
);
1687 if (!lpAccountName
|| !strcmpW( lpAccountName
, Blank
))
1689 lpAccountName
= BUILTIN
;
1692 RtlInitUnicodeString( &account
, lpAccountName
);
1694 /* Check well known SIDs first */
1695 ret
= lookup_local_wellknown_name( &account
, Sid
, cbSid
, ReferencedDomainName
,
1696 cchReferencedDomainName
, peUse
, &handled
);
1700 /* Check user names */
1701 ret
= lookup_local_user_name( &account
, Sid
, cbSid
, ReferencedDomainName
,
1702 cchReferencedDomainName
, peUse
, &handled
);
1706 SetLastError( ERROR_NONE_MAPPED
);
1710 /******************************************************************************
1711 * AccessCheckAndAuditAlarmA [ADVAPI32.@]
1713 BOOL WINAPI
AccessCheckAndAuditAlarmA(LPCSTR Subsystem
, LPVOID HandleId
, LPSTR ObjectTypeName
,
1714 LPSTR ObjectName
, PSECURITY_DESCRIPTOR SecurityDescriptor
, DWORD DesiredAccess
,
1715 PGENERIC_MAPPING GenericMapping
, BOOL ObjectCreation
, LPDWORD GrantedAccess
,
1716 LPBOOL AccessStatus
, LPBOOL pfGenerateOnClose
)
1718 FIXME("stub (%s,%p,%s,%s,%p,%08x,%p,%x,%p,%p,%p)\n", debugstr_a(Subsystem
),
1719 HandleId
, debugstr_a(ObjectTypeName
), debugstr_a(ObjectName
),
1720 SecurityDescriptor
, DesiredAccess
, GenericMapping
,
1721 ObjectCreation
, GrantedAccess
, AccessStatus
, pfGenerateOnClose
);
1725 BOOL WINAPI
ObjectCloseAuditAlarmA(LPCSTR SubsystemName
, LPVOID HandleId
, BOOL GenerateOnClose
)
1727 FIXME("stub (%s,%p,%x)\n", debugstr_a(SubsystemName
), HandleId
, GenerateOnClose
);
1732 BOOL WINAPI
ObjectOpenAuditAlarmA(LPCSTR SubsystemName
, LPVOID HandleId
, LPSTR ObjectTypeName
,
1733 LPSTR ObjectName
, PSECURITY_DESCRIPTOR pSecurityDescriptor
, HANDLE ClientToken
, DWORD DesiredAccess
,
1734 DWORD GrantedAccess
, PPRIVILEGE_SET Privileges
, BOOL ObjectCreation
, BOOL AccessGranted
,
1735 LPBOOL GenerateOnClose
)
1737 FIXME("stub (%s,%p,%s,%s,%p,%p,0x%08x,0x%08x,%p,%x,%x,%p)\n", debugstr_a(SubsystemName
),
1738 HandleId
, debugstr_a(ObjectTypeName
), debugstr_a(ObjectName
), pSecurityDescriptor
,
1739 ClientToken
, DesiredAccess
, GrantedAccess
, Privileges
, ObjectCreation
, AccessGranted
,
1745 BOOL WINAPI
ObjectPrivilegeAuditAlarmA( LPCSTR SubsystemName
, LPVOID HandleId
, HANDLE ClientToken
,
1746 DWORD DesiredAccess
, PPRIVILEGE_SET Privileges
, BOOL AccessGranted
)
1748 FIXME("stub (%s,%p,%p,0x%08x,%p,%x)\n", debugstr_a(SubsystemName
), HandleId
, ClientToken
,
1749 DesiredAccess
, Privileges
, AccessGranted
);
1754 BOOL WINAPI
PrivilegedServiceAuditAlarmA( LPCSTR SubsystemName
, LPCSTR ServiceName
, HANDLE ClientToken
,
1755 PPRIVILEGE_SET Privileges
, BOOL AccessGranted
)
1757 FIXME("stub (%s,%s,%p,%p,%x)\n", debugstr_a(SubsystemName
), debugstr_a(ServiceName
),
1758 ClientToken
, Privileges
, AccessGranted
);
1763 /******************************************************************************
1764 * GetSecurityInfo [ADVAPI32.@]
1766 * Retrieves a copy of the security descriptor associated with an object.
1769 * hObject [I] A handle for the object.
1770 * ObjectType [I] The type of object.
1771 * SecurityInfo [I] A bitmask indicating what info to retrieve.
1772 * ppsidOwner [O] If non-null, receives a pointer to the owner SID.
1773 * ppsidGroup [O] If non-null, receives a pointer to the group SID.
1774 * ppDacl [O] If non-null, receives a pointer to the DACL.
1775 * ppSacl [O] If non-null, receives a pointer to the SACL.
1776 * ppSecurityDescriptor [O] Receives a pointer to the security descriptor,
1777 * which must be freed with LocalFree.
1780 * ERROR_SUCCESS if all's well, and a WIN32 error code otherwise.
1782 DWORD WINAPI
GetSecurityInfo(
1783 HANDLE hObject
, SE_OBJECT_TYPE ObjectType
,
1784 SECURITY_INFORMATION SecurityInfo
, PSID
*ppsidOwner
,
1785 PSID
*ppsidGroup
, PACL
*ppDacl
, PACL
*ppSacl
,
1786 PSECURITY_DESCRIPTOR
*ppSecurityDescriptor
1789 PSECURITY_DESCRIPTOR sd
;
1792 BOOL present
, defaulted
;
1794 /* A NULL descriptor is allowed if any one of the other pointers is not NULL */
1795 if (!(ppsidOwner
||ppsidGroup
||ppDacl
||ppSacl
||ppSecurityDescriptor
)) return ERROR_INVALID_PARAMETER
;
1797 /* If no descriptor, we have to check that there's a pointer for the requested information */
1798 if( !ppSecurityDescriptor
&& (
1799 ((SecurityInfo
& OWNER_SECURITY_INFORMATION
) && !ppsidOwner
)
1800 || ((SecurityInfo
& GROUP_SECURITY_INFORMATION
) && !ppsidGroup
)
1801 || ((SecurityInfo
& DACL_SECURITY_INFORMATION
) && !ppDacl
)
1802 || ((SecurityInfo
& SACL_SECURITY_INFORMATION
) && !ppSacl
) ))
1803 return ERROR_INVALID_PARAMETER
;
1808 status
= SERV_QueryServiceObjectSecurity(hObject
, SecurityInfo
, NULL
, 0, &n1
);
1811 status
= NtQuerySecurityObject(hObject
, SecurityInfo
, NULL
, 0, &n1
);
1814 if (status
!= STATUS_BUFFER_TOO_SMALL
&& status
!= STATUS_SUCCESS
)
1815 return RtlNtStatusToDosError(status
);
1817 sd
= LocalAlloc(0, n1
);
1819 return ERROR_NOT_ENOUGH_MEMORY
;
1824 status
= SERV_QueryServiceObjectSecurity(hObject
, SecurityInfo
, sd
, n1
, &n2
);
1827 status
= NtQuerySecurityObject(hObject
, SecurityInfo
, sd
, n1
, &n2
);
1830 if (status
!= STATUS_SUCCESS
)
1833 return RtlNtStatusToDosError(status
);
1839 GetSecurityDescriptorOwner(sd
, ppsidOwner
, &defaulted
);
1844 GetSecurityDescriptorGroup(sd
, ppsidGroup
, &defaulted
);
1849 GetSecurityDescriptorDacl(sd
, &present
, ppDacl
, &defaulted
);
1854 GetSecurityDescriptorSacl(sd
, &present
, ppSacl
, &defaulted
);
1856 if (ppSecurityDescriptor
)
1857 *ppSecurityDescriptor
= sd
;
1859 /* The security descriptor (sd) cannot be freed if ppSecurityDescriptor is
1860 * NULL, because native happily returns the SIDs and ACLs that are requested
1864 return ERROR_SUCCESS
;
1867 /******************************************************************************
1868 * GetSecurityInfoExA [ADVAPI32.@]
1870 DWORD WINAPI
GetSecurityInfoExA(
1871 HANDLE hObject
, SE_OBJECT_TYPE ObjectType
,
1872 SECURITY_INFORMATION SecurityInfo
, LPCSTR lpProvider
,
1873 LPCSTR lpProperty
, PACTRL_ACCESSA
*ppAccessList
,
1874 PACTRL_AUDITA
*ppAuditList
, LPSTR
*lppOwner
, LPSTR
*lppGroup
1878 return ERROR_BAD_PROVIDER
;
1881 /******************************************************************************
1882 * GetSecurityInfoExW [ADVAPI32.@]
1884 DWORD WINAPI
GetSecurityInfoExW(
1885 HANDLE hObject
, SE_OBJECT_TYPE ObjectType
,
1886 SECURITY_INFORMATION SecurityInfo
, LPCWSTR lpProvider
,
1887 LPCWSTR lpProperty
, PACTRL_ACCESSW
*ppAccessList
,
1888 PACTRL_AUDITW
*ppAuditList
, LPWSTR
*lppOwner
, LPWSTR
*lppGroup
1892 return ERROR_BAD_PROVIDER
;
1895 /******************************************************************************
1896 * BuildExplicitAccessWithNameA [ADVAPI32.@]
1898 VOID WINAPI
BuildExplicitAccessWithNameA( PEXPLICIT_ACCESSA pExplicitAccess
,
1899 LPSTR pTrusteeName
, DWORD AccessPermissions
,
1900 ACCESS_MODE AccessMode
, DWORD Inheritance
)
1902 TRACE("%p %s 0x%08x 0x%08x 0x%08x\n", pExplicitAccess
, debugstr_a(pTrusteeName
),
1903 AccessPermissions
, AccessMode
, Inheritance
);
1905 pExplicitAccess
->grfAccessPermissions
= AccessPermissions
;
1906 pExplicitAccess
->grfAccessMode
= AccessMode
;
1907 pExplicitAccess
->grfInheritance
= Inheritance
;
1909 pExplicitAccess
->Trustee
.pMultipleTrustee
= NULL
;
1910 pExplicitAccess
->Trustee
.MultipleTrusteeOperation
= NO_MULTIPLE_TRUSTEE
;
1911 pExplicitAccess
->Trustee
.TrusteeForm
= TRUSTEE_IS_NAME
;
1912 pExplicitAccess
->Trustee
.TrusteeType
= TRUSTEE_IS_UNKNOWN
;
1913 pExplicitAccess
->Trustee
.ptstrName
= pTrusteeName
;
1916 /******************************************************************************
1917 * BuildExplicitAccessWithNameW [ADVAPI32.@]
1919 VOID WINAPI
BuildExplicitAccessWithNameW( PEXPLICIT_ACCESSW pExplicitAccess
,
1920 LPWSTR pTrusteeName
, DWORD AccessPermissions
,
1921 ACCESS_MODE AccessMode
, DWORD Inheritance
)
1923 TRACE("%p %s 0x%08x 0x%08x 0x%08x\n", pExplicitAccess
, debugstr_w(pTrusteeName
),
1924 AccessPermissions
, AccessMode
, Inheritance
);
1926 pExplicitAccess
->grfAccessPermissions
= AccessPermissions
;
1927 pExplicitAccess
->grfAccessMode
= AccessMode
;
1928 pExplicitAccess
->grfInheritance
= Inheritance
;
1930 pExplicitAccess
->Trustee
.pMultipleTrustee
= NULL
;
1931 pExplicitAccess
->Trustee
.MultipleTrusteeOperation
= NO_MULTIPLE_TRUSTEE
;
1932 pExplicitAccess
->Trustee
.TrusteeForm
= TRUSTEE_IS_NAME
;
1933 pExplicitAccess
->Trustee
.TrusteeType
= TRUSTEE_IS_UNKNOWN
;
1934 pExplicitAccess
->Trustee
.ptstrName
= pTrusteeName
;
1937 /******************************************************************************
1938 * BuildTrusteeWithObjectsAndNameA [ADVAPI32.@]
1940 VOID WINAPI
BuildTrusteeWithObjectsAndNameA( PTRUSTEEA pTrustee
, POBJECTS_AND_NAME_A pObjName
,
1941 SE_OBJECT_TYPE ObjectType
, LPSTR ObjectTypeName
,
1942 LPSTR InheritedObjectTypeName
, LPSTR Name
)
1944 DWORD ObjectsPresent
= 0;
1946 TRACE("%p %p 0x%08x %p %p %s\n", pTrustee
, pObjName
,
1947 ObjectType
, ObjectTypeName
, InheritedObjectTypeName
, debugstr_a(Name
));
1949 /* Fill the OBJECTS_AND_NAME structure */
1950 pObjName
->ObjectType
= ObjectType
;
1951 if (ObjectTypeName
!= NULL
)
1953 ObjectsPresent
|= ACE_OBJECT_TYPE_PRESENT
;
1956 pObjName
->InheritedObjectTypeName
= InheritedObjectTypeName
;
1957 if (InheritedObjectTypeName
!= NULL
)
1959 ObjectsPresent
|= ACE_INHERITED_OBJECT_TYPE_PRESENT
;
1962 pObjName
->ObjectsPresent
= ObjectsPresent
;
1963 pObjName
->ptstrName
= Name
;
1965 /* Fill the TRUSTEE structure */
1966 pTrustee
->pMultipleTrustee
= NULL
;
1967 pTrustee
->MultipleTrusteeOperation
= NO_MULTIPLE_TRUSTEE
;
1968 pTrustee
->TrusteeForm
= TRUSTEE_IS_OBJECTS_AND_NAME
;
1969 pTrustee
->TrusteeType
= TRUSTEE_IS_UNKNOWN
;
1970 pTrustee
->ptstrName
= (LPSTR
)pObjName
;
1973 /******************************************************************************
1974 * BuildTrusteeWithObjectsAndNameW [ADVAPI32.@]
1976 VOID WINAPI
BuildTrusteeWithObjectsAndNameW( PTRUSTEEW pTrustee
, POBJECTS_AND_NAME_W pObjName
,
1977 SE_OBJECT_TYPE ObjectType
, LPWSTR ObjectTypeName
,
1978 LPWSTR InheritedObjectTypeName
, LPWSTR Name
)
1980 DWORD ObjectsPresent
= 0;
1982 TRACE("%p %p 0x%08x %p %p %s\n", pTrustee
, pObjName
,
1983 ObjectType
, ObjectTypeName
, InheritedObjectTypeName
, debugstr_w(Name
));
1985 /* Fill the OBJECTS_AND_NAME structure */
1986 pObjName
->ObjectType
= ObjectType
;
1987 if (ObjectTypeName
!= NULL
)
1989 ObjectsPresent
|= ACE_OBJECT_TYPE_PRESENT
;
1992 pObjName
->InheritedObjectTypeName
= InheritedObjectTypeName
;
1993 if (InheritedObjectTypeName
!= NULL
)
1995 ObjectsPresent
|= ACE_INHERITED_OBJECT_TYPE_PRESENT
;
1998 pObjName
->ObjectsPresent
= ObjectsPresent
;
1999 pObjName
->ptstrName
= Name
;
2001 /* Fill the TRUSTEE structure */
2002 pTrustee
->pMultipleTrustee
= NULL
;
2003 pTrustee
->MultipleTrusteeOperation
= NO_MULTIPLE_TRUSTEE
;
2004 pTrustee
->TrusteeForm
= TRUSTEE_IS_OBJECTS_AND_NAME
;
2005 pTrustee
->TrusteeType
= TRUSTEE_IS_UNKNOWN
;
2006 pTrustee
->ptstrName
= (LPWSTR
)pObjName
;
2009 /******************************************************************************
2010 * BuildTrusteeWithObjectsAndSidA [ADVAPI32.@]
2012 VOID WINAPI
BuildTrusteeWithObjectsAndSidA( PTRUSTEEA pTrustee
, POBJECTS_AND_SID pObjSid
,
2013 GUID
* pObjectGuid
, GUID
* pInheritedObjectGuid
, PSID pSid
)
2015 DWORD ObjectsPresent
= 0;
2017 TRACE("%p %p %p %p %p\n", pTrustee
, pObjSid
, pObjectGuid
, pInheritedObjectGuid
, pSid
);
2019 /* Fill the OBJECTS_AND_SID structure */
2020 if (pObjectGuid
!= NULL
)
2022 pObjSid
->ObjectTypeGuid
= *pObjectGuid
;
2023 ObjectsPresent
|= ACE_OBJECT_TYPE_PRESENT
;
2027 ZeroMemory(&pObjSid
->ObjectTypeGuid
,
2031 if (pInheritedObjectGuid
!= NULL
)
2033 pObjSid
->InheritedObjectTypeGuid
= *pInheritedObjectGuid
;
2034 ObjectsPresent
|= ACE_INHERITED_OBJECT_TYPE_PRESENT
;
2038 ZeroMemory(&pObjSid
->InheritedObjectTypeGuid
,
2042 pObjSid
->ObjectsPresent
= ObjectsPresent
;
2043 pObjSid
->pSid
= pSid
;
2045 /* Fill the TRUSTEE structure */
2046 pTrustee
->pMultipleTrustee
= NULL
;
2047 pTrustee
->MultipleTrusteeOperation
= NO_MULTIPLE_TRUSTEE
;
2048 pTrustee
->TrusteeForm
= TRUSTEE_IS_OBJECTS_AND_SID
;
2049 pTrustee
->TrusteeType
= TRUSTEE_IS_UNKNOWN
;
2050 pTrustee
->ptstrName
= (LPSTR
) pObjSid
;
2053 /******************************************************************************
2054 * BuildTrusteeWithObjectsAndSidW [ADVAPI32.@]
2056 VOID WINAPI
BuildTrusteeWithObjectsAndSidW( PTRUSTEEW pTrustee
, POBJECTS_AND_SID pObjSid
,
2057 GUID
* pObjectGuid
, GUID
* pInheritedObjectGuid
, PSID pSid
)
2059 DWORD ObjectsPresent
= 0;
2061 TRACE("%p %p %p %p %p\n", pTrustee
, pObjSid
, pObjectGuid
, pInheritedObjectGuid
, pSid
);
2063 /* Fill the OBJECTS_AND_SID structure */
2064 if (pObjectGuid
!= NULL
)
2066 pObjSid
->ObjectTypeGuid
= *pObjectGuid
;
2067 ObjectsPresent
|= ACE_OBJECT_TYPE_PRESENT
;
2071 ZeroMemory(&pObjSid
->ObjectTypeGuid
,
2075 if (pInheritedObjectGuid
!= NULL
)
2077 pObjSid
->InheritedObjectTypeGuid
= *pInheritedObjectGuid
;
2078 ObjectsPresent
|= ACE_INHERITED_OBJECT_TYPE_PRESENT
;
2082 ZeroMemory(&pObjSid
->InheritedObjectTypeGuid
,
2086 pObjSid
->ObjectsPresent
= ObjectsPresent
;
2087 pObjSid
->pSid
= pSid
;
2089 /* Fill the TRUSTEE structure */
2090 pTrustee
->pMultipleTrustee
= NULL
;
2091 pTrustee
->MultipleTrusteeOperation
= NO_MULTIPLE_TRUSTEE
;
2092 pTrustee
->TrusteeForm
= TRUSTEE_IS_OBJECTS_AND_SID
;
2093 pTrustee
->TrusteeType
= TRUSTEE_IS_UNKNOWN
;
2094 pTrustee
->ptstrName
= (LPWSTR
) pObjSid
;
2097 /******************************************************************************
2098 * BuildTrusteeWithSidA [ADVAPI32.@]
2100 VOID WINAPI
BuildTrusteeWithSidA(PTRUSTEEA pTrustee
, PSID pSid
)
2102 TRACE("%p %p\n", pTrustee
, pSid
);
2104 pTrustee
->pMultipleTrustee
= NULL
;
2105 pTrustee
->MultipleTrusteeOperation
= NO_MULTIPLE_TRUSTEE
;
2106 pTrustee
->TrusteeForm
= TRUSTEE_IS_SID
;
2107 pTrustee
->TrusteeType
= TRUSTEE_IS_UNKNOWN
;
2108 pTrustee
->ptstrName
= pSid
;
2111 /******************************************************************************
2112 * BuildTrusteeWithSidW [ADVAPI32.@]
2114 VOID WINAPI
BuildTrusteeWithSidW(PTRUSTEEW pTrustee
, PSID pSid
)
2116 TRACE("%p %p\n", pTrustee
, pSid
);
2118 pTrustee
->pMultipleTrustee
= NULL
;
2119 pTrustee
->MultipleTrusteeOperation
= NO_MULTIPLE_TRUSTEE
;
2120 pTrustee
->TrusteeForm
= TRUSTEE_IS_SID
;
2121 pTrustee
->TrusteeType
= TRUSTEE_IS_UNKNOWN
;
2122 pTrustee
->ptstrName
= pSid
;
2125 /******************************************************************************
2126 * BuildTrusteeWithNameA [ADVAPI32.@]
2128 VOID WINAPI
BuildTrusteeWithNameA(PTRUSTEEA pTrustee
, LPSTR name
)
2130 TRACE("%p %s\n", pTrustee
, debugstr_a(name
) );
2132 pTrustee
->pMultipleTrustee
= NULL
;
2133 pTrustee
->MultipleTrusteeOperation
= NO_MULTIPLE_TRUSTEE
;
2134 pTrustee
->TrusteeForm
= TRUSTEE_IS_NAME
;
2135 pTrustee
->TrusteeType
= TRUSTEE_IS_UNKNOWN
;
2136 pTrustee
->ptstrName
= name
;
2139 /******************************************************************************
2140 * BuildTrusteeWithNameW [ADVAPI32.@]
2142 VOID WINAPI
BuildTrusteeWithNameW(PTRUSTEEW pTrustee
, LPWSTR name
)
2144 TRACE("%p %s\n", pTrustee
, debugstr_w(name
) );
2146 pTrustee
->pMultipleTrustee
= NULL
;
2147 pTrustee
->MultipleTrusteeOperation
= NO_MULTIPLE_TRUSTEE
;
2148 pTrustee
->TrusteeForm
= TRUSTEE_IS_NAME
;
2149 pTrustee
->TrusteeType
= TRUSTEE_IS_UNKNOWN
;
2150 pTrustee
->ptstrName
= name
;
2153 /******************************************************************************
2154 * GetTrusteeFormA [ADVAPI32.@]
2156 TRUSTEE_FORM WINAPI
GetTrusteeFormA(PTRUSTEEA pTrustee
)
2158 TRACE("(%p)\n", pTrustee
);
2161 return TRUSTEE_BAD_FORM
;
2163 return pTrustee
->TrusteeForm
;
2166 /******************************************************************************
2167 * GetTrusteeFormW [ADVAPI32.@]
2169 TRUSTEE_FORM WINAPI
GetTrusteeFormW(PTRUSTEEW pTrustee
)
2171 TRACE("(%p)\n", pTrustee
);
2174 return TRUSTEE_BAD_FORM
;
2176 return pTrustee
->TrusteeForm
;
2179 /******************************************************************************
2180 * GetTrusteeNameA [ADVAPI32.@]
2182 LPSTR WINAPI
GetTrusteeNameA(PTRUSTEEA pTrustee
)
2184 TRACE("(%p)\n", pTrustee
);
2189 return pTrustee
->ptstrName
;
2192 /******************************************************************************
2193 * GetTrusteeNameW [ADVAPI32.@]
2195 LPWSTR WINAPI
GetTrusteeNameW(PTRUSTEEW pTrustee
)
2197 TRACE("(%p)\n", pTrustee
);
2202 return pTrustee
->ptstrName
;
2205 /******************************************************************************
2206 * GetTrusteeTypeA [ADVAPI32.@]
2208 TRUSTEE_TYPE WINAPI
GetTrusteeTypeA(PTRUSTEEA pTrustee
)
2210 TRACE("(%p)\n", pTrustee
);
2213 return TRUSTEE_IS_UNKNOWN
;
2215 return pTrustee
->TrusteeType
;
2218 /******************************************************************************
2219 * GetTrusteeTypeW [ADVAPI32.@]
2221 TRUSTEE_TYPE WINAPI
GetTrusteeTypeW(PTRUSTEEW pTrustee
)
2223 TRACE("(%p)\n", pTrustee
);
2226 return TRUSTEE_IS_UNKNOWN
;
2228 return pTrustee
->TrusteeType
;
2231 static DWORD
trustee_name_A_to_W(TRUSTEE_FORM form
, char *trustee_nameA
, WCHAR
**ptrustee_nameW
)
2235 case TRUSTEE_IS_NAME
:
2237 *ptrustee_nameW
= SERV_dup(trustee_nameA
);
2238 return ERROR_SUCCESS
;
2240 case TRUSTEE_IS_OBJECTS_AND_NAME
:
2242 OBJECTS_AND_NAME_A
*objA
= (OBJECTS_AND_NAME_A
*)trustee_nameA
;
2243 OBJECTS_AND_NAME_W
*objW
= NULL
;
2247 if (!(objW
= heap_alloc( sizeof(OBJECTS_AND_NAME_W
) )))
2248 return ERROR_NOT_ENOUGH_MEMORY
;
2250 objW
->ObjectsPresent
= objA
->ObjectsPresent
;
2251 objW
->ObjectType
= objA
->ObjectType
;
2252 objW
->ObjectTypeName
= SERV_dup(objA
->ObjectTypeName
);
2253 objW
->InheritedObjectTypeName
= SERV_dup(objA
->InheritedObjectTypeName
);
2254 objW
->ptstrName
= SERV_dup(objA
->ptstrName
);
2257 *ptrustee_nameW
= (WCHAR
*)objW
;
2258 return ERROR_SUCCESS
;
2260 /* These forms do not require conversion. */
2261 case TRUSTEE_IS_SID
:
2262 case TRUSTEE_IS_OBJECTS_AND_SID
:
2263 *ptrustee_nameW
= (WCHAR
*)trustee_nameA
;
2264 return ERROR_SUCCESS
;
2266 return ERROR_INVALID_PARAMETER
;
2270 static void free_trustee_name(TRUSTEE_FORM form
, WCHAR
*trustee_nameW
)
2274 case TRUSTEE_IS_NAME
:
2275 heap_free( trustee_nameW
);
2277 case TRUSTEE_IS_OBJECTS_AND_NAME
:
2279 OBJECTS_AND_NAME_W
*objW
= (OBJECTS_AND_NAME_W
*)trustee_nameW
;
2283 heap_free( objW
->ptstrName
);
2284 heap_free( objW
->InheritedObjectTypeName
);
2285 heap_free( objW
->ObjectTypeName
);
2291 /* Other forms did not require allocation, so no freeing is necessary. */
2297 static DWORD
trustee_to_sid( DWORD nDestinationSidLength
, PSID pDestinationSid
, PTRUSTEEW pTrustee
)
2299 if (pTrustee
->MultipleTrusteeOperation
== TRUSTEE_IS_IMPERSONATE
)
2301 WARN("bad multiple trustee operation %d\n", pTrustee
->MultipleTrusteeOperation
);
2302 return ERROR_INVALID_PARAMETER
;
2305 switch (pTrustee
->TrusteeForm
)
2307 case TRUSTEE_IS_SID
:
2308 if (!CopySid(nDestinationSidLength
, pDestinationSid
, pTrustee
->ptstrName
))
2310 WARN("bad sid %p\n", pTrustee
->ptstrName
);
2311 return ERROR_INVALID_PARAMETER
;
2314 case TRUSTEE_IS_NAME
:
2316 DWORD sid_size
= nDestinationSidLength
;
2317 DWORD domain_size
= MAX_COMPUTERNAME_LENGTH
+ 1;
2319 if (!strcmpW( pTrustee
->ptstrName
, CURRENT_USER
))
2321 if (!lookup_user_account_name( pDestinationSid
, &sid_size
, NULL
, &domain_size
, &use
))
2323 return GetLastError();
2326 else if (!LookupAccountNameW(NULL
, pTrustee
->ptstrName
, pDestinationSid
, &sid_size
, NULL
, &domain_size
, &use
))
2328 WARN("bad user name %s\n", debugstr_w(pTrustee
->ptstrName
));
2329 return ERROR_INVALID_PARAMETER
;
2333 case TRUSTEE_IS_OBJECTS_AND_SID
:
2334 FIXME("TRUSTEE_IS_OBJECTS_AND_SID unimplemented\n");
2336 case TRUSTEE_IS_OBJECTS_AND_NAME
:
2337 FIXME("TRUSTEE_IS_OBJECTS_AND_NAME unimplemented\n");
2340 WARN("bad trustee form %d\n", pTrustee
->TrusteeForm
);
2341 return ERROR_INVALID_PARAMETER
;
2344 return ERROR_SUCCESS
;
2347 /******************************************************************************
2348 * SetEntriesInAclA [ADVAPI32.@]
2350 DWORD WINAPI
SetEntriesInAclA( ULONG count
, PEXPLICIT_ACCESSA pEntries
,
2351 PACL OldAcl
, PACL
* NewAcl
)
2353 DWORD err
= ERROR_SUCCESS
;
2354 EXPLICIT_ACCESSW
*pEntriesW
;
2355 UINT alloc_index
, free_index
;
2357 TRACE("%d %p %p %p\n", count
, pEntries
, OldAcl
, NewAcl
);
2362 if (!count
&& !OldAcl
)
2363 return ERROR_SUCCESS
;
2365 pEntriesW
= heap_alloc( count
* sizeof(EXPLICIT_ACCESSW
) );
2367 return ERROR_NOT_ENOUGH_MEMORY
;
2369 for (alloc_index
= 0; alloc_index
< count
; ++alloc_index
)
2371 pEntriesW
[alloc_index
].grfAccessPermissions
= pEntries
[alloc_index
].grfAccessPermissions
;
2372 pEntriesW
[alloc_index
].grfAccessMode
= pEntries
[alloc_index
].grfAccessMode
;
2373 pEntriesW
[alloc_index
].grfInheritance
= pEntries
[alloc_index
].grfInheritance
;
2374 pEntriesW
[alloc_index
].Trustee
.pMultipleTrustee
= NULL
; /* currently not supported */
2375 pEntriesW
[alloc_index
].Trustee
.MultipleTrusteeOperation
= pEntries
[alloc_index
].Trustee
.MultipleTrusteeOperation
;
2376 pEntriesW
[alloc_index
].Trustee
.TrusteeForm
= pEntries
[alloc_index
].Trustee
.TrusteeForm
;
2377 pEntriesW
[alloc_index
].Trustee
.TrusteeType
= pEntries
[alloc_index
].Trustee
.TrusteeType
;
2379 err
= trustee_name_A_to_W( pEntries
[alloc_index
].Trustee
.TrusteeForm
,
2380 pEntries
[alloc_index
].Trustee
.ptstrName
,
2381 &pEntriesW
[alloc_index
].Trustee
.ptstrName
);
2382 if (err
!= ERROR_SUCCESS
)
2384 if (err
== ERROR_INVALID_PARAMETER
)
2385 WARN("bad trustee form %d for trustee %d\n",
2386 pEntries
[alloc_index
].Trustee
.TrusteeForm
, alloc_index
);
2392 err
= SetEntriesInAclW( count
, pEntriesW
, OldAcl
, NewAcl
);
2395 /* Free any previously allocated trustee name buffers, taking into account
2396 * a possible out-of-memory condition while building the EXPLICIT_ACCESSW
2398 for (free_index
= 0; free_index
< alloc_index
; ++free_index
)
2399 free_trustee_name( pEntriesW
[free_index
].Trustee
.TrusteeForm
, pEntriesW
[free_index
].Trustee
.ptstrName
);
2401 heap_free( pEntriesW
);
2405 /******************************************************************************
2406 * SetEntriesInAclW [ADVAPI32.@]
2408 DWORD WINAPI
SetEntriesInAclW( ULONG count
, PEXPLICIT_ACCESSW pEntries
,
2409 PACL OldAcl
, PACL
* NewAcl
)
2413 DWORD ret
= ERROR_SUCCESS
;
2414 DWORD acl_size
= sizeof(ACL
);
2417 TRACE("%d %p %p %p\n", count
, pEntries
, OldAcl
, NewAcl
);
2422 if (!count
&& !OldAcl
)
2423 return ERROR_SUCCESS
;
2425 /* allocate array of maximum sized sids allowed */
2426 ppsid
= heap_alloc(count
* (sizeof(SID
*) + FIELD_OFFSET(SID
, SubAuthority
[SID_MAX_SUB_AUTHORITIES
])));
2428 return ERROR_OUTOFMEMORY
;
2430 for (i
= 0; i
< count
; i
++)
2432 ppsid
[i
] = (char *)&ppsid
[count
] + i
* FIELD_OFFSET(SID
, SubAuthority
[SID_MAX_SUB_AUTHORITIES
]);
2434 TRACE("[%d]:\n\tgrfAccessPermissions = 0x%x\n\tgrfAccessMode = %d\n\tgrfInheritance = 0x%x\n\t"
2435 "Trustee.pMultipleTrustee = %p\n\tMultipleTrusteeOperation = %d\n\tTrusteeForm = %d\n\t"
2436 "Trustee.TrusteeType = %d\n\tptstrName = %p\n", i
,
2437 pEntries
[i
].grfAccessPermissions
, pEntries
[i
].grfAccessMode
, pEntries
[i
].grfInheritance
,
2438 pEntries
[i
].Trustee
.pMultipleTrustee
, pEntries
[i
].Trustee
.MultipleTrusteeOperation
,
2439 pEntries
[i
].Trustee
.TrusteeForm
, pEntries
[i
].Trustee
.TrusteeType
,
2440 pEntries
[i
].Trustee
.ptstrName
);
2442 ret
= trustee_to_sid( FIELD_OFFSET(SID
, SubAuthority
[SID_MAX_SUB_AUTHORITIES
]), ppsid
[i
], &pEntries
[i
].Trustee
);
2446 /* Note: we overestimate the ACL size here as a tradeoff between
2447 * instructions (simplicity) and memory */
2448 switch (pEntries
[i
].grfAccessMode
)
2452 acl_size
+= FIELD_OFFSET(ACCESS_ALLOWED_ACE
, SidStart
) + GetLengthSid(ppsid
[i
]);
2455 acl_size
+= FIELD_OFFSET(ACCESS_DENIED_ACE
, SidStart
) + GetLengthSid(ppsid
[i
]);
2457 case SET_AUDIT_SUCCESS
:
2458 case SET_AUDIT_FAILURE
:
2459 acl_size
+= FIELD_OFFSET(SYSTEM_AUDIT_ACE
, SidStart
) + GetLengthSid(ppsid
[i
]);
2464 WARN("bad access mode %d for trustee %d\n", pEntries
[i
].grfAccessMode
, i
);
2465 ret
= ERROR_INVALID_PARAMETER
;
2472 ACL_SIZE_INFORMATION size_info
;
2474 status
= RtlQueryInformationAcl(OldAcl
, &size_info
, sizeof(size_info
), AclSizeInformation
);
2475 if (status
!= STATUS_SUCCESS
)
2477 ret
= RtlNtStatusToDosError(status
);
2480 acl_size
+= size_info
.AclBytesInUse
- sizeof(ACL
);
2483 *NewAcl
= LocalAlloc(0, acl_size
);
2486 ret
= ERROR_OUTOFMEMORY
;
2490 status
= RtlCreateAcl( *NewAcl
, acl_size
, ACL_REVISION
);
2491 if (status
!= STATUS_SUCCESS
)
2493 ret
= RtlNtStatusToDosError(status
);
2497 for (i
= 0; i
< count
; i
++)
2499 switch (pEntries
[i
].grfAccessMode
)
2502 status
= RtlAddAccessAllowedAceEx(*NewAcl
, ACL_REVISION
,
2503 pEntries
[i
].grfInheritance
,
2504 pEntries
[i
].grfAccessPermissions
,
2515 const ACE_HEADER
*existing_ace_header
;
2516 status
= RtlGetAce(OldAcl
, j
, (LPVOID
*)&existing_ace_header
);
2517 if (status
!= STATUS_SUCCESS
)
2519 if (pEntries
[i
].grfAccessMode
== SET_ACCESS
&&
2520 existing_ace_header
->AceType
== ACCESS_ALLOWED_ACE_TYPE
&&
2521 EqualSid(ppsid
[i
], &((ACCESS_ALLOWED_ACE
*)existing_ace_header
)->SidStart
))
2529 status
= RtlAddAccessAllowedAceEx(*NewAcl
, ACL_REVISION
,
2530 pEntries
[i
].grfInheritance
,
2531 pEntries
[i
].grfAccessPermissions
,
2536 status
= RtlAddAccessDeniedAceEx(*NewAcl
, ACL_REVISION
,
2537 pEntries
[i
].grfInheritance
,
2538 pEntries
[i
].grfAccessPermissions
,
2541 case SET_AUDIT_SUCCESS
:
2542 status
= RtlAddAuditAccessAceEx(*NewAcl
, ACL_REVISION
,
2543 pEntries
[i
].grfInheritance
,
2544 pEntries
[i
].grfAccessPermissions
,
2545 ppsid
[i
], TRUE
, FALSE
);
2547 case SET_AUDIT_FAILURE
:
2548 status
= RtlAddAuditAccessAceEx(*NewAcl
, ACL_REVISION
,
2549 pEntries
[i
].grfInheritance
,
2550 pEntries
[i
].grfAccessPermissions
,
2551 ppsid
[i
], FALSE
, TRUE
);
2554 FIXME("unhandled access mode %d\n", pEntries
[i
].grfAccessMode
);
2564 const ACE_HEADER
*old_ace_header
;
2565 status
= RtlGetAce(OldAcl
, i
, (LPVOID
*)&old_ace_header
);
2566 if (status
!= STATUS_SUCCESS
) break;
2567 for (j
= 0; j
< count
; j
++)
2569 if (pEntries
[j
].grfAccessMode
== SET_ACCESS
&&
2570 old_ace_header
->AceType
== ACCESS_ALLOWED_ACE_TYPE
&&
2571 EqualSid(ppsid
[j
], &((ACCESS_ALLOWED_ACE
*)old_ace_header
)->SidStart
))
2573 status
= RtlAddAccessAllowedAceEx(*NewAcl
, ACL_REVISION
, pEntries
[j
].grfInheritance
, pEntries
[j
].grfAccessPermissions
, ppsid
[j
]);
2577 else if (pEntries
[j
].grfAccessMode
== REVOKE_ACCESS
)
2579 switch (old_ace_header
->AceType
)
2581 case ACCESS_ALLOWED_ACE_TYPE
:
2582 if (EqualSid(ppsid
[j
], &((ACCESS_ALLOWED_ACE
*)old_ace_header
)->SidStart
))
2585 case ACCESS_DENIED_ACE_TYPE
:
2586 if (EqualSid(ppsid
[j
], &((ACCESS_DENIED_ACE
*)old_ace_header
)->SidStart
))
2589 case SYSTEM_AUDIT_ACE_TYPE
:
2590 if (EqualSid(ppsid
[j
], &((SYSTEM_AUDIT_ACE
*)old_ace_header
)->SidStart
))
2593 case SYSTEM_ALARM_ACE_TYPE
:
2594 if (EqualSid(ppsid
[j
], &((SYSTEM_ALARM_ACE
*)old_ace_header
)->SidStart
))
2598 FIXME("unhandled ace type %d\n", old_ace_header
->AceType
);
2606 status
= RtlAddAce(*NewAcl
, ACL_REVISION
, 1, (PACE_HEADER
)old_ace_header
, old_ace_header
->AceSize
);
2607 if (status
!= STATUS_SUCCESS
)
2609 WARN("RtlAddAce failed with error 0x%08x\n", status
);
2610 ret
= RtlNtStatusToDosError(status
);
2621 /******************************************************************************
2622 * SetNamedSecurityInfoA [ADVAPI32.@]
2624 DWORD WINAPI
SetNamedSecurityInfoA(LPSTR pObjectName
,
2625 SE_OBJECT_TYPE ObjectType
, SECURITY_INFORMATION SecurityInfo
,
2626 PSID psidOwner
, PSID psidGroup
, PACL pDacl
, PACL pSacl
)
2631 TRACE("%s %d %d %p %p %p %p\n", debugstr_a(pObjectName
), ObjectType
,
2632 SecurityInfo
, psidOwner
, psidGroup
, pDacl
, pSacl
);
2634 wstr
= SERV_dup(pObjectName
);
2635 r
= SetNamedSecurityInfoW( wstr
, ObjectType
, SecurityInfo
, psidOwner
,
2636 psidGroup
, pDacl
, pSacl
);
2643 /******************************************************************************
2644 * SetNamedSecurityInfoW [ADVAPI32.@]
2646 DWORD WINAPI
SetNamedSecurityInfoW(LPWSTR pObjectName
,
2647 SE_OBJECT_TYPE ObjectType
, SECURITY_INFORMATION SecurityInfo
,
2648 PSID psidOwner
, PSID psidGroup
, PACL pDacl
, PACL pSacl
)
2654 TRACE( "%s %d %d %p %p %p %p\n", debugstr_w(pObjectName
), ObjectType
,
2655 SecurityInfo
, psidOwner
, psidGroup
, pDacl
, pSacl
);
2657 if (!pObjectName
) return ERROR_INVALID_PARAMETER
;
2659 if (SecurityInfo
& (OWNER_SECURITY_INFORMATION
|GROUP_SECURITY_INFORMATION
))
2660 access
|= WRITE_OWNER
;
2661 if (SecurityInfo
& DACL_SECURITY_INFORMATION
)
2662 access
|= WRITE_DAC
;
2663 if (SecurityInfo
& SACL_SECURITY_INFORMATION
)
2664 access
|= ACCESS_SYSTEM_SECURITY
;
2669 if (!(err
= get_security_service( pObjectName
, access
, &handle
)))
2671 err
= SetSecurityInfo( handle
, ObjectType
, SecurityInfo
, psidOwner
, psidGroup
, pDacl
, pSacl
);
2672 CloseServiceHandle( handle
);
2675 case SE_REGISTRY_KEY
:
2676 if (!(err
= get_security_regkey( pObjectName
, access
, &handle
)))
2678 err
= SetSecurityInfo( handle
, ObjectType
, SecurityInfo
, psidOwner
, psidGroup
, pDacl
, pSacl
);
2679 RegCloseKey( handle
);
2682 case SE_FILE_OBJECT
:
2683 if (SecurityInfo
& DACL_SECURITY_INFORMATION
)
2684 access
|= READ_CONTROL
;
2685 if (!(err
= get_security_file( pObjectName
, access
, &handle
)))
2687 err
= SetSecurityInfo( handle
, ObjectType
, SecurityInfo
, psidOwner
, psidGroup
, pDacl
, pSacl
);
2688 CloseHandle( handle
);
2692 FIXME( "Object type %d is not currently supported.\n", ObjectType
);
2693 return ERROR_SUCCESS
;
2698 /******************************************************************************
2699 * GetExplicitEntriesFromAclA [ADVAPI32.@]
2701 DWORD WINAPI
GetExplicitEntriesFromAclA( PACL pacl
, PULONG pcCountOfExplicitEntries
,
2702 PEXPLICIT_ACCESSA
* pListOfExplicitEntries
)
2704 FIXME("%p %p %p\n",pacl
, pcCountOfExplicitEntries
, pListOfExplicitEntries
);
2705 return ERROR_CALL_NOT_IMPLEMENTED
;
2708 /******************************************************************************
2709 * GetExplicitEntriesFromAclW [ADVAPI32.@]
2711 DWORD WINAPI
GetExplicitEntriesFromAclW( PACL pacl
, PULONG count
, PEXPLICIT_ACCESSW
*list
)
2713 ACL_SIZE_INFORMATION sizeinfo
;
2714 EXPLICIT_ACCESSW
*entries
;
2715 MAX_SID
*sid_entries
;
2720 TRACE("%p %p %p\n",pacl
, count
, list
);
2722 if (!count
|| !list
)
2723 return ERROR_INVALID_PARAMETER
;
2725 status
= RtlQueryInformationAcl(pacl
, &sizeinfo
, sizeof(sizeinfo
), AclSizeInformation
);
2726 if (status
) return RtlNtStatusToDosError(status
);
2728 if (!sizeinfo
.AceCount
)
2732 return ERROR_SUCCESS
;
2735 entries
= LocalAlloc(LMEM_FIXED
| LMEM_ZEROINIT
, (sizeof(EXPLICIT_ACCESSW
) + sizeof(MAX_SID
)) * sizeinfo
.AceCount
);
2736 if (!entries
) return ERROR_OUTOFMEMORY
;
2737 sid_entries
= (MAX_SID
*)(entries
+ sizeinfo
.AceCount
);
2739 for (i
= 0; i
< sizeinfo
.AceCount
; i
++)
2741 status
= RtlGetAce(pacl
, i
, (void**)&ace
);
2742 if (status
) goto error
;
2744 switch (ace
->AceType
)
2746 case ACCESS_ALLOWED_ACE_TYPE
:
2748 ACCESS_ALLOWED_ACE
*allow
= (ACCESS_ALLOWED_ACE
*)ace
;
2749 entries
[i
].grfAccessMode
= GRANT_ACCESS
;
2750 entries
[i
].grfInheritance
= ace
->AceFlags
;
2751 entries
[i
].grfAccessPermissions
= allow
->Mask
;
2753 CopySid(sizeof(MAX_SID
), (PSID
)&sid_entries
[i
], (PSID
)&allow
->SidStart
);
2754 entries
[i
].Trustee
.pMultipleTrustee
= NULL
;
2755 entries
[i
].Trustee
.MultipleTrusteeOperation
= NO_MULTIPLE_TRUSTEE
;
2756 entries
[i
].Trustee
.TrusteeForm
= TRUSTEE_IS_SID
;
2757 entries
[i
].Trustee
.TrusteeType
= TRUSTEE_IS_UNKNOWN
;
2758 entries
[i
].Trustee
.ptstrName
= (WCHAR
*)&sid_entries
[i
];
2762 case ACCESS_DENIED_ACE_TYPE
:
2764 ACCESS_DENIED_ACE
*deny
= (ACCESS_DENIED_ACE
*)ace
;
2765 entries
[i
].grfAccessMode
= DENY_ACCESS
;
2766 entries
[i
].grfInheritance
= ace
->AceFlags
;
2767 entries
[i
].grfAccessPermissions
= deny
->Mask
;
2769 CopySid(sizeof(MAX_SID
), (PSID
)&sid_entries
[i
], (PSID
)&deny
->SidStart
);
2770 entries
[i
].Trustee
.pMultipleTrustee
= NULL
;
2771 entries
[i
].Trustee
.MultipleTrusteeOperation
= NO_MULTIPLE_TRUSTEE
;
2772 entries
[i
].Trustee
.TrusteeForm
= TRUSTEE_IS_SID
;
2773 entries
[i
].Trustee
.TrusteeType
= TRUSTEE_IS_UNKNOWN
;
2774 entries
[i
].Trustee
.ptstrName
= (WCHAR
*)&sid_entries
[i
];
2779 FIXME("Unhandled ace type %d\n", ace
->AceType
);
2780 entries
[i
].grfAccessMode
= NOT_USED_ACCESS
;
2785 *count
= sizeinfo
.AceCount
;
2787 return ERROR_SUCCESS
;
2791 return RtlNtStatusToDosError(status
);
2794 /******************************************************************************
2795 * GetAuditedPermissionsFromAclA [ADVAPI32.@]
2797 DWORD WINAPI
GetAuditedPermissionsFromAclA( PACL pacl
, PTRUSTEEA pTrustee
, PACCESS_MASK pSuccessfulAuditedRights
,
2798 PACCESS_MASK pFailedAuditRights
)
2800 FIXME("%p %p %p %p\n",pacl
, pTrustee
, pSuccessfulAuditedRights
, pFailedAuditRights
);
2801 return ERROR_CALL_NOT_IMPLEMENTED
;
2805 /******************************************************************************
2806 * GetAuditedPermissionsFromAclW [ADVAPI32.@]
2808 DWORD WINAPI
GetAuditedPermissionsFromAclW( PACL pacl
, PTRUSTEEW pTrustee
, PACCESS_MASK pSuccessfulAuditedRights
,
2809 PACCESS_MASK pFailedAuditRights
)
2811 FIXME("%p %p %p %p\n",pacl
, pTrustee
, pSuccessfulAuditedRights
, pFailedAuditRights
);
2812 return ERROR_CALL_NOT_IMPLEMENTED
;
2816 /******************************************************************************
2817 * ParseAclStringFlags
2819 static DWORD
ParseAclStringFlags(LPCWSTR
* StringAcl
)
2822 LPCWSTR szAcl
= *StringAcl
;
2824 while (*szAcl
&& *szAcl
!= '(')
2828 flags
|= SE_DACL_PROTECTED
;
2830 else if (*szAcl
== 'A')
2834 flags
|= SE_DACL_AUTO_INHERIT_REQ
;
2835 else if (*szAcl
== 'I')
2836 flags
|= SE_DACL_AUTO_INHERITED
;
2845 /******************************************************************************
2846 * ParseAceStringType
2848 static const ACEFLAG AceType
[] =
2850 { SDDL_ALARM
, SYSTEM_ALARM_ACE_TYPE
},
2851 { SDDL_AUDIT
, SYSTEM_AUDIT_ACE_TYPE
},
2852 { SDDL_ACCESS_ALLOWED
, ACCESS_ALLOWED_ACE_TYPE
},
2853 { SDDL_ACCESS_DENIED
, ACCESS_DENIED_ACE_TYPE
},
2854 { SDDL_MANDATORY_LABEL
,SYSTEM_MANDATORY_LABEL_ACE_TYPE
},
2856 { SDDL_OBJECT_ACCESS_ALLOWED, ACCESS_ALLOWED_OBJECT_ACE_TYPE },
2857 { SDDL_OBJECT_ACCESS_DENIED, ACCESS_DENIED_OBJECT_ACE_TYPE },
2858 { SDDL_OBJECT_ALARM, SYSTEM_ALARM_OBJECT_ACE_TYPE },
2859 { SDDL_OBJECT_AUDIT, SYSTEM_AUDIT_OBJECT_ACE_TYPE },
2864 static BYTE
ParseAceStringType(LPCWSTR
* StringAcl
)
2867 LPCWSTR szAcl
= *StringAcl
;
2868 const ACEFLAG
*lpaf
= AceType
;
2870 while (*szAcl
== ' ')
2873 while (lpaf
->wstr
&&
2874 (len
= strlenW(lpaf
->wstr
)) &&
2875 strncmpW(lpaf
->wstr
, szAcl
, len
))
2881 *StringAcl
= szAcl
+ len
;
2886 /******************************************************************************
2887 * ParseAceStringFlags
2889 static const ACEFLAG AceFlags
[] =
2891 { SDDL_CONTAINER_INHERIT
, CONTAINER_INHERIT_ACE
},
2892 { SDDL_AUDIT_FAILURE
, FAILED_ACCESS_ACE_FLAG
},
2893 { SDDL_INHERITED
, INHERITED_ACE
},
2894 { SDDL_INHERIT_ONLY
, INHERIT_ONLY_ACE
},
2895 { SDDL_NO_PROPAGATE
, NO_PROPAGATE_INHERIT_ACE
},
2896 { SDDL_OBJECT_INHERIT
, OBJECT_INHERIT_ACE
},
2897 { SDDL_AUDIT_SUCCESS
, SUCCESSFUL_ACCESS_ACE_FLAG
},
2901 static BYTE
ParseAceStringFlags(LPCWSTR
* StringAcl
)
2905 LPCWSTR szAcl
= *StringAcl
;
2907 while (*szAcl
== ' ')
2910 while (*szAcl
!= ';')
2912 const ACEFLAG
*lpaf
= AceFlags
;
2914 while (lpaf
->wstr
&&
2915 (len
= strlenW(lpaf
->wstr
)) &&
2916 strncmpW(lpaf
->wstr
, szAcl
, len
))
2922 flags
|= lpaf
->value
;
2931 /******************************************************************************
2932 * ParseAceStringRights
2934 static const ACEFLAG AceRights
[] =
2936 { SDDL_GENERIC_ALL
, GENERIC_ALL
},
2937 { SDDL_GENERIC_READ
, GENERIC_READ
},
2938 { SDDL_GENERIC_WRITE
, GENERIC_WRITE
},
2939 { SDDL_GENERIC_EXECUTE
, GENERIC_EXECUTE
},
2941 { SDDL_READ_CONTROL
, READ_CONTROL
},
2942 { SDDL_STANDARD_DELETE
, DELETE
},
2943 { SDDL_WRITE_DAC
, WRITE_DAC
},
2944 { SDDL_WRITE_OWNER
, WRITE_OWNER
},
2946 { SDDL_READ_PROPERTY
, ADS_RIGHT_DS_READ_PROP
},
2947 { SDDL_WRITE_PROPERTY
, ADS_RIGHT_DS_WRITE_PROP
},
2948 { SDDL_CREATE_CHILD
, ADS_RIGHT_DS_CREATE_CHILD
},
2949 { SDDL_DELETE_CHILD
, ADS_RIGHT_DS_DELETE_CHILD
},
2950 { SDDL_LIST_CHILDREN
, ADS_RIGHT_ACTRL_DS_LIST
},
2951 { SDDL_SELF_WRITE
, ADS_RIGHT_DS_SELF
},
2952 { SDDL_LIST_OBJECT
, ADS_RIGHT_DS_LIST_OBJECT
},
2953 { SDDL_DELETE_TREE
, ADS_RIGHT_DS_DELETE_TREE
},
2954 { SDDL_CONTROL_ACCESS
, ADS_RIGHT_DS_CONTROL_ACCESS
},
2956 { SDDL_FILE_ALL
, FILE_ALL_ACCESS
},
2957 { SDDL_FILE_READ
, FILE_GENERIC_READ
},
2958 { SDDL_FILE_WRITE
, FILE_GENERIC_WRITE
},
2959 { SDDL_FILE_EXECUTE
, FILE_GENERIC_EXECUTE
},
2961 { SDDL_KEY_ALL
, KEY_ALL_ACCESS
},
2962 { SDDL_KEY_READ
, KEY_READ
},
2963 { SDDL_KEY_WRITE
, KEY_WRITE
},
2964 { SDDL_KEY_EXECUTE
, KEY_EXECUTE
},
2966 { SDDL_NO_READ_UP
, SYSTEM_MANDATORY_LABEL_NO_READ_UP
},
2967 { SDDL_NO_WRITE_UP
, SYSTEM_MANDATORY_LABEL_NO_WRITE_UP
},
2968 { SDDL_NO_EXECUTE_UP
, SYSTEM_MANDATORY_LABEL_NO_EXECUTE_UP
},
2972 static DWORD
ParseAceStringRights(LPCWSTR
* StringAcl
)
2976 LPCWSTR szAcl
= *StringAcl
;
2978 while (*szAcl
== ' ')
2981 if ((*szAcl
== '0') && (*(szAcl
+ 1) == 'x'))
2985 while (*p
&& *p
!= ';')
2988 if (p
- szAcl
<= 10 /* 8 hex digits + "0x" */ )
2990 rights
= strtoulW(szAcl
, NULL
, 16);
2994 WARN("Invalid rights string format: %s\n", debugstr_wn(szAcl
, p
- szAcl
));
2998 while (*szAcl
!= ';')
3000 const ACEFLAG
*lpaf
= AceRights
;
3002 while (lpaf
->wstr
&&
3003 (len
= strlenW(lpaf
->wstr
)) &&
3004 strncmpW(lpaf
->wstr
, szAcl
, len
))
3012 rights
|= lpaf
->value
;
3022 /******************************************************************************
3023 * ParseStringAclToAcl
3025 * dacl_flags(string_ace1)(string_ace2)... (string_acen)
3027 static BOOL
ParseStringAclToAcl(LPCWSTR StringAcl
, LPDWORD lpdwFlags
,
3028 PACL pAcl
, LPDWORD cBytes
)
3032 DWORD length
= sizeof(ACL
);
3035 PACCESS_ALLOWED_ACE pAce
= NULL
; /* pointer to current ACE */
3036 DWORD error
= ERROR_INVALID_ACL
;
3038 TRACE("%s\n", debugstr_w(StringAcl
));
3043 if (pAcl
) /* pAce is only useful if we're setting values */
3044 pAce
= (PACCESS_ALLOWED_ACE
) (pAcl
+ 1);
3046 /* Parse ACL flags */
3047 *lpdwFlags
= ParseAclStringFlags(&StringAcl
);
3050 while (*StringAcl
== '(')
3054 /* Parse ACE type */
3055 val
= ParseAceStringType(&StringAcl
);
3057 pAce
->Header
.AceType
= (BYTE
) val
;
3058 if (*StringAcl
!= ';')
3060 error
= RPC_S_INVALID_STRING_UUID
;
3065 /* Parse ACE flags */
3066 val
= ParseAceStringFlags(&StringAcl
);
3068 pAce
->Header
.AceFlags
= (BYTE
) val
;
3069 if (*StringAcl
!= ';')
3073 /* Parse ACE rights */
3074 val
= ParseAceStringRights(&StringAcl
);
3077 if (*StringAcl
!= ';')
3081 /* Parse ACE object guid */
3082 while (*StringAcl
== ' ')
3084 if (*StringAcl
!= ';')
3086 FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
3091 /* Parse ACE inherit object guid */
3092 while (*StringAcl
== ' ')
3094 if (*StringAcl
!= ';')
3096 FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
3101 /* Parse ACE account sid */
3102 if (ParseStringSidToSid(StringAcl
, pAce
? &pAce
->SidStart
: NULL
, &sidlen
))
3104 while (*StringAcl
&& *StringAcl
!= ')')
3108 if (*StringAcl
!= ')')
3112 acesize
= sizeof(ACCESS_ALLOWED_ACE
) - sizeof(DWORD
) + sidlen
;
3116 pAce
->Header
.AceSize
= acesize
;
3117 pAce
= (PACCESS_ALLOWED_ACE
)((LPBYTE
)pAce
+ acesize
);
3124 if (length
> 0xffff)
3126 ERR("ACL too large\n");
3132 pAcl
->AclRevision
= ACL_REVISION
;
3134 pAcl
->AclSize
= length
;
3135 pAcl
->AceCount
= acecount
;
3141 SetLastError(error
);
3142 WARN("Invalid ACE string format\n");
3147 /******************************************************************************
3148 * ParseStringSecurityDescriptorToSecurityDescriptor
3150 static BOOL
ParseStringSecurityDescriptorToSecurityDescriptor(
3151 LPCWSTR StringSecurityDescriptor
,
3152 SECURITY_DESCRIPTOR_RELATIVE
* SecurityDescriptor
,
3159 LPBYTE lpNext
= NULL
;
3162 *cBytes
= sizeof(SECURITY_DESCRIPTOR_RELATIVE
);
3164 tok
= heap_alloc( (lstrlenW(StringSecurityDescriptor
) + 1) * sizeof(WCHAR
));
3166 if (SecurityDescriptor
)
3167 lpNext
= (LPBYTE
)(SecurityDescriptor
+ 1);
3169 while (*StringSecurityDescriptor
== ' ')
3170 StringSecurityDescriptor
++;
3172 while (*StringSecurityDescriptor
)
3174 toktype
= *StringSecurityDescriptor
;
3176 /* Expect char identifier followed by ':' */
3177 StringSecurityDescriptor
++;
3178 if (*StringSecurityDescriptor
!= ':')
3180 SetLastError(ERROR_INVALID_PARAMETER
);
3183 StringSecurityDescriptor
++;
3186 lptoken
= StringSecurityDescriptor
;
3187 while (*lptoken
&& *lptoken
!= ':')
3193 len
= lptoken
- StringSecurityDescriptor
;
3194 memcpy( tok
, StringSecurityDescriptor
, len
* sizeof(WCHAR
) );
3203 if (!ParseStringSidToSid(tok
, lpNext
, &bytes
))
3206 if (SecurityDescriptor
)
3208 SecurityDescriptor
->Owner
= lpNext
- (LPBYTE
)SecurityDescriptor
;
3209 lpNext
+= bytes
; /* Advance to next token */
3221 if (!ParseStringSidToSid(tok
, lpNext
, &bytes
))
3224 if (SecurityDescriptor
)
3226 SecurityDescriptor
->Group
= lpNext
- (LPBYTE
)SecurityDescriptor
;
3227 lpNext
+= bytes
; /* Advance to next token */
3240 if (!ParseStringAclToAcl(tok
, &flags
, (PACL
)lpNext
, &bytes
))
3243 if (SecurityDescriptor
)
3245 SecurityDescriptor
->Control
|= SE_DACL_PRESENT
| flags
;
3246 SecurityDescriptor
->Dacl
= lpNext
- (LPBYTE
)SecurityDescriptor
;
3247 lpNext
+= bytes
; /* Advance to next token */
3260 if (!ParseStringAclToAcl(tok
, &flags
, (PACL
)lpNext
, &bytes
))
3263 if (SecurityDescriptor
)
3265 SecurityDescriptor
->Control
|= SE_SACL_PRESENT
| flags
;
3266 SecurityDescriptor
->Sacl
= lpNext
- (LPBYTE
)SecurityDescriptor
;
3267 lpNext
+= bytes
; /* Advance to next token */
3276 FIXME("Unknown token\n");
3277 SetLastError(ERROR_INVALID_PARAMETER
);
3281 StringSecurityDescriptor
= lptoken
;
3291 /******************************************************************************
3292 * ConvertStringSecurityDescriptorToSecurityDescriptorA [ADVAPI32.@]
3294 BOOL WINAPI
ConvertStringSecurityDescriptorToSecurityDescriptorA(
3295 LPCSTR StringSecurityDescriptor
,
3296 DWORD StringSDRevision
,
3297 PSECURITY_DESCRIPTOR
* SecurityDescriptor
,
3298 PULONG SecurityDescriptorSize
)
3301 LPWSTR StringSecurityDescriptorW
;
3303 TRACE("%s, %u, %p, %p\n", debugstr_a(StringSecurityDescriptor
), StringSDRevision
,
3304 SecurityDescriptor
, SecurityDescriptorSize
);
3306 if(!StringSecurityDescriptor
)
3309 StringSecurityDescriptorW
= SERV_dup(StringSecurityDescriptor
);
3310 ret
= ConvertStringSecurityDescriptorToSecurityDescriptorW(StringSecurityDescriptorW
,
3311 StringSDRevision
, SecurityDescriptor
,
3312 SecurityDescriptorSize
);
3313 heap_free(StringSecurityDescriptorW
);
3318 /******************************************************************************
3319 * ConvertStringSecurityDescriptorToSecurityDescriptorW [ADVAPI32.@]
3321 BOOL WINAPI
ConvertStringSecurityDescriptorToSecurityDescriptorW(
3322 LPCWSTR StringSecurityDescriptor
,
3323 DWORD StringSDRevision
,
3324 PSECURITY_DESCRIPTOR
* SecurityDescriptor
,
3325 PULONG SecurityDescriptorSize
)
3328 SECURITY_DESCRIPTOR
* psd
;
3331 TRACE("%s, %u, %p, %p\n", debugstr_w(StringSecurityDescriptor
), StringSDRevision
,
3332 SecurityDescriptor
, SecurityDescriptorSize
);
3334 if (GetVersion() & 0x80000000)
3336 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
3339 else if (!StringSecurityDescriptor
|| !SecurityDescriptor
)
3341 SetLastError(ERROR_INVALID_PARAMETER
);
3344 else if (StringSDRevision
!= SID_REVISION
)
3346 SetLastError(ERROR_UNKNOWN_REVISION
);
3350 /* Compute security descriptor length */
3351 if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor
,
3355 psd
= *SecurityDescriptor
= LocalAlloc(GMEM_ZEROINIT
, cBytes
);
3356 if (!psd
) goto lend
;
3358 psd
->Revision
= SID_REVISION
;
3359 psd
->Control
|= SE_SELF_RELATIVE
;
3361 if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor
,
3362 (SECURITY_DESCRIPTOR_RELATIVE
*)psd
, &cBytes
))
3368 if (SecurityDescriptorSize
)
3369 *SecurityDescriptorSize
= cBytes
;
3374 TRACE(" ret=%d\n", bret
);
3378 static void DumpString(LPCWSTR string
, int cch
, WCHAR
**pwptr
, ULONG
*plen
)
3381 cch
= strlenW(string
);
3388 memcpy(*pwptr
, string
, sizeof(WCHAR
)*cch
);
3393 static BOOL
DumpSidNumeric(PSID psid
, WCHAR
**pwptr
, ULONG
*plen
)
3395 static const WCHAR fmt
[] = { 'S','-','%','u','-','%','d',0 };
3396 static const WCHAR subauthfmt
[] = { '-','%','u',0 };
3401 if( !IsValidSid( psid
) || pisid
->Revision
!= SDDL_REVISION
)
3403 SetLastError(ERROR_INVALID_SID
);
3407 if (pisid
->IdentifierAuthority
.Value
[0] ||
3408 pisid
->IdentifierAuthority
.Value
[1])
3410 FIXME("not matching MS' bugs\n");
3411 SetLastError(ERROR_INVALID_SID
);
3415 sprintfW( buf
, fmt
, pisid
->Revision
,
3417 MAKEWORD( pisid
->IdentifierAuthority
.Value
[5],
3418 pisid
->IdentifierAuthority
.Value
[4] ),
3419 MAKEWORD( pisid
->IdentifierAuthority
.Value
[3],
3420 pisid
->IdentifierAuthority
.Value
[2] )
3422 DumpString(buf
, -1, pwptr
, plen
);
3424 for( i
=0; i
<pisid
->SubAuthorityCount
; i
++ )
3426 sprintfW( buf
, subauthfmt
, pisid
->SubAuthority
[i
] );
3427 DumpString(buf
, -1, pwptr
, plen
);
3432 static BOOL
DumpSid(PSID psid
, WCHAR
**pwptr
, ULONG
*plen
)
3435 for (i
= 0; i
< ARRAY_SIZE(WellKnownSids
); i
++)
3437 if (WellKnownSids
[i
].wstr
[0] && EqualSid(psid
, (PSID
)&(WellKnownSids
[i
].Sid
.Revision
)))
3439 DumpString(WellKnownSids
[i
].wstr
, 2, pwptr
, plen
);
3444 return DumpSidNumeric(psid
, pwptr
, plen
);
3447 static const LPCWSTR AceRightBitNames
[32] = {
3448 SDDL_CREATE_CHILD
, /* 0 */
3452 SDDL_READ_PROPERTY
, /* 4 */
3453 SDDL_WRITE_PROPERTY
,
3456 SDDL_CONTROL_ACCESS
, /* 8 */
3464 SDDL_STANDARD_DELETE
, /* 16 */
3476 SDDL_GENERIC_ALL
, /* 28 */
3477 SDDL_GENERIC_EXECUTE
,
3482 static void DumpRights(DWORD mask
, WCHAR
**pwptr
, ULONG
*plen
)
3484 static const WCHAR fmtW
[] = {'0','x','%','x',0};
3491 /* first check if the right have name */
3492 for (i
= 0; i
< ARRAY_SIZE(AceRights
); i
++)
3494 if (AceRights
[i
].wstr
== NULL
)
3496 if (mask
== AceRights
[i
].value
)
3498 DumpString(AceRights
[i
].wstr
, -1, pwptr
, plen
);
3503 /* then check if it can be built from bit names */
3504 for (i
= 0; i
< 32; i
++)
3506 if ((mask
& (1 << i
)) && (AceRightBitNames
[i
] == NULL
))
3508 /* can't be built from bit names */
3509 sprintfW(buf
, fmtW
, mask
);
3510 DumpString(buf
, -1, pwptr
, plen
);
3515 /* build from bit names */
3516 for (i
= 0; i
< 32; i
++)
3517 if (mask
& (1 << i
))
3518 DumpString(AceRightBitNames
[i
], -1, pwptr
, plen
);
3521 static inline BOOL
is_object_ace(BYTE AceType
)
3525 case ACCESS_ALLOWED_OBJECT_ACE_TYPE
:
3526 case ACCESS_DENIED_OBJECT_ACE_TYPE
:
3527 case ACCESS_AUDIT_OBJECT_ACE_TYPE
:
3528 case ACCESS_ALARM_OBJECT_ACE_TYPE
:
3529 case ACCESS_ALLOWED_CALLBACK_OBJECT_ACE_TYPE
:
3530 case ACCESS_DENIED_CALLBACK_OBJECT_ACE_TYPE
:
3531 case SYSTEM_AUDIT_CALLBACK_OBJECT_ACE_TYPE
:
3532 case SYSTEM_ALARM_CALLBACK_OBJECT_ACE_TYPE
:
3535 default: return FALSE
;
3539 static BOOL
DumpAce(LPVOID pace
, WCHAR
**pwptr
, ULONG
*plen
)
3541 ACCESS_ALLOWED_ACE
*piace
; /* all the supported ACEs have the same memory layout */
3542 static const WCHAR openbr
= '(';
3543 static const WCHAR closebr
= ')';
3544 static const WCHAR semicolon
= ';';
3549 if (piace
->Header
.AceType
> ACCESS_MAX_MS_V5_ACE_TYPE
|| piace
->Header
.AceSize
< sizeof(ACCESS_ALLOWED_ACE
))
3551 SetLastError(ERROR_INVALID_ACL
);
3555 DumpString(&openbr
, 1, pwptr
, plen
);
3556 switch (piace
->Header
.AceType
)
3558 case ACCESS_ALLOWED_ACE_TYPE
:
3559 DumpString(SDDL_ACCESS_ALLOWED
, -1, pwptr
, plen
);
3561 case ACCESS_DENIED_ACE_TYPE
:
3562 DumpString(SDDL_ACCESS_DENIED
, -1, pwptr
, plen
);
3564 case SYSTEM_AUDIT_ACE_TYPE
:
3565 DumpString(SDDL_AUDIT
, -1, pwptr
, plen
);
3567 case SYSTEM_ALARM_ACE_TYPE
:
3568 DumpString(SDDL_ALARM
, -1, pwptr
, plen
);
3571 DumpString(&semicolon
, 1, pwptr
, plen
);
3573 if (piace
->Header
.AceFlags
& OBJECT_INHERIT_ACE
)
3574 DumpString(SDDL_OBJECT_INHERIT
, -1, pwptr
, plen
);
3575 if (piace
->Header
.AceFlags
& CONTAINER_INHERIT_ACE
)
3576 DumpString(SDDL_CONTAINER_INHERIT
, -1, pwptr
, plen
);
3577 if (piace
->Header
.AceFlags
& NO_PROPAGATE_INHERIT_ACE
)
3578 DumpString(SDDL_NO_PROPAGATE
, -1, pwptr
, plen
);
3579 if (piace
->Header
.AceFlags
& INHERIT_ONLY_ACE
)
3580 DumpString(SDDL_INHERIT_ONLY
, -1, pwptr
, plen
);
3581 if (piace
->Header
.AceFlags
& INHERITED_ACE
)
3582 DumpString(SDDL_INHERITED
, -1, pwptr
, plen
);
3583 if (piace
->Header
.AceFlags
& SUCCESSFUL_ACCESS_ACE_FLAG
)
3584 DumpString(SDDL_AUDIT_SUCCESS
, -1, pwptr
, plen
);
3585 if (piace
->Header
.AceFlags
& FAILED_ACCESS_ACE_FLAG
)
3586 DumpString(SDDL_AUDIT_FAILURE
, -1, pwptr
, plen
);
3587 DumpString(&semicolon
, 1, pwptr
, plen
);
3588 DumpRights(piace
->Mask
, pwptr
, plen
);
3589 DumpString(&semicolon
, 1, pwptr
, plen
);
3590 SidStart
= &piace
->SidStart
;
3591 if (is_object_ace(piace
->Header
.AceType
))
3593 ACCESS_ALLOWED_OBJECT_ACE
*objace
= pace
;
3595 SidStart
++; /* Flags */
3596 if (objace
->Flags
& ACE_OBJECT_TYPE_PRESENT
)
3597 SidStart
+= sizeof(GUID
) / sizeof(*SidStart
); /* ObjectType */
3598 if (objace
->Flags
& ACE_INHERITED_OBJECT_TYPE_PRESENT
)
3599 SidStart
+= sizeof(GUID
) / sizeof(*SidStart
); /* InheritedObjectType */
3601 /* objects not supported */
3602 DumpString(&semicolon
, 1, pwptr
, plen
);
3603 /* objects not supported */
3604 DumpString(&semicolon
, 1, pwptr
, plen
);
3605 if (!DumpSid(SidStart
, pwptr
, plen
))
3607 DumpString(&closebr
, 1, pwptr
, plen
);
3611 static BOOL
DumpAcl(PACL pacl
, WCHAR
**pwptr
, ULONG
*plen
, BOOL
protected, BOOL autoInheritReq
, BOOL autoInherited
)
3617 DumpString(SDDL_PROTECTED
, -1, pwptr
, plen
);
3619 DumpString(SDDL_AUTO_INHERIT_REQ
, -1, pwptr
, plen
);
3621 DumpString(SDDL_AUTO_INHERITED
, -1, pwptr
, plen
);
3626 if (!IsValidAcl(pacl
))
3629 count
= pacl
->AceCount
;
3630 for (i
= 0; i
< count
; i
++)
3633 if (!GetAce(pacl
, i
, &ace
))
3635 if (!DumpAce(ace
, pwptr
, plen
))
3642 static BOOL
DumpOwner(PSECURITY_DESCRIPTOR SecurityDescriptor
, WCHAR
**pwptr
, ULONG
*plen
)
3644 static const WCHAR prefix
[] = {'O',':',0};
3648 if (!GetSecurityDescriptorOwner(SecurityDescriptor
, &psid
, &bDefaulted
))
3654 DumpString(prefix
, -1, pwptr
, plen
);
3655 if (!DumpSid(psid
, pwptr
, plen
))
3660 static BOOL
DumpGroup(PSECURITY_DESCRIPTOR SecurityDescriptor
, WCHAR
**pwptr
, ULONG
*plen
)
3662 static const WCHAR prefix
[] = {'G',':',0};
3666 if (!GetSecurityDescriptorGroup(SecurityDescriptor
, &psid
, &bDefaulted
))
3672 DumpString(prefix
, -1, pwptr
, plen
);
3673 if (!DumpSid(psid
, pwptr
, plen
))
3678 static BOOL
DumpDacl(PSECURITY_DESCRIPTOR SecurityDescriptor
, WCHAR
**pwptr
, ULONG
*plen
)
3680 static const WCHAR dacl
[] = {'D',':',0};
3681 SECURITY_DESCRIPTOR_CONTROL control
;
3682 BOOL present
, defaulted
;
3686 if (!GetSecurityDescriptorDacl(SecurityDescriptor
, &present
, &pacl
, &defaulted
))
3689 if (!GetSecurityDescriptorControl(SecurityDescriptor
, &control
, &revision
))
3695 DumpString(dacl
, 2, pwptr
, plen
);
3696 if (!DumpAcl(pacl
, pwptr
, plen
, control
& SE_DACL_PROTECTED
, control
& SE_DACL_AUTO_INHERIT_REQ
, control
& SE_DACL_AUTO_INHERITED
))
3701 static BOOL
DumpSacl(PSECURITY_DESCRIPTOR SecurityDescriptor
, WCHAR
**pwptr
, ULONG
*plen
)
3703 static const WCHAR sacl
[] = {'S',':',0};
3704 SECURITY_DESCRIPTOR_CONTROL control
;
3705 BOOL present
, defaulted
;
3709 if (!GetSecurityDescriptorSacl(SecurityDescriptor
, &present
, &pacl
, &defaulted
))
3712 if (!GetSecurityDescriptorControl(SecurityDescriptor
, &control
, &revision
))
3718 DumpString(sacl
, 2, pwptr
, plen
);
3719 if (!DumpAcl(pacl
, pwptr
, plen
, control
& SE_SACL_PROTECTED
, control
& SE_SACL_AUTO_INHERIT_REQ
, control
& SE_SACL_AUTO_INHERITED
))
3724 /******************************************************************************
3725 * ConvertSecurityDescriptorToStringSecurityDescriptorA [ADVAPI32.@]
3727 BOOL WINAPI
ConvertSecurityDescriptorToStringSecurityDescriptorW(PSECURITY_DESCRIPTOR SecurityDescriptor
, DWORD SDRevision
, SECURITY_INFORMATION RequestedInformation
, LPWSTR
*OutputString
, PULONG OutputLen
)
3732 if (SDRevision
!= SDDL_REVISION_1
)
3734 ERR("Program requested unknown SDDL revision %d\n", SDRevision
);
3735 SetLastError(ERROR_UNKNOWN_REVISION
);
3740 if (RequestedInformation
& OWNER_SECURITY_INFORMATION
)
3741 if (!DumpOwner(SecurityDescriptor
, NULL
, &len
))
3743 if (RequestedInformation
& GROUP_SECURITY_INFORMATION
)
3744 if (!DumpGroup(SecurityDescriptor
, NULL
, &len
))
3746 if (RequestedInformation
& DACL_SECURITY_INFORMATION
)
3747 if (!DumpDacl(SecurityDescriptor
, NULL
, &len
))
3749 if (RequestedInformation
& SACL_SECURITY_INFORMATION
)
3750 if (!DumpSacl(SecurityDescriptor
, NULL
, &len
))
3753 wstr
= wptr
= LocalAlloc(0, (len
+ 1)*sizeof(WCHAR
));
3754 if (RequestedInformation
& OWNER_SECURITY_INFORMATION
)
3755 if (!DumpOwner(SecurityDescriptor
, &wptr
, NULL
)) {
3759 if (RequestedInformation
& GROUP_SECURITY_INFORMATION
)
3760 if (!DumpGroup(SecurityDescriptor
, &wptr
, NULL
)) {
3764 if (RequestedInformation
& DACL_SECURITY_INFORMATION
)
3765 if (!DumpDacl(SecurityDescriptor
, &wptr
, NULL
)) {
3769 if (RequestedInformation
& SACL_SECURITY_INFORMATION
)
3770 if (!DumpSacl(SecurityDescriptor
, &wptr
, NULL
)) {
3776 TRACE("ret: %s, %d\n", wine_dbgstr_w(wstr
), len
);
3777 *OutputString
= wstr
;
3779 *OutputLen
= strlenW(*OutputString
)+1;
3783 /******************************************************************************
3784 * ConvertSecurityDescriptorToStringSecurityDescriptorA [ADVAPI32.@]
3786 BOOL WINAPI
ConvertSecurityDescriptorToStringSecurityDescriptorA(PSECURITY_DESCRIPTOR SecurityDescriptor
, DWORD SDRevision
, SECURITY_INFORMATION Information
, LPSTR
*OutputString
, PULONG OutputLen
)
3790 if (ConvertSecurityDescriptorToStringSecurityDescriptorW(SecurityDescriptor
, SDRevision
, Information
, &wstr
, &len
))
3794 lenA
= WideCharToMultiByte(CP_ACP
, 0, wstr
, len
, NULL
, 0, NULL
, NULL
);
3795 *OutputString
= heap_alloc(lenA
);
3796 WideCharToMultiByte(CP_ACP
, 0, wstr
, len
, *OutputString
, lenA
, NULL
, NULL
);
3799 if (OutputLen
!= NULL
)
3805 *OutputString
= NULL
;
3812 /******************************************************************************
3813 * ConvertStringSidToSidW [ADVAPI32.@]
3815 BOOL WINAPI
ConvertStringSidToSidW(LPCWSTR StringSid
, PSID
* Sid
)
3820 TRACE("%s, %p\n", debugstr_w(StringSid
), Sid
);
3821 if (GetVersion() & 0x80000000)
3822 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
3823 else if (!StringSid
|| !Sid
)
3824 SetLastError(ERROR_INVALID_PARAMETER
);
3825 else if (ParseStringSidToSid(StringSid
, NULL
, &cBytes
))
3827 PSID pSid
= *Sid
= LocalAlloc(0, cBytes
);
3829 bret
= ParseStringSidToSid(StringSid
, pSid
, &cBytes
);
3836 /******************************************************************************
3837 * ConvertStringSidToSidA [ADVAPI32.@]
3839 BOOL WINAPI
ConvertStringSidToSidA(LPCSTR StringSid
, PSID
* Sid
)
3843 TRACE("%s, %p\n", debugstr_a(StringSid
), Sid
);
3844 if (GetVersion() & 0x80000000)
3845 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
3846 else if (!StringSid
|| !Sid
)
3847 SetLastError(ERROR_INVALID_PARAMETER
);
3850 WCHAR
*wStringSid
= SERV_dup(StringSid
);
3851 bret
= ConvertStringSidToSidW(wStringSid
, Sid
);
3852 heap_free(wStringSid
);
3857 /******************************************************************************
3858 * ConvertSidToStringSidW [ADVAPI32.@]
3860 * format of SID string is:
3861 * S-<count>-<auth>-<subauth1>-<subauth2>-<subauth3>...
3863 * <rev> is the revision of the SID encoded as decimal
3864 * <auth> is the identifier authority encoded as hex
3865 * <subauthN> is the subauthority id encoded as decimal
3867 BOOL WINAPI
ConvertSidToStringSidW( PSID pSid
, LPWSTR
*pstr
)
3872 TRACE("%p %p\n", pSid
, pstr
);
3875 if (!DumpSidNumeric(pSid
, NULL
, &len
))
3877 wstr
= wptr
= LocalAlloc(0, (len
+1) * sizeof(WCHAR
));
3878 DumpSidNumeric(pSid
, &wptr
, NULL
);
3885 /******************************************************************************
3886 * ConvertSidToStringSidA [ADVAPI32.@]
3888 BOOL WINAPI
ConvertSidToStringSidA(PSID pSid
, LPSTR
*pstr
)
3894 TRACE("%p %p\n", pSid
, pstr
);
3896 if( !ConvertSidToStringSidW( pSid
, &wstr
) )
3899 len
= WideCharToMultiByte( CP_ACP
, 0, wstr
, -1, NULL
, 0, NULL
, NULL
);
3900 str
= LocalAlloc( 0, len
);
3901 WideCharToMultiByte( CP_ACP
, 0, wstr
, -1, str
, len
, NULL
, NULL
);
3909 /******************************************************************************
3910 * CreateProcessWithLogonW
3912 BOOL WINAPI
CreateProcessWithLogonW( LPCWSTR lpUsername
, LPCWSTR lpDomain
, LPCWSTR lpPassword
, DWORD dwLogonFlags
,
3913 LPCWSTR lpApplicationName
, LPWSTR lpCommandLine
, DWORD dwCreationFlags
, LPVOID lpEnvironment
,
3914 LPCWSTR lpCurrentDirectory
, LPSTARTUPINFOW lpStartupInfo
, LPPROCESS_INFORMATION lpProcessInformation
)
3916 FIXME("%s %s %s 0x%08x %s %s 0x%08x %p %s %p %p stub\n", debugstr_w(lpUsername
), debugstr_w(lpDomain
),
3917 debugstr_w(lpPassword
), dwLogonFlags
, debugstr_w(lpApplicationName
),
3918 debugstr_w(lpCommandLine
), dwCreationFlags
, lpEnvironment
, debugstr_w(lpCurrentDirectory
),
3919 lpStartupInfo
, lpProcessInformation
);
3924 BOOL WINAPI
CreateProcessWithTokenW(HANDLE token
, DWORD logon_flags
, LPCWSTR application_name
, LPWSTR command_line
,
3925 DWORD creation_flags
, void *environment
, LPCWSTR current_directory
, STARTUPINFOW
*startup_info
,
3926 PROCESS_INFORMATION
*process_information
)
3928 FIXME("%p 0x%08x %s %s 0x%08x %p %s %p %p - semi-stub\n", token
,
3929 logon_flags
, debugstr_w(application_name
), debugstr_w(command_line
),
3930 creation_flags
, environment
, debugstr_w(current_directory
),
3931 startup_info
, process_information
);
3933 /* FIXME: check if handles should be inherited */
3934 return CreateProcessW( application_name
, command_line
, NULL
, NULL
, FALSE
, creation_flags
, environment
,
3935 current_directory
, startup_info
, process_information
);
3938 /******************************************************************************
3939 * ComputeStringSidSize
3941 static DWORD
ComputeStringSidSize(LPCWSTR StringSid
)
3943 if (StringSid
[0] == 'S' && StringSid
[1] == '-') /* S-R-I(-S)+ */
3948 if (*StringSid
== '-')
3954 return GetSidLengthRequired(ctok
- 2);
3956 else /* String constant format - Only available in winxp and above */
3960 for (i
= 0; i
< ARRAY_SIZE(WellKnownSids
); i
++)
3961 if (!strncmpW(WellKnownSids
[i
].wstr
, StringSid
, 2))
3962 return GetSidLengthRequired(WellKnownSids
[i
].Sid
.SubAuthorityCount
);
3964 for (i
= 0; i
< ARRAY_SIZE(WellKnownRids
); i
++)
3965 if (!strncmpW(WellKnownRids
[i
].wstr
, StringSid
, 2))
3968 ADVAPI_GetComputerSid(&local
);
3969 return GetSidLengthRequired(*GetSidSubAuthorityCount(&local
) + 1);
3974 return GetSidLengthRequired(0);
3977 /******************************************************************************
3978 * ParseStringSidToSid
3980 static BOOL
ParseStringSidToSid(LPCWSTR StringSid
, PSID pSid
, LPDWORD cBytes
)
3985 TRACE("%s, %p, %p\n", debugstr_w(StringSid
), pSid
, cBytes
);
3988 SetLastError(ERROR_INVALID_PARAMETER
);
3989 TRACE("StringSid is NULL, returning FALSE\n");
3993 while (*StringSid
== ' ')
3996 *cBytes
= ComputeStringSidSize(StringSid
);
3997 if (!pisid
) /* Simply compute the size */
3999 TRACE("only size requested, returning TRUE with %d\n", *cBytes
);
4003 if (StringSid
[0] == 'S' && StringSid
[1] == '-') /* S-R-I-S-S */
4005 DWORD i
= 0, identAuth
;
4006 DWORD csubauth
= ((*cBytes
- GetSidLengthRequired(0)) / sizeof(DWORD
));
4008 StringSid
+= 2; /* Advance to Revision */
4009 pisid
->Revision
= atoiW(StringSid
);
4011 if (pisid
->Revision
!= SDDL_REVISION
)
4013 TRACE("Revision %d is unknown\n", pisid
->Revision
);
4014 goto lend
; /* ERROR_INVALID_SID */
4018 TRACE("SubAuthorityCount is 0\n");
4019 goto lend
; /* ERROR_INVALID_SID */
4022 pisid
->SubAuthorityCount
= csubauth
;
4024 /* Advance to identifier authority */
4025 while (*StringSid
&& *StringSid
!= '-')
4027 if (*StringSid
== '-')
4030 /* MS' implementation can't handle values greater than 2^32 - 1, so
4031 * we don't either; assume most significant bytes are always 0
4033 pisid
->IdentifierAuthority
.Value
[0] = 0;
4034 pisid
->IdentifierAuthority
.Value
[1] = 0;
4035 identAuth
= atoiW(StringSid
);
4036 pisid
->IdentifierAuthority
.Value
[5] = identAuth
& 0xff;
4037 pisid
->IdentifierAuthority
.Value
[4] = (identAuth
& 0xff00) >> 8;
4038 pisid
->IdentifierAuthority
.Value
[3] = (identAuth
& 0xff0000) >> 16;
4039 pisid
->IdentifierAuthority
.Value
[2] = (identAuth
& 0xff000000) >> 24;
4041 /* Advance to first sub authority */
4042 while (*StringSid
&& *StringSid
!= '-')
4044 if (*StringSid
== '-')
4049 pisid
->SubAuthority
[i
++] = atoiW(StringSid
);
4051 while (*StringSid
&& *StringSid
!= '-')
4053 if (*StringSid
== '-')
4057 if (i
!= pisid
->SubAuthorityCount
)
4058 goto lend
; /* ERROR_INVALID_SID */
4062 else /* String constant format - Only available in winxp and above */
4065 pisid
->Revision
= SDDL_REVISION
;
4067 for (i
= 0; i
< ARRAY_SIZE(WellKnownSids
); i
++)
4068 if (!strncmpW(WellKnownSids
[i
].wstr
, StringSid
, 2))
4071 pisid
->SubAuthorityCount
= WellKnownSids
[i
].Sid
.SubAuthorityCount
;
4072 pisid
->IdentifierAuthority
= WellKnownSids
[i
].Sid
.IdentifierAuthority
;
4073 for (j
= 0; j
< WellKnownSids
[i
].Sid
.SubAuthorityCount
; j
++)
4074 pisid
->SubAuthority
[j
] = WellKnownSids
[i
].Sid
.SubAuthority
[j
];
4078 for (i
= 0; i
< ARRAY_SIZE(WellKnownRids
); i
++)
4079 if (!strncmpW(WellKnownRids
[i
].wstr
, StringSid
, 2))
4081 ADVAPI_GetComputerSid(pisid
);
4082 pisid
->SubAuthority
[pisid
->SubAuthorityCount
] = WellKnownRids
[i
].Rid
;
4083 pisid
->SubAuthorityCount
++;
4088 FIXME("String constant not supported: %s\n", debugstr_wn(StringSid
, 2));
4093 SetLastError(ERROR_INVALID_SID
);
4095 TRACE("returning %s\n", bret
? "TRUE" : "FALSE");
4099 /******************************************************************************
4100 * GetNamedSecurityInfoA [ADVAPI32.@]
4102 DWORD WINAPI
GetNamedSecurityInfoA(LPSTR pObjectName
,
4103 SE_OBJECT_TYPE ObjectType
, SECURITY_INFORMATION SecurityInfo
,
4104 PSID
* ppsidOwner
, PSID
* ppsidGroup
, PACL
* ppDacl
, PACL
* ppSacl
,
4105 PSECURITY_DESCRIPTOR
* ppSecurityDescriptor
)
4110 TRACE("%s %d %d %p %p %p %p %p\n", pObjectName
, ObjectType
, SecurityInfo
,
4111 ppsidOwner
, ppsidGroup
, ppDacl
, ppSacl
, ppSecurityDescriptor
);
4113 wstr
= SERV_dup(pObjectName
);
4114 r
= GetNamedSecurityInfoW( wstr
, ObjectType
, SecurityInfo
, ppsidOwner
,
4115 ppsidGroup
, ppDacl
, ppSacl
, ppSecurityDescriptor
);
4122 /******************************************************************************
4123 * GetNamedSecurityInfoW [ADVAPI32.@]
4125 DWORD WINAPI
GetNamedSecurityInfoW( LPWSTR name
, SE_OBJECT_TYPE type
,
4126 SECURITY_INFORMATION info
, PSID
* owner
, PSID
* group
, PACL
* dacl
,
4127 PACL
* sacl
, PSECURITY_DESCRIPTOR
* descriptor
)
4133 TRACE( "%s %d %d %p %p %p %p %p\n", debugstr_w(name
), type
, info
, owner
,
4134 group
, dacl
, sacl
, descriptor
);
4136 /* A NULL descriptor is allowed if any one of the other pointers is not NULL */
4137 if (!name
|| !(owner
||group
||dacl
||sacl
||descriptor
) ) return ERROR_INVALID_PARAMETER
;
4139 /* If no descriptor, we have to check that there's a pointer for the requested information */
4140 if( !descriptor
&& (
4141 ((info
& OWNER_SECURITY_INFORMATION
) && !owner
)
4142 || ((info
& GROUP_SECURITY_INFORMATION
) && !group
)
4143 || ((info
& DACL_SECURITY_INFORMATION
) && !dacl
)
4144 || ((info
& SACL_SECURITY_INFORMATION
) && !sacl
) ))
4145 return ERROR_INVALID_PARAMETER
;
4147 if (info
& (OWNER_SECURITY_INFORMATION
|GROUP_SECURITY_INFORMATION
|DACL_SECURITY_INFORMATION
))
4148 access
|= READ_CONTROL
;
4149 if (info
& SACL_SECURITY_INFORMATION
)
4150 access
|= ACCESS_SYSTEM_SECURITY
;
4155 if (!(err
= get_security_service( name
, access
, &handle
)))
4157 err
= GetSecurityInfo( handle
, type
, info
, owner
, group
, dacl
, sacl
, descriptor
);
4158 CloseServiceHandle( handle
);
4161 case SE_REGISTRY_KEY
:
4162 if (!(err
= get_security_regkey( name
, access
, &handle
)))
4164 err
= GetSecurityInfo( handle
, type
, info
, owner
, group
, dacl
, sacl
, descriptor
);
4165 RegCloseKey( handle
);
4168 case SE_FILE_OBJECT
:
4169 if (!(err
= get_security_file( name
, access
, &handle
)))
4171 err
= GetSecurityInfo( handle
, type
, info
, owner
, group
, dacl
, sacl
, descriptor
);
4172 CloseHandle( handle
);
4176 FIXME( "Object type %d is not currently supported.\n", type
);
4177 if (owner
) *owner
= NULL
;
4178 if (group
) *group
= NULL
;
4179 if (dacl
) *dacl
= NULL
;
4180 if (sacl
) *sacl
= NULL
;
4181 if (descriptor
) *descriptor
= NULL
;
4182 return ERROR_SUCCESS
;
4187 /******************************************************************************
4188 * GetNamedSecurityInfoExW [ADVAPI32.@]
4190 DWORD WINAPI
GetNamedSecurityInfoExW( LPCWSTR object
, SE_OBJECT_TYPE type
,
4191 SECURITY_INFORMATION info
, LPCWSTR provider
, LPCWSTR property
,
4192 PACTRL_ACCESSW
* access_list
, PACTRL_AUDITW
* audit_list
, LPWSTR
* owner
, LPWSTR
* group
)
4194 FIXME("(%s, %d, %d, %s, %s, %p, %p, %p, %p) stub\n", debugstr_w(object
), type
, info
,
4195 debugstr_w(provider
), debugstr_w(property
), access_list
, audit_list
, owner
, group
);
4196 return ERROR_CALL_NOT_IMPLEMENTED
;
4199 /******************************************************************************
4200 * GetNamedSecurityInfoExA [ADVAPI32.@]
4202 DWORD WINAPI
GetNamedSecurityInfoExA( LPCSTR object
, SE_OBJECT_TYPE type
,
4203 SECURITY_INFORMATION info
, LPCSTR provider
, LPCSTR property
,
4204 PACTRL_ACCESSA
* access_list
, PACTRL_AUDITA
* audit_list
, LPSTR
* owner
, LPSTR
* group
)
4206 FIXME("(%s, %d, %d, %s, %s, %p, %p, %p, %p) stub\n", debugstr_a(object
), type
, info
,
4207 debugstr_a(provider
), debugstr_a(property
), access_list
, audit_list
, owner
, group
);
4208 return ERROR_CALL_NOT_IMPLEMENTED
;
4211 /******************************************************************************
4212 * DecryptFileW [ADVAPI32.@]
4214 BOOL WINAPI
DecryptFileW(LPCWSTR lpFileName
, DWORD dwReserved
)
4216 FIXME("(%s, %08x): stub\n", debugstr_w(lpFileName
), dwReserved
);
4220 /******************************************************************************
4221 * DecryptFileA [ADVAPI32.@]
4223 BOOL WINAPI
DecryptFileA(LPCSTR lpFileName
, DWORD dwReserved
)
4225 FIXME("(%s, %08x): stub\n", debugstr_a(lpFileName
), dwReserved
);
4229 /******************************************************************************
4230 * EncryptFileW [ADVAPI32.@]
4232 BOOL WINAPI
EncryptFileW(LPCWSTR lpFileName
)
4234 FIXME("(%s): stub\n", debugstr_w(lpFileName
));
4238 /******************************************************************************
4239 * EncryptFileA [ADVAPI32.@]
4241 BOOL WINAPI
EncryptFileA(LPCSTR lpFileName
)
4243 FIXME("(%s): stub\n", debugstr_a(lpFileName
));
4247 /******************************************************************************
4248 * FileEncryptionStatusW [ADVAPI32.@]
4250 BOOL WINAPI
FileEncryptionStatusW(LPCWSTR lpFileName
, LPDWORD lpStatus
)
4252 FIXME("(%s %p): stub\n", debugstr_w(lpFileName
), lpStatus
);
4255 *lpStatus
= FILE_SYSTEM_NOT_SUPPORT
;
4259 /******************************************************************************
4260 * FileEncryptionStatusA [ADVAPI32.@]
4262 BOOL WINAPI
FileEncryptionStatusA(LPCSTR lpFileName
, LPDWORD lpStatus
)
4264 FIXME("(%s %p): stub\n", debugstr_a(lpFileName
), lpStatus
);
4267 *lpStatus
= FILE_SYSTEM_NOT_SUPPORT
;
4271 static NTSTATUS
combine_dacls(ACL
*parent
, ACL
*child
, ACL
**result
)
4277 /* initialize a combined DACL containing both inherited and new ACEs */
4278 combined
= heap_alloc_zero(child
->AclSize
+parent
->AclSize
);
4280 return STATUS_NO_MEMORY
;
4282 status
= RtlCreateAcl(combined
, parent
->AclSize
+child
->AclSize
, ACL_REVISION
);
4283 if (status
!= STATUS_SUCCESS
)
4285 heap_free(combined
);
4289 /* copy the new ACEs */
4290 for (i
=0; i
<child
->AceCount
; i
++)
4294 if (!GetAce(child
, i
, (void*)&ace
))
4296 if (!AddAce(combined
, ACL_REVISION
, MAXDWORD
, ace
, ace
->AceSize
))
4297 WARN("error adding new ACE\n");
4300 /* copy the inherited ACEs */
4301 for (i
=0; i
<parent
->AceCount
; i
++)
4305 if (!GetAce(parent
, i
, (void*)&ace
))
4307 if (!(ace
->AceFlags
& (OBJECT_INHERIT_ACE
|CONTAINER_INHERIT_ACE
)))
4309 if ((ace
->AceFlags
& (OBJECT_INHERIT_ACE
|CONTAINER_INHERIT_ACE
)) !=
4310 (OBJECT_INHERIT_ACE
|CONTAINER_INHERIT_ACE
))
4312 FIXME("unsupported flags: %x\n", ace
->AceFlags
);
4316 if (ace
->AceFlags
& NO_PROPAGATE_INHERIT_ACE
)
4317 ace
->AceFlags
&= ~(OBJECT_INHERIT_ACE
|CONTAINER_INHERIT_ACE
|NO_PROPAGATE_INHERIT_ACE
);
4318 ace
->AceFlags
&= ~INHERIT_ONLY_ACE
;
4319 ace
->AceFlags
|= INHERITED_ACE
;
4321 if (!AddAce(combined
, ACL_REVISION
, MAXDWORD
, ace
, ace
->AceSize
))
4322 WARN("error adding inherited ACE\n");
4326 return STATUS_SUCCESS
;
4329 /******************************************************************************
4330 * SetSecurityInfo [ADVAPI32.@]
4332 DWORD WINAPI
SetSecurityInfo(HANDLE handle
, SE_OBJECT_TYPE ObjectType
,
4333 SECURITY_INFORMATION SecurityInfo
, PSID psidOwner
,
4334 PSID psidGroup
, PACL pDacl
, PACL pSacl
)
4336 SECURITY_DESCRIPTOR sd
;
4340 if (!InitializeSecurityDescriptor(&sd
, SECURITY_DESCRIPTOR_REVISION
))
4341 return ERROR_INVALID_SECURITY_DESCR
;
4343 if (SecurityInfo
& OWNER_SECURITY_INFORMATION
)
4344 SetSecurityDescriptorOwner(&sd
, psidOwner
, FALSE
);
4345 if (SecurityInfo
& GROUP_SECURITY_INFORMATION
)
4346 SetSecurityDescriptorGroup(&sd
, psidGroup
, FALSE
);
4347 if (SecurityInfo
& DACL_SECURITY_INFORMATION
)
4349 if (ObjectType
== SE_FILE_OBJECT
&& pDacl
)
4351 SECURITY_DESCRIPTOR_CONTROL control
;
4352 PSECURITY_DESCRIPTOR psd
;
4353 OBJECT_NAME_INFORMATION
*name_info
;
4356 status
= NtQuerySecurityObject(handle
, SecurityInfo
, NULL
, 0, &size
);
4357 if (status
!= STATUS_BUFFER_TOO_SMALL
)
4358 return RtlNtStatusToDosError(status
);
4360 psd
= heap_alloc(size
);
4362 return ERROR_NOT_ENOUGH_MEMORY
;
4364 status
= NtQuerySecurityObject(handle
, SecurityInfo
, psd
, size
, &size
);
4368 return RtlNtStatusToDosError(status
);
4371 status
= RtlGetControlSecurityDescriptor(psd
, &control
, &rev
);
4374 return RtlNtStatusToDosError(status
);
4375 /* TODO: copy some control flags to new sd */
4377 /* inherit parent directory DACL */
4378 if (!(control
& SE_DACL_PROTECTED
))
4380 status
= NtQueryObject(handle
, ObjectNameInformation
, NULL
, 0, &size
);
4381 if (status
!= STATUS_INFO_LENGTH_MISMATCH
)
4382 return RtlNtStatusToDosError(status
);
4384 name_info
= heap_alloc(size
);
4386 return ERROR_NOT_ENOUGH_MEMORY
;
4388 status
= NtQueryObject(handle
, ObjectNameInformation
, name_info
, size
, NULL
);
4391 heap_free(name_info
);
4392 return RtlNtStatusToDosError(status
);
4395 for (name_info
->Name
.Length
-=2; name_info
->Name
.Length
>0; name_info
->Name
.Length
-=2)
4396 if (name_info
->Name
.Buffer
[name_info
->Name
.Length
/2-1]=='\\' ||
4397 name_info
->Name
.Buffer
[name_info
->Name
.Length
/2-1]=='/')
4399 if (name_info
->Name
.Length
)
4401 OBJECT_ATTRIBUTES attr
;
4404 PSECURITY_DESCRIPTOR parent_sd
;
4406 DWORD err
= ERROR_ACCESS_DENIED
;
4408 name_info
->Name
.Buffer
[name_info
->Name
.Length
/2] = 0;
4410 attr
.Length
= sizeof(attr
);
4411 attr
.RootDirectory
= 0;
4412 attr
.Attributes
= 0;
4413 attr
.ObjectName
= &name_info
->Name
;
4414 attr
.SecurityDescriptor
= NULL
;
4415 status
= NtOpenFile(&parent
, READ_CONTROL
|SYNCHRONIZE
, &attr
, &io
,
4416 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
4417 FILE_OPEN_FOR_BACKUP_INTENT
);
4418 heap_free(name_info
);
4421 err
= GetSecurityInfo(parent
, SE_FILE_OBJECT
, DACL_SECURITY_INFORMATION
,
4422 NULL
, NULL
, &parent_dacl
, NULL
, &parent_sd
);
4423 CloseHandle(parent
);
4428 status
= combine_dacls(parent_dacl
, pDacl
, &dacl
);
4429 LocalFree(parent_sd
);
4430 if (status
!= STATUS_SUCCESS
)
4431 return RtlNtStatusToDosError(status
);
4435 heap_free(name_info
);
4439 SetSecurityDescriptorDacl(&sd
, TRUE
, dacl
, FALSE
);
4441 if (SecurityInfo
& SACL_SECURITY_INFORMATION
)
4442 SetSecurityDescriptorSacl(&sd
, TRUE
, pSacl
, FALSE
);
4447 FIXME("stub: Service objects are not supported at this time.\n");
4448 status
= STATUS_SUCCESS
; /* Implement SetServiceObjectSecurity */
4451 status
= NtSetSecurityObject(handle
, SecurityInfo
, &sd
);
4456 return RtlNtStatusToDosError(status
);
4459 /******************************************************************************
4460 * SaferCreateLevel [ADVAPI32.@]
4462 BOOL WINAPI
SaferCreateLevel(DWORD ScopeId
, DWORD LevelId
, DWORD OpenFlags
,
4463 SAFER_LEVEL_HANDLE
* LevelHandle
, LPVOID lpReserved
)
4465 FIXME("(%u, %x, %u, %p, %p) stub\n", ScopeId
, LevelId
, OpenFlags
, LevelHandle
, lpReserved
);
4467 *LevelHandle
= (SAFER_LEVEL_HANDLE
)0xdeadbeef;
4471 /******************************************************************************
4472 * SaferComputeTokenFromLevel [ADVAPI32.@]
4474 BOOL WINAPI
SaferComputeTokenFromLevel(SAFER_LEVEL_HANDLE handle
, HANDLE token
, PHANDLE access_token
,
4475 DWORD flags
, LPVOID reserved
)
4477 FIXME("(%p, %p, %p, %x, %p) stub\n", handle
, token
, access_token
, flags
, reserved
);
4479 *access_token
= (flags
& SAFER_TOKEN_NULL_IF_EQUAL
) ? NULL
: (HANDLE
)0xdeadbeef;
4483 /******************************************************************************
4484 * SaferCloseLevel [ADVAPI32.@]
4486 BOOL WINAPI
SaferCloseLevel(SAFER_LEVEL_HANDLE handle
)
4488 FIXME("(%p) stub\n", handle
);
4492 /******************************************************************************
4493 * TreeResetNamedSecurityInfoW [ADVAPI32.@]
4495 DWORD WINAPI
TreeResetNamedSecurityInfoW( LPWSTR pObjectName
,
4496 SE_OBJECT_TYPE ObjectType
, SECURITY_INFORMATION SecurityInfo
,
4497 PSID pOwner
, PSID pGroup
, PACL pDacl
, PACL pSacl
,
4498 BOOL KeepExplicit
, FN_PROGRESS fnProgress
,
4499 PROG_INVOKE_SETTING ProgressInvokeSetting
, PVOID Args
)
4501 FIXME("(%s, %i, %i, %p, %p, %p, %p, %i, %p, %i, %p) stub\n",
4502 debugstr_w(pObjectName
), ObjectType
, SecurityInfo
, pOwner
, pGroup
,
4503 pDacl
, pSacl
, KeepExplicit
, fnProgress
, ProgressInvokeSetting
, Args
);
4505 return ERROR_SUCCESS
;
4508 /******************************************************************************
4509 * SaferGetPolicyInformation [ADVAPI32.@]
4511 BOOL WINAPI
SaferGetPolicyInformation(DWORD scope
, SAFER_POLICY_INFO_CLASS
class, DWORD size
,
4512 PVOID buffer
, PDWORD required
, LPVOID lpReserved
)
4514 FIXME("(%u %u %u %p %p %p) stub\n", scope
, class, size
, buffer
, required
, lpReserved
);
4518 /******************************************************************************
4519 * SaferIdentifyLevel [ADVAPI32.@]
4521 BOOL WINAPI
SaferIdentifyLevel(DWORD count
, SAFER_CODE_PROPERTIES
*properties
, SAFER_LEVEL_HANDLE
*handle
,
4524 FIXME("(%u %p %p %p) stub\n", count
, properties
, handle
, reserved
);
4525 *handle
= (SAFER_LEVEL_HANDLE
)0xdeadbeef;
4529 /******************************************************************************
4530 * SaferSetLevelInformation [ADVAPI32.@]
4532 BOOL WINAPI
SaferSetLevelInformation(SAFER_LEVEL_HANDLE handle
, SAFER_OBJECT_INFO_CLASS infotype
,
4533 LPVOID buffer
, DWORD size
)
4535 FIXME("(%p %u %p %u) stub\n", handle
, infotype
, buffer
, size
);
4539 /******************************************************************************
4540 * LookupSecurityDescriptorPartsA [ADVAPI32.@]
4542 DWORD WINAPI
LookupSecurityDescriptorPartsA(TRUSTEEA
*owner
, TRUSTEEA
*group
, ULONG
*access_count
,
4543 EXPLICIT_ACCESSA
*access_list
, ULONG
*audit_count
,
4544 EXPLICIT_ACCESSA
*audit_list
, SECURITY_DESCRIPTOR
*descriptor
)
4546 FIXME("(%p %p %p %p %p %p %p) stub\n", owner
, group
, access_count
,
4547 access_list
, audit_count
, audit_list
, descriptor
);
4548 return ERROR_CALL_NOT_IMPLEMENTED
;
4551 /******************************************************************************
4552 * LookupSecurityDescriptorPartsW [ADVAPI32.@]
4554 DWORD WINAPI
LookupSecurityDescriptorPartsW(TRUSTEEW
*owner
, TRUSTEEW
*group
, ULONG
*access_count
,
4555 EXPLICIT_ACCESSW
*access_list
, ULONG
*audit_count
,
4556 EXPLICIT_ACCESSW
*audit_list
, SECURITY_DESCRIPTOR
*descriptor
)
4558 FIXME("(%p %p %p %p %p %p %p) stub\n", owner
, group
, access_count
,
4559 access_list
, audit_count
, audit_list
, descriptor
);
4560 return ERROR_CALL_NOT_IMPLEMENTED
;