sync getopt() args with 2.2
[Samba.git] / source / utils / net_ads.c
blob7baa29723054cdda389b2973686c49ebff3708ec
1 /*
2 Samba Unix/Linux SMB client library
3 Version 3.0
4 net ads commands
5 Copyright (C) 2001 Andrew Tridgell (tridge@samba.org)
6 Copyright (C) 2001 Remus Koos (remuskoos@yahoo.com)
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 #include "includes.h"
25 #ifdef HAVE_ADS
27 int net_ads_usage(int argc, const char **argv)
29 d_printf(
30 "\nnet ads join <org_unit>"\
31 "\n\tjoins the local machine to a ADS realm\n"\
32 "\nnet ads leave"\
33 "\n\tremoves the local machine from a ADS realm\n"\
34 "\nnet ads user"\
35 "\n\tlist users in the realm\n"\
36 "\nnet ads group"\
37 "\n\tlist groups in the realm\n"\
38 "\nnet ads info"\
39 "\n\tshows some info on the server\n"\
40 "\nnet ads status"\
41 "\n\tdump the machine account details to stdout\n"
42 "\nnet ads password <username@realm> -Uadmin_username@realm%%admin_pass"\
43 "\n\tchange a user's password using an admin account"
44 "\n\t(note: use realm in UPPERCASE)\n"
45 "\nnet ads chostpass"
46 "\n\tchange the trust account password of this machine in the AD tree\n"
48 return -1;
52 static int net_ads_info(int argc, const char **argv)
54 ADS_STRUCT *ads;
56 ads = ads_init(NULL, NULL, NULL, NULL);
57 ads_connect(ads);
59 if (!ads) {
60 d_printf("Didn't find the ldap server!\n");
61 return -1;
64 d_printf("LDAP server: %s\n", ads->ldap_server);
65 d_printf("LDAP server name: %s\n", ads->ldap_server_name);
66 d_printf("Realm: %s\n", ads->realm);
67 d_printf("Bind Path: %s\n", ads->bind_path);
68 d_printf("LDAP port: %d\n", ads->ldap_port);
70 return 0;
74 static ADS_STRUCT *ads_startup(void)
76 ADS_STRUCT *ads;
77 ADS_STATUS status;
78 extern char *opt_password;
79 extern char *opt_user_name;
81 ads = ads_init(NULL, NULL, NULL, NULL);
83 if (!opt_user_name) {
84 opt_user_name = "administrator";
87 if (!opt_password) {
88 char *prompt;
89 asprintf(&prompt,"%s password: ", opt_user_name);
90 opt_password = getpass(prompt);
91 free(prompt);
93 ads->password = strdup(opt_password);
94 ads->user_name = strdup(opt_user_name);
96 status = ads_connect(ads);
97 if (!ADS_ERR_OK(status)) {
98 d_printf("ads_connect: %s\n", ads_errstr(status));
99 return NULL;
101 return ads;
104 static int net_ads_user(int argc, const char **argv)
106 ADS_STRUCT *ads;
107 ADS_STATUS rc;
108 void *res;
109 const char *attrs[] = {"sAMAccountName", "name", "objectSid", NULL};
111 if (!(ads = ads_startup())) return -1;
112 rc = ads_search(ads, &res, "(objectclass=user)", attrs);
113 if (!ADS_ERR_OK(rc)) {
114 d_printf("ads_search: %s\n", ads_errstr(rc));
115 return -1;
118 if (ads_count_replies(ads, res) == 0) {
119 d_printf("No users found\n");
120 return -1;
123 ads_dump(ads, res);
124 ads_destroy(&ads);
125 return 0;
128 static int net_ads_group(int argc, const char **argv)
130 ADS_STRUCT *ads;
131 ADS_STATUS rc;
132 void *res;
133 const char *attrs[] = {"sAMAccountName", "name", "objectSid", NULL};
135 if (!(ads = ads_startup())) return -1;
136 rc = ads_search(ads, &res, "(objectclass=group)", attrs);
137 if (!ADS_ERR_OK(rc)) {
138 d_printf("ads_search: %s\n", ads_errstr(rc));
139 return -1;
142 if (ads_count_replies(ads, res) == 0) {
143 d_printf("No groups found\n");
144 return -1;
147 ads_dump(ads, res);
148 return 0;
151 static int net_ads_status(int argc, const char **argv)
153 ADS_STRUCT *ads;
154 ADS_STATUS rc;
155 extern pstring global_myname;
156 void *res;
158 if (!(ads = ads_startup())) return -1;
160 rc = ads_find_machine_acct(ads, &res, global_myname);
161 if (!ADS_ERR_OK(rc)) {
162 d_printf("ads_find_machine_acct: %s\n", ads_errstr(rc));
163 return -1;
166 if (ads_count_replies(ads, res) == 0) {
167 d_printf("No machine account for '%s' found\n", global_myname);
168 return -1;
171 ads_dump(ads, res);
173 return 0;
176 static int net_ads_leave(int argc, const char **argv)
178 ADS_STRUCT *ads = NULL;
179 ADS_STATUS rc;
180 extern pstring global_myname;
182 if (!(ads = ads_startup())) {
183 return -1;
186 if (!secrets_init()) {
187 DEBUG(1,("Failed to initialise secrets database\n"));
188 return -1;
191 rc = ads_leave_realm(ads, global_myname);
192 if (!ADS_ERR_OK(rc)) {
193 d_printf("Failed to delete host '%s' from the '%s' realm.\n",
194 global_myname, ads->realm);
195 return -1;
198 d_printf("Removed '%s' from realm '%s'\n", global_myname, ads->realm);
200 return 0;
203 static int net_ads_join(int argc, const char **argv)
205 ADS_STRUCT *ads;
206 ADS_STATUS rc;
207 char *password;
208 char *tmp_password;
209 extern pstring global_myname;
210 const char *org_unit = "Computers";
211 char *dn;
212 void *res;
213 DOM_SID dom_sid;
215 if (argc > 0) org_unit = argv[0];
217 if (!secrets_init()) {
218 DEBUG(1,("Failed to initialise secrets database\n"));
219 return -1;
222 tmp_password = generate_random_str(DEFAULT_TRUST_ACCOUNT_PASSWORD_LENGTH);
223 password = strdup(tmp_password);
225 if (!(ads = ads_startup())) return -1;
227 asprintf(&dn, "cn=%s,%s", org_unit, ads->bind_path);
229 rc = ads_search_dn(ads, &res, dn, NULL);
230 free(dn);
231 ads_msgfree(ads, res);
233 if (rc.error_type == ADS_ERROR_LDAP && rc.rc == LDAP_NO_SUCH_OBJECT) {
234 d_printf("ads_join_realm: organisational unit %s does not exist\n", org_unit);
235 return -1;
238 if (!ADS_ERR_OK(rc)) {
239 d_printf("ads_join_realm: %s\n", ads_errstr(rc));
240 return -1;
243 rc = ads_join_realm(ads, global_myname, org_unit);
244 if (!ADS_ERR_OK(rc)) {
245 d_printf("ads_join_realm: %s\n", ads_errstr(rc));
246 return -1;
249 rc = ads_set_machine_password(ads, global_myname, password);
250 if (!ADS_ERR_OK(rc)) {
251 d_printf("ads_set_machine_password: %s\n", ads_errstr(rc));
252 return -1;
255 rc = ads_domain_sid(ads, &dom_sid);
256 if (!ADS_ERR_OK(rc)) {
257 d_printf("ads_domain_sid: %s\n", ads_errstr(rc));
258 return -1;
261 if (!secrets_store_domain_sid(lp_workgroup(), &dom_sid)) {
262 DEBUG(1,("Failed to save domain sid\n"));
263 return -1;
266 if (!secrets_store_machine_password(password)) {
267 DEBUG(1,("Failed to save machine password\n"));
268 return -1;
271 d_printf("Joined '%s' to realm '%s'\n", global_myname, ads->realm);
273 free(password);
275 return 0;
279 static int net_ads_password(int argc, const char **argv)
281 ADS_STRUCT *ads;
282 extern char *opt_user_name;
283 extern char *opt_password;
284 char *auth_principal = opt_user_name;
285 char *auth_password = opt_password;
286 char *realm = NULL;
287 char *new_password = NULL;
288 char *c;
289 char *prompt;
290 ADS_STATUS ret;
293 if ((argc != 1) || (opt_user_name == NULL) ||
294 (opt_password == NULL) || (strchr(opt_user_name, '@') == NULL) ||
295 (strchr(argv[0], '@') == NULL)) {
296 return net_ads_usage(argc, argv);
299 c = strchr(auth_principal, '@');
300 realm = ++c;
302 /* use the realm so we can eventually change passwords for users
303 in realms other than default */
304 if (!(ads = ads_init(realm, NULL, NULL, NULL))) return -1;
306 asprintf(&prompt, "Enter new password for %s:", argv[0]);
308 new_password = getpass(prompt);
310 ret = kerberos_set_password(ads->kdc_server, auth_principal,
311 auth_password, argv[0], new_password);
312 if (!ADS_ERR_OK(ret)) {
313 d_printf("Password change failed :-( ...\n");
314 ads_destroy(&ads);
315 free(prompt);
316 return -1;
319 d_printf("Password change for %s completed.\n", argv[0]);
320 ads_destroy(&ads);
321 free(prompt);
323 return 0;
327 static int net_ads_change_localhost_pass(int argc, const char **argv)
329 ADS_STRUCT *ads;
330 extern pstring global_myname;
331 char *host_principal;
332 char *hostname;
333 ADS_STATUS ret;
336 if (!(ads = ads_init(NULL, NULL, NULL, NULL))) return -1;
338 hostname = strdup(global_myname);
339 strlower(hostname);
340 asprintf(&host_principal, "%s@%s", hostname, ads->realm);
341 SAFE_FREE(hostname);
342 d_printf("Changing password for principal: HOST/%s\n", host_principal);
344 ret = ads_change_trust_account_password(ads, host_principal);
346 if (!ADS_ERR_OK(ret)) {
347 d_printf("Password change failed :-( ...\n");
348 ads_destroy(&ads);
349 SAFE_FREE(host_principal);
350 return -1;
353 d_printf("Password change for principal HOST/%s succeeded.\n", host_principal);
354 ads_destroy(&ads);
355 SAFE_FREE(host_principal);
357 return 0;
361 int net_ads(int argc, const char **argv)
363 struct functable func[] = {
364 {"INFO", net_ads_info},
365 {"JOIN", net_ads_join},
366 {"LEAVE", net_ads_leave},
367 {"STATUS", net_ads_status},
368 {"USER", net_ads_user},
369 {"GROUP", net_ads_group},
370 {"PASSWORD", net_ads_password},
371 {"CHOSTPASS", net_ads_change_localhost_pass},
372 {NULL, NULL}
375 return net_run_function(argc, argv, func, net_ads_usage);
378 #else
380 int net_ads_usage(int argc, const char **argv)
382 d_printf("ADS support not compiled in\n");
383 return -1;
386 int net_ads(int argc, const char **argv)
388 return net_ads_usage(argc, argv);
391 #endif