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
;