]> git.saurik.com Git - apple/securityd.git/blob - src/transwalkers.cpp
securityd-32597.tar.gz
[apple/securityd.git] / src / transwalkers.cpp
1 /*
2 * Copyright (c) 2003-2004 Apple Computer, 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 // transwalkers - server side transition data walking support
27 //
28 // These are data walker operators for securely marshaling and unmarshaling
29 // data structures across IPC. They are also in charge of fixing byte order
30 // inconsistencies between server and clients.
31 //
32 #include <transwalkers.h>
33
34
35 using LowLevelMemoryUtilities::increment;
36 using LowLevelMemoryUtilities::difference;
37
38
39 bool flipClient()
40 {
41 return Server::process().byteFlipped();
42 }
43
44
45 //
46 // CheckingRelocateWalkers
47 //
48 CheckingReconstituteWalker::CheckingReconstituteWalker(void *ptr, void *base, size_t size, bool flip)
49 : mBase(base), mFlip(flip)
50 {
51 if (mFlip)
52 Flippers::flip(mBase); // came in reversed; fix for base use
53 mOffset = difference(ptr, mBase);
54 mLimit = increment(mBase, size);
55 }
56
57
58 //
59 // Relocation support
60 //
61 void relocate(Context &context, void *base, Context::Attr *attrs, uint32 attrSize)
62 {
63 flip(context);
64 CheckingReconstituteWalker relocator(attrs, base, attrSize, flipClient());
65 context.ContextAttributes = attrs; // fix context->attr vector link
66 for (uint32 n = 0; n < context.attributesInUse(); n++)
67 walk(relocator, context[n]);
68 }
69
70
71 //
72 // Outbound flipping support
73 //
74 FlipWalker::~FlipWalker()
75 {
76 for (set<Flipper>::const_iterator it = mFlips.begin(); it != mFlips.end(); it++)
77 delete it->impl;
78 }
79
80 void FlipWalker::doFlips(bool active)
81 {
82 if (active) {
83 secdebug("flipwalkers", "starting outbound flips");
84 for (set<Flipper>::const_iterator it = mFlips.begin(); it != mFlips.end(); it++)
85 it->impl->flip();
86 secdebug("flipwalkers", "outbound flips done");
87 }
88 }
89
90
91 //
92 // Choose a Database from a choice of two sources, giving preference
93 // to persistent stores and to earlier sources.
94 //
95 Database *pickDb(Database *db1, Database *db2)
96 {
97 // persistent db1 always wins
98 if (db1 && !db1->transient())
99 return db1;
100
101 // persistent db2 is next choice
102 if (db2 && !db2->transient())
103 return db2;
104
105 // pick any existing transient database
106 if (db1)
107 return db1;
108 if (db2)
109 return db2;
110
111 // none at all. use the canonical transient store
112 return Server::optionalDatabase(noDb);
113 }
114
115
116
117 void fixDbAttributes (CssmDbAttributeData &data)
118 {
119 /*
120 NOTE TO FUTURE MAINTAINERS OF THIS CODE:
121
122 This code is called by two different routines; the relocation walker on the input attributes, and flips
123 on the output attributtes. This is bad, because the relocation walker flips the Info data structure,
124 and flips does not. We could fix this in flips, but flips is a template and does different things
125 depending on what its parameters are. As a result, the best place to do this is here.
126 */
127
128 // pull this data out first, so that it is unperverted once the flip occurs
129 unsigned limit = data.size ();
130 unsigned format = data.format ();
131 CssmData* values = data.values ();
132
133 // flip if it is safe to do so
134 if (format > CSSM_DB_ATTRIBUTE_FORMAT_COMPLEX) // is the format screwed up?
135 {
136 flip (data.info ());
137 limit = data.size ();
138 format = data.format ();
139 values = data.values ();
140 }
141
142 unsigned i;
143
144 for (i = 0; i < limit; ++i)
145 {
146 switch (format)
147 {
148 case CSSM_DB_ATTRIBUTE_FORMAT_UINT32:
149 Flippers::flip(*(uint32*) values[i].data ());
150 break;
151
152 case CSSM_DB_ATTRIBUTE_FORMAT_MULTI_UINT32:
153 {
154 CssmData& d = values[i];
155 int numValues = d.length() / sizeof (UInt32);
156 int j;
157 UInt32* v = (UInt32*) d.data();
158 for (j = 0; j < numValues; ++j)
159 {
160 Flippers::flip (v[j]);
161 }
162 }
163 break;
164 }
165 }
166 }
167
168
169
170 void fixDbAttributes (CssmQuery &query)
171 {
172 unsigned i;
173 unsigned numItems = query.size ();
174 for (i = 0; i < numItems; ++i)
175 {
176 fixDbAttributes(query.predicates()[i].attribute());
177 }
178 }
179
180
181
182 void fixDbAttributes (CssmDbRecordAttributeData &data)
183 {
184 unsigned i;
185 unsigned numItems = data.size ();
186 for (i = 0; i < numItems; ++i)
187 {
188 fixDbAttributes(data.attributes()[i]);
189 }
190 }