static gboolean ProtectUser (gunichar2 *path) { DWORD retval = -1; PSID pCurrentSid = GetCurrentUserSid (); if (pCurrentSid) { PACL pDACL = NULL; EXPLICIT_ACCESS ea; ZeroMemory (&ea, sizeof (EXPLICIT_ACCESS)); /* grant exclusive access to the current user */ BuildTrusteeWithSidW (&ea.Trustee, pCurrentSid); ea.grfAccessPermissions = GENERIC_ALL; ea.grfAccessMode = SET_ACCESS; ea.grfInheritance = SUB_CONTAINERS_AND_OBJECTS_INHERIT; ea.Trustee.TrusteeForm = TRUSTEE_IS_SID; ea.Trustee.TrusteeType = TRUSTEE_IS_USER; retval = SetEntriesInAcl (1, &ea, NULL, &pDACL); if (retval == ERROR_SUCCESS) { /* with PROTECTED_DACL_SECURITY_INFORMATION we remove any existing ACL (like inherited ones) */ retval = SetNamedSecurityInfo (path, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION | PROTECTED_DACL_SECURITY_INFORMATION, NULL, NULL, pDACL, NULL); } if (pDACL) LocalFree (pDACL); g_free (pCurrentSid); /* g_malloc0 */ } return (retval == ERROR_SUCCESS); }
// 设置注册表的存取权限 BOOL RegKeySetACL(LPTSTR lpKeyName, DWORD AccessPermissions, ACCESS_MODE AccessMode) { PSECURITY_DESCRIPTOR SD; EXPLICIT_ACCESS ea; PACL OldDACL, NewDACL; SE_OBJECT_TYPE ObjectType = SE_REGISTRY_KEY; //#include <aclapi.h> //默认返回值为FALSE BOOL bRet = FALSE; //建立一个空的ACL; if (SetEntriesInAcl(0, NULL, NULL, &OldDACL) != ERROR_SUCCESS) return bRet; if (SetEntriesInAcl(0, NULL, NULL, &NewDACL) != ERROR_SUCCESS) return bRet; //获取现有的ACL列表到OldDACL: if(GetNamedSecurityInfo(lpKeyName, ObjectType, DACL_SECURITY_INFORMATION, NULL, NULL, &OldDACL, NULL, &SD) != ERROR_SUCCESS) { return bRet; } //设置用户名"Everyone"对指定的键有所有操作权到结构ea: ZeroMemory(&ea, sizeof(EXPLICIT_ACCESS)); char *lpUsers[] = {"SYSTEM", "Administrators", "Everyone", "Users"}; for (int i = 0; i < sizeof(lpUsers) / sizeof(char *); i++) { BuildExplicitAccessWithName(&ea, lpUsers[i], // name of trustee AccessPermissions, // type of access AccessMode, // access mode SUB_CONTAINERS_AND_OBJECTS_INHERIT); //子键继承它的权限 } //合并结构ea和OldDACL的权限列表到新的NewDACL: if (SetEntriesInAcl(1, &ea, NULL, &NewDACL) == ERROR_SUCCESS) { //把新的ACL写入到指定的键: SetNamedSecurityInfo(lpKeyName, ObjectType, DACL_SECURITY_INFORMATION, NULL, NULL, NewDACL, NULL); bRet = TRUE; } //释放指针 if(SD != NULL) LocalFree((HLOCAL) SD); if(NewDACL != NULL) LocalFree((HLOCAL) NewDACL); if(OldDACL != NULL) LocalFree((HLOCAL) OldDACL); return bRet; }
// 'Corrects' the security on a file by taking ownership of it and giving the current user full control // For directories these will do a complete recursive correction. static void CorrectSecurity(TCHAR *f, DWORD attrib, BOOL takeownership, PSID sid, PACL acl, BOOL oneVolumeOnly) { BY_HANDLE_FILE_INFORMATION info; if (attrib != INVALID_FILE_ATTRIBUTES) { DWORD err; if (sid && takeownership) { err = SetNamedSecurityInfo(f, SE_FILE_OBJECT, OWNER_SECURITY_INFORMATION, sid, NULL, NULL, NULL); if (err != ERROR_SUCCESS) { LogFileError(TEXT("SetNamedSecurityInfo (change owner)"), f, err); } } if (sid && acl) { err = SetNamedSecurityInfo(f, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, acl, NULL); if (err != ERROR_SUCCESS) { LogFileError(TEXT("SetNamedSecurityInfo (change DACL)"), f, err); } } if ((attrib & FILE_ATTRIBUTE_DIRECTORY) && !(oneVolumeOnly && FileChangesVolume(f))) { // Recursively go through the directories WIN32_FIND_DATA ffd; TCHAR full[BIG_PATH+5], *file = copyStr(f); HANDLE hFind; DWORD dwError; DWORD len = _tcslen(file); while (len > 0 && file[len-1] == L'\\') file[--len] = 0; file[len ] = TEXT('\\'); file[len+1] = TEXT('*'); file[len+2] = 0; hFind = FindFirstFileEx(file, FindExInfoBasic, &ffd, FindExSearchNameMatch, NULL, FIND_FIRST_EX_LARGE_FETCH); if (hFind == INVALID_HANDLE_VALUE) { dwError = GetLastError(); if (dwError != ERROR_FILE_NOT_FOUND && dwError != ERROR_ACCESS_DENIED) LogFileError(TEXT("FindFirstFileEx in CorrectSecurity failed for"), file, dwError); } else { do { if (_tcscmp(ffd.cFileName, TEXT("..")) == 0 || _tcscmp(ffd.cFileName, TEXT(".")) == 0) continue; CorrectSecurity(makeFullPath(f, ffd.cFileName, full), ffd.dwFileAttributes, takeownership, sid, acl, oneVolumeOnly); } while (FindNextFile(hFind, &ffd) != 0); dwError = GetLastError(); if (dwError != ERROR_NO_MORE_FILES) LogError(TEXT("FindNextFile in CorrectSecurity"), dwError); FindClose(hFind); } free(file); } if (attrib & FILE_ATTRIBUTE_READONLY) { // Remove the read-only attribute SetFileAttributes(f, attrib&!FILE_ATTRIBUTE_READONLY); } } }
static void ChangeDACL(const SchemeType * scheme, TCHAR * path, DWORD mode, BOOL noinherit) { TCHAR * param = (TCHAR *)LocalAlloc(LPTR, g_string_size*sizeof(TCHAR)); TCHAR * trusteeName = NULL; PSID pSid = NULL; DWORD trusteeForm = TRUSTEE_IS_NAME; DWORD permissions = 0; PACL pOldAcl = NULL; PACL pNewAcl = NULL; EXPLICIT_ACCESS access; DWORD ret = 0; if (popstring(param)) ABORT("Trustee is missing"); if (NULL == (trusteeName = ParseTrustee(param, &trusteeForm))) ABORT_s("Bad trustee (%s)", param); if (popstring(param)) ABORT("Permission flags are missing"); if (0 == (permissions = ParsePermissions(scheme, param))) ABORT_s("Bad permission flags (%s)", param); ret = GetNamedSecurityInfo(path, scheme->type, DACL_SECURITY_INFORMATION, NULL, NULL, &pOldAcl, NULL, NULL); if (ret != ERROR_SUCCESS) ABORT_d("Cannot read access control list. Error code: %d", ret); BuildExplicitAccessWithName(&access, _T(""), permissions, (ACCESS_MODE)mode, scheme->defaultInheritance); access.Trustee.TrusteeForm = (TRUSTEE_FORM)trusteeForm; access.Trustee.ptstrName = trusteeName; if (noinherit) access.grfInheritance = NO_INHERITANCE; ret = SetEntriesInAcl(1, &access, pOldAcl, &pNewAcl); if (ret != ERROR_SUCCESS) ABORT_d("Cannot build new access control list. Error code: %d", ret); ret = SetNamedSecurityInfo(path, scheme->type, DACL_SECURITY_INFORMATION, NULL, NULL, pNewAcl, NULL); if (ret != ERROR_SUCCESS) ABORT_d("Cannot apply new access control list. Error code: %d", ret); cleanup: if (NULL != pNewAcl) LocalFree(pNewAcl); if (NULL != pOldAcl) LocalFree(pOldAcl); LocalFree(trusteeName); LocalFree(param); }
static void ChangeOwner(const SchemeType * scheme, TCHAR * path, ChangeMode mode) { TCHAR * param = (TCHAR *)LocalAlloc(LPTR, g_string_size*sizeof(TCHAR)); SECURITY_INFORMATION what; PSID pSidOwner = NULL; PSID pSidGroup = NULL; PSID pSid = NULL; DWORD ret = 0; HANDLE hToken; if (popstring(param)) ABORT("Trustee is missing"); if (NULL == (pSid = ParseSid(param))) ABORT_s("Bad trustee (%s)", param); switch(mode) { case ChangeMode_Owner: what = OWNER_SECURITY_INFORMATION; pSidOwner = pSid; break; case ChangeMode_Group: what = GROUP_SECURITY_INFORMATION; pSidGroup = pSid; break; default: ABORT_d("Bug: Unsupported change mode: %d", mode); } if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) ABORT_d("Cannot open process token. Error code: %d", GetLastError()); if (!SetPrivilege(hToken, SE_RESTORE_NAME, TRUE)) ABORT("Unable to give SE_RESTORE_NAME privilege."); ret = SetNamedSecurityInfo(path, scheme->type, what, pSidOwner, pSidGroup, NULL, NULL); if (ret != ERROR_SUCCESS) ABORT_d("Cannot apply new ownership. Error code: %d", ret); cleanup: SetPrivilege(hToken, SE_RESTORE_NAME, FALSE); CloseHandle(hToken); LocalFree(param); }
int enable_access(char *filename) { int retval = 1; PACL myacl = generate_acl(); if ( ERROR_SUCCESS!=SetNamedSecurityInfo(filename, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, myacl, NULL) ) { retval = 0; } if ( NULL!=myacl ) { LocalFree(myacl); } return retval; }
bool SetOwnerInternal(LPCWSTR Object, LPCWSTR Owner) { bool Result = false; PSID Sid = nullptr; //в winapi от mingw.org неправильный тип параметра. if(!ConvertStringSidToSid((LPWSTR)Owner, &Sid)) { SID_NAME_USE Use; DWORD cSid=0, ReferencedDomain=0; LookupAccountName(nullptr, Owner, nullptr, &cSid, nullptr, &ReferencedDomain, &Use); if(cSid) { Sid = LocalAlloc(LMEM_FIXED, cSid); if(Sid) { LPWSTR ReferencedDomainName = new WCHAR[ReferencedDomain]; if(ReferencedDomainName) { if(LookupAccountName(nullptr, Owner, Sid, &cSid, ReferencedDomainName, &ReferencedDomain, &Use)) { } delete[] ReferencedDomainName; } } } } if(Sid) { Privilege TakeOwnershipPrivilege(SE_TAKE_OWNERSHIP_NAME); Privilege RestorePrivilege(SE_RESTORE_NAME); DWORD dwResult = SetNamedSecurityInfo(const_cast<LPWSTR>(Object), SE_FILE_OBJECT, OWNER_SECURITY_INFORMATION, Sid, nullptr, nullptr, nullptr); if(dwResult == ERROR_SUCCESS) { Result = true; } else { SetLastError(dwResult); } } if(Sid) { LocalFree(Sid); } return Result; }
static gboolean ProtectMachine (gunichar2 *path) { PSID pEveryoneSid = GetEveryoneSid (); PSID pAdminsSid = GetAdministratorsSid (); DWORD retval = -1; if (pEveryoneSid && pAdminsSid) { PACL pDACL = NULL; EXPLICIT_ACCESS ea [2]; ZeroMemory (&ea, 2 * sizeof (EXPLICIT_ACCESS)); /* grant all access to the BUILTIN\Administrators group */ BuildTrusteeWithSidW (&ea [0].Trustee, pAdminsSid); ea [0].grfAccessPermissions = GENERIC_ALL; ea [0].grfAccessMode = SET_ACCESS; ea [0].grfInheritance = SUB_CONTAINERS_AND_OBJECTS_INHERIT; ea [0].Trustee.TrusteeForm = TRUSTEE_IS_SID; ea [0].Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP; /* read-only access everyone */ BuildTrusteeWithSidW (&ea [1].Trustee, pEveryoneSid); ea [1].grfAccessPermissions = GENERIC_READ; ea [1].grfAccessMode = SET_ACCESS; ea [1].grfInheritance = SUB_CONTAINERS_AND_OBJECTS_INHERIT; ea [1].Trustee.TrusteeForm = TRUSTEE_IS_SID; ea [1].Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP; retval = SetEntriesInAcl (2, ea, NULL, &pDACL); if (retval == ERROR_SUCCESS) { /* with PROTECTED_DACL_SECURITY_INFORMATION we */ /* remove any existing ACL (like inherited ones) */ retval = SetNamedSecurityInfo (path, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION | PROTECTED_DACL_SECURITY_INFORMATION, NULL, NULL, pDACL, NULL); } if (pDACL) LocalFree (pDACL); } if (pEveryoneSid) FreeSid (pEveryoneSid); if (pAdminsSid) FreeSid (pAdminsSid); return (retval == ERROR_SUCCESS); }
DWORD ModLoader::AdjustGroupPolicy(std::wstring wstrFilePath) { PACL pOldDACL = NULL, pNewDACL = NULL; PSECURITY_DESCRIPTOR pSD = NULL; EXPLICIT_ACCESS eaAccess; SECURITY_INFORMATION siInfo = DACL_SECURITY_INFORMATION; DWORD dwResult = ERROR_SUCCESS; PSID pSID; // Get a pointer to the existing DACL (Conditionaly). dwResult = GetNamedSecurityInfo(wstrFilePath.c_str(), SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, &pOldDACL, NULL, &pSD); if (dwResult != ERROR_SUCCESS) goto Cleanup; ConvertStringSidToSid(L"S-1-15-2-1", &pSID); if (pSID == NULL) goto Cleanup; ZeroMemory(&eaAccess, sizeof(EXPLICIT_ACCESS)); eaAccess.grfAccessPermissions = GENERIC_READ | GENERIC_EXECUTE; eaAccess.grfAccessMode = SET_ACCESS; eaAccess.grfInheritance = SUB_CONTAINERS_AND_OBJECTS_INHERIT; eaAccess.Trustee.TrusteeForm = TRUSTEE_IS_SID; eaAccess.Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP; eaAccess.Trustee.ptstrName = (LPWSTR)pSID; // Create a new ACL that merges the new ACE into the existing DACL. dwResult = SetEntriesInAcl(1, &eaAccess, pOldDACL, &pNewDACL); if (ERROR_SUCCESS != dwResult) goto Cleanup; // Attach the new ACL as the object's DACL. dwResult = SetNamedSecurityInfo((LPWSTR)wstrFilePath.c_str(), SE_FILE_OBJECT, siInfo, NULL, NULL, pNewDACL, NULL); if (ERROR_SUCCESS != dwResult) goto Cleanup; Cleanup: if (pSD != NULL) LocalFree((HLOCAL)pSD); if (pNewDACL != NULL) LocalFree((HLOCAL)pNewDACL); return dwResult; }
static void ChangeInheritance(const SchemeType * scheme, TCHAR * path, BOOL inherit) { PACL pOldAcl = NULL; DWORD ret = 0; ret = GetNamedSecurityInfo(path, scheme->type, DACL_SECURITY_INFORMATION, NULL, NULL, &pOldAcl, NULL, NULL); if (ret != ERROR_SUCCESS) ABORT_d("Cannot read access control list. Error code: %d", ret); ret = SetNamedSecurityInfo(path, scheme->type, DACL_SECURITY_INFORMATION | (inherit ? UNPROTECTED_DACL_SECURITY_INFORMATION : PROTECTED_DACL_SECURITY_INFORMATION), NULL, NULL, pOldAcl, NULL); if (ret != ERROR_SUCCESS) ABORT_d("Cannot change access control list inheritance. Error code: %d", ret); cleanup: LocalFree(pOldAcl); }
bool SetOwnerInternal(const string& Object, const string& Owner) { bool Result = false; PSID Sid = nullptr; SCOPE_EXIT { LocalFree(Sid); }; if(!ConvertStringSidToSid(Owner.data(), &Sid)) { SID_NAME_USE Use; DWORD cSid=0, ReferencedDomain=0; LookupAccountName(nullptr, Owner.data(), nullptr, &cSid, nullptr, &ReferencedDomain, &Use); if(cSid) { Sid = LocalAlloc(LMEM_FIXED, cSid); if(Sid) { std::vector<wchar_t> ReferencedDomainName(ReferencedDomain); if(LookupAccountName(nullptr, Owner.data(), Sid, &cSid, ReferencedDomainName.data(), &ReferencedDomain, &Use)) { ; } } } } if(Sid) { SCOPED_ACTION(Privilege)(SE_TAKE_OWNERSHIP_NAME); SCOPED_ACTION(Privilege)(SE_RESTORE_NAME); DWORD dwResult = SetNamedSecurityInfo(const_cast<LPWSTR>(Object.data()), SE_FILE_OBJECT, OWNER_SECURITY_INFORMATION, Sid, nullptr, nullptr, nullptr); if(dwResult == ERROR_SUCCESS) { Result = true; } else { SetLastError(dwResult); } } return Result; }
bool CWinSecurity::SetFileOwner(const string& filename, const string& owner, const string& group, unsigned int* uid, unsigned int* gid) { if ( uid ) *uid = 0; if ( gid ) *gid = 0; if ( owner.empty() && group.empty() ) { CNcbiError::Set(CNcbiError::eInvalidArgument); return false; } HANDLE token = INVALID_HANDLE_VALUE; PSID owner_sid = NULL; PSID group_sid = NULL; bool success = false; // Get SIDs for new owner and group if ( !owner.empty() ) { owner_sid = x_GetAccountSidByName(owner, SidTypeUser); if (!owner_sid) { return false; } } if ( !group.empty() ) { group_sid = x_GetAccountSidByName(group, SidTypeGroup); if (!group_sid) { goto cleanup; } } if (uid || gid) { s_GetOwnerGroupFromSIDs(owner_sid, group_sid, NULL, NULL, uid, gid); } // Change owner SECURITY_INFORMATION security_info = 0; if ( owner_sid ) { security_info |= OWNER_SECURITY_INFORMATION; } if ( group_sid ) { security_info |= GROUP_SECURITY_INFORMATION; } // Set new owner/group in the object's security descriptor if ( SetNamedSecurityInfo((TXChar*)_T_XCSTRING(filename), SE_FILE_OBJECT, security_info, owner_sid, group_sid, NULL, NULL) == ERROR_SUCCESS ) { success = true; goto cleanup; } // If the previous call failed because access was denied, // enable the necessary admin privileges for the current thread and try again. token = s_GetThreadToken(TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY); if ( token == INVALID_HANDLE_VALUE) { goto cleanup; } bool prev_ownership_name; bool prev_restore_name; if ( !SetTokenPrivilege(token, SE_TAKE_OWNERSHIP_NAME, true, &prev_ownership_name) || !SetTokenPrivilege(token, SE_RESTORE_NAME, true, &prev_restore_name) ) { goto cleanup; } if ( SetNamedSecurityInfo((TXChar*)_T_XCSTRING(filename), SE_FILE_OBJECT, security_info, owner_sid, group_sid, NULL, NULL) == ERROR_SUCCESS ) { success = true; } // Restore privileges SetTokenPrivilege(token, SE_TAKE_OWNERSHIP_NAME, prev_ownership_name); SetTokenPrivilege(token, SE_RESTORE_NAME, prev_restore_name); cleanup: if ( owner_sid ) LocalFree(owner_sid); if ( group_sid ) LocalFree(group_sid); if ( token != INVALID_HANDLE_VALUE) CloseHandle(token); return success; }
bool perm::set_acls( const char *filename ) { PACL newDACL, oldDACL; PSECURITY_DESCRIPTOR pSD; DWORD err; EXPLICIT_ACCESS ea; PEXPLICIT_ACCESS entryList; ULONG entryCount; unsigned int i; pSD = NULL; newDACL = oldDACL = NULL; // If this is not on an NTFS volume, we're done. In fact, we'll // likely crash if we try all the below ACL junk on a volume which // does not support ACLs. Dooo! if ( !volume_has_acls(filename) ) { dprintf(D_FULLDEBUG, "perm::set_acls(%s): volume has no ACLS\n", filename); // return true (success) here, so upper layers do not consider // this a fatal error --- thus allowing us to run on FAT32. return true; } // Make sure we have the sid. if ( psid == NULL ) { dprintf(D_ALWAYS, "perm::set_acls(%s): do not have SID for user\n", filename); return false; } // first get the file's old DACL so we can copy it into the new one. err = GetNamedSecurityInfo((char*)filename, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, &oldDACL, NULL, &pSD); if ( ERROR_SUCCESS != err ) { // this is intentionally D_FULLDEBUG, since this error often occurs // if the caller doesn't have WRITE_DAC access to the path. The // remedy in that case is to call set_owner() on the path first. dprintf(D_FULLDEBUG, "perm::set_acls(%s): failed to get security info. " "err=%d\n", filename, err); return false; } // now, check to make sure we don't already have an entry in ACL // that matches the one we're about to insert. err = GetExplicitEntriesFromAcl(oldDACL, &entryCount, &entryList); if ( ERROR_SUCCESS != err ) { dprintf(D_ALWAYS, "perm::set_acls(%s): failed to get entries from ACL. " "err=%d\n", filename, err); LocalFree(oldDACL); return false; } for (i=0; i<entryCount; i++) { if ( ( entryList[i].grfAccessPermissions == GENERIC_ALL ) && ( entryList[i].grfAccessMode == GRANT_ACCESS ) && ( entryList[i].Trustee.TrusteeForm == TRUSTEE_IS_SID ) && ( EqualSid(entryList[i].Trustee.ptstrName, psid) ) ) { // MATCH - the ACE is already in the ACL, // so just return success. dprintf(D_FULLDEBUG, "set_acls() found a matching ACE already " "in the ACL, so skipping the add\n"); LocalFree(entryList); LocalFree(oldDACL); return true; } } // didn't find the ACE in there already, so proceed to add it. LocalFree(entryList); // now set up an EXPLICIT_ACCESS structure for the new ACE ZeroMemory(&ea, sizeof(EXPLICIT_ACCESS)); ea.grfAccessPermissions = GENERIC_ALL; ea.grfAccessMode = GRANT_ACCESS; ea.grfInheritance = SUB_CONTAINERS_AND_OBJECTS_INHERIT; ea.Trustee.pMultipleTrustee = NULL; ea.Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE; ea.Trustee.TrusteeForm = TRUSTEE_IS_SID; ea.Trustee.TrusteeType = TRUSTEE_IS_USER; ea.Trustee.ptstrName = (char*)psid; // create the new ACL with the new ACE err = SetEntriesInAcl(1, &ea, oldDACL, &newDACL); if ( ERROR_SUCCESS != err ) { dprintf(D_ALWAYS, "perm::set_acls(%s): failed to add new ACE " "(err=%d)\n", filename, err); LocalFree(oldDACL); return false; } // Attach new ACL to the file // PROTECTED_DACL_SECURITY_INFORMATION causes the function to NOT // inherit its parent's ACL. I believe this is what we want. err = SetNamedSecurityInfo((char*)filename, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION | PROTECTED_DACL_SECURITY_INFORMATION, NULL,NULL,newDACL,NULL); if ( err == ERROR_ACCESS_DENIED ) { // set the SE_SECURITY_NAME privilege and try again. dprintf(D_FULLDEBUG, "SetFileSecurity() failed; " "adding SE_SECURITY_NAME priv and trying again.\n"); HANDLE hToken = NULL; if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken)) { dprintf(D_ALWAYS, "perm: OpenProcessToken failed: %u\n", GetLastError()); } else { // Enable the SE_SECURITY_NAME privilege. if (!SetPrivilege(hToken, SE_SECURITY_NAME, TRUE)) { dprintf(D_ALWAYS, "perm: can't set SE_SECURITY_NAME privs " "to set ACLs.\n"); } else { err = SetNamedSecurityInfo((char*)filename, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION | PROTECTED_DACL_SECURITY_INFORMATION, NULL,NULL,newDACL,NULL); } CloseHandle(hToken); } } // clean up our memory. LocalFree(oldDACL); LocalFree(newDACL); if (err != ERROR_SUCCESS) { dprintf(D_ALWAYS, "perm::set_acls(%s): Unable to set file ACL" "(err=%d).\n", filename,GetLastError() ); return false; } return true; }
JNIEXPORT void JNICALL Java_com_microsoft_tfs_jni_internal_filesystem_NativeFileSystem_nativeRemoveExplicitAllowEntries( JNIEnv *env, jclass cls, jstring jPath, jstring jUserSIDString) { const WCHAR * path = NULL; const WCHAR * userSIDString = NULL; PSID userSID = NULL; DWORD result = 0; PACL dacl = NULL; PSECURITY_DESCRIPTOR securityDescriptor = NULL; ACL_SIZE_INFORMATION aclSizeInfo; ULONG aceCount = 0; BOOL modifiedDACL = FALSE; if (jPath == NULL) { throwRuntimeExceptionString(env, "path must not be null"); goto cleanup; } if (jUserSIDString == NULL) { throwRuntimeExceptionString(env, "user must not be null"); goto cleanup; } // Convert the SID string to a struct if ((userSIDString = javaStringToPlatformChars(env, jUserSIDString)) == NULL) { // String allocation failed, exception already thrown goto cleanup; } if (ConvertStringSidToSidW(userSIDString, &userSID) == FALSE) { throwRuntimeExceptionCode(env, GetLastError(), "Error converting string sid %S to sid", userSIDString); goto cleanup; } if ((path = javaStringToPlatformChars(env, jPath)) == NULL) { // String allocation failed, exception already thrown goto cleanup; } // Get file's DACL result = GetNamedSecurityInfo(path, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, &dacl, NULL, &securityDescriptor); if (result != ERROR_SUCCESS) { throwRuntimeExceptionCode(env, result, "Error getting file security info for %S", path); goto cleanup; } // Get the count of entries int the DACL if (GetAclInformation(dacl, &aclSizeInfo, sizeof(aclSizeInfo), AclSizeInformation) == 0) { throwRuntimeExceptionCode(env, GetLastError(), "Error getting DACL"); goto cleanup; } // Loop over the DACL backwards, removing matching entries for (aceCount = aclSizeInfo.AceCount; aceCount > 0; aceCount--) { ULONG aceIndex = aceCount - 1; ACCESS_ALLOWED_ACE * ace = NULL; PSID sid = NULL; if (GetAce(dacl, aceIndex, (LPVOID *) &ace) == 0) { throwRuntimeExceptionCode(env, GetLastError(), "Error getting ACE at index %d", aceIndex); goto cleanup; } // Skip inherited (non-explicit) entries if ((((ACE_HEADER *) ace)->AceFlags & INHERITED_ACE) == INHERITED_ACE) { continue; } // Extract the SID for "allow" types switch(((ACE_HEADER *) ace)->AceType) { case ACCESS_ALLOWED_ACE_TYPE: sid = (PSID) &((ACCESS_ALLOWED_ACE *) ace)->SidStart; break; case ACCESS_ALLOWED_CALLBACK_ACE_TYPE: sid = (PSID) &((ACCESS_ALLOWED_CALLBACK_ACE *) ace)->SidStart; break; case ACCESS_ALLOWED_CALLBACK_OBJECT_ACE_TYPE: sid = (PSID) &((ACCESS_ALLOWED_CALLBACK_OBJECT_ACE *) ace)->SidStart; break; case ACCESS_ALLOWED_OBJECT_ACE_TYPE: sid = (PSID) &((ACCESS_ALLOWED_OBJECT_ACE *) ace)->SidStart; break; default: // These are "deny" or other entries break; } if (sid != NULL && EqualSid(sid, userSID)) { if (DeleteAce(dacl, aceIndex) == 0) { throwRuntimeExceptionCode(env, GetLastError(), "Error deleting ACE at index %d", aceIndex); goto cleanup; } modifiedDACL = TRUE; } // Nothing to free in the loop, all pointers are into dacl } if (modifiedDACL) { result = SetNamedSecurityInfo((WCHAR *) path, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, dacl, NULL); if (result != ERROR_SUCCESS) { throwRuntimeExceptionCode(env, result, "Error setting security info for %S", path); goto cleanup; } } cleanup: if (path != NULL) { releasePlatformChars(env, jPath, path); } if (userSID != NULL) { LocalFree(userSID); } if (userSIDString != NULL) { releasePlatformChars(env, jUserSIDString, userSIDString); } // dacl points inside securityDescriptor if (securityDescriptor != NULL) { LocalFree(securityDescriptor); } }
JNIEXPORT void JNICALL Java_com_microsoft_tfs_jni_internal_filesystem_NativeFileSystem_nativeCopyExplicitDACLEntries( JNIEnv *env, jclass cls, jstring jSourcePath, jstring jTargetPath) { const WCHAR * sourcePath = NULL; const WCHAR * targetPath = NULL; DWORD result = 0; PACL sourceDACL = NULL; PACL targetDACL = NULL; PACL newDACL = NULL; PSECURITY_DESCRIPTOR sourceSecurityDescriptor = NULL; PSECURITY_DESCRIPTOR targetSecurityDescriptor = NULL; PEXPLICIT_ACCESS sourceExplicitEntries = NULL; ULONG sourceExplicitEntriesCount = 0; if (jSourcePath == NULL) { throwRuntimeExceptionString(env, "source path must not be null"); goto cleanup; } if (jTargetPath == NULL) { throwRuntimeExceptionString(env, "target path must not be null"); goto cleanup; } if ((sourcePath = javaStringToPlatformChars(env, jSourcePath)) == NULL) { // String allocation failed, exception already thrown goto cleanup; } if ((targetPath = javaStringToPlatformChars(env, jTargetPath)) == NULL) { // String allocation failed, exception already thrown goto cleanup; } // Get source's DACL result = GetNamedSecurityInfo(sourcePath, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, &sourceDACL, NULL, &sourceSecurityDescriptor); if (result != ERROR_SUCCESS) { throwRuntimeExceptionCode(env, result, "Error getting security info for %S", sourcePath); goto cleanup; } // Get the explicit entries in the source DACL result = GetExplicitEntriesFromAcl(sourceDACL, &sourceExplicitEntriesCount, &sourceExplicitEntries); if (result != ERROR_SUCCESS) { throwRuntimeExceptionCode(env, result, "Error getting ACL entries"); goto cleanup; } if (sourceExplicitEntries == 0) { goto cleanup; } // Get target's DACL result = GetNamedSecurityInfo(targetPath, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, &targetDACL, NULL, &targetSecurityDescriptor); if (result != ERROR_SUCCESS) { throwRuntimeExceptionCode(env, result, "Error getting security info for %S", targetPath); goto cleanup; } // Merge the source entries into the target list result = SetEntriesInAcl(sourceExplicitEntriesCount, sourceExplicitEntries, targetDACL, &newDACL); if (result != ERROR_SUCCESS) { throwRuntimeExceptionCode(env, result, "Error setting entries in ACL"); goto cleanup; } // Set the list on the target path result = SetNamedSecurityInfo((WCHAR *) targetPath, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, newDACL, NULL); if (result != ERROR_SUCCESS) { throwRuntimeExceptionCode(env, result, "Error setting security info for %S", targetPath); goto cleanup; } cleanup: if (sourcePath != NULL) { releasePlatformChars(env, jSourcePath, sourcePath); } if (targetPath != NULL) { releasePlatformChars(env, jTargetPath, targetPath); } // sourceDACL points into sourceSecurityDescriptor if (sourceSecurityDescriptor != NULL) { LocalFree(sourceSecurityDescriptor); } // targetDACL points into targetSecurityDescriptor if (targetSecurityDescriptor != NULL) { LocalFree(targetSecurityDescriptor); } if (sourceExplicitEntries != NULL) { LocalFree(sourceExplicitEntries); } if (newDACL != NULL) { LocalFree(newDACL); } }
BOOL TakeOwnership (LPTSTR lpszOwnFile) { BOOL bRetval = FALSE; HANDLE hToken = NULL; PSID pSIDAdmin = NULL; PSID pSIDEveryone = NULL; PACL pACL = NULL; SID_IDENTIFIER_AUTHORITY SIDAuthWorld = SECURITY_WORLD_SID_AUTHORITY; SID_IDENTIFIER_AUTHORITY SIDAuthNT = SECURITY_NT_AUTHORITY; const int NUM_ACES = 2; EXPLICIT_ACCESS ea [NUM_ACES]; DWORD dwRes; // Specify the DACL to use. // Create a SID for the Everyone group. if (!AllocateAndInitializeSid (&SIDAuthWorld, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, &pSIDEveryone)) { //printf ("AllocateAndInitializeSid (Everyone) error %u\n", //GetLastError ()); goto Cleanup; } // 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 (Admin) error %u\n", //GetLastError ()); goto Cleanup; } ZeroMemory (&ea, NUM_ACES * sizeof (EXPLICIT_ACCESS)); // Set full control for Everyone. ea [0].grfAccessPermissions = GENERIC_ALL;// GENERIC_READ; 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 (ERROR_SUCCESS != SetEntriesInAcl (NUM_ACES, ea, NULL, &pACL)) { //printf ("Failed SetEntriesInAcl\n"); goto Cleanup; } // Try to modify the object's DACL. dwRes = SetNamedSecurityInfo ( lpszOwnFile, // 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 (ERROR_SUCCESS == dwRes) { //printf ("Successfully changed DACL\n"); bRetval = TRUE; // No more processing needed. goto Cleanup; } if (dwRes != ERROR_ACCESS_DENIED) { //printf ("First SetNamedSecurityInfo call failed: %u\n", //dwRes); goto Cleanup; } // If the preceding 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. if (!OpenProcessToken (GetCurrentProcess (), TOKEN_ADJUST_PRIVILEGES, &hToken)) { //printf ("OpenProcessToken failed: %u\n", GetLastError ()); goto Cleanup; } // Enable the SE_TAKE_OWNERSHIP_NAME privilege. if (!SetPrivilege (hToken, SE_TAKE_OWNERSHIP_NAME, TRUE)) { //printf ("You must be logged on as Administrator.\n"); goto Cleanup; } // Set the owner in the object's security descriptor. dwRes = SetNamedSecurityInfo ( lpszOwnFile, // 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 ("Could not set owner. Error: %u\n", dwRes); goto Cleanup; } // Disable the SE_TAKE_OWNERSHIP_NAME privilege. if (!SetPrivilege (hToken, SE_TAKE_OWNERSHIP_NAME, FALSE)) { //printf ("Failed SetPrivilege call unexpectedly.\n"); goto Cleanup; } // Try again to modify the object's DACL, // now that we are the owner. dwRes = SetNamedSecurityInfo ( lpszOwnFile, // 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 ("Successfully changed DACL\n"); bRetval = TRUE; } else { //printf ("Second SetNamedSecurityInfo call failed: %u\n", //dwRes); } Cleanup: if (pSIDAdmin) FreeSid (pSIDAdmin); if (pSIDEveryone) FreeSid (pSIDEveryone); if (pACL) LocalFree (pACL); if (hToken) CloseHandle (hToken); return bRetval; }
JNIEXPORT void JNICALL Java_com_microsoft_tfs_jni_internal_filesystem_NativeFileSystem_nativeGrantInheritableFullControl( JNIEnv *env, jclass cls, jstring jPath, jstring jUserSIDString, jstring jCopyExplicitRulesFromPath) { const WCHAR * path = NULL; const WCHAR * userSIDString = NULL; const WCHAR * copyExplicitRulesFromPath = NULL; DWORD result = 0; PACL existingDACL = NULL; PACL newDACL = NULL; PSECURITY_DESCRIPTOR securityDescriptor = NULL; PSID userSID = NULL; EXPLICIT_ACCESS fullControl; if (jPath == NULL) { throwRuntimeExceptionString(env, "path must not be null"); goto cleanup; } if (jUserSIDString == NULL) { throwRuntimeExceptionString(env, "user must not be null"); goto cleanup; } // Get the existing DACL entries if (jCopyExplicitRulesFromPath != NULL) { if ((copyExplicitRulesFromPath = javaStringToPlatformChars(env, jCopyExplicitRulesFromPath)) == NULL) { // String allocation failed, exception already thrown goto cleanup; } result = GetNamedSecurityInfo(copyExplicitRulesFromPath, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, &existingDACL, NULL, &securityDescriptor); if (result != ERROR_SUCCESS) { throwRuntimeExceptionCode(env, result, "Error getting file security info for %S", copyExplicitRulesFromPath); goto cleanup; } } // Convert the string SID to a structure if ((userSIDString = javaStringToPlatformChars(env, jUserSIDString)) == NULL) { // String allocation failed, exception already thrown goto cleanup; } if (ConvertStringSidToSidW(userSIDString, &userSID) == FALSE) { throwRuntimeExceptionCode(env, GetLastError(), "Error converting string sid %S to sid", userSIDString); goto cleanup; } /* * Create a new explicit access entry with rights equivalent to .NET's * FileSystemRights.FullControl (0x1F01FF; see FileSecurity.cs) and * full inheritance. */ ZeroMemory(&fullControl, sizeof(EXPLICIT_ACCESS)); fullControl.grfAccessPermissions = 0x1F01FF; fullControl.grfAccessMode = GRANT_ACCESS; fullControl.grfInheritance= CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE; fullControl.Trustee.TrusteeForm = TRUSTEE_IS_SID; fullControl.Trustee.TrusteeType = TRUSTEE_IS_USER; fullControl.Trustee.ptstrName = userSID; // Merge new entry with old entries into a new list result = SetEntriesInAcl(1, &fullControl, existingDACL, &newDACL); if (result != ERROR_SUCCESS) { throwRuntimeExceptionCode(env, result, "Error setting entries in ACL"); goto cleanup; } // Set the list on the path if ((path = javaStringToPlatformChars(env, jPath)) == NULL) { // String allocation failed, exception already thrown goto cleanup; } result = SetNamedSecurityInfo((WCHAR *) path, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, newDACL, NULL); if (result != ERROR_SUCCESS) { throwRuntimeExceptionCode(env, result, "Error setting file security info for %S", path); goto cleanup; } cleanup: if (path != NULL) { releasePlatformChars(env, jPath, path); } if (userSIDString != NULL) { releasePlatformChars(env, jUserSIDString, userSIDString); } if (copyExplicitRulesFromPath != NULL) { releasePlatformChars(env, jCopyExplicitRulesFromPath, copyExplicitRulesFromPath); } if (securityDescriptor != NULL) { LocalFree(securityDescriptor); } if (userSID != NULL) { LocalFree(userSID); } if (newDACL != NULL) { LocalFree(newDACL); } // existingDACL points inside securityDescriptor }
/** * @todo Format code style. * @todo Add full unicode support. * @todo Add event log capabilities / check return values. */ static DWORD vboxServiceWinAddAceToObjectsSecurityDescriptor(LPTSTR pszObjName, SE_OBJECT_TYPE ObjectType, LPTSTR pszTrustee, TRUSTEE_FORM TrusteeForm, DWORD dwAccessRights, ACCESS_MODE AccessMode, DWORD dwInheritance) { DWORD dwRes = 0; PACL pOldDACL = NULL, pNewDACL = NULL; PSECURITY_DESCRIPTOR pSD = NULL; EXPLICIT_ACCESS ea; if (NULL == pszObjName) return ERROR_INVALID_PARAMETER; /* Get a pointer to the existing DACL. */ dwRes = GetNamedSecurityInfo(pszObjName, ObjectType, DACL_SECURITY_INFORMATION, NULL, NULL, &pOldDACL, NULL, &pSD); if (ERROR_SUCCESS != dwRes) { if (dwRes == ERROR_FILE_NOT_FOUND) VBoxServiceError("AddAceToObjectsSecurityDescriptor: Object not found/installed: %s\n", pszObjName); else VBoxServiceError("AddAceToObjectsSecurityDescriptor: GetNamedSecurityInfo: Error %u\n", dwRes); goto l_Cleanup; } /* Initialize an EXPLICIT_ACCESS structure for the new ACE. */ ZeroMemory(&ea, sizeof(EXPLICIT_ACCESS)); ea.grfAccessPermissions = dwAccessRights; ea.grfAccessMode = AccessMode; ea.grfInheritance= dwInheritance; ea.Trustee.TrusteeForm = TrusteeForm; ea.Trustee.ptstrName = pszTrustee; /* Create a new ACL that merges the new ACE into the existing DACL. */ dwRes = SetEntriesInAcl(1, &ea, pOldDACL, &pNewDACL); if (ERROR_SUCCESS != dwRes) { VBoxServiceError("AddAceToObjectsSecurityDescriptor: SetEntriesInAcl: Error %u\n", dwRes); goto l_Cleanup; } /* Attach the new ACL as the object's DACL. */ dwRes = SetNamedSecurityInfo(pszObjName, ObjectType, DACL_SECURITY_INFORMATION, NULL, NULL, pNewDACL, NULL); if (ERROR_SUCCESS != dwRes) { VBoxServiceError("AddAceToObjectsSecurityDescriptor: SetNamedSecurityInfo: Error %u\n", dwRes); goto l_Cleanup; } /** @todo get rid of that spaghetti jump ... */ l_Cleanup: if(pSD != NULL) LocalFree((HLOCAL) pSD); if(pNewDACL != NULL) LocalFree((HLOCAL) pNewDACL); return dwRes; }
void setSecurityACLs() { CString fullPath = getPathToCurrentExeContainer(); // Check to make sure that the dll has the ACLs to load in an appcontainer // We're doing this here as the adapter has no setup script and should be xcopy deployable/removeable PACL pOldDACL = NULL, pNewDACL = NULL; PSECURITY_DESCRIPTOR pSD = NULL; EXPLICIT_ACCESS ea; SECURITY_INFORMATION si = DACL_SECURITY_INFORMATION; // The check is done on the folder and should be inherited to all objects DWORD dwRes = GetNamedSecurityInfo(fullPath, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, &pOldDACL, NULL, &pSD); // Get the SID for "ALL APPLICATION PACAKGES" since it is localized PSID pAllAppPackagesSID = NULL; bool bResult = ConvertStringSidToSid(L"S-1-15-2-1", &pAllAppPackagesSID); if (bResult) { // Initialize an EXPLICIT_ACCESS structure for the new ACE. ZeroMemory(&ea, sizeof(EXPLICIT_ACCESS)); ea.grfAccessPermissions = GENERIC_READ | GENERIC_EXECUTE; ea.grfAccessMode = SET_ACCESS; ea.grfInheritance = SUB_CONTAINERS_AND_OBJECTS_INHERIT; ea.Trustee.TrusteeForm = TRUSTEE_IS_SID;; ea.Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP; ea.Trustee.ptstrName = (LPTSTR)pAllAppPackagesSID; // Create a new ACL that merges the new ACE into the existing DACL. dwRes = SetEntriesInAcl(1, &ea, pOldDACL, &pNewDACL); if (dwRes == ERROR_SUCCESS) { dwRes = SetNamedSecurityInfo(fullPath.GetBuffer(), SE_FILE_OBJECT, si, NULL, NULL, pNewDACL, NULL); if (dwRes == ERROR_SUCCESS) { } else { // The ACL was not set, this isn't fatal as it only impacts IE in EPM and Edge and the user can set it manually wcout << L"Could not set ACL to allow access to IE EPM or Edge."; wcout << L"\n"; wcout << Helpers::GetLastErrorMessage().GetBuffer(); wcout << L"\n"; wcout << L"You can set the ACL manually by adding Read & Execute permissions for 'All APPLICATION PACAKGES' to each dll."; wcout << L"\n"; } } } else { std::cerr << "Failed to get the SID for ALL_APP_PACKAGES." << std::endl; std::cerr << "Win32 error code: " << GetLastError() << std::endl; } if (pAllAppPackagesSID != NULL) { LocalFree(pAllAppPackagesSID); } if (pSD != NULL) { LocalFree((HLOCAL)pSD); } if (pNewDACL != NULL) { LocalFree((HLOCAL)pNewDACL); } }
BOOL SetOwner(LPCTSTR filename, LPCTSTR newOwner) { PSID sid = nullptr; BOOL res = TRUE; PACL pacl = nullptr; // get the SID for the new owner TCHAR domainUnused[4096]; DWORD sidSize = 0; DWORD domainBufSize = 4096; SID_NAME_USE sidUse; // pre-flight to determine required size of the sid LookupAccountName(nullptr, newOwner, nullptr, &sidSize, domainUnused, &domainBufSize, &sidUse); sid = (PSID)malloc(sidSize); // determine sid for account name if (!LookupAccountName(nullptr, newOwner, sid, &sidSize, domainUnused, &domainBufSize, &sidUse)) { qCritical("failed to look up account name: %ls", newOwner); res = FALSE; } else { EXPLICIT_ACCESS access; ZeroMemory(&access, sizeof(EXPLICIT_ACCESS)); wchar_t ownerTemp[UNLEN + 1]; wcsncpy(ownerTemp, newOwner, UNLEN + 1); // Set full control for Administrators. access.grfAccessPermissions = GENERIC_ALL; access.grfAccessMode = SET_ACCESS; access.grfInheritance = SUB_CONTAINERS_AND_OBJECTS_INHERIT; access.Trustee.TrusteeForm = TRUSTEE_IS_SID; access.Trustee.TrusteeType = TRUSTEE_IS_GROUP; access.Trustee.ptstrName = (LPTSTR)sid; DWORD secRes = SetEntriesInAcl(1, &access, nullptr, &pacl); if (secRes != ERROR_SUCCESS) { qCritical("failed to set up acls: %lu", secRes); return FALSE; } // filename parameter for SetNamedSecurityInfo isn't const // which is odd since it is documented to be a input parameter... TCHAR *fileNameBuf = new TCHAR[32768]; wcsncpy_s(fileNameBuf, 32768, filename, 32768); // Set the owner on the file and give him full access secRes = SetNamedSecurityInfo( fileNameBuf, SE_FILE_OBJECT, OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION, sid, nullptr, pacl, nullptr); delete [] fileNameBuf; if (secRes != NOERROR) { qCritical("failed to set file owner: %d", secRes); res = false; } } if (sid != nullptr) { free(sid); } return res; }
///////////////////////////////////////////////////////////////////// // // Function: // // Description: // ///////////////////////////////////////////////////////////////////// UINT CARestorePermissionBOINCData::OnExecution() { DWORD dwRes = 0; PACL pACL = NULL; ULONGLONG rgSidSY[(SECURITY_MAX_SID_SIZE+sizeof(ULONGLONG)-1)/sizeof(ULONGLONG)]={0}; ULONGLONG rgSidBA[(SECURITY_MAX_SID_SIZE+sizeof(ULONGLONG)-1)/sizeof(ULONGLONG)]={0}; DWORD dwSidSize; EXPLICIT_ACCESS ea[2]; ULONG ulEntries = 0; tstring strBOINCDataDirectory; UINT uiReturnValue = -1; uiReturnValue = GetProperty( _T("DATADIR"), strBOINCDataDirectory ); if ( uiReturnValue ) return uiReturnValue; // Initialize an EXPLICIT_ACCESS structure for all ACEs. ZeroMemory(&ea, 2 * sizeof(EXPLICIT_ACCESS)); // Create a SID for the SYSTEM. dwSidSize = sizeof( rgSidSY ); if(!CreateWellKnownSid(WinLocalSystemSid, NULL, rgSidSY, &dwSidSize)) { LogMessage( INSTALLMESSAGE_ERROR, NULL, NULL, NULL, GetLastError(), _T("CreateWellKnownSid Error for SYSTEM") ); return ERROR_INSTALL_FAILURE; } // Create a SID for the Administrators group. dwSidSize = sizeof( rgSidBA ); if(!CreateWellKnownSid(WinBuiltinAdministratorsSid, NULL, rgSidBA, &dwSidSize)) { LogMessage( INSTALLMESSAGE_ERROR, NULL, NULL, NULL, GetLastError(), _T("CreateWellKnownSid Error for BUILTIN\\Administrators") ); return ERROR_INSTALL_FAILURE; } ulEntries = 2; // SYSTEM ea[0].grfAccessPermissions = GENERIC_ALL; ea[0].grfAccessMode = SET_ACCESS; ea[0].grfInheritance = SUB_CONTAINERS_AND_OBJECTS_INHERIT; ea[0].Trustee.TrusteeForm = TRUSTEE_IS_SID; ea[0].Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP; ea[0].Trustee.ptstrName = (LPTSTR)rgSidSY; // Administrators ea[1].grfAccessPermissions = GENERIC_ALL; ea[1].grfAccessMode = SET_ACCESS; ea[1].grfInheritance = SUB_CONTAINERS_AND_OBJECTS_INHERIT; ea[1].Trustee.TrusteeForm = TRUSTEE_IS_SID; ea[1].Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP; ea[1].Trustee.ptstrName = (LPTSTR)rgSidBA; // Create a new ACL that contains the new ACEs. dwRes = SetEntriesInAcl(ulEntries, &ea[0], NULL, &pACL); if (ERROR_SUCCESS != dwRes) { LogMessage( INSTALLMESSAGE_INFO, NULL, NULL, NULL, GetLastError(), _T("SetEntriesInAcl Error") ); LogMessage( INSTALLMESSAGE_ERROR, NULL, NULL, NULL, GetLastError(), _T("SetEntriesInAcl Error") ); return ERROR_INSTALL_FAILURE; } // Set the ACL on the Data Directory itself. dwRes = SetNamedSecurityInfo( (LPWSTR)strBOINCDataDirectory.c_str(), SE_FILE_OBJECT, DACL_SECURITY_INFORMATION | PROTECTED_DACL_SECURITY_INFORMATION, NULL, NULL, pACL, NULL ); if (ERROR_SUCCESS != dwRes) { LogMessage( INSTALLMESSAGE_INFO, NULL, NULL, NULL, GetLastError(), _T("SetNamedSecurityInfo Error") ); LogMessage( INSTALLMESSAGE_ERROR, NULL, NULL, NULL, GetLastError(), _T("SetNamedSecurityInfo Error") ); return ERROR_INSTALL_FAILURE; } // Set ACLs on all files and sub folders. RecursiveSetPermissions(strBOINCDataDirectory, pACL); if (pACL) LocalFree(pACL); return ERROR_SUCCESS; }
bool CSecRunAsUser::SetObjectPermission(CString strDirFile, DWORD lGrantedAccess){ if (!m_hADVAPI32_DLL){ ASSERT ( false ); return false; } if ( strDirFile.IsEmpty() ) return true; SID_NAME_USE snuType; TCHAR* szDomain = NULL; LPVOID pUserSID = NULL; PACL pNewACL = NULL; PSECURITY_DESCRIPTOR pSD = NULL; BOOL fAPISuccess; try { // get user sid DWORD cbDomain = 0; DWORD cbUserSID = 0; fAPISuccess = LookupAccountName(NULL, EMULEACCOUNTW, pUserSID, &cbUserSID, szDomain, &cbDomain, &snuType); if ( (!fAPISuccess) && GetLastError() != ERROR_INSUFFICIENT_BUFFER) throw CString(_T("Run as unpriveleged user: Error: LookupAccountName() failed,")); pUserSID = MHeapAlloc(cbUserSID); if (!pUserSID) throw CString(_T("Run as unpriveleged user: Error: Allocating memory failed,")); szDomain = (TCHAR*)MHeapAlloc(cbDomain * sizeof(TCHAR)); if (!szDomain) throw CString(_T("Run as unpriveleged user: Error: Allocating memory failed,")); fAPISuccess = LookupAccountName(NULL, EMULEACCOUNTW, pUserSID, &cbUserSID, szDomain, &cbDomain, &snuType); if (!fAPISuccess) throw CString(_T("Run as unpriveleged user: Error: LookupAccountName()2 failed")); if (CStringW(szDomain) != m_strDomain) throw CString(_T("Run as unpriveleged user: Logical Error: Domainname mismatch")); // get old ACL PACL pOldACL = NULL; fAPISuccess = GetNamedSecurityInfo(strDirFile.GetBuffer(), SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, &pOldACL, NULL, &pSD); strDirFile.ReleaseBuffer(); if (fAPISuccess != ERROR_SUCCESS){ throw CString(_T("Run as unpriveleged user: Error: GetNamedSecurityInfo() failed")); } // calculate size for new ACL ACL_SIZE_INFORMATION AclInfo; AclInfo.AceCount = 0; // Assume NULL DACL. AclInfo.AclBytesFree = 0; AclInfo.AclBytesInUse = sizeof(ACL); if (pOldACL != NULL && !GetAclInformation(pOldACL, &AclInfo, sizeof(ACL_SIZE_INFORMATION), AclSizeInformation)) throw CString(_T("Run as unpriveleged user: Error: GetAclInformation() failed")); // Create new ACL DWORD cbNewACL = AclInfo.AclBytesInUse + sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(pUserSID) - sizeof(DWORD); pNewACL = (PACL)MHeapAlloc(cbNewACL); if (!pNewACL) throw CString(_T("Run as unpriveleged user: Error: Allocating memory failed,")); if (!InitializeAcl(pNewACL, cbNewACL, ACL_REVISION2)) throw CString(_T("Run as unpriveleged user: Error: Allocating memory failed,")); // copy the entries form the old acl into the new one and enter a new ace in the right order uint32 newAceIndex = 0; uint32 CurrentAceIndex = 0; if (AclInfo.AceCount) { for (CurrentAceIndex = 0; CurrentAceIndex < AclInfo.AceCount; CurrentAceIndex++) { LPVOID pTempAce = NULL; if (!GetAce(pOldACL, CurrentAceIndex, &pTempAce)) throw CString(_T("Run as unpriveleged user: Error: GetAce() failed,")); if (((ACCESS_ALLOWED_ACE *)pTempAce)->Header.AceFlags & INHERITED_ACE) break; // no multiple entries if (EqualSid(pUserSID, &(((ACCESS_ALLOWED_ACE *)pTempAce)->SidStart))) continue; if (!AddAce(pNewACL, ACL_REVISION, MAXDWORD, pTempAce, ((PACE_HEADER) pTempAce)->AceSize)) throw CString(_T("Run as unpriveleged user: Error: AddAce()1 failed,")); newAceIndex++; } } // here we add the actually entry if (!AddAccessAllowedAceEx(pNewACL, ACL_REVISION2, CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE, lGrantedAccess, pUserSID)) throw CString(_T("Run as unpriveleged user: Error: AddAccessAllowedAceEx() failed,")); // copy the rest if (AclInfo.AceCount) { for (; CurrentAceIndex < AclInfo.AceCount; CurrentAceIndex++) { LPVOID pTempAce = NULL; if (!GetAce(pOldACL, CurrentAceIndex, &pTempAce)) throw CString(_T("Run as unpriveleged user: Error: GetAce()2 failed,")); if (!AddAce(pNewACL, ACL_REVISION, MAXDWORD, pTempAce, ((PACE_HEADER) pTempAce)->AceSize)) throw CString(_T("Run as unpriveleged user: Error: AddAce()2 failed,")); } } fAPISuccess = SetNamedSecurityInfo(strDirFile.GetBuffer(), SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, pNewACL, NULL); strDirFile.ReleaseBuffer(); if (fAPISuccess != ERROR_SUCCESS) throw CString(_T("Run as unpriveleged user: Error: SetNamedSecurityInfo() failed,")); fAPISuccess = TRUE; } catch(CString error){ fAPISuccess = FALSE; theApp.QueueDebugLogLine(false, error); } // clean up if (pUserSID != NULL) MHeapFree(pUserSID); if (szDomain != NULL) MHeapFree(szDomain); if (pNewACL != NULL) MHeapFree(pNewACL); if (pSD != NULL) LocalFree(pSD); // finished return fAPISuccess!=FALSE; }
///////////////////////////////////////////////////////////////////// // // Function: // // Description: // ///////////////////////////////////////////////////////////////////// UINT CASetPermissionBOINCDataProjects::OnExecution() { DWORD dwRes = 0; PACL pACL = NULL; ULONGLONG rgSidSY[(SECURITY_MAX_SID_SIZE+sizeof(ULONGLONG)-1)/sizeof(ULONGLONG)]={0}; ULONGLONG rgSidBA[(SECURITY_MAX_SID_SIZE+sizeof(ULONGLONG)-1)/sizeof(ULONGLONG)]={0}; ULONGLONG rgSidBU[(SECURITY_MAX_SID_SIZE+sizeof(ULONGLONG)-1)/sizeof(ULONGLONG)]={0}; DWORD dwSidSize; EXPLICIT_ACCESS ea[6]; ULONG ulEntries = 0; tstring strBOINCAdminsGroupAlias; tstring strBOINCUsersGroupAlias; tstring strBOINCProjectsGroupAlias; tstring strBOINCDataDirectory; tstring strBOINCDataProjectsDirectory; tstring strEnableProtectedApplicationExecution; tstring strEnableUseByAllUsers; UINT uiReturnValue = -1; uiReturnValue = GetProperty( _T("BOINC_ADMINS_GROUPNAME"), strBOINCAdminsGroupAlias ); if ( uiReturnValue ) return uiReturnValue; uiReturnValue = GetProperty( _T("BOINC_USERS_GROUPNAME"), strBOINCUsersGroupAlias ); if ( uiReturnValue ) return uiReturnValue; uiReturnValue = GetProperty( _T("BOINC_PROJECTS_GROUPNAME"), strBOINCProjectsGroupAlias ); if ( uiReturnValue ) return uiReturnValue; uiReturnValue = GetProperty( _T("DATADIR"), strBOINCDataDirectory ); if ( uiReturnValue ) return uiReturnValue; uiReturnValue = GetProperty( _T("ENABLEPROTECTEDAPPLICATIONEXECUTION3"), strEnableProtectedApplicationExecution ); if ( uiReturnValue ) return uiReturnValue; uiReturnValue = GetProperty( _T("ENABLEUSEBYALLUSERS"), strEnableUseByAllUsers ); if ( uiReturnValue ) return uiReturnValue; // If we are not installing as a service, we do not need to modify the // projects directory permissions if (_T("1") != strEnableProtectedApplicationExecution) { return ERROR_SUCCESS; } strBOINCDataProjectsDirectory = strBOINCDataDirectory + _T("\\projects"); // Initialize an EXPLICIT_ACCESS structure for all ACEs. ZeroMemory(&ea, 6 * sizeof(EXPLICIT_ACCESS)); // Create a SID for the SYSTEM. dwSidSize = sizeof( rgSidSY ); if(!CreateWellKnownSid(WinLocalSystemSid, NULL, rgSidSY, &dwSidSize)) { LogMessage( INSTALLMESSAGE_ERROR, NULL, NULL, NULL, GetLastError(), _T("CreateWellKnownSid Error for SYSTEM") ); return ERROR_INSTALL_FAILURE; } // Create a SID for the Administrators group. dwSidSize = sizeof( rgSidBA ); if(!CreateWellKnownSid(WinBuiltinAdministratorsSid, NULL, rgSidBA, &dwSidSize)) { LogMessage( INSTALLMESSAGE_ERROR, NULL, NULL, NULL, GetLastError(), _T("CreateWellKnownSid Error for BUILTIN\\Administrators") ); return ERROR_INSTALL_FAILURE; } // Create a SID for the Users group. dwSidSize = sizeof( rgSidBU ); if(!CreateWellKnownSid(WinBuiltinUsersSid, NULL, rgSidBU, &dwSidSize)) { LogMessage( INSTALLMESSAGE_ERROR, NULL, NULL, NULL, GetLastError(), _T("CreateWellKnownSid Error for BUILTIN\\Users") ); return ERROR_INSTALL_FAILURE; } ulEntries = 5; // SYSTEM ea[0].grfAccessPermissions = GENERIC_ALL; ea[0].grfAccessMode = SET_ACCESS; ea[0].grfInheritance= SUB_CONTAINERS_AND_OBJECTS_INHERIT; ea[0].Trustee.TrusteeForm = TRUSTEE_IS_SID; ea[0].Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP; ea[0].Trustee.ptstrName = (LPTSTR)rgSidSY; // Administrators ea[1].grfAccessPermissions = GENERIC_ALL; ea[1].grfAccessMode = SET_ACCESS; ea[1].grfInheritance= SUB_CONTAINERS_AND_OBJECTS_INHERIT; ea[1].Trustee.TrusteeForm = TRUSTEE_IS_SID; ea[1].Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP; ea[1].Trustee.ptstrName = (LPTSTR)rgSidBA; // boinc_admins ea[2].grfAccessPermissions = GENERIC_ALL; ea[2].grfAccessMode = SET_ACCESS; ea[2].grfInheritance= SUB_CONTAINERS_AND_OBJECTS_INHERIT; ea[2].Trustee.TrusteeForm = TRUSTEE_IS_NAME; ea[2].Trustee.TrusteeType = TRUSTEE_IS_GROUP; ea[2].Trustee.ptstrName = (LPTSTR)strBOINCAdminsGroupAlias.c_str(); // boinc_users ea[3].grfAccessPermissions = GENERIC_READ|GENERIC_EXECUTE; ea[3].grfAccessMode = SET_ACCESS; ea[3].grfInheritance= SUB_CONTAINERS_AND_OBJECTS_INHERIT; ea[3].Trustee.TrusteeForm = TRUSTEE_IS_NAME; ea[3].Trustee.TrusteeType = TRUSTEE_IS_GROUP; ea[3].Trustee.ptstrName = (LPTSTR)strBOINCUsersGroupAlias.c_str(); // boinc_projects ea[4].grfAccessPermissions = GENERIC_ALL; ea[4].grfAccessMode = SET_ACCESS; ea[4].grfInheritance= SUB_CONTAINERS_AND_OBJECTS_INHERIT; ea[4].Trustee.TrusteeForm = TRUSTEE_IS_NAME; ea[4].Trustee.TrusteeType = TRUSTEE_IS_GROUP; ea[4].Trustee.ptstrName = (LPTSTR)strBOINCProjectsGroupAlias.c_str(); // Users if (_T("1") == strEnableUseByAllUsers) { ulEntries = 6; ea[5].grfAccessPermissions = GENERIC_READ|GENERIC_EXECUTE; ea[5].grfAccessMode = SET_ACCESS; ea[5].grfInheritance= SUB_CONTAINERS_AND_OBJECTS_INHERIT; ea[5].Trustee.TrusteeForm = TRUSTEE_IS_SID; ea[5].Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP; ea[5].Trustee.ptstrName = (LPTSTR)rgSidBU; } // Create a new ACL that contains the new ACEs. dwRes = SetEntriesInAcl(ulEntries, &ea[0], NULL, &pACL); if (ERROR_SUCCESS != dwRes) { LogMessage( INSTALLMESSAGE_INFO, NULL, NULL, NULL, GetLastError(), _T("SetEntriesInAcl Error") ); LogMessage( INSTALLMESSAGE_ERROR, NULL, NULL, NULL, GetLastError(), _T("SetEntriesInAcl Error") ); return ERROR_INSTALL_FAILURE; } // Set the ACL on the Data Directory itself. dwRes = SetNamedSecurityInfo( (LPWSTR)strBOINCDataProjectsDirectory.c_str(), SE_FILE_OBJECT, DACL_SECURITY_INFORMATION | PROTECTED_DACL_SECURITY_INFORMATION, NULL, NULL, pACL, NULL ); if (ERROR_SUCCESS != dwRes) { LogMessage( INSTALLMESSAGE_INFO, NULL, NULL, NULL, GetLastError(), _T("SetNamedSecurityInfo Error") ); LogMessage( INSTALLMESSAGE_ERROR, NULL, NULL, NULL, GetLastError(), _T("SetNamedSecurityInfo Error") ); return ERROR_INSTALL_FAILURE; } // Set ACLs on all files and sub folders. RecursiveSetPermissions(strBOINCDataProjectsDirectory, pACL); if (pACL) LocalFree(pACL); return ERROR_SUCCESS; }
BOOL CNTService::ModifyVistaDefaultAuditing(string dir, int remove) { PSECURITY_DESCRIPTOR pSD = NULL; HANDLE hToken; PACL mySacl=NULL; DWORD ret=0; TOKEN_PRIVILEGES tp; LUID luid; if ( !LookupPrivilegeValue(NULL,SE_SECURITY_NAME,&luid)) { printf("LookupPrivilegeValue error: %u\n", GetLastError() ); return FALSE; } tp.PrivilegeCount = 1; tp.Privileges[0].Luid = luid; tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; // Enable the privilege or disable all privileges. OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken); 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; } //recurse through the dir WIN32_FIND_DATA findData; char Match[32], Replace[32]; if (remove){ strncpy_s(Match,_countof(Match),"Everyone",_TRUNCATE); strncpy_s(Replace,_countof(Replace),"ANONYMOUS LOGON",_TRUNCATE); } else { strncpy_s(Match,_countof(Match),"ANONYMOUS LOGON",_TRUNCATE); strncpy_s(Replace,_countof(Replace),"Everyone",_TRUNCATE); } HANDLE hFind=FindFirstFile((dir+"\\*.*").c_str(), &findData); if (hFind == INVALID_HANDLE_VALUE) { return TRUE; } // iterate over file names in directory do { string sFileName(findData.cFileName); if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { // Directory if (sFileName != "." && sFileName != "..") { // descent recursively if (!ModifyVistaDefaultAuditing(dir+"\\"+sFileName, remove)) return FALSE; } } else { // File // grab and modify the file SACL ret = GetNamedSecurityInfo((char *)(dir+"\\"+findData.cFileName).c_str(),SE_FILE_OBJECT,SACL_SECURITY_INFORMATION,NULL,NULL,NULL,&mySacl,&pSD); if (ret == ERROR_SUCCESS && mySacl != NULL && mySacl->AceCount > 0) { int SetNewAcl=0; PACL pNewAcl; ACL_SIZE_INFORMATION aclSizeInfo; ZeroMemory(&aclSizeInfo, sizeof(ACL_SIZE_INFORMATION)); aclSizeInfo.AclBytesInUse = sizeof(ACL); if (!GetAclInformation(mySacl,(LPVOID)&aclSizeInfo,sizeof(ACL_SIZE_INFORMATION),AclSizeInformation)) { printf("Can't find ACL info, exiting\n"); return FALSE; } pNewAcl = (PACL)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,aclSizeInfo.AclBytesInUse); if (!pNewAcl) { printf("Can't allocate new ACL, exiting\n"); return FALSE; } if (!InitializeAcl(pNewAcl,aclSizeInfo.AclBytesInUse,ACL_REVISION)) { printf("Can't allocate new ACL, exiting\n"); return FALSE; } //printf("Checking: %s[%d]\n",(char *)(dir+"\\"+findData.cFileName).c_str(),mySacl->AceCount); for (int i=0; i< mySacl->AceCount; i++) { PVOID pAce;//PACE_HEADER? SID *pAceSid, *pNewAceSid=NULL; DWORD dwCbName = 0; DWORD dwCbDomainName = 0; SID_NAME_USE SidNameUse; TCHAR bufName[MAX_PATH]=""; TCHAR bufDomain[MAX_PATH]=""; ACCESS_MASK mask; SYSTEM_AUDIT_ACE *SA_Ace; TCHAR bufNewDomain[MAX_PATH]; DWORD dwNewCbDomainName = 0; DWORD dwSidSize = 0; dwNewCbDomainName = _countof(bufNewDomain); BOOL bSuccess; if (GetAce(mySacl,i,&pAce)) { if (((ACE_HEADER *)pAce)->AceType != SYSTEM_AUDIT_ACE_TYPE) { printf("ACE ERROR: not SYSTEM_AUDIT_ACE_TYPE\n"); continue; } SA_Ace = (SYSTEM_AUDIT_ACE *)pAce; pAceSid = (SID *)(&SA_Ace->SidStart); mask = SA_Ace->Mask; dwCbName = _countof(bufName); dwCbDomainName = _countof(bufDomain); bSuccess = LookupAccountSid(NULL, pAceSid, bufName, &dwCbName, bufDomain, &dwCbDomainName, &SidNameUse); if (!bSuccess) { printf("Failed to grab SID [%d]", GetLastError()); return FALSE; } //printf("ACE of %s\\%s: %d\n", bufDomain, bufName, mask); if (!strcmp(bufName,Match)) { bSuccess = LookupAccountName(NULL, Replace, NULL, &dwSidSize, bufNewDomain, &dwNewCbDomainName,&SidNameUse); if (!bSuccess && GetLastError() == ERROR_INSUFFICIENT_BUFFER) { pNewAceSid = (SID *)malloc(dwSidSize); if (!pNewAceSid) { printf("memory failed\n"); if (pNewAcl) HeapFree(GetProcessHeap(), 0, (LPVOID)pNewAcl); return FALSE; } bSuccess = LookupAccountName(NULL, Replace, pNewAceSid, &dwSidSize, bufNewDomain, &dwNewCbDomainName,&SidNameUse); if (bSuccess) { if (!AddAuditAccessAce(pNewAcl,ACL_REVISION,mask,pNewAceSid,TRUE,TRUE)) { printf("Failed to updated ACL[%d]\n",GetLastError()); free(pNewAceSid); if (pNewAcl) HeapFree(GetProcessHeap(), 0, (LPVOID)pNewAcl); return FALSE; } SetNewAcl=1; } else { printf("FAILED: %d\n", GetLastError()); //printf("\n"); } free(pNewAceSid); } else { printf("FAILED to find %s\n",Replace); } } else { if (!AddAce(pNewAcl,ACL_REVISION,MAXDWORD,pAce,((PACE_HEADER)pAce)->AceSize)) { printf("Couldn't add ACE to acl [%d]\n",GetLastError()); if (pNewAcl) HeapFree(GetProcessHeap(), 0, (LPVOID)pNewAcl); return FALSE; } } } else { printf("ACE error %d:%d[%d]\n",mySacl->AceCount,i,GetLastError()); return FALSE; } } if (SetNewAcl && pNewAcl) { ret = SetNamedSecurityInfo((char *)(dir+"\\"+findData.cFileName).c_str(),SE_FILE_OBJECT,SACL_SECURITY_INFORMATION,NULL,NULL,NULL,pNewAcl); if (ret == ERROR_SUCCESS) { printf("Fixed: %s\n",(char *)(dir+"\\"+findData.cFileName).c_str()); } else { printf("Failed to fix: %s\n",(char *)(dir+"\\"+findData.cFileName).c_str()); } } if (pNewAcl) HeapFree(GetProcessHeap(), 0, (LPVOID)pNewAcl); } else { if (ret) printf("fail %d %s\n", ret,(char *)(dir+"\\"+findData.cFileName).c_str()); //else printf("NO SACL: %s\n",(char *)(dir+"\\"+findData.cFileName).c_str()); } if (pSD) LocalFree(pSD); } } while (FindNextFile(hFind, &findData)); return TRUE; }
// allow different users to read\write\delete files in lock directory // in case of any error just log it and don't stop engine execution void adjustLockDirectoryAccess(const char* pathname) { PSECURITY_DESCRIPTOR pSecDesc = NULL; PSID pSID_Users = NULL; PSID pSID_Administrators = NULL; PACL pNewACL = NULL; try { // We should pass root directory in format "C:\" into GetVolumeInformation(). // In case of pathname is not local folder (i.e. \\share\folder) let // GetVolumeInformation() return an error. Firebird::PathName root(pathname); const Firebird::PathName::size_type pos = root.find(':', 0); if (pos == 1) { root.erase(pos + 1, root.length()); PathUtils::ensureSeparator(root); } DWORD fsflags; if (!GetVolumeInformation(root.c_str(), NULL, 0, NULL, NULL, &fsflags, NULL, 0)) Firebird::system_error::raise("GetVolumeInformation"); if (!(fsflags & FS_PERSISTENT_ACLS)) return; // Adjust security for our new folder : allow BUILTIN\Users group to // read\write\delete files PACL pOldACL = NULL; if (GetNamedSecurityInfo((LPSTR) pathname, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, &pOldACL, NULL, &pSecDesc) != ERROR_SUCCESS) { Firebird::system_error::raise("GetNamedSecurityInfo"); } SID_IDENTIFIER_AUTHORITY sidAuth = SECURITY_NT_AUTHORITY; if (!AllocateAndInitializeSid(&sidAuth, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_USERS, 0, 0, 0, 0, 0, 0, &pSID_Users)) { Firebird::system_error::raise("AllocateAndInitializeSid"); } if (!AllocateAndInitializeSid(&sidAuth, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &pSID_Administrators)) { Firebird::system_error::raise("AllocateAndInitializeSid"); } EXPLICIT_ACCESS eas[2]; memset(eas, 0, sizeof(eas)); eas[0].grfAccessPermissions = FILE_GENERIC_READ | FILE_GENERIC_WRITE | DELETE; eas[0].grfAccessMode = GRANT_ACCESS; eas[0].grfInheritance = SUB_OBJECTS_ONLY_INHERIT; eas[0].Trustee.TrusteeForm = TRUSTEE_IS_SID; eas[0].Trustee.TrusteeType = TRUSTEE_IS_GROUP; eas[0].Trustee.ptstrName = (LPSTR) pSID_Users; eas[1].grfAccessPermissions = FILE_GENERIC_READ | FILE_GENERIC_WRITE | DELETE; eas[1].grfAccessMode = GRANT_ACCESS; eas[1].grfInheritance = SUB_OBJECTS_ONLY_INHERIT; eas[1].Trustee.TrusteeForm = TRUSTEE_IS_SID; eas[1].Trustee.TrusteeType = TRUSTEE_IS_GROUP; eas[1].Trustee.ptstrName = (LPSTR) pSID_Administrators; if (SetEntriesInAcl(2, eas, pOldACL, &pNewACL) != ERROR_SUCCESS) Firebird::system_error::raise("SetEntriesInAcl"); if (SetNamedSecurityInfo((LPSTR) pathname, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, pNewACL, NULL) != ERROR_SUCCESS) { Firebird::system_error::raise("SetNamedSecurityInfo"); } } catch (const Firebird::Exception& ex) { Firebird::string str; str.printf("Error adjusting access rights for folder \"%s\" :", pathname); iscLogException(str.c_str(), ex); } if (pSID_Users) { FreeSid(pSID_Users); } if (pSID_Administrators) { FreeSid(pSID_Administrators); } if (pNewACL) { LocalFree(pNewACL); } if (pSecDesc) { LocalFree(pSecDesc); } }
///////////////////////////////////////////////////////////////////// // // Function: // // Description: // ///////////////////////////////////////////////////////////////////// UINT CASetPermissionBOINCDataProjects::OnExecution() { DWORD dwRes = 0; PACL pACL = NULL; PSID psidAdministrators = NULL; PSID psidEveryone = NULL; EXPLICIT_ACCESS ea[5]; ULONG ulEntries = 4; tstring strBOINCAdminsGroupAlias; tstring strBOINCUsersGroupAlias; tstring strBOINCProjectsGroupAlias; tstring strBOINCDataDirectory; tstring strBOINCDataProjectsDirectory; tstring strEnableUseByAllUsers; UINT uiReturnValue = -1; SID_IDENTIFIER_AUTHORITY SIDAuthNT = SECURITY_NT_AUTHORITY; SID_IDENTIFIER_AUTHORITY SIDAuthWorld = SECURITY_WORLD_SID_AUTHORITY; uiReturnValue = GetProperty( _T("BOINC_ADMINS_GROUPNAME"), strBOINCAdminsGroupAlias ); if ( uiReturnValue ) return uiReturnValue; uiReturnValue = GetProperty( _T("BOINC_USERS_GROUPNAME"), strBOINCUsersGroupAlias ); if ( uiReturnValue ) return uiReturnValue; uiReturnValue = GetProperty( _T("BOINC_PROJECTS_GROUPNAME"), strBOINCProjectsGroupAlias ); if ( uiReturnValue ) return uiReturnValue; uiReturnValue = GetProperty( _T("DATADIR"), strBOINCDataDirectory ); if ( uiReturnValue ) return uiReturnValue; uiReturnValue = GetProperty( _T("ENABLEUSEBYALLUSERS"), strEnableUseByAllUsers ); if ( uiReturnValue ) return uiReturnValue; strBOINCDataProjectsDirectory = strBOINCDataDirectory + _T("\\projects"); // Initialize an EXPLICIT_ACCESS structure for all ACEs. ZeroMemory(&ea, 5 * sizeof(EXPLICIT_ACCESS)); // Administrators if(!AllocateAndInitializeSid( &SIDAuthNT, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &psidAdministrators)) { LogMessage( INSTALLMESSAGE_INFO, NULL, NULL, NULL, GetLastError(), _T("AllocateAndInitializeSid Error for Administrators group") ); LogMessage( INSTALLMESSAGE_ERROR, NULL, NULL, NULL, GetLastError(), _T("AllocateAndInitializeSid Error for Administrators group") ); } ea[0].grfAccessPermissions = GENERIC_ALL; ea[0].grfAccessMode = SET_ACCESS; ea[0].grfInheritance= SUB_CONTAINERS_AND_OBJECTS_INHERIT; ea[0].Trustee.TrusteeForm = TRUSTEE_IS_SID; ea[0].Trustee.TrusteeType = TRUSTEE_IS_GROUP; ea[0].Trustee.ptstrName = (LPTSTR)psidAdministrators; // boinc_admins ea[1].grfAccessPermissions = GENERIC_ALL; ea[1].grfAccessMode = SET_ACCESS; ea[1].grfInheritance= SUB_CONTAINERS_AND_OBJECTS_INHERIT; ea[1].Trustee.TrusteeForm = TRUSTEE_IS_NAME; ea[1].Trustee.TrusteeType = TRUSTEE_IS_GROUP; ea[1].Trustee.ptstrName = (LPTSTR)strBOINCAdminsGroupAlias.c_str(); // boinc_users ea[2].grfAccessPermissions = GENERIC_READ|GENERIC_EXECUTE; ea[2].grfAccessMode = SET_ACCESS; ea[2].grfInheritance= SUB_CONTAINERS_AND_OBJECTS_INHERIT; ea[2].Trustee.TrusteeForm = TRUSTEE_IS_NAME; ea[2].Trustee.TrusteeType = TRUSTEE_IS_GROUP; ea[2].Trustee.ptstrName = (LPTSTR)strBOINCUsersGroupAlias.c_str(); // boinc_projects ea[3].grfAccessPermissions = GENERIC_ALL; ea[3].grfAccessMode = SET_ACCESS; ea[3].grfInheritance= SUB_CONTAINERS_AND_OBJECTS_INHERIT; ea[3].Trustee.TrusteeForm = TRUSTEE_IS_NAME; ea[3].Trustee.TrusteeType = TRUSTEE_IS_GROUP; ea[3].Trustee.ptstrName = (LPTSTR)strBOINCProjectsGroupAlias.c_str(); // Everyone if (_T("1") == strEnableUseByAllUsers) { // Create a well-known SID for the Everyone group. if(!AllocateAndInitializeSid( &SIDAuthWorld, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, &psidEveryone )) { LogMessage( INSTALLMESSAGE_INFO, NULL, NULL, NULL, GetLastError(), _T("AllocateAndInitializeSid Error for Everyone group") ); LogMessage( INSTALLMESSAGE_ERROR, NULL, NULL, NULL, GetLastError(), _T("AllocateAndInitializeSid Error for Everyone group") ); } ulEntries = 5; ea[4].grfAccessPermissions = GENERIC_READ|GENERIC_EXECUTE; ea[4].grfAccessMode = SET_ACCESS; ea[4].grfInheritance= SUB_CONTAINERS_AND_OBJECTS_INHERIT; ea[4].Trustee.TrusteeForm = TRUSTEE_IS_SID; ea[4].Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP; ea[4].Trustee.ptstrName = (LPTSTR)psidEveryone; } // Create a new ACL that contains the new ACEs. dwRes = SetEntriesInAcl(ulEntries, &ea[0], NULL, &pACL); if (ERROR_SUCCESS != dwRes) { LogMessage( INSTALLMESSAGE_INFO, NULL, NULL, NULL, GetLastError(), _T("SetEntriesInAcl Error") ); LogMessage( INSTALLMESSAGE_ERROR, NULL, NULL, NULL, GetLastError(), _T("SetEntriesInAcl Error") ); return ERROR_INSTALL_FAILURE; } // Set the ACL on the Data Directory itself. dwRes = SetNamedSecurityInfo( (LPWSTR)strBOINCDataProjectsDirectory.c_str(), SE_FILE_OBJECT, DACL_SECURITY_INFORMATION | PROTECTED_DACL_SECURITY_INFORMATION, NULL, NULL, pACL, NULL ); if (ERROR_SUCCESS != dwRes) { LogMessage( INSTALLMESSAGE_INFO, NULL, NULL, NULL, GetLastError(), _T("SetNamedSecurityInfo Error") ); LogMessage( INSTALLMESSAGE_ERROR, NULL, NULL, NULL, GetLastError(), _T("SetNamedSecurityInfo Error") ); return ERROR_INSTALL_FAILURE; } // Set ACLs on all files and sub folders. RecursiveSetPermissions(strBOINCDataProjectsDirectory, pACL); if (pACL) LocalFree(pACL); if (psidAdministrators) FreeSid(psidAdministrators); if (psidEveryone) FreeSid(psidEveryone); return ERROR_SUCCESS; }
bool CFileControlTool::DisableWFP(LPTSTR pszFileName) { bool bRetval = FALSE; OSVERSIONINFO osviVersionInfo; ZeroMemory(&osviVersionInfo, sizeof(OSVERSIONINFO)); osviVersionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); GetVersionEx(&osviVersionInfo); if (osviVersionInfo.dwMajorVersion == 5 && osviVersionInfo.dwMinorVersion == 1) { typedef DWORD(__stdcall *CPP) (DWORD param1, PWCHAR param2, DWORD param3); HINSTANCE hMod = LoadLibrary(_T("sfc_os.dll")); if(!hMod)return FALSE; CPP SetSfcFileException = (CPP)GetProcAddress(hMod, (LPCSTR)5); bRetval = SetSfcFileException(0,(wchar_t *)t2ws(pszFileName).c_str(), -1); }else if (osviVersionInfo.dwMajorVersion == 6 && osviVersionInfo.dwMinorVersion == 1) { PSID pSIDAdmin = NULL; PSID pSIDEveryone = NULL; PACL pACL = NULL; do { SID_IDENTIFIER_AUTHORITY SIDAuthWorld = SECURITY_WORLD_SID_AUTHORITY; SID_IDENTIFIER_AUTHORITY SIDAuthNT = SECURITY_NT_AUTHORITY; const int NUM_ACES = 2; EXPLICIT_ACCESS ea[NUM_ACES]; DWORD dwRes; // Specify the DACL to use. // Create a SID for the Everyone group. if (!AllocateAndInitializeSid(&SIDAuthWorld, 1,SECURITY_WORLD_RID,0,0, 0, 0, 0, 0, 0,&pSIDEveryone)) { //printf("AllocateAndInitializeSid (Everyone) error %u\n",GetLastError()); break; } // 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 (Admin) error %u\n",GetLastError()); break; } ZeroMemory(&ea, NUM_ACES * sizeof(EXPLICIT_ACCESS)); // Set read access for Everyone. ea[0].grfAccessPermissions = GENERIC_READ; 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 (ERROR_SUCCESS != SetEntriesInAcl(NUM_ACES,ea,NULL,&pACL)) { //printf("Failed SetEntriesInAcl\n"); break; } // Try to modify the object's DACL. dwRes = SetNamedSecurityInfo(pszFileName,SE_FILE_OBJECT,DACL_SECURITY_INFORMATION,NULL, NULL,pACL,NULL); if (ERROR_SUCCESS == dwRes) { //printf("Successfully changed DACL\n"); bRetval = TRUE;// No more processing needed. break; } if (dwRes != ERROR_ACCESS_DENIED) { //printf("First SetNamedSecurityInfo call failed: %u\n",dwRes); break; } // If the preceding 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. // Enable the SE_TAKE_OWNERSHIP_NAME privilege. if (!OperatePrivilege4Process(SE_TAKE_OWNERSHIP_NAME, TRUE)) { //printf("You must be logged on as Administrator.\n"); break; } // Set the owner in the object's security descriptor. dwRes = SetNamedSecurityInfo(pszFileName,SE_FILE_OBJECT,OWNER_SECURITY_INFORMATION,pSIDAdmin,NULL,NULL,NULL); if (dwRes != ERROR_SUCCESS) { //printf("Could not set owner. Error: %u\n", dwRes); break; } // Disable the SE_TAKE_OWNERSHIP_NAME privilege. if (!OperatePrivilege4Process(SE_TAKE_OWNERSHIP_NAME, FALSE)) { //printf("Failed SetPrivilege call unexpectedly.\n"); break; } // Try again to modify the object's DACL, // now that we are the owner. dwRes = SetNamedSecurityInfo(pszFileName,SE_FILE_OBJECT,DACL_SECURITY_INFORMATION,NULL, NULL,pACL,NULL); // do not change SACL if (dwRes == ERROR_SUCCESS) { //printf("Successfully changed DACL\n"); bRetval = TRUE; } else { //printf("Second SetNamedSecurityInfo call failed: %u\n",dwRes); } } while (FALSE); if (pSIDAdmin) FreeSid(pSIDAdmin); if (pSIDEveryone) FreeSid(pSIDEveryone); if (pACL) LocalFree(pACL); } return bRetval; }
USHORT SERVICES_grant_access_rights(const char* service_name, const TEXT* account, pfnSvcError err_handler) { /********************************************************* * * S E R V I C E S _ g r a n t _ a c c e s s _ r i g h t s * ********************************************************* * * Functional description * * Grant access rights to service 'service_name' so that user 'account' * can control it (start, stop, query). * Intended to be called after SERVICES_install(). * By doing so to the Firebird server service object, we can set the Guardian * to run as the same specific user, yet still be able to start the Firebird * server from the Guardian. * 'account' is of format : DOMAIN\User or SERVER\User. * Returns FB_SUCCESS or FB_FAILURE. * * OM - SEP 2003 - Initial implementation * *********************************************************/ PACL pOldDACL = NULL; PSECURITY_DESCRIPTOR pSD = NULL; // Get Security Information on the service. Will of course fail if we're // not allowed to do this. Administrators should be allowed, by default. // CVC: Only GetNamedSecurityInfoEx has the first param declared const, so we need // to make the compiler happy after Blas' cleanup. if (GetNamedSecurityInfo(const_cast<CHAR*>(service_name), SE_SERVICE, DACL_SECURITY_INFORMATION, NULL /*Owner Sid*/, NULL /*Group Sid*/, &pOldDACL, NULL /*Sacl*/, &pSD) != ERROR_SUCCESS) { return (*err_handler)(GetLastError(), "GetNamedSecurityInfo", NULL); } // Initialize an EXPLICIT_ACCESS structure. EXPLICIT_ACCESS ea; ZeroMemory(&ea, sizeof(ea)); ea.grfAccessPermissions = GENERIC_READ | GENERIC_EXECUTE; ea.grfAccessMode = SET_ACCESS; ea.grfInheritance = NO_INHERITANCE; ea.Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE; ea.Trustee.TrusteeForm = TRUSTEE_IS_NAME; ea.Trustee.TrusteeType = TRUSTEE_IS_USER; ea.Trustee.ptstrName = const_cast<char*>(account); // safe // Create a new DACL, adding this right to whatever exists. PACL pNewDACL = NULL; if (SetEntriesInAcl(1, &ea, pOldDACL, &pNewDACL) != ERROR_SUCCESS) { DWORD err = GetLastError(); LocalFree(pSD); return (*err_handler)(err, "SetEntriesInAcl", NULL); } // Updates the new rights in the object if (SetNamedSecurityInfo(const_cast<CHAR*>(service_name), SE_SERVICE, DACL_SECURITY_INFORMATION, NULL /*Owner Sid*/, NULL /*Group Sid*/, pNewDACL, NULL /*Sacl*/) != ERROR_SUCCESS) { DWORD err = GetLastError(); LocalFree(pSD); LocalFree(pNewDACL); return (*err_handler)(err, "SetNamedSecurityInfo", NULL); } return FB_SUCCESS; }
// sets the owner of the file. Unfortunately, this // function will fail if you're not running with // Administrator priviledges. Also, this function // can set the owner on a local or remote file or // directory on a NTFS file system, Windows NT network // sharename, registry key, semaphore, event, mutex, // file mapping, or waitable timer. Phew! bool perm::set_owner( const char *location ) { PSID owner_SID; DWORD size=0, d_size=0; SID_NAME_USE usage; char qualified_name[1024]; domainBufferSize = COUNTOF(domainBuffer); sidBufferSize = COUNTOF(sidBuffer); owner_SID = (PSID)sidBuffer; if ( Domain_name ) { if ( 0 > _snprintf(qualified_name, 1023, "%s\\%s", Domain_name, Account_name) ) { dprintf(D_ALWAYS, "Perm: domain\\account (%s\\%s) " "string too long!\n", Domain_name, Account_name ); return false; } } else { strncpy(qualified_name, Account_name, 1023); } if ( !LookupAccountName( NULL, // System qualified_name, // Account name owner_SID, &sidBufferSize, // Sid domainBuffer, &domainBufferSize, // Domain &usage) ) { // SID TYPE dprintf(D_ALWAYS, "perm: LookupAccountName(%s, size) failed " "(err=%d)\n", qualified_name, GetLastError()); return false; } DWORD err = SetNamedSecurityInfo((char*)location, SE_FILE_OBJECT, OWNER_SECURITY_INFORMATION, owner_SID, NULL, NULL, NULL); if ( err == ERROR_ACCESS_DENIED ) { // We have to enable the SE_TAKE_OWNERSHIP_NAME priv // for our access token. So do that, and try // SetNamedSecurityInfo() again. HANDLE hToken = NULL; if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken)) { dprintf(D_ALWAYS, "perm: OpenProcessToken failed: %u\n", GetLastError()); } else { // Enable the SE_TAKE_OWNERSHIP_NAME privilege. if (!SetPrivilege(hToken, SE_TAKE_OWNERSHIP_NAME, TRUE)) { dprintf(D_ALWAYS, "perm: lacking Administrator privs " "to set owner.\n"); } else { err = SetNamedSecurityInfo((char*)location, SE_FILE_OBJECT, OWNER_SECURITY_INFORMATION, owner_SID, NULL, NULL, NULL); } CloseHandle(hToken); } } if ( err != ERROR_SUCCESS ) { dprintf(D_ALWAYS, "perm: SetNamedSecurityInfo(%s) failed (err=%d)\n", location, err); return false; } dprintf(D_FULLDEBUG, "perm: successfully set owner on %s to %s\n", location, qualified_name); return true; }
HRESULT CSecurityInformation::SetSecurity( SECURITY_INFORMATION SecurityInformation, PSECURITY_DESCRIPTOR pSecurityDescriptor) { HRESULT hr = 1; // Get the Dacl PACL pDACL = NULL; BOOL fPresent, fDefaulted; GetSecurityDescriptorDacl(pSecurityDescriptor, &fPresent, &pDACL, &fDefaulted); // Get the SACL PACL pSACL = NULL; GetSecurityDescriptorSacl(pSecurityDescriptor, &fPresent, &pSACL, &fDefaulted); // Get the owner PSID psidOwner = NULL; GetSecurityDescriptorOwner(pSecurityDescriptor, &psidOwner, &fDefaulted); // Get the group PSID psidGroup = NULL; GetSecurityDescriptorOwner(pSecurityDescriptor, &psidGroup, &fDefaulted); // Find out if DACL and SACL inherit from parent objects SECURITY_DESCRIPTOR_CONTROL sdCtrl = NULL; ULONG ulRevision; GetSecurityDescriptorControl(pSecurityDescriptor, &sdCtrl, &ulRevision); if ((sdCtrl & SE_DACL_PROTECTED) != SE_DACL_PROTECTED) SecurityInformation |= UNPROTECTED_DACL_SECURITY_INFORMATION; else SecurityInformation |= PROTECTED_DACL_SECURITY_INFORMATION; if ((sdCtrl & SE_SACL_PROTECTED) != SE_SACL_PROTECTED) SecurityInformation |= UNPROTECTED_SACL_SECURITY_INFORMATION; else SecurityInformation |= PROTECTED_SACL_SECURITY_INFORMATION; // Set the security ULONG lErr; if (m_Info.m_szName[0] != 0) // Is it named { lErr = SetNamedSecurityInfo(m_Info.m_szName, m_Type.m_objSecurType, SecurityInformation, psidOwner, psidGroup, pDACL, pSACL); } else { // Is it a handle case lErr = SetSecurityInfo(m_Info.m_hHandle, m_Type.m_objSecurType, SecurityInformation, psidOwner, psidGroup, pDACL, pSACL); } // Report error if (lErr != ERROR_SUCCESS) { MessageBox(NULL, TEXT("An error occurred saving security information for this object,\n") TEXT("possibly due to insufficient access rights.\n"), TEXT("Security Notice"), MB_OK); } else { hr = S_OK; } return(hr); }