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