window權限 及c++實現 【網摘】(轉)


from : http://blog.csdn.net/zipper9527/article/details/6256459

http://www.lihuasoft.net/article/show.php?id=755

http://www.360doc.com/content/07/0404/15/21275_430071.shtml

 

以程序的方式操縱NTFS 的文件權限

Windows NT/2K/XP版本的操作系統都支持 NTFS 格式的文件系統,這是一個有安全性質的文件系統,你可以通過 Windows 的資源管理器來設置對每個目錄和 文件的用戶訪問權限。這里我就不對 NTFS 的安全性進行講述了,我默認你對 NTFS 的文件目錄的安全設置有了一定的了解。在這里,我將向你介紹使用  Windows 的 API 函數來操縱 NTFS 的文件權限。


一、理論和術語

 

在Windows NT/2K?XP 下的對象,不一定是文件系統,還有其它的一些對象,如:進程、命名管道、打印機、網絡共享、或是注冊表等等,都可以設置用戶訪問權限。在  Windows 系統中,其是用一個安全描述符( Security Descriptors )的結構來保存其權限的設置信息,簡稱為 SD ,其在 Windows SDK中的結構名是“ SECURITY_DESCRIPTOR ”,這是包括了安全設置信息的結構體。一個安全描述符包含以下信息:

一個安全標識符(Security identifiers) ,其標識了該信息是哪個對象的,也就是用於記錄安全對象的 ID 。簡稱為: SID 。

一 個DACL ( Discretionary Access Control List ),其指出了允許和拒絕某用戶或用戶組的存取控制列表。 當一個進程需要訪問安全對象,系統就會檢查 DACL 來決定進程的訪問權。如果一個對象沒有 DACL ,那么就是說這個對象是任何人都可以擁有完全的訪問權 限。

一個SACL ( System Access Control List ),其指出了在該對象上的一組存取方式(如,讀、寫、運行等)的存取控制權限細節的列表。還有其自身的一些控制位。

DACL和 SACL 構成了整個存取控制列表 Access Control List ,簡稱 ACL , ACL 中的每一項,我們叫做 ACE ( Access Control Entry ), ACL 中的每一個 ACE 。

 

我們的程序不用直接維護SD 這個結構,這個結構由系統維護。我們只用使用 Windows  提供的相關的 API 函數來取得並設置 SD 中的信息就行了。不過這些 API 函數只有 Windows NT/2K/XP 才支持。

 

安全對象Securable Object 是擁有 SD 的 Windows 的對象。所有的被命名的 Windows 的對象都是安全對象。一些沒有命名的對象是安全對象,如:進程和線程,也有 安全描述符 SD 。在對大多數的創建安全對象的操作中都需要你傳遞一個 SD 的參數,如: CreateFile 和 CreateProcess 函數。另 外,Windows 還提供了一系列有關安全對象的安全信息的存取函數,以供你取得對象上的安全設置,或修改對象上的安全設置。 如:GetNamedSecurityInfo, SetNamedSecurityInfo , GetSecurityInfo, SetSecurityInfo 。

 

下圖說明了,安全對象和DACL 以及訪問者之間的聯系(來源於 MSDN )。注意, DACL 表中的每個 ACE 的順序是有意義的,如果前面的 Allow(或 denied ) ACE 通過了,那么,系統就不會檢查后面的 ACE 了。

 

系統會按照順序依次檢查所有的ACE 規則,如下面的條件滿足,則退出:

1、 如果一個 Access-Denied 的 ACE 明顯地拒絕了請求者。

2、 如果某 Access-Allowed 的 ACE 明顯地同意了請求者。

3、 全部的 ACE 都檢查完了,但是沒有一條 ACE 明顯地允許或是拒絕請求者,那么系統將使用默認值,拒絕請求者的訪問。

更多的理論和描述,請參看MSDN 。

 

二、實踐與例程

 

1、  例程一:創建一個有權限設置的目錄

 

#include <windows.h>

 

void main(void)

{

  SECURITY_ATTRIBUTES sa;  //和文件有關的安全結構

  SECURITY_DESCRIPTOR sd;  //聲明一個 SD

 

  BYTE aclBuffer[1024];

  PACL pacl=(PACL)&aclBuffer; //聲明一個 ACL ,長度是 1024

 

  BYTE sidBuffer[100];

  PSID psid=(PSID) &sidBuffer;  //聲明一個 SID ,長度是 100

 

  DWORD sidBufferSize = 100;

  char domainBuffer[80];

  DWORD domainBufferSize = 80;

  SID_NAME_USE snu;

  HANDLE file;

 

  //初始化一個 SD

  InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION);

  //初始化一個 ACL

  InitializeAcl(pacl, 1024, ACL_REVISION);

  //查找一個用戶 hchen ,並取該用戶的 SID

  LookupAccountName(0, "hchen", psid,

      &sidBufferSize, domainBuffer,

      &domainBufferSize, &snu);

  //設置該用戶的 Access-Allowed 的 ACE ,其權限為“所有權限”

AddAccessAllowedAce(pacl, ACL_REVISION, GENERIC_ALL, psid);

//把 ACL 設置到 SD 中

  SetSecurityDescriptorDacl(&sd, TRUE, pacl, FALSE);

 

  //把 SD 放到文件安全結構 SA 中

  sa.nLength = sizeof(SECURITY_ATTRIBUTES);

  sa.bInheritHandle = FALSE;

  sa.lpSecurityDescriptor = &sd;

 

  //創建文件

  file = CreateFile("c://testfile",

    0, 0, &sa, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, 0);

  CloseHandle(file);

}

 

 

這 個例子我是從網上找來的,改了改。其中使用到的關鍵的API 函數,我都把其加粗了。從程序中我們可以看到,我們先初始化了一個 SD 和一個 ACL,然后調用  LookupAccountName 取得用戶的 SID ,然后通過這個 SID ,對 ACL 中加入一個有允許訪問權限的 ACE ,然后再把整個 ACL 設置到SD  中。最后,組織文件安全描述的 SA 結構,並調用 CreateFile 創建文件。如果你的操作系統是 NTFS ,那么,你可以看到你創建出來的文件的安全屬性 的樣子:

 

 

這個程序旨在說明如何生成一個新的SD 和 ACL 的用法,其有四個地方的不足和不清:

 

1、 對於 ACL 和 SID 的聲明采用了硬編碼的方式指定其長度。

2、 對於 API 函數,沒有出錯處理。

3、 沒有說明如何修改已有文件或目錄的安全設置。

4、 沒有說明安全設置的繼承性。

 

對於這些我將在下個例程中講述。

 

2、  例程二、為目錄增加一個安全設置項

 

在我把這個例程序例出來以前,請允許我多說一下。

 

1、  對於文件、目錄、命令管道,我們不一定要使用 GetNamedSecurityInfo 和 SetNamedSecurityInfo 函數,我們可以使用其 專用函數 GetFileSecurity和 SetFileSecurity 函數來取得或設置文件對象的 SD ,以設置其訪問權限。需要使用這兩個函數並不容 易,正如前面我們所說的,我們還需要處理 SD參數,要處理 SD ,就需要處理 DACL 和 ACE ,以及用戶的相關 SID ,於是,一系統列的函數就被這兩個函數 帶出來了。

2、  對於上一個例子中的使用硬編碼指定 SID 的處理方法是。調用 LookupAccountName 函數時,先把 SID , Domain 名的參數傳為空  NULL ,於是 LookupAccountName 會返回用戶的 SID 的長度和 Domain 名的長度,於是你可以根據這個長度分配內存,然后再次調用  LookupAccountName 函數。於是就可以達到到態分配內存的效果。對於 ACL 也一樣。

3、  對於給文件的 ACL 中增加一個 ACE 條目,一般的做法是先取出文件上的 ACL ,逐條取出 ACE ,和現需要增加的 ACE 比較,如果有沖突,則刪除已有的  ACE ,把新加的 ACE 添置到最后。這里的最后,應該是非繼承而來的 ACE 的最后。關於 ACL 繼承, NTFS 中,你可以設置文件和目錄是否繼承於其父目錄 的設置。在程序中同樣可以設置。

還是請看例程,這個程序比較長,來源於MSDN ,我做了一點點修改,並把自己的理解加在注釋中,所以,請注意代碼中的注釋:

#include <windows.h>

#include <tchar.h>

#include <stdio.h>

//使用 Windows 的 HeapAlloc 函數進行動態內存分配

#define myheapalloc(x) (HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, x))

#define myheapfree(x) (HeapFree(GetProcessHeap(), 0, x))

typedef BOOL (WINAPI *SetSecurityDescriptorControlFnPtr)(

  IN PSECURITY_DESCRIPTOR pSecurityDescriptor,

  IN SECURITY_DESCRIPTOR_CONTROL ControlBitsOfInterest,

  IN SECURITY_DESCRIPTOR_CONTROL ControlBitsToSet);

typedef BOOL (WINAPI *AddAccessAllowedAceExFnPtr)(

 PACL pAcl,

 DWORD dwAceRevision,

 DWORD AceFlags,

 DWORD AccessMask,

 PSID pSid

);

