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