如何管理以编程方式在 Windows NT 中的用户权限(C 语言)
2009-04-29 09:54
671 查看
loadTOCNode(1, 'moreinformation');
管理用户权限可以实现以编程方式使用下列步骤:
打开与 LsaOpenPolicy() 的目标计算机上的策略。 要授予的权限,打开 POLICY_CREATE_ACCOUNT 和 POLICY_LOOKUP_NAMES 访问策略。 若要吊销权限,打开 POLICY_LOOKUP_NAMES 访问策略。
获取一个 SID (安全标识符),表示用户 / 组感兴趣。 LookupAccountName() 和 LsaLookupNames() API 可以从一个帐户名获取 SID。
调用 LsaAddAccountRights() 向由提供的 SID 的用户授予特权。
调用 LsaRemoveAccountRights() 撤消由提供的 SID 的用户权限。
关闭该策略与 LsaClose()。
要成功授予和吊销权限,调用方需要是目标系统上的管理员。
LSA API LsaEnumerateAccountRights() 可确定已授予的权限的帐户。
LSA API LsaEnumerateAccountsWithUserRight() 可确定哪些帐户已被授予指定的权限。
MSTOOLS\SECURITY 目录中 Windows 32 SDK 中提供的这些 LSA API 的文档和头文件。
在 Win32 SDK 的最新版本中, 邮件头显示在 mstools\samples\win32\winnt\security\include 目录中且文档处于正在 \security\lsasamp\lsaapi.hlp。
注意: 这些 LSA API 是当前实现以 Unicode 格式仅。
本示例将授予特权 SeServiceLogonRight 为 argv [1] 上指定的帐户。
此示例是依赖于这些导入库
advapi32.lib (对于 LsaXxx)
user32.lib (对于 wsprintf)
本示例将工作正确编译 ANSI 或 Unicode。
回到顶端
[/code]
管理用户权限可以实现以编程方式使用下列步骤:
打开与 LsaOpenPolicy() 的目标计算机上的策略。 要授予的权限,打开 POLICY_CREATE_ACCOUNT 和 POLICY_LOOKUP_NAMES 访问策略。 若要吊销权限,打开 POLICY_LOOKUP_NAMES 访问策略。
获取一个 SID (安全标识符),表示用户 / 组感兴趣。 LookupAccountName() 和 LsaLookupNames() API 可以从一个帐户名获取 SID。
调用 LsaAddAccountRights() 向由提供的 SID 的用户授予特权。
调用 LsaRemoveAccountRights() 撤消由提供的 SID 的用户权限。
关闭该策略与 LsaClose()。
要成功授予和吊销权限,调用方需要是目标系统上的管理员。
LSA API LsaEnumerateAccountRights() 可确定已授予的权限的帐户。
LSA API LsaEnumerateAccountsWithUserRight() 可确定哪些帐户已被授予指定的权限。
MSTOOLS\SECURITY 目录中 Windows 32 SDK 中提供的这些 LSA API 的文档和头文件。
在 Win32 SDK 的最新版本中, 邮件头显示在 mstools\samples\win32\winnt\security\include 目录中且文档处于正在 \security\lsasamp\lsaapi.hlp。
注意: 这些 LSA API 是当前实现以 Unicode 格式仅。
本示例将授予特权 SeServiceLogonRight 为 argv [1] 上指定的帐户。
此示例是依赖于这些导入库
advapi32.lib (对于 LsaXxx)
user32.lib (对于 wsprintf)
本示例将工作正确编译 ANSI 或 Unicode。
回到顶端
示例代码
loadTOCNode(2, 'moreinformation');[code]/*++ 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. Scott Field (sfield) 12-Jul-95 --*/ #ifndef UNICODE #define UNICODE #endif // UNICODE #include <windows.h> #include <stdio.h> #include "ntsecapi.h" 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 _cdecl main(int argc, char *argv[]) { LSA_HANDLE PolicyHandle; WCHAR wComputerName[256]=L""; // static machine name buffer TCHAR AccountName[256]; // static account name buffer PSID pSid; NTSTATUS Status; int iRetVal=RTN_ERROR; // assume error from main if(argc == 1) { fprintf(stderr,"Usage: %s <Account> [TargetMachine]\n", argv[0]); return RTN_USAGE; } // // Pick up account name on argv[1]. // Assumes source is ANSI. Resultant string is ANSI or Unicode // wsprintf(AccountName, TEXT("%hS"), argv[1]); // // Pick up machine name on argv[2], if appropriate // assumes source is ANSI. Resultant string is Unicode. // if(argc == 3) wsprintfW(wComputerName, L"%hS", argv[2]); // // Open the policy on the target machine. // if((Status=OpenPolicy( wComputerName, // target machine POLICY_CREATE_ACCOUNT | POLICY_LOOKUP_NAMES, &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 AccountName,// 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. // // Grant the SeServiceLogonRight to users represented by pSid. // if((Status=SetPrivilegeOnAccount( PolicyHandle, // policy handle pSid, // SID to grant privilege L"SeServiceLogonRight", // Unicode privilege TRUE // enable the privilege )) == STATUS_SUCCESS) iRetVal=RTN_OK; else DisplayNtStatus("AddUserRightToAccount", Status); } else { // // Error obtaining SID. // DisplayWinError("GetAccountSid", GetLastError()); } // // 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 ); } /*++ 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( LPTSTR SystemName, LPTSTR 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 // if((*Sid=HeapAlloc( GetProcessHeap(), 0, cbSid )) == NULL) __leave; if((ReferencedDomain=(LPTSTR)HeapAlloc( GetProcessHeap(), 0, cchReferencedDomain * sizeof(TCHAR) )) == 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 // if((*Sid=HeapReAlloc( GetProcessHeap(), 0, *Sid, cbSid )) == NULL) __leave; if((ReferencedDomain=(LPTSTR)HeapReAlloc( GetProcessHeap(), 0, ReferencedDomain, cchReferencedDomain * sizeof(TCHAR) )) == 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; // // TODO: Get this fprintf out of here! // fprintf(stderr,"%s error!\n", szAPI); if(dwBufferLength=FormatMessageA( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, WinError, GetUserDefaultLangID(), (LPSTR) &MessageBuffer, 0, NULL )) { DWORD dwBytesWritten; // unused // // Output message string on stderr. // WriteFile( GetStdHandle(STD_ERROR_HANDLE), MessageBuffer, dwBufferLength, &dwBytesWritten, NULL ); // // Free the buffer allocated by the system. // LocalFree(MessageBuffer); } }
[/code]
[code]/*++ This function enables system access on the account represented by the supplied SID. An example of such access is the SeLogonServiceRight. Note: to disable a given system access, simply remove the supplied access flag from the existing flag, and apply the result to the account. If the function succeeds, the return value is STATUS_SUCCESS. If the function fails, the return value is an NTSTATUS value. Scott Field (sfield) 14-Jul-95 --*/ NTSTATUS AddSystemAccessToAccount( LSA_HANDLE PolicyHandle, PSID AccountSid, ULONG NewAccess ) { LSA_HANDLE AccountHandle; ULONG PreviousAccess; NTSTATUS Status; // // open the account object. If it doesn't exist, create a new one // if((Status=LsaOpenAccount( PolicyHandle, AccountSid, ACCOUNT_ADJUST_SYSTEM_ACCESS | ACCOUNT_VIEW, &AccountHandle )) == STATUS_OBJECT_NAME_NOT_FOUND) { Status=LsaCreateAccount( PolicyHandle, AccountSid, ACCOUNT_ADJUST_SYSTEM_ACCESS | ACCOUNT_VIEW, &AccountHandle ); } // // if an error occurred opening or creating, return // if(Status != STATUS_SUCCESS) return Status; // // obtain current system access flags // if((Status=LsaGetSystemAccessAccount( AccountHandle, &PreviousAccess )) == STATUS_SUCCESS) { // // Add the specified access to the account // Status=LsaSetSystemAccessAccount( AccountHandle, PreviousAccess | NewAccess ); } LsaClose(AccountHandle); return Status; } /*++ This function grants a privilege to the account represented by the supplied SID. An example of such a privilege is the SeBackupPrivilege. Note: To revoke a privilege, use LsaRemovePrivilegesFromAccount. If the function succeeds, the return value is STATUS_SUCCESS. If the function fails, the return value is an NTSTATUS value. Scott Field (sfield) 13-Jul-95 --*/ NTSTATUS AddPrivilegeToAccount( LSA_HANDLE PolicyHandle, PSID AccountSid, LPWSTR PrivilegeName ) { PRIVILEGE_SET ps; LUID_AND_ATTRIBUTES luidattr; LSA_HANDLE AccountHandle; LSA_UNICODE_STRING PrivilegeString; NTSTATUS Status; // // Create a LSA_UNICODE_STRING for the privilege name // InitLsaString(&PrivilegeString, PrivilegeName); // // obtain the LUID of the supplied privilege // if((Status=LsaLookupPrivilegeValue( PolicyHandle, &PrivilegeString, &luidattr.Luid )) != STATUS_SUCCESS) return Status; // // setup PRIVILEGE_SET // luidattr.Attributes=0; ps.PrivilegeCount=1; ps.Control=0; ps.Privilege[0]=luidattr; // // open the account object if it doesn't exist, create a new one // if((Status=LsaOpenAccount( PolicyHandle, AccountSid, ACCOUNT_ADJUST_PRIVILEGES, &AccountHandle )) == STATUS_OBJECT_NAME_NOT_FOUND) { Status=LsaCreateAccount( PolicyHandle, AccountSid, ACCOUNT_ADJUST_PRIVILEGES, &AccountHandle ); } // // if an error occurred opening or creating, return // if(Status != STATUS_SUCCESS) return Status; // // add the privileges to the account // Status=LsaAddPrivilegesToAccount( AccountHandle, &ps ); LsaClose(AccountHandle); return Status; }
转自:http://support.microsoft.com/kb/132958/zh-cn
相关文章推荐
- 如何在Windows NT中以编程方式管理用户权限
- 企业如何管理在线ERP系统用户权限
- 如何用不同的方式来处理安卓的权限管理?
- 用户和角色:通用权限管理系统数据库表结构如何设计?
- [数据库设计]用户和角色:通用权限管理系统数据库表结构如何设计?
- 权限管理系统如何分别实现对用户和角色的授权
- 如何用vsftpd实现用户不同权限:只能下载,可上传,管理权限等
- 如何用不同的方式来处理安卓的权限管理?
- 如何能做一个好的用户权限管理呢
- WIN7系统只有一个标准用户权限(如何提升到管理权限)
- 如何解决网站多用户权限管理
- 权限管理编程的几种设计方式
- [置顶] linux以用户分组的方式做文件权限管理实例
- 不使用三方包时,如何在社交系统ThinkSNS中建立优雅的用户权限管理【研发日记13】
- 不使用三方包时,如何在社交系统ThinkSNS中建立优雅的用户权限管理【研发日记13】
- 权限管理系统如何分别实现对用户和角色的授权
- 权限管理编程的几种设计方式
- 知识管理系统Data Solution研发日记之十四 如何以编程方式处理PDF格式文档
- 用户和角色:通用权限管理系统数据库表结构如何设计?
- 如何获得超级用户的管理权限