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