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 extern char *opt_password
;
79 extern char *opt_user_name
;
81 ads
= ads_init(NULL
, NULL
, NULL
, NULL
);
84 opt_user_name
= "administrator";
89 asprintf(&prompt
,"%s password: ", opt_user_name
);
90 opt_password
= getpass(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
));
104 static int net_ads_user(int argc
, const char **argv
)
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
));
118 if (ads_count_replies(ads
, res
) == 0) {
119 d_printf("No users found\n");
128 static int net_ads_group(int argc
, const char **argv
)
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
));
142 if (ads_count_replies(ads
, res
) == 0) {
143 d_printf("No groups found\n");
151 static int net_ads_status(int argc
, const char **argv
)
155 extern pstring global_myname
;
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
));
166 if (ads_count_replies(ads
, res
) == 0) {
167 d_printf("No machine account for '%s' found\n", global_myname
);
176 static int net_ads_leave(int argc
, const char **argv
)
178 ADS_STRUCT
*ads
= NULL
;
180 extern pstring global_myname
;
182 if (!(ads
= ads_startup())) {
186 if (!secrets_init()) {
187 DEBUG(1,("Failed to initialise secrets database\n"));
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
);
198 d_printf("Removed '%s' from realm '%s'\n", global_myname
, ads
->realm
);
203 static int net_ads_join(int argc
, const char **argv
)
209 extern pstring global_myname
;
210 const char *org_unit
= "Computers";
215 if (argc
> 0) org_unit
= argv
[0];
217 if (!secrets_init()) {
218 DEBUG(1,("Failed to initialise secrets database\n"));
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
);
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
);
238 if (!ADS_ERR_OK(rc
)) {
239 d_printf("ads_join_realm: %s\n", ads_errstr(rc
));
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
));
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
));
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
));
261 if (!secrets_store_domain_sid(lp_workgroup(), &dom_sid
)) {
262 DEBUG(1,("Failed to save domain sid\n"));
266 if (!secrets_store_machine_password(password
)) {
267 DEBUG(1,("Failed to save machine password\n"));
271 d_printf("Joined '%s' to realm '%s'\n", global_myname
, ads
->realm
);
279 static int net_ads_password(int argc
, const char **argv
)
282 extern char *opt_user_name
;
283 extern char *opt_password
;
284 char *auth_principal
= opt_user_name
;
285 char *auth_password
= opt_password
;
287 char *new_password
= NULL
;
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
, '@');
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");
319 d_printf("Password change for %s completed.\n", argv
[0]);
327 static int net_ads_change_localhost_pass(int argc
, const char **argv
)
330 extern pstring global_myname
;
331 char *host_principal
;
336 if (!(ads
= ads_init(NULL
, NULL
, NULL
, NULL
))) return -1;
338 hostname
= strdup(global_myname
);
340 asprintf(&host_principal
, "%s@%s", hostname
, ads
->realm
);
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");
349 SAFE_FREE(host_principal
);
353 d_printf("Password change for principal HOST/%s succeeded.\n", host_principal
);
355 SAFE_FREE(host_principal
);
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
},
375 return net_run_function(argc
, argv
, func
, net_ads_usage
);
380 int net_ads_usage(int argc
, const char **argv
)
382 d_printf("ADS support not compiled in\n");
386 int net_ads(int argc
, const char **argv
)
388 return net_ads_usage(argc
, argv
);