1/* 2 * Copyright (c) 2000-2004,2006,2011,2014 Apple Inc. All Rights Reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. Please obtain a copy of the License at 10 * http://www.opensource.apple.com/apsl/ and read it before using this 11 * file. 12 * 13 * The Original Code and all software distributed under the License are 14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 * Please see the License for the specific language governing rights and 19 * limitations under the License. 20 * 21 * @APPLE_LICENSE_HEADER_END@ 22 */ 23 24 25// 26// acl_process - Process-attribute ACL subject type. 27// 28#include <security_cdsa_utilities/acl_process.h> 29#include <security_utilities/endian.h> 30#include <algorithm> 31 32 33// 34// Validate a credential set against this subject. 35// No credential is required for this match. 36// 37bool ProcessAclSubject::validate(const AclValidationContext &context) const 38{ 39 // reality check (internal structure was validated when created) 40 assert(select.uses(CSSM_ACL_MATCH_BITS)); 41 42 // access the environment 43 Environment *env = context.environment<Environment>(); 44 if (env == NULL) { 45 static Environment localEnvironment; 46 env = &localEnvironment; 47 } 48 49 // match uid 50 if (select.uses(CSSM_ACL_MATCH_UID)) { 51 uid_t uid = env->getuid(); 52 if (!(uid == select.uid || (select.uses(CSSM_ACL_MATCH_HONOR_ROOT) && uid == 0))) 53 return false; 54 } 55 56 // match gid 57 if (select.uses(CSSM_ACL_MATCH_GID) && select.gid != env->getgid()) 58 return false; 59 60 return true; 61} 62 63 64// 65// Make a copy of this subject in CSSM_LIST form 66// 67CssmList ProcessAclSubject::toList(Allocator &alloc) const 68{ 69 // all associated data is public (no secrets) 70 //@@@ ownership of selector data is murky; revisit after leak-plugging pass 71 CssmData sData(memcpy(alloc.alloc<CSSM_ACL_PROCESS_SUBJECT_SELECTOR>(), 72 &select, sizeof(select)), sizeof(select)); 73 return TypedList(alloc, CSSM_ACL_SUBJECT_TYPE_PROCESS, 74 new(alloc) ListElement(sData)); 75} 76 77 78// 79// Create a ProcessAclSubject 80// 81ProcessAclSubject *ProcessAclSubject::Maker::make(const TypedList &list) const 82{ 83 // crack input apart 84 ListElement *selectorData; 85 crack(list, 1, &selectorData, CSSM_LIST_ELEMENT_DATUM); 86 AclProcessSubjectSelector selector; 87 selectorData->extract(selector); 88 89 // validate input 90 if (selector.version != CSSM_ACL_PROCESS_SELECTOR_CURRENT_VERSION) 91 CssmError::throwMe(CSSM_ERRCODE_INVALID_ACL_SUBJECT_VALUE); 92 if (!selector.uses(CSSM_ACL_MATCH_BITS)) 93 CssmError::throwMe(CSSM_ERRCODE_INVALID_ACL_SUBJECT_VALUE); 94 95 // okay 96 return new ProcessAclSubject(selector); 97} 98 99ProcessAclSubject *ProcessAclSubject::Maker::make(Version, Reader &pub, Reader &priv) const 100{ 101 AclProcessSubjectSelector selector; pub(selector); 102 n2hi(selector.version); 103 n2hi(selector.mask); 104 n2hi(selector.uid); 105 n2hi(selector.gid); 106 return new ProcessAclSubject(selector); 107} 108 109 110// 111// Export the subject to a memory blob 112// 113void ProcessAclSubject::exportBlob(Writer::Counter &pub, Writer::Counter &priv) 114{ 115 pub(select); 116} 117 118void ProcessAclSubject::exportBlob(Writer &pub, Writer &priv) 119{ 120 AclProcessSubjectSelector temp; 121 temp.version = h2n (select.version); 122 temp.mask = h2n (select.mask); 123 temp.uid = h2n (select.uid); 124 temp.gid = h2n (select.gid); 125 pub(temp); 126} 127 128 129// 130// Implement the default methods of a ProcessEnvironment 131// 132uid_t ProcessAclSubject::Environment::getuid() const 133{ 134 return ::getuid(); 135} 136 137gid_t ProcessAclSubject::Environment::getgid() const 138{ 139 return ::getgid(); 140} 141 142 143#ifdef DEBUGDUMP 144 145void ProcessAclSubject::debugDump() const 146{ 147 Debug::dump("Process "); 148 if (select.uses(CSSM_ACL_MATCH_UID)) { 149 Debug::dump("uid=%d", int(select.uid)); 150 if (select.uses(CSSM_ACL_MATCH_HONOR_ROOT)) 151 Debug::dump("+root"); 152 } 153 if (select.uses(CSSM_ACL_MATCH_GID)) 154 Debug::dump("gid=%d", int(select.gid)); 155} 156 157#endif //DEBUGDUMP 158