Manipulate NTFS file permissions in a program method (medium)

zhaozj2021-02-08  302

Still study, this program is longer, from MSDN, I have made a little modification, and add your own understanding in the comment, so please note the comments in the code:

#include #include #include // Using Windows's Heapalloc function for dynamic memory assignment #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) {// declare variables SID SID_NAME_USE snuType; // LookupAccountName statements and related variables (note that all 0 To dynamically allocate in the program) TCHAR * szdomain = NULL; DWORD CBDOMAIN = 0; lpvoid puSID = NULL; DWORD CBUSERSID = 0; // and file-related security descriptor SD variables psecurity_descriptor pfilesd = null; // Structural variable DWORD CB Filesd = 0; // SD size // A new SD variable for constructing new ACLs (integrated existing ACLs and new ACLs) SECURITY_DEScriptor newsd; // and ACL-related variable PACL PACL = NULL; BOOL FDACLPRESENT; BOOL FDACLDEFAULTED; ACL_SIZE_INFORMATION ACLITED; // A new ACL variable PACL PNEWAWAWACL = NULL; / / Structural Pointer Variable DWORD CBNEWACL = 0; // ACL Size // A temporary ACE Variable LPVOID PTEMPACE = NULL; uint currentAcEIndex = 0; // ACE Position uint newAceIndex = 0; // The newly added ACE is the return value of the position // API function in the ACL, assumes that all functions return failure.

Bool Fresult; Bool Fapisuccess; security_information secinfo = dacl_security_information; // The following two functions are new API functions, only in Windows 2000 or later operating system support. / / This will be turned from the Advapi32.dll file. If you use the VC 6.0 compiler, and you want to // use the static links of these two functions. Please add: / D_WIN32_WINNT = 0x0500 // compile parameters for your compilation. And make sure your SDK's header file and lib file are the latest. SetSecurityDescriptorControlFnPtr _SetSecurityDescriptorControl = NULL; AddAccessAllowedAceExFnPtr _AddAccessAllowedAceEx = NULL; __try {// // STEP 1: // acquired in this step, the SID LookupAccountName function is called twice, first extraction is required memory // user name Size, then, perform memory allocation. The second call is the account information of the user. // LookupAccountName can also obtain information from domain users or user groups. (Please see MSDN) // FAPISUCCESS = LookupAccountName (Null, Lpszaccountname, Pusersid, & Cbusersid, szdomain, & clomain, "snuType); // The above call API will fail, the cause of failure is insufficient. And pass the required memory size. // The following is an error in processing non-memory.

