ee01536ede5ba78e01bdd10c8a58fcdf3410bdde
[kamenim/samba.git] / source4 / librpc / ndr / ndr_sec.c
1 /* 
2    Unix SMB/CIFS implementation.
3
4    routines for marshalling/unmarshalling security descriptors
5    and related structures
6
7    Copyright (C) Andrew Tridgell 2003
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 2 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, write to the Free Software
21    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24
25 #include "includes.h"
26
27 /*
28   parse a dom_sid2 - this is a dom_sid but with an extra copy of the num_auths field
29 */
30 NTSTATUS ndr_pull_dom_sid2(struct ndr_pull *ndr, int ndr_flags, struct dom_sid *sid)
31 {
32         uint32_t num_auths;
33         if (!(ndr_flags & NDR_SCALARS)) {
34                 return NT_STATUS_OK;
35         }
36         NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &num_auths));
37         NDR_CHECK(ndr_pull_dom_sid(ndr, ndr_flags, sid));
38         if (sid->num_auths != num_auths) {
39                 return ndr_pull_error(ndr, NDR_ERR_ARRAY_SIZE, 
40                                       "Bad array size %u should exceed %u", 
41                                       num_auths, sid->num_auths);
42         }
43         return NT_STATUS_OK;
44 }
45
46 /*
47   parse a dom_sid2 - this is a dom_sid but with an extra copy of the num_auths field
48 */
49 NTSTATUS ndr_push_dom_sid2(struct ndr_push *ndr, int ndr_flags, const struct dom_sid *sid)
50 {
51         if (!(ndr_flags & NDR_SCALARS)) {
52                 return NT_STATUS_OK;
53         }
54         NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, sid->num_auths));
55         return ndr_push_dom_sid(ndr, ndr_flags, sid);
56 }
57
58 /*
59   parse a dom_sid28 - this is a dom_sid in a fixed 28 byte buffer, so we need to ensure there are only upto 5 sub_auth
60 */
61 NTSTATUS ndr_pull_dom_sid28(struct ndr_pull *ndr, int ndr_flags, struct dom_sid *sid)
62 {
63         NTSTATUS status;
64         struct ndr_pull *subndr;
65
66         if (!(ndr_flags & NDR_SCALARS)) {
67                 return NT_STATUS_OK;
68         }
69
70         subndr = talloc_zero(ndr, struct ndr_pull);
71         NT_STATUS_HAVE_NO_MEMORY(subndr);
72         subndr->flags           = ndr->flags;
73         subndr->current_mem_ctx = ndr->current_mem_ctx;
74
75         subndr->data            = ndr->data + ndr->offset;
76         subndr->data_size       = 28;
77         subndr->offset          = 0;
78
79         NDR_CHECK(ndr_pull_advance(ndr, 28));
80
81         status = ndr_pull_dom_sid(subndr, ndr_flags, sid);
82         if (!NT_STATUS_IS_OK(status)) {
83                 /* handle a w2k bug which send random data in the buffer */
84                 ZERO_STRUCTP(sid);
85         }
86
87         return NT_STATUS_OK;
88 }
89
90 /*
91   push a dom_sid28 - this is a dom_sid in a 28 byte fixed buffer
92 */
93 NTSTATUS ndr_push_dom_sid28(struct ndr_push *ndr, int ndr_flags, const struct dom_sid *sid)
94 {
95         uint32_t old_offset;
96         uint32_t padding;
97
98         if (!(ndr_flags & NDR_SCALARS)) {
99                 return NT_STATUS_OK;
100         }
101
102         if (sid->num_auths > 5) {
103                 return ndr_push_error(ndr, NDR_ERR_RANGE, 
104                                       "dom_sid28 allows only upto 5 sub auth [%u]", 
105                                       sid->num_auths);
106         }
107
108         old_offset = ndr->offset;
109         NDR_CHECK(ndr_push_dom_sid(ndr, ndr_flags, sid));
110
111         padding = 28 - (ndr->offset - old_offset);
112
113         if (padding > 0) {
114                 NDR_CHECK(ndr_push_zero(ndr, padding));
115         }
116
117         return NT_STATUS_OK;
118 }
119