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