Some cleanups for "net dom join".
[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 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 "lib/netapi/joindomain.h"
23
24 static int net_dom_usage(int argc, const char **argv)
25 {
26         d_printf("usage: net dom join "
27                  "<domain=DOMAIN> <ou=OU> <account=ACCOUNT> <password=PASSWORD> <reboot>\n");
28         d_printf("usage: net dom unjoin "
29                  "<account=ACCOUNT> <password=PASSWORD> <reboot>\n");
30
31         return -1;
32 }
33
34 int net_help_dom(int argc, const char **argv)
35 {
36         d_printf("net dom join"\
37                 "\n  Join a remote machine\n");
38         d_printf("net dom unjoin"\
39                 "\n  Unjoin a remote machine\n");
40
41         return -1;
42 }
43
44 static int net_dom_unjoin(int argc, const char **argv)
45 {
46         const char *server_name = NULL;
47         const char *account = NULL;
48         const char *password = NULL;
49         uint32_t unjoin_flags = WKSSVC_JOIN_FLAGS_ACCOUNT_DELETE |
50                                 WKSSVC_JOIN_FLAGS_JOIN_TYPE;
51         struct cli_state *cli = NULL;
52         bool reboot = false;
53         NTSTATUS status;
54         WERROR werr;
55         int ret = -1;
56         int i;
57
58         if (argc < 1) {
59                 return net_dom_usage(argc, argv);
60         }
61
62         if (opt_host) {
63                 server_name = opt_host;
64         }
65
66         for (i=0; i<argc; i++) {
67                 if (strnequal(argv[i], "account", strlen("account"))) {
68                         account = get_string_param(argv[i]);
69                         if (!account) {
70                                 return -1;
71                         }
72                 }
73                 if (strnequal(argv[i], "password", strlen("password"))) {
74                         password = get_string_param(argv[i]);
75                         if (!password) {
76                                 return -1;
77                         }
78                 }
79                 if (strequal(argv[i], "reboot")) {
80                         reboot = true;
81                 }
82         }
83
84         if (reboot) {
85                 status = net_make_ipc_connection_ex(opt_workgroup, server_name,
86                                                     NULL, 0, &cli);
87                 if (!NT_STATUS_IS_OK(status)) {
88                         return -1;
89                 }
90         }
91
92         werr = NetUnjoinDomain(server_name, account, password, unjoin_flags);
93         if (!W_ERROR_IS_OK(werr)) {
94                 printf("Failed to unjoin domain: %s\n",
95                         get_friendly_nt_error_msg(werror_to_ntstatus(werr)));
96                 goto done;
97         }
98
99         if (reboot) {
100                 opt_comment = "Shutting down due to a domain membership change";
101                 opt_reboot = true;
102                 opt_timeout = 30;
103
104                 ret = run_rpc_command(cli, PI_INITSHUTDOWN, 0,
105                                       rpc_init_shutdown_internals,
106                                       argc, argv);
107                 if (ret == 0) {
108                         goto done;
109                 }
110
111                 ret = run_rpc_command(cli, PI_WINREG, 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(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 = WKSSVC_JOIN_FLAGS_ACCOUNT_CREATE |
135                               WKSSVC_JOIN_FLAGS_JOIN_TYPE;
136         struct cli_state *cli = NULL;
137         bool reboot = false;
138         NTSTATUS status;
139         WERROR werr;
140         int ret = -1;
141         int i;
142
143         if (argc < 1) {
144                 return net_dom_usage(argc, argv);
145         }
146
147         if (opt_host) {
148                 server_name = opt_host;
149         }
150
151         if (opt_force) {
152                 join_flags |= WKSSVC_JOIN_FLAGS_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                         reboot = true;
182                 }
183         }
184
185         if (reboot) {
186                 status = net_make_ipc_connection_ex(opt_workgroup, server_name,
187                                                     NULL, 0, &cli);
188                 if (!NT_STATUS_IS_OK(status)) {
189                         return -1;
190                 }
191         }
192
193         /* check if domain is a domain or a workgroup */
194
195         werr = NetJoinDomain(server_name, domain_name, account_ou,
196                              Account, password, join_flags);
197         if (!W_ERROR_IS_OK(werr)) {
198                 printf("Failed to join domain: %s (WERROR: %s)\n",
199                         get_friendly_nt_error_msg(werror_to_ntstatus(werr)),
200                         dos_errstr(werr));
201                 goto done;
202         }
203
204         if (reboot) {
205                 opt_comment = "Shutting down due to a domain membership change";
206                 opt_reboot = true;
207                 opt_timeout = 30;
208
209                 ret = run_rpc_command(cli, PI_INITSHUTDOWN, 0,
210                                       rpc_init_shutdown_internals,
211                                       argc, argv);
212                 if (ret == 0) {
213                         goto done;
214                 }
215
216                 ret = run_rpc_command(cli, PI_WINREG, 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 int net_dom(int argc, const char **argv)
233 {
234         struct functable func[] = {
235                 {"JOIN", net_dom_join},
236                 {"UNJOIN", net_dom_unjoin},
237                 {"HELP", net_help_dom},
238                 {NULL, NULL}
239         };
240
241         return net_run_function(argc, argv, func, net_dom_usage);
242 }