/src/samba/librpc/ndr/ndr_sec_helper.c
Line | Count | Source |
1 | | /* |
2 | | Unix SMB/CIFS implementation. |
3 | | |
4 | | fast routines for getting the wire size of security objects |
5 | | |
6 | | Copyright (C) Andrew Tridgell 2003 |
7 | | Copyright (C) Stefan Metzmacher 2006-2008 |
8 | | |
9 | | This program is free software; you can redistribute it and/or modify |
10 | | it under the terms of the GNU General Public License as published by |
11 | | the Free Software Foundation; either version 3 of the License, or |
12 | | (at your option) any later version. |
13 | | |
14 | | This program is distributed in the hope that it will be useful, |
15 | | but WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
17 | | GNU General Public License for more details. |
18 | | |
19 | | You should have received a copy of the GNU General Public License |
20 | | along with this program. If not, see <http://www.gnu.org/licenses/>. |
21 | | */ |
22 | | |
23 | | |
24 | | #include "includes.h" |
25 | | #include "librpc/gen_ndr/ndr_security.h" |
26 | | #include "../libcli/security/security.h" |
27 | | |
28 | | |
29 | | /* |
30 | | * Find the wire size of a security_ace that has no trailing coda. |
31 | | * This is used in ndr_pull_security_ace() generated from security.idl |
32 | | * to work out where the coda starts (and in ndr_size_security_ace() |
33 | | * just below). |
34 | | */ |
35 | | static size_t ndr_size_security_ace_core(const struct security_ace *ace, libndr_flags flags) |
36 | 1.25M | { |
37 | 1.25M | size_t ret; |
38 | | |
39 | 1.25M | if (!ace) return 0; |
40 | | |
41 | 1.25M | ret = 8 + ndr_size_dom_sid(&ace->trustee, flags); |
42 | 1.25M | if (sec_ace_object(ace->type)) { |
43 | 339k | ret += 4; /* uint32 bitmap ace->object.object.flags */ |
44 | 339k | if (ace->object.object.flags & SEC_ACE_OBJECT_TYPE_PRESENT) { |
45 | 169k | ret += 16; /* GUID ace->object.object.type.type */ |
46 | 169k | } |
47 | 339k | if (ace->object.object.flags & SEC_ACE_INHERITED_OBJECT_TYPE_PRESENT) { |
48 | 170k | ret += 16; /* GUID ace->object.object.inherited_type.inherited_type */ |
49 | 170k | } |
50 | 339k | } |
51 | | |
52 | 1.25M | return ret; |
53 | 1.25M | } |
54 | | |
55 | | /* |
56 | | return the wire size of a security_ace |
57 | | */ |
58 | | size_t ndr_size_security_ace(const struct security_ace *ace, libndr_flags flags) |
59 | 900k | { |
60 | 900k | size_t base = ndr_size_security_ace_core(ace, flags); |
61 | 900k | size_t ret = base; |
62 | 900k | if (sec_ace_callback(ace->type)) { |
63 | 194k | ret += ace->coda.conditions.length; |
64 | 705k | } else if (ace->type == SEC_ACE_TYPE_SYSTEM_RESOURCE_ATTRIBUTE) { |
65 | 45.6k | ret += ndr_size_security_ace_coda(&ace->coda, ace->type, flags); |
66 | 660k | } else { |
67 | | /* |
68 | | * Normal ACEs have a coda.ignored blob that is always or |
69 | | * almost always empty. We aren't going to push it (it is |
70 | | * ignored), so we don't add that length to the size. |
71 | | */ |
72 | 660k | } |
73 | | /* round up to a multiple of 4 (MS-DTYP 2.4.4.1) */ |
74 | 900k | ret = (ret + 3ULL) & ~3ULL; |
75 | 900k | if (unlikely(ret < base)) { |
76 | | /* overflow, and there's not much we can do anyway */ |
77 | 0 | return 0; |
78 | 0 | } |
79 | 900k | return ret; |
80 | 900k | } |
81 | | |
82 | | |
83 | | static inline enum ndr_err_code ndr_maybe_pull_security_ace_object_ctr(struct ndr_pull *ndr, |
84 | | ndr_flags_type ndr_flags, |
85 | | struct security_ace *r) |
86 | 1.62M | { |
87 | | /* |
88 | | * If this is not an object ACE (as is usually common), |
89 | | * ndr_pull_security_ace_object_ctr() will do nothing. |
90 | | * |
91 | | * By avoiding calling the function in that case, we avoid some |
92 | | * tallocing and ndr token busywork. |
93 | | */ |
94 | 1.62M | bool is_object = sec_ace_object(r->type); |
95 | 1.62M | if (is_object) { |
96 | 256k | NDR_CHECK(ndr_pull_set_switch_value(ndr, &r->object, is_object)); |
97 | 256k | NDR_CHECK(ndr_pull_security_ace_object_ctr(ndr, ndr_flags, &r->object)); |
98 | 256k | } |
99 | 1.62M | return NDR_ERR_SUCCESS; |
100 | 1.62M | } |
101 | | |
102 | | |
103 | | _PUBLIC_ enum ndr_err_code ndr_pull_security_ace(struct ndr_pull *ndr, ndr_flags_type ndr_flags, struct security_ace *r) |
104 | 1.62M | { |
105 | 1.62M | NDR_PULL_CHECK_FLAGS(ndr, ndr_flags); |
106 | 1.62M | if (ndr_flags & NDR_SCALARS) { |
107 | 896k | ssize_t sub_size; |
108 | 896k | NDR_CHECK(ndr_pull_align(ndr, 5)); |
109 | 896k | NDR_CHECK(ndr_pull_security_ace_type(ndr, NDR_SCALARS, &r->type)); |
110 | 895k | NDR_CHECK(ndr_pull_security_ace_flags(ndr, NDR_SCALARS, &r->flags)); |
111 | 895k | NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->size)); |
112 | 895k | NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->access_mask)); |
113 | 894k | NDR_CHECK(ndr_maybe_pull_security_ace_object_ctr(ndr, NDR_SCALARS, r)); |
114 | 894k | NDR_CHECK(ndr_pull_dom_sid(ndr, NDR_SCALARS, &r->trustee)); |
115 | 893k | sub_size = ndr_subcontext_size_of_ace_coda(r, r->size, ndr->flags); |
116 | 893k | if (sub_size == 0 && !sec_ace_has_extra_blob(r->type)) { |
117 | 611k | r->coda.ignored.data = NULL; |
118 | 611k | r->coda.ignored.length = 0; |
119 | 611k | } else { |
120 | 281k | struct ndr_pull *_ndr_coda; |
121 | 281k | NDR_CHECK(ndr_pull_subcontext_start(ndr, &_ndr_coda, 0, sub_size)); |
122 | 280k | NDR_CHECK(ndr_pull_set_switch_value(_ndr_coda, &r->coda, r->type)); |
123 | 280k | NDR_CHECK(ndr_pull_security_ace_coda(_ndr_coda, NDR_SCALARS|NDR_BUFFERS, &r->coda)); |
124 | 277k | NDR_CHECK(ndr_pull_subcontext_end(ndr, _ndr_coda, 0, sub_size)); |
125 | 277k | } |
126 | 888k | NDR_CHECK(ndr_pull_trailer_align(ndr, 5)); |
127 | 888k | } |
128 | 1.62M | if (ndr_flags & NDR_BUFFERS) { |
129 | 732k | NDR_CHECK(ndr_maybe_pull_security_ace_object_ctr(ndr, NDR_BUFFERS, r)); |
130 | 732k | } |
131 | 1.62M | return NDR_ERR_SUCCESS; |
132 | 1.62M | } |
133 | | |
134 | | |
135 | | static inline enum ndr_err_code ndr_maybe_push_security_ace_object_ctr(struct ndr_push *ndr, |
136 | | ndr_flags_type ndr_flags, |
137 | | const struct security_ace *r) |
138 | 697k | { |
139 | | /* |
140 | | * ndr_push_security_ace_object_ctr() does nothing (except tallocing |
141 | | * and ndr_token fiddling) unless the ACE is an object ACE, which is |
142 | | * usually very unlikely. |
143 | | */ |
144 | 697k | bool is_object = sec_ace_object(r->type); |
145 | 697k | if (is_object) { |
146 | 134k | NDR_CHECK(ndr_push_set_switch_value(ndr, &r->object, is_object)); |
147 | 134k | NDR_CHECK(ndr_push_security_ace_object_ctr(ndr, ndr_flags, &r->object)); |
148 | 134k | } |
149 | 697k | return NDR_ERR_SUCCESS; |
150 | 697k | } |
151 | | |
152 | | _PUBLIC_ enum ndr_err_code ndr_push_security_ace(struct ndr_push *ndr, ndr_flags_type ndr_flags, const struct security_ace *r) |
153 | 697k | { |
154 | 697k | NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags); |
155 | 697k | if (ndr_flags & NDR_SCALARS) { |
156 | 348k | NDR_CHECK(ndr_push_align(ndr, 5)); |
157 | 348k | NDR_CHECK(ndr_push_security_ace_type(ndr, NDR_SCALARS, r->type)); |
158 | 348k | NDR_CHECK(ndr_push_security_ace_flags(ndr, NDR_SCALARS, r->flags)); |
159 | 348k | NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, ndr_size_security_ace(r, ndr->flags))); |
160 | 348k | NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->access_mask)); |
161 | 348k | NDR_CHECK(ndr_maybe_push_security_ace_object_ctr(ndr, NDR_SCALARS, r)); |
162 | 348k | NDR_CHECK(ndr_push_dom_sid(ndr, NDR_SCALARS, &r->trustee)); |
163 | 348k | if (sec_ace_has_extra_blob(r->type)) { |
164 | 72.7k | struct ndr_push *_ndr_coda; |
165 | 72.7k | size_t coda_size = ndr_subcontext_size_of_ace_coda( |
166 | 72.7k | r, |
167 | 72.7k | ndr_size_security_ace(r, ndr->flags), |
168 | 72.7k | ndr->flags); |
169 | 72.7k | NDR_CHECK(ndr_push_subcontext_start(ndr, &_ndr_coda, 0, coda_size)); |
170 | 72.7k | NDR_CHECK(ndr_push_set_switch_value(_ndr_coda, &r->coda, r->type)); |
171 | 72.7k | NDR_CHECK(ndr_push_security_ace_coda(_ndr_coda, NDR_SCALARS|NDR_BUFFERS, &r->coda)); |
172 | 72.7k | NDR_CHECK(ndr_push_subcontext_end(ndr, _ndr_coda, 0, coda_size)); |
173 | 72.7k | } |
174 | 348k | NDR_CHECK(ndr_push_trailer_align(ndr, 5)); |
175 | 348k | } |
176 | 697k | if (ndr_flags & NDR_BUFFERS) { |
177 | 348k | NDR_CHECK(ndr_maybe_push_security_ace_object_ctr(ndr, NDR_BUFFERS, r)); |
178 | 348k | } |
179 | 697k | return NDR_ERR_SUCCESS; |
180 | 697k | } |
181 | | |
182 | | |
183 | | /* |
184 | | * An ACE coda can't be bigger than the space allowed for by |
185 | | * ace->size, so we need to check this from the context of the ACE. |
186 | | * |
187 | | * Usually the coda also can't be any smaller than the remaining |
188 | | * space, because it is defined as a blob consuming everything it can. |
189 | | * |
190 | | * This is only used to find the size for the coda subcontext in |
191 | | * security.idl. |
192 | | */ |
193 | | size_t ndr_subcontext_size_of_ace_coda(const struct security_ace *ace, |
194 | | size_t ace_size, |
195 | | libndr_flags flags) |
196 | 965k | { |
197 | 965k | size_t core_size; |
198 | 965k | if (ace_size == 0) { |
199 | 612k | return 0; |
200 | 612k | } |
201 | 353k | core_size = ndr_size_security_ace_core(ace, flags); |
202 | 353k | if (ace_size < core_size) { |
203 | 54.5k | return 0; |
204 | 54.5k | } |
205 | 299k | return ace_size - core_size; |
206 | 353k | } |
207 | | |
208 | | /* |
209 | | return the wire size of a security_acl |
210 | | */ |
211 | | size_t ndr_size_security_acl(const struct security_acl *theacl, libndr_flags flags) |
212 | 27.4k | { |
213 | 27.4k | size_t ret; |
214 | 27.4k | uint32_t i; |
215 | 27.4k | if (!theacl) return 0; |
216 | 26.3k | ret = 8; |
217 | 505k | for (i=0;i<theacl->num_aces;i++) { |
218 | 479k | ret += ndr_size_security_ace(&theacl->aces[i], flags); |
219 | 479k | } |
220 | 26.3k | return ret; |
221 | 27.4k | } |
222 | | |
223 | | /* |
224 | | return the wire size of a security descriptor |
225 | | */ |
226 | | size_t ndr_size_security_descriptor(const struct security_descriptor *sd, libndr_flags flags) |
227 | 12.1k | { |
228 | 12.1k | size_t ret; |
229 | 12.1k | if (!sd) return 0; |
230 | | |
231 | 4.33k | ret = 20; |
232 | 4.33k | ret += ndr_size_dom_sid(sd->owner_sid, flags); |
233 | 4.33k | ret += ndr_size_dom_sid(sd->group_sid, flags); |
234 | 4.33k | ret += ndr_size_security_acl(sd->dacl, flags); |
235 | 4.33k | ret += ndr_size_security_acl(sd->sacl, flags); |
236 | 4.33k | return ret; |
237 | 12.1k | } |
238 | | |
239 | | /* |
240 | | return the wire size of a dom_sid |
241 | | */ |
242 | | size_t ndr_size_dom_sid(const struct dom_sid *sid, libndr_flags flags) |
243 | 1.30M | { |
244 | 1.30M | if (!sid) return 0; |
245 | 1.29M | return 8 + 4*sid->num_auths; |
246 | 1.30M | } |
247 | | |
248 | | size_t ndr_size_dom_sid28(const struct dom_sid *sid, libndr_flags flags) |
249 | 208k | { |
250 | 208k | if (all_zero((const uint8_t *)sid, sizeof(struct dom_sid))) { |
251 | 196k | return 0; |
252 | 196k | } |
253 | 11.7k | return ndr_size_dom_sid(sid, flags); |
254 | 208k | } |
255 | | |
256 | | size_t ndr_size_dom_sid0(const struct dom_sid *sid, libndr_flags flags) |
257 | 203k | { |
258 | 203k | return ndr_size_dom_sid28(sid, flags); |
259 | 203k | } |
260 | | |
261 | | /* |
262 | | print a dom_sid |
263 | | */ |
264 | | void ndr_print_dom_sid(struct ndr_print *ndr, const char *name, const struct dom_sid *sid) |
265 | 477k | { |
266 | 477k | struct dom_sid_buf buf; |
267 | 477k | ndr->print(ndr, "%-25s: %s", name, dom_sid_str_buf(sid, &buf)); |
268 | 477k | } |
269 | | |
270 | | void ndr_print_dom_sid2(struct ndr_print *ndr, const char *name, const struct dom_sid *sid) |
271 | 10.4k | { |
272 | 10.4k | ndr_print_dom_sid(ndr, name, sid); |
273 | 10.4k | } |
274 | | |
275 | | void ndr_print_dom_sid28(struct ndr_print *ndr, const char *name, const struct dom_sid *sid) |
276 | 4.94k | { |
277 | 4.94k | ndr_print_dom_sid(ndr, name, sid); |
278 | 4.94k | } |
279 | | |
280 | | void ndr_print_dom_sid0(struct ndr_print *ndr, const char *name, const struct dom_sid *sid) |
281 | 40.7k | { |
282 | 40.7k | ndr_print_dom_sid(ndr, name, sid); |
283 | 40.7k | } |
284 | | |
285 | | |
286 | | /* |
287 | | parse a dom_sid2 - this is a dom_sid but with an extra copy of the num_auths field |
288 | | */ |
289 | | enum ndr_err_code ndr_pull_dom_sid2(struct ndr_pull *ndr, ndr_flags_type ndr_flags, struct dom_sid *sid) |
290 | 69.6k | { |
291 | 69.6k | uint32_t num_auths; |
292 | 69.6k | if (!(ndr_flags & NDR_SCALARS)) { |
293 | 0 | return NDR_ERR_SUCCESS; |
294 | 0 | } |
295 | 69.6k | NDR_CHECK(ndr_pull_uint3264(ndr, NDR_SCALARS, &num_auths)); |
296 | 69.3k | NDR_CHECK(ndr_pull_dom_sid(ndr, ndr_flags, sid)); |
297 | 68.9k | if (sid->num_auths != num_auths) { |
298 | 532 | return ndr_pull_error(ndr, NDR_ERR_ARRAY_SIZE, |
299 | 532 | "Bad num_auths %"PRIu32"; should equal %"PRId8, |
300 | 532 | num_auths, sid->num_auths); |
301 | 532 | } |
302 | 68.3k | return NDR_ERR_SUCCESS; |
303 | 68.9k | } |
304 | | |
305 | | /* |
306 | | parse a dom_sid2 - this is a dom_sid but with an extra copy of the num_auths field |
307 | | */ |
308 | | enum ndr_err_code ndr_push_dom_sid2(struct ndr_push *ndr, ndr_flags_type ndr_flags, const struct dom_sid *sid) |
309 | 10.9k | { |
310 | 10.9k | if (!(ndr_flags & NDR_SCALARS)) { |
311 | 0 | return NDR_ERR_SUCCESS; |
312 | 0 | } |
313 | 10.9k | NDR_CHECK(ndr_push_uint3264(ndr, NDR_SCALARS, sid->num_auths)); |
314 | 10.9k | return ndr_push_dom_sid(ndr, ndr_flags, sid); |
315 | 10.9k | } |
316 | | |
317 | | /* |
318 | | parse a dom_sid28 - this is a dom_sid in a fixed 28 byte buffer, so we need to ensure there are only up to 5 sub_auth |
319 | | */ |
320 | | enum ndr_err_code ndr_pull_dom_sid28(struct ndr_pull *ndr, ndr_flags_type ndr_flags, struct dom_sid *sid) |
321 | 29.2k | { |
322 | 29.2k | enum ndr_err_code status; |
323 | 29.2k | struct ndr_pull *subndr; |
324 | | |
325 | 29.2k | if (!(ndr_flags & NDR_SCALARS)) { |
326 | 7.19k | return NDR_ERR_SUCCESS; |
327 | 7.19k | } |
328 | | |
329 | 22.0k | subndr = talloc_zero(ndr, struct ndr_pull); |
330 | 22.0k | NDR_ERR_HAVE_NO_MEMORY(subndr); |
331 | 22.0k | subndr->flags = ndr->flags; |
332 | 22.0k | subndr->current_mem_ctx = ndr->current_mem_ctx; |
333 | | |
334 | 22.0k | subndr->data = ndr->data + ndr->offset; |
335 | 22.0k | subndr->data_size = 28; |
336 | 22.0k | subndr->offset = 0; |
337 | | |
338 | 22.0k | status = ndr_pull_advance(ndr, 28); |
339 | 22.0k | if (!NDR_ERR_CODE_IS_SUCCESS(status)) { |
340 | 107 | TALLOC_FREE(subndr); |
341 | 107 | return status; |
342 | 107 | } |
343 | | |
344 | 21.9k | status = ndr_pull_dom_sid(subndr, ndr_flags, sid); |
345 | 21.9k | if (!NDR_ERR_CODE_IS_SUCCESS(status)) { |
346 | | /* handle a w2k bug which send random data in the buffer */ |
347 | 10.3k | ZERO_STRUCTP(sid); |
348 | 11.6k | } else if (sid->num_auths == 0) { |
349 | 9.28k | ZERO_STRUCT(sid->sub_auths); |
350 | 9.28k | } |
351 | | |
352 | 21.9k | TALLOC_FREE(subndr); |
353 | 21.9k | return NDR_ERR_SUCCESS; |
354 | 22.0k | } |
355 | | |
356 | | /* |
357 | | push a dom_sid28 - this is a dom_sid in a 28 byte fixed buffer |
358 | | */ |
359 | | enum ndr_err_code ndr_push_dom_sid28(struct ndr_push *ndr, ndr_flags_type ndr_flags, const struct dom_sid *sid) |
360 | 14.3k | { |
361 | 14.3k | uint32_t old_offset; |
362 | 14.3k | uint32_t padding; |
363 | | |
364 | 14.3k | if (!(ndr_flags & NDR_SCALARS)) { |
365 | 6.72k | return NDR_ERR_SUCCESS; |
366 | 6.72k | } |
367 | | |
368 | 7.62k | if (sid->num_auths > 5) { |
369 | 0 | return ndr_push_error(ndr, NDR_ERR_RANGE, |
370 | 0 | "dom_sid28 allows only up to 5 sub auths [%"PRId8"]", |
371 | 0 | sid->num_auths); |
372 | 0 | } |
373 | | |
374 | 7.62k | old_offset = ndr->offset; |
375 | 7.62k | NDR_CHECK(ndr_push_dom_sid(ndr, ndr_flags, sid)); |
376 | | |
377 | 7.62k | padding = 28 - (ndr->offset - old_offset); |
378 | | |
379 | 7.62k | if (padding > 0) { |
380 | 7.12k | NDR_CHECK(ndr_push_zero(ndr, padding)); |
381 | 7.12k | } |
382 | | |
383 | 7.62k | return NDR_ERR_SUCCESS; |
384 | 7.62k | } |
385 | | |
386 | | /* |
387 | | parse a dom_sid0 - this is a dom_sid in a variable byte buffer, which is maybe empty |
388 | | */ |
389 | | enum ndr_err_code ndr_pull_dom_sid0(struct ndr_pull *ndr, ndr_flags_type ndr_flags, struct dom_sid *sid) |
390 | 62.0k | { |
391 | 62.0k | if (!(ndr_flags & NDR_SCALARS)) { |
392 | 0 | return NDR_ERR_SUCCESS; |
393 | 0 | } |
394 | | |
395 | 62.0k | if (ndr->data_size == ndr->offset) { |
396 | 58.5k | ZERO_STRUCTP(sid); |
397 | 58.5k | return NDR_ERR_SUCCESS; |
398 | 58.5k | } |
399 | | |
400 | 3.50k | return ndr_pull_dom_sid(ndr, ndr_flags, sid); |
401 | 62.0k | } |
402 | | |
403 | | /* |
404 | | push a dom_sid0 - this is a dom_sid in a variable byte buffer, which is maybe empty |
405 | | */ |
406 | | enum ndr_err_code ndr_push_dom_sid0(struct ndr_push *ndr, ndr_flags_type ndr_flags, const struct dom_sid *sid) |
407 | 41.0k | { |
408 | 41.0k | if (!(ndr_flags & NDR_SCALARS)) { |
409 | 0 | return NDR_ERR_SUCCESS; |
410 | 0 | } |
411 | | |
412 | 41.0k | if (!sid) { |
413 | 0 | return NDR_ERR_SUCCESS; |
414 | 0 | } |
415 | | |
416 | 41.0k | if (all_zero((const uint8_t *)sid, sizeof(struct dom_sid))) { |
417 | 39.1k | return NDR_ERR_SUCCESS; |
418 | 39.1k | } |
419 | | |
420 | 1.90k | return ndr_push_dom_sid(ndr, ndr_flags, sid); |
421 | 41.0k | } |
422 | | |
423 | | _PUBLIC_ enum ndr_err_code ndr_push_dom_sid(struct ndr_push *ndr, ndr_flags_type ndr_flags, const struct dom_sid *r) |
424 | 466k | { |
425 | 466k | uint32_t cntr_sub_auths_0; |
426 | 466k | if (ndr_flags & NDR_SCALARS) { |
427 | 466k | NDR_CHECK(ndr_push_align(ndr, 4)); |
428 | 466k | NDR_CHECK(ndr_push_uint8(ndr, NDR_SCALARS, r->sid_rev_num)); |
429 | 466k | NDR_CHECK(ndr_push_int8(ndr, NDR_SCALARS, r->num_auths)); |
430 | 466k | NDR_CHECK(ndr_push_array_uint8(ndr, NDR_SCALARS, r->id_auth, 6)); |
431 | 466k | if (r->num_auths < 0 || r->num_auths > ARRAY_SIZE(r->sub_auths)) { |
432 | 0 | return ndr_push_error(ndr, NDR_ERR_RANGE, "value (%"PRId8") out of range (0 - %zu)", r->num_auths, ARRAY_SIZE(r->sub_auths)); |
433 | 0 | } |
434 | 1.02M | for (cntr_sub_auths_0 = 0; cntr_sub_auths_0 < r->num_auths; cntr_sub_auths_0++) { |
435 | 559k | NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->sub_auths[cntr_sub_auths_0])); |
436 | 559k | } |
437 | 466k | } |
438 | 466k | return NDR_ERR_SUCCESS; |
439 | 466k | } |
440 | | |
441 | | _PUBLIC_ enum ndr_err_code ndr_pull_dom_sid(struct ndr_pull *ndr, ndr_flags_type ndr_flags, struct dom_sid *r) |
442 | 3.55M | { |
443 | 3.55M | uint32_t cntr_sub_auths_0; |
444 | 3.55M | if (ndr_flags & NDR_SCALARS) { |
445 | 3.55M | NDR_CHECK(ndr_pull_align(ndr, 4)); |
446 | 3.55M | NDR_CHECK(ndr_pull_uint8(ndr, NDR_SCALARS, &r->sid_rev_num)); |
447 | 3.54M | NDR_CHECK(ndr_pull_int8(ndr, NDR_SCALARS, &r->num_auths)); |
448 | 3.54M | if (r->num_auths < 0 || r->num_auths > ARRAY_SIZE(r->sub_auths)) { |
449 | 10.9k | return ndr_pull_error(ndr, NDR_ERR_RANGE, "value (%"PRId8") out of range (0 - %zu)", r->num_auths, ARRAY_SIZE(r->sub_auths)); |
450 | 10.9k | } |
451 | 3.53M | NDR_CHECK(ndr_pull_array_uint8(ndr, NDR_SCALARS, r->id_auth, 6)); |
452 | 3.53M | ZERO_STRUCT(r->sub_auths); |
453 | 5.10M | for (cntr_sub_auths_0 = 0; cntr_sub_auths_0 < r->num_auths; cntr_sub_auths_0++) { |
454 | 1.56M | NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->sub_auths[cntr_sub_auths_0])); |
455 | 1.56M | } |
456 | 3.53M | } |
457 | 3.53M | return NDR_ERR_SUCCESS; |
458 | 3.55M | } |