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)
6 Copyright (C) 2002 Jim McDonough (jmcd@us.ibm.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.
24 #include "../utils/net.h"
28 int net_ads_usage(int argc, const char **argv)
31 "\nnet ads join <org_unit>"\
32 "\n\tjoins the local machine to a ADS realm\n"\
34 "\n\tremoves the local machine from a ADS realm\n"\
36 "\n\ttests that an exiting join is OK\n"\
38 "\n\tlist, add, or delete users in the realm\n"\
40 "\n\tlist, add, or delete groups in the realm\n"\
42 "\n\tshows some info on the server\n"\
44 "\n\tdump the machine account details to stdout\n"
46 "\n\tperform a CLDAP search on the server\n"
47 "\nnet ads password <username@realm> -Uadmin_username@realm%%admin_pass"\
48 "\n\tchange a user's password using an admin account"\
49 "\n\t(note: use realm in UPPERCASE)\n"\
50 "\nnet ads changetrustpw"\
51 "\n\tchange the trust account password of this machine in the AD tree\n"\
52 "\nnet ads printer [info | publish | remove] <printername> <servername>"\
53 "\n\t lookup, add, or remove directory entry for a printer\n"\
55 "\n\tperform a raw LDAP search and dump the results\n"
57 "\n\tperform a raw LDAP search and dump attributes of a particular DN\n"
64 this implements the CLDAP based netlogon lookup requests
65 for finding the domain controller of a ADS domain
67 static int net_ads_lookup(int argc, const char **argv)
71 ads = ads_init(NULL, NULL, opt_host);
73 ads->auth.flags |= ADS_AUTH_NO_BIND;
78 if (!ads || !ads->config.realm) {
79 d_printf("Didn't find the cldap server!\n");
83 return ads_cldap_netlogon(ads);
88 static int net_ads_info(int argc, const char **argv)
92 ads = ads_init(NULL, NULL, opt_host);
95 ads->auth.flags |= ADS_AUTH_NO_BIND;
100 if (!ads || !ads->config.realm) {
101 d_printf("Didn't find the ldap server!\n");
105 d_printf("LDAP server: %s\n", inet_ntoa(ads->ldap_ip));
106 d_printf("LDAP server name: %s\n", ads->config.ldap_server_name);
107 d_printf("Realm: %s\n", ads->config.realm);
108 d_printf("Bind Path: %s\n", ads->config.bind_path);
109 d_printf("LDAP port: %d\n", ads->ldap_port);
110 d_printf("Server time: %s\n", http_timestring(ads->config.current_time));
112 d_printf("KDC server: %s\n", ads->auth.kdc_server );
113 d_printf("Server time offset: %d\n", ads->auth.time_offset );
118 static void use_in_memory_ccache(void) {
119 /* Use in-memory credentials cache so we do not interfere with
120 * existing credentials */
121 setenv(KRB5_ENV_CCNAME, "MEMORY:net_ads", 1);
124 static ADS_STRUCT *ads_startup(void)
128 BOOL need_password = False;
129 BOOL second_time = False;
132 ads = ads_init(NULL, NULL, opt_host);
134 if (!opt_user_name) {
135 opt_user_name = "administrator";
138 if (opt_user_specified) {
139 need_password = True;
143 if (!opt_password && need_password) {
145 asprintf(&prompt,"%s password: ", opt_user_name);
146 opt_password = getpass(prompt);
151 use_in_memory_ccache();
152 ads->auth.password = smb_xstrdup(opt_password);
155 ads->auth.user_name = smb_xstrdup(opt_user_name);
158 * If the username is of the form "name@realm",
159 * extract the realm and convert to upper case.
160 * This is only used to establish the connection.
162 if ((cp = strchr(ads->auth.user_name, '@'))!=0) {
164 ads->auth.realm = smb_xstrdup(cp);
165 strupper(ads->auth.realm);
168 status = ads_connect(ads);
170 if (!ADS_ERR_OK(status)) {
171 if (!need_password && !second_time) {
172 need_password = True;
176 DEBUG(1,("ads_connect: %s\n", ads_errstr(status)));
185 Check to see if connection can be made via ads.
186 ads_startup() stores the password in opt_password if it needs to so
187 that rpc or rap can use it without re-prompting.
189 int net_ads_check(void)
201 determine the netbios workgroup name for a domain
203 static int net_ads_workgroup(int argc, const char **argv)
209 if (!(ads = ads_startup())) return -1;
211 if (!(ctx = talloc_init("net_ads_workgroup"))) {
215 if (!ADS_ERR_OK(ads_workgroup_name(ads, ctx, &workgroup))) {
216 d_printf("Failed to find workgroup for realm '%s'\n",
222 d_printf("Workgroup: %s\n", workgroup);
231 static BOOL usergrp_display(char *field, void **values, void *data_area)
233 char **disp_fields = (char **) data_area;
235 if (!field) { /* must be end of record */
236 if (!strchr_m(disp_fields[0], '$')) {
238 d_printf("%-21.21s %s\n",
239 disp_fields[0], disp_fields[1]);
241 d_printf("%s\n", disp_fields[0]);
243 SAFE_FREE(disp_fields[0]);
244 SAFE_FREE(disp_fields[1]);
247 if (!values) /* must be new field, indicate string field */
249 if (StrCaseCmp(field, "sAMAccountName") == 0) {
250 disp_fields[0] = strdup((char *) values[0]);
252 if (StrCaseCmp(field, "description") == 0)
253 disp_fields[1] = strdup((char *) values[0]);
257 static int net_ads_user_usage(int argc, const char **argv)
259 return net_help_user(argc, argv);
262 static int ads_user_add(int argc, const char **argv)
270 if (argc < 1) return net_ads_user_usage(argc, argv);
272 if (!(ads = ads_startup())) return -1;
274 status = ads_find_user_acct(ads, &res, argv[0]);
276 if (!ADS_ERR_OK(status)) {
277 d_printf("ads_user_add: %s\n", ads_errstr(status));
281 if (ads_count_replies(ads, res)) {
282 d_printf("ads_user_add: User %s already exists\n", argv[0]);
286 status = ads_add_user_acct(ads, argv[0], opt_container, opt_comment);
288 if (!ADS_ERR_OK(status)) {
289 d_printf("Could not add user %s: %s\n", argv[0],
294 /* if no password is to be set, we're done */
296 d_printf("User %s added\n", argv[0]);
301 /* try setting the password */
302 asprintf(&upn, "%s@%s", argv[0], ads->config.realm);
303 status = ads_krb5_set_password(ads->auth.kdc_server, upn, argv[1],
304 ads->auth.time_offset);
306 if (ADS_ERR_OK(status)) {
307 d_printf("User %s added\n", argv[0]);
312 /* password didn't set, delete account */
313 d_printf("Could not add user %s. Error setting password %s\n",
314 argv[0], ads_errstr(status));
315 ads_msgfree(ads, res);
316 status=ads_find_user_acct(ads, &res, argv[0]);
317 if (ADS_ERR_OK(status)) {
318 userdn = ads_get_dn(ads, res);
319 ads_del_dn(ads, userdn);
320 ads_memfree(ads, userdn);
325 ads_msgfree(ads, res);
330 static int ads_user_info(int argc, const char **argv)
335 const char *attrs[] = {"memberOf", NULL};
336 char *searchstring=NULL;
338 char *escaped_user = escape_ldap_string_alloc(argv[0]);
340 if (argc < 1) return net_ads_user_usage(argc, argv);
342 if (!(ads = ads_startup())) return -1;
345 d_printf("ads_user_info: failed to escape user %s\n", argv[0]);
349 asprintf(&searchstring, "(sAMAccountName=%s)", escaped_user);
350 rc = ads_search(ads, &res, searchstring, attrs);
351 safe_free(searchstring);
353 if (!ADS_ERR_OK(rc)) {
354 d_printf("ads_search: %s\n", ads_errstr(rc));
358 grouplist = ldap_get_values(ads->ld, res, "memberOf");
363 for (i=0;grouplist[i];i++) {
364 groupname = ldap_explode_dn(grouplist[i], 1);
365 d_printf("%s\n", groupname[0]);
366 ldap_value_free(groupname);
368 ldap_value_free(grouplist);
371 ads_msgfree(ads, res);
377 static int ads_user_delete(int argc, const char **argv)
384 if (argc < 1) return net_ads_user_usage(argc, argv);
386 if (!(ads = ads_startup())) return -1;
388 rc = ads_find_user_acct(ads, &res, argv[0]);
389 if (!ADS_ERR_OK(rc)) {
390 DEBUG(0, ("User %s does not exist\n", argv[0]));
393 userdn = ads_get_dn(ads, res);
394 ads_msgfree(ads, res);
395 rc = ads_del_dn(ads, userdn);
396 ads_memfree(ads, userdn);
397 if (!ADS_ERR_OK(rc)) {
398 d_printf("User %s deleted\n", argv[0]);
401 d_printf("Error deleting user %s: %s\n", argv[0],
406 int net_ads_user(int argc, const char **argv)
408 struct functable func[] = {
409 {"ADD", ads_user_add},
410 {"INFO", ads_user_info},
411 {"DELETE", ads_user_delete},
416 const char *shortattrs[] = {"sAMAccountName", NULL};
417 const char *longattrs[] = {"sAMAccountName", "description", NULL};
418 char *disp_fields[2] = {NULL, NULL};
421 if (!(ads = ads_startup())) return -1;
423 if (opt_long_list_entries)
424 d_printf("\nUser name Comment"\
425 "\n-----------------------------\n");
427 rc = ads_do_search_all_fn(ads, ads->config.bind_path,
429 "(objectclass=user)",
430 opt_long_list_entries ? longattrs :
431 shortattrs, usergrp_display,
437 return net_run_function(argc, argv, func, net_ads_user_usage);
440 static int net_ads_group_usage(int argc, const char **argv)
442 return net_help_group(argc, argv);
445 static int ads_group_add(int argc, const char **argv)
452 if (argc < 1) return net_ads_group_usage(argc, argv);
454 if (!(ads = ads_startup())) return -1;
456 status = ads_find_user_acct(ads, &res, argv[0]);
458 if (!ADS_ERR_OK(status)) {
459 d_printf("ads_group_add: %s\n", ads_errstr(status));
463 if (ads_count_replies(ads, res)) {
464 d_printf("ads_group_add: Group %s already exists\n", argv[0]);
465 ads_msgfree(ads, res);
469 status = ads_add_group_acct(ads, argv[0], opt_container, opt_comment);
471 if (ADS_ERR_OK(status)) {
472 d_printf("Group %s added\n", argv[0]);
475 d_printf("Could not add group %s: %s\n", argv[0],
481 ads_msgfree(ads, res);
486 static int ads_group_delete(int argc, const char **argv)
493 if (argc < 1) return net_ads_group_usage(argc, argv);
495 if (!(ads = ads_startup())) return -1;
497 rc = ads_find_user_acct(ads, &res, argv[0]);
498 if (!ADS_ERR_OK(rc)) {
499 DEBUG(0, ("Group %s does not exist\n", argv[0]));
502 groupdn = ads_get_dn(ads, res);
503 ads_msgfree(ads, res);
504 rc = ads_del_dn(ads, groupdn);
505 ads_memfree(ads, groupdn);
506 if (!ADS_ERR_OK(rc)) {
507 d_printf("Group %s deleted\n", argv[0]);
510 d_printf("Error deleting group %s: %s\n", argv[0],
515 int net_ads_group(int argc, const char **argv)
517 struct functable func[] = {
518 {"ADD", ads_group_add},
519 {"DELETE", ads_group_delete},
524 const char *shortattrs[] = {"sAMAccountName", NULL};
525 const char *longattrs[] = {"sAMAccountName", "description", NULL};
526 char *disp_fields[2] = {NULL, NULL};
529 if (!(ads = ads_startup())) return -1;
531 if (opt_long_list_entries)
532 d_printf("\nGroup name Comment"\
533 "\n-----------------------------\n");
534 rc = ads_do_search_all_fn(ads, ads->config.bind_path,
536 "(objectclass=group)",
537 opt_long_list_entries ? longattrs :
538 shortattrs, usergrp_display,
544 return net_run_function(argc, argv, func, net_ads_group_usage);
547 static int net_ads_status(int argc, const char **argv)
553 if (!(ads = ads_startup())) return -1;
555 rc = ads_find_machine_acct(ads, &res, global_myname());
556 if (!ADS_ERR_OK(rc)) {
557 d_printf("ads_find_machine_acct: %s\n", ads_errstr(rc));
561 if (ads_count_replies(ads, res) == 0) {
562 d_printf("No machine account for '%s' found\n", global_myname());
571 static int net_ads_leave(int argc, const char **argv)
573 ADS_STRUCT *ads = NULL;
576 if (!secrets_init()) {
577 DEBUG(1,("Failed to initialise secrets database\n"));
583 asprintf(&user_name, "%s$", global_myname());
584 opt_password = secrets_fetch_machine_password(opt_target_workgroup, NULL, NULL);
585 opt_user_name = user_name;
588 if (!(ads = ads_startup())) {
592 rc = ads_leave_realm(ads, global_myname());
593 if (!ADS_ERR_OK(rc)) {
594 d_printf("Failed to delete host '%s' from the '%s' realm.\n",
595 global_myname(), ads->config.realm);
599 d_printf("Removed '%s' from realm '%s'\n", global_myname(), ads->config.realm);
604 static int net_ads_join_ok(void)
607 ADS_STRUCT *ads = NULL;
609 if (!secrets_init()) {
610 DEBUG(1,("Failed to initialise secrets database\n"));
614 asprintf(&user_name, "%s$", global_myname());
615 opt_user_name = user_name;
616 opt_password = secrets_fetch_machine_password(opt_target_workgroup, NULL, NULL);
618 if (!(ads = ads_startup())) {
627 check that an existing join is OK
629 int net_ads_testjoin(int argc, const char **argv)
631 use_in_memory_ccache();
633 /* Display success or failure */
634 if (net_ads_join_ok() != 0) {
635 fprintf(stderr,"Join to domain is not valid\n");
639 printf("Join is OK\n");
644 join a domain using ADS
646 int net_ads_join(int argc, const char **argv)
652 const char *org_unit = "Computers";
657 uint32 sec_channel_type = SEC_CHAN_WKSTA;
658 uint32 account_type = UF_WORKSTATION_TRUST_ACCOUNT;
660 if (argc > 0) org_unit = argv[0];
662 if (!secrets_init()) {
663 DEBUG(1,("Failed to initialise secrets database\n"));
667 tmp_password = generate_random_str(DEFAULT_TRUST_ACCOUNT_PASSWORD_LENGTH);
668 password = strdup(tmp_password);
670 if (!(ads = ads_startup())) return -1;
672 ou_str = ads_ou_string(org_unit);
673 asprintf(&dn, "%s,%s", ou_str, ads->config.bind_path);
676 rc = ads_search_dn(ads, &res, dn, NULL);
677 ads_msgfree(ads, res);
679 if (rc.error_type == ADS_ERROR_LDAP && rc.err.rc == LDAP_NO_SUCH_OBJECT) {
680 d_printf("ads_join_realm: organizational unit %s does not exist (dn:%s)\n",
686 if (!ADS_ERR_OK(rc)) {
687 d_printf("ads_join_realm: %s\n", ads_errstr(rc));
691 rc = ads_join_realm(ads, global_myname(), account_type, org_unit);
692 if (!ADS_ERR_OK(rc)) {
693 d_printf("ads_join_realm: %s\n", ads_errstr(rc));
697 rc = ads_domain_sid(ads, &dom_sid);
698 if (!ADS_ERR_OK(rc)) {
699 d_printf("ads_domain_sid: %s\n", ads_errstr(rc));
703 rc = ads_set_machine_password(ads, global_myname(), password);
704 if (!ADS_ERR_OK(rc)) {
705 d_printf("ads_set_machine_password: %s\n", ads_errstr(rc));
709 if (!secrets_store_domain_sid(lp_workgroup(), &dom_sid)) {
710 DEBUG(1,("Failed to save domain sid\n"));
714 if (!secrets_store_machine_password(password, lp_workgroup(), sec_channel_type)) {
715 DEBUG(1,("Failed to save machine password\n"));
719 d_printf("Joined '%s' to realm '%s'\n", global_myname(), ads->config.realm);
726 int net_ads_printer_usage(int argc, const char **argv)
729 "\nnet ads printer info <printer> <server>"
730 "\n\tlookup info in directory for printer on server"
731 "\n\t(note: printer defaults to \"*\", server defaults to local)\n"
732 "\nnet ads printer publish <printername>"
733 "\n\tpublish printer in directory"
734 "\n\t(note: printer name is required)\n"
735 "\nnet ads printer remove <printername>"
736 "\n\tremove printer from directory"
737 "\n\t(note: printer name is required)\n");
741 static int net_ads_printer_info(int argc, const char **argv)
745 const char *servername, *printername;
748 if (!(ads = ads_startup())) return -1;
751 printername = argv[0];
756 servername = argv[1];
758 servername = global_myname();
760 rc = ads_find_printer_on_server(ads, &res, printername, servername);
762 if (!ADS_ERR_OK(rc)) {
763 d_printf("ads_find_printer_on_server: %s\n", ads_errstr(rc));
764 ads_msgfree(ads, res);
768 if (ads_count_replies(ads, res) == 0) {
769 d_printf("Printer '%s' not found\n", printername);
770 ads_msgfree(ads, res);
775 ads_msgfree(ads, res);
780 void do_drv_upgrade_printer(int msg_type, pid_t src, void *buf, size_t len)
785 static int net_ads_printer_publish(int argc, const char **argv)
789 const char *servername;
790 struct cli_state *cli;
791 struct in_addr server_ip;
793 TALLOC_CTX *mem_ctx = talloc_init("net_ads_printer_publish");
794 ADS_MODLIST mods = ads_init_mods(mem_ctx);
795 char *prt_dn, *srv_dn, **srv_cn;
798 if (!(ads = ads_startup())) return -1;
801 return net_ads_printer_usage(argc, argv);
804 servername = argv[1];
806 servername = global_myname();
808 ads_find_machine_acct(ads, &res, servername);
809 srv_dn = ldap_get_dn(ads->ld, res);
810 srv_cn = ldap_explode_dn(srv_dn, 1);
811 asprintf(&prt_dn, "cn=%s-%s,%s", srv_cn[0], argv[0], srv_dn);
813 resolve_name(servername, &server_ip, 0x20);
815 nt_status = cli_full_connection(&cli, global_myname(), servername,
818 opt_user_name, opt_workgroup,
819 opt_password ? opt_password : "",
820 CLI_FULL_CONNECTION_USE_KERBEROS,
823 cli_nt_session_open(cli, PI_SPOOLSS);
824 get_remote_printer_publishing_data(cli, mem_ctx, &mods, argv[0]);
826 rc = ads_add_printer_entry(ads, prt_dn, mem_ctx, &mods);
827 if (!ADS_ERR_OK(rc)) {
828 d_printf("ads_publish_printer: %s\n", ads_errstr(rc));
832 d_printf("published printer\n");
837 static int net_ads_printer_remove(int argc, const char **argv)
841 const char *servername;
845 if (!(ads = ads_startup())) return -1;
848 return net_ads_printer_usage(argc, argv);
851 servername = argv[1];
853 servername = global_myname();
855 rc = ads_find_printer_on_server(ads, &res, argv[0], servername);
857 if (!ADS_ERR_OK(rc)) {
858 d_printf("ads_find_printer_on_server: %s\n", ads_errstr(rc));
859 ads_msgfree(ads, res);
863 if (ads_count_replies(ads, res) == 0) {
864 d_printf("Printer '%s' not found\n", argv[1]);
865 ads_msgfree(ads, res);
869 prt_dn = ads_get_dn(ads, res);
870 ads_msgfree(ads, res);
871 rc = ads_del_dn(ads, prt_dn);
872 ads_memfree(ads, prt_dn);
874 if (!ADS_ERR_OK(rc)) {
875 d_printf("ads_del_dn: %s\n", ads_errstr(rc));
882 static int net_ads_printer(int argc, const char **argv)
884 struct functable func[] = {
885 {"INFO", net_ads_printer_info},
886 {"PUBLISH", net_ads_printer_publish},
887 {"REMOVE", net_ads_printer_remove},
891 return net_run_function(argc, argv, func, net_ads_printer_usage);
895 static int net_ads_password(int argc, const char **argv)
898 const char *auth_principal = opt_user_name;
899 const char *auth_password = opt_password;
901 char *new_password = NULL;
906 if (opt_user_name == NULL || opt_password == NULL) {
907 d_printf("You must supply an administrator username/password\n");
913 d_printf("ERROR: You must say which username to change password for\n");
918 if (!strchr(user, '@')) {
919 asprintf(&c, "%s@%s", argv[0], lp_realm());
923 use_in_memory_ccache();
924 c = strchr(auth_principal, '@');
931 /* use the realm so we can eventually change passwords for users
932 in realms other than default */
933 if (!(ads = ads_init(realm, NULL, NULL))) return -1;
935 /* we don't actually need a full connect, but it's the easy way to
936 fill in the KDC's addresss */
939 if (!ads || !ads->config.realm) {
940 d_printf("Didn't find the kerberos server!\n");
944 asprintf(&prompt, "Enter new password for %s:", user);
946 new_password = getpass(prompt);
948 ret = kerberos_set_password(ads->auth.kdc_server, auth_principal,
949 auth_password, user, new_password, ads->auth.time_offset);
950 if (!ADS_ERR_OK(ret)) {
951 d_printf("Password change failed :-( ...\n");
957 d_printf("Password change for %s completed.\n", user);
965 int net_ads_changetrustpw(int argc, const char **argv)
968 char *host_principal;
973 if (!secrets_init()) {
974 DEBUG(1,("Failed to initialise secrets database\n"));
978 asprintf(&user_name, "%s$", global_myname());
979 opt_user_name = user_name;
981 opt_password = secrets_fetch_machine_password(opt_target_workgroup, NULL, NULL);
983 use_in_memory_ccache();
985 if (!(ads = ads_startup())) {
989 hostname = strdup(global_myname());
991 asprintf(&host_principal, "%s@%s", hostname, ads->config.realm);
993 d_printf("Changing password for principal: HOST/%s\n", host_principal);
995 ret = ads_change_trust_account_password(ads, host_principal);
997 if (!ADS_ERR_OK(ret)) {
998 d_printf("Password change failed :-( ...\n");
1000 SAFE_FREE(host_principal);
1004 d_printf("Password change for principal HOST/%s succeeded.\n", host_principal);
1006 SAFE_FREE(host_principal);
1012 help for net ads search
1014 static int net_ads_search_usage(int argc, const char **argv)
1017 "\nnet ads search <expression> <attributes...>\n"\
1018 "\nperform a raw LDAP search on a ADS server and dump the results\n"\
1019 "The expression is a standard LDAP search expression, and the\n"\
1020 "attributes are a list of LDAP fields to show in the results\n\n"\
1021 "Example: net ads search '(objectCategory=group)' sAMAccountName\n\n"
1023 net_common_flags_usage(argc, argv);
1029 general ADS search function. Useful in diagnosing problems in ADS
1031 static int net_ads_search(int argc, const char **argv)
1035 const char *ldap_exp;
1040 return net_ads_search_usage(argc, argv);
1043 if (!(ads = ads_startup())) {
1050 rc = ads_do_search_all(ads, ads->config.bind_path,
1052 ldap_exp, attrs, &res);
1053 if (!ADS_ERR_OK(rc)) {
1054 d_printf("search failed: %s\n", ads_errstr(rc));
1058 d_printf("Got %d replies\n\n", ads_count_replies(ads, res));
1060 /* dump the results */
1063 ads_msgfree(ads, res);
1071 help for net ads search
1073 static int net_ads_dn_usage(int argc, const char **argv)
1076 "\nnet ads dn <dn> <attributes...>\n"\
1077 "\nperform a raw LDAP search on a ADS server and dump the results\n"\
1078 "The DN standard LDAP DN, and the attributes are a list of LDAP fields \n"\
1079 "to show in the results\n\n"\
1080 "Example: net ads dn 'CN=administrator,CN=Users,DC=my,DC=domain' sAMAccountName\n\n"
1082 net_common_flags_usage(argc, argv);
1088 general ADS search function. Useful in diagnosing problems in ADS
1090 static int net_ads_dn(int argc, const char **argv)
1099 return net_ads_dn_usage(argc, argv);
1102 if (!(ads = ads_startup())) {
1109 rc = ads_do_search_all(ads, dn,
1111 "(objectclass=*)", attrs, &res);
1112 if (!ADS_ERR_OK(rc)) {
1113 d_printf("search failed: %s\n", ads_errstr(rc));
1117 d_printf("Got %d replies\n\n", ads_count_replies(ads, res));
1119 /* dump the results */
1122 ads_msgfree(ads, res);
1129 int net_ads_help(int argc, const char **argv)
1131 struct functable func[] = {
1132 {"USER", net_ads_user_usage},
1133 {"GROUP", net_ads_group_usage},
1134 {"PRINTER", net_ads_printer_usage},
1135 {"SEARCH", net_ads_search_usage},
1137 {"INFO", net_ads_info},
1138 {"JOIN", net_ads_join},
1139 {"LEAVE", net_ads_leave},
1140 {"STATUS", net_ads_status},
1141 {"PASSWORD", net_ads_password},
1142 {"CHANGETRUSTPW", net_ads_changetrustpw},
1147 return net_run_function(argc, argv, func, net_ads_usage);
1150 int net_ads(int argc, const char **argv)
1152 struct functable func[] = {
1153 {"INFO", net_ads_info},
1154 {"JOIN", net_ads_join},
1155 {"TESTJOIN", net_ads_testjoin},
1156 {"LEAVE", net_ads_leave},
1157 {"STATUS", net_ads_status},
1158 {"USER", net_ads_user},
1159 {"GROUP", net_ads_group},
1160 {"PASSWORD", net_ads_password},
1161 {"CHANGETRUSTPW", net_ads_changetrustpw},
1162 {"PRINTER", net_ads_printer},
1163 {"SEARCH", net_ads_search},
1165 {"WORKGROUP", net_ads_workgroup},
1166 {"LOOKUP", net_ads_lookup},
1167 {"HELP", net_ads_help},
1171 return net_run_function(argc, argv, func, net_ads_usage);
1176 static int net_ads_noads(void)
1178 d_printf("ADS support not compiled in\n");
1182 int net_ads_usage(int argc, const char **argv)
1184 return net_ads_noads();
1187 int net_ads_help(int argc, const char **argv)
1189 return net_ads_noads();
1192 int net_ads_changetrustpw(int argc, const char **argv)
1194 return net_ads_noads();
1197 int net_ads_join(int argc, const char **argv)
1199 return net_ads_noads();
1202 int net_ads_user(int argc, const char **argv)
1204 return net_ads_noads();
1207 int net_ads_group(int argc, const char **argv)
1209 return net_ads_noads();
1212 /* this one shouldn't display a message */
1213 int net_ads_check(void)
1218 int net_ads(int argc, const char **argv)
1220 return net_ads_usage(argc, argv);