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

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

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

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

 

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

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


1、理論和術語安全

 

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

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

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

一個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 規則,以下面的條件知足,則退出:

一、 若是一個 Access-Denied 的 ACE 明顯地拒絕了請求者。

二、 若是某 Access-Allowed 的 ACE 明顯地贊成了請求者。

三、 所有的 ACE 都檢查完了,可是沒有一條 ACE 明顯地容許或是拒絕請求者,那麼系統將使用默認值,拒絕請求者的訪問。

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

 

2、實踐與例程

 

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

 

#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 的用法,其有四個地方的不足和不清:

 

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

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

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

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

 

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

 

二、  例程2、爲目錄增長一個安全設置項

 

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

 

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

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

三、  對於給文件的 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;

  }

}

 

3、 一些相關的API 函數

 

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

一、 若是你要加入一個 Access-Denied  的 ACE ,你可使用 AddAccessDeniedAce 函數

二、 若是你要刪除一個 ACE ,你可使用 DeleteAce 函數

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

 

Windows XP權限整合應用全解

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

  所以本文以Windows XP Professional 版本爲平臺,引領你們感覺一下 Windows XP 在「權限」方面的設計魅力!

  1、什麼是權限

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

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

  利用權限能夠控制資源被訪問的方式,如User 組的成員對某個資源擁有「讀取」操做權限、 Administrators 組成員擁有「讀取 + 寫入 + 刪除」操做權限等。

   值得一提的是,有一些Windows 用戶每每會將「權力」與「權限」兩個很是類似的概念搞混淆,這裏作一下簡單解釋:「權力」 (Right) 主要是針對 用戶而言的。「權力」一般包含「登陸權力」 (Logon Right) 和「特權」 (Privilege) 兩種。登陸權力決定了用戶如何登陸到計算機,如是否採用本地交互式登陸、是否爲網絡登陸等。特權則是一系列 權力的總稱,這些權力主要用於幫助用戶對系統進行管理,如是否容許用戶安裝或加載驅動程序等。顯然,權力與權限有本質上的區別。

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

   說到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 管理;域的帳戶則會被活動目錄進行管理……

  通常來講,權限的指派過程實際上就是爲某個資源指定安全主體( 即用戶、用戶組等 ) 能夠擁有怎樣的操做過程。由於用戶組包括多個用戶,因此大多數狀況下,爲資源指派權限時建議使用用戶組來完成,這樣能夠很是方便地完成統一管理。

  3、權限的四項基本原則

  在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 」組的所有成員將能夠經過「奪取全部權」等方法得到這個權限。

  4、資源權限高級應用

  以文件與文件夾的權限爲例,依據是否被共享到網絡上,其權限能夠分爲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 」用戶。

  若是想在圖形界面中查看全部者是誰,那麼須要進入資源的屬性對話框,點擊「安全」選項卡設置界面中的「高級」按鈕,在彈出的「( 用戶名 ) 高級安全設置」界面中點擊「全部者」選項卡,從其中的「目前該項目的全部者」列表中就能夠看到當前資源的全部者是誰了。

  若是想將全部者更改用戶,那麼只需在「將全部者更改成」列表中選擇目標用戶名後,點擊「肯定」按鈕便可。此外,也能夠直接在「安全」選項卡設置界面中點擊「添加」按鈕添加一個用戶並賦予相應的權限後,讓這個用戶來得到當前文件夾的全部權。

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

  5、程序使用權限設定

  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設置」→「安全設置」→「本地策略」→「用戶權利指派」,雙擊右側的「管理審覈和安全日誌」項,在彈出的對話框中添加所需的 用戶便可。

  6、內置安全主體與權限

  在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" 用戶。     若是想在圖形界面中查看全部者是誰,那麼須要進入資源的屬性對話框,點擊" 安全" 選項卡設置界面中的" 高級" 按鈕,在彈出的"( 用戶名) 高級安全設置" 界面中點擊" 全部者" 選項卡,從其中的" 目前該項目的全部者" 列表中就能夠看到當前資源的全部者是誰了。     若是想將全部者更改用戶,那麼只需在" 將全部者更改成" 列表中選擇目標用戶名後,點擊" 肯定" 按鈕便可。此外,也能夠直接在" 安全" 選項卡設置界面中點擊" 添加" 按鈕添加一個用戶並賦予相應的權限後,讓這個用戶來得到當前文件夾的全部權。     注意:查看全部者究竟對資源擁有什麼樣的權限,可點擊進入" 有效權限" 選項卡設置界面,從中點擊" 選擇" 按鈕添加當前資源的全部者後,就能夠從下方的列表中權限選項的勾取狀態來獲知了。 5、程序使用權限設定     Windows XP 操做系統在文件管理方面功能設計上頗爲多樣、周全和智能化。這裏經過" 程序文件使用權限" 設置、將" 加密文件受權多個用戶能夠訪問" 和了解系統日誌的訪問權限三個例子給你們解釋一下如何進行平常應用。 1. 程序文件權限設定     要了解Windows XP 中關於程序文件的訪問權限,咱們應首先來了解一下Windows XP 在這方面的兩個設計, 1、是組策略中軟件限制策略的設計; 2、是臨時分配程序文件使用權限的設計。 (1) 軟件限制策略     在" 運行" 欄中輸入 "Gpedit.msc" 命令打開組策略窗口後,在" 計算機配置"→"Windows 設置"→" 安全設置" 分支中,右鍵選中" 軟件限制策略" 分 支,在彈出的快捷菜單中選擇新建一個策略後,就能夠從" 軟件限制策略" 分支下新出現的" 安全級別" 中看到有兩種安全級別的存在了。     這兩條安全級別對於程序文件與用戶權限以前是有密切聯繫的: ① 不容許的:從其解釋中能夠看出,不管用戶的訪問權如何,軟件都不會運行; ② 不受限的:這是默認的安全級別,其解釋爲 " 軟件訪問權由用戶的訪問權來決定" 。顯然,之因此在系統中能夠設置各類權限,是由於有這個默認安全策略在背後默默支持的緣故。若是想把" 不容許的" 安全級別設置爲默認狀態,只需雙擊進入其屬性界面後點擊" 設爲默認值" 按鈕便可。 (2) 臨時分配程序文件     爲何要臨時分配程序文件的管理權限呢?這是由於在Windows XP 中,有許多很重要的程序都是要求用戶具備必定的管理權限才能使用的,所以在使用權限不足以使用某些程序的帳戶時,爲了可以使用程序,咱們就須要爲本身臨時分配一個訪問程序的管理權限了。爲程序分配臨時管理權限的方法很簡單:右鍵點擊要運行的程序圖標, 在彈出的快捷菜單中選擇" 運行方式" ,在打開的" 運行身份" 對話框中選中" 下列用戶" 選項,在" 用戶名" 和" 密碼" 右側的文本框中指定用戶及密碼便可。     顯然,這個臨時切換程序文件管理權限的設計是十分有必要的,它能夠很好地起到保護系統的目的。 2. 受權多個用戶訪問加密文件     Windows XP 在EFS 上的改進之一就是能夠容許多個用戶訪問加密文件,這些用戶既能夠是本地用戶,也能夠是域用戶或受信任域的用戶。因爲沒法將證書頒發給用戶組,而只能頒發給用戶,因此只能受權單個的帳戶訪問加密文件,而用戶組將不能被受權。     要受權加密文件能夠被多個用戶訪問,能夠按照以下方法進行操做:     選中已經加密的文件,用鼠標右鍵點擊該加密文件,選擇" 屬性" ,在打開的屬性對話框中" 常規" 選項卡下點擊" 高級" 按鈕,打開加密文件的高級屬性對話框,點擊其中的" 詳細信息" 按鈕( 加密文件夾此按鈕無效) ,在打開的對話框中點擊" 添加" 按鈕添加一個或多個新用戶便可( 若是計算機加入了域,則還能夠點擊" 尋找用戶" 按鈕在整個域範圍內尋找用戶) 。     若是要刪除某個用戶對加密文件的訪問權限,那麼只需選中此用戶後點擊" 刪除" 按鈕便可。 3. 日誌的訪問權限     什麼是日誌?咱們能夠將日誌理解爲系統日記,這本" 日記" 能夠按系統管理員預先的設定,自動將系統中發生的全部事件都一一記錄在案,供管理員查詢。既然日誌信息具備如此重要的參考做用,那麼就應該作好未經受權的用戶修改或查看的權限控制。所以,咱們很是有必要去了解一下日誌的訪問權限在Windows XP 中是怎樣設計的。通常來講,Administrators 、SYSTEM 、Everyone 三種類型的帳戶能夠訪問日誌。     這三種類型的帳戶對不一樣類型的日誌擁有不一樣的訪問權限,下面來看一下表格中具體的說明,請注意"√" 表示擁有此權限;"×" 表示無此權限。     經過對比,能夠看出SYSTEM 擁有的權限最高,能夠對任意類型的日誌進行讀寫和清除操做;Everyone 用戶則能夠讀取應用程序和系統日誌,但對安全日誌沒法讀取。這是由於安全日誌相對其餘幾種類型的日誌在安全性方面的要求要高一些,只有SYSTEM 可以對之寫入。     若是想爲其餘用戶賦予管理審覈安全日誌的權限,那麼能夠在" 運行" 欄中輸入"Gpedit.msc" 命令打開組策略編輯器窗口後,依次進入" 計算機配置"→"Windows 設置"→" 安全設置 "→" 本地策略"→" 用戶權利指派" ,雙擊右側的" 管理審覈和安全日誌" 項,在彈出的對話框中添加所需的用戶便可。 6、內置安全主體與權限     在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 :指任何經過終端服務登陸的用戶。

相關文章
相關標籤/搜索