BOOL AddAccessRights(TCHAR *lpszFileName, TCHAR *lpszAccountName,

   DWORD dwAccessMask) {

  // 聲明 SID 變量

  SID_NAME_USE  snuType;

  // 聲明和 LookupAccountName 相關的變量(注意,全為 0 ,要在程序中動態分配)

  TCHAR *    szDomain    = NULL;

  DWORD     cbDomain    = 0;

  LPVOID     pUserSID    = NULL;

  DWORD     cbUserSID   = 0;

  // 和文件相關的安全描述符  SD  的變量

  PSECURITY_DESCRIPTOR pFileSD = NULL;   // 結構變量

  DWORD     cbFileSD    = 0;    // SD的 size

  // 一個新的 SD 的變量,用於構造新的 ACL (把已有的 ACL 和需要新加的 ACL 整合起來)

  SECURITY_DESCRIPTOR newSD;

  // 和 ACL  相關的變量

  PACL      pACL      = NULL;

  BOOL      fDaclPresent;

  BOOL      fDaclDefaulted;

  ACL_SIZE_INFORMATION AclInfo;

  // 一個新的  ACL  變量

  PACL      pNewACL    = NULL; //結構指針變量

  DWORD     cbNewACL    = 0;   //ACL的 size

  // 一個臨時使用的  ACE  變量

  LPVOID     pTempAce    = NULL;

  UINT      CurrentAceIndex = 0; //ACE在 ACL 中的位置

  UINT      newAceIndex = 0; //新添的 ACE 在 ACL 中的位置

  //API函數的返回值,假設所有的函數都返回失敗。

  BOOL      fResult;

  BOOL      fAPISuccess;

  SECURITY_INFORMATION secInfo = DACL_SECURITY_INFORMATION;

  // 下面的兩個函數是新的 API 函數,僅在 Windows 2000 以上版本的操作系統支持。

  // 在此將從 Advapi32.dll 文件中動態載入。如果你使用 VC++ 6.0 編譯程序,而且你想

  // 使用這兩個函數的靜態鏈接。則請為你的編譯加上: /D_WIN32_WINNT=0x0500

  // 的編譯參數。並且確保你的 SDK 的頭文件和 lib 文件是最新的。

  SetSecurityDescriptorControlFnPtr _SetSecurityDescriptorControl = NULL;

  AddAccessAllowedAceExFnPtr _AddAccessAllowedAceEx = NULL;

  __try {

   //

   // STEP 1: 通過用戶名取得 SID

   //   在這一步中 LookupAccountName 函數被調用了兩次,第一次是取出所需要

   // 的內存的大小,然后,進行內存分配。第二次調用才是取得了用戶的帳戶信息。

   // LookupAccountName同樣可以取得域用戶或是用戶組的信息。(請參看 MSDN )

   //

   fAPISuccess = LookupAccountName(NULL, lpszAccountName,

      pUserSID, &cbUserSID, szDomain, &cbDomain, &snuType);

   // 以上調用 API 會失敗,失敗原因是內存不足。並把所需要的內存大小傳出。

   // 下面是處理非內存不足的錯誤。

   if (fAPISuccess)

     __leave;

   else if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {

     _tprintf(TEXT("LookupAccountName() failed. Error %d/n"),

        GetLastError());

     __leave;

   }

   pUserSID = myheapalloc(cbUserSID);

   if (!pUserSID) {

     _tprintf(TEXT("HeapAlloc() failed. Error %d/n"), GetLastError());

     __leave;

   }

   szDomain = (TCHAR *) myheapalloc(cbDomain * sizeof(TCHAR));

   if (!szDomain) {

     _tprintf(TEXT("HeapAlloc() failed. Error %d/n"), GetLastError());

     __leave;

   }

   fAPISuccess = LookupAccountName(NULL, lpszAccountName,

      pUserSID, &cbUserSID, szDomain, &cbDomain, &snuType);

   if (!fAPISuccess) {

     _tprintf(TEXT("LookupAccountName() failed. Error %d/n"),

        GetLastError());

     __leave;

   }

   //

   // STEP 2: 取得文件(目錄)相關的安全描述符 SD

   //   使用 GetFileSecurity 函數取得一份文件 SD 的拷貝,同樣,這個函數也

    // 是被調用兩次,第一次同樣是取 SD 的內存長度。注意, SD 有兩種格式:自相關的

    // ( self-relative )和 完全的( absolute ), GetFileSecurity 只能取到“自

    // 相關的”,而 SetFileSecurity 則需要完全的。這就是為什么需要一個新的 SD ,

    // 而不是直接在 GetFileSecurity 返回的 SD 上進行修改。因為“自相關的”信息

    // 是不完整的。

   fAPISuccess = GetFileSecurity(lpszFileName,

      secInfo, pFileSD, 0, &cbFileSD);

   // 以上調用 API 會失敗,失敗原因是內存不足。並把所需要的內存大小傳出。

   // 下面是處理非內存不足的錯誤。

   if (fAPISuccess)

     __leave;

   else if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {

     _tprintf(TEXT("GetFileSecurity() failed. Error %d/n"),

        GetLastError());

     __leave;

   }

   pFileSD = myheapalloc(cbFileSD);

   if (!pFileSD) {

     _tprintf(TEXT("HeapAlloc() failed. Error %d/n"), GetLastError());

     __leave;

   }

   fAPISuccess = GetFileSecurity(lpszFileName,

      secInfo, pFileSD, cbFileSD, &cbFileSD);

   if (!fAPISuccess) {

     _tprintf(TEXT("GetFileSecurity() failed. Error %d/n"),

        GetLastError());

     __leave;

   }

   //

   // STEP 3: 初始化一個新的 SD

   //

   if (!InitializeSecurityDescriptor(&newSD,

      SECURITY_DESCRIPTOR_REVISION)) {

     _tprintf(TEXT("InitializeSecurityDescriptor() failed.")

      TEXT("Error %d/n"), GetLastError());

     __leave;

   }

   //

   // STEP 4: 從 GetFileSecurity  返回的 SD 中取 DACL

   //

   if (!GetSecurityDescriptorDacl(pFileSD, &fDaclPresent, &pACL,

      &fDaclDefaulted)) {

     _tprintf(TEXT("GetSecurityDescriptorDacl() failed. Error %d/n"),

        GetLastError());

     __leave;

   }

   //

   // STEP 5: 取  DACL 的內存 size

   //   GetAclInformation可以提供 DACL 的內存大小。只傳入一個類型為

   // ACL_SIZE_INFORMATION的 structure 的參數,需 DACL 的信息,是為了

   // 方便我們遍歷其中的 ACE 。

   AclInfo.AceCount = 0; // Assume NULL DACL.

   AclInfo.AclBytesFree = 0;

   AclInfo.AclBytesInUse = sizeof(ACL);

   if (pACL == NULL)

     fDaclPresent = FALSE;

   // 如果 DACL 不為空,則取其信息。(大多數情況下“自關聯”的 DACL 為空)

   if (fDaclPresent) {      

     if (!GetAclInformation(pACL, &AclInfo,

        sizeof(ACL_SIZE_INFORMATION), AclSizeInformation)) {

      _tprintf(TEXT("GetAclInformation() failed. Error %d/n"),

         GetLastError());

      __leave;

     }

   }

   //

   // STEP 6: 計算新的 ACL 的 size

   //  計算的公式是:原有的 DACL 的 size 加上需要添加的一個 ACE 的 size ,以

   // 及加上一個和 ACE 相關的 SID 的 size ,最后減去兩個字節以獲得精確的大小。

   cbNewACL = AclInfo.AclBytesInUse + sizeof(ACCESS_ALLOWED_ACE)

      + GetLengthSid(pUserSID) - sizeof(DWORD);

   //

   // STEP 7: 為新的 ACL 分配內存

   //

   pNewACL = (PACL) myheapalloc(cbNewACL);

   if (!pNewACL) {

     _tprintf(TEXT("HeapAlloc() failed. Error %d/n"), GetLastError());

     __leave;

   }

   //

   // STEP 8: 初始化新的 ACL 結構

   //

   if (!InitializeAcl(pNewACL, cbNewACL, ACL_REVISION2)) {

     _tprintf(TEXT("InitializeAcl() failed. Error %d/n"),

        GetLastError());

     __leave;

   }

   //

   // STEP 9 如果文件(目錄)  DACL  有數據,拷貝其中的 ACE 到新的 DACL 中

   //

   //   下面的代碼假設首先檢查指定文件(目錄)是否存在的 DACL ,如果有的話,

   // 那么就拷貝所有的 ACE 到新的 DACL 結構中,我們可以看到其遍歷的方法是采用

   // ACL_SIZE_INFORMATION結構中的 AceCount 成員來完成的。在這個循環中,

   // 會按照默認的 ACE 的順序來進行拷貝( ACE 在 ACL 中的順序是很關鍵的),在拷

   // 貝過程中,先拷貝非繼承的 ACE (我們知道 ACE 會從上層目錄中繼承下來)

   //

   newAceIndex = 0;

   if (fDaclPresent && AclInfo.AceCount) {

     for (CurrentAceIndex = 0;

        CurrentAceIndex < AclInfo.AceCount;

        CurrentAceIndex++) {

      //

      // STEP 10: 從 DACL 中取 ACE

      //

      if (!GetAce(pACL, CurrentAceIndex, &pTempAce)) {

        _tprintf(TEXT("GetAce() failed. Error %d/n"),

           GetLastError());

        __leave;

      }

      //

      // STEP 11: 檢查是否是非繼承的 ACE

      //   如果當前的 ACE 是一個從父目錄繼承來的 ACE ,那么就退出循環。

      // 因為,繼承的 ACE 總是在非繼承的 ACE 之后,而我們所要添加的 ACE

      // 應該在已有的非繼承的 ACE 之后,所有的繼承的 ACE 之前。退出循環

      // 正是為了要添加一個新的 ACE 到新的 DACL 中,這后,我們再把繼承的

      // ACE拷貝到新的 DACL 中。

      //

      if (((ACCESS_ALLOWED_ACE *)pTempAce)->Header.AceFlags

        & INHERITED_ACE)

        break;

      //

      // STEP 12: 檢查要拷貝的 ACE 的 SID 是否和需要加入的 ACE 的 SID 一樣,

      // 如果一樣,那么就應該廢掉已存在的 ACE ,也就是說,同一個用戶的存取

      // 權限的設置的 ACE ,在 DACL 中應該唯一。這在里,跳過對同一用戶已設置

      // 了的 ACE ,僅是拷貝其它用戶的 ACE 。

      //

      if (EqualSid(pUserSID,

        &(((ACCESS_ALLOWED_ACE *)pTempAce)->SidStart)))

        continue;

      //

      // STEP 13: 把 ACE 加入到新的 DACL 中

      //  下面的代碼中,注意  AddAce  函數的第三個參數,這個參數的意思是

      // ACL中的索引值,意為要把 ACE 加到某索引位置之后,參數 MAXDWORD 的

       // 意思是確保當前的 ACE 是被加入到最后的位置。

      //

      if (!AddAce(pNewACL, ACL_REVISION, MAXDWORD, pTempAce,

         ((PACE_HEADER) pTempAce)->AceSize)) {

        _tprintf(TEXT("AddAce() failed. Error %d/n"),

           GetLastError());

        __leave;

      }

      newAceIndex++;

     }

   }

 

  //

  // STEP 14: 把一個  access-allowed  的 ACE  加入到新的 DACL 中

  //   前面的循環拷貝了所有的非繼承且 SID 為其它用戶的 ACE ,退出循環的第一件事

  // 就是加入我們指定的 ACE 。請注意首先先動態裝載了一個 AddAccessAllowedAceEx

  // 的 API 函數,如果裝載不成功,就調用 AddAccessAllowedAce 函數。前一個函數僅

  // 在 Windows 2000 以后的版本支持, NT 則沒有,我們為了使用新版本的函數,我們首

  // 先先檢查一下當前系統中可不可以裝載這個函數,如果可以則就使用。使用動態鏈接

  // 比使用靜態鏈接的好處是,程序運行時不會因為沒有這個 API 函數而報錯。

  //

  // Ex版的函數多出了一個參數 AceFlag (第三人參數),用這個參數我們可以來設置一

  // 個叫 ACE_HEADER 的結構,以便讓我們所設置的 ACE 可以被其子目錄所繼承下去,而

  // AddAccessAllowedAce函數不能定制這個參數,在 AddAccessAllowedAce 函數

  // 中,其會把 ACE_HEADER 這個結構設置成非繼承的。

  //

   _AddAccessAllowedAceEx = (AddAccessAllowedAceExFnPtr)

      GetProcAddress(GetModuleHandle(TEXT("advapi32.dll")),

      "AddAccessAllowedAceEx");

   if (_AddAccessAllowedAceEx) {

      if (!_AddAccessAllowedAceEx(pNewACL, ACL_REVISION2,

       CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE ,

        dwAccessMask, pUserSID)) {

       _tprintf(TEXT("AddAccessAllowedAceEx() failed. Error %d/n"),

          GetLastError());

       __leave;

     }

   }else{

     if (!AddAccessAllowedAce(pNewACL, ACL_REVISION2,

        dwAccessMask, pUserSID)) {

       _tprintf(TEXT("AddAccessAllowedAce() failed. Error %d/n"),

          GetLastError());

       __leave;

     }

   }

   //

   // STEP 15: 按照已存在的 ACE 的順序拷貝從父目錄繼承而來的 ACE

   //

   if (fDaclPresent && AclInfo.AceCount) {

     for (;

       CurrentAceIndex < AclInfo.AceCount;

       CurrentAceIndex++) {

      //

      // STEP 16: 從文件(目錄)的 DACL 中繼續取 ACE

      //

      if (!GetAce(pACL, CurrentAceIndex, &pTempAce)) {

        _tprintf(TEXT("GetAce() failed. Error %d/n"),

           GetLastError());

        __leave;

      }

      //

      // STEP 17: 把 ACE 加入到新的 DACL 中

      //

      if (!AddAce(pNewACL, ACL_REVISION, MAXDWORD, pTempAce,

         ((PACE_HEADER) pTempAce)->AceSize)) {

        _tprintf(TEXT("AddAce() failed. Error %d/n"),

           GetLastError());

        __leave;

      }

     }

   }

   //

   // STEP 18: 把新的 ACL 設置到新的 SD 中

   //

   if (!SetSecurityDescriptorDacl(&newSD, TRUE, pNewACL,

      FALSE)) {

     _tprintf(TEXT("SetSecurityDescriptorDacl() failed. Error %d/n"),

        GetLastError());

     __leave;

   }

   //

   // STEP 19: 把老的 SD 中的控制標記再拷貝到新的 SD 中,我們使用的是一個叫

   // SetSecurityDescriptorControl() 的 API 函數,這個函數同樣只存在於

   // Windows 2000以后的版本中,所以我們還是要動態地把其從 advapi32.dll

   // 中載入,如果系統不支持這個函數,那就不拷貝老的 SD 的控制標記了。

   //

   _SetSecurityDescriptorControl =(SetSecurityDescriptorControlFnPtr)

      GetProcAddress(GetModuleHandle(TEXT("advapi32.dll")),

      "SetSecurityDescriptorControl");

   if (_SetSecurityDescriptorControl) {

     SECURITY_DESCRIPTOR_CONTROL controlBitsOfInterest = 0;

     SECURITY_DESCRIPTOR_CONTROL controlBitsToSet = 0;

     SECURITY_DESCRIPTOR_CONTROL oldControlBits = 0;

     DWORD dwRevision = 0;

     if (!GetSecurityDescriptorControl(pFileSD, &oldControlBits,

      &dwRevision)) {

      _tprintf(TEXT("GetSecurityDescriptorControl() failed.")

         TEXT("Error %d/n"), GetLastError());

      __leave;

     }

     if (oldControlBits & SE_DACL_AUTO_INHERITED) {

      controlBitsOfInterest =

        SE_DACL_AUTO_INHERIT_REQ |

        SE_DACL_AUTO_INHERITED ;

      controlBitsToSet = controlBitsOfInterest;

     }

     else if (oldControlBits & SE_DACL_PROTECTED) {

      controlBitsOfInterest = SE_DACL_PROTECTED;

      controlBitsToSet = controlBitsOfInterest;

     }    

     if (controlBitsOfInterest) {

      if (!_SetSecurityDescriptorControl(&newSD,

        controlBitsOfInterest,

        controlBitsToSet)) {

        _tprintf(TEXT("SetSecurityDescriptorControl() failed.")

           TEXT("Error %d/n"), GetLastError());

        __leave;

      }

     }

   }

   //

   // STEP 20: 把新的 SD 設置設置到文件的安全屬性中(千山萬水啊,終於到了)

   //

   if (!SetFileSecurity(lpszFileName, secInfo,

      &newSD)) {

     _tprintf(TEXT("SetFileSecurity() failed. Error %d/n"),

        GetLastError());

     __leave;

   }

   fResult = TRUE;

  } __finally {

   //

   // STEP 21: 釋放已分配的內存,以免 Memory Leak

   //

   if (pUserSID) myheapfree(pUserSID);

   if (szDomain) myheapfree(szDomain);

   if (pFileSD) myheapfree(pFileSD);

   if (pNewACL) myheapfree(pNewACL);

  }

  return fResult;

}

