/* * StoreACL: Stores the value of the class variable pACL in the registry. * Returns TRUE if successful. */ BOOL vncAccessControl::StoreACL(PACL pACL){ HKEY hk = NULL; BOOL isSaveOK = FALSE; ACL_SIZE_INFORMATION AclInfo = {0, 0, 0}; DWORD nAclInformationLength = sizeof(AclInfo); // Todo: Better error handling if (pACL) GetAclInformation(pACL, &AclInfo, nAclInformationLength, AclSizeInformation); __try{ if (RegCreateKey(HKEY_LOCAL_MACHINE, _T("Software\\ORL\\WinVNC3"), &hk) != ERROR_SUCCESS){ __leave; } if (hk) RegCloseKey(hk); if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("Software\\ORL\\WinVNC3"), 0, KEY_SET_VALUE, &hk) != ERROR_SUCCESS){ __leave; } if (RegSetValueEx(hk, _T("ACL"), 0, REG_BINARY, (LPBYTE) pACL, AclInfo.AclBytesInUse) != ERROR_SUCCESS){ __leave; } isSaveOK = TRUE; } __finally { if (hk) RegCloseKey(hk); } return isSaveOK; }
HRESULT COpcSecurity::CopyACL(PACL pDest, PACL pSrc) { ACL_SIZE_INFORMATION aclSizeInfo; LPVOID pAce; ACE_HEADER *aceHeader; if (pSrc == NULL) return S_OK; if (!GetAclInformation(pSrc, (LPVOID) &aclSizeInfo, sizeof(ACL_SIZE_INFORMATION), AclSizeInformation)) return HRESULT_FROM_WIN32(GetLastError()); // Copy all of the ACEs to the new ACL for (UINT i = 0; i < aclSizeInfo.AceCount; i++) { if (!GetAce(pSrc, i, &pAce)) return HRESULT_FROM_WIN32(GetLastError()); aceHeader = (ACE_HEADER *) pAce; if (!AddAce(pDest, ACL_REVISION, 0xffffffff, pAce, aceHeader->AceSize)) return HRESULT_FROM_WIN32(GetLastError()); } return S_OK; }
void DumpSD(PSECURITY_DESCRIPTOR pSD) { DWORD dwSize = GetSecurityDescriptorLength(pSD); printf("\nSecurity Descriptor is of size %d", dwSize); BOOL DaclPresent, DaclDefaulted; PACL pDacl; if(GetSecurityDescriptorDacl(pSD, &DaclPresent, &pDacl, &DaclDefaulted) && DaclPresent) { // Dump the aces ACL_SIZE_INFORMATION inf; DWORD dwNumAces; if(GetAclInformation( pDacl, &inf, sizeof(ACL_SIZE_INFORMATION), AclSizeInformation )) { dwNumAces = inf.AceCount; printf("\nThe DACL has %d ACEs", dwNumAces); for(DWORD dwCnt = 0; dwCnt < dwNumAces; dwCnt++) { ACCESS_ALLOWED_ACE * pAce; if(GetAce(pDacl, dwCnt, (LPVOID *)&pAce)) DumpAce(pAce); } } } }
static PyObject *get_perms(PyObject *self, PyObject *args) { PyObject *py_perms = PyDict_New(); //get file or directory name char *file; if (!PyArg_ParseTuple(args, "s", &file)) return NULL; //setup security code PSECURITY_DESCRIPTOR pSD; PACL pDACL; //GetNamedSecurityInfo() will give you the DACL when you ask for //DACL_SECURITY_INFORMATION. At this point, you have SIDs in the ACEs contained in the DACL. ULONG result = GetNamedSecurityInfo(file,SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, &pDACL, NULL, &pSD); if (result != ERROR_SUCCESS){ return NULL;} if (result == ERROR_SUCCESS){ ACL_SIZE_INFORMATION aclSize = {0}; if(pDACL != NULL){ if(!GetAclInformation(pDACL, &aclSize, sizeof(aclSize), AclSizeInformation)){ return NULL; } } file_perms *fp = new file_perms[aclSize.AceCount]; acl_info(pDACL, aclSize.AceCount, fp ); //Dict for (ULONG i=0;i //Boilerplate functions //3 parts //name of python function //C++ function //flags METH_VARARGS means function takes variable number of args static PyMethodDef fileperm_methods[] = { { "get_perms", get_perms, METH_VARARGS }, { NULL } }; void initfileperm() { Py_InitModule("fileperm",fileperm_methods); }
HRESULT RemoveAllInheritedAces(PACL *ppAcl) { BOOL bResult = FALSE; DWORD errorCode = S_OK; HRESULT hr = S_OK; ACL_SIZE_INFORMATION aclInformation; DWORD totalCount; DWORD aceIndex = 0; LPVOID ace = nullptr; BYTE aceFlags = 0; if ( !ARGUMENT_PRESENT(*ppAcl) ) { return E_INVALIDARG; } bResult = GetAclInformation( *ppAcl, &aclInformation, sizeof(aclInformation), AclSizeInformation ); FailGracefullyGLE(bResult, L"GetAclInformation"); totalCount = aclInformation.AceCount; while ( aceIndex < totalCount ) { bResult = GetAce( *ppAcl, aceIndex, &ace ); FailGracefullyGLE(bResult, L"GetAce"); aceFlags = ((PACE_HEADER)ace)->AceFlags; if (IS_FLAG_SET(aceFlags,INHERITED_ACE)) { bResult = DeleteAce( *ppAcl, aceIndex); FailGracefullyGLE(bResult, L"DeleteAce"); totalCount--; } else { aceIndex++; } } exit_gracefully: return hr; }
// This goes through every ACE in 'acl', sums the size of the inheritable // ACEs, and puts it in dwSizeNeeded. HRESULT GetSizeOfAllInheritableAces(PACL acl, DWORD &dwSizeNeeded) { BOOL bResult; DWORD errorCode = S_OK; HRESULT hr = S_OK; ACL_SIZE_INFORMATION aclInformation; DWORD totalCount; LPVOID ace; BYTE aceFlags; if ( !ARGUMENT_PRESENT(acl) ) { return E_INVALIDARG; } bResult = GetAclInformation( acl, &aclInformation, sizeof(aclInformation), AclSizeInformation ); FailGracefullyGLE(bResult, L"GetAclInformation"); totalCount = aclInformation.AceCount; // Start with zero as the size. We'll only initialize this // to sizeof(ACL) if we find an inheritable ACE. dwSizeNeeded = 0; for ( DWORD aceIndex = 0; aceIndex < totalCount; aceIndex ++ ) { bResult = GetAce( acl, aceIndex, &ace ); FailGracefullyGLE(bResult, L"GetAce"); aceFlags = ((PACE_HEADER)ace)->AceFlags; // Only count the inheritable ACEs if (IsInheritableAce(aceFlags)) { // Initialize the size now that we've found an inheritable ACE if ( dwSizeNeeded == 0 ) { dwSizeNeeded = sizeof(ACL); } dwSizeNeeded += ((PACE_HEADER)ace)->AceSize; } } exit_gracefully: return hr; }
void Process::fillAceList(){ ACL_SIZE_INFORMATION aclSizeInfo; ZeroMemory(&aclSizeInfo, sizeof(ACL_SIZE_INFORMATION)); aclSizeInfo.AclBytesInUse = sizeof(ACL); ACL_REVISION_INFORMATION aclRevisionInformation; ZeroMemory(&aclRevisionInformation,sizeof(ACL_REVISION_INFORMATION)); GetAclInformation( _dacl, (LPVOID)&aclRevisionInformation, sizeof(ACL_REVISION_INFORMATION), AclRevisionInformation); DWORD dwRtnCode = GetAclInformation(//Узнаем всю информацию о ACL. - Кол-во ACE в ней _dacl, (LPVOID)&aclSizeInfo, sizeof(ACL_SIZE_INFORMATION), AclSizeInformation); if (!dwRtnCode) throw(ProcessException("GetAclInformation error =",GetLastError())); PVOID pAce; for (DWORD i=0;i<aclSizeInfo.AceCount;++i){//По всем ACE if (GetAce(_dacl,i,&pAce)){ switch (((ACE_HEADER*)pAce)->AceType) { case ACCESS_ALLOWED_ACE_TYPE: _allowedACEs.push_back((ACCESS_ALLOWED_ACE*)pAce); break; case ACCESS_DENIED_ACE_TYPE: _deniedACEs.push_back((ACCESS_DENIED_ACE*)pAce); break; default: printf("Undefined type\n"); break; } }else throw(ProcessException("GetAce ERROR = ", GetLastError())); } }
void vncImportACL::GetOldACL(){ PACL pOldACL = NULL; ACL_SIZE_INFORMATION asi; HKEY hk = NULL; DWORD dwValueLength = SECURITY_DESCRIPTOR_MIN_LENGTH; __try{ if (ERROR_SUCCESS != RegOpenKeyEx( HKEY_LOCAL_MACHINE, _T("Software\\ORL\\WinVNC3"), 0, KEY_QUERY_VALUE, &hk )){ __leave; } // Read the ACL value from the VNC registry key // First call to RegQueryValueEx just gets the buffer length. if (ERROR_SUCCESS != RegQueryValueEx(hk, // subkey handle _T("ACL"), // value name 0, // must be zero 0, // value type , not needed here NULL, // &dwValueLength)){ // length of value data __leave; } pOldACL = (PACL) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwValueLength); if (ERROR_SUCCESS != RegQueryValueEx(hk, // subkey handle _T("ACL"), // value name 0, // must be zero 0, // value type (LPBYTE) pOldACL, &dwValueLength)){ // length of value data __leave; } } __finally { if (hk) RegCloseKey(hk); } if ( pOldACL == NULL ) return; if (!GetAclInformation( pOldACL, &asi, sizeof asi, AclSizeInformation)) { _ftprintf(stderr, _T("GAI(): gle == %lu\n"), GetLastError()); return; } for (DWORD i = 0; i < asi.AceCount; ++ i) ReadAce(i, pOldACL); HeapFree(GetProcessHeap(), 0, pOldACL); }
DWORD AddAccessDeniedACEToACL ( PACL *Acl, DWORD PermissionMask, LPTSTR Principal ) { ACL_SIZE_INFORMATION aclSizeInfo; int aclSize; DWORD returnValue; PSID principalSID; PACL oldACL, newACL; oldACL = *Acl; returnValue = GetPrincipalSID (Principal, &principalSID); if (returnValue != ERROR_SUCCESS) return returnValue; GetAclInformation (oldACL, (LPVOID) &aclSizeInfo, (DWORD) sizeof (ACL_SIZE_INFORMATION), AclSizeInformation); aclSize = aclSizeInfo.AclBytesInUse + sizeof (ACL) + sizeof (ACCESS_DENIED_ACE) + GetLengthSid (principalSID) - sizeof (DWORD); newACL = (PACL) new BYTE [aclSize]; if (!InitializeAcl (newACL, aclSize, ACL_REVISION)) { free (principalSID); return GetLastError(); } if (!AddAccessDeniedAce (newACL, ACL_REVISION2, PermissionMask, principalSID)) { free (principalSID); return GetLastError(); } returnValue = CopyACL (oldACL, newACL); if (returnValue != ERROR_SUCCESS) { free (principalSID); return returnValue; } *Acl = newACL; free (principalSID); return ERROR_SUCCESS; }
HRESULT COpcSecurity::AddAccessAllowedACEToACL(PACL *ppAcl, LPCTSTR pszPrincipal, DWORD dwAccessMask) { ACL_SIZE_INFORMATION aclSizeInfo; int aclSize; DWORD returnValue; PSID principalSID; PACL oldACL, newACL = NULL; oldACL = *ppAcl; returnValue = GetPrincipalSID(pszPrincipal, &principalSID); if (FAILED(returnValue)) return returnValue; aclSizeInfo.AclBytesInUse = 0; if (*ppAcl != NULL) GetAclInformation(oldACL, (LPVOID) &aclSizeInfo, (DWORD) sizeof(ACL_SIZE_INFORMATION), AclSizeInformation); aclSize = aclSizeInfo.AclBytesInUse + sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(principalSID) - sizeof(DWORD); OPCTRY(newACL = (PACL) new BYTE[aclSize]); if (newACL == NULL) return E_OUTOFMEMORY; if (!InitializeAcl(newACL, aclSize, ACL_REVISION)) { free(principalSID); return HRESULT_FROM_WIN32(GetLastError()); } returnValue = CopyACL(newACL, oldACL); if (FAILED(returnValue)) { free(principalSID); return returnValue; } if (!AddAccessAllowedAce(newACL, ACL_REVISION2, dwAccessMask, principalSID)) { free(principalSID); return HRESULT_FROM_WIN32(GetLastError()); } *ppAcl = newACL; if (oldACL != NULL) free(oldACL); free(principalSID); return S_OK; }
/* * Returns JNI_TRUE if the specified owner is the only SID will access * to the file. */ static jboolean isAccessUserOnly(JNIEnv* env, SID* owner, ACL* acl) { ACL_SIZE_INFORMATION acl_size_info; DWORD i; /* * If there's no DACL then there's no access to the file */ if (acl == NULL) { return JNI_TRUE; } /* * Get the ACE count */ if (!GetAclInformation(acl, (void *) &acl_size_info, sizeof(acl_size_info), AclSizeInformation)) { JNU_ThrowIOExceptionWithLastError(env, "GetAclInformation failed"); return JNI_FALSE; } /* * Iterate over the ACEs. For each "allow" type check that the SID * matches the owner, and check that the access is read only. */ for (i = 0; i < acl_size_info.AceCount; i++) { void* ace; ACCESS_ALLOWED_ACE *access; SID* sid; if (!GetAce(acl, i, &ace)) { JNU_ThrowIOExceptionWithLastError(env, "GetAce failed"); return -1; } if (((ACCESS_ALLOWED_ACE *)ace)->Header.AceType != ACCESS_ALLOWED_ACE_TYPE) { continue; } access = (ACCESS_ALLOWED_ACE *)ace; sid = (SID *) &access->SidStart; if (!EqualSid(owner, sid)) { /* * If the ACE allows any access then the file is not secure. */ if (access->Mask & ANY_ACCESS) { return JNI_FALSE; } } } return JNI_TRUE; }
DWORD CopyACL( PACL OldACL, PACL NewACL) { ACL_SIZE_INFORMATION aclSizeInfo; LPVOID ace; ACE_HEADER *aceHeader; ULONG i; GetAclInformation( OldACL, (LPVOID) &aclSizeInfo, (DWORD) sizeof (aclSizeInfo), AclSizeInformation); // // Copy all of the ACEs to the new ACL // for (i = 0; i < aclSizeInfo.AceCount; i++) { // // Get the ACE and header info // if (!GetAce (OldACL, i, &ace)) { return GetLastError(); } aceHeader = (ACE_HEADER *) ace; // // Add the ACE to the new list // if (!AddAce( NewACL, ACL_REVISION, 0xffffffff, ace, aceHeader->AceSize)) { return GetLastError(); } } return ERROR_SUCCESS; }
void vncExportACL::PrintAcl(PACL acl) { DWORD i; ACL_SIZE_INFORMATION aci; if ( acl == 0 ) return; if (!GetAclInformation( acl, &aci, sizeof aci, AclSizeInformation)) { _tprintf(_T("GAI(): gle == %lu\n"), GetLastError()); return; } for ( i = 0; i < aci.AceCount; ++ i ) PrintAce(i, acl); }
bool vncImportACL::SetACL(PACL pACL){ HKEY hk = NULL; bool isSaveOK = false; DWORD dwDisposition; ACL_SIZE_INFORMATION AclInformation = {0, 0, 0}; DWORD nAclInformationLength = sizeof(AclInformation); // Todo: Better error handling if (pACL) GetAclInformation(pACL, &AclInformation, nAclInformationLength, AclSizeInformation); __try{ //if (ERROR_SUCCESS != RegOpenKeyEx( HKEY_LOCAL_MACHINE, // _T("Software\\ORL\\WinVNC3"), // 0, KEY_SET_VALUE, &hk )){ // _ftprintf(stderr, _T("Error %d: RegOpenKeyEx\n"), GetLastError()); // __leave; //} if (ERROR_SUCCESS != RegCreateKeyEx( HKEY_LOCAL_MACHINE, _T("Software\\ORL\\WinVNC3"), 0, NULL, 0, KEY_SET_VALUE, NULL, &hk, &dwDisposition )){ _ftprintf(stderr, _T("Error %d: RegOpenKeyEx\n"), GetLastError()); __leave; } // Add the ACL value to the VNC registry key if (ERROR_SUCCESS != RegSetValueEx(hk, _T("ACL"), 0, REG_BINARY, (LPBYTE) pACL, AclInformation.AclBytesInUse)){ _ftprintf(stderr, _T("Error %d: RegSetValueEx\n"), GetLastError()); __leave; } isSaveOK = true; _ftprintf(stderr, _T("RegSetValueEx passed\n")); } __finally { if (hk) RegCloseKey(hk); } return isSaveOK; }
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; }
int perm_granted(char *path, int perm_mask, char *user, char *realuser) { int rc; DWORD i, j; ACL *pdacl = NULL; SECURITY_DESCRIPTOR *psd = NULL; ACL_SIZE_INFORMATION sizeInfo; ACCESS_ALLOWED_ACE *pace; struct accessinfo *allowed = NULL; struct accessinfo *denied = NULL; int mask; char *name; SID *usid; if (GetNamedSecurityInfo(path, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, 0, 0, &pdacl, 0, &psd) != ERROR_SUCCESS) { errno = GetLastError(); rc = 1; goto perm_chkerr; } usid = getusersid2(user, realuser); if (usid == NULL) { rc = 2; goto perm_chkerr; } /* make sure perm mask granted only to privilege groups or the special 'owner' */ GetAclInformation(pdacl, &sizeInfo, sizeof(sizeInfo), AclSizeInformation); allowed = (struct accessinfo *)malloc(sizeof(struct accessinfo)*sizeInfo.AceCount); denied = (struct accessinfo *)malloc(sizeof(struct accessinfo)*sizeInfo.AceCount); if (allowed == NULL || denied == NULL) { rc = 3; goto perm_chkerr; } accessinfo_init(allowed, sizeInfo.AceCount); accessinfo_init(denied, sizeInfo.AceCount); for (i=0; i < sizeInfo.AceCount; i++) { GetAce(pdacl, i, (void **)&pace); name = getgrpname_full((SID *)&pace->SidStart); if (name == NULL) name = getusername((SID *)&pace->SidStart); /* later, we need to also check denied access which */ /* overrides allowed access. */ if ( (pace->Header.AceType == ACCESS_ALLOWED_ACE_TYPE) && \ (mask=(pace->Mask & perm_mask)) && \ EqualSid((SID *)&pace->SidStart, usid) ) { (void)accessinfo_add(allowed, sizeInfo.AceCount, name, (mask & 0xFFFF)); } else if (pace->Header.AceType == ACCESS_DENIED_ACE_TYPE) { (void)accessinfo_add(denied, sizeInfo.AceCount, name, (pace->Mask & 0xFFFF)); } else { if (name) { (void)free(name); } } } /* filter the allowed pool so that none appear in denied */ for (i=0; i < sizeInfo.AceCount; i++) { for (j=0; j < sizeInfo.AceCount; j++) { if( allowed[i].group == NULL || \ denied[j].group == NULL ) continue; if (strcmp(allowed[i].group, denied[j].group) == 0) allowed[i].mask &= ~denied[j].mask; /* unset the denied mask from allowed */ } } /* now filter perm_mask to those specified in allowed */ for (i=0; i < sizeInfo.AceCount; i++) { if (allowed[i].group == NULL) continue; /* unset the allowed mask from perm_mask */ perm_mask &= ~allowed[i].mask; } if (perm_mask != 0) { rc = 4; goto perm_chkerr; } rc = 0; perm_chkerr: if (pdacl) LocalFree(pdacl); if (psd) LocalFree(psd); if (allowed) accessinfo_free(allowed, sizeInfo.AceCount); if (denied) accessinfo_free(denied, sizeInfo.AceCount); if (usid) LocalFree(usid); return (rc); }
/** * This function adjusts the specified Desktop to include the specfied * user. * * See: http://msdn2.microsoft.com/en-us/library/aa379608(VS.85).aspx **/ BOOL AddAceToDesktop(HDESK hdesk, PSID psid) { ACL_SIZE_INFORMATION aclSizeInfo; BOOL bDaclExist; BOOL bDaclPresent; BOOL bSuccess = FALSE; DWORD dwNewAclSize; DWORD dwSidSize = 0; DWORD dwSdSizeNeeded; PACL pacl = NULL; PACL pNewAcl = NULL; PSECURITY_DESCRIPTOR psd = NULL; PSECURITY_DESCRIPTOR psdNew = NULL; PVOID pTempAce; SECURITY_INFORMATION si = DACL_SECURITY_INFORMATION; unsigned int i; try { // Obtain the security descriptor for the desktop object. if (!GetUserObjectSecurity( hdesk, &si, psd, dwSidSize, &dwSdSizeNeeded)) { if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) { psd = (PSECURITY_DESCRIPTOR)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwSdSizeNeeded ); if (psd == NULL) throw; psdNew = (PSECURITY_DESCRIPTOR)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwSdSizeNeeded); if (psdNew == NULL) throw; dwSidSize = dwSdSizeNeeded; if (!GetUserObjectSecurity( hdesk, &si, psd, dwSidSize, &dwSdSizeNeeded) ) throw; } else throw; } // Create a new security descriptor. if (!InitializeSecurityDescriptor( psdNew, SECURITY_DESCRIPTOR_REVISION) ) throw; // Obtain the DACL from the security descriptor. if (!GetSecurityDescriptorDacl( psd, &bDaclPresent, &pacl, &bDaclExist) ) throw; // Initialize. ZeroMemory(&aclSizeInfo, sizeof(ACL_SIZE_INFORMATION)); aclSizeInfo.AclBytesInUse = sizeof(ACL); // Call only if NULL DACL. if (pacl != NULL) { // Determine the size of the ACL information. if (!GetAclInformation( pacl, (LPVOID)&aclSizeInfo, sizeof(ACL_SIZE_INFORMATION), AclSizeInformation) ) throw; } // Compute the size of the new ACL. dwNewAclSize = aclSizeInfo.AclBytesInUse + sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(psid) - sizeof(DWORD); // Allocate buffer for the new ACL. pNewAcl = (PACL)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwNewAclSize); if (pNewAcl == NULL) throw; // Initialize the new ACL. if (!InitializeAcl(pNewAcl, dwNewAclSize, ACL_REVISION)) throw; // If DACL is present, copy it to a new DACL. if (bDaclPresent) { // Copy the ACEs to the new ACL. if (aclSizeInfo.AceCount) { for (i=0; i < aclSizeInfo.AceCount; i++) { // Get an ACE. if (!GetAce(pacl, i, &pTempAce)) throw; // Add the ACE to the new ACL. if (!AddAce( pNewAcl, ACL_REVISION, MAXDWORD, pTempAce, ((PACE_HEADER)pTempAce)->AceSize) ) throw; } } } // Add ACE to the DACL. if (!AddAccessAllowedAce( pNewAcl, ACL_REVISION, GENERIC_ALL, psid) ) throw; // Set new DACL to the new security descriptor. if (!SetSecurityDescriptorDacl( psdNew, TRUE, pNewAcl, FALSE) ) throw; // Set the new security descriptor for the desktop object. if (!SetUserObjectSecurity(hdesk, &si, psdNew)) throw; // Indicate success. bSuccess = TRUE; } catch(...) { // Free buffers. if (pNewAcl != NULL) HeapFree(GetProcessHeap(), 0, (LPVOID)pNewAcl); if (psd != NULL) HeapFree(GetProcessHeap(), 0, (LPVOID)psd); if (psdNew != NULL) HeapFree(GetProcessHeap(), 0, (LPVOID)psdNew); } return bSuccess; }
/** * This function adjusts the specified WindowStation to include the specfied * user. * * See: http://msdn2.microsoft.com/en-us/library/aa379608(VS.85).aspx **/ BOOL AddAceToWindowStation(HWINSTA hwinsta, PSID psid) { ACCESS_ALLOWED_ACE *pace = NULL; ACL_SIZE_INFORMATION aclSizeInfo; BOOL bDaclExist; BOOL bDaclPresent; BOOL bSuccess = FALSE; DWORD dwNewAclSize; DWORD dwSidSize = 0; DWORD dwSdSizeNeeded; PACL pacl = NULL; PACL pNewAcl = NULL; PSECURITY_DESCRIPTOR psd = NULL; PSECURITY_DESCRIPTOR psdNew = NULL; PVOID pTempAce; SECURITY_INFORMATION si = DACL_SECURITY_INFORMATION; unsigned int i; try { // Obtain the DACL for the window station. if (!GetUserObjectSecurity( hwinsta, &si, psd, dwSidSize, &dwSdSizeNeeded) ) if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) { psd = (PSECURITY_DESCRIPTOR)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwSdSizeNeeded); if (psd == NULL) throw; psdNew = (PSECURITY_DESCRIPTOR)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwSdSizeNeeded); if (psdNew == NULL) throw; dwSidSize = dwSdSizeNeeded; if (!GetUserObjectSecurity( hwinsta, &si, psd, dwSidSize, &dwSdSizeNeeded) ) throw; } else throw; // Create a new DACL. if (!InitializeSecurityDescriptor( psdNew, SECURITY_DESCRIPTOR_REVISION) ) throw; // Get the DACL from the security descriptor. if (!GetSecurityDescriptorDacl( psd, &bDaclPresent, &pacl, &bDaclExist) ) throw; // Initialize the ACL. ZeroMemory(&aclSizeInfo, sizeof(ACL_SIZE_INFORMATION)); aclSizeInfo.AclBytesInUse = sizeof(ACL); // Call only if the DACL is not NULL. if (pacl != NULL) { // get the file ACL size info if (!GetAclInformation( pacl, (LPVOID)&aclSizeInfo, sizeof(ACL_SIZE_INFORMATION), AclSizeInformation) ) throw; } // Compute the size of the new ACL. dwNewAclSize = aclSizeInfo.AclBytesInUse + (2*sizeof(ACCESS_ALLOWED_ACE)) + (2*GetLengthSid(psid)) - (2*sizeof(DWORD)); // Allocate memory for the new ACL. pNewAcl = (PACL)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwNewAclSize); if (pNewAcl == NULL) throw; // Initialize the new DACL. if (!InitializeAcl(pNewAcl, dwNewAclSize, ACL_REVISION)) throw; // If DACL is present, copy it to a new DACL. if (bDaclPresent) { // Copy the ACEs to the new ACL. if (aclSizeInfo.AceCount) { for (i=0; i < aclSizeInfo.AceCount; i++) { // Get an ACE. if (!GetAce(pacl, i, &pTempAce)) throw; // Add the ACE to the new ACL. if (!AddAce( pNewAcl, ACL_REVISION, MAXDWORD, pTempAce, ((PACE_HEADER)pTempAce)->AceSize) ) throw; } } } // Add the first ACE to the window station. pace = (ACCESS_ALLOWED_ACE *)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(psid) - sizeof(DWORD) ); if (pace == NULL) throw; pace->Header.AceType = ACCESS_ALLOWED_ACE_TYPE; pace->Header.AceFlags = CONTAINER_INHERIT_ACE | INHERIT_ONLY_ACE | OBJECT_INHERIT_ACE; pace->Header.AceSize = (WORD)sizeof(ACCESS_ALLOWED_ACE) + (WORD)GetLengthSid(psid) - (WORD)sizeof(DWORD); pace->Mask = GENERIC_ALL; if (!CopySid(GetLengthSid(psid), &pace->SidStart, psid)) throw; if (!AddAce( pNewAcl, ACL_REVISION, MAXDWORD, (LPVOID)pace, pace->Header.AceSize) ) throw; // Add an ACE to the window station. pace->Header.AceFlags = NO_PROPAGATE_INHERIT_ACE; pace->Mask = GENERIC_ALL; if (!AddAce( pNewAcl, ACL_REVISION, MAXDWORD, (LPVOID)pace, pace->Header.AceSize) ) throw; // Set a new DACL for the security descriptor. if (!SetSecurityDescriptorDacl( psdNew, TRUE, pNewAcl, FALSE) ) throw; // Set the new security descriptor for the window station. if (!SetUserObjectSecurity(hwinsta, &si, psdNew)) throw; // Indicate success. bSuccess = TRUE; } catch(...) { // Free the allocated buffers. if (pace != NULL) HeapFree(GetProcessHeap(), 0, (LPVOID)pace); if (pNewAcl != NULL) HeapFree(GetProcessHeap(), 0, (LPVOID)pNewAcl); if (psd != NULL) HeapFree(GetProcessHeap(), 0, (LPVOID)psd); if (psdNew != NULL) HeapFree(GetProcessHeap(), 0, (LPVOID)psdNew); } return bSuccess; }
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); } }
static BOOL new_acl(SaveAclStruct *save_acl){ HANDLE tokenh; TOKEN_DEFAULT_DACL newdacl; DWORD required; PACL oldacl; PACL newacl; int i; ACL_SIZE_INFORMATION si; size_t newsize; PSID extra_sid; SID_IDENTIFIER_AUTHORITY nt_auth = SECURITY_NT_AUTHORITY; TOKEN_DEFAULT_DACL dummy; save_acl->initialized = FALSE; if(!OpenProcessToken(GetCurrentProcess(), TOKEN_READ|TOKEN_WRITE,&tokenh)){ log_warning("Failed to open access token."); return FALSE; } save_acl->defdacl = &dummy; required = sizeof(TOKEN_DEFAULT_DACL); GetTokenInformation(tokenh, TokenDefaultDacl, &(save_acl->defdacl), sizeof(TOKEN_DEFAULT_DACL), &required); if(required == 0){ log_warning("Failed to get any ACL info from token."); CloseHandle(tokenh); return FALSE; } save_acl->defdacl = LocalAlloc(LPTR,required); if(!GetTokenInformation(tokenh, TokenDefaultDacl, save_acl->defdacl, required, &required)){ #ifdef HARDDEBUG { char *mes; FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &mes, 0, NULL ); log_info(mes); LocalFree(mes); } #endif log_warning("Failed to get default ACL from token."); CloseHandle(tokenh); return FALSE; } oldacl = save_acl->defdacl->DefaultDacl; if(!GetAclInformation(oldacl, &si, sizeof(si), AclSizeInformation)){ log_warning("Failed to get size information for ACL"); CloseHandle(tokenh); return FALSE; } if(!AllocateAndInitializeSid(&nt_auth, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &extra_sid)){ log_warning("Failed to initialize administrator SID."); CloseHandle(tokenh); return FALSE; } newsize = si.AclBytesInUse + sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(extra_sid); newacl = LocalAlloc(LPTR,newsize); if(!InitializeAcl(newacl, newsize, ACL_REVISION)){ log_warning("Failed to initialize new ACL."); LocalFree(newacl); FreeSid(extra_sid); CloseHandle(tokenh); return FALSE; } for(i=0;i<((int)si.AceCount);++i){ ACE_HEADER *ace_header; if (!GetAce (oldacl, i, &ace_header)){ log_warning("Failed to get ACE from old ACL."); LocalFree(newacl); FreeSid(extra_sid); CloseHandle(tokenh); return FALSE; } if(!AddAce(newacl,ACL_REVISION,0xffffffff,ace_header, ace_header->AceSize)){ log_warning("Failed to set ACE in new ACL."); LocalFree(newacl); FreeSid(extra_sid); CloseHandle(tokenh); return FALSE; } } if(!AddAccessAllowedAce(newacl, ACL_REVISION2, PROCESS_ALL_ACCESS, extra_sid)){ log_warning("Failed to add system ACE to new ACL."); LocalFree(newacl); FreeSid(extra_sid); return FALSE; } newdacl.DefaultDacl = newacl; if(!SetTokenInformation(tokenh, TokenDefaultDacl, &newdacl, sizeof(newdacl))){ log_warning("Failed to set token information"); LocalFree(newacl); FreeSid(extra_sid); CloseHandle(tokenh); return FALSE; } save_acl->initialized = TRUE; save_acl->newacl = newacl; save_acl->adminsid = extra_sid; CloseHandle(tokenh); return TRUE; }
DWORD RemovePrincipalFromACL ( PACL Acl, LPTSTR Principal ) { ACL_SIZE_INFORMATION aclSizeInfo; ULONG i; LPVOID ace; ACCESS_ALLOWED_ACE *accessAllowedAce; ACCESS_DENIED_ACE *accessDeniedAce; SYSTEM_AUDIT_ACE *systemAuditAce; PSID principalSID; DWORD returnValue; ACE_HEADER *aceHeader; returnValue = GetPrincipalSID (Principal, &principalSID); if (returnValue != ERROR_SUCCESS) return returnValue; GetAclInformation (Acl, (LPVOID) &aclSizeInfo, (DWORD) sizeof (ACL_SIZE_INFORMATION), AclSizeInformation); for (i = 0; i < aclSizeInfo.AceCount; i++) { if (!GetAce (Acl, i, &ace)) { free (principalSID); return GetLastError(); } aceHeader = (ACE_HEADER *) ace; if (aceHeader->AceType == ACCESS_ALLOWED_ACE_TYPE) { accessAllowedAce = (ACCESS_ALLOWED_ACE *) ace; if (EqualSid (principalSID, (PSID) &accessAllowedAce->SidStart)) { DeleteAce (Acl, i); free (principalSID); return ERROR_SUCCESS; } } else if (aceHeader->AceType == ACCESS_DENIED_ACE_TYPE) { accessDeniedAce = (ACCESS_DENIED_ACE *) ace; if (EqualSid (principalSID, (PSID) &accessDeniedAce->SidStart)) { DeleteAce (Acl, i); free (principalSID); return ERROR_SUCCESS; } } else if (aceHeader->AceType == SYSTEM_AUDIT_ACE_TYPE) { systemAuditAce = (SYSTEM_AUDIT_ACE *) ace; if (EqualSid (principalSID, (PSID) &systemAuditAce->SidStart)) { DeleteAce (Acl, i); free (principalSID); return ERROR_SUCCESS; } } } free (principalSID); return ERROR_SUCCESS; }
/*---------------------------------------------------------------------------*\ * NAME: ListACL * * --------------------------------------------------------------------------* * DESCRIPTION: \*---------------------------------------------------------------------------*/ void ListACL ( PACL Acl, DWORD dwSDType ) { ACL_SIZE_INFORMATION aclSizeInfo = {0}; ACL_REVISION_INFORMATION aclRevInfo = {0}; ULONG i; LPVOID pvAce = NULL; ACE_HEADER *pAceHeader = NULL; ACCESS_ALLOWED_ACE *pAccessAllowedAce = NULL; ACCESS_DENIED_ACE *pAccessDeniedAce = NULL; TCHAR tszDomainName [SIZE_NAME_BUFFER] = {0}; TCHAR tszUserName [SIZE_NAME_BUFFER] = {0}; DWORD cchName = 0; SID_NAME_USE snu; if (!GetAclInformation (Acl, &aclSizeInfo, sizeof (ACL_SIZE_INFORMATION), AclSizeInformation)) { _tprintf (_T("Could not get AclSizeInformation")); return; } if (!GetAclInformation (Acl, &aclRevInfo, sizeof (ACL_REVISION_INFORMATION), AclRevisionInformation)) { _tprintf (_T("Could not get AclRevisionInformation")); return; } for (i = 0; i < aclSizeInfo.AceCount; i++) { if (!GetAce (Acl, i, &pvAce)) return; pAceHeader = (ACE_HEADER *) pvAce; if (pAceHeader->AceType == ACCESS_ALLOWED_ACE_TYPE) { pAccessAllowedAce = (ACCESS_ALLOWED_ACE *) pvAce; cchName = SIZE_NAME_BUFFER-1; LookupAccountSid (NULL, &pAccessAllowedAce->SidStart, tszUserName, &cchName, tszDomainName, &cchName, &snu); DisplayAccess(pAccessAllowedAce->Mask, dwSDType, _T("permitted"), tszUserName, tszDomainName); } else if (pAceHeader->AceType == ACCESS_DENIED_ACE_TYPE) { pAccessDeniedAce = (ACCESS_DENIED_ACE *) pvAce; cchName = SIZE_NAME_BUFFER-1; LookupAccountSid (NULL, &pAccessDeniedAce->SidStart, tszUserName, &cchName, tszDomainName, &cchName, &snu); DisplayAccess(pAccessDeniedAce->Mask, dwSDType, _T("denied"), tszUserName, tszDomainName); } } }
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; }
// // get_permissions: 1 = yes, 0 = no, -1 = unknown/error // int perm::get_permissions( const char *file_name, ACCESS_MASK &AccessRights ) { DWORD retVal; PACL pacl; PSECURITY_DESCRIPTOR pSD; DWORD pSD_length = 0; DWORD pSD_length_needed = 0; BOOL acl_present = FALSE; BOOL acl_defaulted = FALSE; // Do the call first to find out how much space is needed. pSD = NULL; GetFileSecurity( file_name, // address of string for file name DACL_SECURITY_INFORMATION, // requested information pSD, // address of security descriptor pSD_length, // size of security descriptor buffer &pSD_length_needed // address of required size of buffer ); if( pSD_length_needed <= 0 ) { // Find out how much space is needed, if <=0 then error if ( (GetLastError() == ERROR_FILE_NOT_FOUND) || (GetLastError() == ERROR_PATH_NOT_FOUND) ) { // Here we have the tricky part of walking up the directory path // Typically it works like this: If the filename exists, great, we'll // get the permissions on that. If the filename does not exist, then // we pop the filename part off the file_name and look at the // directory. If that directory should be (for some odd reason) non- // existant, then we just pop that off, until either we find something // thats will give us a permissions bitmask, or we run out of places // to look (which shouldn't happen since c:\ should always give us // SOMETHING... int i = strlen( file_name ) - 1; while ( i >= 0 && ( file_name[i] != '\\' && file_name[i] != '/' ) ) { i--; } if ( i < 0 ) { // We've nowhere else to look, and this is bad. return -1; // Its not a no, its an unknown } char *new_file_name = new char[i+1]; strncpy(new_file_name, file_name, i); new_file_name[i]= '\0'; // Now that we've chopped off more of the filename, call get_permissions // again... retVal = get_permissions( new_file_name, AccessRights ); delete[] new_file_name; // ... and return what it returns. (after deleting the string that was // allocated. return retVal; } dprintf(D_ALWAYS, "perm::GetFileSecurity failed (err=%d)\n", GetLastError()); return -1; } pSD_length = pSD_length_needed + 2; // Add 2 for safety. pSD_length_needed = 0; pSD = new BYTE[pSD_length]; // Okay, now that we've found something, and know how large of an SD we need, // call the thing for real and lets get ON WITH IT ALREADY... if( !GetFileSecurity( file_name, // address of string for file name DACL_SECURITY_INFORMATION, // requested information pSD, // address of security descriptor pSD_length, // size of security descriptor buffer &pSD_length_needed // address of required size of buffer ) ) { dprintf(D_ALWAYS, "perm::GetFileSecurity(%s) failed (err=%d)\n", file_name, GetLastError()); delete[] pSD; return -1; } // Now, get the ACL from the security descriptor if( !GetSecurityDescriptorDacl( pSD, // address of security descriptor &acl_present, // address of flag for presence of disc. ACL &pacl, // address of pointer to ACL &acl_defaulted // address of flag for default disc. ACL ) ) { dprintf(D_ALWAYS, "perm::GetSecurityDescriptorDacl failed (file=%s err=%d)\n", file_name, GetLastError()); delete[] pSD; return -1; } // This is the workaround for the broken API GetEffectiveRightsFromAcl(). // It should be guaranteed to work on all versions of NT and 2000 but be aware // that nested global group permissions are not supported. // C. Stolley - June 2001 ACL_SIZE_INFORMATION acl_info; // Structure contains the following members: // DWORD AceCount; // DWORD AclBytesInUse; // DWORD AclBytesFree; // first get the number of ACEs in the ACL if (! GetAclInformation( pacl, // acl to get info from &acl_info, // buffer to receive info sizeof(acl_info), // size in bytes of buffer AclSizeInformation // class of info to retrieve ) ) { dprintf(D_ALWAYS, "Perm::GetAclInformation failed with error %d\n", GetLastError() ); return -1; } ACCESS_MASK allow = 0x0; ACCESS_MASK deny = 0x0; unsigned int aceCount = acl_info.AceCount; int result; // now look at each ACE in the ACL and see if it contains the user we're looking for for (unsigned int i=0; i < aceCount; i++) { LPVOID current_ace; if (! GetAce( pacl, // pointer to ACL i, // index of ACE we want ¤t_ace // pointer to ACE ) ) { dprintf(D_ALWAYS, "Perm::GetAce() failed! Error code %d\n", GetLastError() ); return -1; } dprintf(D_FULLDEBUG, "Calling Perm::userInAce() for %s\\%s\n", (Domain_name) ? Domain_name : "NULL", (Account_name) ? Account_name : "NULL" ); result = userInAce ( current_ace, Account_name, Domain_name ); if (result == 1) { switch ( ( (PACE_HEADER) current_ace)->AceType ) { case ACCESS_ALLOWED_ACE_TYPE: case ACCESS_ALLOWED_OBJECT_ACE_TYPE: allow |= ( (ACCESS_ALLOWED_ACE*) current_ace)->Mask; break; case ACCESS_DENIED_ACE_TYPE: case ACCESS_DENIED_OBJECT_ACE_TYPE: deny |= ( (ACCESS_DENIED_ACE*) current_ace)->Mask; break; } } } AccessRights = allow; AccessRights &= ~deny; // and now if we've made this far everything's happy so return true return 1; }
/** * @brief * perm_granted_admin_and_name: returns 0 if permission mask in 'disallow' has * been granted to only admin-type of accounts and 'owner'. 'owner' can be * set to NULL. Otherwise, it will return the values EPERM or EACCESS with * error message returned in 'errmsg'. */ int perm_granted_admin_and_owner(char *path, int disallow, char *owner, char *errmsg) { int rc; DWORD i, j; SID *powner = NULL; char *powner_s = NULL; ACL *pdacl = NULL; SECURITY_DESCRIPTOR *psd = NULL; ACL_SIZE_INFORMATION sizeInfo; ACCESS_ALLOWED_ACE *pace; int violate = 0; struct accessinfo *allowed = NULL; struct accessinfo *denied = NULL; int mask; char *name; SID *esid = getusersid("Everyone"); if (GetNamedSecurityInfo(path, SE_FILE_OBJECT, OWNER_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION, &powner, 0, &pdacl, 0, &psd) != ERROR_SUCCESS) { errno = GetLastError(); rc = errno; sprintf(errmsg, "GetNameSecurityInfo on file %s failed", path); goto chkerr; } /* is owner SID a privilege user? */ powner_s = getusername(powner); if (powner_s == NULL) powner_s = getgrpname(powner); if (powner_s != NULL) { if ( !sidIsAdminPrivilege(powner) || \ ( (owner != NULL) && strcmp(owner, powner_s) != 0 ) ) { rc = EPERM; sprintf(errmsg, "File %s not owned by user %s or an admin-type user!", path, owner); goto chkerr; } } /* make sure perm mask granted only to privilege groups or the special 'owner' */ GetAclInformation(pdacl, &sizeInfo, sizeof(sizeInfo), AclSizeInformation); allowed = (struct accessinfo *)malloc(sizeof(struct accessinfo)*sizeInfo.AceCount); denied = (struct accessinfo *)malloc(sizeof(struct accessinfo)*sizeInfo.AceCount); if (allowed == NULL || denied == NULL) { rc = errno; strcpy(errmsg, "malloc of allowed or denied struct failed!"); goto chkerr; } accessinfo_init(allowed, sizeInfo.AceCount); accessinfo_init(denied, sizeInfo.AceCount); for (i=0; i < sizeInfo.AceCount; i++) { GetAce(pdacl, i, (void **)&pace); name = getgrpname_full((SID *)&pace->SidStart); if (name == NULL) name = getusername((SID *)&pace->SidStart); /* later, we need to also check denied access which */ /* overrides allowed access. */ if ( pace->Header.AceType == ACCESS_ALLOWED_ACE_TYPE &&\ (mask=(pace->Mask & disallow)) && \ ( EqualSid((SID *)&pace->SidStart, esid) || \ sid2rid((SID *)&pace->SidStart) != \ SECURITY_CREATOR_OWNER_RID ) && \ (!sidIsAdminPrivilege( (SID *)&pace->SidStart)) || \ ((owner != NULL) && strcmp(name, owner) != 0) ) { (void)accessinfo_add(allowed, sizeInfo.AceCount, name, (mask & 0xFFFF)); } else if (pace->Header.AceType == ACCESS_DENIED_ACE_TYPE) { (void)accessinfo_add(denied, sizeInfo.AceCount, name, (pace->Mask & 0xFFFF)); } else { if (name) { (void)free(name); } } } /* validate */ for (i=0; i < sizeInfo.AceCount; i++) { for (j=0; j < sizeInfo.AceCount; j++) { if( allowed[i].group == NULL || \ denied[j].group == NULL ) continue; if (strcmp(allowed[i].group, denied[j].group) == 0) allowed[i].mask &= ~denied[j].mask; /* unset the denied mask from allowed */ } } if (!accessinfo_mask_allzero(allowed, sizeInfo.AceCount)) { rc = EACCES; sprintf(errmsg, "File %s has following disallowed perm masks: ", path); strcat(errmsg, accessinfo_values(allowed, sizeInfo.AceCount)); goto chkerr; } rc = 0; chkerr: if (powner_s)(void)free(powner_s); /* NOTE: powner and pdacl hang off of psd, so a free of psd would */ /* automatically free them */ if (psd) LocalFree(psd); if (allowed) accessinfo_free(allowed, sizeInfo.AceCount); if (denied) accessinfo_free(denied, sizeInfo.AceCount); if (esid) LocalFree(esid); return (rc); }
BOOL AddAceToWindowStation(HWINSTA hwinsta, PSID psid) { // Obtain the DACL for the window station. SECURITY_INFORMATION si = DACL_SECURITY_INFORMATION; DWORD sd_length = 0; if (!GetUserObjectSecurity(hwinsta, &si, NULL, 0, &sd_length)) { if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) { printf("GetUserObjectSecurity() failed: %d\n", GetLastError()); return FALSE; } } auto_buffer<PSECURITY_DESCRIPTOR> psd(sd_length); if (!GetUserObjectSecurity(hwinsta, &si, psd.get(), sd_length, &sd_length)) { printf("GetUserObjectSecurity() failed: %d\n", GetLastError()); return FALSE; } // Create a new DACL. auto_buffer<PSECURITY_DESCRIPTOR> psd_new(sd_length); if (!InitializeSecurityDescriptor(psd_new.get(), SECURITY_DESCRIPTOR_REVISION)) { printf("InitializeSecurityDescriptor() failed: %d\n", GetLastError()); return FALSE; } // Get the DACL from the security descriptor. BOOL bDaclPresent; PACL pacl; BOOL bDaclExist; if (!GetSecurityDescriptorDacl(psd.get(), &bDaclPresent, &pacl, &bDaclExist)) { printf("GetSecurityDescriptorDacl() failed: %d\n", GetLastError()); return FALSE; } // Initialize the ACL. ACL_SIZE_INFORMATION aclSizeInfo = {}; aclSizeInfo.AclBytesInUse = sizeof(ACL); if (NULL != pacl) { // get the file ACL size info if (!GetAclInformation(pacl, &aclSizeInfo, sizeof aclSizeInfo, AclSizeInformation)) { printf("GetAclInformation() failed: %d\n", GetLastError()); return FALSE; } } // Compute the size of the new ACL. DWORD new_acl_size = aclSizeInfo.AclBytesInUse + (2 * sizeof(ACCESS_ALLOWED_ACE)) + (2 * GetLengthSid(psid)) - (2 * sizeof(DWORD)); auto_buffer<PACL> new_acl(new_acl_size); // Initialize the new DACL. if (!InitializeAcl(new_acl.get(), new_acl_size, ACL_REVISION)) { printf("InitializeAcl() failed: %d\n", GetLastError()); return FALSE; } // If DACL is present, copy it to a new DACL. if (bDaclPresent) { // Copy the ACEs to the new ACL. if (aclSizeInfo.AceCount) { for (DWORD i = 0; i != aclSizeInfo.AceCount; ++i) { LPVOID pTempAce; if (!GetAce(pacl, i, &pTempAce)) { printf("GetAce() failed: %d\n", GetLastError()); return FALSE; } if (!AddAce(new_acl.get(), ACL_REVISION, MAXDWORD, pTempAce, ((PACE_HEADER)pTempAce)->AceSize)) { printf("AddAce() failed: %d\n", GetLastError()); return FALSE; } } } } // Add the first ACE to the window station. auto_buffer<ACCESS_ALLOWED_ACE*> ace(sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(psid) - sizeof(DWORD)); ace->Header.AceType = ACCESS_ALLOWED_ACE_TYPE; ace->Header.AceFlags = CONTAINER_INHERIT_ACE | INHERIT_ONLY_ACE | OBJECT_INHERIT_ACE; ace->Header.AceSize = (WORD) (sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(psid) - sizeof(DWORD)); ace->Mask = GENERIC_ACCESS; if (!CopySid(GetLengthSid(psid), &ace->SidStart, psid)) { printf("CopySid() failed: %d\n", GetLastError()); return FALSE; } if (!AddAce(new_acl.get(), ACL_REVISION, MAXDWORD, ace.get(), ace->Header.AceSize)) { printf("AddAce() failed: %d\n", GetLastError()); return FALSE; } // Add the second ACE to the window station. ace->Header.AceFlags = NO_PROPAGATE_INHERIT_ACE; ace->Mask = WINSTA_ALL; if (!AddAce(new_acl.get(), ACL_REVISION,MAXDWORD, ace.get(), ace->Header.AceSize)) { printf("AddAce() failed: %d\n", GetLastError()); return FALSE; } // Set a new DACL for the security descriptor. if (!SetSecurityDescriptorDacl(psd_new.get(), TRUE, new_acl.get(), FALSE)) { printf("SetSecurityDescriptorDacl() failed: %d\n", GetLastError()); return FALSE; } // Set the new security descriptor for the window station. if (!SetUserObjectSecurity(hwinsta, &si, psd_new.get())) { printf("SetUserObjectSecurity() failed: %d\n", GetLastError()); return FALSE; } return TRUE; }
BOOL RemoveAceFromDesktop(HDESK hdesk, PSID psid) { // Obtain the security descriptor for the desktop object. SECURITY_INFORMATION si = DACL_SECURITY_INFORMATION; DWORD sd_size = 0; if (!GetUserObjectSecurity(hdesk, &si, NULL, 0, &sd_size)) { if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) { printf("GetUserObjectSecurity() failed: %d\n", GetLastError()); return FALSE; } } auto_buffer<PSECURITY_DESCRIPTOR> psd(sd_size); if (!GetUserObjectSecurity(hdesk, &si, psd.get(), sd_size, &sd_size)) { printf("GetUserObjectSecurity() failed: %d\n", GetLastError()); return FALSE; } // Create a new security descriptor. auto_buffer<PSECURITY_DESCRIPTOR> psd_new(sd_size); if (!InitializeSecurityDescriptor(psd_new.get(), SECURITY_DESCRIPTOR_REVISION)) { printf("InitializeSecurityDescriptor() failed: %d\n", GetLastError()); return FALSE; } // Obtain the DACL from the security descriptor. BOOL bDaclPresent; PACL pacl; BOOL bDaclExist; if (!GetSecurityDescriptorDacl(psd.get(), &bDaclPresent, &pacl, &bDaclExist)) { printf("GetSecurityDescriptorDacl() failed: %d\n", GetLastError()); return FALSE; } // Initialize. ACL_SIZE_INFORMATION aclSizeInfo = {}; aclSizeInfo.AclBytesInUse = sizeof(ACL); if (pacl != NULL) { // Determine the size of the ACL information. if (!GetAclInformation(pacl, (LPVOID)&aclSizeInfo, sizeof aclSizeInfo, AclSizeInformation)) { printf("GetAclInformation() failed: %d\n", GetLastError()); return FALSE; } } // Allocate buffer for the new ACL. DWORD dwNewAclSize = aclSizeInfo.AclBytesInUse - (sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(psid) - sizeof(DWORD)); auto_buffer<PACL> new_acl(dwNewAclSize); // Initialize the new ACL. if (!InitializeAcl(new_acl.get(), dwNewAclSize, ACL_REVISION)) { printf("InitializeAcl() failed: %d\n", GetLastError()); return FALSE; } // If DACL is present, copy it to a new DACL. if (bDaclPresent) { // Copy the ACEs to the new ACL. for (DWORD i = 0; i != aclSizeInfo.AceCount; ++i) { // Get an ACE. ACCESS_ALLOWED_ACE* pace; if (!GetAce(pacl, i, (void**)&pace)) { printf("GetAce() failed: %d\n", GetLastError()); return FALSE; } if (!EqualSid(psid, &pace->SidStart)) { // Add the ACE to the new ACL. if (!AddAce(new_acl.get(), ACL_REVISION,MAXDWORD, pace, pace->Header.AceSize)) { printf("AddAce() failed: %d\n", GetLastError()); return FALSE; } } } } // Set new DACL to the new security descriptor. if (!SetSecurityDescriptorDacl(psd_new.get(), TRUE, new_acl.get(), FALSE)) { printf("SetSecurityDescriptorDacl() failed: %d\n", GetLastError()); return FALSE; } // Set the new security descriptor for the desktop object. if (!SetUserObjectSecurity(hdesk, &si, psd_new.get())) { printf("SetUserObjectSecurity() failed: %d\n", GetLastError()); return FALSE; } return TRUE; }
BOOL RemoveAceFromWindowStation(HWINSTA hwinsta, PSID psid) { // Obtain the DACL for the window station. SECURITY_INFORMATION si = DACL_SECURITY_INFORMATION; DWORD sd_length = 0; if (!GetUserObjectSecurity(hwinsta, &si, NULL, 0, &sd_length)) { if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) { printf("GetUserObjectSecurity() failed: %d\n", GetLastError()); return FALSE; } } auto_buffer<PSECURITY_DESCRIPTOR> psd(sd_length); if (!GetUserObjectSecurity(hwinsta, &si, psd.get(), sd_length, &sd_length)) { printf("GetUserObjectSecurity() failed: %d\n", GetLastError()); return FALSE; } // Create a new DACL. auto_buffer<PSECURITY_DESCRIPTOR> psd_new(sd_length); if (!InitializeSecurityDescriptor(psd_new.get(), SECURITY_DESCRIPTOR_REVISION)) { printf("InitializeSecurityDescriptor() failed: %d\n", GetLastError()); return FALSE; } // Get the DACL from the security descriptor. BOOL bDaclPresent; PACL pacl; BOOL bDaclExist; if (!GetSecurityDescriptorDacl(psd.get(), &bDaclPresent, &pacl, &bDaclExist)) { printf("GetSecurityDescriptorDacl() failed: %d\n", GetLastError()); return FALSE; } // Initialize the ACL. ACL_SIZE_INFORMATION aclSizeInfo = {}; aclSizeInfo.AclBytesInUse = sizeof(ACL); if (NULL != pacl) { // get the file ACL size info if (!GetAclInformation(pacl, &aclSizeInfo, sizeof aclSizeInfo, AclSizeInformation)) { printf("GetAclInformation() failed: %d\n", GetLastError()); return FALSE; } } // Compute the size of the new ACL. DWORD new_acl_size = aclSizeInfo.AclBytesInUse - ((2 * sizeof(ACCESS_ALLOWED_ACE)) + (2 * GetLengthSid(psid)) - (2 * sizeof(DWORD))); auto_buffer<PACL> new_acl(new_acl_size); // Initialize the new DACL. if (!InitializeAcl(new_acl.get(), new_acl_size, ACL_REVISION)) { printf("InitializeAcl() failed: %d\n", GetLastError()); return FALSE; } // If DACL is present, copy it to a new DACL. if (bDaclPresent) { // Copy the ACEs to the new ACL. for (DWORD i = 0; i != aclSizeInfo.AceCount; ++i) { ACCESS_ALLOWED_ACE* pace; if (!GetAce(pacl, i, (void**)&pace)) { printf("GetAce() failed: %d\n", GetLastError()); return FALSE; } if (!EqualSid(psid, &pace->SidStart)) { if (!AddAce(new_acl.get(), ACL_REVISION, MAXDWORD, pace, pace->Header.AceSize)) { printf("AddAce() failed: %d\n", GetLastError()); return FALSE; } } } } // Set a new DACL for the security descriptor. if (!SetSecurityDescriptorDacl(psd_new.get(), TRUE, new_acl.get(), FALSE)) { printf("SetSecurityDescriptorDacl() failed: %d\n", GetLastError()); return FALSE; } // Set the new security descriptor for the window station. if (!SetUserObjectSecurity(hwinsta, &si, psd_new.get())) { printf("SetUserObjectSecurity() failed: %d\n", GetLastError()); return FALSE; } return TRUE; }
HRESULT COpcSecurity::RemovePrincipalFromACL(PACL pAcl, LPCTSTR pszPrincipal) { ACL_SIZE_INFORMATION aclSizeInfo; ULONG i; LPVOID ace; ACCESS_ALLOWED_ACE *accessAllowedAce; ACCESS_DENIED_ACE *accessDeniedAce; SYSTEM_AUDIT_ACE *systemAuditAce; PSID principalSID; DWORD returnValue; ACE_HEADER *aceHeader; returnValue = GetPrincipalSID(pszPrincipal, &principalSID); if (FAILED(returnValue)) return returnValue; GetAclInformation(pAcl, (LPVOID) &aclSizeInfo, (DWORD) sizeof(ACL_SIZE_INFORMATION), AclSizeInformation); for (i = 0; i < aclSizeInfo.AceCount; i++) { if (!GetAce(pAcl, i, &ace)) { free(principalSID); return HRESULT_FROM_WIN32(GetLastError()); } aceHeader = (ACE_HEADER *) ace; if (aceHeader->AceType == ACCESS_ALLOWED_ACE_TYPE) { accessAllowedAce = (ACCESS_ALLOWED_ACE *) ace; if (EqualSid(principalSID, (PSID) &accessAllowedAce->SidStart)) { DeleteAce(pAcl, i); free(principalSID); return S_OK; } } else if (aceHeader->AceType == ACCESS_DENIED_ACE_TYPE) { accessDeniedAce = (ACCESS_DENIED_ACE *) ace; if (EqualSid(principalSID, (PSID) &accessDeniedAce->SidStart)) { DeleteAce(pAcl, i); free(principalSID); return S_OK; } } else if (aceHeader->AceType == SYSTEM_AUDIT_ACE_TYPE) { systemAuditAce = (SYSTEM_AUDIT_ACE *) ace; if (EqualSid(principalSID, (PSID) &systemAuditAce->SidStart)) { DeleteAce(pAcl, i); free(principalSID); return S_OK; } } } free(principalSID); return S_OK; }
static int TestplatformChmod( const char *nativePath, int pmode) { static const SECURITY_INFORMATION infoBits = OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION; static const DWORD readOnlyMask = FILE_DELETE_CHILD | FILE_ADD_FILE | FILE_ADD_SUBDIRECTORY | FILE_WRITE_EA | FILE_APPEND_DATA | FILE_WRITE_DATA | DELETE; /* * References to security functions (only available on NT and later). */ const BOOL set_readOnly = !(pmode & 0222); BOOL acl_readOnly_found = FALSE, curAclPresent, curAclDefaulted; SID_IDENTIFIER_AUTHORITY userSidAuthority = { SECURITY_WORLD_SID_AUTHORITY }; BYTE *secDesc = 0; DWORD secDescLen, attr, newAclSize; ACL_SIZE_INFORMATION ACLSize; PACL curAcl, newAcl = 0; WORD j; SID *userSid = 0; char *userDomain = 0; int res = 0; /* * Process the chmod request. */ attr = GetFileAttributesA(nativePath); /* * nativePath not found */ if (attr == 0xffffffff) { res = -1; goto done; } /* * If nativePath is not a directory, there is no special handling. */ if (!(attr & FILE_ATTRIBUTE_DIRECTORY)) { goto done; } /* * Set the result to error, if the ACL change is successful it will be * reset to 0. */ res = -1; /* * Read the security descriptor for the directory. Note the first call * obtains the size of the security descriptor. */ if (!GetFileSecurityA(nativePath, infoBits, NULL, 0, &secDescLen)) { DWORD secDescLen2 = 0; if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) { goto done; } secDesc = (BYTE *) ckalloc(secDescLen); if (!GetFileSecurityA(nativePath, infoBits, (PSECURITY_DESCRIPTOR) secDesc, secDescLen, &secDescLen2) || (secDescLen < secDescLen2)) { goto done; } } /* * Get the World SID. */ userSid = (SID *) ckalloc(GetSidLengthRequired((UCHAR) 1)); InitializeSid(userSid, &userSidAuthority, (BYTE) 1); *(GetSidSubAuthority(userSid, 0)) = SECURITY_WORLD_RID; /* * If curAclPresent == false then curAcl and curAclDefaulted not valid. */ if (!GetSecurityDescriptorDacl((PSECURITY_DESCRIPTOR) secDesc, &curAclPresent, &curAcl, &curAclDefaulted)) { goto done; } if (!curAclPresent || !curAcl) { ACLSize.AclBytesInUse = 0; ACLSize.AceCount = 0; } else if (!GetAclInformation(curAcl, &ACLSize, sizeof(ACLSize), AclSizeInformation)) { goto done; } /* * Allocate memory for the new ACL. */ newAclSize = ACLSize.AclBytesInUse + sizeof(ACCESS_DENIED_ACE) + GetLengthSid(userSid) - sizeof(DWORD); newAcl = (ACL *) ckalloc(newAclSize); /* * Initialize the new ACL. */ if (!InitializeAcl(newAcl, newAclSize, ACL_REVISION)) { goto done; } /* * Add denied to make readonly, this will be known as a "read-only tag". */ if (set_readOnly && !AddAccessDeniedAce(newAcl, ACL_REVISION, readOnlyMask, userSid)) { goto done; } acl_readOnly_found = FALSE; for (j = 0; j < ACLSize.AceCount; j++) { LPVOID pACE2; ACE_HEADER *phACE2; if (!GetAce(curAcl, j, &pACE2)) { goto done; } phACE2 = (ACE_HEADER *) pACE2; /* * Do NOT propagate inherited ACEs. */ if (phACE2->AceFlags & INHERITED_ACE) { continue; } /* * Skip the "read-only tag" restriction (either added above, or it is * being removed). */ if (phACE2->AceType == ACCESS_DENIED_ACE_TYPE) { ACCESS_DENIED_ACE *pACEd = (ACCESS_DENIED_ACE *) phACE2; if (pACEd->Mask == readOnlyMask && EqualSid(userSid, (PSID) &pACEd->SidStart)) { acl_readOnly_found = TRUE; continue; } } /* * Copy the current ACE from the old to the new ACL. */ if (!AddAce(newAcl, ACL_REVISION, MAXDWORD, (PACL *) pACE2, ((PACE_HEADER) pACE2)->AceSize)) { goto done; } } /* * Apply the new ACL. */ if (set_readOnly == acl_readOnly_found || SetNamedSecurityInfoA( (LPSTR) nativePath, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, newAcl, NULL) == ERROR_SUCCESS) { res = 0; } done: if (secDesc) { ckfree((char *) secDesc); } if (newAcl) { ckfree((char *) newAcl); } if (userSid) { ckfree((char *) userSid); } if (userDomain) { ckfree((char *) userDomain); } if (res != 0) { return res; } /* * Run normal chmod command. */ return chmod(nativePath, pmode); }