/*++ Copyright (c) 1990 - 1995 Microsoft Corporation Module Name: mapsd.c Abstract: Mapping Security Descriptors Author: Dave Snipp (DaveSn) 15-Mar-1991 Revision History: --*/ #include // Object types // extern GENERIC_MAPPING GenericMapping[]; PSECURITY_DESCRIPTOR MapPrinterSDToShareSD( PSECURITY_DESCRIPTOR pPrinterSD ); BOOL ProcessSecurityDescriptorDacl( PSECURITY_DESCRIPTOR pSourceSD, PACL *ppDacl, LPBOOL pDefaulted ); DWORD MapPrinterMaskToShareMask( DWORD PrinterMask ); PSECURITY_DESCRIPTOR MapPrinterSDToShareSD( PSECURITY_DESCRIPTOR pPrinterSD ) { SECURITY_DESCRIPTOR AbsoluteSD; PSECURITY_DESCRIPTOR pRelative; BOOL Defaulted = FALSE; PSID pOwnerSid = NULL; PSID pGroupSid = NULL; PACL pDacl = NULL; BOOL ErrorOccurred = FALSE; DWORD SDLength = 0; if (!IsValidSecurityDescriptor(pPrinterSD)) { return(NULL); } if (!InitializeSecurityDescriptor (&AbsoluteSD ,SECURITY_DESCRIPTOR_REVISION1)) { return(NULL); } if(GetSecurityDescriptorOwner( pPrinterSD, &pOwnerSid, &Defaulted ) ) SetSecurityDescriptorOwner( &AbsoluteSD, pOwnerSid, Defaulted ); else ErrorOccurred = TRUE; if( GetSecurityDescriptorGroup( pPrinterSD, &pGroupSid, &Defaulted ) ) SetSecurityDescriptorGroup( &AbsoluteSD, pGroupSid, Defaulted ); else ErrorOccurred = TRUE; if (ProcessSecurityDescriptorDacl(pPrinterSD, &pDacl, &Defaulted)) { (VOID)SetSecurityDescriptorDacl (&AbsoluteSD, TRUE, pDacl, FALSE ); } else ErrorOccurred = TRUE; if (ErrorOccurred) { if (pDacl) { LocalFree(pDacl); } return(NULL); } SDLength = GetSecurityDescriptorLength( &AbsoluteSD); pRelative = LocalAlloc(LPTR, SDLength); if (!pRelative) { LocalFree(pDacl); return(NULL); } if (!MakeSelfRelativeSD (&AbsoluteSD, pRelative, &SDLength)) { LocalFree(pRelative); LocalFree(pDacl); return(NULL); } LocalFree(pDacl); return(pRelative); } BOOL ProcessSecurityDescriptorDacl( PSECURITY_DESCRIPTOR pSourceSD, PACL *ppDacl, LPBOOL pDefaulted ) { BOOL DaclPresent = FALSE; BOOL bRet = FALSE; DWORD DestAceCount = 0; DWORD DaclLength = 0; PACL TmpAcl = NULL; PACL pDacl = NULL; PSID *ppSid = NULL; ACCESS_MASK *pAccessMask = NULL; BYTE *pInheritFlags = NULL; UCHAR *pAceType = NULL; PACCESS_ALLOWED_ACE pAce = NULL; DWORD dwLengthSid = 0; PSID pSourceSid = NULL; PSID pDestSid = NULL; DWORD i = 0; PACCESS_ALLOWED_ACE TmpAce = NULL; ACL_SIZE_INFORMATION AclSizeInfo; *ppDacl = NULL; bRet = GetSecurityDescriptorDacl( pSourceSD, &DaclPresent, &pDacl, pDefaulted ); if (bRet) { bRet = DaclPresent; } if (bRet) { GetAclInformation(pDacl, &AclSizeInfo, sizeof(ACL_SIZE_INFORMATION), AclSizeInformation); ppSid = LocalAlloc(LPTR, sizeof(PSID)* AclSizeInfo.AceCount); pAccessMask = LocalAlloc(LPTR, sizeof(ACCESS_MASK)* AclSizeInfo.AceCount); pInheritFlags = LocalAlloc(LPTR, sizeof(BYTE)*AclSizeInfo.AceCount); pAceType = LocalAlloc(LPTR, sizeof(UCHAR)*AclSizeInfo.AceCount); bRet = ppSid && pAccessMask && pInheritFlags && pAceType; } for (i = 0 ; bRet && i < AclSizeInfo.AceCount; i++) { GetAce(pDacl, i, (LPVOID *)&pAce); // // Skip the Ace if it is inherit only // if ( ((PACE_HEADER)pAce)->AceFlags & INHERIT_ONLY_ACE ) { continue; } *(pAceType + DestAceCount) = ((PACE_HEADER)pAce)->AceType; *(pAccessMask + DestAceCount) = MapPrinterMaskToShareMask(((PACCESS_ALLOWED_ACE)pAce)->Mask); *(pInheritFlags + DestAceCount) = ((PACE_HEADER)pAce)->AceFlags; // // Copy the sid information // pSourceSid = (PSID)(&(((PACCESS_ALLOWED_ACE)pAce)->SidStart)); dwLengthSid = GetLengthSid(pSourceSid); pDestSid = (LPBYTE)LocalAlloc(LPTR, dwLengthSid); if (pDestSid) { CopySid(dwLengthSid, pDestSid, pSourceSid); *(ppSid + DestAceCount) = pDestSid; } else { // // We failed to allocate the memory, we signal that we failed and // fall down to the cleanup code below. // bRet = FALSE; break; } DestAceCount++; } // // Compute size of the Dacl // if (bRet) { DaclLength = (DWORD)sizeof(ACL); for (i = 0; i < DestAceCount; i++) { DaclLength += GetLengthSid( *(ppSid + i)) + (DWORD)sizeof(ACCESS_ALLOWED_ACE) - (DWORD)sizeof(DWORD); //Subtract out SidStart field length } TmpAcl = LocalAlloc(LPTR, DaclLength); bRet = (TmpAcl != NULL); } if (bRet) { bRet = InitializeAcl(TmpAcl, DaclLength, ACL_REVISION2); } for (i = 0; bRet && i < DestAceCount; i++) { if( *(pAceType +i) == ACCESS_ALLOWED_ACE_TYPE ) (VOID)AddAccessAllowedAce ( TmpAcl, ACL_REVISION2, *(pAccessMask + i), *(ppSid + i)); else (VOID)AddAccessDeniedAce ( TmpAcl, ACL_REVISION2, *(pAccessMask + i), *(ppSid + i)); if (*(pInheritFlags + i) != 0) { (VOID)GetAce( TmpAcl, i, (LPVOID *)&TmpAce ); TmpAce->Header.AceFlags = *(pInheritFlags + i); } } // // Write the Dacl back from the TmpAcl. // if (bRet) { *ppDacl = TmpAcl; TmpAcl = NULL; } // // Free all of our temporary space. // if (ppSid) { for (i = 0; i < DestAceCount; i++) { LocalFree(*(ppSid + i)); } LocalFree(ppSid); } if (pAccessMask) { LocalFree(pAccessMask); } if (pInheritFlags) { LocalFree(pInheritFlags); } if (pAceType) { LocalFree(pAceType); } if (TmpAcl) { LocalFree(TmpAcl); } return bRet; } DWORD MapPrinterMaskToShareMask( DWORD PrinterMask ) { DWORD ReturnMask = 0; MapGenericMask(&PrinterMask, &GenericMapping[SPOOLER_OBJECT_PRINTER]); if ((PrinterMask & PRINTER_ACCESS_ADMINISTER) || (PrinterMask & PRINTER_ACCESS_USE)) { ReturnMask |= GENERIC_ALL; } return(ReturnMask); }