s3:libads: Add net ads leave keep-account option
[metze/samba/wip.git] / source3 / utils / net.c
1 /*
2    Samba Unix/Linux SMB client library
3    Distributed SMB/CIFS Server Management Utility
4    Copyright (C) 2001 Steve French  (sfrench@us.ibm.com)
5    Copyright (C) 2001 Jim McDonough (jmcd@us.ibm.com)
6    Copyright (C) 2001 Andrew Tridgell (tridge@samba.org)
7    Copyright (C) 2001 Andrew Bartlett (abartlet@samba.org)
8    Copyright (C) 2008 Kai Blin (kai@samba.org)
9
10    Originally written by Steve and Jim. Largely rewritten by tridge in
11    November 2001.
12
13    Reworked again by abartlet in December 2001
14
15    Another overhaul, moving functionality into plug-ins loaded on demand by Kai
16    in May 2008.
17
18    This program is free software; you can redistribute it and/or modify
19    it under the terms of the GNU General Public License as published by
20    the Free Software Foundation; either version 3 of the License, or
21    (at your option) any later version.
22
23    This program is distributed in the hope that it will be useful,
24    but WITHOUT ANY WARRANTY; without even the implied warranty of
25    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
26    GNU General Public License for more details.
27
28    You should have received a copy of the GNU General Public License
29    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
30
31 /*****************************************************/
32 /*                                                   */
33 /*   Distributed SMB/CIFS Server Management Utility  */
34 /*                                                   */
35 /*   The intent was to make the syntax similar       */
36 /*   to the NET utility (first developed in DOS      */
37 /*   with additional interesting & useful functions  */
38 /*   added in later SMB server network operating     */
39 /*   systems).                                       */
40 /*                                                   */
41 /*****************************************************/
42
43 #include "includes.h"
44 #include "popt_common.h"
45 #include "utils/net.h"
46 #include "secrets.h"
47 #include "lib/netapi/netapi.h"
48 #include "../libcli/security/security.h"
49 #include "passdb.h"
50 #include "messages.h"
51
52 #ifdef WITH_FAKE_KASERVER
53 #include "utils/net_afs.h"
54 #endif
55
56 /***********************************************************************/
57 /* end of internationalization section                                 */
58 /***********************************************************************/
59
60 enum netr_SchannelType get_sec_channel_type(const char *param)
61 {
62         if (!(param && *param)) {
63                 return get_default_sec_channel();
64         } else {
65                 if (strequal(param, "PDC")) {
66                         return SEC_CHAN_BDC;
67                 } else if (strequal(param, "BDC")) {
68                         return SEC_CHAN_BDC;
69                 } else if (strequal(param, "MEMBER")) {
70                         return SEC_CHAN_WKSTA;
71 #if 0
72                 } else if (strequal(param, "DOMAIN")) {
73                         return SEC_CHAN_DOMAIN;
74 #endif
75                 } else {
76                         return get_default_sec_channel();
77                 }
78         }
79 }
80
81 static int net_changetrustpw(struct net_context *c, int argc, const char **argv)
82 {
83         if (net_ads_check_our_domain(c) == 0)
84                 return net_ads_changetrustpw(c, argc, argv);
85
86         return net_rpc_changetrustpw(c, argc, argv);
87 }
88
89 static void set_line_buffering(FILE *f)
90 {
91         setvbuf(f, NULL, _IOLBF, 0);
92 }
93
94 static int net_primarytrust_dumpinfo(struct net_context *c, int argc,
95                                      const char **argv)
96 {
97         int role = lp_server_role();
98         const char *domain = lp_workgroup();
99         struct secrets_domain_info1 *info = NULL;
100         bool include_secrets = c->opt_force;
101         char *str = NULL;
102         NTSTATUS status;
103
104         if (role >= ROLE_ACTIVE_DIRECTORY_DC) {
105                 d_printf(_("net primarytrust dumpinfo is only supported "
106                          "on a DOMAIN_MEMBER for now.\n"));
107                 return 1;
108         }
109
110         if (c->opt_stdin) {
111                 set_line_buffering(stdin);
112                 set_line_buffering(stdout);
113                 set_line_buffering(stderr);
114         }
115
116         status = secrets_fetch_or_upgrade_domain_info(domain,
117                                                       talloc_tos(),
118                                                       &info);
119         if (!NT_STATUS_IS_OK(status)) {
120                 d_fprintf(stderr,
121                           _("Unable to fetch the information for domain[%s] "
122                           "in the secrets database.\n"),
123                           domain);
124                 return 1;
125         }
126
127         str = secrets_domain_info_string(info, info, domain, include_secrets);
128         if (str == NULL) {
129                 d_fprintf(stderr, "secrets_domain_info_string() failed.\n");
130                 return 1;
131         }
132
133         d_printf("%s", str);
134         if (!c->opt_force) {
135                 d_printf(_("The password values are only included using "
136                          "-f flag.\n"));
137         }
138
139         TALLOC_FREE(info);
140         return 0;
141 }
142
143 /**
144  * Entrypoint for 'net primarytrust' code.
145  *
146  * @param argc Standard argc.
147  * @param argv Standard argv without initial components.
148  *
149  * @return Integer status (0 means success).
150  */
151
152 static int net_primarytrust(struct net_context *c, int argc, const char **argv)
153 {
154         struct functable func[] = {
155                 {
156                         "dumpinfo",
157                         net_primarytrust_dumpinfo,
158                         NET_TRANSPORT_LOCAL,
159                         N_("Dump the details of the workstation trust"),
160                         N_("  net [options] primarytrust dumpinfo'\n"
161                            "    Dump the details of the workstation trust "
162                            "in secrets.tdb.\n"
163                            "    Requires the -f flag to include the password values.")
164                 },
165                 {NULL, NULL, 0, NULL, NULL}
166         };
167
168         return net_run_function(c, argc, argv, "net primarytrust", func);
169 }
170
171 static int net_changesecretpw(struct net_context *c, int argc,
172                               const char **argv)
173 {
174         char *trust_pw;
175         int role = lp_server_role();
176
177         if (role != ROLE_DOMAIN_MEMBER) {
178                 d_printf(_("Machine account password change only supported on a DOMAIN_MEMBER.\n"
179                            "Do NOT use this function unless you know what it does!\n"
180                            "This function will change the ADS Domain member "
181                            "machine account password in the secrets.tdb file!\n"));
182                 return 1;
183         }
184
185         if(c->opt_force) {
186                 struct secrets_domain_info1 *info = NULL;
187                 struct secrets_domain_info1_change *prev = NULL;
188                 NTSTATUS status;
189                 struct timeval tv = timeval_current();
190                 NTTIME now = timeval_to_nttime(&tv);
191
192                 if (c->opt_stdin) {
193                         set_line_buffering(stdin);
194                         set_line_buffering(stdout);
195                         set_line_buffering(stderr);
196                 }
197
198                 trust_pw = get_pass(_("Enter machine password: "), c->opt_stdin);
199                 if (trust_pw == NULL) {
200                             d_fprintf(stderr,
201                                       _("Error in reading machine password\n"));
202                             return 1;
203                 }
204
205                 status = secrets_prepare_password_change(lp_workgroup(),
206                                                          "localhost",
207                                                          trust_pw,
208                                                          talloc_tos(),
209                                                          &info, &prev);
210                 if (!NT_STATUS_IS_OK(status)) {
211                         d_fprintf(stderr,
212                                 _("Unable to write the machine account password in the secrets database"));
213                         return 1;
214                 }
215                 if (prev != NULL) {
216                         d_fprintf(stderr,
217                                 _("Pending machine account password change found - aborting."));
218                         status = secrets_failed_password_change("localhost",
219                                                 NT_STATUS_REQUEST_NOT_ACCEPTED,
220                                                 NT_STATUS_NOT_COMMITTED,
221                                                 info);
222                         if (!NT_STATUS_IS_OK(status)) {
223                                 d_fprintf(stderr,
224                                         _("Failed to abort machine account password change"));
225                         }
226                         return 1;
227                 }
228                 status = secrets_finish_password_change("localhost", now, info);
229                 if (!NT_STATUS_IS_OK(status)) {
230                         d_fprintf(stderr,
231                                 _("Unable to write the machine account password in the secrets database"));
232                         return 1;
233                 }
234
235                 d_printf(_("Modified trust account password in secrets database\n"));
236         }
237         else {
238                 d_printf(_("Machine account password change requires the -f flag.\n"
239                            "Do NOT use this function unless you know what it does!\n"
240                            "This function will change the ADS Domain member "
241                            "machine account password in the secrets.tdb file!\n"));
242         }
243
244         return 0;
245 }
246
247 /**
248  * @brief Set the authorised user for winbindd access in secrets.tdb
249  */
250 static int net_setauthuser(struct net_context *c, int argc, const char **argv)
251 {
252         const char *password = NULL;
253
254         if (!secrets_init()) {
255                 d_fprintf(stderr, _("Failed to open secrets.tdb.\n"));
256                 return 1;
257         }
258
259         /* Delete the settings. */
260         if (argc >= 1) {
261                 if (strncmp(argv[0], "delete", 6) != 0) {
262                         d_fprintf(stderr,_("Usage:\n"));
263                         d_fprintf(stderr,
264                                   _("    net setauthuser -U user[%%password] \n"
265                                     "        Set the auth user account to user"
266                                     "password. Prompt for password if not "
267                                     "specified.\n"));
268                         d_fprintf(stderr,
269                                   _("    net setauthuser delete\n"
270                                     "        Delete the auth user setting.\n"));
271                         return 1;
272                 }
273                 secrets_delete_entry(SECRETS_AUTH_USER);
274                 secrets_delete_entry(SECRETS_AUTH_DOMAIN);
275                 secrets_delete_entry(SECRETS_AUTH_PASSWORD);
276                 return 0;
277         }
278
279         if (!c->opt_user_specified) {
280                 d_fprintf(stderr, _("Usage:\n"));
281                 d_fprintf(stderr,
282                           _("    net setauthuser -U user[%%password]\n"
283                             "        Set the auth user account to user"
284                             "password. Prompt for password if not "
285                             "specified.\n"));
286                 d_fprintf(stderr,
287                           _("    net setauthuser delete\n"
288                             "        Delete the auth user setting.\n"));
289                 return 1;
290         }
291
292         password = net_prompt_pass(c, _("the auth user"));
293         if (password == NULL) {
294                 d_fprintf(stderr,_("Failed to get the auth users password.\n"));
295                 return 1;
296         }
297
298         if (!secrets_store(SECRETS_AUTH_USER, c->opt_user_name,
299                            strlen(c->opt_user_name) + 1)) {
300                 d_fprintf(stderr, _("error storing auth user name\n"));
301                 return 1;
302         }
303
304         if (!secrets_store(SECRETS_AUTH_DOMAIN, c->opt_workgroup,
305                            strlen(c->opt_workgroup) + 1)) {
306                 d_fprintf(stderr, _("error storing auth user domain\n"));
307                 return 1;
308         }
309
310         if (!secrets_store(SECRETS_AUTH_PASSWORD, password,
311                            strlen(password) + 1)) {
312                 d_fprintf(stderr, _("error storing auth user password\n"));
313                 return 1;
314         }
315
316         return 0;
317 }
318
319 /**
320  * @brief Get the auth user settings
321  */
322 static int net_getauthuser(struct net_context *c, int argc, const char **argv)
323 {
324         char *user, *domain, *password;
325
326         /* Lift data from secrets file */
327
328         secrets_fetch_ipc_userpass(&user, &domain, &password);
329
330         if ((!user || !*user) && (!domain || !*domain ) &&
331             (!password || !*password)){
332
333                 SAFE_FREE(user);
334                 SAFE_FREE(domain);
335                 SAFE_FREE(password);
336                 d_printf(_("No authorised user configured\n"));
337                 return 0;
338         }
339
340         /* Pretty print authorised user info */
341
342         d_printf("%s%s%s%s%s\n", domain ? domain : "",
343                  domain ? lp_winbind_separator(): "", user,
344                  password ? "%" : "", password ? password : "");
345
346         SAFE_FREE(user);
347         SAFE_FREE(domain);
348         SAFE_FREE(password);
349
350         return 0;
351 }
352 /*
353  Retrieve our local SID or the SID for the specified name
354  */
355 static int net_getlocalsid(struct net_context *c, int argc, const char **argv)
356 {
357         struct dom_sid sid;
358         const char *name;
359         fstring sid_str;
360
361         if (argc >= 1) {
362                 name = argv[0];
363         }
364         else {
365                 name = lp_netbios_name();
366         }
367
368         if(!initialize_password_db(false, NULL)) {
369                 d_fprintf(stderr, _("WARNING: Could not open passdb\n"));
370                 return 1;
371         }
372
373         /* first check to see if we can even access secrets, so we don't
374            panic when we can't. */
375
376         if (!secrets_init()) {
377                 d_fprintf(stderr,
378                           _("Unable to open secrets.tdb.  Can't fetch domain "
379                             "SID for name: %s\n"), name);
380                 return 1;
381         }
382
383         /* Generate one, if it doesn't exist */
384         get_global_sam_sid();
385
386         if (!secrets_fetch_domain_sid(name, &sid)) {
387                 DEBUG(0, ("Can't fetch domain SID for name: %s\n", name));
388                 return 1;
389         }
390         sid_to_fstring(sid_str, &sid);
391         d_printf(_("SID for domain %s is: %s\n"), name, sid_str);
392         return 0;
393 }
394
395 static int net_setlocalsid(struct net_context *c, int argc, const char **argv)
396 {
397         struct dom_sid sid;
398
399         if ( (argc != 1)
400              || (strncmp(argv[0], "S-1-5-21-", strlen("S-1-5-21-")) != 0)
401              || (!string_to_sid(&sid, argv[0]))
402              || (sid.num_auths != 4)) {
403                 d_printf(_("Usage:"));
404                 d_printf(" net setlocalsid S-1-5-21-x-y-z\n");
405                 return 1;
406         }
407
408         if (!secrets_store_domain_sid(lp_netbios_name(), &sid)) {
409                 DEBUG(0,("Can't store domain SID as a pdc/bdc.\n"));
410                 return 1;
411         }
412
413         return 0;
414 }
415
416 static int net_setdomainsid(struct net_context *c, int argc, const char **argv)
417 {
418         struct dom_sid sid;
419
420         if ( (argc != 1)
421              || (strncmp(argv[0], "S-1-5-21-", strlen("S-1-5-21-")) != 0)
422              || (!string_to_sid(&sid, argv[0]))
423              || (sid.num_auths != 4)) {
424                 d_printf(_("Usage:"));
425                 d_printf(" net setdomainsid S-1-5-21-x-y-z\n");
426                 return 1;
427         }
428
429         if (!secrets_store_domain_sid(lp_workgroup(), &sid)) {
430                 DEBUG(0,("Can't store domain SID.\n"));
431                 return 1;
432         }
433
434         return 0;
435 }
436
437 static int net_getdomainsid(struct net_context *c, int argc, const char **argv)
438 {
439         struct dom_sid domain_sid;
440         fstring sid_str;
441
442         if (argc > 0) {
443                 d_printf(_("Usage:"));
444                 d_printf(" net getdomainsid\n");
445                 return 1;
446         }
447
448         if(!initialize_password_db(false, NULL)) {
449                 d_fprintf(stderr, _("WARNING: Could not open passdb\n"));
450                 return 1;
451         }
452
453         /* first check to see if we can even access secrets, so we don't
454            panic when we can't. */
455
456         if (!secrets_init()) {
457                 d_fprintf(stderr, _("Unable to open secrets.tdb.  Can't fetch "
458                                     "domain SID for name: %s\n"),
459                           get_global_sam_name());
460                 return 1;
461         }
462
463         /* Generate one, if it doesn't exist */
464         get_global_sam_sid();
465
466         if (!IS_DC) {
467                 if (!secrets_fetch_domain_sid(lp_netbios_name(), &domain_sid)) {
468                         d_fprintf(stderr, _("Could not fetch local SID\n"));
469                         return 1;
470                 }
471                 sid_to_fstring(sid_str, &domain_sid);
472                 d_printf(_("SID for local machine %s is: %s\n"),
473                          lp_netbios_name(), sid_str);
474         }
475         if (!secrets_fetch_domain_sid(c->opt_workgroup, &domain_sid)) {
476                 d_fprintf(stderr, _("Could not fetch domain SID\n"));
477                 return 1;
478         }
479
480         sid_to_fstring(sid_str, &domain_sid);
481         d_printf(_("SID for domain %s is: %s\n"), c->opt_workgroup, sid_str);
482
483         return 0;
484 }
485
486 static bool search_maxrid(struct pdb_search *search, const char *type,
487                           uint32_t *max_rid)
488 {
489         struct samr_displayentry *entries;
490         uint32_t i, num_entries;
491
492         if (search == NULL) {
493                 d_fprintf(stderr, _("get_maxrid: Could not search %s\n"), type);
494                 return false;
495         }
496
497         num_entries = pdb_search_entries(search, 0, 0xffffffff, &entries);
498         for (i=0; i<num_entries; i++)
499                 *max_rid = MAX(*max_rid, entries[i].rid);
500         TALLOC_FREE(search);
501         return true;
502 }
503
504 static uint32_t get_maxrid(void)
505 {
506         uint32_t max_rid = 0;
507
508         if (!search_maxrid(pdb_search_users(talloc_tos(), 0), "users", &max_rid))
509                 return 0;
510
511         if (!search_maxrid(pdb_search_groups(talloc_tos()), "groups", &max_rid))
512                 return 0;
513
514         if (!search_maxrid(pdb_search_aliases(talloc_tos(),
515                                               get_global_sam_sid()),
516                            "aliases", &max_rid))
517                 return 0;
518
519         return max_rid;
520 }
521
522 static int net_maxrid(struct net_context *c, int argc, const char **argv)
523 {
524         uint32_t rid;
525
526         if (argc != 0) {
527                 d_fprintf(stderr, "%s net maxrid\n", _("Usage:"));
528                 return 1;
529         }
530
531         if ((rid = get_maxrid()) == 0) {
532                 d_fprintf(stderr, _("can't get current maximum rid\n"));
533                 return 1;
534         }
535
536         d_printf(_("Currently used maximum rid: %d\n"), rid);
537
538         return 0;
539 }
540
541 /* main function table */
542 static struct functable net_func[] = {
543         {
544                 "rpc",
545                 net_rpc,
546                 NET_TRANSPORT_RPC,
547                 N_("Run functions using RPC transport"),
548                 N_("  Use 'net help rpc' to get more extensive information "
549                    "about 'net rpc' commands.")
550         },
551         {
552                 "rap",
553                 net_rap,
554                 NET_TRANSPORT_RAP,
555                 N_("Run functions using RAP transport"),
556                 N_("  Use 'net help rap' to get more extensive information "
557                    "about 'net rap' commands.")
558         },
559         {
560                 "ads",
561                 net_ads,
562                 NET_TRANSPORT_ADS,
563                 N_("Run functions using ADS transport"),
564                 N_("  Use 'net help ads' to get more extensive information "
565                    "about 'net ads' commands.")
566         },
567
568         /* eventually these should auto-choose the transport ... */
569         {
570                 "file",
571                 net_file,
572                 NET_TRANSPORT_RPC | NET_TRANSPORT_RAP,
573                 N_("Functions on remote opened files"),
574                 N_("  Use 'net help file' to get more information about 'net "
575                    "file' commands.")
576         },
577         {
578                 "share",
579                 net_share,
580                 NET_TRANSPORT_RPC | NET_TRANSPORT_RAP,
581                 N_("Functions on shares"),
582                 N_("  Use 'net help share' to get more information about 'net "
583                    "share' commands.")
584         },
585         {
586                 "session",
587                 net_rap_session,
588                 NET_TRANSPORT_RAP,
589                 N_("Manage sessions"),
590                 N_("  Use 'net help session' to get more information about "
591                    "'net session' commands.")
592         },
593         {
594                 "server",
595                 net_rap_server,
596                 NET_TRANSPORT_RAP,
597                 N_("List servers in workgroup"),
598                 N_("  Use 'net help server' to get more information about 'net "
599                    "server' commands.")
600         },
601         {
602                 "domain",
603                 net_rap_domain,
604                 NET_TRANSPORT_RAP,
605                 N_("List domains/workgroups on network"),
606                 N_("  Use 'net help domain' to get more information about 'net "
607                    "domain' commands.")
608         },
609         {
610                 "printq",
611                 net_rap_printq,
612                 NET_TRANSPORT_RAP,
613                 N_("Modify printer queue"),
614                 N_("  Use 'net help printq' to get more information about 'net "
615                    "printq' commands.")
616         },
617         {
618                 "user",
619                 net_user,
620                 NET_TRANSPORT_ADS | NET_TRANSPORT_RPC | NET_TRANSPORT_RAP,
621                 N_("Manage users"),
622                 N_("  Use 'net help user' to get more information about 'net "
623                    "user' commands.")
624         },
625         {
626                 "group",
627                 net_group,
628                 NET_TRANSPORT_ADS | NET_TRANSPORT_RPC | NET_TRANSPORT_RAP,
629                 N_("Manage groups"),
630                 N_("  Use 'net help group' to get more information about 'net "
631                    "group' commands.")
632         },
633         {
634                 "groupmap",
635                 net_groupmap,
636                 NET_TRANSPORT_LOCAL,
637                 N_("Manage group mappings"),
638                 N_("  Use 'net help groupmap' to get more information about "
639                    "'net groupmap' commands.")
640         },
641         {
642                 "sam",
643                 net_sam,
644                 NET_TRANSPORT_LOCAL,
645                 N_("Functions on the SAM database"),
646                 N_("  Use 'net help sam' to get more information about 'net "
647                    "sam' commands.")
648         },
649         {
650                 "validate",
651                 net_rap_validate,
652                 NET_TRANSPORT_RAP,
653                 N_("Validate username and password"),
654                 N_("  Use 'net help validate' to get more information about "
655                    "'net validate' commands.")
656         },
657         {
658                 "groupmember",
659                 net_rap_groupmember,
660                 NET_TRANSPORT_RAP,
661                 N_("Modify group memberships"),
662                 N_("  Use 'net help groupmember' to get more information about "
663                    "'net groupmember' commands.")
664         },
665         {       "admin",
666                 net_rap_admin,
667                 NET_TRANSPORT_RAP,
668                 N_("Execute remote command on a remote OS/2 server"),
669                 N_("  Use 'net help admin' to get more information about 'net "
670                    "admin' commands.")
671         },
672         {       "service",
673                 net_rap_service,
674                 NET_TRANSPORT_RAP,
675                 N_("List/modify running services"),
676                 N_("  Use 'net help service' to get more information about "
677                    "'net service' commands.")
678         },
679         {
680                 "password",
681                 net_rap_password,
682                 NET_TRANSPORT_RAP,
683                 N_("Change user password on target server"),
684                 N_("  Use 'net help password' to get more information about "
685                    "'net password' commands.")
686         },
687         {
688                 "primarytrust",
689                 net_primarytrust,
690                 NET_TRANSPORT_RPC,
691                 N_("Run functions related to the primary workstation trust."),
692                 N_("  Use 'net help primarytrust' to get more extensive information "
693                    "about 'net primarytrust' commands.")
694         },
695         {       "changetrustpw",
696                 net_changetrustpw,
697                 NET_TRANSPORT_ADS | NET_TRANSPORT_RPC,
698                 N_("Change the trust password"),
699                 N_("  Use 'net help changetrustpw' to get more information "
700                    "about 'net changetrustpw'.")
701         },
702         {       "changesecretpw",
703                 net_changesecretpw,
704                 NET_TRANSPORT_LOCAL,
705                 N_("Change the secret password"),
706                 N_("  net [options] changesecretpw\n"
707                    "    Change the ADS domain member machine account password "
708                    "in secrets.tdb.\n"
709                    "    Do NOT use this function unless you know what it does.\n"
710                    "    Requires the -f flag to work.")
711         },
712         {
713                 "setauthuser",
714                 net_setauthuser,
715                 NET_TRANSPORT_LOCAL,
716                 N_("Set the winbind auth user"),
717                 N_("  net -U user[%%password] [-W domain] setauthuser\n"
718                    "    Set the auth user, password (and optionally domain\n"
719                    "    Will prompt for password if not given.\n"
720                    "  net setauthuser delete\n"
721                    "    Delete the existing auth user settings.")
722         },
723         {
724                 "getauthuser",
725                 net_getauthuser,
726                 NET_TRANSPORT_LOCAL,
727                 N_("Get the winbind auth user settings"),
728                 N_("  net getauthuser\n"
729                    "    Get the current winbind auth user settings.")
730         },
731         {       "time",
732                 net_time,
733                 NET_TRANSPORT_LOCAL,
734                 N_("Show/set time"),
735                 N_("  Use 'net help time' to get more information about 'net "
736                    "time' commands.")
737         },
738         {       "lookup",
739                 net_lookup,
740                 NET_TRANSPORT_LOCAL,
741                 N_("Look up host names/IP addresses"),
742                 N_("  Use 'net help lookup' to get more information about 'net "
743                    "lookup' commands.")
744         },
745         {       "g_lock",
746                 net_g_lock,
747                 NET_TRANSPORT_LOCAL,
748                 N_("Manipulate the global lock table"),
749                 N_("  Use 'net help g_lock' to get more information about "
750                    "'net g_lock' commands.")
751         },
752         {       "join",
753                 net_join,
754                 NET_TRANSPORT_ADS | NET_TRANSPORT_RPC,
755                 N_("Join a domain/AD"),
756                 N_("  Use 'net help join' to get more information about 'net "
757                    "join'.")
758         },
759         {       "dom",
760                 net_dom,
761                 NET_TRANSPORT_LOCAL,
762                 N_("Join/unjoin (remote) machines to/from a domain/AD"),
763                 N_("  Use 'net help dom' to get more information about 'net "
764                    "dom' commands.")
765         },
766         {       "cache",
767                 net_cache,
768                 NET_TRANSPORT_LOCAL,
769                 N_("Operate on the cache tdb file"),
770                 N_("  Use 'net help cache' to get more information about 'net "
771                    "cache' commands.")
772         },
773         {       "getlocalsid",
774                 net_getlocalsid,
775                 NET_TRANSPORT_LOCAL,
776                 N_("Get the SID for the local domain"),
777                 N_("  net getlocalsid")
778         },
779         {       "setlocalsid",
780                 net_setlocalsid,
781                 NET_TRANSPORT_LOCAL,
782                 N_("Set the SID for the local domain"),
783                 N_("  net setlocalsid S-1-5-21-x-y-z")
784         },
785         {       "setdomainsid",
786                 net_setdomainsid,
787                 NET_TRANSPORT_LOCAL,
788                 N_("Set domain SID on member servers"),
789                 N_("  net setdomainsid S-1-5-21-x-y-z")
790         },
791         {       "getdomainsid",
792                 net_getdomainsid,
793                 NET_TRANSPORT_LOCAL,
794                 N_("Get domain SID on member servers"),
795                 N_("  net getdomainsid")
796         },
797         {       "maxrid",
798                 net_maxrid,
799                 NET_TRANSPORT_LOCAL,
800                 N_("Display the maximum RID currently used"),
801                 N_("  net maxrid")
802         },
803         {       "idmap",
804                 net_idmap,
805                 NET_TRANSPORT_LOCAL,
806                 N_("IDmap functions"),
807                 N_("  Use 'net help idmap to get more information about 'net "
808                   "idmap' commands.")
809         },
810         {       "status",
811                 net_status,
812                 NET_TRANSPORT_LOCAL,
813                 N_("Display server status"),
814                 N_("  Use 'net help status' to get more information about 'net "
815                    "status' commands.")
816         },
817         {       "usershare",
818                 net_usershare,
819                 NET_TRANSPORT_LOCAL,
820                 N_("Manage user-modifiable shares"),
821                 N_("  Use 'net help usershare to get more information about "
822                    "'net usershare' commands.")
823         },
824         {       "usersidlist",
825                 net_usersidlist,
826                 NET_TRANSPORT_RPC,
827                 N_("Display list of all users with SID"),
828                 N_("  Use 'net help usersidlist' to get more information about "
829                    "'net usersidlist'.")
830         },
831         {       "conf",
832                 net_conf,
833                 NET_TRANSPORT_LOCAL,
834                 N_("Manage Samba registry based configuration"),
835                 N_("  Use 'net help conf' to get more information about 'net "
836                    "conf' commands.")
837         },
838         {       "registry",
839                 net_registry,
840                 NET_TRANSPORT_LOCAL,
841                 N_("Manage the Samba registry"),
842                 N_("  Use 'net help registry' to get more information about "
843                    "'net registry' commands.")
844         },
845         {       "eventlog",
846                 net_eventlog,
847                 NET_TRANSPORT_LOCAL,
848                 N_("Process Win32 *.evt eventlog files"),
849                 N_("  Use 'net help eventlog' to get more information about "
850                    "'net eventlog' commands.")
851         },
852         {       "printing",
853                 net_printing,
854                 NET_TRANSPORT_LOCAL,
855                 N_("Process tdb printer files"),
856                 N_("  Use 'net help printing' to get more information about "
857                    "'net printing' commands.")
858         },
859
860         {       "serverid",
861                 net_serverid,
862                 NET_TRANSPORT_LOCAL,
863                 N_("Manage the serverid tdb"),
864                 N_("  Use 'net help serverid' to get more information about "
865                    "'net serverid' commands.")
866         },
867
868         {       "notify",
869                 net_notify,
870                 NET_TRANSPORT_LOCAL,
871                 N_("notifyd client code"),
872                 N_("  Use 'net help notify' to get more information about "
873                    "'net notify' commands.")
874         },
875
876         {       "tdb",
877                 net_tdb,
878                 NET_TRANSPORT_LOCAL,
879                 N_("Show information from tdb records"),
880                 N_("  Use 'net help tdb' to get more information about "
881                    "'net tdb' commands.")
882         },
883
884 #ifdef WITH_FAKE_KASERVER
885         {       "afs",
886                 net_afs,
887                 NET_TRANSPORT_LOCAL,
888                 N_("Manage AFS tokens"),
889                 N_("  Use 'net help afs' to get more information about 'net "
890                    "afs' commands.")
891         },
892 #endif
893
894         {       "help",
895                 net_help,
896                 NET_TRANSPORT_LOCAL,
897                 N_("Print usage information"),
898                 N_("  Use 'net help help' to list usage information for 'net' "
899                    "commands.")
900         },
901         {NULL, NULL, 0, NULL, NULL}
902 };
903
904
905 /****************************************************************************
906   main program
907 ****************************************************************************/
908  int main(int argc, char **argv)
909 {
910         int opt,i;
911         char *p;
912         int rc = 0;
913         int argc_new = 0;
914         const char ** argv_new;
915         const char **argv_const = discard_const_p(const char *, argv);
916         poptContext pc;
917         TALLOC_CTX *frame = talloc_stackframe();
918         struct tevent_context *ev;
919         struct net_context *c = talloc_zero(frame, struct net_context);
920         NTSTATUS status;
921
922         struct poptOption long_options[] = {
923                 {"help",        'h', POPT_ARG_NONE,   0, 'h'},
924                 {"workgroup",   'w', POPT_ARG_STRING, &c->opt_target_workgroup},
925                 {"user",        'U', POPT_ARG_STRING, &c->opt_user_name, 'U'},
926                 {"ipaddress",   'I', POPT_ARG_STRING, 0,'I'},
927                 {"port",        'p', POPT_ARG_INT,    &c->opt_port},
928                 {"myname",      'n', POPT_ARG_STRING, &c->opt_requester_name},
929                 {"server",      'S', POPT_ARG_STRING, &c->opt_host},
930                 {"encrypt",     'e', POPT_ARG_NONE,   NULL, 'e', N_("Encrypt SMB transport") },
931                 {"container",   'c', POPT_ARG_STRING, &c->opt_container},
932                 {"comment",     'C', POPT_ARG_STRING, &c->opt_comment},
933                 {"maxusers",    'M', POPT_ARG_INT,    &c->opt_maxusers},
934                 {"flags",       'F', POPT_ARG_INT,    &c->opt_flags},
935                 {"long",        'l', POPT_ARG_NONE,   &c->opt_long_list_entries},
936                 {"reboot",      'r', POPT_ARG_NONE,   &c->opt_reboot},
937                 {"force",       'f', POPT_ARG_NONE,   &c->opt_force},
938                 {"stdin",       'i', POPT_ARG_NONE,   &c->opt_stdin},
939                 {"timeout",     't', POPT_ARG_INT,    &c->opt_timeout},
940                 {"request-timeout",0,POPT_ARG_INT,    &c->opt_request_timeout},
941                 {"machine-pass",'P', POPT_ARG_NONE,   &c->opt_machine_pass},
942                 {"kerberos",    'k', POPT_ARG_NONE,   &c->opt_kerberos},
943                 {"myworkgroup", 'W', POPT_ARG_STRING, &c->opt_workgroup},
944                 {"use-ccache",    0, POPT_ARG_NONE,   &c->opt_ccache},
945                 {"verbose",     'v', POPT_ARG_NONE,   &c->opt_verbose},
946                 {"test",        'T', POPT_ARG_NONE,   &c->opt_testmode},
947                 /* Options for 'net groupmap set' */
948                 {"local",       'L', POPT_ARG_NONE,   &c->opt_localgroup},
949                 {"domain",      'D', POPT_ARG_NONE,   &c->opt_domaingroup},
950                 {"ntname",      'N', POPT_ARG_STRING, &c->opt_newntname},
951                 {"rid",         'R', POPT_ARG_INT,    &c->opt_rid},
952                 /* Options for 'net rpc share migrate' */
953                 {"acls",        0, POPT_ARG_NONE,     &c->opt_acls},
954                 {"attrs",       0, POPT_ARG_NONE,     &c->opt_attrs},
955                 {"timestamps",  0, POPT_ARG_NONE,     &c->opt_timestamps},
956                 {"exclude",     'X', POPT_ARG_STRING, &c->opt_exclude},
957                 {"destination", 0, POPT_ARG_STRING,   &c->opt_destination},
958                 {"tallocreport", 0, POPT_ARG_NONE,    &c->do_talloc_report},
959                 /* Options for 'net rpc vampire (keytab)' */
960                 {"force-full-repl", 0, POPT_ARG_NONE, &c->opt_force_full_repl},
961                 {"single-obj-repl", 0, POPT_ARG_NONE, &c->opt_single_obj_repl},
962                 {"clean-old-entries", 0, POPT_ARG_NONE, &c->opt_clean_old_entries},
963                 /* Options for 'net idmap'*/
964                 {"db", 0, POPT_ARG_STRING, &c->opt_db},
965                 {"lock", 0, POPT_ARG_NONE,   &c->opt_lock},
966                 {"auto", 'a', POPT_ARG_NONE,   &c->opt_auto},
967                 {"repair", 0, POPT_ARG_NONE,   &c->opt_repair},
968                 /* Options for 'net registry check'*/
969                 {"reg-version", 0, POPT_ARG_INT, &c->opt_reg_version},
970                 {"output", 'o', POPT_ARG_STRING, &c->opt_output},
971                 {"wipe", 0, POPT_ARG_NONE, &c->opt_wipe},
972                 /* Options for 'net registry import' */
973                 {"precheck", 0, POPT_ARG_STRING, &c->opt_precheck},
974                 /* Options for 'net ads join or leave' */
975                 {"no-dns-updates", 0, POPT_ARG_NONE, &c->opt_no_dns_updates},
976                 {"keep-account", 0, POPT_ARG_NONE, &c->opt_keep_account},
977                 POPT_COMMON_SAMBA
978                 { 0, 0, 0, 0}
979         };
980
981         zero_sockaddr(&c->opt_dest_ip);
982
983         setup_logging(argv[0], DEBUG_STDERR);
984
985         smb_init_locale();
986
987         setlocale(LC_ALL, "");
988 #if defined(HAVE_BINDTEXTDOMAIN)
989         bindtextdomain(MODULE_NAME, get_dyn_LOCALEDIR());
990 #endif
991 #if defined(HAVE_TEXTDOMAIN)
992         textdomain(MODULE_NAME);
993 #endif
994
995         /* set default debug level to 0 regardless of what smb.conf sets */
996         lp_set_cmdline("log level", "0");
997         c->private_data = net_func;
998
999         pc = poptGetContext(NULL, argc, argv_const, long_options,
1000                             POPT_CONTEXT_KEEP_FIRST);
1001
1002         while((opt = poptGetNextOpt(pc)) != -1) {
1003                 switch (opt) {
1004                 case 'h':
1005                         c->display_usage = true;
1006                         break;
1007                 case 'e':
1008                         c->smb_encrypt = true;
1009                         break;
1010                 case 'I':
1011                         if (!interpret_string_addr(&c->opt_dest_ip,
1012                                                 poptGetOptArg(pc), 0)) {
1013                                 d_fprintf(stderr, _("\nInvalid ip address specified\n"));
1014                         } else {
1015                                 c->opt_have_ip = true;
1016                         }
1017                         break;
1018                 case 'U':
1019                         c->opt_user_specified = true;
1020                         c->opt_user_name = talloc_strdup(c, c->opt_user_name);
1021                         p = strchr(c->opt_user_name,'%');
1022                         if (p) {
1023                                 *p = 0;
1024                                 c->opt_password = p+1;
1025                         }
1026                         break;
1027                 default:
1028                         d_fprintf(stderr, _("\nInvalid option %s: %s\n"),
1029                                  poptBadOption(pc, 0), poptStrerror(opt));
1030                         net_help(c, argc, argv_const);
1031                         exit(1);
1032                 }
1033         }
1034
1035         if (!lp_load_initial_only(get_dyn_CONFIGFILE())) {
1036                 d_fprintf(stderr, "Can't load %s - run testparm to debug it\n",
1037                           get_dyn_CONFIGFILE());
1038                 exit(1);
1039         }
1040
1041         ev = samba_tevent_context_init(c);
1042         if (ev == NULL) {
1043                 d_fprintf(stderr, "samba_tevent_context_init failed\n");
1044                 exit(1);
1045         }
1046         status = messaging_init_client(c, ev, &c->msg_ctx);
1047         if (geteuid() != 0 &&
1048                         NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
1049                 /*
1050                  * Normal to fail to initialize messaging context
1051                  * if we're not root as we don't have ability to
1052                  * read lock directory.
1053                  */
1054                 DBG_NOTICE("Unable to initialize messaging context. "
1055                         "Must be root to do that.\n");
1056         } else if (!NT_STATUS_IS_OK(status)) {
1057                 d_fprintf(stderr, "Failed to init messaging context\n");
1058                 exit(1);
1059         }
1060
1061         if (!lp_load_global(get_dyn_CONFIGFILE())) {
1062                 d_fprintf(stderr, "Can't load %s - run testparm to debug it\n",
1063                           get_dyn_CONFIGFILE());
1064                 exit(1);
1065         }
1066
1067 #if defined(HAVE_BIND_TEXTDOMAIN_CODESET)
1068         /* Bind our gettext results to 'unix charset'
1069            
1070            This ensures that the translations and any embedded strings are in the
1071            same charset.  It won't be the one from the user's locale (we no
1072            longer auto-detect that), but it will be self-consistent.
1073         */
1074         bind_textdomain_codeset(MODULE_NAME, lp_unix_charset());
1075 #endif
1076
1077         argv_new = (const char **)poptGetArgs(pc);
1078
1079         argc_new = argc;
1080         for (i=0; i<argc; i++) {
1081                 if (argv_new[i] == NULL) {
1082                         argc_new = i;
1083                         break;
1084                 }
1085         }
1086
1087         if (c->do_talloc_report) {
1088                 talloc_enable_leak_report();
1089         }
1090
1091         if (c->opt_requester_name) {
1092                 lp_set_cmdline("netbios name", c->opt_requester_name);
1093         }
1094
1095         if (!c->opt_user_name && getenv("LOGNAME")) {
1096                 c->opt_user_name = getenv("LOGNAME");
1097         }
1098
1099         if (!c->opt_workgroup) {
1100                 c->opt_workgroup = talloc_strdup(c, lp_workgroup());
1101         }
1102
1103         if (!c->opt_target_workgroup) {
1104                 c->opt_target_workgroup = talloc_strdup(c, lp_workgroup());
1105         }
1106
1107         if (!init_names())
1108                 exit(1);
1109
1110         load_interfaces();
1111
1112         /* this makes sure that when we do things like call scripts,
1113            that it won't assert because we are not root */
1114         sec_init();
1115
1116         if (c->opt_machine_pass) {
1117                 /* it is very useful to be able to make ads queries as the
1118                    machine account for testing purposes and for domain leave */
1119
1120                 net_use_krb_machine_account(c);
1121         }
1122
1123         if (!c->opt_password) {
1124                 c->opt_password = getenv("PASSWD");
1125         }
1126
1127         popt_burn_cmdline_password(argc, argv);
1128
1129         rc = net_run_function(c, argc_new-1, argv_new+1, "net", net_func);
1130
1131         DEBUG(2,("return code = %d\n", rc));
1132
1133         gencache_stabilize();
1134
1135         libnetapi_free(c->netapi_ctx);
1136
1137         poptFreeContext(pc);
1138
1139         TALLOC_FREE(frame);
1140         return rc;
1141 }