#include <security_cdsa_utilities/acl_process.h>
#include <security_utilities/endian.h>
#include <algorithm>
bool ProcessAclSubject::validates(const AclValidationContext &context) const
{
assert(select.uses(CSSM_ACL_MATCH_BITS));
Environment *env = context.environment<Environment>();
if (env == NULL) {
static Environment localEnvironment;
env = &localEnvironment;
}
if (select.uses(CSSM_ACL_MATCH_UID)) {
uid_t uid = env->getuid();
if (!(uid == select.uid || (select.uses(CSSM_ACL_MATCH_HONOR_ROOT) && uid == 0)))
return false;
}
if (select.uses(CSSM_ACL_MATCH_GID) && select.gid != env->getgid())
return false;
return true;
}
CssmList ProcessAclSubject::toList(Allocator &alloc) const
{
CssmData sData(memcpy(alloc.alloc<CSSM_ACL_PROCESS_SUBJECT_SELECTOR>(),
&select, sizeof(select)), sizeof(select));
return TypedList(alloc, CSSM_ACL_SUBJECT_TYPE_PROCESS,
new(alloc) ListElement(sData));
}
ProcessAclSubject *ProcessAclSubject::Maker::make(const TypedList &list) const
{
ListElement *selectorData;
crack(list, 1, &selectorData, CSSM_LIST_ELEMENT_DATUM);
AclProcessSubjectSelector selector;
selectorData->extract(selector);
if (selector.version != CSSM_ACL_PROCESS_SELECTOR_CURRENT_VERSION)
CssmError::throwMe(CSSM_ERRCODE_INVALID_ACL_SUBJECT_VALUE);
if (!selector.uses(CSSM_ACL_MATCH_BITS))
CssmError::throwMe(CSSM_ERRCODE_INVALID_ACL_SUBJECT_VALUE);
return new ProcessAclSubject(selector);
}
ProcessAclSubject *ProcessAclSubject::Maker::make(Version, Reader &pub, Reader &priv) const
{
AclProcessSubjectSelector selector; pub(selector);
n2hi(selector.version);
n2hi(selector.mask);
n2hi(selector.uid);
n2hi(selector.gid);
return new ProcessAclSubject(selector);
}
void ProcessAclSubject::exportBlob(Writer::Counter &pub, Writer::Counter &priv)
{
pub(select);
}
void ProcessAclSubject::exportBlob(Writer &pub, Writer &priv)
{
AclProcessSubjectSelector temp;
temp.version = h2n (select.version);
temp.mask = h2n (select.mask);
temp.uid = h2n (select.uid);
temp.gid = h2n (select.gid);
pub(temp);
}
uid_t ProcessAclSubject::Environment::getuid() const
{
return ::getuid();
}
gid_t ProcessAclSubject::Environment::getgid() const
{
return ::getgid();
}
#ifdef DEBUGDUMP
void ProcessAclSubject::debugDump() const
{
Debug::dump("Process ");
if (select.uses(CSSM_ACL_MATCH_UID)) {
Debug::dump("uid=%d", int(select.uid));
if (select.uses(CSSM_ACL_MATCH_HONOR_ROOT))
Debug::dump("+root");
}
if (select.uses(CSSM_ACL_MATCH_GID))
Debug::dump("gid=%d", int(select.gid));
}
#endif //DEBUGDUMP