1*00b67f09SDavid van Moolenbroek /*
2*00b67f09SDavid van Moolenbroek * Portions Copyright (C) 2004, 2007, 2009, 2013 Internet Systems Consortium, Inc. ("ISC")
3*00b67f09SDavid van Moolenbroek * Portions Copyright (C) 2001, 2002 Internet Software Consortium.
4*00b67f09SDavid van Moolenbroek *
5*00b67f09SDavid van Moolenbroek * Permission to use, copy, modify, and/or distribute this software for any
6*00b67f09SDavid van Moolenbroek * purpose with or without fee is hereby granted, provided that the above
7*00b67f09SDavid van Moolenbroek * copyright notice and this permission notice appear in all copies.
8*00b67f09SDavid van Moolenbroek *
9*00b67f09SDavid van Moolenbroek * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
10*00b67f09SDavid van Moolenbroek * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11*00b67f09SDavid van Moolenbroek * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
12*00b67f09SDavid van Moolenbroek * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13*00b67f09SDavid van Moolenbroek * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
14*00b67f09SDavid van Moolenbroek * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15*00b67f09SDavid van Moolenbroek * PERFORMANCE OF THIS SOFTWARE.
16*00b67f09SDavid van Moolenbroek */
17*00b67f09SDavid van Moolenbroek
18*00b67f09SDavid van Moolenbroek /* Id: AccountInfo.cpp,v 1.10 2009/09/29 23:48:04 tbox Exp */
19*00b67f09SDavid van Moolenbroek
20*00b67f09SDavid van Moolenbroek /* Compiled with UNICODE */
21*00b67f09SDavid van Moolenbroek
22*00b67f09SDavid van Moolenbroek #include "stdafx.h"
23*00b67f09SDavid van Moolenbroek
24*00b67f09SDavid van Moolenbroek #include <windows.h>
25*00b67f09SDavid van Moolenbroek #include <lm.h>
26*00b67f09SDavid van Moolenbroek #include <ntsecapi.h>
27*00b67f09SDavid van Moolenbroek
28*00b67f09SDavid van Moolenbroek #include <isc/ntgroups.h>
29*00b67f09SDavid van Moolenbroek #include <isc/result.h>
30*00b67f09SDavid van Moolenbroek #include "AccountInfo.h"
31*00b67f09SDavid van Moolenbroek
32*00b67f09SDavid van Moolenbroek #define MAX_NAME_LENGTH 256
33*00b67f09SDavid van Moolenbroek
34*00b67f09SDavid van Moolenbroek NTSTATUS
35*00b67f09SDavid van Moolenbroek OpenPolicy(
36*00b67f09SDavid van Moolenbroek LPWSTR ServerName, /* machine to open policy on (Unicode) */
37*00b67f09SDavid van Moolenbroek DWORD DesiredAccess, /* desired access to policy */
38*00b67f09SDavid van Moolenbroek PLSA_HANDLE PolicyHandle /* resultant policy handle */
39*00b67f09SDavid van Moolenbroek );
40*00b67f09SDavid van Moolenbroek
41*00b67f09SDavid van Moolenbroek BOOL
42*00b67f09SDavid van Moolenbroek GetAccountSid(
43*00b67f09SDavid van Moolenbroek LPTSTR SystemName, /* where to lookup account */
44*00b67f09SDavid van Moolenbroek LPTSTR AccountName, /* account of interest */
45*00b67f09SDavid van Moolenbroek PSID *Sid /* resultant buffer containing SID */
46*00b67f09SDavid van Moolenbroek );
47*00b67f09SDavid van Moolenbroek
48*00b67f09SDavid van Moolenbroek NTSTATUS
49*00b67f09SDavid van Moolenbroek SetPrivilegeOnAccount(
50*00b67f09SDavid van Moolenbroek LSA_HANDLE PolicyHandle, /* open policy handle */
51*00b67f09SDavid van Moolenbroek PSID AccountSid, /* SID to grant privilege to */
52*00b67f09SDavid van Moolenbroek LPWSTR PrivilegeName, /* privilege to grant (Unicode) */
53*00b67f09SDavid van Moolenbroek BOOL bEnable /* enable or disable */
54*00b67f09SDavid van Moolenbroek );
55*00b67f09SDavid van Moolenbroek
56*00b67f09SDavid van Moolenbroek NTSTATUS
57*00b67f09SDavid van Moolenbroek GetPrivilegesOnAccount(
58*00b67f09SDavid van Moolenbroek LSA_HANDLE PolicyHandle, /* open policy handle */
59*00b67f09SDavid van Moolenbroek PSID AccountSid, /* SID to grant privilege to */
60*00b67f09SDavid van Moolenbroek wchar_t **PrivList, /* Ptr to List of Privileges found */
61*00b67f09SDavid van Moolenbroek unsigned int *PrivCount /* total number of Privileges in list */
62*00b67f09SDavid van Moolenbroek );
63*00b67f09SDavid van Moolenbroek
64*00b67f09SDavid van Moolenbroek NTSTATUS
65*00b67f09SDavid van Moolenbroek AddPrivilegeToAcccount(
66*00b67f09SDavid van Moolenbroek LPTSTR AccountName, /* Name of the account */
67*00b67f09SDavid van Moolenbroek LPWSTR PrivilegeName /* Privilege to Add */
68*00b67f09SDavid van Moolenbroek );
69*00b67f09SDavid van Moolenbroek
70*00b67f09SDavid van Moolenbroek void
71*00b67f09SDavid van Moolenbroek InitLsaString(
72*00b67f09SDavid van Moolenbroek PLSA_UNICODE_STRING LsaString, /* destination */
73*00b67f09SDavid van Moolenbroek LPWSTR String /* source (Unicode) */
74*00b67f09SDavid van Moolenbroek );
75*00b67f09SDavid van Moolenbroek
76*00b67f09SDavid van Moolenbroek void
77*00b67f09SDavid van Moolenbroek DisplayNtStatus(
78*00b67f09SDavid van Moolenbroek LPSTR szAPI, /* pointer to function name (ANSI) */
79*00b67f09SDavid van Moolenbroek NTSTATUS Status /* NTSTATUS error value */
80*00b67f09SDavid van Moolenbroek );
81*00b67f09SDavid van Moolenbroek
82*00b67f09SDavid van Moolenbroek void
83*00b67f09SDavid van Moolenbroek DisplayWinError(
84*00b67f09SDavid van Moolenbroek LPSTR szAPI, /* pointer to function name (ANSI) */
85*00b67f09SDavid van Moolenbroek DWORD WinError /* DWORD WinError */
86*00b67f09SDavid van Moolenbroek );
87*00b67f09SDavid van Moolenbroek
88*00b67f09SDavid van Moolenbroek #ifndef STATUS_SUCCESS
89*00b67f09SDavid van Moolenbroek #define STATUS_SUCCESS ((NTSTATUS)0x00000000L)
90*00b67f09SDavid van Moolenbroek #endif
91*00b67f09SDavid van Moolenbroek
92*00b67f09SDavid van Moolenbroek /*
93*00b67f09SDavid van Moolenbroek * Note that this code only retrieves the list of privileges of the
94*00b67f09SDavid van Moolenbroek * requested account or group. However, all accounts belong to the
95*00b67f09SDavid van Moolenbroek * Everyone group even though that group is not returned by the
96*00b67f09SDavid van Moolenbroek * calls to get the groups to which that account belongs.
97*00b67f09SDavid van Moolenbroek * The Everyone group has two privileges associated with it:
98*00b67f09SDavid van Moolenbroek * SeChangeNotifyPrivilege and SeNetworkLogonRight
99*00b67f09SDavid van Moolenbroek * It is not advisable to disable or remove these privileges
100*00b67f09SDavid van Moolenbroek * from the group nor can the account be removed from the Everyone
101*00b67f09SDavid van Moolenbroek * group
102*00b67f09SDavid van Moolenbroek * The None group has no privileges associated with it and is the group
103*00b67f09SDavid van Moolenbroek * to which an account belongs if it is associated with no group.
104*00b67f09SDavid van Moolenbroek */
105*00b67f09SDavid van Moolenbroek
106*00b67f09SDavid van Moolenbroek int
GetAccountPrivileges(char * name,wchar_t ** PrivList,unsigned int * PrivCount,char ** Accounts,unsigned int * totalAccounts,int maxAccounts)107*00b67f09SDavid van Moolenbroek GetAccountPrivileges(char *name, wchar_t **PrivList, unsigned int *PrivCount,
108*00b67f09SDavid van Moolenbroek char **Accounts, unsigned int *totalAccounts,
109*00b67f09SDavid van Moolenbroek int maxAccounts)
110*00b67f09SDavid van Moolenbroek {
111*00b67f09SDavid van Moolenbroek LSA_HANDLE PolicyHandle;
112*00b67f09SDavid van Moolenbroek TCHAR AccountName[256]; /* static account name buffer */
113*00b67f09SDavid van Moolenbroek PSID pSid;
114*00b67f09SDavid van Moolenbroek unsigned int i;
115*00b67f09SDavid van Moolenbroek NTSTATUS Status;
116*00b67f09SDavid van Moolenbroek isc_result_t istatus;
117*00b67f09SDavid van Moolenbroek int iRetVal = RTN_ERROR; /* assume error from main */
118*00b67f09SDavid van Moolenbroek
119*00b67f09SDavid van Moolenbroek /*
120*00b67f09SDavid van Moolenbroek * Open the policy on the target machine.
121*00b67f09SDavid van Moolenbroek */
122*00b67f09SDavid van Moolenbroek if ((Status = OpenPolicy(NULL,
123*00b67f09SDavid van Moolenbroek POLICY_LOOKUP_NAMES,
124*00b67f09SDavid van Moolenbroek &PolicyHandle)) != STATUS_SUCCESS)
125*00b67f09SDavid van Moolenbroek return (RTN_ERROR);
126*00b67f09SDavid van Moolenbroek
127*00b67f09SDavid van Moolenbroek /*
128*00b67f09SDavid van Moolenbroek * Let's see if the account exists. Return if not
129*00b67f09SDavid van Moolenbroek */
130*00b67f09SDavid van Moolenbroek wsprintf(AccountName, TEXT("%hS"), name);
131*00b67f09SDavid van Moolenbroek if (!GetAccountSid(NULL, AccountName, &pSid))
132*00b67f09SDavid van Moolenbroek return (RTN_NOACCOUNT);
133*00b67f09SDavid van Moolenbroek /*
134*00b67f09SDavid van Moolenbroek * Find out what groups the account belongs to
135*00b67f09SDavid van Moolenbroek */
136*00b67f09SDavid van Moolenbroek istatus = isc_ntsecurity_getaccountgroups(name, Accounts, maxAccounts,
137*00b67f09SDavid van Moolenbroek totalAccounts);
138*00b67f09SDavid van Moolenbroek if (istatus == ISC_R_NOMEMORY)
139*00b67f09SDavid van Moolenbroek return (RTN_NOMEMORY);
140*00b67f09SDavid van Moolenbroek else if (istatus != ISC_R_SUCCESS)
141*00b67f09SDavid van Moolenbroek return (RTN_ERROR);
142*00b67f09SDavid van Moolenbroek
143*00b67f09SDavid van Moolenbroek Accounts[*totalAccounts] = name; /* Add the account to the list */
144*00b67f09SDavid van Moolenbroek (*totalAccounts)++;
145*00b67f09SDavid van Moolenbroek
146*00b67f09SDavid van Moolenbroek /*
147*00b67f09SDavid van Moolenbroek * Loop through each Account to get the list of privileges
148*00b67f09SDavid van Moolenbroek */
149*00b67f09SDavid van Moolenbroek for (i = 0; i < *totalAccounts; i++) {
150*00b67f09SDavid van Moolenbroek wsprintf(AccountName, TEXT("%hS"), Accounts[i]);
151*00b67f09SDavid van Moolenbroek /* Obtain the SID of the user/group. */
152*00b67f09SDavid van Moolenbroek if (!GetAccountSid(NULL, AccountName, &pSid))
153*00b67f09SDavid van Moolenbroek continue; /* Try the next one */
154*00b67f09SDavid van Moolenbroek /* Get the Privileges allocated to this SID */
155*00b67f09SDavid van Moolenbroek if ((Status = GetPrivilegesOnAccount(PolicyHandle, pSid,
156*00b67f09SDavid van Moolenbroek PrivList, PrivCount)) == STATUS_SUCCESS)
157*00b67f09SDavid van Moolenbroek {
158*00b67f09SDavid van Moolenbroek iRetVal=RTN_OK;
159*00b67f09SDavid van Moolenbroek if (pSid != NULL)
160*00b67f09SDavid van Moolenbroek HeapFree(GetProcessHeap(), 0, pSid);
161*00b67f09SDavid van Moolenbroek } else {
162*00b67f09SDavid van Moolenbroek if (pSid != NULL)
163*00b67f09SDavid van Moolenbroek HeapFree(GetProcessHeap(), 0, pSid);
164*00b67f09SDavid van Moolenbroek continue; /* Try the next one */
165*00b67f09SDavid van Moolenbroek }
166*00b67f09SDavid van Moolenbroek }
167*00b67f09SDavid van Moolenbroek /*
168*00b67f09SDavid van Moolenbroek * Close the policy handle.
169*00b67f09SDavid van Moolenbroek */
170*00b67f09SDavid van Moolenbroek LsaClose(PolicyHandle);
171*00b67f09SDavid van Moolenbroek
172*00b67f09SDavid van Moolenbroek (*totalAccounts)--; /* Correct for the number of groups */
173*00b67f09SDavid van Moolenbroek return iRetVal;
174*00b67f09SDavid van Moolenbroek }
175*00b67f09SDavid van Moolenbroek
176*00b67f09SDavid van Moolenbroek BOOL
CreateServiceAccount(char * name,char * password)177*00b67f09SDavid van Moolenbroek CreateServiceAccount(char *name, char *password) {
178*00b67f09SDavid van Moolenbroek NTSTATUS retstat;
179*00b67f09SDavid van Moolenbroek USER_INFO_1 ui;
180*00b67f09SDavid van Moolenbroek DWORD dwLevel = 1;
181*00b67f09SDavid van Moolenbroek DWORD dwError = 0;
182*00b67f09SDavid van Moolenbroek NET_API_STATUS nStatus;
183*00b67f09SDavid van Moolenbroek
184*00b67f09SDavid van Moolenbroek size_t namelen = strlen(name);
185*00b67f09SDavid van Moolenbroek size_t passwdlen = strlen(password);
186*00b67f09SDavid van Moolenbroek wchar_t AccountName[MAX_NAME_LENGTH];
187*00b67f09SDavid van Moolenbroek wchar_t AccountPassword[MAX_NAME_LENGTH];
188*00b67f09SDavid van Moolenbroek
189*00b67f09SDavid van Moolenbroek mbstowcs(AccountName, name, namelen + 1);
190*00b67f09SDavid van Moolenbroek mbstowcs(AccountPassword, password, passwdlen + 1);
191*00b67f09SDavid van Moolenbroek
192*00b67f09SDavid van Moolenbroek /*
193*00b67f09SDavid van Moolenbroek * Set up the USER_INFO_1 structure.
194*00b67f09SDavid van Moolenbroek * USER_PRIV_USER: name is required here when creating an account
195*00b67f09SDavid van Moolenbroek * rather than an administrator or a guest.
196*00b67f09SDavid van Moolenbroek */
197*00b67f09SDavid van Moolenbroek
198*00b67f09SDavid van Moolenbroek ui.usri1_name = (LPWSTR) &AccountName;
199*00b67f09SDavid van Moolenbroek ui.usri1_password = (LPWSTR) &AccountPassword;
200*00b67f09SDavid van Moolenbroek ui.usri1_priv = USER_PRIV_USER;
201*00b67f09SDavid van Moolenbroek ui.usri1_home_dir = NULL;
202*00b67f09SDavid van Moolenbroek ui.usri1_comment = L"ISC BIND Service Account";
203*00b67f09SDavid van Moolenbroek ui.usri1_flags = UF_PASSWD_CANT_CHANGE | UF_DONT_EXPIRE_PASSWD |
204*00b67f09SDavid van Moolenbroek UF_SCRIPT;
205*00b67f09SDavid van Moolenbroek ui.usri1_script_path = NULL;
206*00b67f09SDavid van Moolenbroek /*
207*00b67f09SDavid van Moolenbroek * Call the NetUserAdd function, specifying level 1.
208*00b67f09SDavid van Moolenbroek */
209*00b67f09SDavid van Moolenbroek nStatus = NetUserAdd(NULL, dwLevel, (LPBYTE)&ui, &dwError);
210*00b67f09SDavid van Moolenbroek
211*00b67f09SDavid van Moolenbroek if (nStatus != NERR_Success)
212*00b67f09SDavid van Moolenbroek return (FALSE);
213*00b67f09SDavid van Moolenbroek
214*00b67f09SDavid van Moolenbroek retstat = AddPrivilegeToAcccount(name, SE_SERVICE_LOGON_PRIV);
215*00b67f09SDavid van Moolenbroek return (TRUE);
216*00b67f09SDavid van Moolenbroek }
217*00b67f09SDavid van Moolenbroek
218*00b67f09SDavid van Moolenbroek NTSTATUS
AddPrivilegeToAcccount(LPTSTR name,LPWSTR PrivilegeName)219*00b67f09SDavid van Moolenbroek AddPrivilegeToAcccount(LPTSTR name, LPWSTR PrivilegeName) {
220*00b67f09SDavid van Moolenbroek LSA_HANDLE PolicyHandle;
221*00b67f09SDavid van Moolenbroek TCHAR AccountName[256]; /* static account name buffer */
222*00b67f09SDavid van Moolenbroek PSID pSid;
223*00b67f09SDavid van Moolenbroek NTSTATUS Status;
224*00b67f09SDavid van Moolenbroek unsigned long err;
225*00b67f09SDavid van Moolenbroek
226*00b67f09SDavid van Moolenbroek /*
227*00b67f09SDavid van Moolenbroek * Open the policy on the target machine.
228*00b67f09SDavid van Moolenbroek */
229*00b67f09SDavid van Moolenbroek if ((Status = OpenPolicy(NULL, POLICY_ALL_ACCESS, &PolicyHandle))
230*00b67f09SDavid van Moolenbroek != STATUS_SUCCESS)
231*00b67f09SDavid van Moolenbroek return (RTN_ERROR);
232*00b67f09SDavid van Moolenbroek
233*00b67f09SDavid van Moolenbroek /*
234*00b67f09SDavid van Moolenbroek * Let's see if the account exists. Return if not
235*00b67f09SDavid van Moolenbroek */
236*00b67f09SDavid van Moolenbroek wsprintf(AccountName, TEXT("%hS"), name);
237*00b67f09SDavid van Moolenbroek if (!GetAccountSid(NULL, AccountName, &pSid))
238*00b67f09SDavid van Moolenbroek return (RTN_NOACCOUNT);
239*00b67f09SDavid van Moolenbroek
240*00b67f09SDavid van Moolenbroek err = LsaNtStatusToWinError(SetPrivilegeOnAccount(PolicyHandle,
241*00b67f09SDavid van Moolenbroek pSid, PrivilegeName, TRUE));
242*00b67f09SDavid van Moolenbroek
243*00b67f09SDavid van Moolenbroek LsaClose(PolicyHandle);
244*00b67f09SDavid van Moolenbroek if (err == ERROR_SUCCESS)
245*00b67f09SDavid van Moolenbroek return (RTN_OK);
246*00b67f09SDavid van Moolenbroek else
247*00b67f09SDavid van Moolenbroek return (err);
248*00b67f09SDavid van Moolenbroek }
249*00b67f09SDavid van Moolenbroek
250*00b67f09SDavid van Moolenbroek void
InitLsaString(PLSA_UNICODE_STRING LsaString,LPWSTR String)251*00b67f09SDavid van Moolenbroek InitLsaString(PLSA_UNICODE_STRING LsaString, LPWSTR String){
252*00b67f09SDavid van Moolenbroek size_t StringLength;
253*00b67f09SDavid van Moolenbroek
254*00b67f09SDavid van Moolenbroek if (String == NULL) {
255*00b67f09SDavid van Moolenbroek LsaString->Buffer = NULL;
256*00b67f09SDavid van Moolenbroek LsaString->Length = 0;
257*00b67f09SDavid van Moolenbroek LsaString->MaximumLength = 0;
258*00b67f09SDavid van Moolenbroek return;
259*00b67f09SDavid van Moolenbroek }
260*00b67f09SDavid van Moolenbroek
261*00b67f09SDavid van Moolenbroek StringLength = wcslen(String);
262*00b67f09SDavid van Moolenbroek LsaString->Buffer = String;
263*00b67f09SDavid van Moolenbroek LsaString->Length = (USHORT) StringLength * sizeof(WCHAR);
264*00b67f09SDavid van Moolenbroek LsaString->MaximumLength = (USHORT)(StringLength+1) * sizeof(WCHAR);
265*00b67f09SDavid van Moolenbroek }
266*00b67f09SDavid van Moolenbroek
267*00b67f09SDavid van Moolenbroek NTSTATUS
OpenPolicy(LPWSTR ServerName,DWORD DesiredAccess,PLSA_HANDLE PolicyHandle)268*00b67f09SDavid van Moolenbroek OpenPolicy(LPWSTR ServerName, DWORD DesiredAccess, PLSA_HANDLE PolicyHandle){
269*00b67f09SDavid van Moolenbroek LSA_OBJECT_ATTRIBUTES ObjectAttributes;
270*00b67f09SDavid van Moolenbroek LSA_UNICODE_STRING ServerString;
271*00b67f09SDavid van Moolenbroek PLSA_UNICODE_STRING Server = NULL;
272*00b67f09SDavid van Moolenbroek
273*00b67f09SDavid van Moolenbroek /*
274*00b67f09SDavid van Moolenbroek * Always initialize the object attributes to all zeroes.
275*00b67f09SDavid van Moolenbroek */
276*00b67f09SDavid van Moolenbroek ZeroMemory(&ObjectAttributes, sizeof(ObjectAttributes));
277*00b67f09SDavid van Moolenbroek
278*00b67f09SDavid van Moolenbroek if (ServerName != NULL) {
279*00b67f09SDavid van Moolenbroek /*
280*00b67f09SDavid van Moolenbroek * Make a LSA_UNICODE_STRING out of the LPWSTR passed in
281*00b67f09SDavid van Moolenbroek */
282*00b67f09SDavid van Moolenbroek InitLsaString(&ServerString, ServerName);
283*00b67f09SDavid van Moolenbroek Server = &ServerString;
284*00b67f09SDavid van Moolenbroek }
285*00b67f09SDavid van Moolenbroek
286*00b67f09SDavid van Moolenbroek /*
287*00b67f09SDavid van Moolenbroek * Attempt to open the policy.
288*00b67f09SDavid van Moolenbroek */
289*00b67f09SDavid van Moolenbroek return (LsaOpenPolicy(Server, &ObjectAttributes, DesiredAccess,
290*00b67f09SDavid van Moolenbroek PolicyHandle));
291*00b67f09SDavid van Moolenbroek }
292*00b67f09SDavid van Moolenbroek
293*00b67f09SDavid van Moolenbroek BOOL
GetAccountSid(LPTSTR SystemName,LPTSTR AccountName,PSID * Sid)294*00b67f09SDavid van Moolenbroek GetAccountSid(LPTSTR SystemName, LPTSTR AccountName, PSID *Sid) {
295*00b67f09SDavid van Moolenbroek LPTSTR ReferencedDomain = NULL;
296*00b67f09SDavid van Moolenbroek DWORD cbSid = 128; /* initial allocation attempt */
297*00b67f09SDavid van Moolenbroek DWORD cbReferencedDomain = 16; /* initial allocation size */
298*00b67f09SDavid van Moolenbroek SID_NAME_USE peUse;
299*00b67f09SDavid van Moolenbroek BOOL bSuccess = FALSE; /* assume this function will fail */
300*00b67f09SDavid van Moolenbroek
301*00b67f09SDavid van Moolenbroek __try {
302*00b67f09SDavid van Moolenbroek /*
303*00b67f09SDavid van Moolenbroek * initial memory allocations
304*00b67f09SDavid van Moolenbroek */
305*00b67f09SDavid van Moolenbroek if ((*Sid = HeapAlloc(GetProcessHeap(), 0, cbSid)) == NULL)
306*00b67f09SDavid van Moolenbroek __leave;
307*00b67f09SDavid van Moolenbroek
308*00b67f09SDavid van Moolenbroek if ((ReferencedDomain = (LPTSTR) HeapAlloc(GetProcessHeap(), 0,
309*00b67f09SDavid van Moolenbroek cbReferencedDomain)) == NULL) __leave;
310*00b67f09SDavid van Moolenbroek
311*00b67f09SDavid van Moolenbroek /*
312*00b67f09SDavid van Moolenbroek * Obtain the SID of the specified account on the specified system.
313*00b67f09SDavid van Moolenbroek */
314*00b67f09SDavid van Moolenbroek while (!LookupAccountName(SystemName, AccountName, *Sid, &cbSid,
315*00b67f09SDavid van Moolenbroek ReferencedDomain, &cbReferencedDomain,
316*00b67f09SDavid van Moolenbroek &peUse))
317*00b67f09SDavid van Moolenbroek {
318*00b67f09SDavid van Moolenbroek if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
319*00b67f09SDavid van Moolenbroek /* reallocate memory */
320*00b67f09SDavid van Moolenbroek if ((*Sid = HeapReAlloc(GetProcessHeap(), 0,
321*00b67f09SDavid van Moolenbroek *Sid, cbSid)) == NULL) __leave;
322*00b67f09SDavid van Moolenbroek
323*00b67f09SDavid van Moolenbroek if ((ReferencedDomain= (LPTSTR) HeapReAlloc(
324*00b67f09SDavid van Moolenbroek GetProcessHeap(), 0, ReferencedDomain,
325*00b67f09SDavid van Moolenbroek cbReferencedDomain)) == NULL)
326*00b67f09SDavid van Moolenbroek __leave;
327*00b67f09SDavid van Moolenbroek }
328*00b67f09SDavid van Moolenbroek else
329*00b67f09SDavid van Moolenbroek __leave;
330*00b67f09SDavid van Moolenbroek }
331*00b67f09SDavid van Moolenbroek bSuccess = TRUE;
332*00b67f09SDavid van Moolenbroek } /* finally */
333*00b67f09SDavid van Moolenbroek __finally {
334*00b67f09SDavid van Moolenbroek
335*00b67f09SDavid van Moolenbroek /* Cleanup and indicate failure, if appropriate. */
336*00b67f09SDavid van Moolenbroek
337*00b67f09SDavid van Moolenbroek HeapFree(GetProcessHeap(), 0, ReferencedDomain);
338*00b67f09SDavid van Moolenbroek
339*00b67f09SDavid van Moolenbroek if (!bSuccess) {
340*00b67f09SDavid van Moolenbroek if (*Sid != NULL) {
341*00b67f09SDavid van Moolenbroek HeapFree(GetProcessHeap(), 0, *Sid);
342*00b67f09SDavid van Moolenbroek *Sid = NULL;
343*00b67f09SDavid van Moolenbroek }
344*00b67f09SDavid van Moolenbroek }
345*00b67f09SDavid van Moolenbroek
346*00b67f09SDavid van Moolenbroek }
347*00b67f09SDavid van Moolenbroek
348*00b67f09SDavid van Moolenbroek return (bSuccess);
349*00b67f09SDavid van Moolenbroek }
350*00b67f09SDavid van Moolenbroek
351*00b67f09SDavid van Moolenbroek NTSTATUS
SetPrivilegeOnAccount(LSA_HANDLE PolicyHandle,PSID AccountSid,LPWSTR PrivilegeName,BOOL bEnable)352*00b67f09SDavid van Moolenbroek SetPrivilegeOnAccount(LSA_HANDLE PolicyHandle, PSID AccountSid,
353*00b67f09SDavid van Moolenbroek LPWSTR PrivilegeName, BOOL bEnable)
354*00b67f09SDavid van Moolenbroek {
355*00b67f09SDavid van Moolenbroek LSA_UNICODE_STRING PrivilegeString;
356*00b67f09SDavid van Moolenbroek
357*00b67f09SDavid van Moolenbroek /* Create a LSA_UNICODE_STRING for the privilege name. */
358*00b67f09SDavid van Moolenbroek InitLsaString(&PrivilegeString, PrivilegeName);
359*00b67f09SDavid van Moolenbroek
360*00b67f09SDavid van Moolenbroek /* grant or revoke the privilege, accordingly */
361*00b67f09SDavid van Moolenbroek if (bEnable)
362*00b67f09SDavid van Moolenbroek return (LsaAddAccountRights(PolicyHandle, AccountSid,
363*00b67f09SDavid van Moolenbroek &PrivilegeString, 1));
364*00b67f09SDavid van Moolenbroek else
365*00b67f09SDavid van Moolenbroek return (LsaRemoveAccountRights(PolicyHandle, AccountSid,
366*00b67f09SDavid van Moolenbroek FALSE, &PrivilegeString, 1));
367*00b67f09SDavid van Moolenbroek }
368*00b67f09SDavid van Moolenbroek
369*00b67f09SDavid van Moolenbroek NTSTATUS
GetPrivilegesOnAccount(LSA_HANDLE PolicyHandle,PSID AccountSid,wchar_t ** PrivList,unsigned int * PrivCount)370*00b67f09SDavid van Moolenbroek GetPrivilegesOnAccount(LSA_HANDLE PolicyHandle, PSID AccountSid,
371*00b67f09SDavid van Moolenbroek wchar_t **PrivList, unsigned int *PrivCount)
372*00b67f09SDavid van Moolenbroek {
373*00b67f09SDavid van Moolenbroek NTSTATUS Status;
374*00b67f09SDavid van Moolenbroek LSA_UNICODE_STRING *UserRights;
375*00b67f09SDavid van Moolenbroek ULONG CountOfRights;
376*00b67f09SDavid van Moolenbroek unsigned int retlen = 0;
377*00b67f09SDavid van Moolenbroek DWORD i, j;
378*00b67f09SDavid van Moolenbroek int found;
379*00b67f09SDavid van Moolenbroek
380*00b67f09SDavid van Moolenbroek Status = LsaEnumerateAccountRights(PolicyHandle, AccountSid,
381*00b67f09SDavid van Moolenbroek &UserRights, &CountOfRights);
382*00b67f09SDavid van Moolenbroek /* Only continue if there is something */
383*00b67f09SDavid van Moolenbroek if (UserRights == NULL || Status != STATUS_SUCCESS)
384*00b67f09SDavid van Moolenbroek return (Status);
385*00b67f09SDavid van Moolenbroek
386*00b67f09SDavid van Moolenbroek for (i = 0; i < CountOfRights; i++) {
387*00b67f09SDavid van Moolenbroek found = -1;
388*00b67f09SDavid van Moolenbroek retlen = UserRights[i].Length/sizeof(wchar_t);
389*00b67f09SDavid van Moolenbroek for (j = 0; j < *PrivCount; j++) {
390*00b67f09SDavid van Moolenbroek found = wcsncmp(PrivList[j], UserRights[i].Buffer,
391*00b67f09SDavid van Moolenbroek retlen);
392*00b67f09SDavid van Moolenbroek if (found == 0)
393*00b67f09SDavid van Moolenbroek break;
394*00b67f09SDavid van Moolenbroek }
395*00b67f09SDavid van Moolenbroek if (found != 0) {
396*00b67f09SDavid van Moolenbroek PrivList[*PrivCount] =
397*00b67f09SDavid van Moolenbroek (wchar_t *)malloc(UserRights[i].MaximumLength);
398*00b67f09SDavid van Moolenbroek if (PrivList[*PrivCount] == NULL)
399*00b67f09SDavid van Moolenbroek return (RTN_NOMEMORY);
400*00b67f09SDavid van Moolenbroek
401*00b67f09SDavid van Moolenbroek wcsncpy(PrivList[*PrivCount], UserRights[i].Buffer,
402*00b67f09SDavid van Moolenbroek retlen);
403*00b67f09SDavid van Moolenbroek PrivList[*PrivCount][retlen] = L'\0';
404*00b67f09SDavid van Moolenbroek (*PrivCount)++;
405*00b67f09SDavid van Moolenbroek }
406*00b67f09SDavid van Moolenbroek
407*00b67f09SDavid van Moolenbroek }
408*00b67f09SDavid van Moolenbroek
409*00b67f09SDavid van Moolenbroek return (Status);
410*00b67f09SDavid van Moolenbroek }
411*00b67f09SDavid van Moolenbroek
412*00b67f09SDavid van Moolenbroek void
DisplayNtStatus(LPSTR szAPI,NTSTATUS Status)413*00b67f09SDavid van Moolenbroek DisplayNtStatus(LPSTR szAPI, NTSTATUS Status) {
414*00b67f09SDavid van Moolenbroek /* Convert the NTSTATUS to Winerror. Then call DisplayWinError(). */
415*00b67f09SDavid van Moolenbroek DisplayWinError(szAPI, LsaNtStatusToWinError(Status));
416*00b67f09SDavid van Moolenbroek }
417*00b67f09SDavid van Moolenbroek
418*00b67f09SDavid van Moolenbroek void
DisplayWinError(LPSTR szAPI,DWORD WinError)419*00b67f09SDavid van Moolenbroek DisplayWinError(LPSTR szAPI, DWORD WinError) {
420*00b67f09SDavid van Moolenbroek LPSTR MessageBuffer;
421*00b67f09SDavid van Moolenbroek DWORD dwBufferLength;
422*00b67f09SDavid van Moolenbroek
423*00b67f09SDavid van Moolenbroek if (dwBufferLength=FormatMessageA(
424*00b67f09SDavid van Moolenbroek FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
425*00b67f09SDavid van Moolenbroek NULL, WinError, GetUserDefaultLangID(),
426*00b67f09SDavid van Moolenbroek (LPSTR) &MessageBuffer, 0, NULL)){
427*00b67f09SDavid van Moolenbroek DWORD dwBytesWritten; /* unused */
428*00b67f09SDavid van Moolenbroek
429*00b67f09SDavid van Moolenbroek /* Output message string on stderr. */
430*00b67f09SDavid van Moolenbroek WriteFile(GetStdHandle(STD_ERROR_HANDLE), MessageBuffer,
431*00b67f09SDavid van Moolenbroek dwBufferLength, &dwBytesWritten, NULL);
432*00b67f09SDavid van Moolenbroek
433*00b67f09SDavid van Moolenbroek /* Free the buffer allocated by the system. */
434*00b67f09SDavid van Moolenbroek LocalFree(MessageBuffer);
435*00b67f09SDavid van Moolenbroek }
436*00b67f09SDavid van Moolenbroek }
437