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