I recently read the Windows Access Control Model on msdn. Access control is"Use appropriate resources right persons use right resources."
So,
Step 1: Verify the Operating SystemAuthenticationTo verify whether the user identity is declared by the user. Verification passed. Later,
Step 2: Authorize the Operating SystemAuthorization,User A wants to read a file and the operating system checks the file's security descriptor;
If "user a" is stored in the "List of users with read permission", the operating system continues to read files;
This process is "Authorization" authorization;
This article focuses on authorization (Authorization), Authorization mainly looks at Access Control (Access Control Model);
1) User Token
After a user logs on, the operating system gives the user an access token, which mainly stores the user's permission privileges, such as shutdown, debugging, and backup system.
When a user creates a process, the process copies the user's token to the process information. The process creation thread (including the main thread) automatically obtains the token. In addition, the thread can "impersonate" a customer identity, impersonate, And the thread gets the token' of other users (login, or passing in parameters ), this means that this user can access resources that only this user can access.
The token also stores the Security Identifier of the user.
======================================
User Token information printing
======================================
Void dumptokeninfo (void) {handle htoken = NULL; If (! Openprocesstoken (getcurrentprocess (), token_query, & htoken) return; DWORD retlen = 0; gettokeninformation (htoken, tokengroupsandprivileges, null, 0, & retlen ); optional * ptgap = (token_groups_and_privileges *) localalloc (0, retlen); gettokeninformation (htoken, tokengroupsandprivileges, ptgap, retlen, & retlen ); // query the SID array information printf ("\ n ================== SIDS ========== =========\ N "); For (DWORD I = 0; I <ptgap-> sidcount; ++ I) {psid = ptgap-> SIDS [I]. sid; sid_name_use sidtype; char szname [max_path] = ""; DWORD dwnamelen = max_path; char szdomain [max_path] = ""; DWORD dwdomainlen = max_path; lookupaccountsida (null, psid, szname, & dwnamelen, szdomain, & dwdomainlen, & sidtype); printf ("SIDS [% d] = % s @ % s \ n", I, szname, szdomain );} // query the permission information printf ("\ n =================== priv Eleges ===================================\ N "); For (DWORD I = 0; I <ptgap-> privilegecount; ++ I) {char szname [max_path] = ""; DWORD dwnamelen = max_path; lookupprivilegenamea (null, & ptgap-> privileges [I]. luid, szname, & dwnamelen); printf ("privileges [% d] = % s \ n", I, szname );}} /*************************************** ********************************* 0: 001>! Token <windbg printed token information> ///////////////////////// //////////////////////////////////////// //// // thread is not impersonating. using process token... TS Session ID: 0 User: S-1-5-21-2233661284-422353248-3399546490-500Groups: 00 S-1-5-21-2233661284-422353248-3399546490-513Attributes-mandatory default enabled 01 S-1-1-0Attributes-mandatory default enabled 02 S-1-5-32-544Attributes-mandatory default enabled owner 03 S-1-5-32-545Attributes-mandatory default enabled 04 S-1-5-4Attributes-mandatory default enabled 05 S-1-5-11Attributes-mandatory default enabled 06 S-1-5-15Attributes- mandatory default enabled 07 S-1-5-5-0-48147Attributes-mandatory default enabled logonid 08 S-1-2-0Attributes-mandatory default enabled 09 S-1-5-64-10Attributes-mandatory default enabled primary group: s-1-5-21-2233661284-422353248-3399546490-513Privs: 00 0x000000017 bytes attributes-enabled default 01 0x000000008 sesecurityprivilege attributes-enabled 02 0x000000011 bytes attributes-03 0x000000012 bytes attributes-04 0x00000000c sesystemtimeprivilege attributes-enabled 05 0x000000013 seshutdownprivilege attributes-enabled 06 0x000000018 bytes attributes-enabled 07 0x000000009 bytes attributes-enabled 08 0x000000014 bytes attributes-enabled 09 0x000000016 bytes attributes-enabled 10 0x0000b percent attributes-enabled 11 0x00000000d your attributes-enabled 12 0x00000000e your attributes-enabled 13 0x000000000000a your attributes-enabled 14 0x0000f your attributes-enabled 15 0x000000005 your attributes-enabled 16 0x000000019 attributes-envilege attributes-enabled 18 0x00000001d seimpersonateprivilege butes-enabled default 19 0x00000001e secreateglobalprivilege attributes-enabled default auth ID: 0: c32fimpersonation level: anonymoustokentype: primaryis restricted token: No. **************************************** ********************************/
======================================
Imitating customers' access to special permission files
======================================
# Include <sys/STAT. h> # include <fcntl. h> # include <Io. h> int main (INT argc, char * argv []) {char szcmd [0x20]; printf ("impersonateloggedonuser? [Y/n]> "); gets (szcmd); // imitates the user if (! _ Strnicmp (szcmd, "Y", 1) {handle htoken = invalid_handle_value; If (! Logonusera ("Test2 ",". "," Test2 ", logon32_logon_interactive, logon32_provider_default, & htoken) {printf (" fail to logonusera, error % d \ n ", getlasterror (); Return-1 ;} if (! Impersonateloggedonuser (htoken) {printf ("fail to impersonateloggedonuser, error % d \ n", getlasterror (); Return-1 ;}} // It is actually the information in the folder where the access file is located, struct _ stat _ st; If (_ Stat ("F: \ test.txt", & _ st) Return-1; printf ("fsize = % d \ n", _ St. st_size); // The truly accessed file int FD = open ("F: \ test.txt", o_rdonly); If (FD> 0) {printf ("Open File OK. \ n "); close (FD);} else {printf (" Open failed % d. \ n ", getlasterror (); Return-1;} getchar (); Return 0 ;}
2) Security Descriptor
All resource objects in the operating system (processes, threads, files, semaphores ...) There is a security descriptor to describe which users can access this object, and the security descriptor stores two lists,Discretionary Access Control List
(DACL), SACL.
DACL stores the accesskey (Access Control entries). An ace contains the access permission (deny, allow, and audit) related to the SID ).
======================================
Security Descriptor information printing
======================================
# Include "accctrl. H "# include" aclapi. H "# pragma comment (Lib," advapi32.lib ")/* adjust permissions */bool setprivilege (handle htoken, // access token handle lpctstr lpszprivilege, // name of privilege to enable/disable bool benableprivilege // to enable or disable privilege) {token_privileges TP; luid; If (! Upper (null, // lookup privilege on local system lpszprivilege, // privilege to lookup & luid) // es luid of privilege {printf ("lookupprivilegevalue error: % u \ n ", getlasterror (); Return false;} TP. privilegecount = 1; TP. privileges [0]. luid = luid; If (benableprivilege) TP. privileges [0]. attributes = se_privilege_enabled; else TP. privileges [0]. attributes = 0; // enable the P Rivilege or disable all privileges. If (! Adjusttokenprivileges (htoken, false, & TP, sizeof (token_privileges), (ptoken_privileges) null, (pdword) null) {printf ("adjusttokenprivileges error: % u \ n ", getlasterror (); Return false;} If (getlasterror () = error_not_all_assigned) {printf ("the token does not have the specified privilege. \ n "); Return false;} return true;} int main (void) {DWORD dwrtncode = 0; psid psidowner = NULL, psidgroup = NULL; PACl pdacl = NULL, psacl = NULL; bool brtnbool = true; lptstr acctname = NULL; lptstr domainname = NULL; DWORD dwacctname = 1, dwdomainname = 1; sid_name_use euse = sidtypeunknown; handle hfile; psecurity_descriptor PSD = NULL; handle htoken = NULL; If (! Openprocesstoken (getcurrentprocess (), token_query | token_adjust_privileges, & htoken) Return-1; setprivilege (htoken, se_security_name, true); // get the handle of the file object. hfile = createfile (text ("H: \ workspace \ test \ Test2 \ Test2 \ test2.cpp"), generic_read | read_control | access_system_security, file_assist_read, null, open_existing, file_attribute_normal, null); // check getlasterror F Or createfile error code. if (hfile = invalid_handle_value) {DWORD dwerrorcode = 0; dwerrorcode = getlasterror (); _ tprintf (text ("createfile error = % d \ n"), dwerrorcode ); return-1;} // get the owner SID of the file. dwrtncode = getsecurityinfo (hfile, se_file_object, dacl_security_information | sacl_security_information | owner_security_information | group_security_information, & psidowner, & PS Idgroup, & pdacl, & psacl, & PSD); // check getlasterror for getsecurityinfo error condition. If (dwrtncode! = Error_success) {DWORD dwerrorcode = 0; dwerrorcode = getlasterror (); _ tprintf (text ("getsecurityinfo error = % d \ n"), dwerrorcode); Return-1 ;} // first call to lookupaccountsid to get the buffer sizes. brtnbool = lookupaccountsid (null, // local computer psidowner, acctname, (lpdword) & dwacctname, domainname, (lpdword) & dwdomainname, & euse); // reallocate memory for buffers. acctname = (lptstr) Globalalloc (gmem_fixed, dwacctname); // check getlasterror for globalalloc error condition. if (acctname = NULL) {DWORD dwerrorcode = 0; dwerrorcode = getlasterror (); _ tprintf (text ("globalalloc error = % d \ n"), dwerrorcode ); return-1;} domainname = (lptstr) globalalloc (gmem_fixed, dwdomainname); // check getlasterror for globalalloc error condition. if (domainname = NULL) {DWORD dwerrorcode = 0; dwerrorcode = getlasterror (); _ tprintf (text ("globalalloc error = % d \ n"), dwerrorcode); Return-1 ;} // second call to lookupaccountsid to get the account name. brtnbool = lookupaccountsid (null, // name of local or remote computer psidowner, // Security Identifier acctname, // account name buffer (lpdword) & dwacctname, // size of Account Name Buffer domainname, // domain name (lpdword) & dwdoma Inname, // size of domain name buffer & euse); // Sid type // check getlasterror for lookupaccountsid error condition. if (brtnbool = false) {DWORD dwerrorcode = 0; dwerrorcode = getlasterror (); If (dwerrorcode = error_none_mapped) _ tprintf (text ("account owner not found for specified. Sid. \ n "); else _ tprintf (text (" error in lookupaccountsid. \ n "); Return-1;} else if (brtnbool = true) // print The account name. _ tprintf (text ("account owner = % s \ n"), acctname); // print DACL information if (null = pdacl |! Isvalidacl (pdacl) Return-1; acl_size_information ASI; If (! Getaclinformation (pdacl, & ASI, sizeof (ASI), aclsizeinformation) Return-1; for (INT I = 0; I <asi. acecount; ++ I) {void * pace = NULL; getace (pdacl, I, & pace ); printf ("Access Credential entries [% d] is at % P \ n", I, Pace) ;}return 0 ;}
======================================
Create an object with security attributes-File
======================================
Void createkeywithsecdesc (char * filepath) {DWORD dwres, dwdisposition; long lres; // create a well-known Sid sid_identifier_authority sidauthworld = Hangzhou for the Everyone group; psid peveryonesid = NULL; if (! Allocateandinitializesid (& sidauthworld, 1, security_world_rid, 0, 0, 0, 0, 0, 0, 0, & peveryonesid )) {_ tprintf (_ T ("allocateandinitializesid error % u \ n"), getlasterror (); goto cleanup ;} // initialize a "display access" structure for Ace // this ace allows everyone to read this object explicit_access EA [2]; zeromemory (& EA, 2 * sizeof (explicit_access )); EA [0]. grfaccesspermissions = file_generic_read | file_generic_execute; EA [0]. grfaccessmode = set_ac Cess; EA [0]. grfinheritance = no_inheritance; EA [0]. trustee. trusteeform = trustee_is_sid; EA [0]. trustee. trusteetype = trustee_is_well_known_group; EA [0]. trustee. ptstrname = (lptstr) peveryonesid; // create a Sid sid_identifier_authority sidauthnt = security_nt_authority for the Administrator group; psid padminsid = NULL; If (! Allocateandinitializesid (& sidauthnt, 2, security_builtin_domain_rid, domain_alias_rid_admins, 0, 0, 0, 0, 0, 0, & padminsid )) {_ tprintf (_ T ("allocateandinitializesid error % u \ n"), getlasterror (); goto cleanup ;} // initialize a "show access" structure for Ace // this ace allows the Administrator group to fully control the power of this object EA [1]. grfaccesspermissions = file_all_access; EA [1]. grfaccessmode = set_access; EA [1]. grfinheritance = no_inheritance; EA [1]. trustee. trusteefo Rm = trustee_is_sid; EA [1]. trustee. trusteetype = trustee_is_group; EA [1]. trustee. ptstrname = (lptstr) padminsid; // create a new ACL that contains the two ACE/ace machines configured above, therefore, use the "show access" structure // to create the ACL PACl = NULL; dwres = setentriesinacl (2, EA, null, & PACl); If (error_success! = Dwres) {_ tprintf (_ T ("setentriesinacl error % u \ n"), getlasterror (); goto cleanup;} // assign a minimum "Security Descriptor ". psecurity_descriptor PSD = NULL; PSD = (psecurity_descriptor) localalloc (lptr, security_descriptor_min_length); If (null = PSD) {_ tprintf (_ T ("localalloc error % u \ n"), getlasterror (); goto cleanup;} // initialize "Security Descriptor" If (! Initializesecuritydescriptor (PSD, security_descriptor_revision) {_ tprintf (_ T ("initializesecuritydescriptor error % u \ n"), getlasterror (); goto cleanup ;} // Add the ACL to the "Security Descriptor" If (! Setsecuritydescriptordacl (PSD, true, // bdaclpresent flag PACl, false) // not a default DACL {_ tprintf (_ T ("setsecuritydescriptordacl error % u \ n "), getlasterror (); goto cleanup;} // set the security descriptor to security_attributes SA; SA. nlength = sizeof (security_attributes); SA. lpsecuritydescriptor = PSD; SA. binherithandle = false; // use the Security Attribute structure as the parameter, // set the Security Descriptor information to the newly created object. Handle hfile = createfilea (filepath, File_generic_read | file_generic_write | file_generic_execute, file_share_read | file_share_write, & SA, create_always, file_attribute_normal, null); If (hfile! = Invalid_handle_value) {closehandle (hfile);} else _ tprintf (_ T ("createfile result % u \ n"), lres); cleanup: If (peveryonesid) freesid (peveryonesid); If (padminsid) freesid (padminsid); If (PACl) localfree (PACl); If (PSD) localfree (PSD); return ;}
3) authorization process
When a thread accesses a resource, the system first checks the impersionate token of the thread. If not, the system obtains the Sid from the access token of the process and then traverses the DACL's ace, view every ace related to this Sid. If you know that you are looking for a rejected or allowed ace, return.
Http://msdn.microsoft.com/en-us/library/windows/desktop/aa374860 (V = vs.85). aspx