LCOV - code coverage report
Current view: top level - lib/cmdline - cmdline.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 404 512 78.9 %
Date: 2024-04-21 15:09:00 Functions: 25 26 96.2 %

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2020      Andreas Schneider <asn@samba.org>
       3             :  *
       4             :  * This program is free software: you can redistribute it and/or modify
       5             :  * it under the terms of the GNU General Public License as published by
       6             :  * the Free Software Foundation, either version 3 of the License, or
       7             :  * (at your option) any later version.
       8             :  *
       9             :  * This program is distributed in the hope that it will be useful,
      10             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      11             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      12             :  * GNU General Public License for more details.
      13             :  *
      14             :  * You should have received a copy of the GNU General Public License
      15             :  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
      16             :  */
      17             : 
      18             : #include "includes.h"
      19             : #include "lib/param/param.h"
      20             : #include "dynconfig/dynconfig.h"
      21             : #include "auth/gensec/gensec.h"
      22             : #include "libcli/smb/smb_util.h"
      23             : #include "cmdline_private.h"
      24             : #include "lib/util/util_process.h"
      25             : 
      26             : #include <samba/version.h>
      27             : 
      28             : static TALLOC_CTX *cmdline_mem_ctx;
      29             : static struct loadparm_context *cmdline_lp_ctx;
      30             : static struct cli_credentials *cmdline_creds;
      31             : static samba_cmdline_load_config cmdline_load_config_fn;
      32             : static struct samba_cmdline_daemon_cfg cmdline_daemon_cfg;
      33             : 
      34             : static NTSTATUS (*cli_credentials_set_machine_account_fn)(
      35             :         struct cli_credentials *cred,
      36             :         struct loadparm_context *lp_ctx) =
      37             :         cli_credentials_set_machine_account;
      38             : 
      39             : /* PRIVATE */
      40       26839 : bool samba_cmdline_set_talloc_ctx(TALLOC_CTX *mem_ctx)
      41             : {
      42       26839 :         if (cmdline_mem_ctx != NULL) {
      43           0 :                 return false;
      44             :         }
      45             : 
      46       26839 :         cmdline_mem_ctx = mem_ctx;
      47       26839 :         return true;
      48             : }
      49             : 
      50       84154 : TALLOC_CTX *samba_cmdline_get_talloc_ctx(void)
      51             : {
      52       84154 :         return cmdline_mem_ctx;
      53             : }
      54             : 
      55           6 : static void _samba_cmdline_talloc_log(const char *message)
      56             : {
      57           6 :         D_ERR("%s", message);
      58           6 : }
      59             : 
      60       26839 : bool samba_cmdline_init_common(TALLOC_CTX *mem_ctx)
      61             : {
      62         423 :         bool ok;
      63             : 
      64       26839 :         ok = samba_cmdline_set_talloc_ctx(mem_ctx);
      65       26839 :         if (!ok) {
      66           0 :                 return false;
      67             :         }
      68             : 
      69       26839 :         cmdline_daemon_cfg = (struct samba_cmdline_daemon_cfg) {
      70             :                 .fork = true,
      71             :         };
      72             : 
      73       26839 :         fault_setup();
      74             : 
      75             :         /*
      76             :          * Log to stderr by default.
      77             :          * This can be changed to stdout using the option: --debug-stdout
      78             :          */
      79       26839 :         setup_logging(getprogname(), DEBUG_DEFAULT_STDERR);
      80             : 
      81       26839 :         talloc_set_log_fn(_samba_cmdline_talloc_log);
      82       26839 :         talloc_set_abort_fn(smb_panic);
      83             : 
      84       26839 :         return true;
      85             : }
      86             : 
      87       26839 : bool samba_cmdline_set_load_config_fn(samba_cmdline_load_config fn)
      88             : {
      89       26839 :         cmdline_load_config_fn = fn;
      90       26839 :         return true;
      91             : }
      92             : 
      93             : /* PUBLIC */
      94       26839 : bool samba_cmdline_set_lp_ctx(struct loadparm_context *lp_ctx)
      95             : {
      96       26839 :         if (lp_ctx == NULL) {
      97           0 :                 return false;
      98             :         }
      99       26839 :         cmdline_lp_ctx = lp_ctx;
     100             : 
     101       26839 :         return true;
     102             : }
     103             : 
     104      200763 : struct loadparm_context *samba_cmdline_get_lp_ctx(void)
     105             : {
     106      200763 :         return cmdline_lp_ctx;
     107             : }
     108             : 
     109       26839 : bool samba_cmdline_set_creds(struct cli_credentials *creds)
     110             : {
     111       26839 :         if (creds == NULL) {
     112           0 :                 return false;
     113             :         }
     114             : 
     115       26839 :         TALLOC_FREE(cmdline_creds);
     116       26839 :         cmdline_creds = creds;
     117             : 
     118       26839 :         return true;
     119             : }
     120             : 
     121     2344780 : struct cli_credentials *samba_cmdline_get_creds(void)
     122             : {
     123     2344780 :         return cmdline_creds;
     124             : }
     125             : 
     126        6744 : struct samba_cmdline_daemon_cfg *samba_cmdline_get_daemon_cfg(void)
     127             : {
     128        6744 :         return &cmdline_daemon_cfg;
     129             : }
     130             : 
     131       21846 : void samba_cmdline_set_machine_account_fn(
     132             :         NTSTATUS (*fn) (struct cli_credentials *cred,
     133             :                         struct loadparm_context *lp_ctx))
     134             : {
     135       21846 :         cli_credentials_set_machine_account_fn = fn;
     136       21846 : }
     137             : 
     138       36185 : bool samba_cmdline_burn(int argc, char *argv[])
     139             : {
     140       36185 :         bool burnt = false;
     141       36185 :         bool found = false;
     142       36185 :         bool is_user = false;
     143       36185 :         char *p = NULL;
     144         176 :         int i;
     145       36185 :         size_t ulen = 0;
     146             : 
     147      230430 :         for (i = 0; i < argc; i++) {
     148      194245 :                 p = argv[i];
     149      194245 :                 if (p == NULL) {
     150           0 :                         return false;
     151             :                 }
     152             : 
     153             :                 /*
     154             :                  * Take care that this list must be in longest-match
     155             :                  * first order
     156             :                  */
     157      194245 :                 if (strncmp(p, "-U", 2) == 0) {
     158       17838 :                         ulen = 2;
     159       17838 :                         found = true;
     160       17838 :                         is_user = true;
     161      176407 :                 } else if (strncmp(p, "--user", 6) == 0) {
     162          11 :                         ulen = 6;
     163          11 :                         found = true;
     164          11 :                         is_user = true;
     165      176396 :                 } else if (strncmp(p, "--password2", 11) == 0) {
     166           0 :                         ulen = 11;
     167           0 :                         found = true;
     168      176396 :                 } else if (strncmp(p, "--password", 10) == 0) {
     169         378 :                         ulen = 10;
     170         378 :                         found = true;
     171      176017 :                 } else if (strncmp(p, "--newpassword", 13) == 0) {
     172          55 :                         ulen = 13;
     173          55 :                         found = true;
     174             :                 }
     175             : 
     176      194245 :                 if (found) {
     177       19020 :                         char *q = NULL;
     178             : 
     179       19020 :                         if (strlen(p) == ulen) {
     180         737 :                                 continue;
     181             :                         }
     182             : 
     183       18283 :                         if (is_user) {
     184       17849 :                                 q = strchr_m(p, '%');
     185       17849 :                                 if (q != NULL) {
     186       17384 :                                         p = q;
     187             :                                 }
     188             :                         } else {
     189         434 :                                 p += ulen;
     190             :                         }
     191             : 
     192       18283 :                         memset_s(p, strlen(p), '\0', strlen(p));
     193       18283 :                         found = false;
     194       18283 :                         is_user = false;
     195       18283 :                         burnt = true;
     196             :                 }
     197             :         }
     198       36009 :         return burnt;
     199             : }
     200             : 
     201    91655347 : static bool is_popt_table_end(const struct poptOption *o)
     202             : {
     203    91655347 :         if (o->longName == NULL &&
     204    22016131 :             o->shortName == 0 &&
     205    21706887 :             o->argInfo == 0 &&
     206     8183271 :             o->arg == NULL &&
     207     8183271 :             o->val == 0 &&
     208     8183271 :             o->descrip == NULL &&
     209     8183271 :             o->argDescrip == NULL) {
     210     8051235 :                 return true;
     211             :         }
     212             : 
     213    82243516 :         return false;
     214             : }
     215             : 
     216     8008137 : static void find_duplicates(const struct poptOption *needle,
     217             :                             const struct poptOption *haystack,
     218             :                             size_t *count)
     219             : {
     220     8008137 :         for(;
     221    89906705 :             !is_popt_table_end(haystack);
     222    81898568 :             haystack++) {
     223    81898568 :                 switch (haystack->argInfo) {
     224     6727633 :                 case POPT_ARG_INCLUDE_TABLE:
     225     6727633 :                         if (haystack->arg != NULL) {
     226     6727633 :                                 find_duplicates(needle, haystack->arg, count);
     227             :                         }
     228             : 
     229     6617574 :                         break;
     230    75170935 :                 default:
     231    75170935 :                         if (needle->shortName != 0 &&
     232    37191617 :                             needle->shortName == haystack->shortName) {
     233      662692 :                                 (*count)++;
     234      662692 :                                 break;
     235             :                         }
     236             : 
     237    74508243 :                         if (needle->longName != NULL &&
     238   140960166 :                             haystack->longName != NULL &&
     239    67617582 :                             strequal(needle->longName, haystack->longName)) {
     240      617812 :                                 (*count)++;
     241      617812 :                                 break;
     242             :                         }
     243    72815034 :                         break;
     244             :                 }
     245             : 
     246    81898568 :                 if (*count > 1) {
     247           0 :                         return;
     248             :                 }
     249             :         }
     250             : }
     251             : 
     252      175134 : static bool cmdline_sanity_checker(const struct poptOption *current_opts,
     253             :                              const struct poptOption *full_opts)
     254             : {
     255      175134 :         const struct poptOption *o = current_opts;
     256             : 
     257      175134 :         for(;
     258     1748642 :             !is_popt_table_end(o);
     259     1573508 :             o++) {
     260       23820 :                 bool ok;
     261             : 
     262     1573508 :                 switch (o->argInfo) {
     263      146502 :                 case POPT_ARG_INCLUDE_TABLE:
     264      146502 :                         if (o->arg != NULL) {
     265      146502 :                                 ok = cmdline_sanity_checker(o->arg, full_opts);
     266      146502 :                                 if (!ok) {
     267           0 :                                         return false;
     268             :                                 }
     269             :                         }
     270             : 
     271      144234 :                         break;
     272     1427006 :                 default:
     273     1427006 :                         if (o->longName != NULL || o->shortName != 0) {
     274     1280504 :                                 size_t count = 0;
     275             : 
     276     1280504 :                                 find_duplicates(o, full_opts, &count);
     277     1280504 :                                 if (count > 1) {
     278           0 :                                         DBG_ERR("Duplicate option '--%s|-%c' "
     279             :                                                 "detected!\n",
     280             :                                                 o->longName,
     281             :                                                 o->shortName != 0 ?
     282             :                                                         o->shortName :
     283             :                                                         '-');
     284           0 :                                         return false;
     285             :                                 }
     286             :                         }
     287             : 
     288     1405454 :                         break;
     289             :                 }
     290             :         }
     291             : 
     292      172441 :         return true;
     293             : }
     294             : 
     295       28632 : bool samba_cmdline_sanity_check(const struct poptOption *opts)
     296             : {
     297       28632 :         return cmdline_sanity_checker(opts, opts);
     298             : }
     299             : 
     300       27094 : poptContext samba_popt_get_context(const char * name,
     301             :                                    int argc, const char ** argv,
     302             :                                    const struct poptOption * options,
     303             :                                    unsigned int flags)
     304             : {
     305             : #ifdef DEVELOPER
     306         233 :         bool ok;
     307             : 
     308       27094 :         ok = samba_cmdline_sanity_check(options);
     309       27094 :         if (!ok) {
     310           0 :                 return NULL;
     311             :         }
     312             : #endif
     313       27094 :         process_save_binary_name(name);
     314       27094 :         return poptGetContext(name, argc, argv, options, flags);
     315             : }
     316             : 
     317             : /**********************************************************
     318             :  * COMMON SAMBA POPT
     319             :  **********************************************************/
     320             : 
     321             : static bool log_to_file;
     322             : 
     323       30107 : static bool set_logfile(TALLOC_CTX *mem_ctx,
     324             :                         struct loadparm_context *lp_ctx,
     325             :                         const char *log_basename,
     326             :                         const char *process_name,
     327             :                         bool from_cmdline)
     328             : {
     329       30107 :         bool ok = false;
     330       30107 :         char *new_logfile = talloc_asprintf(mem_ctx,
     331             :                                             "%s/log.%s",
     332             :                                             log_basename,
     333             :                                             process_name);
     334       30107 :         if (new_logfile == NULL) {
     335           0 :                 return false;
     336             :         }
     337             : 
     338       30107 :         if (from_cmdline) {
     339         643 :                 ok = lpcfg_set_cmdline(lp_ctx,
     340             :                                        "log file",
     341             :                                        new_logfile);
     342             :         } else {
     343       29464 :                 ok = lpcfg_do_global_parameter(lp_ctx,
     344             :                                                "log file",
     345             :                                                new_logfile);
     346             :         }
     347       30107 :         if (!ok) {
     348           0 :                 fprintf(stderr,
     349             :                         "Failed to set log to %s\n",
     350             :                         new_logfile);
     351           0 :                 TALLOC_FREE(new_logfile);
     352           0 :                 return false;
     353             :         }
     354       30107 :         debug_set_logfile(new_logfile);
     355       30107 :         TALLOC_FREE(new_logfile);
     356             : 
     357       30107 :         return true;
     358             : }
     359             : 
     360       84154 : static void popt_samba_callback(poptContext popt_ctx,
     361             :                                 enum poptCallbackReason reason,
     362             :                                 const struct poptOption *opt,
     363             :                                 const char *arg, const void *data)
     364             : {
     365       84154 :         TALLOC_CTX *mem_ctx = samba_cmdline_get_talloc_ctx();
     366       84154 :         struct loadparm_context *lp_ctx = samba_cmdline_get_lp_ctx();
     367       84154 :         const char *pname = NULL;
     368        1436 :         bool ok;
     369             : 
     370             :         /* Find out basename of current program */
     371       84154 :         pname = getprogname();
     372             : 
     373       84154 :         if (reason == POPT_CALLBACK_REASON_PRE) {
     374       29464 :                 if (lp_ctx == NULL) {
     375           0 :                         fprintf(stderr,
     376             :                                 "Command line parsing not initialized!\n");
     377           0 :                         exit(1);
     378             :                 }
     379       29464 :                 ok = set_logfile(mem_ctx,
     380             :                                  lp_ctx,
     381             :                                  get_dyn_LOGFILEBASE(),
     382             :                                  pname,
     383             :                                  false);
     384       29464 :                 if (!ok) {
     385           0 :                         fprintf(stderr,
     386             :                                 "Failed to set log file for %s\n",
     387             :                                 pname);
     388           0 :                         exit(1);
     389             :                 }
     390       29037 :                 return;
     391             :         }
     392             : 
     393       54690 :         if (reason == POPT_CALLBACK_REASON_POST) {
     394       29392 :                 ok = cmdline_load_config_fn();
     395       29392 :                 if (!ok) {
     396           0 :                         fprintf(stderr,
     397             :                                 "%s - Failed to load config file!\n",
     398             :                                 getprogname());
     399           0 :                         exit(1);
     400             :                 }
     401             : 
     402       29392 :                 if (log_to_file) {
     403           0 :                         const struct loadparm_substitution *lp_sub =
     404         643 :                                 lpcfg_noop_substitution();
     405         643 :                         char *logfile = NULL;
     406             : 
     407         643 :                         logfile = lpcfg_logfile(lp_ctx, lp_sub, mem_ctx);
     408         643 :                         if (logfile == NULL) {
     409           0 :                                 fprintf(stderr,
     410             :                                         "Failed to setup logging to file!");
     411           0 :                                         exit(1);
     412             :                         }
     413         643 :                         debug_set_logfile(logfile);
     414         643 :                         setup_logging(logfile, DEBUG_FILE);
     415         643 :                         TALLOC_FREE(logfile);
     416             :                 }
     417             : 
     418       29392 :                 return;
     419             :         }
     420             : 
     421       25298 :         switch(opt->val) {
     422           0 :         case OPT_LEAK_REPORT:
     423           0 :                 talloc_enable_leak_report();
     424           0 :                 break;
     425           0 :         case OPT_LEAK_REPORT_FULL:
     426           0 :                 talloc_enable_leak_report_full();
     427           0 :                 break;
     428       11275 :         case OPT_OPTION:
     429       11275 :                 if (arg != NULL) {
     430       11275 :                         ok = lpcfg_set_option(lp_ctx, arg);
     431       11275 :                         if (!ok) {
     432           1 :                                 fprintf(stderr, "Error setting option '%s'\n", arg);
     433           1 :                                 exit(1);
     434             :                         }
     435             :                 }
     436       10930 :                 break;
     437         646 :         case 'd':
     438         646 :                 if (arg != NULL) {
     439         646 :                         ok = lpcfg_set_cmdline(lp_ctx, "log level", arg);
     440         646 :                         if (!ok) {
     441           0 :                                 fprintf(stderr,
     442             :                                         "Failed to set debug level to: %s\n",
     443             :                                         arg);
     444           0 :                                 exit(1);
     445             :                         }
     446             :                 }
     447         633 :                 break;
     448         141 :         case OPT_DEBUG_STDOUT:
     449         141 :                 setup_logging(pname, DEBUG_STDOUT);
     450         141 :                 break;
     451       12593 :         case OPT_CONFIGFILE:
     452       12593 :                 if (arg != NULL) {
     453       12593 :                         set_dyn_CONFIGFILE(arg);
     454             :                 }
     455       12401 :                 break;
     456         643 :         case 'l':
     457         643 :                 if (arg != NULL) {
     458         643 :                         ok = set_logfile(mem_ctx, lp_ctx, arg, pname, true);
     459         643 :                         if (!ok) {
     460           0 :                                 fprintf(stderr,
     461             :                                         "Failed to set log file for %s\n",
     462             :                                         arg);
     463           0 :                                 exit(1);
     464             :                         }
     465         643 :                         log_to_file = true;
     466             : 
     467         643 :                         set_dyn_LOGFILEBASE(arg);
     468             :                 }
     469         643 :                 break;
     470             :         }
     471             : }
     472             : 
     473             : static struct poptOption popt_common_debug[] = {
     474             :         {
     475             :                 .argInfo    = POPT_ARG_CALLBACK|POPT_CBFLAG_PRE|POPT_CBFLAG_POST,
     476             :                 .arg        = (void *)popt_samba_callback,
     477             :         },
     478             :         {
     479             :                 .longName   = "debuglevel",
     480             :                 .shortName  = 'd',
     481             :                 .argInfo    = POPT_ARG_STRING,
     482             :                 .val        = 'd',
     483             :                 .descrip    = "Set debug level",
     484             :                 .argDescrip = "DEBUGLEVEL",
     485             :         },
     486             :         {
     487             :                 .longName   = "debug-stdout",
     488             :                 .argInfo    = POPT_ARG_NONE,
     489             :                 .val        = OPT_DEBUG_STDOUT,
     490             :                 .descrip    = "Send debug output to standard output",
     491             :         },
     492             :         POPT_TABLEEND
     493             : };
     494             : 
     495             : static struct poptOption popt_common_option[] = {
     496             :         {
     497             :                 .argInfo    = POPT_ARG_CALLBACK|POPT_CBFLAG_PRE|POPT_CBFLAG_POST,
     498             :                 .arg        = (void *)popt_samba_callback,
     499             :         },
     500             :         {
     501             :                 .longName   = "option",
     502             :                 .argInfo    = POPT_ARG_STRING,
     503             :                 .val        = OPT_OPTION,
     504             :                 .descrip    = "Set smb.conf option from command line",
     505             :                 .argDescrip = "name=value",
     506             :         },
     507             :         POPT_TABLEEND
     508             : };
     509             : 
     510             : static struct poptOption popt_common_config[] = {
     511             :         {
     512             :                 .argInfo    = POPT_ARG_CALLBACK|POPT_CBFLAG_PRE|POPT_CBFLAG_POST,
     513             :                 .arg        = (void *)popt_samba_callback,
     514             :         },
     515             :         {
     516             :                 .longName   = "configfile",
     517             :                 .argInfo    = POPT_ARG_STRING,
     518             :                 .val        = OPT_CONFIGFILE,
     519             :                 .descrip    = "Use alternative configuration file",
     520             :                 .argDescrip = "CONFIGFILE",
     521             :         },
     522             :         POPT_TABLEEND
     523             : };
     524             : 
     525             : static struct poptOption popt_common_samba[] = {
     526             :         {
     527             :                 .argInfo    = POPT_ARG_CALLBACK|POPT_CBFLAG_PRE|POPT_CBFLAG_POST,
     528             :                 .arg        = (void *)popt_samba_callback,
     529             :         },
     530             :         {
     531             :                 .longName   = "debuglevel",
     532             :                 .shortName  = 'd',
     533             :                 .argInfo    = POPT_ARG_STRING,
     534             :                 .val        = 'd',
     535             :                 .descrip    = "Set debug level",
     536             :                 .argDescrip = "DEBUGLEVEL",
     537             :         },
     538             :         {
     539             :                 .longName   = "debug-stdout",
     540             :                 .argInfo    = POPT_ARG_NONE,
     541             :                 .val        = OPT_DEBUG_STDOUT,
     542             :                 .descrip    = "Send debug output to standard output",
     543             :         },
     544             :         {
     545             :                 .longName   = "configfile",
     546             :                 .shortName  = 's',
     547             :                 .argInfo    = POPT_ARG_STRING,
     548             :                 .val        = OPT_CONFIGFILE,
     549             :                 .descrip    = "Use alternative configuration file",
     550             :                 .argDescrip = "CONFIGFILE",
     551             :         },
     552             :         {
     553             :                 .longName   = "option",
     554             :                 .argInfo    = POPT_ARG_STRING,
     555             :                 .val        = OPT_OPTION,
     556             :                 .descrip    = "Set smb.conf option from command line",
     557             :                 .argDescrip = "name=value",
     558             :         },
     559             :         {
     560             :                 .longName   = "log-basename",
     561             :                 .shortName  = 'l',
     562             :                 .argInfo    = POPT_ARG_STRING,
     563             :                 .val        = 'l',
     564             :                 .descrip    = "Basename for log/debug files",
     565             :                 .argDescrip = "LOGFILEBASE",
     566             :         },
     567             :         {
     568             :                 .longName   = "leak-report",
     569             :                 .argInfo    = POPT_ARG_NONE,
     570             :                 .val        = OPT_LEAK_REPORT,
     571             :                 .descrip    = "enable talloc leak reporting on exit",
     572             :         },
     573             :         {
     574             :                 .longName   = "leak-report-full",
     575             :                 .argInfo    = POPT_ARG_NONE,
     576             :                 .val        = OPT_LEAK_REPORT_FULL,
     577             :                 .descrip    = "enable full talloc leak reporting on exit",
     578             :         },
     579             :         POPT_TABLEEND
     580             : };
     581             : 
     582             : static struct poptOption popt_common_samba_ldb[] = {
     583             :         {
     584             :                 .argInfo    = POPT_ARG_CALLBACK|POPT_CBFLAG_PRE|POPT_CBFLAG_POST,
     585             :                 .arg        = (void *)popt_samba_callback,
     586             :         },
     587             :         {
     588             :                 .longName   = "debuglevel",
     589             :                 .shortName  = 'd',
     590             :                 .argInfo    = POPT_ARG_STRING,
     591             :                 .val        = 'd',
     592             :                 .descrip    = "Set debug level",
     593             :                 .argDescrip = "DEBUGLEVEL",
     594             :         },
     595             :         {
     596             :                 .longName   = "debug-stdout",
     597             :                 .argInfo    = POPT_ARG_NONE,
     598             :                 .val        = OPT_DEBUG_STDOUT,
     599             :                 .descrip    = "Send debug output to standard output",
     600             :         },
     601             :         {
     602             :                 .longName   = "configfile",
     603             :                 .argInfo    = POPT_ARG_STRING,
     604             :                 .val        = OPT_CONFIGFILE,
     605             :                 .descrip    = "Use alternative configuration file",
     606             :                 .argDescrip = "CONFIGFILE",
     607             :         },
     608             :         {
     609             :                 .longName   = "option",
     610             :                 .argInfo    = POPT_ARG_STRING,
     611             :                 .val        = OPT_OPTION,
     612             :                 .descrip    = "Set smb.conf option from command line",
     613             :                 .argDescrip = "name=value",
     614             :         },
     615             :         {
     616             :                 .longName   = "log-basename",
     617             :                 .shortName  = 'l',
     618             :                 .argInfo    = POPT_ARG_STRING,
     619             :                 .val        = 'l',
     620             :                 .descrip    = "Basename for log/debug files",
     621             :                 .argDescrip = "LOGFILEBASE",
     622             :         },
     623             :         {
     624             :                 .longName   = "leak-report",
     625             :                 .argInfo    = POPT_ARG_NONE,
     626             :                 .val        = OPT_LEAK_REPORT,
     627             :                 .descrip    = "enable talloc leak reporting on exit",
     628             :         },
     629             :         {
     630             :                 .longName   = "leak-report-full",
     631             :                 .argInfo    = POPT_ARG_NONE,
     632             :                 .val        = OPT_LEAK_REPORT_FULL,
     633             :                 .descrip    = "enable full talloc leak reporting on exit",
     634             :         },
     635             :         POPT_TABLEEND
     636             : };
     637             : 
     638             : /**********************************************************
     639             :  * CONNECTION POPT
     640             :  **********************************************************/
     641             : 
     642       29573 : static void popt_connection_callback(poptContext popt_ctx,
     643             :                                      enum poptCallbackReason reason,
     644             :                                      const struct poptOption *opt,
     645             :                                      const char *arg,
     646             :                                      const void *data)
     647             : {
     648       29573 :         struct loadparm_context *lp_ctx = cmdline_lp_ctx;
     649             : 
     650       29573 :         if (reason == POPT_CALLBACK_REASON_PRE) {
     651       21655 :                 if (lp_ctx == NULL) {
     652           0 :                         fprintf(stderr,
     653             :                                 "Command line parsing not initialized!\n");
     654           0 :                         exit(1);
     655             :                 }
     656       21333 :                 return;
     657             :         }
     658             : 
     659        7918 :         switch(opt->val) {
     660           0 :         case 'O':
     661           0 :                 if (arg != NULL) {
     662           0 :                         lpcfg_set_cmdline(lp_ctx, "socket options", arg);
     663             :                 }
     664           0 :                 break;
     665           0 :         case 'R':
     666           0 :                 if (arg != NULL) {
     667           0 :                         lpcfg_set_cmdline(lp_ctx, "name resolve order", arg);
     668             :                 }
     669           0 :                 break;
     670        6907 :         case 'm':
     671        6907 :                 if (arg != NULL) {
     672        6907 :                         lpcfg_set_cmdline(lp_ctx, "client max protocol", arg);
     673             :                 }
     674        6907 :                 break;
     675           0 :         case OPT_NETBIOS_SCOPE:
     676           0 :                 if (arg != NULL) {
     677           0 :                         lpcfg_set_cmdline(lp_ctx, "netbios scope", arg);
     678             :                 }
     679           0 :                 break;
     680          28 :         case 'n':
     681          28 :                 if (arg != NULL) {
     682          28 :                         lpcfg_set_cmdline(lp_ctx, "netbios name", arg);
     683             :                 }
     684          28 :                 break;
     685         949 :         case 'W':
     686         949 :                 if (arg != NULL) {
     687         949 :                         lpcfg_set_cmdline(lp_ctx, "workgroup", arg);
     688             :                 }
     689         926 :                 break;
     690          34 :         case 'r':
     691          34 :                 if (arg != NULL) {
     692          34 :                         lpcfg_set_cmdline(lp_ctx, "realm", arg);
     693             :                 }
     694          34 :                 break;
     695             :         }
     696             : }
     697             : 
     698             : static struct poptOption popt_common_connection[] = {
     699             :         {
     700             :                 .argInfo    = POPT_ARG_CALLBACK|POPT_CBFLAG_PRE,
     701             :                 .arg        = (void *)popt_connection_callback,
     702             :         },
     703             :         {
     704             :                 .longName   = "name-resolve",
     705             :                 .shortName  = 'R',
     706             :                 .argInfo    = POPT_ARG_STRING,
     707             :                 .val        = 'R',
     708             :                 .descrip    = "Use these name resolution services only",
     709             :                 .argDescrip = "NAME-RESOLVE-ORDER",
     710             :         },
     711             :         {
     712             :                 .longName   = "socket-options",
     713             :                 .shortName  = 'O',
     714             :                 .argInfo    = POPT_ARG_STRING,
     715             :                 .val        = 'O',
     716             :                 .descrip    = "socket options to use",
     717             :                 .argDescrip = "SOCKETOPTIONS",
     718             :         },
     719             :         {
     720             :                 .longName   = "max-protocol",
     721             :                 .shortName  = 'm',
     722             :                 .argInfo    = POPT_ARG_STRING,
     723             :                 .val        = 'm',
     724             :                 .descrip    = "Set max protocol level",
     725             :                 .argDescrip = "MAXPROTOCOL",
     726             :         },
     727             :         {
     728             :                 .longName   = "netbiosname",
     729             :                 .shortName  = 'n',
     730             :                 .argInfo    = POPT_ARG_STRING,
     731             :                 .val        = 'n',
     732             :                 .descrip    = "Primary netbios name",
     733             :                 .argDescrip = "NETBIOSNAME",
     734             :         },
     735             :         {
     736             :                 .longName   = "netbios-scope",
     737             :                 .argInfo    = POPT_ARG_STRING,
     738             :                 .val        = OPT_NETBIOS_SCOPE,
     739             :                 .descrip    = "Use this Netbios scope",
     740             :                 .argDescrip = "SCOPE",
     741             :         },
     742             :         {
     743             :                 .longName   = "workgroup",
     744             :                 .shortName  = 'W',
     745             :                 .argInfo    = POPT_ARG_STRING,
     746             :                 .val        = 'W',
     747             :                 .descrip    = "Set the workgroup name",
     748             :                 .argDescrip = "WORKGROUP",
     749             :         },
     750             :         {
     751             :                 .longName   = "realm",
     752             :                 .argInfo    = POPT_ARG_STRING,
     753             :                 .val        = 'r',
     754             :                 .descrip    = "Set the realm name",
     755             :                 .argDescrip = "REALM",
     756             :         },
     757             :         POPT_TABLEEND
     758             : };
     759             : 
     760             : /**********************************************************
     761             :  * CREDENTIALS POPT
     762             :  **********************************************************/
     763             : 
     764             : static bool skip_password_callback;
     765             : static bool machine_account_pending;
     766             : 
     767       62291 : static void popt_common_credentials_callback(poptContext popt_ctx,
     768             :                                              enum poptCallbackReason reason,
     769             :                                              const struct poptOption *opt,
     770             :                                              const char *arg,
     771             :                                              const void *data)
     772             : {
     773       62291 :         struct loadparm_context *lp_ctx = samba_cmdline_get_lp_ctx();
     774       62291 :         struct cli_credentials *creds = samba_cmdline_get_creds();
     775         710 :         bool ok;
     776             : 
     777       62291 :         if (reason == POPT_CALLBACK_REASON_PRE) {
     778       21354 :                 if (creds == NULL) {
     779           0 :                         fprintf(stderr,
     780             :                                 "Command line parsing not initialized!\n");
     781           0 :                         exit(1);
     782             :                 }
     783       21032 :                 return;
     784             :         }
     785             : 
     786       40937 :         if (reason == POPT_CALLBACK_REASON_POST) {
     787       21334 :                 const char *username = NULL;
     788       21334 :                 enum credentials_obtained username_obtained =
     789             :                         CRED_UNINITIALISED;
     790       21334 :                 enum credentials_obtained password_obtained =
     791             :                         CRED_UNINITIALISED;
     792             : 
     793             :                 /*
     794             :                  * This calls cli_credentials_set_conf() to get the defaults
     795             :                  * form smb.conf and set the winbind separator.
     796             :                  *
     797             :                  * Just warn that we can't read the smb.conf. There might not be
     798             :                  * one available or we want to ignore it.
     799             :                  */
     800       21334 :                 ok = cli_credentials_guess(creds, lp_ctx);
     801       21334 :                 if (!ok) {
     802           0 :                         fprintf(stderr,
     803             :                                 "Unable to read defaults from smb.conf\n");
     804             :                 }
     805             : 
     806       21334 :                 (void)cli_credentials_get_password_and_obtained(creds,
     807             :                                                                 &password_obtained);
     808       21334 :                 if (!skip_password_callback &&
     809       20734 :                     password_obtained < CRED_CALLBACK) {
     810        3392 :                         ok = cli_credentials_set_cmdline_callbacks(creds);
     811        3392 :                         if (!ok) {
     812           0 :                                 fprintf(stderr,
     813             :                                         "Failed to set cmdline password "
     814             :                                         "callback\n");
     815           0 :                                 exit(1);
     816             :                         }
     817             :                 }
     818             : 
     819       21334 :                 if (machine_account_pending) {
     820           0 :                         NTSTATUS status;
     821             : 
     822         163 :                         status = cli_credentials_set_machine_account_fn(
     823             :                                 creds, lp_ctx);
     824         163 :                         if (!NT_STATUS_IS_OK(status)) {
     825          10 :                                 fprintf(stderr,
     826             :                                         "Failed to set machine account: %s\n",
     827             :                                         nt_errstr(status));
     828          10 :                                 exit(1);
     829             :                         }
     830             :                 }
     831             : 
     832             :                 /*
     833             :                  * When we set the username during the handling of the options
     834             :                  * passed to the binary we haven't loaded the config yet. This
     835             :                  * means that we didn't take the 'winbind separator' into
     836             :                  * account.
     837             :                  *
     838             :                  * The username might contain the domain name and thus it
     839             :                  * hasn't been correctly parsed yet. If we have a username we
     840             :                  * need to set it again to run the string parser for the
     841             :                  * username correctly.
     842             :                  */
     843         322 :                 username =
     844       21324 :                         cli_credentials_get_username_and_obtained(
     845             :                                         creds, &username_obtained);
     846       21324 :                 if (username_obtained == CRED_SPECIFIED &&
     847       17710 :                     username != NULL && username[0] != '\0') {
     848       17224 :                         cli_credentials_parse_string(creds,
     849             :                                                      username,
     850             :                                                      CRED_SPECIFIED);
     851             :                 }
     852             : 
     853       21324 :                 return;
     854             :         }
     855             : 
     856       19603 :         switch(opt->val) {
     857       17499 :         case 'U':
     858       17499 :                 if (arg != NULL) {
     859       17499 :                         cli_credentials_parse_string(creds,
     860             :                                                      arg,
     861             :                                                      CRED_SPECIFIED);
     862             :                 }
     863       17441 :                 break;
     864         119 :         case OPT_PASSWORD:
     865         119 :                 if (arg != NULL) {
     866         119 :                         ok = cli_credentials_set_password(creds,
     867             :                                                           arg,
     868             :                                                           CRED_SPECIFIED);
     869         119 :                         if (!ok) {
     870           0 :                                 fprintf(stderr,
     871             :                                         "Failed to set password!\n");
     872           0 :                                 exit(1);
     873             :                         }
     874             : 
     875         119 :                         skip_password_callback = true;
     876             :                 }
     877         119 :                 break;
     878           2 :         case OPT_NT_HASH:
     879           2 :                 cli_credentials_set_password_will_be_nt_hash(creds, true);
     880           2 :                 break;
     881          54 :         case 'A':
     882          54 :                 if (arg != NULL) {
     883          54 :                         ok = cli_credentials_parse_file(creds,
     884             :                                                         arg,
     885             :                                                         CRED_SPECIFIED);
     886          54 :                         if (!ok) {
     887           0 :                                 fprintf(stderr,
     888             :                                         "Failed to set parse authentication file!\n");
     889           0 :                                 exit(1);
     890             :                         }
     891          54 :                         skip_password_callback = true;
     892             :                 }
     893          54 :                 break;
     894          62 :         case 'N':
     895          62 :                 ok = cli_credentials_set_password(creds,
     896             :                                                   NULL,
     897             :                                                   CRED_SPECIFIED);
     898          62 :                 if (!ok) {
     899           0 :                         fprintf(stderr,
     900             :                                 "Failed to set password!\n");
     901           0 :                         exit(1);
     902             :                 }
     903          62 :                 skip_password_callback = true;
     904          62 :                 break;
     905         163 :         case 'P':
     906             :                 /*
     907             :                  * Later, after this is all over, get the machine account
     908             :                  * details from the secrets.(l|t)db.
     909             :                  */
     910         163 :                 machine_account_pending = true;
     911         163 :                 break;
     912          55 :         case OPT_SIMPLE_BIND_DN:
     913          55 :                 if (arg != NULL) {
     914          55 :                         ok = cli_credentials_set_bind_dn(creds, arg);
     915          55 :                         if (!ok) {
     916           0 :                                 fprintf(stderr,
     917             :                                         "Failed to set bind DN!\n");
     918           0 :                                 exit(1);
     919             :                         }
     920             :                 }
     921          55 :                 break;
     922         206 :         case OPT_USE_KERBEROS: {
     923         206 :                 int32_t use_kerberos = INT_MIN;
     924         206 :                 if (arg == NULL) {
     925           0 :                         fprintf(stderr,
     926             :                                 "Failed to parse "
     927             :                                 "--use-kerberos=desired|required|off: "
     928             :                                 "Missing argument\n");
     929           0 :                         exit(1);
     930             :                 }
     931             : 
     932         206 :                 use_kerberos = lpcfg_parse_enum_vals("client use kerberos",
     933             :                                                      arg);
     934         206 :                 if (use_kerberos == INT_MIN) {
     935           0 :                         fprintf(stderr,
     936             :                                 "Failed to parse "
     937             :                                 "--use-kerberos=desired|required|off: "
     938             :                                 "Invalid argument\n");
     939           0 :                         exit(1);
     940             :                 }
     941             : 
     942         206 :                 ok = cli_credentials_set_kerberos_state(creds,
     943             :                                                         use_kerberos,
     944             :                                                         CRED_SPECIFIED);
     945         206 :                 if (!ok) {
     946           0 :                         fprintf(stderr,
     947             :                                 "Failed to set Kerberos state to %s!\n", arg);
     948           0 :                         exit(1);
     949             :                 }
     950         206 :                 break;
     951             :         }
     952         296 :         case OPT_USE_KERBEROS_CCACHE: {
     953         296 :                 const char *error_string = NULL;
     954           0 :                 int rc;
     955             : 
     956         296 :                 if (arg == NULL) {
     957           0 :                         fprintf(stderr,
     958             :                                 "Failed to parse --use-krb5-ccache=CCACHE: "
     959             :                                 "Missing argument\n");
     960           0 :                         exit(1);
     961             :                 }
     962             : 
     963         296 :                 ok = cli_credentials_set_kerberos_state(creds,
     964             :                                                         CRED_USE_KERBEROS_REQUIRED,
     965             :                                                         CRED_SPECIFIED);
     966         296 :                 if (!ok) {
     967           0 :                         fprintf(stderr,
     968             :                                 "Failed to set Kerberos state to %s!\n", arg);
     969           0 :                         exit(1);
     970             :                 }
     971             : 
     972         296 :                 rc = cli_credentials_set_ccache(creds,
     973             :                                                 lp_ctx,
     974             :                                                 arg,
     975             :                                                 CRED_SPECIFIED,
     976             :                                                 &error_string);
     977         296 :                 if (rc != 0) {
     978           0 :                         fprintf(stderr,
     979             :                                 "Error reading krb5 credentials cache: '%s'"
     980             :                                 " - %s\n",
     981             :                                 arg,
     982             :                                 error_string);
     983           0 :                         exit(1);
     984             :                 }
     985             : 
     986         296 :                 skip_password_callback = true;
     987         296 :                 break;
     988             :         }
     989          48 :         case OPT_USE_WINBIND_CCACHE:
     990             :         {
     991           0 :                 uint32_t gensec_features;
     992             : 
     993          48 :                 gensec_features = cli_credentials_get_gensec_features(creds);
     994          48 :                 gensec_features |= GENSEC_FEATURE_NTLM_CCACHE;
     995             : 
     996          48 :                 ok = cli_credentials_set_gensec_features(creds,
     997             :                                                          gensec_features,
     998             :                                                          CRED_SPECIFIED);
     999          48 :                 if (!ok) {
    1000           0 :                         fprintf(stderr,
    1001             :                                 "Failed to set gensec feature!\n");
    1002           0 :                         exit(1);
    1003             :                 }
    1004             : 
    1005          48 :                 skip_password_callback = true;
    1006          48 :                 break;
    1007             :         }
    1008        1099 :         case OPT_CLIENT_PROTECTION: {
    1009           8 :                 uint32_t gensec_features;
    1010        1099 :                 enum smb_signing_setting signing_state =
    1011             :                         SMB_SIGNING_OFF;
    1012        1099 :                 enum smb_encryption_setting encryption_state =
    1013             :                         SMB_ENCRYPTION_OFF;
    1014             : 
    1015        1099 :                 if (arg == NULL) {
    1016           0 :                         fprintf(stderr,
    1017             :                                 "Failed to parse "
    1018             :                                 "--client-protection=sign|encrypt|off: "
    1019             :                                 "Missing argument\n");
    1020           0 :                         exit(1);
    1021             :                 }
    1022             : 
    1023           8 :                 gensec_features =
    1024        1099 :                         cli_credentials_get_gensec_features(
    1025             :                                         creds);
    1026             : 
    1027        1099 :                 if (strequal(arg, "off")) {
    1028          38 :                         gensec_features &=
    1029             :                                 ~(GENSEC_FEATURE_SIGN|GENSEC_FEATURE_SEAL);
    1030             : 
    1031          38 :                         signing_state = SMB_SIGNING_OFF;
    1032          38 :                         encryption_state = SMB_ENCRYPTION_OFF;
    1033        1061 :                 } else if (strequal(arg, "sign")) {
    1034         703 :                         gensec_features |= GENSEC_FEATURE_SIGN;
    1035             : 
    1036         703 :                         signing_state = SMB_SIGNING_REQUIRED;
    1037         703 :                         encryption_state = SMB_ENCRYPTION_OFF;
    1038         358 :                 } else if (strequal(arg, "encrypt")) {
    1039         358 :                         gensec_features |= GENSEC_FEATURE_SEAL;
    1040             : 
    1041         358 :                         signing_state = SMB_SIGNING_REQUIRED;
    1042         358 :                         encryption_state = SMB_ENCRYPTION_REQUIRED;
    1043             :                 } else {
    1044           0 :                         fprintf(stderr,
    1045             :                                 "Failed to parse --client-protection\n");
    1046           0 :                         exit(1);
    1047             :                 }
    1048             : 
    1049        1099 :                 ok = cli_credentials_set_gensec_features(creds,
    1050             :                                                                 gensec_features,
    1051             :                                                                 CRED_SPECIFIED);
    1052        1099 :                 if (!ok) {
    1053           0 :                         fprintf(stderr,
    1054             :                                 "Failed to set gensec feature!\n");
    1055           0 :                         exit(1);
    1056             :                 }
    1057             : 
    1058        1099 :                 ok = cli_credentials_set_smb_signing(creds,
    1059             :                                                         signing_state,
    1060             :                                                         CRED_SPECIFIED);
    1061        1099 :                 if (!ok) {
    1062           0 :                         fprintf(stderr,
    1063             :                                 "Failed to set smb signing!\n");
    1064           0 :                         exit(1);
    1065             :                 }
    1066             : 
    1067        1099 :                 ok = cli_credentials_set_smb_encryption(creds,
    1068             :                                                         encryption_state,
    1069             :                                                         CRED_SPECIFIED);
    1070        1099 :                 if (!ok) {
    1071           0 :                         fprintf(stderr,
    1072             :                                 "Failed to set smb encryption!\n");
    1073           0 :                         exit(1);
    1074             :                 }
    1075        1091 :                 break;
    1076             :         }
    1077             :         } /* switch */
    1078             : }
    1079             : 
    1080             : static struct poptOption popt_common_credentials[] = {
    1081             :         {
    1082             :                 .argInfo    = POPT_ARG_CALLBACK|POPT_CBFLAG_PRE|POPT_CBFLAG_POST,
    1083             :                 .arg        = (void *)popt_common_credentials_callback,
    1084             :         },
    1085             :         {
    1086             :                 .longName   = "user",
    1087             :                 .shortName  = 'U',
    1088             :                 .argInfo    = POPT_ARG_STRING,
    1089             :                 .val        = 'U',
    1090             :                 .descrip    = "Set the network username",
    1091             :                 .argDescrip = "[DOMAIN/]USERNAME[%PASSWORD]",
    1092             :         },
    1093             :         {
    1094             :                 .longName   = "no-pass",
    1095             :                 .shortName  = 'N',
    1096             :                 .argInfo    = POPT_ARG_NONE,
    1097             :                 .val        = 'N',
    1098             :                 .descrip    = "Don't ask for a password",
    1099             :         },
    1100             :         {
    1101             :                 .longName   = "password",
    1102             :                 .argInfo    = POPT_ARG_STRING,
    1103             :                 .val        = OPT_PASSWORD,
    1104             :                 .descrip    = "Password",
    1105             :         },
    1106             :         {
    1107             :                 .longName   = "pw-nt-hash",
    1108             :                 .argInfo    = POPT_ARG_NONE,
    1109             :                 .val        = OPT_NT_HASH,
    1110             :                 .descrip    = "The supplied password is the NT hash",
    1111             :         },
    1112             :         {
    1113             :                 .longName   = "authentication-file",
    1114             :                 .shortName  = 'A',
    1115             :                 .argInfo    = POPT_ARG_STRING,
    1116             :                 .val        = 'A',
    1117             :                 .descrip    = "Get the credentials from a file",
    1118             :                 .argDescrip = "FILE",
    1119             :         },
    1120             :         {
    1121             :                 .longName   = "machine-pass",
    1122             :                 .shortName  = 'P',
    1123             :                 .argInfo    = POPT_ARG_NONE,
    1124             :                 .val        = 'P',
    1125             :                 .descrip    = "Use stored machine account password",
    1126             :         },
    1127             :         {
    1128             :                 .longName   = "simple-bind-dn",
    1129             :                 .argInfo    = POPT_ARG_STRING,
    1130             :                 .val        = OPT_SIMPLE_BIND_DN,
    1131             :                 .descrip    = "DN to use for a simple bind",
    1132             :                 .argDescrip = "DN",
    1133             :         },
    1134             :         {
    1135             :                 .longName   = "use-kerberos",
    1136             :                 .argInfo    = POPT_ARG_STRING,
    1137             :                 .val        = OPT_USE_KERBEROS,
    1138             :                 .descrip    = "Use Kerberos authentication",
    1139             :                 .argDescrip = "desired|required|off",
    1140             :         },
    1141             :         {
    1142             :                 .longName   = "use-krb5-ccache",
    1143             :                 .argInfo    = POPT_ARG_STRING,
    1144             :                 .val        = OPT_USE_KERBEROS_CCACHE,
    1145             :                 .descrip    = "Credentials cache location for Kerberos",
    1146             :                 .argDescrip = "CCACHE",
    1147             :         },
    1148             :         {
    1149             :                 .longName   = "use-winbind-ccache",
    1150             :                 .argInfo    = POPT_ARG_NONE,
    1151             :                 .val        = OPT_USE_WINBIND_CCACHE,
    1152             :                 .descrip    = "Use the winbind ccache for authentication",
    1153             :         },
    1154             :         {
    1155             :                 .longName   = "client-protection",
    1156             :                 .argInfo    = POPT_ARG_STRING,
    1157             :                 .val        = OPT_CLIENT_PROTECTION,
    1158             :                 .descrip    = "Configure used protection for client connections",
    1159             :                 .argDescrip = "sign|encrypt|off",
    1160             :         },
    1161             :         POPT_TABLEEND
    1162             : };
    1163             : 
    1164             : /**********************************************************
    1165             :  * VERSION POPT
    1166             :  **********************************************************/
    1167             : 
    1168           0 : static void popt_version_callback(poptContext ctx,
    1169             :                                   enum poptCallbackReason reason,
    1170             :                                   const struct poptOption *opt,
    1171             :                                   const char *arg,
    1172             :                                   const void *data)
    1173             : {
    1174           0 :         switch(opt->val) {
    1175           0 :         case 'V':
    1176           0 :                 printf("Version %s\n", SAMBA_VERSION_STRING);
    1177           0 :                 exit(0);
    1178             :         }
    1179           0 : }
    1180             : 
    1181             : static struct poptOption popt_common_version[] = {
    1182             :         {
    1183             :                 .argInfo    = POPT_ARG_CALLBACK,
    1184             :                 .arg        = (void *)popt_version_callback,
    1185             :         },
    1186             :         {
    1187             :                 .longName   = "version",
    1188             :                 .shortName  = 'V',
    1189             :                 .argInfo    = POPT_ARG_NONE,
    1190             :                 .val        = 'V',
    1191             :                 .descrip    = "Print version",
    1192             :         },
    1193             :         POPT_TABLEEND
    1194             : };
    1195             : 
    1196             : /**********************************************************
    1197             :  * DAEMON POPT
    1198             :  **********************************************************/
    1199             : 
    1200         372 : static void popt_daemon_callback(poptContext ctx,
    1201             :                                  enum poptCallbackReason reason,
    1202             :                                  const struct poptOption *opt,
    1203             :                                  const char *arg,
    1204             :                                  const void *data)
    1205             : {
    1206         372 :         switch(opt->val) {
    1207           0 :         case OPT_DAEMON:
    1208           0 :                 cmdline_daemon_cfg.daemon = true;
    1209           0 :                 break;
    1210          72 :         case OPT_INTERACTIVE:
    1211          72 :                 cmdline_daemon_cfg.interactive = true;
    1212          72 :                 cmdline_daemon_cfg.fork = false;
    1213          72 :                 break;
    1214         131 :         case OPT_FORK:
    1215         131 :                 cmdline_daemon_cfg.fork = false;
    1216         131 :                 break;
    1217         169 :         case OPT_NO_PROCESS_GROUP:
    1218         169 :                 cmdline_daemon_cfg.no_process_group = true;
    1219         169 :                 break;
    1220             :         }
    1221         372 : }
    1222             : 
    1223             : static struct poptOption popt_common_daemon[] = {
    1224             :         {
    1225             :                 .argInfo    = POPT_ARG_CALLBACK,
    1226             :                 .arg        = (void *)popt_daemon_callback
    1227             :         },
    1228             :         {
    1229             :                 .longName   = "daemon",
    1230             :                 .shortName  = 'D',
    1231             :                 .argInfo    = POPT_ARG_NONE,
    1232             :                 .arg        = NULL,
    1233             :                 .val        = OPT_DAEMON,
    1234             :                 .descrip    = "Become a daemon (default)" ,
    1235             :         },
    1236             :         {
    1237             :                 .longName   = "interactive",
    1238             :                 .shortName  = 'i',
    1239             :                 .argInfo    = POPT_ARG_NONE,
    1240             :                 .arg        = NULL,
    1241             :                 .val        = OPT_INTERACTIVE,
    1242             :                 .descrip    = "Run interactive (not a daemon) and log to stdout",
    1243             :         },
    1244             :         {
    1245             :                 .longName   = "foreground",
    1246             :                 .shortName  = 'F',
    1247             :                 .argInfo    = POPT_ARG_NONE,
    1248             :                 .arg        = NULL,
    1249             :                 .val        = OPT_FORK,
    1250             :                 .descrip    = "Run daemon in foreground (for daemontools, etc.)",
    1251             :         },
    1252             :         {
    1253             :                 .longName   = "no-process-group",
    1254             :                 .shortName  = '\0',
    1255             :                 .argInfo    = POPT_ARG_NONE,
    1256             :                 .arg        = NULL,
    1257             :                 .val        = OPT_NO_PROCESS_GROUP,
    1258             :                 .descrip    = "Don't create a new process group" ,
    1259             :         },
    1260             :         POPT_TABLEEND
    1261             : };
    1262             : 
    1263             : /**********************************************************
    1264             :  * LEGACY S3 POPT
    1265             :  **********************************************************/
    1266             : 
    1267          21 : static void popt_legacy_s3_callback(poptContext ctx,
    1268             :                                     enum poptCallbackReason reason,
    1269             :                                     const struct poptOption *opt,
    1270             :                                     const char *arg,
    1271             :                                     const void *data)
    1272             : {
    1273          21 :         struct cli_credentials *creds = samba_cmdline_get_creds();
    1274           0 :         bool ok;
    1275             : 
    1276          21 :         switch(opt->val) {
    1277          21 :         case 'k':
    1278          21 :                 fprintf(stderr,
    1279             :                         "WARNING: The option -k|--kerberos is deprecated!\n");
    1280             : 
    1281          21 :                 ok = cli_credentials_set_kerberos_state(creds,
    1282             :                                                         CRED_USE_KERBEROS_REQUIRED,
    1283             :                                                         CRED_SPECIFIED);
    1284          21 :                 if (!ok) {
    1285           0 :                         fprintf(stderr,
    1286             :                                 "Failed to set Kerberos state to %s!\n", arg);
    1287           0 :                         exit(1);
    1288             :                 }
    1289             : 
    1290          21 :                 skip_password_callback = true;
    1291          21 :                 break;
    1292             :         }
    1293          21 : }
    1294             : 
    1295             : /* We allow '-k yes' too. */
    1296             : static struct poptOption popt_legacy_s3[] = {
    1297             :         {
    1298             :                 .argInfo    = POPT_ARG_CALLBACK,
    1299             :                 .arg        = (void *)popt_legacy_s3_callback,
    1300             :         },
    1301             :         {
    1302             :                 .longName   = "kerberos",
    1303             :                 .shortName  = 'k',
    1304             :                 .argInfo    = POPT_ARG_NONE,
    1305             :                 .val        = 'k',
    1306             :                 .descrip    = "DEPRECATED: Migrate to --use-kerberos",
    1307             :         },
    1308             :         POPT_TABLEEND
    1309             : };
    1310             : 
    1311             : /**********************************************************
    1312             :  * LEGACY S4 POPT
    1313             :  **********************************************************/
    1314             : 
    1315         748 : static void popt_legacy_s4_callback(poptContext ctx,
    1316             :                                     enum poptCallbackReason reason,
    1317             :                                     const struct poptOption *opt,
    1318             :                                     const char *arg,
    1319             :                                     const void *data)
    1320             : {
    1321         748 :         struct cli_credentials *creds = samba_cmdline_get_creds();
    1322          10 :         bool ok;
    1323             : 
    1324         748 :         switch(opt->val) {
    1325         748 :         case 'k': {
    1326         748 :                 enum credentials_use_kerberos use_kerberos =
    1327             :                         CRED_USE_KERBEROS_REQUIRED;
    1328             : 
    1329         748 :                 fprintf(stderr,
    1330             :                         "WARNING: The option -k|--kerberos is deprecated!\n");
    1331             : 
    1332         748 :                 if (arg != NULL) {
    1333         748 :                         if (strcasecmp_m(arg, "yes") == 0) {
    1334         522 :                                 use_kerberos = CRED_USE_KERBEROS_REQUIRED;
    1335         223 :                         } else if (strcasecmp_m(arg, "no") == 0) {
    1336         216 :                                 use_kerberos = CRED_USE_KERBEROS_DISABLED;
    1337             :                         } else {
    1338           0 :                                 fprintf(stderr,
    1339             :                                         "Error parsing -k %s. Should be "
    1340             :                                         "-k [yes|no]\n",
    1341             :                                         arg);
    1342           0 :                                 exit(1);
    1343             :                         }
    1344             :                 }
    1345             : 
    1346         748 :                 ok = cli_credentials_set_kerberos_state(creds,
    1347             :                                                         use_kerberos,
    1348             :                                                         CRED_SPECIFIED);
    1349         748 :                 if (!ok) {
    1350           0 :                         fprintf(stderr,
    1351             :                                 "Failed to set Kerberos state to %s!\n", arg);
    1352           0 :                         exit(1);
    1353             :                 }
    1354             : 
    1355         738 :                 break;
    1356             :         }
    1357             :         }
    1358         748 : }
    1359             : 
    1360             : static struct poptOption popt_legacy_s4[] = {
    1361             :         {
    1362             :                 .argInfo    = POPT_ARG_CALLBACK,
    1363             :                 .arg        = (void *)popt_legacy_s4_callback,
    1364             :         },
    1365             :         {
    1366             :                 .longName   = "kerberos",
    1367             :                 .shortName  = 'k',
    1368             :                 .argInfo    = POPT_ARG_STRING,
    1369             :                 .val        = 'k',
    1370             :                 .descrip    = "DEPRECATED: Migrate to --use-kerberos",
    1371             :         },
    1372             :         POPT_TABLEEND
    1373             : };
    1374             : 
    1375      121291 : struct poptOption *samba_cmdline_get_popt(enum smb_cmdline_popt_options opt)
    1376             : {
    1377      121291 :         switch (opt) {
    1378        2286 :         case SAMBA_CMDLINE_POPT_OPT_DEBUG_ONLY:
    1379        2286 :                 return popt_common_debug;
    1380           4 :                 break;
    1381        2290 :         case SAMBA_CMDLINE_POPT_OPT_OPTION_ONLY:
    1382        2290 :                 return popt_common_option;
    1383           0 :                 break;
    1384         329 :         case SAMBA_CMDLINE_POPT_OPT_CONFIG_ONLY:
    1385         329 :                 return popt_common_config;
    1386         227 :                 break;
    1387       23011 :         case SAMBA_CMDLINE_POPT_OPT_SAMBA:
    1388       23011 :                 return popt_common_samba;
    1389         322 :                 break;
    1390       21649 :         case SAMBA_CMDLINE_POPT_OPT_CONNECTION:
    1391       21649 :                 return popt_common_connection;
    1392         322 :                 break;
    1393       21348 :         case SAMBA_CMDLINE_POPT_OPT_CREDENTIALS:
    1394       21348 :                 return popt_common_credentials;
    1395         422 :                 break;
    1396       27227 :         case SAMBA_CMDLINE_POPT_OPT_VERSION:
    1397       27227 :                 return popt_common_version;
    1398          33 :                 break;
    1399         275 :         case SAMBA_CMDLINE_POPT_OPT_DAEMON:
    1400         275 :                 return popt_common_daemon;
    1401         192 :                 break;
    1402        1538 :         case SAMBA_CMDLINE_POPT_OPT_SAMBA_LDB:
    1403        1538 :                 return popt_common_samba_ldb;
    1404           5 :                 break;
    1405       17321 :         case SAMBA_CMDLINE_POPT_OPT_LEGACY_S3:
    1406       17321 :                 return popt_legacy_s3;
    1407         317 :                 break;
    1408        4013 :         case SAMBA_CMDLINE_POPT_OPT_LEGACY_S4:
    1409        4013 :                 return popt_legacy_s4;
    1410           0 :                 break;
    1411             :         }
    1412             : 
    1413             :         /* Never reached */
    1414           0 :         return NULL;
    1415             : }

Generated by: LCOV version 1.14