s3-lsa: separate out init_lsa headers.
[ab/samba.git/.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 #include "rpc_client/init_lsa.h"
26
27 /****************************************************************
28 ****************************************************************/
29
30 WERROR libnetapi_samr_open_domain(struct libnetapi_ctx *mem_ctx,
31                                   struct rpc_pipe_client *pipe_cli,
32                                   uint32_t connect_mask,
33                                   uint32_t domain_mask,
34                                   struct policy_handle *connect_handle,
35                                   struct policy_handle *domain_handle,
36                                   struct dom_sid2 **domain_sid)
37 {
38         NTSTATUS status;
39         WERROR werr;
40         struct libnetapi_private_ctx *priv;
41         uint32_t resume_handle = 0;
42         uint32_t num_entries = 0;
43         struct samr_SamArray *sam = NULL;
44         const char *domain_name = NULL;
45         struct lsa_String lsa_domain_name;
46         bool domain_found = true;
47         int i;
48
49         priv = talloc_get_type_abort(mem_ctx->private_data,
50                 struct libnetapi_private_ctx);
51
52         if (is_valid_policy_hnd(&priv->samr.connect_handle)) {
53                 if ((priv->samr.connect_mask & connect_mask) == connect_mask) {
54                         *connect_handle = priv->samr.connect_handle;
55                 } else {
56                         libnetapi_samr_close_connect_handle(mem_ctx,
57                                 &priv->samr.connect_handle);
58                 }
59         }
60
61         if (is_valid_policy_hnd(&priv->samr.domain_handle)) {
62                 if ((priv->samr.domain_mask & domain_mask) == domain_mask) {
63                         *domain_handle = priv->samr.domain_handle;
64                 } else {
65                         libnetapi_samr_close_domain_handle(mem_ctx,
66                                 &priv->samr.domain_handle);
67                 }
68         }
69
70         if (priv->samr.domain_sid) {
71                 *domain_sid = priv->samr.domain_sid;
72         }
73
74         if (is_valid_policy_hnd(&priv->samr.connect_handle) &&
75             ((priv->samr.connect_mask & connect_mask) == connect_mask) &&
76             is_valid_policy_hnd(&priv->samr.domain_handle) &&
77             (priv->samr.domain_mask & domain_mask) == domain_mask) {
78                 return WERR_OK;
79         }
80
81         if (!is_valid_policy_hnd(connect_handle)) {
82                 status = rpccli_try_samr_connects(pipe_cli, mem_ctx,
83                                                   connect_mask,
84                                                   connect_handle);
85                 if (!NT_STATUS_IS_OK(status)) {
86                         werr = ntstatus_to_werror(status);
87                         goto done;
88                 }
89         }
90
91         status = rpccli_samr_EnumDomains(pipe_cli, mem_ctx,
92                                          connect_handle,
93                                          &resume_handle,
94                                          &sam,
95                                          0xffffffff,
96                                          &num_entries);
97         if (!NT_STATUS_IS_OK(status)) {
98                 werr = ntstatus_to_werror(status);
99                 goto done;
100         }
101
102         for (i=0; i<num_entries; i++) {
103
104                 domain_name = sam->entries[i].name.string;
105
106                 if (strequal(domain_name, builtin_domain_name())) {
107                         continue;
108                 }
109
110                 domain_found = true;
111                 break;
112         }
113
114         if (!domain_found) {
115                 werr = WERR_NO_SUCH_DOMAIN;
116                 goto done;
117         }
118
119         init_lsa_String(&lsa_domain_name, domain_name);
120
121         status = rpccli_samr_LookupDomain(pipe_cli, mem_ctx,
122                                           connect_handle,
123                                           &lsa_domain_name,
124                                           domain_sid);
125         if (!NT_STATUS_IS_OK(status)) {
126                 werr = ntstatus_to_werror(status);
127                 goto done;
128         }
129
130         status = rpccli_samr_OpenDomain(pipe_cli, mem_ctx,
131                                         connect_handle,
132                                         domain_mask,
133                                         *domain_sid,
134                                         domain_handle);
135         if (!NT_STATUS_IS_OK(status)) {
136                 werr = ntstatus_to_werror(status);
137                 goto done;
138         }
139
140         priv->samr.cli                  = pipe_cli;
141
142         priv->samr.domain_name          = domain_name;
143         priv->samr.domain_sid           = *domain_sid;
144
145         priv->samr.connect_mask         = connect_mask;
146         priv->samr.connect_handle       = *connect_handle;
147
148         priv->samr.domain_mask          = domain_mask;
149         priv->samr.domain_handle        = *domain_handle;
150
151         werr = WERR_OK;
152
153  done:
154         return werr;
155 }
156
157 /****************************************************************
158 ****************************************************************/
159
160 WERROR libnetapi_samr_open_builtin_domain(struct libnetapi_ctx *mem_ctx,
161                                           struct rpc_pipe_client *pipe_cli,
162                                           uint32_t connect_mask,
163                                           uint32_t builtin_mask,
164                                           struct policy_handle *connect_handle,
165                                           struct policy_handle *builtin_handle)
166 {
167         NTSTATUS status;
168         WERROR werr;
169         struct libnetapi_private_ctx *priv;
170
171         priv = talloc_get_type_abort(mem_ctx->private_data,
172                 struct libnetapi_private_ctx);
173
174         if (is_valid_policy_hnd(&priv->samr.connect_handle)) {
175                 if ((priv->samr.connect_mask & connect_mask) == connect_mask) {
176                         *connect_handle = priv->samr.connect_handle;
177                 } else {
178                         libnetapi_samr_close_connect_handle(mem_ctx,
179                                 &priv->samr.connect_handle);
180                 }
181         }
182
183         if (is_valid_policy_hnd(&priv->samr.builtin_handle)) {
184                 if ((priv->samr.builtin_mask & builtin_mask) == builtin_mask) {
185                         *builtin_handle = priv->samr.builtin_handle;
186                 } else {
187                         libnetapi_samr_close_builtin_handle(mem_ctx,
188                                 &priv->samr.builtin_handle);
189                 }
190         }
191
192         if (is_valid_policy_hnd(&priv->samr.connect_handle) &&
193             ((priv->samr.connect_mask & connect_mask) == connect_mask) &&
194             is_valid_policy_hnd(&priv->samr.builtin_handle) &&
195             (priv->samr.builtin_mask & builtin_mask) == builtin_mask) {
196                 return WERR_OK;
197         }
198
199         if (!is_valid_policy_hnd(connect_handle)) {
200                 status = rpccli_try_samr_connects(pipe_cli, mem_ctx,
201                                                   connect_mask,
202                                                   connect_handle);
203                 if (!NT_STATUS_IS_OK(status)) {
204                         werr = ntstatus_to_werror(status);
205                         goto done;
206                 }
207         }
208
209         status = rpccli_samr_OpenDomain(pipe_cli, mem_ctx,
210                                         connect_handle,
211                                         builtin_mask,
212                                         CONST_DISCARD(struct dom_sid *, &global_sid_Builtin),
213                                         builtin_handle);
214         if (!NT_STATUS_IS_OK(status)) {
215                 werr = ntstatus_to_werror(status);
216                 goto done;
217         }
218
219         priv->samr.cli                  = pipe_cli;
220
221         priv->samr.connect_mask         = connect_mask;
222         priv->samr.connect_handle       = *connect_handle;
223
224         priv->samr.builtin_mask         = builtin_mask;
225         priv->samr.builtin_handle       = *builtin_handle;
226
227         werr = WERR_OK;
228
229  done:
230         return werr;
231 }
232
233 /****************************************************************
234 ****************************************************************/
235
236 void libnetapi_samr_close_domain_handle(struct libnetapi_ctx *ctx,
237                                         struct policy_handle *handle)
238 {
239         struct libnetapi_private_ctx *priv;
240
241         if (!is_valid_policy_hnd(handle)) {
242                 return;
243         }
244
245         priv = talloc_get_type_abort(ctx->private_data,
246                 struct libnetapi_private_ctx);
247
248         if (!policy_hnd_equal(handle, &priv->samr.domain_handle)) {
249                 return;
250         }
251
252         rpccli_samr_Close(priv->samr.cli, ctx, handle);
253
254         ZERO_STRUCT(priv->samr.domain_handle);
255 }
256
257 /****************************************************************
258 ****************************************************************/
259
260 void libnetapi_samr_close_builtin_handle(struct libnetapi_ctx *ctx,
261                                          struct policy_handle *handle)
262 {
263         struct libnetapi_private_ctx *priv;
264
265         if (!is_valid_policy_hnd(handle)) {
266                 return;
267         }
268
269         priv = talloc_get_type_abort(ctx->private_data,
270                 struct libnetapi_private_ctx);
271
272         if (!policy_hnd_equal(handle, &priv->samr.builtin_handle)) {
273                 return;
274         }
275
276         rpccli_samr_Close(priv->samr.cli, ctx, handle);
277
278         ZERO_STRUCT(priv->samr.builtin_handle);
279 }
280
281 /****************************************************************
282 ****************************************************************/
283
284 void libnetapi_samr_close_connect_handle(struct libnetapi_ctx *ctx,
285                                          struct policy_handle *handle)
286 {
287         struct libnetapi_private_ctx *priv;
288
289         if (!is_valid_policy_hnd(handle)) {
290                 return;
291         }
292
293         priv = talloc_get_type_abort(ctx->private_data,
294                 struct libnetapi_private_ctx);
295
296         if (!policy_hnd_equal(handle, &priv->samr.connect_handle)) {
297                 return;
298         }
299
300         rpccli_samr_Close(priv->samr.cli, ctx, handle);
301
302         ZERO_STRUCT(priv->samr.connect_handle);
303 }
304
305 /****************************************************************
306 ****************************************************************/
307
308 void libnetapi_samr_free(struct libnetapi_ctx *ctx)
309 {
310         struct libnetapi_private_ctx *priv;
311
312         if (!ctx->private_data) {
313                 return;
314         }
315
316         priv = talloc_get_type_abort(ctx->private_data,
317                 struct libnetapi_private_ctx);
318
319         libnetapi_samr_close_domain_handle(ctx, &priv->samr.domain_handle);
320         libnetapi_samr_close_builtin_handle(ctx, &priv->samr.builtin_handle);
321         libnetapi_samr_close_connect_handle(ctx, &priv->samr.connect_handle);
322 }