• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt/router/samba-3.0.25b/source/rpc_parse/
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}
404