--------------------------------------------------------------------------------

int _tmain(int argc, TCHAR *argv[]) {

  if (argc < 3) {

   _tprintf(TEXT("usage: /"%s/" <FileName> <AccountName>/n"), argv[0]);

   return 1;

  }

  // argv[1] – 文件(目錄)名

  // argv[2] – 用戶(組)名

  // GENERIC_ALL表示所有的權限,其是一系列的 NTFS 權限的或

  //   NTFS的文件權限很細,還請參看 MSDN 。

  if (!AddAccessRights(argv[1], argv[2], GENERIC_ALL)) {

   _tprintf(TEXT("AddAccessRights() failed./n"));

   return 1;

  }

  else {

   _tprintf(TEXT("AddAccessRights() succeeded./n"));

   return 0;

  }

}

 

三、 一些相關的API 函數

 

通過以上的示例,相信你已知道如何操作NTFS 文件安全屬性了,還有一些 API 函數需要介紹一下。

1、 如果你要加入一個 Access-Denied  的 ACE ,你可以使用 AddAccessDeniedAce 函數

2、 如果你要刪除一個 ACE ,你可以使用 DeleteAce 函數

3、 如果你要檢查你所設置的 ACL 是否合法,你可以使用 IsValidAcl 函數,同樣,對於 SD 的合法也有一個叫 IsValidSecurityDescriptor 的函數

 

