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