Fix bug 7005 - mangle method = hash truncates files with dot '. ' character
[Samba.git] / source / utils / net.c
bloba8203b662e8598d16a329cdc0d1e320af2e53e7f
1 /*
2 Samba Unix/Linux SMB client library
3 Distributed SMB/CIFS Server Management Utility
4 Copyright (C) 2001 Steve French (sfrench@us.ibm.com)
5 Copyright (C) 2001 Jim McDonough (jmcd@us.ibm.com)
6 Copyright (C) 2001 Andrew Tridgell (tridge@samba.org)
7 Copyright (C) 2001 Andrew Bartlett (abartlet@samba.org)
8 Copyright (C) 2008 Kai Blin (kai@samba.org)
10 Originally written by Steve and Jim. Largely rewritten by tridge in
11 November 2001.
13 Reworked again by abartlet in December 2001
15 Another overhaul, moving functionality into plug-ins loaded on demand by Kai
16 in May 2008.
18 This program is free software; you can redistribute it and/or modify
19 it under the terms of the GNU General Public License as published by
20 the Free Software Foundation; either version 3 of the License, or
21 (at your option) any later version.
23 This program is distributed in the hope that it will be useful,
24 but WITHOUT ANY WARRANTY; without even the implied warranty of
25 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26 GNU General Public License for more details.
28 You should have received a copy of the GNU General Public License
29 along with this program. If not, see <http://www.gnu.org/licenses/>. */
31 /*****************************************************/
32 /* */
33 /* Distributed SMB/CIFS Server Management Utility */
34 /* */
35 /* The intent was to make the syntax similar */
36 /* to the NET utility (first developed in DOS */
37 /* with additional interesting & useful functions */
38 /* added in later SMB server network operating */
39 /* systems). */
40 /* */
41 /*****************************************************/
43 #include "includes.h"
44 #include "utils/net.h"
46 extern bool AllowDebugChange;
48 #ifdef WITH_FAKE_KASERVER
49 #include "utils/net_afs.h"
50 #endif
52 /***********************************************************************/
53 /* Beginning of internationalization section. Translatable constants */
54 /* should be kept in this area and referenced in the rest of the code. */
55 /* */
56 /* No functions, outside of Samba or LSB (Linux Standards Base) should */
57 /* be used (if possible). */
58 /***********************************************************************/
60 #define YES_STRING "Yes"
61 #define NO_STRING "No"
63 /***********************************************************************/
64 /* end of internationalization section */
65 /***********************************************************************/
67 uint32 get_sec_channel_type(const char *param)
69 if (!(param && *param)) {
70 return get_default_sec_channel();
71 } else {
72 if (strequal(param, "PDC")) {
73 return SEC_CHAN_BDC;
74 } else if (strequal(param, "BDC")) {
75 return SEC_CHAN_BDC;
76 } else if (strequal(param, "MEMBER")) {
77 return SEC_CHAN_WKSTA;
78 #if 0
79 } else if (strequal(param, "DOMAIN")) {
80 return SEC_CHAN_DOMAIN;
81 #endif
82 } else {
83 return get_default_sec_channel();
88 static int net_changetrustpw(struct net_context *c, int argc, const char **argv)
90 if (net_ads_check_our_domain(c) == 0)
91 return net_ads_changetrustpw(c, argc, argv);
93 return net_rpc_changetrustpw(c, argc, argv);
96 static void set_line_buffering(FILE *f)
98 setvbuf(f, NULL, _IOLBF, 0);
101 static int net_changesecretpw(struct net_context *c, int argc,
102 const char **argv)
104 char *trust_pw;
105 uint32 sec_channel_type = SEC_CHAN_WKSTA;
107 if(c->opt_force) {
108 if (c->opt_stdin) {
109 set_line_buffering(stdin);
110 set_line_buffering(stdout);
111 set_line_buffering(stderr);
114 trust_pw = get_pass("Enter machine password: ", c->opt_stdin);
116 if (!secrets_store_machine_password(trust_pw, lp_workgroup(), sec_channel_type)) {
117 d_fprintf(stderr, "Unable to write the machine account password in the secrets database");
118 return 1;
120 else {
121 d_printf("Modified trust account password in secrets database\n");
124 else {
125 d_printf("Machine account password change requires the -f flag.\n");
126 d_printf("Do NOT use this function unless you know what it does!\n");
127 d_printf("This function will change the ADS Domain member machine account password in the secrets.tdb file!\n");
130 return 0;
134 Retrieve our local SID or the SID for the specified name
136 static int net_getlocalsid(struct net_context *c, int argc, const char **argv)
138 DOM_SID sid;
139 const char *name;
140 fstring sid_str;
142 if (argc >= 1) {
143 name = argv[0];
145 else {
146 name = global_myname();
149 if(!initialize_password_db(false, NULL)) {
150 DEBUG(0, ("WARNING: Could not open passdb - local sid may not reflect passdb\n"
151 "backend knowledge (such as the sid stored in LDAP)\n"));
154 /* first check to see if we can even access secrets, so we don't
155 panic when we can't. */
157 if (!secrets_init()) {
158 d_fprintf(stderr, "Unable to open secrets.tdb. Can't fetch domain SID for name: %s\n", name);
159 return 1;
162 /* Generate one, if it doesn't exist */
163 get_global_sam_sid();
165 if (!secrets_fetch_domain_sid(name, &sid)) {
166 DEBUG(0, ("Can't fetch domain SID for name: %s\n", name));
167 return 1;
169 sid_to_fstring(sid_str, &sid);
170 d_printf("SID for domain %s is: %s\n", name, sid_str);
171 return 0;
174 static int net_setlocalsid(struct net_context *c, int argc, const char **argv)
176 DOM_SID sid;
178 if ( (argc != 1)
179 || (strncmp(argv[0], "S-1-5-21-", strlen("S-1-5-21-")) != 0)
180 || (!string_to_sid(&sid, argv[0]))
181 || (sid.num_auths != 4)) {
182 d_printf("usage: net setlocalsid S-1-5-21-x-y-z\n");
183 return 1;
186 if (!secrets_store_domain_sid(global_myname(), &sid)) {
187 DEBUG(0,("Can't store domain SID as a pdc/bdc.\n"));
188 return 1;
191 return 0;
194 static int net_setdomainsid(struct net_context *c, int argc, const char **argv)
196 DOM_SID sid;
198 if ( (argc != 1)
199 || (strncmp(argv[0], "S-1-5-21-", strlen("S-1-5-21-")) != 0)
200 || (!string_to_sid(&sid, argv[0]))
201 || (sid.num_auths != 4)) {
202 d_printf("usage: net setdomainsid S-1-5-21-x-y-z\n");
203 return 1;
206 if (!secrets_store_domain_sid(lp_workgroup(), &sid)) {
207 DEBUG(0,("Can't store domain SID.\n"));
208 return 1;
211 return 0;
214 static int net_getdomainsid(struct net_context *c, int argc, const char **argv)
216 DOM_SID domain_sid;
217 fstring sid_str;
219 if (argc > 0) {
220 d_printf("usage: net getdomainsid\n");
221 return 1;
224 if(!initialize_password_db(false, NULL)) {
225 DEBUG(0, ("WARNING: Could not open passdb - domain SID may "
226 "not reflect passdb\n"
227 "backend knowledge (such as the SID stored in "
228 "LDAP)\n"));
231 /* first check to see if we can even access secrets, so we don't
232 panic when we can't. */
234 if (!secrets_init()) {
235 d_fprintf(stderr, "Unable to open secrets.tdb. Can't fetch domain"
236 "SID for name: %s\n", get_global_sam_name());
237 return 1;
240 /* Generate one, if it doesn't exist */
241 get_global_sam_sid();
243 if (!secrets_fetch_domain_sid(global_myname(), &domain_sid)) {
244 d_fprintf(stderr, "Could not fetch local SID\n");
245 return 1;
247 sid_to_fstring(sid_str, &domain_sid);
248 d_printf("SID for local machine %s is: %s\n", global_myname(), sid_str);
250 if (!secrets_fetch_domain_sid(c->opt_workgroup, &domain_sid)) {
251 d_fprintf(stderr, "Could not fetch domain SID\n");
252 return 1;
255 sid_to_fstring(sid_str, &domain_sid);
256 d_printf("SID for domain %s is: %s\n", c->opt_workgroup, sid_str);
258 return 0;
261 static bool search_maxrid(struct pdb_search *search, const char *type,
262 uint32 *max_rid)
264 struct samr_displayentry *entries;
265 uint32 i, num_entries;
267 if (search == NULL) {
268 d_fprintf(stderr, "get_maxrid: Could not search %s\n", type);
269 return false;
272 num_entries = pdb_search_entries(search, 0, 0xffffffff, &entries);
273 for (i=0; i<num_entries; i++)
274 *max_rid = MAX(*max_rid, entries[i].rid);
275 pdb_search_destroy(search);
276 return true;
279 static uint32 get_maxrid(void)
281 uint32 max_rid = 0;
283 if (!search_maxrid(pdb_search_users(0), "users", &max_rid))
284 return 0;
286 if (!search_maxrid(pdb_search_groups(), "groups", &max_rid))
287 return 0;
289 if (!search_maxrid(pdb_search_aliases(get_global_sam_sid()),
290 "aliases", &max_rid))
291 return 0;
293 return max_rid;
296 static int net_maxrid(struct net_context *c, int argc, const char **argv)
298 uint32 rid;
300 if (argc != 0) {
301 DEBUG(0, ("usage: net maxrid\n"));
302 return 1;
305 if ((rid = get_maxrid()) == 0) {
306 DEBUG(0, ("can't get current maximum rid\n"));
307 return 1;
310 d_printf("Currently used maximum rid: %d\n", rid);
312 return 0;
315 /* main function table */
316 static struct functable net_func[] = {
318 "rpc",
319 net_rpc,
320 NET_TRANSPORT_RPC,
321 "Run functions using RPC transport",
322 " Use 'net help rpc' to get more extensive information about "
323 "'net rpc' commands."
326 "rap",
327 net_rap,
328 NET_TRANSPORT_RAP,
329 "Run functions using RAP transport",
330 " Use 'net help rap' to get more extensive information about "
331 "'net rap' commands."
334 "ads",
335 net_ads,
336 NET_TRANSPORT_ADS,
337 "Run functions using ADS transport",
338 " Use 'net help ads' to get more extensive information about "
339 "'net ads' commands."
342 /* eventually these should auto-choose the transport ... */
344 "file",
345 net_file,
346 NET_TRANSPORT_RPC | NET_TRANSPORT_RAP,
347 "Functions on remote opened files",
348 " Use 'net help file' to get more information about 'net "
349 "file' commands."
352 "share",
353 net_share,
354 NET_TRANSPORT_RPC | NET_TRANSPORT_RAP,
355 "Functions on shares",
356 " Use 'net help share' to get more information about 'net "
357 "share' commands."
360 "session",
361 net_rap_session,
362 NET_TRANSPORT_RAP,
363 "Manage sessions",
364 " Use 'net help session' to get more information about 'net "
365 "session' commands."
368 "server",
369 net_rap_server,
370 NET_TRANSPORT_RAP,
371 "List servers in workgroup",
372 " Use 'net help server' to get more information about 'net "
373 "server' commands."
376 "domain",
377 net_rap_domain,
378 NET_TRANSPORT_RAP,
379 "List domains/workgroups on network",
380 " Use 'net help domain' to get more information about 'net "
381 "domain' commands."
384 "printq",
385 net_rap_printq,
386 NET_TRANSPORT_RAP,
387 "Modify printer queue",
388 " Use 'net help printq' to get more information about 'net "
389 "printq' commands."
392 "user",
393 net_user,
394 NET_TRANSPORT_ADS | NET_TRANSPORT_RPC | NET_TRANSPORT_RAP,
395 "Manage users",
396 " Use 'net help user' to get more information about 'net "
397 "user' commands."
400 "group",
401 net_group,
402 NET_TRANSPORT_ADS | NET_TRANSPORT_RPC | NET_TRANSPORT_RAP,
403 "Manage groups",
404 " Use 'net help group' to get more information about 'net "
405 "group' commands."
408 "groupmap",
409 net_groupmap,
410 NET_TRANSPORT_LOCAL,
411 "Manage group mappings",
412 " Use 'net help groupmap' to get more information about 'net "
413 "groupmap' commands."
416 "sam",
417 net_sam,
418 NET_TRANSPORT_LOCAL,
419 "Functions on the SAM database",
420 " Use 'net help sam' to get more information about 'net sam' "
421 "commands."
424 "validate",
425 net_rap_validate,
426 NET_TRANSPORT_RAP,
427 "Validate username and password",
428 " Use 'net help validate' to get more information about 'net "
429 "validate' commands."
432 "groupmember",
433 net_rap_groupmember,
434 NET_TRANSPORT_RAP,
435 "Modify group memberships",
436 " Use 'net help groupmember' to get more information about "
437 "'net groupmember' commands."
439 { "admin",
440 net_rap_admin,
441 NET_TRANSPORT_RAP,
442 "Execute remote command on a remote OS/2 server",
443 " Use 'net help admin' to get more information about 'net "
444 "admin' commands."
446 { "service",
447 net_rap_service,
448 NET_TRANSPORT_RAP,
449 "List/modify running services",
450 " Use 'net help service' to get more information about 'net "
451 "service' commands."
454 "password",
455 net_rap_password,
456 NET_TRANSPORT_RAP,
457 "Change user password on target server",
458 " Use 'net help password' to get more information about 'net "
459 "password' commands."
461 { "changetrustpw",
462 net_changetrustpw,
463 NET_TRANSPORT_ADS | NET_TRANSPORT_RPC,
464 "Change the trust password",
465 " Use 'net help changetrustpw' to get more information about "
466 "'net changetrustpw'."
468 { "changesecretpw",
469 net_changesecretpw,
470 NET_TRANSPORT_LOCAL,
471 "Change the secret password",
472 " net [options] changesecretpw\n"
473 " Change the ADS domain member machine account password in "
474 "secrets.tdb.\n"
475 " Do NOT use this function unless you know what it does.\n"
476 " Requires the -f flag to work."
478 { "time",
479 net_time,
480 NET_TRANSPORT_LOCAL,
481 "Show/set time",
482 " Use 'net help time' to get more information about 'net "
483 "time' commands."
485 { "lookup",
486 net_lookup,
487 NET_TRANSPORT_LOCAL,
488 "Look up host names/IP addresses",
489 " Use 'net help lookup' to get more information about 'net "
490 "lookup' commands."
492 { "join",
493 net_join,
494 NET_TRANSPORT_ADS | NET_TRANSPORT_RPC,
495 "Join a domain/AD",
496 " Use 'net help join' to get more information about 'net "
497 "join'."
499 { "dom",
500 net_dom,
501 NET_TRANSPORT_LOCAL,
502 "Join/unjoin (remote) machines to/from a domain/AD",
503 " Use 'net help dom' to get more information about 'net dom' "
504 "commands."
506 { "cache",
507 net_cache,
508 NET_TRANSPORT_LOCAL,
509 "Operate on the cache tdb file",
510 " Use 'net help cache' to get more information about 'net "
511 "cache' commands."
513 { "getlocalsid",
514 net_getlocalsid,
515 NET_TRANSPORT_LOCAL,
516 "Get the SID for the local domain",
517 " net getlocalsid"
519 { "setlocalsid",
520 net_setlocalsid,
521 NET_TRANSPORT_LOCAL,
522 "Set the SID for the local domain",
523 " net setlocalsid S-1-5-21-x-y-z"
525 { "setdomainsid",
526 net_setdomainsid,
527 NET_TRANSPORT_LOCAL,
528 "Set domain SID on member servers",
529 " net setdomainsid S-1-5-21-x-y-z"
531 { "getdomainsid",
532 net_getdomainsid,
533 NET_TRANSPORT_LOCAL,
534 "Get domain SID on member servers",
535 " net getdomainsid"
537 { "maxrid",
538 net_maxrid,
539 NET_TRANSPORT_LOCAL,
540 "Display the maximul RID currently used",
541 " net maxrid"
543 { "idmap",
544 net_idmap,
545 NET_TRANSPORT_LOCAL,
546 "IDmap functions",
547 " Use 'net help idmap to get more information about 'net "
548 "idmap' commands."
550 { "status",
551 net_status,
552 NET_TRANSPORT_LOCAL,
553 "Display server status",
554 " Use 'net help status' to get more information about 'net "
555 "status' commands."
557 { "usershare",
558 net_usershare,
559 NET_TRANSPORT_LOCAL,
560 "Manage user-modifiable shares",
561 " Use 'net help usershare to get more information about 'net "
562 "usershare' commands."
564 { "usersidlist",
565 net_usersidlist,
566 NET_TRANSPORT_RPC,
567 "Display list of all users with SID",
568 " Use 'net help usersidlist' to get more information about "
569 "'net usersidlist'."
571 { "conf",
572 net_conf,
573 NET_TRANSPORT_LOCAL,
574 "Manage Samba registry based configuration",
575 " Use 'net help conf' to get more information about 'net "
576 "conf' commands."
578 { "registry",
579 net_registry,
580 NET_TRANSPORT_LOCAL,
581 "Manage the Samba registry",
582 " Use 'net help registry' to get more information about 'net "
583 "registry' commands."
585 #ifdef WITH_FAKE_KASERVER
586 { "afs",
587 net_afs,
588 NET_TRANSPORT_LOCAL,
589 "Manage AFS tokens",
590 " Use 'net help afs' to get more information about 'net afs' "
591 "commands."
593 #endif
595 { "help",
596 net_help,
597 NET_TRANSPORT_LOCAL,
598 "Print usage information",
599 " Use 'net help help' to list usage information for 'net' "
600 "commands."
602 {NULL, NULL, 0, NULL, NULL}
606 /****************************************************************************
607 main program
608 ****************************************************************************/
609 int main(int argc, const char **argv)
611 int opt,i;
612 char *p;
613 int rc = 0;
614 int argc_new = 0;
615 const char ** argv_new;
616 poptContext pc;
617 TALLOC_CTX *frame = talloc_stackframe();
618 struct net_context *c = talloc_zero(frame, struct net_context);
620 struct poptOption long_options[] = {
621 {"help", 'h', POPT_ARG_NONE, 0, 'h'},
622 {"workgroup", 'w', POPT_ARG_STRING, &c->opt_target_workgroup},
623 {"user", 'U', POPT_ARG_STRING, &c->opt_user_name, 'U'},
624 {"ipaddress", 'I', POPT_ARG_STRING, 0,'I'},
625 {"port", 'p', POPT_ARG_INT, &c->opt_port},
626 {"myname", 'n', POPT_ARG_STRING, &c->opt_requester_name},
627 {"server", 'S', POPT_ARG_STRING, &c->opt_host},
628 {"encrypt", 'e', POPT_ARG_NONE, NULL, 'e', "Encrypt SMB transport (UNIX extended servers only)" },
629 {"container", 'c', POPT_ARG_STRING, &c->opt_container},
630 {"comment", 'C', POPT_ARG_STRING, &c->opt_comment},
631 {"maxusers", 'M', POPT_ARG_INT, &c->opt_maxusers},
632 {"flags", 'F', POPT_ARG_INT, &c->opt_flags},
633 {"long", 'l', POPT_ARG_NONE, &c->opt_long_list_entries},
634 {"reboot", 'r', POPT_ARG_NONE, &c->opt_reboot},
635 {"force", 'f', POPT_ARG_NONE, &c->opt_force},
636 {"stdin", 'i', POPT_ARG_NONE, &c->opt_stdin},
637 {"timeout", 't', POPT_ARG_INT, &c->opt_timeout},
638 {"request-timeout",0,POPT_ARG_INT, &c->opt_request_timeout},
639 {"machine-pass",'P', POPT_ARG_NONE, &c->opt_machine_pass},
640 {"kerberos", 'k', POPT_ARG_NONE, &c->opt_kerberos},
641 {"myworkgroup", 'W', POPT_ARG_STRING, &c->opt_workgroup},
642 {"verbose", 'v', POPT_ARG_NONE, &c->opt_verbose},
643 {"test", 'T', POPT_ARG_NONE, &c->opt_testmode},
644 /* Options for 'net groupmap set' */
645 {"local", 'L', POPT_ARG_NONE, &c->opt_localgroup},
646 {"domain", 'D', POPT_ARG_NONE, &c->opt_domaingroup},
647 {"ntname", 'N', POPT_ARG_STRING, &c->opt_newntname},
648 {"rid", 'R', POPT_ARG_INT, &c->opt_rid},
649 /* Options for 'net rpc share migrate' */
650 {"acls", 0, POPT_ARG_NONE, &c->opt_acls},
651 {"attrs", 0, POPT_ARG_NONE, &c->opt_attrs},
652 {"timestamps", 0, POPT_ARG_NONE, &c->opt_timestamps},
653 {"exclude", 'X', POPT_ARG_STRING, &c->opt_exclude},
654 {"destination", 0, POPT_ARG_STRING, &c->opt_destination},
655 {"tallocreport", 0, POPT_ARG_NONE, &c->do_talloc_report},
656 /* Options for 'net rpc vampire (keytab)' */
657 {"force-full-repl", 0, POPT_ARG_NONE, &c->opt_force_full_repl},
658 {"single-obj-repl", 0, POPT_ARG_NONE, &c->opt_single_obj_repl},
659 {"clean-old-entries", 0, POPT_ARG_NONE, &c->opt_clean_old_entries},
661 POPT_COMMON_SAMBA
662 { 0, 0, 0, 0}
666 zero_sockaddr(&c->opt_dest_ip);
668 load_case_tables();
670 /* set default debug level to 0 regardless of what smb.conf sets */
671 DEBUGLEVEL_CLASS[DBGC_ALL] = 0;
672 dbf = x_stderr;
673 c->private_data = net_func;
675 pc = poptGetContext(NULL, argc, (const char **) argv, long_options,
676 POPT_CONTEXT_KEEP_FIRST);
678 while((opt = poptGetNextOpt(pc)) != -1) {
679 switch (opt) {
680 case 'h':
681 c->display_usage = true;
682 break;
683 case 'e':
684 c->smb_encrypt = true;
685 break;
686 case 'I':
687 if (!interpret_string_addr(&c->opt_dest_ip,
688 poptGetOptArg(pc), 0)) {
689 d_fprintf(stderr, "\nInvalid ip address specified\n");
690 } else {
691 c->opt_have_ip = true;
693 break;
694 case 'U':
695 c->opt_user_specified = true;
696 c->opt_user_name = SMB_STRDUP(c->opt_user_name);
697 p = strchr(c->opt_user_name,'%');
698 if (p) {
699 *p = 0;
700 c->opt_password = p+1;
702 break;
703 default:
704 d_fprintf(stderr, "\nInvalid option %s: %s\n",
705 poptBadOption(pc, 0), poptStrerror(opt));
706 net_help(c, argc, argv);
707 exit(1);
712 * Don't load debug level from smb.conf. It should be
713 * set by cmdline arg or remain default (0)
715 AllowDebugChange = false;
716 lp_load(get_dyn_CONFIGFILE(), true, false, false, true);
718 argv_new = (const char **)poptGetArgs(pc);
720 argc_new = argc;
721 for (i=0; i<argc; i++) {
722 if (argv_new[i] == NULL) {
723 argc_new = i;
724 break;
728 if (c->do_talloc_report) {
729 talloc_enable_leak_report();
732 if (c->opt_requester_name) {
733 set_global_myname(c->opt_requester_name);
736 if (!c->opt_user_name && getenv("LOGNAME")) {
737 c->opt_user_name = getenv("LOGNAME");
740 if (!c->opt_workgroup) {
741 c->opt_workgroup = smb_xstrdup(lp_workgroup());
744 if (!c->opt_target_workgroup) {
745 c->opt_target_workgroup = smb_xstrdup(lp_workgroup());
748 if (!init_names())
749 exit(1);
751 load_interfaces();
753 /* this makes sure that when we do things like call scripts,
754 that it won't assert becouse we are not root */
755 sec_init();
757 if (c->opt_machine_pass) {
758 /* it is very useful to be able to make ads queries as the
759 machine account for testing purposes and for domain leave */
761 net_use_krb_machine_account(c);
764 if (!c->opt_password) {
765 c->opt_password = getenv("PASSWD");
768 rc = net_run_function(c, argc_new-1, argv_new+1, "net", net_func);
770 DEBUG(2,("return code = %d\n", rc));
772 libnetapi_free(c->netapi_ctx);
774 poptFreeContext(pc);
776 TALLOC_FREE(frame);
777 return rc;