]> git.saurik.com Git - apple/security.git/blob - OSX/libsecurity_cdsa_utilities/lib/acl_process.cpp
Security-59754.41.1.tar.gz
[apple/security.git] / OSX / libsecurity_cdsa_utilities / lib / acl_process.cpp
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 //
37 bool ProcessAclSubject::validates(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 //
67 CssmList 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 //
81 ProcessAclSubject *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
96 // okay
97 return new ProcessAclSubject(selector);
98 }
99
100 ProcessAclSubject *ProcessAclSubject::Maker::make(Version, Reader &pub, Reader &priv) const
101 {
102 AclProcessSubjectSelector selector; pub(selector);
103 n2hi(selector.version);
104 n2hi(selector.mask);
105 n2hi(selector.uid);
106 n2hi(selector.gid);
107 return new ProcessAclSubject(selector);
108 }
109
110
111 //
112 // Export the subject to a memory blob
113 //
114 void ProcessAclSubject::exportBlob(Writer::Counter &pub, Writer::Counter &priv)
115 {
116 pub(select);
117 }
118
119 void ProcessAclSubject::exportBlob(Writer &pub, Writer &priv)
120 {
121 AclProcessSubjectSelector temp;
122 temp.version = h2n (select.version);
123 temp.mask = h2n (select.mask);
124 temp.uid = h2n (select.uid);
125 temp.gid = h2n (select.gid);
126 pub(temp);
127 }
128
129
130 //
131 // Implement the default methods of a ProcessEnvironment
132 //
133 uid_t ProcessAclSubject::Environment::getuid() const
134 {
135 return ::getuid();
136 }
137
138 gid_t ProcessAclSubject::Environment::getgid() const
139 {
140 return ::getgid();
141 }
142
143
144 #ifdef DEBUGDUMP
145
146 void ProcessAclSubject::debugDump() const
147 {
148 Debug::dump("Process ");
149 if (select.uses(CSSM_ACL_MATCH_UID)) {
150 Debug::dump("uid=%d", int(select.uid));
151 if (select.uses(CSSM_ACL_MATCH_HONOR_ROOT))
152 Debug::dump("+root");
153 }
154 if (select.uses(CSSM_ACL_MATCH_GID))
155 Debug::dump("gid=%d", int(select.gid));
156 }
157
158 #endif //DEBUGDUMP