//+--------------------------------------------------------------------------- // // Microsoft Windows // Copyright (C) Microsoft Corporation, 1992 - 1996. // // File: security.cxx // // Contents: Security-related helper functions used by the Task Scheduler // setup program to set security on the job folder. // // Classes: None. // // Functions: // // History: 23-Sep-96 AnirudhS Copied with minor modifications from // ..\job\security.cxx. // //---------------------------------------------------------------------------- #include #include "..\inc\security.hxx" #define schDebugOut(x) #define schAssert(x) //+--------------------------------------------------------------------------- // // Function: CreateSecurityDescriptor // // Synopsis: Create a security descriptor with the ACE information // specified. // // Arguments: [AceCount] -- ACE count (no. of rgMyAce and rgAce elements). // [rgMyAce] -- ACE specification array. // [rgAce] -- Caller allocated array of ptrs to ACEs so // this function doesn't have to allocate it. // // Returns: TRUE -- Function succeeded, // FALSE -- Otherwise. // // Notes: None. // //---------------------------------------------------------------------------- PSECURITY_DESCRIPTOR CreateSecurityDescriptor( DWORD AceCount, MYACE rgMyAce[], PACCESS_ALLOWED_ACE rgAce[], DWORD * pStatus) { PSECURITY_DESCRIPTOR pSecurityDescriptor = NULL; PACL pAcl = NULL; DWORD LengthAces = 0; DWORD LengthAcl; DWORD i; DWORD Status; for (i = 0; i < AceCount; i++) { rgAce[i] = CreateAccessAllowedAce(rgMyAce[i].pSid, rgMyAce[i].AccessMask, 0, rgMyAce[i].InheritFlags, &Status); if (rgAce[i] == NULL) { goto ErrorExit; } LengthAces += rgAce[i]->Header.AceSize; } // // Calculate ACL and SD sizes // LengthAcl = sizeof(ACL) + LengthAces; // // Create the ACL. // pAcl = (PACL)LocalAlloc(LMEM_FIXED, LengthAcl); if (pAcl == NULL) { Status = ERROR_NOT_ENOUGH_MEMORY; schDebugOut((DEB_ERROR, "CreateSecurityDescriptor, ACL allocation failed\n")); goto ErrorExit; } if (!InitializeAcl(pAcl, LengthAcl, ACL_REVISION)) { Status = GetLastError(); schDebugOut((DEB_ERROR, "CreateSecurityDescriptor, InitializeAcl failed, " \ "status = 0x%lx\n", Status)); goto ErrorExit; } for (i = 0; i < AceCount; i++) { if (!AddAce(pAcl, ACL_REVISION, 0, rgAce[i], rgAce[i]->Header.AceSize)) { Status = GetLastError(); schDebugOut((DEB_ERROR, "CreateSecurityDescriptor, AddAce[%l] failed, " \ "status = 0x%lx\n", i, Status)); goto ErrorExit; } LocalFree(rgAce[i]); rgAce[i] = NULL; } // // Create the security descriptor. // pSecurityDescriptor = LocalAlloc(LMEM_FIXED, SECURITY_DESCRIPTOR_MIN_LENGTH); if (pSecurityDescriptor == NULL) { Status = ERROR_NOT_ENOUGH_MEMORY; schDebugOut((DEB_ERROR, "CreateSecurityDescriptor, SECURITY_DESCRIPTOR allocation " \ "failed\n")); goto ErrorExit; } if (!InitializeSecurityDescriptor(pSecurityDescriptor, SECURITY_DESCRIPTOR_REVISION)) { Status = GetLastError(); schDebugOut((DEB_ERROR, "CreateSecurityDescriptor, InitializeSecurityDescriptor " \ "failed, status = 0x%lx\n", Status)); goto ErrorExit; } if (!SetSecurityDescriptorDacl(pSecurityDescriptor, TRUE, pAcl, FALSE)) { Status = GetLastError(); schDebugOut((DEB_ERROR, "CreateSecurityDescriptor, SetSecurityDescriptorDacl " \ "failed, status = 0x%lx\n", Status)); goto ErrorExit; } if (pStatus != NULL) *pStatus = ERROR_SUCCESS; return(pSecurityDescriptor); ErrorExit: for (i = 0; i < AceCount; i++) { if (rgAce[i] != NULL) { LocalFree(rgAce[i]); rgAce[i] = NULL; } } if (pAcl != NULL) LocalFree(pAcl); if (pSecurityDescriptor != NULL) LocalFree(pSecurityDescriptor); if (pStatus != NULL) *pStatus = Status; return(NULL); } //+--------------------------------------------------------------------------- // // Function: DeleteSecurityDescriptor // // Synopsis: Deallocate the security descriptor allocated in // CreateSecurityDescriptor. // // Arguments: [pSecurityDescriptor] -- SD returned from // CreateSecurityDescriptor. // // Returns: None. // // Notes: None. // //---------------------------------------------------------------------------- void DeleteSecurityDescriptor(PSECURITY_DESCRIPTOR pSecurityDescriptor) { BOOL fPresent; BOOL fDefaulted; PACL pAcl; schAssert(pSecurityDescriptor != NULL); if (GetSecurityDescriptorDacl(pSecurityDescriptor, &fPresent, &pAcl, &fDefaulted)) { if (fPresent && pAcl != NULL) { LocalFree(pAcl); } } else { schDebugOut((DEB_ERROR, "DeleteSecurityDescriptor, GetSecurityDescriptorDacl failed, " \ "status = 0x%lx\n", GetLastError())); } LocalFree(pSecurityDescriptor); } //+--------------------------------------------------------------------------- // // Function: CreateAccessAllowedAce // // Synopsis: Scavenged code from winlogon to create an access allowed ACE. // Modified a bit to use Win32 vs. Rtl. // // Arguments: [pSid] -- Sid to which this ACE is applied. // [AccessMask] -- ACE access mask value. // [AceFlags] -- ACE flags value. // [InheritFlags] -- ACE inherit flags value. // // Returns: Created ACE if successful. // NULL on error. // // Notes: None. // //---------------------------------------------------------------------------- PACCESS_ALLOWED_ACE CreateAccessAllowedAce( PSID pSid, ACCESS_MASK AccessMask, UCHAR AceFlags, UCHAR InheritFlags, DWORD * pStatus) { ULONG LengthSid = GetLengthSid(pSid); ULONG LengthACE = sizeof(ACE_HEADER) + sizeof(ACCESS_MASK) + LengthSid; PACCESS_ALLOWED_ACE Ace; Ace = (PACCESS_ALLOWED_ACE)LocalAlloc(LMEM_FIXED, LengthACE); if (Ace == NULL) { if (pStatus != NULL) *pStatus = ERROR_NOT_ENOUGH_MEMORY; schDebugOut((DEB_ERROR, "CreateAccessAllowedAce, ACE allocation failed\n")); return(NULL); } Ace->Header.AceType = ACCESS_ALLOWED_ACE_TYPE; Ace->Header.AceSize = (UCHAR)LengthACE; Ace->Header.AceFlags = AceFlags | InheritFlags; Ace->Mask = AccessMask; CopySid(LengthSid, (PSID)(&(Ace->SidStart)), pSid); if (pStatus != NULL) *pStatus = ERROR_SUCCESS; return(Ace); }