2 Unix SMB/CIFS implementation.
6 Copyright (C) Andrew Tridgell 2003
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.
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.
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/>.
25 return the wire size of a dom_sid
27 size_t ndr_size_dom_sid(const struct dom_sid *sid, int flags)
30 return 8 + 4*sid->num_auths;
33 size_t ndr_size_dom_sid28(const struct dom_sid *sid, int flags)
35 struct dom_sid zero_sid;
39 ZERO_STRUCT(zero_sid);
41 if (memcmp(&zero_sid, sid, sizeof(zero_sid)) == 0) {
45 return 8 + 4*sid->num_auths;
48 size_t ndr_size_dom_sid0(const struct dom_sid *sid, int flags)
50 return ndr_size_dom_sid28(sid, flags);
53 enum ndr_err_code ndr_push_dom_sid(struct ndr_push *ndr, int ndr_flags, const struct dom_sid *r)
55 uint32_t cntr_sub_auths_0;
56 if (ndr_flags & NDR_SCALARS) {
57 NDR_CHECK(ndr_push_align(ndr, 4));
58 NDR_CHECK(ndr_push_uint8(ndr, NDR_SCALARS, r->sid_rev_num));
59 NDR_CHECK(ndr_push_int8(ndr, NDR_SCALARS, r->num_auths));
60 NDR_CHECK(ndr_push_array_uint8(ndr, NDR_SCALARS, r->id_auth, 6));
61 for (cntr_sub_auths_0 = 0; cntr_sub_auths_0 < r->num_auths; cntr_sub_auths_0++) {
62 NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->sub_auths[cntr_sub_auths_0]));
65 if (ndr_flags & NDR_BUFFERS) {
67 return NDR_ERR_SUCCESS;
70 enum ndr_err_code ndr_pull_dom_sid(struct ndr_pull *ndr, int ndr_flags, struct dom_sid *r)
72 uint32_t cntr_sub_auths_0;
73 if (ndr_flags & NDR_SCALARS) {
74 NDR_CHECK(ndr_pull_align(ndr, 4));
75 NDR_CHECK(ndr_pull_uint8(ndr, NDR_SCALARS, &r->sid_rev_num));
76 NDR_CHECK(ndr_pull_uint8(ndr, NDR_SCALARS, &r->num_auths));
77 if (r->num_auths > 15) {
78 return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range");
80 NDR_CHECK(ndr_pull_array_uint8(ndr, NDR_SCALARS, r->id_auth, 6));
81 for (cntr_sub_auths_0 = 0; cntr_sub_auths_0 < r->num_auths; cntr_sub_auths_0++) {
82 NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->sub_auths[cntr_sub_auths_0]));
85 if (ndr_flags & NDR_BUFFERS) {
87 return NDR_ERR_SUCCESS;
91 convert a dom_sid to a string
93 char *dom_sid_string(TALLOC_CTX *mem_ctx, const struct dom_sid *sid)
100 return talloc_strdup(mem_ctx, "(NULL SID)");
103 maxlen = sid->num_auths * 11 + 25;
104 ret = (char *)talloc_size(mem_ctx, maxlen);
105 if (!ret) return talloc_strdup(mem_ctx, "(SID ERR)");
108 * BIG NOTE: this function only does SIDS where the identauth is not
109 * >= ^32 in a range of 2^48.
112 ia = (sid->id_auth[5]) +
113 (sid->id_auth[4] << 8 ) +
114 (sid->id_auth[3] << 16) +
115 (sid->id_auth[2] << 24);
117 ofs = snprintf(ret, maxlen, "S-%u-%lu",
118 (unsigned int)sid->sid_rev_num, (unsigned long)ia);
120 for (i = 0; i < sid->num_auths; i++) {
121 ofs += snprintf(ret + ofs, maxlen - ofs, "-%lu", (unsigned long)sid->sub_auths[i]);
128 parse a dom_sid2 - this is a dom_sid but with an extra copy of the num_auths field
130 enum ndr_err_code ndr_pull_dom_sid2(struct ndr_pull *ndr, int ndr_flags, struct dom_sid *sid)
133 if (!(ndr_flags & NDR_SCALARS)) {
134 return NDR_ERR_SUCCESS;
136 NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &num_auths));
137 NDR_CHECK(ndr_pull_dom_sid(ndr, ndr_flags, sid));
138 if (sid->num_auths != num_auths) {
139 return ndr_pull_error(ndr, NDR_ERR_ARRAY_SIZE,
140 "Bad array size %u should exceed %u",
141 num_auths, sid->num_auths);
143 return NDR_ERR_SUCCESS;
147 parse a dom_sid2 - this is a dom_sid but with an extra copy of the num_auths field
149 enum ndr_err_code ndr_push_dom_sid2(struct ndr_push *ndr, int ndr_flags, const struct dom_sid *sid)
151 if (!(ndr_flags & NDR_SCALARS)) {
152 return NDR_ERR_SUCCESS;
154 NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, sid->num_auths));
155 return ndr_push_dom_sid(ndr, ndr_flags, sid);
159 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
161 enum ndr_err_code ndr_pull_dom_sid28(struct ndr_pull *ndr, int ndr_flags, struct dom_sid *sid)
163 enum ndr_err_code status;
164 struct ndr_pull *subndr;
166 if (!(ndr_flags & NDR_SCALARS)) {
167 return NDR_ERR_SUCCESS;
170 subndr = talloc_zero(ndr, struct ndr_pull);
171 NDR_ERR_HAVE_NO_MEMORY(subndr);
172 subndr->flags = ndr->flags;
173 subndr->current_mem_ctx = ndr->current_mem_ctx;
175 subndr->data = ndr->data + ndr->offset;
176 subndr->data_size = 28;
179 NDR_CHECK(ndr_pull_advance(ndr, 28));
181 status = ndr_pull_dom_sid(subndr, ndr_flags, sid);
182 if (!NDR_ERR_CODE_IS_SUCCESS(status)) {
183 /* handle a w2k bug which send random data in the buffer */
187 return NDR_ERR_SUCCESS;
191 push a dom_sid28 - this is a dom_sid in a 28 byte fixed buffer
193 enum ndr_err_code ndr_push_dom_sid28(struct ndr_push *ndr, int ndr_flags, const struct dom_sid *sid)
198 if (!(ndr_flags & NDR_SCALARS)) {
199 return NDR_ERR_SUCCESS;
202 if (sid->num_auths > 5) {
203 return ndr_push_error(ndr, NDR_ERR_RANGE,
204 "dom_sid28 allows only upto 5 sub auth [%u]",
208 old_offset = ndr->offset;
209 NDR_CHECK(ndr_push_dom_sid(ndr, ndr_flags, sid));
211 padding = 28 - (ndr->offset - old_offset);
214 NDR_CHECK(ndr_push_zero(ndr, padding));
217 return NDR_ERR_SUCCESS;
221 parse a dom_sid0 - this is a dom_sid in a variable byte buffer, which is maybe empty
223 enum ndr_err_code ndr_pull_dom_sid0(struct ndr_pull *ndr, int ndr_flags, struct dom_sid *sid)
225 if (!(ndr_flags & NDR_SCALARS)) {
226 return NDR_ERR_SUCCESS;
229 if (ndr->data_size == ndr->offset) {
231 return NDR_ERR_SUCCESS;
234 return ndr_pull_dom_sid(ndr, ndr_flags, sid);
238 push a dom_sid0 - this is a dom_sid in a variable byte buffer, which is maybe empty
240 enum ndr_err_code ndr_push_dom_sid0(struct ndr_push *ndr, int ndr_flags, const struct dom_sid *sid)
242 struct dom_sid zero_sid;
244 if (!(ndr_flags & NDR_SCALARS)) {
245 return NDR_ERR_SUCCESS;
249 return NDR_ERR_SUCCESS;
252 ZERO_STRUCT(zero_sid);
254 if (memcmp(&zero_sid, sid, sizeof(zero_sid)) == 0) {
255 return NDR_ERR_SUCCESS;
258 return ndr_push_dom_sid(ndr, ndr_flags, sid);
264 void ndr_print_dom_sid(struct ndr_print *ndr, const char *name, const struct dom_sid *sid)
266 ndr->print(ndr, "%-25s: %s", name, dom_sid_string(ndr, sid));
269 void ndr_print_dom_sid2(struct ndr_print *ndr, const char *name, const struct dom_sid *sid)
271 ndr_print_dom_sid(ndr, name, sid);
274 void ndr_print_dom_sid28(struct ndr_print *ndr, const char *name, const struct dom_sid *sid)
276 ndr_print_dom_sid(ndr, name, sid);
279 void ndr_print_dom_sid0(struct ndr_print *ndr, const char *name, const struct dom_sid *sid)
281 ndr_print_dom_sid(ndr, name, sid);