mirror of https://github.com/BOINC/boinc.git
303 lines
7.6 KiB
C++
303 lines
7.6 KiB
C++
/*++
|
|
|
|
Copyright 1996 - 1997 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
privs.c
|
|
|
|
Abstract:
|
|
|
|
This module illustrates how to use the Windows NT LSA security API
|
|
to manage account privileges on the local or a remote machine.
|
|
|
|
When targetting a domain controller for privilege update operations,
|
|
be sure to target the primary domain controller for the domain.
|
|
The privilege settings are replicated by the primary domain controller
|
|
to each backup domain controller as appropriate. The NetGetDCName()
|
|
Lan Manager API call can be used to get the primary domain controller
|
|
computer name from a domain name.
|
|
|
|
For a list of privilges, consult winnt.h, and search for
|
|
SE_ASSIGNPRIMARYTOKEN_NAME.
|
|
|
|
For a list of logon rights, which can also be assigned using this
|
|
sample code, consult ntsecapi.h, and search for SE_BATCH_LOGON_NAME
|
|
|
|
You can use domain\account as argv[1]. For instance, mydomain\scott will
|
|
grant the privilege to the mydomain domain account scott.
|
|
|
|
The optional target machine is specified as argv[2], otherwise, the
|
|
account database is updated on the local machine.
|
|
|
|
The LSA APIs used by this sample are Unicode only.
|
|
|
|
Use LsaRemoveAccountRights() to remove account rights.
|
|
|
|
Author:
|
|
|
|
Scott Field (sfield) 17-Apr-96
|
|
Minor cleanup
|
|
|
|
Scott Field (sfield) 12-Jul-95
|
|
|
|
--*/
|
|
|
|
#include "stdafx.h"
|
|
#include "boinccas.h"
|
|
#include "lsaprivs.h"
|
|
|
|
|
|
/*++
|
|
This function attempts to obtain a SID representing the supplied
|
|
account on the supplied system.
|
|
|
|
If the function succeeds, the return value is TRUE. A buffer is
|
|
allocated which contains the SID representing the supplied account.
|
|
This buffer should be freed when it is no longer needed by calling
|
|
HeapFree(GetProcessHeap(), 0, buffer)
|
|
|
|
If the function fails, the return value is FALSE. Call GetLastError()
|
|
to obtain extended error information.
|
|
|
|
Scott Field (sfield) 12-Jul-95
|
|
--*/
|
|
|
|
BOOL
|
|
GetAccountSid(
|
|
LPCTSTR SystemName,
|
|
LPCTSTR AccountName,
|
|
PSID *Sid
|
|
)
|
|
{
|
|
LPTSTR ReferencedDomain=NULL;
|
|
DWORD cbSid=128; // initial allocation attempt
|
|
DWORD cchReferencedDomain=16; // initial allocation size
|
|
SID_NAME_USE peUse;
|
|
BOOL bSuccess=FALSE; // assume this function will fail
|
|
|
|
__try {
|
|
|
|
//
|
|
// initial memory allocations
|
|
//
|
|
*Sid = (PSID)HeapAlloc(GetProcessHeap(), 0, cbSid);
|
|
|
|
if(*Sid == NULL) __leave;
|
|
|
|
ReferencedDomain = (LPTSTR)HeapAlloc(
|
|
GetProcessHeap(),
|
|
0,
|
|
cchReferencedDomain * sizeof(TCHAR)
|
|
);
|
|
|
|
if(ReferencedDomain == NULL) __leave;
|
|
|
|
//
|
|
// Obtain the SID of the specified account on the specified system.
|
|
//
|
|
while(!LookupAccountName(
|
|
SystemName, // machine to lookup account on
|
|
AccountName, // account to lookup
|
|
*Sid, // SID of interest
|
|
&cbSid, // size of SID
|
|
ReferencedDomain, // domain account was found on
|
|
&cchReferencedDomain,
|
|
&peUse
|
|
)) {
|
|
if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
|
|
//
|
|
// reallocate memory
|
|
//
|
|
*Sid = (PSID)HeapReAlloc(
|
|
GetProcessHeap(),
|
|
0,
|
|
*Sid,
|
|
cbSid
|
|
);
|
|
if(*Sid == NULL) __leave;
|
|
|
|
ReferencedDomain = (LPTSTR)HeapReAlloc(
|
|
GetProcessHeap(),
|
|
0,
|
|
ReferencedDomain,
|
|
cchReferencedDomain * sizeof(TCHAR)
|
|
);
|
|
if(ReferencedDomain == NULL) __leave;
|
|
}
|
|
else __leave;
|
|
}
|
|
|
|
//
|
|
// Indicate success.
|
|
//
|
|
bSuccess = TRUE;
|
|
|
|
} // try
|
|
__finally {
|
|
|
|
//
|
|
// Cleanup and indicate failure, if appropriate.
|
|
//
|
|
|
|
HeapFree(GetProcessHeap(), 0, ReferencedDomain);
|
|
|
|
if(!bSuccess) {
|
|
if(*Sid != NULL) {
|
|
HeapFree(GetProcessHeap(), 0, *Sid);
|
|
*Sid = NULL;
|
|
}
|
|
}
|
|
|
|
} // finally
|
|
|
|
return bSuccess;
|
|
}
|
|
|
|
NTSTATUS
|
|
SetPrivilegeOnAccount(
|
|
LSA_HANDLE PolicyHandle, // open policy handle
|
|
PSID AccountSid, // SID to grant privilege to
|
|
LPWSTR PrivilegeName, // privilege to grant (Unicode)
|
|
BOOL bEnable // enable or disable
|
|
)
|
|
{
|
|
LSA_UNICODE_STRING PrivilegeString;
|
|
|
|
//
|
|
// Create a LSA_UNICODE_STRING for the privilege name.
|
|
//
|
|
InitLsaString(&PrivilegeString, PrivilegeName);
|
|
|
|
//
|
|
// grant or revoke the privilege, accordingly
|
|
//
|
|
if(bEnable) {
|
|
return LsaAddAccountRights(
|
|
PolicyHandle, // open policy handle
|
|
AccountSid, // target SID
|
|
&PrivilegeString, // privileges
|
|
1 // privilege count
|
|
);
|
|
}
|
|
else {
|
|
return LsaRemoveAccountRights(
|
|
PolicyHandle, // open policy handle
|
|
AccountSid, // target SID
|
|
FALSE, // do not disable all rights
|
|
&PrivilegeString, // privileges
|
|
1 // privilege count
|
|
);
|
|
}
|
|
}
|
|
|
|
void
|
|
InitLsaString(
|
|
PLSA_UNICODE_STRING LsaString,
|
|
LPWSTR String
|
|
)
|
|
{
|
|
DWORD StringLength;
|
|
|
|
if(String == NULL) {
|
|
LsaString->Buffer = NULL;
|
|
LsaString->Length = 0;
|
|
LsaString->MaximumLength = 0;
|
|
return;
|
|
}
|
|
|
|
StringLength = lstrlenW(String);
|
|
LsaString->Buffer = String;
|
|
LsaString->Length = (USHORT) StringLength * sizeof(WCHAR);
|
|
LsaString->MaximumLength=(USHORT)(StringLength+1) * sizeof(WCHAR);
|
|
}
|
|
|
|
NTSTATUS
|
|
OpenPolicy(
|
|
LPWSTR ServerName,
|
|
DWORD DesiredAccess,
|
|
PLSA_HANDLE PolicyHandle
|
|
)
|
|
{
|
|
LSA_OBJECT_ATTRIBUTES ObjectAttributes;
|
|
LSA_UNICODE_STRING ServerString;
|
|
PLSA_UNICODE_STRING Server;
|
|
|
|
//
|
|
// Always initialize the object attributes to all zeroes.
|
|
//
|
|
ZeroMemory(&ObjectAttributes, sizeof(ObjectAttributes));
|
|
|
|
if (ServerName != NULL) {
|
|
//
|
|
// Make a LSA_UNICODE_STRING out of the LPWSTR passed in
|
|
//
|
|
InitLsaString(&ServerString, ServerName);
|
|
Server = &ServerString;
|
|
} else {
|
|
Server = NULL;
|
|
}
|
|
|
|
//
|
|
// Attempt to open the policy.
|
|
//
|
|
return LsaOpenPolicy(
|
|
Server,
|
|
&ObjectAttributes,
|
|
DesiredAccess,
|
|
PolicyHandle
|
|
);
|
|
}
|
|
|
|
|
|
BOOL
|
|
GrantUserRight(
|
|
PSID psidAccountSid,
|
|
LPWSTR pszUserRight,
|
|
BOOL bEnable
|
|
)
|
|
{
|
|
LSA_HANDLE PolicyHandle = NULL;
|
|
NTSTATUS Status;
|
|
|
|
//
|
|
// Open the policy on the local host.
|
|
//
|
|
Status = OpenPolicy(
|
|
_T(""),
|
|
POLICY_CREATE_ACCOUNT | POLICY_LOOKUP_NAMES,
|
|
&PolicyHandle
|
|
);
|
|
|
|
|
|
if(Status != STATUS_SUCCESS) {
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
//
|
|
// Grant the requested user right represented by psidAccountSid.
|
|
//
|
|
Status = SetPrivilegeOnAccount(
|
|
PolicyHandle, // policy handle
|
|
psidAccountSid, // SID to grant privilege
|
|
pszUserRight, // Unicode privilege
|
|
bEnable // enable the privilege
|
|
);
|
|
|
|
if(Status != STATUS_SUCCESS)
|
|
{
|
|
LsaClose(PolicyHandle);
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// Cleanup any handles and memory allocated during the custom action
|
|
//
|
|
LsaClose(PolicyHandle);
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
const char *BOINC_RCSID_0a9587b165 = "$Id$";
|