source: branches/samba-3.3.x/source/librpc/ndr/sid.c

Last change on this file was 206, checked in by Herwig Bauernfeind, 16 years ago

Import Samba 3.3 branch at 3.0.0 level (psmedley's port)

File size: 6.1 KB
Line 
1/*
2 Unix SMB/CIFS implementation.
3
4 libndr interface
5
6 Copyright (C) Andrew Tridgell 2003
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
20*/
21
22#include "includes.h"
23
24enum ndr_err_code ndr_push_dom_sid(struct ndr_push *ndr, int ndr_flags, const struct dom_sid *r)
25{
26 uint32_t cntr_sub_auths_0;
27 if (ndr_flags & NDR_SCALARS) {
28 NDR_CHECK(ndr_push_align(ndr, 4));
29 NDR_CHECK(ndr_push_uint8(ndr, NDR_SCALARS, r->sid_rev_num));
30 NDR_CHECK(ndr_push_int8(ndr, NDR_SCALARS, r->num_auths));
31 NDR_CHECK(ndr_push_array_uint8(ndr, NDR_SCALARS, r->id_auth, 6));
32 for (cntr_sub_auths_0 = 0; cntr_sub_auths_0 < r->num_auths; cntr_sub_auths_0++) {
33 NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->sub_auths[cntr_sub_auths_0]));
34 }
35 }
36 if (ndr_flags & NDR_BUFFERS) {
37 }
38 return NDR_ERR_SUCCESS;
39}
40
41enum ndr_err_code ndr_pull_dom_sid(struct ndr_pull *ndr, int ndr_flags, struct dom_sid *r)
42{
43 uint32_t cntr_sub_auths_0;
44 if (ndr_flags & NDR_SCALARS) {
45 NDR_CHECK(ndr_pull_align(ndr, 4));
46 NDR_CHECK(ndr_pull_uint8(ndr, NDR_SCALARS, &r->sid_rev_num));
47 NDR_CHECK(ndr_pull_uint8(ndr, NDR_SCALARS, &r->num_auths));
48 if (r->num_auths > 15) {
49 return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range");
50 }
51 NDR_CHECK(ndr_pull_array_uint8(ndr, NDR_SCALARS, r->id_auth, 6));
52 for (cntr_sub_auths_0 = 0; cntr_sub_auths_0 < r->num_auths; cntr_sub_auths_0++) {
53 NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->sub_auths[cntr_sub_auths_0]));
54 }
55 }
56 if (ndr_flags & NDR_BUFFERS) {
57 }
58 return NDR_ERR_SUCCESS;
59}
60
61/*
62 convert a dom_sid to a string
63*/
64char *dom_sid_string(TALLOC_CTX *mem_ctx, const struct dom_sid *sid)
65{
66 int i, ofs, maxlen;
67 uint32_t ia;
68 char *ret;
69
70 if (!sid) {
71 return talloc_strdup(mem_ctx, "(NULL SID)");
72 }
73
74 maxlen = sid->num_auths * 11 + 25;
75 ret = (char *)talloc_size(mem_ctx, maxlen);
76 if (!ret) return talloc_strdup(mem_ctx, "(SID ERR)");
77
78 /*
79 * BIG NOTE: this function only does SIDS where the identauth is not
80 * >= ^32 in a range of 2^48.
81 */
82
83 ia = (sid->id_auth[5]) +
84 (sid->id_auth[4] << 8 ) +
85 (sid->id_auth[3] << 16) +
86 (sid->id_auth[2] << 24);
87
88 ofs = snprintf(ret, maxlen, "S-%u-%lu",
89 (unsigned int)sid->sid_rev_num, (unsigned long)ia);
90
91 for (i = 0; i < sid->num_auths; i++) {
92 ofs += snprintf(ret + ofs, maxlen - ofs, "-%lu", (unsigned long)sid->sub_auths[i]);
93 }
94
95 return ret;
96}
97
98/*
99 parse a dom_sid2 - this is a dom_sid but with an extra copy of the num_auths field
100*/
101enum ndr_err_code ndr_pull_dom_sid2(struct ndr_pull *ndr, int ndr_flags, struct dom_sid *sid)
102{
103 uint32_t num_auths;
104 if (!(ndr_flags & NDR_SCALARS)) {
105 return NDR_ERR_SUCCESS;
106 }
107 NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &num_auths));
108 NDR_CHECK(ndr_pull_dom_sid(ndr, ndr_flags, sid));
109 if (sid->num_auths != num_auths) {
110 return ndr_pull_error(ndr, NDR_ERR_ARRAY_SIZE,
111 "Bad array size %u should exceed %u",
112 num_auths, sid->num_auths);
113 }
114 return NDR_ERR_SUCCESS;
115}
116
117/*
118 parse a dom_sid2 - this is a dom_sid but with an extra copy of the num_auths field
119*/
120enum ndr_err_code ndr_push_dom_sid2(struct ndr_push *ndr, int ndr_flags, const struct dom_sid *sid)
121{
122 if (!(ndr_flags & NDR_SCALARS)) {
123 return NDR_ERR_SUCCESS;
124 }
125 NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, sid->num_auths));
126 return ndr_push_dom_sid(ndr, ndr_flags, sid);
127}
128
129/*
130 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
131*/
132enum ndr_err_code ndr_pull_dom_sid28(struct ndr_pull *ndr, int ndr_flags, struct dom_sid *sid)
133{
134 enum ndr_err_code status;
135 struct ndr_pull *subndr;
136
137 if (!(ndr_flags & NDR_SCALARS)) {
138 return NDR_ERR_SUCCESS;
139 }
140
141 subndr = talloc_zero(ndr, struct ndr_pull);
142 NDR_ERR_HAVE_NO_MEMORY(subndr);
143 subndr->flags = ndr->flags;
144 subndr->current_mem_ctx = ndr->current_mem_ctx;
145
146 subndr->data = ndr->data + ndr->offset;
147 subndr->data_size = 28;
148 subndr->offset = 0;
149
150 NDR_CHECK(ndr_pull_advance(ndr, 28));
151
152 status = ndr_pull_dom_sid(subndr, ndr_flags, sid);
153 if (!NDR_ERR_CODE_IS_SUCCESS(status)) {
154 /* handle a w2k bug which send random data in the buffer */
155 ZERO_STRUCTP(sid);
156 }
157
158 return NDR_ERR_SUCCESS;
159}
160
161/*
162 push a dom_sid28 - this is a dom_sid in a 28 byte fixed buffer
163*/
164enum ndr_err_code ndr_push_dom_sid28(struct ndr_push *ndr, int ndr_flags, const struct dom_sid *sid)
165{
166 uint32_t old_offset;
167 uint32_t padding;
168
169 if (!(ndr_flags & NDR_SCALARS)) {
170 return NDR_ERR_SUCCESS;
171 }
172
173 if (sid->num_auths > 5) {
174 return ndr_push_error(ndr, NDR_ERR_RANGE,
175 "dom_sid28 allows only upto 5 sub auth [%u]",
176 sid->num_auths);
177 }
178
179 old_offset = ndr->offset;
180 NDR_CHECK(ndr_push_dom_sid(ndr, ndr_flags, sid));
181
182 padding = 28 - (ndr->offset - old_offset);
183
184 if (padding > 0) {
185 NDR_CHECK(ndr_push_zero(ndr, padding));
186 }
187
188 return NDR_ERR_SUCCESS;
189}
190
191/*
192 parse a dom_sid0 - this is a dom_sid in a variable byte buffer, which is maybe empty
193*/
194enum ndr_err_code ndr_pull_dom_sid0(struct ndr_pull *ndr, int ndr_flags, struct dom_sid *sid)
195{
196 if (!(ndr_flags & NDR_SCALARS)) {
197 return NDR_ERR_SUCCESS;
198 }
199
200 if (ndr->data_size == ndr->offset) {
201 ZERO_STRUCTP(sid);
202 return NDR_ERR_SUCCESS;
203 }
204
205 return ndr_pull_dom_sid(ndr, ndr_flags, sid);
206}
207
208/*
209 push a dom_sid0 - this is a dom_sid in a variable byte buffer, which is maybe empty
210*/
211enum ndr_err_code ndr_push_dom_sid0(struct ndr_push *ndr, int ndr_flags, const struct dom_sid *sid)
212{
213 struct dom_sid zero_sid;
214
215 if (!(ndr_flags & NDR_SCALARS)) {
216 return NDR_ERR_SUCCESS;
217 }
218
219 if (!sid) {
220 return NDR_ERR_SUCCESS;
221 }
222
223 ZERO_STRUCT(zero_sid);
224
225 if (memcmp(&zero_sid, sid, sizeof(zero_sid)) == 0) {
226 return NDR_ERR_SUCCESS;
227 }
228
229 return ndr_push_dom_sid(ndr, ndr_flags, sid);
230}
Note: See TracBrowser for help on using the repository browser.