AccountInfo.cpp revision fcb5e646e4d775539e348fa21ba13307f2695bf5
4b6dc226f78862286daa69fba761eac9fd5da16aAutomatic Updater * Portions Copyright (C) 2001, 2002, 2004, 2007, 2009, 2013, 2016 Internet Systems Consortium, Inc. ("ISC")
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * This Source Code Form is subject to the terms of the Mozilla Public
ec5347e2c775f027573ce5648b910361aa926c01Automatic Updater * License, v. 2.0. If a copy of the MPL was not distributed with this
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * file, You can obtain one at http://mozilla.org/MPL/2.0/.
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews/* $Id: AccountInfo.cpp,v 1.10 2009/09/29 23:48:04 tbox Exp $ */
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews/* Compiled with UNICODE */
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews LPWSTR ServerName, /* machine to open policy on (Unicode) */
394f4aec2189750d7f861d00f97fe28ffcd9f659Mark Andrews DWORD DesiredAccess, /* desired access to policy */
394f4aec2189750d7f861d00f97fe28ffcd9f659Mark Andrews PLSA_HANDLE PolicyHandle /* resultant policy handle */
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews LPTSTR SystemName, /* where to lookup account */
0da29be670f6fa5b2a6320d9d843bc8b802c153aMark Andrews PSID *Sid /* resultant buffer containing SID */
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews LSA_HANDLE PolicyHandle, /* open policy handle */
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews PSID AccountSid, /* SID to grant privilege to */
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews LPWSTR PrivilegeName, /* privilege to grant (Unicode) */
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews LSA_HANDLE PolicyHandle, /* open policy handle */
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews PSID AccountSid, /* SID to grant privilege to */
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews wchar_t **PrivList, /* Ptr to List of Privileges found */
1676408640d8283c9f17eec0b183e1302ea7fd70Mark Andrews unsigned int *PrivCount /* total number of Privileges in list */
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews PLSA_UNICODE_STRING LsaString, /* destination */
1676408640d8283c9f17eec0b183e1302ea7fd70Mark Andrews LPSTR szAPI, /* pointer to function name (ANSI) */
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews LPSTR szAPI, /* pointer to function name (ANSI) */
37dee1ff94960a61243f611c0f87f8c316815c53Mark Andrews * Note that this code only retrieves the list of privileges of the
37dee1ff94960a61243f611c0f87f8c316815c53Mark Andrews * requested account or group. However, all accounts belong to the
37dee1ff94960a61243f611c0f87f8c316815c53Mark Andrews * Everyone group even though that group is not returned by the
37dee1ff94960a61243f611c0f87f8c316815c53Mark Andrews * calls to get the groups to which that account belongs.
394f4aec2189750d7f861d00f97fe28ffcd9f659Mark Andrews * The Everyone group has two privileges associated with it:
37dee1ff94960a61243f611c0f87f8c316815c53Mark Andrews * SeChangeNotifyPrivilege and SeNetworkLogonRight
37dee1ff94960a61243f611c0f87f8c316815c53Mark Andrews * It is not advisable to disable or remove these privileges
394f4aec2189750d7f861d00f97fe28ffcd9f659Mark Andrews * from the group nor can the account be removed from the Everyone
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * The None group has no privileges associated with it and is the group
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * to which an account belongs if it is associated with no group.
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark AndrewsGetAccountPrivileges(char *name, wchar_t **PrivList, unsigned int *PrivCount,
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews TCHAR AccountName[256]; /* static account name buffer */
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews unsigned int i;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews int iRetVal = RTN_ERROR; /* assume error from main */
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * Open the policy on the target machine.
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * Let's see if the account exists. Return if not
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews n = wnsprintf(AccountName, sizeof(AccountName), TEXT("%hS"), name);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews if (n < 0 || (size_t)n >= sizeof(AccountName)) {
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews if (!GetAccountSid(NULL, AccountName, &pSid)) {
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * Find out what groups the account belongs to
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews istatus = isc_ntsecurity_getaccountgroups(name, Accounts, maxAccounts,
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews Accounts[*totalAccounts] = name; /* Add the account to the list */
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * Loop through each Account to get the list of privileges
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews for (i = 0; i < *totalAccounts; i++) {
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews n = wnsprintf(AccountName, sizeof(AccountName), TEXT("%hS"),
394f4aec2189750d7f861d00f97fe28ffcd9f659Mark Andrews if (n < 0 || (size_t)n >= sizeof(AccountName)) {
394f4aec2189750d7f861d00f97fe28ffcd9f659Mark Andrews /* Obtain the SID of the user/group. */
394f4aec2189750d7f861d00f97fe28ffcd9f659Mark Andrews if (!GetAccountSid(NULL, AccountName, &pSid)) {
394f4aec2189750d7f861d00f97fe28ffcd9f659Mark Andrews continue; /* Try the next one */
37dee1ff94960a61243f611c0f87f8c316815c53Mark Andrews /* Get the Privileges allocated to this SID */
37dee1ff94960a61243f611c0f87f8c316815c53Mark Andrews if ((Status = GetPrivilegesOnAccount(PolicyHandle, pSid,
394f4aec2189750d7f861d00f97fe28ffcd9f659Mark Andrews continue; /* Try the next one */
394f4aec2189750d7f861d00f97fe28ffcd9f659Mark Andrews * Close the policy handle.
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews (*totalAccounts)--; /* Correct for the number of groups */
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark AndrewsCreateServiceAccount(char *name, char *password) {
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews mbstowcs(AccountPassword, password, passwdlen + 1);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * Set up the USER_INFO_1 structure.
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * USER_PRIV_USER: name is required here when creating an account
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * rather than an administrator or a guest.
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews ui.usri1_comment = L"ISC BIND Service Account";
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews ui.usri1_flags = UF_PASSWD_CANT_CHANGE | UF_DONT_EXPIRE_PASSWD |
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * Call the NetUserAdd function, specifying level 1.
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews nStatus = NetUserAdd(NULL, dwLevel, (LPBYTE)&ui, &dwError);
394f4aec2189750d7f861d00f97fe28ffcd9f659Mark Andrews retstat = AddPrivilegeToAcccount(name, SE_SERVICE_LOGON_PRIV);
37dee1ff94960a61243f611c0f87f8c316815c53Mark AndrewsAddPrivilegeToAcccount(LPTSTR name, LPWSTR PrivilegeName) {
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews TCHAR AccountName[256]; /* static account name buffer */
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews unsigned long err;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * Open the policy on the target machine.
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews if ((Status = OpenPolicy(NULL, POLICY_ALL_ACCESS, &PolicyHandle))
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * Let's see if the account exists. Return if not
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews n = wnsprintf(AccountName, sizeof(AccountName), TEXT("%hS"), name);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews if (n < 0 || (size_t)n >= sizeof(AccountName)) {
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews if (!GetAccountSid(NULL, AccountName, &pSid)) {
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews err = LsaNtStatusToWinError(SetPrivilegeOnAccount(PolicyHandle,
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark AndrewsInitLsaString(PLSA_UNICODE_STRING LsaString, LPWSTR String){
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews LsaString->Length = (USHORT) StringLength * sizeof(WCHAR);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews LsaString->MaximumLength = (USHORT)(StringLength+1) * sizeof(WCHAR);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark AndrewsOpenPolicy(LPWSTR ServerName, DWORD DesiredAccess, PLSA_HANDLE PolicyHandle){
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * Always initialize the object attributes to all zeroes.
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews ZeroMemory(&ObjectAttributes, sizeof(ObjectAttributes));
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * Make a LSA_UNICODE_STRING out of the LPWSTR passed in
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * Attempt to open the policy.
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews return (LsaOpenPolicy(Server, &ObjectAttributes, DesiredAccess,
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark AndrewsGetAccountSid(LPTSTR SystemName, LPTSTR AccountName, PSID *Sid) {
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews DWORD cbSid = 128; /* initial allocation attempt */
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews DWORD cbReferencedDomain = 16; /* initial allocation size */
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews BOOL bSuccess = FALSE; /* assume this function will fail */
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews * initial memory allocations
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews if ((*Sid = HeapAlloc(GetProcessHeap(), 0, cbSid)) == NULL)
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews if ((ReferencedDomain = (LPTSTR) HeapAlloc(GetProcessHeap(), 0,
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews * Obtain the SID of the specified account on the specified system.
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews while (!LookupAccountName(SystemName, AccountName, *Sid, &cbSid,
3d17a3ba61a303d5c4d9867068d0fbe9f24d2988Mark Andrews if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
3d17a3ba61a303d5c4d9867068d0fbe9f24d2988Mark Andrews /* reallocate memory */
if (!bSuccess) {
return (bSuccess);
if (bEnable)
unsigned int retlen = 0;
DWORD i, j;
int found;
return (Status);
for (i = 0; i < CountOfRights; i++) {
for (j = 0; j < *PrivCount; j++) {
retlen);
if (found == 0)
if (found != 0) {
return (RTN_NOMEMORY);
retlen);
(*PrivCount)++;
return (Status);