s3:dom_sid Global replace of DOM_SID with struct dom_sid
[bbaumbach/samba-autobuild/.git] / source3 / lib / netapi / samr.c
1 /*
2  *  Unix SMB/CIFS implementation.
3  *  NetApi Samr Support
4  *  Copyright (C) Guenther Deschner 2008
5  *
6  *  This program is free software; you can redistribute it and/or modify
7  *  it under the terms of the GNU General Public License as published by
8  *  the Free Software Foundation; either version 3 of the License, or
9  *  (at your option) any later version.
10  *
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License
17  *  along with this program; if not, see <http://www.gnu.org/licenses/>.
18  */
19
20 #include "includes.h"
21 #include "lib/netapi/netapi.h"
22 #include "lib/netapi/netapi_private.h"
23 #include "../librpc/gen_ndr/cli_samr.h"
24 #include "rpc_client/cli_samr.h"
25
26 /****************************************************************
27 ****************************************************************/
28
29 WERROR libnetapi_samr_open_domain(struct libnetapi_ctx *mem_ctx,
30                                   struct rpc_pipe_client *pipe_cli,
31                                   uint32_t connect_mask,
32                                   uint32_t domain_mask,
33                                   struct policy_handle *connect_handle,
34                                   struct policy_handle *domain_handle,
35                                   struct dom_sid2 **domain_sid)
36 {
37         NTSTATUS status;
38         WERROR werr;
39         struct libnetapi_private_ctx *priv;
40         uint32_t resume_handle = 0;
41         uint32_t num_entries = 0;
42         struct samr_SamArray *sam = NULL;
43         const char *domain_name = NULL;
44         struct lsa_String lsa_domain_name;
45         bool domain_found = true;
46         int i;
47
48         priv = talloc_get_type_abort(mem_ctx->private_data,
49                 struct libnetapi_private_ctx);
50
51         if (is_valid_policy_hnd(&priv->samr.connect_handle)) {
52                 if ((priv->samr.connect_mask & connect_mask) == connect_mask) {
53                         *connect_handle = priv->samr.connect_handle;
54                 } else {
55                         libnetapi_samr_close_connect_handle(mem_ctx,
56                                 &priv->samr.connect_handle);
57                 }
58         }
59
60         if (is_valid_policy_hnd(&priv->samr.domain_handle)) {
61                 if ((priv->samr.domain_mask & domain_mask) == domain_mask) {
62                         *domain_handle = priv->samr.domain_handle;
63                 } else {
64                         libnetapi_samr_close_domain_handle(mem_ctx,
65                                 &priv->samr.domain_handle);
66                 }
67         }
68
69         if (priv->samr.domain_sid) {
70                 *domain_sid = priv->samr.domain_sid;
71         }
72
73         if (is_valid_policy_hnd(&priv->samr.connect_handle) &&
74             ((priv->samr.connect_mask & connect_mask) == connect_mask) &&
75             is_valid_policy_hnd(&priv->samr.domain_handle) &&
76             (priv->samr.domain_mask & domain_mask) == domain_mask) {
77                 return WERR_OK;
78         }
79
80         if (!is_valid_policy_hnd(connect_handle)) {
81                 status = rpccli_try_samr_connects(pipe_cli, mem_ctx,
82                                                   connect_mask,
83                                                   connect_handle);
84                 if (!NT_STATUS_IS_OK(status)) {
85                         werr = ntstatus_to_werror(status);
86                         goto done;
87                 }
88         }
89
90         status = rpccli_samr_EnumDomains(pipe_cli, mem_ctx,
91                                          connect_handle,
92                                          &resume_handle,
93                                          &sam,
94                                          0xffffffff,
95                                          &num_entries);
96         if (!NT_STATUS_IS_OK(status)) {
97                 werr = ntstatus_to_werror(status);
98                 goto done;
99         }
100
101         for (i=0; i<num_entries; i++) {
102
103                 domain_name = sam->entries[i].name.string;
104
105                 if (strequal(domain_name, builtin_domain_name())) {
106                         continue;
107                 }
108
109                 domain_found = true;
110                 break;
111         }
112
113         if (!domain_found) {
114                 werr = WERR_NO_SUCH_DOMAIN;
115                 goto done;
116         }
117
118         init_lsa_String(&lsa_domain_name, domain_name);
119
120         status = rpccli_samr_LookupDomain(pipe_cli, mem_ctx,
121                                           connect_handle,
122                                           &lsa_domain_name,
123                                           domain_sid);
124         if (!NT_STATUS_IS_OK(status)) {
125                 werr = ntstatus_to_werror(status);
126                 goto done;
127         }
128
129         status = rpccli_samr_OpenDomain(pipe_cli, mem_ctx,
130                                         connect_handle,
131                                         domain_mask,
132                                         *domain_sid,
133                                         domain_handle);
134         if (!NT_STATUS_IS_OK(status)) {
135                 werr = ntstatus_to_werror(status);
136                 goto done;
137         }
138
139         priv->samr.cli                  = pipe_cli;
140
141         priv->samr.domain_name          = domain_name;
142         priv->samr.domain_sid           = *domain_sid;
143
144         priv->samr.connect_mask         = connect_mask;
145         priv->samr.connect_handle       = *connect_handle;
146
147         priv->samr.domain_mask          = domain_mask;
148         priv->samr.domain_handle        = *domain_handle;
149
150         werr = WERR_OK;
151
152  done:
153         return werr;
154 }
155
156 /****************************************************************
157 ****************************************************************/
158
159 WERROR libnetapi_samr_open_builtin_domain(struct libnetapi_ctx *mem_ctx,
160                                           struct rpc_pipe_client *pipe_cli,
161                                           uint32_t connect_mask,
162                                           uint32_t builtin_mask,
163                                           struct policy_handle *connect_handle,
164                                           struct policy_handle *builtin_handle)
165 {
166         NTSTATUS status;
167         WERROR werr;
168         struct libnetapi_private_ctx *priv;
169
170         priv = talloc_get_type_abort(mem_ctx->private_data,
171                 struct libnetapi_private_ctx);
172
173         if (is_valid_policy_hnd(&priv->samr.connect_handle)) {
174                 if ((priv->samr.connect_mask & connect_mask) == connect_mask) {
175                         *connect_handle = priv->samr.connect_handle;
176                 } else {
177                         libnetapi_samr_close_connect_handle(mem_ctx,
178                                 &priv->samr.connect_handle);
179                 }
180         }
181
182         if (is_valid_policy_hnd(&priv->samr.builtin_handle)) {
183                 if ((priv->samr.builtin_mask & builtin_mask) == builtin_mask) {
184                         *builtin_handle = priv->samr.builtin_handle;
185                 } else {
186                         libnetapi_samr_close_builtin_handle(mem_ctx,
187                                 &priv->samr.builtin_handle);
188                 }
189         }
190
191         if (is_valid_policy_hnd(&priv->samr.connect_handle) &&
192             ((priv->samr.connect_mask & connect_mask) == connect_mask) &&
193             is_valid_policy_hnd(&priv->samr.builtin_handle) &&
194             (priv->samr.builtin_mask & builtin_mask) == builtin_mask) {
195                 return WERR_OK;
196         }
197
198         if (!is_valid_policy_hnd(connect_handle)) {
199                 status = rpccli_try_samr_connects(pipe_cli, mem_ctx,
200                                                   connect_mask,
201                                                   connect_handle);
202                 if (!NT_STATUS_IS_OK(status)) {
203                         werr = ntstatus_to_werror(status);
204                         goto done;
205                 }
206         }
207
208         status = rpccli_samr_OpenDomain(pipe_cli, mem_ctx,
209                                         connect_handle,
210                                         builtin_mask,
211                                         CONST_DISCARD(struct dom_sid *, &global_sid_Builtin),
212                                         builtin_handle);
213         if (!NT_STATUS_IS_OK(status)) {
214                 werr = ntstatus_to_werror(status);
215                 goto done;
216         }
217
218         priv->samr.cli                  = pipe_cli;
219
220         priv->samr.connect_mask         = connect_mask;
221         priv->samr.connect_handle       = *connect_handle;
222
223         priv->samr.builtin_mask         = builtin_mask;
224         priv->samr.builtin_handle       = *builtin_handle;
225
226         werr = WERR_OK;
227
228  done:
229         return werr;
230 }
231
232 /****************************************************************
233 ****************************************************************/
234
235 void libnetapi_samr_close_domain_handle(struct libnetapi_ctx *ctx,
236                                         struct policy_handle *handle)
237 {
238         struct libnetapi_private_ctx *priv;
239
240         if (!is_valid_policy_hnd(handle)) {
241                 return;
242         }
243
244         priv = talloc_get_type_abort(ctx->private_data,
245                 struct libnetapi_private_ctx);
246
247         if (!policy_hnd_equal(handle, &priv->samr.domain_handle)) {
248                 return;
249         }
250
251         rpccli_samr_Close(priv->samr.cli, ctx, handle);
252
253         ZERO_STRUCT(priv->samr.domain_handle);
254 }
255
256 /****************************************************************
257 ****************************************************************/
258
259 void libnetapi_samr_close_builtin_handle(struct libnetapi_ctx *ctx,
260                                          struct policy_handle *handle)
261 {
262         struct libnetapi_private_ctx *priv;
263
264         if (!is_valid_policy_hnd(handle)) {
265                 return;
266         }
267
268         priv = talloc_get_type_abort(ctx->private_data,
269                 struct libnetapi_private_ctx);
270
271         if (!policy_hnd_equal(handle, &priv->samr.builtin_handle)) {
272                 return;
273         }
274
275         rpccli_samr_Close(priv->samr.cli, ctx, handle);
276
277         ZERO_STRUCT(priv->samr.builtin_handle);
278 }
279
280 /****************************************************************
281 ****************************************************************/
282
283 void libnetapi_samr_close_connect_handle(struct libnetapi_ctx *ctx,
284                                          struct policy_handle *handle)
285 {
286         struct libnetapi_private_ctx *priv;
287
288         if (!is_valid_policy_hnd(handle)) {
289                 return;
290         }
291
292         priv = talloc_get_type_abort(ctx->private_data,
293                 struct libnetapi_private_ctx);
294
295         if (!policy_hnd_equal(handle, &priv->samr.connect_handle)) {
296                 return;
297         }
298
299         rpccli_samr_Close(priv->samr.cli, ctx, handle);
300
301         ZERO_STRUCT(priv->samr.connect_handle);
302 }
303
304 /****************************************************************
305 ****************************************************************/
306
307 void libnetapi_samr_free(struct libnetapi_ctx *ctx)
308 {
309         struct libnetapi_private_ctx *priv;
310
311         if (!ctx->private_data) {
312                 return;
313         }
314
315         priv = talloc_get_type_abort(ctx->private_data,
316                 struct libnetapi_private_ctx);
317
318         libnetapi_samr_close_domain_handle(ctx, &priv->samr.domain_handle);
319         libnetapi_samr_close_builtin_handle(ctx, &priv->samr.builtin_handle);
320         libnetapi_samr_close_connect_handle(ctx, &priv->samr.connect_handle);
321 }