MORE places??? TODO??? s3:net: call fault_setup() in order to get usefull backtraces
[metze/samba/wip.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    Copyright (C) 2008 Kai Blin (kai@samba.org)
9
10    Originally written by Steve and Jim. Largely rewritten by tridge in
11    November 2001.
12
13    Reworked again by abartlet in December 2001
14
15    Another overhaul, moving functionality into plug-ins loaded on demand by Kai
16    in May 2008.
17
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.
22
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.
27
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/>.  */
30
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 /*****************************************************/
42
43 #include "includes.h"
44 #include "popt_common_cmdline.h"
45 #include "utils/net.h"
46 #include "secrets.h"
47 #include "lib/netapi/netapi.h"
48 #include "../libcli/security/security.h"
49 #include "passdb.h"
50 #include "messages.h"
51 #include "cmdline_contexts.h"
52 #include "lib/gencache.h"
53 #include "auth/credentials/credentials.h"
54
55 #ifdef WITH_FAKE_KASERVER
56 #include "utils/net_afs.h"
57 #endif
58
59 /***********************************************************************/
60 /* end of internationalization section                                 */
61 /***********************************************************************/
62
63 enum netr_SchannelType get_sec_channel_type(const char *param)
64 {
65         if (!(param && *param)) {
66                 return get_default_sec_channel();
67         } else {
68                 if (strequal(param, "PDC")) {
69                         return SEC_CHAN_BDC;
70                 } else if (strequal(param, "BDC")) {
71                         return SEC_CHAN_BDC;
72                 } else if (strequal(param, "MEMBER")) {
73                         return SEC_CHAN_WKSTA;
74 #if 0
75                 } else if (strequal(param, "DOMAIN")) {
76                         return SEC_CHAN_DOMAIN;
77 #endif
78                 } else {
79                         return get_default_sec_channel();
80                 }
81         }
82 }
83
84 static int net_changetrustpw(struct net_context *c, int argc, const char **argv)
85 {
86         if (net_ads_check_our_domain(c) == 0)
87                 return net_ads_changetrustpw(c, argc, argv);
88
89         return net_rpc_changetrustpw(c, argc, argv);
90 }
91
92 static void set_line_buffering(FILE *f)
93 {
94         setvbuf(f, NULL, _IOLBF, 0);
95 }
96
97 static int net_primarytrust_dumpinfo(struct net_context *c, int argc,
98                                      const char **argv)
99 {
100         int role = lp_server_role();
101         const char *domain = lp_workgroup();
102         struct secrets_domain_info1 *info = NULL;
103         bool include_secrets = c->opt_force;
104         char *str = NULL;
105         NTSTATUS status;
106
107         if (role >= ROLE_ACTIVE_DIRECTORY_DC) {
108                 d_printf(_("net primarytrust dumpinfo is only supported "
109                          "on a DOMAIN_MEMBER for now.\n"));
110                 return 1;
111         }
112
113         if (c->opt_stdin) {
114                 set_line_buffering(stdin);
115                 set_line_buffering(stdout);
116                 set_line_buffering(stderr);
117         }
118
119         status = secrets_fetch_or_upgrade_domain_info(domain,
120                                                       talloc_tos(),
121                                                       &info);
122         if (!NT_STATUS_IS_OK(status)) {
123                 d_fprintf(stderr,
124                           _("Unable to fetch the information for domain[%s] "
125                           "in the secrets database.\n"),
126                           domain);
127                 return 1;
128         }
129
130         str = secrets_domain_info_string(info, info, domain, include_secrets);
131         if (str == NULL) {
132                 d_fprintf(stderr, "secrets_domain_info_string() failed.\n");
133                 return 1;
134         }
135
136         d_printf("%s", str);
137         if (!c->opt_force) {
138                 d_printf(_("The password values are only included using "
139                          "-f flag.\n"));
140         }
141
142         TALLOC_FREE(info);
143         return 0;
144 }
145
146 /**
147  * Entrypoint for 'net primarytrust' code.
148  *
149  * @param argc Standard argc.
150  * @param argv Standard argv without initial components.
151  *
152  * @return Integer status (0 means success).
153  */
154
155 static int net_primarytrust(struct net_context *c, int argc, const char **argv)
156 {
157         struct functable func[] = {
158                 {
159                         .funcname         = "dumpinfo",
160                         .fn               = net_primarytrust_dumpinfo,
161                         .valid_transports = NET_TRANSPORT_LOCAL,
162                         .description      = N_("Dump the details of the "
163                                                "workstation trust"),
164                         .usage            = N_("  net [options] primarytrust "
165                                                "dumpinfo'\n"
166                                                "    Dump the details of the "
167                                                "workstation trust in "
168                                                "secrets.tdb.\n"
169                                                "    Requires the -f flag to "
170                                                "include the password values."),
171                 },
172                 {
173                         .funcname = NULL,
174                 },
175         };
176
177         return net_run_function(c, argc, argv, "net primarytrust", func);
178 }
179
180 static int net_changesecretpw(struct net_context *c, int argc,
181                               const char **argv)
182 {
183         char *trust_pw;
184         int role = lp_server_role();
185
186         if (role != ROLE_DOMAIN_MEMBER) {
187                 d_printf(_("Machine account password change only supported on a DOMAIN_MEMBER.\n"
188                            "Do NOT use this function unless you know what it does!\n"
189                            "This function will change the ADS Domain member "
190                            "machine account password in the secrets.tdb file!\n"));
191                 return 1;
192         }
193
194         if(c->opt_force) {
195                 struct secrets_domain_info1 *info = NULL;
196                 struct secrets_domain_info1_change *prev = NULL;
197                 NTSTATUS status;
198                 struct timeval tv = timeval_current();
199                 NTTIME now = timeval_to_nttime(&tv);
200
201                 if (c->opt_stdin) {
202                         set_line_buffering(stdin);
203                         set_line_buffering(stdout);
204                         set_line_buffering(stderr);
205                 }
206
207                 trust_pw = get_pass(_("Enter machine password: "), c->opt_stdin);
208                 if (trust_pw == NULL) {
209                             d_fprintf(stderr,
210                                       _("Error in reading machine password\n"));
211                             return 1;
212                 }
213
214                 status = secrets_prepare_password_change(lp_workgroup(),
215                                                          "localhost",
216                                                          trust_pw,
217                                                          talloc_tos(),
218                                                          &info, &prev);
219                 if (!NT_STATUS_IS_OK(status)) {
220                         d_fprintf(stderr,
221                                 _("Unable to write the machine account password in the secrets database"));
222                         return 1;
223                 }
224                 if (prev != NULL) {
225                         d_fprintf(stderr,
226                                 _("Pending machine account password change found - aborting."));
227                         status = secrets_failed_password_change("localhost",
228                                                 NT_STATUS_REQUEST_NOT_ACCEPTED,
229                                                 NT_STATUS_NOT_COMMITTED,
230                                                 info);
231                         if (!NT_STATUS_IS_OK(status)) {
232                                 d_fprintf(stderr,
233                                         _("Failed to abort machine account password change"));
234                         }
235                         return 1;
236                 }
237                 status = secrets_finish_password_change("localhost", now, info);
238                 if (!NT_STATUS_IS_OK(status)) {
239                         d_fprintf(stderr,
240                                 _("Unable to write the machine account password in the secrets database"));
241                         return 1;
242                 }
243
244                 d_printf(_("Modified trust account password in secrets database\n"));
245         }
246         else {
247                 d_printf(_("Machine account password change requires the -f flag.\n"
248                            "Do NOT use this function unless you know what it does!\n"
249                            "This function will change the ADS Domain member "
250                            "machine account password in the secrets.tdb file!\n"));
251         }
252
253         return 0;
254 }
255
256 /**
257  * @brief Set the authorised user for winbindd access in secrets.tdb
258  */
259 static int net_setauthuser(struct net_context *c, int argc, const char **argv)
260 {
261         const char *password = NULL;
262
263         if (!secrets_init()) {
264                 d_fprintf(stderr, _("Failed to open secrets.tdb.\n"));
265                 return 1;
266         }
267
268         /* Delete the settings. */
269         if (argc >= 1) {
270                 if (strncmp(argv[0], "delete", 6) != 0) {
271                         d_fprintf(stderr,_("Usage:\n"));
272                         d_fprintf(stderr,
273                                   _("    net setauthuser -U user[%%password] \n"
274                                     "        Set the auth user account to user"
275                                     "password. Prompt for password if not "
276                                     "specified.\n"));
277                         d_fprintf(stderr,
278                                   _("    net setauthuser delete\n"
279                                     "        Delete the auth user setting.\n"));
280                         return 1;
281                 }
282                 secrets_delete_entry(SECRETS_AUTH_USER);
283                 secrets_delete_entry(SECRETS_AUTH_DOMAIN);
284                 secrets_delete_entry(SECRETS_AUTH_PASSWORD);
285                 return 0;
286         }
287
288         if (!c->opt_user_specified) {
289                 d_fprintf(stderr, _("Usage:\n"));
290                 d_fprintf(stderr,
291                           _("    net setauthuser -U user[%%password]\n"
292                             "        Set the auth user account to user"
293                             "password. Prompt for password if not "
294                             "specified.\n"));
295                 d_fprintf(stderr,
296                           _("    net setauthuser delete\n"
297                             "        Delete the auth user setting.\n"));
298                 return 1;
299         }
300
301         password = net_prompt_pass(c, _("the auth user"));
302         if (password == NULL) {
303                 d_fprintf(stderr,_("Failed to get the auth users password.\n"));
304                 return 1;
305         }
306
307         if (!secrets_store(SECRETS_AUTH_USER, c->opt_user_name,
308                            strlen(c->opt_user_name) + 1)) {
309                 d_fprintf(stderr, _("error storing auth user name\n"));
310                 return 1;
311         }
312
313         if (!secrets_store(SECRETS_AUTH_DOMAIN, c->opt_workgroup,
314                            strlen(c->opt_workgroup) + 1)) {
315                 d_fprintf(stderr, _("error storing auth user domain\n"));
316                 return 1;
317         }
318
319         if (!secrets_store(SECRETS_AUTH_PASSWORD, password,
320                            strlen(password) + 1)) {
321                 d_fprintf(stderr, _("error storing auth user password\n"));
322                 return 1;
323         }
324
325         return 0;
326 }
327
328 /**
329  * @brief Get the auth user settings
330  */
331 static int net_getauthuser(struct net_context *c, int argc, const char **argv)
332 {
333         char *user, *domain, *password;
334
335         /* Lift data from secrets file */
336
337         secrets_fetch_ipc_userpass(&user, &domain, &password);
338
339         if ((!user || !*user) && (!domain || !*domain ) &&
340             (!password || !*password)){
341
342                 SAFE_FREE(user);
343                 SAFE_FREE(domain);
344                 SAFE_FREE(password);
345                 d_printf(_("No authorised user configured\n"));
346                 return 0;
347         }
348
349         /* Pretty print authorised user info */
350
351         d_printf("%s%s%s%s%s\n", domain ? domain : "",
352                  domain ? lp_winbind_separator(): "", user,
353                  password ? "%" : "", password ? password : "");
354
355         SAFE_FREE(user);
356         SAFE_FREE(domain);
357         SAFE_FREE(password);
358
359         return 0;
360 }
361 /*
362  Retrieve our local SID or the SID for the specified name
363  */
364 static int net_getlocalsid(struct net_context *c, int argc, const char **argv)
365 {
366         struct dom_sid sid;
367         const char *name;
368         struct dom_sid_buf sid_str;
369
370         if (argc >= 1) {
371                 name = argv[0];
372         }
373         else {
374                 name = lp_netbios_name();
375         }
376
377         if(!initialize_password_db(false, NULL)) {
378                 d_fprintf(stderr, _("WARNING: Could not open passdb\n"));
379                 return 1;
380         }
381
382         /* first check to see if we can even access secrets, so we don't
383            panic when we can't. */
384
385         if (!secrets_init()) {
386                 d_fprintf(stderr,
387                           _("Unable to open secrets.tdb.  Can't fetch domain "
388                             "SID for name: %s\n"), name);
389                 return 1;
390         }
391
392         /* Generate one, if it doesn't exist */
393         get_global_sam_sid();
394
395         if (!secrets_fetch_domain_sid(name, &sid)) {
396                 DEBUG(0, ("Can't fetch domain SID for name: %s\n", name));
397                 return 1;
398         }
399         d_printf(_("SID for domain %s is: %s\n"),
400                  name,
401                  dom_sid_str_buf(&sid, &sid_str));
402         return 0;
403 }
404
405 static int net_setlocalsid(struct net_context *c, int argc, const char **argv)
406 {
407         struct dom_sid sid;
408
409         if ( (argc != 1)
410              || (strncmp(argv[0], "S-1-5-21-", strlen("S-1-5-21-")) != 0)
411              || (!string_to_sid(&sid, argv[0]))
412              || (sid.num_auths != 4)) {
413                 d_printf(_("Usage:"));
414                 d_printf(" net setlocalsid S-1-5-21-x-y-z\n");
415                 return 1;
416         }
417
418         if (!secrets_store_domain_sid(lp_netbios_name(), &sid)) {
419                 DEBUG(0,("Can't store domain SID as a pdc/bdc.\n"));
420                 return 1;
421         }
422
423         return 0;
424 }
425
426 static int net_setdomainsid(struct net_context *c, int argc, const char **argv)
427 {
428         struct dom_sid sid;
429
430         if ( (argc != 1)
431              || (strncmp(argv[0], "S-1-5-21-", strlen("S-1-5-21-")) != 0)
432              || (!string_to_sid(&sid, argv[0]))
433              || (sid.num_auths != 4)) {
434                 d_printf(_("Usage:"));
435                 d_printf(" net setdomainsid S-1-5-21-x-y-z\n");
436                 return 1;
437         }
438
439         if (!secrets_store_domain_sid(lp_workgroup(), &sid)) {
440                 DEBUG(0,("Can't store domain SID.\n"));
441                 return 1;
442         }
443
444         return 0;
445 }
446
447 static int net_getdomainsid(struct net_context *c, int argc, const char **argv)
448 {
449         struct dom_sid domain_sid;
450         struct dom_sid_buf sid_str;
451
452         if (argc > 0) {
453                 d_printf(_("Usage:"));
454                 d_printf(" net getdomainsid\n");
455                 return 1;
456         }
457
458         if(!initialize_password_db(false, NULL)) {
459                 d_fprintf(stderr, _("WARNING: Could not open passdb\n"));
460                 return 1;
461         }
462
463         /* first check to see if we can even access secrets, so we don't
464            panic when we can't. */
465
466         if (!secrets_init()) {
467                 d_fprintf(stderr, _("Unable to open secrets.tdb.  Can't fetch "
468                                     "domain SID for name: %s\n"),
469                           get_global_sam_name());
470                 return 1;
471         }
472
473         /* Generate one, if it doesn't exist */
474         get_global_sam_sid();
475
476         if (!IS_DC) {
477                 if (!secrets_fetch_domain_sid(lp_netbios_name(), &domain_sid)) {
478                         d_fprintf(stderr, _("Could not fetch local SID\n"));
479                         return 1;
480                 }
481                 d_printf(_("SID for local machine %s is: %s\n"),
482                          lp_netbios_name(),
483                          dom_sid_str_buf(&domain_sid, &sid_str));
484         }
485         if (!secrets_fetch_domain_sid(c->opt_workgroup, &domain_sid)) {
486                 d_fprintf(stderr, _("Could not fetch domain SID\n"));
487                 return 1;
488         }
489
490         d_printf(_("SID for domain %s is: %s\n"),
491                  c->opt_workgroup,
492                  dom_sid_str_buf(&domain_sid, &sid_str));
493
494         return 0;
495 }
496
497 static bool search_maxrid(struct pdb_search *search, const char *type,
498                           uint32_t *max_rid)
499 {
500         struct samr_displayentry *entries;
501         uint32_t i, num_entries;
502
503         if (search == NULL) {
504                 d_fprintf(stderr, _("get_maxrid: Could not search %s\n"), type);
505                 return false;
506         }
507
508         num_entries = pdb_search_entries(search, 0, 0xffffffff, &entries);
509         for (i=0; i<num_entries; i++)
510                 *max_rid = MAX(*max_rid, entries[i].rid);
511         TALLOC_FREE(search);
512         return true;
513 }
514
515 static uint32_t get_maxrid(void)
516 {
517         uint32_t max_rid = 0;
518
519         if (!search_maxrid(pdb_search_users(talloc_tos(), 0), "users", &max_rid))
520                 return 0;
521
522         if (!search_maxrid(pdb_search_groups(talloc_tos()), "groups", &max_rid))
523                 return 0;
524
525         if (!search_maxrid(pdb_search_aliases(talloc_tos(),
526                                               get_global_sam_sid()),
527                            "aliases", &max_rid))
528                 return 0;
529
530         return max_rid;
531 }
532
533 static int net_maxrid(struct net_context *c, int argc, const char **argv)
534 {
535         uint32_t rid;
536
537         if (argc != 0) {
538                 d_fprintf(stderr, "%s net maxrid\n", _("Usage:"));
539                 return 1;
540         }
541
542         if ((rid = get_maxrid()) == 0) {
543                 d_fprintf(stderr, _("can't get current maximum rid\n"));
544                 return 1;
545         }
546
547         d_printf(_("Currently used maximum rid: %d\n"), rid);
548
549         return 0;
550 }
551
552 /* main function table */
553 static struct functable net_func[] = {
554         {
555                 "rpc",
556                 net_rpc,
557                 NET_TRANSPORT_RPC,
558                 N_("Run functions using RPC transport"),
559                 N_("  Use 'net help rpc' to get more extensive information "
560                    "about 'net rpc' commands.")
561         },
562         {
563                 "rap",
564                 net_rap,
565                 NET_TRANSPORT_RAP,
566                 N_("Run functions using RAP transport"),
567                 N_("  Use 'net help rap' to get more extensive information "
568                    "about 'net rap' commands.")
569         },
570         {
571                 "ads",
572                 net_ads,
573                 NET_TRANSPORT_ADS,
574                 N_("Run functions using ADS transport"),
575                 N_("  Use 'net help ads' to get more extensive information "
576                    "about 'net ads' commands.")
577         },
578
579         /* eventually these should auto-choose the transport ... */
580         {
581                 "file",
582                 net_file,
583                 NET_TRANSPORT_RPC | NET_TRANSPORT_RAP,
584                 N_("Functions on remote opened files"),
585                 N_("  Use 'net help file' to get more information about 'net "
586                    "file' commands.")
587         },
588         {
589                 "share",
590                 net_share,
591                 NET_TRANSPORT_RPC | NET_TRANSPORT_RAP,
592                 N_("Functions on shares"),
593                 N_("  Use 'net help share' to get more information about 'net "
594                    "share' commands.")
595         },
596         {
597                 "session",
598                 net_rap_session,
599                 NET_TRANSPORT_RAP,
600                 N_("Manage sessions"),
601                 N_("  Use 'net help session' to get more information about "
602                    "'net session' commands.")
603         },
604         {
605                 "server",
606                 net_rap_server,
607                 NET_TRANSPORT_RAP,
608                 N_("List servers in workgroup"),
609                 N_("  Use 'net help server' to get more information about 'net "
610                    "server' commands.")
611         },
612         {
613                 "domain",
614                 net_rap_domain,
615                 NET_TRANSPORT_RAP,
616                 N_("List domains/workgroups on network"),
617                 N_("  Use 'net help domain' to get more information about 'net "
618                    "domain' commands.")
619         },
620         {
621                 "printq",
622                 net_rap_printq,
623                 NET_TRANSPORT_RAP,
624                 N_("Modify printer queue"),
625                 N_("  Use 'net help printq' to get more information about 'net "
626                    "printq' commands.")
627         },
628         {
629                 "user",
630                 net_user,
631                 NET_TRANSPORT_ADS | NET_TRANSPORT_RPC | NET_TRANSPORT_RAP,
632                 N_("Manage users"),
633                 N_("  Use 'net help user' to get more information about 'net "
634                    "user' commands.")
635         },
636         {
637                 "group",
638                 net_group,
639                 NET_TRANSPORT_ADS | NET_TRANSPORT_RPC | NET_TRANSPORT_RAP,
640                 N_("Manage groups"),
641                 N_("  Use 'net help group' to get more information about 'net "
642                    "group' commands.")
643         },
644         {
645                 "groupmap",
646                 net_groupmap,
647                 NET_TRANSPORT_LOCAL,
648                 N_("Manage group mappings"),
649                 N_("  Use 'net help groupmap' to get more information about "
650                    "'net groupmap' commands.")
651         },
652         {
653                 "sam",
654                 net_sam,
655                 NET_TRANSPORT_LOCAL,
656                 N_("Functions on the SAM database"),
657                 N_("  Use 'net help sam' to get more information about 'net "
658                    "sam' commands.")
659         },
660         {
661                 "validate",
662                 net_rap_validate,
663                 NET_TRANSPORT_RAP,
664                 N_("Validate username and password"),
665                 N_("  Use 'net help validate' to get more information about "
666                    "'net validate' commands.")
667         },
668         {
669                 "groupmember",
670                 net_rap_groupmember,
671                 NET_TRANSPORT_RAP,
672                 N_("Modify group memberships"),
673                 N_("  Use 'net help groupmember' to get more information about "
674                    "'net groupmember' commands.")
675         },
676         {       "admin",
677                 net_rap_admin,
678                 NET_TRANSPORT_RAP,
679                 N_("Execute remote command on a remote OS/2 server"),
680                 N_("  Use 'net help admin' to get more information about 'net "
681                    "admin' commands.")
682         },
683         {       "service",
684                 net_rap_service,
685                 NET_TRANSPORT_RAP,
686                 N_("List/modify running services"),
687                 N_("  Use 'net help service' to get more information about "
688                    "'net service' commands.")
689         },
690         {
691                 "password",
692                 net_rap_password,
693                 NET_TRANSPORT_RAP,
694                 N_("Change user password on target server"),
695                 N_("  Use 'net help password' to get more information about "
696                    "'net password' commands.")
697         },
698         {
699                 "primarytrust",
700                 net_primarytrust,
701                 NET_TRANSPORT_RPC,
702                 N_("Run functions related to the primary workstation trust."),
703                 N_("  Use 'net help primarytrust' to get more extensive information "
704                    "about 'net primarytrust' commands.")
705         },
706         {       "changetrustpw",
707                 net_changetrustpw,
708                 NET_TRANSPORT_ADS | NET_TRANSPORT_RPC,
709                 N_("Change the trust password"),
710                 N_("  Use 'net help changetrustpw' to get more information "
711                    "about 'net changetrustpw'.")
712         },
713         {       "changesecretpw",
714                 net_changesecretpw,
715                 NET_TRANSPORT_LOCAL,
716                 N_("Change the secret password"),
717                 N_("  net [options] changesecretpw\n"
718                    "    Change the ADS domain member machine account password "
719                    "in secrets.tdb.\n"
720                    "    Do NOT use this function unless you know what it does.\n"
721                    "    Requires the -f flag to work.")
722         },
723         {
724                 "setauthuser",
725                 net_setauthuser,
726                 NET_TRANSPORT_LOCAL,
727                 N_("Set the winbind auth user"),
728                 N_("  net -U user[%%password] [-W domain] setauthuser\n"
729                    "    Set the auth user, password (and optionally domain\n"
730                    "    Will prompt for password if not given.\n"
731                    "  net setauthuser delete\n"
732                    "    Delete the existing auth user settings.")
733         },
734         {
735                 "getauthuser",
736                 net_getauthuser,
737                 NET_TRANSPORT_LOCAL,
738                 N_("Get the winbind auth user settings"),
739                 N_("  net getauthuser\n"
740                    "    Get the current winbind auth user settings.")
741         },
742         {       "time",
743                 net_time,
744                 NET_TRANSPORT_LOCAL,
745                 N_("Show/set time"),
746                 N_("  Use 'net help time' to get more information about 'net "
747                    "time' commands.")
748         },
749         {       "lookup",
750                 net_lookup,
751                 NET_TRANSPORT_LOCAL,
752                 N_("Look up host names/IP addresses"),
753                 N_("  Use 'net help lookup' to get more information about 'net "
754                    "lookup' commands.")
755         },
756         {       "g_lock",
757                 net_g_lock,
758                 NET_TRANSPORT_LOCAL,
759                 N_("Manipulate the global lock table"),
760                 N_("  Use 'net help g_lock' to get more information about "
761                    "'net g_lock' commands.")
762         },
763         {       "join",
764                 net_join,
765                 NET_TRANSPORT_ADS | NET_TRANSPORT_RPC,
766                 N_("Join a domain/AD"),
767                 N_("  Use 'net help join' to get more information about 'net "
768                    "join'.")
769         },
770         {       "dom",
771                 net_dom,
772                 NET_TRANSPORT_LOCAL,
773                 N_("Join/unjoin (remote) machines to/from a domain/AD"),
774                 N_("  Use 'net help dom' to get more information about 'net "
775                    "dom' commands.")
776         },
777         {       "cache",
778                 net_cache,
779                 NET_TRANSPORT_LOCAL,
780                 N_("Operate on the cache tdb file"),
781                 N_("  Use 'net help cache' to get more information about 'net "
782                    "cache' commands.")
783         },
784         {       "getlocalsid",
785                 net_getlocalsid,
786                 NET_TRANSPORT_LOCAL,
787                 N_("Get the SID for the local domain"),
788                 N_("  net getlocalsid")
789         },
790         {       "setlocalsid",
791                 net_setlocalsid,
792                 NET_TRANSPORT_LOCAL,
793                 N_("Set the SID for the local domain"),
794                 N_("  net setlocalsid S-1-5-21-x-y-z")
795         },
796         {       "setdomainsid",
797                 net_setdomainsid,
798                 NET_TRANSPORT_LOCAL,
799                 N_("Set domain SID on member servers"),
800                 N_("  net setdomainsid S-1-5-21-x-y-z")
801         },
802         {       "getdomainsid",
803                 net_getdomainsid,
804                 NET_TRANSPORT_LOCAL,
805                 N_("Get domain SID on member servers"),
806                 N_("  net getdomainsid")
807         },
808         {       "maxrid",
809                 net_maxrid,
810                 NET_TRANSPORT_LOCAL,
811                 N_("Display the maximum RID currently used"),
812                 N_("  net maxrid")
813         },
814         {       "idmap",
815                 net_idmap,
816                 NET_TRANSPORT_LOCAL,
817                 N_("IDmap functions"),
818                 N_("  Use 'net help idmap to get more information about 'net "
819                   "idmap' commands.")
820         },
821         {       "status",
822                 net_status,
823                 NET_TRANSPORT_LOCAL,
824                 N_("Display server status"),
825                 N_("  Use 'net help status' to get more information about 'net "
826                    "status' commands.")
827         },
828         {       "usershare",
829                 net_usershare,
830                 NET_TRANSPORT_LOCAL,
831                 N_("Manage user-modifiable shares"),
832                 N_("  Use 'net help usershare to get more information about "
833                    "'net usershare' commands.")
834         },
835         {       "usersidlist",
836                 net_usersidlist,
837                 NET_TRANSPORT_RPC,
838                 N_("Display list of all users with SID"),
839                 N_("  Use 'net help usersidlist' to get more information about "
840                    "'net usersidlist'.")
841         },
842         {       "conf",
843                 net_conf,
844                 NET_TRANSPORT_LOCAL,
845                 N_("Manage Samba registry based configuration"),
846                 N_("  Use 'net help conf' to get more information about 'net "
847                    "conf' commands.")
848         },
849         {       "registry",
850                 net_registry,
851                 NET_TRANSPORT_LOCAL,
852                 N_("Manage the Samba registry"),
853                 N_("  Use 'net help registry' to get more information about "
854                    "'net registry' commands.")
855         },
856         {       "eventlog",
857                 net_eventlog,
858                 NET_TRANSPORT_LOCAL,
859                 N_("Process Win32 *.evt eventlog files"),
860                 N_("  Use 'net help eventlog' to get more information about "
861                    "'net eventlog' commands.")
862         },
863         {       "printing",
864                 net_printing,
865                 NET_TRANSPORT_LOCAL,
866                 N_("Process tdb printer files"),
867                 N_("  Use 'net help printing' to get more information about "
868                    "'net printing' commands.")
869         },
870
871         {       "serverid",
872                 net_serverid,
873                 NET_TRANSPORT_LOCAL,
874                 N_("Manage the serverid tdb"),
875                 N_("  Use 'net help serverid' to get more information about "
876                    "'net serverid' commands.")
877         },
878
879         {       "notify",
880                 net_notify,
881                 NET_TRANSPORT_LOCAL,
882                 N_("notifyd client code"),
883                 N_("  Use 'net help notify' to get more information about "
884                    "'net notify' commands.")
885         },
886
887         {       "tdb",
888                 net_tdb,
889                 NET_TRANSPORT_LOCAL,
890                 N_("Show information from tdb records"),
891                 N_("  Use 'net help tdb' to get more information about "
892                    "'net tdb' commands.")
893         },
894
895 #ifdef WITH_FAKE_KASERVER
896         {       "afs",
897                 net_afs,
898                 NET_TRANSPORT_LOCAL,
899                 N_("Manage AFS tokens"),
900                 N_("  Use 'net help afs' to get more information about 'net "
901                    "afs' commands.")
902         },
903 #endif
904
905         {       "help",
906                 net_help,
907                 NET_TRANSPORT_LOCAL,
908                 N_("Print usage information"),
909                 N_("  Use 'net help help' to list usage information for 'net' "
910                    "commands.")
911         },
912         {NULL, NULL, 0, NULL, NULL}
913 };
914
915
916 static void get_credentials_file(struct net_context *c,
917                                  const char *file)
918 {
919         struct cli_credentials *cred = cli_credentials_init(c);
920
921         if (cred == NULL) {
922                 d_printf("ERROR: Unable to allocate memory!\n");
923                 exit(-1);
924         }
925
926         if (!cli_credentials_parse_file(cred, file, CRED_GUESS_FILE)) {
927                 exit(-1);
928         }
929
930         c->opt_user_name = cli_credentials_get_username(cred);
931         c->opt_user_specified = (c->opt_user_name != NULL);
932         c->opt_password = cli_credentials_get_password(cred);
933         c->opt_target_workgroup = cli_credentials_get_domain(cred);
934 }
935
936 /****************************************************************************
937   main program
938 ****************************************************************************/
939  int main(int argc, char **argv)
940 {
941         int opt,i;
942         char *p;
943         int rc = 0;
944         int argc_new = 0;
945         const char ** argv_new;
946         const char **argv_const = discard_const_p(const char *, argv);
947         poptContext pc;
948         TALLOC_CTX *frame = talloc_stackframe();
949         struct net_context *c = talloc_zero(frame, struct net_context);
950
951         struct poptOption long_options[] = {
952                 {
953                         .longName   = "help",
954                         .shortName  = 'h',
955                         .argInfo    = POPT_ARG_NONE,
956                         .val        = 'h',
957                 },
958                 {
959                         .longName   = "workgroup",
960                         .shortName  = 'w',
961                         .argInfo    = POPT_ARG_STRING,
962                         .arg        = &c->opt_target_workgroup,
963                 },
964                 {
965                         .longName   = "user",
966                         .shortName  = 'U',
967                         .argInfo    = POPT_ARG_STRING,
968                         .arg        = &c->opt_user_name,
969                         .val        = 'U',
970                 },
971                 {
972                         .longName   = "authentication-file",
973                         .shortName  = 'A',
974                         .argInfo    = POPT_ARG_STRING,
975                         .arg        = &c->opt_user_name,
976                         .val        = 'A',
977                         .descrip    = "Get the credentials from a file",
978                         .argDescrip = "FILE",
979                 },
980                 {
981                         .longName   = "ipaddress",
982                         .shortName  = 'I',
983                         .argInfo    = POPT_ARG_STRING,
984                         .arg        = 0,
985                         .val        = 'I',
986                 },
987                 {
988                         .longName   = "port",
989                         .shortName  = 'p',
990                         .argInfo    = POPT_ARG_INT,
991                         .arg        = &c->opt_port,
992                 },
993                 {
994                         .longName   = "myname",
995                         .shortName  = 'n',
996                         .argInfo    = POPT_ARG_STRING,
997                         .arg        = &c->opt_requester_name,
998                 },
999                 {
1000                         .longName   = "server",
1001                         .shortName  = 'S',
1002                         .argInfo    = POPT_ARG_STRING,
1003                         .arg        = &c->opt_host,
1004                 },
1005                 {
1006                         .longName   = "encrypt",
1007                         .shortName  = 'e',
1008                         .argInfo    = POPT_ARG_NONE,
1009                         .arg        = NULL,
1010                         .val        = 'e',
1011                         .descrip    = N_("Encrypt SMB transport"),
1012                 },
1013                 {
1014                         .longName   = "container",
1015                         .shortName  = 'c',
1016                         .argInfo    = POPT_ARG_STRING,
1017                         .arg        = &c->opt_container,
1018                 },
1019                 {
1020                         .longName   = "comment",
1021                         .shortName  = 'C',
1022                         .argInfo    = POPT_ARG_STRING,
1023                         .arg        = &c->opt_comment,
1024                 },
1025                 {
1026                         .longName   = "maxusers",
1027                         .shortName  = 'M',
1028                         .argInfo    = POPT_ARG_INT,
1029                         .arg        = &c->opt_maxusers,
1030                 },
1031                 {
1032                         .longName   = "flags",
1033                         .shortName  = 'F',
1034                         .argInfo    = POPT_ARG_INT,
1035                         .arg        = &c->opt_flags,
1036                 },
1037                 {
1038                         .longName   = "long",
1039                         .shortName  = 'l',
1040                         .argInfo    = POPT_ARG_NONE,
1041                         .arg        = &c->opt_long_list_entries,
1042                 },
1043                 {
1044                         .longName   = "reboot",
1045                         .shortName  = 'r',
1046                         .argInfo    = POPT_ARG_NONE,
1047                         .arg        = &c->opt_reboot,
1048                 },
1049                 {
1050                         .longName   = "force",
1051                         .shortName  = 'f',
1052                         .argInfo    = POPT_ARG_NONE,
1053                         .arg        = &c->opt_force,
1054                 },
1055                 {
1056                         .longName   = "stdin",
1057                         .shortName  = 'i',
1058                         .argInfo    = POPT_ARG_NONE,
1059                         .arg        = &c->opt_stdin,
1060                 },
1061                 {
1062                         .longName   = "timeout",
1063                         .shortName  = 't',
1064                         .argInfo    = POPT_ARG_INT,
1065                         .arg        = &c->opt_timeout,
1066                 },
1067                 {
1068                         .longName   = "request-timeout",
1069                         .shortName  = 0,
1070                         .argInfo    = POPT_ARG_INT,
1071                         .arg        = &c->opt_request_timeout,
1072                 },
1073                 {
1074                         .longName   = "machine-pass",
1075                         .shortName  = 'P',
1076                         .argInfo    = POPT_ARG_NONE,
1077                         .arg        = &c->opt_machine_pass,
1078                 },
1079                 {
1080                         .longName   = "kerberos",
1081                         .shortName  = 'k',
1082                         .argInfo    = POPT_ARG_NONE,
1083                         .arg        = &c->opt_kerberos,
1084                 },
1085                 {
1086                         .longName   = "myworkgroup",
1087                         .shortName  = 'W',
1088                         .argInfo    = POPT_ARG_STRING,
1089                         .arg        = &c->opt_workgroup,
1090                 },
1091                 {
1092                         .longName   = "use-ccache",
1093                         .shortName  = 0,
1094                         .argInfo    = POPT_ARG_NONE,
1095                         .arg        = &c->opt_ccache,
1096                 },
1097                 {
1098                         .longName   = "verbose",
1099                         .shortName  = 'v',
1100                         .argInfo    = POPT_ARG_NONE,
1101                         .arg        = &c->opt_verbose,
1102                 },
1103                 {
1104                         .longName   = "test",
1105                         .shortName  = 'T',
1106                         .argInfo    = POPT_ARG_NONE,
1107                         .arg        = &c->opt_testmode,
1108                 },
1109                 /* Options for 'net groupmap set' */
1110                 {
1111                         .longName   = "local",
1112                         .shortName  = 'L',
1113                         .argInfo    = POPT_ARG_NONE,
1114                         .arg        = &c->opt_localgroup,
1115                 },
1116                 {
1117                         .longName   = "domain",
1118                         .shortName  = 'D',
1119                         .argInfo    = POPT_ARG_NONE,
1120                         .arg        = &c->opt_domaingroup,
1121                 },
1122                 {
1123                         .longName   = "ntname",
1124                         .shortName  = 'N',
1125                         .argInfo    = POPT_ARG_STRING,
1126                         .arg        = &c->opt_newntname,
1127                 },
1128                 {
1129                         .longName   = "rid",
1130                         .shortName  = 'R',
1131                         .argInfo    = POPT_ARG_INT,
1132                         .arg        = &c->opt_rid,
1133                 },
1134                 /* Options for 'net rpc share migrate' */
1135                 {
1136                         .longName   = "acls",
1137                         .shortName  = 0,
1138                         .argInfo    = POPT_ARG_NONE,
1139                         .arg        = &c->opt_acls,
1140                 },
1141                 {
1142                         .longName   = "attrs",
1143                         .shortName  = 0,
1144                         .argInfo    = POPT_ARG_NONE,
1145                         .arg        = &c->opt_attrs,
1146                 },
1147                 {
1148                         .longName   = "timestamps",
1149                         .shortName  = 0,
1150                         .argInfo    = POPT_ARG_NONE,
1151                         .arg        = &c->opt_timestamps,
1152                 },
1153                 {
1154                         .longName   = "exclude",
1155                         .shortName  = 'X',
1156                         .argInfo    = POPT_ARG_STRING,
1157                         .arg        = &c->opt_exclude,
1158                 },
1159                 {
1160                         .longName   = "destination",
1161                         .shortName  = 0,
1162                         .argInfo    = POPT_ARG_STRING,
1163                         .arg        = &c->opt_destination,
1164                 },
1165                 {
1166                         .longName   = "tallocreport",
1167                         .shortName  = 0,
1168                         .argInfo    = POPT_ARG_NONE,
1169                         .arg        = &c->do_talloc_report,
1170                 },
1171                 /* Options for 'net rpc vampire (keytab)' */
1172                 {
1173                         .longName   = "force-full-repl",
1174                         .shortName  = 0,
1175                         .argInfo    = POPT_ARG_NONE,
1176                         .arg        = &c->opt_force_full_repl,
1177                 },
1178                 {
1179                         .longName   = "single-obj-repl",
1180                         .shortName  = 0,
1181                         .argInfo    = POPT_ARG_NONE,
1182                         .arg        = &c->opt_single_obj_repl,
1183                 },
1184                 {
1185                         .longName   = "clean-old-entries",
1186                         .shortName  = 0,
1187                         .argInfo    = POPT_ARG_NONE,
1188                         .arg        = &c->opt_clean_old_entries,
1189                 },
1190                 /* Options for 'net idmap'*/
1191                 {
1192                         .longName   = "db",
1193                         .shortName  = 0,
1194                         .argInfo    = POPT_ARG_STRING,
1195                         .arg        = &c->opt_db,
1196                 },
1197                 {
1198                         .longName   = "lock",
1199                         .shortName  = 0,
1200                         .argInfo    = POPT_ARG_NONE,
1201                         .arg        =   &c->opt_lock,
1202                 },
1203                 {
1204                         .longName   = "auto",
1205                         .shortName  = 'a',
1206                         .argInfo    = POPT_ARG_NONE,
1207                         .arg        = &c->opt_auto,
1208                 },
1209                 {
1210                         .longName   = "repair",
1211                         .shortName  = 0,
1212                         .argInfo    = POPT_ARG_NONE,
1213                         .arg        =   &c->opt_repair,
1214                 },
1215                 /* Options for 'net registry check'*/
1216                 {
1217                         .longName   = "reg-version",
1218                         .shortName  = 0,
1219                         .argInfo    = POPT_ARG_INT,
1220                         .arg        = &c->opt_reg_version,
1221                 },
1222                 {
1223                         .longName   = "output",
1224                         .shortName  = 'o',
1225                         .argInfo    = POPT_ARG_STRING,
1226                         .arg        = &c->opt_output,
1227                 },
1228                 {
1229                         .longName   = "wipe",
1230                         .shortName  = 0,
1231                         .argInfo    = POPT_ARG_NONE,
1232                         .arg        = &c->opt_wipe,
1233                 },
1234                 /* Options for 'net registry import' */
1235                 {
1236                         .longName   = "precheck",
1237                         .shortName  = 0,
1238                         .argInfo    = POPT_ARG_STRING,
1239                         .arg        = &c->opt_precheck,
1240                 },
1241                 /* Options for 'net ads join or leave' */
1242                 {
1243                         .longName   = "no-dns-updates",
1244                         .shortName  = 0,
1245                         .argInfo    = POPT_ARG_NONE,
1246                         .arg        = &c->opt_no_dns_updates,
1247                 },
1248                 {
1249                         .longName   = "keep-account",
1250                         .shortName  = 0,
1251                         .argInfo    = POPT_ARG_NONE,
1252                         .arg        = &c->opt_keep_account,
1253                 },
1254                 {
1255                         .longName   = "json",
1256                         .shortName  = 0,
1257                         .argInfo    = POPT_ARG_NONE,
1258                         .arg        = &c->opt_json,
1259                 },
1260                 POPT_COMMON_SAMBA
1261                 POPT_TABLEEND
1262         };
1263
1264         zero_sockaddr(&c->opt_dest_ip);
1265
1266         setup_logging(argv[0], DEBUG_STDERR);
1267         fault_setup();
1268         smb_init_locale();
1269
1270         setlocale(LC_ALL, "");
1271 #if defined(HAVE_BINDTEXTDOMAIN)
1272         bindtextdomain(MODULE_NAME, get_dyn_LOCALEDIR());
1273 #endif
1274 #if defined(HAVE_TEXTDOMAIN)
1275         textdomain(MODULE_NAME);
1276 #endif
1277
1278         /* set default debug level to 0 regardless of what smb.conf sets */
1279         lp_set_cmdline("log level", "0");
1280         c->private_data = net_func;
1281
1282         pc = poptGetContext(NULL, argc, argv_const, long_options,
1283                             POPT_CONTEXT_KEEP_FIRST);
1284
1285         while((opt = poptGetNextOpt(pc)) != -1) {
1286                 switch (opt) {
1287                 case 'h':
1288                         c->display_usage = true;
1289                         break;
1290                 case 'e':
1291                         c->smb_encrypt = true;
1292                         break;
1293                 case 'I':
1294                         if (!interpret_string_addr(&c->opt_dest_ip,
1295                                                 poptGetOptArg(pc), 0)) {
1296                                 d_fprintf(stderr, _("\nInvalid ip address specified\n"));
1297                         } else {
1298                                 c->opt_have_ip = true;
1299                         }
1300                         break;
1301                 case 'U':
1302                         c->opt_user_specified = true;
1303                         c->opt_user_name = talloc_strdup(c, c->opt_user_name);
1304                         p = strchr(c->opt_user_name,'%');
1305                         if (p) {
1306                                 *p = 0;
1307                                 c->opt_password = p+1;
1308                         }
1309                         break;
1310                 case 'A':
1311                         get_credentials_file(c, c->opt_user_name);
1312                         break;
1313                 default:
1314                         d_fprintf(stderr, _("\nInvalid option %s: %s\n"),
1315                                  poptBadOption(pc, 0), poptStrerror(opt));
1316                         net_help(c, argc, argv_const);
1317                         exit(1);
1318                 }
1319         }
1320
1321         c->msg_ctx = cmdline_messaging_context(get_dyn_CONFIGFILE());
1322
1323         if (!lp_load_global(get_dyn_CONFIGFILE())) {
1324                 d_fprintf(stderr, "Can't load %s - run testparm to debug it\n",
1325                           get_dyn_CONFIGFILE());
1326                 exit(1);
1327         }
1328
1329 #if defined(HAVE_BIND_TEXTDOMAIN_CODESET)
1330         /* Bind our gettext results to 'unix charset'
1331            
1332            This ensures that the translations and any embedded strings are in the
1333            same charset.  It won't be the one from the user's locale (we no
1334            longer auto-detect that), but it will be self-consistent.
1335         */
1336         bind_textdomain_codeset(MODULE_NAME, lp_unix_charset());
1337 #endif
1338
1339         argv_new = (const char **)poptGetArgs(pc);
1340
1341         argc_new = argc;
1342         for (i=0; i<argc; i++) {
1343                 if (argv_new[i] == NULL) {
1344                         argc_new = i;
1345                         break;
1346                 }
1347         }
1348
1349         if (c->do_talloc_report) {
1350                 talloc_enable_leak_report();
1351         }
1352
1353         if (c->opt_requester_name) {
1354                 lp_set_cmdline("netbios name", c->opt_requester_name);
1355         }
1356
1357         if (!c->opt_user_name && getenv("LOGNAME")) {
1358                 c->opt_user_name = getenv("LOGNAME");
1359         }
1360
1361         if (!c->opt_workgroup) {
1362                 c->opt_workgroup = talloc_strdup(c, lp_workgroup());
1363         }
1364
1365         if (!c->opt_target_workgroup) {
1366                 c->opt_target_workgroup = talloc_strdup(c, lp_workgroup());
1367         }
1368
1369         if (!init_names())
1370                 exit(1);
1371
1372         load_interfaces();
1373
1374         /* this makes sure that when we do things like call scripts,
1375            that it won't assert because we are not root */
1376         sec_init();
1377
1378         if (c->opt_machine_pass) {
1379                 /* it is very useful to be able to make ads queries as the
1380                    machine account for testing purposes and for domain leave */
1381
1382                 net_use_krb_machine_account(c);
1383         }
1384
1385         if (!c->opt_password) {
1386                 c->opt_password = getenv("PASSWD");
1387         }
1388
1389         popt_burn_cmdline_password(argc, argv);
1390
1391         rc = net_run_function(c, argc_new-1, argv_new+1, "net", net_func);
1392
1393         DEBUG(2,("return code = %d\n", rc));
1394
1395         libnetapi_free(c->netapi_ctx);
1396
1397         poptFreeContext(pc);
1398
1399         TALLOC_FREE(frame);
1400         return rc;
1401 }