26
26
#include "includes.h"
27
#include "popt_common.h"
27
28
#include "utils/ntlm_auth.h"
28
29
#include "../libcli/auth/libcli_auth.h"
29
30
#include "../libcli/auth/spnego.h"
31
#include "../libcli/auth/ntlmssp.h"
30
32
#include "smb_krb5.h"
31
33
#include <iniparser.h>
34
#include "../lib/crypto/arcfour.h"
35
#include "libads/kerberos_proto.h"
36
#include "nsswitch/winbind_client.h"
37
#include "librpc/gen_ndr/krb5pac.h"
38
#include "../lib/util/asn1.h"
33
40
#ifndef PAM_WINBIND_CONFIG_FILE
34
41
#define PAM_WINBIND_CONFIG_FILE "/etc/security/pam_winbind.conf"
303
310
dictionary *d = NULL;
305
312
if (!opt_pam_winbind_conf || !*opt_pam_winbind_conf) {
306
313
opt_pam_winbind_conf = PAM_WINBIND_CONFIG_FILE;
309
316
d = iniparser_load(CONST_DISCARD(char *, opt_pam_winbind_conf));
315
322
if (iniparser_getboolean(d, CONST_DISCARD(char *, "global:krb5_auth"), false)) {
316
323
ctrl |= WINBIND_KRB5_AUTH;
319
326
iniparser_freedict(d);
534
541
memcpy(request.data.chng_pswd_auth_crap.old_lm_hash_enc, old_lm_hash_enc.data, sizeof(request.data.chng_pswd_auth_crap.old_lm_hash_enc));
535
542
request.data.chng_pswd_auth_crap.old_lm_hash_enc_len = old_lm_hash_enc.length;
538
545
result = winbindd_request_response(WINBINDD_PAM_CHNG_PSWD_AUTH_CRAP, &request, &response);
540
547
/* Display response */
560
567
winbindd_free_response(&response);
562
569
return nt_status;
565
static NTSTATUS winbind_pw_check(struct ntlmssp_state *ntlmssp_state, DATA_BLOB *user_session_key, DATA_BLOB *lm_session_key)
572
static NTSTATUS winbind_pw_check(struct ntlmssp_state *ntlmssp_state, TALLOC_CTX *mem_ctx,
573
DATA_BLOB *user_session_key, DATA_BLOB *lm_session_key)
567
575
static const char zeros[16] = { 0, };
568
576
NTSTATUS nt_status;
572
580
char *unix_name = NULL;
574
582
nt_status = contact_winbind_auth_crap(ntlmssp_state->user, ntlmssp_state->domain,
575
ntlmssp_state->workstation,
583
ntlmssp_state->client.netbios_name,
576
584
&ntlmssp_state->chal,
577
585
&ntlmssp_state->lm_resp,
578
586
&ntlmssp_state->nt_resp,
583
591
if (NT_STATUS_IS_OK(nt_status)) {
584
592
if (memcmp(lm_key, zeros, 8) != 0) {
585
*lm_session_key = data_blob_talloc(ntlmssp_state, NULL, 16);
593
*lm_session_key = data_blob_talloc(mem_ctx, NULL, 16);
586
594
memcpy(lm_session_key->data, lm_key, 8);
587
595
memset(lm_session_key->data+8, '\0', 8);
590
598
if (memcmp(user_sess_key, zeros, 16) != 0) {
591
*user_session_key = data_blob_talloc(ntlmssp_state, user_sess_key, 16);
599
*user_session_key = data_blob_talloc(mem_ctx, user_sess_key, 16);
593
ntlmssp_state->auth_context = talloc_strdup(ntlmssp_state,
601
ntlmssp_state->callback_private = talloc_strdup(ntlmssp_state,
596
604
DEBUG(NT_STATUS_EQUAL(nt_status, NT_STATUS_ACCESS_DENIED) ? 0 : 3,
597
605
("Login for user [%s]\\[%s]@[%s] failed due to [%s]\n",
598
606
ntlmssp_state->domain, ntlmssp_state->user,
599
ntlmssp_state->workstation,
607
ntlmssp_state->client.netbios_name,
600
608
error_string ? error_string : "unknown error (NULL)"));
601
ntlmssp_state->auth_context = NULL;
609
ntlmssp_state->callback_private = NULL;
604
612
SAFE_FREE(error_string);
606
614
return nt_status;
609
static NTSTATUS local_pw_check(struct ntlmssp_state *ntlmssp_state, DATA_BLOB *user_session_key, DATA_BLOB *lm_session_key)
617
static NTSTATUS local_pw_check(struct ntlmssp_state *ntlmssp_state, TALLOC_CTX *mem_ctx,
618
DATA_BLOB *user_session_key, DATA_BLOB *lm_session_key)
611
620
NTSTATUS nt_status;
612
621
struct samr_Password lm_pw, nt_pw;
614
623
nt_lm_owf_gen (opt_password, nt_pw.hash, lm_pw.hash);
616
nt_status = ntlm_password_check(ntlmssp_state,
625
nt_status = ntlm_password_check(mem_ctx,
618
627
&ntlmssp_state->chal,
619
628
&ntlmssp_state->lm_resp,
622
631
ntlmssp_state->user,
623
632
ntlmssp_state->domain,
624
633
&lm_pw, &nt_pw, user_session_key, lm_session_key);
626
635
if (NT_STATUS_IS_OK(nt_status)) {
627
ntlmssp_state->auth_context = talloc_asprintf(ntlmssp_state,
636
ntlmssp_state->callback_private = talloc_asprintf(ntlmssp_state,
628
637
"%s%c%s", ntlmssp_state->domain,
629
638
*lp_winbind_separator(),
630
639
ntlmssp_state->user);
632
641
DEBUG(3, ("Login for user [%s]\\[%s]@[%s] failed due to [%s]\n",
633
ntlmssp_state->domain, ntlmssp_state->user, ntlmssp_state->workstation,
642
ntlmssp_state->domain, ntlmssp_state->user,
643
ntlmssp_state->client.netbios_name,
634
644
nt_errstr(nt_status)));
635
ntlmssp_state->auth_context = NULL;
645
ntlmssp_state->callback_private = NULL;
637
647
return nt_status;
640
static NTSTATUS ntlm_auth_start_ntlmssp_client(NTLMSSP_STATE **client_ntlmssp_state)
650
static NTSTATUS ntlm_auth_start_ntlmssp_client(struct ntlmssp_state **client_ntlmssp_state)
643
653
if ( (opt_username == NULL) || (opt_domain == NULL) ) {
646
656
return NT_STATUS_INVALID_PARAMETER;
649
status = ntlmssp_client_start(client_ntlmssp_state);
659
status = ntlmssp_client_start(NULL,
662
lp_client_ntlmv2_auth(),
663
client_ntlmssp_state);
651
665
if (!NT_STATUS_IS_OK(status)) {
652
666
DEBUG(1, ("Could not start NTLMSSP client: %s\n",
653
667
nt_errstr(status)));
654
ntlmssp_end(client_ntlmssp_state);
668
TALLOC_FREE(*client_ntlmssp_state);
660
674
if (!NT_STATUS_IS_OK(status)) {
661
675
DEBUG(1, ("Could not set username: %s\n",
662
676
nt_errstr(status)));
663
ntlmssp_end(client_ntlmssp_state);
677
TALLOC_FREE(*client_ntlmssp_state);
669
683
if (!NT_STATUS_IS_OK(status)) {
670
684
DEBUG(1, ("Could not set domain: %s\n",
671
685
nt_errstr(status)));
672
ntlmssp_end(client_ntlmssp_state);
686
TALLOC_FREE(*client_ntlmssp_state);
676
690
if (opt_password) {
677
691
status = ntlmssp_set_password(*client_ntlmssp_state, opt_password);
679
693
if (!NT_STATUS_IS_OK(status)) {
680
694
DEBUG(1, ("Could not set password: %s\n",
681
695
nt_errstr(status)));
682
ntlmssp_end(client_ntlmssp_state);
696
TALLOC_FREE(*client_ntlmssp_state);
687
701
return NT_STATUS_OK;
690
static NTSTATUS ntlm_auth_start_ntlmssp_server(NTLMSSP_STATE **ntlmssp_state)
704
static NTSTATUS ntlm_auth_start_ntlmssp_server(struct ntlmssp_state **ntlmssp_state)
692
NTSTATUS status = ntlmssp_server_start(ntlmssp_state);
707
const char *netbios_name;
708
const char *netbios_domain;
709
const char *dns_name;
711
bool is_standalone = false;
714
netbios_name = global_myname();
715
netbios_domain = lp_workgroup();
717
netbios_name = get_winbind_netbios_name();
718
netbios_domain = get_winbind_domain();
720
/* This should be a 'netbios domain -> DNS domain' mapping */
721
dns_domain = get_mydnsdomname(talloc_tos());
723
strlower_m(dns_domain);
725
dns_name = get_mydnsfullname();
727
status = ntlmssp_server_start(NULL,
694
734
if (!NT_STATUS_IS_OK(status)) {
695
735
DEBUG(1, ("Could not start NTLMSSP server: %s\n",
696
736
nt_errstr(status)));
700
740
/* Have we been given a local password, or should we ask winbind? */
701
741
if (opt_password) {
702
742
(*ntlmssp_state)->check_password = local_pw_check;
703
(*ntlmssp_state)->get_domain = lp_workgroup;
704
(*ntlmssp_state)->get_global_myname = global_myname;
706
744
(*ntlmssp_state)->check_password = winbind_pw_check;
707
(*ntlmssp_state)->get_domain = get_winbind_domain;
708
(*ntlmssp_state)->get_global_myname = get_winbind_netbios_name;
710
746
return NT_STATUS_OK;
732
768
* child of the trusted domain. If we ask the primary domain for
733
769
* ntlm_ccache_auth, it will fail. So, we have to ask the trusted
734
770
* domain's child for ccache_ntlm_auth. that is to say, we have to
735
* set WBFALG_PAM_CONTACT_TRUSTDOM in request.flags.
771
* set WBFLAG_PAM_CONTACT_TRUSTDOM in request.flags.
737
773
ctrl = get_pam_winbind_config();
830
866
if (strncmp(buf, "YR", 2) == 0) {
831
if (state->ntlmssp_state)
832
ntlmssp_end(&state->ntlmssp_state);
867
TALLOC_FREE(state->ntlmssp_state);
833
868
state->svr_state = SERVER_INITIAL;
834
869
} else if (strncmp(buf, "KK", 2) == 0) {
835
870
/* No special preprocessing required */
895
930
nt_errstr(nt_status));
896
931
DEBUG(0, ("NTLMSSP BH: %s\n", nt_errstr(nt_status)));
898
ntlmssp_end(&state->ntlmssp_state);
933
TALLOC_FREE(state->ntlmssp_state);
899
934
} else if (!NT_STATUS_IS_OK(nt_status)) {
900
935
*response = talloc_asprintf(mem_ctx, "NA %s",
901
936
nt_errstr(nt_status));
904
939
*response = talloc_asprintf(
905
940
mem_ctx, "AF %s",
906
(char *)state->ntlmssp_state->auth_context);
941
(char *)state->ntlmssp_state->callback_private);
907
942
DEBUG(10, ("NTLMSSP OK!\n"));
909
944
if(state->have_session_key)
1008
1043
if (strncmp(buf, "YR", 2) == 0) {
1009
if (state->ntlmssp_state)
1010
ntlmssp_end(&state->ntlmssp_state);
1044
TALLOC_FREE(state->ntlmssp_state);
1011
1045
state->cli_state = CLIENT_INITIAL;
1012
1046
} else if (strncmp(buf, "TT", 2) == 0) {
1013
1047
/* No special preprocessing required */
1099
1133
DEBUG(10, ("NTLMSSP OK!\n"));
1100
1134
state->cli_state = CLIENT_FINISHED;
1101
if (state->ntlmssp_state)
1102
ntlmssp_end(&state->ntlmssp_state);
1135
TALLOC_FREE(state->ntlmssp_state);
1104
1137
x_fprintf(x_stdout, "BH %s\n", nt_errstr(nt_status));
1105
1138
DEBUG(0, ("NTLMSSP BH: %s\n", nt_errstr(nt_status)));
1106
1139
state->cli_state = CLIENT_ERROR;
1107
if (state->ntlmssp_state)
1108
ntlmssp_end(&state->ntlmssp_state);
1140
TALLOC_FREE(state->ntlmssp_state);
1111
1143
data_blob_free(&request);
1129
1161
if (state->helper_mode == SQUID_2_5_BASIC) {
1130
1162
rfc1738_unescape(user);
1131
1163
rfc1738_unescape(pass);
1134
1166
if (check_plaintext_auth(user, pass, False)) {
1135
1167
x_fprintf(x_stdout, "OK\n");
1199
static bool _spnego_parse_krb5_wrap(TALLOC_CTX *ctx, DATA_BLOB blob, DATA_BLOB *ticket, uint8 tok_id[2])
1231
bool spnego_parse_krb5_wrap(TALLOC_CTX *ctx, DATA_BLOB blob, DATA_BLOB *ticket, uint8 tok_id[2])
1202
1234
ASN1_DATA *data;
1263
1295
if (strncmp(buf, "YR", 2) == 0) {
1264
if (state->ntlmssp_state)
1265
ntlmssp_end(&state->ntlmssp_state);
1296
TALLOC_FREE(state->ntlmssp_state);
1266
1297
TALLOC_FREE(state->spnego_mech);
1267
1298
TALLOC_FREE(state->spnego_mech_oid);
1268
1299
} else if (strncmp(buf, "KK", 2) == 0) {
1395
1426
x_fprintf(x_stdout, "BH Client wants a new "
1396
1427
"NTLMSSP challenge, but "
1397
1428
"already got one\n");
1398
ntlmssp_end(&state->ntlmssp_state);
1429
TALLOC_FREE(state->ntlmssp_state);
1472
1503
domain = talloc_strdup(ctx, state->ntlmssp_state->domain);
1474
1505
if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1475
ntlmssp_end(&state->ntlmssp_state);
1506
TALLOC_FREE(state->ntlmssp_state);
1477
1508
#ifdef HAVE_KRB5
1478
1509
} else if (strcmp(state->spnego_mech, "krb5") == 0) {
1479
1510
char *principal;
1480
1511
DATA_BLOB ap_rep;
1481
1512
DATA_BLOB session_key;
1482
struct PAC_DATA *pac_data = NULL;
1513
struct PAC_LOGON_INFO *logon_info = NULL;
1483
1514
DATA_BLOB ticket;
1484
1515
uint8_t tok_id[2];
1486
if (!_spnego_parse_krb5_wrap(ctx, raw_in_token,
1517
if (!spnego_parse_krb5_wrap(ctx, raw_in_token,
1488
1519
DEBUG(1, ("spnego_parse_krb5_wrap failed\n"));
1489
1520
x_fprintf(x_stdout, "BH spnego_parse_krb5_wrap failed\n");
1493
1524
status = ads_verify_ticket(ctx, lp_realm(), 0,
1495
&principal, &pac_data, &ap_rep,
1526
&principal, &logon_info, &ap_rep,
1496
1527
&session_key, True);
1498
1529
/* Now in "principal" we have the name we are authenticated as. */
1514
1545
domain = talloc_strdup(ctx, domain);
1515
1546
user = talloc_strdup(ctx, principal);
1518
struct PAC_LOGON_INFO *logon_info;
1519
logon_info = get_logon_info_from_pac(
1522
netsamlogon_cache_store(
1524
&logon_info->info3);
1549
netsamlogon_cache_store(
1550
user, &logon_info->info3);
1528
1553
data_blob_free(&ap_rep);
1637
1662
NT_STATUS_IS_OK(status)) ) {
1638
1663
DEBUG(1, ("Expected OK or MORE_PROCESSING_REQUIRED, got: %s\n",
1639
1664
nt_errstr(status)));
1640
ntlmssp_end(&client_ntlmssp_state);
1665
TALLOC_FREE(client_ntlmssp_state);
1671
1696
if (spnego.negTokenTarg.negResult == SPNEGO_REJECT) {
1672
1697
x_fprintf(x_stdout, "NA\n");
1673
ntlmssp_end(&client_ntlmssp_state);
1698
TALLOC_FREE(client_ntlmssp_state);
1677
1702
if (spnego.negTokenTarg.negResult == SPNEGO_ACCEPT_COMPLETED) {
1678
1703
x_fprintf(x_stdout, "AF\n");
1679
ntlmssp_end(&client_ntlmssp_state);
1704
TALLOC_FREE(client_ntlmssp_state);
1683
1708
status = ntlmssp_update(client_ntlmssp_state,
1684
1709
spnego.negTokenTarg.responseToken,
1687
1712
if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1688
1713
DEBUG(1, ("Expected MORE_PROCESSING_REQUIRED from "
1689
1714
"ntlmssp_client_update, got: %s\n",
1691
1716
x_fprintf(x_stdout, "BH Expected MORE_PROCESSING_REQUIRED from "
1692
1717
"ntlmssp_client_update\n");
1693
1718
data_blob_free(&request);
1694
ntlmssp_end(&client_ntlmssp_state);
1719
TALLOC_FREE(client_ntlmssp_state);
1700
1725
spnego.negTokenTarg.supportedMech = (char *)OID_NTLMSSP;
1701
1726
spnego.negTokenTarg.responseToken = request;
1702
1727
spnego.negTokenTarg.mechListMIC = null_blob;
1704
1729
spnego_write_data(ctx, &to_server, &spnego);
1705
1730
data_blob_free(&request);
1744
1769
spnego.negTokenInit.mechListMIC.length);
1745
1770
principal[spnego.negTokenInit.mechListMIC.length] = '\0';
1747
retval = cli_krb5_get_ticket(principal, 0, &tkt, &session_key_krb5, 0, NULL, NULL, NULL);
1772
retval = cli_krb5_get_ticket(ctx, principal, 0,
1773
&tkt, &session_key_krb5,
1774
0, NULL, NULL, NULL);
1750
1776
char *user = NULL;
1771
retval = cli_krb5_get_ticket(principal, 0, &tkt, &session_key_krb5, 0, NULL, NULL, NULL);
1797
retval = cli_krb5_get_ticket(ctx, principal, 0,
1798
&tkt, &session_key_krb5,
1799
0, NULL, NULL, NULL);
1774
1801
DEBUG(10, ("Kinit suceeded, but getting a ticket failed: %s\n", error_message(retval)));
1854
1881
/* We asked for a password and obviously got it :-) */
1856
1883
opt_password = SMB_STRNDUP((const char *)request.data, request.length);
1858
1885
if (opt_password == NULL) {
1859
1886
DEBUG(1, ("Out of memory\n"));
1860
1887
x_fprintf(x_stdout, "BH Out of memory\n");
1982
2009
static char *plaintext_password;
1983
2010
static bool ntlm_server_1_user_session_key;
1984
2011
static bool ntlm_server_1_lm_session_key;
1986
2013
if (strequal(buf, ".")) {
1987
2014
if (!full_username && !username) {
1988
2015
x_fprintf(x_stdout, "Error: No username supplied!\n");
2012
2039
if (full_username && !username) {
2013
2040
fstring fstr_user;
2014
2041
fstring fstr_domain;
2016
2043
if (!parse_ntlm_auth_domain_user(full_username, fstr_user, fstr_domain)) {
2017
2044
/* username might be 'tainted', don't print into our new-line deleimianted stream */
2018
2045
x_fprintf(x_stdout, "Error: Could not parse into domain and username\n");
2098
2125
parameter = strstr_m(request, ":: ");
2099
2126
if (!parameter) {
2100
2127
parameter = strstr_m(request, ": ");
2102
2129
if (!parameter) {
2103
2130
DEBUG(0, ("Parameter not found!\n"));
2104
2131
x_fprintf(x_stdout, "Error: Parameter not found!\n.\n");
2108
2135
parameter[0] ='\0';
2110
2137
parameter[0] ='\0';
2186
2213
new_nt_pswd = data_blob(NULL, 516);
2187
2214
old_nt_hash_enc = data_blob(NULL, 16);
2189
2216
/* Calculate the MD4 hash (NT compatible) of the
2191
2218
E_md4hash(oldpswd, old_nt_hash);
2194
2221
/* E_deshash returns false for 'long'
2195
2222
passwords (> 14 DOS chars).
2197
2224
Therefore, don't send a buffer
2198
2225
encrypted with the truncated hash
2199
2226
(it could allow an even easier
2223
2250
encode_pw_buffer(new_nt_pswd.data, newpswd,
2226
2253
arcfour_crypt(new_nt_pswd.data, old_nt_hash, 516);
2227
2254
E_old_pw_hash(new_nt_hash, old_nt_hash,
2228
2255
old_nt_hash_enc.data);
2231
2258
if (!full_username && !username) {
2232
2259
x_fprintf(x_stdout, "Error: No username supplied!\n");
2233
2260
} else if ((!new_nt_pswd.data || !old_nt_hash_enc.data) &&
2298
2325
parameter = strstr_m(request, ":: ");
2299
2326
if (!parameter) {
2300
2327
parameter = strstr_m(request, ": ");
2302
2329
if (!parameter) {
2303
2330
DEBUG(0, ("Parameter not found!\n"));
2304
2331
x_fprintf(x_stdout, "Error: Parameter not found!\n.\n");
2308
2335
parameter[0] ='\0';
2310
2337
parameter[0] ='\0';
2580
2607
{ "request-lm-key", 0, POPT_ARG_NONE, &request_lm_key, OPT_LM_KEY, "Retrieve LM session key"},
2581
2608
{ "request-nt-key", 0, POPT_ARG_NONE, &request_user_session_key, OPT_USER_SESSION_KEY, "Retrieve User (NT) session key"},
2582
2609
{ "use-cached-creds", 0, POPT_ARG_NONE, &use_cached_creds, OPT_USE_CACHED_CREDS, "Use cached credentials if no password is given"},
2583
{ "diagnostics", 0, POPT_ARG_NONE, &diagnostics, OPT_DIAGNOSTICS, "Perform diagnostics on the authentictaion chain"},
2610
{ "diagnostics", 0, POPT_ARG_NONE, &diagnostics,
2612
"Perform diagnostics on the authentication chain"},
2584
2613
{ "require-membership-of", 0, POPT_ARG_STRING, &require_membership_of, OPT_REQUIRE_MEMBERSHIP, "Require that a user be a member of this group (either name or SID) for authentication to succeed" },
2585
2614
{ "pam-winbind-conf", 0, POPT_ARG_STRING, &opt_pam_winbind_conf, OPT_PAM_WINBIND_CONF, "Require that request must set WBFLAG_PAM_CONTACT_TRUSTDOM when krb5 auth is required" },
2586
2615
POPT_COMMON_CONFIGFILE