Windows XP權限整合應用全解

如果要刪除某個用戶對加密文件的訪問權限,那么只需選中此用戶后點擊“刪除”按鈕即可。作為 微軟  第 一個穩定且安全的操作系統,Windows XP 經過幾年的磨合過渡期,終於以超過 Windows 系列操作系統 50% 的用戶占有量成為目前用戶使用最多的操作系統。在慢慢熟悉了 Windows XP 后,人們逐漸開始不滿足基本的系統應用了,他們更加渴望學習一些較深入且實用的知識,以便能讓系統充分發揮出 Windows XP 的高級性能。

  因此本文以Windows XP Professional 版本為平台,引領大家感受一下 Windows XP 在“權限”方面的設計魅力!

  一、什么是權限

  Windows XP 提供了非常細致的權限控制項,能夠精確定制用戶對資源的訪問控制能力,大多數的權限從其名稱上就可以基本了解其所能實現的內容。

   “權限”(Permission) 是針對資源而言的。也就是說,設置權限只能是以資源為對象,即“設置某個文件夾有哪些用戶可以擁有相應的權限”,而不 能是以用戶為主,即“設置某個用戶可以對哪些資源擁有權限”。這就意味着“權限”必須針對“資源”而言,脫離了資源去談權限毫無意義──在提到權限的具體 實施時,“某個資源”是必須存在的。

  利用權限可以控制資源被訪問的方式,如User 組的成員對某個資源擁有“讀取”操作權限、 Administrators 組成員擁有“讀取 + 寫入 + 刪除”操作權限等。

   值得一提的是,有一些Windows 用戶往往會將“權力”與“權限”兩個非常相似的概念搞混淆,這里做一下簡單解釋:“權力” (Right) 主要是針對 用戶而言的。“權力”通常包含“登錄權力” (Logon Right) 和“特權” (Privilege) 兩種。登錄權力決定了用戶如何登錄到計算機,如是否采用本地交互式登錄、是否為網絡登錄等。特權則是一系列 權力的總稱,這些權力主要用於幫助用戶對系統進行管理,如是否允許用戶安裝或加載驅動程序等。顯然,權力與權限有本質上的區別。

  二、安全標識符、訪問控制列表、安全主體

   說到Windows XP 的權限,就不能不說說“安全標識符” (Security Identifier, SID) 、“訪問控制列表” (Access Control List , ACL) 和安全主體(Security Principal) 這三個與其息息相關的設計了。

  1. 安全標識符

  在 Windows XP 中,系統是通過 SID 對用戶進行識別的,而不是很多用戶認為的“用戶名稱”。 SID 可以應用於系統內的所有用戶、組、服務或計算機,因為 SID 是一個 具有惟一性、絕對不會重復產生的數值,所以,在刪除了一個賬戶 ( 如名為“ A ”的賬戶 ) 后,再次創建這個“ A ”賬戶時,前一個 A 與后一個 A 賬戶的 SID 是不 相同的。這種設計使得賬戶的權限得到了最基礎的保護,盜用權限的情況也就徹底杜絕了。

  查看用戶、組、服務或計算機 的SID 值,可以使用“ Whoami ”工具來執行,該工具包含在 Windows XP 安裝光盤的“ Support/Tools ”目錄中,雙擊執行該目錄下的“ Setup ”文件后,將會有包括 Whoami 工具在內的一系列命令行工具拷貝 到“ X:/Program Files/Support Tools ”目錄中。此后在任意一個命令提示符窗口中都可以執行“ Whoami /all ”命令來查看當前用戶的全部信息。

  2. 訪問控制列表 (ACL)

  訪問控制列表是權限的核心技術。顧名思義,這是一個權限列表,用於定義特定用戶對某個資源的訪問權限,實際上這就是Windows XP 對資源進行保護時所使用的一個標准。

   在訪問控制列表中,每一個用戶或用戶組都對應一組訪問控制項(Access Control Entry, ACE) ,這一點只需在“組或用戶名稱”列表中選擇不同的用戶或組時,通過下方的權限列表設置項是不同的這一點就可以看出來。顯然,所有用戶或用戶組的權 限訪問設置都將會在這里被存儲下來,並允許隨時被有權限進行修改的用戶進行調整,如取消某個用戶對某個資源的“寫入”權限。

  3. 安全主體 (Security Principal)

  在Windows XP 中,可以將用戶、用戶組、計算機或服務都看成是一個安全主體,每個安全主體都擁有相對應的賬戶名稱和 SID 。根據系統架構的不同,賬戶的管理方式也有所不同──本地賬戶被本地的 SAM 管理;域的賬戶則會被活動目錄進行管理……

  一般來說,權限的指派過程實際上就是為某個資源指定安全主體( 即用戶、用戶組等 ) 可以擁有怎樣的操作過程。因為用戶組包括多個用戶,所以大多數情況下,為資源指派權限時建議使用用戶組來完成,這樣可以非常方便地完成統一管理。

  三、權限的四項基本原則

  在Windows XP 中,針對權限的管理有四項基本原則,即:拒絕優於允許原則、權限最小化原則、累加原則和權限繼承性原則。這四項基本原則對於權限的設置來說,將會起到非常重要的作用,下面就來了解一下:

  1. 拒絕優於允許原則

   “拒絕優於允許”原則是一條非常重要且基礎性的原則,它可以非常完美地處理好因用戶在用戶組的歸屬方面引起的權限“糾紛”,例如,“shyzhong ” 這個用戶既屬於“ shyzhongs ”用戶組,也屬於“ xhxs ”用戶組,當我們對“ xhxs ”組中某個資源進行“寫入”權限的集中分配( 即針對用戶組進 行 ) 時,這個時候該組中的“ shyzhong ”賬戶將自動擁有“寫入”的權限。

  但令人奇怪的是, “shyzhong ”賬戶明明擁有對這個資源的“寫入”權限,為什么實際操作中卻無法執行呢?原來,在“ shyzhongs ”組中同樣也對 “ shyzhong ”用戶進行了針對這個資源的權限設置,但設置的權限是“拒絕寫入”。基於“拒絕優於允許”的原則,“ shyzhong ”在 “ shyzhongs”組中被 “拒絕寫入”的權限將優先於“ xhxs ”組中被賦予的允許“寫入”權限被執行。因此,在實際操作中,“ shyzhong ”用戶無法對這個資源進行“寫入” 操作。

  2. 權限最小化原則

  Windows XP 將“保持用戶最小的權限”作為一個基本原則進行執行,這一點是非常有必要的。這條原則可以確保資源得到最大的安全保障。這條原則可以盡量讓用戶不能訪問或不必要訪問的資源得到有效的權限賦予限制。

   基於這條原則,在實際的權限賦予操作中,我們就必須為資源明確賦予允許或拒絕操作的權限。例如系統中新建的受限用戶“shyzhong ”在默認狀態下對 “ DOC ”目錄是沒有任何權限的,現在需要為這個用戶賦予對“ DOC ”目錄有“讀取”的權限,那么就必須在“ DOC ”目錄的權限列表中為 “ shyzhong ”用戶添加“讀取”權限。

  3. 權限繼承性原則

  權限 繼承性原則可以讓資源的權限設置變得更加簡單。假設現在有個“DOC ”目錄,在這個目錄中有“ DOC01 ”、“ DOC02 ”、“ DOC03”等子目錄,現 在需要對 DOC 目錄及其下的子目錄均設置“ shyzhong ”用戶有“寫入”權限。因為有繼承性原則,所以只需對“ DOC ”目錄設置“shyzhong ” 用戶有“寫入”權限,其下的所有子目錄將自動繼承這個權限的設置。

  4. 累加原則

  這個原則比較好理解,假設現在“zhong ”用戶既屬於“ A ”用戶組,也屬於“ B ”用戶組,它在 A 用戶組的權限是“讀取”,在“ B ”用戶組中的權限是“寫入”,那么根據累加原則,“ zhong ”用戶的實際權限將會是“讀取 + 寫入”兩種。

  顯然,“拒絕優於允許”原則是用於解決權限設置上的沖突問題的;“權限最小化”原則是用於保障資源安全的;“權限繼承性”原則是用於“自動化”執行權限設置的;而“累加原則”則是讓權限的設置更加靈活多變。幾個原則各有所用,缺少哪一項都會給權限的設置帶來很多麻煩!

   注意:在Windows XP 中,“ Administrators ”組的全部成員都擁有“取得所有者身份” (Take Ownership) 的權力,也就是管理員組的成員可以從其他用戶手中“奪取”其身份的權力,例如受限用戶“ shyzhong ”建立了一個 DOC 目錄,並 只賦予自己擁有讀取權力,這看似周到的權限設置,實際上,“ Administrators ”組的全部成員將可以通過“奪取所有權”等方法獲得這個權限。

  四、資源權限高級應用

  以文件與文件夾的權限為例,依據是否被共享到網絡上,其權限可以分為NTFS 權限與共享權限兩種,這兩種權限既可以單獨使用,也可以相輔使用。兩者之間既能夠相互制約,也可以相互補充。下面來看看如何進行設置:

  1.NTFS 權限

  首先我們要知道:只要是存在NTFS 磁盤分區上的文件夾或文件,無論是否被共享,都具有此權限。此權限對於使用 FAT16/FAT32 文件系統的文件與文件夾無效!

  NTFS 權限有兩大要素:一是標准訪問權限;二是特別訪問權限。前者將一些常用的系統權限選項比較籠統地組成 6 種“套餐型”的權限,即:完全控制、修改、讀取和運行、列出文件夾目錄、讀取、寫入。

   在大多數的情況下,“標准權限”是可以滿足管理需要的,但對於權限管理要求嚴格的環境,它往往就不能令管理員們滿意了,如只想賦予某用戶有建立文件夾的 權限,卻沒有建立文件的權限;如只能刪除當前目錄中的文件,卻不能刪除當前目錄中的子目錄的權限等……這個時候,就可以讓擁有所有權限選項的“特別權限” 來大顯身手了。也就是說,特別權限不再使用“套餐型”,而是使用可以允許用戶進行“菜單型”的細節化權限管理選擇了。

  那么如何設置標准訪問權限呢?以對一個在NTFS 分區中的名為“ zhiguo ”的文件夾進行設置標准訪問權限為例,可以按照如下方法進行操作:

   因為NTFS 權限需要在資源屬性頁面的“安全”選項卡設置界面中進行,而 Windows XP 在安裝后默認狀態下是沒有激活“安全”選項卡設置功能的,所以需要首先啟用系統中的“安全”選項卡。方法是:依次點擊“開始”→“設置”→“控制面 板”,雙擊“文件夾選項”,在“查看”標簽頁設置界面上的“高級設置”選項列表中清除“使用簡單文件共享 ( 推薦 ) ”選項前的復選框后點擊“應用”按鈕即 可。

  設置完畢后就可以右鍵點擊“zhiguo ”文件夾,在彈出的快捷菜單中選擇“共享與安全”,在“ zhiguo  屬性”窗口中就可以看見“安全”選項卡的存在了。針對資源進行 NTFS 權限設置就是通過這個選項卡來實現的,此時應首先在“組或用戶名稱”列表中選擇需要 賦予權限的用戶名組 ( 這里選擇“ zhong ”用戶 ) ,接着在下方的“ zhong  的權限”列表中設置該用戶可以擁有的權限即可。

  下面簡單解釋一下六個權限選項的含義:

  ①完全控制(Full Control) :該權限允許用戶對文件夾、子文件夾、文件進行全權控制,如修改資源的權限、獲取資源的所有者、刪除資源的權限等,擁有完全控制權限就等於擁有了其他所有的權限;

  ②修改(Modify) :該權限允許用戶修改或刪除資源,同時讓用戶擁有寫入及讀取和運行權限;

  ③讀取和運行(Read & Execute) :該權限允許用戶擁有讀取和列出資源目錄的權限,另外也允許用戶在資源中進行移動和遍歷,這使得用戶能夠直接訪問子文件夾與文件,即使用戶沒有權限訪問這個路徑;

  ④列出文件夾目錄(List Folder Contents) :該權限允許用戶查看資源中的子文件夾與文件名稱;

  ⑤讀取(Read) :該權限允許用戶查看該文件夾中的文件以及子文件夾,也允許查看該文件夾的屬性、所有者和擁有的權限等;

  ⑥寫入(Write) :該權限允許用戶在該文件夾中創建新的文件和子文件夾,也可以改變文件夾的屬性、查看文件夾的所有者和權限等。

   如果在“組或用戶名稱”列表中沒有所需的用戶或組,那么就需要進行相應的添加操作了,方法如下:點擊“添加”按鈕后,在出現的“選擇用戶和組”對話框 中,既可以直接在“輸入對象名稱來選擇”文本區域中輸入用戶或組的名稱( 使用“計算機名 / 用戶名”這種方式 ) ,也可以點擊“高級”按鈕,在彈出的對話框中 點擊“立即查找”按鈕讓系統列出當前系統中所有的用戶組和用戶名稱列表。此時再雙擊選擇所需用戶或組將其加入即可。如圖 2 所示。

   如果想刪除某個用戶組或用戶的話,只需在“組或用戶名稱”列表中選中相應的用戶或用戶組后,點擊下方的“刪除”按鈕即可。但實際上,這種刪除並不能確保 被刪除的用戶或用戶組被拒絕訪問某個資源,因此,如果希望拒絕某個用戶或用戶組訪問某個資源,還要在“組或用戶名稱”列表中選擇相應的用戶名用戶組后,為 其選中下方的“拒絕”復選框即可。

  那么如何設置特殊權限呢?假設現在需要對一個名為“zhiguo ”的目錄賦予 “ zhong ”用戶對其具有“讀取”、“建立文件和目錄”的權限,基於安全考慮,又決定取消該賬戶的“刪除”權限。此時,如果使用“標准權限”的話,將無 法完成要求,而使用特別權限則可以很輕松地完成設置。

   首先,右鍵點擊“zhiguo ”目錄,在右鍵快捷菜單中選擇“共享與安全”項,隨后在“安全”選項卡設置界面中選中“ zhong ”用戶並點擊下方的“高 級”按鈕,在彈出的對話框中點擊清空“從父項繼承那些可以應用到子對象的權限項目,包括那些在此明確定義的項目”項選中狀態,這樣可以斷開當前權限設置與 父級權限設置之前的繼承關系。在隨即彈出的“安全”對話框中點擊“復制”或“刪除”按鈕后 ( 點擊“復制”按鈕可以首先復制繼承的父級權限設置,然后再斷開 繼承關系 ) ,接着點擊“應用”按鈕確認設置,再選中“ zhong ”用戶並點擊“編輯”按鈕,在彈出的“ zhong 的權限項目”對話框中請首先點擊“全部清 除”按鈕,接着在“權限”列表中選擇“遍歷文件夾 / 運行文件”、“列出文件夾 / 讀取數據”、“讀取屬性”、“創建文件 / 寫入數據”、“創建文件夾 / 附加數 據”、“讀取權限”幾項,最后點擊“確定”按鈕結束設置。

  在經過上述設置后,“zhong ”用戶在對“ zhiguo ”進行刪除操作時,就會彈出提示框警告操作不能成功的提示了。顯然,相對於標准訪問權限設置上的籠統,特別訪問權限則可以實現更具體、全面、精確的權限設置。

  為了大家更好地理解特殊權限列表中的權限含義,以便做出更精確的權限設置,下面簡單解釋一下其含義:

   ⑴遍歷文件夾/ 運行文件 (Traverse Folder/Execute File) :該權限允許用戶在文件夾及其子文件夾之間移動 ( 遍歷 ) ,即使這些文件夾本身沒有訪問權限。注意:只有當在“組策略”中 ( “計算機配置”→ “ Windows 設置”→“安全設置”→“本地策略”→“用戶權利指派” ) 將“跳過遍歷檢查”項授予了特定的用戶或用戶組,該項權限才能起作用。默認狀態 下,包括“ Administrators ”、“ Users ”、“ Everyone ”等在內的組都可以使用該權限。對於文件來說,擁了這項權限后,用戶可以 執行該程序文件。但是,如果僅為文件夾設置了這項權限的話,並不會讓用戶對其中的文件帶上“執行”的權限;

  ⑵列出文件/ 讀取數據 (List Folder/Read Data) :該權限允許用戶查看文件夾中的文件名稱、子文件夾名稱和查看文件中的數據;

  ⑶讀取屬性(Read Attributes) :該權限允許用戶查看文件或文件夾的屬性 ( 如系統、只讀、隱藏等屬性 ) ;

  ⑷讀取擴展屬性(Read Extended Attributes) :該權限允許查看文件或文件夾的擴展屬性,這些擴展屬性通常由程序所定義,並可以被程序修改;

  ⑸創建文件/ 寫入屬性 (Create Files/Write Data) :該權限允許用戶在文件夾中創建新文件,也允許將數據寫入現有文件並覆蓋現有文件中的數據;

  ⑹創建文件夾/ 附加數據 (Create Folder/Append Data) :該權限允許用戶在文件夾中創建新文件夾或允許用戶在現有文件的末尾添加數據,但不能對文件現有的數據進行覆蓋、修改,也不能刪除數據;

  ⑺寫入屬性(Write Attributes) :該權限允許用戶改變文件或文件夾的屬性;

  ⑻寫入擴展屬性(Write Extended Attributes) :該權限允許用戶對文件或文件夾的擴展屬性進行修改;

  ⑼刪除子文件夾及文件(Delete Subfolders and Files) :該權限允許用戶刪除文件夾中的子文件夾或文件,即使在這些子文件夾和文件上沒有設置刪除權限;

  ⑽刪除(Delete) :該權限允許用戶刪除當前文件夾和文件,如果用戶在該文件或文件夾上沒有刪除權限,但是在其父級的文件夾上有刪除子文件及文件夾權限,那么就仍然可以刪除它;

  ⑾讀取權限(Read Permissions) :該權限允許用戶讀取文件或文件夾的權限列表;

  ⑿更改權限(Change Permissions) :該權限允許用戶改變文件或文件夾上的現有權限;

  ⒀取得所有權(Take Ownership) :該權限允許用戶獲取文件或文件夾的所有權,一旦獲取了所有權,用戶就可以對文件或文件夾進行全權控制。

   這里需要單獨說明一下“修改”權限與“寫入”權限的區別:如果僅僅對一個文件擁有修改權限,那么,不僅可以對該文件數據進行寫入和附加,而且還可以創建 新文件或刪除現有文件。而如果僅僅對一個文件擁有寫入權限,那么既可以對文件數據進行寫入和附加,也可以創建新文件,但是不能刪除文件。也就是說,有寫入 權限不等於具有刪除權限,但擁有修改權限,就等同於擁有刪除和寫入權限。

  2. 共享權限 (Shared Permission)

   只要是共享出來的文件夾就一定具有此權限。如該文件夾存在於NTFS 分區中,那么它將同時具有 NTFS 權限與共享權限,如果這個資源同時擁有NTFS 和 共享兩種權限,那么系統中對權限的具體實施將以兩種權限中的“較嚴格的權限”為准──這也是“拒絕優於允許”原則的一種體現!

  例如,某個共享資源的NTFS 權限設置為完全控制,而共享權限設置為讀取,那么遠程用戶就只能使用“讀取”權限對共享資源進行訪問了。

   注意:如果是FAT16/FAT32 文件系統中的共享文件夾,那么將只能受到共享權限的保護,這樣一來就容易產生安全性漏洞。這是因為共享權限只能夠限 制從網絡上訪問資源的用戶,並無法限制直接登錄本機的人,即用戶只要能夠登錄本機,就可以任意修改、刪除 FAT16/FAT32 分區中的數據了。因此,從 安全角度來看,我們是不推薦在 Windows XP 中使用 FAT16/FAT32 分區的。

  設置共享權限很簡單,在 右鍵選中並點擊一個文件夾后,在右鍵快捷菜單中選擇“共享與安全”項,在彈出的屬性對話框“共享”選項卡設置界面中點擊選中“共享該文件夾”項即可,這將 使共享資源使用默認的權限設置( 即“ Everyone ”用戶擁有讀取權限 ) 。如果想具體設置共享權限,那么請點擊“權限”按鈕,在打開的對話框中可以看到 權限列表中有“完全控制”、“更改”和“讀取”三項權限可供選擇。

  下面先簡單介紹一下這三個權限的含義:

  ①完全控制:允許用戶創建、讀取、寫入、重命名、刪除當前文件夾中的文件以及子文件夾,另外,也可以修改該文件夾中的NTFS 訪問權限和奪取所有權;

  ②更改:允許用戶讀取、寫入、重命名和刪除當前文件夾中的文件和子文件夾,但不能創建新文件;

  ③讀取:允許用戶讀取當前文件夾的文件和子文件夾,但是不能進行寫入或刪除操作。

  說完了權限的含義,我們就可以點擊“添加”按鈕,將需要設置權限的用戶或用戶組添加進來了。在缺省情況下,當添加新的組或用戶時,該組或用戶將具備“讀取”(Read) 權限,我們可以根據實際情況在下方的權限列表中進行復選框的選擇與清空。

   接着再來說說令很多讀者感到奇怪的“組和用戶名稱”列表中的“Everyone ”組的含義。在 Windows 2000 中,這個組因為包含了“Anonymous Logon ”組,所以它表示“每個人”的意思。但在 Windows XP 中,請注意──這個組因為只包括“ Authenticated Users ”和“ Guests ”兩個組,而不再包括“ Anonymous Logon ”組,所以它表示了“可訪問計算機的所有用戶”,而不再是“每個人”!請注意這是有區別的,“可訪問計算機的所有用戶”意味着必須是通過認證的 用戶,而“每個人”則不必考慮用戶是否通過了認證。從安全方面來看,這一點是直接導致安全隱患是否存在關鍵所在!

   當然,如果想在Windows XP 中實現 Windows 2000 中那種“ Everyone ”設計機制,那么可以通過編輯“本地安全策略”來實現,方法是:在“運行”欄中輸入“ Secpol.msc ”命令打開 “安全設置”管理單元,依次展開“安全設置”→“本地策略”,然后進入“安全選項”,雙擊右側的“網絡訪問:讓‘每個人’權限應用於匿名用戶”項,然后選 擇“已啟用”項既可。

  注意:在Windows XP Professional 中,最多可以同時有 10 個用戶通過網絡登錄 ( 指使用認證賬戶登錄的用戶,對於訪問由 IIS 提供的 Web 服務的用戶沒有限制 ) 方式使用某一台計算機提供的共享資源。

  3. 資源復制或移動時權限的變化與處理

  在權限的應用中,不可避免地會遇到設置了權限后的資源需要復制或移動的情況,那么這個時候資源相應的權限會發生怎樣的變化呢?下面來了解一下:

  (1) 復制資源時

  在復制資源時,原資源的權限不會發生變化,而新生成的資源,將繼承其目標位置父級資源的權限。

  (2) 移動資源時

   在移動資源時,一般會遇到兩種情況,一是如果資源的移動發生在同一驅動器內,那么對象保留本身原有的權限不變( 包括資源本身權限及原先從父級資源中繼承 的權限 ) ;二是如果資源的移動發生在不同的驅動器之間,那么不僅對象本身的權限會丟失,而且原先從父級資源中繼承的權限也會被從目標位置的父級資源繼承的 權限所替代。實際上,移動操作就是首先進行資源的復制,然后從原有位置刪除資源的操作。

  (3) 非 NTFS 分區

  上述復制或移動資源時產生的權限變化只是針對NTFS 分區上而言的,如果將資源復制或移動到非 NTFS 分區 ( 如 FAT16/FAT32 分區 ) 上,那么所有的權限均會自動全部丟失。

  4. 資源所有權的高級管理

   有時我們會發現當前登錄的用戶無法對某個資源進行任何操作,這是什么原因呢?其實這種常見的現象很有可能是因為對某個資源進行的NTFS 權限設置得不夠 完善導致的──這將會造成所有人 ( 包括“ Administrator ”組成員 ) 都無法訪問資源,例如不小心將“ zhiguo ”這個文件夾的所有用戶都刪除 了,這將會導致所有用戶都無法訪問這個文件夾,此時很多朋友就會束手無策了,其實通過使用更改所有權的方法就可以很輕松地解決這類權限問題了。

   首先,我們需要檢查一下資源的所有者是誰,如果想查看某個資源( 如 sony 目錄 ) 的用戶所有權的話,那么只需使用“ dir sony /q ”命令就可以了。在反饋信息的第一行就可以看到用戶是誰了,例如第一行的信息是“ lovebook/zhong ”,那么意思就是 lovebook 這台 計算機中的“ zhong ”用戶。

  如果想在圖形界面中查看所有者是誰,那么需要進入資源的屬性對話框,點擊“安全”選項卡設置界面中的“高級”按鈕,在彈出的“( 用戶名 ) 高級安全設置”界面中點擊“所有者”選項卡,從其中的“目前該項目的所有者”列表中就可以看到當前資源的所有者是誰了。

  如果想將所有者更改用戶,那么只需在“將所有者更改為”列表中選擇目標用戶名后,點擊“確定”按鈕即可。此外,也可以直接在“安全”選項卡設置界面中點擊“添加”按鈕添加一個用戶並賦予相應的權限后,讓這個用戶來獲得當前文件夾的所有權。

  注意:查看所有者究竟對資源擁有什么樣的權限,可點擊進入“有效權限”選項卡設置界面,從中點擊“選擇”按鈕添加當前資源的所有者后,就可以從下方的列表中權限選項的勾取狀態來獲知了。

  五、程序使用權限設定

  Windows XP 操作系統在文件管理方面功能設計上頗為多樣、周全和智能化。這里通過“程序文件使用權限”設置、將“加密文件授權多個用戶可以訪問”和了解系統日志的訪問權限三個例子給大家解釋一下如何進行日常應用。

  1. 程序文件權限設定

  要了解Windows XP 中關於程序文件的訪問權限,我們應首先來了解一下 Windows XP 在這方面的兩個設計,一是組策略中 軟件  限制策略的設計;二是臨時分配程序文件使用權限的設計。

  (1) 軟件限制策略

   在“運行”欄中輸入“Gpedit.msc ”命令打開組策略窗口后,在“計算機配置”→“ Windows 設置”→“安全設置”分支中,右鍵選中“軟件限 制策略”分支,在彈出的快捷菜單中選擇新建一個策略后,就可以從“軟件限制策略”分支下新出現的“安全級別”中看到有兩種安全級別的存在了。

  這兩條安全級別對於程序文件與用戶權限之前是有密切聯系的:

  ①不允許的:從其解釋中可以看出,無論用戶的訪問權如何,軟件都不會運行;

   ②不受限的:這是默認的安全級別,其解釋為“軟件訪問權由用戶的訪問權來決定”。顯然,之所以在系統中可以設置各種權限,是因為有這個默認安全策略在背 后默默支持的緣故。如果想把“不允許的" 安全級別設置為默認狀態,只需雙擊進入其屬性界面后點擊“設為默認值”按鈕即可。

  (2) 臨時分配程序文件

   為什么要臨時分配程序文件的管理權限呢?這是因為在Windows XP 中,有許多很重要的程序都是要求用戶具有一定的管理權限才能使用的,因此在使用權限不足以使用某些程序的賬戶時,為了能夠使用程序,我們就需要為自己 臨時分配一個訪問程序的管理權限了。為程序分配臨時管理權限的方法很簡單:右鍵點擊要運行的程序圖標,在彈出的快捷菜單中選擇“運行方式”,在打開的“運 行身份”對話框中選中“下列用戶”選項,在“用戶名”和“密碼”右側的文本框中指定用戶及密碼即可。

  顯然,這個臨時切換程序文件管理權限的設計是十分有必要的,它可以很好地起到保護系統的目的。

  2. 授權多個用戶訪問加密文件

  Windows XP 在 EFS 上的改進之一就是可以允許多個用戶訪問加密文件,這些用戶既可以是本地用戶,也可以是域用戶或受信任域的用戶。由於無法將證書頒發給用戶組,而只能頒發給用戶,所以只能授權單個的賬戶訪問加密文件,而用戶組將不能被授權。

  要授權加密文件可以被多個用戶訪問,可以按照如下方法進行操作:

   選中已經加密的文件,用鼠標右鍵點擊該加密文件,選擇“屬性”,在打開的屬性對話框中“常規”選項卡下點擊“高級”按鈕,打開加密文件的高級屬性對話 框,點擊其中的“詳細信息”按鈕( 加密文件夾此按鈕無效 ) ,在打開的對話框中點擊“添加”按鈕添加一個或多個新用戶即可 ( 如果計算機加入了域,則還可以點 擊“尋找用戶”按鈕在整個域范圍內尋找用戶 ) 。

  3. 日志的訪問權限

   什么是日志?我們可以將日志理解為系統日記,這本“日記”可以按系統管理員預先的設定,自動將系統中發生的所有事件都一一記錄在案,供管理員查詢。既然 日志信息具有如此重要的參考作用,那么就應該做好未經授權的用戶修改或查看的權限控制。因此,我們非常有必要去了解一下日志的訪問權限在Windows XP 中是怎樣設計的。一般來說, Administrators 、 SYSTEM 、 Everyone 三種類型的賬戶可以訪問日志。

  這三種類型的賬戶對不同類型的日志擁有不同的訪問權限,下面來看一下表格中具體的說明,請注意“√”表示擁有此權限;“×”表示無此權限。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

