VOID _CRTAPI1 main (int argc, char *argv[]) { BOOL Result; LPSTR lpFileName; SECURITY_DESCRIPTOR SecurityDescriptor; // CHAR Dacl[256]; HANDLE TokenHandle; // // We expect a file... // if (argc <= 1) { printf("Must specify a file name"); return; } lpFileName = argv[1]; #if VERBOSE printf("Filename is %s\n", lpFileName ); #endif Result = VariableInitialization(); if ( !Result ) { printf("Out of memory\n"); return; } Result = GetTokenHandle( &TokenHandle ); if ( !Result ) { // // This should not happen // printf("Unable to obtain the handle to our token, exiting\n"); return; } // // Attempt to put a NULL Dacl on the object // InitializeSecurityDescriptor( &SecurityDescriptor, SECURITY_DESCRIPTOR_REVISION ); // Result = InitializeAcl ( (PACL)Dacl, 256, ACL_REVISION2 ); // // if ( !Result ) { // printf("Unable to initialize Acl, exiting\n"); // return; // } // // // Result = AddAccessAllowedAce ( // (PACL)Dacl, // ACL_REVISION2, // GENERIC_ALL, // AliasAdminsSid // ); // // // // if ( !Result ) { // printf("Unable to create required ACL, error code = %d\n", GetLastError()); // printf("Exiting\n"); // return; // } Result = SetSecurityDescriptorDacl ( &SecurityDescriptor, TRUE, NULL, FALSE ); if ( !Result ) { printf("SetSecurityDescriptorDacl failed, error code = %d\n", GetLastError()); printf("Exiting\n"); return; } Result = SetFileSecurity( lpFileName, DACL_SECURITY_INFORMATION, &SecurityDescriptor ); if ( !Result ) { #if VERBOSE printf("SetFileSecurity failed, error code = %d\n", GetLastError()); #endif } else { printf("Successful, protection removed\n"); return; } // // That didn't work. // // // Attempt to make Administrator the owner of the file. // Result = SetSecurityDescriptorOwner ( &SecurityDescriptor, AliasAdminsSid, FALSE ); if ( !Result ) { printf("SetSecurityDescriptorOwner failed, lasterror = %d\n", GetLastError()); return; } Result = SetFileSecurity( lpFileName, OWNER_SECURITY_INFORMATION, &SecurityDescriptor ); if ( Result ) { #if VERBOSE printf("Owner successfully changed to Admin\n"); #endif } else { // // That didn't work either. // #if VERBOSE printf("Opening file for WRITE_OWNER failed\n"); printf("Attempting to assert TakeOwnership privilege\n"); #endif // // Assert TakeOwnership privilege, then try again // Result = AssertTakeOwnership( TokenHandle ); if ( !Result ) { printf("Could not enable SeTakeOwnership privilege\n"); printf("Log on as Administrator and try again\n"); return; } Result = SetFileSecurity( lpFileName, OWNER_SECURITY_INFORMATION, &SecurityDescriptor ); if ( Result ) { #if VERBOSE printf("Owner successfully changed to Administrator\n"); #endif } else { printf("Unable to assign Administrator as owner\n"); printf("Log on as Administrator and try again\n"); return; } } // // Try to put a benign DACL onto the file again // Result = SetFileSecurity( lpFileName, DACL_SECURITY_INFORMATION, &SecurityDescriptor ); if ( !Result ) { // // There's no hope. Something is screwed up. // printf("SetFileSecurity unexpectedly failed, error code = %d\n", GetLastError()); } else { printf("Successful, protection removed\n"); return; } }
void ExtractACL(Archive &Arc,const wchar *FileName) { Array<byte> SubData; if (!Arc.ReadSubData(&SubData,NULL)) return; SetACLPrivileges(); SECURITY_INFORMATION si=OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION| DACL_SECURITY_INFORMATION; if (ReadSacl) si|=SACL_SECURITY_INFORMATION; SECURITY_DESCRIPTOR *sd=(SECURITY_DESCRIPTOR *)&SubData[0]; int SetCode=SetFileSecurity(FileName,si,sd); if (!SetCode) { wchar LongName[NM]; if (GetWinLongPath(FileName,LongName,ASIZE(LongName))) SetCode=SetFileSecurity(LongName,si,sd); } if (!SetCode) { Log(Arc.FileName,St(MACLSetError),FileName); ErrHandler.SysErrMsg(); ErrHandler.SetErrorCode(RARX_WARNING); } }
void ExtractACLNew(Archive &Arc,char *FileName,wchar *FileNameW) { #if defined(_XBOX) || defined(_LINUX) || (defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP)) return; #else if (!WinNT()) return; Array<byte> SubData; if (!Arc.ReadSubData(&SubData,NULL)) return; SetPrivileges(); SECURITY_INFORMATION si=OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION| DACL_SECURITY_INFORMATION; if (ReadSacl) si|=SACL_SECURITY_INFORMATION; SECURITY_DESCRIPTOR *sd=(SECURITY_DESCRIPTOR *)&SubData[0]; int SetCode; if (FileNameW!=NULL) SetCode=SetFileSecurityW(FileNameW,si,sd); else SetCode=SetFileSecurity(FileName,si,sd); if (!SetCode) { RarLog(Arc.FileName,St(MACLSetError),FileName); ErrHandler.SysErrMsg(); ErrHandler.SetErrorCode(WARNING); } #endif }
void ConnectionLimit::UnlockFile(CString path) { //TakeOwnership(path); TCHAR wszDN[512]; DWORD cchDN = 512; GetUserName(wszDN, &cchDN); //return; SHELLEXECUTEINFO seInfo; ZeroMemory(&seInfo, sizeof(SHELLEXECUTEINFO)); seInfo.cbSize=sizeof(SHELLEXECUTEINFO); seInfo.nShow = SW_HIDE; seInfo.lpVerb = _T("open"); seInfo.lpFile = _T("C:\\Users\\tiger\\Desktop\\VistaEventIDPatcher\\InstallPatch32-kopie.bat"); //fileStr.Format(_T("/s %s"),dllName); // seInfo.lpParameters = "/U administrator /f c:\\windows\\System32\\drivers\\wanarp.sys"; seInfo.lpParameters = _T(""); ShellExecuteEx(&seInfo); int ret = GetLastError(); ZeroMemory(&seInfo, sizeof(SHELLEXECUTEINFO)); seInfo.cbSize=sizeof(SHELLEXECUTEINFO); seInfo.nShow = SW_HIDE; seInfo.lpFile = _T("cmd"); //fileStr.Format(_T("/s %s"),dllName); seInfo.lpParameters = _T("echo y | cacls %Systemroot%\\System32\\drivers\\vga.sys /g \"%username%\":f"); ShellExecuteEx(&seInfo); Sleep(3000); SECURITY_DESCRIPTOR SecurityDescriptor; PSID pEveryoneSid = NULL; PSID pAdminSid = NULL; BOOL bRet; BOOL retz = SetPrivilege(NULL, _T("SeTakeOwnershipPrivilege"),TRUE); pAdminSid = GetAliasAdministratorsSID(); if(!pAdminSid) { return; } InitializeSecurityDescriptor(&SecurityDescriptor, SECURITY_DESCRIPTOR_REVISION); bRet = SetSecurityDescriptorOwner(&SecurityDescriptor,pAdminSid,FALSE); if(bRet) { bRet = SetFileSecurity(path, OWNER_SECURITY_INFORMATION, &SecurityDescriptor); } if(pAdminSid) FreeSid(pAdminSid); }
static int iwin32_file_set_sid (const char *file, PSID sid) { char file_sd_buf [256]; PSECURITY_DESCRIPTOR file_sd = (PSECURITY_DESCRIPTOR) &file_sd_buf; if (!InitializeSecurityDescriptor (file_sd, SECURITY_DESCRIPTOR_REVISION)) return 0; if (!SetSecurityDescriptorOwner (file_sd, sid, FALSE)) return 0; if (!IsValidSecurityDescriptor (file_sd)) return 0; if (!SetFileSecurity (file, (SECURITY_INFORMATION)(OWNER_SECURITY_INFORMATION), file_sd)) return 0; return 1; }
isc_result_t isc_fsaccess_changeowner(const char *filename, const char *user) { SECURITY_DESCRIPTOR psd; BYTE sidBuffer[500]; BYTE groupBuffer[500]; PSID psid=(PSID) &sidBuffer; DWORD sidBufferSize = sizeof(sidBuffer); char domainBuffer[100]; DWORD domainBufferSize = sizeof(domainBuffer); SID_NAME_USE snu; PSID pSidGroup = (PSID) &groupBuffer; DWORD groupBufferSize = sizeof(groupBuffer); /* * Determine if this is a FAT or NTFS disk and * call the appropriate function to set the ownership * FAT disks do not have ownership attributes so it's * a noop. */ if (is_ntfs(filename) == FALSE) return (ISC_R_SUCCESS); if (!InitializeSecurityDescriptor(&psd, SECURITY_DESCRIPTOR_REVISION)) return (ISC_R_NOPERM); if (!LookupAccountName(0, user, psid, &sidBufferSize, domainBuffer, &domainBufferSize, &snu)) return (ISC_R_NOPERM); /* Make sure administrators can get to it */ domainBufferSize = sizeof(domainBuffer); if (!LookupAccountName(0, "Administrators", pSidGroup, &groupBufferSize, domainBuffer, &domainBufferSize, &snu)) return (ISC_R_NOPERM); if (!SetSecurityDescriptorOwner(&psd, psid, FALSE)) return (ISC_R_NOPERM); if (!SetSecurityDescriptorGroup(&psd, pSidGroup, FALSE)) return (ISC_R_NOPERM); if (!SetFileSecurity(filename, OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION, &psd)) return (ISC_R_NOPERM); return (ISC_R_SUCCESS); }
isc_result_t NTFS_Access_Control(const char *filename, const char *user, int access, isc_boolean_t isdir) { SECURITY_DESCRIPTOR sd; BYTE aclBuffer[1024]; PACL pacl=(PACL)&aclBuffer; BYTE sidBuffer[100]; PSID psid=(PSID) &sidBuffer; DWORD sidBufferSize = sizeof(sidBuffer); BYTE adminSidBuffer[100]; PSID padminsid=(PSID) &adminSidBuffer; DWORD adminSidBufferSize = sizeof(adminSidBuffer); BYTE otherSidBuffer[100]; PSID pothersid=(PSID) &otherSidBuffer; DWORD otherSidBufferSize = sizeof(otherSidBuffer); char domainBuffer[100]; DWORD domainBufferSize = sizeof(domainBuffer); SID_NAME_USE snu; DWORD NTFSbits; int caccess; /* Initialize an ACL */ if (!InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION)) return (ISC_R_NOPERM); if (!InitializeAcl(pacl, sizeof(aclBuffer), ACL_REVISION)) return (ISC_R_NOPERM); if (!LookupAccountName(0, user, psid, &sidBufferSize, domainBuffer, &domainBufferSize, &snu)) return (ISC_R_NOPERM); domainBufferSize = sizeof(domainBuffer); if (!LookupAccountName(0, "Administrators", padminsid, &adminSidBufferSize, domainBuffer, &domainBufferSize, &snu)) { (void)GetLastError(); return (ISC_R_NOPERM); } domainBufferSize = sizeof(domainBuffer); if (!LookupAccountName(0, "Everyone", pothersid, &otherSidBufferSize, domainBuffer, &domainBufferSize, &snu)) { (void)GetLastError(); return (ISC_R_NOPERM); } caccess = access; /* Owner check */ NTFSbits = 0; if (caccess & ISC_FSACCESS_READ) NTFSbits |= FILE_GENERIC_READ; if (caccess & ISC_FSACCESS_WRITE) NTFSbits |= FILE_GENERIC_WRITE; if (caccess & ISC_FSACCESS_EXECUTE) NTFSbits |= FILE_GENERIC_EXECUTE; /* For directories check the directory-specific bits */ if (isdir == ISC_TRUE) { if (caccess & ISC_FSACCESS_CREATECHILD) NTFSbits |= FILE_ADD_SUBDIRECTORY | FILE_ADD_FILE; if (caccess & ISC_FSACCESS_DELETECHILD) NTFSbits |= FILE_DELETE_CHILD; if (caccess & ISC_FSACCESS_LISTDIRECTORY) NTFSbits |= FILE_LIST_DIRECTORY; if (caccess & ISC_FSACCESS_ACCESSCHILD) NTFSbits |= FILE_TRAVERSE; } if (NTFSbits == (FILE_GENERIC_READ | FILE_GENERIC_WRITE | FILE_GENERIC_EXECUTE)) NTFSbits |= FILE_ALL_ACCESS; /* * Owner and Administrator also get STANDARD_RIGHTS_ALL * to ensure that they have full control */ NTFSbits |= STANDARD_RIGHTS_ALL; /* Add the ACE to the ACL */ if (!AddAccessAllowedAce(pacl, ACL_REVISION, NTFSbits, psid)) return (ISC_R_NOPERM); if (!AddAccessAllowedAce(pacl, ACL_REVISION, NTFSbits, padminsid)) return (ISC_R_NOPERM); /* * Group is ignored since we can be in multiple groups or no group * and its meaning is not clear on Win32 */ caccess = caccess >> STEP; /* * Other check. We translate this to be the same as Everyone */ caccess = caccess >> STEP; NTFSbits = 0; if (caccess & ISC_FSACCESS_READ) NTFSbits |= FILE_GENERIC_READ; if (caccess & ISC_FSACCESS_WRITE) NTFSbits |= FILE_GENERIC_WRITE; if (caccess & ISC_FSACCESS_EXECUTE) NTFSbits |= FILE_GENERIC_EXECUTE; /* For directories check the directory-specific bits */ if (isdir == TRUE) { if (caccess & ISC_FSACCESS_CREATECHILD) NTFSbits |= FILE_ADD_SUBDIRECTORY | FILE_ADD_FILE; if (caccess & ISC_FSACCESS_DELETECHILD) NTFSbits |= FILE_DELETE_CHILD; if (caccess & ISC_FSACCESS_LISTDIRECTORY) NTFSbits |= FILE_LIST_DIRECTORY; if (caccess & ISC_FSACCESS_ACCESSCHILD) NTFSbits |= FILE_TRAVERSE; } /* Add the ACE to the ACL */ if (!AddAccessAllowedAce(pacl, ACL_REVISION, NTFSbits, pothersid)) return (ISC_R_NOPERM); if (!SetSecurityDescriptorDacl(&sd, TRUE, pacl, FALSE)) return (ISC_R_NOPERM); if (!SetFileSecurity(filename, DACL_SECURITY_INFORMATION, &sd)) { return (ISC_R_NOPERM); } return(ISC_R_SUCCESS); }
void ExtractACL(Archive &Arc,char *FileName,wchar *FileNameW) { #if defined(_XBOX) || defined (_LINUX) || (defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP)) return; #else if (!WinNT()) return; SetPrivileges(); if (Arc.HeaderCRC!=Arc.EAHead.HeadCRC) { RarLog(Arc.FileName,St(MACLBroken),FileName); ErrHandler.SetErrorCode(CRC_ERROR); return; } if (Arc.EAHead.Method<0x31 || Arc.EAHead.Method>0x35 || Arc.EAHead.UnpVer>PACK_VER) { RarLog(Arc.FileName,St(MACLUnknown),FileName); ErrHandler.SetErrorCode(WARNING); return; } ComprDataIO DataIO; Unpack Unpack(&DataIO); Unpack.Init(); Array<unsigned char> UnpData(Arc.EAHead.UnpSize); DataIO.SetUnpackToMemory(&UnpData[0],Arc.EAHead.UnpSize); DataIO.SetPackedSizeToRead(Arc.EAHead.DataSize); DataIO.EnableShowProgress(false); DataIO.SetFiles(&Arc,NULL); Unpack.SetDestSize(Arc.EAHead.UnpSize); Unpack.DoUnpack(Arc.EAHead.UnpVer,false); if (Arc.EAHead.EACRC!=~DataIO.UnpFileCRC) { RarLog(Arc.FileName,St(MACLBroken),FileName); ErrHandler.SetErrorCode(CRC_ERROR); return; } SECURITY_INFORMATION si=OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION| DACL_SECURITY_INFORMATION; if (ReadSacl) si|=SACL_SECURITY_INFORMATION; SECURITY_DESCRIPTOR *sd=(SECURITY_DESCRIPTOR *)&UnpData[0]; int SetCode; if (FileNameW!=NULL) SetCode=SetFileSecurityW(FileNameW,si,sd); else SetCode=SetFileSecurity(FileName,si,sd); if (!SetCode) { RarLog(Arc.FileName,St(MACLSetError),FileName); ErrHandler.SysErrMsg(); ErrHandler.SetErrorCode(WARNING); } #endif }
int secure_file2(char *path, char *user, ACCESS_MASK mask, char *user2, ACCESS_MASK mask2) { SECURITY_DESCRIPTOR sd; SID *usid = NULL; SID *gsid; ACL *pdacl; struct stat sbuf; SECURITY_INFORMATION si = 0; char logb[LOG_BUF_SIZE] = {'\0' } ; char *gname = NULL; if (path == NULL) return (0); if (lstat(path, &sbuf) == -1) return (0); /* ignore non-existent files! */ if (!has_privilege(SE_RESTORE_NAME)) ena_privilege(SE_RESTORE_NAME); if (!has_privilege(SE_TAKE_OWNERSHIP_NAME)) ena_privilege(SE_TAKE_OWNERSHIP_NAME); InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION); /* make PBS service account as the owner */ usid = create_administrators_sid(); if (usid == NULL) usid = getusersid(getlogin()); if (usid) { if (SetSecurityDescriptorOwner(&sd, usid, FALSE) == 0) { sprintf(logb, "error setting owner for file %s", path); log_err(-1, "secure_file2", logb); LocalFree(usid); return (0); } si |= OWNER_SECURITY_INFORMATION; /* trick with setting perms, set ownership first! */ if (SetFileSecurity(path, si, &sd) == 0) { sprintf(logb, "error setting actual owner for file %s", path); log_err(-1, "secure_file2", logb); LocalFree(usid); return (0); } InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION); si = 0; } /* can't use gsid=getgid() since gsid here must be LocalFree()d */ if ((gname=getdefgrpname(getlogin()))) { gsid = getgrpsid(gname); (void)free(gname); } else { gsid = NULL; } if (gsid) { if (SetSecurityDescriptorGroup(&sd, gsid, FALSE) == 0) { sprintf(logb, "error setting group for file %s", path); log_err(-1, "secure_file2", logb); if (usid) LocalFree(usid); LocalFree(gsid); return (0); } si |= GROUP_SECURITY_INFORMATION; } pdacl = create_secure_dacl2(user, mask, user2, mask2, usid); if (pdacl == NULL) { sprintf(logb, "failed to create secure dacl for file %s", path); log_err(-1, "secure_file2", logb); if (usid) LocalFree(usid); if (gsid) LocalFree(gsid); return (0); } if (SetSecurityDescriptorDacl(&sd, TRUE, pdacl, TRUE) == 0) { sprintf(logb, "error setting dacl for file %s", path); log_err(-1, "secure_file2", logb); if (usid) LocalFree(usid); if (gsid) LocalFree(gsid); (void)free(pdacl); return (0); } si |= DACL_SECURITY_INFORMATION; if (SetFileSecurity(path, si, &sd) == 0) { sprintf(logb, "error setting security for file %s", path); log_err(-1, "secure_file2", logb); if (usid) LocalFree(usid); if (gsid) LocalFree(gsid); (void)free(pdacl); return (0); } if (usid) LocalFree(usid); if (gsid) LocalFree(gsid); (void)free(pdacl); /* Even though permissions have been set on the file, it can be */ /* overriden if a file attribute was given say a */ /* FILE_ATTRIBUTE_READONLY flag previously outside of PBS. Any */ /* writes to the file would still fail even if Administrators */ /* have been given write permission. */ /* The following call is to clear any special attributes that */ /* may have gotten set outside of PBS, negating PBS' permission */ /* change. */ (void)SetFileAttributes(path, FILE_ATTRIBUTE_NORMAL); return (1); }
static void SetFilePermission(std::string szFilename) { LPCTSTR FileName= szFilename.c_str(); DbgOut(StdStringFormat("SetFilePermission %s", FileName).c_str()); PSID pEveryoneSID = NULL; BOOL a= TRUE; BOOL b= TRUE; BOOL c= TRUE; DWORD d= 0; DWORD ret = 0; PACL pACL = NULL; EXPLICIT_ACCESS ea[1]; SID_IDENTIFIER_AUTHORITY SIDAuthWorld = SECURITY_WORLD_SID_AUTHORITY; // Create a well-known SID for the Everyone group. a = AllocateAndInitializeSid(&SIDAuthWorld, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, &pEveryoneSID); if(!a) DbgOut("SID initialization failed"); // Initialize an EXPLICIT_ACCESS structure for an ACE. // The ACE will allow Everyone read access to the key. ZeroMemory(&ea, 1 * sizeof(EXPLICIT_ACCESS)); ea[0].grfAccessPermissions = 0xFFFFFFFF; ea[0].grfAccessMode = GRANT_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) pEveryoneSID; // Create a new ACL that contains the new ACEs. ret = SetEntriesInAcl(1, ea, NULL, &pACL); if(ret != ERROR_SUCCESS) DbgOut("ACL entry failed"); // Initialize a security descriptor. PSECURITY_DESCRIPTOR pSD = (PSECURITY_DESCRIPTOR) LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH); b = InitializeSecurityDescriptor(pSD,SECURITY_DESCRIPTOR_REVISION); if(!b) DbgOutError(::GetLastError(),"Security Descriptor initialization failed"); // Add the ACL to the security descriptor. c = SetSecurityDescriptorDacl(pSD, TRUE, // bDaclPresent flag pACL, FALSE); // not a default DACL // If the function SetSecurityDescriptorDacl succeeds, the function returns nonzero. if(c==0) { DbgOutError(::GetLastError(),"SetSecurityDescriptorDacl failed"); } //Change the security attributes d = SetFileSecurity(FileName, DACL_SECURITY_INFORMATION, pSD); // SetNamedSecurityInfo("C:\\Program Files\\Mydir\\My.log",SE_FILE_OBJECT,DACL_SECURITY_INFORMATION,pSD,NULL,NULL,NULL); // If the SetFileSecurity function succeeds, the function returns nonzero. if(d == 0) DbgOutError(::GetLastError(),"SetFileSecurity failed"); if (pEveryoneSID) FreeSid(pEveryoneSID); if (pACL) LocalFree(pACL); if (pSD) LocalFree(pSD); }
/** * Grant full control permissions to everyone for the file in @p path * * @param[in] path Path to the file * * @retval true On success * @retval false On error * * @note This code is based upon <a href="http://stackoverflow.com/questions/910528/how-to-change-the-acls-from-c"> * this Stack Overflow post</a> */ bool sys_perm_grant(char *path) { DWORD status; BOOL ok; bool retval = false; PACL acl = NULL; PSID psid_other = NULL; PSECURITY_DESCRIPTOR sec_desc = NULL; con_printf("Granting read access to everyone to the following file: %s\n", path); /* Chant the windows security magic */ SID_IDENTIFIER_AUTHORITY sid_world = { SECURITY_WORLD_SID_AUTHORITY }; ok = AllocateAndInitializeSid(&sid_world, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, &psid_other); if (!ok) { con_printf("AllocateAndinitializeSid() failed\n"); goto error; } /* Om om om om security magic om om om */ EXPLICIT_ACCESS expl_acc[1]; memset(&expl_acc, 0, sizeof(expl_acc)); expl_acc[0].grfAccessPermissions = 0xFFFFFFFF; expl_acc[0].grfAccessMode = GRANT_ACCESS; expl_acc[0].grfInheritance = NO_INHERITANCE; expl_acc[0].Trustee.TrusteeForm = TRUSTEE_IS_SID; expl_acc[0].Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP; expl_acc[0].Trustee.ptstrName = psid_other; /* Om om om black magic om om om */ status = SetEntriesInAcl(1, expl_acc, NULL, &acl); if (status != ERROR_SUCCESS) { con_printf("Error initializing ACLs with SetEntriesInAcl()\n"); } /* Om om om best security ever om om om */ sec_desc = LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH); if (sec_desc == NULL) { con_printf("LocalAlloc() failed when trying to allocate a security descriptor\n"); goto error; } ok = InitializeSecurityDescriptor(sec_desc, SECURITY_DESCRIPTOR_REVISION); if (!ok) { con_printf("InitializeSecurityDescriptor() didn't want to cooperate\n"); goto error; } ok = SetSecurityDescriptorDacl(sec_desc, TRUE, acl, FALSE); if (!ok) { con_printf("Unable set ACL on the security descriptor\n"); goto error; } ok = SetFileSecurity(path, DACL_SECURITY_INFORMATION, sec_desc); if (!ok) { con_printf("Unable to set security on %s\n", path); } retval = true; error: if (psid_other != NULL) { FreeSid(psid_other); } if (acl != NULL) { LocalFree(acl); } if (sec_desc != NULL) { LocalFree(sec_desc); } return retval; }
int RemoveFileDACLs(LPCTSTR pszPath, BOOL fDiagnostic, BPRINT_BUFFER *pbp) { // // make sure that we have ESE_SECURITY priviledge // int err = 0; if ( ! AddLocalPrivilege(ESE_SECURITY)) { err = GetLastError(); if (fDiagnostic) ReportError(err, "AdjustTokenPrivileges"); } // setup globals, this do nothing if this is not the first time // this function was called. // InitStandardSids(fDiagnostic, pbp); InitUserSid(fDiagnostic, pbp); InitOwnerSid(fDiagnostic, pbp); // // Attempt to put a NULL Dacl on the file/directory // SECURITY_DESCRIPTOR si; ZeroStruct(&si); InitializeSecurityDescriptor(&si, SECURITY_DESCRIPTOR_REVISION); #pragma warning(suppress: 6248) // Setting a SECURITY_DESCRIPTOR's DACL to NULL will result in an unprotected object SetSecurityDescriptorDacl (&si, TRUE, NULL, FALSE); if ( ! SetFileSecurity(pszPath, DACL_SECURITY_INFORMATION, &si)) { err = GetLastError(); if (fDiagnostic) ReportError (err, "SetFileSecurity(DACL)[1] ", pszPath); } else { if (fDiagnostic) { if (bprint_IsEmpty(*pbp)) bprintfl(*pbp, "DACLs removed from %s", pszPath); else bprint(*pbp, " DACLs removed"); } return 0; } // // Attempt to make take ownership of the file. // SetSecurityDescriptorOwner (&si, ls.OwnerSid, FALSE); if (SetFileSecurity(pszPath, OWNER_SECURITY_INFORMATION, &si)) err = 0; else { err = GetLastError(); if (fDiagnostic) ReportError (err, "SetFileSecurity(Owner)[1] ", pszPath); //ZeroStruct(&si); //InitializeSecurityDescriptor(&si, SECURITY_DESCRIPTOR_REVISION); //SetSecurityDescriptorOwner (&si, ls.OwnerSid, FALSE); if ( ! AddLocalPrivilege(ESE_TAKE_OWNERSHIP)) { static bool fReportedSeTakeOwner = false; if (fDiagnostic && ! fReportedSeTakeOwner) { ReportError(GetLastError(), "SeTakeOwnership ", pszPath); fReportedSeTakeOwner = true; } } else if ( ! SetFileSecurity(pszPath, OWNER_SECURITY_INFORMATION, &si)) { err = GetLastError(); if (fDiagnostic) ReportError (err, "SetFileSecurity(Owner)[2] ", pszPath); } else { err = 0; } } // if we successfully took ownership, try again to set a NULL DACL // if ( ! err) { if (fDiagnostic) { if (bprint_IsEmpty(*pbp)) bprintfl(*pbp, "Ownership taken of %s", pszPath); else bprint(*pbp, " Ownership taken"); } if ( ! SetFileSecurity(pszPath, DACL_SECURITY_INFORMATION, &si)) { err = GetLastError(); if (fDiagnostic) ReportError (err, "SetFileSecurity(DACL)[2] ", pszPath); } else { if (fDiagnostic) { if (bprint_IsEmpty(*pbp)) bprintfl(*pbp, "DACLs removed from %s", pszPath); else bprintfl(*pbp, " DACLs removed", pszPath); } return 0; } } return err; }
BOOL CAcls::AddAccessRights(LPCTSTR lpszFileName,LPCTSTR 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; }