2 Samba Unix/Linux SMB client library
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.
27 int net_ads_usage(int argc, const char **argv)
30 "\nnet ads join <org_unit>"\
31 "\n\tjoins the local machine to a ADS realm\n"\
33 "\n\tremoves the local machine from a ADS realm\n"\
35 "\n\tlist users in the realm\n"\
37 "\n\tlist groups in the realm\n"\
39 "\n\tshows some info on the server\n"\
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"
46 "\n\tchange the trust account password of this machine in the AD tree\n"
52 static int net_ads_info(int argc, const char **argv)
56 ads = ads_init(NULL, NULL, NULL, NULL);
60 d_printf("Didn't find the ldap server!\n");
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);
74 static ADS_STRUCT *ads_startup(void)
78 BOOL need_password = False;
79 BOOL second_time = False;
80 extern char *opt_password;
81 extern char *opt_user_name;
82 extern BOOL opt_user_specified;
85 ads = ads_init(NULL, NULL, NULL, NULL);
88 opt_user_name = "administrator";
91 if (opt_user_specified)
95 if (!opt_password && need_password) {
97 asprintf(&prompt,"%s password: ", opt_user_name);
98 opt_password = getpass(prompt);
100 ads->password = strdup(opt_password);
103 ads->user_name = strdup(opt_user_name);
105 status = ads_connect(ads);
106 if (!ADS_ERR_OK(status)) {
107 if (!need_password && !second_time) {
108 need_password = True;
112 d_printf("ads_connect: %s\n", ads_errstr(status));
119 static int net_ads_user(int argc, const char **argv)
124 const char *attrs[] = {"sAMAccountName", "name", "objectSid", NULL};
126 if (!(ads = ads_startup())) return -1;
127 rc = ads_search(ads, &res, "(objectclass=user)", attrs);
128 if (!ADS_ERR_OK(rc)) {
129 d_printf("ads_search: %s\n", ads_errstr(rc));
133 if (ads_count_replies(ads, res) == 0) {
134 d_printf("No users found\n");
143 static int net_ads_group(int argc, const char **argv)
148 const char *attrs[] = {"sAMAccountName", "name", "objectSid", NULL};
150 if (!(ads = ads_startup())) return -1;
151 rc = ads_search(ads, &res, "(objectclass=group)", attrs);
152 if (!ADS_ERR_OK(rc)) {
153 d_printf("ads_search: %s\n", ads_errstr(rc));
157 if (ads_count_replies(ads, res) == 0) {
158 d_printf("No groups found\n");
166 static int net_ads_status(int argc, const char **argv)
170 extern pstring global_myname;
173 if (!(ads = ads_startup())) return -1;
175 rc = ads_find_machine_acct(ads, &res, global_myname);
176 if (!ADS_ERR_OK(rc)) {
177 d_printf("ads_find_machine_acct: %s\n", ads_errstr(rc));
181 if (ads_count_replies(ads, res) == 0) {
182 d_printf("No machine account for '%s' found\n", global_myname);
191 static int net_ads_leave(int argc, const char **argv)
193 ADS_STRUCT *ads = NULL;
195 extern pstring global_myname;
197 if (!(ads = ads_startup())) {
201 if (!secrets_init()) {
202 DEBUG(1,("Failed to initialise secrets database\n"));
206 rc = ads_leave_realm(ads, global_myname);
207 if (!ADS_ERR_OK(rc)) {
208 d_printf("Failed to delete host '%s' from the '%s' realm.\n",
209 global_myname, ads->realm);
213 d_printf("Removed '%s' from realm '%s'\n", global_myname, ads->realm);
218 static int net_ads_join(int argc, const char **argv)
224 extern pstring global_myname;
225 const char *org_unit = "Computers";
231 if (argc > 0) org_unit = argv[0];
233 if (!secrets_init()) {
234 DEBUG(1,("Failed to initialise secrets database\n"));
238 tmp_password = generate_random_str(DEFAULT_TRUST_ACCOUNT_PASSWORD_LENGTH);
239 password = strdup(tmp_password);
241 if (!(ads = ads_startup())) return -1;
243 ou_str = ads_ou_string(org_unit);
244 asprintf(&dn, "%s,%s", ou_str, ads->bind_path);
247 rc = ads_search_dn(ads, &res, dn, NULL);
248 ads_msgfree(ads, res);
250 if (rc.error_type == ADS_ERROR_LDAP && rc.rc == LDAP_NO_SUCH_OBJECT) {
251 d_printf("ads_join_realm: organisational unit %s does not exist (dn:%s)\n",
257 if (!ADS_ERR_OK(rc)) {
258 d_printf("ads_join_realm: %s\n", ads_errstr(rc));
262 rc = ads_join_realm(ads, global_myname, org_unit);
263 if (!ADS_ERR_OK(rc)) {
264 d_printf("ads_join_realm: %s\n", ads_errstr(rc));
268 rc = ads_set_machine_password(ads, global_myname, password);
269 if (!ADS_ERR_OK(rc)) {
270 d_printf("ads_set_machine_password: %s\n", ads_errstr(rc));
274 rc = ads_domain_sid(ads, &dom_sid);
275 if (!ADS_ERR_OK(rc)) {
276 d_printf("ads_domain_sid: %s\n", ads_errstr(rc));
280 if (!secrets_store_domain_sid(lp_workgroup(), &dom_sid)) {
281 DEBUG(1,("Failed to save domain sid\n"));
285 if (!secrets_store_machine_password(password)) {
286 DEBUG(1,("Failed to save machine password\n"));
290 d_printf("Joined '%s' to realm '%s'\n", global_myname, ads->realm);
298 static int net_ads_password(int argc, const char **argv)
301 extern char *opt_user_name;
302 extern char *opt_password;
303 char *auth_principal = opt_user_name;
304 char *auth_password = opt_password;
306 char *new_password = NULL;
312 if ((argc != 1) || (opt_user_name == NULL) ||
313 (opt_password == NULL) || (strchr(opt_user_name, '@') == NULL) ||
314 (strchr(argv[0], '@') == NULL)) {
315 return net_ads_usage(argc, argv);
318 c = strchr(auth_principal, '@');
321 /* use the realm so we can eventually change passwords for users
322 in realms other than default */
323 if (!(ads = ads_init(realm, NULL, NULL, NULL))) return -1;
325 asprintf(&prompt, "Enter new password for %s:", argv[0]);
327 new_password = getpass(prompt);
329 ret = kerberos_set_password(ads->kdc_server, auth_principal,
330 auth_password, argv[0], new_password);
331 if (!ADS_ERR_OK(ret)) {
332 d_printf("Password change failed :-( ...\n");
338 d_printf("Password change for %s completed.\n", argv[0]);
346 static int net_ads_change_localhost_pass(int argc, const char **argv)
349 extern pstring global_myname;
350 char *host_principal;
355 if (!(ads = ads_init(NULL, NULL, NULL, NULL))) return -1;
357 hostname = strdup(global_myname);
359 asprintf(&host_principal, "%s@%s", hostname, ads->realm);
361 d_printf("Changing password for principal: HOST/%s\n", host_principal);
363 ret = ads_change_trust_account_password(ads, host_principal);
365 if (!ADS_ERR_OK(ret)) {
366 d_printf("Password change failed :-( ...\n");
368 SAFE_FREE(host_principal);
372 d_printf("Password change for principal HOST/%s succeeded.\n", host_principal);
374 SAFE_FREE(host_principal);
380 int net_ads(int argc, const char **argv)
382 struct functable func[] = {
383 {"INFO", net_ads_info},
384 {"JOIN", net_ads_join},
385 {"LEAVE", net_ads_leave},
386 {"STATUS", net_ads_status},
387 {"USER", net_ads_user},
388 {"GROUP", net_ads_group},
389 {"PASSWORD", net_ads_password},
390 {"CHOSTPASS", net_ads_change_localhost_pass},
394 return net_run_function(argc, argv, func, net_ads_usage);
399 int net_ads_usage(int argc, const char **argv)
401 d_printf("ADS support not compiled in\n");
405 int net_ads(int argc, const char **argv)
407 return net_ads_usage(argc, argv);