對應用程序日志的權限

 

賬戶

 

讀取

 

寫入

 

清除

 

Administrators

 

 

 

 

 

SYSTEM

 

 

 

 

 

Everyone

 

 

 

×

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

對安全日志的權限

 

賬戶

 

讀取

 

寫入

 

清除

 

Administrators

 

 

×

 

 

 

SYSTEM

 

 

 

 

 

Everyone

 

×

 

×

 

×

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

對系統日志的權限

 

賬戶

 

讀取

 

寫入

 

清除

 

Administrators

 

 

 

 

 

SYSTEM

 

 

 

 

 

Everyone

 

 

×

 

×

  通過對比,可以看出SYSTEM擁有的權限最高,可以對任意類型的日志進行讀寫和清除操作;Everyone用戶則可以讀取應用程序和系統日 志,但對安全日志無法讀取。這是因為安全日志相對其他幾種類型的日志在安全性方面的要求要高一些,只有SYSTEM能夠對之寫入。

  如果想為其他用戶賦予管理審核安全日志的權限,那么可以在“運行”欄中輸入“Gpedit.msc”命令打開組策略編輯器窗口后,依次進入“計 算機配置”→“Windows設置”→“安全設置”→“本地策略”→“用戶權利指派”,雙擊右側的“管理審核和安全日志”項,在彈出的對話框中添加所需的 用戶即可。

  六、內置安全主體與權限

  在Windows XP中,有一群不為人知的用戶,它們的作用是可以讓我們指派權限到某種“狀態”的用戶(如“匿名用戶”、“網絡用戶”)等,而不是某個特定的用戶或組(如 “zhong”、“CPCW”這類用戶)。這樣一來,對用戶權限的管理就更加容易精確控制了。這群用戶在Windows XP中,統一稱為內置安全主體。下面讓我們來了解一下:

  1.安全主體的藏身之處

  下面假設需要為一個名為“zhiguo”的目錄設置內置安全主體中的“Network”類用戶權限為例,看看這群“默默無聞”的用戶藏身在系統何處。

  首先進入“zhiguo”目錄屬性界面的“安全”選項卡設置界面,點擊其中的“添加”按鈕,在彈出的“選擇用戶或組”對話框中點擊“對象類型”按鈕。在彈出對話框中只保留列表中的“內置安全主體”項,並點擊“確定”按鈕。

  在接下來的對話框中點擊“高級”按鈕,然后在展開的對話框中點擊“立即查找”按鈕,就可以看到內置安全主體中包含的用戶列表了。

 

  2.安全主體作用說明

  雖然內置安全主體有很多,但正常能在權限設置中使用到的並不多,所以下面僅說明其中幾個較重要的:

  ①Anonymous Logon:任何沒有經過Windows XP驗證程序(Authentication),而以匿名方式登錄域的用戶均屬於此組;

  ②Authenticated Users:與前項相反,所有經過Windows XP驗證程序登錄的用戶均屬於此組。設置權限和用戶權力時,可考慮用此項代替Everyone組;

  ③BATCH:這個組包含任何訪問這台計算機的批處理程序(Batch Process);

  ④DIALUP:任何通過撥號網絡登錄的用戶;

  ⑤Everyone:指所有經驗證登錄的用戶及來賓(Guest);

  ⑥Network:任何通過網絡登錄的用戶;

  ⑦Interactive:指任何直接登錄本機的用戶;

  ⑧Terminal server user:指任何通過終端服務登錄的用戶。

  ……

  在明白了內置安全主體的作用后,在進行權限的具體指派時就可以讓權限的應用精確程度更高、權限的應用效果更加高效。顯然,Windows XP中設置此類賬戶是十分有必要的,畢竟計算機是以應用為主,以應用類型進行賬戶分類,必然會使權限的管理不再混亂,管理更加合理!

 

