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