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