Windows XP權限整合應用全解(二)

接着再來說說令很多讀者感到奇怪的" 組和用戶名稱" 列表中的"Everyone" 組的含義。在Windows 2000 中,這個組因為包含了"Anonymous Logon" 組,所以它表示" 每個人" 的意思。但在Windows XP 中,請注意── 這個組因為只包括"Authenticated Users" 和"Guests" 兩個組,而不再包括"Anonymous Logon" 組,所以它表示了" 可訪問計算機的所有用戶" ,而不再是" 每個人" !請注意這是有區別的," 可訪問計算機的所有用戶" 意味着必須是通過認證的用戶,而" 每個人" 則不必考慮用戶是否通過了認證。從安全方面來看,這一點是直接導致安全隱患是否存在關鍵所在! 

    當然,如果想在Windows XP 中實現Windows 2000 中那種"Everyone" 設計機制,那么可以通過編輯" 本地安全策略" 來實現,方法是:在" 運行" 欄中輸入"Secpol.msc" 命令打開" 安全設置" 管理單元,依次展開" 安全設置"→" 本地策略" ,然后進入" 安全選項" ,雙擊右側的" 網絡訪問:讓‘ 每個人’ 權限應用於匿名 
用戶" 項,然后選擇" 已啟用" 項即可。 

    注意:在Windows XP Professional 中,最多可以同時有10 個用戶通過網絡登錄( 指使用認證賬戶登錄的用戶,對於訪問由IIS 提供的Web 服務的用戶沒有限制) 方式使用某一台計算機提供的共享資源。 

