2 Samba Unix/Linux SMB client library
4 Copyright (C) 2001 Andrew Tridgell (tridge@samba.org)
5 Copyright (C) 2001 Remus Koos (remuskoos@yahoo.com)
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 int net_ads_usage(int argc, const char **argv)
29 "\nnet ads join <org_unit>"\
30 "\n\tjoins the local machine to a ADS realm\n"\
32 "\n\tremoves the local machine from a ADS realm\n"\
34 "\n\tlist users in the realm\n"\
36 "\n\tlist groups in the realm\n"\
38 "\n\tshows some info on the server\n"\
40 "\n\tdump the machine account details to stdout\n"
41 "\nnet ads password <username@realm> -Uadmin_username@realm%%admin_pass"\
42 "\n\tchange a user's password using an admin account"
43 "\n\t(note: use realm in UPPERCASE)\n"
45 "\n\tchange the trust account password of this machine in the AD tree\n"
51 static int net_ads_info(int argc, const char **argv)
55 ads = ads_init(NULL, NULL, NULL, NULL);
59 d_printf("Didn't find the ldap server!\n");
63 d_printf("LDAP server: %s\n", ads->ldap_server);
64 d_printf("LDAP server name: %s\n", ads->ldap_server_name);
65 d_printf("Realm: %s\n", ads->realm);
66 d_printf("Bind Path: %s\n", ads->bind_path);
67 d_printf("LDAP port: %d\n", ads->ldap_port);
73 static ADS_STRUCT *ads_startup(void)
77 BOOL need_password = False;
78 BOOL second_time = False;
79 extern char *opt_password;
80 extern char *opt_user_name;
81 extern BOOL opt_user_specified;
84 ads = ads_init(NULL, NULL, NULL, NULL);
87 opt_user_name = "administrator";
90 if (opt_user_specified)
94 if (!opt_password && need_password) {
96 asprintf(&prompt,"%s password: ", opt_user_name);
97 opt_password = getpass(prompt);
99 ads->password = strdup(opt_password);
102 ads->user_name = strdup(opt_user_name);
104 status = ads_connect(ads);
105 if (!ADS_ERR_OK(status)) {
106 if (!need_password && !second_time) {
107 need_password = True;
111 d_printf("ads_connect: %s\n", ads_errstr(status));
118 static int net_ads_user(int argc, const char **argv)
123 const char *attrs[] = {"sAMAccountName", "name", "objectSid", NULL};
125 if (!(ads = ads_startup())) return -1;
126 rc = ads_search(ads, &res, "(objectclass=user)", attrs);
127 if (!ADS_ERR_OK(rc)) {
128 d_printf("ads_search: %s\n", ads_errstr(rc));
132 if (ads_count_replies(ads, res) == 0) {
133 d_printf("No users found\n");
142 static int net_ads_group(int argc, const char **argv)
147 const char *attrs[] = {"sAMAccountName", "name", "objectSid", NULL};
149 if (!(ads = ads_startup())) return -1;
150 rc = ads_search(ads, &res, "(objectclass=group)", attrs);
151 if (!ADS_ERR_OK(rc)) {
152 d_printf("ads_search: %s\n", ads_errstr(rc));
156 if (ads_count_replies(ads, res) == 0) {
157 d_printf("No groups found\n");
165 static int net_ads_status(int argc, const char **argv)
169 extern pstring global_myname;
172 if (!(ads = ads_startup())) return -1;
174 rc = ads_find_machine_acct(ads, &res, global_myname);
175 if (!ADS_ERR_OK(rc)) {
176 d_printf("ads_find_machine_acct: %s\n", ads_errstr(rc));
180 if (ads_count_replies(ads, res) == 0) {
181 d_printf("No machine account for '%s' found\n", global_myname);
190 static int net_ads_leave(int argc, const char **argv)
192 ADS_STRUCT *ads = NULL;
194 extern pstring global_myname;
196 if (!(ads = ads_startup())) {
200 if (!secrets_init()) {
201 DEBUG(1,("Failed to initialise secrets database\n"));
205 rc = ads_leave_realm(ads, global_myname);
206 if (!ADS_ERR_OK(rc)) {
207 d_printf("Failed to delete host '%s' from the '%s' realm.\n",
208 global_myname, ads->realm);
212 d_printf("Removed '%s' from realm '%s'\n", global_myname, ads->realm);
217 static int net_ads_join(int argc, const char **argv)
223 extern pstring global_myname;
224 const char *org_unit = "Computers";
230 if (argc > 0) org_unit = argv[0];
232 if (!secrets_init()) {
233 DEBUG(1,("Failed to initialise secrets database\n"));
237 tmp_password = generate_random_str(DEFAULT_TRUST_ACCOUNT_PASSWORD_LENGTH);
238 password = strdup(tmp_password);
240 if (!(ads = ads_startup())) return -1;
242 ou_str = ads_ou_string(org_unit);
243 asprintf(&dn, "%s,%s", ou_str, ads->bind_path);
246 rc = ads_search_dn(ads, &res, dn, NULL);
247 ads_msgfree(ads, res);
249 if (rc.error_type == ADS_ERROR_LDAP && rc.rc == LDAP_NO_SUCH_OBJECT) {
250 d_printf("ads_join_realm: organisational unit %s does not exist (dn:%s)\n",
256 if (!ADS_ERR_OK(rc)) {
257 d_printf("ads_join_realm: %s\n", ads_errstr(rc));
261 rc = ads_join_realm(ads, global_myname, org_unit);
262 if (!ADS_ERR_OK(rc)) {
263 d_printf("ads_join_realm: %s\n", ads_errstr(rc));
267 rc = ads_set_machine_password(ads, global_myname, password);
268 if (!ADS_ERR_OK(rc)) {
269 d_printf("ads_set_machine_password: %s\n", ads_errstr(rc));
273 rc = ads_domain_sid(ads, &dom_sid);
274 if (!ADS_ERR_OK(rc)) {
275 d_printf("ads_domain_sid: %s\n", ads_errstr(rc));
279 if (!secrets_store_domain_sid(lp_workgroup(), &dom_sid)) {
280 DEBUG(1,("Failed to save domain sid\n"));
284 if (!secrets_store_machine_password(password)) {
285 DEBUG(1,("Failed to save machine password\n"));
289 d_printf("Joined '%s' to realm '%s'\n", global_myname, ads->realm);
297 static int net_ads_password(int argc, const char **argv)
300 extern char *opt_user_name;
301 extern char *opt_password;
302 char *auth_principal = opt_user_name;
303 char *auth_password = opt_password;
305 char *new_password = NULL;
311 if ((argc != 1) || (opt_user_name == NULL) ||
312 (opt_password == NULL) || (strchr(opt_user_name, '@') == NULL) ||
313 (strchr(argv[0], '@') == NULL)) {
314 return net_ads_usage(argc, argv);
317 c = strchr(auth_principal, '@');
320 /* use the realm so we can eventually change passwords for users
321 in realms other than default */
322 if (!(ads = ads_init(realm, NULL, NULL, NULL))) return -1;
324 asprintf(&prompt, "Enter new password for %s:", argv[0]);
326 new_password = getpass(prompt);
328 ret = kerberos_set_password(ads->kdc_server, auth_principal,
329 auth_password, argv[0], new_password);
330 if (!ADS_ERR_OK(ret)) {
331 d_printf("Password change failed :-( ...\n");
337 d_printf("Password change for %s completed.\n", argv[0]);
345 static int net_ads_change_localhost_pass(int argc, const char **argv)
348 extern pstring global_myname;
349 char *host_principal;
354 if (!(ads = ads_init(NULL, NULL, NULL, NULL))) return -1;
356 hostname = strdup(global_myname);
358 asprintf(&host_principal, "%s@%s", hostname, ads->realm);
360 d_printf("Changing password for principal: HOST/%s\n", host_principal);
362 ret = ads_change_trust_account_password(ads, host_principal);
364 if (!ADS_ERR_OK(ret)) {
365 d_printf("Password change failed :-( ...\n");
367 SAFE_FREE(host_principal);
371 d_printf("Password change for principal HOST/%s succeeded.\n", host_principal);
373 SAFE_FREE(host_principal);
379 int net_ads(int argc, const char **argv)
381 struct functable func[] = {
382 {"INFO", net_ads_info},
383 {"JOIN", net_ads_join},
384 {"LEAVE", net_ads_leave},
385 {"STATUS", net_ads_status},
386 {"USER", net_ads_user},
387 {"GROUP", net_ads_group},
388 {"PASSWORD", net_ads_password},
389 {"CHOSTPASS", net_ads_change_localhost_pass},
393 return net_run_function(argc, argv, func, net_ads_usage);
398 int net_ads_usage(int argc, const char **argv)
400 d_printf("ADS support not compiled in\n");
404 int net_ads(int argc, const char **argv)
406 return net_ads_usage(argc, argv);