Getting rid of external credentials in libnetapi.
[nivanova/samba-autobuild/.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 #include "lib/netapi/joindomain.h"
22
23 static WERROR NetJoinDomainLocal(TALLOC_CTX *mem_ctx,
24                                  const char *server_name,
25                                  const char *domain_name,
26                                  const char *account_ou,
27                                  const char *Account,
28                                  const char *password,
29                                  uint32_t join_flags)
30 {
31         struct libnet_JoinCtx *r = NULL;
32         WERROR werr;
33
34         werr = libnet_init_JoinCtx(mem_ctx, &r);
35         W_ERROR_NOT_OK_RETURN(werr);
36
37         if (!server_name || !domain_name) {
38                 return WERR_INVALID_PARAM;
39         }
40
41         r->in.server_name = talloc_strdup(mem_ctx, server_name);
42         W_ERROR_HAVE_NO_MEMORY(r->in.server_name);
43
44         r->in.domain_name = talloc_strdup(mem_ctx, domain_name);
45         W_ERROR_HAVE_NO_MEMORY(r->in.domain_name);
46
47         if (account_ou) {
48                 r->in.account_ou = talloc_strdup(mem_ctx, account_ou);
49                 W_ERROR_HAVE_NO_MEMORY(r->in.account_ou);
50         }
51
52         if (Account) {
53                 r->in.admin_account = talloc_strdup(mem_ctx, Account);
54                 W_ERROR_HAVE_NO_MEMORY(r->in.admin_account);
55         }
56
57         if (password) {
58                 r->in.password = talloc_strdup(mem_ctx, password);
59                 W_ERROR_HAVE_NO_MEMORY(r->in.password);
60         }
61
62         r->in.join_flags = join_flags;
63         r->in.modify_config = true;
64
65         return libnet_Join(mem_ctx, r);
66 }
67
68 static WERROR NetJoinDomainRemote(TALLOC_CTX *mem_ctx,
69                                   const char *server_name,
70                                   const char *domain_name,
71                                   const char *account_ou,
72                                   const char *Account,
73                                   const char *password,
74                                   uint32_t join_flags)
75 {
76         struct cli_state *cli = NULL;
77         struct rpc_pipe_client *pipe_cli = NULL;
78         struct wkssvc_PasswordBuffer encrypted_password;
79         NTSTATUS status;
80         WERROR werr;
81         unsigned int old_timeout = 0;
82
83         ZERO_STRUCT(encrypted_password);
84
85         status = cli_full_connection(&cli, NULL, server_name,
86                                      NULL, 0,
87                                      "IPC$", "IPC",
88                                      opt_user_name, opt_workgroup,
89                                      opt_password, 0, Undefined, NULL);
90
91         if (!NT_STATUS_IS_OK(status)) {
92                 werr = ntstatus_to_werror(status);
93                 goto done;
94         }
95
96         old_timeout = cli_set_timeout(cli, 60000);
97
98         pipe_cli = cli_rpc_pipe_open_noauth(cli, PI_WKSSVC,
99                                             &status);
100         if (!pipe_cli) {
101                 werr = ntstatus_to_werror(status);
102                 goto done;
103         };
104
105         if (password) {
106                 encode_wkssvc_join_password_buffer(mem_ctx,
107                                                    password,
108                                                    &cli->user_session_key,
109                                                    &encrypted_password);
110         }
111
112         old_timeout = cli_set_timeout(cli, 60000);
113
114         status = rpccli_wkssvc_NetrJoinDomain2(pipe_cli, mem_ctx,
115                                                server_name, domain_name,
116                                                account_ou, Account,
117                                                &encrypted_password,
118                                                join_flags, &werr);
119         if (!NT_STATUS_IS_OK(status)) {
120                 werr = ntstatus_to_werror(status);
121                 goto done;
122         }
123
124  done:
125         if (cli) {
126                 cli_set_timeout(cli, old_timeout);
127                 cli_shutdown(cli);
128         }
129
130         return werr;
131 }
132
133 WERROR NetJoinDomain(const char *server_name,
134                      const char *domain_name,
135                      const char *account_ou,
136                      const char *Account,
137                      const char *password,
138                      uint32_t join_flags)
139 {
140         TALLOC_CTX *mem_ctx = NULL;
141         WERROR werr;
142
143         mem_ctx = talloc_init("NetJoinDomain");
144         if (!mem_ctx) {
145                 werr = WERR_NOMEM;
146                 goto done;
147         }
148
149         if (!domain_name) {
150                 werr = WERR_INVALID_PARAM;
151                 goto done;
152         }
153
154         if (!server_name || is_myname_or_ipaddr(server_name)) {
155
156                 const char *dc = NULL;
157
158                 /* FIXME: DsGetDcName */
159                 if (server_name == NULL) {
160                         dc = domain_name;
161                 } else {
162                         dc = domain_name;
163                 }
164
165                 werr = NetJoinDomainLocal(mem_ctx,
166                                           dc,
167                                           domain_name,
168                                           account_ou,
169                                           Account,
170                                           password,
171                                           join_flags);
172
173                 goto done;
174         }
175
176         werr = NetJoinDomainRemote(mem_ctx,
177                                    server_name,
178                                    domain_name,
179                                    account_ou,
180                                    Account,
181                                    password,
182                                    join_flags);
183 done:
184         TALLOC_FREE(mem_ctx);
185
186         return werr;
187 }
188
189 WERROR NetUnjoinDomain(const char *server_name,
190                        const char *account,
191                        const char *password,
192                        uint32_t unjoin_flags)
193 {
194         TALLOC_CTX *mem_ctx = NULL;
195         struct cli_state *cli = NULL;
196         struct rpc_pipe_client *pipe_cli = NULL;
197         struct wkssvc_PasswordBuffer encrypted_password;
198         NTSTATUS status;
199         WERROR werr;
200         unsigned int old_timeout = 0;
201
202         ZERO_STRUCT(encrypted_password);
203
204         mem_ctx = talloc_init("NetUnjoinDomain");
205         if (!mem_ctx) {
206                 werr = WERR_NOMEM;
207                 goto done;
208         }
209
210         if (!server_name || is_myname_or_ipaddr(server_name)) {
211                 werr = WERR_NOT_SUPPORTED;
212                 goto done;
213         }
214
215         status = cli_full_connection(&cli, NULL, server_name,
216                                      NULL, 0,
217                                      "IPC$", "IPC",
218                                      ctx->username,
219                                      ctx->workgroup,
220                                      ctx->password,
221                                      0, Undefined, NULL);
222
223         if (!NT_STATUS_IS_OK(status)) {
224                 werr = ntstatus_to_werror(status);
225                 goto done;
226         }
227
228         old_timeout = cli_set_timeout(cli, 60000);
229
230         pipe_cli = cli_rpc_pipe_open_noauth(cli, PI_WKSSVC,
231                                             &status);
232         if (!pipe_cli) {
233                 werr = ntstatus_to_werror(status);
234                 goto done;
235         };
236
237         if (password) {
238                 encode_wkssvc_join_password_buffer(mem_ctx,
239                                                    password,
240                                                    &cli->user_session_key,
241                                                    &encrypted_password);
242         }
243
244         old_timeout = cli_set_timeout(cli, 60000);
245
246         status = rpccli_wkssvc_NetrUnjoinDomain2(pipe_cli, mem_ctx,
247                                                  server_name,
248                                                  account,
249                                                  &encrypted_password,
250                                                  unjoin_flags,
251                                                  &werr);
252         if (!NT_STATUS_IS_OK(status)) {
253                 werr = ntstatus_to_werror(status);
254                 goto done;
255         }
256
257  done:
258         if (cli) {
259                 cli_set_timeout(cli, old_timeout);
260                 cli_shutdown(cli);
261         }
262         TALLOC_FREE(mem_ctx);
263
264         return werr;
265 }
266
267 WERROR NetGetJoinInformation(const char *server_name,
268                              const char **name_buffer,
269                              uint16_t *name_type)
270 {
271         TALLOC_CTX *mem_ctx = NULL;
272         struct cli_state *cli = NULL;
273         struct rpc_pipe_client *pipe_cli = NULL;
274         NTSTATUS status;
275         WERROR werr;
276
277         mem_ctx = talloc_init("NetGetJoinInformation");
278         if (!mem_ctx) {
279                 werr = WERR_NOMEM;
280                 goto done;
281         }
282
283         if (!server_name || is_myname_or_ipaddr(server_name)) {
284                 if ((lp_security() == SEC_ADS) && lp_realm()) {
285                         *name_buffer = SMB_STRDUP(lp_realm());
286                 } else {
287                         *name_buffer = SMB_STRDUP(lp_workgroup());
288                 }
289                 if (!*name_buffer) {
290                         werr = WERR_NOMEM;
291                         goto done;
292                 }
293                 switch (lp_server_role()) {
294                         case ROLE_DOMAIN_MEMBER:
295                         case ROLE_DOMAIN_PDC:
296                         case ROLE_DOMAIN_BDC:
297                                 *name_type = NetSetupDomainName;
298                                 break;
299                         case ROLE_STANDALONE:
300                         default:
301                                 *name_type = NetSetupWorkgroupName;
302                                 break;
303                 }
304
305                 werr = WERR_OK;
306                 goto done;
307         }
308
309         status = cli_full_connection(&cli, NULL, server_name,
310                                      NULL, 0,
311                                      "IPC$", "IPC",
312                                      ctx->username,
313                                      ctx->workgroup,
314                                      ctx->password,
315                                      0, Undefined, NULL);
316
317         if (!NT_STATUS_IS_OK(status)) {
318                 werr = ntstatus_to_werror(status);
319                 goto done;
320         }
321
322         pipe_cli = cli_rpc_pipe_open_noauth(cli, PI_WKSSVC,
323                                             &status);
324         if (!pipe_cli) {
325                 werr = ntstatus_to_werror(status);
326                 goto done;
327         };
328
329         status = rpccli_wkssvc_NetrGetJoinInformation(pipe_cli, mem_ctx,
330                                                       server_name,
331                                                       name_buffer,
332                                                       (enum wkssvc_NetJoinStatus *)name_type,
333                                                       &werr);
334         if (!NT_STATUS_IS_OK(status)) {
335                 werr = ntstatus_to_werror(status);
336                 goto done;
337         }
338
339  done:
340         if (cli) {
341                 cli_shutdown(cli);
342         }
343         TALLOC_FREE(mem_ctx);
344
345         return werr;
346 }