==============================ModuleK===================================== | | | The program examples' source codes have been arranged in the same | | order that appeared in the Tutorial. This is unedited and unverified | | compilation. Published as is basis for educational, reacretional and | | brain teaser purposes. All trademarks, copyrights and IPs, wherever | | exist, are the sole property of their respective owner and/or | | holder. Any damage or loss by using the materials presented in this | | tutorial is USER responsibility. Part or full distribution, | | reproduction and modification is granted to any body. | | Copyright 2003-2005 © Tenouk, Inc. All rights reserved. | | Distributed through http://www.tenouk.com | | | | | =========================================================================== Compiled using VC++/VC++ .Net.....unmanaged... #include #include BOOL SetPrivilege( HANDLE hToken, // access token handle LPCTSTR lpszPrivilege, // name of privilege to enable/disable BOOL bEnablePrivilege // to enable (or disable privilege) ) { // Token privilege structure TOKEN_PRIVILEGES tp; // Used by local system to identify the privilege LUID luid; if(!LookupPrivilegeValue( NULL, // lookup privilege on local system lpszPrivilege, // privilege to lookup &luid)) // receives LUID of privilege { printf("LookupPrivilegeValue() error: %u\n", GetLastError()); return FALSE; } else printf("LookupPrivilegeValue() is OK\n"); tp.PrivilegeCount = 1; tp.Privileges[0].Luid = luid; // Don't forget to disable the privileges after you enabled them, // or have already completed your task. Don't mess up your system :o) if(bEnablePrivilege) { tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; printf("tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED\n"); } else { tp.Privileges[0].Attributes = 0; printf("tp.Privileges[0].Attributes = 0\n"); } // Enable the privilege (or disable all privileges). if(!AdjustTokenPrivileges( hToken, FALSE, // If TRUE, function disables all privileges, if FALSE // the function modifies privilege based on the tp &tp, sizeof(TOKEN_PRIVILEGES), (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL)) { printf("AdjustTokenPrivileges() error: %u\n", GetLastError()); return FALSE; } else { printf("AdjustTokenPrivileges() is OK, last error if any: %u\n", GetLastError()); printf("Should be 0, means the operation completed successfully = ERROR_SUCCESS\n"); } return TRUE; } int main() { LPCTSTR lpszPrivilege = "SeSecurityPrivilege"; // Change this BOOL value to set/unset the SE_PRIVILEGE_ENABLED attribute BOOL bEnablePrivilege = TRUE; HANDLE hToken; // Open a handle to the access token for the calling process. // That is this running program if(!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken)) { printf("OpenProcessToken() error %u\n", GetLastError()); return FALSE; } else printf("OpenProcessToken() is OK\n"); // Call the user defined SetPrivilege() function to enable // and set the needed privilege BOOL test = SetPrivilege(hToken, lpszPrivilege, bEnablePrivilege); printf("The SetPrivilege() return value: %d\n\n", test); //************************************************ // TODO: Complete your task here //*********************************************** // After we have completed our task, don't forget to disable the privilege bEnablePrivilege = FALSE; BOOL test1 = SetPrivilege(hToken, lpszPrivilege, bEnablePrivilege); printf("The SetPrivilage() return value: %d\n", test1); return 0; } ------------------------------------------------------------------------------------------------ // Modifying ACL of an object. Here we are going to // add Allow standard right access and set an ACE for SACL. // This Win XP machine is logged in by user named Mike // who is a member of Administrators group... // To access a SACL using the GetNamedSecurityInfo() // or SetNamedSecurityInfo() functions, you have to enable // the SE_SECURITY_NAME privilege. #include #include #include #include //********* Enabling (Disabling) the privilege ********* 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; // Used by local system to identify the privilege LUID luid; if(!LookupPrivilegeValue( NULL, // lookup privilege on local system lpszPrivilege, // privilege to lookup &luid)) // receives LUID of privilege { printf("LookupPrivilegeValue() error: %u\n", GetLastError()); return FALSE; } else printf("LookupPrivilegeValue() is OK\n"); tp.PrivilegeCount = 1; tp.Privileges[0].Luid = luid; // Don't forget to disable the privilege after you enable them, // don't mess up your system :-) if(bEnablePrivilege) { tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; printf("tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED\n"); } else { tp.Privileges[0].Attributes = 0; printf("tp.Privileges[0].Attributes = 0\n"); } // Enable the privilege (or disable all privileges). if(!AdjustTokenPrivileges( hToken, FALSE, // If TRUE, function disables all privileges, if FALSE // the function modifies privileges based on the tp &tp, sizeof(TOKEN_PRIVILEGES), (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL)) { printf("AdjustTokenPrivileges() error: %u\n", GetLastError()); return FALSE; } else { printf("AdjustTokenPrivileges() is OK, last error if any: %u\n", GetLastError()); printf("Should be 0, means the operation completed successfully = ERROR_SUCCESS\n"); } return TRUE; } //************** Clean up routine *************** void Cleanup(PSECURITY_DESCRIPTOR pSS, PACL pNewSACL) { if(pSS != NULL) LocalFree((HLOCAL) pSS); else printf("pSS cleaning is OK\n"); if(pNewSACL != NULL) LocalFree((HLOCAL) pNewSACL); else printf("pNewSACL cleaning is OK\n"); } //******** The main() ********** int main() { // name of object, here we will add an ACE for a directory LPTSTR pszObjName = "C:\\Testdir2\\Testdir3"; // type of object, file or directory, a directory SE_OBJECT_TYPE ObjectType = SE_FILE_OBJECT; // access mask for new ACE equal to 0X11000000 // GENERIC_ALL and ACCESS_SYSTEM_SECURITY DWORD dwAccessRights = 0X11000000; // type of ACE, set audit for success ACCESS_MODE AccessMode = SET_AUDIT_SUCCESS; // inheritance flags for new ACE. // The OBJECT_INHERIT_ACE and CONTAINER_INHERIT_ACE flags are // not propagated to an inherited ACE. DWORD dwInheritance = NO_PROPAGATE_INHERIT_ACE; // format of trustee structure, the trustee is name TRUSTEE_FORM TrusteeForm = TRUSTEE_IS_NAME; // the new trustee for the ACE is set to testuser, // a normal user LPTSTR pszTrustee = "testuser"; // Result DWORD dwRes = 0; // Existing and new SACL pointers... PACL pOldSACL = NULL, pNewSACL = NULL; // Security descriptor PSECURITY_DESCRIPTOR pSS = NULL; // EXPLICIT_ACCESS structure EXPLICIT_ACCESS ea; // Verify the object name validity if(pszObjName == NULL) return ERROR_INVALID_PARAMETER; else printf("The object name is OK\n"); LPCTSTR lpszPrivilege = "SeSecurityPrivilege"; // Change this BOOL value to set/unset the SE_PRIVILEGE_ENABLED attribute BOOL bEnablePrivilege = TRUE; // Handle to the running process that is this (running) program HANDLE hToken; //*************** Get the handle to the process ******************** // Open a handle to the access token for the calling process. // That is this running program... if(!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken)) { printf("OpenProcessToken() error %u\n", GetLastError()); return FALSE; } else printf("OpenProcessToken() is OK\n"); //********************* Enabling privilege *************************** // Call the user defined SetPrivilege() function to enable privilege BOOL test = SetPrivilege(hToken, lpszPrivilege, bEnablePrivilege); // Verify printf("The SetPrivilege() return value: %d\n\n", test); //********************* End enabling privilege ************************ // By assuming that we have enabled the required privilege, accomplish // our task. Here, get a pointer to the existing SACL. dwRes = GetNamedSecurityInfo(pszObjName, ObjectType, SACL_SECURITY_INFORMATION, NULL, NULL, NULL, &pOldSACL, &pSS); // Verify if(dwRes != ERROR_SUCCESS) { printf("GetNamedSecurityInfo() Error %u\n", dwRes); Cleanup(pSS, pNewSACL); } else printf("GetNamedSecurityInfo() is OK\n"); // Initialize an EXPLICIT_ACCESS structure for the new ACE. // For more ACE entries, declare an array of the EXPLICIT_ACCESS structure ZeroMemory(&ea, sizeof(EXPLICIT_ACCESS)); ea.grfAccessPermissions = dwAccessRights; ea.grfAccessMode = AccessMode; ea.grfInheritance= dwInheritance; ea.Trustee.TrusteeForm = TrusteeForm; // Other structure elements that might be needed... // ea.Trustee.TrusteeType = TRUSTEE_IS_GROUP; // ea.Trustee.TrusteeType = TRUSTEE_IS_USER; // The trustee is testuser ea.Trustee.ptstrName = pszTrustee; // Create a new ACL that merges the new ACE // into the existing ACL. dwRes = SetEntriesInAcl(1, &ea, pOldSACL, &pNewSACL); if(dwRes != ERROR_SUCCESS) { printf("SetEntriesInAcl() error %u\n", dwRes); Cleanup(pSS, pNewSACL); } else printf("SetEntriesInAcl() is OK\n"); // Attach the new ACL as the object's SACL. dwRes = SetNamedSecurityInfo(pszObjName, ObjectType, SACL_SECURITY_INFORMATION, NULL, NULL, NULL, pNewSACL); if(dwRes != ERROR_SUCCESS) { printf("SetNamedSecurityInfo() error %u\n", dwRes); Cleanup(pSS, pNewSACL); } else printf("SetNamedSecurityInfo() is OK\n\n"); // Disable the privilege //****************** Disabling privilege ******************* bEnablePrivilege = FALSE; BOOL test1 = SetPrivilege(hToken, lpszPrivilege, bEnablePrivilege); printf("The SetPrivilege() return value: %d\n", test1); //****************** End disabling privilege *************** // Close the process handle by calling the CloseHandle(hToken) return 0; } ------------------------------------------------------------------------------------------------ // Searching for a SID in an Access Token // This program run on the standalone Windows Xp Pro // not a domain based machine... #include #include #define MAX_NAME 256 BOOL SearchTokenGroupsForSID(void) { DWORD i, dwSize = 0, dwResult = 0; HANDLE hToken; PTOKEN_GROUPS pGroupInfo; SID_NAME_USE SidType; char lpName[MAX_NAME]; char lpDomain[MAX_NAME]; BYTE sidBuffer[100]; PSID pSID = (PSID)&sidBuffer; // Open a handle to the access token for the calling process, // that is, this running program (process). So we get the handle // to the token for the current user that run this program and/or login // to this machine. Depend on your task, change the TOKEN_QUERY to // others accordingly... if(!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken)) { printf("OpenProcessToken() error %u\n", GetLastError()); return FALSE; } else printf("OpenProcessToken() for the current process is OK\n"); // By assuming that we got the handle to the token... // Call GetTokenInformation() to get the buffer size for storage. // This is for Tokengroups, change accordingly for others such as // TokenUser, TokenOwner, TokenType etc if(!GetTokenInformation(hToken, TokenGroups, NULL, dwSize, &dwSize)) { dwResult = GetLastError(); if(dwResult != ERROR_INSUFFICIENT_BUFFER) { printf("GetTokenInformation() error %u\n", dwResult); return FALSE; } else printf("GetTokenInformation() for the buffer size is OK\n"); } else printf("GetTokenInformation() for storage of the Token group is OK\n"); // By assuming that we got the storage, then allocate the buffer. pGroupInfo = (PTOKEN_GROUPS) GlobalAlloc(GPTR, dwSize); // Call GetTokenInformation() again to get the group information. if(!GetTokenInformation(hToken, TokenGroups, pGroupInfo, dwSize, &dwSize)) { printf("GetTokenInformation() error %u\n", GetLastError()); return FALSE; } else printf("GetTokenInformation() for getting the TokenGroups is OK\n"); //****************** Playing with SIDs ***************************** // Create a SID for the BUILTIN\Administrators group... // You can try other groups also lol as commented out on the following // codes. Uncomment/comment out the SIDs for testing.... // This is 32 bit RID value. Applications that require longer RID values, // use CreateWellKnownSid() instead //*********************** Administrator group *********************** SID_IDENTIFIER_AUTHORITY SIDAuth = SECURITY_NT_AUTHORITY; if(!AllocateAndInitializeSid(&SIDAuth, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &pSID)) { printf("AllocateAndInitializeSid() error %u\n", GetLastError()); return FALSE; } else printf("AllocateAndInitializeSid(), SID for BUILTIN\\Administrators group is\n successfully created\n"); //************************ Local group ******************** // An example for creating a SID for the Local group... // SID_IDENTIFIER_AUTHORITY SIDAuth = SECURITY_LOCAL_SID_AUTHORITY; // // if(!AllocateAndInitializeSid(&SIDAuth, 1, // SECURITY_LOCAL_RID, // 0, 0, 0, 0, 0, 0, 0, // &pSID)) // { // printf("AllocateAndInitializeSid() error %u\n", GetLastError()); // return FALSE; // } // else // printf("AllocateAndInitializeSid(), SID for Local group is\n successfully created\n"); //********************* Authenticated users *********************** // Another example for creating a SID for the Authenticated users... // SID_IDENTIFIER_AUTHORITY SIDAuth = SECURITY_NT_AUTHORITY; // if(!AllocateAndInitializeSid(&SIDAuth, 1, // SECURITY_AUTHENTICATED_USER_RID, // 0, 0, 0, 0, 0, 0, 0, // &pSID)) // { // printf("AllocateAndInitializeSid() error %u\n", GetLastError()); // return FALSE; // } // else // printf("AllocateAndInitializeSid(), SID for Local group is\n successfully created\n"); //****************************************************************** // Loop through the group SIDs looking for the created group SID. for(i=0; iGroupCount; i++) { // Compare the created SID with the available group SIDs if(EqualSid(pSID, pGroupInfo->Groups[i].Sid)) { // Lookup the account name and print it. dwSize = MAX_NAME; if(!LookupAccountSid(NULL, pGroupInfo->Groups[i].Sid, lpName, &dwSize, lpDomain, &dwSize, &SidType)) { // If not found or something wrong... dwResult = GetLastError(); if(dwResult == ERROR_NONE_MAPPED) strcpy(lpName, "NONE_MAPPED"); else { printf("LookupAccountSid() error %u\n", GetLastError()); return FALSE; } } // If found... else { //******************* Built-in\Administrators group ********************* printf("LookupAccountSid() for BUILTIN\\Administrators group is OK\n"); printf("Current user is a member of the %s\\%s group\n", lpDomain, lpName); //******************* Local group *************************************** // printf("LookupAccountSid() for Local group is OK\n"); // printf("Current user is a member of the %s group\n", lpName); //******************** Authenticated users ******************************* // printf("LookupAccountSid() for Authenticated users is OK\n"); // printf("Current user is a member of the %s\\%s group\n", lpDomain, lpName); } //**************** End playing with SIDs ********************************* // Find out whether the SID is enabled in the token. if(pGroupInfo->Groups[i].Attributes & SE_GROUP_ENABLED) printf("The group SID is enabled.\n"); else if (pGroupInfo->Groups[i].Attributes & SE_GROUP_USE_FOR_DENY_ONLY) printf("The group SID is a deny-only SID.\n"); else printf("The group SID is not enabled.\n"); } } // Release resources back to system if(pSID) FreeSid(pSID); if(pGroupInfo) GlobalFree(pGroupInfo); return TRUE; } //******** main() ******** int main() { // Call the user defined SearchTokenGroupsForSID() function // to search the token group SID BOOL test = SearchTokenGroupsForSID(); // Verify printf("The return value of SearchTokenGroupsForSID() is: %d\n", test); return 0; } ------------------------------------------------------------------------------------------------ #include #include BOOL IsUserAdminGrp(void) /* This routine returns TRUE if the caller's process is a member of the Administrators local group. Caller is NOT expected to be impersonating anyone and is expected to be able to open its own process and process token. Arguments: None. Return Value: TRUE - Caller has Administrators local group. FALSE - Caller does not have Administrators local group. */ { BOOL check; SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY; PSID AdministratorsGroup; check = AllocateAndInitializeSid( &NtAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &AdministratorsGroup); if(check) { printf("AllocateAndInitializeSid() is OK\n"); if(!CheckTokenMembership( NULL, // uses the impersonation token of the calling thread. // If the thread is not impersonating, the function duplicates // the thread's primary token to create an impersonation token. AdministratorsGroup, // Pointer to a SID structure &check // Result of the SID )) { // If the SID (the 2nd parameter) is present // and has the SE_GROUP_ENABLED attribute, // IsMember (3rd paramaeter) returns TRUE; otherwise, it returns FALSE. printf("The received value of the third parameter: %u\n", check); check = FALSE; printf("CheckTokenMembership() is NOT OK\n"); } else printf("CheckTokenMembership() is OK\n"); printf("You are Administrators Local Group lol!\n"); printf("The received value of the third parameter: %u, last error if any: %u\n", check, GetLastError()); FreeSid(AdministratorsGroup); } else printf("AllocateAndInitializeSid() is NOT OK\n"); return(check); } int main() { BOOL test = IsUserAdminGrp(); printf("The return value of the IsUserAdminGrp(): %u, last error if any: %u\n", test, GetLastError()); return 0; } --------------------------------------------------------------------------------------------------------------- // Finding the Owner of a File Object #include #include #include int main(int argc, char *argv[]) { DWORD dwRtnCode = 0; PSID pSidOwner; BOOL bRtnBool = TRUE; // Dummy initial value, no string... LPTSTR AcctName = "", DomainName = ""; DWORD dwAcctName = 1, dwDomainName = 1; // Dummy initial value, just use the defined one but unknown SID_NAME_USE eUse = SidTypeUnknown; HANDLE hFile; PSECURITY_DESCRIPTOR pSD; // Get the handle of the file object. hFile = CreateFile( "D:\\testfile.doc", // The file name and the path if any GENERIC_READ, // Access right FILE_SHARE_READ, // Share mode NULL, // Security attribute for inherited or not by child OPEN_EXISTING, // Open the file, fail if not exist FILE_ATTRIBUTE_NORMAL, // file attribute flag, Normal NULL); // Handle to template file if GENERIC_READ right access // Check GetLastError() for CreateFile()... if(hFile == INVALID_HANDLE_VALUE) { printf("CreateFile() error = %d\n", GetLastError()); return -1; } else printf("Handle to CreateFile() is OK\n"); // Allocate memory for the SID structure. pSidOwner = (PSID)GlobalAlloc(GMEM_FIXED, sizeof(PSID)); // Allocate memory for the security descriptor structure. pSD = (PSECURITY_DESCRIPTOR)GlobalAlloc(GMEM_FIXED, sizeof(PSECURITY_DESCRIPTOR)); // Get the owner SID of the file. Try for other object such as // SE_SERVICE, SE_PRINTER, SE_REGISTRY_KEY, SE_KERNEL_OBJECT, SE_WINDOW_OBJECT etc. // for 2nd parameter and 3rd parameter such as DACL_SECURITY_INFORMATION, // GROUP_SECURITY_INFORMATION and SACL_SECURITY_INFORMATION dwRtnCode = GetSecurityInfo( hFile, // Handle to the file SE_FILE_OBJECT, // Directory or file OWNER_SECURITY_INFORMATION, // Owner information of the (file) object &pSidOwner, // Pointer to the owner of the (file) object NULL, NULL, NULL, &pSD); // Pointer to the security descriptor of the (file) object // Check GetLastError for GetSecurityInfo error condition. if(dwRtnCode != ERROR_SUCCESS) { printf("GetSecurityInfo error = %d\n", GetLastError()); return -1; } else printf("GetSecurityInfo() is OK\n"); // First call to LookupAccountSid() to get the buffer sizes AcctName. bRtnBool = LookupAccountSid( NULL, // Local computer pSidOwner, // Pointer to the SID to lookup for AcctName, // The account name of the SID (pSIDOwner) (LPDWORD)&dwAcctName, // Size of the AcctName in TCHAR DomainName, // Pointer to the name of the Domain where the account name was found (LPDWORD)&dwDomainName, // Size of the DomainName in TCHAR &eUse); // Value of the SID_NAME_USE enum type that specify the SID type // Reallocate memory for the buffers. AcctName = (char *)GlobalAlloc(GMEM_FIXED, dwAcctName); // Check GetLastError() for GlobalAlloc() error condition. if(AcctName == NULL) { printf("GlobalAlloc() error = %d\n", GetLastError()); return -1; } else printf("Buffer allocation for AcctName is OK\n"); DomainName = (char *)GlobalAlloc(GMEM_FIXED, dwDomainName); // Check GetLastError() for GlobalAlloc() error condition. if(DomainName == NULL) { printf("GlobalAlloc() error = %d\n", GetLastError()); return -1; } else printf("Buffer allocation for DomainName is OK\n"); // Second call to LookupAccountSid() to get the account name. bRtnBool = LookupAccountSid( NULL, // name of local or remote computer pSidOwner, // security identifier, SID AcctName, // account name buffer (LPDWORD)&dwAcctName, // size of account name buffer DomainName, // domain name (LPDWORD)&dwDomainName, // 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) printf("Account owner not found for specified SID.\n"); else { printf("Error in LookupAccountSid().\n"); return -1; } } else if (bRtnBool == TRUE) // Print the account name. printf("Account owner = %s\n", AcctName); CloseHandle(hFile); return 0; } ---------------------------------------------------------------------------------------------------------------- // Taking object ownership #include #include #include #include //****** Cleanup routine ********** void Cleanup(PSID pSIDAdmin, PSID pSIDEveryone, PACL pACL, HANDLE hToken) { if(pSIDAdmin) FreeSid(pSIDAdmin); if(pSIDEveryone) FreeSid(pSIDEveryone); if(pACL) LocalFree(pACL); if(hToken) CloseHandle(hToken); } //************ Enabling/disabling the privilege **************** 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 luid; if(!LookupPrivilegeValue( NULL, // lookup privilege on local system lpszPrivilege, // privilege to lookup &luid)) // receives LUID of privilege { printf("LookupPrivilegeValue() of %s error: %u\n", lpszPrivilege, GetLastError()); return FALSE; } else printf("LookupPrivilegeValue() of %s is OK\n", lpszPrivilege); tp.PrivilegeCount = 1; tp.Privileges[0].Luid = luid; // Don't forget to disable the privilege after you enable them, // don't mess up your system :-). Change the bEnablePrivilege to // TRUE or FALSE to enable or disable the privilege respectively if(bEnablePrivilege) { tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; printf("tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED\n"); } else { tp.Privileges[0].Attributes = 0; printf("tp.Privileges[0].Attributes = 0\n"); } // Enable the privilege (or disable all privileges). if(!AdjustTokenPrivileges( hToken, FALSE, // If TRUE, function disables all privileges, if FALSE // the function modifies privileges based on the tp &tp, sizeof(TOKEN_PRIVILEGES), (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL)) { printf("AdjustTokenPrivileges() error: %u\n\n", GetLastError()); return FALSE; } else { printf("AdjustTokenPrivileges() is OK, last error if any: %u\n", GetLastError()); printf("Should be 0, means the operation completed successfully = ERROR_SUCCESS\n\n"); return TRUE; } } //********** Take ownership routine ************* BOOL TakeOwnership(LPTSTR lpszDir) { // Return value BOOL bRetval = FALSE; // Handle to token HANDLE hToken = NULL; // Pointer to SID for Administrators group PSID pSIDAdmin = NULL; // Pointer to SID for Everyone group PSID pSIDEveryone = NULL; // Pointer to access control list PACL pACL = NULL; SID_IDENTIFIER_AUTHORITY SIDAuthWorld = SECURITY_WORLD_SID_AUTHORITY; SID_IDENTIFIER_AUTHORITY SIDAuthNT = SECURITY_NT_AUTHORITY; const int NUM_ACCESS = 2; // Explicit access arrays structure. Here only two entries. // Change the array size for more entries EXPLICIT_ACCESS ea[NUM_ACCESS]; // Result DWORD dwRes; // Specify the DACL to use. Allow write for Everyone and full // control for Administrators group. // Create a SID for the Everyone group. if(!AllocateAndInitializeSid(&SIDAuthWorld, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, &pSIDEveryone)) { printf("AllocateAndInitializeSid() for Everyone group error %u\n", GetLastError()); Cleanup(pSIDAdmin, pSIDEveryone, pACL, hToken); } else printf("AllocateAndInitializeSid() for Everyone group is OK\n"); // Create a SID for the BUILTIN\Administrators group. if(!AllocateAndInitializeSid(&SIDAuthNT, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &pSIDAdmin)) { printf("AllocateAndInitializeSid() for Administrators group error %u\n\n", GetLastError()); Cleanup(pSIDAdmin, pSIDEveryone, pACL, hToken); } else printf("AllocateAndInitializeSid() for Administrators group is OK\n\n"); ZeroMemory(&ea, NUM_ACCESS * sizeof(EXPLICIT_ACCESS)); //***************** EXPLICIT ACCESS structure ****************** // Construct the structure, add other entries as needed by changing the array size // Set write access for Everyone. ea[0].grfAccessPermissions = GENERIC_WRITE; ea[0].grfAccessMode = SET_ACCESS; 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) pSIDEveryone; // Set full control for Administrators. ea[1].grfAccessPermissions = GENERIC_ALL; ea[1].grfAccessMode = SET_ACCESS; ea[1].grfInheritance = NO_INHERITANCE; ea[1].Trustee.TrusteeForm = TRUSTEE_IS_SID; ea[1].Trustee.TrusteeType = TRUSTEE_IS_GROUP; ea[1].Trustee.ptstrName = (LPTSTR) pSIDAdmin; //************************************************************** if(SetEntriesInAcl(NUM_ACCESS, ea, NULL, &pACL) != ERROR_SUCCESS) { printf("SetEntriesInAcl() for Everyone and Administrators group is NOT OK\n"); Cleanup(pSIDAdmin, pSIDEveryone, pACL, hToken); } else printf("SetEntriesInAcl() Everyone and Administrators group is OK\n"); //*************************************************************** // Try to modify the object's DACL. dwRes = SetNamedSecurityInfo( lpszDir, // name of the object SE_FILE_OBJECT, // type of object, directory DACL_SECURITY_INFORMATION, // change only the object's DACL NULL, NULL, // do not change owner or group pACL, // DACL specified NULL); // do not change SACL if(dwRes == ERROR_SUCCESS) { printf("SetNamedSecurityInfo()-Modifying the DACL is OK, return value: %u\n\n", dwRes); printf("Successfully changed DACL\n"); // No more processing needed. // Just return/exit bRetval = TRUE; Cleanup(pSIDAdmin, pSIDEveryone, pACL, hToken); } else if (dwRes == ERROR_ACCESS_DENIED) { printf("SetNamedSecurityInfo()-Modifying the DACL is NOT OK\n"); printf("If return value is 5, it is \"Access is denied\" (ERROR_ACCESS_DENIED)\n"); printf("Please get a proper permission!\n\n"); // If the previous call failed because access was denied, // enable the SE_TAKE_OWNERSHIP_NAME privilege, create a SID for // the Administrators group, take ownership of the object, and // disable the privilege. Then try again to set the object's DACL. //********************************************************************** // Open a handle to the access token for the calling process // that is the currently login access token if(!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken)) { printf("OpenProcessToken()-Getting the handle to access token failed: %u\n", GetLastError()); Cleanup(pSIDAdmin, pSIDEveryone, pACL, hToken); } else printf("OpenProcessToken()-Getting the handle to access token is OK\n"); //********************************************************************** // Enable the SE_TAKE_OWNERSHIP_NAME privilege. if(!SetPrivilege(hToken, SE_TAKE_OWNERSHIP_NAME, TRUE)) { // Verify the login printf("You must be logged on as Administrator.\n"); printf("SetPrivilege()-Enable the SE_TAKE_OWNERSHIP_NAME privilege is NOT OK\n"); Cleanup(pSIDAdmin, pSIDEveryone, pACL, hToken); } else { printf("Your login credential is OK\n"); printf("SetPrivilege()-Enable the SE_TAKE_OWNERSHIP_NAME privilege is OK\n"); } //********************************************************************* // Set the new owner in the object's security descriptor. dwRes = SetNamedSecurityInfo( lpszDir, // name of the object SE_FILE_OBJECT, // type of object OWNER_SECURITY_INFORMATION, // change only the object's owner pSIDAdmin, // SID of Administrator group NULL, NULL, NULL); if(dwRes != ERROR_SUCCESS) { printf("SetNamedSecurityInfo()-Could not set the new owner, error: %u\n", dwRes); Cleanup(pSIDAdmin, pSIDEveryone, pACL, hToken); } else printf("SetNamedSecurityInfo()-Changing the owner is OK\n"); //*********************************************************************** // Try again to modify the object's DACL, now that we are the owner. dwRes = SetNamedSecurityInfo( lpszDir, // name of the object SE_FILE_OBJECT, // type of object DACL_SECURITY_INFORMATION, // change only the object's DACL NULL, NULL, // do not change owner or group pACL, // DACL specified NULL); // do not change SACL if(dwRes == ERROR_SUCCESS) { printf("SetNamedSecurityInfo()-Successfully changed the DACL\n"); bRetval = TRUE; } else { printf("SetNamedSecurityInfo()-Failed changing the DACL, return value: %u\n", dwRes); } //********************************************************************** // Verify that the SE_TAKE_OWNERSHIP_NAME privilege is disabled. if(SetPrivilege(hToken, SE_TAKE_OWNERSHIP_NAME, FALSE)) { printf("SetPrivilege()-Disable the SE_TAKE_OWNERSHIP_NAME privilege is OK.\n"); Cleanup(pSIDAdmin, pSIDEveryone, pACL, hToken); } else { printf("SetPrivilege()-Disable the SE_TAKE_OWNERSHIP_NAME privilege is NOT OK.\n"); printf("Or the privilege might be already disabled\n"); } } return bRetval; } //******* main() ******* int main() { LPTSTR lpszDir = "E:\\Testfolder"; BOOL test = TakeOwnership(lpszDir); printf("\nTakeOwnership() return value: %u\n", test); return 0; } ======================================================================================================