2 Unix SMB/CIFS implementation.
3 Samba utility functions
4 Copyright (C) Andrew Tridgell 1992-1998
5 Copyright (C) Jeremy Allison 2001-2007
6 Copyright (C) Simo Sorce 2001
7 Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003
8 Copyright (C) James Peach 2006
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 3 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program. If not, see <http://www.gnu.org/licenses/>.
25 #include "auth_info.h"
27 #include "param/param.h"
28 #include "librpc/gen_ndr/samr.h"
29 #include "auth/credentials/credentials.h"
30 #include "auth/gensec/gensec.h"
32 /**************************************************************************n
33 Code to cope with username/password auth options from the commandline.
34 Used mainly in client tools.
35 ****************************************************************************/
37 struct user_auth_info {
38 struct cli_credentials *creds;
39 struct loadparm_context *lp_ctx;
44 bool use_machine_account;
49 struct user_auth_info *user_auth_info_init(TALLOC_CTX *mem_ctx)
51 struct user_auth_info *result = NULL;
53 result = talloc_zero(mem_ctx, struct user_auth_info);
58 result->lp_ctx = loadparm_init_s3(result, loadparm_s3_helpers());
59 if (result->lp_ctx == NULL) {
64 result->creds = cli_credentials_init(result);
65 if (result->creds == NULL) {
70 cli_credentials_set_conf(result->creds, result->lp_ctx);
72 result->signing_state = SMB_SIGNING_DEFAULT;
76 void set_cmdline_auth_info_guess(struct user_auth_info *auth_info)
79 * Note that cli_credentials_guess() calls
80 * cli_credentials_set_conf() again, which will
81 * hopefully cope with a reloaded smb.conf.
83 cli_credentials_set_username(auth_info->creds, "GUEST", CRED_GUESS_ENV);
84 cli_credentials_guess(auth_info->creds, auth_info->lp_ctx);
87 void set_cmdline_auth_info_from_file(struct user_auth_info *auth_info,
92 ok = cli_credentials_parse_file(auth_info->creds, filename,
97 auth_info->got_username = true;
100 const char *get_cmdline_auth_info_username(const struct user_auth_info *auth_info)
102 const char *username = NULL;
104 username = cli_credentials_get_username(auth_info->creds);
105 if (username == NULL) {
112 void set_cmdline_auth_info_username(struct user_auth_info *auth_info,
113 const char *username)
115 const char *new_val = NULL;
117 if (username == NULL) {
120 cli_credentials_parse_string(auth_info->creds,
123 new_val = cli_credentials_get_username(auth_info->creds);
124 if (new_val == NULL) {
128 auth_info->got_username = true;
129 if (strchr_m(username, '%') != NULL) {
130 auth_info->got_pass = true;
134 void reset_cmdline_auth_info_username(struct user_auth_info *auth_info)
136 const char *username = NULL;
137 const char *new_val = NULL;
139 if (!auth_info->got_username) {
143 username = cli_credentials_get_username(auth_info->creds);
144 if (username == NULL) {
147 if (username[0] == '\0') {
151 cli_credentials_parse_string(auth_info->creds,
154 new_val = cli_credentials_get_username(auth_info->creds);
155 if (new_val == NULL) {
160 const char *get_cmdline_auth_info_domain(const struct user_auth_info *auth_info)
162 const char *domain = NULL;
164 domain = cli_credentials_get_domain(auth_info->creds);
165 if (domain == NULL) {
172 void set_cmdline_auth_info_domain(struct user_auth_info *auth_info,
177 ok = cli_credentials_set_domain(auth_info->creds, domain, CRED_SPECIFIED);
183 const char *get_cmdline_auth_info_password(const struct user_auth_info *auth_info)
185 const char *password = NULL;
187 if (auth_info->pw_nt_hash != NULL) {
188 return auth_info->pw_nt_hash;
191 if (auth_info->use_pw_nt_hash) {
192 struct user_auth_info *ai =
193 discard_const_p(struct user_auth_info, auth_info);
194 struct samr_Password *nt_hash = NULL;
196 nt_hash = cli_credentials_get_nt_hash(ai->creds,
198 if (nt_hash == NULL) {
202 ai->pw_nt_hash = hex_encode_talloc(ai,
204 sizeof(nt_hash->hash));
205 TALLOC_FREE(nt_hash);
206 if (ai->pw_nt_hash == NULL) {
210 return auth_info->pw_nt_hash;
213 password = cli_credentials_get_password(auth_info->creds);
214 if (password == NULL) {
221 void set_cmdline_auth_info_password(struct user_auth_info *auth_info,
222 const char *password)
226 auth_info->got_pass = true;
228 if (password != NULL && strlen(password) == 0) {
232 ok = cli_credentials_set_password(auth_info->creds,
240 bool set_cmdline_auth_info_signing_state(struct user_auth_info *auth_info,
243 auth_info->signing_state = SMB_SIGNING_DEFAULT;
244 if (strequal(arg, "off") || strequal(arg, "no") ||
245 strequal(arg, "false")) {
246 auth_info->signing_state = SMB_SIGNING_OFF;
247 } else if (strequal(arg, "on") || strequal(arg, "yes") ||
248 strequal(arg, "if_required") ||
249 strequal(arg, "true") || strequal(arg, "auto")) {
250 auth_info->signing_state = SMB_SIGNING_IF_REQUIRED;
251 } else if (strequal(arg, "force") || strequal(arg, "required") ||
252 strequal(arg, "forced")) {
253 auth_info->signing_state = SMB_SIGNING_REQUIRED;
260 void set_cmdline_auth_info_signing_state_raw(struct user_auth_info *auth_info,
263 auth_info->signing_state = signing_state;
266 int get_cmdline_auth_info_signing_state(const struct user_auth_info *auth_info)
268 if (auth_info->smb_encrypt) {
269 return SMB_SIGNING_REQUIRED;
271 return auth_info->signing_state;
274 void set_cmdline_auth_info_use_ccache(struct user_auth_info *auth_info, bool b)
276 uint32_t gensec_features;
278 gensec_features = cli_credentials_get_gensec_features(auth_info->creds);
279 gensec_features |= GENSEC_FEATURE_NTLM_CCACHE;
280 cli_credentials_set_gensec_features(auth_info->creds, gensec_features);
283 bool get_cmdline_auth_info_use_ccache(const struct user_auth_info *auth_info)
285 uint32_t gensec_features;
287 gensec_features = cli_credentials_get_gensec_features(auth_info->creds);
288 if (gensec_features & GENSEC_FEATURE_NTLM_CCACHE) {
295 void set_cmdline_auth_info_use_pw_nt_hash(struct user_auth_info *auth_info,
298 TALLOC_FREE(auth_info->pw_nt_hash);
299 auth_info->use_pw_nt_hash = b;
300 cli_credentials_set_password_will_be_nt_hash(auth_info->creds, b);
303 bool get_cmdline_auth_info_use_pw_nt_hash(
304 const struct user_auth_info *auth_info)
306 return auth_info->use_pw_nt_hash;
309 void set_cmdline_auth_info_use_kerberos(struct user_auth_info *auth_info,
312 enum credentials_use_kerberos krb5_state;
315 krb5_state = CRED_MUST_USE_KERBEROS;
317 krb5_state = CRED_DONT_USE_KERBEROS;
320 cli_credentials_set_kerberos_state(auth_info->creds, krb5_state);
323 bool get_cmdline_auth_info_use_kerberos(const struct user_auth_info *auth_info)
325 enum credentials_use_kerberos krb5_state;
327 krb5_state = cli_credentials_get_kerberos_state(auth_info->creds);
329 if (krb5_state == CRED_MUST_USE_KERBEROS) {
336 void set_cmdline_auth_info_fallback_after_kerberos(struct user_auth_info *auth_info,
339 enum credentials_use_kerberos krb5_state;
341 krb5_state = cli_credentials_get_kerberos_state(auth_info->creds);
343 switch (krb5_state) {
344 case CRED_MUST_USE_KERBEROS:
346 krb5_state = CRED_AUTO_USE_KERBEROS;
349 case CRED_AUTO_USE_KERBEROS:
351 krb5_state = CRED_MUST_USE_KERBEROS;
354 case CRED_DONT_USE_KERBEROS:
359 cli_credentials_set_kerberos_state(auth_info->creds, krb5_state);
362 bool get_cmdline_auth_info_fallback_after_kerberos(const struct user_auth_info *auth_info)
364 enum credentials_use_kerberos krb5_state;
366 krb5_state = cli_credentials_get_kerberos_state(auth_info->creds);
368 if (krb5_state == CRED_AUTO_USE_KERBEROS) {
375 /* This should only be used by lib/popt_common.c JRA */
376 void set_cmdline_auth_info_use_krb5_ticket(struct user_auth_info *auth_info)
378 set_cmdline_auth_info_use_kerberos(auth_info, true);
379 auth_info->got_pass = true;
382 /* This should only be used by lib/popt_common.c JRA */
383 void set_cmdline_auth_info_smb_encrypt(struct user_auth_info *auth_info)
385 auth_info->smb_encrypt = true;
388 void set_cmdline_auth_info_use_machine_account(struct user_auth_info *auth_info)
390 cli_credentials_set_machine_account_pending(auth_info->creds,
392 auth_info->use_machine_account = true;
395 bool get_cmdline_auth_info_got_pass(const struct user_auth_info *auth_info)
397 return auth_info->got_pass;
400 bool get_cmdline_auth_info_smb_encrypt(const struct user_auth_info *auth_info)
402 return auth_info->smb_encrypt;
405 bool get_cmdline_auth_info_use_machine_account(const struct user_auth_info *auth_info)
407 return auth_info->use_machine_account;
410 bool set_cmdline_auth_info_machine_account_creds(struct user_auth_info *auth_info)
412 struct db_context *db_ctx = NULL;
415 if (!get_cmdline_auth_info_use_machine_account(auth_info)) {
419 db_ctx = secrets_db_ctx();
420 if (db_ctx == NULL) {
421 d_printf("ERROR: Unable to open secrets database\n");
425 cli_credentials_set_domain(auth_info->creds, lpcfg_workgroup(auth_info->lp_ctx),
428 status = cli_credentials_set_machine_account_db_ctx(auth_info->creds,
431 if (!NT_STATUS_IS_OK(status)) {
432 d_printf("ERROR: Unable to fetch machine password for "
433 "%s in domain %s - %s\n",
434 lpcfg_netbios_name(auth_info->lp_ctx),
435 lpcfg_workgroup(auth_info->lp_ctx),
443 static const char *cmdline_auth_info_pw_callback(struct cli_credentials *creds)
445 TALLOC_CTX *frame = talloc_stackframe();
446 const char *name = NULL;
452 name = cli_credentials_get_unparsed_name(creds, frame);
456 label = talloc_asprintf(frame, "Enter %s's password: ", name);
460 rc = samba_getpass(label, pwd, sizeof(pwd), false, false);
464 ret = talloc_strdup(creds, pwd);
468 talloc_set_name_const(ret, __location__);
475 /****************************************************************************
476 Ensure we have a password if one not given.
477 ****************************************************************************/
479 void set_cmdline_auth_info_getpass(struct user_auth_info *auth_info)
481 if (get_cmdline_auth_info_got_pass(auth_info) ||
482 get_cmdline_auth_info_use_ccache(auth_info) ||
483 get_cmdline_auth_info_use_kerberos(auth_info)) {
484 /* Already got one... */
488 cli_credentials_set_password_callback(auth_info->creds,
489 cmdline_auth_info_pw_callback);
492 struct cli_credentials *get_cmdline_auth_info_creds(
493 const struct user_auth_info *auth_info)
495 return auth_info->creds;