s3fs-client: Burn commandline password of client utils.
[metze/samba/wip.git] / source3 / utils / net.c
1 /*
2    Samba Unix/Linux SMB client library
3    Distributed SMB/CIFS Server Management Utility
4    Copyright (C) 2001 Steve French  (sfrench@us.ibm.com)
5    Copyright (C) 2001 Jim McDonough (jmcd@us.ibm.com)
6    Copyright (C) 2001 Andrew Tridgell (tridge@samba.org)
7    Copyright (C) 2001 Andrew Bartlett (abartlet@samba.org)
8    Copyright (C) 2008 Kai Blin (kai@samba.org)
9
10    Originally written by Steve and Jim. Largely rewritten by tridge in
11    November 2001.
12
13    Reworked again by abartlet in December 2001
14
15    Another overhaul, moving functionality into plug-ins loaded on demand by Kai
16    in May 2008.
17
18    This program is free software; you can redistribute it and/or modify
19    it under the terms of the GNU General Public License as published by
20    the Free Software Foundation; either version 3 of the License, or
21    (at your option) any later version.
22
23    This program is distributed in the hope that it will be useful,
24    but WITHOUT ANY WARRANTY; without even the implied warranty of
25    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
26    GNU General Public License for more details.
27
28    You should have received a copy of the GNU General Public License
29    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
30
31 /*****************************************************/
32 /*                                                   */
33 /*   Distributed SMB/CIFS Server Management Utility  */
34 /*                                                   */
35 /*   The intent was to make the syntax similar       */
36 /*   to the NET utility (first developed in DOS      */
37 /*   with additional interesting & useful functions  */
38 /*   added in later SMB server network operating     */
39 /*   systems).                                       */
40 /*                                                   */
41 /*****************************************************/
42
43 #include "includes.h"
44 #include "popt_common.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
52 #ifdef WITH_FAKE_KASERVER
53 #include "utils/net_afs.h"
54 #endif
55
56 /***********************************************************************/
57 /* end of internationalization section                                 */
58 /***********************************************************************/
59
60 enum netr_SchannelType get_sec_channel_type(const char *param)
61 {
62         if (!(param && *param)) {
63                 return get_default_sec_channel();
64         } else {
65                 if (strequal(param, "PDC")) {
66                         return SEC_CHAN_BDC;
67                 } else if (strequal(param, "BDC")) {
68                         return SEC_CHAN_BDC;
69                 } else if (strequal(param, "MEMBER")) {
70                         return SEC_CHAN_WKSTA;
71 #if 0
72                 } else if (strequal(param, "DOMAIN")) {
73                         return SEC_CHAN_DOMAIN;
74 #endif
75                 } else {
76                         return get_default_sec_channel();
77                 }
78         }
79 }
80
81 static int net_changetrustpw(struct net_context *c, int argc, const char **argv)
82 {
83         if (net_ads_check_our_domain(c) == 0)
84                 return net_ads_changetrustpw(c, argc, argv);
85
86         return net_rpc_changetrustpw(c, argc, argv);
87 }
88
89 static void set_line_buffering(FILE *f)
90 {
91         setvbuf(f, NULL, _IOLBF, 0);
92 }
93
94 static int net_changesecretpw(struct net_context *c, int argc,
95                               const char **argv)
96 {
97         char *trust_pw;
98         enum netr_SchannelType sec_channel_type = SEC_CHAN_WKSTA;
99
100         if(c->opt_force) {
101                 if (c->opt_stdin) {
102                         set_line_buffering(stdin);
103                         set_line_buffering(stdout);
104                         set_line_buffering(stderr);
105                 }
106
107                 trust_pw = get_pass(_("Enter machine password: "), c->opt_stdin);
108
109                 if (!secrets_store_machine_password(trust_pw, lp_workgroup(), sec_channel_type)) {
110                             d_fprintf(stderr,
111                                       _("Unable to write the machine account password in the secrets database"));
112                             return 1;
113                 }
114                 else {
115                     d_printf(_("Modified trust account password in secrets database\n"));
116                 }
117         }
118         else {
119                 d_printf(_("Machine account password change requires the -f flag.\n"
120                            "Do NOT use this function unless you know what it does!\n"
121                            "This function will change the ADS Domain member "
122                            "machine account password in the secrets.tdb file!\n"));
123         }
124
125         return 0;
126 }
127
128 /**
129  * @brief Set the authorised user for winbindd access in secrets.tdb
130  */
131 static int net_setauthuser(struct net_context *c, int argc, const char **argv)
132 {
133         const char *password = NULL;
134
135         if (!secrets_init()) {
136                 d_fprintf(stderr, _("Failed to open secrets.tdb.\n"));
137                 return 1;
138         }
139
140         /* Delete the settings. */
141         if (argc >= 1) {
142                 if (strncmp(argv[0], "delete", 6) != 0) {
143                         d_fprintf(stderr,_("Usage:\n"));
144                         d_fprintf(stderr,
145                                   _("    net setauthuser -U user[%%password] \n"
146                                     "        Set the auth user account to user"
147                                     "password. Prompt for password if not "
148                                     "specified.\n"));
149                         d_fprintf(stderr,
150                                   _("    net setauthuser delete\n"
151                                     "        Delete the auth user setting.\n"));
152                         return 1;
153                 }
154                 secrets_delete(SECRETS_AUTH_USER);
155                 secrets_delete(SECRETS_AUTH_DOMAIN);
156                 secrets_delete(SECRETS_AUTH_PASSWORD);
157                 return 0;
158         }
159
160         if (!c->opt_user_specified) {
161                 d_fprintf(stderr, _("Usage:\n"));
162                 d_fprintf(stderr,
163                           _("    net setauthuser -U user[%%password]\n"
164                             "        Set the auth user account to user"
165                             "password. Prompt for password if not "
166                             "specified.\n"));
167                 d_fprintf(stderr,
168                           _("    net setauthuser delete\n"
169                             "        Delete the auth user setting.\n"));
170                 return 1;
171         }
172
173         password = net_prompt_pass(c, _("the auth user"));
174         if (password == NULL) {
175                 d_fprintf(stderr,_("Failed to get the auth users password.\n"));
176                 return 1;
177         }
178
179         if (!secrets_store(SECRETS_AUTH_USER, c->opt_user_name,
180                            strlen(c->opt_user_name) + 1)) {
181                 d_fprintf(stderr, _("error storing auth user name\n"));
182                 return 1;
183         }
184
185         if (!secrets_store(SECRETS_AUTH_DOMAIN, c->opt_workgroup,
186                            strlen(c->opt_workgroup) + 1)) {
187                 d_fprintf(stderr, _("error storing auth user domain\n"));
188                 return 1;
189         }
190
191         if (!secrets_store(SECRETS_AUTH_PASSWORD, password,
192                            strlen(password) + 1)) {
193                 d_fprintf(stderr, _("error storing auth user password\n"));
194                 return 1;
195         }
196
197         return 0;
198 }
199
200 /**
201  * @brief Get the auth user settings
202  */
203 static int net_getauthuser(struct net_context *c, int argc, const char **argv)
204 {
205         char *user, *domain, *password;
206
207         /* Lift data from secrets file */
208
209         secrets_fetch_ipc_userpass(&user, &domain, &password);
210
211         if ((!user || !*user) && (!domain || !*domain ) &&
212             (!password || !*password)){
213
214                 SAFE_FREE(user);
215                 SAFE_FREE(domain);
216                 SAFE_FREE(password);
217                 d_printf(_("No authorised user configured\n"));
218                 return 0;
219         }
220
221         /* Pretty print authorised user info */
222
223         d_printf("%s%s%s%s%s\n", domain ? domain : "",
224                  domain ? lp_winbind_separator(): "", user,
225                  password ? "%" : "", password ? password : "");
226
227         SAFE_FREE(user);
228         SAFE_FREE(domain);
229         SAFE_FREE(password);
230
231         return 0;
232 }
233 /*
234  Retrieve our local SID or the SID for the specified name
235  */
236 static int net_getlocalsid(struct net_context *c, int argc, const char **argv)
237 {
238         struct dom_sid sid;
239         const char *name;
240         fstring sid_str;
241
242         if (argc >= 1) {
243                 name = argv[0];
244         }
245         else {
246                 name = lp_netbios_name();
247         }
248
249         if(!initialize_password_db(false, NULL)) {
250                 d_fprintf(stderr, _("WARNING: Could not open passdb\n"));
251                 return 1;
252         }
253
254         /* first check to see if we can even access secrets, so we don't
255            panic when we can't. */
256
257         if (!secrets_init()) {
258                 d_fprintf(stderr,
259                           _("Unable to open secrets.tdb.  Can't fetch domain "
260                             "SID for name: %s\n"), name);
261                 return 1;
262         }
263
264         /* Generate one, if it doesn't exist */
265         get_global_sam_sid();
266
267         if (!secrets_fetch_domain_sid(name, &sid)) {
268                 DEBUG(0, ("Can't fetch domain SID for name: %s\n", name));
269                 return 1;
270         }
271         sid_to_fstring(sid_str, &sid);
272         d_printf(_("SID for domain %s is: %s\n"), name, sid_str);
273         return 0;
274 }
275
276 static int net_setlocalsid(struct net_context *c, int argc, const char **argv)
277 {
278         struct dom_sid sid;
279
280         if ( (argc != 1)
281              || (strncmp(argv[0], "S-1-5-21-", strlen("S-1-5-21-")) != 0)
282              || (!string_to_sid(&sid, argv[0]))
283              || (sid.num_auths != 4)) {
284                 d_printf(_("Usage:"));
285                 d_printf(" net setlocalsid S-1-5-21-x-y-z\n");
286                 return 1;
287         }
288
289         if (!secrets_store_domain_sid(lp_netbios_name(), &sid)) {
290                 DEBUG(0,("Can't store domain SID as a pdc/bdc.\n"));
291                 return 1;
292         }
293
294         return 0;
295 }
296
297 static int net_setdomainsid(struct net_context *c, int argc, const char **argv)
298 {
299         struct dom_sid sid;
300
301         if ( (argc != 1)
302              || (strncmp(argv[0], "S-1-5-21-", strlen("S-1-5-21-")) != 0)
303              || (!string_to_sid(&sid, argv[0]))
304              || (sid.num_auths != 4)) {
305                 d_printf(_("Usage:"));
306                 d_printf(" net setdomainsid S-1-5-21-x-y-z\n");
307                 return 1;
308         }
309
310         if (!secrets_store_domain_sid(lp_workgroup(), &sid)) {
311                 DEBUG(0,("Can't store domain SID.\n"));
312                 return 1;
313         }
314
315         return 0;
316 }
317
318 static int net_getdomainsid(struct net_context *c, int argc, const char **argv)
319 {
320         struct dom_sid domain_sid;
321         fstring sid_str;
322
323         if (argc > 0) {
324                 d_printf(_("Usage:"));
325                 d_printf(" net getdomainsid\n");
326                 return 1;
327         }
328
329         if(!initialize_password_db(false, NULL)) {
330                 d_fprintf(stderr, _("WARNING: Could not open passdb\n"));
331                 return 1;
332         }
333
334         /* first check to see if we can even access secrets, so we don't
335            panic when we can't. */
336
337         if (!secrets_init()) {
338                 d_fprintf(stderr, _("Unable to open secrets.tdb.  Can't fetch "
339                                     "domain SID for name: %s\n"),
340                           get_global_sam_name());
341                 return 1;
342         }
343
344         /* Generate one, if it doesn't exist */
345         get_global_sam_sid();
346
347         if (!IS_DC) {
348                 if (!secrets_fetch_domain_sid(lp_netbios_name(), &domain_sid)) {
349                         d_fprintf(stderr, _("Could not fetch local SID\n"));
350                         return 1;
351                 }
352                 sid_to_fstring(sid_str, &domain_sid);
353                 d_printf(_("SID for local machine %s is: %s\n"),
354                          lp_netbios_name(), sid_str);
355         }
356         if (!secrets_fetch_domain_sid(c->opt_workgroup, &domain_sid)) {
357                 d_fprintf(stderr, _("Could not fetch domain SID\n"));
358                 return 1;
359         }
360
361         sid_to_fstring(sid_str, &domain_sid);
362         d_printf(_("SID for domain %s is: %s\n"), c->opt_workgroup, sid_str);
363
364         return 0;
365 }
366
367 static bool search_maxrid(struct pdb_search *search, const char *type,
368                           uint32 *max_rid)
369 {
370         struct samr_displayentry *entries;
371         uint32 i, num_entries;
372
373         if (search == NULL) {
374                 d_fprintf(stderr, _("get_maxrid: Could not search %s\n"), type);
375                 return false;
376         }
377
378         num_entries = pdb_search_entries(search, 0, 0xffffffff, &entries);
379         for (i=0; i<num_entries; i++)
380                 *max_rid = MAX(*max_rid, entries[i].rid);
381         TALLOC_FREE(search);
382         return true;
383 }
384
385 static uint32 get_maxrid(void)
386 {
387         uint32 max_rid = 0;
388
389         if (!search_maxrid(pdb_search_users(talloc_tos(), 0), "users", &max_rid))
390                 return 0;
391
392         if (!search_maxrid(pdb_search_groups(talloc_tos()), "groups", &max_rid))
393                 return 0;
394
395         if (!search_maxrid(pdb_search_aliases(talloc_tos(),
396                                               get_global_sam_sid()),
397                            "aliases", &max_rid))
398                 return 0;
399
400         return max_rid;
401 }
402
403 static int net_maxrid(struct net_context *c, int argc, const char **argv)
404 {
405         uint32 rid;
406
407         if (argc != 0) {
408                 d_fprintf(stderr, "%s net maxrid\n", _("Usage:"));
409                 return 1;
410         }
411
412         if ((rid = get_maxrid()) == 0) {
413                 d_fprintf(stderr, _("can't get current maximum rid\n"));
414                 return 1;
415         }
416
417         d_printf(_("Currently used maximum rid: %d\n"), rid);
418
419         return 0;
420 }
421
422 /* main function table */
423 static struct functable net_func[] = {
424         {
425                 "rpc",
426                 net_rpc,
427                 NET_TRANSPORT_RPC,
428                 N_("Run functions using RPC transport"),
429                 N_("  Use 'net help rpc' to get more extensive information "
430                    "about 'net rpc' commands.")
431         },
432         {
433                 "rap",
434                 net_rap,
435                 NET_TRANSPORT_RAP,
436                 N_("Run functions using RAP transport"),
437                 N_("  Use 'net help rap' to get more extensive information "
438                    "about 'net rap' commands.")
439         },
440         {
441                 "ads",
442                 net_ads,
443                 NET_TRANSPORT_ADS,
444                 N_("Run functions using ADS transport"),
445                 N_("  Use 'net help ads' to get more extensive information "
446                    "about 'net ads' commands.")
447         },
448
449         /* eventually these should auto-choose the transport ... */
450         {
451                 "file",
452                 net_file,
453                 NET_TRANSPORT_RPC | NET_TRANSPORT_RAP,
454                 N_("Functions on remote opened files"),
455                 N_("  Use 'net help file' to get more information about 'net "
456                    "file' commands.")
457         },
458         {
459                 "share",
460                 net_share,
461                 NET_TRANSPORT_RPC | NET_TRANSPORT_RAP,
462                 N_("Functions on shares"),
463                 N_("  Use 'net help share' to get more information about 'net "
464                    "share' commands.")
465         },
466         {
467                 "session",
468                 net_rap_session,
469                 NET_TRANSPORT_RAP,
470                 N_("Manage sessions"),
471                 N_("  Use 'net help session' to get more information about "
472                    "'net session' commands.")
473         },
474         {
475                 "server",
476                 net_rap_server,
477                 NET_TRANSPORT_RAP,
478                 N_("List servers in workgroup"),
479                 N_("  Use 'net help server' to get more information about 'net "
480                    "server' commands.")
481         },
482         {
483                 "domain",
484                 net_rap_domain,
485                 NET_TRANSPORT_RAP,
486                 N_("List domains/workgroups on network"),
487                 N_("  Use 'net help domain' to get more information about 'net "
488                    "domain' commands.")
489         },
490         {
491                 "printq",
492                 net_rap_printq,
493                 NET_TRANSPORT_RAP,
494                 N_("Modify printer queue"),
495                 N_("  Use 'net help printq' to get more information about 'net "
496                    "printq' commands.")
497         },
498         {
499                 "user",
500                 net_user,
501                 NET_TRANSPORT_ADS | NET_TRANSPORT_RPC | NET_TRANSPORT_RAP,
502                 N_("Manage users"),
503                 N_("  Use 'net help user' to get more information about 'net "
504                    "user' commands.")
505         },
506         {
507                 "group",
508                 net_group,
509                 NET_TRANSPORT_ADS | NET_TRANSPORT_RPC | NET_TRANSPORT_RAP,
510                 N_("Manage groups"),
511                 N_("  Use 'net help group' to get more information about 'net "
512                    "group' commands.")
513         },
514         {
515                 "groupmap",
516                 net_groupmap,
517                 NET_TRANSPORT_LOCAL,
518                 N_("Manage group mappings"),
519                 N_("  Use 'net help groupmap' to get more information about "
520                    "'net groupmap' commands.")
521         },
522         {
523                 "sam",
524                 net_sam,
525                 NET_TRANSPORT_LOCAL,
526                 N_("Functions on the SAM database"),
527                 N_("  Use 'net help sam' to get more information about 'net "
528                    "sam' commands.")
529         },
530         {
531                 "validate",
532                 net_rap_validate,
533                 NET_TRANSPORT_RAP,
534                 N_("Validate username and password"),
535                 N_("  Use 'net help validate' to get more information about "
536                    "'net validate' commands.")
537         },
538         {
539                 "groupmember",
540                 net_rap_groupmember,
541                 NET_TRANSPORT_RAP,
542                 N_("Modify group memberships"),
543                 N_("  Use 'net help groupmember' to get more information about "
544                    "'net groupmember' commands.")
545         },
546         {       "admin",
547                 net_rap_admin,
548                 NET_TRANSPORT_RAP,
549                 N_("Execute remote command on a remote OS/2 server"),
550                 N_("  Use 'net help admin' to get more information about 'net "
551                    "admin' commands.")
552         },
553         {       "service",
554                 net_rap_service,
555                 NET_TRANSPORT_RAP,
556                 N_("List/modify running services"),
557                 N_("  Use 'net help service' to get more information about "
558                    "'net service' commands.")
559         },
560         {
561                 "password",
562                 net_rap_password,
563                 NET_TRANSPORT_RAP,
564                 N_("Change user password on target server"),
565                 N_("  Use 'net help password' to get more information about "
566                    "'net password' commands.")
567         },
568         {       "changetrustpw",
569                 net_changetrustpw,
570                 NET_TRANSPORT_ADS | NET_TRANSPORT_RPC,
571                 N_("Change the trust password"),
572                 N_("  Use 'net help changetrustpw' to get more information "
573                    "about 'net changetrustpw'.")
574         },
575         {       "changesecretpw",
576                 net_changesecretpw,
577                 NET_TRANSPORT_LOCAL,
578                 N_("Change the secret password"),
579                 N_("  net [options] changesecretpw\n"
580                    "    Change the ADS domain member machine account password "
581                    "in secrets.tdb.\n"
582                    "    Do NOT use this function unless you know what it does.\n"
583                    "    Requires the -f flag to work.")
584         },
585         {
586                 "setauthuser",
587                 net_setauthuser,
588                 NET_TRANSPORT_LOCAL,
589                 N_("Set the winbind auth user"),
590                 N_("  net -U user[%%password] [-W domain] setauthuser\n"
591                    "    Set the auth user, password (and optionally domain\n"
592                    "    Will prompt for password if not given.\n"
593                    "  net setauthuser delete\n"
594                    "    Delete the existing auth user settings.")
595         },
596         {
597                 "getauthuser",
598                 net_getauthuser,
599                 NET_TRANSPORT_LOCAL,
600                 N_("Get the winbind auth user settings"),
601                 N_("  net getauthuser\n"
602                    "    Get the current winbind auth user settings.")
603         },
604         {       "time",
605                 net_time,
606                 NET_TRANSPORT_LOCAL,
607                 N_("Show/set time"),
608                 N_("  Use 'net help time' to get more information about 'net "
609                    "time' commands.")
610         },
611         {       "lookup",
612                 net_lookup,
613                 NET_TRANSPORT_LOCAL,
614                 N_("Look up host names/IP addresses"),
615                 N_("  Use 'net help lookup' to get more information about 'net "
616                    "lookup' commands.")
617         },
618         {       "g_lock",
619                 net_g_lock,
620                 NET_TRANSPORT_LOCAL,
621                 N_("Manipulate the global lock table"),
622                 N_("  Use 'net help g_lock' to get more information about "
623                    "'net g_lock' commands.")
624         },
625         {       "join",
626                 net_join,
627                 NET_TRANSPORT_ADS | NET_TRANSPORT_RPC,
628                 N_("Join a domain/AD"),
629                 N_("  Use 'net help join' to get more information about 'net "
630                    "join'.")
631         },
632         {       "dom",
633                 net_dom,
634                 NET_TRANSPORT_LOCAL,
635                 N_("Join/unjoin (remote) machines to/from a domain/AD"),
636                 N_("  Use 'net help dom' to get more information about 'net "
637                    "dom' commands.")
638         },
639         {       "cache",
640                 net_cache,
641                 NET_TRANSPORT_LOCAL,
642                 N_("Operate on the cache tdb file"),
643                 N_("  Use 'net help cache' to get more information about 'net "
644                    "cache' commands.")
645         },
646         {       "getlocalsid",
647                 net_getlocalsid,
648                 NET_TRANSPORT_LOCAL,
649                 N_("Get the SID for the local domain"),
650                 N_("  net getlocalsid")
651         },
652         {       "setlocalsid",
653                 net_setlocalsid,
654                 NET_TRANSPORT_LOCAL,
655                 N_("Set the SID for the local domain"),
656                 N_("  net setlocalsid S-1-5-21-x-y-z")
657         },
658         {       "setdomainsid",
659                 net_setdomainsid,
660                 NET_TRANSPORT_LOCAL,
661                 N_("Set domain SID on member servers"),
662                 N_("  net setdomainsid S-1-5-21-x-y-z")
663         },
664         {       "getdomainsid",
665                 net_getdomainsid,
666                 NET_TRANSPORT_LOCAL,
667                 N_("Get domain SID on member servers"),
668                 N_("  net getdomainsid")
669         },
670         {       "maxrid",
671                 net_maxrid,
672                 NET_TRANSPORT_LOCAL,
673                 N_("Display the maximum RID currently used"),
674                 N_("  net maxrid")
675         },
676         {       "idmap",
677                 net_idmap,
678                 NET_TRANSPORT_LOCAL,
679                 N_("IDmap functions"),
680                 N_("  Use 'net help idmap to get more information about 'net "
681                   "idmap' commands.")
682         },
683         {       "status",
684                 net_status,
685                 NET_TRANSPORT_LOCAL,
686                 N_("Display server status"),
687                 N_("  Use 'net help status' to get more information about 'net "
688                    "status' commands.")
689         },
690         {       "usershare",
691                 net_usershare,
692                 NET_TRANSPORT_LOCAL,
693                 N_("Manage user-modifiable shares"),
694                 N_("  Use 'net help usershare to get more information about "
695                    "'net usershare' commands.")
696         },
697         {       "usersidlist",
698                 net_usersidlist,
699                 NET_TRANSPORT_RPC,
700                 N_("Display list of all users with SID"),
701                 N_("  Use 'net help usersidlist' to get more information about "
702                    "'net usersidlist'.")
703         },
704         {       "conf",
705                 net_conf,
706                 NET_TRANSPORT_LOCAL,
707                 N_("Manage Samba registry based configuration"),
708                 N_("  Use 'net help conf' to get more information about 'net "
709                    "conf' commands.")
710         },
711         {       "registry",
712                 net_registry,
713                 NET_TRANSPORT_LOCAL,
714                 N_("Manage the Samba registry"),
715                 N_("  Use 'net help registry' to get more information about "
716                    "'net registry' commands.")
717         },
718         {       "eventlog",
719                 net_eventlog,
720                 NET_TRANSPORT_LOCAL,
721                 N_("Process Win32 *.evt eventlog files"),
722                 N_("  Use 'net help eventlog' to get more information about "
723                    "'net eventlog' commands.")
724         },
725         {       "printing",
726                 net_printing,
727                 NET_TRANSPORT_LOCAL,
728                 N_("Process tdb printer files"),
729                 N_("  Use 'net help printing' to get more information about "
730                    "'net printing' commands.")
731         },
732
733         {       "serverid",
734                 net_serverid,
735                 NET_TRANSPORT_LOCAL,
736                 N_("Manage the serverid tdb"),
737                 N_("  Use 'net help serverid' to get more information about "
738                    "'net serverid' commands.")
739         },
740
741 #ifdef WITH_FAKE_KASERVER
742         {       "afs",
743                 net_afs,
744                 NET_TRANSPORT_LOCAL,
745                 N_("Manage AFS tokens"),
746                 N_("  Use 'net help afs' to get more information about 'net "
747                    "afs' commands.")
748         },
749 #endif
750
751         {       "help",
752                 net_help,
753                 NET_TRANSPORT_LOCAL,
754                 N_("Print usage information"),
755                 N_("  Use 'net help help' to list usage information for 'net' "
756                    "commands.")
757         },
758         {NULL, NULL, 0, NULL, NULL}
759 };
760
761
762 /****************************************************************************
763   main program
764 ****************************************************************************/
765  int main(int argc, const char **argv)
766 {
767         int opt,i;
768         char *p;
769         int rc = 0;
770         int argc_new = 0;
771         const char ** argv_new;
772         poptContext pc;
773         TALLOC_CTX *frame = talloc_stackframe();
774         struct net_context *c = talloc_zero(frame, struct net_context);
775
776         struct poptOption long_options[] = {
777                 {"help",        'h', POPT_ARG_NONE,   0, 'h'},
778                 {"workgroup",   'w', POPT_ARG_STRING, &c->opt_target_workgroup},
779                 {"user",        'U', POPT_ARG_STRING, &c->opt_user_name, 'U'},
780                 {"ipaddress",   'I', POPT_ARG_STRING, 0,'I'},
781                 {"port",        'p', POPT_ARG_INT,    &c->opt_port},
782                 {"myname",      'n', POPT_ARG_STRING, &c->opt_requester_name},
783                 {"server",      'S', POPT_ARG_STRING, &c->opt_host},
784                 {"encrypt",     'e', POPT_ARG_NONE,   NULL, 'e', N_("Encrypt SMB transport (UNIX extended servers only)") },
785                 {"container",   'c', POPT_ARG_STRING, &c->opt_container},
786                 {"comment",     'C', POPT_ARG_STRING, &c->opt_comment},
787                 {"maxusers",    'M', POPT_ARG_INT,    &c->opt_maxusers},
788                 {"flags",       'F', POPT_ARG_INT,    &c->opt_flags},
789                 {"long",        'l', POPT_ARG_NONE,   &c->opt_long_list_entries},
790                 {"reboot",      'r', POPT_ARG_NONE,   &c->opt_reboot},
791                 {"force",       'f', POPT_ARG_NONE,   &c->opt_force},
792                 {"stdin",       'i', POPT_ARG_NONE,   &c->opt_stdin},
793                 {"timeout",     't', POPT_ARG_INT,    &c->opt_timeout},
794                 {"request-timeout",0,POPT_ARG_INT,    &c->opt_request_timeout},
795                 {"machine-pass",'P', POPT_ARG_NONE,   &c->opt_machine_pass},
796                 {"kerberos",    'k', POPT_ARG_NONE,   &c->opt_kerberos},
797                 {"myworkgroup", 'W', POPT_ARG_STRING, &c->opt_workgroup},
798                 {"use-ccache",    0, POPT_ARG_NONE,   &c->opt_ccache},
799                 {"verbose",     'v', POPT_ARG_NONE,   &c->opt_verbose},
800                 {"test",        'T', POPT_ARG_NONE,   &c->opt_testmode},
801                 /* Options for 'net groupmap set' */
802                 {"local",       'L', POPT_ARG_NONE,   &c->opt_localgroup},
803                 {"domain",      'D', POPT_ARG_NONE,   &c->opt_domaingroup},
804                 {"ntname",      'N', POPT_ARG_STRING, &c->opt_newntname},
805                 {"rid",         'R', POPT_ARG_INT,    &c->opt_rid},
806                 /* Options for 'net rpc share migrate' */
807                 {"acls",        0, POPT_ARG_NONE,     &c->opt_acls},
808                 {"attrs",       0, POPT_ARG_NONE,     &c->opt_attrs},
809                 {"timestamps",  0, POPT_ARG_NONE,     &c->opt_timestamps},
810                 {"exclude",     'X', POPT_ARG_STRING, &c->opt_exclude},
811                 {"destination", 0, POPT_ARG_STRING,   &c->opt_destination},
812                 {"tallocreport", 0, POPT_ARG_NONE,    &c->do_talloc_report},
813                 /* Options for 'net rpc vampire (keytab)' */
814                 {"force-full-repl", 0, POPT_ARG_NONE, &c->opt_force_full_repl},
815                 {"single-obj-repl", 0, POPT_ARG_NONE, &c->opt_single_obj_repl},
816                 {"clean-old-entries", 0, POPT_ARG_NONE, &c->opt_clean_old_entries},
817                 /* Options for 'net idmap'*/
818                 {"db", 0, POPT_ARG_STRING, &c->opt_db},
819                 {"lock", 0, POPT_ARG_NONE,   &c->opt_lock},
820                 {"auto", 'a', POPT_ARG_NONE,   &c->opt_auto},
821                 {"repair", 0, POPT_ARG_NONE,   &c->opt_repair},
822                 /* Options for 'net registry check'*/
823                 {"reg-version", 0, POPT_ARG_INT, &c->opt_reg_version},
824                 {"output", 'o', POPT_ARG_STRING, &c->opt_output},
825                 {"wipe", 0, POPT_ARG_NONE, &c->opt_wipe},
826                 /* Options for 'net registry import' */
827                 {"precheck", 0, POPT_ARG_STRING, &c->opt_precheck},
828                 POPT_COMMON_SAMBA
829                 { 0, 0, 0, 0}
830         };
831
832         zero_sockaddr(&c->opt_dest_ip);
833
834         setup_logging(argv[0], DEBUG_STDERR);
835
836         load_case_tables();
837
838         setlocale(LC_ALL, "");
839 #if defined(HAVE_BINDTEXTDOMAIN)
840         bindtextdomain(MODULE_NAME, get_dyn_LOCALEDIR());
841 #endif
842 #if defined(HAVE_TEXTDOMAIN)
843         textdomain(MODULE_NAME);
844 #endif
845
846         /* set default debug level to 0 regardless of what smb.conf sets */
847         lp_set_cmdline("log level", "0");
848         c->private_data = net_func;
849
850         pc = poptGetContext(NULL, argc, (const char **) argv, long_options,
851                             POPT_CONTEXT_KEEP_FIRST);
852
853         while((opt = poptGetNextOpt(pc)) != -1) {
854                 switch (opt) {
855                 case 'h':
856                         c->display_usage = true;
857                         break;
858                 case 'e':
859                         c->smb_encrypt = true;
860                         break;
861                 case 'I':
862                         if (!interpret_string_addr(&c->opt_dest_ip,
863                                                 poptGetOptArg(pc), 0)) {
864                                 d_fprintf(stderr, _("\nInvalid ip address specified\n"));
865                         } else {
866                                 c->opt_have_ip = true;
867                         }
868                         break;
869                 case 'U':
870                         c->opt_user_specified = true;
871                         c->opt_user_name = talloc_strdup(c, c->opt_user_name);
872                         p = strchr(c->opt_user_name,'%');
873                         if (p) {
874                                 *p = 0;
875                                 c->opt_password = p+1;
876                         }
877                         break;
878                 default:
879                         d_fprintf(stderr, _("\nInvalid option %s: %s\n"),
880                                  poptBadOption(pc, 0), poptStrerror(opt));
881                         net_help(c, argc, argv);
882                         exit(1);
883                 }
884         }
885
886         lp_load_global(get_dyn_CONFIGFILE());
887
888 #if defined(HAVE_BIND_TEXTDOMAIN_CODESET)
889         /* Bind our gettext results to 'unix charset'
890            
891            This ensures that the translations and any embedded strings are in the
892            same charset.  It won't be the one from the user's locale (we no
893            longer auto-detect that), but it will be self-consistent.
894         */
895         bind_textdomain_codeset(MODULE_NAME, lp_unix_charset());
896 #endif
897
898         argv_new = (const char **)poptGetArgs(pc);
899
900         argc_new = argc;
901         for (i=0; i<argc; i++) {
902                 if (argv_new[i] == NULL) {
903                         argc_new = i;
904                         break;
905                 }
906         }
907
908         if (c->do_talloc_report) {
909                 talloc_enable_leak_report();
910         }
911
912         if (c->opt_requester_name) {
913                 lp_set_cmdline("netbios name", c->opt_requester_name);
914         }
915
916         if (!c->opt_user_name && getenv("LOGNAME")) {
917                 c->opt_user_name = getenv("LOGNAME");
918         }
919
920         if (!c->opt_workgroup) {
921                 c->opt_workgroup = smb_xstrdup(lp_workgroup());
922         }
923
924         if (!c->opt_target_workgroup) {
925                 c->opt_target_workgroup = smb_xstrdup(lp_workgroup());
926         }
927
928         if (!init_names())
929                 exit(1);
930
931         load_interfaces();
932
933         /* this makes sure that when we do things like call scripts,
934            that it won't assert because we are not root */
935         sec_init();
936
937         if (c->opt_machine_pass) {
938                 /* it is very useful to be able to make ads queries as the
939                    machine account for testing purposes and for domain leave */
940
941                 net_use_krb_machine_account(c);
942         }
943
944         if (!c->opt_password) {
945                 c->opt_password = getenv("PASSWD");
946         }
947
948         popt_burn_cmdline_password(argc, argv);
949
950         /* Failing to init the msg_ctx isn't a fatal error. Only
951            root-level things (joining/leaving domains etc.) will be denied. */
952
953         c->msg_ctx = messaging_init(c, event_context_init(c));
954
955         rc = net_run_function(c, argc_new-1, argv_new+1, "net", net_func);
956
957         DEBUG(2,("return code = %d\n", rc));
958
959         gencache_stabilize();
960
961         libnetapi_free(c->netapi_ctx);
962
963         poptFreeContext(pc);
964
965         TALLOC_FREE(frame);
966         return rc;
967 }