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

Generated by: LCOV version 1.14