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
, opt_target_workgroup
, 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
, opt_target_workgroup
, 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
, opt_target_workgroup
, 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_m(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 search <printer>"
730 "\n\tsearch for a printer in the directory"
731 "\nnet ads printer info <printer> <server>"
732 "\n\tlookup info in directory for printer on server"
733 "\n\t(note: printer defaults to \"*\", server defaults to local)\n"
734 "\nnet ads printer publish <printername>"
735 "\n\tpublish printer in directory"
736 "\n\t(note: printer name is required)\n"
737 "\nnet ads printer remove <printername>"
738 "\n\tremove printer from directory"
739 "\n\t(note: printer name is required)\n");
743 static int net_ads_printer_search(int argc
, const char **argv
)
749 if (!(ads
= ads_startup()))
752 rc
= ads_find_printers(ads
, &res
);
754 if (!ADS_ERR_OK(rc
)) {
755 d_printf("ads_find_printer: %s\n", ads_errstr(rc
));
756 ads_msgfree(ads
, res
);
760 if (ads_count_replies(ads
, res
) == 0) {
761 d_printf("No results found\n");
762 ads_msgfree(ads
, res
);
767 ads_msgfree(ads
, res
);
772 static int net_ads_printer_info(int argc
, const char **argv
)
776 const char *servername
, *printername
;
779 if (!(ads
= ads_startup())) return -1;
782 printername
= argv
[0];
787 servername
= argv
[1];
789 servername
= global_myname();
791 rc
= ads_find_printer_on_server(ads
, &res
, printername
, servername
);
793 if (!ADS_ERR_OK(rc
)) {
794 d_printf("ads_find_printer_on_server: %s\n", ads_errstr(rc
));
795 ads_msgfree(ads
, res
);
799 if (ads_count_replies(ads
, res
) == 0) {
800 d_printf("Printer '%s' not found\n", printername
);
801 ads_msgfree(ads
, res
);
806 ads_msgfree(ads
, res
);
811 void do_drv_upgrade_printer(int msg_type
, pid_t src
, void *buf
, size_t len
)
816 static int net_ads_printer_publish(int argc
, const char **argv
)
820 const char *servername
, *printername
;
821 struct cli_state
*cli
;
822 struct in_addr server_ip
;
824 TALLOC_CTX
*mem_ctx
= talloc_init("net_ads_printer_publish");
825 ADS_MODLIST mods
= ads_init_mods(mem_ctx
);
826 char *prt_dn
, *srv_dn
, **srv_cn
;
829 if (!(ads
= ads_startup())) return -1;
832 return net_ads_printer_usage(argc
, argv
);
834 printername
= argv
[0];
837 servername
= argv
[1];
839 servername
= global_myname();
841 /* Get printer data from SPOOLSS */
843 resolve_name(servername
, &server_ip
, 0x20);
845 nt_status
= cli_full_connection(&cli
, global_myname(), servername
,
848 opt_user_name
, opt_workgroup
,
849 opt_password
? opt_password
: "",
850 CLI_FULL_CONNECTION_USE_KERBEROS
,
853 if (NT_STATUS_IS_ERR(nt_status
)) {
854 d_printf("Unable to open a connnection to %s to obtain data "
855 "for %s\n", servername
, printername
);
859 /* Publish on AD server */
861 ads_find_machine_acct(ads
, &res
, servername
);
863 if (ads_count_replies(ads
, res
) == 0) {
864 d_printf("Could not find machine account for server %s\n",
869 srv_dn
= ldap_get_dn(ads
->ld
, res
);
870 srv_cn
= ldap_explode_dn(srv_dn
, 1);
872 asprintf(&prt_dn
, "cn=%s-%s,%s", srv_cn
[0], printername
, srv_dn
);
874 cli_nt_session_open(cli
, PI_SPOOLSS
);
875 get_remote_printer_publishing_data(cli
, mem_ctx
, &mods
, printername
);
877 rc
= ads_add_printer_entry(ads
, prt_dn
, mem_ctx
, &mods
);
878 if (!ADS_ERR_OK(rc
)) {
879 d_printf("ads_publish_printer: %s\n", ads_errstr(rc
));
883 d_printf("published printer\n");
888 static int net_ads_printer_remove(int argc
, const char **argv
)
892 const char *servername
;
896 if (!(ads
= ads_startup())) return -1;
899 return net_ads_printer_usage(argc
, argv
);
902 servername
= argv
[1];
904 servername
= global_myname();
906 rc
= ads_find_printer_on_server(ads
, &res
, argv
[0], servername
);
908 if (!ADS_ERR_OK(rc
)) {
909 d_printf("ads_find_printer_on_server: %s\n", ads_errstr(rc
));
910 ads_msgfree(ads
, res
);
914 if (ads_count_replies(ads
, res
) == 0) {
915 d_printf("Printer '%s' not found\n", argv
[1]);
916 ads_msgfree(ads
, res
);
920 prt_dn
= ads_get_dn(ads
, res
);
921 ads_msgfree(ads
, res
);
922 rc
= ads_del_dn(ads
, prt_dn
);
923 ads_memfree(ads
, prt_dn
);
925 if (!ADS_ERR_OK(rc
)) {
926 d_printf("ads_del_dn: %s\n", ads_errstr(rc
));
933 static int net_ads_printer(int argc
, const char **argv
)
935 struct functable func
[] = {
936 {"SEARCH", net_ads_printer_search
},
937 {"INFO", net_ads_printer_info
},
938 {"PUBLISH", net_ads_printer_publish
},
939 {"REMOVE", net_ads_printer_remove
},
943 return net_run_function(argc
, argv
, func
, net_ads_printer_usage
);
947 static int net_ads_password(int argc
, const char **argv
)
950 const char *auth_principal
= opt_user_name
;
951 const char *auth_password
= opt_password
;
953 char *new_password
= NULL
;
958 if (opt_user_name
== NULL
|| opt_password
== NULL
) {
959 d_printf("You must supply an administrator username/password\n");
965 d_printf("ERROR: You must say which username to change password for\n");
970 if (!strchr(user
, '@')) {
971 asprintf(&c
, "%s@%s", argv
[0], lp_realm());
975 use_in_memory_ccache();
976 c
= strchr(auth_principal
, '@');
983 /* use the realm so we can eventually change passwords for users
984 in realms other than default */
985 if (!(ads
= ads_init(realm
, NULL
, NULL
))) return -1;
987 /* we don't actually need a full connect, but it's the easy way to
988 fill in the KDC's addresss */
991 if (!ads
|| !ads
->config
.realm
) {
992 d_printf("Didn't find the kerberos server!\n");
996 asprintf(&prompt
, "Enter new password for %s:", user
);
998 new_password
= getpass(prompt
);
1000 ret
= kerberos_set_password(ads
->auth
.kdc_server
, auth_principal
,
1001 auth_password
, user
, new_password
, ads
->auth
.time_offset
);
1002 if (!ADS_ERR_OK(ret
)) {
1003 d_printf("Password change failed :-( ...\n");
1009 d_printf("Password change for %s completed.\n", user
);
1017 int net_ads_changetrustpw(int argc
, const char **argv
)
1020 char *host_principal
;
1025 if (!secrets_init()) {
1026 DEBUG(1,("Failed to initialise secrets database\n"));
1030 asprintf(&user_name
, "%s$", global_myname());
1031 opt_user_name
= user_name
;
1033 opt_password
= secrets_fetch_machine_password(opt_target_workgroup
, NULL
, NULL
);
1035 use_in_memory_ccache();
1037 if (!(ads
= ads_startup())) {
1041 hostname
= strdup(global_myname());
1042 strlower_m(hostname
);
1043 asprintf(&host_principal
, "%s@%s", hostname
, ads
->config
.realm
);
1044 SAFE_FREE(hostname
);
1045 d_printf("Changing password for principal: HOST/%s\n", host_principal
);
1047 ret
= ads_change_trust_account_password(ads
, host_principal
);
1049 if (!ADS_ERR_OK(ret
)) {
1050 d_printf("Password change failed :-( ...\n");
1052 SAFE_FREE(host_principal
);
1056 d_printf("Password change for principal HOST/%s succeeded.\n", host_principal
);
1058 SAFE_FREE(host_principal
);
1064 help for net ads search
1066 static int net_ads_search_usage(int argc
, const char **argv
)
1069 "\nnet ads search <expression> <attributes...>\n"\
1070 "\nperform a raw LDAP search on a ADS server and dump the results\n"\
1071 "The expression is a standard LDAP search expression, and the\n"\
1072 "attributes are a list of LDAP fields to show in the results\n\n"\
1073 "Example: net ads search '(objectCategory=group)' sAMAccountName\n\n"
1075 net_common_flags_usage(argc
, argv
);
1081 general ADS search function. Useful in diagnosing problems in ADS
1083 static int net_ads_search(int argc
, const char **argv
)
1087 const char *ldap_exp
;
1092 return net_ads_search_usage(argc
, argv
);
1095 if (!(ads
= ads_startup())) {
1102 rc
= ads_do_search_all(ads
, ads
->config
.bind_path
,
1104 ldap_exp
, attrs
, &res
);
1105 if (!ADS_ERR_OK(rc
)) {
1106 d_printf("search failed: %s\n", ads_errstr(rc
));
1110 d_printf("Got %d replies\n\n", ads_count_replies(ads
, res
));
1112 /* dump the results */
1115 ads_msgfree(ads
, res
);
1123 help for net ads search
1125 static int net_ads_dn_usage(int argc
, const char **argv
)
1128 "\nnet ads dn <dn> <attributes...>\n"\
1129 "\nperform a raw LDAP search on a ADS server and dump the results\n"\
1130 "The DN standard LDAP DN, and the attributes are a list of LDAP fields \n"\
1131 "to show in the results\n\n"\
1132 "Example: net ads dn 'CN=administrator,CN=Users,DC=my,DC=domain' sAMAccountName\n\n"
1134 net_common_flags_usage(argc
, argv
);
1140 general ADS search function. Useful in diagnosing problems in ADS
1142 static int net_ads_dn(int argc
, const char **argv
)
1151 return net_ads_dn_usage(argc
, argv
);
1154 if (!(ads
= ads_startup())) {
1161 rc
= ads_do_search_all(ads
, dn
,
1163 "(objectclass=*)", attrs
, &res
);
1164 if (!ADS_ERR_OK(rc
)) {
1165 d_printf("search failed: %s\n", ads_errstr(rc
));
1169 d_printf("Got %d replies\n\n", ads_count_replies(ads
, res
));
1171 /* dump the results */
1174 ads_msgfree(ads
, res
);
1181 int net_ads_help(int argc
, const char **argv
)
1183 struct functable func
[] = {
1184 {"USER", net_ads_user_usage
},
1185 {"GROUP", net_ads_group_usage
},
1186 {"PRINTER", net_ads_printer_usage
},
1187 {"SEARCH", net_ads_search_usage
},
1189 {"INFO", net_ads_info
},
1190 {"JOIN", net_ads_join
},
1191 {"LEAVE", net_ads_leave
},
1192 {"STATUS", net_ads_status
},
1193 {"PASSWORD", net_ads_password
},
1194 {"CHANGETRUSTPW", net_ads_changetrustpw
},
1199 return net_run_function(argc
, argv
, func
, net_ads_usage
);
1202 int net_ads(int argc
, const char **argv
)
1204 struct functable func
[] = {
1205 {"INFO", net_ads_info
},
1206 {"JOIN", net_ads_join
},
1207 {"TESTJOIN", net_ads_testjoin
},
1208 {"LEAVE", net_ads_leave
},
1209 {"STATUS", net_ads_status
},
1210 {"USER", net_ads_user
},
1211 {"GROUP", net_ads_group
},
1212 {"PASSWORD", net_ads_password
},
1213 {"CHANGETRUSTPW", net_ads_changetrustpw
},
1214 {"PRINTER", net_ads_printer
},
1215 {"SEARCH", net_ads_search
},
1217 {"WORKGROUP", net_ads_workgroup
},
1218 {"LOOKUP", net_ads_lookup
},
1219 {"HELP", net_ads_help
},
1223 return net_run_function(argc
, argv
, func
, net_ads_usage
);
1228 static int net_ads_noads(void)
1230 d_printf("ADS support not compiled in\n");
1234 int net_ads_usage(int argc
, const char **argv
)
1236 return net_ads_noads();
1239 int net_ads_help(int argc
, const char **argv
)
1241 return net_ads_noads();
1244 int net_ads_changetrustpw(int argc
, const char **argv
)
1246 return net_ads_noads();
1249 int net_ads_join(int argc
, const char **argv
)
1251 return net_ads_noads();
1254 int net_ads_user(int argc
, const char **argv
)
1256 return net_ads_noads();
1259 int net_ads_group(int argc
, const char **argv
)
1261 return net_ads_noads();
1264 /* this one shouldn't display a message */
1265 int net_ads_check(void)
1270 int net_ads(int argc
, const char **argv
)
1272 return net_ads_usage(argc
, argv
);