source: trunk/samba/source/librpc/ndr/sid.c @ 26

Last change on this file since 26 was 26, checked in by Paul Smedley, 14 years ago

Updated source to 3.0.25rc1

File size: 7.4 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 2 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, write to the Free Software
20   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21*/
22
23#include "includes.h"
24
25NTSTATUS ndr_push_dom_sid(struct ndr_push *ndr, int ndr_flags, const struct dom_sid *r)
26{
27        uint32_t cntr_sub_auths_0;
28        if (ndr_flags & NDR_SCALARS) {
29                NDR_CHECK(ndr_push_align(ndr, 4));
30                NDR_CHECK(ndr_push_uint8(ndr, NDR_SCALARS, r->sid_rev_num));
31                NDR_CHECK(ndr_push_int8(ndr, NDR_SCALARS, r->num_auths));
32                NDR_CHECK(ndr_push_array_uint8(ndr, NDR_SCALARS, r->id_auth, 6));
33                for (cntr_sub_auths_0 = 0; cntr_sub_auths_0 < r->num_auths; cntr_sub_auths_0++) {
34                        NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->sub_auths[cntr_sub_auths_0]));
35                }
36        }
37        if (ndr_flags & NDR_BUFFERS) {
38        }
39        return NT_STATUS_OK;
40}
41
42NTSTATUS ndr_pull_dom_sid(struct ndr_pull *ndr, int ndr_flags, struct dom_sid *r)
43{
44        uint32_t cntr_sub_auths_0;
45        if (ndr_flags & NDR_SCALARS) {
46                NDR_CHECK(ndr_pull_align(ndr, 4));
47                NDR_CHECK(ndr_pull_uint8(ndr, NDR_SCALARS, &r->sid_rev_num));
48                NDR_CHECK(ndr_pull_uint8(ndr, NDR_SCALARS, &r->num_auths));
49                if (r->num_auths > 15) {
50                        return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range");
51                }
52                NDR_CHECK(ndr_pull_array_uint8(ndr, NDR_SCALARS, r->id_auth, 6));
53                for (cntr_sub_auths_0 = 0; cntr_sub_auths_0 < r->num_auths; cntr_sub_auths_0++) {
54                        NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->sub_auths[cntr_sub_auths_0]));
55                }
56        }
57        if (ndr_flags & NDR_BUFFERS) {
58        }
59        return NT_STATUS_OK;
60}
61
62/*
63  convert a dom_sid to a string
64*/
65char *dom_sid_string(TALLOC_CTX *mem_ctx, const struct dom_sid *sid)
66{
67        int i, ofs, maxlen;
68        uint32_t ia;
69        char *ret;
70       
71        if (!sid) {
72                return talloc_strdup(mem_ctx, "(NULL SID)");
73        }
74
75        maxlen = sid->num_auths * 11 + 25;
76        ret = (char *)talloc_size(mem_ctx, maxlen);
77        if (!ret) return talloc_strdup(mem_ctx, "(SID ERR)");
78
79        ia = (sid->id_auth[5]) +
80                (sid->id_auth[4] << 8 ) +
81                (sid->id_auth[3] << 16) +
82                (sid->id_auth[2] << 24);
83
84        ofs = snprintf(ret, maxlen, "S-%u-%lu", 
85                       (unsigned int)sid->sid_rev_num, (unsigned long)ia);
86
87        for (i = 0; i < sid->num_auths; i++) {
88                ofs += snprintf(ret + ofs, maxlen - ofs, "-%lu", (unsigned long)sid->sub_auths[i]);
89        }
90       
91        return ret;
92}
93
94/*
95  parse a dom_sid2 - this is a dom_sid but with an extra copy of the num_auths field
96*/
97NTSTATUS ndr_pull_dom_sid2(struct ndr_pull *ndr, int ndr_flags, struct dom_sid *sid)
98{
99        uint32_t num_auths;
100        if (!(ndr_flags & NDR_SCALARS)) {
101                return NT_STATUS_OK;
102        }
103        NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &num_auths));
104        NDR_CHECK(ndr_pull_dom_sid(ndr, ndr_flags, sid));
105        if (sid->num_auths != num_auths) {
106                return ndr_pull_error(ndr, NDR_ERR_ARRAY_SIZE, 
107                                      "Bad array size %u should exceed %u", 
108                                      num_auths, sid->num_auths);
109        }
110        return NT_STATUS_OK;
111}
112
113/*
114  parse a dom_sid2 - this is a dom_sid but with an extra copy of the num_auths field
115*/
116NTSTATUS ndr_push_dom_sid2(struct ndr_push *ndr, int ndr_flags, const struct dom_sid *sid)
117{
118        if (!(ndr_flags & NDR_SCALARS)) {
119                return NT_STATUS_OK;
120        }
121        NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, sid->num_auths));
122        return ndr_push_dom_sid(ndr, ndr_flags, sid);
123}
124
125/*
126  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
127*/
128NTSTATUS ndr_pull_dom_sid28(struct ndr_pull *ndr, int ndr_flags, struct dom_sid *sid)
129{
130        NTSTATUS status;
131        struct ndr_pull *subndr;
132
133        if (!(ndr_flags & NDR_SCALARS)) {
134                return NT_STATUS_OK;
135        }
136
137        subndr = talloc_zero(ndr, struct ndr_pull);
138        NT_STATUS_HAVE_NO_MEMORY(subndr);
139        subndr->flags           = ndr->flags;
140        subndr->current_mem_ctx = ndr->current_mem_ctx;
141
142        subndr->data            = ndr->data + ndr->offset;
143        subndr->data_size       = 28;
144        subndr->offset          = 0;
145
146        NDR_CHECK(ndr_pull_advance(ndr, 28));
147
148        status = ndr_pull_dom_sid(subndr, ndr_flags, sid);
149        if (!NT_STATUS_IS_OK(status)) {
150                /* handle a w2k bug which send random data in the buffer */
151                ZERO_STRUCTP(sid);
152        }
153
154        return NT_STATUS_OK;
155}
156
157/*
158  push a dom_sid28 - this is a dom_sid in a 28 byte fixed buffer
159*/
160NTSTATUS ndr_push_dom_sid28(struct ndr_push *ndr, int ndr_flags, const struct dom_sid *sid)
161{
162        uint32_t old_offset;
163        uint32_t padding;
164
165        if (!(ndr_flags & NDR_SCALARS)) {
166                return NT_STATUS_OK;
167        }
168
169        if (sid->num_auths > 5) {
170                return ndr_push_error(ndr, NDR_ERR_RANGE, 
171                                      "dom_sid28 allows only upto 5 sub auth [%u]", 
172                                      sid->num_auths);
173        }
174
175        old_offset = ndr->offset;
176        NDR_CHECK(ndr_push_dom_sid(ndr, ndr_flags, sid));
177
178        padding = 28 - (ndr->offset - old_offset);
179
180        if (padding > 0) {
181                NDR_CHECK(ndr_push_zero(ndr, padding));
182        }
183
184        return NT_STATUS_OK;
185}
186
187NTSTATUS ndr_push_sec_desc_buf(struct ndr_push *ndr, int ndr_flags, const struct sec_desc_buf *r)
188{
189        if (ndr_flags & NDR_SCALARS) {
190                NDR_CHECK(ndr_push_align(ndr, 4));
191                NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_size_security_descriptor(r->sd,ndr->flags)));
192                NDR_CHECK(ndr_push_unique_ptr(ndr, r->sd));
193        }
194        if (ndr_flags & NDR_BUFFERS) {
195                if (r->sd) {
196                        {
197                                struct ndr_push *_ndr_sd;
198                                NDR_CHECK(ndr_push_subcontext_start(ndr, &_ndr_sd, 4, -1));
199                                NDR_CHECK(ndr_push_security_descriptor(_ndr_sd, NDR_SCALARS|NDR_BUFFERS, r->sd));
200                                NDR_CHECK(ndr_push_subcontext_end(ndr, _ndr_sd, 4, -1));
201                        }
202                }
203        }
204        return NT_STATUS_OK;
205}
206
207NTSTATUS ndr_pull_sec_desc_buf(struct ndr_pull *ndr, int ndr_flags, struct sec_desc_buf *r)
208{
209        uint32_t _ptr_sd;
210        TALLOC_CTX *_mem_save_sd_0;
211        if (ndr_flags & NDR_SCALARS) {
212                NDR_CHECK(ndr_pull_align(ndr, 4));
213                NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->sd_size));
214                if (r->sd_size > 0x40000) { /* sd_size is unsigned */
215                        return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range");
216                }
217                NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_sd));
218                if (_ptr_sd) {
219                        NDR_PULL_ALLOC(ndr, r->sd);
220                } else {
221                        r->sd = NULL;
222                }
223        }
224        if (ndr_flags & NDR_BUFFERS) {
225                if (r->sd) {
226                        _mem_save_sd_0 = NDR_PULL_GET_MEM_CTX(ndr);
227                        NDR_PULL_SET_MEM_CTX(ndr, r->sd, 0);
228                        {
229                                struct ndr_pull *_ndr_sd;
230                                NDR_CHECK(ndr_pull_subcontext_start(ndr, &_ndr_sd, 4, -1));
231                                NDR_CHECK(ndr_pull_security_descriptor(_ndr_sd, NDR_SCALARS|NDR_BUFFERS, r->sd));
232                                NDR_CHECK(ndr_pull_subcontext_end(ndr, _ndr_sd, 4, -1));
233                        }
234                        NDR_PULL_SET_MEM_CTX(ndr, _mem_save_sd_0, 0);
235                }
236        }
237        return NT_STATUS_OK;
238}
239
240void ndr_print_sec_desc_buf(struct ndr_print *ndr, const char *name, const struct sec_desc_buf *r)
241{
242        ndr_print_struct(ndr, name, "sec_desc_buf");
243        ndr->depth++;
244        ndr_print_uint32(ndr, "sd_size", (ndr->flags & LIBNDR_PRINT_SET_VALUES)?ndr_size_security_descriptor(r->sd,ndr->flags):r->sd_size);
245        ndr_print_ptr(ndr, "sd", r->sd);
246        ndr->depth++;
247        if (r->sd) {
248                ndr_print_security_descriptor(ndr, "sd", r->sd);
249        }
250        ndr->depth--;
251        ndr->depth--;
252}
Note: See TracBrowser for help on using the repository browser.