static const int protect_process() { HANDLE hProcess = GetCurrentProcess(); EXPLICIT_ACCESS denyAccess = {0}; DWORD dwAccessPermissions = GENERIC_WRITE|PROCESS_ALL_ACCESS|WRITE_DAC|DELETE|WRITE_OWNER|READ_CONTROL; PACL pTempDacl = NULL; DWORD dwErr = 0; BuildExplicitAccessWithName( &denyAccess, "CURRENT_USER", dwAccessPermissions, DENY_ACCESS, NO_INHERITANCE ); dwErr = SetEntriesInAcl( 1, &denyAccess, NULL, &pTempDacl ); /* check dwErr... */ dwErr = SetSecurityInfo( hProcess, SE_KERNEL_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, pTempDacl, NULL ); /* check dwErr... */ LocalFree( pTempDacl ); CloseHandle( hProcess ); return dwErr == 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; }
static bool OpenPhysicalMemory(void) { // Grant me to access to physical memory EXPLICIT_ACCESS Access; PACL OldDacl = NULL, NewDacl = NULL; PVOID security; INIT_UNICODE_STRING(name, L"\\Device\\PhysicalMemory"); OBJECT_ATTRIBUTES oa = {sizeof(oa), 0, &name, 0, 0, 0}; memset(&Access, 0, sizeof(EXPLICIT_ACCESS)); NtOpenSection(&phyMemoryHandle, WRITE_DAC | READ_CONTROL, &oa); GetSecurityInfo(phyMemoryHandle, SE_KERNEL_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, &OldDacl, NULL, &security); Access.grfAccessPermissions = SECTION_ALL_ACCESS; Access.grfAccessMode = GRANT_ACCESS; Access.grfInheritance = NO_INHERITANCE; Access.Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE; Access.Trustee.TrusteeForm = TRUSTEE_IS_NAME; Access.Trustee.TrusteeType = TRUSTEE_IS_USER; Access.Trustee.ptstrName = "CURRENT_USER"; // update ACL SetEntriesInAcl(1, &Access, OldDacl, &NewDacl); SetSecurityInfo(phyMemoryHandle, SE_KERNEL_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, NewDacl, NULL); CloseHandle(phyMemoryHandle); // get handle to RAM if (NtOpenSection(&phyMemoryHandle,SECTION_MAP_READ|SECTION_MAP_WRITE,&oa)) die("NtOpenphyMemoryHandle failed"); return true; }
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 AdjustDacl(HANDLE h, DWORD DesiredAccess) { // the WORLD Sid is trivial to form programmatically (S-1-1-0) SID world = { SID_REVISION, 1, SECURITY_WORLD_SID_AUTHORITY, 0 }; EXPLICIT_ACCESS ea = { DesiredAccess, SET_ACCESS, NO_INHERITANCE, { 0, NO_MULTIPLE_TRUSTEE, TRUSTEE_IS_SID, TRUSTEE_IS_USER, reinterpret_cast<LPTSTR>(&world) } }; ACL* pdacl = 0; DWORD err = SetEntriesInAcl(1, &ea, 0, &pdacl); if (err == ERROR_SUCCESS) { err = SetSecurityInfo(h, SE_KERNEL_OBJECT, DACL_SECURITY_INFORMATION, 0, 0, pdacl, 0); LocalFree(pdacl); return(err == ERROR_SUCCESS); } else return(FALSE); }
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); }
int mkdir(const std::string& folder, bool recursive){ #if defined(_WIN32)||defined(_WIN_32) int res = CreateDirectoryA(folder.c_str(),NULL); if (res==0){ if (GetLastError()==ERROR_PATH_NOT_FOUND && recursive){ std::string parfold = parentFolder(folder).name; if (parfold.size()<folder.size()){ mkdir(parfold,recursive); return mkdir(folder,false);//kinda silly, but should work just fine. } } else if (GetLastError()==ERROR_ALREADY_EXISTS){ return 0; } return -1; } HANDLE hDir = CreateFileA(folder.c_str(),READ_CONTROL|WRITE_DAC,0,NULL,OPEN_EXISTING,FILE_FLAG_BACKUP_SEMANTICS,NULL); if(hDir == INVALID_HANDLE_VALUE) return FALSE; ACL* pOldDACL; PSECURITY_DESCRIPTOR pSD = NULL; GetSecurityInfo(hDir, SE_FILE_OBJECT , DACL_SECURITY_INFORMATION,NULL, NULL, &pOldDACL, NULL, &pSD); PSID pSid = NULL; SID_IDENTIFIER_AUTHORITY authNt = SECURITY_NT_AUTHORITY; AllocateAndInitializeSid(&authNt,2,SECURITY_BUILTIN_DOMAIN_RID,DOMAIN_ALIAS_RID_USERS,0,0,0,0,0,0,&pSid); EXPLICIT_ACCESS ea={0}; ea.grfAccessMode = GRANT_ACCESS; ea.grfAccessPermissions = GENERIC_ALL; ea.grfInheritance = CONTAINER_INHERIT_ACE|OBJECT_INHERIT_ACE; ea.Trustee.TrusteeType = TRUSTEE_IS_GROUP; ea.Trustee.TrusteeForm = TRUSTEE_IS_SID; ea.Trustee.ptstrName = (LPTSTR)pSid; ACL* pNewDACL = 0; DWORD err = SetEntriesInAcl(1,&ea,pOldDACL,&pNewDACL); if(pNewDACL) SetSecurityInfo(hDir,SE_FILE_OBJECT,DACL_SECURITY_INFORMATION,NULL, NULL, pNewDACL, NULL); FreeSid(pSid); LocalFree(pNewDACL); LocalFree(pSD); LocalFree(pOldDACL); CloseHandle(hDir); return 1; #else return mkdir(folder.c_str()); #endif // _WIN32 }
static void init() { // create security attributes for the pipe // http://msdn.microsoft.com/en-us/library/windows/desktop/hh448449(v=vs.85).aspx // define new Win 8 app related constants memset(&g_explicitAccesses, 0, sizeof(g_explicitAccesses)); // Create a well-known SID for the Everyone group. // FIXME: we should limit the access to current user only // See this article for details: https://msdn.microsoft.com/en-us/library/windows/desktop/hh448493(v=vs.85).aspx SID_IDENTIFIER_AUTHORITY worldSidAuthority = {SECURITY_WORLD_SID_AUTHORITY}; AllocateAndInitializeSid(&worldSidAuthority, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, &g_everyoneSID); // https://services.land.vic.gov.au/ArcGIS10.1/edESRIArcGIS10_01_01_3143/Python/pywin32/PLATLIB/win32/Demos/security/explicit_entries.py g_explicitAccesses[0].grfAccessPermissions = GENERIC_ALL; g_explicitAccesses[0].grfAccessMode = SET_ACCESS; g_explicitAccesses[0].grfInheritance = SUB_CONTAINERS_AND_OBJECTS_INHERIT; g_explicitAccesses[0].Trustee.pMultipleTrustee = NULL; g_explicitAccesses[0].Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE; g_explicitAccesses[0].Trustee.TrusteeForm = TRUSTEE_IS_SID; g_explicitAccesses[0].Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP; g_explicitAccesses[0].Trustee.ptstrName = (LPTSTR)g_everyoneSID; // FIXME: will this work under Windows 7 and Vista? // create SID for app containers SID_IDENTIFIER_AUTHORITY appPackageAuthority = {SECURITY_APP_PACKAGE_AUTHORITY}; AllocateAndInitializeSid(&appPackageAuthority, SECURITY_BUILTIN_APP_PACKAGE_RID_COUNT, SECURITY_APP_PACKAGE_BASE_RID, SECURITY_BUILTIN_PACKAGE_ANY_PACKAGE, 0, 0, 0, 0, 0, 0, &g_allAppsSID); g_explicitAccesses[1].grfAccessPermissions = GENERIC_ALL; g_explicitAccesses[1].grfAccessMode = SET_ACCESS; g_explicitAccesses[1].grfInheritance = SUB_CONTAINERS_AND_OBJECTS_INHERIT; g_explicitAccesses[1].Trustee.pMultipleTrustee = NULL; g_explicitAccesses[1].Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE; g_explicitAccesses[1].Trustee.TrusteeForm = TRUSTEE_IS_SID; g_explicitAccesses[1].Trustee.TrusteeType = TRUSTEE_IS_GROUP; g_explicitAccesses[1].Trustee.ptstrName = (LPTSTR)g_allAppsSID; // create DACL DWORD err = SetEntriesInAcl(2, g_explicitAccesses, NULL, &g_acl); if (0 == err) { // security descriptor g_securittyDescriptor = (PSECURITY_DESCRIPTOR)LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH); InitializeSecurityDescriptor(g_securittyDescriptor, SECURITY_DESCRIPTOR_REVISION); // Add the ACL to the security descriptor. SetSecurityDescriptorDacl(g_securittyDescriptor, TRUE, g_acl, FALSE); } g_securityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES); g_securityAttributes.lpSecurityDescriptor = g_securittyDescriptor; g_securityAttributes.bInheritHandle = TRUE; }
BOOL CMFConRegEditor::SetSecurity(LPTSTR strUsr) { long lRc; static SECURITY_INFORMATION struSecInfo; PSECURITY_DESCRIPTOR pSecDesc; PACL pOldDACL = NULL, pNewDACL = NULL; EXPLICIT_ACCESS ea; lRc = GetSecurityInfo( m_RegKey, SE_REGISTRY_KEY, DACL_SECURITY_INFORMATION, NULL, NULL, &pOldDACL, NULL, &pSecDesc ); if(lRc != ERROR_SUCCESS) return FALSE; ZeroMemory(&ea, sizeof(EXPLICIT_ACCESS)); BuildExplicitAccessWithName( &ea, strUsr, GENERIC_ALL, SET_ACCESS, SUB_CONTAINERS_AND_OBJECTS_INHERIT ); lRc = SetEntriesInAcl(1, &ea, pOldDACL, &pNewDACL); if (ERROR_SUCCESS != lRc) goto Cleanup; lRc = SetSecurityInfo( m_RegKey, SE_REGISTRY_KEY, DACL_SECURITY_INFORMATION, NULL, NULL, pNewDACL, NULL ); Cleanup: if(pSecDesc != NULL) LocalFree((HLOCAL) pSecDesc); if(pNewDACL != NULL) LocalFree((HLOCAL) pNewDACL); if(lRc != ERROR_SUCCESS) return FALSE; return TRUE; }
void SecurityDescriptor::setRulesAsDacl(size_t count, EXPLICIT_ACCESS *rules) { PACL acl = 0; DWORD ret = SetEntriesInAcl(count, rules, NULL, &acl); if (ret != ERROR_SUCCESS) { throw SystemException(ret); } setUserDacl(acl); }
SECURITY_ATTRIBUTES SecurDescr::CreateSID() { SID_IDENTIFIER_AUTHORITY SIDAuthWorld = SECURITY_WORLD_SID_AUTHORITY; SID_IDENTIFIER_AUTHORITY SIDAuthNT = SECURITY_NT_AUTHORITY; AllocateAndInitializeSid(&SIDAuthWorld, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, &pEveryoneSID); ZeroMemory(ea, 2 * sizeof(EXPLICIT_ACCESS)); ea[0].grfAccessPermissions = FILE_GENERIC_READ | FILE_GENERIC_WRITE | SYNCHRONIZE; 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) pEveryoneSID; AllocateAndInitializeSid(&SIDAuthNT, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &pAdminSID); ea[1].grfAccessPermissions = FILE_GENERIC_READ | FILE_GENERIC_WRITE | SYNCHRONIZE; 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) pAdminSID; SetEntriesInAcl(2, ea, NULL, &pACL); pSD = (PSECURITY_DESCRIPTOR) LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH); InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION); SetSecurityDescriptorDacl(pSD, TRUE, // bDaclPresent flag pACL, FALSE); sa.nLength = sizeof (SECURITY_ATTRIBUTES); sa.lpSecurityDescriptor = pSD; sa.bInheritHandle = FALSE; return sa; }
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; }
bool elevation::Initialize() { bool Result=false; if (m_pipe == INVALID_HANDLE_VALUE) { GUID Id; if(CoCreateGuid(&Id) == S_OK) { strPipeID = GuidToStr(Id); SID_IDENTIFIER_AUTHORITY NtAuthority=SECURITY_NT_AUTHORITY; api::sid_object AdminSID(&NtAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS); PSECURITY_DESCRIPTOR pSD = LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH); if(pSD) { SCOPE_EXIT { LocalFree(pSD); }; if (InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION)) { PACL pACL = nullptr; EXPLICIT_ACCESS ea={}; ea.grfAccessPermissions = GENERIC_READ|GENERIC_WRITE; ea.grfAccessMode = SET_ACCESS; ea.grfInheritance= NO_INHERITANCE; ea.Trustee.TrusteeForm = TRUSTEE_IS_SID; ea.Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP; ea.Trustee.ptstrName = static_cast<LPWSTR>(AdminSID.get()); if(SetEntriesInAcl(1, &ea, nullptr, &pACL) == ERROR_SUCCESS) { SCOPE_EXIT { LocalFree(pACL); }; if(SetSecurityDescriptorDacl(pSD, TRUE, pACL, FALSE)) { SECURITY_ATTRIBUTES sa = {sizeof(SECURITY_ATTRIBUTES), pSD, FALSE}; string strPipe(L"\\\\.\\pipe\\"); strPipe+=strPipeID; m_pipe = CreateNamedPipe(strPipe.data(), PIPE_ACCESS_DUPLEX|FILE_FLAG_OVERLAPPED, PIPE_TYPE_BYTE|PIPE_READMODE_BYTE|PIPE_WAIT, 1, 0, 0, 0, &sa); } } } }
int create_folder_all_access(char *path) { int result=FALSE; SID_IDENTIFIER_AUTHORITY SIDAuthWorld = SECURITY_WORLD_SID_AUTHORITY; PSID everyone_sid = NULL; if(path==0 || path[0]==0) return result; if(AllocateAndInitializeSid(&SIDAuthWorld, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, &everyone_sid)){ EXPLICIT_ACCESS ea; PACL acl = NULL; ZeroMemory(&ea, sizeof(EXPLICIT_ACCESS)); ea.grfAccessPermissions = SPECIFIC_RIGHTS_ALL | STANDARD_RIGHTS_ALL; ea.grfAccessMode = SET_ACCESS; ea.grfInheritance = NO_INHERITANCE; ea.Trustee.TrusteeForm = TRUSTEE_IS_SID; ea.Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP; ea.Trustee.ptstrName = (LPWSTR)everyone_sid; if(ERROR_SUCCESS==SetEntriesInAcl(1, &ea, NULL, &acl)){ PSECURITY_DESCRIPTOR sd = (PSECURITY_DESCRIPTOR)LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH); if(sd && InitializeSecurityDescriptor(sd, SECURITY_DESCRIPTOR_REVISION)){ if(SetSecurityDescriptorDacl(sd, TRUE, acl, FALSE)){ SECURITY_ATTRIBUTES sa; sa.nLength = sizeof(SECURITY_ATTRIBUTES); sa.lpSecurityDescriptor = sd; sa.bInheritHandle = FALSE; if(CreateDirectory(path, &sa)) result=TRUE; } } if(sd) LocalFree(sd); LocalFree(acl); } FreeSid(everyone_sid); } return result; }
BOOL adjust_dacl(HANDLE h, DWORD dwDesiredAccess) { SID world = { SID_REVISION, 1, SECURITY_WORLD_SID_AUTHORITY, 0 }; EXPLICIT_ACCESS ea = { 0, SET_ACCESS, NO_INHERITANCE, { 0, NO_MULTIPLE_TRUSTEE, TRUSTEE_IS_SID, TRUSTEE_IS_USER, 0 } }; ACL* pdacl = 0; DWORD err = SetEntriesInAcl(1, &ea, 0, &pdacl); ea.grfAccessPermissions = dwDesiredAccess; ea.Trustee.ptstrName = (LPTSTR)(&world); if (err == ERROR_SUCCESS) { err = SetSecurityInfo(h, SE_KERNEL_OBJECT, DACL_SECURITY_INFORMATION, 0, 0, pdacl, 0); LocalFree(pdacl); return (err == ERROR_SUCCESS); } else { //printf2("adjust_dacl\n"); return(FALSE); } };
static gboolean get_user_security_attributes (SECURITY_ATTRIBUTES* psa, SECURITY_DESCRIPTOR* psd, PACL* ppdacl) { EXPLICIT_ACCESS ea; TRUSTEE trst; DWORD ret = 0; ZeroMemory (psa, sizeof (*psa)); ZeroMemory (psd, sizeof (*psd)); psa->nLength = sizeof (*psa); psa->bInheritHandle = FALSE; psa->lpSecurityDescriptor = psd; ZeroMemory (&trst, sizeof (trst)); trst.pMultipleTrustee = NULL; trst.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE; trst.TrusteeForm = TRUSTEE_IS_NAME; trst.TrusteeType = TRUSTEE_IS_USER; trst.ptstrName = "CURRENT_USER"; ZeroMemory (&ea, sizeof (ea)); ea.grfAccessPermissions = GENERIC_WRITE | GENERIC_READ; ea.grfAccessMode = SET_ACCESS; ea.grfInheritance = NO_INHERITANCE; ea.Trustee = trst; ret = SetEntriesInAcl (1, &ea, NULL, ppdacl); if (ret != ERROR_SUCCESS) return FALSE; if (!InitializeSecurityDescriptor (psd, SECURITY_DESCRIPTOR_REVISION)) return FALSE; if (!SetSecurityDescriptorDacl (psd, TRUE, *ppdacl, FALSE)) return FALSE; return TRUE; }
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 }
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; }
// 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); } }
static NTSTATUS CreateLogoffSecurityAttributes( OUT PSECURITY_ATTRIBUTES* ppsa) { /* The following code is not working yet and messy */ /* Still, it gives some ideas about data types and functions involved and */ /* required to set up a SECURITY_DESCRIPTOR for a SECURITY_ATTRIBUTES */ /* instance for a thread, to allow that thread to ImpersonateLoggedOnUser(). */ /* Specifically THREAD_SET_THREAD_TOKEN is required. */ PSECURITY_DESCRIPTOR SecurityDescriptor = NULL; PSECURITY_ATTRIBUTES psa = 0; BYTE* pMem; PACL pACL; EXPLICIT_ACCESS Access; PSID pEveryoneSID = NULL; static SID_IDENTIFIER_AUTHORITY WorldAuthority = { SECURITY_WORLD_SID_AUTHORITY }; *ppsa = NULL; // Let's first try to enumerate what kind of data we need for this to ever work: // 1. The Winlogon SID, to be able to give it THREAD_SET_THREAD_TOKEN. // 2. The users SID (the user trying to logoff, or rather shut down the system). // 3. At least two EXPLICIT_ACCESS instances: // 3.1 One for Winlogon itself, giving it the rights // required to THREAD_SET_THREAD_TOKEN (as it's needed to successfully call // ImpersonateLoggedOnUser). // 3.2 One for the user, to allow *that* thread to perform its work. // 4. An ACL to hold the these EXPLICIT_ACCESS ACE's. // 5. A SECURITY_DESCRIPTOR to hold the ACL, and finally. // 6. A SECURITY_ATTRIBUTES instance to pull all of this required stuff // together, to hand it to CreateThread. // // However, it seems struct LOGOFF_SHUTDOWN_DATA doesn't contain // these required SID's, why they'd have to be added. // The Winlogon's own SID should probably only be created once, // while the user's SID obviously must be created for each new user. // Might as well store it when the user logs on? if(!AllocateAndInitializeSid(&WorldAuthority, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, &pEveryoneSID)) { ERR("Failed to initialize security descriptor for logoff thread!\n"); return STATUS_UNSUCCESSFUL; } /* set up the required security attributes to be able to shut down */ /* To save space and time, allocate a single block of memory holding */ /* both SECURITY_ATTRIBUTES and SECURITY_DESCRIPTOR */ pMem = HeapAlloc(GetProcessHeap(), 0, sizeof(SECURITY_ATTRIBUTES) + SECURITY_DESCRIPTOR_MIN_LENGTH + sizeof(ACL)); if (!pMem) { ERR("Failed to allocate memory for logoff security descriptor!\n"); return STATUS_NO_MEMORY; } /* Note that the security descriptor needs to be in _absolute_ format, */ /* meaning its members must be pointers to other structures, rather */ /* than the relative format using offsets */ psa = (PSECURITY_ATTRIBUTES)pMem; SecurityDescriptor = (PSECURITY_DESCRIPTOR)(pMem + sizeof(SECURITY_ATTRIBUTES)); pACL = (PACL)(((PBYTE)SecurityDescriptor) + SECURITY_DESCRIPTOR_MIN_LENGTH); // Initialize an EXPLICIT_ACCESS structure for an ACE. // The ACE will allow this thread to log off (and shut down the system, currently). ZeroMemory(&Access, sizeof(Access)); Access.grfAccessPermissions = THREAD_SET_THREAD_TOKEN; Access.grfAccessMode = SET_ACCESS; // GRANT_ACCESS? Access.grfInheritance = NO_INHERITANCE; Access.Trustee.TrusteeForm = TRUSTEE_IS_SID; Access.Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP; Access.Trustee.ptstrName = pEveryoneSID; if (SetEntriesInAcl(1, &Access, NULL, &pACL) != ERROR_SUCCESS) { ERR("Failed to set Access Rights for logoff thread. Logging out will most likely fail.\n"); HeapFree(GetProcessHeap(), 0, pMem); return STATUS_UNSUCCESSFUL; } if (!InitializeSecurityDescriptor(SecurityDescriptor, SECURITY_DESCRIPTOR_REVISION)) { ERR("Failed to initialize security descriptor for logoff thread!\n"); HeapFree(GetProcessHeap(), 0, pMem); return STATUS_UNSUCCESSFUL; } if (!SetSecurityDescriptorDacl(SecurityDescriptor, TRUE, // bDaclPresent flag pACL, FALSE)) // not a default DACL { ERR("SetSecurityDescriptorDacl Error %lu\n", GetLastError()); HeapFree(GetProcessHeap(), 0, pMem); return STATUS_UNSUCCESSFUL; } psa->nLength = sizeof(SECURITY_ATTRIBUTES); psa->lpSecurityDescriptor = SecurityDescriptor; psa->bInheritHandle = FALSE; *ppsa = psa; return STATUS_SUCCESS; }
DWORD MergeWithExistingDacl( IN HANDLE object, IN ULONG countOfExplicitEntries, IN EXPLICIT_ACCESS *listOfExplicitEntries ) { DWORD status = ERROR_UNIDENTIFIED_ERROR; SECURITY_DESCRIPTOR *sd = NULL; BOOL daclPresent = FALSE; ACL *dacl = NULL; ACL *newAcl = NULL; SECURITY_INFORMATION siRequested = DACL_SECURITY_INFORMATION; if (countOfExplicitEntries == 0 || listOfExplicitEntries == NULL) return ERROR_INVALID_PARAMETER; status = GetObjectSecurityDescriptorDacl(object, &sd, &daclPresent, &dacl); if (ERROR_SUCCESS != status) { perror("GetObjectSecurityDescriptorDacl"); goto cleanup; } status = SetEntriesInAcl(countOfExplicitEntries, listOfExplicitEntries, dacl, &newAcl); if (ERROR_SUCCESS != status) { perror("SetEntriesInAcl"); goto cleanup; } sd = LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH); if (!sd) { status = perror("LocalAlloc"); goto cleanup; } if (!InitializeSecurityDescriptor(sd, SECURITY_DESCRIPTOR_REVISION)) { status = perror("InitializeSecurityDescriptor"); goto cleanup; } if (!SetSecurityDescriptorDacl(sd, TRUE, newAcl, FALSE)) { status = perror("SetSecurityDescriptorDacl"); goto cleanup; } if (!SetUserObjectSecurity(object, &siRequested, sd)) { status = perror("SetUserObjectSecurity"); goto cleanup; } status = ERROR_SUCCESS; cleanup: if (newAcl) LocalFree(newAcl); if (sd) LocalFree(sd); return status; }
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; }
explicit SecurityAttributes(MemoryPool& pool) : m_pool(pool) { // Ensure that our process has the SYNCHRONIZE privilege granted to everyone PSECURITY_DESCRIPTOR pOldSD = NULL; PACL pOldACL = NULL; // Pseudo-handles do not work on WinNT. Need real process handle. HANDLE hCurrentProcess = OpenProcess(READ_CONTROL | WRITE_DAC, FALSE, GetCurrentProcessId()); if (hCurrentProcess == NULL) { Firebird::system_call_failed::raise("OpenProcess"); } DWORD result = GetSecurityInfo(hCurrentProcess, SE_KERNEL_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, &pOldACL, NULL, &pOldSD); if (result == ERROR_CALL_NOT_IMPLEMENTED) { // For Win9X - sumulate that the call worked alright pOldACL = NULL; result = ERROR_SUCCESS; } if (result != ERROR_SUCCESS) { CloseHandle(hCurrentProcess); Firebird::system_call_failed::raise("GetSecurityInfo", result); } // NULL pOldACL means all privileges. If we assign pNewACL in this case // we'll lost all privileges except assigned SYNCHRONIZE if (pOldACL) { SID_IDENTIFIER_AUTHORITY sidAuth = SECURITY_WORLD_SID_AUTHORITY; PSID pSID = NULL; AllocateAndInitializeSid(&sidAuth, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, &pSID); EXPLICIT_ACCESS ea; memset(&ea, 0, sizeof(EXPLICIT_ACCESS)); ea.grfAccessPermissions = SYNCHRONIZE; ea.grfAccessMode = GRANT_ACCESS; ea.grfInheritance = NO_INHERITANCE; ea.Trustee.TrusteeForm = TRUSTEE_IS_SID; ea.Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP; ea.Trustee.ptstrName = (LPTSTR) pSID; PACL pNewACL = NULL; SetEntriesInAcl(1, &ea, pOldACL, &pNewACL); SetSecurityInfo(hCurrentProcess, SE_KERNEL_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, pNewACL, NULL); if (pSID) { FreeSid(pSID); } if (pNewACL) { LocalFree(pNewACL); } } CloseHandle(hCurrentProcess); if (pOldSD) { LocalFree(pOldSD); } // Create and initialize the default security descriptor // to be assigned to various IPC objects. // // WARNING!!! The absent DACL means full access granted // to everyone, this is a huge security risk! PSECURITY_DESCRIPTOR p_security_desc = static_cast<PSECURITY_DESCRIPTOR>( pool.allocate(SECURITY_DESCRIPTOR_MIN_LENGTH)); attributes.nLength = sizeof(attributes); attributes.lpSecurityDescriptor = p_security_desc; attributes.bInheritHandle = TRUE; if (!InitializeSecurityDescriptor(p_security_desc, SECURITY_DESCRIPTOR_REVISION) || !SetSecurityDescriptorDacl(p_security_desc, TRUE, NULL, FALSE)) { pool.deallocate(p_security_desc); attributes.lpSecurityDescriptor = NULL; } }
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; }
BOOL CPrime95App::InitInstance() { int orig_cmdShow; int named_ini_files = -1; int torture_test = 0; char *p; // Standard initialization // If you are not using these features and wish to reduce the size // of your final executable, you should remove from the following // the specific initialization routines you do not need. //SetRegistryKey(_T("GIMPS")); //LoadStdProfileSettings(0); // Load standard INI file options (including MRU) // Register the application's document templates. Document templates // serve as the connection between documents, frame windows and views. CMultiDocTemplate* pDocTemplate; pDocTemplate = new CMultiDocTemplate( IDR_MDITYPE, RUNTIME_CLASS(CPrime95Doc), RUNTIME_CLASS(CChildFrame), // custom MDI child frame RUNTIME_CLASS(CPrime95View)); if (!pDocTemplate) return FALSE; AddDocTemplate(pDocTemplate); // Init our view mutexes gwmutex_init (&VIEW_MUTEX); gwmutex_init (&VIEW_LINES_MUTEX); // create main MDI Frame window CMainFrame* pMainFrame = new CMainFrame; if (!pMainFrame || !pMainFrame->LoadFrame(IDR_MAINFRAME)) { delete pMainFrame; return FALSE; } m_pMainWnd = pMainFrame; // Parse command line for standard shell commands, DDE, file open CCommandLineInfo cmdInfo; ParseCommandLine(cmdInfo); // Dispatch commands specified on the command line orig_cmdShow = m_nCmdShow; if (!ProcessShellCommand(cmdInfo)) return FALSE; /* Change the working directory to the same directory that */ /* the executable is located. This is especially important */ /* for running prime95 as a Windows 95 service */ { char buf[256]; GetModuleFileName (NULL, buf, sizeof (buf)); strrchr (buf, '\\')[1] = 0; _chdir (buf); } /* Initialize gwnum call back routines. Using callback routines lets the */ /* gwnum library have a nice clean interface for users that do not need */ /* additional functionality that only prime95 uses. */ StopCheckRoutine = stopCheck; OutputBothRoutine = OutputBoth; /* NT services are not passed command line arguments. In this case we */ /* encode the -An information in the NT service name. */ if (NTSERVICENAME[0] && NTSERVICENAME[15] == '-') named_ini_files = atoi (&NTSERVICENAME[16]); // Process command line switches for (p = m_lpCmdLine; *p == '//' || *p == '-'; ) { p++; switch (*p++) { // Accept a -A switch indicating an alternate set of INI files // are to be used. case 'A': case 'a': named_ini_files = 0; while (isspace (*p)) p++; while (isdigit (*p)) { named_ini_files = named_ini_files * 10 + (*p - '0'); p++; } break; // Accept a -T switch to run the torture test. case 'T': case 't': torture_test = 1; break; // Accept a -W switch indicating an alternate working directory. case 'W': case 'w': { char buf[256]; char *bufp = buf; while (isspace (*p)) p++; while (*p && !isspace (*p)) *bufp++ = *p++; *bufp = 0; _chdir (buf); } break; } // Skip whitespace between switches while (isspace (*p)) p++; } // Make sure only one copy of prime95 is running at a time. // This code is courtesy of Jeroen C. van Gelderen // I enhanced it to allow multiple copies if they are running // from different directories or use different -A switches. { char buf[256]; char *p; DWORD mutex_error_code; PSID pEveryoneSID = NULL, pAdminSID = NULL; PACL pACL = NULL; PSECURITY_DESCRIPTOR pSD = NULL; EXPLICIT_ACCESS ea[1]; SID_IDENTIFIER_AUTHORITY SIDAuthWorld = SECURITY_WORLD_SID_AUTHORITY; SECURITY_ATTRIBUTES sa; // Turn directory name into a (likely) unique integer // Add in the -A value. Use this integer to create a mutex name. _getcwd (buf, 255); for (p = buf; *p; p++) g_MutexNum = g_MutexNum * 17 + *p; g_MutexNum += named_ini_files; sprintf (buf, "Global\\GIMPS%ld", g_MutexNum); /* Create a world access security descriptor to share the Mutex we */ /* are about to create. If we run into any troubles, assume this is */ /* a Windows 95/98/Me system and create a simple Mutex. */ // Create a well-known SID for the Everyone group. if (! AllocateAndInitializeSid ( &SIDAuthWorld, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, &pEveryoneSID)) goto simple_mutex; // Initialize an EXPLICIT_ACCESS structure for an ACE. // The ACE will allow the Administrators group full access to the key. ZeroMemory (&ea, sizeof (EXPLICIT_ACCESS)); ea[0].grfAccessPermissions = EVENT_ALL_ACCESS; 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) pEveryoneSID; // Create a new ACL that contains the new ACEs. if (SetEntriesInAcl (1, ea, NULL, &pACL) != ERROR_SUCCESS) goto simple_mutex; // Initialize a security descriptor. pSD = (PSECURITY_DESCRIPTOR) LocalAlloc (LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH); if (pSD == NULL) goto simple_mutex; if (! InitializeSecurityDescriptor (pSD, SECURITY_DESCRIPTOR_REVISION)) goto simple_mutex; // Add the ACL to the security descriptor. if (! SetSecurityDescriptorDacl (pSD, TRUE, pACL, FALSE)) goto simple_mutex; // Initialize a security attributes structure. sa.nLength = sizeof (SECURITY_ATTRIBUTES); sa.lpSecurityDescriptor = pSD; sa.bInheritHandle = FALSE; // Create our mutex. Windows XP uses terminal services to support user // switching. The "Global\" prefix is required so that this mutex is // is created in the global kernel objects namespace. Unfortunately, // the "\" character raises an error on Windows 95/98/Me systems. g_hMutexInst = CreateMutex ( &sa, // World access FALSE, // Not owned !! buf); // Unique name if (g_hMutexInst == NULL) simple_mutex: g_hMutexInst = CreateMutex ( NULL, // No security stuff FALSE, // Not owned !! buf+7); // Unique name mutex_error_code = GetLastError (); // Cleanup all the security structures we initialized if (pEveryoneSID) FreeSid (pEveryoneSID); if (pACL) LocalFree (pACL); if (pSD) LocalFree (pSD); // Test for failure if (g_hMutexInst == NULL) return 0; // If mutex already exists then another instance is already running if (mutex_error_code == ERROR_ALREADY_EXISTS) { HWND hwndPrevInst = 0; // Give other instance a little time to display it's main window Sleep (750); // Find the window handle EnumWindows (&MyEnumProc, (LPARAM) &hwndPrevInst); // Unhide the other instance's window if (hwndPrevInst) { ShowWindow (hwndPrevInst, SW_HIDE); ShowWindow (hwndPrevInst, SW_SHOWMINIMIZED); ShowWindow (hwndPrevInst, SW_SHOWNORMAL); } CloseHandle (g_hMutexInst); g_hMutexInst = NULL; return 0; } // Set the window user data so we can be identified by // another instance of this program. SetWindowLongPtr (m_pMainWnd->m_hWnd, GWLP_USERDATA, (LONG_PTR) g_MutexNum); } /* Cache icon handles to work around Windows deadlocking bug */ ICON_IDLE = LoadIcon (IDI_YELLOW_ICON); ICON_WORKING = LoadIcon (IDR_MAINFRAME); /* Name and read the INI files. Perform some other startup initializations. */ nameAndReadIniFiles (named_ini_files); initCommCode (); /* Before processing the INI file, hide and/or position the */ /* main window so that we can display error messages */ m_pMainWnd->SetWindowText ("Prime95"); WINDOWPLACEMENT wp; m_pMainWnd->GetWindowPlacement (&wp); int left = IniGetInt (INI_FILE, "Left", 0); int top = IniGetInt (INI_FILE, "Top", 0); int right = IniGetInt (INI_FILE, "Right", 0); int bottom = IniGetInt (INI_FILE, "Bottom", 0); if (right + left + top + bottom != 0) { wp.rcNormalPosition.left = left; wp.rcNormalPosition.top = top; wp.rcNormalPosition.right = right; wp.rcNormalPosition.bottom = bottom; } wp.showCmd = HIDE_ICON ? SW_HIDE : SW_SHOWMINIMIZED; m_pMainWnd->SetWindowPlacement (&wp); /* Now show the main window and post initial messages */ // Put prime95 in the system tray if (TRAY_ICON) TrayMessage (NIM_ADD, "Prime95", 0); // See if we are running as a Windows95 service WINDOWS95_SERVICE = IniGetInt (INI_FILE, "Windows95Service", 0); WINDOWS95_A_SWITCH = named_ini_files; Service95 (); // Run the torture test if asked to by a command line argument if (torture_test) { m_pMainWnd->ShowWindow (orig_cmdShow); m_pMainWnd->PostMessage (WM_COMMAND, USR_TORTURE, 0); } // On first run, see if this is a stress tester. If not, step // user throught the primenet dialog boxes. else if (STRESS_TESTER == 99) { m_pMainWnd->ShowWindow (orig_cmdShow); m_pMainWnd->PostMessage (WM_COMMAND, USR_WELCOME, 0); } // Take stress testers straight to the torture dialog box else if (STRESS_TESTER) { m_pMainWnd->ShowWindow (orig_cmdShow); m_pMainWnd->PostMessage (WM_COMMAND, IDM_TORTURE, 0); } // Auto-continue if there is any work to do. else if (USE_PRIMENET || WELL_BEHAVED_WORK || WORKTODO_COUNT) { m_pMainWnd->PostMessage (WM_COMMAND, IDM_CONTINUE, 0); } // Otherwise, show the window else if (!HIDE_ICON) { m_pMainWnd->ShowWindow (orig_cmdShow); ChangeIcon (MAIN_THREAD_NUM, IDLE_ICON); } // Initialization complete return TRUE; }
nsresult TestPermissions() { nsresult rv; // Return value // File variables HANDLE tempFileHandle; nsCOMPtr<nsILocalFile> tempFile; nsCOMPtr<nsILocalFile> tempDirectory1; nsCOMPtr<nsILocalFile> tempDirectory2; WCHAR filePath[MAX_PATH]; WCHAR dir1Path[MAX_PATH]; WCHAR dir2Path[MAX_PATH]; // Security variables DWORD result; PSID everyoneSID = NULL, adminSID = NULL; PACL dirACL = NULL, fileACL = NULL; PSECURITY_DESCRIPTOR dirSD = NULL, fileSD = NULL; EXPLICIT_ACCESS ea[2]; SID_IDENTIFIER_AUTHORITY SIDAuthWorld = SECURITY_WORLD_SID_AUTHORITY; SID_IDENTIFIER_AUTHORITY SIDAuthNT = SECURITY_NT_AUTHORITY; SECURITY_ATTRIBUTES sa; TRUSTEE everyoneTrustee; ACCESS_MASK everyoneRights; // Create a well-known SID for the Everyone group. if(!AllocateAndInitializeSid(&SIDAuthWorld, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, &everyoneSID)) { fail("NTFS Permissions: AllocateAndInitializeSid Error"); return NS_ERROR_FAILURE; } // Create a SID for the Administrators group. if(! AllocateAndInitializeSid(&SIDAuthNT, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &adminSID)) { fail("NTFS Permissions: AllocateAndInitializeSid Error"); return NS_ERROR_FAILURE; } // Initialize an EXPLICIT_ACCESS structure for an ACE. // The ACE will allow Everyone read access to the directory. ZeroMemory(&ea, 2 * sizeof(EXPLICIT_ACCESS)); ea[0].grfAccessPermissions = GENERIC_READ; 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) everyoneSID; // Initialize an EXPLICIT_ACCESS structure for an ACE. // The ACE will allow the Administrators group full access ea[1].grfAccessPermissions = GENERIC_ALL | STANDARD_RIGHTS_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_GROUP; ea[1].Trustee.ptstrName = (LPTSTR) adminSID; // Create a new ACL that contains the new ACEs. result = SetEntriesInAcl(2, ea, NULL, &dirACL); if (ERROR_SUCCESS != result) { fail("NTFS Permissions: SetEntriesInAcl Error"); return NS_ERROR_FAILURE; } // Initialize a security descriptor. dirSD = (PSECURITY_DESCRIPTOR) LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH); if (NULL == dirSD) { fail("NTFS Permissions: LocalAlloc Error"); return NS_ERROR_FAILURE; } if (!InitializeSecurityDescriptor(dirSD, SECURITY_DESCRIPTOR_REVISION)) { fail("NTFS Permissions: InitializeSecurityDescriptor Error"); return NS_ERROR_FAILURE; } // Add the ACL to the security descriptor. if (!SetSecurityDescriptorDacl(dirSD, true, dirACL, false)) { fail("NTFS Permissions: SetSecurityDescriptorDacl Error"); return NS_ERROR_FAILURE; } // Initialize a security attributes structure. sa.nLength = sizeof (SECURITY_ATTRIBUTES); sa.lpSecurityDescriptor = dirSD; sa.bInheritHandle = false; // Create and open first temporary directory if(!CreateDirectoryW(L".\\NTFSPERMTEMP1", &sa)) { fail("NTFS Permissions: Creating Temporary Directory"); return NS_ERROR_FAILURE; } GetFullPathNameW((LPCWSTR)L".\\NTFSPERMTEMP1", MAX_PATH, dir1Path, NULL); rv = NS_NewLocalFile(nsEmbedString(dir1Path), false, getter_AddRefs(tempDirectory1)); if (NS_FAILED(rv)) { fail("NTFS Permissions: Opening Temporary Directory 1"); return rv; } // Create and open temporary file tempFileHandle = CreateFileW(L".\\NTFSPERMTEMP1\\NTFSPerm.tmp", GENERIC_READ | GENERIC_WRITE, 0, NULL, //default security CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if(tempFileHandle == INVALID_HANDLE_VALUE) { fail("NTFS Permissions: Creating Temporary File"); return NS_ERROR_FAILURE; } CloseHandle(tempFileHandle); GetFullPathNameW((LPCWSTR)L".\\NTFSPERMTEMP1\\NTFSPerm.tmp", MAX_PATH, filePath, NULL); rv = NS_NewLocalFile(nsEmbedString(filePath), false, getter_AddRefs(tempFile)); if (NS_FAILED(rv)) { fail("NTFS Permissions: Opening Temporary File"); return rv; } // Update Everyone Explict_Acess to full access. ea[0].grfAccessPermissions = GENERIC_ALL | STANDARD_RIGHTS_ALL; // Update the ACL to contain the new ACEs. result = SetEntriesInAcl(2, ea, NULL, &dirACL); if (ERROR_SUCCESS != result) { fail("NTFS Permissions: SetEntriesInAcl 2 Error"); return NS_ERROR_FAILURE; } // Add the new ACL to the security descriptor. if (!SetSecurityDescriptorDacl(dirSD, true, dirACL, false)) { fail("NTFS Permissions: SetSecurityDescriptorDacl 2 Error"); return NS_ERROR_FAILURE; } // Create and open second temporary directory if(!CreateDirectoryW(L".\\NTFSPERMTEMP2", &sa)) { fail("NTFS Permissions: Creating Temporary Directory 2"); return NS_ERROR_FAILURE; } GetFullPathNameW((LPCWSTR)L".\\NTFSPERMTEMP2", MAX_PATH, dir2Path, NULL); rv = NS_NewLocalFile(nsEmbedString(dir2Path), false, getter_AddRefs(tempDirectory2)); if (NS_FAILED(rv)) { fail("NTFS Permissions: Opening Temporary Directory 2"); return rv; } // Move the file. rv = tempFile->MoveTo(tempDirectory2, EmptyString()); if (NS_FAILED(rv)) { fail("NTFS Permissions: Moving"); return rv; } // Access the ACL of the file result = GetNamedSecurityInfoW(L".\\NTFSPERMTEMP2\\NTFSPerm.tmp", SE_FILE_OBJECT, DACL_SECURITY_INFORMATION | UNPROTECTED_DACL_SECURITY_INFORMATION, NULL, NULL, &fileACL, NULL, &fileSD); if (ERROR_SUCCESS != result) { fail("NTFS Permissions: GetNamedSecurityDescriptor Error"); return NS_ERROR_FAILURE; } // Build a trustee representing "Everyone" BuildTrusteeWithSid(&everyoneTrustee, everyoneSID); // Get Everyone's effective rights. result = GetEffectiveRightsFromAcl(fileACL, &everyoneTrustee, &everyoneRights); if (ERROR_SUCCESS != result) { fail("NTFS Permissions: GetEffectiveRightsFromAcl Error"); return NS_ERROR_FAILURE; } // Check for delete access, which we won't have unless permissions have // updated if((everyoneRights & DELETE) == (DELETE)) { passed("NTFS Permissions Test"); rv = NS_OK; } else { fail("NTFS Permissions: Access check."); rv = NS_ERROR_FAILURE; } // Cleanup if (everyoneSID) FreeSid(everyoneSID); if (adminSID) FreeSid(adminSID); if (dirACL) LocalFree(dirACL); if (dirSD) LocalFree(dirSD); if(fileACL) LocalFree(fileACL); tempDirectory1->Remove(true); tempDirectory2->Remove(true); return rv; }
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); } }
void changeServiceAccess(const char* szName) { gcAssert(szName); SC_HANDLE scm = nullptr; SC_HANDLE Service = nullptr; BOOL bDaclPresent = FALSE; BOOL bDaclDefaulted = FALSE; DWORD dwSize = 0; EXPLICIT_ACCESS ea; PACL pacl = nullptr; PACL pNewAcl = nullptr; PSECURITY_DESCRIPTOR psd = nullptr; SECURITY_DESCRIPTOR sd; //open connection to SCM scm = OpenSCManager(nullptr, nullptr, SC_MANAGER_CONNECT); if (!scm) throw gcException(ERR_NULLSCMANAGER, GetLastError(), "Failed to open the Service Control Manager"); gcWString wName(szName); try { //open service Service = OpenService(scm, wName.c_str(), READ_CONTROL|WRITE_DAC); if (!Service) throw gcException(ERR_NULLSERVICE, GetLastError(), gcString("Failed to open service: {0}", szName)); // Get the current security descriptor. if (!QueryServiceObjectSecurity(Service, DACL_SECURITY_INFORMATION, psd, 0, &dwSize)) { if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) { psd = (PSECURITY_DESCRIPTOR)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwSize); if (!psd) throw gcException(ERR_SERVICE, gcString("Failed heap allocation for service service: {0}", szName)); //get securtty info if (!QueryServiceObjectSecurity(Service, DACL_SECURITY_INFORMATION, psd, dwSize, &dwSize)) throw gcException(ERR_SERVICE, GetLastError(), gcString("QueryServiceObjectSecurity failed for service: {0}", szName)); } } if (!psd) throw gcException(ERR_SERVICE, gcString("Failed heap allocation for service service: {0}", szName)); // Get the DACL. if (!GetSecurityDescriptorDacl(psd, &bDaclPresent, &pacl, &bDaclDefaulted)) throw gcException(ERR_SERVICE, GetLastError(), gcString("GetSecurityDescriptorDacl failed for service: {0}", szName)); DWORD SidSize; PSID TheSID; SidSize = SECURITY_MAX_SID_SIZE; // Allocate enough memory for the largest possible SID. if(!(TheSID = LocalAlloc(LMEM_FIXED, SidSize))) { LocalFree(TheSID); throw gcException(ERR_SERVICE, GetLastError(), gcString("LocalAlloc failed for service: {0}", szName)); } if(!CreateWellKnownSid(WinWorldSid, nullptr, TheSID, &SidSize)) { LocalFree(TheSID); throw gcException(ERR_SERVICE, GetLastError(), gcString("CreateWellKnownSid failed for service: {0}", szName)); } wchar_t everyone[255]; wchar_t domain[255]; DWORD eSize = 255; DWORD dSize = 255; SID_NAME_USE rSidNameUse; if (!LookupAccountSid(nullptr, TheSID, everyone, &eSize, domain, &dSize, &rSidNameUse)) { LocalFree(TheSID); throw gcException(ERR_SERVICE, GetLastError(), gcString("LookupAccountSid failed for service: {0}", szName)); } LocalFree(TheSID); // Build the ACE. BuildExplicitAccessWithName(&ea, everyone, SERVICE_START|SERVICE_STOP|READ_CONTROL|SERVICE_QUERY_STATUS|PROCESS_QUERY_INFORMATION, SET_ACCESS, NO_INHERITANCE); if (SetEntriesInAcl(1, &ea, pacl, &pNewAcl) != ERROR_SUCCESS) { throw gcException(ERR_SERVICE, GetLastError(), gcString("SetEntriesInAcl failed for service: {0}", szName)); } // Initialize a NEW Security Descriptor. if (!InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION)) throw gcException(ERR_SERVICE, GetLastError(), gcString("InitializeSecurityDescriptor failed for service: {0}", szName)); // Set the new DACL in the Security Descriptor. if (!SetSecurityDescriptorDacl(&sd, TRUE, pNewAcl, FALSE)) throw gcException(ERR_SERVICE, GetLastError(), gcString("SetSecurityDescriptorDacl failed for service: {0}", szName)); // Set the new DACL for the service object. if (!SetServiceObjectSecurity(Service, DACL_SECURITY_INFORMATION, &sd)) throw gcException(ERR_SERVICE, GetLastError(), gcString("SetServiceObjectSecurity failed for service: {0}", szName)); } catch (gcException &e) { if (Service) CloseServiceHandle(Service); if (scm) CloseServiceHandle(scm); // Free buffers. LocalFree((HLOCAL)pNewAcl); HeapFree(GetProcessHeap(), 0, (LPVOID)psd); throw e; } CloseServiceHandle(scm); CloseServiceHandle(Service); // Free buffers. LocalFree((HLOCAL)pNewAcl); HeapFree(GetProcessHeap(), 0, (LPVOID)psd); }
PVOID DisableProt(BOOL mode) { HANDLE Section; DWORD Res; NTSTATUS ntS; PACL OldDacl=NULL, NewDacl=NULL; PSECURITY_DESCRIPTOR SecDesc=NULL; EXPLICIT_ACCESS Access; OBJECT_ATTRIBUTES ObAttributes; INIT_UNICODE(ObName, L"\\Device\\PhysicalMemory"); //mode 1 = current //mode 2 = user memset(&Access, 0, sizeof(EXPLICIT_ACCESS)); InitializeObjectAttributes(&ObAttributes, &ObName, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL); // open handle de \Device\PhysicalMemory ntS = NtOpenSection(&Section, WRITE_DAC | READ_CONTROL, &ObAttributes); if (ntS != STATUS_SUCCESS) { printf("error: NtOpenSection (code: %x)\n", ntS); goto cleanup; } // retrieve a copy of the security descriptor Res = GetSecurityInfo(Section, SE_KERNEL_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, &OldDacl, NULL, &SecDesc); if (Res != ERROR_SUCCESS) { printf("error: GetSecurityInfo (code: %lu)\n", Res); goto cleanup; } Access.grfAccessPermissions = SECTION_ALL_ACCESS; // :P Access.grfAccessMode = GRANT_ACCESS; Access.grfInheritance = NO_INHERITANCE; Access.Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE; // change these informations to grant access to a group or other user Access.Trustee.TrusteeForm = TRUSTEE_IS_NAME; Access.Trustee.TrusteeType = TRUSTEE_IS_USER; Access.Trustee.ptstrName = "CURRENT_USER"; // create the new ACL Res = SetEntriesInAcl(1, &Access, OldDacl, &NewDacl); if (Res != ERROR_SUCCESS) { printf("error: SetEntriesInAcl (code: %lu)\n", Res); goto cleanup; } // update ACL Res = SetSecurityInfo(Section, SE_KERNEL_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, NewDacl, NULL); if (Res != ERROR_SUCCESS) { printf("error: SetEntriesInAcl (code: %lu)\n", Res); goto cleanup; } printf("\\Device\\PhysicalMemory chmoded\n"); cleanup: if (Section) NtClose(Section); if (SecDesc) LocalFree(SecDesc); return(0); }