LCOV - code coverage report
Current view: top level - lib/cmdline - cmdline.c (source / functions) Hit Total Coverage
Test: coverage report for master 98b443d9 Lines: 415 523 79.3 %
Date: 2024-05-31 13:13:24 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       27343 : bool samba_cmdline_set_talloc_ctx(TALLOC_CTX *mem_ctx)
      41             : {
      42       27343 :         if (cmdline_mem_ctx != NULL) {
      43           0 :                 return false;
      44             :         }
      45             : 
      46       27343 :         cmdline_mem_ctx = mem_ctx;
      47       27343 :         return true;
      48             : }
      49             : 
      50       85574 : TALLOC_CTX *samba_cmdline_get_talloc_ctx(void)
      51             : {
      52       85574 :         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       27343 : bool samba_cmdline_init_common(TALLOC_CTX *mem_ctx)
      61             : {
      62         423 :         bool ok;
      63             : 
      64       27343 :         ok = samba_cmdline_set_talloc_ctx(mem_ctx);
      65       27343 :         if (!ok) {
      66           0 :                 return false;
      67             :         }
      68             : 
      69       27343 :         cmdline_daemon_cfg = (struct samba_cmdline_daemon_cfg) {
      70             :                 .fork = true,
      71             :         };
      72             : 
      73       27343 :         fault_setup();
      74             : 
      75             :         /*
      76             :          * Log to stderr by default.
      77             :          * This can be changed to stdout using the option: --debug-stdout
      78             :          */
      79       27343 :         setup_logging(getprogname(), DEBUG_DEFAULT_STDERR);
      80             : 
      81       27343 :         talloc_set_log_fn(_samba_cmdline_talloc_log);
      82       27343 :         talloc_set_abort_fn(smb_panic);
      83             : 
      84       27343 :         return true;
      85             : }
      86             : 
      87       27343 : bool samba_cmdline_set_load_config_fn(samba_cmdline_load_config fn)
      88             : {
      89       27343 :         cmdline_load_config_fn = fn;
      90       27343 :         return true;
      91             : }
      92             : 
      93             : /* PUBLIC */
      94       27343 : bool samba_cmdline_set_lp_ctx(struct loadparm_context *lp_ctx)
      95             : {
      96       27343 :         if (lp_ctx == NULL) {
      97           0 :                 return false;
      98             :         }
      99       27343 :         cmdline_lp_ctx = lp_ctx;
     100             : 
     101       27343 :         return true;
     102             : }
     103             : 
     104      204911 : struct loadparm_context *samba_cmdline_get_lp_ctx(void)
     105             : {
     106      204911 :         return cmdline_lp_ctx;
     107             : }
     108             : 
     109       27343 : bool samba_cmdline_set_creds(struct cli_credentials *creds)
     110             : {
     111       27343 :         if (creds == NULL) {
     112           0 :                 return false;
     113             :         }
     114             : 
     115       27343 :         TALLOC_FREE(cmdline_creds);
     116       27343 :         cmdline_creds = creds;
     117             : 
     118       27343 :         return true;
     119             : }
     120             : 
     121     2330939 : struct cli_credentials *samba_cmdline_get_creds(void)
     122             : {
     123     2330939 :         return cmdline_creds;
     124             : }
     125             : 
     126        6884 : struct samba_cmdline_daemon_cfg *samba_cmdline_get_daemon_cfg(void)
     127             : {
     128        6884 :         return &cmdline_daemon_cfg;
     129             : }
     130             : 
     131       22211 : void samba_cmdline_set_machine_account_fn(
     132             :         NTSTATUS (*fn) (struct cli_credentials *cred,
     133             :                         struct loadparm_context *lp_ctx))
     134             : {
     135       22211 :         cli_credentials_set_machine_account_fn = fn;
     136       22211 : }
     137             : 
     138       36607 : bool samba_cmdline_burn(int argc, char *argv[])
     139             : {
     140       36607 :         bool burnt = false;
     141       36607 :         bool found = false;
     142       36607 :         bool is_user = false;
     143       36607 :         char *p = NULL;
     144         176 :         int i;
     145       36607 :         size_t ulen = 0;
     146             : 
     147      233074 :         for (i = 0; i < argc; i++) {
     148      196467 :                 p = argv[i];
     149      196467 :                 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      196467 :                 if (strncmp(p, "-U", 2) == 0) {
     158       18177 :                         ulen = 2;
     159       18177 :                         found = true;
     160       18177 :                         is_user = true;
     161      178290 :                 } else if (strncmp(p, "--user", 6) == 0) {
     162          11 :                         ulen = 6;
     163          11 :                         found = true;
     164          11 :                         is_user = true;
     165      178279 :                 } else if (strncmp(p, "--password2", 11) == 0) {
     166           0 :                         ulen = 11;
     167           0 :                         found = true;
     168      178279 :                 } else if (strncmp(p, "--password", 10) == 0) {
     169         378 :                         ulen = 10;
     170         378 :                         found = true;
     171      177900 :                 } else if (strncmp(p, "--newpassword", 13) == 0) {
     172          57 :                         ulen = 13;
     173          57 :                         found = true;
     174             :                 }
     175             : 
     176      196467 :                 if (found) {
     177       19361 :                         char *q = NULL;
     178             : 
     179       19361 :                         if (strlen(p) == ulen) {
     180         737 :                                 continue;
     181             :                         }
     182             : 
     183       18624 :                         if (is_user) {
     184       18188 :                                 q = strchr_m(p, '%');
     185       18188 :                                 if (q != NULL) {
     186       17723 :                                         p = q;
     187             :                                 }
     188             :                         } else {
     189         436 :                                 p += ulen;
     190             :                         }
     191             : 
     192       18624 :                         memset_s(p, strlen(p), '\0', strlen(p));
     193       18624 :                         found = false;
     194       18624 :                         is_user = false;
     195       18624 :                         burnt = true;
     196             :                 }
     197             :         }
     198       36431 :         return burnt;
     199             : }
     200             : 
     201    93392417 : static bool is_popt_table_end(const struct poptOption *o)
     202             : {
     203    93392417 :         if (o->longName == NULL &&
     204    22492532 :             o->shortName == 0 &&
     205    22174763 :             o->argInfo == 0 &&
     206     8355923 :             o->arg == NULL &&
     207     8355923 :             o->val == 0 &&
     208     8355923 :             o->descrip == NULL &&
     209     8355923 :             o->argDescrip == NULL) {
     210     8223887 :                 return true;
     211             :         }
     212             : 
     213    83807934 :         return false;
     214             : }
     215             : 
     216     8177301 : static void find_duplicates(const struct poptOption *needle,
     217             :                             const struct poptOption *haystack,
     218             :                             size_t *count)
     219             : {
     220     8177301 :         for(;
     221    91609786 :             !is_popt_table_end(haystack);
     222    83432485 :             haystack++) {
     223    83432485 :                 switch (haystack->argInfo) {
     224     6872262 :                 case POPT_ARG_INCLUDE_TABLE:
     225     6872262 :                         if (haystack->arg != NULL) {
     226     6872262 :                                 find_duplicates(needle, haystack->arg, count);
     227             :                         }
     228             : 
     229     6762203 :                         break;
     230    76560223 :                 default:
     231    76560223 :                         if (needle->shortName != 0 &&
     232    37910093 :                             needle->shortName == haystack->shortName) {
     233      675708 :                                 (*count)++;
     234      675708 :                                 break;
     235             :                         }
     236             : 
     237    75884515 :                         if (needle->longName != NULL &&
     238   143542506 :                             haystack->longName != NULL &&
     239    68832795 :                             strequal(needle->longName, haystack->longName)) {
     240      629331 :                                 (*count)++;
     241      629331 :                                 break;
     242             :                         }
     243    74179787 :                         break;
     244             :                 }
     245             : 
     246    83432485 :                 if (*count > 1) {
     247           0 :                         return;
     248             :                 }
     249             :         }
     250             : }
     251             : 
     252      178622 : static bool cmdline_sanity_checker(const struct poptOption *current_opts,
     253             :                              const struct poptOption *full_opts)
     254             : {
     255      178622 :         const struct poptOption *o = current_opts;
     256             : 
     257      178622 :         for(;
     258     1782631 :             !is_popt_table_end(o);
     259     1604009 :             o++) {
     260       23820 :                 bool ok;
     261             : 
     262     1604009 :                 switch (o->argInfo) {
     263      149485 :                 case POPT_ARG_INCLUDE_TABLE:
     264      149485 :                         if (o->arg != NULL) {
     265      149485 :                                 ok = cmdline_sanity_checker(o->arg, full_opts);
     266      149485 :                                 if (!ok) {
     267           0 :                                         return false;
     268             :                                 }
     269             :                         }
     270             : 
     271      147217 :                         break;
     272     1454524 :                 default:
     273     1454524 :                         if (o->longName != NULL || o->shortName != 0) {
     274     1305039 :                                 size_t count = 0;
     275             : 
     276     1305039 :                                 find_duplicates(o, full_opts, &count);
     277     1305039 :                                 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     1432972 :                         break;
     289             :                 }
     290             :         }
     291             : 
     292      175929 :         return true;
     293             : }
     294             : 
     295       29137 : bool samba_cmdline_sanity_check(const struct poptOption *opts)
     296             : {
     297       29137 :         return cmdline_sanity_checker(opts, opts);
     298             : }
     299             : 
     300       27444 : 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       27444 :         ok = samba_cmdline_sanity_check(options);
     309       27444 :         if (!ok) {
     310           0 :                 return NULL;
     311             :         }
     312             : #endif
     313       27444 :         process_save_binary_name(name);
     314       27444 :         return poptGetContext(name, argc, argv, options, flags);
     315             : }
     316             : 
     317             : /**********************************************************
     318             :  * COMMON SAMBA POPT
     319             :  **********************************************************/
     320             : 
     321             : static bool log_to_file;
     322             : 
     323       30597 : 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       30597 :         bool ok = false;
     330       30597 :         char *new_logfile = talloc_asprintf(mem_ctx,
     331             :                                             "%s/log.%s",
     332             :                                             log_basename,
     333             :                                             process_name);
     334       30597 :         if (new_logfile == NULL) {
     335           0 :                 return false;
     336             :         }
     337             : 
     338       30597 :         if (from_cmdline) {
     339         624 :                 ok = lpcfg_set_cmdline(lp_ctx,
     340             :                                        "log file",
     341             :                                        new_logfile);
     342             :         } else {
     343       29973 :                 ok = lpcfg_do_global_parameter(lp_ctx,
     344             :                                                "log file",
     345             :                                                new_logfile);
     346             :         }
     347       30597 :         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       30597 :         debug_set_logfile(new_logfile);
     355       30597 :         TALLOC_FREE(new_logfile);
     356             : 
     357       30597 :         return true;
     358             : }
     359             : 
     360       85574 : 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       85574 :         TALLOC_CTX *mem_ctx = samba_cmdline_get_talloc_ctx();
     366       85574 :         struct loadparm_context *lp_ctx = samba_cmdline_get_lp_ctx();
     367       85574 :         const char *pname = NULL;
     368        1436 :         bool ok;
     369             : 
     370             :         /* Find out basename of current program */
     371       85574 :         pname = getprogname();
     372             : 
     373       85574 :         if (reason == POPT_CALLBACK_REASON_PRE) {
     374       29973 :                 if (lp_ctx == NULL) {
     375           0 :                         fprintf(stderr,
     376             :                                 "Command line parsing not initialized!\n");
     377           0 :                         exit(1);
     378             :                 }
     379       29973 :                 ok = set_logfile(mem_ctx,
     380             :                                  lp_ctx,
     381             :                                  get_dyn_LOGFILEBASE(),
     382             :                                  pname,
     383             :                                  false);
     384       29973 :                 if (!ok) {
     385           0 :                         fprintf(stderr,
     386             :                                 "Failed to set log file for %s\n",
     387             :                                 pname);
     388           0 :                         exit(1);
     389             :                 }
     390       29546 :                 return;
     391             :         }
     392             : 
     393       55601 :         if (reason == POPT_CALLBACK_REASON_POST) {
     394       29901 :                 ok = cmdline_load_config_fn();
     395       29901 :                 if (!ok) {
     396           0 :                         fprintf(stderr,
     397             :                                 "%s - Failed to load config file!\n",
     398             :                                 getprogname());
     399           0 :                         exit(1);
     400             :                 }
     401             : 
     402       29901 :                 if (log_to_file) {
     403           0 :                         const struct loadparm_substitution *lp_sub =
     404         624 :                                 lpcfg_noop_substitution();
     405         624 :                         char *logfile = NULL;
     406             : 
     407         624 :                         logfile = lpcfg_logfile(lp_ctx, lp_sub, mem_ctx);
     408         624 :                         if (logfile == NULL) {
     409           0 :                                 fprintf(stderr,
     410             :                                         "Failed to setup logging to file!");
     411           0 :                                         exit(1);
     412             :                         }
     413         624 :                         debug_set_logfile(logfile);
     414         624 :                         setup_logging(logfile, DEBUG_FILE);
     415         624 :                         TALLOC_FREE(logfile);
     416             :                 }
     417             : 
     418       29901 :                 return;
     419             :         }
     420             : 
     421       25700 :         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       11723 :         case OPT_OPTION:
     429       11723 :                 if (arg != NULL) {
     430       11723 :                         ok = lpcfg_set_option(lp_ctx, arg);
     431       11723 :                         if (!ok) {
     432           1 :                                 fprintf(stderr, "Error setting option '%s'\n", arg);
     433           1 :                                 exit(1);
     434             :                         }
     435             :                 }
     436       11378 :                 break;
     437         632 :         case 'd':
     438         632 :                 if (arg != NULL) {
     439         632 :                         ok = lpcfg_set_cmdline(lp_ctx, "log level", arg);
     440         632 :                         if (!ok) {
     441           0 :                                 fprintf(stderr,
     442             :                                         "Failed to set debug level to: %s\n",
     443             :                                         arg);
     444           0 :                                 exit(1);
     445             :                         }
     446             :                 }
     447         619 :                 break;
     448         141 :         case OPT_DEBUG_STDOUT:
     449         141 :                 setup_logging(pname, DEBUG_STDOUT);
     450         141 :                 break;
     451       12580 :         case OPT_CONFIGFILE:
     452       12580 :                 if (arg != NULL) {
     453       12580 :                         set_dyn_CONFIGFILE(arg);
     454             :                 }
     455       12388 :                 break;
     456         624 :         case 'l':
     457         624 :                 if (arg != NULL) {
     458         624 :                         ok = set_logfile(mem_ctx, lp_ctx, arg, pname, true);
     459         624 :                         if (!ok) {
     460           0 :                                 fprintf(stderr,
     461             :                                         "Failed to set log file for %s\n",
     462             :                                         arg);
     463           0 :                                 exit(1);
     464             :                         }
     465         624 :                         log_to_file = true;
     466             : 
     467         624 :                         set_dyn_LOGFILEBASE(arg);
     468             :                 }
     469         624 :                 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       30054 : 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       30054 :         struct loadparm_context *lp_ctx = cmdline_lp_ctx;
     649             : 
     650       30054 :         if (reason == POPT_CALLBACK_REASON_PRE) {
     651       22152 :                 if (lp_ctx == NULL) {
     652           0 :                         fprintf(stderr,
     653             :                                 "Command line parsing not initialized!\n");
     654           0 :                         exit(1);
     655             :                 }
     656       21830 :                 return;
     657             :         }
     658             : 
     659        7902 :         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         933 :         case 'W':
     686         933 :                 if (arg != NULL) {
     687         933 :                         lpcfg_set_cmdline(lp_ctx, "workgroup", arg);
     688             :                 }
     689         910 :                 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       64007 : 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       64007 :         struct loadparm_context *lp_ctx = samba_cmdline_get_lp_ctx();
     774       64007 :         struct cli_credentials *creds = samba_cmdline_get_creds();
     775         710 :         bool ok;
     776             : 
     777       64007 :         if (reason == POPT_CALLBACK_REASON_PRE) {
     778       21852 :                 if (creds == NULL) {
     779           0 :                         fprintf(stderr,
     780             :                                 "Command line parsing not initialized!\n");
     781           0 :                         exit(1);
     782             :                 }
     783       21530 :                 return;
     784             :         }
     785             : 
     786       42155 :         if (reason == POPT_CALLBACK_REASON_POST) {
     787       21832 :                 const char *username = NULL;
     788       21832 :                 enum credentials_obtained username_obtained =
     789             :                         CRED_UNINITIALISED;
     790       21832 :                 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       21832 :                 ok = cli_credentials_guess(creds, lp_ctx);
     801       21832 :                 if (!ok) {
     802           0 :                         fprintf(stderr,
     803             :                                 "Unable to read defaults from smb.conf\n");
     804             :                 }
     805             : 
     806       21832 :                 if (machine_account_pending) {
     807           0 :                         NTSTATUS status;
     808             : 
     809         187 :                         status = cli_credentials_set_machine_account_fn(
     810             :                                 creds, lp_ctx);
     811         187 :                         if (!NT_STATUS_IS_OK(status)) {
     812          10 :                                 fprintf(stderr,
     813             :                                         "Failed to set machine account: %s\n",
     814             :                                         nt_errstr(status));
     815          10 :                                 exit(1);
     816             :                         }
     817             :                 }
     818             : 
     819             :                 /*
     820             :                  * When we set the username during the handling of the options
     821             :                  * passed to the binary we haven't loaded the config yet. This
     822             :                  * means that we didn't take the 'winbind separator' into
     823             :                  * account.
     824             :                  *
     825             :                  * The username might contain the domain name and thus it
     826             :                  * hasn't been correctly parsed yet. If we have a username we
     827             :                  * need to set it again to run the string parser for the
     828             :                  * username correctly.
     829             :                  */
     830         322 :                 username =
     831       21822 :                         cli_credentials_get_username_and_obtained(
     832             :                                         creds, &username_obtained);
     833       21822 :                 if (username_obtained == CRED_SPECIFIED &&
     834       18206 :                     username != NULL && username[0] != '\0') {
     835       17720 :                         cli_credentials_parse_string(creds,
     836             :                                                      username,
     837             :                                                      CRED_SPECIFIED);
     838             :                 }
     839             : 
     840       21822 :                 if (cli_credentials_get_kerberos_state(creds) ==
     841             :                     CRED_USE_KERBEROS_REQUIRED)
     842             :                 {
     843         999 :                         enum credentials_obtained ccache_obtained =
     844             :                                 CRED_UNINITIALISED;
     845         999 :                         enum credentials_obtained principal_obtained =
     846             :                                 CRED_UNINITIALISED;
     847           3 :                         bool ccache_valid;
     848             : 
     849           3 :                         principal_obtained =
     850         999 :                                 cli_credentials_get_principal_obtained(creds);
     851         999 :                         ccache_valid = cli_credentials_get_ccache_name_obtained(
     852             :                                 creds, NULL, NULL, &ccache_obtained);
     853         999 :                         if (ccache_valid &&
     854         283 :                             ccache_obtained == principal_obtained)
     855             :                         {
     856         281 :                                 skip_password_callback = true;
     857             :                         }
     858             :                 }
     859       21822 :                 if (!skip_password_callback) {
     860       21220 :                         (void)cli_credentials_get_password_and_obtained(creds,
     861             :                                                                         &password_obtained);
     862             :                 }
     863       21822 :                 if (!skip_password_callback &&
     864       21220 :                     password_obtained < CRED_CALLBACK) {
     865        3230 :                         ok = cli_credentials_set_cmdline_callbacks(creds);
     866        3230 :                         if (!ok) {
     867           0 :                                 fprintf(stderr,
     868             :                                         "Failed to set cmdline password "
     869             :                                         "callback\n");
     870           0 :                                 exit(1);
     871             :                         }
     872             :                 }
     873             : 
     874       21822 :                 return;
     875             :         }
     876             : 
     877       20323 :         switch(opt->val) {
     878       17971 :         case 'U':
     879       17971 :                 if (arg != NULL) {
     880       17971 :                         cli_credentials_parse_string(creds,
     881             :                                                      arg,
     882             :                                                      CRED_SPECIFIED);
     883             :                 }
     884       17913 :                 break;
     885         119 :         case OPT_PASSWORD:
     886         119 :                 if (arg != NULL) {
     887         119 :                         ok = cli_credentials_set_password(creds,
     888             :                                                           arg,
     889             :                                                           CRED_SPECIFIED);
     890         119 :                         if (!ok) {
     891           0 :                                 fprintf(stderr,
     892             :                                         "Failed to set password!\n");
     893           0 :                                 exit(1);
     894             :                         }
     895             : 
     896         119 :                         skip_password_callback = true;
     897             :                 }
     898         119 :                 break;
     899           2 :         case OPT_NT_HASH:
     900           2 :                 cli_credentials_set_password_will_be_nt_hash(creds, true);
     901           2 :                 break;
     902          54 :         case 'A':
     903          54 :                 if (arg != NULL) {
     904          54 :                         ok = cli_credentials_parse_file(creds,
     905             :                                                         arg,
     906             :                                                         CRED_SPECIFIED);
     907          54 :                         if (!ok) {
     908           0 :                                 fprintf(stderr,
     909             :                                         "Failed to set parse authentication file!\n");
     910           0 :                                 exit(1);
     911             :                         }
     912          54 :                         skip_password_callback = true;
     913             :                 }
     914          54 :                 break;
     915          62 :         case 'N':
     916          62 :                 ok = cli_credentials_set_password(creds,
     917             :                                                   NULL,
     918             :                                                   CRED_SPECIFIED);
     919          62 :                 if (!ok) {
     920           0 :                         fprintf(stderr,
     921             :                                 "Failed to set password!\n");
     922           0 :                         exit(1);
     923             :                 }
     924          62 :                 skip_password_callback = true;
     925          62 :                 break;
     926         187 :         case 'P':
     927             :                 /*
     928             :                  * Later, after this is all over, get the machine account
     929             :                  * details from the secrets.(l|t)db.
     930             :                  */
     931         187 :                 machine_account_pending = true;
     932         187 :                 break;
     933          55 :         case OPT_SIMPLE_BIND_DN:
     934          55 :                 if (arg != NULL) {
     935          55 :                         ok = cli_credentials_set_bind_dn(creds, arg);
     936          55 :                         if (!ok) {
     937           0 :                                 fprintf(stderr,
     938             :                                         "Failed to set bind DN!\n");
     939           0 :                                 exit(1);
     940             :                         }
     941             :                 }
     942          55 :                 break;
     943         390 :         case OPT_USE_KERBEROS: {
     944         390 :                 int32_t use_kerberos = INT_MIN;
     945         390 :                 if (arg == NULL) {
     946           0 :                         fprintf(stderr,
     947             :                                 "Failed to parse "
     948             :                                 "--use-kerberos=desired|required|off: "
     949             :                                 "Missing argument\n");
     950           0 :                         exit(1);
     951             :                 }
     952             : 
     953         390 :                 use_kerberos = lpcfg_parse_enum_vals("client use kerberos",
     954             :                                                      arg);
     955         390 :                 if (use_kerberos == INT_MIN) {
     956           0 :                         fprintf(stderr,
     957             :                                 "Failed to parse "
     958             :                                 "--use-kerberos=desired|required|off: "
     959             :                                 "Invalid argument\n");
     960           0 :                         exit(1);
     961             :                 }
     962             : 
     963         390 :                 ok = cli_credentials_set_kerberos_state(creds,
     964             :                                                         use_kerberos,
     965             :                                                         CRED_SPECIFIED);
     966         390 :                 if (!ok) {
     967           0 :                         fprintf(stderr,
     968             :                                 "Failed to set Kerberos state to %s!\n", arg);
     969           0 :                         exit(1);
     970             :                 }
     971         390 :                 break;
     972             :         }
     973         296 :         case OPT_USE_KERBEROS_CCACHE: {
     974         296 :                 const char *error_string = NULL;
     975           0 :                 int rc;
     976             : 
     977         296 :                 if (arg == NULL) {
     978           0 :                         fprintf(stderr,
     979             :                                 "Failed to parse --use-krb5-ccache=CCACHE: "
     980             :                                 "Missing argument\n");
     981           0 :                         exit(1);
     982             :                 }
     983             : 
     984         296 :                 ok = cli_credentials_set_kerberos_state(creds,
     985             :                                                         CRED_USE_KERBEROS_REQUIRED,
     986             :                                                         CRED_SPECIFIED);
     987         296 :                 if (!ok) {
     988           0 :                         fprintf(stderr,
     989             :                                 "Failed to set Kerberos state to %s!\n", arg);
     990           0 :                         exit(1);
     991             :                 }
     992             : 
     993         296 :                 rc = cli_credentials_set_ccache(creds,
     994             :                                                 lp_ctx,
     995             :                                                 arg,
     996             :                                                 CRED_SPECIFIED,
     997             :                                                 &error_string);
     998         296 :                 if (rc != 0) {
     999           0 :                         fprintf(stderr,
    1000             :                                 "Error reading krb5 credentials cache: '%s'"
    1001             :                                 " - %s\n",
    1002             :                                 arg,
    1003             :                                 error_string);
    1004           0 :                         exit(1);
    1005             :                 }
    1006             : 
    1007         296 :                 skip_password_callback = true;
    1008         296 :                 break;
    1009             :         }
    1010          48 :         case OPT_USE_WINBIND_CCACHE:
    1011             :         {
    1012           0 :                 uint32_t gensec_features;
    1013             : 
    1014          48 :                 gensec_features = cli_credentials_get_gensec_features(creds);
    1015          48 :                 gensec_features |= GENSEC_FEATURE_NTLM_CCACHE;
    1016             : 
    1017          48 :                 ok = cli_credentials_set_gensec_features(creds,
    1018             :                                                          gensec_features,
    1019             :                                                          CRED_SPECIFIED);
    1020          48 :                 if (!ok) {
    1021           0 :                         fprintf(stderr,
    1022             :                                 "Failed to set gensec feature!\n");
    1023           0 :                         exit(1);
    1024             :                 }
    1025             : 
    1026          48 :                 skip_password_callback = true;
    1027          48 :                 break;
    1028             :         }
    1029        1139 :         case OPT_CLIENT_PROTECTION: {
    1030           8 :                 uint32_t gensec_features;
    1031        1139 :                 enum smb_signing_setting signing_state =
    1032             :                         SMB_SIGNING_OFF;
    1033        1139 :                 enum smb_encryption_setting encryption_state =
    1034             :                         SMB_ENCRYPTION_OFF;
    1035             : 
    1036        1139 :                 if (arg == NULL) {
    1037           0 :                         fprintf(stderr,
    1038             :                                 "Failed to parse "
    1039             :                                 "--client-protection=sign|encrypt|off: "
    1040             :                                 "Missing argument\n");
    1041           0 :                         exit(1);
    1042             :                 }
    1043             : 
    1044           8 :                 gensec_features =
    1045        1139 :                         cli_credentials_get_gensec_features(
    1046             :                                         creds);
    1047             : 
    1048        1139 :                 if (strequal(arg, "off")) {
    1049          38 :                         gensec_features &=
    1050             :                                 ~(GENSEC_FEATURE_SIGN|GENSEC_FEATURE_SEAL);
    1051             : 
    1052          38 :                         signing_state = SMB_SIGNING_OFF;
    1053          38 :                         encryption_state = SMB_ENCRYPTION_OFF;
    1054        1101 :                 } else if (strequal(arg, "sign")) {
    1055         743 :                         gensec_features |= GENSEC_FEATURE_SIGN;
    1056             : 
    1057         743 :                         signing_state = SMB_SIGNING_REQUIRED;
    1058         743 :                         encryption_state = SMB_ENCRYPTION_OFF;
    1059         358 :                 } else if (strequal(arg, "encrypt")) {
    1060         358 :                         gensec_features |= GENSEC_FEATURE_SEAL;
    1061             : 
    1062         358 :                         signing_state = SMB_SIGNING_REQUIRED;
    1063         358 :                         encryption_state = SMB_ENCRYPTION_REQUIRED;
    1064             :                 } else {
    1065           0 :                         fprintf(stderr,
    1066             :                                 "Failed to parse --client-protection\n");
    1067           0 :                         exit(1);
    1068             :                 }
    1069             : 
    1070        1139 :                 ok = cli_credentials_set_gensec_features(creds,
    1071             :                                                                 gensec_features,
    1072             :                                                                 CRED_SPECIFIED);
    1073        1139 :                 if (!ok) {
    1074           0 :                         fprintf(stderr,
    1075             :                                 "Failed to set gensec feature!\n");
    1076           0 :                         exit(1);
    1077             :                 }
    1078             : 
    1079        1139 :                 ok = cli_credentials_set_smb_signing(creds,
    1080             :                                                         signing_state,
    1081             :                                                         CRED_SPECIFIED);
    1082        1139 :                 if (!ok) {
    1083           0 :                         fprintf(stderr,
    1084             :                                 "Failed to set smb signing!\n");
    1085           0 :                         exit(1);
    1086             :                 }
    1087             : 
    1088        1139 :                 ok = cli_credentials_set_smb_encryption(creds,
    1089             :                                                         encryption_state,
    1090             :                                                         CRED_SPECIFIED);
    1091        1139 :                 if (!ok) {
    1092           0 :                         fprintf(stderr,
    1093             :                                 "Failed to set smb encryption!\n");
    1094           0 :                         exit(1);
    1095             :                 }
    1096        1131 :                 break;
    1097             :         }
    1098             :         } /* switch */
    1099             : }
    1100             : 
    1101             : static struct poptOption popt_common_credentials[] = {
    1102             :         {
    1103             :                 .argInfo    = POPT_ARG_CALLBACK|POPT_CBFLAG_PRE|POPT_CBFLAG_POST,
    1104             :                 .arg        = (void *)popt_common_credentials_callback,
    1105             :         },
    1106             :         {
    1107             :                 .longName   = "user",
    1108             :                 .shortName  = 'U',
    1109             :                 .argInfo    = POPT_ARG_STRING,
    1110             :                 .val        = 'U',
    1111             :                 .descrip    = "Set the network username",
    1112             :                 .argDescrip = "[DOMAIN/]USERNAME[%PASSWORD]",
    1113             :         },
    1114             :         {
    1115             :                 .longName   = "no-pass",
    1116             :                 .shortName  = 'N',
    1117             :                 .argInfo    = POPT_ARG_NONE,
    1118             :                 .val        = 'N',
    1119             :                 .descrip    = "Don't ask for a password",
    1120             :         },
    1121             :         {
    1122             :                 .longName   = "password",
    1123             :                 .argInfo    = POPT_ARG_STRING,
    1124             :                 .val        = OPT_PASSWORD,
    1125             :                 .descrip    = "Password",
    1126             :         },
    1127             :         {
    1128             :                 .longName   = "pw-nt-hash",
    1129             :                 .argInfo    = POPT_ARG_NONE,
    1130             :                 .val        = OPT_NT_HASH,
    1131             :                 .descrip    = "The supplied password is the NT hash",
    1132             :         },
    1133             :         {
    1134             :                 .longName   = "authentication-file",
    1135             :                 .shortName  = 'A',
    1136             :                 .argInfo    = POPT_ARG_STRING,
    1137             :                 .val        = 'A',
    1138             :                 .descrip    = "Get the credentials from a file",
    1139             :                 .argDescrip = "FILE",
    1140             :         },
    1141             :         {
    1142             :                 .longName   = "machine-pass",
    1143             :                 .shortName  = 'P',
    1144             :                 .argInfo    = POPT_ARG_NONE,
    1145             :                 .val        = 'P',
    1146             :                 .descrip    = "Use stored machine account password",
    1147             :         },
    1148             :         {
    1149             :                 .longName   = "simple-bind-dn",
    1150             :                 .argInfo    = POPT_ARG_STRING,
    1151             :                 .val        = OPT_SIMPLE_BIND_DN,
    1152             :                 .descrip    = "DN to use for a simple bind",
    1153             :                 .argDescrip = "DN",
    1154             :         },
    1155             :         {
    1156             :                 .longName   = "use-kerberos",
    1157             :                 .argInfo    = POPT_ARG_STRING,
    1158             :                 .val        = OPT_USE_KERBEROS,
    1159             :                 .descrip    = "Use Kerberos authentication",
    1160             :                 .argDescrip = "desired|required|off",
    1161             :         },
    1162             :         {
    1163             :                 .longName   = "use-krb5-ccache",
    1164             :                 .argInfo    = POPT_ARG_STRING,
    1165             :                 .val        = OPT_USE_KERBEROS_CCACHE,
    1166             :                 .descrip    = "Credentials cache location for Kerberos",
    1167             :                 .argDescrip = "CCACHE",
    1168             :         },
    1169             :         {
    1170             :                 .longName   = "use-winbind-ccache",
    1171             :                 .argInfo    = POPT_ARG_NONE,
    1172             :                 .val        = OPT_USE_WINBIND_CCACHE,
    1173             :                 .descrip    = "Use the winbind ccache for authentication",
    1174             :         },
    1175             :         {
    1176             :                 .longName   = "client-protection",
    1177             :                 .argInfo    = POPT_ARG_STRING,
    1178             :                 .val        = OPT_CLIENT_PROTECTION,
    1179             :                 .descrip    = "Configure used protection for client connections",
    1180             :                 .argDescrip = "sign|encrypt|off",
    1181             :         },
    1182             :         POPT_TABLEEND
    1183             : };
    1184             : 
    1185             : /**********************************************************
    1186             :  * VERSION POPT
    1187             :  **********************************************************/
    1188             : 
    1189           0 : static void popt_version_callback(poptContext ctx,
    1190             :                                   enum poptCallbackReason reason,
    1191             :                                   const struct poptOption *opt,
    1192             :                                   const char *arg,
    1193             :                                   const void *data)
    1194             : {
    1195           0 :         switch(opt->val) {
    1196           0 :         case 'V':
    1197           0 :                 printf("Version %s\n", SAMBA_VERSION_STRING);
    1198           0 :                 exit(0);
    1199             :         }
    1200           0 : }
    1201             : 
    1202             : static struct poptOption popt_common_version[] = {
    1203             :         {
    1204             :                 .argInfo    = POPT_ARG_CALLBACK,
    1205             :                 .arg        = (void *)popt_version_callback,
    1206             :         },
    1207             :         {
    1208             :                 .longName   = "version",
    1209             :                 .shortName  = 'V',
    1210             :                 .argInfo    = POPT_ARG_NONE,
    1211             :                 .val        = 'V',
    1212             :                 .descrip    = "Print version",
    1213             :         },
    1214             :         POPT_TABLEEND
    1215             : };
    1216             : 
    1217             : /**********************************************************
    1218             :  * DAEMON POPT
    1219             :  **********************************************************/
    1220             : 
    1221         371 : static void popt_daemon_callback(poptContext ctx,
    1222             :                                  enum poptCallbackReason reason,
    1223             :                                  const struct poptOption *opt,
    1224             :                                  const char *arg,
    1225             :                                  const void *data)
    1226             : {
    1227         371 :         switch(opt->val) {
    1228           0 :         case OPT_DAEMON:
    1229           0 :                 cmdline_daemon_cfg.daemon = true;
    1230           0 :                 break;
    1231          72 :         case OPT_INTERACTIVE:
    1232          72 :                 cmdline_daemon_cfg.interactive = true;
    1233          72 :                 cmdline_daemon_cfg.fork = false;
    1234          72 :                 break;
    1235         130 :         case OPT_FORK:
    1236         130 :                 cmdline_daemon_cfg.fork = false;
    1237         130 :                 break;
    1238         169 :         case OPT_NO_PROCESS_GROUP:
    1239         169 :                 cmdline_daemon_cfg.no_process_group = true;
    1240         169 :                 break;
    1241             :         }
    1242         371 : }
    1243             : 
    1244             : static struct poptOption popt_common_daemon[] = {
    1245             :         {
    1246             :                 .argInfo    = POPT_ARG_CALLBACK,
    1247             :                 .arg        = (void *)popt_daemon_callback
    1248             :         },
    1249             :         {
    1250             :                 .longName   = "daemon",
    1251             :                 .shortName  = 'D',
    1252             :                 .argInfo    = POPT_ARG_NONE,
    1253             :                 .arg        = NULL,
    1254             :                 .val        = OPT_DAEMON,
    1255             :                 .descrip    = "Become a daemon (default)" ,
    1256             :         },
    1257             :         {
    1258             :                 .longName   = "interactive",
    1259             :                 .shortName  = 'i',
    1260             :                 .argInfo    = POPT_ARG_NONE,
    1261             :                 .arg        = NULL,
    1262             :                 .val        = OPT_INTERACTIVE,
    1263             :                 .descrip    = "Run interactive (not a daemon) and log to stdout",
    1264             :         },
    1265             :         {
    1266             :                 .longName   = "foreground",
    1267             :                 .shortName  = 'F',
    1268             :                 .argInfo    = POPT_ARG_NONE,
    1269             :                 .arg        = NULL,
    1270             :                 .val        = OPT_FORK,
    1271             :                 .descrip    = "Run daemon in foreground (for daemontools, etc.)",
    1272             :         },
    1273             :         {
    1274             :                 .longName   = "no-process-group",
    1275             :                 .shortName  = '\0',
    1276             :                 .argInfo    = POPT_ARG_NONE,
    1277             :                 .arg        = NULL,
    1278             :                 .val        = OPT_NO_PROCESS_GROUP,
    1279             :                 .descrip    = "Don't create a new process group" ,
    1280             :         },
    1281             :         POPT_TABLEEND
    1282             : };
    1283             : 
    1284             : /**********************************************************
    1285             :  * LEGACY S3 POPT
    1286             :  **********************************************************/
    1287             : 
    1288          21 : static void popt_legacy_s3_callback(poptContext ctx,
    1289             :                                     enum poptCallbackReason reason,
    1290             :                                     const struct poptOption *opt,
    1291             :                                     const char *arg,
    1292             :                                     const void *data)
    1293             : {
    1294          21 :         struct cli_credentials *creds = samba_cmdline_get_creds();
    1295           0 :         bool ok;
    1296             : 
    1297          21 :         switch(opt->val) {
    1298          21 :         case 'k':
    1299          21 :                 fprintf(stderr,
    1300             :                         "WARNING: The option -k|--kerberos is deprecated!\n");
    1301             : 
    1302          21 :                 ok = cli_credentials_set_kerberos_state(creds,
    1303             :                                                         CRED_USE_KERBEROS_REQUIRED,
    1304             :                                                         CRED_SPECIFIED);
    1305          21 :                 if (!ok) {
    1306           0 :                         fprintf(stderr,
    1307             :                                 "Failed to set Kerberos state to %s!\n", arg);
    1308           0 :                         exit(1);
    1309             :                 }
    1310             : 
    1311          21 :                 skip_password_callback = true;
    1312          21 :                 break;
    1313             :         }
    1314          21 : }
    1315             : 
    1316             : /* We allow '-k yes' too. */
    1317             : static struct poptOption popt_legacy_s3[] = {
    1318             :         {
    1319             :                 .argInfo    = POPT_ARG_CALLBACK,
    1320             :                 .arg        = (void *)popt_legacy_s3_callback,
    1321             :         },
    1322             :         {
    1323             :                 .longName   = "kerberos",
    1324             :                 .shortName  = 'k',
    1325             :                 .argInfo    = POPT_ARG_NONE,
    1326             :                 .val        = 'k',
    1327             :                 .descrip    = "DEPRECATED: Migrate to --use-kerberos",
    1328             :         },
    1329             :         POPT_TABLEEND
    1330             : };
    1331             : 
    1332             : /**********************************************************
    1333             :  * LEGACY S4 POPT
    1334             :  **********************************************************/
    1335             : 
    1336         732 : static void popt_legacy_s4_callback(poptContext ctx,
    1337             :                                     enum poptCallbackReason reason,
    1338             :                                     const struct poptOption *opt,
    1339             :                                     const char *arg,
    1340             :                                     const void *data)
    1341             : {
    1342         732 :         struct cli_credentials *creds = samba_cmdline_get_creds();
    1343          10 :         bool ok;
    1344             : 
    1345         732 :         switch(opt->val) {
    1346         732 :         case 'k': {
    1347         732 :                 enum credentials_use_kerberos use_kerberos =
    1348             :                         CRED_USE_KERBEROS_REQUIRED;
    1349             : 
    1350         732 :                 fprintf(stderr,
    1351             :                         "WARNING: The option -k|--kerberos is deprecated!\n");
    1352             : 
    1353         732 :                 if (arg != NULL) {
    1354         732 :                         if (strcasecmp_m(arg, "yes") == 0) {
    1355         506 :                                 use_kerberos = CRED_USE_KERBEROS_REQUIRED;
    1356         223 :                         } else if (strcasecmp_m(arg, "no") == 0) {
    1357         216 :                                 use_kerberos = CRED_USE_KERBEROS_DISABLED;
    1358             :                         } else {
    1359           0 :                                 fprintf(stderr,
    1360             :                                         "Error parsing -k %s. Should be "
    1361             :                                         "-k [yes|no]\n",
    1362             :                                         arg);
    1363           0 :                                 exit(1);
    1364             :                         }
    1365             :                 }
    1366             : 
    1367         732 :                 ok = cli_credentials_set_kerberos_state(creds,
    1368             :                                                         use_kerberos,
    1369             :                                                         CRED_SPECIFIED);
    1370         732 :                 if (!ok) {
    1371           0 :                         fprintf(stderr,
    1372             :                                 "Failed to set Kerberos state to %s!\n", arg);
    1373           0 :                         exit(1);
    1374             :                 }
    1375             : 
    1376         722 :                 break;
    1377             :         }
    1378             :         }
    1379         732 : }
    1380             : 
    1381             : static struct poptOption popt_legacy_s4[] = {
    1382             :         {
    1383             :                 .argInfo    = POPT_ARG_CALLBACK,
    1384             :                 .arg        = (void *)popt_legacy_s4_callback,
    1385             :         },
    1386             :         {
    1387             :                 .longName   = "kerberos",
    1388             :                 .shortName  = 'k',
    1389             :                 .argInfo    = POPT_ARG_STRING,
    1390             :                 .val        = 'k',
    1391             :                 .descrip    = "DEPRECATED: Migrate to --use-kerberos",
    1392             :         },
    1393             :         POPT_TABLEEND
    1394             : };
    1395             : 
    1396      123795 : struct poptOption *samba_cmdline_get_popt(enum smb_cmdline_popt_options opt)
    1397             : {
    1398      123795 :         switch (opt) {
    1399        2291 :         case SAMBA_CMDLINE_POPT_OPT_DEBUG_ONLY:
    1400        2291 :                 return popt_common_debug;
    1401           4 :                 break;
    1402        2295 :         case SAMBA_CMDLINE_POPT_OPT_OPTION_ONLY:
    1403        2295 :                 return popt_common_option;
    1404           0 :                 break;
    1405         329 :         case SAMBA_CMDLINE_POPT_OPT_CONFIG_ONLY:
    1406         329 :                 return popt_common_config;
    1407         227 :                 break;
    1408       23355 :         case SAMBA_CMDLINE_POPT_OPT_SAMBA:
    1409       23355 :                 return popt_common_samba;
    1410         322 :                 break;
    1411       22146 :         case SAMBA_CMDLINE_POPT_OPT_CONNECTION:
    1412       22146 :                 return popt_common_connection;
    1413         322 :                 break;
    1414       21846 :         case SAMBA_CMDLINE_POPT_OPT_CREDENTIALS:
    1415       21846 :                 return popt_common_credentials;
    1416         422 :                 break;
    1417       27730 :         case SAMBA_CMDLINE_POPT_OPT_VERSION:
    1418       27730 :                 return popt_common_version;
    1419          33 :                 break;
    1420         274 :         case SAMBA_CMDLINE_POPT_OPT_DAEMON:
    1421         274 :                 return popt_common_daemon;
    1422         192 :                 break;
    1423        1693 :         case SAMBA_CMDLINE_POPT_OPT_SAMBA_LDB:
    1424        1693 :                 return popt_common_samba_ldb;
    1425           5 :                 break;
    1426       17680 :         case SAMBA_CMDLINE_POPT_OPT_LEGACY_S3:
    1427       17680 :                 return popt_legacy_s3;
    1428         317 :                 break;
    1429        4152 :         case SAMBA_CMDLINE_POPT_OPT_LEGACY_S4:
    1430        4152 :                 return popt_legacy_s4;
    1431           0 :                 break;
    1432             :         }
    1433             : 
    1434             :         /* Never reached */
    1435           0 :         return NULL;
    1436             : }

Generated by: LCOV version 1.14