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