19ba4f0e8a730e76bff151d5c32c8442c5f83535
[amitay/samba.git] / source3 / utils / net.c
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 3 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, see <http://www.gnu.org/licenses/>.  */
26
27 /*****************************************************/
28 /*                                                   */
29 /*   Distributed SMB/CIFS Server Management Utility  */
30 /*                                                   */
31 /*   The intent was to make the syntax similar       */
32 /*   to the NET utility (first developed in DOS      */
33 /*   with additional interesting & useful functions  */
34 /*   added in later SMB server network operating     */
35 /*   systems).                                       */
36 /*                                                   */
37 /*****************************************************/
38
39 #include "includes.h"
40 #include "utils/net.h"
41
42 /***********************************************************************/
43 /* Beginning of internationalization section.  Translatable constants  */
44 /* should be kept in this area and referenced in the rest of the code. */
45 /*                                                                     */
46 /* No functions, outside of Samba or LSB (Linux Standards Base) should */
47 /* be used (if possible).                                              */
48 /***********************************************************************/
49
50 #define YES_STRING              "Yes"
51 #define NO_STRING               "No"
52
53 /***********************************************************************/
54 /* end of internationalization section                                 */
55 /***********************************************************************/
56
57 /* Yes, these buggers are globals.... */
58 const char *opt_requester_name = NULL;
59 const char *opt_host = NULL;
60 const char *opt_password = NULL;
61 const char *opt_user_name = NULL;
62 bool opt_user_specified = False;
63 const char *opt_workgroup = NULL;
64 int opt_long_list_entries = 0;
65 int opt_reboot = 0;
66 int opt_force = 0;
67 int opt_stdin = 0;
68 int opt_port = 0;
69 int opt_verbose = 0;
70 int opt_maxusers = -1;
71 const char *opt_comment = "";
72 const char *opt_container = NULL;
73 int opt_flags = -1;
74 int opt_timeout = 0;
75 const char *opt_target_workgroup = NULL;
76 int opt_machine_pass = 0;
77 int opt_localgroup = False;
78 int opt_domaingroup = False;
79 static int do_talloc_report=False;
80 const char *opt_newntname = "";
81 int opt_rid = 0;
82 int opt_acls = 0;
83 int opt_attrs = 0;
84 int opt_timestamps = 0;
85 const char *opt_exclude = NULL;
86 const char *opt_destination = NULL;
87 int opt_testmode = False;
88
89 int opt_have_ip = False;
90 struct sockaddr_storage opt_dest_ip;
91 bool smb_encrypt;
92 struct libnetapi_ctx *netapi_ctx = NULL;
93
94 extern bool AllowDebugChange;
95
96 uint32 get_sec_channel_type(const char *param)
97 {
98         if (!(param && *param)) {
99                 return get_default_sec_channel();
100         } else {
101                 if (strequal(param, "PDC")) {
102                         return SEC_CHAN_BDC;
103                 } else if (strequal(param, "BDC")) {
104                         return SEC_CHAN_BDC;
105                 } else if (strequal(param, "MEMBER")) {
106                         return SEC_CHAN_WKSTA;
107 #if 0
108                 } else if (strequal(param, "DOMAIN")) {
109                         return SEC_CHAN_DOMAIN;
110 #endif
111                 } else {
112                         return get_default_sec_channel();
113                 }
114         }
115 }
116
117 /*
118   run a function from a function table. If not found then
119   call the specified usage function
120 */
121 int net_run_function(int argc, const char **argv, struct functable *table,
122                      int (*usage_fn)(int argc, const char **argv))
123 {
124         int i;
125
126         if (argc < 1) {
127                 d_printf("\nUsage: \n");
128                 return usage_fn(argc, argv);
129         }
130         for (i=0; table[i].funcname; i++) {
131                 if (StrCaseCmp(argv[0], table[i].funcname) == 0)
132                         return table[i].fn(argc-1, argv+1);
133         }
134         d_fprintf(stderr, "No command: %s\n", argv[0]);
135         return usage_fn(argc, argv);
136 }
137
138 /*
139  * run a function from a function table.
140  */
141 int net_run_function2(int argc, const char **argv, const char *whoami,
142                       struct functable2 *table)
143 {
144         int i;
145
146         if (argc != 0) {
147                 for (i=0; table[i].funcname; i++) {
148                         if (StrCaseCmp(argv[0], table[i].funcname) == 0)
149                                 return table[i].fn(argc-1, argv+1);
150                 }
151         }
152
153         for (i=0; table[i].funcname != NULL; i++) {
154                 d_printf("%s %-15s %s\n", whoami, table[i].funcname,
155                          table[i].helptext);
156         }
157
158         return -1;
159 }
160
161 /****************************************************************************
162  Connect to \\server\service.
163 ****************************************************************************/
164
165 NTSTATUS connect_to_service(struct cli_state **c,
166                                         struct sockaddr_storage *server_ss,
167                                         const char *server_name,
168                                         const char *service_name,
169                                         const char *service_type)
170 {
171         NTSTATUS nt_status;
172
173         opt_password = net_prompt_pass(opt_user_name);
174         if (!opt_password) {
175                 return NT_STATUS_NO_MEMORY;
176         }
177
178         nt_status = cli_full_connection(c, NULL, server_name,
179                                         server_ss, opt_port,
180                                         service_name, service_type,
181                                         opt_user_name, opt_workgroup,
182                                         opt_password, 0, Undefined, NULL);
183         if (!NT_STATUS_IS_OK(nt_status)) {
184                 d_fprintf(stderr, "Could not connect to server %s\n", server_name);
185
186                 /* Display a nicer message depending on the result */
187
188                 if (NT_STATUS_V(nt_status) ==
189                     NT_STATUS_V(NT_STATUS_LOGON_FAILURE))
190                         d_fprintf(stderr, "The username or password was not correct.\n");
191
192                 if (NT_STATUS_V(nt_status) ==
193                     NT_STATUS_V(NT_STATUS_ACCOUNT_LOCKED_OUT))
194                         d_fprintf(stderr, "The account was locked out.\n");
195
196                 if (NT_STATUS_V(nt_status) ==
197                     NT_STATUS_V(NT_STATUS_ACCOUNT_DISABLED))
198                         d_fprintf(stderr, "The account was disabled.\n");
199                 return nt_status;
200         }
201
202         if (smb_encrypt) {
203                 nt_status = cli_force_encryption(*c,
204                                         opt_user_name,
205                                         opt_password,
206                                         opt_workgroup);
207
208                 if (NT_STATUS_EQUAL(nt_status,NT_STATUS_NOT_SUPPORTED)) {
209                         d_printf("Encryption required and "
210                                 "server that doesn't support "
211                                 "UNIX extensions - failing connect\n");
212                 } else if (NT_STATUS_EQUAL(nt_status,NT_STATUS_UNKNOWN_REVISION)) {
213                         d_printf("Encryption required and "
214                                 "can't get UNIX CIFS extensions "
215                                 "version from server.\n");
216                 } else if (NT_STATUS_EQUAL(nt_status,NT_STATUS_UNSUPPORTED_COMPRESSION)) {
217                         d_printf("Encryption required and "
218                                 "share %s doesn't support "
219                                 "encryption.\n", service_name);
220                 } else if (!NT_STATUS_IS_OK(nt_status)) {
221                         d_printf("Encryption required and "
222                                 "setup failed with error %s.\n",
223                                 nt_errstr(nt_status));
224                 }
225
226                 if (!NT_STATUS_IS_OK(nt_status)) {
227                         cli_shutdown(*c);
228                         *c = NULL;
229                 }
230         }
231
232         return nt_status;
233 }
234
235 /****************************************************************************
236  Connect to \\server\ipc$.
237 ****************************************************************************/
238
239 NTSTATUS connect_to_ipc(struct cli_state **c,
240                         struct sockaddr_storage *server_ss,
241                         const char *server_name)
242 {
243         return connect_to_service(c, server_ss, server_name, "IPC$", "IPC");
244 }
245
246 /****************************************************************************
247  Connect to \\server\ipc$ anonymously.
248 ****************************************************************************/
249
250 NTSTATUS connect_to_ipc_anonymous(struct cli_state **c,
251                                 struct sockaddr_storage *server_ss,
252                                 const char *server_name)
253 {
254         NTSTATUS nt_status;
255
256         nt_status = cli_full_connection(c, opt_requester_name, server_name,
257                                         server_ss, opt_port,
258                                         "IPC$", "IPC",
259                                         "", "",
260                                         "", 0, Undefined, NULL);
261
262         if (NT_STATUS_IS_OK(nt_status)) {
263                 return nt_status;
264         } else {
265                 DEBUG(1,("Cannot connect to server (anonymously).  Error was %s\n", nt_errstr(nt_status)));
266                 return nt_status;
267         }
268 }
269
270 /****************************************************************************
271  Return malloced user@realm for krb5 login.
272 ****************************************************************************/
273
274 static char *get_user_and_realm(const char *username)
275 {
276         char *user_and_realm = NULL;
277
278         if (!username) {
279                 return NULL;
280         }
281         if (strchr_m(username, '@')) {
282                 user_and_realm = SMB_STRDUP(username);
283         } else {
284                 if (asprintf(&user_and_realm, "%s@%s", username, lp_realm()) == -1) {
285                         user_and_realm = NULL;
286                 }
287         }
288         return user_and_realm;
289 }
290
291 /****************************************************************************
292  Connect to \\server\ipc$ using KRB5.
293 ****************************************************************************/
294
295 NTSTATUS connect_to_ipc_krb5(struct cli_state **c,
296                         struct sockaddr_storage *server_ss,
297                         const char *server_name)
298 {
299         NTSTATUS nt_status;
300         char *user_and_realm = NULL;
301
302         opt_password = net_prompt_pass(opt_user_name);
303         if (!opt_password) {
304                 return NT_STATUS_NO_MEMORY;
305         }
306
307         user_and_realm = get_user_and_realm(opt_user_name);
308         if (!user_and_realm) {
309                 return NT_STATUS_NO_MEMORY;
310         }
311
312         nt_status = cli_full_connection(c, NULL, server_name,
313                                         server_ss, opt_port,
314                                         "IPC$", "IPC",
315                                         user_and_realm, opt_workgroup,
316                                         opt_password, CLI_FULL_CONNECTION_USE_KERBEROS, 
317                                         Undefined, NULL);
318
319         SAFE_FREE(user_and_realm);
320
321         if (!NT_STATUS_IS_OK(nt_status)) {
322                 DEBUG(1,("Cannot connect to server using kerberos.  Error was %s\n", nt_errstr(nt_status)));
323                 return nt_status;
324         }
325
326         if (smb_encrypt) {
327                 nt_status = cli_cm_force_encryption(*c,
328                                         user_and_realm,
329                                         opt_password,
330                                         opt_workgroup,
331                                         "IPC$");
332                 if (!NT_STATUS_IS_OK(nt_status)) {
333                         cli_shutdown(*c);
334                         *c = NULL;
335                 }
336         }
337
338         return nt_status;
339 }
340
341 /**
342  * Connect a server and open a given pipe
343  *
344  * @param cli_dst               A cli_state
345  * @param pipe                  The pipe to open
346  * @param got_pipe              boolean that stores if we got a pipe
347  *
348  * @return Normal NTSTATUS return.
349  **/
350 NTSTATUS connect_dst_pipe(struct cli_state **cli_dst, struct rpc_pipe_client **pp_pipe_hnd, int pipe_num)
351 {
352         NTSTATUS nt_status;
353         char *server_name = SMB_STRDUP("127.0.0.1");
354         struct cli_state *cli_tmp = NULL;
355         struct rpc_pipe_client *pipe_hnd = NULL;
356
357         if (server_name == NULL) {
358                 return NT_STATUS_NO_MEMORY;
359         }
360
361         if (opt_destination) {
362                 SAFE_FREE(server_name);
363                 if ((server_name = SMB_STRDUP(opt_destination)) == NULL) {
364                         return NT_STATUS_NO_MEMORY;
365                 }
366         }
367
368         /* make a connection to a named pipe */
369         nt_status = connect_to_ipc(&cli_tmp, NULL, server_name);
370         if (!NT_STATUS_IS_OK(nt_status)) {
371                 SAFE_FREE(server_name);
372                 return nt_status;
373         }
374
375         pipe_hnd = cli_rpc_pipe_open_noauth(cli_tmp, pipe_num, &nt_status);
376         if (!pipe_hnd) {
377                 DEBUG(0, ("couldn't not initialize pipe\n"));
378                 cli_shutdown(cli_tmp);
379                 SAFE_FREE(server_name);
380                 return nt_status;
381         }
382
383         *cli_dst = cli_tmp;
384         *pp_pipe_hnd = pipe_hnd;
385         SAFE_FREE(server_name);
386
387         return nt_status;
388 }
389
390 /****************************************************************************
391  Use the local machine account (krb) and password for this session.
392 ****************************************************************************/
393
394 int net_use_krb_machine_account(void)
395 {
396         char *user_name = NULL;
397
398         if (!secrets_init()) {
399                 d_fprintf(stderr, "ERROR: Unable to open secrets database\n");
400                 exit(1);
401         }
402
403         opt_password = secrets_fetch_machine_password(opt_target_workgroup, NULL, NULL);
404         if (asprintf(&user_name, "%s$@%s", global_myname(), lp_realm()) == -1) {
405                 return -1;
406         }
407         opt_user_name = user_name;
408         return 0;
409 }
410
411 /****************************************************************************
412  Use the machine account name and password for this session.
413 ****************************************************************************/
414
415 int net_use_machine_account(void)
416 {
417         char *user_name = NULL;
418
419         if (!secrets_init()) {
420                 d_fprintf(stderr, "ERROR: Unable to open secrets database\n");
421                 exit(1);
422         }
423
424         opt_password = secrets_fetch_machine_password(opt_target_workgroup, NULL, NULL);
425         if (asprintf(&user_name, "%s$", global_myname()) == -1) {
426                 return -1;
427         }
428         opt_user_name = user_name;
429         return 0;
430 }
431
432 bool net_find_server(const char *domain,
433                         unsigned flags,
434                         struct sockaddr_storage *server_ss,
435                         char **server_name)
436 {
437         const char *d = domain ? domain : opt_target_workgroup;
438
439         if (opt_host) {
440                 *server_name = SMB_STRDUP(opt_host);
441         }
442
443         if (opt_have_ip) {
444                 *server_ss = opt_dest_ip;
445                 if (!*server_name) {
446                         char addr[INET6_ADDRSTRLEN];
447                         print_sockaddr(addr, sizeof(addr), &opt_dest_ip);
448                         *server_name = SMB_STRDUP(addr);
449                 }
450         } else if (*server_name) {
451                 /* resolve the IP address */
452                 if (!resolve_name(*server_name, server_ss, 0x20))  {
453                         DEBUG(1,("Unable to resolve server name\n"));
454                         return false;
455                 }
456         } else if (flags & NET_FLAGS_PDC) {
457                 fstring dc_name;
458                 struct sockaddr_storage pdc_ss;
459
460                 if (!get_pdc_ip(d, &pdc_ss)) {
461                         DEBUG(1,("Unable to resolve PDC server address\n"));
462                         return false;
463                 }
464
465                 if (is_zero_addr(&pdc_ss)) {
466                         return false;
467                 }
468
469                 if (!name_status_find(d, 0x1b, 0x20, &pdc_ss, dc_name)) {
470                         return False;
471                 }
472
473                 *server_name = SMB_STRDUP(dc_name);
474                 *server_ss = pdc_ss;
475         } else if (flags & NET_FLAGS_DMB) {
476                 struct sockaddr_storage msbrow_ss;
477                 char addr[INET6_ADDRSTRLEN];
478
479                 /*  if (!resolve_name(MSBROWSE, &msbrow_ip, 1)) */
480                 if (!resolve_name(d, &msbrow_ss, 0x1B))  {
481                         DEBUG(1,("Unable to resolve domain browser via name lookup\n"));
482                         return false;
483                 }
484                 *server_ss = msbrow_ss;
485                 print_sockaddr(addr, sizeof(addr), server_ss);
486                 *server_name = SMB_STRDUP(addr);
487         } else if (flags & NET_FLAGS_MASTER) {
488                 struct sockaddr_storage brow_ss;
489                 char addr[INET6_ADDRSTRLEN];
490                 if (!resolve_name(d, &brow_ss, 0x1D))  {
491                                 /* go looking for workgroups */
492                         DEBUG(1,("Unable to resolve master browser via name lookup\n"));
493                         return false;
494                 }
495                 *server_ss = brow_ss;
496                 print_sockaddr(addr, sizeof(addr), server_ss);
497                 *server_name = SMB_STRDUP(addr);
498         } else if (!(flags & NET_FLAGS_LOCALHOST_DEFAULT_INSANE)) {
499                 if (!interpret_string_addr(server_ss,
500                                         "127.0.0.1", AI_NUMERICHOST)) {
501                         DEBUG(1,("Unable to resolve 127.0.0.1\n"));
502                         return false;
503                 }
504                 *server_name = SMB_STRDUP("127.0.0.1");
505         }
506
507         if (!*server_name) {
508                 DEBUG(1,("no server to connect to\n"));
509                 return False;
510         }
511
512         return True;
513 }
514
515 bool net_find_pdc(struct sockaddr_storage *server_ss,
516                 fstring server_name,
517                 const char *domain_name)
518 {
519         if (!get_pdc_ip(domain_name, server_ss)) {
520                 return false;
521         }
522         if (is_zero_addr(server_ss)) {
523                 return false;
524         }
525
526         if (!name_status_find(domain_name, 0x1b, 0x20, server_ss, server_name)) {
527                 return false;
528         }
529
530         return true;
531 }
532
533 NTSTATUS net_make_ipc_connection(unsigned flags, struct cli_state **pcli)
534 {
535         return net_make_ipc_connection_ex(NULL, NULL, NULL, flags, pcli);
536 }
537
538 NTSTATUS net_make_ipc_connection_ex(const char *domain, const char *server,
539                                     struct sockaddr_storage *pss, unsigned flags,
540                                     struct cli_state **pcli)
541 {
542         char *server_name = NULL;
543         struct sockaddr_storage server_ss;
544         struct cli_state *cli = NULL;
545         NTSTATUS nt_status;
546
547         if ( !server || !pss ) {
548                 if (!net_find_server(domain, flags, &server_ss, &server_name)) {
549                         d_fprintf(stderr, "Unable to find a suitable server\n");
550                         nt_status = NT_STATUS_UNSUCCESSFUL;
551                         goto done;
552                 }
553         } else {
554                 server_name = SMB_STRDUP( server );
555                 server_ss = *pss;
556         }
557
558         if (flags & NET_FLAGS_ANONYMOUS) {
559                 nt_status = connect_to_ipc_anonymous(&cli, &server_ss, server_name);
560         } else {
561                 nt_status = connect_to_ipc(&cli, &server_ss, server_name);
562         }
563
564         /* store the server in the affinity cache if it was a PDC */
565
566         if ( (flags & NET_FLAGS_PDC) && NT_STATUS_IS_OK(nt_status) )
567                 saf_store( cli->server_domain, cli->desthost );
568
569         SAFE_FREE(server_name);
570         if (!NT_STATUS_IS_OK(nt_status)) {
571                 d_fprintf(stderr, "Connection failed: %s\n",
572                           nt_errstr(nt_status));
573                 cli = NULL;
574         }
575
576 done:
577         if (pcli != NULL) {
578                 *pcli = cli;
579         }
580         return nt_status;
581 }
582
583 static int net_user(int argc, const char **argv)
584 {
585         if (net_ads_check() == 0)
586                 return net_ads_user(argc, argv);
587
588         /* if server is not specified, default to PDC? */
589         if (net_rpc_check(NET_FLAGS_PDC))
590                 return net_rpc_user(argc, argv);
591
592         return net_rap_user(argc, argv);
593 }
594
595 static int net_group(int argc, const char **argv)
596 {
597         if (net_ads_check() == 0)
598                 return net_ads_group(argc, argv);
599
600         if (argc == 0 && net_rpc_check(NET_FLAGS_PDC))
601                 return net_rpc_group(argc, argv);
602
603         return net_rap_group(argc, argv);
604 }
605
606 static int net_join(int argc, const char **argv)
607 {
608         if (net_ads_check_our_domain() == 0) {
609                 if (net_ads_join(argc, argv) == 0)
610                         return 0;
611                 else
612                         d_fprintf(stderr, "ADS join did not work, falling back to RPC...\n");
613         }
614         return net_rpc_join(argc, argv);
615 }
616
617 static int net_changetrustpw(int argc, const char **argv)
618 {
619         if (net_ads_check_our_domain() == 0)
620                 return net_ads_changetrustpw(argc, argv);
621
622         return net_rpc_changetrustpw(argc, argv);
623 }
624
625 static void set_line_buffering(FILE *f)
626 {
627         setvbuf(f, NULL, _IOLBF, 0);
628 }
629
630 static int net_changesecretpw(int argc, const char **argv)
631 {
632         char *trust_pw;
633         uint32 sec_channel_type = SEC_CHAN_WKSTA;
634
635         if(opt_force) {
636                 if (opt_stdin) {
637                         set_line_buffering(stdin);
638                         set_line_buffering(stdout);
639                         set_line_buffering(stderr);
640                 }
641
642                 trust_pw = get_pass("Enter machine password: ", opt_stdin);
643
644                 if (!secrets_store_machine_password(trust_pw, lp_workgroup(), sec_channel_type)) {
645                             d_fprintf(stderr, "Unable to write the machine account password in the secrets database");
646                             return 1;
647                 }
648                 else {
649                     d_printf("Modified trust account password in secrets database\n");
650                 }
651         }
652         else {
653                 d_printf("Machine account password change requires the -f flag.\n");
654                 d_printf("Do NOT use this function unless you know what it does!\n");
655                 d_printf("This function will change the ADS Domain member machine account password in the secrets.tdb file!\n");
656         }
657
658         return 0;
659 }
660
661 static int net_share(int argc, const char **argv)
662 {
663         if (net_rpc_check(0))
664                 return net_rpc_share(argc, argv);
665         return net_rap_share(argc, argv);
666 }
667
668 static int net_file(int argc, const char **argv)
669 {
670         if (net_rpc_check(0))
671                 return net_rpc_file(argc, argv);
672         return net_rap_file(argc, argv);
673 }
674
675 /*
676  Retrieve our local SID or the SID for the specified name
677  */
678 static int net_getlocalsid(int argc, const char **argv)
679 {
680         DOM_SID sid;
681         const char *name;
682         fstring sid_str;
683
684         if (argc >= 1) {
685                 name = argv[0];
686         }
687         else {
688                 name = global_myname();
689         }
690
691         if(!initialize_password_db(False, NULL)) {
692                 DEBUG(0, ("WARNING: Could not open passdb - local sid may not reflect passdb\n"
693                           "backend knowledge (such as the sid stored in LDAP)\n"));
694         }
695
696         /* first check to see if we can even access secrets, so we don't
697            panic when we can't. */
698
699         if (!secrets_init()) {
700                 d_fprintf(stderr, "Unable to open secrets.tdb.  Can't fetch domain SID for name: %s\n", name);
701                 return 1;
702         }
703
704         /* Generate one, if it doesn't exist */
705         get_global_sam_sid();
706
707         if (!secrets_fetch_domain_sid(name, &sid)) {
708                 DEBUG(0, ("Can't fetch domain SID for name: %s\n", name));
709                 return 1;
710         }
711         sid_to_fstring(sid_str, &sid);
712         d_printf("SID for domain %s is: %s\n", name, sid_str);
713         return 0;
714 }
715
716 static int net_setlocalsid(int argc, const char **argv)
717 {
718         DOM_SID sid;
719
720         if ( (argc != 1)
721              || (strncmp(argv[0], "S-1-5-21-", strlen("S-1-5-21-")) != 0)
722              || (!string_to_sid(&sid, argv[0]))
723              || (sid.num_auths != 4)) {
724                 d_printf("usage: net setlocalsid S-1-5-21-x-y-z\n");
725                 return 1;
726         }
727
728         if (!secrets_store_domain_sid(global_myname(), &sid)) {
729                 DEBUG(0,("Can't store domain SID as a pdc/bdc.\n"));
730                 return 1;
731         }
732
733         return 0;
734 }
735
736 static int net_setdomainsid(int argc, const char **argv)
737 {
738         DOM_SID sid;
739
740         if ( (argc != 1)
741              || (strncmp(argv[0], "S-1-5-21-", strlen("S-1-5-21-")) != 0)
742              || (!string_to_sid(&sid, argv[0]))
743              || (sid.num_auths != 4)) {
744                 d_printf("usage: net setdomainsid S-1-5-21-x-y-z\n");
745                 return 1;
746         }
747
748         if (!secrets_store_domain_sid(lp_workgroup(), &sid)) {
749                 DEBUG(0,("Can't store domain SID.\n"));
750                 return 1;
751         }
752
753         return 0;
754 }
755
756 static int net_getdomainsid(int argc, const char **argv)
757 {
758         DOM_SID domain_sid;
759         fstring sid_str;
760
761         if (argc > 0) {
762                 d_printf("usage: net getdomainsid\n");
763                 return 1;
764         }
765
766         if(!initialize_password_db(False, NULL)) {
767                 DEBUG(0, ("WARNING: Could not open passdb - domain SID may "
768                           "not reflect passdb\n"
769                           "backend knowledge (such as the SID stored in "
770                           "LDAP)\n"));
771         }
772
773         /* first check to see if we can even access secrets, so we don't
774            panic when we can't. */
775
776         if (!secrets_init()) {
777                 d_fprintf(stderr, "Unable to open secrets.tdb.  Can't fetch domain"
778                                   "SID for name: %s\n", get_global_sam_name());
779                 return 1;
780         }
781
782         /* Generate one, if it doesn't exist */
783         get_global_sam_sid();
784
785         if (!secrets_fetch_domain_sid(global_myname(), &domain_sid)) {
786                 d_fprintf(stderr, "Could not fetch local SID\n");
787                 return 1;
788         }
789         sid_to_fstring(sid_str, &domain_sid);
790         d_printf("SID for local machine %s is: %s\n", global_myname(), sid_str);
791
792         if (!secrets_fetch_domain_sid(opt_workgroup, &domain_sid)) {
793                 d_fprintf(stderr, "Could not fetch domain SID\n");
794                 return 1;
795         }
796
797         sid_to_fstring(sid_str, &domain_sid);
798         d_printf("SID for domain %s is: %s\n", opt_workgroup, sid_str);
799
800         return 0;
801 }
802
803 #ifdef WITH_FAKE_KASERVER
804
805 int net_help_afs(int argc, const char **argv)
806 {
807         d_printf("  net afs key filename\n"
808                  "\tImports a OpenAFS KeyFile into our secrets.tdb\n\n");
809         d_printf("  net afs impersonate <user> <cell>\n"
810                  "\tCreates a token for user@cell\n\n");
811         return -1;
812 }
813
814 static int net_afs_key(int argc, const char **argv)
815 {
816         int fd;
817         struct afs_keyfile keyfile;
818
819         if (argc != 2) {
820                 d_printf("usage: 'net afs key <keyfile> cell'\n");
821                 return -1;
822         }
823
824         if (!secrets_init()) {
825                 d_fprintf(stderr, "Could not open secrets.tdb\n");
826                 return -1;
827         }
828
829         if ((fd = open(argv[0], O_RDONLY, 0)) < 0) {
830                 d_fprintf(stderr, "Could not open %s\n", argv[0]);
831                 return -1;
832         }
833
834         if (read(fd, &keyfile, sizeof(keyfile)) != sizeof(keyfile)) {
835                 d_fprintf(stderr, "Could not read keyfile\n");
836                 return -1;
837         }
838
839         if (!secrets_store_afs_keyfile(argv[1], &keyfile)) {
840                 d_fprintf(stderr, "Could not write keyfile to secrets.tdb\n");
841                 return -1;
842         }
843
844         return 0;
845 }
846
847 static int net_afs_impersonate(int argc, const char **argv)
848 {
849         char *token;
850
851         if (argc != 2) {
852                 fprintf(stderr, "Usage: net afs impersonate <user> <cell>\n");
853                 exit(1);
854         }
855
856         token = afs_createtoken_str(argv[0], argv[1]);
857
858         if (token == NULL) {
859                 fprintf(stderr, "Could not create token\n");
860                 exit(1);
861         }
862
863         if (!afs_settoken_str(token)) {
864                 fprintf(stderr, "Could not set token into kernel\n");
865                 exit(1);
866         }
867
868         printf("Success: %s@%s\n", argv[0], argv[1]);
869         return 0;
870 }
871
872 static int net_afs(int argc, const char **argv)
873 {
874         struct functable func[] = {
875                 {"key", net_afs_key},
876                 {"impersonate", net_afs_impersonate},
877                 {"help", net_help_afs},
878                 {NULL, NULL}
879         };
880         return net_run_function(argc, argv, func, net_help_afs);
881 }
882
883 #endif /* WITH_FAKE_KASERVER */
884
885 static bool search_maxrid(struct pdb_search *search, const char *type,
886                           uint32 *max_rid)
887 {
888         struct samr_displayentry *entries;
889         uint32 i, num_entries;
890
891         if (search == NULL) {
892                 d_fprintf(stderr, "get_maxrid: Could not search %s\n", type);
893                 return False;
894         }
895
896         num_entries = pdb_search_entries(search, 0, 0xffffffff, &entries);
897         for (i=0; i<num_entries; i++)
898                 *max_rid = MAX(*max_rid, entries[i].rid);
899         pdb_search_destroy(search);
900         return True;
901 }
902
903 static uint32 get_maxrid(void)
904 {
905         uint32 max_rid = 0;
906
907         if (!search_maxrid(pdb_search_users(0), "users", &max_rid))
908                 return 0;
909
910         if (!search_maxrid(pdb_search_groups(), "groups", &max_rid))
911                 return 0;
912
913         if (!search_maxrid(pdb_search_aliases(get_global_sam_sid()),
914                            "aliases", &max_rid))
915                 return 0;
916
917         return max_rid;
918 }
919
920 static int net_maxrid(int argc, const char **argv)
921 {
922         uint32 rid;
923
924         if (argc != 0) {
925                 DEBUG(0, ("usage: net maxrid\n"));
926                 return 1;
927         }
928
929         if ((rid = get_maxrid()) == 0) {
930                 DEBUG(0, ("can't get current maximum rid\n"));
931                 return 1;
932         }
933
934         d_printf("Currently used maximum rid: %d\n", rid);
935
936         return 0;
937 }
938
939 /****************************************************************************
940 ****************************************************************************/
941
942 const char *net_prompt_pass(const char *user)
943 {
944         char *prompt = NULL;
945         const char *pass = NULL;
946
947         if (opt_password) {
948                 return opt_password;
949         }
950
951         if (opt_machine_pass) {
952                 return NULL;
953         }
954
955         asprintf(&prompt, "Enter %s's password:", user);
956         if (!prompt) {
957                 return NULL;
958         }
959
960         pass = getpass(prompt);
961         SAFE_FREE(prompt);
962
963         return pass;
964 }
965
966 /* main function table */
967 static struct functable net_func[] = {
968         {"RPC", net_rpc},
969         {"RAP", net_rap},
970         {"ADS", net_ads},
971
972         /* eventually these should auto-choose the transport ... */
973         {"FILE", net_file},
974         {"SHARE", net_share},
975         {"SESSION", net_rap_session},
976         {"SERVER", net_rap_server},
977         {"DOMAIN", net_rap_domain},
978         {"PRINTQ", net_rap_printq},
979         {"USER", net_user},
980         {"GROUP", net_group},
981         {"GROUPMAP", net_groupmap},
982         {"SAM", net_sam},
983         {"VALIDATE", net_rap_validate},
984         {"GROUPMEMBER", net_rap_groupmember},
985         {"ADMIN", net_rap_admin},
986         {"SERVICE", net_rap_service},
987         {"PASSWORD", net_rap_password},
988         {"CHANGETRUSTPW", net_changetrustpw},
989         {"CHANGESECRETPW", net_changesecretpw},
990         {"TIME", net_time},
991         {"LOOKUP", net_lookup},
992         {"JOIN", net_join},
993         {"DOM", net_dom},
994         {"CACHE", net_cache},
995         {"GETLOCALSID", net_getlocalsid},
996         {"SETLOCALSID", net_setlocalsid},
997         {"SETDOMAINSID", net_setdomainsid},
998         {"GETDOMAINSID", net_getdomainsid},
999         {"MAXRID", net_maxrid},
1000         {"IDMAP", net_idmap},
1001         {"STATUS", net_status},
1002         {"USERSHARE", net_usershare},
1003         {"USERSIDLIST", net_usersidlist},
1004         {"CONF", net_conf},
1005         {"REGISTRY", net_registry},
1006 #ifdef WITH_FAKE_KASERVER
1007         {"AFS", net_afs},
1008 #endif
1009
1010         {"HELP", net_help},
1011         {NULL, NULL}
1012 };
1013
1014
1015 /****************************************************************************
1016   main program
1017 ****************************************************************************/
1018  int main(int argc, const char **argv)
1019 {
1020         int opt,i;
1021         char *p;
1022         int rc = 0;
1023         int argc_new = 0;
1024         const char ** argv_new;
1025         poptContext pc;
1026
1027         struct poptOption long_options[] = {
1028                 {"help",        'h', POPT_ARG_NONE,   0, 'h'},
1029                 {"workgroup",   'w', POPT_ARG_STRING, &opt_target_workgroup},
1030                 {"user",        'U', POPT_ARG_STRING, &opt_user_name, 'U'},
1031                 {"ipaddress",   'I', POPT_ARG_STRING, 0,'I'},
1032                 {"port",        'p', POPT_ARG_INT,    &opt_port},
1033                 {"myname",      'n', POPT_ARG_STRING, &opt_requester_name},
1034                 {"server",      'S', POPT_ARG_STRING, &opt_host},
1035                 {"encrypt",     'e', POPT_ARG_NONE,   NULL, 'e', "Encrypt SMB transport (UNIX extended servers only)" },
1036                 {"container",   'c', POPT_ARG_STRING, &opt_container},
1037                 {"comment",     'C', POPT_ARG_STRING, &opt_comment},
1038                 {"maxusers",    'M', POPT_ARG_INT,    &opt_maxusers},
1039                 {"flags",       'F', POPT_ARG_INT,    &opt_flags},
1040                 {"long",        'l', POPT_ARG_NONE,   &opt_long_list_entries},
1041                 {"reboot",      'r', POPT_ARG_NONE,   &opt_reboot},
1042                 {"force",       'f', POPT_ARG_NONE,   &opt_force},
1043                 {"stdin",       'i', POPT_ARG_NONE,   &opt_stdin},
1044                 {"timeout",     't', POPT_ARG_INT,    &opt_timeout},
1045                 {"machine-pass",'P', POPT_ARG_NONE,   &opt_machine_pass},
1046                 {"myworkgroup", 'W', POPT_ARG_STRING, &opt_workgroup},
1047                 {"verbose",     'v', POPT_ARG_NONE,   &opt_verbose},
1048                 {"test",        'T', POPT_ARG_NONE,   &opt_testmode},
1049                 /* Options for 'net groupmap set' */
1050                 {"local",       'L', POPT_ARG_NONE,   &opt_localgroup},
1051                 {"domain",      'D', POPT_ARG_NONE,   &opt_domaingroup},
1052                 {"ntname",      'N', POPT_ARG_STRING, &opt_newntname},
1053                 {"rid",         'R', POPT_ARG_INT,    &opt_rid},
1054                 /* Options for 'net rpc share migrate' */
1055                 {"acls",        0, POPT_ARG_NONE,     &opt_acls},
1056                 {"attrs",       0, POPT_ARG_NONE,     &opt_attrs},
1057                 {"timestamps",  0, POPT_ARG_NONE,     &opt_timestamps},
1058                 {"exclude",     'X', POPT_ARG_STRING, &opt_exclude},
1059                 {"destination", 0, POPT_ARG_STRING,   &opt_destination},
1060                 {"tallocreport", 0, POPT_ARG_NONE, &do_talloc_report},
1061
1062                 POPT_COMMON_SAMBA
1063                 { 0, 0, 0, 0}
1064         };
1065
1066         TALLOC_CTX *frame = talloc_stackframe();
1067
1068         zero_addr(&opt_dest_ip);
1069
1070         load_case_tables();
1071
1072         /* set default debug level to 0 regardless of what smb.conf sets */
1073         DEBUGLEVEL_CLASS[DBGC_ALL] = 0;
1074         dbf = x_stderr;
1075
1076         pc = poptGetContext(NULL, argc, (const char **) argv, long_options,
1077                             POPT_CONTEXT_KEEP_FIRST);
1078
1079         while((opt = poptGetNextOpt(pc)) != -1) {
1080                 switch (opt) {
1081                 case 'h':
1082                         net_help(argc, argv);
1083                         exit(0);
1084                         break;
1085                 case 'e':
1086                         smb_encrypt=true;
1087                         break;
1088                 case 'I':
1089                         if (!interpret_string_addr(&opt_dest_ip,
1090                                                 poptGetOptArg(pc), 0)) {
1091                                 d_fprintf(stderr, "\nInvalid ip address specified\n");
1092                         } else {
1093                                 opt_have_ip = True;
1094                         }
1095                         break;
1096                 case 'U':
1097                         opt_user_specified = True;
1098                         opt_user_name = SMB_STRDUP(opt_user_name);
1099                         p = strchr(opt_user_name,'%');
1100                         if (p) {
1101                                 *p = 0;
1102                                 opt_password = p+1;
1103                         }
1104                         break;
1105                 default:
1106                         d_fprintf(stderr, "\nInvalid option %s: %s\n",
1107                                  poptBadOption(pc, 0), poptStrerror(opt));
1108                         net_help(argc, argv);
1109                         exit(1);
1110                 }
1111         }
1112
1113         /*
1114          * Don't load debug level from smb.conf. It should be
1115          * set by cmdline arg or remain default (0)
1116          */
1117         AllowDebugChange = False;
1118         lp_load(get_dyn_CONFIGFILE(),True,False,False,True);
1119
1120         argv_new = (const char **)poptGetArgs(pc);
1121
1122         argc_new = argc;
1123         for (i=0; i<argc; i++) {
1124                 if (argv_new[i] == NULL) {
1125                         argc_new = i;
1126                         break;
1127                 }
1128         }
1129
1130         if (do_talloc_report) {
1131                 talloc_enable_leak_report();
1132         }
1133
1134         if (opt_requester_name) {
1135                 set_global_myname(opt_requester_name);
1136         }
1137
1138         if (!opt_user_name && getenv("LOGNAME")) {
1139                 opt_user_name = getenv("LOGNAME");
1140         }
1141
1142         if (!opt_workgroup) {
1143                 opt_workgroup = smb_xstrdup(lp_workgroup());
1144         }
1145
1146         if (!opt_target_workgroup) {
1147                 opt_target_workgroup = smb_xstrdup(lp_workgroup());
1148         }
1149
1150         if (!init_names())
1151                 exit(1);
1152
1153         load_interfaces();
1154
1155         /* this makes sure that when we do things like call scripts,
1156            that it won't assert becouse we are not root */
1157         sec_init();
1158
1159         if (opt_machine_pass) {
1160                 /* it is very useful to be able to make ads queries as the
1161                    machine account for testing purposes and for domain leave */
1162
1163                 net_use_krb_machine_account();
1164         }
1165
1166         if (!opt_password) {
1167                 opt_password = getenv("PASSWD");
1168         }
1169
1170         rc = net_run_function(argc_new-1, argv_new+1, net_func, net_help);
1171
1172         DEBUG(2,("return code = %d\n", rc));
1173
1174         libnetapi_free(netapi_ctx);
1175
1176         TALLOC_FREE(frame);
1177         return rc;
1178 }