STDMETHOD(SetSecurity) (THIS_ SECURITY_INFORMATION SecurityInformation, PSECURITY_DESCRIPTOR pSecurityDescriptor ) { DWORD bufferLength = 0; MakeSelfRelativeSD(pSecurityDescriptor, NULL, &bufferLength); SAFEARRAY* sdArray = SafeArrayCreateVector(VT_UI1, 0, bufferLength); if (sdArray) { MakeSelfRelativeSD(pSecurityDescriptor, (sdArray)->pvData, &bufferLength); try { m_filesystem->SetPathSecurityDescriptor(m_pathName, sdArray); } catch (_com_error &e) { com_error_Message(e); } SafeArrayDestroy(sdArray); } return S_OK; }
/* * GetSD: Accessor function for SecurityDescriptor * Creates an (absolute) SD from the GetACL return value */ PSECURITY_DESCRIPTOR vncAccessControl::GetSD(){ PSECURITY_DESCRIPTOR pSD; PSECURITY_DESCRIPTOR pSelfRelativeSD; PACL pACL = NULL; DWORD dwBufferLength = 0; // If we can't retrieve a valid ACL we create an empty one (i.e. no access). if (!(pACL = GetACL()) || !IsValidAcl(pACL)) { pACL = (PACL) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(ACL)); // Initialize the new ACL. if (!InitializeAcl(pACL, sizeof(ACL), ACL_REVISION)) { ; // Todo: Report an error. } } // Construct SD pSD = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, SECURITY_DESCRIPTOR_MIN_LENGTH); if(InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION) && // Set our ACL to the SD. SetSecurityDescriptorDacl(pSD, TRUE, pACL, FALSE) && // AccessCheck() is picky about what is in the SD. SetSecurityDescriptorOwner(pSD, GetOwnerSID(), FALSE) && SetSecurityDescriptorGroup(pSD, GetOwnerSID(), FALSE)) { } else { // Todo: Report an error. } // Make SD self-relative and use LocalAlloc MakeSelfRelativeSD(pSD, NULL, &dwBufferLength); pSelfRelativeSD = (PSECURITY_DESCRIPTOR) LocalAlloc(0, dwBufferLength); MakeSelfRelativeSD(pSD, pSelfRelativeSD, &dwBufferLength); FreeSD(pSD); return pSelfRelativeSD; }
/*---------------------------------------------------------------------------*\ * NAME: RemovePrincipalFromNamedValueSD * --------------------------------------------------------------------------* * DESCRIPTION: Retrieves the designated security descriptor from the * registry and removes all ACLs that belong to the named principal. \*---------------------------------------------------------------------------*/ DWORD RemovePrincipalFromNamedValueSD ( HKEY hkeyRoot, LPTSTR tszKeyName, LPTSTR tszValueName, LPTSTR tszPrincipal, DWORD fAceType ) { DWORD dwReturnValue = ERROR_SUCCESS; SECURITY_DESCRIPTOR *pSD = NULL; SECURITY_DESCRIPTOR *psdSelfRelative = NULL; SECURITY_DESCRIPTOR *psdAbsolute = NULL; DWORD cbSecurityDesc = 0; BOOL fPresent = FALSE; BOOL fDefaultDACL = FALSE; PACL pDacl = NULL; dwReturnValue = GetNamedValueSD (hkeyRoot, tszKeyName, tszValueName, &pSD, NULL); // Get security descriptor from registry or create a new one if (dwReturnValue != ERROR_SUCCESS) { if(dwReturnValue == ERROR_FILE_NOT_FOUND) { dwReturnValue = ERROR_SUCCESS; } goto CLEANUP; } if (!GetSecurityDescriptorDacl (pSD, &fPresent, &pDacl, &fDefaultDACL)) { dwReturnValue = GetLastError(); goto CLEANUP; } // Remove the tszPrincipal that the caller wants removed dwReturnValue = RemovePrincipalFromACL (pDacl, tszPrincipal, fAceType); if(dwReturnValue == ERROR_FILE_NOT_FOUND) { dwReturnValue = ERROR_SUCCESS; goto CLEANUP; } else if (dwReturnValue != ERROR_SUCCESS) { dwReturnValue = GetLastError(); goto CLEANUP; } // Make the security descriptor absolute if it isn't new dwReturnValue = MakeSDAbsolute ((PSECURITY_DESCRIPTOR) pSD, (PSECURITY_DESCRIPTOR *) &psdAbsolute); if (dwReturnValue != ERROR_SUCCESS) goto CLEANUP; // Set the discretionary ACL on the security descriptor if (!SetSecurityDescriptorDacl (psdAbsolute, TRUE, pDacl, FALSE)) { dwReturnValue = GetLastError(); goto CLEANUP; } // Make the security descriptor self-relative so that we can // store it in the registry cbSecurityDesc = 0; MakeSelfRelativeSD (psdAbsolute, psdSelfRelative, &cbSecurityDesc); psdSelfRelative = (SECURITY_DESCRIPTOR *) malloc (cbSecurityDesc); if (!MakeSelfRelativeSD (psdAbsolute, psdSelfRelative, &cbSecurityDesc)) { dwReturnValue = GetLastError(); goto CLEANUP; } // Store the security descriptor in the registry dwReturnValue = SetNamedValueSD (hkeyRoot, tszKeyName, tszValueName, psdSelfRelative); CLEANUP: if(pSD) free (pSD); if(psdSelfRelative) free (psdSelfRelative); if(psdAbsolute) free (psdAbsolute); return dwReturnValue; }
/*---------------------------------------------------------------------------*\ * NAME: UpdatePrincipalInNamedValueSD * --------------------------------------------------------------------------* * DESCRIPTION: Retrieves the designated security descriptor from the * registry and updates all ACLs that belong to the named principal. \*---------------------------------------------------------------------------*/ DWORD UpdatePrincipalInNamedValueSD ( HKEY hkeyRoot, LPTSTR tszKeyName, LPTSTR tszValueName, LPTSTR tszPrincipal, DWORD dwAccessMask, BOOL fRemove, DWORD fAceType ) { DWORD dwReturnValue = ERROR_SUCCESS; SECURITY_DESCRIPTOR *pSD = NULL; SECURITY_DESCRIPTOR *psdSelfRelative = NULL; SECURITY_DESCRIPTOR *psdAbsolute = NULL; DWORD cbSecurityDesc = 0; BOOL fPresent = FALSE; BOOL fDefaultDACL = FALSE; PACL pDacl = NULL; // Get security descriptor from registry dwReturnValue = GetNamedValueSD (hkeyRoot, tszKeyName, tszValueName, &pSD, NULL); if (dwReturnValue != ERROR_SUCCESS) { if(dwReturnValue == ERROR_FILE_NOT_FOUND && fRemove) { dwReturnValue = ERROR_SUCCESS; } goto CLEANUP; } if (!GetSecurityDescriptorDacl (pSD, &fPresent, &pDacl, &fDefaultDACL)) { dwReturnValue = GetLastError(); goto CLEANUP; } // Update the tszPrincipal that the caller wants to change dwReturnValue = UpdatePrincipalInACL (pDacl, tszPrincipal, dwAccessMask, fRemove, fAceType); if(dwReturnValue == ERROR_FILE_NOT_FOUND) { dwReturnValue = ERROR_SUCCESS; goto CLEANUP; } else if (dwReturnValue != ERROR_SUCCESS) { dwReturnValue = GetLastError(); goto CLEANUP; } // Make the security descriptor absolute dwReturnValue = MakeSDAbsolute ((PSECURITY_DESCRIPTOR) pSD, (PSECURITY_DESCRIPTOR *) &psdAbsolute); if (dwReturnValue != ERROR_SUCCESS) goto CLEANUP; // Set the discretionary ACL on the security descriptor if (!SetSecurityDescriptorDacl (psdAbsolute, TRUE, pDacl, FALSE)) { dwReturnValue = GetLastError(); goto CLEANUP; } //Now ensure consistency of the SD dwReturnValue = CanonicalizeSD(psdAbsolute); if (dwReturnValue != ERROR_SUCCESS) goto CLEANUP; // Make the security descriptor self-relative so that we can // store it in the registry cbSecurityDesc = 0; MakeSelfRelativeSD (psdAbsolute, psdSelfRelative, &cbSecurityDesc); psdSelfRelative = (SECURITY_DESCRIPTOR *) malloc (cbSecurityDesc); if (!MakeSelfRelativeSD (psdAbsolute, psdSelfRelative, &cbSecurityDesc)) { dwReturnValue = GetLastError(); goto CLEANUP; } // Store the security descriptor in the registry dwReturnValue = SetNamedValueSD (hkeyRoot, tszKeyName, tszValueName, psdSelfRelative); CLEANUP: if(pSD) free (pSD); if(psdSelfRelative) free (psdSelfRelative); if(psdAbsolute) free (psdAbsolute); return dwReturnValue; }
/*---------------------------------------------------------------------------*\ * NAME: AddPrincipalToNamedValueSD * --------------------------------------------------------------------------* * DESCRIPTION: Retrieves the designated security descriptor from the * registry and adds an ACE for the designated principal. \*---------------------------------------------------------------------------*/ DWORD AddPrincipalToNamedValueSD ( HKEY hkeyRoot, LPTSTR tszKeyName, LPTSTR tszValueName, LPTSTR tszPrincipal, BOOL fPermit, DWORD dwAccessMask, DWORD dwSDType ) { DWORD dwReturnValue = ERROR_SUCCESS; SECURITY_DESCRIPTOR *pSD = NULL; SECURITY_DESCRIPTOR *psdSelfRelative = NULL; SECURITY_DESCRIPTOR *psdAbsolute = NULL; DWORD cbSecurityDesc = 0; BOOL fPresent = FALSE; BOOL fDefaultDACL = FALSE; PACL pDacl = NULL; BOOL fNewSD = FALSE; dwReturnValue = GetNamedValueSD (hkeyRoot, tszKeyName, tszValueName, &pSD, &fNewSD); // Get security descriptor from registry or create a new one if (dwReturnValue != ERROR_SUCCESS) goto CLEANUP; if (!GetSecurityDescriptorDacl (pSD, &fPresent, &pDacl, &fDefaultDACL)) { dwReturnValue = GetLastError(); goto CLEANUP; } if (fNewSD) { dwReturnValue = SetAclDefaults(&pDacl, dwSDType); if (dwReturnValue != ERROR_SUCCESS) goto CLEANUP; } // Add the tszPrincipal that the caller wants added if (fPermit) { dwReturnValue = AddAccessAllowedACEToACL (&pDacl, dwAccessMask, tszPrincipal); } else { dwReturnValue = AddAccessDeniedACEToACL (&pDacl, dwAccessMask, tszPrincipal); } if (dwReturnValue != ERROR_SUCCESS) goto CLEANUP; // Make the security descriptor absolute if it isn't new if (!fNewSD) { dwReturnValue = MakeSDAbsolute ((PSECURITY_DESCRIPTOR) pSD, (PSECURITY_DESCRIPTOR *) &psdAbsolute); if (dwReturnValue != ERROR_SUCCESS) goto CLEANUP; } else { psdAbsolute = pSD; } // Set the discretionary ACL on the security descriptor if (!SetSecurityDescriptorDacl (psdAbsolute, TRUE, pDacl, FALSE)) { dwReturnValue = GetLastError(); goto CLEANUP; } //Now ensure consistency of the SD dwReturnValue = CanonicalizeSD(psdAbsolute); if (dwReturnValue != ERROR_SUCCESS) goto CLEANUP; // Make the security descriptor self-relative so that we can // store it in the registry cbSecurityDesc = 0; MakeSelfRelativeSD (psdAbsolute, psdSelfRelative, &cbSecurityDesc); psdSelfRelative = (SECURITY_DESCRIPTOR *) malloc (cbSecurityDesc); if(!psdSelfRelative) { dwReturnValue = ERROR_OUTOFMEMORY; goto CLEANUP; } if (!MakeSelfRelativeSD (psdAbsolute, psdSelfRelative, &cbSecurityDesc)) { dwReturnValue = GetLastError(); goto CLEANUP; } // Store the security descriptor in the registry SetNamedValueSD (hkeyRoot, tszKeyName, tszValueName, psdSelfRelative); CLEANUP: if(pSD) free (pSD); if(psdSelfRelative) free (psdSelfRelative); if(psdAbsolute && pSD != psdAbsolute) free (psdAbsolute); return dwReturnValue; }
/*)) // NOTE!!! that does not check for length of Security Descriptor \\ so if buffer is unsufficient memory will be messed // To obtain size of buffer use XFSSecurityDescriptorSize() ((*/ LIB_EXPORT rc_t CC XFSSecurityDescriptor ( SECURITY_INFORMATION SecInfo, const char * Permissions, XFSNType NodeType, PSECURITY_DESCRIPTOR Descriptor, ULONG DescriptorLength ) { rc_t RCt; SECURITY_DESCRIPTOR AbsDescriptor; const struct XFSPerm * Perm; DWORD DscLen; RCt = 0; Perm = NULL; DscLen = DescriptorLength; if ( Permissions == NULL || Descriptor == NULL ) { return XFS_RC ( rcNull ); } RCt = XFSPermMake ( Permissions, & Perm ); if ( RCt != 0 || Perm == NULL ) { return XFS_RC ( rcInvalid ); } RCt = _SD_Set ( SecInfo, Perm, NodeType, & AbsDescriptor ); if ( RCt == 0 ) { /*)) Checking if SD is valid ((*/ if ( IsValidSecurityDescriptor ( & AbsDescriptor ) == 0 ) { RCt = XFS_RC ( rcInvalid ); } else { /*)) we should convert absolute to selfrelative ((*/ if ( MakeSelfRelativeSD ( & AbsDescriptor, Descriptor, & DscLen ) == 0 ) { RCt = XFS_RC ( rcInvalid ); } } } /* _SD_SR_Dump ( & AbsDescriptor ); _SD_AB_Dump ( Descriptor, DescriptorLength ); */ free ( ( struct XFSPerm * ) Perm ); _SD_Dispose ( & AbsDescriptor ); return RCt; } /* XFSSecurityDescriptor () */
DWORD RemovePrincipalFromNamedValueSD ( HKEY RootKey, LPTSTR KeyName, LPTSTR ValueName, LPTSTR Principal ) { DWORD returnValue; SECURITY_DESCRIPTOR *sd; SECURITY_DESCRIPTOR *sdSelfRelative = NULL; SECURITY_DESCRIPTOR *sdAbsolute; DWORD secDescSize; BOOL present; BOOL defaultDACL; PACL dacl; BOOL newSD = FALSE; returnValue = GetNamedValueSD (RootKey, KeyName, ValueName, &sd, &newSD); // // Get security descriptor from registry or create a new one // if (returnValue != ERROR_SUCCESS) return returnValue; if (!GetSecurityDescriptorDacl (sd, &present, &dacl, &defaultDACL)) return GetLastError(); // // If the security descriptor is new, add the required Principals to it // if (newSD) { AddAccessAllowedACEToACL (&dacl, COM_RIGHTS_EXECUTE, TEXT("SYSTEM")); AddAccessAllowedACEToACL (&dacl, COM_RIGHTS_EXECUTE, TEXT("INTERACTIVE")); } // // Remove the Principal that the caller wants removed // returnValue = RemovePrincipalFromACL (dacl, Principal); if (returnValue != ERROR_SUCCESS) { free (sd); return returnValue; } // // Make the security descriptor absolute if it isn't new // if (!newSD) MakeSDAbsolute ((PSECURITY_DESCRIPTOR) sd, (PSECURITY_DESCRIPTOR *) &sdAbsolute); else sdAbsolute = sd; // // Set the discretionary ACL on the security descriptor // if (!SetSecurityDescriptorDacl (sdAbsolute, TRUE, dacl, FALSE)) return GetLastError(); // // Make the security descriptor self-relative so that we can // store it in the registry // secDescSize = 0; MakeSelfRelativeSD (sdAbsolute, sdSelfRelative, &secDescSize); sdSelfRelative = (SECURITY_DESCRIPTOR *) malloc (secDescSize); if (!MakeSelfRelativeSD (sdAbsolute, sdSelfRelative, &secDescSize)) return GetLastError(); // // Store the security descriptor in the registry // SetNamedValueSD (RootKey, KeyName, ValueName, sdSelfRelative); free (sd); free (sdSelfRelative); free (sdAbsolute); return ERROR_SUCCESS; }
DWORD setDCOMPermission( HKEY RootKey, LPTSTR KeyName, PSID sid, LPTSTR ValueName, DWORD dwPermissionMask, BOOL bLimits) { DWORD returnValue; SECURITY_DESCRIPTOR *sd = NULL; SECURITY_DESCRIPTOR *sdSelfRelative = NULL; SECURITY_DESCRIPTOR *sdAbsolute = NULL; DWORD secDescSize; BOOL present; BOOL defaultDACL; PACL dacl; BOOL newSD = FALSE; returnValue = GetNamedValueSD (RootKey, KeyName, ValueName, &sd, &newSD); // // Get security descriptor from registry or create a new one // if (returnValue != ERROR_SUCCESS) { return returnValue; } if (!GetSecurityDescriptorDacl (sd, &present, &dacl, &defaultDACL)) { return GetLastError(); } if ((newSD) && (!bLimits)) { AddAccessAllowedACEToACL( &dacl, COM_RIGHTS_EXECUTE, TEXT("SYSTEM")); AddAccessAllowedACEToACL( &dacl, COM_RIGHTS_EXECUTE, TEXT("INTERACTIVE")); } //get account according to the SID TCHAR userName[256]; TCHAR acctName[256]; TCHAR domainName[256]; DWORD dwAcctName = 256; DWORD dwDomainName = 256; SID_NAME_USE eUse = SidTypeUnknown; if (LookupAccountSid( NULL, sid, acctName, (LPDWORD)&dwAcctName, domainName, &dwDomainName, &eUse)) { sprintf(userName, "%s\\%s", domainName, acctName); } else { return GetLastError(); } returnValue = AddAccessAllowedACEToACL ( &dacl, dwPermissionMask, userName); if (returnValue != ERROR_SUCCESS) { free (sd); return returnValue; } // // Make the security descriptor absolute if it isn't new // if (!newSD) { MakeSDAbsolute ( (PSECURITY_DESCRIPTOR) sd, (PSECURITY_DESCRIPTOR *) &sdAbsolute); } else { sdAbsolute = sd; } // // Set the discretionary ACL on the security descriptor // if (!SetSecurityDescriptorDacl (sdAbsolute, TRUE, dacl, FALSE)) return GetLastError(); // // Make the security descriptor self-relative so that we can // store it in the registry // secDescSize = 0; MakeSelfRelativeSD (sdAbsolute, sdSelfRelative, &secDescSize); sdSelfRelative = (SECURITY_DESCRIPTOR *) malloc (secDescSize); if (!MakeSelfRelativeSD (sdAbsolute, sdSelfRelative, &secDescSize)) { return GetLastError(); } // // Store the security descriptor in the registry // SetNamedValueSD (RootKey, KeyName, ValueName, sdSelfRelative); free (sd); free (sdSelfRelative); if (sd != sdAbsolute) { free (sdAbsolute); } return ERROR_SUCCESS; }