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