net_usershare: Use dom_sid_str_buf
[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         fstring 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         sid_to_fstring(sid_str, &sid);
394         d_printf(_("SID for domain %s is: %s\n"), name, sid_str);
395         return 0;
396 }
397
398 static int net_setlocalsid(struct net_context *c, int argc, const char **argv)
399 {
400         struct dom_sid sid;
401
402         if ( (argc != 1)
403              || (strncmp(argv[0], "S-1-5-21-", strlen("S-1-5-21-")) != 0)
404              || (!string_to_sid(&sid, argv[0]))
405              || (sid.num_auths != 4)) {
406                 d_printf(_("Usage:"));
407                 d_printf(" net setlocalsid S-1-5-21-x-y-z\n");
408                 return 1;
409         }
410
411         if (!secrets_store_domain_sid(lp_netbios_name(), &sid)) {
412                 DEBUG(0,("Can't store domain SID as a pdc/bdc.\n"));
413                 return 1;
414         }
415
416         return 0;
417 }
418
419 static int net_setdomainsid(struct net_context *c, int argc, const char **argv)
420 {
421         struct dom_sid sid;
422
423         if ( (argc != 1)
424              || (strncmp(argv[0], "S-1-5-21-", strlen("S-1-5-21-")) != 0)
425              || (!string_to_sid(&sid, argv[0]))
426              || (sid.num_auths != 4)) {
427                 d_printf(_("Usage:"));
428                 d_printf(" net setdomainsid S-1-5-21-x-y-z\n");
429                 return 1;
430         }
431
432         if (!secrets_store_domain_sid(lp_workgroup(), &sid)) {
433                 DEBUG(0,("Can't store domain SID.\n"));
434                 return 1;
435         }
436
437         return 0;
438 }
439
440 static int net_getdomainsid(struct net_context *c, int argc, const char **argv)
441 {
442         struct dom_sid domain_sid;
443         fstring sid_str;
444
445         if (argc > 0) {
446                 d_printf(_("Usage:"));
447                 d_printf(" net getdomainsid\n");
448                 return 1;
449         }
450
451         if(!initialize_password_db(false, NULL)) {
452                 d_fprintf(stderr, _("WARNING: Could not open passdb\n"));
453                 return 1;
454         }
455
456         /* first check to see if we can even access secrets, so we don't
457            panic when we can't. */
458
459         if (!secrets_init()) {
460                 d_fprintf(stderr, _("Unable to open secrets.tdb.  Can't fetch "
461                                     "domain SID for name: %s\n"),
462                           get_global_sam_name());
463                 return 1;
464         }
465
466         /* Generate one, if it doesn't exist */
467         get_global_sam_sid();
468
469         if (!IS_DC) {
470                 if (!secrets_fetch_domain_sid(lp_netbios_name(), &domain_sid)) {
471                         d_fprintf(stderr, _("Could not fetch local SID\n"));
472                         return 1;
473                 }
474                 sid_to_fstring(sid_str, &domain_sid);
475                 d_printf(_("SID for local machine %s is: %s\n"),
476                          lp_netbios_name(), sid_str);
477         }
478         if (!secrets_fetch_domain_sid(c->opt_workgroup, &domain_sid)) {
479                 d_fprintf(stderr, _("Could not fetch domain SID\n"));
480                 return 1;
481         }
482
483         sid_to_fstring(sid_str, &domain_sid);
484         d_printf(_("SID for domain %s is: %s\n"), c->opt_workgroup, sid_str);
485
486         return 0;
487 }
488
489 static bool search_maxrid(struct pdb_search *search, const char *type,
490                           uint32_t *max_rid)
491 {
492         struct samr_displayentry *entries;
493         uint32_t i, num_entries;
494
495         if (search == NULL) {
496                 d_fprintf(stderr, _("get_maxrid: Could not search %s\n"), type);
497                 return false;
498         }
499
500         num_entries = pdb_search_entries(search, 0, 0xffffffff, &entries);
501         for (i=0; i<num_entries; i++)
502                 *max_rid = MAX(*max_rid, entries[i].rid);
503         TALLOC_FREE(search);
504         return true;
505 }
506
507 static uint32_t get_maxrid(void)
508 {
509         uint32_t max_rid = 0;
510
511         if (!search_maxrid(pdb_search_users(talloc_tos(), 0), "users", &max_rid))
512                 return 0;
513
514         if (!search_maxrid(pdb_search_groups(talloc_tos()), "groups", &max_rid))
515                 return 0;
516
517         if (!search_maxrid(pdb_search_aliases(talloc_tos(),
518                                               get_global_sam_sid()),
519                            "aliases", &max_rid))
520                 return 0;
521
522         return max_rid;
523 }
524
525 static int net_maxrid(struct net_context *c, int argc, const char **argv)
526 {
527         uint32_t rid;
528
529         if (argc != 0) {
530                 d_fprintf(stderr, "%s net maxrid\n", _("Usage:"));
531                 return 1;
532         }
533
534         if ((rid = get_maxrid()) == 0) {
535                 d_fprintf(stderr, _("can't get current maximum rid\n"));
536                 return 1;
537         }
538
539         d_printf(_("Currently used maximum rid: %d\n"), rid);
540
541         return 0;
542 }
543
544 /* main function table */
545 static struct functable net_func[] = {
546         {
547                 "rpc",
548                 net_rpc,
549                 NET_TRANSPORT_RPC,
550                 N_("Run functions using RPC transport"),
551                 N_("  Use 'net help rpc' to get more extensive information "
552                    "about 'net rpc' commands.")
553         },
554         {
555                 "rap",
556                 net_rap,
557                 NET_TRANSPORT_RAP,
558                 N_("Run functions using RAP transport"),
559                 N_("  Use 'net help rap' to get more extensive information "
560                    "about 'net rap' commands.")
561         },
562         {
563                 "ads",
564                 net_ads,
565                 NET_TRANSPORT_ADS,
566                 N_("Run functions using ADS transport"),
567                 N_("  Use 'net help ads' to get more extensive information "
568                    "about 'net ads' commands.")
569         },
570
571         /* eventually these should auto-choose the transport ... */
572         {
573                 "file",
574                 net_file,
575                 NET_TRANSPORT_RPC | NET_TRANSPORT_RAP,
576                 N_("Functions on remote opened files"),
577                 N_("  Use 'net help file' to get more information about 'net "
578                    "file' commands.")
579         },
580         {
581                 "share",
582                 net_share,
583                 NET_TRANSPORT_RPC | NET_TRANSPORT_RAP,
584                 N_("Functions on shares"),
585                 N_("  Use 'net help share' to get more information about 'net "
586                    "share' commands.")
587         },
588         {
589                 "session",
590                 net_rap_session,
591                 NET_TRANSPORT_RAP,
592                 N_("Manage sessions"),
593                 N_("  Use 'net help session' to get more information about "
594                    "'net session' commands.")
595         },
596         {
597                 "server",
598                 net_rap_server,
599                 NET_TRANSPORT_RAP,
600                 N_("List servers in workgroup"),
601                 N_("  Use 'net help server' to get more information about 'net "
602                    "server' commands.")
603         },
604         {
605                 "domain",
606                 net_rap_domain,
607                 NET_TRANSPORT_RAP,
608                 N_("List domains/workgroups on network"),
609                 N_("  Use 'net help domain' to get more information about 'net "
610                    "domain' commands.")
611         },
612         {
613                 "printq",
614                 net_rap_printq,
615                 NET_TRANSPORT_RAP,
616                 N_("Modify printer queue"),
617                 N_("  Use 'net help printq' to get more information about 'net "
618                    "printq' commands.")
619         },
620         {
621                 "user",
622                 net_user,
623                 NET_TRANSPORT_ADS | NET_TRANSPORT_RPC | NET_TRANSPORT_RAP,
624                 N_("Manage users"),
625                 N_("  Use 'net help user' to get more information about 'net "
626                    "user' commands.")
627         },
628         {
629                 "group",
630                 net_group,
631                 NET_TRANSPORT_ADS | NET_TRANSPORT_RPC | NET_TRANSPORT_RAP,
632                 N_("Manage groups"),
633                 N_("  Use 'net help group' to get more information about 'net "
634                    "group' commands.")
635         },
636         {
637                 "groupmap",
638                 net_groupmap,
639                 NET_TRANSPORT_LOCAL,
640                 N_("Manage group mappings"),
641                 N_("  Use 'net help groupmap' to get more information about "
642                    "'net groupmap' commands.")
643         },
644         {
645                 "sam",
646                 net_sam,
647                 NET_TRANSPORT_LOCAL,
648                 N_("Functions on the SAM database"),
649                 N_("  Use 'net help sam' to get more information about 'net "
650                    "sam' commands.")
651         },
652         {
653                 "validate",
654                 net_rap_validate,
655                 NET_TRANSPORT_RAP,
656                 N_("Validate username and password"),
657                 N_("  Use 'net help validate' to get more information about "
658                    "'net validate' commands.")
659         },
660         {
661                 "groupmember",
662                 net_rap_groupmember,
663                 NET_TRANSPORT_RAP,
664                 N_("Modify group memberships"),
665                 N_("  Use 'net help groupmember' to get more information about "
666                    "'net groupmember' commands.")
667         },
668         {       "admin",
669                 net_rap_admin,
670                 NET_TRANSPORT_RAP,
671                 N_("Execute remote command on a remote OS/2 server"),
672                 N_("  Use 'net help admin' to get more information about 'net "
673                    "admin' commands.")
674         },
675         {       "service",
676                 net_rap_service,
677                 NET_TRANSPORT_RAP,
678                 N_("List/modify running services"),
679                 N_("  Use 'net help service' to get more information about "
680                    "'net service' commands.")
681         },
682         {
683                 "password",
684                 net_rap_password,
685                 NET_TRANSPORT_RAP,
686                 N_("Change user password on target server"),
687                 N_("  Use 'net help password' to get more information about "
688                    "'net password' commands.")
689         },
690         {
691                 "primarytrust",
692                 net_primarytrust,
693                 NET_TRANSPORT_RPC,
694                 N_("Run functions related to the primary workstation trust."),
695                 N_("  Use 'net help primarytrust' to get more extensive information "
696                    "about 'net primarytrust' commands.")
697         },
698         {       "changetrustpw",
699                 net_changetrustpw,
700                 NET_TRANSPORT_ADS | NET_TRANSPORT_RPC,
701                 N_("Change the trust password"),
702                 N_("  Use 'net help changetrustpw' to get more information "
703                    "about 'net changetrustpw'.")
704         },
705         {       "changesecretpw",
706                 net_changesecretpw,
707                 NET_TRANSPORT_LOCAL,
708                 N_("Change the secret password"),
709                 N_("  net [options] changesecretpw\n"
710                    "    Change the ADS domain member machine account password "
711                    "in secrets.tdb.\n"
712                    "    Do NOT use this function unless you know what it does.\n"
713                    "    Requires the -f flag to work.")
714         },
715         {
716                 "setauthuser",
717                 net_setauthuser,
718                 NET_TRANSPORT_LOCAL,
719                 N_("Set the winbind auth user"),
720                 N_("  net -U user[%%password] [-W domain] setauthuser\n"
721                    "    Set the auth user, password (and optionally domain\n"
722                    "    Will prompt for password if not given.\n"
723                    "  net setauthuser delete\n"
724                    "    Delete the existing auth user settings.")
725         },
726         {
727                 "getauthuser",
728                 net_getauthuser,
729                 NET_TRANSPORT_LOCAL,
730                 N_("Get the winbind auth user settings"),
731                 N_("  net getauthuser\n"
732                    "    Get the current winbind auth user settings.")
733         },
734         {       "time",
735                 net_time,
736                 NET_TRANSPORT_LOCAL,
737                 N_("Show/set time"),
738                 N_("  Use 'net help time' to get more information about 'net "
739                    "time' commands.")
740         },
741         {       "lookup",
742                 net_lookup,
743                 NET_TRANSPORT_LOCAL,
744                 N_("Look up host names/IP addresses"),
745                 N_("  Use 'net help lookup' to get more information about 'net "
746                    "lookup' commands.")
747         },
748         {       "g_lock",
749                 net_g_lock,
750                 NET_TRANSPORT_LOCAL,
751                 N_("Manipulate the global lock table"),
752                 N_("  Use 'net help g_lock' to get more information about "
753                    "'net g_lock' commands.")
754         },
755         {       "join",
756                 net_join,
757                 NET_TRANSPORT_ADS | NET_TRANSPORT_RPC,
758                 N_("Join a domain/AD"),
759                 N_("  Use 'net help join' to get more information about 'net "
760                    "join'.")
761         },
762         {       "dom",
763                 net_dom,
764                 NET_TRANSPORT_LOCAL,
765                 N_("Join/unjoin (remote) machines to/from a domain/AD"),
766                 N_("  Use 'net help dom' to get more information about 'net "
767                    "dom' commands.")
768         },
769         {       "cache",
770                 net_cache,
771                 NET_TRANSPORT_LOCAL,
772                 N_("Operate on the cache tdb file"),
773                 N_("  Use 'net help cache' to get more information about 'net "
774                    "cache' commands.")
775         },
776         {       "getlocalsid",
777                 net_getlocalsid,
778                 NET_TRANSPORT_LOCAL,
779                 N_("Get the SID for the local domain"),
780                 N_("  net getlocalsid")
781         },
782         {       "setlocalsid",
783                 net_setlocalsid,
784                 NET_TRANSPORT_LOCAL,
785                 N_("Set the SID for the local domain"),
786                 N_("  net setlocalsid S-1-5-21-x-y-z")
787         },
788         {       "setdomainsid",
789                 net_setdomainsid,
790                 NET_TRANSPORT_LOCAL,
791                 N_("Set domain SID on member servers"),
792                 N_("  net setdomainsid S-1-5-21-x-y-z")
793         },
794         {       "getdomainsid",
795                 net_getdomainsid,
796                 NET_TRANSPORT_LOCAL,
797                 N_("Get domain SID on member servers"),
798                 N_("  net getdomainsid")
799         },
800         {       "maxrid",
801                 net_maxrid,
802                 NET_TRANSPORT_LOCAL,
803                 N_("Display the maximum RID currently used"),
804                 N_("  net maxrid")
805         },
806         {       "idmap",
807                 net_idmap,
808                 NET_TRANSPORT_LOCAL,
809                 N_("IDmap functions"),
810                 N_("  Use 'net help idmap to get more information about 'net "
811                   "idmap' commands.")
812         },
813         {       "status",
814                 net_status,
815                 NET_TRANSPORT_LOCAL,
816                 N_("Display server status"),
817                 N_("  Use 'net help status' to get more information about 'net "
818                    "status' commands.")
819         },
820         {       "usershare",
821                 net_usershare,
822                 NET_TRANSPORT_LOCAL,
823                 N_("Manage user-modifiable shares"),
824                 N_("  Use 'net help usershare to get more information about "
825                    "'net usershare' commands.")
826         },
827         {       "usersidlist",
828                 net_usersidlist,
829                 NET_TRANSPORT_RPC,
830                 N_("Display list of all users with SID"),
831                 N_("  Use 'net help usersidlist' to get more information about "
832                    "'net usersidlist'.")
833         },
834         {       "conf",
835                 net_conf,
836                 NET_TRANSPORT_LOCAL,
837                 N_("Manage Samba registry based configuration"),
838                 N_("  Use 'net help conf' to get more information about 'net "
839                    "conf' commands.")
840         },
841         {       "registry",
842                 net_registry,
843                 NET_TRANSPORT_LOCAL,
844                 N_("Manage the Samba registry"),
845                 N_("  Use 'net help registry' to get more information about "
846                    "'net registry' commands.")
847         },
848         {       "eventlog",
849                 net_eventlog,
850                 NET_TRANSPORT_LOCAL,
851                 N_("Process Win32 *.evt eventlog files"),
852                 N_("  Use 'net help eventlog' to get more information about "
853                    "'net eventlog' commands.")
854         },
855         {       "printing",
856                 net_printing,
857                 NET_TRANSPORT_LOCAL,
858                 N_("Process tdb printer files"),
859                 N_("  Use 'net help printing' to get more information about "
860                    "'net printing' commands.")
861         },
862
863         {       "serverid",
864                 net_serverid,
865                 NET_TRANSPORT_LOCAL,
866                 N_("Manage the serverid tdb"),
867                 N_("  Use 'net help serverid' to get more information about "
868                    "'net serverid' commands.")
869         },
870
871         {       "notify",
872                 net_notify,
873                 NET_TRANSPORT_LOCAL,
874                 N_("notifyd client code"),
875                 N_("  Use 'net help notify' to get more information about "
876                    "'net notify' commands.")
877         },
878
879         {       "tdb",
880                 net_tdb,
881                 NET_TRANSPORT_LOCAL,
882                 N_("Show information from tdb records"),
883                 N_("  Use 'net help tdb' to get more information about "
884                    "'net tdb' commands.")
885         },
886
887 #ifdef WITH_FAKE_KASERVER
888         {       "afs",
889                 net_afs,
890                 NET_TRANSPORT_LOCAL,
891                 N_("Manage AFS tokens"),
892                 N_("  Use 'net help afs' to get more information about 'net "
893                    "afs' commands.")
894         },
895 #endif
896
897         {       "help",
898                 net_help,
899                 NET_TRANSPORT_LOCAL,
900                 N_("Print usage information"),
901                 N_("  Use 'net help help' to list usage information for 'net' "
902                    "commands.")
903         },
904         {NULL, NULL, 0, NULL, NULL}
905 };
906
907
908 static void get_credentials_file(struct net_context *c,
909                                  const char *file)
910 {
911         struct cli_credentials *cred = cli_credentials_init(c);
912
913         if (cred == NULL) {
914                 d_printf("ERROR: Unable to allocate memory!\n");
915                 exit(-1);
916         }
917
918         if (!cli_credentials_parse_file(cred, file, CRED_GUESS_FILE)) {
919                 exit(-1);
920         }
921
922         c->opt_user_name = cli_credentials_get_username(cred);
923         c->opt_user_specified = (c->opt_user_name != NULL);
924         c->opt_password = cli_credentials_get_password(cred);
925         c->opt_target_workgroup = cli_credentials_get_domain(cred);
926 }
927
928 /****************************************************************************
929   main program
930 ****************************************************************************/
931  int main(int argc, char **argv)
932 {
933         int opt,i;
934         char *p;
935         int rc = 0;
936         int argc_new = 0;
937         const char ** argv_new;
938         const char **argv_const = discard_const_p(const char *, argv);
939         poptContext pc;
940         TALLOC_CTX *frame = talloc_stackframe();
941         struct net_context *c = talloc_zero(frame, struct net_context);
942
943         struct poptOption long_options[] = {
944                 {"help",        'h', POPT_ARG_NONE,   0, 'h'},
945                 {"workgroup",   'w', POPT_ARG_STRING, &c->opt_target_workgroup},
946                 {"user",        'U', POPT_ARG_STRING, &c->opt_user_name, 'U'},
947                 {"authentication-file", 'A', POPT_ARG_STRING, &c->opt_user_name, 'A', "Get the credentials from a file", "FILE"},
948                 {"ipaddress",   'I', POPT_ARG_STRING, 0,'I'},
949                 {"port",        'p', POPT_ARG_INT,    &c->opt_port},
950                 {"myname",      'n', POPT_ARG_STRING, &c->opt_requester_name},
951                 {"server",      'S', POPT_ARG_STRING, &c->opt_host},
952                 {"encrypt",     'e', POPT_ARG_NONE,   NULL, 'e', N_("Encrypt SMB transport") },
953                 {"container",   'c', POPT_ARG_STRING, &c->opt_container},
954                 {"comment",     'C', POPT_ARG_STRING, &c->opt_comment},
955                 {"maxusers",    'M', POPT_ARG_INT,    &c->opt_maxusers},
956                 {"flags",       'F', POPT_ARG_INT,    &c->opt_flags},
957                 {"long",        'l', POPT_ARG_NONE,   &c->opt_long_list_entries},
958                 {"reboot",      'r', POPT_ARG_NONE,   &c->opt_reboot},
959                 {"force",       'f', POPT_ARG_NONE,   &c->opt_force},
960                 {"stdin",       'i', POPT_ARG_NONE,   &c->opt_stdin},
961                 {"timeout",     't', POPT_ARG_INT,    &c->opt_timeout},
962                 {"request-timeout",0,POPT_ARG_INT,    &c->opt_request_timeout},
963                 {"machine-pass",'P', POPT_ARG_NONE,   &c->opt_machine_pass},
964                 {"kerberos",    'k', POPT_ARG_NONE,   &c->opt_kerberos},
965                 {"myworkgroup", 'W', POPT_ARG_STRING, &c->opt_workgroup},
966                 {"use-ccache",    0, POPT_ARG_NONE,   &c->opt_ccache},
967                 {"verbose",     'v', POPT_ARG_NONE,   &c->opt_verbose},
968                 {"test",        'T', POPT_ARG_NONE,   &c->opt_testmode},
969                 /* Options for 'net groupmap set' */
970                 {"local",       'L', POPT_ARG_NONE,   &c->opt_localgroup},
971                 {"domain",      'D', POPT_ARG_NONE,   &c->opt_domaingroup},
972                 {"ntname",      'N', POPT_ARG_STRING, &c->opt_newntname},
973                 {"rid",         'R', POPT_ARG_INT,    &c->opt_rid},
974                 /* Options for 'net rpc share migrate' */
975                 {"acls",        0, POPT_ARG_NONE,     &c->opt_acls},
976                 {"attrs",       0, POPT_ARG_NONE,     &c->opt_attrs},
977                 {"timestamps",  0, POPT_ARG_NONE,     &c->opt_timestamps},
978                 {"exclude",     'X', POPT_ARG_STRING, &c->opt_exclude},
979                 {"destination", 0, POPT_ARG_STRING,   &c->opt_destination},
980                 {"tallocreport", 0, POPT_ARG_NONE,    &c->do_talloc_report},
981                 /* Options for 'net rpc vampire (keytab)' */
982                 {"force-full-repl", 0, POPT_ARG_NONE, &c->opt_force_full_repl},
983                 {"single-obj-repl", 0, POPT_ARG_NONE, &c->opt_single_obj_repl},
984                 {"clean-old-entries", 0, POPT_ARG_NONE, &c->opt_clean_old_entries},
985                 /* Options for 'net idmap'*/
986                 {"db", 0, POPT_ARG_STRING, &c->opt_db},
987                 {"lock", 0, POPT_ARG_NONE,   &c->opt_lock},
988                 {"auto", 'a', POPT_ARG_NONE,   &c->opt_auto},
989                 {"repair", 0, POPT_ARG_NONE,   &c->opt_repair},
990                 /* Options for 'net registry check'*/
991                 {"reg-version", 0, POPT_ARG_INT, &c->opt_reg_version},
992                 {"output", 'o', POPT_ARG_STRING, &c->opt_output},
993                 {"wipe", 0, POPT_ARG_NONE, &c->opt_wipe},
994                 /* Options for 'net registry import' */
995                 {"precheck", 0, POPT_ARG_STRING, &c->opt_precheck},
996                 /* Options for 'net ads join or leave' */
997                 {"no-dns-updates", 0, POPT_ARG_NONE, &c->opt_no_dns_updates},
998                 {"keep-account", 0, POPT_ARG_NONE, &c->opt_keep_account},
999                 {"json", 0, POPT_ARG_NONE, &c->opt_json},
1000                 POPT_COMMON_SAMBA
1001                 { 0, 0, 0, 0}
1002         };
1003
1004         zero_sockaddr(&c->opt_dest_ip);
1005
1006         setup_logging(argv[0], DEBUG_STDERR);
1007
1008         smb_init_locale();
1009
1010         setlocale(LC_ALL, "");
1011 #if defined(HAVE_BINDTEXTDOMAIN)
1012         bindtextdomain(MODULE_NAME, get_dyn_LOCALEDIR());
1013 #endif
1014 #if defined(HAVE_TEXTDOMAIN)
1015         textdomain(MODULE_NAME);
1016 #endif
1017
1018         /* set default debug level to 0 regardless of what smb.conf sets */
1019         lp_set_cmdline("log level", "0");
1020         c->private_data = net_func;
1021
1022         pc = poptGetContext(NULL, argc, argv_const, long_options,
1023                             POPT_CONTEXT_KEEP_FIRST);
1024
1025         while((opt = poptGetNextOpt(pc)) != -1) {
1026                 switch (opt) {
1027                 case 'h':
1028                         c->display_usage = true;
1029                         break;
1030                 case 'e':
1031                         c->smb_encrypt = true;
1032                         break;
1033                 case 'I':
1034                         if (!interpret_string_addr(&c->opt_dest_ip,
1035                                                 poptGetOptArg(pc), 0)) {
1036                                 d_fprintf(stderr, _("\nInvalid ip address specified\n"));
1037                         } else {
1038                                 c->opt_have_ip = true;
1039                         }
1040                         break;
1041                 case 'U':
1042                         c->opt_user_specified = true;
1043                         c->opt_user_name = talloc_strdup(c, c->opt_user_name);
1044                         p = strchr(c->opt_user_name,'%');
1045                         if (p) {
1046                                 *p = 0;
1047                                 c->opt_password = p+1;
1048                         }
1049                         break;
1050                 case 'A':
1051                         get_credentials_file(c, c->opt_user_name);
1052                         break;
1053                 default:
1054                         d_fprintf(stderr, _("\nInvalid option %s: %s\n"),
1055                                  poptBadOption(pc, 0), poptStrerror(opt));
1056                         net_help(c, argc, argv_const);
1057                         exit(1);
1058                 }
1059         }
1060
1061         c->msg_ctx = cmdline_messaging_context(get_dyn_CONFIGFILE());
1062
1063         if (!lp_load_global(get_dyn_CONFIGFILE())) {
1064                 d_fprintf(stderr, "Can't load %s - run testparm to debug it\n",
1065                           get_dyn_CONFIGFILE());
1066                 exit(1);
1067         }
1068
1069 #if defined(HAVE_BIND_TEXTDOMAIN_CODESET)
1070         /* Bind our gettext results to 'unix charset'
1071            
1072            This ensures that the translations and any embedded strings are in the
1073            same charset.  It won't be the one from the user's locale (we no
1074            longer auto-detect that), but it will be self-consistent.
1075         */
1076         bind_textdomain_codeset(MODULE_NAME, lp_unix_charset());
1077 #endif
1078
1079         argv_new = (const char **)poptGetArgs(pc);
1080
1081         argc_new = argc;
1082         for (i=0; i<argc; i++) {
1083                 if (argv_new[i] == NULL) {
1084                         argc_new = i;
1085                         break;
1086                 }
1087         }
1088
1089         if (c->do_talloc_report) {
1090                 talloc_enable_leak_report();
1091         }
1092
1093         if (c->opt_requester_name) {
1094                 lp_set_cmdline("netbios name", c->opt_requester_name);
1095         }
1096
1097         if (!c->opt_user_name && getenv("LOGNAME")) {
1098                 c->opt_user_name = getenv("LOGNAME");
1099         }
1100
1101         if (!c->opt_workgroup) {
1102                 c->opt_workgroup = talloc_strdup(c, lp_workgroup());
1103         }
1104
1105         if (!c->opt_target_workgroup) {
1106                 c->opt_target_workgroup = talloc_strdup(c, lp_workgroup());
1107         }
1108
1109         if (!init_names())
1110                 exit(1);
1111
1112         load_interfaces();
1113
1114         /* this makes sure that when we do things like call scripts,
1115            that it won't assert because we are not root */
1116         sec_init();
1117
1118         if (c->opt_machine_pass) {
1119                 /* it is very useful to be able to make ads queries as the
1120                    machine account for testing purposes and for domain leave */
1121
1122                 net_use_krb_machine_account(c);
1123         }
1124
1125         if (!c->opt_password) {
1126                 c->opt_password = getenv("PASSWD");
1127         }
1128
1129         popt_burn_cmdline_password(argc, argv);
1130
1131         rc = net_run_function(c, argc_new-1, argv_new+1, "net", net_func);
1132
1133         DEBUG(2,("return code = %d\n", rc));
1134
1135         libnetapi_free(c->netapi_ctx);
1136
1137         poptFreeContext(pc);
1138
1139         TALLOC_FREE(frame);
1140         return rc;
1141 }