3. 資源復制或移動時權限的變化與處理 

    在權限的應用中,不可避免地會遇到設置了權限后的資源需要復制或移動的情況,那么這個時候資源相應的權限會發生怎樣的變化呢?下面來了解一下: 

(1) 復制資源時 

   在復制資源時,原資源的權限不會發生變化,而新生成的資源,將繼承其目標位置父級資源的權限。 

(2) 移動資源時 

    在移動資源時,一般會遇到兩種情況,一是如果資源的移動發生在同一驅動器內,那么對象保留本身原有的權限不變( 包括資源本身權限及原先從父級資源中繼承的權限) ;二是如果資源的移動發生在不同的驅動器之間,那么不僅對象本身的權限會丟失,而且原先從父級資 源中繼承的權限也會被從目標位置的父級資源繼承的權限所替代。實際上,移動操作就是首先進行資源的復制,然后從原有位置刪除資源的操作。 

(3) 非NTFS 分區 

    上述復制或移動資源時產生的權限變化只是針對NTFS 分區上而言的,如果將資源復制或移動到非NTFS 分區( 如FAT16/FAT32 分區) 上,那么所有的權限均會自動全部丟失。 

4. 資源所有權的高級管理 

    有時我們會發現當前登錄的用戶無法對某個資源進行任何操作,這是什么原因呢?其實這種常見的現象很有可能是因為對某個資源進行的NTFS 權限設置得不夠完善導致的── 這將會造成所有人( 包括 "Administrator" 組成員) 都無法訪問資源,例如不小心將"zhiguo" 這個文件夾的所有用戶都刪除了,這將會導致所有用戶都無法訪問這個文件夾,此時很多朋友就會束手無策了,其實通過使用更改所有權的方法就可以很輕松地解決這類權限問題了。 

   首先,我們需要檢查一下資源的所有者是誰,如果想查看某個資源( 如sony 目錄) 的用戶所有權的話,那么只需使用"dir sony /q" 命令就可以了。在反饋信息的第一行就可以看到用戶是誰了,例如第一行的信息是"lovebook/zhong" ,那么意思就是lovebook 這台計算機中的"zhong" 用戶。 
    如果想在圖形界面中查看所有者是誰,那么需要進入資源的屬性對話框,點擊" 安全" 選項卡設置界面中的" 高級" 按鈕,在彈出的"( 用戶名) 高級安全設置" 界面中點擊" 所有者" 選項卡,從其中的" 目前該項目的所有者" 列表中就可以看到當前資源的所有者是誰了。 

    如果想將所有者更改用戶,那么只需在" 將所有者更改為" 列表中選擇目標用戶名后,點擊" 確定" 按鈕即可。此外,也可以直接在" 安全" 選項卡設置界面中點擊" 添加" 按鈕添加一個用戶並賦予相應的權限后,讓這個用戶來獲得當前文件夾的所有權。 

    注意:查看所有者究竟對資源擁有什么樣的權限,可點擊進入" 有效權限" 選項卡設置界面,從中點擊" 選擇" 按鈕添加當前資源的所有者后,就可以從下方的列表中權限選項的勾取狀態來獲知了。 

