3bf6a27289ab6890c9101b24573f5915ce3f2f3a
[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 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
32         return -1;
33 }
34
35 static int net_dom_unjoin(struct net_context *c, int argc, const char **argv)
36 {
37         const char *server_name = NULL;
38         const char *account = NULL;
39         const char *password = NULL;
40         uint32_t unjoin_flags = NETSETUP_ACCT_DELETE |
41                                 NETSETUP_JOIN_DOMAIN |
42                                 NETSETUP_IGNORE_UNSUPPORTED_FLAGS;
43         struct cli_state *cli = NULL;
44         bool do_reboot = false;
45         NTSTATUS ntstatus;
46         NET_API_STATUS status;
47         int ret = -1;
48         int i;
49
50         if (argc < 1 || c->display_usage) {
51                 return net_dom_usage(c, argc, argv);
52         }
53
54         if (c->opt_host) {
55                 server_name = c->opt_host;
56         }
57
58         for (i=0; i<argc; i++) {
59                 if (strnequal(argv[i], "account", strlen("account"))) {
60                         account = get_string_param(argv[i]);
61                         if (!account) {
62                                 return -1;
63                         }
64                 }
65                 if (strnequal(argv[i], "password", strlen("password"))) {
66                         password = get_string_param(argv[i]);
67                         if (!password) {
68                                 return -1;
69                         }
70                 }
71                 if (strequal(argv[i], "reboot")) {
72                         do_reboot = true;
73                 }
74         }
75
76         if (do_reboot) {
77                 ntstatus = net_make_ipc_connection_ex(c, c->opt_workgroup,
78                                                       server_name, NULL, 0,
79                                                       &cli);
80                 if (!NT_STATUS_IS_OK(ntstatus)) {
81                         return -1;
82                 }
83         }
84
85         status = NetUnjoinDomain(server_name, account, password, unjoin_flags);
86         if (status != 0) {
87                 printf("Failed to unjoin domain: %s\n",
88                         libnetapi_get_error_string(c->netapi_ctx, status));
89                 goto done;
90         }
91
92         if (do_reboot) {
93                 c->opt_comment = "Shutting down due to a domain membership "
94                                  "change";
95                 c->opt_reboot = true;
96                 c->opt_timeout = 30;
97
98                 ret = run_rpc_command(c, cli,
99                                       &ndr_table_initshutdown.syntax_id,
100                                       0, rpc_init_shutdown_internals,
101                                       argc, argv);
102                 if (ret == 0) {
103                         goto done;
104                 }
105
106                 ret = run_rpc_command(c, cli, &ndr_table_winreg.syntax_id, 0,
107                                       rpc_reg_shutdown_internals,
108                                       argc, argv);
109                 goto done;
110         }
111
112         ret = 0;
113
114  done:
115         if (cli) {
116                 cli_shutdown(cli);
117         }
118
119         return ret;
120 }
121
122 static int net_dom_join(struct net_context *c, int argc, const char **argv)
123 {
124         const char *server_name = NULL;
125         const char *domain_name = NULL;
126         const char *account_ou = NULL;
127         const char *Account = NULL;
128         const char *password = NULL;
129         uint32_t join_flags = NETSETUP_ACCT_CREATE |
130                               NETSETUP_JOIN_DOMAIN;
131         struct cli_state *cli = NULL;
132         bool do_reboot = false;
133         NTSTATUS ntstatus;
134         NET_API_STATUS status;
135         int ret = -1;
136         int i;
137
138         if (argc < 1 || c->display_usage) {
139                 return net_dom_usage(c, argc, argv);
140         }
141
142         if (c->opt_host) {
143                 server_name = c->opt_host;
144         }
145
146         if (c->opt_force) {
147                 join_flags |= NETSETUP_DOMAIN_JOIN_IF_JOINED;
148         }
149
150         for (i=0; i<argc; i++) {
151                 if (strnequal(argv[i], "ou", strlen("ou"))) {
152                         account_ou = get_string_param(argv[i]);
153                         if (!account_ou) {
154                                 return -1;
155                         }
156                 }
157                 if (strnequal(argv[i], "domain", strlen("domain"))) {
158                         domain_name = get_string_param(argv[i]);
159                         if (!domain_name) {
160                                 return -1;
161                         }
162                 }
163                 if (strnequal(argv[i], "account", strlen("account"))) {
164                         Account = get_string_param(argv[i]);
165                         if (!Account) {
166                                 return -1;
167                         }
168                 }
169                 if (strnequal(argv[i], "password", strlen("password"))) {
170                         password = get_string_param(argv[i]);
171                         if (!password) {
172                                 return -1;
173                         }
174                 }
175                 if (strequal(argv[i], "reboot")) {
176                         do_reboot = true;
177                 }
178         }
179
180         if (do_reboot) {
181                 ntstatus = net_make_ipc_connection_ex(c, c->opt_workgroup,
182                                                       server_name, NULL, 0,
183                                                       &cli);
184                 if (!NT_STATUS_IS_OK(ntstatus)) {
185                         return -1;
186                 }
187         }
188
189         /* check if domain is a domain or a workgroup */
190
191         status = NetJoinDomain(server_name, domain_name, account_ou,
192                                Account, password, join_flags);
193         if (status != 0) {
194                 printf("Failed to join domain: %s\n",
195                         libnetapi_get_error_string(c->netapi_ctx, status));
196                 goto done;
197         }
198
199         if (do_reboot) {
200                 c->opt_comment = "Shutting down due to a domain membership "
201                                  "change";
202                 c->opt_reboot = true;
203                 c->opt_timeout = 30;
204
205                 ret = run_rpc_command(c, cli, &ndr_table_initshutdown.syntax_id, 0,
206                                       rpc_init_shutdown_internals,
207                                       argc, argv);
208                 if (ret == 0) {
209                         goto done;
210                 }
211
212                 ret = run_rpc_command(c, cli, &ndr_table_winreg.syntax_id, 0,
213                                       rpc_reg_shutdown_internals,
214                                       argc, argv);
215                 goto done;
216         }
217
218         ret = 0;
219
220  done:
221         if (cli) {
222                 cli_shutdown(cli);
223         }
224
225         return ret;
226 }
227
228 int net_dom(struct net_context *c, int argc, const char **argv)
229 {
230         NET_API_STATUS status;
231
232         struct functable func[] = {
233                 {
234                         "join",
235                         net_dom_join,
236                         NET_TRANSPORT_LOCAL,
237                         "Join a remote machine",
238                         "net dom join <domain=DOMAIN> <ou=OU> "
239                         "<account=ACCOUNT> <password=PASSWORD> <reboot>\n"
240                         "  Join a remote machine"
241                 },
242                 {
243                         "unjoin",
244                         net_dom_unjoin,
245                         NET_TRANSPORT_LOCAL,
246                         "Unjoin a remote machine",
247                         "net dom unjoin <account=ACCOUNT> <password=PASSWORD> "
248                         "<reboot>\n"
249                         "  Unjoin a remote machine"
250                 },
251                 {NULL, NULL, 0, NULL, NULL}
252         };
253
254         status = libnetapi_init(&c->netapi_ctx);
255         if (status != 0) {
256                 return -1;
257         }
258
259         libnetapi_set_username(c->netapi_ctx, c->opt_user_name);
260         libnetapi_set_password(c->netapi_ctx, c->opt_password);
261         if (c->opt_kerberos) {
262                 libnetapi_set_use_kerberos(c->netapi_ctx);
263         }
264
265         return net_run_function(c, argc, argv, "net dom", func);
266 }