s3:util:net_registry: registry_value_cmp() uses NUMERIC_CMP()
[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 "lib/cmdline/cmdline.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 #include "cmdline_contexts.h"
52 #include "lib/gencache.h"
53 #include "auth/credentials/credentials.h"
54 #include "source3/utils/passwd_proto.h"
55 #include "auth/gensec/gensec.h"
56 #include "lib/param/param.h"
57
58 #ifdef WITH_FAKE_KASERVER
59 #include "utils/net_afs.h"
60 #endif
61
62 /***********************************************************************/
63 /* end of internationalization section                                 */
64 /***********************************************************************/
65
66 enum netr_SchannelType get_sec_channel_type(const char *param)
67 {
68         if (!(param && *param)) {
69                 return get_default_sec_channel();
70         } else {
71                 if (strequal(param, "PDC")) {
72                         return SEC_CHAN_BDC;
73                 } else if (strequal(param, "BDC")) {
74                         return SEC_CHAN_BDC;
75                 } else if (strequal(param, "MEMBER")) {
76                         return SEC_CHAN_WKSTA;
77 #if 0
78                 } else if (strequal(param, "DOMAIN")) {
79                         return SEC_CHAN_DOMAIN;
80 #endif
81                 } else {
82                         return get_default_sec_channel();
83                 }
84         }
85 }
86
87 static int net_changetrustpw(struct net_context *c, int argc, const char **argv)
88 {
89         net_warn_member_options();
90
91         if (net_ads_check_our_domain(c) == 0)
92                 return net_ads_changetrustpw(c, argc, argv);
93
94         return net_rpc_changetrustpw(c, argc, argv);
95 }
96
97 static void set_line_buffering(FILE *f)
98 {
99         setvbuf(f, NULL, _IOLBF, 0);
100 }
101
102 static int net_primarytrust_dumpinfo(struct net_context *c, int argc,
103                                      const char **argv)
104 {
105         int role = lp_server_role();
106         const char *domain = lp_workgroup();
107         struct secrets_domain_info1 *info = NULL;
108         bool include_secrets = c->opt_force;
109         char *str = NULL;
110         NTSTATUS status;
111
112         if (role >= ROLE_ACTIVE_DIRECTORY_DC) {
113                 d_printf(_("net primarytrust dumpinfo is only supported "
114                          "on a DOMAIN_MEMBER for now.\n"));
115                 return 1;
116         }
117
118         net_warn_member_options();
119
120         if (c->opt_stdin) {
121                 set_line_buffering(stdin);
122                 set_line_buffering(stdout);
123                 set_line_buffering(stderr);
124         }
125
126         status = secrets_fetch_or_upgrade_domain_info(domain,
127                                                       talloc_tos(),
128                                                       &info);
129         if (!NT_STATUS_IS_OK(status)) {
130                 d_fprintf(stderr,
131                           _("Unable to fetch the information for domain[%s] "
132                           "in the secrets database.\n"),
133                           domain);
134                 return 1;
135         }
136
137         str = secrets_domain_info_string(info, info, domain, include_secrets);
138         if (str == NULL) {
139                 d_fprintf(stderr, "secrets_domain_info_string() failed.\n");
140                 return 1;
141         }
142
143         d_printf("%s", str);
144         if (!c->opt_force) {
145                 d_printf(_("The password values are only included using "
146                          "-f flag.\n"));
147         }
148
149         TALLOC_FREE(info);
150         return 0;
151 }
152
153 /**
154  * Entrypoint for 'net primarytrust' code.
155  *
156  * @param argc Standard argc.
157  * @param argv Standard argv without initial components.
158  *
159  * @return Integer status (0 means success).
160  */
161
162 static int net_primarytrust(struct net_context *c, int argc, const char **argv)
163 {
164         struct functable func[] = {
165                 {
166                         .funcname         = "dumpinfo",
167                         .fn               = net_primarytrust_dumpinfo,
168                         .valid_transports = NET_TRANSPORT_LOCAL,
169                         .description      = N_("Dump the details of the "
170                                                "workstation trust"),
171                         .usage            = N_("  net [options] primarytrust "
172                                                "dumpinfo'\n"
173                                                "    Dump the details of the "
174                                                "workstation trust in "
175                                                "secrets.tdb.\n"
176                                                "    Requires the -f flag to "
177                                                "include the password values."),
178                 },
179                 {
180                         .funcname = NULL,
181                 },
182         };
183
184         return net_run_function(c, argc, argv, "net primarytrust", func);
185 }
186
187 static int net_changesecretpw(struct net_context *c, int argc,
188                               const char **argv)
189 {
190         char *trust_pw;
191         int role = lp_server_role();
192
193         if (role != ROLE_DOMAIN_MEMBER) {
194                 d_printf(_("Machine account password change only supported on a DOMAIN_MEMBER.\n"
195                            "Do NOT use this function unless you know what it does!\n"
196                            "This function will change the ADS Domain member "
197                            "machine account password in the secrets.tdb file!\n"));
198                 return 1;
199         }
200
201         net_warn_member_options();
202
203         if(c->opt_force) {
204                 struct secrets_domain_info1 *info = NULL;
205                 struct secrets_domain_info1_change *prev = NULL;
206                 NTSTATUS status;
207                 struct timeval tv = timeval_current();
208                 NTTIME now = timeval_to_nttime(&tv);
209
210                 if (c->opt_stdin) {
211                         set_line_buffering(stdin);
212                         set_line_buffering(stdout);
213                         set_line_buffering(stderr);
214                 }
215
216                 trust_pw = get_pass(_("Enter machine password: "), c->opt_stdin);
217                 if (trust_pw == NULL) {
218                             d_fprintf(stderr,
219                                       _("Error in reading machine password\n"));
220                             return 1;
221                 }
222
223                 status = secrets_prepare_password_change(lp_workgroup(),
224                                                          "localhost",
225                                                          trust_pw,
226                                                          talloc_tos(),
227                                                          &info, &prev);
228                 if (!NT_STATUS_IS_OK(status)) {
229                         d_fprintf(stderr,
230                                 _("Unable to write the machine account password in the secrets database"));
231                         return 1;
232                 }
233                 if (prev != NULL) {
234                         d_fprintf(stderr,
235                                 _("Pending machine account password change found - aborting."));
236                         status = secrets_failed_password_change("localhost",
237                                                 NT_STATUS_REQUEST_NOT_ACCEPTED,
238                                                 NT_STATUS_NOT_COMMITTED,
239                                                 info);
240                         if (!NT_STATUS_IS_OK(status)) {
241                                 d_fprintf(stderr,
242                                         _("Failed to abort machine account password change"));
243                         }
244                         return 1;
245                 }
246                 status = secrets_finish_password_change("localhost", now, info);
247                 if (!NT_STATUS_IS_OK(status)) {
248                         d_fprintf(stderr,
249                                 _("Unable to write the machine account password in the secrets database"));
250                         return 1;
251                 }
252
253                 d_printf(_("Modified trust account password in secrets database\n"));
254         }
255         else {
256                 d_printf(_("Machine account password change requires the -f flag.\n"
257                            "Do NOT use this function unless you know what it does!\n"
258                            "This function will change the ADS Domain member "
259                            "machine account password in the secrets.tdb file!\n"));
260         }
261
262         return 0;
263 }
264
265 /**
266  * @brief Set the authorised user for winbindd access in secrets.tdb
267  */
268 static int net_setauthuser(struct net_context *c, int argc, const char **argv)
269 {
270         const char *password = NULL;
271         bool ok;
272
273         if (!secrets_init()) {
274                 d_fprintf(stderr, _("Failed to open secrets.tdb.\n"));
275                 return 1;
276         }
277
278         /* Delete the settings. */
279         if (argc >= 1) {
280                 if (strncmp(argv[0], "delete", 6) != 0) {
281                         d_fprintf(stderr,_("Usage:\n"));
282                         d_fprintf(stderr,
283                                   _("    net setauthuser -U user[%%password] \n"
284                                     "        Set the auth user account to user"
285                                     "password. Prompt for password if not "
286                                     "specified.\n"));
287                         d_fprintf(stderr,
288                                   _("    net setauthuser delete\n"
289                                     "        Delete the auth user setting.\n"));
290                         return 1;
291                 }
292                 secrets_delete_entry(SECRETS_AUTH_USER);
293                 secrets_delete_entry(SECRETS_AUTH_DOMAIN);
294                 secrets_delete_entry(SECRETS_AUTH_PASSWORD);
295                 return 0;
296         }
297
298         if (!c->opt_user_specified) {
299                 d_fprintf(stderr, _("Usage:\n"));
300                 d_fprintf(stderr,
301                           _("    net setauthuser -U user[%%password]\n"
302                             "        Set the auth user account to user"
303                             "password. Prompt for password if not "
304                             "specified.\n"));
305                 d_fprintf(stderr,
306                           _("    net setauthuser delete\n"
307                             "        Delete the auth user setting.\n"));
308                 return 1;
309         }
310
311         password = net_prompt_pass(c, _("the auth user"));
312         if (password == NULL) {
313                 d_fprintf(stderr,_("Failed to get the auth users password.\n"));
314                 return 1;
315         }
316
317         ok = secrets_store_creds(c->creds);
318         if (!ok) {
319                 d_fprintf(stderr, _("Failed storing auth user credentials\n"));
320                 return 1;
321         }
322
323         return 0;
324 }
325
326 /**
327  * @brief Get the auth user settings
328  */
329 static int net_getauthuser(struct net_context *c, int argc, const char **argv)
330 {
331         char *user, *domain, *password;
332
333         /* Lift data from secrets file */
334
335         secrets_fetch_ipc_userpass(&user, &domain, &password);
336
337         if ((!user || !*user) && (!domain || !*domain ) &&
338             (!password || !*password)){
339
340                 SAFE_FREE(user);
341                 SAFE_FREE(domain);
342                 BURN_FREE_STR(password);
343                 d_printf(_("No authorised user configured\n"));
344                 return 0;
345         }
346
347         /* Pretty print authorised user info */
348
349         d_printf("%s%s%s%s%s\n", domain ? domain : "",
350                  domain ? lp_winbind_separator(): "", user,
351                  password ? "%" : "", password ? password : "");
352
353         SAFE_FREE(user);
354         SAFE_FREE(domain);
355         BURN_FREE_STR(password);
356
357         return 0;
358 }
359 /*
360  Retrieve our local SID or the SID for the specified name
361  */
362 static int net_getlocalsid(struct net_context *c, int argc, const char **argv)
363 {
364         struct dom_sid sid;
365         const char *name;
366         struct dom_sid_buf sid_str;
367
368         if (argc >= 1) {
369                 name = argv[0];
370         }
371         else {
372                 name = lp_netbios_name();
373         }
374
375         if(!initialize_password_db(false, NULL)) {
376                 d_fprintf(stderr, _("WARNING: Could not open passdb\n"));
377                 return 1;
378         }
379
380         /* first check to see if we can even access secrets, so we don't
381            panic when we can't. */
382
383         if (!secrets_init()) {
384                 d_fprintf(stderr,
385                           _("Unable to open secrets.tdb.  Can't fetch domain "
386                             "SID for name: %s\n"), name);
387                 return 1;
388         }
389
390         /* Generate one, if it doesn't exist */
391         get_global_sam_sid();
392
393         if (!secrets_fetch_domain_sid(name, &sid)) {
394                 DEBUG(0, ("Can't fetch domain SID for name: %s\n", name));
395                 return 1;
396         }
397         d_printf(_("SID for domain %s is: %s\n"),
398                  name,
399                  dom_sid_str_buf(&sid, &sid_str));
400         return 0;
401 }
402
403 static int net_setlocalsid(struct net_context *c, int argc, const char **argv)
404 {
405         struct dom_sid sid;
406
407         if ( (argc != 1)
408              || (strncmp(argv[0], "S-1-5-21-", strlen("S-1-5-21-")) != 0)
409              || (!string_to_sid(&sid, argv[0]))
410              || (sid.num_auths != 4)) {
411                 d_printf(_("Usage:"));
412                 d_printf(" net setlocalsid S-1-5-21-x-y-z\n");
413                 return 1;
414         }
415
416         if (!secrets_store_domain_sid(lp_netbios_name(), &sid)) {
417                 DEBUG(0,("Can't store domain SID as a pdc/bdc.\n"));
418                 return 1;
419         }
420
421         return 0;
422 }
423
424 static int net_setdomainsid(struct net_context *c, int argc, const char **argv)
425 {
426         struct dom_sid sid;
427
428         if ( (argc != 1)
429              || (strncmp(argv[0], "S-1-5-21-", strlen("S-1-5-21-")) != 0)
430              || (!string_to_sid(&sid, argv[0]))
431              || (sid.num_auths != 4)) {
432                 d_printf(_("Usage:"));
433                 d_printf(" net setdomainsid S-1-5-21-x-y-z\n");
434                 return 1;
435         }
436
437         if (!secrets_store_domain_sid(lp_workgroup(), &sid)) {
438                 DEBUG(0,("Can't store domain SID.\n"));
439                 return 1;
440         }
441
442         return 0;
443 }
444
445 static int net_getdomainsid(struct net_context *c, int argc, const char **argv)
446 {
447         struct dom_sid domain_sid;
448         struct dom_sid_buf sid_str;
449
450         if (argc > 0) {
451                 d_printf(_("Usage:"));
452                 d_printf(" net getdomainsid\n");
453                 return 1;
454         }
455
456         if(!initialize_password_db(false, NULL)) {
457                 d_fprintf(stderr, _("WARNING: Could not open passdb\n"));
458                 return 1;
459         }
460
461         /* first check to see if we can even access secrets, so we don't
462            panic when we can't. */
463
464         if (!secrets_init()) {
465                 d_fprintf(stderr, _("Unable to open secrets.tdb.  Can't fetch "
466                                     "domain SID for name: %s\n"),
467                           get_global_sam_name());
468                 return 1;
469         }
470
471         /* Generate one, if it doesn't exist */
472         get_global_sam_sid();
473
474         if (!IS_DC) {
475                 if (!secrets_fetch_domain_sid(lp_netbios_name(), &domain_sid)) {
476                         d_fprintf(stderr, _("Could not fetch local SID\n"));
477                         return 1;
478                 }
479                 d_printf(_("SID for local machine %s is: %s\n"),
480                          lp_netbios_name(),
481                          dom_sid_str_buf(&domain_sid, &sid_str));
482         }
483         if (!secrets_fetch_domain_sid(c->opt_workgroup, &domain_sid)) {
484                 d_fprintf(stderr, _("Could not fetch domain SID\n"));
485                 return 1;
486         }
487
488         d_printf(_("SID for domain %s is: %s\n"),
489                  c->opt_workgroup,
490                  dom_sid_str_buf(&domain_sid, &sid_str));
491
492         return 0;
493 }
494
495 static bool search_maxrid(struct pdb_search *search, const char *type,
496                           uint32_t *max_rid)
497 {
498         struct samr_displayentry *entries;
499         uint32_t i, num_entries;
500
501         if (search == NULL) {
502                 d_fprintf(stderr, _("get_maxrid: Could not search %s\n"), type);
503                 return false;
504         }
505
506         num_entries = pdb_search_entries(search, 0, 0xffffffff, &entries);
507         for (i=0; i<num_entries; i++)
508                 *max_rid = MAX(*max_rid, entries[i].rid);
509         TALLOC_FREE(search);
510         return true;
511 }
512
513 static uint32_t get_maxrid(void)
514 {
515         uint32_t max_rid = 0;
516
517         if (!search_maxrid(pdb_search_users(talloc_tos(), 0), "users", &max_rid))
518                 return 0;
519
520         if (!search_maxrid(pdb_search_groups(talloc_tos()), "groups", &max_rid))
521                 return 0;
522
523         if (!search_maxrid(pdb_search_aliases(talloc_tos(),
524                                               get_global_sam_sid()),
525                            "aliases", &max_rid))
526                 return 0;
527
528         return max_rid;
529 }
530
531 static int net_maxrid(struct net_context *c, int argc, const char **argv)
532 {
533         uint32_t rid;
534
535         if (argc != 0) {
536                 d_fprintf(stderr, "%s net maxrid\n", _("Usage:"));
537                 return 1;
538         }
539
540         if ((rid = get_maxrid()) == 0) {
541                 d_fprintf(stderr, _("can't get current maximum rid\n"));
542                 return 1;
543         }
544
545         d_printf(_("Currently used maximum rid: %d\n"), rid);
546
547         return 0;
548 }
549
550 /* main function table */
551 static struct functable net_func[] = {
552         {
553                 "rpc",
554                 net_rpc,
555                 NET_TRANSPORT_RPC,
556                 N_("Run functions using RPC transport"),
557                 N_("  Use 'net help rpc' to get more extensive information "
558                    "about 'net rpc' commands.")
559         },
560         {
561                 "rap",
562                 net_rap,
563                 NET_TRANSPORT_RAP,
564                 N_("Run functions using RAP transport"),
565                 N_("  Use 'net help rap' to get more extensive information "
566                    "about 'net rap' commands.")
567         },
568         {
569                 "ads",
570                 net_ads,
571                 NET_TRANSPORT_ADS,
572                 N_("Run functions using ADS transport"),
573                 N_("  Use 'net help ads' to get more extensive information "
574                    "about 'net ads' commands.")
575         },
576
577         /* eventually these should auto-choose the transport ... */
578         {
579                 "file",
580                 net_file,
581                 NET_TRANSPORT_RPC | NET_TRANSPORT_RAP,
582                 N_("Functions on remote opened files"),
583                 N_("  Use 'net help file' to get more information about 'net "
584                    "file' commands.")
585         },
586         {
587                 "share",
588                 net_share,
589                 NET_TRANSPORT_RPC | NET_TRANSPORT_RAP,
590                 N_("Functions on shares"),
591                 N_("  Use 'net help share' to get more information about 'net "
592                    "share' commands.")
593         },
594         {
595                 "session",
596                 net_rap_session,
597                 NET_TRANSPORT_RAP,
598                 N_("Manage sessions"),
599                 N_("  Use 'net help session' to get more information about "
600                    "'net session' commands.")
601         },
602         {
603                 "server",
604                 net_rap_server,
605                 NET_TRANSPORT_RAP,
606                 N_("List servers in workgroup"),
607                 N_("  Use 'net help server' to get more information about 'net "
608                    "server' commands.")
609         },
610         {
611                 "domain",
612                 net_rap_domain,
613                 NET_TRANSPORT_RAP,
614                 N_("List domains/workgroups on network"),
615                 N_("  Use 'net help domain' to get more information about 'net "
616                    "domain' commands.")
617         },
618         {
619                 "printq",
620                 net_rap_printq,
621                 NET_TRANSPORT_RAP,
622                 N_("Modify printer queue"),
623                 N_("  Use 'net help printq' to get more information about 'net "
624                    "printq' commands.")
625         },
626         {
627                 "user",
628                 net_user,
629                 NET_TRANSPORT_ADS | NET_TRANSPORT_RPC | NET_TRANSPORT_RAP,
630                 N_("Manage users"),
631                 N_("  Use 'net help user' to get more information about 'net "
632                    "user' commands.")
633         },
634         {
635                 "group",
636                 net_group,
637                 NET_TRANSPORT_ADS | NET_TRANSPORT_RPC | NET_TRANSPORT_RAP,
638                 N_("Manage groups"),
639                 N_("  Use 'net help group' to get more information about 'net "
640                    "group' commands.")
641         },
642         {
643                 "groupmap",
644                 net_groupmap,
645                 NET_TRANSPORT_LOCAL,
646                 N_("Manage group mappings"),
647                 N_("  Use 'net help groupmap' to get more information about "
648                    "'net groupmap' commands.")
649         },
650         {
651                 "sam",
652                 net_sam,
653                 NET_TRANSPORT_LOCAL,
654                 N_("Functions on the SAM database"),
655                 N_("  Use 'net help sam' to get more information about 'net "
656                    "sam' commands.")
657         },
658         {
659                 "validate",
660                 net_rap_validate,
661                 NET_TRANSPORT_RAP,
662                 N_("Validate username and password"),
663                 N_("  Use 'net help validate' to get more information about "
664                    "'net validate' commands.")
665         },
666         {
667                 "groupmember",
668                 net_rap_groupmember,
669                 NET_TRANSPORT_RAP,
670                 N_("Modify group memberships"),
671                 N_("  Use 'net help groupmember' to get more information about "
672                    "'net groupmember' commands.")
673         },
674         {       "admin",
675                 net_rap_admin,
676                 NET_TRANSPORT_RAP,
677                 N_("Execute remote command on a remote OS/2 server"),
678                 N_("  Use 'net help admin' to get more information about 'net "
679                    "admin' commands.")
680         },
681         {       "service",
682                 net_rap_service,
683                 NET_TRANSPORT_RAP,
684                 N_("List/modify running services"),
685                 N_("  Use 'net help service' to get more information about "
686                    "'net service' commands.")
687         },
688         {
689                 "password",
690                 net_rap_password,
691                 NET_TRANSPORT_RAP,
692                 N_("Change user password on target server"),
693                 N_("  Use 'net help password' to get more information about "
694                    "'net password' commands.")
695         },
696         {
697                 "primarytrust",
698                 net_primarytrust,
699                 NET_TRANSPORT_RPC,
700                 N_("Run functions related to the primary workstation trust."),
701                 N_("  Use 'net help primarytrust' to get more extensive information "
702                    "about 'net primarytrust' commands.")
703         },
704         {       "changetrustpw",
705                 net_changetrustpw,
706                 NET_TRANSPORT_ADS | NET_TRANSPORT_RPC,
707                 N_("Change the trust password"),
708                 N_("  Use 'net help changetrustpw' to get more information "
709                    "about 'net changetrustpw'.")
710         },
711         {       "changesecretpw",
712                 net_changesecretpw,
713                 NET_TRANSPORT_LOCAL,
714                 N_("Change the secret password"),
715                 N_("  net [options] changesecretpw\n"
716                    "    Change the ADS domain member machine account password "
717                    "in secrets.tdb.\n"
718                    "    Do NOT use this function unless you know what it does.\n"
719                    "    Requires the -f flag to work.")
720         },
721         {
722                 "setauthuser",
723                 net_setauthuser,
724                 NET_TRANSPORT_LOCAL,
725                 N_("Set the winbind auth user"),
726                 N_("  net -U user[%%password] [-W domain] setauthuser\n"
727                    "    Set the auth user, password (and optionally domain\n"
728                    "    Will prompt for password if not given.\n"
729                    "  net setauthuser delete\n"
730                    "    Delete the existing auth user settings.")
731         },
732         {
733                 "getauthuser",
734                 net_getauthuser,
735                 NET_TRANSPORT_LOCAL,
736                 N_("Get the winbind auth user settings"),
737                 N_("  net getauthuser\n"
738                    "    Get the current winbind auth user settings.")
739         },
740         {       "time",
741                 net_time,
742                 NET_TRANSPORT_LOCAL,
743                 N_("Show/set time"),
744                 N_("  Use 'net help time' to get more information about 'net "
745                    "time' commands.")
746         },
747         {       "lookup",
748                 net_lookup,
749                 NET_TRANSPORT_LOCAL,
750                 N_("Look up host names/IP addresses"),
751                 N_("  Use 'net help lookup' to get more information about 'net "
752                    "lookup' commands.")
753         },
754         {       "g_lock",
755                 net_g_lock,
756                 NET_TRANSPORT_LOCAL,
757                 N_("Manipulate the global lock table"),
758                 N_("  Use 'net help g_lock' to get more information about "
759                    "'net g_lock' commands.")
760         },
761         {       "join",
762                 net_join,
763                 NET_TRANSPORT_ADS | NET_TRANSPORT_RPC,
764                 N_("Join a domain/AD"),
765                 N_("  Use 'net help join' to get more information about 'net "
766                    "join'.")
767         },
768         {       "offlinejoin",
769                 net_offlinejoin,
770                 NET_TRANSPORT_ADS | NET_TRANSPORT_RPC,
771                 N_("Perform offline domain join"),
772                 N_("  Use 'net help offlinejoin' to get more information about 'net "
773                    "offlinejoin'.")
774         },
775         {       "dom",
776                 net_dom,
777                 NET_TRANSPORT_LOCAL,
778                 N_("Join/unjoin (remote) machines to/from a domain/AD"),
779                 N_("  Use 'net help dom' to get more information about 'net "
780                    "dom' commands.")
781         },
782         {       "cache",
783                 net_cache,
784                 NET_TRANSPORT_LOCAL,
785                 N_("Operate on the cache tdb file"),
786                 N_("  Use 'net help cache' to get more information about 'net "
787                    "cache' commands.")
788         },
789         {       "getlocalsid",
790                 net_getlocalsid,
791                 NET_TRANSPORT_LOCAL,
792                 N_("Get the SID for the local domain"),
793                 N_("  net getlocalsid")
794         },
795         {       "setlocalsid",
796                 net_setlocalsid,
797                 NET_TRANSPORT_LOCAL,
798                 N_("Set the SID for the local domain"),
799                 N_("  net setlocalsid S-1-5-21-x-y-z")
800         },
801         {       "setdomainsid",
802                 net_setdomainsid,
803                 NET_TRANSPORT_LOCAL,
804                 N_("Set domain SID on member servers"),
805                 N_("  net setdomainsid S-1-5-21-x-y-z")
806         },
807         {       "getdomainsid",
808                 net_getdomainsid,
809                 NET_TRANSPORT_LOCAL,
810                 N_("Get domain SID on member servers"),
811                 N_("  net getdomainsid")
812         },
813         {       "maxrid",
814                 net_maxrid,
815                 NET_TRANSPORT_LOCAL,
816                 N_("Display the maximum RID currently used"),
817                 N_("  net maxrid")
818         },
819         {       "idmap",
820                 net_idmap,
821                 NET_TRANSPORT_LOCAL,
822                 N_("IDmap functions"),
823                 N_("  Use 'net help idmap to get more information about 'net "
824                   "idmap' commands.")
825         },
826         {       "status",
827                 net_status,
828                 NET_TRANSPORT_LOCAL,
829                 N_("Display server status"),
830                 N_("  Use 'net help status' to get more information about 'net "
831                    "status' commands.")
832         },
833         {       "usershare",
834                 net_usershare,
835                 NET_TRANSPORT_LOCAL,
836                 N_("Manage user-modifiable shares"),
837                 N_("  Use 'net help usershare to get more information about "
838                    "'net usershare' commands.")
839         },
840         {       "usersidlist",
841                 net_usersidlist,
842                 NET_TRANSPORT_RPC,
843                 N_("Display list of all users with SID"),
844                 N_("  Use 'net help usersidlist' to get more information about "
845                    "'net usersidlist'.")
846         },
847         {       "conf",
848                 net_conf,
849                 NET_TRANSPORT_LOCAL,
850                 N_("Manage Samba registry based configuration"),
851                 N_("  Use 'net help conf' to get more information about 'net "
852                    "conf' commands.")
853         },
854         {       "registry",
855                 net_registry,
856                 NET_TRANSPORT_LOCAL,
857                 N_("Manage the Samba registry"),
858                 N_("  Use 'net help registry' to get more information about "
859                    "'net registry' commands.")
860         },
861         {       "eventlog",
862                 net_eventlog,
863                 NET_TRANSPORT_LOCAL,
864                 N_("Process Win32 *.evt eventlog files"),
865                 N_("  Use 'net help eventlog' to get more information about "
866                    "'net eventlog' commands.")
867         },
868         {       "printing",
869                 net_printing,
870                 NET_TRANSPORT_LOCAL,
871                 N_("Process tdb printer files"),
872                 N_("  Use 'net help printing' to get more information about "
873                    "'net printing' commands.")
874         },
875
876         {       "serverid",
877                 net_serverid,
878                 NET_TRANSPORT_LOCAL,
879                 N_("Manage the serverid tdb"),
880                 N_("  Use 'net help serverid' to get more information about "
881                    "'net serverid' commands.")
882         },
883
884         {       "notify",
885                 net_notify,
886                 NET_TRANSPORT_LOCAL,
887                 N_("notifyd client code"),
888                 N_("  Use 'net help notify' to get more information about "
889                    "'net notify' commands.")
890         },
891
892         {       "tdb",
893                 net_tdb,
894                 NET_TRANSPORT_LOCAL,
895                 N_("Show information from tdb records"),
896                 N_("  Use 'net help tdb' to get more information about "
897                    "'net tdb' commands.")
898         },
899
900         {       "vfs",
901                 net_vfs,
902                 NET_TRANSPORT_LOCAL,
903                 N_("Filesystem operation through the VFS stack"),
904                 N_("  Use 'net help vfs' to get more information about "
905                    "'net vfs' commands.")
906         },
907
908         {       "witness",
909                 net_witness,
910                 NET_TRANSPORT_LOCAL,
911                 N_("Manage witness registrations"),
912                 N_("  Use 'net help witness' to get more information about "
913                    "'net witness' commands.")
914         },
915
916 #ifdef WITH_FAKE_KASERVER
917         {       "afs",
918                 net_afs,
919                 NET_TRANSPORT_LOCAL,
920                 N_("Manage AFS tokens"),
921                 N_("  Use 'net help afs' to get more information about 'net "
922                    "afs' commands.")
923         },
924 #endif
925
926         {       "help",
927                 net_help,
928                 NET_TRANSPORT_LOCAL,
929                 N_("Print usage information"),
930                 N_("  Use 'net help help' to list usage information for 'net' "
931                    "commands.")
932         },
933         {NULL, NULL, 0, NULL, NULL}
934 };
935
936
937 /****************************************************************************
938   main program
939 ****************************************************************************/
940  int main(int argc, char **argv)
941 {
942         int opt,i;
943         int rc = 0;
944         int argc_new = 0;
945         const char ** argv_new;
946         const char **argv_const = discard_const_p(const char *, argv);
947         poptContext pc;
948         TALLOC_CTX *frame = talloc_stackframe();
949         struct net_context *c = talloc_zero(frame, struct net_context);
950         bool ok;
951
952         struct poptOption long_options[] = {
953                 {
954                         .longName   = "help",
955                         .shortName  = 'h',
956                         .argInfo    = POPT_ARG_NONE,
957                         .val        = 'h',
958                 },
959                 {
960                         .longName   = "target-workgroup",
961                         .shortName  = 'w',
962                         .argInfo    = POPT_ARG_STRING,
963                         .arg        = &c->opt_target_workgroup,
964                 },
965                 {
966                         .longName   = "ipaddress",
967                         .shortName  = 'I',
968                         .argInfo    = POPT_ARG_STRING,
969                         .arg        = 0,
970                         .val        = 'I',
971                 },
972                 {
973                         .longName   = "port",
974                         .shortName  = 'p',
975                         .argInfo    = POPT_ARG_INT,
976                         .arg        = &c->opt_port,
977                 },
978                 {
979                         .longName   = "myname",
980                         .shortName  = 0,
981                         .argInfo    = POPT_ARG_STRING,
982                         .arg        = &c->opt_requester_name,
983                 },
984                 {
985                         .longName   = "server",
986                         .shortName  = 'S',
987                         .argInfo    = POPT_ARG_STRING,
988                         .arg        = &c->opt_host,
989                 },
990                 {
991                         .longName   = "container",
992                         .shortName  = 'c',
993                         .argInfo    = POPT_ARG_STRING,
994                         .arg        = &c->opt_container,
995                 },
996                 {
997                         .longName   = "comment",
998                         .shortName  = 'C',
999                         .argInfo    = POPT_ARG_STRING,
1000                         .arg        = &c->opt_comment,
1001                 },
1002                 {
1003                         .longName   = "maxusers",
1004                         .shortName  = 'M',
1005                         .argInfo    = POPT_ARG_INT,
1006                         .arg        = &c->opt_maxusers,
1007                 },
1008                 {
1009                         .longName   = "flags",
1010                         .shortName  = 'F',
1011                         .argInfo    = POPT_ARG_INT,
1012                         .arg        = &c->opt_flags,
1013                 },
1014                 {
1015                         .longName   = "long",
1016                         .argInfo    = POPT_ARG_NONE,
1017                         .arg        = &c->opt_long_list_entries,
1018                 },
1019                 {
1020                         .longName   = "reboot",
1021                         .shortName  = 'r',
1022                         .argInfo    = POPT_ARG_NONE,
1023                         .arg        = &c->opt_reboot,
1024                 },
1025                 {
1026                         .longName   = "force",
1027                         .shortName  = 'f',
1028                         .argInfo    = POPT_ARG_NONE,
1029                         .arg        = &c->opt_force,
1030                 },
1031                 {
1032                         .longName   = "stdin",
1033                         .shortName  = 'i',
1034                         .argInfo    = POPT_ARG_NONE,
1035                         .arg        = &c->opt_stdin,
1036                 },
1037                 {
1038                         .longName   = "timeout",
1039                         .shortName  = 't',
1040                         .argInfo    = POPT_ARG_INT,
1041                         .arg        = &c->opt_timeout,
1042                 },
1043                 {
1044                         .longName   = "request-timeout",
1045                         .shortName  = 0,
1046                         .argInfo    = POPT_ARG_INT,
1047                         .arg        = &c->opt_request_timeout,
1048                 },
1049                 {
1050                         .longName   = "use-ccache",
1051                         .shortName  = 0,
1052                         .argInfo    = POPT_ARG_NONE,
1053                         .arg        = &c->opt_ccache,
1054                 },
1055                 {
1056                         .longName   = "verbose",
1057                         .shortName  = 'v',
1058                         .argInfo    = POPT_ARG_NONE,
1059                         .arg        = &c->opt_verbose,
1060                 },
1061                 {
1062                         .longName   = "test",
1063                         .shortName  = 'T',
1064                         .argInfo    = POPT_ARG_NONE,
1065                         .arg        = &c->opt_testmode,
1066                 },
1067                 /* Options for 'net groupmap set' */
1068                 {
1069                         .longName   = "local",
1070                         .shortName  = 'L',
1071                         .argInfo    = POPT_ARG_NONE,
1072                         .arg        = &c->opt_localgroup,
1073                 },
1074                 {
1075                         .longName   = "domain",
1076                         .shortName  = 'D',
1077                         .argInfo    = POPT_ARG_NONE,
1078                         .arg        = &c->opt_domaingroup,
1079                 },
1080                 {
1081                         .longName   = "ntname",
1082                         .shortName  = 0,
1083                         .argInfo    = POPT_ARG_STRING,
1084                         .arg        = &c->opt_newntname,
1085                 },
1086                 {
1087                         .longName   = "rid",
1088                         .shortName  = 0,
1089                         .argInfo    = POPT_ARG_INT,
1090                         .arg        = &c->opt_rid,
1091                 },
1092                 /* Options for 'net rpc share migrate' */
1093                 {
1094                         .longName   = "acls",
1095                         .shortName  = 0,
1096                         .argInfo    = POPT_ARG_NONE,
1097                         .arg        = &c->opt_acls,
1098                 },
1099                 {
1100                         .longName   = "attrs",
1101                         .shortName  = 0,
1102                         .argInfo    = POPT_ARG_NONE,
1103                         .arg        = &c->opt_attrs,
1104                 },
1105                 {
1106                         .longName   = "timestamps",
1107                         .shortName  = 0,
1108                         .argInfo    = POPT_ARG_NONE,
1109                         .arg        = &c->opt_timestamps,
1110                 },
1111                 {
1112                         .longName   = "exclude",
1113                         .shortName  = 'X',
1114                         .argInfo    = POPT_ARG_STRING,
1115                         .arg        = &c->opt_exclude,
1116                 },
1117                 {
1118                         .longName   = "destination",
1119                         .shortName  = 0,
1120                         .argInfo    = POPT_ARG_STRING,
1121                         .arg        = &c->opt_destination,
1122                 },
1123                 {
1124                         .longName   = "tallocreport",
1125                         .shortName  = 0,
1126                         .argInfo    = POPT_ARG_NONE,
1127                         .arg        = &c->do_talloc_report,
1128                 },
1129                 /* Options for 'net rpc vampire (keytab)' */
1130                 {
1131                         .longName   = "force-full-repl",
1132                         .shortName  = 0,
1133                         .argInfo    = POPT_ARG_NONE,
1134                         .arg        = &c->opt_force_full_repl,
1135                 },
1136                 {
1137                         .longName   = "single-obj-repl",
1138                         .shortName  = 0,
1139                         .argInfo    = POPT_ARG_NONE,
1140                         .arg        = &c->opt_single_obj_repl,
1141                 },
1142                 {
1143                         .longName   = "clean-old-entries",
1144                         .shortName  = 0,
1145                         .argInfo    = POPT_ARG_NONE,
1146                         .arg        = &c->opt_clean_old_entries,
1147                 },
1148                 /* Options for 'net idmap'*/
1149                 {
1150                         .longName   = "db",
1151                         .shortName  = 0,
1152                         .argInfo    = POPT_ARG_STRING,
1153                         .arg        = &c->opt_db,
1154                 },
1155                 {
1156                         .longName   = "lock",
1157                         .shortName  = 0,
1158                         .argInfo    = POPT_ARG_NONE,
1159                         .arg        =   &c->opt_lock,
1160                 },
1161                 {
1162                         .longName   = "auto",
1163                         .shortName  = 'a',
1164                         .argInfo    = POPT_ARG_NONE,
1165                         .arg        = &c->opt_auto,
1166                 },
1167                 {
1168                         .longName   = "repair",
1169                         .shortName  = 0,
1170                         .argInfo    = POPT_ARG_NONE,
1171                         .arg        =   &c->opt_repair,
1172                 },
1173                 /* Options for 'net registry check'*/
1174                 {
1175                         .longName   = "reg-version",
1176                         .shortName  = 0,
1177                         .argInfo    = POPT_ARG_INT,
1178                         .arg        = &c->opt_reg_version,
1179                 },
1180                 {
1181                         .longName   = "output",
1182                         .shortName  = 'o',
1183                         .argInfo    = POPT_ARG_STRING,
1184                         .arg        = &c->opt_output,
1185                 },
1186                 {
1187                         .longName   = "wipe",
1188                         .shortName  = 0,
1189                         .argInfo    = POPT_ARG_NONE,
1190                         .arg        = &c->opt_wipe,
1191                 },
1192                 /* Options for 'net registry import' */
1193                 {
1194                         .longName   = "precheck",
1195                         .shortName  = 0,
1196                         .argInfo    = POPT_ARG_STRING,
1197                         .arg        = &c->opt_precheck,
1198                 },
1199                 /* Options for 'net ads join or leave' */
1200                 {
1201                         .longName   = "no-dns-updates",
1202                         .shortName  = 0,
1203                         .argInfo    = POPT_ARG_NONE,
1204                         .arg        = &c->opt_no_dns_updates,
1205                 },
1206                 {
1207                         .longName   = "keep-account",
1208                         .shortName  = 0,
1209                         .argInfo    = POPT_ARG_NONE,
1210                         .arg        = &c->opt_keep_account,
1211                 },
1212                 {
1213                         .longName   = "json",
1214                         .shortName  = 0,
1215                         .argInfo    = POPT_ARG_NONE,
1216                         .arg        = &c->opt_json,
1217                 },
1218                 /* Options for 'net vfs' */
1219                 {
1220                         .longName   = "continue",
1221                         .argInfo    = POPT_ARG_NONE,
1222                         .arg        = &c->opt_continue_on_error,
1223                         .descrip    = "Continue on errors",
1224                 },
1225                 {
1226                         .longName   = "recursive",
1227                         .argInfo    = POPT_ARG_NONE,
1228                         .arg        = &c->opt_recursive,
1229                         .descrip    = "Traverse directory hierarchy",
1230                 },
1231                 {
1232                         .longName   = "follow-symlinks",
1233                         .argInfo    = POPT_ARG_NONE,
1234                         .arg        = &c->opt_follow_symlink,
1235                         .descrip    = "follow symlinks",
1236                 },
1237                 /* Options for 'net ads dns register' */
1238                 {
1239                         .longName   = "dns-ttl",
1240                         .argInfo    = POPT_ARG_INT,
1241                         .arg        = &c->opt_dns_ttl,
1242                         .descrip    = "TTL in seconds of DNS records",
1243                 },
1244                 /* Options for 'net witness {list,...}' */
1245                 {
1246                         .longName   = "witness-registration",
1247                         .shortName  = 0,
1248                         .argInfo    = POPT_ARG_STRING,
1249                         .arg        = &c->opt_witness_registration,
1250                 },
1251                 {
1252                         .longName   = "witness-net-name",
1253                         .shortName  = 0,
1254                         .argInfo    = POPT_ARG_STRING,
1255                         .arg        = &c->opt_witness_net_name,
1256                 },
1257                 {
1258                         .longName   = "witness-share-name",
1259                         .shortName  = 0,
1260                         .argInfo    = POPT_ARG_STRING,
1261                         .arg        = &c->opt_witness_share_name,
1262                 },
1263                 {
1264                         .longName   = "witness-ip-address",
1265                         .shortName  = 0,
1266                         .argInfo    = POPT_ARG_STRING,
1267                         .arg        = &c->opt_witness_ip_address,
1268                 },
1269                 {
1270                         .longName   = "witness-client-computer-name",
1271                         .shortName  = 0,
1272                         .argInfo    = POPT_ARG_STRING,
1273                         .arg        = &c->opt_witness_client_computer_name,
1274                 },
1275                 {
1276                         .longName   = "witness-apply-to-all",
1277                         .shortName  = 0,
1278                         .argInfo    = POPT_ARG_NONE,
1279                         .arg        = &c->opt_witness_apply_to_all,
1280                 },
1281                 {
1282                         .longName   = "witness-new-ip",
1283                         .shortName  = 0,
1284                         .argInfo    = POPT_ARG_STRING,
1285                         .arg        = &c->opt_witness_new_ip,
1286                 },
1287                 {
1288                         .longName   = "witness-new-node",
1289                         .shortName  = 0,
1290                         .argInfo    = POPT_ARG_INT,
1291                         .arg        = &c->opt_witness_new_node,
1292                 },
1293                 {
1294                         .longName   = "witness-forced-response",
1295                         .shortName  = 0,
1296                         .argInfo    = POPT_ARG_STRING,
1297                         .arg        = &c->opt_witness_forced_response,
1298                 },
1299                 POPT_COMMON_SAMBA
1300                 POPT_COMMON_CONNECTION
1301                 POPT_COMMON_CREDENTIALS
1302                 POPT_COMMON_VERSION
1303                 POPT_LEGACY_S3
1304                 POPT_TABLEEND
1305         };
1306
1307         /* Ignore possible SIGPIPE upon ldap_unbind when over TLS */
1308         BlockSignals(True, SIGPIPE);
1309
1310         zero_sockaddr(&c->opt_dest_ip);
1311         c->opt_witness_new_node = -2;
1312
1313         smb_init_locale();
1314
1315         setlocale(LC_ALL, "");
1316 #if defined(HAVE_BINDTEXTDOMAIN)
1317         bindtextdomain(MODULE_NAME, get_dyn_LOCALEDIR());
1318 #endif
1319 #if defined(HAVE_TEXTDOMAIN)
1320         textdomain(MODULE_NAME);
1321 #endif
1322
1323         ok = samba_cmdline_init(frame,
1324                                 SAMBA_CMDLINE_CONFIG_CLIENT,
1325                                 false /* require_smbconf */);
1326         if (!ok) {
1327                 DBG_ERR("Failed to init cmdline parser!\n");
1328                 TALLOC_FREE(frame);
1329                 exit(1);
1330         }
1331         c->lp_ctx = samba_cmdline_get_lp_ctx();
1332         /* set default debug level to 0 regardless of what smb.conf sets */
1333         lpcfg_set_cmdline(c->lp_ctx, "log level", "0");
1334         c->private_data = net_func;
1335
1336         pc = samba_popt_get_context(getprogname(),
1337                                     argc,
1338                                     argv_const,
1339                                     long_options,
1340                                     POPT_CONTEXT_KEEP_FIRST);
1341         if (pc == NULL) {
1342                 DBG_ERR("Failed to setup popt context!\n");
1343                 TALLOC_FREE(frame);
1344                 exit(1);
1345         }
1346
1347         while((opt = poptGetNextOpt(pc)) != -1) {
1348                 switch (opt) {
1349                 case 'h':
1350                         c->display_usage = true;
1351                         break;
1352                 case 'I':
1353                         if (!interpret_string_addr(&c->opt_dest_ip,
1354                                                 poptGetOptArg(pc), 0)) {
1355                                 d_fprintf(stderr, _("\nInvalid ip address specified\n"));
1356                         } else {
1357                                 c->opt_have_ip = true;
1358                         }
1359                         break;
1360                 default:
1361                         d_fprintf(stderr, _("\nInvalid option %s: %s\n"),
1362                                  poptBadOption(pc, 0), poptStrerror(opt));
1363                         net_help(c, argc, argv_const);
1364                         exit(1);
1365                 }
1366         }
1367
1368         c->creds = samba_cmdline_get_creds();
1369
1370         {
1371                 enum credentials_obtained username_obtained =
1372                         CRED_UNINITIALISED;
1373                 enum smb_encryption_setting encrypt_state =
1374                         cli_credentials_get_smb_encryption(c->creds);
1375                 enum credentials_use_kerberos krb5_state =
1376                         cli_credentials_get_kerberos_state(c->creds);
1377                 uint32_t gensec_features;
1378
1379                 c->opt_user_name = cli_credentials_get_username_and_obtained(
1380                                 c->creds,
1381                                 &username_obtained);
1382                 c->opt_user_specified = (username_obtained == CRED_SPECIFIED);
1383
1384                 c->opt_workgroup = cli_credentials_get_domain(c->creds);
1385
1386                 c->smb_encrypt = (encrypt_state == SMB_ENCRYPTION_REQUIRED);
1387
1388                 c->opt_kerberos = (krb5_state > CRED_USE_KERBEROS_DESIRED);
1389
1390                 gensec_features = cli_credentials_get_gensec_features(c->creds);
1391                 c->opt_ccache = (gensec_features & GENSEC_FEATURE_NTLM_CCACHE);
1392         }
1393
1394         c->msg_ctx = cmdline_messaging_context(get_dyn_CONFIGFILE());
1395
1396 #if defined(HAVE_BIND_TEXTDOMAIN_CODESET)
1397         /* Bind our gettext results to 'unix charset'
1398
1399            This ensures that the translations and any embedded strings are in the
1400            same charset.  It won't be the one from the user's locale (we no
1401            longer auto-detect that), but it will be self-consistent.
1402         */
1403         bind_textdomain_codeset(MODULE_NAME, lp_unix_charset());
1404 #endif
1405
1406         argv_new = (const char **)poptGetArgs(pc);
1407
1408         argc_new = argc;
1409         for (i=0; i<argc; i++) {
1410                 if (argv_new[i] == NULL) {
1411                         argc_new = i;
1412                         break;
1413                 }
1414         }
1415
1416         if (c->do_talloc_report) {
1417                 talloc_enable_leak_report();
1418         }
1419
1420         if (c->opt_requester_name) {
1421                 lpcfg_set_cmdline(c->lp_ctx, "netbios name", c->opt_requester_name);
1422         }
1423
1424         if (!c->opt_target_workgroup) {
1425                 c->opt_target_workgroup = talloc_strdup(c, lp_workgroup());
1426         }
1427
1428         load_interfaces();
1429
1430         /* this makes sure that when we do things like call scripts,
1431            that it won't assert because we are not root */
1432         sec_init();
1433
1434         samba_cmdline_burn(argc, argv);
1435
1436         rc = net_run_function(c, argc_new-1, argv_new+1, "net", net_func);
1437
1438         DEBUG(2,("return code = %d\n", rc));
1439
1440         libnetapi_free(c->netapi_ctx);
1441
1442         poptFreeContext(pc);
1443
1444         cmdline_messaging_context_free();
1445
1446         gfree_all();
1447
1448         TALLOC_FREE(frame);
1449         return rc;
1450 }