summaryrefslogtreecommitdiff
path: root/source3/utils/ntlm_auth.c
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2003-03-24 09:54:13 +0000
committerAndrew Bartlett <abartlet@samba.org>2003-03-24 09:54:13 +0000
commit53beee9e5675a59c67d9ecfbaec50dca4ac01750 (patch)
treeb4ca6d9d3055c941bab8da23d70abf3e9eae4260 /source3/utils/ntlm_auth.c
parent7d4bfa0eda4f79f55950d4089e636eecc37975f6 (diff)
downloadsamba-53beee9e5675a59c67d9ecfbaec50dca4ac01750.tar.gz
samba-53beee9e5675a59c67d9ecfbaec50dca4ac01750.tar.bz2
samba-53beee9e5675a59c67d9ecfbaec50dca4ac01750.zip
(merge from HEAD)
NTLM Authentication: - Add a 'privileged' mode to Winbindd. This is achieved by means of a directory under lockdir, that the admin can change the group access for. - This mode is now required to access with 'CRAP' authentication feature. - This *will* break the current SQUID helper, so I've fixed up our ntlm_auth replacement: - Update our NTLMSSP code to cope with 'datagram' mode, where we don't get a challenge. - Use this to make our ntlm_auth utility suitable for use in current Squid 2.5 servers. - Tested - works for Win2k clients, but not Win9X at present. NTLMSSP updates are needed. - Now uses fgets(), not x_fgets() to cope with Squid environment (I think somthing to do with non-blocking stdin). - Add much more robust connection code to wb_common.c - it will not connect to a server of a different protocol version, and it will automatically try and reconnect to the 'privileged' pipe if possible. - This could help with 'privileged' idmap operations etc in future. - Add a generic HEX encode routine to util_str.c, - fix a small line of dodgy C in StrnCpy_fn() - Correctly pull our 'session key' out of the info3 from th the DC. This is used in both the auth code, and in for export over the winbind pipe to ntlm_auth. - Given the user's challenge/response and access to the privileged pipe, allow external access to the 'session key'. To be used for MSCHAPv2 integration. Andrew Bartlett (This used to be commit ec071ca3dcbd3881dc08e6a8d7ac2ff0bcd57664)
Diffstat (limited to 'source3/utils/ntlm_auth.c')
-rw-r--r--source3/utils/ntlm_auth.c164
1 files changed, 82 insertions, 82 deletions
diff --git a/source3/utils/ntlm_auth.c b/source3/utils/ntlm_auth.c
index b76308c55f..ac456769f2 100644
--- a/source3/utils/ntlm_auth.c
+++ b/source3/utils/ntlm_auth.c
@@ -51,6 +51,8 @@ static unsigned char *lm_response;
static size_t lm_response_len;
static unsigned char *nt_response;
static size_t nt_response_len;
+static int request_lm_key;
+static int request_nt_key;
static char *password;
@@ -197,7 +199,7 @@ static NTSTATUS winbind_pw_check(struct ntlmssp_state *ntlmssp_state)
memcpy(request.data.auth_crap.lm_resp, ntlmssp_state->lm_resp.data,
MIN(ntlmssp_state->lm_resp.length, sizeof(request.data.auth_crap.lm_resp)));
- memcpy(request.data.auth_crap.nt_resp, ntlmssp_state->lm_resp.data,
+ memcpy(request.data.auth_crap.nt_resp, ntlmssp_state->nt_resp.data,
MIN(ntlmssp_state->nt_resp.length, sizeof(request.data.auth_crap.nt_resp)));
request.data.auth_crap.lm_resp_len = ntlmssp_state->lm_resp.length;
@@ -217,10 +219,28 @@ static NTSTATUS winbind_pw_check(struct ntlmssp_state *ntlmssp_state)
static void manage_squid_ntlmssp_request(enum squid_mode squid_mode,
char *buf, int length)
{
- static NTLMSSP_STATE *ntlmssp_state;
+ static NTLMSSP_STATE *ntlmssp_state = NULL;
DATA_BLOB request, reply;
NTSTATUS nt_status;
+ if (strlen(buf) < 2) {
+ DEBUG(1, ("NTLMSSP query [%s] invalid", buf));
+ x_fprintf(x_stdout, "BH\n");
+ return;
+ }
+
+ if (strlen(buf) > 3) {
+ request = base64_decode_data_blob(buf + 3);
+ } else if (strcmp(buf, "YR") == 0) {
+ request = data_blob(NULL, 0);
+ if (ntlmssp_state)
+ ntlmssp_server_end(&ntlmssp_state);
+ } else {
+ DEBUG(1, ("NTLMSSP query [%s] invalid", buf));
+ x_fprintf(x_stdout, "BH\n");
+ return;
+ }
+
if (!ntlmssp_state) {
ntlmssp_server_start(&ntlmssp_state);
ntlmssp_state->check_password = winbind_pw_check;
@@ -228,15 +248,8 @@ static void manage_squid_ntlmssp_request(enum squid_mode squid_mode,
ntlmssp_state->get_global_myname = get_winbind_netbios_name;
}
- if (strlen(buf) < 3) {
- x_fprintf(x_stdout, "BH\n");
- return;
- }
-
- request = base64_decode_data_blob(buf + 3);
-
- DEBUG(0, ("got NTLMSSP packet:\n"));
- dump_data(0, request.data, request.length);
+ DEBUG(10, ("got NTLMSSP packet:\n"));
+ dump_data(10, request.data, request.length);
nt_status = ntlmssp_server_update(ntlmssp_state, request, &reply);
@@ -245,10 +258,13 @@ static void manage_squid_ntlmssp_request(enum squid_mode squid_mode,
x_fprintf(x_stdout, "TT %s\n", reply_base64);
SAFE_FREE(reply_base64);
data_blob_free(&reply);
+ DEBUG(10, ("NTLMSSP challenge\n"));
} else if (!NT_STATUS_IS_OK(nt_status)) {
x_fprintf(x_stdout, "NA %s\n", nt_errstr(nt_status));
+ DEBUG(10, ("NTLMSSP %s\n", nt_errstr(nt_status)));
} else {
x_fprintf(x_stdout, "AF %s\\%s\n", ntlmssp_state->domain, ntlmssp_state->user);
+ DEBUG(10, ("NTLMSSP OK!\n"));
}
data_blob_free(&request);
@@ -287,10 +303,11 @@ static void manage_squid_request(enum squid_mode squid_mode)
int length;
char *c;
static BOOL err;
-
- if (x_fgets(buf, sizeof(buf)-1, x_stdin) == NULL) {
- DEBUG(1, ("fgets() failed! dying..... errno=%d (%s)\n", errno,
- strerror(errno)));
+
+ /* this is not a typo - x_fgets doesn't work too well under squid */
+ if (fgets(buf, sizeof(buf)-1, stdin) == NULL) {
+ DEBUG(1, ("fgets() failed! dying..... errno=%d (%s)\n", ferror(stdin),
+ strerror(ferror(stdin))));
exit(1); /* BIIG buffer */
}
@@ -341,12 +358,22 @@ static BOOL check_auth_crap(void)
{
struct winbindd_request request;
struct winbindd_response response;
+ char *lm_key;
+ char *nt_key;
+ static uint8 zeros[16];
+
NSS_STATUS result;
/* Send off request */
ZERO_STRUCT(request);
ZERO_STRUCT(response);
+ if (request_lm_key)
+ request.data.auth_crap.flags |= WINBIND_PAM_LMKEY;
+
+ if (request_nt_key)
+ request.data.auth_crap.flags |= WINBIND_PAM_NTKEY;
+
fstrcpy(request.data.auth_crap.user, username);
fstrcpy(request.data.auth_crap.domain, domain);
@@ -373,6 +400,27 @@ static BOOL check_auth_crap(void)
response.data.auth.nt_status_string,
response.data.auth.nt_status);
+ if (response.data.auth.nt_status == 0) {
+ if (request_lm_key
+ && (memcmp(zeros, response.data.auth.first_8_lm_hash,
+ sizeof(response.data.auth.first_8_lm_hash)) != 0)) {
+ hex_encode(response.data.auth.first_8_lm_hash,
+ sizeof(response.data.auth.first_8_lm_hash),
+ &lm_key);
+ d_printf("LM_KEY: %s\n", lm_key);
+ SAFE_FREE(lm_key);
+ }
+ if (request_nt_key
+ && (memcmp(zeros, response.data.auth.nt_session_key,
+ sizeof(response.data.auth.nt_session_key)) != 0)) {
+ hex_encode(response.data.auth.nt_session_key,
+ sizeof(response.data.auth.nt_session_key),
+ &nt_key);
+ d_printf("NT_KEY: %s\n", nt_key);
+ SAFE_FREE(nt_key);
+ }
+ }
+
return result == NSS_STATUS_SUCCESS;
}
@@ -386,68 +434,11 @@ enum {
OPT_RESPONSE,
OPT_LM,
OPT_NT,
- OPT_PASSWORD
+ OPT_PASSWORD,
+ OPT_LM_KEY,
+ OPT_NT_KEY
};
-/*************************************************************
- Routine to set hex password characters into an allocated array.
-**************************************************************/
-
-static void hex_encode(const unsigned char *buff_in, size_t len, char **out_hex_buffer)
-{
- int i;
- char *hex_buffer;
-
- *out_hex_buffer = smb_xmalloc((len*2)+1);
- hex_buffer = *out_hex_buffer;
-
- for (i = 0; i < len; i++)
- slprintf(&hex_buffer[i*2], 3, "%02X", buff_in[i]);
-}
-
-/*************************************************************
- Routine to get the 32 hex characters and turn them
- into a 16 byte array.
-**************************************************************/
-
-static BOOL hex_decode(const char *hex_buf_in, unsigned char **out_buffer, size_t *size)
-{
- int i;
- size_t hex_buf_in_len = strlen(hex_buf_in);
- unsigned char partial_byte_hex;
- unsigned char partial_byte;
- const char *hexchars = "0123456789ABCDEF";
- char *p;
- BOOL high = True;
-
- if (!hex_buf_in)
- return (False);
-
- *size = (hex_buf_in_len + 1) / 2;
-
- *out_buffer = smb_xmalloc(*size);
-
- for (i = 0; i < hex_buf_in_len; i++) {
- partial_byte_hex = toupper(hex_buf_in[i]);
-
- p = strchr(hexchars, partial_byte_hex);
-
- if (!p)
- return (False);
-
- partial_byte = PTR_DIFF(p, hexchars);
-
- if (high) {
- (*out_buffer)[i / 2] = (partial_byte << 4);
- } else {
- (*out_buffer)[i / 2] |= partial_byte;
- }
- high = !high;
- }
- return (True);
-}
-
-
int main(int argc, const char **argv)
{
int opt;
@@ -464,6 +455,8 @@ int main(int argc, const char **argv)
{ "lm-response", 0, POPT_ARG_STRING, &hex_lm_response, OPT_LM, "LM Response to the challenge (HEX encoded)"},
{ "nt-response", 0, POPT_ARG_STRING, &hex_nt_response, OPT_NT, "NT or NTLMv2 Response to the challenge (HEX encoded)"},
{ "password", 0, POPT_ARG_STRING, &password, OPT_PASSWORD, "User's plaintext password"},
+ { "request-lm-key", 0, POPT_ARG_NONE, &request_lm_key, OPT_LM_KEY, "Retreive LM session key"},
+ { "request-nt-key", 0, POPT_ARG_NONE, &request_nt_key, OPT_NT_KEY, "Retreive NT session key"},
{ NULL, 0, POPT_ARG_INCLUDE_TABLE, popt_common_debug },
{ NULL, 0, POPT_ARG_INCLUDE_TABLE, popt_common_configfile },
{ NULL, 0, POPT_ARG_INCLUDE_TABLE, popt_common_version},
@@ -491,20 +484,27 @@ int main(int argc, const char **argv)
while((opt = poptGetNextOpt(pc)) != -1) {
switch (opt) {
case OPT_CHALLENGE:
- if (!hex_decode(hex_challenge, &challenge, &challenge_len)) {
- fprintf(stderr, "hex decode of %s failed!\n", hex_challenge);
+ challenge_len = strlen(hex_challenge);
+ challenge = smb_xmalloc((challenge_len+1)/2);
+ if ((challenge_len = strhex_to_str(challenge, challenge_len, hex_challenge)) != 8) {
+ fprintf(stderr, "hex decode of %s failed (only got %u bytes)!\n",
+ hex_challenge, challenge_len);
exit(1);
}
break;
case OPT_LM:
- if (!hex_decode(hex_lm_response, &lm_response, &lm_response_len)) {
- fprintf(stderr, "hex decode of %s failed!\n", lm_response);
+ lm_response_len = strlen(hex_lm_response);
+ lm_response = smb_xmalloc((lm_response_len+1)/2);
+ if ((lm_response_len = strhex_to_str(lm_response, lm_response_len, hex_lm_response)) != 24) {
+ fprintf(stderr, "hex decode of %s failed!\n", hex_lm_response);
exit(1);
}
break;
- case OPT_NT:
- if (!hex_decode(hex_lm_response, &lm_response, &lm_response_len)) {
- fprintf(stderr, "hex decode of %s failed!\n", lm_response);
+ case OPT_NT:
+ nt_response_len = strlen(hex_nt_response);
+ nt_response = smb_xmalloc((nt_response_len+1)/2);
+ if ((nt_response_len = strhex_to_str(nt_response, nt_response_len, hex_nt_response)) < 24) {
+ fprintf(stderr, "hex decode of %s failed!\n", hex_nt_response);
exit(1);
}
break;