2f0eac53a97037ee18478b5aedc479b498ed6702Tinderbox User * Portions Copyright (C) 2001, 2002, 2004, 2007, 2009, 2013, 2016, 2017 Internet Systems Consortium, Inc. ("ISC")
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews * This Source Code Form is subject to the terms of the Mozilla Public
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews * License, v. 2.0. If a copy of the MPL was not distributed with this
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews * file, You can obtain one at http://mozilla.org/MPL/2.0/.
61dd99bfae0ffa8ec193cf48fc86e4fa246a06e2Automatic Updater/* $Id: AccountInfo.cpp,v 1.10 2009/09/29 23:48:04 tbox Exp $ */
c3c8823fed039b3a2b8e5ca8bc2f3301d1dd840eMark Andrews/* Compiled with UNICODE */
1ebeb6bbf3c25a710ed7b6fbd2608f3850fc7f8fDanny Mayer LPWSTR ServerName, /* machine to open policy on (Unicode) */
1ebeb6bbf3c25a710ed7b6fbd2608f3850fc7f8fDanny Mayer DWORD DesiredAccess, /* desired access to policy */
1ebeb6bbf3c25a710ed7b6fbd2608f3850fc7f8fDanny Mayer PLSA_HANDLE PolicyHandle /* resultant policy handle */
1ebeb6bbf3c25a710ed7b6fbd2608f3850fc7f8fDanny Mayer LPTSTR SystemName, /* where to lookup account */
1ebeb6bbf3c25a710ed7b6fbd2608f3850fc7f8fDanny Mayer LSA_HANDLE PolicyHandle, /* open policy handle */
1ebeb6bbf3c25a710ed7b6fbd2608f3850fc7f8fDanny Mayer PSID AccountSid, /* SID to grant privilege to */
1ebeb6bbf3c25a710ed7b6fbd2608f3850fc7f8fDanny Mayer LPWSTR PrivilegeName, /* privilege to grant (Unicode) */
1ebeb6bbf3c25a710ed7b6fbd2608f3850fc7f8fDanny Mayer LSA_HANDLE PolicyHandle, /* open policy handle */
1ebeb6bbf3c25a710ed7b6fbd2608f3850fc7f8fDanny Mayer PSID AccountSid, /* SID to grant privilege to */
1ebeb6bbf3c25a710ed7b6fbd2608f3850fc7f8fDanny Mayer wchar_t **PrivList, /* Ptr to List of Privileges found */
1ebeb6bbf3c25a710ed7b6fbd2608f3850fc7f8fDanny Mayer unsigned int *PrivCount /* total number of Privileges in list */
1ebeb6bbf3c25a710ed7b6fbd2608f3850fc7f8fDanny Mayer PLSA_UNICODE_STRING LsaString, /* destination */
1ebeb6bbf3c25a710ed7b6fbd2608f3850fc7f8fDanny Mayer LPSTR szAPI, /* pointer to function name (ANSI) */
1ebeb6bbf3c25a710ed7b6fbd2608f3850fc7f8fDanny Mayer LPSTR szAPI, /* pointer to function name (ANSI) */
1ebeb6bbf3c25a710ed7b6fbd2608f3850fc7f8fDanny Mayer * Note that this code only retrieves the list of privileges of the
1ebeb6bbf3c25a710ed7b6fbd2608f3850fc7f8fDanny Mayer * requested account or group. However, all accounts belong to the
1ebeb6bbf3c25a710ed7b6fbd2608f3850fc7f8fDanny Mayer * Everyone group even though that group is not returned by the
1ebeb6bbf3c25a710ed7b6fbd2608f3850fc7f8fDanny Mayer * calls to get the groups to which that account belongs.
1ebeb6bbf3c25a710ed7b6fbd2608f3850fc7f8fDanny Mayer * The Everyone group has two privileges associated with it:
1ebeb6bbf3c25a710ed7b6fbd2608f3850fc7f8fDanny Mayer * SeChangeNotifyPrivilege and SeNetworkLogonRight
1ebeb6bbf3c25a710ed7b6fbd2608f3850fc7f8fDanny Mayer * It is not advisable to disable or remove these privileges
1ebeb6bbf3c25a710ed7b6fbd2608f3850fc7f8fDanny Mayer * from the group nor can the account be removed from the Everyone
1ebeb6bbf3c25a710ed7b6fbd2608f3850fc7f8fDanny Mayer * The None group has no privileges associated with it and is the group
1ebeb6bbf3c25a710ed7b6fbd2608f3850fc7f8fDanny Mayer * to which an account belongs if it is associated with no group.
1ebeb6bbf3c25a710ed7b6fbd2608f3850fc7f8fDanny MayerGetAccountPrivileges(char *name, wchar_t **PrivList, unsigned int *PrivCount,
1ebeb6bbf3c25a710ed7b6fbd2608f3850fc7f8fDanny Mayer TCHAR AccountName[256]; /* static account name buffer */
1ebeb6bbf3c25a710ed7b6fbd2608f3850fc7f8fDanny Mayer unsigned int i;
4cef36044caea537bb4671bcef6a4d2c0a85ab62Andreas Gustafsson int iRetVal = RTN_ERROR; /* assume error from main */
1ebeb6bbf3c25a710ed7b6fbd2608f3850fc7f8fDanny Mayer * Open the policy on the target machine.
1ebeb6bbf3c25a710ed7b6fbd2608f3850fc7f8fDanny Mayer * Let's see if the account exists. Return if not
fcb5e646e4d775539e348fa21ba13307f2695bf5Mark Andrews n = wnsprintf(AccountName, sizeof(AccountName), TEXT("%hS"), name);
fcb5e646e4d775539e348fa21ba13307f2695bf5Mark Andrews if (n < 0 || (size_t)n >= sizeof(AccountName)) {
fcb5e646e4d775539e348fa21ba13307f2695bf5Mark Andrews if (!GetAccountSid(NULL, AccountName, &pSid)) {
1ebeb6bbf3c25a710ed7b6fbd2608f3850fc7f8fDanny Mayer * Find out what groups the account belongs to
290e1b94e4d4a330acb9e45c15cc4a6369065a22Danny Mayer istatus = isc_ntsecurity_getaccountgroups(name, Accounts, maxAccounts,
1ebeb6bbf3c25a710ed7b6fbd2608f3850fc7f8fDanny Mayer Accounts[*totalAccounts] = name; /* Add the account to the list */
1ebeb6bbf3c25a710ed7b6fbd2608f3850fc7f8fDanny Mayer * Loop through each Account to get the list of privileges
84b0ad095922000fcc017f18cd294691c126d0c4Andreas Gustafsson for (i = 0; i < *totalAccounts; i++) {
fcb5e646e4d775539e348fa21ba13307f2695bf5Mark Andrews n = wnsprintf(AccountName, sizeof(AccountName), TEXT("%hS"),
fcb5e646e4d775539e348fa21ba13307f2695bf5Mark Andrews if (n < 0 || (size_t)n >= sizeof(AccountName)) {
fcb5e646e4d775539e348fa21ba13307f2695bf5Mark Andrews /* Obtain the SID of the user/group. */
fcb5e646e4d775539e348fa21ba13307f2695bf5Mark Andrews if (!GetAccountSid(NULL, AccountName, &pSid)) {
1ebeb6bbf3c25a710ed7b6fbd2608f3850fc7f8fDanny Mayer continue; /* Try the next one */
61dd99bfae0ffa8ec193cf48fc86e4fa246a06e2Automatic Updater /* Get the Privileges allocated to this SID */
61dd99bfae0ffa8ec193cf48fc86e4fa246a06e2Automatic Updater if ((Status = GetPrivilegesOnAccount(PolicyHandle, pSid,
1ebeb6bbf3c25a710ed7b6fbd2608f3850fc7f8fDanny Mayer continue; /* Try the next one */
1ebeb6bbf3c25a710ed7b6fbd2608f3850fc7f8fDanny Mayer * Close the policy handle.
1ebeb6bbf3c25a710ed7b6fbd2608f3850fc7f8fDanny Mayer (*totalAccounts)--; /* Correct for the number of groups */
1ebeb6bbf3c25a710ed7b6fbd2608f3850fc7f8fDanny MayerCreateServiceAccount(char *name, char *password) {
1ebeb6bbf3c25a710ed7b6fbd2608f3850fc7f8fDanny Mayer mbstowcs(AccountPassword, password, passwdlen + 1);
1ebeb6bbf3c25a710ed7b6fbd2608f3850fc7f8fDanny Mayer * Set up the USER_INFO_1 structure.
61dd99bfae0ffa8ec193cf48fc86e4fa246a06e2Automatic Updater * USER_PRIV_USER: name is required here when creating an account
1ebeb6bbf3c25a710ed7b6fbd2608f3850fc7f8fDanny Mayer * rather than an administrator or a guest.
c9fb8b9f199022c2fd18c1c13788d7564b02265fDanny Mayer ui.usri1_flags = UF_PASSWD_CANT_CHANGE | UF_DONT_EXPIRE_PASSWD |
1ebeb6bbf3c25a710ed7b6fbd2608f3850fc7f8fDanny Mayer * Call the NetUserAdd function, specifying level 1.
1ebeb6bbf3c25a710ed7b6fbd2608f3850fc7f8fDanny Mayer nStatus = NetUserAdd(NULL, dwLevel, (LPBYTE)&ui, &dwError);
1ebeb6bbf3c25a710ed7b6fbd2608f3850fc7f8fDanny Mayer retstat = AddPrivilegeToAcccount(name, SE_SERVICE_LOGON_PRIV);
1ebeb6bbf3c25a710ed7b6fbd2608f3850fc7f8fDanny MayerAddPrivilegeToAcccount(LPTSTR name, LPWSTR PrivilegeName) {
1ebeb6bbf3c25a710ed7b6fbd2608f3850fc7f8fDanny Mayer TCHAR AccountName[256]; /* static account name buffer */
1ebeb6bbf3c25a710ed7b6fbd2608f3850fc7f8fDanny Mayer * Open the policy on the target machine.
84b0ad095922000fcc017f18cd294691c126d0c4Andreas Gustafsson if ((Status = OpenPolicy(NULL, POLICY_ALL_ACCESS, &PolicyHandle))
1ebeb6bbf3c25a710ed7b6fbd2608f3850fc7f8fDanny Mayer * Let's see if the account exists. Return if not
fcb5e646e4d775539e348fa21ba13307f2695bf5Mark Andrews n = wnsprintf(AccountName, sizeof(AccountName), TEXT("%hS"), name);
fcb5e646e4d775539e348fa21ba13307f2695bf5Mark Andrews if (n < 0 || (size_t)n >= sizeof(AccountName)) {
fcb5e646e4d775539e348fa21ba13307f2695bf5Mark Andrews if (!GetAccountSid(NULL, AccountName, &pSid)) {
61dd99bfae0ffa8ec193cf48fc86e4fa246a06e2Automatic Updater err = LsaNtStatusToWinError(SetPrivilegeOnAccount(PolicyHandle,
1ebeb6bbf3c25a710ed7b6fbd2608f3850fc7f8fDanny MayerInitLsaString(PLSA_UNICODE_STRING LsaString, LPWSTR String){
1ebeb6bbf3c25a710ed7b6fbd2608f3850fc7f8fDanny Mayer LsaString->Length = (USHORT) StringLength * sizeof(WCHAR);
84b0ad095922000fcc017f18cd294691c126d0c4Andreas Gustafsson LsaString->MaximumLength = (USHORT)(StringLength+1) * sizeof(WCHAR);
1ebeb6bbf3c25a710ed7b6fbd2608f3850fc7f8fDanny MayerOpenPolicy(LPWSTR ServerName, DWORD DesiredAccess, PLSA_HANDLE PolicyHandle){
1ebeb6bbf3c25a710ed7b6fbd2608f3850fc7f8fDanny Mayer * Always initialize the object attributes to all zeroes.
1ebeb6bbf3c25a710ed7b6fbd2608f3850fc7f8fDanny Mayer ZeroMemory(&ObjectAttributes, sizeof(ObjectAttributes));
84b0ad095922000fcc017f18cd294691c126d0c4Andreas Gustafsson * Make a LSA_UNICODE_STRING out of the LPWSTR passed in
1ebeb6bbf3c25a710ed7b6fbd2608f3850fc7f8fDanny Mayer * Attempt to open the policy.
1ebeb6bbf3c25a710ed7b6fbd2608f3850fc7f8fDanny Mayer return (LsaOpenPolicy(Server, &ObjectAttributes, DesiredAccess,
84b0ad095922000fcc017f18cd294691c126d0c4Andreas GustafssonGetAccountSid(LPTSTR SystemName, LPTSTR AccountName, PSID *Sid) {
84b0ad095922000fcc017f18cd294691c126d0c4Andreas Gustafsson DWORD cbSid = 128; /* initial allocation attempt */
84b0ad095922000fcc017f18cd294691c126d0c4Andreas Gustafsson DWORD cbReferencedDomain = 16; /* initial allocation size */
84b0ad095922000fcc017f18cd294691c126d0c4Andreas Gustafsson BOOL bSuccess = FALSE; /* assume this function will fail */
1ebeb6bbf3c25a710ed7b6fbd2608f3850fc7f8fDanny Mayer * initial memory allocations
84b0ad095922000fcc017f18cd294691c126d0c4Andreas Gustafsson if ((*Sid = HeapAlloc(GetProcessHeap(), 0, cbSid)) == NULL)
84b0ad095922000fcc017f18cd294691c126d0c4Andreas Gustafsson if ((ReferencedDomain = (LPTSTR) HeapAlloc(GetProcessHeap(), 0,
1ebeb6bbf3c25a710ed7b6fbd2608f3850fc7f8fDanny Mayer * Obtain the SID of the specified account on the specified system.
84b0ad095922000fcc017f18cd294691c126d0c4Andreas Gustafsson while (!LookupAccountName(SystemName, AccountName, *Sid, &cbSid,
1ebeb6bbf3c25a710ed7b6fbd2608f3850fc7f8fDanny Mayer if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
1ebeb6bbf3c25a710ed7b6fbd2608f3850fc7f8fDanny Mayer /* reallocate memory */
84b0ad095922000fcc017f18cd294691c126d0c4Andreas Gustafsson if ((*Sid = HeapReAlloc(GetProcessHeap(), 0,
84b0ad095922000fcc017f18cd294691c126d0c4Andreas Gustafsson if ((ReferencedDomain= (LPTSTR) HeapReAlloc(
84b0ad095922000fcc017f18cd294691c126d0c4Andreas Gustafsson } /* finally */
84b0ad095922000fcc017f18cd294691c126d0c4Andreas Gustafsson /* Cleanup and indicate failure, if appropriate. */
1ebeb6bbf3c25a710ed7b6fbd2608f3850fc7f8fDanny Mayer HeapFree(GetProcessHeap(), 0, ReferencedDomain);
1ebeb6bbf3c25a710ed7b6fbd2608f3850fc7f8fDanny MayerSetPrivilegeOnAccount(LSA_HANDLE PolicyHandle, PSID AccountSid,
1ebeb6bbf3c25a710ed7b6fbd2608f3850fc7f8fDanny Mayer /* Create a LSA_UNICODE_STRING for the privilege name. */
1ebeb6bbf3c25a710ed7b6fbd2608f3850fc7f8fDanny Mayer /* grant or revoke the privilege, accordingly */
1ebeb6bbf3c25a710ed7b6fbd2608f3850fc7f8fDanny Mayer return (LsaAddAccountRights(PolicyHandle, AccountSid,
1ebeb6bbf3c25a710ed7b6fbd2608f3850fc7f8fDanny Mayer return (LsaRemoveAccountRights(PolicyHandle, AccountSid,
1ebeb6bbf3c25a710ed7b6fbd2608f3850fc7f8fDanny MayerGetPrivilegesOnAccount(LSA_HANDLE PolicyHandle, PSID AccountSid,
61dd99bfae0ffa8ec193cf48fc86e4fa246a06e2Automatic Updater wchar_t **PrivList, unsigned int *PrivCount)
1ebeb6bbf3c25a710ed7b6fbd2608f3850fc7f8fDanny Mayer Status = LsaEnumerateAccountRights(PolicyHandle, AccountSid,
1ebeb6bbf3c25a710ed7b6fbd2608f3850fc7f8fDanny Mayer /* Only continue if there is something */
84b0ad095922000fcc017f18cd294691c126d0c4Andreas Gustafsson if (UserRights == NULL || Status != STATUS_SUCCESS)
84b0ad095922000fcc017f18cd294691c126d0c4Andreas Gustafsson for (i = 0; i < CountOfRights; i++) {
84b0ad095922000fcc017f18cd294691c126d0c4Andreas Gustafsson for (j = 0; j < *PrivCount; j++) {
1ebeb6bbf3c25a710ed7b6fbd2608f3850fc7f8fDanny Mayer found = wcsncmp(PrivList[j], UserRights[i].Buffer,
1ebeb6bbf3c25a710ed7b6fbd2608f3850fc7f8fDanny Mayer wcsncpy(PrivList[*PrivCount], UserRights[i].Buffer,
84b0ad095922000fcc017f18cd294691c126d0c4Andreas GustafssonDisplayNtStatus(LPSTR szAPI, NTSTATUS Status) {
1ebeb6bbf3c25a710ed7b6fbd2608f3850fc7f8fDanny Mayer /* Convert the NTSTATUS to Winerror. Then call DisplayWinError(). */
1ebeb6bbf3c25a710ed7b6fbd2608f3850fc7f8fDanny Mayer DisplayWinError(szAPI, LsaNtStatusToWinError(Status));
84b0ad095922000fcc017f18cd294691c126d0c4Andreas GustafssonDisplayWinError(LPSTR szAPI, DWORD WinError) {
1ebeb6bbf3c25a710ed7b6fbd2608f3850fc7f8fDanny Mayer FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
1ebeb6bbf3c25a710ed7b6fbd2608f3850fc7f8fDanny Mayer /* Output message string on stderr. */
1ebeb6bbf3c25a710ed7b6fbd2608f3850fc7f8fDanny Mayer WriteFile(GetStdHandle(STD_ERROR_HANDLE), MessageBuffer,
1ebeb6bbf3c25a710ed7b6fbd2608f3850fc7f8fDanny Mayer /* Free the buffer allocated by the system. */