Làm thế nào để xác định liệu một chủ đề chạy trong bối cảnh người dùng tài khoản quản trị địa phương

QUAN TRỌNG: Bài viết này được dịch bằng phần mềm dịch máy của Microsoft chứ không phải do con người dịch. Microsoft cung cấp các bài viết do con người dịch và cả các bài viết do máy dịch để bạn có thể truy cập vào tất cả các bài viết trong Cơ sở Kiến thức của chúng tôi bằng ngôn ngữ của bạn. Tuy nhiên, bài viết do máy dịch không phải lúc nào cũng hoàn hảo. Loại bài viết này có thể chứa các sai sót về từ vựng, cú pháp hoặc ngữ pháp, giống như một người nước ngoài có thể mắc sai sót khi nói ngôn ngữ của bạn. Microsoft không chịu trách nhiệm về bất kỳ sự thiếu chính xác, sai sót hoặc thiệt hại nào do việc dịch sai nội dung hoặc do hoạt động sử dụng của khách hàng gây ra. Microsoft cũng thường xuyên cập nhật phần mềm dịch máy này.

Nhấp chuột vào đây để xem bản tiếng Anh của bài viết này:118626
TÓM TẮT
Để xác định liệu một chủ đề chạy theo một địa phương tài khoản quản trị, bạn phải kiểm tra mã thông báo truy cập được liên kết với chủ đề. Bài viết này mô tả làm thế nào để làm điều này.

Với Windows Phiên bản 2000 và sau này, bạn có thể sử dụng các CheckTokenMembership() API thay vì của các bước được mô tả trong bài viết này. Cho thông tin thêm, xem tài liệu Microsoft nền tảng SDK.
THÔNG TIN THÊM
Theo mặc định, mã thông báo đó là liên kết với một chủ đề là mà của quá trình chứa của nó. Bối cảnh người dùng"này" superceded bởi bất kỳ mã thông báo mà được gắn trực tiếp vào các chủ đề. Vì vậy, để xác định một thread bối cảnh người dùng, đầu tiên bạn nên cố gắng để có được một mã thông báo cho chủ đề với các OpenThreadToken chức năng. Nếu phương pháp này không thành công và các GetLastError chức năng báo cáo ERROR_NO_TOKEN, sau đó bạn có thể có được mã thông báo cho quá trình với các OpenProcessToken chức năng.

Sau khi bạn có được mã thông báo của hiện tại người sử dụng, bạn có thể sử dụng các AccessCheck chức năng phát hiện cho dù người dùng là một quản trị viên. Để làm Điều này, hãy làm theo các bước sau:
  1. Tạo ra một định danh bảo mật (SID) cho các địa phương nhóm người quản trị bằng cách sử dụng các AllocateAndInitializeSid chức năng.
  2. Xây dựng một mô tả bảo mật mới (SD) với một Tùy Access Control List (DACL) có chứa một mục điều khiển truy cập (ACE) cho nhóm người quản trị SID.
  3. Cuộc gọi AccessCheck với mã thông báo của người dùng hiện tại và vừa được xây dựng SD để phát hiện cho dù người dùng là một quản trị viên.
Mẫu mã sau đây sử dụng các chức năng được đề cập trước đó trong bài viết này để thử nghiệm cho dù các chủ đề hiện tại đang chạy như một người sử dụng Ai là người quản trị trên máy tính địa phương.

Mã mẫu

