source: branches/samba-3.0/source/rpc_parse/parse_sec.c

Last change on this file was 39, checked in by Paul Smedley, 18 years ago

Upgrade source to 3.0.25a

File size: 10.5 KB
Line 
1/*
2 * Unix SMB/Netbios implementation.
3 * Version 1.9.
4 * RPC Pipe client / server routines
5 * Copyright (C) Andrew Tridgell 1992-1998,
6 * Copyright (C) Jeremy R. Allison 1995-2005.
7 * Copyright (C) Luke Kenneth Casson Leighton 1996-1998,
8 * Copyright (C) Paul Ashton 1997-1998.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 */
24
25#include "includes.h"
26
27#undef DBGC_CLASS
28#define DBGC_CLASS DBGC_RPC_PARSE
29
30/*******************************************************************
31 Reads or writes a SEC_ACE structure.
32********************************************************************/
33
34BOOL sec_io_ace(const char *desc, SEC_ACE *psa, prs_struct *ps, int depth)
35{
36 uint32 old_offset;
37 uint32 offset_ace_size;
38
39 if (psa == NULL)
40 return False;
41
42 prs_debug(ps, depth, desc, "sec_io_ace");
43 depth++;
44
45 old_offset = prs_offset(ps);
46
47 if(!prs_uint8("type ", ps, depth, &psa->type))
48 return False;
49
50 if(!prs_uint8("flags", ps, depth, &psa->flags))
51 return False;
52
53 if(!prs_uint16_pre("size ", ps, depth, &psa->size, &offset_ace_size))
54 return False;
55
56 if (!prs_uint32("access_mask", ps, depth, &psa->access_mask))
57 return False;
58
59 /* check whether object access is present */
60 if (!sec_ace_object(psa->type)) {
61 if (!smb_io_dom_sid("trustee ", &psa->trustee , ps, depth))
62 return False;
63 } else {
64 if (!prs_uint32("obj_flags", ps, depth, &psa->obj_flags))
65 return False;
66
67 if (psa->obj_flags & SEC_ACE_OBJECT_PRESENT)
68 if (!smb_io_uuid("obj_guid", &psa->obj_guid, ps,depth))
69 return False;
70
71 if (psa->obj_flags & SEC_ACE_OBJECT_INHERITED_PRESENT)
72 if (!smb_io_uuid("inh_guid", &psa->inh_guid, ps,depth))
73 return False;
74
75 if(!smb_io_dom_sid("trustee ", &psa->trustee , ps, depth))
76 return False;
77 }
78
79 /* Theorectically an ACE can have a size greater than the
80 sum of its components. When marshalling, pad with extra null bytes up to the
81 correct size. */
82
83 if (MARSHALLING(ps) && (psa->size > prs_offset(ps) - old_offset)) {
84 uint32 extra_len = psa->size - (prs_offset(ps) - old_offset);
85 uint32 i;
86 uint8 c = 0;
87
88 for (i = 0; i < extra_len; i++) {
89 if (!prs_uint8("ace extra space", ps, depth, &c))
90 return False;
91 }
92 }
93
94 if(!prs_uint16_post("size ", ps, depth, &psa->size, offset_ace_size, old_offset))
95 return False;
96
97 return True;
98}
99
100/*******************************************************************
101 Reads or writes a SEC_ACL structure.
102
103 First of the xx_io_xx functions that allocates its data structures
104 for you as it reads them.
105********************************************************************/
106
107BOOL sec_io_acl(const char *desc, SEC_ACL **ppsa, prs_struct *ps, int depth)
108{
109 unsigned int i;
110 uint32 old_offset;
111 uint32 offset_acl_size;
112 SEC_ACL *psa;
113
114 /*
115 * Note that the size is always a multiple of 4 bytes due to the
116 * nature of the data structure. Therefore the prs_align() calls
117 * have been removed as they through us off when doing two-layer
118 * marshalling such as in the printing code (RPC_BUFFER). --jerry
119 */
120
121 if (ppsa == NULL)
122 return False;
123
124 psa = *ppsa;
125
126 if(UNMARSHALLING(ps) && psa == NULL) {
127 /*
128 * This is a read and we must allocate the stuct to read into.
129 */
130 if((psa = PRS_ALLOC_MEM(ps, SEC_ACL, 1)) == NULL)
131 return False;
132 *ppsa = psa;
133 }
134
135 prs_debug(ps, depth, desc, "sec_io_acl");
136 depth++;
137
138 old_offset = prs_offset(ps);
139
140 if(!prs_uint16("revision", ps, depth, &psa->revision))
141 return False;
142
143 if(!prs_uint16_pre("size ", ps, depth, &psa->size, &offset_acl_size))
144 return False;
145
146 if(!prs_uint32("num_aces ", ps, depth, &psa->num_aces))
147 return False;
148
149 if (UNMARSHALLING(ps)) {
150 if (psa->num_aces) {
151 if((psa->aces = PRS_ALLOC_MEM(ps, SEC_ACE, psa->num_aces)) == NULL)
152 return False;
153 } else {
154 psa->aces = NULL;
155 }
156 }
157
158 for (i = 0; i < psa->num_aces; i++) {
159 fstring tmp;
160 slprintf(tmp, sizeof(tmp)-1, "ace_list[%02d]: ", i);
161 if(!sec_io_ace(tmp, &psa->aces[i], ps, depth))
162 return False;
163 }
164
165 /* Theorectically an ACL can have a size greater than the
166 sum of its components. When marshalling, pad with extra null bytes up to the
167 correct size. */
168
169 if (MARSHALLING(ps) && (psa->size > prs_offset(ps) - old_offset)) {
170 uint32 extra_len = psa->size - (prs_offset(ps) - old_offset);
171 uint8 c = 0;
172
173 for (i = 0; i < extra_len; i++) {
174 if (!prs_uint8("acl extra space", ps, depth, &c))
175 return False;
176 }
177 }
178
179 if(!prs_uint16_post("size ", ps, depth, &psa->size, offset_acl_size, old_offset))
180 return False;
181
182 return True;
183}
184
185/*******************************************************************
186 Reads or writes a SEC_DESC structure.
187 If reading and the *ppsd = NULL, allocates the structure.
188********************************************************************/
189
190BOOL sec_io_desc(const char *desc, SEC_DESC **ppsd, prs_struct *ps, int depth)
191{
192 uint32 old_offset;
193 uint32 max_offset = 0; /* after we're done, move offset to end */
194 uint32 tmp_offset = 0;
195
196 SEC_DESC *psd;
197
198 if (ppsd == NULL)
199 return False;
200
201 psd = *ppsd;
202
203 if (psd == NULL) {
204 if(UNMARSHALLING(ps)) {
205 if((psd = PRS_ALLOC_MEM(ps,SEC_DESC,1)) == NULL)
206 return False;
207 *ppsd = psd;
208 } else {
209 /* Marshalling - just ignore. */
210 return True;
211 }
212 }
213
214 prs_debug(ps, depth, desc, "sec_io_desc");
215 depth++;
216
217 /* start of security descriptor stored for back-calc offset purposes */
218 old_offset = prs_offset(ps);
219
220 if(!prs_uint16("revision ", ps, depth, &psd->revision))
221 return False;
222
223 if(!prs_uint16("type ", ps, depth, &psd->type))
224 return False;
225
226 if (MARSHALLING(ps)) {
227 uint32 offset = SEC_DESC_HEADER_SIZE;
228
229 /*
230 * Work out the offsets here, as we write it out.
231 */
232
233 if (psd->sacl != NULL) {
234 psd->off_sacl = offset;
235 offset += psd->sacl->size;
236 } else {
237 psd->off_sacl = 0;
238 }
239
240 if (psd->dacl != NULL) {
241 psd->off_dacl = offset;
242 offset += psd->dacl->size;
243 } else {
244 psd->off_dacl = 0;
245 }
246
247 if (psd->owner_sid != NULL) {
248 psd->off_owner_sid = offset;
249 offset += sid_size(psd->owner_sid);
250 } else {
251 psd->off_owner_sid = 0;
252 }
253
254 if (psd->group_sid != NULL) {
255 psd->off_grp_sid = offset;
256 offset += sid_size(psd->group_sid);
257 } else {
258 psd->off_grp_sid = 0;
259 }
260 }
261
262 if(!prs_uint32("off_owner_sid", ps, depth, &psd->off_owner_sid))
263 return False;
264
265 if(!prs_uint32("off_grp_sid ", ps, depth, &psd->off_grp_sid))
266 return False;
267
268 if(!prs_uint32("off_sacl ", ps, depth, &psd->off_sacl))
269 return False;
270
271 if(!prs_uint32("off_dacl ", ps, depth, &psd->off_dacl))
272 return False;
273
274 max_offset = MAX(max_offset, prs_offset(ps));
275
276 if (psd->off_owner_sid != 0) {
277
278 tmp_offset = prs_offset(ps);
279 if(!prs_set_offset(ps, old_offset + psd->off_owner_sid))
280 return False;
281
282 if (UNMARSHALLING(ps)) {
283 /* reading */
284 if((psd->owner_sid = PRS_ALLOC_MEM(ps,DOM_SID,1)) == NULL)
285 return False;
286 }
287
288 if(!smb_io_dom_sid("owner_sid ", psd->owner_sid , ps, depth))
289 return False;
290
291 max_offset = MAX(max_offset, prs_offset(ps));
292
293 if (!prs_set_offset(ps,tmp_offset))
294 return False;
295 }
296
297 if (psd->off_grp_sid != 0) {
298
299 tmp_offset = prs_offset(ps);
300 if(!prs_set_offset(ps, old_offset + psd->off_grp_sid))
301 return False;
302
303 if (UNMARSHALLING(ps)) {
304 /* reading */
305 if((psd->group_sid = PRS_ALLOC_MEM(ps,DOM_SID,1)) == NULL)
306 return False;
307 }
308
309 if(!smb_io_dom_sid("group_sid", psd->group_sid, ps, depth))
310 return False;
311
312 max_offset = MAX(max_offset, prs_offset(ps));
313
314 if (!prs_set_offset(ps,tmp_offset))
315 return False;
316 }
317
318 if ((psd->type & SEC_DESC_SACL_PRESENT) && psd->off_sacl) {
319 tmp_offset = prs_offset(ps);
320 if(!prs_set_offset(ps, old_offset + psd->off_sacl))
321 return False;
322 if(!sec_io_acl("sacl", &psd->sacl, ps, depth))
323 return False;
324 max_offset = MAX(max_offset, prs_offset(ps));
325 if (!prs_set_offset(ps,tmp_offset))
326 return False;
327 }
328
329 if ((psd->type & SEC_DESC_DACL_PRESENT) && psd->off_dacl != 0) {
330 tmp_offset = prs_offset(ps);
331 if(!prs_set_offset(ps, old_offset + psd->off_dacl))
332 return False;
333 if(!sec_io_acl("dacl", &psd->dacl, ps, depth))
334 return False;
335 max_offset = MAX(max_offset, prs_offset(ps));
336 if (!prs_set_offset(ps,tmp_offset))
337 return False;
338 }
339
340 if(!prs_set_offset(ps, max_offset))
341 return False;
342
343 return True;
344}
345
346/*******************************************************************
347 Reads or writes a SEC_DESC_BUF structure.
348********************************************************************/
349
350BOOL sec_io_desc_buf(const char *desc, SEC_DESC_BUF **ppsdb, prs_struct *ps, int depth)
351{
352 uint32 off_len;
353 uint32 off_max_len;
354 uint32 old_offset;
355 uint32 size;
356 SEC_DESC_BUF *psdb;
357
358 if (ppsdb == NULL)
359 return False;
360
361 psdb = *ppsdb;
362
363 if (UNMARSHALLING(ps) && psdb == NULL) {
364 if((psdb = PRS_ALLOC_MEM(ps,SEC_DESC_BUF,1)) == NULL)
365 return False;
366 *ppsdb = psdb;
367 }
368
369 prs_debug(ps, depth, desc, "sec_io_desc_buf");
370 depth++;
371
372 if(!prs_align(ps))
373 return False;
374
375 if(!prs_uint32_pre("max_len", ps, depth, &psdb->max_len, &off_max_len))
376 return False;
377
378 if(!prs_uint32 ("ptr ", ps, depth, &psdb->ptr))
379 return False;
380
381 if(!prs_uint32_pre("len ", ps, depth, &psdb->len, &off_len))
382 return False;
383
384 old_offset = prs_offset(ps);
385
386 /* reading, length is non-zero; writing, descriptor is non-NULL */
387 if ((UNMARSHALLING(ps) && psdb->len != 0) || (MARSHALLING(ps) && psdb->sec != NULL)) {
388 if(!sec_io_desc("sec ", &psdb->sec, ps, depth))
389 return False;
390 }
391
392 if(!prs_align(ps))
393 return False;
394
395 size = prs_offset(ps) - old_offset;
396 if(!prs_uint32_post("max_len", ps, depth, &psdb->max_len, off_max_len, size == 0 ? psdb->max_len : size))
397 return False;
398
399 if(!prs_uint32_post("len ", ps, depth, &psdb->len, off_len, size))
400 return False;
401
402 return True;
403}
Note: See TracBrowser for help on using the repository browser.