void VerifyACL(char *file, Attributes a, Promise *pp) { if (!CheckACLSyntax(file, a.acl, pp)) { cfPS(cf_error, CF_INTERPT, "", pp, a, " !! Syntax error in access control list for \"%s\"", file); PromiseRef(cf_error, pp); return; } SetACLDefaults(file, &a.acl); // decide which ACL API to use switch (a.acl.acl_type) { case cfacl_notype: // fallthrough: acl_type defaults to generic case cfacl_generic: #if defined(__linux__) CheckPosixLinuxACL(file, a.acl, a, pp); #elif defined(__MINGW32__) Nova_CheckNtACL(file, a.acl, a, pp); #else CfOut(cf_inform, "", "!! ACLs are not yet supported on this system."); #endif break; case cfacl_posix: #if defined(__linux__) CheckPosixLinuxACL(file, a.acl, a, pp); #else CfOut(cf_inform, "", "!! Posix ACLs are not supported on this system"); #endif break; case cfacl_ntfs: #if defined(__MINGW32__) Nova_CheckNtACL(file, a.acl, a, pp); #else CfOut(cf_inform, "", "!! NTFS ACLs are not supported on this system"); #endif break; default: CfOut(cf_error, "", "!! Unknown ACL type - software error"); break; } }
void VerifyACL(EvalContext *ctx, char *file, Attributes a, Promise *pp) { if (!CheckACLSyntax(file, a.acl, pp)) { cfPS(ctx, OUTPUT_LEVEL_ERROR, PROMISE_RESULT_INTERRUPTED, "", pp, a, " !! Syntax error in access control list for \"%s\"", file); PromiseRef(OUTPUT_LEVEL_ERROR, pp); return; } SetACLDefaults(file, &a.acl); // decide which ACL API to use switch (a.acl.acl_type) { case ACL_TYPE_NONE: // fallthrough: acl_type defaults to generic case ACL_TYPE_GENERIC: #if defined(__linux__) CheckPosixLinuxACL(ctx, file, a.acl, a, pp); #elif defined(__MINGW32__) Nova_CheckNtACL(ctx, file, a.acl, a, pp); #else CfOut(OUTPUT_LEVEL_INFORM, "", "!! ACLs are not yet supported on this system."); #endif break; case ACL_TYPE_POSIX: #if defined(__linux__) CheckPosixLinuxACL(ctx, file, a.acl, a, pp); #else CfOut(OUTPUT_LEVEL_INFORM, "", "!! Posix ACLs are not supported on this system"); #endif break; case ACL_TYPE_NTFS_: #if defined(__MINGW32__) Nova_CheckNtACL(ctx, file, a.acl, a, pp); #else CfOut(OUTPUT_LEVEL_INFORM, "", "!! NTFS ACLs are not supported on this system"); #endif break; default: CfOut(OUTPUT_LEVEL_ERROR, "", "!! Unknown ACL type - software error"); break; } }
static int CheckACLSyntax(char *file, Acl acl, Promise *pp) { int valid = true; int deny_support = false; int mask_support = false; char *valid_ops = NULL; char *valid_nperms = NULL; Rlist *rp; // set unset fields to defautls SetACLDefaults(file, &acl); // find valid values for op switch (acl.acl_method) { case cfacl_overwrite: valid_ops = CF_VALID_OPS_METHOD_OVERWRITE; break; case cfacl_append: valid_ops = CF_VALID_OPS_METHOD_APPEND; break; default: // never executed: should be set to a default value by now break; } switch (acl.acl_type) { case cfacl_generic: // generic ACL type: cannot include native or deny-type permissions valid_nperms = ""; deny_support = false; mask_support = false; break; case cfacl_posix: valid_nperms = CF_VALID_NPERMS_POSIX; deny_support = false; // posix does not support deny-type permissions mask_support = true; // mask-ACE is allowed in POSIX break; case cfacl_ntfs: valid_nperms = CF_VALID_NPERMS_NTFS; deny_support = true; mask_support = false; break; default: // never executed: should be set to a default value by now break; } // check that acl_directory_inherit is set to a valid value if (!CheckDirectoryInherit(file, &acl, pp)) { return false; } for (rp = acl.acl_entries; rp != NULL; rp = rp->next) { valid = CheckACESyntax(ScalarValue(rp), valid_ops, valid_nperms, deny_support, mask_support, pp); if (!valid) // wrong syntax in this ace { CfOut(cf_error, "", "The ACE \"%s\" contains errors", ScalarValue(rp)); PromiseRef(cf_error, pp); break; } } for (rp = acl.acl_inherit_entries; rp != NULL; rp = rp->next) { valid = CheckACESyntax(rp->item, valid_ops, valid_nperms, deny_support, mask_support, pp); if (!valid) // wrong syntax in this ace { CfOut(cf_error, "", "The ACE \"%s\" contains errors", ScalarValue(rp)); PromiseRef(cf_error, pp); break; } } return valid; }
static int CheckACLSyntax(char *file, Acl acl, Promise *pp) { int valid = true; int deny_support = false; int mask_support = false; char *valid_ops = NULL; char *valid_nperms = NULL; Rlist *rp; // set unset fields to defautls SetACLDefaults(file, &acl); // find valid values for op switch (acl.acl_method) { case ACL_METHOD_OVERWRITE: valid_ops = CF_VALID_OPS_METHOD_OVERWRITE; break; case ACL_METHOD_APPEND: valid_ops = CF_VALID_OPS_METHOD_APPEND; break; default: // never executed: should be set to a default value by now break; } switch (acl.acl_type) { case ACL_TYPE_GENERIC: // generic ACL type: cannot include native or deny-type permissions valid_nperms = ""; deny_support = false; mask_support = false; break; case ACL_TYPE_POSIX: valid_nperms = CF_VALID_NPERMS_POSIX; deny_support = false; // posix does not support deny-type permissions mask_support = true; // mask-ACE is allowed in POSIX break; case ACL_TYPE_NTFS_: valid_nperms = CF_VALID_NPERMS_NTFS; deny_support = true; mask_support = false; break; default: // never executed: should be set to a default value by now break; } // check that acl_default is set to a valid value if (!CheckAclDefault(file, &acl, pp)) { return false; } for (rp = acl.acl_entries; rp != NULL; rp = rp->next) { valid = CheckACESyntax(RlistScalarValue(rp), valid_ops, valid_nperms, deny_support, mask_support, pp); if (!valid) // wrong syntax in this ace { Log(LOG_LEVEL_ERR, "The ACE '%s' contains errors", RlistScalarValue(rp)); PromiseRef(LOG_LEVEL_ERR, pp); break; } } for (rp = acl.acl_default_entries; rp != NULL; rp = rp->next) { valid = CheckACESyntax(rp->item, valid_ops, valid_nperms, deny_support, mask_support, pp); if (!valid) // wrong syntax in this ace { Log(LOG_LEVEL_ERR, "The ACE '%s' contains errors", RlistScalarValue(rp)); PromiseRef(LOG_LEVEL_ERR, pp); break; } } return valid; }
DWORD COxtSecurityHelper::AddPrincipalToNamedSecurityDescriptor(LPCTSTR tszPermissionName, LPCTSTR tszPrincipal, DWORD dwAccessMask, DWORD dwSDType) { DWORD dwReturnValue = ERROR_SUCCESS; SECURITY_DESCRIPTOR *pSD = NULL; SECURITY_DESCRIPTOR *psdSelfRelative = NULL; SECURITY_DESCRIPTOR *psdAbsolute = NULL; DWORD cbSecurityDesc = 0; BOOL bPresent = FALSE; BOOL bDefaultDACL = FALSE; PACL pDacl = NULL; BOOL bNewSD = FALSE; do { // Get security descriptor from registry or create a new one dwReturnValue = GetSecurityDescripterByName(tszPermissionName, &pSD, &bNewSD); if (dwReturnValue != ERROR_SUCCESS) break; if (!::GetSecurityDescriptorDacl(pSD, &bPresent, &pDacl, &bDefaultDACL)) { dwReturnValue = ::GetLastError(); break; } if (bNewSD) { dwReturnValue = SetACLDefaults(&pDacl, dwSDType); if (dwReturnValue != ERROR_SUCCESS) break; } // Add the Principal that the caller wants added dwReturnValue = AddAccessDeniedACEToACL(&pDacl, dwAccessMask, tszPrincipal); if (dwReturnValue != ERROR_SUCCESS) break; // Make the security descriptor absolute if it isn't new if (!bNewSD) { dwReturnValue = MakeAbsoluteSecurityDescriptor((PSECURITY_DESCRIPTOR)pSD, (PSECURITY_DESCRIPTOR *)&psdAbsolute); if (dwReturnValue != ERROR_SUCCESS) break; } else psdAbsolute = pSD; // Set the discretionary ACL on the security descriptor if (!::SetSecurityDescriptorDacl(psdAbsolute, TRUE, pDacl, FALSE)) { dwReturnValue = ::GetLastError(); break; } // Now ensure consistency of the SD dwReturnValue = CanonicalizeSecurityDescriptor(psdAbsolute); if (dwReturnValue != ERROR_SUCCESS) break; // 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 == NULL) { dwReturnValue = ERROR_OUTOFMEMORY; break; } if (!::MakeSelfRelativeSD(psdAbsolute, psdSelfRelative, &cbSecurityDesc)) { dwReturnValue = GetLastError(); break; } // Store the security descriptor in the registry dwReturnValue = SetSecurityDescriptorByName(tszPermissionName, psdSelfRelative); } while (false); if (pSD != NULL) free(pSD); if (psdSelfRelative != NULL) free(psdSelfRelative); if ((psdAbsolute != NULL)&&(pSD != psdAbsolute)) free(psdAbsolute); return dwReturnValue; }