if (fAPISuccess) __leave; else if (! GetLastError () = ERROR_INSUFFICIENT_BUFFER) {_tprintf (TEXT ( ". LookupAccountName () failed Error% d / n"), GetLastError ()); __leave;} pUserSID = myheapalloc (cbUserSID); If (! puSERSID) {_tprintf ("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 ("LookuPaccountName () Failed. Error% D / N"), getLastError ()); __leave;} // // STEP 2: A File (Directory) Related Security Descriptor SD / / Use the getFileSecurity function to get a copy of a file SD, and the same, this function is also // is called twice, and the first time the memory length is taken to take the SD. Note that SD has two formats: self-correlation // (self-relative) and complete (Absolute), getFileSecurity can only be "self-/ related", while SetFileSecurity needs to be complete. That's why there is a new SD, / / ​​instead of being modified directly on the SD returned by GetFileSecurity. Because "autocorrelation" information // is incomplete. FAPISUCCESS = GetFileSecurity (LPSZFileName, SECINFO, PFILESD, 0, & CBFilesd); // The above call API will fail, the cause of failure is insufficient memory. And pass the required memory size. // The following is an error in processing non-memory.

if (fAPISuccess) __leave; else if (! GetLastError () = ERROR_INSUFFICIENT_BUFFER) {_tprintf (TEXT ( ". GetFileSecurity () failed Error% d / n"), GetLastError ()); __leave;} pFileSD = myheapalloc (cbFileSD); IF (! pfilesd) {_tprintf ("HeapAlloc () failed. Error% D / N"), getLastError ()); __leave;} fapisuccess = getFileSecurity (LpszFileName, SECINFO, PFILESD, CBFILESD, & CBFilesd; if (! FAPISUCCESS) {_tprintf ("getFileSecurity () failed. Error% D / N"), getLastError ()); __leave;} // // Step 3: Initialize a new SD // if (! InitializeSecurityDescriptor (& newsd, Security_descriptor_revision) {_tprintf ("INITIALIZESECURITYDESCRIPTOR () Failed.") TEXT ("Error% D / N"), getLastError ()); __LEAVE;} // // STEP 4: Take DACL from the SD returned from getFileSecurity // if (! GetSecurityDescriptORDACL (pfilesd, & fdaclpresent, & PACL, & fdacldefault) {_tprintf ("GetSecurityDescriptOracl () Failed. Error% D / N"), getLastError ()); __LEAVE;} // // Step 5: Take DACL Memory Size // getAclinformation Provides DACL memory size. Only passing the parameters for Structure // acl_size_information, you need DACL information, just for //, it is convenient for us to traverse the ACE. Aclinfo.Acecount = 0; // AssuMe Null Dacl. Aclinfo.aclbytesfree = 0; aclinfo.aclbytesinuse = sizeof (ACL); if (PACL == Null) fdaclpresent = false; // If DACL is not empty, take information .

(Most cases "self-associated" DACL is empty) IF (fdaclpresent) {if (! GetAclinformation) {_tprintf (text ("getAclinformation () failed. Error% d / N "), getLastError ()); __LEAVE;}} // // Step 6: Calculating the new ACL's size // calculated formula is: the original DACL Size plus the Size of an ACE you need to add, With // and plus a SID-related SID, final minus two bytes to obtain precise size. cbNewACL = AclInfo.AclBytesInUse sizeof (ACCESS_ALLOWED_ACE) GetLengthSid (pUserSID) - sizeof (DWORD); // // STEP 7: allocate memory for the new ACL // pNewACL = (PACL) myheapalloc (cbNewACL); if (pNewACL! ) {_TPrintf ("HeapAlloc () failed. Error% D / N"), getLastError ()); __leave;} // // Step 8: Initialization new ACL structure // if (! InitializeAcl (pnewacl, cbenewacl , Acl_revision2)) {_tprintf ("INITIALIZEACL () Failed. Error% D / N"), getLastError ()); __leave;} (The program is not finished, please see the next article) // // step 9 If the file (directory) DACL has data, copying ACE to new DACL // // The following code hypothesis first checks the specified file (directory) DACL existing, if any, // then copy all ACE to new In the DACL structure, we can see that its traversal is completed by the Acecount member in // acl_size_information structure.

In this cycle, copy according to the order of the default ACE (the order in the ACE is critical in the ACL), in the copy // biscuit, copy the ACE to inherited first (we know the ACE will Inherited in the upper list) // newAcEindex = 0; if (fdaclpresent && aclinfo.cecount) {for (currentAcEIndex = 0; currentAcEIndex Header.aceflags & Inherited_ace) Break; // // step 12: Check if the SID of the ACE you want to copy and the SID of the ACE you want to join, // If Then it should be abolished, that is, the ACE set of the same user's access // authority should be unique in DACL. In this, skip the ACE that has been set to the same user, just copying other users' ACE. // if (Equalsid, & ((Access_allowed_ace *) PTEMPACE -> SidStart)) Continue; // // STEP 13: Add ACE to the new DACL // below the code, pay attention to the addAcE function The third parameter, this parameter means the index value in // ACL, means that after adding ACE to an index position, the parameter MaxDword // means ensuring that the current ACE is added to the last position.

// if (! Addace (PNewaCl, ACL_REVISION, MAXDWORD, PTEMPACE) -> ACESIZE)) {_tprintf (text ("addace () failed. Error% D / N"), getLastError ()); __leave;} newaceindex ;}} <- Previous Next->

(All rights reserved, please indicate the source and author information when reproduced)

转载请注明原文地址:https://www.9cbs.com/read-1127.html

New Post(0)