Merge branch 'master' of ssh://git.samba.org/data/git/samba
[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         pdb_search_destroy(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(0), "users", &max_rid))
284                 return 0;
285
286         if (!search_maxrid(pdb_search_groups(), "groups", &max_rid))
287                 return 0;
288
289         if (!search_maxrid(pdb_search_aliases(get_global_sam_sid()),
290                            "aliases", &max_rid))
291                 return 0;
292
293         return max_rid;
294 }
295
296 static int net_maxrid(struct net_context *c, int argc, const char **argv)
297 {
298         uint32 rid;
299
300         if (argc != 0) {
301                 DEBUG(0, ("usage: net maxrid\n"));
302                 return 1;
303         }
304
305         if ((rid = get_maxrid()) == 0) {
306                 DEBUG(0, ("can't get current maximum rid\n"));
307                 return 1;
308         }
309
310         d_printf("Currently used maximum rid: %d\n", rid);
311
312         return 0;
313 }
314
315 /* main function table */
316 static struct functable net_func[] = {
317         {
318                 "rpc",
319                 net_rpc,
320                 NET_TRANSPORT_RPC,
321                 "Run functions using RPC transport",
322                 "  Use 'net help rpc' to get more extensive information about "
323                 "'net rpc' commands."
324         },
325         {
326                 "rap",
327                 net_rap,
328                 NET_TRANSPORT_RAP,
329                 "Run functions using RAP transport",
330                 "  Use 'net help rap' to get more extensive information about "
331                 "'net rap' commands."
332         },
333         {
334                 "ads",
335                 net_ads,
336                 NET_TRANSPORT_ADS,
337                 "Run functions using ADS transport",
338                 "  Use 'net help ads' to get more extensive information about "
339                 "'net ads' commands."
340         },
341
342         /* eventually these should auto-choose the transport ... */
343         {
344                 "file",
345                 net_file,
346                 NET_TRANSPORT_RPC | NET_TRANSPORT_RAP,
347                 "Functions on remote opened files",
348                 "  Use 'net help file' to get more information about 'net "
349                 "file' commands."
350         },
351         {
352                 "share",
353                 net_share,
354                 NET_TRANSPORT_RPC | NET_TRANSPORT_RAP,
355                 "Functions on shares",
356                 "  Use 'net help share' to get more information about 'net "
357                 "share' commands."
358         },
359         {
360                 "session",
361                 net_rap_session,
362                 NET_TRANSPORT_RAP,
363                 "Manage sessions",
364                 "  Use 'net help session' to get more information about 'net "
365                 "session' commands."
366         },
367         {
368                 "server",
369                 net_rap_server,
370                 NET_TRANSPORT_RAP,
371                 "List servers in workgroup",
372                 "  Use 'net help server' to get more information about 'net "
373                 "server' commands."
374         },
375         {
376                 "domain",
377                 net_rap_domain,
378                 NET_TRANSPORT_RAP,
379                 "List domains/workgroups on network",
380                 "  Use 'net help domain' to get more information about 'net "
381                 "domain' commands."
382         },
383         {
384                 "printq",
385                 net_rap_printq,
386                 NET_TRANSPORT_RAP,
387                 "Modify printer queue",
388                 "  Use 'net help printq' to get more information about 'net "
389                 "printq' commands."
390         },
391         {
392                 "user",
393                 net_user,
394                 NET_TRANSPORT_ADS | NET_TRANSPORT_RPC | NET_TRANSPORT_RAP,
395                 "Manage users",
396                 "  Use 'net help user' to get more information about 'net "
397                 "user' commands."
398         },
399         {
400                 "group",
401                 net_group,
402                 NET_TRANSPORT_ADS | NET_TRANSPORT_RPC | NET_TRANSPORT_RAP,
403                 "Manage groups",
404                 "  Use 'net help group' to get more information about 'net "
405                 "group' commands."
406         },
407         {
408                 "groupmap",
409                 net_groupmap,
410                 NET_TRANSPORT_LOCAL,
411                 "Manage group mappings",
412                 "  Use 'net help groupmap' to get more information about 'net "
413                 "groupmap' commands."
414         },
415         {
416                 "sam",
417                 net_sam,
418                 NET_TRANSPORT_LOCAL,
419                 "Functions on the SAM database",
420                 "  Use 'net help sam' to get more information about 'net sam' "
421                 "commands."
422         },
423         {
424                 "validate",
425                 net_rap_validate,
426                 NET_TRANSPORT_RAP,
427                 "Validate username and password",
428                 "  Use 'net help validate' to get more information about 'net "
429                 "validate' commands."
430         },
431         {
432                 "groupmember",
433                 net_rap_groupmember,
434                 NET_TRANSPORT_RAP,
435                 "Modify group memberships",
436                 "  Use 'net help groupmember' to get more information about "
437                 "'net groupmember' commands."
438         },
439         {       "admin",
440                 net_rap_admin,
441                 NET_TRANSPORT_RAP,
442                 "Execute remote command on a remote OS/2 server",
443                 "  Use 'net help admin' to get more information about 'net "
444                 "admin' commands."
445         },
446         {       "service",
447                 net_rap_service,
448                 NET_TRANSPORT_RAP,
449                 "List/modify running services",
450                 "  Use 'net help service' to get more information about 'net "
451                 "service' commands."
452         },
453         {
454                 "password",
455                 net_rap_password,
456                 NET_TRANSPORT_RAP,
457                 "Change user password on target server",
458                 "  Use 'net help password' to get more information about 'net "
459                 "password' commands."
460         },
461         {       "changetrustpw",
462                 net_changetrustpw,
463                 NET_TRANSPORT_ADS | NET_TRANSPORT_RPC,
464                 "Change the trust password",
465                 "  Use 'net help changetrustpw' to get more information about "
466                 "'net changetrustpw'."
467         },
468         {       "changesecretpw",
469                 net_changesecretpw,
470                 NET_TRANSPORT_LOCAL,
471                 "Change the secret password",
472                 "  net [options] changesecretpw\n"
473                 "    Change the ADS domain member machine account password in "
474                 "secrets.tdb.\n"
475                 "    Do NOT use this function unless you know what it does.\n"
476                 "    Requires the -f flag to work."
477         },
478         {       "time",
479                 net_time,
480                 NET_TRANSPORT_LOCAL,
481                 "Show/set time",
482                 "  Use 'net help time' to get more information about 'net "
483                 "time' commands."
484         },
485         {       "lookup",
486                 net_lookup,
487                 NET_TRANSPORT_LOCAL,
488                 "Look up host names/IP addresses",
489                 "  Use 'net help lookup' to get more information about 'net "
490                 "lookup' commands."
491         },
492         {       "join",
493                 net_join,
494                 NET_TRANSPORT_ADS | NET_TRANSPORT_RPC,
495                 "Join a domain/AD",
496                 "  Use 'net help join' to get more information about 'net "
497                 "join'."
498         },
499         {       "dom",
500                 net_dom,
501                 NET_TRANSPORT_LOCAL,
502                 "Join/unjoin (remote) machines to/from a domain/AD",
503                 "  Use 'net help dom' to get more information about 'net dom' "
504                 "commands."
505         },
506         {       "cache",
507                 net_cache,
508                 NET_TRANSPORT_LOCAL,
509                 "Operate on the cache tdb file",
510                 "  Use 'net help cache' to get more information about 'net "
511                 "cache' commands."
512         },
513         {       "getlocalsid",
514                 net_getlocalsid,
515                 NET_TRANSPORT_LOCAL,
516                 "Get the SID for the local domain",
517                 "  net getlocalsid"
518         },
519         {       "setlocalsid",
520                 net_setlocalsid,
521                 NET_TRANSPORT_LOCAL,
522                 "Set the SID for the local domain",
523                 "  net setlocalsid S-1-5-21-x-y-z"
524         },
525         {       "setdomainsid",
526                 net_setdomainsid,
527                 NET_TRANSPORT_LOCAL,
528                 "Set domain SID on member servers",
529                 "  net setdomainsid S-1-5-21-x-y-z"
530         },
531         {       "getdomainsid",
532                 net_getdomainsid,
533                 NET_TRANSPORT_LOCAL,
534                 "Get domain SID on member servers",
535                 "  net getdomainsid"
536         },
537         {       "maxrid",
538                 net_maxrid,
539                 NET_TRANSPORT_LOCAL,
540                 "Display the maximul RID currently used",
541                 "  net maxrid"
542         },
543         {       "idmap",
544                 net_idmap,
545                 NET_TRANSPORT_LOCAL,
546                 "IDmap functions",
547                 "  Use 'net help idmap to get more information about 'net "
548                 "idmap' commands."
549         },
550         {       "status",
551                 net_status,
552                 NET_TRANSPORT_LOCAL,
553                 "Display server status",
554                 "  Use 'net help status' to get more information about 'net "
555                 "status' commands."
556         },
557         {       "usershare",
558                 net_usershare,
559                 NET_TRANSPORT_LOCAL,
560                 "Manage user-modifiable shares",
561                 "  Use 'net help usershare to get more information about 'net "
562                 "usershare' commands."
563         },
564         {       "usersidlist",
565                 net_usersidlist,
566                 NET_TRANSPORT_RPC,
567                 "Display list of all users with SID",
568                 "  Use 'net help usersidlist' to get more information about "
569                 "'net usersidlist'."
570         },
571         {       "conf",
572                 net_conf,
573                 NET_TRANSPORT_LOCAL,
574                 "Manage Samba registry based configuration",
575                 "  Use 'net help conf' to get more information about 'net "
576                 "conf' commands."
577         },
578         {       "registry",
579                 net_registry,
580                 NET_TRANSPORT_LOCAL,
581                 "Manage the Samba registry",
582                 "  Use 'net help registry' to get more information about 'net "
583                 "registry' commands."
584         },
585 #ifdef WITH_FAKE_KASERVER
586         {       "afs",
587                 net_afs,
588                 NET_TRANSPORT_LOCAL,
589                 "Manage AFS tokens",
590                 "  Use 'net help afs' to get more information about 'net afs' "
591                 "commands."
592         },
593 #endif
594
595         {       "help",
596                 net_help,
597                 NET_TRANSPORT_LOCAL,
598                 "Print usage information",
599                 "  Use 'net help help' to list usage information for 'net' "
600                 "commands."
601         },
602         {NULL, NULL, 0, NULL, NULL}
603 };
604
605
606 /****************************************************************************
607   main program
608 ****************************************************************************/
609  int main(int argc, const char **argv)
610 {
611         int opt,i;
612         char *p;
613         int rc = 0;
614         int argc_new = 0;
615         const char ** argv_new;
616         poptContext pc;
617         TALLOC_CTX *frame = talloc_stackframe();
618         struct net_context *c = talloc_zero(frame, struct net_context);
619
620         struct poptOption long_options[] = {
621                 {"help",        'h', POPT_ARG_NONE,   0, 'h'},
622                 {"workgroup",   'w', POPT_ARG_STRING, &c->opt_target_workgroup},
623                 {"user",        'U', POPT_ARG_STRING, &c->opt_user_name, 'U'},
624                 {"ipaddress",   'I', POPT_ARG_STRING, 0,'I'},
625                 {"port",        'p', POPT_ARG_INT,    &c->opt_port},
626                 {"myname",      'n', POPT_ARG_STRING, &c->opt_requester_name},
627                 {"server",      'S', POPT_ARG_STRING, &c->opt_host},
628                 {"encrypt",     'e', POPT_ARG_NONE,   NULL, 'e', "Encrypt SMB transport (UNIX extended servers only)" },
629                 {"container",   'c', POPT_ARG_STRING, &c->opt_container},
630                 {"comment",     'C', POPT_ARG_STRING, &c->opt_comment},
631                 {"maxusers",    'M', POPT_ARG_INT,    &c->opt_maxusers},
632                 {"flags",       'F', POPT_ARG_INT,    &c->opt_flags},
633                 {"long",        'l', POPT_ARG_NONE,   &c->opt_long_list_entries},
634                 {"reboot",      'r', POPT_ARG_NONE,   &c->opt_reboot},
635                 {"force",       'f', POPT_ARG_NONE,   &c->opt_force},
636                 {"stdin",       'i', POPT_ARG_NONE,   &c->opt_stdin},
637                 {"timeout",     't', POPT_ARG_INT,    &c->opt_timeout},
638                 {"machine-pass",'P', POPT_ARG_NONE,   &c->opt_machine_pass},
639                 {"kerberos",    'k', POPT_ARG_NONE,   &c->opt_kerberos},
640                 {"myworkgroup", 'W', POPT_ARG_STRING, &c->opt_workgroup},
641                 {"verbose",     'v', POPT_ARG_NONE,   &c->opt_verbose},
642                 {"test",        'T', POPT_ARG_NONE,   &c->opt_testmode},
643                 /* Options for 'net groupmap set' */
644                 {"local",       'L', POPT_ARG_NONE,   &c->opt_localgroup},
645                 {"domain",      'D', POPT_ARG_NONE,   &c->opt_domaingroup},
646                 {"ntname",      'N', POPT_ARG_STRING, &c->opt_newntname},
647                 {"rid",         'R', POPT_ARG_INT,    &c->opt_rid},
648                 /* Options for 'net rpc share migrate' */
649                 {"acls",        0, POPT_ARG_NONE,     &c->opt_acls},
650                 {"attrs",       0, POPT_ARG_NONE,     &c->opt_attrs},
651                 {"timestamps",  0, POPT_ARG_NONE,     &c->opt_timestamps},
652                 {"exclude",     'X', POPT_ARG_STRING, &c->opt_exclude},
653                 {"destination", 0, POPT_ARG_STRING,   &c->opt_destination},
654                 {"tallocreport", 0, POPT_ARG_NONE,    &c->do_talloc_report},
655                 /* Options for 'net rpc vampire (keytab)' */
656                 {"force-full-repl", 0, POPT_ARG_NONE, &c->opt_force_full_repl},
657                 {"single-obj-repl", 0, POPT_ARG_NONE, &c->opt_single_obj_repl},
658                 {"clean-old-entries", 0, POPT_ARG_NONE, &c->opt_clean_old_entries},
659
660                 POPT_COMMON_SAMBA
661                 { 0, 0, 0, 0}
662         };
663
664
665         zero_sockaddr(&c->opt_dest_ip);
666
667         load_case_tables();
668
669         /* set default debug level to 0 regardless of what smb.conf sets */
670         DEBUGLEVEL_CLASS[DBGC_ALL] = 0;
671         dbf = x_stderr;
672         c->private_data = net_func;
673
674         pc = poptGetContext(NULL, argc, (const char **) argv, long_options,
675                             POPT_CONTEXT_KEEP_FIRST);
676
677         while((opt = poptGetNextOpt(pc)) != -1) {
678                 switch (opt) {
679                 case 'h':
680                         c->display_usage = true;
681                         break;
682                 case 'e':
683                         c->smb_encrypt = true;
684                         break;
685                 case 'I':
686                         if (!interpret_string_addr(&c->opt_dest_ip,
687                                                 poptGetOptArg(pc), 0)) {
688                                 d_fprintf(stderr, "\nInvalid ip address specified\n");
689                         } else {
690                                 c->opt_have_ip = true;
691                         }
692                         break;
693                 case 'U':
694                         c->opt_user_specified = true;
695                         c->opt_user_name = SMB_STRDUP(c->opt_user_name);
696                         p = strchr(c->opt_user_name,'%');
697                         if (p) {
698                                 *p = 0;
699                                 c->opt_password = p+1;
700                         }
701                         break;
702                 default:
703                         d_fprintf(stderr, "\nInvalid option %s: %s\n",
704                                  poptBadOption(pc, 0), poptStrerror(opt));
705                         net_help(c, argc, argv);
706                         exit(1);
707                 }
708         }
709
710         /*
711          * Don't load debug level from smb.conf. It should be
712          * set by cmdline arg or remain default (0)
713          */
714         AllowDebugChange = false;
715         lp_load(get_dyn_CONFIGFILE(), true, false, false, true);
716
717         argv_new = (const char **)poptGetArgs(pc);
718
719         argc_new = argc;
720         for (i=0; i<argc; i++) {
721                 if (argv_new[i] == NULL) {
722                         argc_new = i;
723                         break;
724                 }
725         }
726
727         if (c->do_talloc_report) {
728                 talloc_enable_leak_report();
729         }
730
731         if (c->opt_requester_name) {
732                 set_global_myname(c->opt_requester_name);
733         }
734
735         if (!c->opt_user_name && getenv("LOGNAME")) {
736                 c->opt_user_name = getenv("LOGNAME");
737         }
738
739         if (!c->opt_workgroup) {
740                 c->opt_workgroup = smb_xstrdup(lp_workgroup());
741         }
742
743         if (!c->opt_target_workgroup) {
744                 c->opt_target_workgroup = smb_xstrdup(lp_workgroup());
745         }
746
747         if (!init_names())
748                 exit(1);
749
750         load_interfaces();
751
752         /* this makes sure that when we do things like call scripts,
753            that it won't assert becouse we are not root */
754         sec_init();
755
756         if (c->opt_machine_pass) {
757                 /* it is very useful to be able to make ads queries as the
758                    machine account for testing purposes and for domain leave */
759
760                 net_use_krb_machine_account(c);
761         }
762
763         if (!c->opt_password) {
764                 c->opt_password = getenv("PASSWD");
765         }
766
767         rc = net_run_function(c, argc_new-1, argv_new+1, "net", net_func);
768
769         DEBUG(2,("return code = %d\n", rc));
770
771         libnetapi_free(c->netapi_ctx);
772
773         poptFreeContext(pc);
774
775         TALLOC_FREE(frame);
776         return rc;
777 }