2 * Copyright (c) 2020 Andreas Schneider <asn@samba.org>
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.
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.
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/>.
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"
26 #include <samba/version.h>
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
;
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
;
40 bool samba_cmdline_set_talloc_ctx(TALLOC_CTX
*mem_ctx
)
42 if (cmdline_mem_ctx
!= NULL
) {
46 cmdline_mem_ctx
= mem_ctx
;
50 TALLOC_CTX
*samba_cmdline_get_talloc_ctx(void)
52 return cmdline_mem_ctx
;
55 static void _samba_cmdline_talloc_log(const char *message
)
60 bool samba_cmdline_init_common(TALLOC_CTX
*mem_ctx
)
64 ok
= samba_cmdline_set_talloc_ctx(mem_ctx
);
69 cmdline_daemon_cfg
= (struct samba_cmdline_daemon_cfg
) {
76 * Log to stderr by default.
77 * This can be changed to stdout using the option: --debug-stdout
79 setup_logging(getprogname(), DEBUG_DEFAULT_STDERR
);
81 talloc_set_log_fn(_samba_cmdline_talloc_log
);
82 talloc_set_abort_fn(smb_panic
);
87 bool samba_cmdline_set_load_config_fn(samba_cmdline_load_config fn
)
89 cmdline_load_config_fn
= fn
;
94 bool samba_cmdline_set_lp_ctx(struct loadparm_context
*lp_ctx
)
99 cmdline_lp_ctx
= lp_ctx
;
104 struct loadparm_context
*samba_cmdline_get_lp_ctx(void)
106 return cmdline_lp_ctx
;
109 bool samba_cmdline_set_creds(struct cli_credentials
*creds
)
115 TALLOC_FREE(cmdline_creds
);
116 cmdline_creds
= creds
;
121 struct cli_credentials
*samba_cmdline_get_creds(void)
123 return cmdline_creds
;
126 struct samba_cmdline_daemon_cfg
*samba_cmdline_get_daemon_cfg(void)
128 return &cmdline_daemon_cfg
;
131 void samba_cmdline_set_machine_account_fn(
132 NTSTATUS (*fn
) (struct cli_credentials
*cred
,
133 struct loadparm_context
*lp_ctx
))
135 cli_credentials_set_machine_account_fn
= fn
;
139 * Are the strings p and option equal from the point of view of option
140 * parsing, meaning is the next character '\0' or '='.
142 static bool strneq_cmdline_exact(const char *p
, const char *option
, size_t len
)
144 if (strncmp(p
, option
, len
) == 0) {
145 if (p
[len
] == 0 || p
[len
] == '=') {
153 * Return true if the argument to the option should be redacted.
155 * The option name is presumed to contain the substring "pass". It is checked
156 * against a list of options that specify secrets. If it is there, the value
157 * should be redacted and we return early.
159 * Otherwise, it is checked against a list of known safe options. If it is
160 * there, we return false.
162 * If the option is not in either list, we assume it might be secret and
163 * redact the argument, but warn loudly about it. The hope is that developers
164 * will see what they're doing and add the option to the appropriate list.
166 * If true is returned, *ulen will be set to the apparent length of the
167 * option. It is set to zero if false is returned (we don't need it in that
170 static bool is_password_option(const char *p
, size_t *ulen
)
173 static const char *must_burn
[] = {
183 static const char *allowed
[] = {
184 "--bad-password-count-reset",
185 "--badpassword-frequency",
186 "--change-user-password",
187 "--force-initialized-passwords",
188 "--machine-pass", /* distinct from --machinepass */
189 "--managed-password-interval",
198 "--password-from-stdin",
201 "--strip-passed-output",
202 "--with-smbpasswd-file",
208 for (i
= 0; i
< ARRAY_SIZE(must_burn
); i
++) {
210 len
= strlen(must_burn
[i
]);
211 secret
= strneq_cmdline_exact(p
, must_burn
[i
], len
);
218 for (i
= 0; i
< ARRAY_SIZE(allowed
); i
++) {
220 len
= strlen(allowed
[i
]);
221 safe
= strneq_cmdline_exact(p
, allowed
[i
], len
);
227 * We have found a suspicious option, and we need to work out where to
228 * burn it from. It could be
230 * --secret-password=cow -> password after '='
231 * --secret-password -> password is in next argument.
233 * but we also have the possibility of
235 * --cow=secret-password
237 * that is, the 'pass' in this option string is not in the option but
238 * the argument to it, which should not be burnt.
240 equals
= strchr(p
, '=');
241 if (equals
== NULL
) {
244 char *pass
= (strstr(p
, "pass"));
246 /* this is --foo=pass, not --pass=foo */
252 * This message will be seen with Python tools when an option
253 * is misspelt, but not with C tools, because in C burning
254 * happens after the command line is parsed, while in Python
255 * it happens before (on a copy of argv).
257 * In either case it will appear for a newly added option, and
258 * we hope developers will notice it before pushing.
260 DBG_ERR("\nNote for developers: if '%*s' is not misspelt, it should be "
261 "added to the appropriate list in is_password_option().\n\n",
266 bool samba_cmdline_burn(int argc
, char *argv
[])
271 for (i
= 0; i
< argc
; i
++) {
273 bool is_user
= false;
282 if (strncmp(p
, "-U", 2) == 0) {
284 * Note: this won't catch combinations of
286 * `samba-tool -NUAdministrator%...`, which is
287 * not possible in general outside of the
288 * actual parser (consider for example
289 * `-NHUroot%password`, which parses as
290 * `-N -H 'Uroot%password'`). We don't know
291 * here which short options might take
294 * This is an argument for embedding redaction
295 * inside the parser (e.g. by adding a flag to
296 * the option definitions), but we decided not
297 * to do that in order to share cmdline_burn().
302 } else if (strneq_cmdline_exact(p
, "--user", 6)) {
306 } else if (strneq_cmdline_exact(p
, "--username", 10)) {
310 } else if (strncmp(p
, "--", 2) == 0 && strstr(p
, "pass")) {
312 * We have many secret options like --password,
313 * --adminpass, --newpassword, and we could easily
314 * add more, so we will use an allowlist to let the
315 * safe ones through (of which there are also many).
317 found
= is_password_option(p
, &ulen
);
321 if (strlen(p
) == ulen
) {
323 * The option string has no '=', so
324 * its argument will come in the NEXT
325 * argv member. If there is one, we
326 * can just step forward and take it,
329 * {"--password=secret"} --> {"--password"}
330 * {"--password", "secret"} --> {"--password", ""}
331 * {"-Uadmin%secret"} --> {"-Uadmin"}
332 * {"-U", "admin%secret"} --> {"-U", "admin"}
337 * this looks like an invalid
338 * command line, but that's
339 * for the caller to decide.
351 char *q
= strchr_m(p
, '%');
353 /* -U without '%' has no secret */
361 BURN_PTR_SIZE(p
, strlen(p
));
368 static bool is_popt_table_end(const struct poptOption
*o
)
370 if (o
->longName
== NULL
&&
375 o
->descrip
== NULL
&&
376 o
->argDescrip
== NULL
) {
383 static void find_duplicates(const struct poptOption
*needle
,
384 const struct poptOption
*haystack
,
388 !is_popt_table_end(haystack
);
390 switch (haystack
->argInfo
) {
391 case POPT_ARG_INCLUDE_TABLE
:
392 if (haystack
->arg
!= NULL
) {
393 find_duplicates(needle
, haystack
->arg
, count
);
398 if (needle
->shortName
!= 0 &&
399 needle
->shortName
== haystack
->shortName
) {
404 if (needle
->longName
!= NULL
&&
405 haystack
->longName
!= NULL
&&
406 strequal(needle
->longName
, haystack
->longName
)) {
419 static bool cmdline_sanity_checker(const struct poptOption
*current_opts
,
420 const struct poptOption
*full_opts
)
422 const struct poptOption
*o
= current_opts
;
425 !is_popt_table_end(o
);
429 switch (o
->argInfo
) {
430 case POPT_ARG_INCLUDE_TABLE
:
431 if (o
->arg
!= NULL
) {
432 ok
= cmdline_sanity_checker(o
->arg
, full_opts
);
440 if (o
->longName
!= NULL
|| o
->shortName
!= 0) {
443 find_duplicates(o
, full_opts
, &count
);
445 DBG_ERR("Duplicate option '--%s|-%c' "
462 bool samba_cmdline_sanity_check(const struct poptOption
*opts
)
464 return cmdline_sanity_checker(opts
, opts
);
467 poptContext
samba_popt_get_context(const char * name
,
468 int argc
, const char ** argv
,
469 const struct poptOption
* options
,
475 ok
= samba_cmdline_sanity_check(options
);
480 process_save_binary_name(name
);
481 return poptGetContext(name
, argc
, argv
, options
, flags
);
484 /**********************************************************
486 **********************************************************/
488 static bool log_to_file
;
490 static bool set_logfile(TALLOC_CTX
*mem_ctx
,
491 struct loadparm_context
*lp_ctx
,
492 const char *log_basename
,
493 const char *process_name
,
497 char *new_logfile
= talloc_asprintf(mem_ctx
,
501 if (new_logfile
== NULL
) {
506 ok
= lpcfg_set_cmdline(lp_ctx
,
510 ok
= lpcfg_do_global_parameter(lp_ctx
,
516 "Failed to set log to %s\n",
518 TALLOC_FREE(new_logfile
);
521 debug_set_logfile(new_logfile
);
522 TALLOC_FREE(new_logfile
);
527 static void popt_samba_callback(poptContext popt_ctx
,
528 enum poptCallbackReason reason
,
529 const struct poptOption
*opt
,
530 const char *arg
, const void *data
)
532 TALLOC_CTX
*mem_ctx
= samba_cmdline_get_talloc_ctx();
533 struct loadparm_context
*lp_ctx
= samba_cmdline_get_lp_ctx();
534 const char *pname
= NULL
;
537 /* Find out basename of current program */
538 pname
= getprogname();
540 if (reason
== POPT_CALLBACK_REASON_PRE
) {
541 if (lp_ctx
== NULL
) {
543 "Command line parsing not initialized!\n");
546 ok
= set_logfile(mem_ctx
,
548 get_dyn_LOGFILEBASE(),
553 "Failed to set log file for %s\n",
560 if (reason
== POPT_CALLBACK_REASON_POST
) {
561 ok
= cmdline_load_config_fn();
564 "%s - Failed to load config file!\n",
570 const struct loadparm_substitution
*lp_sub
=
571 lpcfg_noop_substitution();
572 char *logfile
= NULL
;
574 logfile
= lpcfg_logfile(lp_ctx
, lp_sub
, mem_ctx
);
575 if (logfile
== NULL
) {
577 "Failed to setup logging to file!");
580 debug_set_logfile(logfile
);
581 setup_logging(logfile
, DEBUG_FILE
);
582 TALLOC_FREE(logfile
);
589 case OPT_LEAK_REPORT
:
590 talloc_enable_leak_report();
592 case OPT_LEAK_REPORT_FULL
:
593 talloc_enable_leak_report_full();
597 ok
= lpcfg_set_option(lp_ctx
, arg
);
599 fprintf(stderr
, "Error setting option '%s'\n", arg
);
606 ok
= lpcfg_set_cmdline(lp_ctx
, "log level", arg
);
609 "Failed to set debug level to: %s\n",
615 case OPT_DEBUG_STDOUT
:
616 setup_logging(pname
, DEBUG_STDOUT
);
620 set_dyn_CONFIGFILE(arg
);
625 ok
= set_logfile(mem_ctx
, lp_ctx
, arg
, pname
, true);
628 "Failed to set log file for %s\n",
634 set_dyn_LOGFILEBASE(arg
);
640 static struct poptOption popt_common_debug
[] = {
642 .argInfo
= POPT_ARG_CALLBACK
|POPT_CBFLAG_PRE
|POPT_CBFLAG_POST
,
643 .arg
= (void *)popt_samba_callback
,
646 .longName
= "debuglevel",
648 .argInfo
= POPT_ARG_STRING
,
650 .descrip
= "Set debug level",
651 .argDescrip
= "DEBUGLEVEL",
654 .longName
= "debug-stdout",
655 .argInfo
= POPT_ARG_NONE
,
656 .val
= OPT_DEBUG_STDOUT
,
657 .descrip
= "Send debug output to standard output",
662 static struct poptOption popt_common_option
[] = {
664 .argInfo
= POPT_ARG_CALLBACK
|POPT_CBFLAG_PRE
|POPT_CBFLAG_POST
,
665 .arg
= (void *)popt_samba_callback
,
668 .longName
= "option",
669 .argInfo
= POPT_ARG_STRING
,
671 .descrip
= "Set smb.conf option from command line",
672 .argDescrip
= "name=value",
677 static struct poptOption popt_common_config
[] = {
679 .argInfo
= POPT_ARG_CALLBACK
|POPT_CBFLAG_PRE
|POPT_CBFLAG_POST
,
680 .arg
= (void *)popt_samba_callback
,
683 .longName
= "configfile",
684 .argInfo
= POPT_ARG_STRING
,
685 .val
= OPT_CONFIGFILE
,
686 .descrip
= "Use alternative configuration file",
687 .argDescrip
= "CONFIGFILE",
692 static struct poptOption popt_common_samba
[] = {
694 .argInfo
= POPT_ARG_CALLBACK
|POPT_CBFLAG_PRE
|POPT_CBFLAG_POST
,
695 .arg
= (void *)popt_samba_callback
,
698 .longName
= "debuglevel",
700 .argInfo
= POPT_ARG_STRING
,
702 .descrip
= "Set debug level",
703 .argDescrip
= "DEBUGLEVEL",
706 .longName
= "debug-stdout",
707 .argInfo
= POPT_ARG_NONE
,
708 .val
= OPT_DEBUG_STDOUT
,
709 .descrip
= "Send debug output to standard output",
712 .longName
= "configfile",
714 .argInfo
= POPT_ARG_STRING
,
715 .val
= OPT_CONFIGFILE
,
716 .descrip
= "Use alternative configuration file",
717 .argDescrip
= "CONFIGFILE",
720 .longName
= "option",
721 .argInfo
= POPT_ARG_STRING
,
723 .descrip
= "Set smb.conf option from command line",
724 .argDescrip
= "name=value",
727 .longName
= "log-basename",
729 .argInfo
= POPT_ARG_STRING
,
731 .descrip
= "Basename for log/debug files",
732 .argDescrip
= "LOGFILEBASE",
735 .longName
= "leak-report",
736 .argInfo
= POPT_ARG_NONE
,
737 .val
= OPT_LEAK_REPORT
,
738 .descrip
= "enable talloc leak reporting on exit",
741 .longName
= "leak-report-full",
742 .argInfo
= POPT_ARG_NONE
,
743 .val
= OPT_LEAK_REPORT_FULL
,
744 .descrip
= "enable full talloc leak reporting on exit",
749 static struct poptOption popt_common_samba_ldb
[] = {
751 .argInfo
= POPT_ARG_CALLBACK
|POPT_CBFLAG_PRE
|POPT_CBFLAG_POST
,
752 .arg
= (void *)popt_samba_callback
,
755 .longName
= "debuglevel",
757 .argInfo
= POPT_ARG_STRING
,
759 .descrip
= "Set debug level",
760 .argDescrip
= "DEBUGLEVEL",
763 .longName
= "debug-stdout",
764 .argInfo
= POPT_ARG_NONE
,
765 .val
= OPT_DEBUG_STDOUT
,
766 .descrip
= "Send debug output to standard output",
769 .longName
= "configfile",
770 .argInfo
= POPT_ARG_STRING
,
771 .val
= OPT_CONFIGFILE
,
772 .descrip
= "Use alternative configuration file",
773 .argDescrip
= "CONFIGFILE",
776 .longName
= "option",
777 .argInfo
= POPT_ARG_STRING
,
779 .descrip
= "Set smb.conf option from command line",
780 .argDescrip
= "name=value",
783 .longName
= "log-basename",
785 .argInfo
= POPT_ARG_STRING
,
787 .descrip
= "Basename for log/debug files",
788 .argDescrip
= "LOGFILEBASE",
791 .longName
= "leak-report",
792 .argInfo
= POPT_ARG_NONE
,
793 .val
= OPT_LEAK_REPORT
,
794 .descrip
= "enable talloc leak reporting on exit",
797 .longName
= "leak-report-full",
798 .argInfo
= POPT_ARG_NONE
,
799 .val
= OPT_LEAK_REPORT_FULL
,
800 .descrip
= "enable full talloc leak reporting on exit",
805 /**********************************************************
807 **********************************************************/
809 static void popt_connection_callback(poptContext popt_ctx
,
810 enum poptCallbackReason reason
,
811 const struct poptOption
*opt
,
815 struct loadparm_context
*lp_ctx
= cmdline_lp_ctx
;
817 if (reason
== POPT_CALLBACK_REASON_PRE
) {
818 if (lp_ctx
== NULL
) {
820 "Command line parsing not initialized!\n");
829 lpcfg_set_cmdline(lp_ctx
, "socket options", arg
);
834 lpcfg_set_cmdline(lp_ctx
, "name resolve order", arg
);
839 lpcfg_set_cmdline(lp_ctx
, "client max protocol", arg
);
842 case OPT_NETBIOS_SCOPE
:
844 lpcfg_set_cmdline(lp_ctx
, "netbios scope", arg
);
849 lpcfg_set_cmdline(lp_ctx
, "netbios name", arg
);
854 lpcfg_set_cmdline(lp_ctx
, "workgroup", arg
);
859 lpcfg_set_cmdline(lp_ctx
, "realm", arg
);
865 static struct poptOption popt_common_connection
[] = {
867 .argInfo
= POPT_ARG_CALLBACK
|POPT_CBFLAG_PRE
,
868 .arg
= (void *)popt_connection_callback
,
871 .longName
= "name-resolve",
873 .argInfo
= POPT_ARG_STRING
,
875 .descrip
= "Use these name resolution services only",
876 .argDescrip
= "NAME-RESOLVE-ORDER",
879 .longName
= "socket-options",
881 .argInfo
= POPT_ARG_STRING
,
883 .descrip
= "socket options to use",
884 .argDescrip
= "SOCKETOPTIONS",
887 .longName
= "max-protocol",
889 .argInfo
= POPT_ARG_STRING
,
891 .descrip
= "Set max protocol level",
892 .argDescrip
= "MAXPROTOCOL",
895 .longName
= "netbiosname",
897 .argInfo
= POPT_ARG_STRING
,
899 .descrip
= "Primary netbios name",
900 .argDescrip
= "NETBIOSNAME",
903 .longName
= "netbios-scope",
904 .argInfo
= POPT_ARG_STRING
,
905 .val
= OPT_NETBIOS_SCOPE
,
906 .descrip
= "Use this Netbios scope",
907 .argDescrip
= "SCOPE",
910 .longName
= "workgroup",
912 .argInfo
= POPT_ARG_STRING
,
914 .descrip
= "Set the workgroup name",
915 .argDescrip
= "WORKGROUP",
919 .argInfo
= POPT_ARG_STRING
,
921 .descrip
= "Set the realm name",
922 .argDescrip
= "REALM",
927 /**********************************************************
929 **********************************************************/
931 static bool skip_password_callback
;
932 static bool machine_account_pending
;
934 static void popt_common_credentials_callback(poptContext popt_ctx
,
935 enum poptCallbackReason reason
,
936 const struct poptOption
*opt
,
940 struct loadparm_context
*lp_ctx
= samba_cmdline_get_lp_ctx();
941 struct cli_credentials
*creds
= samba_cmdline_get_creds();
944 if (reason
== POPT_CALLBACK_REASON_PRE
) {
947 "Command line parsing not initialized!\n");
953 if (reason
== POPT_CALLBACK_REASON_POST
) {
954 const char *username
= NULL
;
955 enum credentials_obtained username_obtained
=
957 enum credentials_obtained password_obtained
=
961 * This calls cli_credentials_set_conf() to get the defaults
962 * form smb.conf and set the winbind separator.
964 * Just warn that we can't read the smb.conf. There might not be
965 * one available or we want to ignore it.
967 ok
= cli_credentials_guess(creds
, lp_ctx
);
970 "Unable to read defaults from smb.conf\n");
973 if (machine_account_pending
) {
976 status
= cli_credentials_set_machine_account_fn(
978 if (!NT_STATUS_IS_OK(status
)) {
980 "Failed to set machine account: %s\n",
987 * When we set the username during the handling of the options
988 * passed to the binary we haven't loaded the config yet. This
989 * means that we didn't take the 'winbind separator' into
992 * The username might contain the domain name and thus it
993 * hasn't been correctly parsed yet. If we have a username we
994 * need to set it again to run the string parser for the
995 * username correctly.
998 cli_credentials_get_username_and_obtained(
999 creds
, &username_obtained
);
1000 if (username_obtained
== CRED_SPECIFIED
&&
1001 username
!= NULL
&& username
[0] != '\0') {
1002 cli_credentials_parse_string(creds
,
1007 if (cli_credentials_get_kerberos_state(creds
) ==
1008 CRED_USE_KERBEROS_REQUIRED
)
1010 enum credentials_obtained ccache_obtained
=
1012 enum credentials_obtained principal_obtained
=
1016 principal_obtained
=
1017 cli_credentials_get_principal_obtained(creds
);
1018 ccache_valid
= cli_credentials_get_ccache_name_obtained(
1019 creds
, NULL
, NULL
, &ccache_obtained
);
1021 ccache_obtained
== principal_obtained
)
1023 skip_password_callback
= true;
1026 if (!skip_password_callback
) {
1027 (void)cli_credentials_get_password_and_obtained(creds
,
1028 &password_obtained
);
1030 if (!skip_password_callback
&&
1031 password_obtained
< CRED_CALLBACK
) {
1032 ok
= cli_credentials_set_cmdline_callbacks(creds
);
1035 "Failed to set cmdline password "
1047 cli_credentials_parse_string(creds
,
1054 ok
= cli_credentials_set_password(creds
,
1059 "Failed to set password!\n");
1063 skip_password_callback
= true;
1067 cli_credentials_set_password_will_be_nt_hash(creds
, true);
1071 ok
= cli_credentials_parse_file(creds
,
1076 "Failed to set parse authentication file!\n");
1079 skip_password_callback
= true;
1083 ok
= cli_credentials_set_password(creds
,
1088 "Failed to set password!\n");
1091 skip_password_callback
= true;
1095 * Later, after this is all over, get the machine account
1096 * details from the secrets.(l|t)db.
1098 machine_account_pending
= true;
1100 case OPT_SIMPLE_BIND_DN
:
1102 ok
= cli_credentials_set_bind_dn(creds
, arg
);
1105 "Failed to set bind DN!\n");
1110 case OPT_USE_KERBEROS
: {
1111 int32_t use_kerberos
= INT_MIN
;
1115 "--use-kerberos=desired|required|off: "
1116 "Missing argument\n");
1120 use_kerberos
= lpcfg_parse_enum_vals("client use kerberos",
1122 if (use_kerberos
== INT_MIN
) {
1125 "--use-kerberos=desired|required|off: "
1126 "Invalid argument\n");
1130 ok
= cli_credentials_set_kerberos_state(creds
,
1135 "Failed to set Kerberos state to %s!\n", arg
);
1140 case OPT_USE_KERBEROS_CCACHE
: {
1141 const char *error_string
= NULL
;
1146 "Failed to parse --use-krb5-ccache=CCACHE: "
1147 "Missing argument\n");
1151 ok
= cli_credentials_set_kerberos_state(creds
,
1152 CRED_USE_KERBEROS_REQUIRED
,
1156 "Failed to set Kerberos state to %s!\n", arg
);
1160 rc
= cli_credentials_set_ccache(creds
,
1167 "Error reading krb5 credentials cache: '%s'"
1174 skip_password_callback
= true;
1177 case OPT_USE_WINBIND_CCACHE
:
1179 ok
= cli_credentials_add_gensec_features(
1180 creds
, GENSEC_FEATURE_NTLM_CCACHE
, CRED_SPECIFIED
);
1183 "Failed to set gensec feature!\n");
1187 skip_password_callback
= true;
1190 case OPT_CLIENT_PROTECTION
: {
1191 uint32_t gensec_features
;
1192 enum smb_signing_setting signing_state
=
1194 enum smb_encryption_setting encryption_state
=
1200 "--client-protection=sign|encrypt|off: "
1201 "Missing argument\n");
1206 cli_credentials_get_gensec_features(
1209 if (strequal(arg
, "off")) {
1211 ~(GENSEC_FEATURE_SIGN
|GENSEC_FEATURE_SEAL
);
1213 signing_state
= SMB_SIGNING_OFF
;
1214 encryption_state
= SMB_ENCRYPTION_OFF
;
1215 } else if (strequal(arg
, "sign")) {
1216 gensec_features
|= GENSEC_FEATURE_SIGN
;
1218 signing_state
= SMB_SIGNING_REQUIRED
;
1219 encryption_state
= SMB_ENCRYPTION_OFF
;
1220 } else if (strequal(arg
, "encrypt")) {
1221 gensec_features
|= GENSEC_FEATURE_SEAL
;
1223 signing_state
= SMB_SIGNING_REQUIRED
;
1224 encryption_state
= SMB_ENCRYPTION_REQUIRED
;
1227 "Failed to parse --client-protection\n");
1231 ok
= cli_credentials_set_gensec_features(creds
,
1236 "Failed to set gensec feature!\n");
1240 ok
= cli_credentials_set_smb_signing(creds
,
1245 "Failed to set smb signing!\n");
1249 ok
= cli_credentials_set_smb_encryption(creds
,
1254 "Failed to set smb encryption!\n");
1262 static struct poptOption popt_common_credentials
[] = {
1264 .argInfo
= POPT_ARG_CALLBACK
|POPT_CBFLAG_PRE
|POPT_CBFLAG_POST
,
1265 .arg
= (void *)popt_common_credentials_callback
,
1270 .argInfo
= POPT_ARG_STRING
,
1272 .descrip
= "Set the network username",
1273 .argDescrip
= "[DOMAIN/]USERNAME[%PASSWORD]",
1276 .longName
= "no-pass",
1278 .argInfo
= POPT_ARG_NONE
,
1280 .descrip
= "Don't ask for a password",
1283 .longName
= "password",
1284 .argInfo
= POPT_ARG_STRING
,
1285 .val
= OPT_PASSWORD
,
1286 .descrip
= "Password",
1289 .longName
= "pw-nt-hash",
1290 .argInfo
= POPT_ARG_NONE
,
1292 .descrip
= "The supplied password is the NT hash",
1295 .longName
= "authentication-file",
1297 .argInfo
= POPT_ARG_STRING
,
1299 .descrip
= "Get the credentials from a file",
1300 .argDescrip
= "FILE",
1303 .longName
= "machine-pass",
1305 .argInfo
= POPT_ARG_NONE
,
1307 .descrip
= "Use stored machine account password",
1310 .longName
= "simple-bind-dn",
1311 .argInfo
= POPT_ARG_STRING
,
1312 .val
= OPT_SIMPLE_BIND_DN
,
1313 .descrip
= "DN to use for a simple bind",
1317 .longName
= "use-kerberos",
1318 .argInfo
= POPT_ARG_STRING
,
1319 .val
= OPT_USE_KERBEROS
,
1320 .descrip
= "Use Kerberos authentication",
1321 .argDescrip
= "desired|required|off",
1324 .longName
= "use-krb5-ccache",
1325 .argInfo
= POPT_ARG_STRING
,
1326 .val
= OPT_USE_KERBEROS_CCACHE
,
1327 .descrip
= "Credentials cache location for Kerberos",
1328 .argDescrip
= "CCACHE",
1331 .longName
= "use-winbind-ccache",
1332 .argInfo
= POPT_ARG_NONE
,
1333 .val
= OPT_USE_WINBIND_CCACHE
,
1334 .descrip
= "Use the winbind ccache for authentication",
1337 .longName
= "client-protection",
1338 .argInfo
= POPT_ARG_STRING
,
1339 .val
= OPT_CLIENT_PROTECTION
,
1340 .descrip
= "Configure used protection for client connections",
1341 .argDescrip
= "sign|encrypt|off",
1346 /**********************************************************
1348 **********************************************************/
1350 static void popt_version_callback(poptContext ctx
,
1351 enum poptCallbackReason reason
,
1352 const struct poptOption
*opt
,
1358 printf("Version %s\n", SAMBA_VERSION_STRING
);
1363 static struct poptOption popt_common_version
[] = {
1365 .argInfo
= POPT_ARG_CALLBACK
,
1366 .arg
= (void *)popt_version_callback
,
1369 .longName
= "version",
1371 .argInfo
= POPT_ARG_NONE
,
1373 .descrip
= "Print version",
1378 /**********************************************************
1380 **********************************************************/
1382 static void popt_daemon_callback(poptContext ctx
,
1383 enum poptCallbackReason reason
,
1384 const struct poptOption
*opt
,
1390 cmdline_daemon_cfg
.daemon
= true;
1392 case OPT_INTERACTIVE
:
1393 cmdline_daemon_cfg
.interactive
= true;
1394 cmdline_daemon_cfg
.fork
= false;
1397 cmdline_daemon_cfg
.fork
= false;
1399 case OPT_NO_PROCESS_GROUP
:
1400 cmdline_daemon_cfg
.no_process_group
= true;
1405 static struct poptOption popt_common_daemon
[] = {
1407 .argInfo
= POPT_ARG_CALLBACK
,
1408 .arg
= (void *)popt_daemon_callback
1411 .longName
= "daemon",
1413 .argInfo
= POPT_ARG_NONE
,
1416 .descrip
= "Become a daemon (default)" ,
1419 .longName
= "interactive",
1421 .argInfo
= POPT_ARG_NONE
,
1423 .val
= OPT_INTERACTIVE
,
1424 .descrip
= "Run interactive (not a daemon) and log to stdout",
1427 .longName
= "foreground",
1429 .argInfo
= POPT_ARG_NONE
,
1432 .descrip
= "Run daemon in foreground (for daemontools, etc.)",
1435 .longName
= "no-process-group",
1437 .argInfo
= POPT_ARG_NONE
,
1439 .val
= OPT_NO_PROCESS_GROUP
,
1440 .descrip
= "Don't create a new process group" ,
1445 /**********************************************************
1447 **********************************************************/
1449 static void popt_legacy_s3_callback(poptContext ctx
,
1450 enum poptCallbackReason reason
,
1451 const struct poptOption
*opt
,
1455 struct cli_credentials
*creds
= samba_cmdline_get_creds();
1461 "WARNING: The option -k|--kerberos is deprecated!\n");
1463 ok
= cli_credentials_set_kerberos_state(creds
,
1464 CRED_USE_KERBEROS_REQUIRED
,
1468 "Failed to set Kerberos state to %s!\n", arg
);
1472 skip_password_callback
= true;
1477 /* We allow '-k yes' too. */
1478 static struct poptOption popt_legacy_s3
[] = {
1480 .argInfo
= POPT_ARG_CALLBACK
,
1481 .arg
= (void *)popt_legacy_s3_callback
,
1484 .longName
= "kerberos",
1486 .argInfo
= POPT_ARG_NONE
,
1488 .descrip
= "DEPRECATED: Migrate to --use-kerberos",
1493 /**********************************************************
1495 **********************************************************/
1497 static void popt_legacy_s4_callback(poptContext ctx
,
1498 enum poptCallbackReason reason
,
1499 const struct poptOption
*opt
,
1503 struct cli_credentials
*creds
= samba_cmdline_get_creds();
1508 enum credentials_use_kerberos use_kerberos
=
1509 CRED_USE_KERBEROS_REQUIRED
;
1512 "WARNING: The option -k|--kerberos is deprecated!\n");
1515 if (strcasecmp_m(arg
, "yes") == 0) {
1516 use_kerberos
= CRED_USE_KERBEROS_REQUIRED
;
1517 } else if (strcasecmp_m(arg
, "no") == 0) {
1518 use_kerberos
= CRED_USE_KERBEROS_DISABLED
;
1521 "Error parsing -k %s. Should be "
1528 ok
= cli_credentials_set_kerberos_state(creds
,
1533 "Failed to set Kerberos state to %s!\n", arg
);
1542 static struct poptOption popt_legacy_s4
[] = {
1544 .argInfo
= POPT_ARG_CALLBACK
,
1545 .arg
= (void *)popt_legacy_s4_callback
,
1548 .longName
= "kerberos",
1550 .argInfo
= POPT_ARG_STRING
,
1552 .descrip
= "DEPRECATED: Migrate to --use-kerberos",
1557 struct poptOption
*samba_cmdline_get_popt(enum smb_cmdline_popt_options opt
)
1560 case SAMBA_CMDLINE_POPT_OPT_DEBUG_ONLY
:
1561 return popt_common_debug
;
1563 case SAMBA_CMDLINE_POPT_OPT_OPTION_ONLY
:
1564 return popt_common_option
;
1566 case SAMBA_CMDLINE_POPT_OPT_CONFIG_ONLY
:
1567 return popt_common_config
;
1569 case SAMBA_CMDLINE_POPT_OPT_SAMBA
:
1570 return popt_common_samba
;
1572 case SAMBA_CMDLINE_POPT_OPT_CONNECTION
:
1573 return popt_common_connection
;
1575 case SAMBA_CMDLINE_POPT_OPT_CREDENTIALS
:
1576 return popt_common_credentials
;
1578 case SAMBA_CMDLINE_POPT_OPT_VERSION
:
1579 return popt_common_version
;
1581 case SAMBA_CMDLINE_POPT_OPT_DAEMON
:
1582 return popt_common_daemon
;
1584 case SAMBA_CMDLINE_POPT_OPT_SAMBA_LDB
:
1585 return popt_common_samba_ldb
;
1587 case SAMBA_CMDLINE_POPT_OPT_LEGACY_S3
:
1588 return popt_legacy_s3
;
1590 case SAMBA_CMDLINE_POPT_OPT_LEGACY_S4
:
1591 return popt_legacy_s4
;