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 9 Originally written by Steve and Jim. Largely rewritten by tridge in 10 November 2001. 11 12 Reworked again by abartlet in December 2001 13 14 This program is free software; you can redistribute it and/or modify 15 it under the terms of the GNU General Public License as published by 16 the Free Software Foundation; either version 2 of the License, or 17 (at your option) any later version. 18 19 This program is distributed in the hope that it will be useful, 20 but WITHOUT ANY WARRANTY; without even the implied warranty of 21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 22 GNU General Public License for more details. 23 24 You should have received a copy of the GNU General Public License 25 along with this program; if not, write to the Free Software 26 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ 27 28/*****************************************************/ 29/* */ 30/* Distributed SMB/CIFS Server Management Utility */ 31/* */ 32/* The intent was to make the syntax similar */ 33/* to the NET utility (first developed in DOS */ 34/* with additional interesting & useful functions */ 35/* added in later SMB server network operating */ 36/* systems). */ 37/* */ 38/*****************************************************/ 39 40#include "includes.h" 41#include "utils/net.h" 42 43/***********************************************************************/ 44/* Beginning of internationalization section. Translatable constants */ 45/* should be kept in this area and referenced in the rest of the code. */ 46/* */ 47/* No functions, outside of Samba or LSB (Linux Standards Base) should */ 48/* be used (if possible). */ 49/***********************************************************************/ 50 51#define YES_STRING "Yes" 52#define NO_STRING "No" 53 54/************************************************************************************/ 55/* end of internationalization section */ 56/************************************************************************************/ 57 58/* Yes, these buggers are globals.... */ 59const char *opt_requester_name = NULL; 60const char *opt_host = NULL; 61const char *opt_password = NULL; 62const char *opt_user_name = NULL; 63BOOL opt_user_specified = False; 64const char *opt_workgroup = NULL; 65int opt_long_list_entries = 0; 66int opt_reboot = 0; 67int opt_force = 0; 68int opt_port = 0; 69int opt_verbose = 0; 70int opt_maxusers = -1; 71const char *opt_comment = ""; 72const char *opt_container = NULL; 73int opt_flags = -1; 74int opt_timeout = 0; 75const char *opt_target_workgroup = NULL; 76int opt_machine_pass = 0; 77BOOL opt_localgroup = False; 78BOOL opt_domaingroup = False; 79const char *opt_newntname = ""; 80int opt_rid = 0; 81int opt_acls = 0; 82int opt_attrs = 0; 83int opt_timestamps = 0; 84const char *opt_exclude = NULL; 85const char *opt_destination = NULL; 86 87BOOL opt_have_ip = False; 88struct in_addr opt_dest_ip; 89 90extern BOOL AllowDebugChange; 91 92uint32 get_sec_channel_type(const char *param) 93{ 94 if (!(param && *param)) { 95 return get_default_sec_channel(); 96 } else { 97 if (strequal(param, "PDC")) { 98 return SEC_CHAN_BDC; 99 } else if (strequal(param, "BDC")) { 100 return SEC_CHAN_BDC; 101 } else if (strequal(param, "MEMBER")) { 102 return SEC_CHAN_WKSTA; 103#if 0 104 } else if (strequal(param, "DOMAIN")) { 105 return SEC_CHAN_DOMAIN; 106#endif 107 } else { 108 return get_default_sec_channel(); 109 } 110 } 111} 112 113/* 114 run a function from a function table. If not found then 115 call the specified usage function 116*/ 117int net_run_function(int argc, const char **argv, struct functable *table, 118 int (*usage_fn)(int argc, const char **argv)) 119{ 120 int i; 121 122 if (argc < 1) { 123 d_printf("\nUsage: \n"); 124 return usage_fn(argc, argv); 125 } 126 for (i=0; table[i].funcname; i++) { 127 if (StrCaseCmp(argv[0], table[i].funcname) == 0) 128 return table[i].fn(argc-1, argv+1); 129 } 130 d_printf("No command: %s\n", argv[0]); 131 return usage_fn(argc, argv); 132} 133 134/**************************************************************************** 135connect to \\server\service 136****************************************************************************/ 137NTSTATUS connect_to_service(struct cli_state **c, struct in_addr *server_ip, 138 const char *server_name, 139 const char *service_name, 140 const char *service_type) 141{ 142 NTSTATUS nt_status; 143 144 if (!opt_password && !opt_machine_pass) { 145 char *pass = getpass("Password:"); 146 if (pass) { 147 opt_password = SMB_STRDUP(pass); 148 } 149 } 150 151 nt_status = cli_full_connection(c, NULL, server_name, 152 server_ip, opt_port, 153 service_name, service_type, 154 opt_user_name, opt_workgroup, 155 opt_password, 0, Undefined, NULL); 156 157 if (NT_STATUS_IS_OK(nt_status)) { 158 return nt_status; 159 } else { 160 d_printf("Could not connect to server %s\n", server_name); 161 162 /* Display a nicer message depending on the result */ 163 164 if (NT_STATUS_V(nt_status) == 165 NT_STATUS_V(NT_STATUS_LOGON_FAILURE)) 166 d_printf("The username or password was not correct.\n"); 167 168 if (NT_STATUS_V(nt_status) == 169 NT_STATUS_V(NT_STATUS_ACCOUNT_LOCKED_OUT)) 170 d_printf("The account was locked out.\n"); 171 172 if (NT_STATUS_V(nt_status) == 173 NT_STATUS_V(NT_STATUS_ACCOUNT_DISABLED)) 174 d_printf("The account was disabled.\n"); 175 176 return nt_status; 177 } 178} 179 180 181/**************************************************************************** 182connect to \\server\ipc$ 183****************************************************************************/ 184NTSTATUS connect_to_ipc(struct cli_state **c, struct in_addr *server_ip, 185 const char *server_name) 186{ 187 return connect_to_service(c, server_ip, server_name, "IPC$", "IPC"); 188} 189 190/**************************************************************************** 191connect to \\server\ipc$ anonymously 192****************************************************************************/ 193NTSTATUS connect_to_ipc_anonymous(struct cli_state **c, 194 struct in_addr *server_ip, const char *server_name) 195{ 196 NTSTATUS nt_status; 197 198 nt_status = cli_full_connection(c, opt_requester_name, server_name, 199 server_ip, opt_port, 200 "IPC$", "IPC", 201 "", "", 202 "", 0, Undefined, NULL); 203 204 if (NT_STATUS_IS_OK(nt_status)) { 205 return nt_status; 206 } else { 207 DEBUG(1,("Cannot connect to server (anonymously). Error was %s\n", nt_errstr(nt_status))); 208 return nt_status; 209 } 210} 211 212/** 213 * Connect a server and open a given pipe 214 * 215 * @param cli_dst A cli_state 216 * @param pipe The pipe to open 217 * @param got_pipe boolean that stores if we got a pipe 218 * 219 * @return Normal NTSTATUS return. 220 **/ 221NTSTATUS connect_pipe(struct cli_state **cli_dst, int pipe_num, BOOL *got_pipe) 222{ 223 NTSTATUS nt_status; 224 char *server_name = SMB_STRDUP("127.0.0.1"); 225 struct cli_state *cli_tmp = NULL; 226 227 if (opt_destination) 228 server_name = SMB_STRDUP(opt_destination); 229 230 /* make a connection to a named pipe */ 231 nt_status = connect_to_ipc(&cli_tmp, NULL, server_name); 232 if (!NT_STATUS_IS_OK(nt_status)) 233 return nt_status; 234 235 if (!cli_nt_session_open(cli_tmp, pipe_num)) { 236 DEBUG(0, ("couldn't not initialize pipe\n")); 237 cli_shutdown(cli_tmp); 238 return NT_STATUS_UNSUCCESSFUL; 239 } 240 241 *cli_dst = cli_tmp; 242 *got_pipe = True; 243 244 return nt_status; 245} 246 247 248/**************************************************************************** 249 Use the local machine's password for this session 250****************************************************************************/ 251int net_use_machine_password(void) 252{ 253 char *user_name = NULL; 254 255 if (!secrets_init()) { 256 d_printf("ERROR: Unable to open secrets database\n"); 257 exit(1); 258 } 259 260 user_name = NULL; 261 opt_password = secrets_fetch_machine_password(opt_target_workgroup, NULL, NULL); 262 if (asprintf(&user_name, "%s$@%s", global_myname(), lp_realm()) == -1) { 263 return -1; 264 } 265 opt_user_name = user_name; 266 return 0; 267} 268 269BOOL net_find_server(unsigned flags, struct in_addr *server_ip, char **server_name) 270{ 271 272 if (opt_host) { 273 *server_name = SMB_STRDUP(opt_host); 274 } 275 276 if (opt_have_ip) { 277 *server_ip = opt_dest_ip; 278 if (!*server_name) { 279 *server_name = SMB_STRDUP(inet_ntoa(opt_dest_ip)); 280 } 281 } else if (*server_name) { 282 /* resolve the IP address */ 283 if (!resolve_name(*server_name, server_ip, 0x20)) { 284 DEBUG(1,("Unable to resolve server name\n")); 285 return False; 286 } 287 } else if (flags & NET_FLAGS_PDC) { 288 struct in_addr pdc_ip; 289 290 if (get_pdc_ip(opt_target_workgroup, &pdc_ip)) { 291 fstring dc_name; 292 293 if (is_zero_ip(pdc_ip)) 294 return False; 295 296 if ( !name_status_find(opt_target_workgroup, 0x1b, 0x20, pdc_ip, dc_name) ) 297 return False; 298 299 *server_name = SMB_STRDUP(dc_name); 300 *server_ip = pdc_ip; 301 } 302 303 } else if (flags & NET_FLAGS_DMB) { 304 struct in_addr msbrow_ip; 305 /* if (!resolve_name(MSBROWSE, &msbrow_ip, 1)) */ 306 if (!resolve_name(opt_target_workgroup, &msbrow_ip, 0x1B)) { 307 DEBUG(1,("Unable to resolve domain browser via name lookup\n")); 308 return False; 309 } else { 310 *server_ip = msbrow_ip; 311 } 312 *server_name = SMB_STRDUP(inet_ntoa(opt_dest_ip)); 313 } else if (flags & NET_FLAGS_MASTER) { 314 struct in_addr brow_ips; 315 if (!resolve_name(opt_target_workgroup, &brow_ips, 0x1D)) { 316 /* go looking for workgroups */ 317 DEBUG(1,("Unable to resolve master browser via name lookup\n")); 318 return False; 319 } else { 320 *server_ip = brow_ips; 321 } 322 *server_name = SMB_STRDUP(inet_ntoa(opt_dest_ip)); 323 } else if (!(flags & NET_FLAGS_LOCALHOST_DEFAULT_INSANE)) { 324 extern struct in_addr loopback_ip; 325 *server_ip = loopback_ip; 326 *server_name = SMB_STRDUP("127.0.0.1"); 327 } 328 329 if (!server_name || !*server_name) { 330 DEBUG(1,("no server to connect to\n")); 331 return False; 332 } 333 334 return True; 335} 336 337 338BOOL net_find_pdc(struct in_addr *server_ip, fstring server_name, const char *domain_name) 339{ 340 if (get_pdc_ip(domain_name, server_ip)) { 341 if (is_zero_ip(*server_ip)) 342 return False; 343 344 if (!name_status_find(domain_name, 0x1b, 0x20, *server_ip, server_name)) 345 return False; 346 347 return True; 348 } 349 else 350 return False; 351} 352 353 354struct cli_state *net_make_ipc_connection(unsigned flags) 355{ 356 char *server_name = NULL; 357 struct in_addr server_ip; 358 struct cli_state *cli = NULL; 359 NTSTATUS nt_status; 360 361 if (!net_find_server(flags, &server_ip, &server_name)) { 362 d_printf("\nUnable to find a suitable server\n"); 363 return NULL; 364 } 365 366 if (flags & NET_FLAGS_ANONYMOUS) { 367 nt_status = connect_to_ipc_anonymous(&cli, &server_ip, server_name); 368 } else { 369 nt_status = connect_to_ipc(&cli, &server_ip, server_name); 370 } 371 372 SAFE_FREE(server_name); 373 if (NT_STATUS_IS_OK(nt_status)) { 374 return cli; 375 } else { 376 return NULL; 377 } 378} 379 380static int net_user(int argc, const char **argv) 381{ 382 if (net_ads_check() == 0) 383 return net_ads_user(argc, argv); 384 385 /* if server is not specified, default to PDC? */ 386 if (net_rpc_check(NET_FLAGS_PDC)) 387 return net_rpc_user(argc, argv); 388 389 return net_rap_user(argc, argv); 390} 391 392static int net_group(int argc, const char **argv) 393{ 394 if (net_ads_check() == 0) 395 return net_ads_group(argc, argv); 396 397 if (argc == 0 && net_rpc_check(NET_FLAGS_PDC)) 398 return net_rpc_group(argc, argv); 399 400 return net_rap_group(argc, argv); 401} 402 403static int net_join(int argc, const char **argv) 404{ 405 if (net_ads_check() == 0) { 406 if (net_ads_join(argc, argv) == 0) 407 return 0; 408 else 409 d_printf("ADS join did not work, falling back to RPC...\n"); 410 } 411 return net_rpc_join(argc, argv); 412} 413 414static int net_changetrustpw(int argc, const char **argv) 415{ 416 if (net_ads_check() == 0) 417 return net_ads_changetrustpw(argc, argv); 418 419 return net_rpc_changetrustpw(argc, argv); 420} 421 422static int net_changesecretpw(int argc, const char **argv) 423{ 424 char *trust_pw; 425 uint32 sec_channel_type = SEC_CHAN_WKSTA; 426 427 if(opt_force) { 428 trust_pw = getpass("Enter machine password: "); 429 430 if (!secrets_store_machine_password(trust_pw, lp_workgroup(), sec_channel_type)) { 431 d_printf("Unable to write the machine account password in the secrets database"); 432 return 1; 433 } 434 else { 435 d_printf("Modified trust account password in secrets database\n"); 436 } 437 } 438 else { 439 d_printf("Machine account password change requires the -f flag.\n"); 440 d_printf("Do NOT use this function unless you know what it does!\n"); 441 d_printf("This function will change the ADS Domain member machine account password in the secrets.tdb file!\n"); 442 } 443 444 return 0; 445} 446 447static int net_share(int argc, const char **argv) 448{ 449 if (net_rpc_check(0)) 450 return net_rpc_share(argc, argv); 451 return net_rap_share(argc, argv); 452} 453 454static int net_file(int argc, const char **argv) 455{ 456 if (net_rpc_check(0)) 457 return net_rpc_file(argc, argv); 458 return net_rap_file(argc, argv); 459} 460 461/* 462 Retrieve our local SID or the SID for the specified name 463 */ 464static int net_getlocalsid(int argc, const char **argv) 465{ 466 DOM_SID sid; 467 const char *name; 468 fstring sid_str; 469 470 if (argc >= 1) { 471 name = argv[0]; 472 } 473 else { 474 name = global_myname(); 475 } 476 477 if(!initialize_password_db(False)) { 478 DEBUG(0, ("WARNING: Could not open passdb - local sid may not reflect passdb\n" 479 "backend knowlege (such as the sid stored in LDAP)\n")); 480 } 481 482 /* first check to see if we can even access secrets, so we don't 483 panic when we can't. */ 484 485 if (!secrets_init()) { 486 d_printf("Unable to open secrets.tdb. Can't fetch domain SID for name: %s\n", name); 487 return 1; 488 } 489 490 /* Generate one, if it doesn't exist */ 491 get_global_sam_sid(); 492 493 if (!secrets_fetch_domain_sid(name, &sid)) { 494 DEBUG(0, ("Can't fetch domain SID for name: %s\n", name)); 495 return 1; 496 } 497 sid_to_string(sid_str, &sid); 498 d_printf("SID for domain %s is: %s\n", name, sid_str); 499 return 0; 500} 501 502static int net_setlocalsid(int argc, const char **argv) 503{ 504 DOM_SID sid; 505 506 if ( (argc != 1) 507 || (strncmp(argv[0], "S-1-5-21-", strlen("S-1-5-21-")) != 0) 508 || (!string_to_sid(&sid, argv[0])) 509 || (sid.num_auths != 4)) { 510 d_printf("usage: net setlocalsid S-1-5-21-x-y-z\n"); 511 return 1; 512 } 513 514 if (!secrets_store_domain_sid(global_myname(), &sid)) { 515 DEBUG(0,("Can't store domain SID as a pdc/bdc.\n")); 516 return 1; 517 } 518 519 return 0; 520} 521 522static int net_getdomainsid(int argc, const char **argv) 523{ 524 DOM_SID domain_sid; 525 fstring sid_str; 526 527 if(!initialize_password_db(False)) { 528 DEBUG(0, ("WARNING: Could not open passdb - domain sid may not reflect passdb\n" 529 "backend knowlege (such as the sid stored in LDAP)\n")); 530 } 531 532 /* Generate one, if it doesn't exist */ 533 get_global_sam_sid(); 534 535 if (!secrets_fetch_domain_sid(global_myname(), &domain_sid)) { 536 d_printf("Could not fetch local SID\n"); 537 return 1; 538 } 539 sid_to_string(sid_str, &domain_sid); 540 d_printf("SID for domain %s is: %s\n", global_myname(), sid_str); 541 542 if (!secrets_fetch_domain_sid(opt_workgroup, &domain_sid)) { 543 d_printf("Could not fetch domain SID\n"); 544 return 1; 545 } 546 547 sid_to_string(sid_str, &domain_sid); 548 d_printf("SID for domain %s is: %s\n", opt_workgroup, sid_str); 549 550 return 0; 551} 552 553#ifdef WITH_FAKE_KASERVER 554 555int net_help_afs(int argc, const char **argv) 556{ 557 d_printf(" net afs key filename\n" 558 "\tImports a OpenAFS KeyFile into our secrets.tdb\n\n"); 559 d_printf(" net afs impersonate <user> <cell>\n" 560 "\tCreates a token for user@cell\n\n"); 561 return -1; 562} 563 564static int net_afs_key(int argc, const char **argv) 565{ 566 int fd; 567 struct afs_keyfile keyfile; 568 569 if (argc != 2) { 570 d_printf("usage: 'net afskey <keyfile> cell'\n"); 571 return -1; 572 } 573 574 if (!secrets_init()) { 575 d_printf("Could not open secrets.tdb\n"); 576 return -1; 577 } 578 579 if ((fd = open(argv[0], O_RDONLY, 0)) < 0) { 580 d_printf("Could not open %s\n", argv[0]); 581 return -1; 582 } 583 584 if (read(fd, &keyfile, sizeof(keyfile)) != sizeof(keyfile)) { 585 d_printf("Could not read keyfile\n"); 586 return -1; 587 } 588 589 if (!secrets_store_afs_keyfile(argv[1], &keyfile)) { 590 d_printf("Could not write keyfile to secrets.tdb\n"); 591 return -1; 592 } 593 594 return 0; 595} 596 597static int net_afs_impersonate(int argc, const char **argv) 598{ 599 char *token; 600 601 if (argc != 2) { 602 fprintf(stderr, "Usage: net afs impersonate <user> <cell>\n"); 603 exit(1); 604 } 605 606 token = afs_createtoken_str(argv[0], argv[1]); 607 608 if (token == NULL) { 609 fprintf(stderr, "Could not create token\n"); 610 exit(1); 611 } 612 613 if (!afs_settoken_str(token)) { 614 fprintf(stderr, "Could not set token into kernel\n"); 615 exit(1); 616 } 617 618 printf("Success: %s@%s\n", argv[0], argv[1]); 619 return 0; 620} 621 622static int net_afs(int argc, const char **argv) 623{ 624 struct functable func[] = { 625 {"key", net_afs_key}, 626 {"impersonate", net_afs_impersonate}, 627 {"help", net_help_afs}, 628 {NULL, NULL} 629 }; 630 return net_run_function(argc, argv, func, net_help_afs); 631} 632 633#endif /* WITH_FAKE_KASERVER */ 634 635static uint32 get_maxrid(void) 636{ 637 SAM_ACCOUNT *pwd = NULL; 638 uint32 max_rid = 0; 639 GROUP_MAP *map = NULL; 640 int num_entries = 0; 641 int i; 642 643 if (!pdb_setsampwent(False, 0)) { 644 DEBUG(0, ("get_maxrid: Unable to open passdb.\n")); 645 return 0; 646 } 647 648 for (; (NT_STATUS_IS_OK(pdb_init_sam(&pwd))) 649 && pdb_getsampwent(pwd) == True; pwd=NULL) { 650 uint32 rid; 651 652 if (!sid_peek_rid(pdb_get_user_sid(pwd), &rid)) { 653 DEBUG(0, ("can't get RID for user '%s'\n", 654 pdb_get_username(pwd))); 655 pdb_free_sam(&pwd); 656 continue; 657 } 658 659 if (rid > max_rid) 660 max_rid = rid; 661 662 DEBUG(1,("%d is user '%s'\n", rid, pdb_get_username(pwd))); 663 pdb_free_sam(&pwd); 664 } 665 666 pdb_endsampwent(); 667 pdb_free_sam(&pwd); 668 669 if (!pdb_enum_group_mapping(SID_NAME_UNKNOWN, &map, &num_entries, 670 ENUM_ONLY_MAPPED)) 671 return max_rid; 672 673 for (i = 0; i < num_entries; i++) { 674 uint32 rid; 675 676 if (!sid_peek_check_rid(get_global_sam_sid(), &map[i].sid, 677 &rid)) { 678 DEBUG(3, ("skipping map for group '%s', SID %s\n", 679 map[i].nt_name, 680 sid_string_static(&map[i].sid))); 681 continue; 682 } 683 DEBUG(1,("%d is group '%s'\n", rid, map[i].nt_name)); 684 685 if (rid > max_rid) 686 max_rid = rid; 687 } 688 689 SAFE_FREE(map); 690 691 return max_rid; 692} 693 694static int net_maxrid(int argc, const char **argv) 695{ 696 uint32 rid; 697 698 if (argc != 0) { 699 DEBUG(0, ("usage: net maxrid\n")); 700 return 1; 701 } 702 703 if ((rid = get_maxrid()) == 0) { 704 DEBUG(0, ("can't get current maximum rid\n")); 705 return 1; 706 } 707 708 d_printf("Currently used maximum rid: %d\n", rid); 709 710 return 0; 711} 712 713/* main function table */ 714static struct functable net_func[] = { 715 {"RPC", net_rpc}, 716 {"RAP", net_rap}, 717 {"ADS", net_ads}, 718 719 /* eventually these should auto-choose the transport ... */ 720 {"FILE", net_file}, 721 {"SHARE", net_share}, 722 {"SESSION", net_rap_session}, 723 {"SERVER", net_rap_server}, 724 {"DOMAIN", net_rap_domain}, 725 {"PRINTQ", net_rap_printq}, 726 {"USER", net_user}, 727 {"GROUP", net_group}, 728 {"GROUPMAP", net_groupmap}, 729 {"VALIDATE", net_rap_validate}, 730 {"GROUPMEMBER", net_rap_groupmember}, 731 {"ADMIN", net_rap_admin}, 732 {"SERVICE", net_rap_service}, 733 {"PASSWORD", net_rap_password}, 734 {"CHANGETRUSTPW", net_changetrustpw}, 735 {"CHANGESECRETPW", net_changesecretpw}, 736 {"TIME", net_time}, 737 {"LOOKUP", net_lookup}, 738 {"JOIN", net_join}, 739 {"CACHE", net_cache}, 740 {"GETLOCALSID", net_getlocalsid}, 741 {"SETLOCALSID", net_setlocalsid}, 742 {"GETDOMAINSID", net_getdomainsid}, 743 {"MAXRID", net_maxrid}, 744 {"IDMAP", net_idmap}, 745 {"STATUS", net_status}, 746 {"USERSIDLIST", net_usersidlist}, 747#ifdef WITH_FAKE_KASERVER 748 {"AFS", net_afs}, 749#endif 750 751 {"HELP", net_help}, 752 {NULL, NULL} 753}; 754 755 756/**************************************************************************** 757 main program 758****************************************************************************/ 759 int main(int argc, const char **argv) 760{ 761 int opt,i; 762 char *p; 763 int rc = 0; 764 int argc_new = 0; 765 const char ** argv_new; 766 poptContext pc; 767 768 struct poptOption long_options[] = { 769 {"help", 'h', POPT_ARG_NONE, 0, 'h'}, 770 {"workgroup", 'w', POPT_ARG_STRING, &opt_target_workgroup}, 771 {"user", 'U', POPT_ARG_STRING, &opt_user_name, 'U'}, 772 {"ipaddress", 'I', POPT_ARG_STRING, 0,'I'}, 773 {"port", 'p', POPT_ARG_INT, &opt_port}, 774 {"myname", 'n', POPT_ARG_STRING, &opt_requester_name}, 775 {"server", 'S', POPT_ARG_STRING, &opt_host}, 776 {"container", 'c', POPT_ARG_STRING, &opt_container}, 777 {"comment", 'C', POPT_ARG_STRING, &opt_comment}, 778 {"maxusers", 'M', POPT_ARG_INT, &opt_maxusers}, 779 {"flags", 'F', POPT_ARG_INT, &opt_flags}, 780 {"long", 'l', POPT_ARG_NONE, &opt_long_list_entries}, 781 {"reboot", 'r', POPT_ARG_NONE, &opt_reboot}, 782 {"force", 'f', POPT_ARG_NONE, &opt_force}, 783 {"timeout", 't', POPT_ARG_INT, &opt_timeout}, 784 {"machine-pass",'P', POPT_ARG_NONE, &opt_machine_pass}, 785 {"myworkgroup", 'W', POPT_ARG_STRING, &opt_workgroup}, 786 {"verbose", 'v', POPT_ARG_NONE, &opt_verbose}, 787 /* Options for 'net groupmap set' */ 788 {"local", 'L', POPT_ARG_NONE, &opt_localgroup}, 789 {"domain", 'D', POPT_ARG_NONE, &opt_domaingroup}, 790 {"ntname", 'N', POPT_ARG_STRING, &opt_newntname}, 791 {"rid", 'R', POPT_ARG_INT, &opt_rid}, 792 /* Options for 'net rpc share migrate' */ 793 {"acls", 0, POPT_ARG_NONE, &opt_acls}, 794 {"attrs", 0, POPT_ARG_NONE, &opt_attrs}, 795 {"timestamps", 0, POPT_ARG_NONE, &opt_timestamps}, 796 {"exclude", 'e', POPT_ARG_STRING, &opt_exclude}, 797 {"destination", 0, POPT_ARG_STRING, &opt_destination}, 798 799 POPT_COMMON_SAMBA 800 { 0, 0, 0, 0} 801 }; 802 803 zero_ip(&opt_dest_ip); 804 805 /* set default debug level to 0 regardless of what smb.conf sets */ 806 DEBUGLEVEL_CLASS[DBGC_ALL] = 0; 807 dbf = x_stderr; 808 809 pc = poptGetContext(NULL, argc, (const char **) argv, long_options, 810 POPT_CONTEXT_KEEP_FIRST); 811 812 while((opt = poptGetNextOpt(pc)) != -1) { 813 switch (opt) { 814 case 'h': 815 net_help(argc, argv); 816 exit(0); 817 break; 818 case 'I': 819 opt_dest_ip = *interpret_addr2(poptGetOptArg(pc)); 820 if (is_zero_ip(opt_dest_ip)) 821 d_printf("\nInvalid ip address specified\n"); 822 else 823 opt_have_ip = True; 824 break; 825 case 'U': 826 opt_user_specified = True; 827 opt_user_name = SMB_STRDUP(opt_user_name); 828 p = strchr(opt_user_name,'%'); 829 if (p) { 830 *p = 0; 831 opt_password = p+1; 832 } 833 break; 834 default: 835 d_printf("\nInvalid option %s: %s\n", 836 poptBadOption(pc, 0), poptStrerror(opt)); 837 net_help(argc, argv); 838 exit(1); 839 } 840 } 841 842 /* 843 * Don't load debug level from smb.conf. It should be 844 * set by cmdline arg or remain default (0) 845 */ 846 AllowDebugChange = False; 847 lp_load(dyn_CONFIGFILE,True,False,False); 848 849 argv_new = (const char **)poptGetArgs(pc); 850 851 argc_new = argc; 852 for (i=0; i<argc; i++) { 853 if (argv_new[i] == NULL) { 854 argc_new = i; 855 break; 856 } 857 } 858 859 if (opt_requester_name) { 860 set_global_myname(opt_requester_name); 861 } 862 863 if (!opt_user_name && getenv("LOGNAME")) { 864 opt_user_name = getenv("LOGNAME"); 865 } 866 867 if (!opt_workgroup) { 868 opt_workgroup = smb_xstrdup(lp_workgroup()); 869 } 870 871 if (!opt_target_workgroup) { 872 opt_target_workgroup = smb_xstrdup(lp_workgroup()); 873 } 874 875 if (!init_names()) 876 exit(1); 877 878 load_interfaces(); 879 880 /* this makes sure that when we do things like call scripts, 881 that it won't assert becouse we are not root */ 882 sec_init(); 883 884 if (opt_machine_pass) { 885 /* it is very useful to be able to make ads queries as the 886 machine account for testing purposes and for domain leave */ 887 888 net_use_machine_password(); 889 } 890 891 if (!opt_password) { 892 opt_password = getenv("PASSWD"); 893 } 894 895 rc = net_run_function(argc_new-1, argv_new+1, net_func, net_help); 896 897 DEBUG(2,("return code = %d\n", rc)); 898 return rc; 899} 900