]> git.saurik.com Git - apple/securityd.git/blob - src/structure.h
f5b61bf6b3591e72a423936216bb88ed510f3bce
[apple/securityd.git] / src / structure.h
1 /*
2 * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
7 *
8 * This file contains Original Code and/or Modifications of Original Code
9 * as defined in and that are subject to the Apple Public Source License
10 * Version 2.0 (the 'License'). You may not use this file except in
11 * compliance with the License. Please obtain a copy of the License at
12 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * file.
14 *
15 * The Original Code and all software distributed under the License are
16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20 * Please see the License for the specific language governing rights and
21 * limitations under the License.
22 *
23 * @APPLE_LICENSE_HEADER_END@
24 */
25
26
27 //
28 // structure - structural framework for securityd objects
29 //
30 #ifndef _H_STRUCTURE
31 #define _H_STRUCTURE
32
33 #include "securityserver.h"
34 #include <security_utilities/refcount.h>
35 #include <security_cdsa_utilities/handleobject.h>
36
37
38 //
39 // Track a per-process real world object
40 //
41 template <class Base, class Glob> class Node;
42 class PerConnection;
43 class PerProcess;
44 class PerSession;
45 class PerGlobal;
46
47
48 //
49 // A generic core node of the object mesh.
50 // Repeat after me: "Everything that matters is a Node."
51 //
52 // This contains the mesh links (as smart pointers to NodeCores).
53 // The 'parent' is the next-more-global related object in the mesh, if any;
54 // nodes with the same parent "belong together" at the more global layer.
55 // For example, processes have their sessions as parents.
56 // The 'referent' is an object at the *same* globality layer that controls
57 // the lifetime of this node. For example, a Database has its Process as
58 // its referent.
59 // Both parent and referent are optional (can be NULL).
60 // The references set is a partial referent back-link. All NodeCores listed
61 // in a node's References have this node as a referent, but the set is
62 // selective (not necessarily complete). The References set propagates the
63 // 'kill' operation up the referents chain; thus being included in a node's
64 // References means that a kill() on the referent will (recursively) kill
65 // all references, too.
66 //
67 // Do not inherit directly from NodeCore; use Node<> (below).
68 //
69 class NodeCore : public RefCount, public Mutex {
70 template <class Base, class Glob> friend class Node;
71 public:
72 #if !defined(DEBUGDUMP) // (see below if DEBUGDUMP)
73 NodeCore() : Mutex(Mutex::recursive) { }
74 #endif
75 virtual ~NodeCore();
76
77 bool hasParent() const { return mParent; }
78 bool hasReferent() const { return mReferent; }
79
80 // reference set operations
81 template <class Sub>
82 void allReferences(void (Sub::*func)());
83 template <class Sub, class Value>
84 Sub *findFirst(Value (Sub::*func)() const, Value compare);
85 void clearReferences();
86
87 virtual void kill(); // always invoke NodeCore's in your override
88
89 // for STL ordering (so we can have sets of RefPointers of NodeCores)
90 bool operator < (const NodeCore &other) const
91 { return this < &other; }
92
93 private:
94 RefPointer<NodeCore> mParent;
95 RefPointer<NodeCore> mReferent;
96 typedef set<RefPointer<NodeCore> > ReferenceSet;
97 ReferenceSet mReferences;
98
99 #if defined(DEBUGDUMP)
100 public: // dump support
101 NodeCore(); // dump-only constructor (registers node)
102
103 virtual void dumpNode(); // node description (partial line)
104 virtual void dump(); // dumpNode() + references + NL
105 static void dumpAll(); // dump all nodes
106
107 static Mutex mCoreLock; // lock for mCoreNodes
108 static set<NodeCore *> mCoreNodes; // (debug) set of all known nodes
109 #endif //DEBUGDUMP
110 };
111
112
113 template <class Sub>
114 void NodeCore::allReferences(void (Sub::*func)())
115 {
116 StLock<Mutex> _(*this);
117 for (ReferenceSet::const_iterator it = mReferences.begin(); it != mReferences.end(); it++)
118 if (Sub *sub = dynamic_cast<Sub *>(it->get()))
119 (sub->*func)();
120 }
121
122 template <class Sub, class Value>
123 Sub *NodeCore::findFirst(Value (Sub::*func)() const, Value compare)
124 {
125 StLock<Mutex> _(*this);
126 for (ReferenceSet::const_iterator it = mReferences.begin(); it != mReferences.end(); it++)
127 if (Sub *sub = dynamic_cast<Sub *>(it->get()))
128 if ((sub->*func)() == compare)
129 return sub;
130 return NULL;
131 }
132
133
134 //
135 // A typed node of the object mesh.
136 // This adds type-safe accessors and modifiers to NodeCore.
137 //
138 template <class Base, class Glob>
139 class Node : public NodeCore {
140 protected:
141 void parent(Glob &p)
142 { StLock<Mutex> _(*this); mParent = &p; }
143
144 virtual void referent(Base &r)
145 { StLock<Mutex> _(*this); mReferent = &r; }
146
147 void clearReferent()
148 {
149 StLock<Mutex> _(*this);
150 mReferent = NULL;
151 }
152
153 public:
154 template <class T>
155 T& parent() const
156 { assert(mParent); return safer_cast<T &>(*mParent); }
157
158 template <class T>
159 T& referent() const
160 { assert(mReferent); return safer_cast<T &>(*mReferent); }
161
162 public:
163 void addReference(Base &p)
164 { StLock<Mutex> _(*this); assert(p.mReferent == this); mReferences.insert(&p); }
165 void removeReference(Base &p) { StLock<Mutex> _(*this); mReferences.erase(&p); }
166 };
167
168
169 //
170 // Connection (client thread) layer nodes
171 //
172 class PerConnection : public Node<PerConnection, PerProcess> {
173 public:
174 };
175
176
177 //
178 // Process (client process) layer nodes
179 //
180 class PerProcess : public HandleObject, public Node<PerProcess, PerSession> {
181 public:
182 };
183
184
185 //
186 // Session (client-side session) layer nodes
187 //
188 class PerSession : public Node<PerSession, PerGlobal> {
189 public:
190 };
191
192
193 //
194 // Global (per-system) layer nodes
195 //
196 class PerGlobal : public Node<PerGlobal, PerGlobal> {
197 public:
198 };
199
200
201 //
202 // A map from mach port names to (refcounted) pointers-to-somethings
203 //
204 template <class Node>
205 class PortMap : public Mutex, public std::map<Port, RefPointer<Node> > {
206 typedef std::map<Port, RefPointer<Node> > _Map;
207 public:
208 bool contains(mach_port_t port) const { return find(port) != end(); }
209 Node *getOpt(mach_port_t port) const
210 {
211 typename _Map::const_iterator it = find(port);
212 return (it == end()) ? NULL : it->second;
213 }
214
215 Node *get(mach_port_t port) const
216 {
217 typename _Map::const_iterator it = find(port);
218 assert(it != end());
219 return it->second;
220 }
221
222 Node *get(mach_port_t port, OSStatus error) const
223 {
224 typename _Map::const_iterator it = find(port);
225 if (it == end())
226 MacOSError::throwMe(error);
227 return it->second;
228 }
229
230 void dump();
231 };
232
233 template <class Node>
234 void PortMap<Node>::dump()
235 {
236 for (typename _Map::const_iterator it = begin(); it != end(); it++)
237 it->second->dump();
238 }
239
240
241 #endif //_H_STRUCTURE