[GLUE] Rsync SAMBA_3_0 SVN r25598 in order to create the v3-0-test branch.
[Samba.git] / source / rpc_parse / parse_sec.c
blob15c6d7f16579ae36477d45cff781e3eb999ae8af
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.
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.
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.
25 #include "includes.h"
27 #undef DBGC_CLASS
28 #define DBGC_CLASS DBGC_RPC_PARSE
30 /*******************************************************************
31 Reads or writes a SEC_ACE structure.
32 ********************************************************************/
34 BOOL sec_io_ace(const char *desc, SEC_ACE *psa, prs_struct *ps, int depth)
36 uint32 old_offset;
37 uint32 offset_ace_size;
39 if (psa == NULL)
40 return False;
42 prs_debug(ps, depth, desc, "sec_io_ace");
43 depth++;
45 old_offset = prs_offset(ps);
47 if(!prs_uint8("type ", ps, depth, &psa->type))
48 return False;
50 if(!prs_uint8("flags", ps, depth, &psa->flags))
51 return False;
53 if(!prs_uint16_pre("size ", ps, depth, &psa->size, &offset_ace_size))
54 return False;
56 if (!prs_uint32("access_mask", ps, depth, &psa->access_mask))
57 return False;
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;
67 if (psa->obj_flags & SEC_ACE_OBJECT_PRESENT)
68 if (!smb_io_uuid("obj_guid", &psa->obj_guid, ps,depth))
69 return False;
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;
75 if(!smb_io_dom_sid("trustee ", &psa->trustee , ps, depth))
76 return False;
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. */
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;
88 for (i = 0; i < extra_len; i++) {
89 if (!prs_uint8("ace extra space", ps, depth, &c))
90 return False;
94 if(!prs_uint16_post("size ", ps, depth, &psa->size, offset_ace_size, old_offset))
95 return False;
97 return True;
100 /*******************************************************************
101 Reads or writes a SEC_ACL structure.
103 First of the xx_io_xx functions that allocates its data structures
104 for you as it reads them.
105 ********************************************************************/
107 BOOL sec_io_acl(const char *desc, SEC_ACL **ppsa, prs_struct *ps, int depth)
109 unsigned int i;
110 uint32 old_offset;
111 uint32 offset_acl_size;
112 SEC_ACL *psa;
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
121 if (ppsa == NULL)
122 return False;
124 psa = *ppsa;
126 if(UNMARSHALLING(ps) && psa == NULL) {
128 * This is a read and we must allocate the stuct to read into.
130 if((psa = PRS_ALLOC_MEM(ps, SEC_ACL, 1)) == NULL)
131 return False;
132 *ppsa = psa;
135 prs_debug(ps, depth, desc, "sec_io_acl");
136 depth++;
138 old_offset = prs_offset(ps);
140 if(!prs_uint16("revision", ps, depth, &psa->revision))
141 return False;
143 if(!prs_uint16_pre("size ", ps, depth, &psa->size, &offset_acl_size))
144 return False;
146 if(!prs_uint32("num_aces ", ps, depth, &psa->num_aces))
147 return False;
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;
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;
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. */
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;
173 for (i = 0; i < extra_len; i++) {
174 if (!prs_uint8("acl extra space", ps, depth, &c))
175 return False;
179 if(!prs_uint16_post("size ", ps, depth, &psa->size, offset_acl_size, old_offset))
180 return False;
182 return True;
185 /*******************************************************************
186 Reads or writes a SEC_DESC structure.
187 If reading and the *ppsd = NULL, allocates the structure.
188 ********************************************************************/
190 BOOL sec_io_desc(const char *desc, SEC_DESC **ppsd, prs_struct *ps, int depth)
192 uint32 old_offset;
193 uint32 max_offset = 0; /* after we're done, move offset to end */
194 uint32 tmp_offset = 0;
196 SEC_DESC *psd;
198 if (ppsd == NULL)
199 return False;
201 psd = *ppsd;
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;
214 prs_debug(ps, depth, desc, "sec_io_desc");
215 depth++;
217 /* start of security descriptor stored for back-calc offset purposes */
218 old_offset = prs_offset(ps);
220 if(!prs_uint16("revision ", ps, depth, &psd->revision))
221 return False;
223 if(!prs_uint16("type ", ps, depth, &psd->type))
224 return False;
226 if (MARSHALLING(ps)) {
227 uint32 offset = SEC_DESC_HEADER_SIZE;
230 * Work out the offsets here, as we write it out.
233 if (psd->sacl != NULL) {
234 psd->off_sacl = offset;
235 offset += psd->sacl->size;
236 } else {
237 psd->off_sacl = 0;
240 if (psd->dacl != NULL) {
241 psd->off_dacl = offset;
242 offset += psd->dacl->size;
243 } else {
244 psd->off_dacl = 0;
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;
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;
262 if(!prs_uint32("off_owner_sid", ps, depth, &psd->off_owner_sid))
263 return False;
265 if(!prs_uint32("off_grp_sid ", ps, depth, &psd->off_grp_sid))
266 return False;
268 if(!prs_uint32("off_sacl ", ps, depth, &psd->off_sacl))
269 return False;
271 if(!prs_uint32("off_dacl ", ps, depth, &psd->off_dacl))
272 return False;
274 max_offset = MAX(max_offset, prs_offset(ps));
276 if (psd->off_owner_sid != 0) {
278 tmp_offset = prs_offset(ps);
279 if(!prs_set_offset(ps, old_offset + psd->off_owner_sid))
280 return False;
282 if (UNMARSHALLING(ps)) {
283 /* reading */
284 if((psd->owner_sid = PRS_ALLOC_MEM(ps,DOM_SID,1)) == NULL)
285 return False;
288 if(!smb_io_dom_sid("owner_sid ", psd->owner_sid , ps, depth))
289 return False;
291 max_offset = MAX(max_offset, prs_offset(ps));
293 if (!prs_set_offset(ps,tmp_offset))
294 return False;
297 if (psd->off_grp_sid != 0) {
299 tmp_offset = prs_offset(ps);
300 if(!prs_set_offset(ps, old_offset + psd->off_grp_sid))
301 return False;
303 if (UNMARSHALLING(ps)) {
304 /* reading */
305 if((psd->group_sid = PRS_ALLOC_MEM(ps,DOM_SID,1)) == NULL)
306 return False;
309 if(!smb_io_dom_sid("group_sid", psd->group_sid, ps, depth))
310 return False;
312 max_offset = MAX(max_offset, prs_offset(ps));
314 if (!prs_set_offset(ps,tmp_offset))
315 return False;
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;
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;
340 if(!prs_set_offset(ps, max_offset))
341 return False;
343 return True;
346 /*******************************************************************
347 Reads or writes a SEC_DESC_BUF structure.
348 ********************************************************************/
350 BOOL sec_io_desc_buf(const char *desc, SEC_DESC_BUF **ppsdb, prs_struct *ps, int depth)
352 uint32 off_len;
353 uint32 off_max_len;
354 uint32 old_offset;
355 uint32 size;
356 SEC_DESC_BUF *psdb;
358 if (ppsdb == NULL)
359 return False;
361 psdb = *ppsdb;
363 if (UNMARSHALLING(ps) && psdb == NULL) {
364 if((psdb = PRS_ALLOC_MEM(ps,SEC_DESC_BUF,1)) == NULL)
365 return False;
366 *ppsdb = psdb;
369 prs_debug(ps, depth, desc, "sec_io_desc_buf");
370 depth++;
372 if(!prs_align(ps))
373 return False;
375 if(!prs_uint32_pre("max_len", ps, depth, &psdb->max_len, &off_max_len))
376 return False;
378 if(!prs_uint32 ("ptr ", ps, depth, &psdb->ptr))
379 return False;
381 if(!prs_uint32_pre("len ", ps, depth, &psdb->len, &off_len))
382 return False;
384 old_offset = prs_offset(ps);
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;
392 if(!prs_align(ps))
393 return False;
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;
399 if(!prs_uint32_post("len ", ps, depth, &psdb->len, off_len, size))
400 return False;
402 return True;