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