e139ef4e032373fdfb233946413a79b7239da8ba
[nivanova/samba-autobuild/.git] / source3 / utils / net_dom.c
1 /*
2    Samba Unix/Linux SMB client library
3    net dom commands for remote join/unjoin
4    Copyright (C) 2007,2009 Günther Deschner
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 "utils/net.h"
22 #include "../librpc/gen_ndr/cli_initshutdown.h"
23
24 int net_dom_usage(struct net_context *c, int argc, const char **argv)
25 {
26         d_printf(_("Usage:"), _(" net dom join "
27                    "<domain=DOMAIN> <ou=OU> <account=ACCOUNT> "
28                    "<password=PASSWORD> <reboot>\n  Join a remote machine\n"));
29         d_printf(_("Usage:"), _(" net dom unjoin "
30                    "<account=ACCOUNT> <password=PASSWORD> <reboot>\n"
31                    "  Unjoin a remote machine\n"));
32         d_printf(_("Usage:"), _(" net dom renamecomputer "
33                    "<newname=NEWNAME> "
34                    "<account=ACCOUNT> <password=PASSWORD> <reboot>\n"
35                    "  Rename joined computer\n"));
36
37         return -1;
38 }
39
40 static int net_dom_unjoin(struct net_context *c, int argc, const char **argv)
41 {
42         const char *server_name = NULL;
43         const char *account = NULL;
44         const char *password = NULL;
45         uint32_t unjoin_flags = NETSETUP_ACCT_DELETE |
46                                 NETSETUP_JOIN_DOMAIN |
47                                 NETSETUP_IGNORE_UNSUPPORTED_FLAGS;
48         struct cli_state *cli = NULL;
49         bool do_reboot = false;
50         NTSTATUS ntstatus;
51         NET_API_STATUS status;
52         int ret = -1;
53         int i;
54
55         if (argc < 1 || c->display_usage) {
56                 return net_dom_usage(c, argc, argv);
57         }
58
59         if (c->opt_host) {
60                 server_name = c->opt_host;
61         }
62
63         for (i=0; i<argc; i++) {
64                 if (strnequal(argv[i], "account", strlen("account"))) {
65                         account = get_string_param(argv[i]);
66                         if (!account) {
67                                 return -1;
68                         }
69                 }
70                 if (strnequal(argv[i], "password", strlen("password"))) {
71                         password = get_string_param(argv[i]);
72                         if (!password) {
73                                 return -1;
74                         }
75                 }
76                 if (strequal(argv[i], "reboot")) {
77                         do_reboot = true;
78                 }
79         }
80
81         if (do_reboot) {
82                 ntstatus = net_make_ipc_connection_ex(c, c->opt_workgroup,
83                                                       server_name, NULL, 0,
84                                                       &cli);
85                 if (!NT_STATUS_IS_OK(ntstatus)) {
86                         return -1;
87                 }
88         }
89
90         status = NetUnjoinDomain(server_name, account, password, unjoin_flags);
91         if (status != 0) {
92                 printf(_("Failed to unjoin domain: %s\n"),
93                         libnetapi_get_error_string(c->netapi_ctx, status));
94                 goto done;
95         }
96
97         if (do_reboot) {
98                 c->opt_comment = _("Shutting down due to a domain membership "
99                                    "change");
100                 c->opt_reboot = true;
101                 c->opt_timeout = 30;
102
103                 ret = run_rpc_command(c, cli,
104                                       &ndr_table_initshutdown.syntax_id,
105                                       0, rpc_init_shutdown_internals,
106                                       argc, argv);
107                 if (ret == 0) {
108                         goto done;
109                 }
110
111                 ret = run_rpc_command(c, cli, &ndr_table_winreg.syntax_id, 0,
112                                       rpc_reg_shutdown_internals,
113                                       argc, argv);
114                 goto done;
115         }
116
117         ret = 0;
118
119  done:
120         if (cli) {
121                 cli_shutdown(cli);
122         }
123
124         return ret;
125 }
126
127 static int net_dom_join(struct net_context *c, int argc, const char **argv)
128 {
129         const char *server_name = NULL;
130         const char *domain_name = NULL;
131         const char *account_ou = NULL;
132         const char *Account = NULL;
133         const char *password = NULL;
134         uint32_t join_flags = NETSETUP_ACCT_CREATE |
135                               NETSETUP_JOIN_DOMAIN;
136         struct cli_state *cli = NULL;
137         bool do_reboot = false;
138         NTSTATUS ntstatus;
139         NET_API_STATUS status;
140         int ret = -1;
141         int i;
142
143         if (argc < 1 || c->display_usage) {
144                 return net_dom_usage(c, argc, argv);
145         }
146
147         if (c->opt_host) {
148                 server_name = c->opt_host;
149         }
150
151         if (c->opt_force) {
152                 join_flags |= NETSETUP_DOMAIN_JOIN_IF_JOINED;
153         }
154
155         for (i=0; i<argc; i++) {
156                 if (strnequal(argv[i], "ou", strlen("ou"))) {
157                         account_ou = get_string_param(argv[i]);
158                         if (!account_ou) {
159                                 return -1;
160                         }
161                 }
162                 if (strnequal(argv[i], "domain", strlen("domain"))) {
163                         domain_name = get_string_param(argv[i]);
164                         if (!domain_name) {
165                                 return -1;
166                         }
167                 }
168                 if (strnequal(argv[i], "account", strlen("account"))) {
169                         Account = get_string_param(argv[i]);
170                         if (!Account) {
171                                 return -1;
172                         }
173                 }
174                 if (strnequal(argv[i], "password", strlen("password"))) {
175                         password = get_string_param(argv[i]);
176                         if (!password) {
177                                 return -1;
178                         }
179                 }
180                 if (strequal(argv[i], "reboot")) {
181                         do_reboot = true;
182                 }
183         }
184
185         if (do_reboot) {
186                 ntstatus = net_make_ipc_connection_ex(c, c->opt_workgroup,
187                                                       server_name, NULL, 0,
188                                                       &cli);
189                 if (!NT_STATUS_IS_OK(ntstatus)) {
190                         return -1;
191                 }
192         }
193
194         /* check if domain is a domain or a workgroup */
195
196         status = NetJoinDomain(server_name, domain_name, account_ou,
197                                Account, password, join_flags);
198         if (status != 0) {
199                 printf(_("Failed to join domain: %s\n"),
200                         libnetapi_get_error_string(c->netapi_ctx, status));
201                 goto done;
202         }
203
204         if (do_reboot) {
205                 c->opt_comment = _("Shutting down due to a domain membership "
206                                    "change");
207                 c->opt_reboot = true;
208                 c->opt_timeout = 30;
209
210                 ret = run_rpc_command(c, cli, &ndr_table_initshutdown.syntax_id, 0,
211                                       rpc_init_shutdown_internals,
212                                       argc, argv);
213                 if (ret == 0) {
214                         goto done;
215                 }
216
217                 ret = run_rpc_command(c, cli, &ndr_table_winreg.syntax_id, 0,
218                                       rpc_reg_shutdown_internals,
219                                       argc, argv);
220                 goto done;
221         }
222
223         ret = 0;
224
225  done:
226         if (cli) {
227                 cli_shutdown(cli);
228         }
229
230         return ret;
231 }
232
233 static int net_dom_renamecomputer(struct net_context *c, int argc, const char **argv)
234 {
235         const char *server_name = NULL;
236         const char *account = NULL;
237         const char *password = NULL;
238         const char *newname = NULL;
239         uint32_t rename_options = NETSETUP_ACCT_CREATE;
240         struct cli_state *cli = NULL;
241         bool do_reboot = false;
242         NTSTATUS ntstatus;
243         NET_API_STATUS status;
244         int ret = -1;
245         int i;
246
247         if (argc < 1 || c->display_usage) {
248                 return net_dom_usage(c, argc, argv);
249         }
250
251         if (c->opt_host) {
252                 server_name = c->opt_host;
253         }
254
255         for (i=0; i<argc; i++) {
256                 if (strnequal(argv[i], "account", strlen("account"))) {
257                         account = get_string_param(argv[i]);
258                         if (!account) {
259                                 return -1;
260                         }
261                 }
262                 if (strnequal(argv[i], "password", strlen("password"))) {
263                         password = get_string_param(argv[i]);
264                         if (!password) {
265                                 return -1;
266                         }
267                 }
268                 if (strnequal(argv[i], "newname", strlen("newname"))) {
269                         newname = get_string_param(argv[i]);
270                         if (!newname) {
271                                 return -1;
272                         }
273                 }
274                 if (strequal(argv[i], "reboot")) {
275                         do_reboot = true;
276                 }
277         }
278
279         if (do_reboot) {
280                 ntstatus = net_make_ipc_connection_ex(c, c->opt_workgroup,
281                                                       server_name, NULL, 0,
282                                                       &cli);
283                 if (!NT_STATUS_IS_OK(ntstatus)) {
284                         return -1;
285                 }
286         }
287
288         status = NetRenameMachineInDomain(server_name, newname,
289                                           account, password, rename_options);
290         if (status != 0) {
291                 printf(_("Failed to rename machine: "));
292                 if (status == W_ERROR_V(WERR_SETUP_NOT_JOINED)) {
293                         printf(_("Computer is not joined to a Domain\n"));
294                         goto done;
295                 }
296                 printf("%s\n",
297                         libnetapi_get_error_string(c->netapi_ctx, status));
298                 goto done;
299         }
300
301         if (do_reboot) {
302                 c->opt_comment = _("Shutting down due to a computer rename");
303                 c->opt_reboot = true;
304                 c->opt_timeout = 30;
305
306                 ret = run_rpc_command(c, cli,
307                                       &ndr_table_initshutdown.syntax_id,
308                                       0, rpc_init_shutdown_internals,
309                                       argc, argv);
310                 if (ret == 0) {
311                         goto done;
312                 }
313
314                 ret = run_rpc_command(c, cli, &ndr_table_winreg.syntax_id, 0,
315                                       rpc_reg_shutdown_internals,
316                                       argc, argv);
317                 goto done;
318         }
319
320         ret = 0;
321
322  done:
323         if (cli) {
324                 cli_shutdown(cli);
325         }
326
327         return ret;
328 }
329
330 int net_dom(struct net_context *c, int argc, const char **argv)
331 {
332         NET_API_STATUS status;
333
334         struct functable func[] = {
335                 {
336                         "join",
337                         net_dom_join,
338                         NET_TRANSPORT_LOCAL,
339                         N_("Join a remote machine"),
340                         N_("net dom join <domain=DOMAIN> <ou=OU> "
341                            "<account=ACCOUNT> <password=PASSWORD> <reboot>\n"
342                            "  Join a remote machine")
343                 },
344                 {
345                         "unjoin",
346                         net_dom_unjoin,
347                         NET_TRANSPORT_LOCAL,
348                         N_("Unjoin a remote machine"),
349                         N_("net dom unjoin <account=ACCOUNT> "
350                            "<password=PASSWORD> <reboot>\n"
351                            "  Unjoin a remote machine")
352                 },
353                 {
354                         "renamecomputer",
355                         net_dom_renamecomputer,
356                         NET_TRANSPORT_LOCAL,
357                         N_("Rename a computer that is joined to a domain"),
358                         N_("net dom renamecomputer <newname=NEWNAME> "
359                            "<account=ACCOUNT> <password=PASSWORD> "
360                            "<reboot>\n"
361                            "  Rename joined computer")
362                 },
363
364                 {NULL, NULL, 0, NULL, NULL}
365         };
366
367         status = libnetapi_init(&c->netapi_ctx);
368         if (status != 0) {
369                 return -1;
370         }
371
372         libnetapi_set_username(c->netapi_ctx, c->opt_user_name);
373         libnetapi_set_password(c->netapi_ctx, c->opt_password);
374         if (c->opt_kerberos) {
375                 libnetapi_set_use_kerberos(c->netapi_ctx);
376         }
377
378         return net_run_function(c, argc, argv, "net dom", func);
379 }