五、程序使用權限設定 

    Windows XP 操作系統在文件管理方面功能設計上頗為多樣、周全和智能化。這里通過" 程序文件使用權限" 設置、將" 加密文件授權多個用戶可以訪問" 和了解系統日志的訪問權限三個例子給大家解釋一下如何進行日常應用。 

1. 程序文件權限設定 

    要了解Windows XP 中關於程序文件的訪問權限,我們應首先來了解一下Windows XP 在這方面的兩個設計, 
一、是組策略中軟件限制策略的設計; 
二、是臨時分配程序文件使用權限的設計。 

(1) 軟件限制策略 

    在" 運行" 欄中輸入 "Gpedit.msc" 命令打開組策略窗口后,在" 計算機配置"→"Windows 設置"→" 安全設置" 分支中,右鍵選中" 軟件限制策略" 分 
支,在彈出的快捷菜單中選擇新建一個策略后,就可以從" 軟件限制策略" 分支下新出現的" 安全級別" 中看到有兩種安全級別的存在了。 

    這兩條安全級別對於程序文件與用戶權限之前是有密切聯系的: 

① 不允許的:從其解釋中可以看出,無論用戶的訪問權如何,軟件都不會運行; 

② 不受限的:這是默認的安全級別,其解釋為 " 軟件訪問權由用戶的訪問權來決定" 。顯然,之所以在系統中可以設置各種權限,是因為有這個默認安全策略在背后默默支持的緣故。如果想把" 不允許的" 安全級別設置為默認狀態,只需雙擊進入其屬性界面后點擊" 設為默認值" 按鈕即可。 

(2) 臨時分配程序文件 

    為什么要臨時分配程序文件的管理權限呢?這是因為在Windows XP 中,有許多很重要的程序都是要求用戶具有一定的管理權限才能使用的,因此在使用權限不足以使用某些程序的賬戶時,為了能夠使用程序,我們就需要為自己臨時分配一個訪問程序的管理權限了。為程序分配臨時管理權限的方法很簡單:右鍵點擊要運行的程序圖標, 在彈出的快捷菜單中選擇" 運行方式" ,在打開的" 運行身份" 對話框中選中" 下列用戶" 選項,在" 用戶名" 和" 密碼" 右側的文本框中指定用戶及密碼即可。 

    顯然,這個臨時切換程序文件管理權限的設計是十分有必要的,它可以很好地起到保護系統的目的。 

2. 授權多個用戶訪問加密文件 

    Windows XP 在EFS 上的改進之一就是可以允許多個用戶訪問加密文件,這些用戶既可以是本地用戶,也可以是域用戶或受信任域的用戶。由於無法將證書頒發給用戶組,而只能頒發給用戶,所以只能授權單個的賬戶訪問加密文件,而用戶組將不能被授權。 

    要授權加密文件可以被多個用戶訪問,可以按照如下方法進行操作: 

    選中已經加密的文件,用鼠標右鍵點擊該加密文件,選擇" 屬性" ,在打開的屬性對話框中" 常規" 選項卡下點擊" 高級" 按鈕,打開加密文件的高級屬性對話框,點擊其中的" 詳細信息" 按鈕( 加密文件夾此按鈕無效) ,在打開的對話框中點擊" 添加" 按鈕添加一個或多個新用戶即可( 如果計算機加入了域,則還可以點擊" 尋找用戶" 按鈕在整個域范圍內尋找用戶) 。 

    如果要刪除某個用戶對加密文件的訪問權限,那么只需選中此用戶后點擊" 刪除" 按鈕即可。 

3. 日志的訪問權限 

    什么是日志?我們可以將日志理解為系統日記,這本" 日記" 可以按系統管理員預先的設定,自動將系統中發生的所有事件都一一記錄在案,供管理員查詢。既然日志信息具有如此重要的參考作用,那么就應該做好未經授權的用戶修改或查看的權限控制。因此,我們非常有必要去了解一下日志的訪問權限在Windows XP 中是怎樣設計的。一般來說,Administrators 、SYSTEM 、Everyone 三種類型的賬戶可以訪問日志。 

    這三種類型的賬戶對不同類型的日志擁有不同的訪問權限,下面來看一下表格中具體的說明,請注意"√" 表示擁有此權限;"×" 表示無此權限。 

    通過對比,可以看出SYSTEM 擁有的權限最高,可以對任意類型的日志進行讀寫和清除操作;Everyone 用戶則可以讀取應用程序和系統日志,但對安全日志無法讀取。這是因為安全日志相對其他幾種類型的日志在安全性方面的要求要高一些,只有SYSTEM 能夠對之寫入。 

    如果想為其他用戶賦予管理審核安全日志的權限,那么可以在" 運行" 欄中輸入"Gpedit.msc" 命令打開組策略編輯器窗口后,依次進入" 計算機配置"→"Windows 設置"→" 安全設置 "→" 本地策略"→" 用戶權利指派" ,雙擊右側的" 管理審核和安全日志" 項,在彈出的對話框中添加所需的用戶即可。 

六、內置安全主體與權限 

    在Windows XP 中,有一群不為人知的用戶,它們的作用是可以讓我們指派權限到某種" 狀態" 的用戶( 如" 匿名用戶" 、" 網絡用戶") 等,而不是某個特定的用戶或組( 如 "zhong" 、"CPCW" 這類用戶) 。這樣一來,對用戶權限的管理就更加容易精確控制了。這群用戶在Windows XP 中,統一稱 

    為內置安全主體。下面讓我們來了解一下 
1. 安全主體的藏身之處 
    下面假設需要為一個名為"zhiguo" 的目錄設置內置安全主體中的"Network" 類用戶權限為例,看看這群" 默默無聞" 的用戶藏身在系統何處。 
    首先進入"zhiguo" 目錄屬性界面的" 安全" 選項卡設置界面,點擊其中的" 添加" 按鈕,在彈出的" 選擇用戶或組" 對話框中點擊" 對象類型" 按鈕。 
    在彈出對話框中只保留列表中的" 內置安全主體" 項,並點擊" 確定" 按鈕。 
    在接下來的對話框中點擊" 高級" 按鈕,然后在展開的對話框中點擊" 立即查找" 按鈕,就可以看到內置安全主體中包含的用戶列表了。 
2. 安全主體作用說明 
    雖然內置安全主體有很多,但正常能在權限設置中使用到的並不多,所以下面僅說明其中幾個較重要的: 
①Anonymous Logon :任何沒有經過Windows XP 驗證程序(Authentication) ,而以匿名方式登錄域的用戶均屬於此組; 
②Authenticated Users :與前項相反,所有經過Windows XP 驗證程序登錄的用戶均屬於此組。設置權限和用戶權力時,可考慮用此項代替 
Everyone 組; 
③BATCH :這個組包含任何訪問這台計算機的批處理程序(Batch Process) ; 
④DIALUP :任何通過撥號網絡登錄的用戶; 
⑤Everyone :指所有經驗證登錄的用戶及來賓(Guest) ; 
⑥Network :任何通過網絡登錄的用戶; 
⑦Interactive :指任何直接登錄本機的用戶; 
⑧Terminal server user :指任何通過終端服務登錄的用戶。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM