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