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