Remove unrequired TALLOC_CTX from libnetapi_NetJoinDomain & friends.
[ira/wip.git] / source3 / lib / netapi / joindomain.c
1 /*
2  *  Unix SMB/CIFS implementation.
3  *  NetApi Join Support
4  *  Copyright (C) Guenther Deschner 2007
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
22 #include "lib/netapi/netapi.h"
23 #include "libnet/libnet.h"
24
25 static WERROR NetJoinDomainLocal(struct libnetapi_ctx *mem_ctx,
26                                  const char *server_name,
27                                  const char *domain_name,
28                                  const char *account_ou,
29                                  const char *Account,
30                                  const char *password,
31                                  uint32_t join_flags)
32 {
33         struct libnet_JoinCtx *r = NULL;
34         WERROR werr;
35
36         werr = libnet_init_JoinCtx(mem_ctx, &r);
37         W_ERROR_NOT_OK_RETURN(werr);
38
39         if (!domain_name) {
40                 return WERR_INVALID_PARAM;
41         }
42
43         r->in.domain_name = talloc_strdup(mem_ctx, domain_name);
44         W_ERROR_HAVE_NO_MEMORY(r->in.domain_name);
45
46         if (join_flags & WKSSVC_JOIN_FLAGS_JOIN_TYPE) {
47                 NTSTATUS status;
48                 struct DS_DOMAIN_CONTROLLER_INFO *info = NULL;
49                 uint32_t flags = DS_DIRECTORY_SERVICE_REQUIRED |
50                                  DS_WRITABLE_REQUIRED |
51                                  DS_RETURN_DNS_NAME;
52                 status = DsGetDcName(mem_ctx, NULL, domain_name,
53                                      NULL, NULL, flags, &info);
54                 if (!NT_STATUS_IS_OK(status)) {
55                         return ntstatus_to_werror(status);
56                 }
57                 r->in.server_name = talloc_strdup(mem_ctx, info->domain_controller_name);
58                 W_ERROR_HAVE_NO_MEMORY(r->in.server_name);
59         }
60
61         if (account_ou) {
62                 r->in.account_ou = talloc_strdup(mem_ctx, account_ou);
63                 W_ERROR_HAVE_NO_MEMORY(r->in.account_ou);
64         }
65
66         if (Account) {
67                 r->in.admin_account = talloc_strdup(mem_ctx, Account);
68                 W_ERROR_HAVE_NO_MEMORY(r->in.admin_account);
69         }
70
71         if (password) {
72                 r->in.password = talloc_strdup(mem_ctx, password);
73                 W_ERROR_HAVE_NO_MEMORY(r->in.password);
74         }
75
76         r->in.join_flags = join_flags;
77         r->in.modify_config = true;
78
79         return libnet_Join(mem_ctx, r);
80 }
81
82 static WERROR NetJoinDomainRemote(struct libnetapi_ctx *ctx,
83                                   const char *server_name,
84                                   const char *domain_name,
85                                   const char *account_ou,
86                                   const char *Account,
87                                   const char *password,
88                                   uint32_t join_flags)
89 {
90         struct cli_state *cli = NULL;
91         struct rpc_pipe_client *pipe_cli = NULL;
92         struct wkssvc_PasswordBuffer encrypted_password;
93         NTSTATUS status;
94         WERROR werr;
95         unsigned int old_timeout = 0;
96
97         ZERO_STRUCT(encrypted_password);
98
99         status = cli_full_connection(&cli, NULL, server_name,
100                                      NULL, 0,
101                                      "IPC$", "IPC",
102                                      ctx->username,
103                                      ctx->workgroup,
104                                      ctx->password,
105                                      0, Undefined, NULL);
106
107         if (!NT_STATUS_IS_OK(status)) {
108                 werr = ntstatus_to_werror(status);
109                 goto done;
110         }
111
112         old_timeout = cli_set_timeout(cli, 60000);
113
114         pipe_cli = cli_rpc_pipe_open_noauth(cli, PI_WKSSVC,
115                                             &status);
116         if (!pipe_cli) {
117                 werr = ntstatus_to_werror(status);
118                 goto done;
119         };
120
121         if (password) {
122                 encode_wkssvc_join_password_buffer(ctx,
123                                                    password,
124                                                    &cli->user_session_key,
125                                                    &encrypted_password);
126         }
127
128         old_timeout = cli_set_timeout(cli, 60000);
129
130         status = rpccli_wkssvc_NetrJoinDomain2(pipe_cli, ctx,
131                                                server_name, domain_name,
132                                                account_ou, Account,
133                                                &encrypted_password,
134                                                join_flags, &werr);
135         if (!NT_STATUS_IS_OK(status)) {
136                 werr = ntstatus_to_werror(status);
137                 goto done;
138         }
139
140  done:
141         if (cli) {
142                 cli_set_timeout(cli, old_timeout);
143                 cli_shutdown(cli);
144         }
145
146         return werr;
147 }
148
149 static WERROR libnetapi_NetJoinDomain(struct libnetapi_ctx *ctx,
150                                       const char *server_name,
151                                       const char *domain_name,
152                                       const char *account_ou,
153                                       const char *Account,
154                                       const char *password,
155                                       uint32_t join_flags)
156 {
157         if (!domain_name) {
158                 return WERR_INVALID_PARAM;
159         }
160
161         if (!server_name || is_myname_or_ipaddr(server_name)) {
162
163                 return NetJoinDomainLocal(ctx,
164                                           server_name,
165                                           domain_name,
166                                           account_ou,
167                                           Account,
168                                           password,
169                                           join_flags);
170         }
171
172         return NetJoinDomainRemote(ctx,
173                                    server_name,
174                                    domain_name,
175                                    account_ou,
176                                    Account,
177                                    password,
178                                    join_flags);
179 }
180
181 NET_API_STATUS NetJoinDomain(const char *server_name,
182                              const char *domain_name,
183                              const char *account_ou,
184                              const char *Account,
185                              const char *password,
186                              uint32_t join_flags)
187 {
188         struct libnetapi_ctx *ctx = NULL;
189         NET_API_STATUS status;
190         WERROR werr;
191
192         status = libnetapi_getctx(&ctx);
193         if (status != 0) {
194                 return status;
195         }
196
197         werr = libnetapi_NetJoinDomain(ctx,
198                                        server_name,
199                                        domain_name,
200                                        account_ou,
201                                        Account,
202                                        password,
203                                        join_flags);
204         if (!W_ERROR_IS_OK(werr)) {
205                 return W_ERROR_V(werr);
206         }
207
208         return 0;
209 }
210
211 static WERROR libnetapi_NetUnjoinDomain(struct libnetapi_ctx *ctx,
212                                         const char *server_name,
213                                         const char *account,
214                                         const char *password,
215                                         uint32_t unjoin_flags)
216 {
217         struct cli_state *cli = NULL;
218         struct rpc_pipe_client *pipe_cli = NULL;
219         struct wkssvc_PasswordBuffer encrypted_password;
220         NTSTATUS status;
221         WERROR werr;
222         unsigned int old_timeout = 0;
223
224         ZERO_STRUCT(encrypted_password);
225
226         status = cli_full_connection(&cli, NULL, server_name,
227                                      NULL, 0,
228                                      "IPC$", "IPC",
229                                      ctx->username,
230                                      ctx->workgroup,
231                                      ctx->password,
232                                      0, Undefined, NULL);
233
234         if (!NT_STATUS_IS_OK(status)) {
235                 werr = ntstatus_to_werror(status);
236                 goto done;
237         }
238
239         old_timeout = cli_set_timeout(cli, 60000);
240
241         pipe_cli = cli_rpc_pipe_open_noauth(cli, PI_WKSSVC,
242                                             &status);
243         if (!pipe_cli) {
244                 werr = ntstatus_to_werror(status);
245                 goto done;
246         };
247
248         if (password) {
249                 encode_wkssvc_join_password_buffer(ctx,
250                                                    password,
251                                                    &cli->user_session_key,
252                                                    &encrypted_password);
253         }
254
255         old_timeout = cli_set_timeout(cli, 60000);
256
257         status = rpccli_wkssvc_NetrUnjoinDomain2(pipe_cli, ctx,
258                                                  server_name,
259                                                  account,
260                                                  &encrypted_password,
261                                                  unjoin_flags,
262                                                  &werr);
263         if (!NT_STATUS_IS_OK(status)) {
264                 werr = ntstatus_to_werror(status);
265                 goto done;
266         }
267
268  done:
269         if (cli) {
270                 cli_set_timeout(cli, old_timeout);
271                 cli_shutdown(cli);
272         }
273
274         return werr;
275 }
276
277 NET_API_STATUS NetUnjoinDomain(const char *server_name,
278                                const char *account,
279                                const char *password,
280                                uint32_t unjoin_flags)
281 {
282         struct libnetapi_ctx *ctx = NULL;
283         NET_API_STATUS status;
284         WERROR werr;
285
286         status = libnetapi_getctx(&ctx);
287         if (status != 0) {
288                 return status;
289         }
290
291         werr = libnetapi_NetUnjoinDomain(ctx,
292                                          server_name,
293                                          account,
294                                          password,
295                                          unjoin_flags);
296         if (!W_ERROR_IS_OK(werr)) {
297                 return W_ERROR_V(werr);
298         }
299
300         return 0;
301 }
302
303
304 WERROR libnetapi_NetGetJoinInformation(struct libnetapi_ctx *ctx,
305                                        const char *server_name,
306                                        const char **name_buffer,
307                                        uint16_t *name_type)
308 {
309         TALLOC_CTX *mem_ctx = NULL;
310         struct cli_state *cli = NULL;
311         struct rpc_pipe_client *pipe_cli = NULL;
312         NTSTATUS status;
313         WERROR werr;
314
315         mem_ctx = talloc_init("NetGetJoinInformation");
316         if (!mem_ctx) {
317                 werr = WERR_NOMEM;
318                 goto done;
319         }
320
321         if (!server_name || is_myname_or_ipaddr(server_name)) {
322                 if ((lp_security() == SEC_ADS) && lp_realm()) {
323                         *name_buffer = SMB_STRDUP(lp_realm());
324                 } else {
325                         *name_buffer = SMB_STRDUP(lp_workgroup());
326                 }
327                 if (!*name_buffer) {
328                         werr = WERR_NOMEM;
329                         goto done;
330                 }
331                 switch (lp_server_role()) {
332                         case ROLE_DOMAIN_MEMBER:
333                         case ROLE_DOMAIN_PDC:
334                         case ROLE_DOMAIN_BDC:
335                                 *name_type = NetSetupDomainName;
336                                 break;
337                         case ROLE_STANDALONE:
338                         default:
339                                 *name_type = NetSetupWorkgroupName;
340                                 break;
341                 }
342
343                 werr = WERR_OK;
344                 goto done;
345         }
346
347         status = cli_full_connection(&cli, NULL, server_name,
348                                      NULL, 0,
349                                      "IPC$", "IPC",
350                                      ctx->username,
351                                      ctx->workgroup,
352                                      ctx->password,
353                                      0, Undefined, NULL);
354
355         if (!NT_STATUS_IS_OK(status)) {
356                 werr = ntstatus_to_werror(status);
357                 goto done;
358         }
359
360         pipe_cli = cli_rpc_pipe_open_noauth(cli, PI_WKSSVC,
361                                             &status);
362         if (!pipe_cli) {
363                 werr = ntstatus_to_werror(status);
364                 goto done;
365         };
366
367         status = rpccli_wkssvc_NetrGetJoinInformation(pipe_cli, mem_ctx,
368                                                       server_name,
369                                                       name_buffer,
370                                                       (enum wkssvc_NetJoinStatus *)name_type,
371                                                       &werr);
372         if (!NT_STATUS_IS_OK(status)) {
373                 werr = ntstatus_to_werror(status);
374                 goto done;
375         }
376
377  done:
378         if (cli) {
379                 cli_shutdown(cli);
380         }
381         TALLOC_FREE(mem_ctx);
382
383         return werr;
384 }
385
386 NET_API_STATUS NetGetJoinInformation(const char *server_name,
387                                      const char **name_buffer,
388                                      uint16_t *name_type)
389 {
390         struct libnetapi_ctx *ctx = NULL;
391         NET_API_STATUS status;
392         WERROR werr;
393
394         status = libnetapi_getctx(&ctx);
395         if (status != 0) {
396                 return status;
397         }
398
399         werr = libnetapi_NetGetJoinInformation(ctx,
400                                                server_name,
401                                                name_buffer,
402                                                name_type);
403         if (!W_ERROR_IS_OK(werr)) {
404                 return W_ERROR_V(werr);
405         }
406
407         return 0;
408 }