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
, '@')) {
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
= krb5_set_password(ads
->auth
.kdc_server
, upn
, argv
[1], ads
->auth
.time_offset
);
305 if (ADS_ERR_OK(status
)) {
306 d_printf("User %s added\n", argv
[0]);
311 /* password didn't set, delete account */
312 d_printf("Could not add user %s. Error setting password %s\n",
313 argv
[0], ads_errstr(status
));
314 ads_msgfree(ads
, res
);
315 status
=ads_find_user_acct(ads
, &res
, argv
[0]);
316 if (ADS_ERR_OK(status
)) {
317 userdn
= ads_get_dn(ads
, res
);
318 ads_del_dn(ads
, userdn
);
319 ads_memfree(ads
, userdn
);
324 ads_msgfree(ads
, res
);
329 static int ads_user_info(int argc
, const char **argv
)
334 const char *attrs
[] = {"memberOf", NULL
};
335 char *searchstring
=NULL
;
337 char *escaped_user
= escape_ldap_string_alloc(argv
[0]);
339 if (argc
< 1) return net_ads_user_usage(argc
, argv
);
341 if (!(ads
= ads_startup())) return -1;
344 d_printf("ads_user_info: failed to escape user %s\n", argv
[0]);
348 asprintf(&searchstring
, "(sAMAccountName=%s)", escaped_user
);
349 rc
= ads_search(ads
, &res
, searchstring
, attrs
);
350 safe_free(searchstring
);
352 if (!ADS_ERR_OK(rc
)) {
353 d_printf("ads_search: %s\n", ads_errstr(rc
));
357 grouplist
= ldap_get_values(ads
->ld
, res
, "memberOf");
362 for (i
=0;grouplist
[i
];i
++) {
363 groupname
= ldap_explode_dn(grouplist
[i
], 1);
364 d_printf("%s\n", groupname
[0]);
365 ldap_value_free(groupname
);
367 ldap_value_free(grouplist
);
370 ads_msgfree(ads
, res
);
376 static int ads_user_delete(int argc
, const char **argv
)
383 if (argc
< 1) return net_ads_user_usage(argc
, argv
);
385 if (!(ads
= ads_startup())) return -1;
387 rc
= ads_find_user_acct(ads
, &res
, argv
[0]);
388 if (!ADS_ERR_OK(rc
)) {
389 DEBUG(0, ("User %s does not exist\n", argv
[0]));
392 userdn
= ads_get_dn(ads
, res
);
393 ads_msgfree(ads
, res
);
394 rc
= ads_del_dn(ads
, userdn
);
395 ads_memfree(ads
, userdn
);
396 if (!ADS_ERR_OK(rc
)) {
397 d_printf("User %s deleted\n", argv
[0]);
400 d_printf("Error deleting user %s: %s\n", argv
[0],
405 int net_ads_user(int argc
, const char **argv
)
407 struct functable func
[] = {
408 {"ADD", ads_user_add
},
409 {"INFO", ads_user_info
},
410 {"DELETE", ads_user_delete
},
415 const char *shortattrs
[] = {"sAMAccountName", NULL
};
416 const char *longattrs
[] = {"sAMAccountName", "description", NULL
};
417 char *disp_fields
[2] = {NULL
, NULL
};
420 if (!(ads
= ads_startup())) return -1;
422 if (opt_long_list_entries
)
423 d_printf("\nUser name Comment"\
424 "\n-----------------------------\n");
426 rc
= ads_do_search_all_fn(ads
, ads
->config
.bind_path
,
428 "(objectclass=user)",
429 opt_long_list_entries
? longattrs
:
430 shortattrs
, usergrp_display
,
436 return net_run_function(argc
, argv
, func
, net_ads_user_usage
);
439 static int net_ads_group_usage(int argc
, const char **argv
)
441 return net_help_group(argc
, argv
);
444 static int ads_group_add(int argc
, const char **argv
)
451 if (argc
< 1) return net_ads_group_usage(argc
, argv
);
453 if (!(ads
= ads_startup())) return -1;
455 status
= ads_find_user_acct(ads
, &res
, argv
[0]);
457 if (!ADS_ERR_OK(status
)) {
458 d_printf("ads_group_add: %s\n", ads_errstr(status
));
462 if (ads_count_replies(ads
, res
)) {
463 d_printf("ads_group_add: Group %s already exists\n", argv
[0]);
464 ads_msgfree(ads
, res
);
468 status
= ads_add_group_acct(ads
, argv
[0], opt_container
, opt_comment
);
470 if (ADS_ERR_OK(status
)) {
471 d_printf("Group %s added\n", argv
[0]);
474 d_printf("Could not add group %s: %s\n", argv
[0],
480 ads_msgfree(ads
, res
);
485 static int ads_group_delete(int argc
, const char **argv
)
492 if (argc
< 1) return net_ads_group_usage(argc
, argv
);
494 if (!(ads
= ads_startup())) return -1;
496 rc
= ads_find_user_acct(ads
, &res
, argv
[0]);
497 if (!ADS_ERR_OK(rc
)) {
498 DEBUG(0, ("Group %s does not exist\n", argv
[0]));
501 groupdn
= ads_get_dn(ads
, res
);
502 ads_msgfree(ads
, res
);
503 rc
= ads_del_dn(ads
, groupdn
);
504 ads_memfree(ads
, groupdn
);
505 if (!ADS_ERR_OK(rc
)) {
506 d_printf("Group %s deleted\n", argv
[0]);
509 d_printf("Error deleting group %s: %s\n", argv
[0],
514 int net_ads_group(int argc
, const char **argv
)
516 struct functable func
[] = {
517 {"ADD", ads_group_add
},
518 {"DELETE", ads_group_delete
},
523 const char *shortattrs
[] = {"sAMAccountName", NULL
};
524 const char *longattrs
[] = {"sAMAccountName", "description", NULL
};
525 char *disp_fields
[2] = {NULL
, NULL
};
528 if (!(ads
= ads_startup())) return -1;
530 if (opt_long_list_entries
)
531 d_printf("\nGroup name Comment"\
532 "\n-----------------------------\n");
533 rc
= ads_do_search_all_fn(ads
, ads
->config
.bind_path
,
535 "(objectclass=group)",
536 opt_long_list_entries
? longattrs
:
537 shortattrs
, usergrp_display
,
543 return net_run_function(argc
, argv
, func
, net_ads_group_usage
);
546 static int net_ads_status(int argc
, const char **argv
)
552 if (!(ads
= ads_startup())) return -1;
554 rc
= ads_find_machine_acct(ads
, &res
, global_myname());
555 if (!ADS_ERR_OK(rc
)) {
556 d_printf("ads_find_machine_acct: %s\n", ads_errstr(rc
));
560 if (ads_count_replies(ads
, res
) == 0) {
561 d_printf("No machine account for '%s' found\n", global_myname());
570 static int net_ads_leave(int argc
, const char **argv
)
572 ADS_STRUCT
*ads
= NULL
;
575 if (!secrets_init()) {
576 DEBUG(1,("Failed to initialise secrets database\n"));
582 asprintf(&user_name
, "%s$", global_myname());
583 opt_password
= secrets_fetch_machine_password(opt_target_workgroup
, NULL
, NULL
);
584 opt_user_name
= user_name
;
587 if (!(ads
= ads_startup())) {
591 rc
= ads_leave_realm(ads
, global_myname());
592 if (!ADS_ERR_OK(rc
)) {
593 d_printf("Failed to delete host '%s' from the '%s' realm.\n",
594 global_myname(), ads
->config
.realm
);
598 d_printf("Removed '%s' from realm '%s'\n", global_myname(), ads
->config
.realm
);
603 static int net_ads_join_ok(void)
606 ADS_STRUCT
*ads
= NULL
;
608 if (!secrets_init()) {
609 DEBUG(1,("Failed to initialise secrets database\n"));
613 asprintf(&user_name
, "%s$", global_myname());
614 opt_user_name
= user_name
;
615 opt_password
= secrets_fetch_machine_password(opt_target_workgroup
, NULL
, NULL
);
617 if (!(ads
= ads_startup())) {
626 check that an existing join is OK
628 int net_ads_testjoin(int argc
, const char **argv
)
630 use_in_memory_ccache();
632 /* Display success or failure */
633 if (net_ads_join_ok() != 0) {
634 fprintf(stderr
,"Join to domain is not valid\n");
638 printf("Join is OK\n");
643 join a domain using ADS
645 int net_ads_join(int argc
, const char **argv
)
651 const char *org_unit
= "Computers";
656 uint32 sec_channel_type
= SEC_CHAN_WKSTA
;
657 uint32 account_type
= UF_WORKSTATION_TRUST_ACCOUNT
;
659 if (argc
> 0) org_unit
= argv
[0];
661 if (!secrets_init()) {
662 DEBUG(1,("Failed to initialise secrets database\n"));
666 tmp_password
= generate_random_str(DEFAULT_TRUST_ACCOUNT_PASSWORD_LENGTH
);
667 password
= strdup(tmp_password
);
669 if (!(ads
= ads_startup())) return -1;
671 ou_str
= ads_ou_string(org_unit
);
672 asprintf(&dn
, "%s,%s", ou_str
, ads
->config
.bind_path
);
675 rc
= ads_search_dn(ads
, &res
, dn
, NULL
);
676 ads_msgfree(ads
, res
);
678 if (rc
.error_type
== ADS_ERROR_LDAP
&& rc
.err
.rc
== LDAP_NO_SUCH_OBJECT
) {
679 d_printf("ads_join_realm: organizational unit %s does not exist (dn:%s)\n",
685 if (!ADS_ERR_OK(rc
)) {
686 d_printf("ads_join_realm: %s\n", ads_errstr(rc
));
690 rc
= ads_join_realm(ads
, global_myname(), account_type
, org_unit
);
691 if (!ADS_ERR_OK(rc
)) {
692 d_printf("ads_join_realm: %s\n", ads_errstr(rc
));
696 rc
= ads_domain_sid(ads
, &dom_sid
);
697 if (!ADS_ERR_OK(rc
)) {
698 d_printf("ads_domain_sid: %s\n", ads_errstr(rc
));
702 rc
= ads_set_machine_password(ads
, global_myname(), password
);
703 if (!ADS_ERR_OK(rc
)) {
704 d_printf("ads_set_machine_password: %s\n", ads_errstr(rc
));
708 if (!secrets_store_domain_sid(lp_workgroup(), &dom_sid
)) {
709 DEBUG(1,("Failed to save domain sid\n"));
713 if (!secrets_store_machine_password(password
, lp_workgroup(), sec_channel_type
)) {
714 DEBUG(1,("Failed to save machine password\n"));
718 d_printf("Joined '%s' to realm '%s'\n", global_myname(), ads
->config
.realm
);
725 int net_ads_printer_usage(int argc
, const char **argv
)
728 "\nnet ads printer info <printer> <server>"
729 "\n\tlookup info in directory for printer on server"
730 "\n\t(note: printer defaults to \"*\", server defaults to local)\n"
731 "\nnet ads printer publish <printername>"
732 "\n\tpublish printer in directory"
733 "\n\t(note: printer name is required)\n"
734 "\nnet ads printer remove <printername>"
735 "\n\tremove printer from directory"
736 "\n\t(note: printer name is required)\n");
740 static int net_ads_printer_info(int argc
, const char **argv
)
744 const char *servername
, *printername
;
747 if (!(ads
= ads_startup())) return -1;
750 printername
= argv
[0];
755 servername
= argv
[1];
757 servername
= global_myname();
759 rc
= ads_find_printer_on_server(ads
, &res
, printername
, servername
);
761 if (!ADS_ERR_OK(rc
)) {
762 d_printf("ads_find_printer_on_server: %s\n", ads_errstr(rc
));
763 ads_msgfree(ads
, res
);
767 if (ads_count_replies(ads
, res
) == 0) {
768 d_printf("Printer '%s' not found\n", printername
);
769 ads_msgfree(ads
, res
);
774 ads_msgfree(ads
, res
);
779 void do_drv_upgrade_printer(int msg_type
, pid_t src
, void *buf
, size_t len
)
784 static int net_ads_printer_publish(int argc
, const char **argv
)
788 const char *servername
;
789 struct cli_state
*cli
;
790 struct in_addr server_ip
;
792 TALLOC_CTX
*mem_ctx
= talloc_init("net_ads_printer_publish");
793 ADS_MODLIST mods
= ads_init_mods(mem_ctx
);
794 char *prt_dn
, *srv_dn
, **srv_cn
;
797 if (!(ads
= ads_startup())) return -1;
800 return net_ads_printer_usage(argc
, argv
);
803 servername
= argv
[1];
805 servername
= global_myname();
807 ads_find_machine_acct(ads
, &res
, servername
);
808 srv_dn
= ldap_get_dn(ads
->ld
, res
);
809 srv_cn
= ldap_explode_dn(srv_dn
, 1);
810 asprintf(&prt_dn
, "cn=%s-%s,%s", srv_cn
[0], argv
[0], srv_dn
);
812 resolve_name(servername
, &server_ip
, 0x20);
814 nt_status
= cli_full_connection(&cli
, global_myname(), servername
,
817 opt_user_name
, opt_workgroup
,
818 opt_password
? opt_password
: "",
819 CLI_FULL_CONNECTION_USE_KERBEROS
,
822 cli_nt_session_open(cli
, PI_SPOOLSS
);
823 get_remote_printer_publishing_data(cli
, mem_ctx
, &mods
, argv
[0]);
825 rc
= ads_add_printer_entry(ads
, prt_dn
, mem_ctx
, &mods
);
826 if (!ADS_ERR_OK(rc
)) {
827 d_printf("ads_publish_printer: %s\n", ads_errstr(rc
));
831 d_printf("published printer\n");
836 static int net_ads_printer_remove(int argc
, const char **argv
)
840 const char *servername
;
844 if (!(ads
= ads_startup())) return -1;
847 return net_ads_printer_usage(argc
, argv
);
850 servername
= argv
[1];
852 servername
= global_myname();
854 rc
= ads_find_printer_on_server(ads
, &res
, argv
[0], servername
);
856 if (!ADS_ERR_OK(rc
)) {
857 d_printf("ads_find_printer_on_server: %s\n", ads_errstr(rc
));
858 ads_msgfree(ads
, res
);
862 if (ads_count_replies(ads
, res
) == 0) {
863 d_printf("Printer '%s' not found\n", argv
[1]);
864 ads_msgfree(ads
, res
);
868 prt_dn
= ads_get_dn(ads
, res
);
869 ads_msgfree(ads
, res
);
870 rc
= ads_del_dn(ads
, prt_dn
);
871 ads_memfree(ads
, prt_dn
);
873 if (!ADS_ERR_OK(rc
)) {
874 d_printf("ads_del_dn: %s\n", ads_errstr(rc
));
881 static int net_ads_printer(int argc
, const char **argv
)
883 struct functable func
[] = {
884 {"INFO", net_ads_printer_info
},
885 {"PUBLISH", net_ads_printer_publish
},
886 {"REMOVE", net_ads_printer_remove
},
890 return net_run_function(argc
, argv
, func
, net_ads_printer_usage
);
894 static int net_ads_password(int argc
, const char **argv
)
897 const char *auth_principal
= opt_user_name
;
898 const char *auth_password
= opt_password
;
900 char *new_password
= NULL
;
906 if ((argc
!= 1) || (opt_user_name
== NULL
) ||
907 (opt_password
== NULL
) || (strchr(opt_user_name
, '@') == NULL
) ||
908 (strchr(argv
[0], '@') == NULL
)) {
909 return net_ads_usage(argc
, argv
);
912 use_in_memory_ccache();
913 c
= strchr(auth_principal
, '@');
916 /* use the realm so we can eventually change passwords for users
917 in realms other than default */
918 if (!(ads
= ads_init(realm
, NULL
, NULL
))) return -1;
920 /* we don't actually need a full connect, but it's the easy way to
921 fill in the KDC's addresss */
924 if (!ads
|| !ads
->config
.realm
) {
925 d_printf("Didn't find the kerberos server!\n");
929 asprintf(&prompt
, "Enter new password for %s:", argv
[0]);
931 new_password
= getpass(prompt
);
933 ret
= kerberos_set_password(ads
->auth
.kdc_server
, auth_principal
,
934 auth_password
, argv
[0], new_password
, ads
->auth
.time_offset
);
935 if (!ADS_ERR_OK(ret
)) {
936 d_printf("Password change failed :-( ...\n");
942 d_printf("Password change for %s completed.\n", argv
[0]);
950 int net_ads_changetrustpw(int argc
, const char **argv
)
953 char *host_principal
;
958 if (!secrets_init()) {
959 DEBUG(1,("Failed to initialise secrets database\n"));
963 asprintf(&user_name
, "%s$", global_myname());
964 opt_user_name
= user_name
;
966 opt_password
= secrets_fetch_machine_password(opt_target_workgroup
, NULL
, NULL
);
968 use_in_memory_ccache();
970 if (!(ads
= ads_startup())) {
974 hostname
= strdup(global_myname());
976 asprintf(&host_principal
, "%s@%s", hostname
, ads
->config
.realm
);
978 d_printf("Changing password for principal: HOST/%s\n", host_principal
);
980 ret
= ads_change_trust_account_password(ads
, host_principal
);
982 if (!ADS_ERR_OK(ret
)) {
983 d_printf("Password change failed :-( ...\n");
985 SAFE_FREE(host_principal
);
989 d_printf("Password change for principal HOST/%s succeeded.\n", host_principal
);
991 SAFE_FREE(host_principal
);
997 help for net ads search
999 static int net_ads_search_usage(int argc
, const char **argv
)
1002 "\nnet ads search <expression> <attributes...>\n"\
1003 "\nperform a raw LDAP search on a ADS server and dump the results\n"\
1004 "The expression is a standard LDAP search expression, and the\n"\
1005 "attributes are a list of LDAP fields to show in the results\n\n"\
1006 "Example: net ads search '(objectCategory=group)' sAMAccountName\n\n"
1008 net_common_flags_usage(argc
, argv
);
1014 general ADS search function. Useful in diagnosing problems in ADS
1016 static int net_ads_search(int argc
, const char **argv
)
1025 return net_ads_search_usage(argc
, argv
);
1028 if (!(ads
= ads_startup())) {
1035 rc
= ads_do_search_all(ads
, ads
->config
.bind_path
,
1038 if (!ADS_ERR_OK(rc
)) {
1039 d_printf("search failed: %s\n", ads_errstr(rc
));
1043 d_printf("Got %d replies\n\n", ads_count_replies(ads
, res
));
1045 /* dump the results */
1048 ads_msgfree(ads
, res
);
1056 help for net ads search
1058 static int net_ads_dn_usage(int argc
, const char **argv
)
1061 "\nnet ads dn <dn> <attributes...>\n"\
1062 "\nperform a raw LDAP search on a ADS server and dump the results\n"\
1063 "The DN standard LDAP DN, and the attributes are a list of LDAP fields \n"\
1064 "to show in the results\n\n"\
1065 "Example: net ads dn 'CN=administrator,CN=Users,DC=my,DC=domain' sAMAccountName\n\n"
1067 net_common_flags_usage(argc
, argv
);
1073 general ADS search function. Useful in diagnosing problems in ADS
1075 static int net_ads_dn(int argc
, const char **argv
)
1084 return net_ads_dn_usage(argc
, argv
);
1087 if (!(ads
= ads_startup())) {
1094 rc
= ads_do_search_all(ads
, dn
,
1096 "(objectclass=*)", attrs
, &res
);
1097 if (!ADS_ERR_OK(rc
)) {
1098 d_printf("search failed: %s\n", ads_errstr(rc
));
1102 d_printf("Got %d replies\n\n", ads_count_replies(ads
, res
));
1104 /* dump the results */
1107 ads_msgfree(ads
, res
);
1114 int net_ads_help(int argc
, const char **argv
)
1116 struct functable func
[] = {
1117 {"USER", net_ads_user_usage
},
1118 {"GROUP", net_ads_group_usage
},
1119 {"PRINTER", net_ads_printer_usage
},
1120 {"SEARCH", net_ads_search_usage
},
1122 {"INFO", net_ads_info
},
1123 {"JOIN", net_ads_join
},
1124 {"LEAVE", net_ads_leave
},
1125 {"STATUS", net_ads_status
},
1126 {"PASSWORD", net_ads_password
},
1127 {"CHANGETRUSTPW", net_ads_changetrustpw
},
1132 return net_run_function(argc
, argv
, func
, net_ads_usage
);
1135 int net_ads(int argc
, const char **argv
)
1137 struct functable func
[] = {
1138 {"INFO", net_ads_info
},
1139 {"JOIN", net_ads_join
},
1140 {"TESTJOIN", net_ads_testjoin
},
1141 {"LEAVE", net_ads_leave
},
1142 {"STATUS", net_ads_status
},
1143 {"USER", net_ads_user
},
1144 {"GROUP", net_ads_group
},
1145 {"PASSWORD", net_ads_password
},
1146 {"CHANGETRUSTPW", net_ads_changetrustpw
},
1147 {"PRINTER", net_ads_printer
},
1148 {"SEARCH", net_ads_search
},
1150 {"WORKGROUP", net_ads_workgroup
},
1151 {"LOOKUP", net_ads_lookup
},
1152 {"HELP", net_ads_help
},
1156 return net_run_function(argc
, argv
, func
, net_ads_usage
);
1161 static int net_ads_noads(void)
1163 d_printf("ADS support not compiled in\n");
1167 int net_ads_usage(int argc
, const char **argv
)
1169 return net_ads_noads();
1172 int net_ads_help(int argc
, const char **argv
)
1174 return net_ads_noads();
1177 int net_ads_changetrustpw(int argc
, const char **argv
)
1179 return net_ads_noads();
1182 int net_ads_join(int argc
, const char **argv
)
1184 return net_ads_noads();
1187 int net_ads_user(int argc
, const char **argv
)
1189 return net_ads_noads();
1192 int net_ads_group(int argc
, const char **argv
)
1194 return net_ads_noads();
1197 /* this one shouldn't display a message */
1198 int net_ads_check(void)
1203 int net_ads(int argc
, const char **argv
)
1205 return net_ads_usage(argc
, argv
);