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/>.
24 enum ndr_err_code
ndr_push_dom_sid(struct ndr_push
*ndr
, int ndr_flags
, const struct dom_sid
*r
)
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
]));
36 if (ndr_flags
& NDR_BUFFERS
) {
38 return NDR_ERR_SUCCESS
;
41 enum ndr_err_code
ndr_pull_dom_sid(struct ndr_pull
*ndr
, int ndr_flags
, struct dom_sid
*r
)
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");
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
]));
56 if (ndr_flags
& NDR_BUFFERS
) {
58 return NDR_ERR_SUCCESS
;
62 convert a dom_sid to a string
64 char *dom_sid_string(TALLOC_CTX
*mem_ctx
, const struct dom_sid
*sid
)
71 return talloc_strdup(mem_ctx
, "(NULL SID)");
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)");
79 * BIG NOTE: this function only does SIDS where the identauth is not
80 * >= ^32 in a range of 2^48.
83 ia
= (sid
->id_auth
[5]) +
84 (sid
->id_auth
[4] << 8 ) +
85 (sid
->id_auth
[3] << 16) +
86 (sid
->id_auth
[2] << 24);
88 ofs
= snprintf(ret
, maxlen
, "S-%u-%lu",
89 (unsigned int)sid
->sid_rev_num
, (unsigned long)ia
);
91 for (i
= 0; i
< sid
->num_auths
; i
++) {
92 ofs
+= snprintf(ret
+ ofs
, maxlen
- ofs
, "-%lu", (unsigned long)sid
->sub_auths
[i
]);
99 parse a dom_sid2 - this is a dom_sid but with an extra copy of the num_auths field
101 enum ndr_err_code
ndr_pull_dom_sid2(struct ndr_pull
*ndr
, int ndr_flags
, struct dom_sid
*sid
)
104 if (!(ndr_flags
& NDR_SCALARS
)) {
105 return NDR_ERR_SUCCESS
;
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
);
114 return NDR_ERR_SUCCESS
;
118 parse a dom_sid2 - this is a dom_sid but with an extra copy of the num_auths field
120 enum ndr_err_code
ndr_push_dom_sid2(struct ndr_push
*ndr
, int ndr_flags
, const struct dom_sid
*sid
)
122 if (!(ndr_flags
& NDR_SCALARS
)) {
123 return NDR_ERR_SUCCESS
;
125 NDR_CHECK(ndr_push_uint32(ndr
, NDR_SCALARS
, sid
->num_auths
));
126 return ndr_push_dom_sid(ndr
, ndr_flags
, sid
);
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
132 enum ndr_err_code
ndr_pull_dom_sid28(struct ndr_pull
*ndr
, int ndr_flags
, struct dom_sid
*sid
)
134 enum ndr_err_code status
;
135 struct ndr_pull
*subndr
;
137 if (!(ndr_flags
& NDR_SCALARS
)) {
138 return NDR_ERR_SUCCESS
;
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
;
146 subndr
->data
= ndr
->data
+ ndr
->offset
;
147 subndr
->data_size
= 28;
150 NDR_CHECK(ndr_pull_advance(ndr
, 28));
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 */
158 return NDR_ERR_SUCCESS
;
162 push a dom_sid28 - this is a dom_sid in a 28 byte fixed buffer
164 enum ndr_err_code
ndr_push_dom_sid28(struct ndr_push
*ndr
, int ndr_flags
, const struct dom_sid
*sid
)
169 if (!(ndr_flags
& NDR_SCALARS
)) {
170 return NDR_ERR_SUCCESS
;
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]",
179 old_offset
= ndr
->offset
;
180 NDR_CHECK(ndr_push_dom_sid(ndr
, ndr_flags
, sid
));
182 padding
= 28 - (ndr
->offset
- old_offset
);
185 NDR_CHECK(ndr_push_zero(ndr
, padding
));
188 return NDR_ERR_SUCCESS
;
192 parse a dom_sid0 - this is a dom_sid in a variable byte buffer, which is maybe empty
194 enum ndr_err_code
ndr_pull_dom_sid0(struct ndr_pull
*ndr
, int ndr_flags
, struct dom_sid
*sid
)
196 if (!(ndr_flags
& NDR_SCALARS
)) {
197 return NDR_ERR_SUCCESS
;
200 if (ndr
->data_size
== ndr
->offset
) {
202 return NDR_ERR_SUCCESS
;
205 return ndr_pull_dom_sid(ndr
, ndr_flags
, sid
);
209 push a dom_sid0 - this is a dom_sid in a variable byte buffer, which is maybe empty
211 enum ndr_err_code
ndr_push_dom_sid0(struct ndr_push
*ndr
, int ndr_flags
, const struct dom_sid
*sid
)
213 struct dom_sid zero_sid
;
215 if (!(ndr_flags
& NDR_SCALARS
)) {
216 return NDR_ERR_SUCCESS
;
220 return NDR_ERR_SUCCESS
;
223 ZERO_STRUCT(zero_sid
);
225 if (memcmp(&zero_sid
, sid
, sizeof(zero_sid
)) == 0) {
226 return NDR_ERR_SUCCESS
;
229 return ndr_push_dom_sid(ndr
, ndr_flags
, sid
);