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 : }
|