AccountInfo.cpp revision 84b0ad095922000fcc017f18cd294691c126d0c4
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews * Copyright (C) 2001 Internet Software Consortium.
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews * Permission to use, copy, modify, and distribute this software for any
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews * purpose with or without fee is hereby granted, provided that the above
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews * copyright notice and this permission notice appear in all copies.
20bd7b4bbf2437ef2f9109edca168ab0ce8445b3David Lawrence * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
20bd7b4bbf2437ef2f9109edca168ab0ce8445b3David Lawrence * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
20bd7b4bbf2437ef2f9109edca168ab0ce8445b3David Lawrence * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
20bd7b4bbf2437ef2f9109edca168ab0ce8445b3David Lawrence * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
20bd7b4bbf2437ef2f9109edca168ab0ce8445b3David Lawrence * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
6b7257f756eb0530cdf54df9a7fab8d51a5001c3David Lawrence * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20bd7b4bbf2437ef2f9109edca168ab0ce8445b3David Lawrence/* $Id: AccountInfo.cpp,v 1.2 2001/09/29 00:01:43 gson Exp $ */
73a691c373488e4f70387a62462cd8ce0d991705David Lawrence#endif /* UNICODE */
669e9657c731176df235832367f61435f7b83ddfAndreas Gustafsson LPWSTR ServerName, /* machine to open policy on (Unicode) */
3db78e0855a8dfc162180880cd70d9c1a03d9301David Lawrence DWORD DesiredAccess, /* desired access to policy */
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington PLSA_HANDLE PolicyHandle /* resultant policy handle */
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington LPTSTR SystemName, /* where to lookup account */
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington LPTSTR AccountName, /* account of interest */
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington PSID *Sid /* resultant buffer containing SID */
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington LSA_HANDLE PolicyHandle, /* open policy handle */
b493dfe8bce94b05efc0f161238d32f1234c5670Brian Wellington PSID AccountSid, /* SID to grant privilege to */
20bd7b4bbf2437ef2f9109edca168ab0ce8445b3David Lawrence LPWSTR PrivilegeName, /* privilege to grant (Unicode) */
80b67b3a4f2d9fc7fdd32a50edc67ff189894da2Danny Mayer LSA_HANDLE PolicyHandle, /* open policy handle */
326bcfa0e2a6b924cb829a0bcc3bf9590ce21ad6Mark Andrews PSID AccountSid, /* SID to grant privilege to */
87983da955bf63128de85d180359bdc418516c3cDavid Lawrence wchar_t **PrivList, /* Ptr to List of Privileges found */
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington unsigned int *PrivCount /* total number of Privileges in list */
b6b9d8b8434e4eaab74b69cd14fcacf448055ca5Brian Wellington LPTSTR AccountName, /* Name of the account */
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington PLSA_UNICODE_STRING LsaString, /* destination */
73a691c373488e4f70387a62462cd8ce0d991705David Lawrence LPSTR szAPI, /* pointer to function name (ANSI) */
20bd7b4bbf2437ef2f9109edca168ab0ce8445b3David Lawrence LPSTR szAPI, /* pointer to function name (ANSI) */
debd489a44363870f96f75818e89ec27d3cab736Francis Dupont#define STATUS_SUCCESS ((NTSTATUS)0x00000000L)
5b79d154014f87b6c54b1ec2d3912c35b02042a1Mark Andrews * Note that this code only retrieves the list of privileges of the
9e804040a29b9c3066c8471b43835f30707039b7Evan Hunt * requested account or group. However, all accounts belong to the
94b166ffa58ef0ff263563c0550d0b30eb9f7772David Lawrence * Everyone group even though that group is not returned by the
f7c21e46c4b5fdae516b91374c24a87671f83ea3Andreas Gustafsson * calls to get the groups to which that account belongs.
94b166ffa58ef0ff263563c0550d0b30eb9f7772David Lawrence * The Everyone group has two privileges associated with it:
d96f74a3cb6212ac9e4a7a0fa8924f850348eae9Mark Andrews * SeChangeNotifyPrivilege and SeNetworkLogonRight
fc39b6a96109b78154ec148d20eaf29e8abc14b6Mukund Sivaraman * It is not advisable to disable or remove these privileges
d96f74a3cb6212ac9e4a7a0fa8924f850348eae9Mark Andrews * from the group nor can the account be removed from the Everyone
d6a0e00dc3e047f8470b938878926957070def77Mark Andrews * The None group has no privileges associated with it and is the group
d6a0e00dc3e047f8470b938878926957070def77Mark Andrews * to which an account belongs if it is associated with no group.
b326d7e3a3a50eb65dd06db007d2fddc62606bbfMark AndrewsGetAccountPrivileges(char *name, wchar_t **PrivList, unsigned int *PrivCount,
5455f30a7532738d750252c00e649890c694ee30Brian Wellington char **Accounts, unsigned int *totalAccounts,
6150d3cb666a58d5e3a15275562c9fc5c5b6b2d8Evan Hunt TCHAR AccountName[256]; /* static account name buffer */
d96f74a3cb6212ac9e4a7a0fa8924f850348eae9Mark Andrews unsigned int i;
d96f74a3cb6212ac9e4a7a0fa8924f850348eae9Mark Andrews int iRetVal=RTN_ERROR; /* assume error from main */
d96f74a3cb6212ac9e4a7a0fa8924f850348eae9Mark Andrews * Open the policy on the target machine.
ecaed3593cd14f2491d1bd81fc98cb940e12f8bbMark Andrews * Let's see if the account exists. Return if not
fc39b6a96109b78154ec148d20eaf29e8abc14b6Mukund Sivaraman if (!GetAccountSid(NULL, AccountName, &pSid))
d96f74a3cb6212ac9e4a7a0fa8924f850348eae9Mark Andrews * Find out what groups the account belongs to
323bb31d7c54078aa62146b3aa946b755cbfd52bMark Andrews Status = isc_ntsecurity_getaccountgroups(name, Accounts, maxAccounts,
547411428e467f2a2848886eaac0a8b3e136a9abEvan Hunt Accounts[*totalAccounts] = name; /* Add the account to the list */
547411428e467f2a2848886eaac0a8b3e136a9abEvan Hunt * Loop through each Account to get the list of privileges
547411428e467f2a2848886eaac0a8b3e136a9abEvan Hunt for (i = 0; i < *totalAccounts; i++) {
d96f74a3cb6212ac9e4a7a0fa8924f850348eae9Mark Andrews /* Obtain the SID of the user/group. */
d96f74a3cb6212ac9e4a7a0fa8924f850348eae9Mark Andrews continue; /* Try the next one */
d96f74a3cb6212ac9e4a7a0fa8924f850348eae9Mark Andrews /* Get the Privileges allocated to this SID */
d96f74a3cb6212ac9e4a7a0fa8924f850348eae9Mark Andrews if ((Status = GetPrivilegesOnAccount(PolicyHandle, pSid,
d96f74a3cb6212ac9e4a7a0fa8924f850348eae9Mark Andrews continue; /* Try the next one */
d96f74a3cb6212ac9e4a7a0fa8924f850348eae9Mark Andrews * Close the policy handle.
d96f74a3cb6212ac9e4a7a0fa8924f850348eae9Mark Andrews (*totalAccounts)--; /* Correct for the number of groups */
d96f74a3cb6212ac9e4a7a0fa8924f850348eae9Mark AndrewsCreateServiceAccount(char *name, char *password) {
d96f74a3cb6212ac9e4a7a0fa8924f850348eae9Mark Andrews wchar_t *AccountName = (wchar_t *)malloc((namelen + 1)*
d96f74a3cb6212ac9e4a7a0fa8924f850348eae9Mark Andrews sizeof(wchar_t));
d96f74a3cb6212ac9e4a7a0fa8924f850348eae9Mark Andrews wchar_t *AccountPassword = (wchar_t *)malloc((passwdlen + 1)*
d96f74a3cb6212ac9e4a7a0fa8924f850348eae9Mark Andrews sizeof(wchar_t));
d96f74a3cb6212ac9e4a7a0fa8924f850348eae9Mark Andrews mbstowcs(AccountPassword, password, passwdlen + 1);
d96f74a3cb6212ac9e4a7a0fa8924f850348eae9Mark Andrews * Set up the USER_INFO_1 structure.
d96f74a3cb6212ac9e4a7a0fa8924f850348eae9Mark Andrews * USER_PRIV_USER: name is required here when creating an account
d96f74a3cb6212ac9e4a7a0fa8924f850348eae9Mark Andrews * rather than an administrator or a guest.
d96f74a3cb6212ac9e4a7a0fa8924f850348eae9Mark Andrews ui.usri1_comment = L"ISC BIND Service Account";
d96f74a3cb6212ac9e4a7a0fa8924f850348eae9Mark Andrews ui.usri1_flags = UF_PASSWD_CANT_CHANGE | UF_DONT_EXPIRE_PASSWD;
94b166ffa58ef0ff263563c0550d0b30eb9f7772David Lawrence * Call the NetUserAdd function, specifying level 1.
87983da955bf63128de85d180359bdc418516c3cDavid Lawrence nStatus = NetUserAdd(NULL, dwLevel, (LPBYTE)&ui, &dwError);
b493dfe8bce94b05efc0f161238d32f1234c5670Brian Wellington retstat = AddPrivilegeToAcccount(name, SE_SERVICE_LOGON_PRIV);
4423c99613db1399dbb5c51e86ef0d351a1418c2Mark AndrewsAddPrivilegeToAcccount(LPTSTR name, LPWSTR PrivilegeName) {
1d16cf8bb8596c3e4dc1123a5bdf360bf24a272bAutomatic Updater TCHAR AccountName[256]; /* static account name buffer */
4423c99613db1399dbb5c51e86ef0d351a1418c2Mark Andrews unsigned long err;
4423c99613db1399dbb5c51e86ef0d351a1418c2Mark Andrews * Open the policy on the target machine.
b493dfe8bce94b05efc0f161238d32f1234c5670Brian Wellington if ((Status = OpenPolicy(NULL, POLICY_ALL_ACCESS, &PolicyHandle))
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington * Let's see if the account exists. Return if not
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington if (!GetAccountSid(NULL, AccountName, &pSid))
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington err = LsaNtStatusToWinError(SetPrivilegeOnAccount(PolicyHandle,
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian WellingtonInitLsaString(PLSA_UNICODE_STRING LsaString, LPWSTR String){
73a691c373488e4f70387a62462cd8ce0d991705David Lawrence LsaString->Length = (USHORT) StringLength * sizeof(WCHAR);
e1d05d323526e7e65df13a6d3dfbec30f6ddb500Brian Wellington LsaString->MaximumLength = (USHORT)(StringLength+1) * sizeof(WCHAR);
c4f9e613e12f03795bee18cf2ca8e6a9d39d6468Mark AndrewsOpenPolicy(LPWSTR ServerName, DWORD DesiredAccess, PLSA_HANDLE PolicyHandle){
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington * Always initialize the object attributes to all zeroes.
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington ZeroMemory(&ObjectAttributes, sizeof(ObjectAttributes));
73a691c373488e4f70387a62462cd8ce0d991705David Lawrence * Make a LSA_UNICODE_STRING out of the LPWSTR passed in
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington * Attempt to open the policy.
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington return (LsaOpenPolicy(Server, &ObjectAttributes, DesiredAccess,
e4cd5a1e5d0358abeee7618b02b4592c055d957fBrian WellingtonGetAccountSid(LPTSTR SystemName, LPTSTR AccountName, PSID *Sid) {
e7c0d42b11358f08e04316d31c67c23261dcdf36Evan Hunt DWORD cbSid = 128; /* initial allocation attempt */
e7c0d42b11358f08e04316d31c67c23261dcdf36Evan Hunt DWORD cbReferencedDomain = 16; /* initial allocation size */
e4cd5a1e5d0358abeee7618b02b4592c055d957fBrian Wellington BOOL bSuccess = FALSE; /* assume this function will fail */
9e804040a29b9c3066c8471b43835f30707039b7Evan Hunt * initial memory allocations
9e804040a29b9c3066c8471b43835f30707039b7Evan Hunt if ((*Sid = HeapAlloc(GetProcessHeap(), 0, cbSid)) == NULL)
9e804040a29b9c3066c8471b43835f30707039b7Evan Hunt if ((ReferencedDomain = (LPTSTR) HeapAlloc(GetProcessHeap(), 0,
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington * Obtain the SID of the specified account on the specified system.
f07fe5a1ac9d1345eb7a36a0bc38716a03e25f61Mark Andrews while (!LookupAccountName(SystemName, AccountName, *Sid, &cbSid,
f07fe5a1ac9d1345eb7a36a0bc38716a03e25f61Mark Andrews if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington /* reallocate memory */
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington if ((*Sid = HeapReAlloc(GetProcessHeap(), 0,
72ddc4cef9c6a6de53aae530dea1ddbb90631131Mark Andrews } /* finally */
72ddc4cef9c6a6de53aae530dea1ddbb90631131Mark Andrews /* Cleanup and indicate failure, if appropriate. */
72ddc4cef9c6a6de53aae530dea1ddbb90631131Mark Andrews HeapFree(GetProcessHeap(), 0, ReferencedDomain);
4eb998928b9aef0ceda42d7529980d658138698aEvan HuntSetPrivilegeOnAccount(LSA_HANDLE PolicyHandle, PSID AccountSid,
a2b15b3305acd52179e6f3dc7d073b07fbc40b8eMark Andrews /* Create a LSA_UNICODE_STRING for the privilege name. */
72ddc4cef9c6a6de53aae530dea1ddbb90631131Mark Andrews InitLsaString(&PrivilegeString, PrivilegeName);
72ddc4cef9c6a6de53aae530dea1ddbb90631131Mark Andrews /* grant or revoke the privilege, accordingly */
72ddc4cef9c6a6de53aae530dea1ddbb90631131Mark Andrews return (LsaAddAccountRights(PolicyHandle, AccountSid,
72ddc4cef9c6a6de53aae530dea1ddbb90631131Mark Andrews return (LsaRemoveAccountRights(PolicyHandle, AccountSid,
72ddc4cef9c6a6de53aae530dea1ddbb90631131Mark AndrewsGetPrivilegesOnAccount(LSA_HANDLE PolicyHandle, PSID AccountSid,
72ddc4cef9c6a6de53aae530dea1ddbb90631131Mark Andrews unsigned int retlen = 0;
e32d354f754a5d7847a0862bcd6302827ea225bfEvan Hunt Status = LsaEnumerateAccountRights(PolicyHandle, AccountSid,
e32d354f754a5d7847a0862bcd6302827ea225bfEvan Hunt /* Only continue if there is something */
4eb998928b9aef0ceda42d7529980d658138698aEvan Hunt if (UserRights == NULL || Status != STATUS_SUCCESS)
e32d354f754a5d7847a0862bcd6302827ea225bfEvan Hunt for (i = 0; i < CountOfRights; i++) {
e32d354f754a5d7847a0862bcd6302827ea225bfEvan Hunt for (j = 0; j < *PrivCount; j++) {
e32d354f754a5d7847a0862bcd6302827ea225bfEvan Hunt found = wcsncmp(PrivList[j], UserRights[i].Buffer,
72ddc4cef9c6a6de53aae530dea1ddbb90631131Mark Andrews (wchar_t *)malloc(UserRights[i].MaximumLength);
72ddc4cef9c6a6de53aae530dea1ddbb90631131Mark Andrews wcsncpy(PrivList[*PrivCount], UserRights[i].Buffer,
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian WellingtonDisplayNtStatus(LPSTR szAPI, NTSTATUS Status) {
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington /* Convert the NTSTATUS to Winerror. Then call DisplayWinError(). */
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington DisplayWinError(szAPI, LsaNtStatusToWinError(Status));
71ca6e64b4d208a090d255eb64c24f945e615ea0Brian WellingtonDisplayWinError(LPSTR szAPI, DWORD WinError) {
420e5e1022ff5ca4697ed5286462eeaf03614e53Brian Wellington FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
b6b9d8b8434e4eaab74b69cd14fcacf448055ca5Brian Wellington /* Output message string on stderr. */
420e5e1022ff5ca4697ed5286462eeaf03614e53Brian Wellington WriteFile(GetStdHandle(STD_ERROR_HANDLE), MessageBuffer,
b6b9d8b8434e4eaab74b69cd14fcacf448055ca5Brian Wellington /* Free the buffer allocated by the system. */