#include <windows.h>#include <stdio.h>#include <lmcons.h>BOOL IsCurrentUserLocalAdministrator(void);void main(int argc, char **argv){   if (IsCurrentUserLocalAdministrator())      printf("You are an administrator\n");   else      printf("You are not an administrator\n");}/*--------------------------------------------------------------------------IsCurrentUserLocalAdministrator ()This function checks the token of the calling thread to see if the callerbelongs to the Administrators group.Return Value:   TRUE if the caller is an administrator on the local machine.   Otherwise, FALSE.--------------------------------------------------------------------------*/BOOL IsCurrentUserLocalAdministrator(void){   BOOL   fReturn         = FALSE;   DWORD  dwStatus;   DWORD  dwAccessMask;   DWORD  dwAccessDesired;   DWORD  dwACLSize;   DWORD  dwStructureSize = sizeof(PRIVILEGE_SET);   PACL   pACL            = NULL;   PSID   psidAdmin       = NULL;   HANDLE hToken              = NULL;   HANDLE hImpersonationToken = NULL;   PRIVILEGE_SET   ps;   GENERIC_MAPPING GenericMapping;   PSECURITY_DESCRIPTOR     psdAdmin           = NULL;   SID_IDENTIFIER_AUTHORITY SystemSidAuthority = SECURITY_NT_AUTHORITY;   /*      Determine if the current thread is running as a user that is a member of      the local admins group.  To do this, create a security descriptor that      has a DACL which has an ACE that allows only local aministrators access.      Then, call AccessCheck with the current thread's token and the security      descriptor.  It will say whether the user could access an object if it      had that security descriptor.  Note: you do not need to actually create      the object.  Just checking access against the security descriptor alone      will be sufficient.   */   const DWORD ACCESS_READ  = 1;   const DWORD ACCESS_WRITE = 2;   __try   {      /*         AccessCheck() requires an impersonation token.  We first get a primary         token and then create a duplicate impersonation token.  The         impersonation token is not actually assigned to the thread, but is         used in the call to AccessCheck.  Thus, this function itself never         impersonates, but does use the identity of the thread.  If the thread         was impersonating already, this function uses that impersonation context.      */      if (!OpenThreadToken(GetCurrentThread(), TOKEN_DUPLICATE|TOKEN_QUERY, TRUE, &hToken))      {         if (GetLastError() != ERROR_NO_TOKEN)            __leave;         if (!OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE|TOKEN_QUERY, &hToken))            __leave;      }      if (!DuplicateToken (hToken, SecurityImpersonation, &hImpersonationToken))          __leave;      /*        Create the binary representation of the well-known SID that        represents the local administrators group.  Then create the security        descriptor and DACL with an ACE that allows only local admins access.        After that, perform the access check.  This will determine whether        the current user is a local admin.      */      if (!AllocateAndInitializeSid(&SystemSidAuthority, 2,                                    SECURITY_BUILTIN_DOMAIN_RID,                                    DOMAIN_ALIAS_RID_ADMINS,                                    0, 0, 0, 0, 0, 0, &psidAdmin))         __leave;      psdAdmin = LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH);      if (psdAdmin == NULL)         __leave;      if (!InitializeSecurityDescriptor(psdAdmin, SECURITY_DESCRIPTOR_REVISION))         __leave;      // Compute size needed for the ACL.      dwACLSize = sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE) +                  GetLengthSid(psidAdmin) - sizeof(DWORD);      pACL = (PACL)LocalAlloc(LPTR, dwACLSize);      if (pACL == NULL)         __leave;      if (!InitializeAcl(pACL, dwACLSize, ACL_REVISION2))         __leave;      dwAccessMask= ACCESS_READ | ACCESS_WRITE;      if (!AddAccessAllowedAce(pACL, ACL_REVISION2, dwAccessMask, psidAdmin))         __leave;      if (!SetSecurityDescriptorDacl(psdAdmin, TRUE, pACL, FALSE))         __leave;      /*         AccessCheck validates a security descriptor somewhat; set the group         and owner so that enough of the security descriptor is filled out to         make AccessCheck happy.      */      SetSecurityDescriptorGroup(psdAdmin, psidAdmin, FALSE);      SetSecurityDescriptorOwner(psdAdmin, psidAdmin, FALSE);      if (!IsValidSecurityDescriptor(psdAdmin))         __leave;      dwAccessDesired = ACCESS_READ;      /*         Initialize GenericMapping structure even though you         do not use generic rights.      */      GenericMapping.GenericRead    = ACCESS_READ;      GenericMapping.GenericWrite   = ACCESS_WRITE;      GenericMapping.GenericExecute = 0;      GenericMapping.GenericAll     = ACCESS_READ | ACCESS_WRITE;      if (!AccessCheck(psdAdmin, hImpersonationToken, dwAccessDesired,                       &GenericMapping, &ps, &dwStructureSize, &dwStatus,                       &fReturn))      {         fReturn = FALSE;         __leave;      }   }   __finally   {      // Clean up.      if (pACL) LocalFree(pACL);      if (psdAdmin) LocalFree(psdAdmin);      if (psidAdmin) FreeSid(psidAdmin);      if (hImpersonationToken) CloseHandle (hImpersonationToken);      if (hToken) CloseHandle (hToken);   }   return fReturn;}

Cảnh báo: Bài viết này được dịch tự động

Thuộc tính

ID Bài viết: 118626 - Xem lại Lần cuối: 08/17/2011 13:54:00 - Bản sửa đổi: 2.0

Microsoft Win32 Application Programming Interface

  • kbapi kbhowto kbkernbase kbsecurity kbmt KB118626 KbMtvi
Phản hồi