int GetFileOwner (const char *Computer, const char *Name, char *Owner) { SECURITY_INFORMATION si = OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION; SECURITY_DESCRIPTOR *sd; char sddata[500]; *Owner=0; sd=(SECURITY_DESCRIPTOR *)sddata; char AnsiName[NM]; OemToChar(Name,AnsiName); SetFileApisToANSI(); DWORD Needed; int GetCode=GetFileSecurity(AnsiName,si,sd,sizeof(sddata),&Needed); SetFileApisToOEM(); if (!GetCode || (Needed>sizeof(sddata))) return(FALSE); PSID pOwner; BOOL OwnerDefaulted; if (!GetSecurityDescriptorOwner(sd,&pOwner,&OwnerDefaulted)) return(FALSE); char AccountName[200],DomainName[200]; DWORD AccountLength=sizeof(AccountName),DomainLength=sizeof(DomainName); SID_NAME_USE snu; if (!LookupAccountSid(Computer,pOwner,AccountName,&AccountLength,DomainName,&DomainLength,&snu)) return(FALSE); CharToOem(AccountName,Owner); return(TRUE); }
/* * FreeSD: Frees the memory of an absolute SD. */ void vncAccessControl::FreeSD(PSECURITY_DESCRIPTOR pSD){ PSID pOwnerSID = NULL; PSID pGroupSID = NULL; PACL pDACL = NULL; PACL pSACL = NULL; BOOL bOwnerDefaulted = FALSE; BOOL bGroupDefaulted = FALSE; BOOL bDaclPresent = FALSE; BOOL bDaclDefaulted = FALSE; BOOL bSaclPresent = FALSE; BOOL bSaclDefaulted = FALSE; if (pSD) { GetSecurityDescriptorOwner(pSD, &pOwnerSID, &bOwnerDefaulted); GetSecurityDescriptorGroup(pSD, &pGroupSID, &bGroupDefaulted); GetSecurityDescriptorDacl(pSD, &bDaclPresent, &pDACL, &bDaclDefaulted); GetSecurityDescriptorSacl(pSD, &bSaclPresent, &pSACL, &bSaclDefaulted); } // Clean up if (pSD) HeapFree(GetProcessHeap(), 0, pSD); if (bDaclPresent && pDACL) HeapFree(GetProcessHeap(), 0, pDACL); if (bSaclPresent && pSACL) HeapFree(GetProcessHeap(), 0, pSACL); if (pOwnerSID) HeapFree(GetProcessHeap(), 0, pOwnerSID); if (pGroupSID) HeapFree(GetProcessHeap(), 0, pGroupSID); }
static int iwin32_file_get_owner (const char *file, user_id_t *uid) { char file_sd_buf [256]; DWORD sd_size = 256; PSECURITY_DESCRIPTOR file_sd = (PSECURITY_DESCRIPTOR) &file_sd_buf; PSID sid; BOOL dummy; assert (file != NULL); assert (uid != NULL); if (!InitializeSecurityDescriptor (file_sd, SECURITY_DESCRIPTOR_REVISION)) return 0; if (!GetFileSecurity (file, (SECURITY_INFORMATION)(OWNER_SECURITY_INFORMATION), file_sd, sizeof (file_sd_buf), &sd_size)) return 0; if (!GetSecurityDescriptorOwner (file_sd, &sid, &dummy)) return 0; if (!IsValidSid (sid)) return 0; uid->value = malloc (sd_size); if (!uid->value) return 0; if (!CopySid (sd_size, uid->value, sid)) return 0; return 1; }
bool GetFileOwner(const string& Computer,const string& Name, string &strOwner) { bool Result=false; strOwner.clear(); SECURITY_INFORMATION si=OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION;; DWORD LengthNeeded=0; NTPath strName(Name); static char sddata[64 * 1024]; PSECURITY_DESCRIPTOR sd = reinterpret_cast<PSECURITY_DESCRIPTOR>(sddata); if (GetFileSecurity(strName.data(),si,sd,sizeof(sddata),&LengthNeeded) && LengthNeeded<=sizeof(sddata)) { PSID pOwner; BOOL OwnerDefaulted; if (GetSecurityDescriptorOwner(sd,&pOwner,&OwnerDefaulted)) { if (IsValidSid(pOwner)) { Result = SidToNameCached(pOwner, strOwner, Computer); } } } return Result; }
LPCTSTR getOwnerString(HKEY root, LPCTSTR subkey) { SECURITY_INFORMATION setOwner = OWNER_SECURITY_INFORMATION; HKEY hkey; DWORD psdsize = 1; REGSAM sam = KEY_READ | KEY_ENUMERATE_SUB_KEYS; LONG err = RegOpenKeyEx(root, subkey, 0, sam, &hkey); if(err == 0 && hkey != 0) { PSID owner; BOOL ownerDefaulted = 0; LPTSTR ownerSidString; // first call gets the %$#@ size! RegGetKeySecurity(hkey, OWNER_SECURITY_INFORMATION, NULL, &psdsize); PSECURITY_DESCRIPTOR psd = LocalAlloc(LMEM_FIXED, psdsize); RegGetKeySecurity(hkey, OWNER_SECURITY_INFORMATION, psd, &psdsize); GetSecurityDescriptorOwner(psd, &owner, &ownerDefaulted); ConvertSidToStringSid(owner, &ownerSidString); return ownerSidString; LocalFree(psd); } else return NULL; }
/* * Returns pointer to the SID identifying the owner of the specified * file. */ static SID* getFileOwner(JNIEnv* env, SECURITY_DESCRIPTOR* sd) { SID* owner; BOOL defaulted; if (!GetSecurityDescriptorOwner(sd, &owner, &defaulted)) { JNU_ThrowIOExceptionWithLastError(env, "GetSecurityDescriptorOwner failed"); return NULL; } return owner; }
BOOL ValidateSecurity(uch *securitydata) { PSECURITY_DESCRIPTOR sd = (PSECURITY_DESCRIPTOR)securitydata; PACL pAcl; PSID pSid; BOOL bAclPresent; BOOL bDefaulted; if(!IsWinNT()) return TRUE; /* don't do anything if not on WinNT */ if(!IsValidSecurityDescriptor(sd)) return FALSE; /* verify Dacl integrity */ if(!GetSecurityDescriptorDacl(sd, &bAclPresent, &pAcl, &bDefaulted)) return FALSE; if(bAclPresent && pAcl!=NULL) { if(!IsValidAcl(pAcl)) return FALSE; } /* verify Sacl integrity */ if(!GetSecurityDescriptorSacl(sd, &bAclPresent, &pAcl, &bDefaulted)) return FALSE; if(bAclPresent && pAcl!=NULL) { if(!IsValidAcl(pAcl)) return FALSE; } /* verify owner integrity */ if(!GetSecurityDescriptorOwner(sd, &pSid, &bDefaulted)) return FALSE; if(pSid != NULL) { if(!IsValidSid(pSid)) return FALSE; } /* verify group integrity */ if(!GetSecurityDescriptorGroup(sd, &pSid, &bDefaulted)) return FALSE; if(pSid != NULL) { if(!IsValidSid(pSid)) return FALSE; } return TRUE; }
/***************************************************************************** * WCMD_getfileowner * * Reverse a WCHARacter string in-place (strrev() is not available under unixen :-( ). */ static void WCMD_getfileowner(WCHAR *filename, WCHAR *owner, int ownerlen) { ULONG sizeNeeded = 0; DWORD rc; WCHAR name[MAXSTRING]; WCHAR domain[MAXSTRING]; /* In case of error, return empty string */ *owner = 0x00; /* Find out how much space we need for the owner security descriptor */ GetFileSecurityW(filename, OWNER_SECURITY_INFORMATION, 0, 0, &sizeNeeded); rc = GetLastError(); if(rc == ERROR_INSUFFICIENT_BUFFER && sizeNeeded > 0) { LPBYTE secBuffer; PSID pSID = NULL; BOOL defaulted = FALSE; ULONG nameLen = MAXSTRING; ULONG domainLen = MAXSTRING; SID_NAME_USE nameuse; secBuffer = HeapAlloc(GetProcessHeap(),0,sizeNeeded * sizeof(BYTE)); if(!secBuffer) return; /* Get the owners security descriptor */ if(!GetFileSecurityW(filename, OWNER_SECURITY_INFORMATION, secBuffer, sizeNeeded, &sizeNeeded)) { HeapFree(GetProcessHeap(),0,secBuffer); return; } /* Get the SID from the SD */ if(!GetSecurityDescriptorOwner(secBuffer, &pSID, &defaulted)) { HeapFree(GetProcessHeap(),0,secBuffer); return; } /* Convert to a username */ if (LookupAccountSidW(NULL, pSID, name, &nameLen, domain, &domainLen, &nameuse)) { static const WCHAR fmt[] = {'%','s','%','c','%','s','\0'}; snprintfW(owner, ownerlen, fmt, domain, '\\', name); } HeapFree(GetProcessHeap(),0,secBuffer); } return; }
void readKeys(LPCTSTR *keys, int numKeys, REGSAM sam) { //RegSetKeySecurity(NULL,NULL,NULL); SECURITY_INFORMATION setOwner = OWNER_SECURITY_INFORMATION; HKEY hkey; DWORD psdsize = 1; sam |= KEY_ENUMERATE_SUB_KEYS; for(int i = 0; i < numKeys; i++) { LONG err = RegOpenKeyEx(HKEY_CLASSES_ROOT, keys[i], 0, sam, &hkey); if(err == 0 && hkey != 0) { PSID owner; BOOL ownerDefaulted; LPTSTR ownerSidString; // first call gets the %$#@ size! RegGetKeySecurity(hkey, OWNER_SECURITY_INFORMATION, NULL, &psdsize); PSECURITY_DESCRIPTOR psd = LocalAlloc(LMEM_FIXED, psdsize); RegGetKeySecurity(hkey, OWNER_SECURITY_INFORMATION, psd, &psdsize); GetSecurityDescriptorOwner(psd, &owner, &ownerDefaulted); ConvertSidToStringSid(owner, &ownerSidString); wprintf(TEXT("Key = %s, SID of owner = %s\n"), keys[i], ownerSidString); //SetSecurityDescriptorOwner(psd, //RegSetKeySecurity(hkey, setOwner, psd); //SetSecurityDescriptorOwner LocalFree(psd); } else displayError(err, keys[i]); } }
bool GetFileOwner(const wchar_t *Computer,const wchar_t *Name, string &strOwner) { bool Result=false; /* if(!Owner) { SIDCacheFlush(); return TRUE; } */ strOwner.Clear(); SECURITY_INFORMATION si=OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION;; DWORD LengthNeeded=0; NTPath strName(Name); PSECURITY_DESCRIPTOR sd=reinterpret_cast<PSECURITY_DESCRIPTOR>(sddata); if (GetFileSecurity(strName,si,sd,sizeof(sddata),&LengthNeeded) && LengthNeeded<=sizeof(sddata)) { PSID pOwner; BOOL OwnerDefaulted; if (GetSecurityDescriptorOwner(sd,&pOwner,&OwnerDefaulted)) { if (IsValidSid(pOwner)) { const wchar_t *Owner=GetNameFromSIDCache(pOwner); if (!Owner) { Owner=AddSIDToCache(Computer,pOwner); } if (Owner) { strOwner=Owner; Result=true; } } } } return Result; }
/* (in) PSECURITY_DESCRIPTOR file or directory handle (in/out) struct acl * acl */ int get_file_acl(PSECURITY_DESCRIPTOR pSD,struct acl * acl) { DWORD dwLastError; PACL pDacl; PSID pOwnerSid,pGroupSid; SID_NAME_USE eUse; BOOL bPresent; BOOL bDef; int i; if (0 == GetSecurityDescriptorOwner(pSD, &pOwnerSid, &bDef)){ return (-1); } if (0 == GetSecurityDescriptorGroup(pSD, &pGroupSid, &bDef)){ return(-1); } if (0 == GetSecurityDescriptorDacl(pSD,&bPresent,&pDacl,&bDef)){ return(-1); } if (get_account_sid(pOwnerSid,acl->owner,MAX_LEN,&eUse) == -1){ return (-1); } if (get_account_sid(pGroupSid,acl->group,MAX_LEN,&eUse) == -1){ return (-1); } if (pDacl != NULL) get_ace(pDacl,acl,&eUse); return (0); }
HRESULT COpcSecurity::Attach(PSECURITY_DESCRIPTOR pSelfRelativeSD) { PACL pDACL = NULL; PACL pSACL = NULL; BOOL bDACLPresent, bSACLPresent; BOOL bDefaulted; PACL m_pDACL = NULL; ACCESS_ALLOWED_ACE* pACE; HRESULT hr; PSID pUserSid; PSID pGroupSid; hr = Initialize(); if(FAILED(hr)) return hr; // get the existing DACL. if (!GetSecurityDescriptorDacl(pSelfRelativeSD, &bDACLPresent, &pDACL, &bDefaulted)) goto failed; if (bDACLPresent) { if (pDACL) { // allocate new DACL. m_pDACL = (PACL) malloc(pDACL->AclSize); if (m_pDACL == NULL) { hr = E_OUTOFMEMORY; goto failedMemory; } // initialize the DACL if (!InitializeAcl(m_pDACL, pDACL->AclSize, ACL_REVISION)) goto failed; // copy the ACES for (int i = 0; i < pDACL->AceCount; i++) { if (!GetAce(pDACL, i, (void **)&pACE)) goto failed; if (!AddAccessAllowedAce(m_pDACL, ACL_REVISION, pACE->Mask, (PSID)&(pACE->SidStart))) goto failed; } if (!IsValidAcl(m_pDACL)) goto failed; } // set the DACL if (!SetSecurityDescriptorDacl(m_pSD, m_pDACL ? TRUE : FALSE, m_pDACL, bDefaulted)) goto failed; } // get the existing SACL. if (!GetSecurityDescriptorSacl(pSelfRelativeSD, &bSACLPresent, &pSACL, &bDefaulted)) goto failed; if (bSACLPresent) { if (pSACL) { // allocate new SACL. m_pSACL = (PACL) malloc(pSACL->AclSize); if (m_pSACL == NULL) { hr = E_OUTOFMEMORY; goto failedMemory; } // initialize the SACL if (!InitializeAcl(m_pSACL, pSACL->AclSize, ACL_REVISION)) goto failed; // copy the ACES for (int i = 0; i < pSACL->AceCount; i++) { if (!GetAce(pSACL, i, (void **)&pACE)) goto failed; if (!AddAccessAllowedAce(m_pSACL, ACL_REVISION, pACE->Mask, (PSID)&(pACE->SidStart))) goto failed; } if (!IsValidAcl(m_pSACL)) goto failed; } // set the SACL if (!SetSecurityDescriptorSacl(m_pSD, m_pSACL ? TRUE : FALSE, m_pSACL, bDefaulted)) goto failed; } if (!GetSecurityDescriptorOwner(m_pSD, &pUserSid, &bDefaulted)) goto failed; if (FAILED(SetOwner(pUserSid, bDefaulted))) goto failed; if (!GetSecurityDescriptorGroup(m_pSD, &pGroupSid, &bDefaulted)) goto failed; if (FAILED(SetGroup(pGroupSid, bDefaulted))) goto failed; if (!IsValidSecurityDescriptor(m_pSD)) goto failed; return hr; failed: hr = HRESULT_FROM_WIN32(hr); failedMemory: if (m_pDACL) { free(m_pDACL); m_pDACL = NULL; } if (m_pSD) { free(m_pSD); m_pSD = NULL; } return hr; }
/*---------------------------------------------------------------------------*\ * NAME: MakeSDAbsolute * --------------------------------------------------------------------------* * DESCRIPTION: Takes a self-relative security descriptor and returns a * newly created absolute security descriptor. \*---------------------------------------------------------------------------*/ DWORD MakeSDAbsolute ( PSECURITY_DESCRIPTOR psidOld, PSECURITY_DESCRIPTOR *psidNew ) { PSECURITY_DESCRIPTOR pSid = NULL; DWORD cbDescriptor = 0; DWORD cbDacl = 0; DWORD cbSacl = 0; DWORD cbOwnerSID = 0; DWORD cbGroupSID = 0; PACL pDacl = NULL; PACL pSacl = NULL; PSID psidOwner = NULL; PSID psidGroup = NULL; BOOL fPresent = FALSE; BOOL fSystemDefault = FALSE; DWORD dwReturnValue = ERROR_SUCCESS; // Get SACL if (!GetSecurityDescriptorSacl (psidOld, &fPresent, &pSacl, &fSystemDefault)) { dwReturnValue = GetLastError(); goto CLEANUP; } if (pSacl && fPresent) { cbSacl = pSacl->AclSize; } // Get DACL if (!GetSecurityDescriptorDacl (psidOld, &fPresent, &pDacl, &fSystemDefault)) { dwReturnValue = GetLastError(); goto CLEANUP; } if (pDacl && fPresent) { cbDacl = pDacl->AclSize; } // Get Owner if (!GetSecurityDescriptorOwner (psidOld, &psidOwner, &fSystemDefault)) { dwReturnValue = GetLastError(); goto CLEANUP; } cbOwnerSID = GetLengthSid (psidOwner); // Get Group if (!GetSecurityDescriptorGroup (psidOld, &psidGroup, &fSystemDefault)) { dwReturnValue = GetLastError(); goto CLEANUP; } cbGroupSID = GetLengthSid (psidGroup); // Do the conversion cbDescriptor = 0; MakeAbsoluteSD (psidOld, pSid, &cbDescriptor, pDacl, &cbDacl, pSacl, &cbSacl, psidOwner, &cbOwnerSID, psidGroup, &cbGroupSID); pSid = (PSECURITY_DESCRIPTOR) malloc(cbDescriptor); if(!pSid) { dwReturnValue = ERROR_OUTOFMEMORY; goto CLEANUP; } ZeroMemory(pSid, cbDescriptor); if (!InitializeSecurityDescriptor (pSid, SECURITY_DESCRIPTOR_REVISION)) { dwReturnValue = GetLastError(); goto CLEANUP; } if (!MakeAbsoluteSD (psidOld, pSid, &cbDescriptor, pDacl, &cbDacl, pSacl, &cbSacl, psidOwner, &cbOwnerSID, psidGroup, &cbGroupSID)) { dwReturnValue = GetLastError(); goto CLEANUP; } CLEANUP: if(dwReturnValue != ERROR_SUCCESS && pSid) { free(pSid); pSid = NULL; } *psidNew = pSid; return dwReturnValue; }
int CShellCommandOwner::Execute(CConsole &rConsole, CArgumentParser& rArguments) { const TCHAR *pchKey = NULL; BOOL blnDo = TRUE; BOOL blnBadParameter = FALSE; BOOL blnHelp = FALSE; const TCHAR *pchParameter; DWORD dwError; rArguments.ResetArgumentIteration(); const TCHAR *pchCommandItself = rArguments.GetNextArgument(); if ((_tcsnicmp(pchCommandItself,OWNER_CMD _T(".."),OWNER_CMD_LENGTH+2*sizeof(TCHAR)) == 0)|| (_tcsnicmp(pchCommandItself,OWNER_CMD _T("\\"),OWNER_CMD_LENGTH+1*sizeof(TCHAR)) == 0)) { pchKey = pchCommandItself + OWNER_CMD_LENGTH; } else if (_tcsnicmp(pchCommandItself,OWNER_CMD _T("/"),OWNER_CMD_LENGTH+1*sizeof(TCHAR)) == 0) { pchParameter = pchCommandItself + OWNER_CMD_LENGTH; goto CheckOwnerArgument; } while((pchParameter = rArguments.GetNextArgument()) != NULL) { CheckOwnerArgument: blnBadParameter = FALSE; if ((_tcsicmp(pchParameter,_T("/?")) == 0) ||(_tcsicmp(pchParameter,_T("-?")) == 0)) { blnHelp = TRUE; blnDo = pchKey != NULL; } else if (!pchKey) { pchKey = pchParameter; blnDo = TRUE; } else { blnBadParameter = TRUE; } if (blnBadParameter) { rConsole.Write(_T("Bad parameter: ")); rConsole.Write(pchParameter); rConsole.Write(_T("\n")); } } CRegistryKey Key; if (!m_rTree.GetKey(pchKey?pchKey:_T("."),KEY_QUERY_VALUE|READ_CONTROL,Key)) { rConsole.Write(m_rTree.GetLastErrorDescription()); blnDo = FALSE; } if (blnHelp) { rConsole.Write(GetHelpString()); } if (blnDo&&blnHelp) rConsole.Write(_T("\n")); if (!blnDo) return 0; if (Key.IsRoot()) { // root key rConsole.Write(OWNER_CMD COMMAND_NA_ON_ROOT); return 0; } PISECURITY_DESCRIPTOR pSecurityDescriptor = NULL; TCHAR *pchName = NULL, *pchDomainName = NULL; try { DWORD dwSecurityDescriptorLength; rConsole.Write(_T("Key : ")); rConsole.Write(_T("\\")); rConsole.Write(Key.GetKeyName()); rConsole.Write(_T("\n")); dwError = Key.GetSecurityDescriptorLength(&dwSecurityDescriptorLength); if (dwError != ERROR_SUCCESS) throw dwError; pSecurityDescriptor = (PISECURITY_DESCRIPTOR) new unsigned char [dwSecurityDescriptorLength]; DWORD dwSecurityDescriptorLength1 = dwSecurityDescriptorLength; dwError = Key.GetSecurityDescriptor((SECURITY_INFORMATION)OWNER_SECURITY_INFORMATION,pSecurityDescriptor,&dwSecurityDescriptorLength1); if (dwError != ERROR_SUCCESS) throw dwError; PSID psidOwner; BOOL blnOwnerDefaulted; if (!GetSecurityDescriptorOwner(pSecurityDescriptor,&psidOwner,&blnOwnerDefaulted)) throw GetLastError(); if (psidOwner == NULL) { rConsole.Write(_T("Key has no owner.")); } else { if (!IsValidSid(psidOwner)) { rConsole.Write(_T("Key has invalid owner SID.")); } else { rConsole.Write(_T("Key Owner: \n")); DWORD dwSIDStringSize = 0; BOOL blnRet = GetTextualSid(psidOwner,NULL,&dwSIDStringSize); ASSERT(!blnRet); ASSERT(GetLastError() == ERROR_INSUFFICIENT_BUFFER); TCHAR *pchSID = new TCHAR[dwSIDStringSize]; if(!GetTextualSid(psidOwner,pchSID,&dwSIDStringSize)) { dwError = GetLastError(); ASSERT(dwError != ERROR_INSUFFICIENT_BUFFER); rConsole.Write(_T("Error ")); TCHAR Buffer[256]; rConsole.Write(_itoa(dwError,Buffer,10)); rConsole.Write(_T("\nGetting string representation of SID\n")); } else { rConsole.Write(_T("\tSID: ")); rConsole.Write(pchSID); rConsole.Write(_T("\n")); } delete [] pchSID; DWORD dwNameBufferLength, dwDomainNameBufferLength; dwNameBufferLength = 1024; dwDomainNameBufferLength = 1024; pchName = new TCHAR [dwNameBufferLength]; pchDomainName = new TCHAR [dwDomainNameBufferLength]; DWORD dwNameLength = dwNameBufferLength, dwDomainNameLength = dwDomainNameBufferLength; SID_NAME_USE Use; if (!LookupAccountSid(NULL,psidOwner,pchName,&dwNameLength,pchDomainName,&dwDomainNameLength,&Use)) throw GetLastError(); else { rConsole.Write(_T("\tOwner Domain: ")); rConsole.Write(pchDomainName); rConsole.Write(_T("\n")); rConsole.Write(_T("\tOwner Name: ")); rConsole.Write(pchName); rConsole.Write(_T("\n\tSID type: ")); rConsole.Write(GetSidTypeName(Use)); rConsole.Write(_T("\n")); rConsole.Write(_T("\tOwner defaulted: ")); rConsole.Write(blnOwnerDefaulted?_T("Yes"):_T("No")); rConsole.Write(_T("\n")); } delete [] pchName; pchName = NULL; delete [] pchDomainName; pchDomainName = NULL; } } delete [] pSecurityDescriptor; } catch (DWORD dwError) { rConsole.Write(_T("Error ")); TCHAR Buffer[256]; rConsole.Write(_itoa(dwError,Buffer,10)); rConsole.Write(_T("\n")); if (pchName) delete [] pchName; if (pchDomainName) delete [] pchDomainName; if (pSecurityDescriptor) delete [] pSecurityDescriptor; } return 0; }
/* Dump ACE to file line per line in the following format: * ownerSID, groupSID, ACEType, ACEFlags, AccessMask, (Flags), (ObjectType guid), (InheritedObjectType guid), TrusteeSID */ void DumpACE( IN long long sd_id, IN unsigned char *buffer, IN FILE *dump ) { BOOL daclPresent, daclDefaulted; PACL dacl; PSID owner, group; BOOL ownerDefaulted, groupDefaulted; LPVOID ace; LPWSTR stringOwner = NULL; LPWSTR stringGroup = NULL; LPWSTR stringTrustee = NULL; RPC_WSTR OTGuid = NULL; RPC_WSTR IOTGuid = NULL; unsigned int i; GetSecurityDescriptorOwner(buffer, &owner, &ownerDefaulted); ConvertSidToStringSid(owner, &stringOwner); GetSecurityDescriptorGroup(buffer, &group, &groupDefaulted); ConvertSidToStringSid(group, &stringGroup); GetSecurityDescriptorDacl(buffer, &daclPresent, &dacl, &daclDefaulted); for(i = 0 ; GetAce(dacl, i, &ace) ; i++) { //Remove inherited ACE if((((ACE_HEADER *)ace)->AceFlags & INHERITED_ACE) != INHERITED_ACE) { fwprintf(dump,L"\n"); //Standard allow&deny ACE if(((ACE_HEADER *)ace)->AceType < 0x5) { ConvertSidToStringSid((PSID)&(((ACCESS_ALLOWED_ACE *)ace)->SidStart), &stringTrustee); fwprintf_s(dump, L"%lld\t%s\t%s\t%.2X\t%.2X\t%d\t\t\t\t%s", sd_id, stringOwner, stringGroup, ((ACE_HEADER *)ace)->AceType, ((ACE_HEADER *)ace)->AceFlags, ((ACCESS_ALLOWED_ACE *)ace)->Mask, stringTrustee ); } //Object ACE else { switch(((ACCESS_ALLOWED_OBJECT_ACE *)ace)->Flags) { //not any OT case 0x0: { ConvertSidToStringSid((PSID)((DWORD)&(((ACCESS_ALLOWED_OBJECT_ACE *)ace)->SidStart) - 2 * sizeof(GUID)), &stringTrustee ); break; } //Only OT case 0x1: { UuidToString(&(((ACCESS_ALLOWED_OBJECT_ACE *)ace)->ObjectType), &OTGuid); ConvertSidToStringSid((PSID)((DWORD)&(((ACCESS_ALLOWED_OBJECT_ACE *)ace)->SidStart) - sizeof(GUID)), &stringTrustee ); break; } //Only IOT case 0x2: { UuidToString(&(((ACCESS_ALLOWED_OBJECT_ACE *)ace)->InheritedObjectType), &IOTGuid); ConvertSidToStringSid((PSID)((DWORD)&(((ACCESS_ALLOWED_OBJECT_ACE *)ace)->SidStart) - sizeof(GUID)), &stringTrustee ); break; } //both case 0x3: { UuidToString(&(((ACCESS_ALLOWED_OBJECT_ACE *)ace)->ObjectType), &OTGuid); UuidToString(&(((ACCESS_ALLOWED_OBJECT_ACE *)ace)->InheritedObjectType), &IOTGuid); ConvertSidToStringSid((PSID)&(((ACCESS_ALLOWED_OBJECT_ACE *)ace)->SidStart), &stringTrustee ); break; } } fwprintf_s(dump, L"%lld\t%s\t%s\t%.2X\t%.2X\t%d\t%d\t%s\t%s\t%s", sd_id, stringOwner, stringGroup, ((ACE_HEADER *)ace)->AceType, ((ACE_HEADER *)ace)->AceFlags, ((ACCESS_ALLOWED_OBJECT_ACE *)ace)->Mask, ((ACCESS_ALLOWED_OBJECT_ACE *)ace)->Flags, OTGuid, IOTGuid, stringTrustee ); } LocalFree(stringTrustee); stringTrustee = NULL; RpcStringFree(&OTGuid); OTGuid = NULL; RpcStringFree(&IOTGuid); IOTGuid = NULL; } } LocalFree(stringOwner); stringOwner = NULL; LocalFree(stringGroup); stringGroup = NULL; }
DWORD MakeSDAbsolute ( PSECURITY_DESCRIPTOR OldSD, PSECURITY_DESCRIPTOR *NewSD ) { PSECURITY_DESCRIPTOR sd = NULL; DWORD descriptorSize; DWORD daclSize; DWORD saclSize; DWORD ownerSIDSize; DWORD groupSIDSize; PACL dacl; PACL sacl; PSID ownerSID; PSID groupSID; BOOL present; BOOL systemDefault; // // Get SACL // if (!GetSecurityDescriptorSacl (OldSD, &present, &sacl, &systemDefault)) return GetLastError(); if (sacl && present) { saclSize = sacl->AclSize; } else saclSize = 0; // // Get DACL // if (!GetSecurityDescriptorDacl (OldSD, &present, &dacl, &systemDefault)) return GetLastError(); if (dacl && present) { daclSize = dacl->AclSize; } else daclSize = 0; // // Get Owner // if (!GetSecurityDescriptorOwner (OldSD, &ownerSID, &systemDefault)) return GetLastError(); ownerSIDSize = GetLengthSid (ownerSID); // // Get Group // if (!GetSecurityDescriptorGroup (OldSD, &groupSID, &systemDefault)) return GetLastError(); groupSIDSize = GetLengthSid (groupSID); // // Do the conversion // descriptorSize = 0; MakeAbsoluteSD (OldSD, sd, &descriptorSize, dacl, &daclSize, sacl, &saclSize, ownerSID, &ownerSIDSize, groupSID, &groupSIDSize); sd = (PSECURITY_DESCRIPTOR) new BYTE [SECURITY_DESCRIPTOR_MIN_LENGTH]; if (!InitializeSecurityDescriptor (sd, SECURITY_DESCRIPTOR_REVISION)) return GetLastError(); if (!MakeAbsoluteSD (OldSD, sd, &descriptorSize, dacl, &daclSize, sacl, &saclSize, ownerSID, &ownerSIDSize, groupSID, &groupSIDSize)) return GetLastError(); *NewSD = sd; return ERROR_SUCCESS; }
/* ** Wrapper around the access() system call. This code was copied from Tcl ** 8.6 and then modified. */ int win32_access(const char *zFilename, int flags){ int rc = 0; PSECURITY_DESCRIPTOR pSd = NULL; unsigned long size; PSID pSid = NULL; BOOL sidDefaulted; BOOL impersonated = FALSE; SID_IDENTIFIER_AUTHORITY unmapped = {{0, 0, 0, 0, 0, 22}}; GENERIC_MAPPING genMap; HANDLE hToken = NULL; DWORD desiredAccess = 0, grantedAccess = 0; BOOL accessYesNo = FALSE; PRIVILEGE_SET privSet; DWORD privSetSize = sizeof(PRIVILEGE_SET); wchar_t *zMbcs = fossil_utf8_to_filename(zFilename); DWORD attr = GetFileAttributesW(zMbcs); if( attr==INVALID_FILE_ATTRIBUTES ){ /* * File might not exist. */ if( GetLastError()!=ERROR_SHARING_VIOLATION ){ rc = -1; goto done; } } if( flags==F_OK ){ /* * File exists, nothing else to check. */ goto done; } if( (flags & W_OK) && (attr & FILE_ATTRIBUTE_READONLY) && !(attr & FILE_ATTRIBUTE_DIRECTORY) ){ /* * The attributes say the file is not writable. If the file is a * regular file (i.e., not a directory), then the file is not * writable, full stop. For directories, the read-only bit is * (mostly) ignored by Windows, so we can't ascertain anything about * directory access from the attrib data. */ rc = -1; goto done; } /* * It looks as if the permissions are ok, but if we are on NT, 2000 or XP, * we have a more complex permissions structure so we try to check that. * The code below is remarkably complex for such a simple thing as finding * what permissions the OS has set for a file. */ /* * First find out how big the buffer needs to be. */ size = 0; GetFileSecurityW(zMbcs, OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION | LABEL_SECURITY_INFORMATION, 0, 0, &size); /* * Should have failed with ERROR_INSUFFICIENT_BUFFER */ if( GetLastError()!=ERROR_INSUFFICIENT_BUFFER ){ /* * Most likely case is ERROR_ACCESS_DENIED, which we will convert to * EACCES - just what we want! */ rc = -1; goto done; } /* * Now size contains the size of buffer needed. */ pSd = (PSECURITY_DESCRIPTOR)HeapAlloc(GetProcessHeap(), 0, size); if( pSd==NULL ){ rc = -1; goto done; } /* * Call GetFileSecurity() for real. */ if( !GetFileSecurityW(zMbcs, OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION | LABEL_SECURITY_INFORMATION, pSd, size, &size) ){ /* * Error getting owner SD */ rc = -1; goto done; } /* * As of Samba 3.0.23 (10-Jul-2006), unmapped users and groups are * assigned to SID domains S-1-22-1 and S-1-22-2, where "22" is the * top-level authority. If the file owner and group is unmapped then * the ACL access check below will only test against world access, * which is likely to be more restrictive than the actual access * restrictions. Since the ACL tests are more likely wrong than * right, skip them. Moreover, the unix owner access permissions are * usually mapped to the Windows attributes, so if the user is the * file owner then the attrib checks above are correct (as far as they * go). */ if( !GetSecurityDescriptorOwner(pSd, &pSid, &sidDefaulted) || memcmp(GetSidIdentifierAuthority(pSid), &unmapped, sizeof(SID_IDENTIFIER_AUTHORITY))==0 ){ goto done; /* Attrib tests say access allowed. */ } /* * Perform security impersonation of the user and open the resulting * thread token. */ if( !ImpersonateSelf(SecurityImpersonation) ){ /* * Unable to perform security impersonation. */ rc = -1; goto done; } impersonated = TRUE; if( !OpenThreadToken(GetCurrentThread(), TOKEN_DUPLICATE | TOKEN_QUERY, FALSE, &hToken) ){ /* * Unable to get current thread's token. */ rc = -1; goto done; } /* * Setup desiredAccess according to the access priveleges we are * checking. */ if( flags & R_OK ){ desiredAccess |= FILE_GENERIC_READ; } if( flags & W_OK){ desiredAccess |= FILE_GENERIC_WRITE; } memset(&genMap, 0, sizeof(GENERIC_MAPPING)); genMap.GenericRead = FILE_GENERIC_READ; genMap.GenericWrite = FILE_GENERIC_WRITE; genMap.GenericExecute = FILE_GENERIC_EXECUTE; genMap.GenericAll = FILE_ALL_ACCESS; /* * Perform access check using the token. */ if( !AccessCheck(pSd, hToken, desiredAccess, &genMap, &privSet, &privSetSize, &grantedAccess, &accessYesNo) ){ /* * Unable to perform access check. */ rc = -1; goto done; } if( !accessYesNo ) rc = -1; done: if( hToken != NULL ){ CloseHandle(hToken); } if( impersonated ){ RevertToSelf(); impersonated = FALSE; } if( pSd!=NULL ){ HeapFree(GetProcessHeap(), 0, pSd); } fossil_filename_free(zMbcs); return rc; }
HRESULT CSecurityInformation::SetSecurity( SECURITY_INFORMATION SecurityInformation, PSECURITY_DESCRIPTOR pSecurityDescriptor) { HRESULT hr = 1; // Get the Dacl PACL pDACL = NULL; BOOL fPresent, fDefaulted; GetSecurityDescriptorDacl(pSecurityDescriptor, &fPresent, &pDACL, &fDefaulted); // Get the SACL PACL pSACL = NULL; GetSecurityDescriptorSacl(pSecurityDescriptor, &fPresent, &pSACL, &fDefaulted); // Get the owner PSID psidOwner = NULL; GetSecurityDescriptorOwner(pSecurityDescriptor, &psidOwner, &fDefaulted); // Get the group PSID psidGroup = NULL; GetSecurityDescriptorOwner(pSecurityDescriptor, &psidGroup, &fDefaulted); // Find out if DACL and SACL inherit from parent objects SECURITY_DESCRIPTOR_CONTROL sdCtrl = NULL; ULONG ulRevision; GetSecurityDescriptorControl(pSecurityDescriptor, &sdCtrl, &ulRevision); if ((sdCtrl & SE_DACL_PROTECTED) != SE_DACL_PROTECTED) SecurityInformation |= UNPROTECTED_DACL_SECURITY_INFORMATION; else SecurityInformation |= PROTECTED_DACL_SECURITY_INFORMATION; if ((sdCtrl & SE_SACL_PROTECTED) != SE_SACL_PROTECTED) SecurityInformation |= UNPROTECTED_SACL_SECURITY_INFORMATION; else SecurityInformation |= PROTECTED_SACL_SECURITY_INFORMATION; // Set the security ULONG lErr; if (m_Info.m_szName[0] != 0) // Is it named { lErr = SetNamedSecurityInfo(m_Info.m_szName, m_Type.m_objSecurType, SecurityInformation, psidOwner, psidGroup, pDACL, pSACL); } else { // Is it a handle case lErr = SetSecurityInfo(m_Info.m_hHandle, m_Type.m_objSecurType, SecurityInformation, psidOwner, psidGroup, pDACL, pSACL); } // Report error if (lErr != ERROR_SUCCESS) { MessageBox(NULL, TEXT("An error occurred saving security information for this object,\n") TEXT("possibly due to insufficient access rights.\n"), TEXT("Security Notice"), MB_OK); } else { hr = S_OK; } return(hr); }