[patch] functional mod_ntlm_winbind
Nicolas Dehaine
nicko at stbernard.com
Thu Aug 5 19:31:43 GMT 2004
Hello everyone,
Here is a patch for Tim Potter's mod_ntlm_winbind which allows Apache to
interface with winbindd to authenticate users for browsers supporting
NTLM authentication.
The patch is against the latest version (mod_ntlm_winbind.c 1.10 and
ntlmssp.c 1.3), available from
http://cvs.samba.org/cgi-bin/cvsweb/mod_ntlm_winbind/ and should work
with:
- Apache 1.3.31
- Samba 3.0.2/3.0.5
- NTLM v1 (no support for v2)
- Tested on FreeBSD 4.x and 5.2
- Tested with IE 5.x 6.x on Windows 95,98,ME,NT4,2000,XP,2003
- Tested with Firefox 0.9.3 on XP
----------------------------------------------------
Nicolas Dehaine - RAPID Development Manager
St Bernard Software - San Diego, CA.
http://www.stbernard.com
-------------- next part --------------
Index: ntlmssp.c
===================================================================
RCS file: ntlmssp.c,v
*** ntlmssp.c 2002/10/23 17:53:12
--- ntlmssp.c 2004/08/05 16:22:44
***************
*** 23,35 ****
#define RESP_LEN 24
#define NONCE_LEN 8
struct ntlm_msg1 {
unsigned char protocol[8];
unsigned char type; /* 1 */
unsigned char zero1[3];
! unsigned char flags1;
! unsigned char flags2;
! unsigned char zero2[2];
unsigned char dom_len[4];
unsigned char dom_off[4];
--- 23,67 ----
#define RESP_LEN 24
#define NONCE_LEN 8
+ // ###### flags for msg 1, 2 & 3
+ #define UNICODE 0x00000001
+ #define ASCII 0x00000002
+ #define REQUEST_TARGET 0x00000004
+ #define UNKNOWN1 0x00000008
+ #define SIGN 0x00000010
+ #define SEAL 0x00000020
+ #define USE_DATAGRAM 0x00000040
+ #define USE_LM 0x00000080
+ #define USE_NETWARE 0x00000100
+ #define USE_NTLM 0x00000200
+ #define UNKNOWN2 0x00000400
+ #define UNKNOWN3 0x00000800
+ #define DOMAIN_SUPPLIED 0x00001000
+ #define WORKSTATION_SUPPLIED 0x00002000
+ #define LOCAL_CALL 0x00004000
+ #define ALWAYS_SIGN 0x00008000
+ #define TARGET_DOMAIN 0x00010000
+ #define TARGET_SERVER 0x00020000
+ #define TARGET_SHARE 0x00040000
+ #define NTLM2 0x00080000
+ #define INIT_RESPONSE 0x00100000
+ #define ACCEPT_RESPONSE 0x00200000
+ #define NON_NT_SESSION_KEY 0x00400000
+ #define TARGET_INFO 0x00800000
+ #define UNKNOWN4 0x01000000
+ #define UNKNOWN5 0x02000000
+ #define UNKNOWN6 0x04000000
+ #define UNKNOWN7 0x08000000
+ #define UNKNOWN8 0x10000000
+ #define NEGOTIATE_128 0x20000000
+ #define KEY_EXCHANGE 0x40000000
+ #define UNKNOWN9 0x80000000
+
struct ntlm_msg1 {
unsigned char protocol[8];
unsigned char type; /* 1 */
unsigned char zero1[3];
! unsigned char flags[4];
unsigned char dom_len[4];
unsigned char dom_off[4];
***************
*** 39,51 ****
} __attribute__((packed));
! struct ntlm_msg2 {
unsigned char protocol[8];
unsigned char type; /* 2 */
unsigned char zero1[7];
unsigned char msg_len[4];
! unsigned char flags[2];
unsigned char zero2[2];
unsigned char nonce[8];
unsigned char zero3[8];
--- 71,96 ----
} __attribute__((packed));
! struct ntlm_msg2_bad {
unsigned char protocol[8];
unsigned char type; /* 2 */
unsigned char zero1[7];
unsigned char msg_len[4];
! unsigned char flags[4];
!
! unsigned char nonce[8];
! unsigned char zero3[8];
! } __attribute__((packed));
!
! struct ntlm_msg2 {
! unsigned char protocol[8];
! unsigned char type; /* 2 */
! unsigned char zero1[3];
! unsigned char dom_len[2];
! unsigned char dom_maxlen[2];
! unsigned char dom_offset[2];
unsigned char zero2[2];
+ unsigned char flags[4];
unsigned char nonce[8];
unsigned char zero3[8];
***************
*** 81,90 ****
unsigned char domain[MAX_DOMLEN + 1];
unsigned char lm[RESP_LEN];
unsigned char nt[RESP_LEN];
} ntlmssp_info_rec;
! #define little_endian_word(x) x[0] + (((unsigned)x[1]) << 8)
#define set_little_endian_word(x,y) x[0]=(y&0xff);x[1]=(y>>8)
static int
ntlm_msg_type(unsigned char *raw_msg, unsigned msglen)
--- 126,140 ----
unsigned char domain[MAX_DOMLEN + 1];
unsigned char lm[RESP_LEN];
unsigned char nt[RESP_LEN];
+ int nt_resp_actual_len;
+ unsigned char msg1_flags[4];
} ntlmssp_info_rec;
+
+ void dump_flags(request_rec *r, char *p);
! #define little_endian_word(x) (x[0] + (((unsigned)x[1]) << 8))
#define set_little_endian_word(x,y) x[0]=(y&0xff);x[1]=(y>>8)
+ #define set_little_endian_dword(x,y) x[0]=(char)((y)&0xff);x[1]=(char)(((y)>>8)&0xff);x[2]=(char)(((y)>>16)&0xff);x[3]=(char)(((y)>>24)&0xff)
static int
ntlm_msg_type(unsigned char *raw_msg, unsigned msglen)
***************
*** 99,104 ****
--- 149,162 ----
}
static int
+ ntlm_extract_dword(request_rec * r, char *raw_msg, int msg_len, int offset, int *result)
+ {
+ if ( msg_len < offset + 1 )
+ return 1;
+ *result = raw_msg[offset] + (raw_msg[offset+1] << 8);
+ return 0;
+ }
+
ntlm_extract_mem(request_rec * r, unsigned char *dst,
unsigned char *src, unsigned srclen,
unsigned char *off, unsigned char *len,
***************
*** 126,131 ****
--- 184,190 ----
{
unsigned o = little_endian_word(off);
unsigned l = little_endian_word(len);
+ ap_log_rerror(APLOG_MARK, NTLM_DEBUG, r, "ntlm_extract_string(): srclen (%u), off (0x%02x%02x), len (0x%02x%02x), l (%u), max (%u)", srclen, off[1], off[0], len[1], len[0], l, max);
if (l > max)
return -1;
if (o >= srclen)
***************
*** 140,145 ****
--- 199,213 ----
}
static int
+ ntlm_encode_unicode(char *str, char *result)
+ {
+ int i;
+ bzero(result, strlen(str) * 2);
+ for (i=0; i<strlen(str); i++)
+ result[i*2] = str[i];
+ }
+
+ static int
ntlm_extract_unicode(request_rec * r, unsigned char *dst,
unsigned char *src, unsigned srclen,
unsigned char *off, unsigned char *len,
***************
*** 147,166 ****
{
unsigned o = little_endian_word(off);
unsigned l = little_endian_word(len) / 2; /* Unicode! */
! if (l > max)
return -1;
! if (o >= srclen)
return -1;
! if (o + l > srclen)
return -1;
src += o;
while (l > 0) {
/* Unicode to ASCII */
*dst++ = *src;
src += 2;
! l -= 2;
}
*dst = 0;
return 0;
}
--- 215,246 ----
{
unsigned o = little_endian_word(off);
unsigned l = little_endian_word(len) / 2; /* Unicode! */
!
! /* debug
! ap_log_rerror(APLOG_MARK, NTLM_DEBUG, r, "ntlm_extract_unicode(): srclen (%u), off (0x%02x%02x), len (0x%02x%02x), l (%u), max (%u)", srclen, off[1], off[0], len[1], len[0], l, max);
! */
!
! if (l > max) {
! ap_log_rerror(APLOG_MARK, NTLM_DEBUG, r, "ntlm_extract_unicode(): length (%u) > max (%u)", l, max);
return -1;
! }
! if (o >= srclen) {
! ap_log_rerror(APLOG_MARK, NTLM_DEBUG, r, "ntlm_extract_unicode(): offset (%u) >= source length (%u)", o, srclen);
return -1;
! }
! if (o + l > srclen) {
! ap_log_rerror(APLOG_MARK, NTLM_DEBUG, r, "ntlm_extract_unicode(): offset (%u) + length (%u) > source length (%u)", o, l, srclen);
return -1;
+ }
src += o;
while (l > 0) {
/* Unicode to ASCII */
*dst++ = *src;
src += 2;
! l -= 1; /* was 2, back when the little_endian_word macro above was broken... */
}
*dst = 0;
+
return 0;
}
***************
*** 172,178 ****
if (ntlm_extract_string(r, hostname, (char *) msg, msglen,
msg->host_off, msg->host_len, MAX_HOSTLEN))
return 1;
! ap_log_rerror(APLOG_MARK, NTLM_DEBUG, r, "got hostname %s", hostname);
return 0;
}
--- 252,258 ----
if (ntlm_extract_string(r, hostname, (char *) msg, msglen,
msg->host_off, msg->host_len, MAX_HOSTLEN))
return 1;
! ap_log_rerror(APLOG_MARK, NTLM_DEBUG, r, "got hostname '%s'", hostname);
return 0;
}
***************
*** 185,195 ****
msglen, msg->dom_off, msg->dom_len, MAX_DOMLEN))
return 2;
! ap_log_rerror(APLOG_MARK, NTLM_DEBUG, r, "got domainname %s", domainname);
return 0;
}
static int
ntlm_msg3_getlm(request_rec * r, unsigned char *raw_msg, unsigned msglen,
unsigned char *lm)
{
--- 265,304 ----
msglen, msg->dom_off, msg->dom_len, MAX_DOMLEN))
return 2;
! ap_log_rerror(APLOG_MARK, NTLM_DEBUG, r, "got domainname '%s'", domainname);
return 0;
}
static int
+ ntlm_msg1_getflags(request_rec * r, unsigned char *raw_msg,
+ unsigned msglen, unsigned char *flags)
+ {
+ struct ntlm_msg1 *msg = (struct ntlm_msg1 *) raw_msg;
+
+ memcpy(flags, msg->flags, 4);
+
+ ap_log_rerror(APLOG_MARK, NTLM_DEBUG, r, "got flags '%02x%02x%02x%02x'",
+ flags[3], flags[2], flags[1], flags[0]);
+ dump_flags(r, flags);
+
+ return 0;
+ }
+
+ /* debug for next two */
+ void
+ dump_mem_hex(request_rec * r, unsigned char *srcp, unsigned cnt) {
+ int i;
+ int outsize=cnt*2+1;
+ char out[outsize];
+ char * outp = out;
+ for (i=0; i<cnt; i++) {
+ snprintf(outp, 3, "%02x", srcp[i]);
+ outp+=2;
+ }
+ ap_log_rerror(APLOG_MARK, NTLM_DEBUG, r, " mem: %s", out);
+ }
+
+ static int
ntlm_msg3_getlm(request_rec * r, unsigned char *raw_msg, unsigned msglen,
unsigned char *lm)
{
***************
*** 199,204 ****
--- 308,314 ----
return 4;
ap_log_rerror(APLOG_MARK, NTLM_DEBUG, r, "Getting lm hash");
+ dump_mem_hex(r, lm, little_endian_word(msg->lm_len));
return 0;
}
***************
*** 209,217 ****
struct ntlm_msg3 *msg = (struct ntlm_msg3 *) raw_msg;
if (ntlm_extract_mem(r, nt, (char *) msg, msglen, msg->nt_off,
msg->nt_len, RESP_LEN))
! return 8;
! ap_log_rerror(APLOG_MARK, NTLM_DEBUG, r, "Getting nt hash");
return 0;
}
--- 319,329 ----
struct ntlm_msg3 *msg = (struct ntlm_msg3 *) raw_msg;
if (ntlm_extract_mem(r, nt, (char *) msg, msglen, msg->nt_off,
msg->nt_len, RESP_LEN))
! return 0;
! // return 8;
! ap_log_rerror(APLOG_MARK, NTLM_DEBUG, r, "Getting nt hash:");
! dump_mem_hex(r, nt, little_endian_word(msg->nt_len));
return 0;
}
***************
*** 229,234 ****
--- 341,357 ----
}
static int
+ ntlm_msg3_getntlen(request_rec * r, unsigned char *raw_msg,
+ unsigned msglen, int *ntlen)
+ {
+ if (ntlm_extract_dword(r, raw_msg, msglen, 20, ntlen))
+ return 32;
+
+ ap_log_rerror(APLOG_MARK, NTLM_DEBUG, r, "got nt len %d", *ntlen);
+ return 0;
+ }
+
+ static int
ntlm_msg3_gethostname(request_rec * r, unsigned char *raw_msg, unsigned msglen,
unsigned char *hostname)
{
***************
*** 237,242 ****
--- 360,367 ----
msg->host_off, msg->host_len, MAX_HOSTLEN))
return 0; /* this one FAILS, but since the value is not used,
* we just pretend it was ok. */
+
+ ap_log_rerror(APLOG_MARK, NTLM_DEBUG, r, "got hostname %s", hostname);
return 0;
}
***************
*** 248,286 ****
if (ntlm_extract_unicode(r, domainname, (char *) msg, msglen,
msg->dom_off, msg->dom_len, MAX_DOMLEN))
return 64;
return 0;
}
static int
ntlm_decode_msg(request_rec * r, struct ntlmssp_info *info,
unsigned char *raw_msg, unsigned msglen)
{
! ap_log_rerror(APLOG_MARK, NTLM_DEBUG, r,
! "Decoding auth message type %d",
! ntlm_msg_type(raw_msg, msglen));
! switch (info->msg_type = ntlm_msg_type(raw_msg, msglen)) {
case 1:
! return ntlm_msg1_gethostname(r, raw_msg, msglen, info->host)
! + ntlm_msg1_getdomainname(r, raw_msg, msglen, info->domain);
case 3:
! return ntlm_msg3_getlm(r, raw_msg, msglen, info->lm)
+ ntlm_msg3_getnt(r, raw_msg, msglen, info->nt)
+ ntlm_msg3_getusername(r, raw_msg, msglen, info->user)
+ ntlm_msg3_gethostname(r, raw_msg, msglen, info->host)
+ ntlm_msg3_getdomainname(r, raw_msg, msglen, info->domain);
}
return -1;
}
static int
! ntlm_encode_msg2(unsigned char *nonce, struct ntlm_msg2 *msg)
{
memset(msg, 0, sizeof(struct ntlm_msg2));
strcpy(msg->protocol, "NTLMSSP");
msg->type = 0x02;
! set_little_endian_word(msg->msg_len, sizeof(struct ntlm_msg2));
! set_little_endian_word(msg->flags, 0x8201);
memcpy(msg->nonce, nonce, sizeof(msg->nonce));
return 0;
}
--- 373,495 ----
if (ntlm_extract_unicode(r, domainname, (char *) msg, msglen,
msg->dom_off, msg->dom_len, MAX_DOMLEN))
return 64;
+
+ ap_log_rerror(APLOG_MARK, NTLM_DEBUG, r, "got domainname %s", domainname);
+ return 0;
+ }
+
+ static int
+ ntlm_msg3_getusername_ascii(request_rec * r, unsigned char *raw_msg,
+ unsigned msglen, unsigned char *username)
+ {
+ struct ntlm_msg3 *msg = (struct ntlm_msg3 *) raw_msg;
+ if (ntlm_extract_string(r, username, (char *) msg, msglen,
+ msg->user_off, msg->user_len, MAX_USERLEN))
+ return 16;
+
+ ap_log_rerror(APLOG_MARK, NTLM_DEBUG, r, "got username %s", username);
+ return 0;
+ }
+
+ static int
+ ntlm_msg3_gethostname_ascii(request_rec * r, unsigned char *raw_msg, unsigned msglen,
+ unsigned char *hostname)
+ {
+ struct ntlm_msg3 *msg = (struct ntlm_msg3 *) raw_msg;
+ if (ntlm_extract_string(r, hostname, (char *) msg, msglen,
+ msg->host_off, msg->host_len, MAX_HOSTLEN))
+ return 0; /* this one FAILS, but since the value is not used,
+ * we just pretend it was ok. */
+
+ ap_log_rerror(APLOG_MARK, NTLM_DEBUG, r, "got hostname %s", hostname);
+ return 0;
+ }
+
+ static int
+ ntlm_msg3_getdomainname_ascii(request_rec * r, unsigned char *raw_msg,
+ unsigned msglen, unsigned char *domainname)
+ {
+ struct ntlm_msg3 *msg = (struct ntlm_msg3 *) raw_msg;
+ if (ntlm_extract_string(r, domainname, (char *) msg, msglen,
+ msg->dom_off, msg->dom_len, MAX_DOMLEN))
+ return 64;
+
+ ap_log_rerror(APLOG_MARK, NTLM_DEBUG, r, "got domainname %s", domainname);
return 0;
}
+ unsigned long
+ test_flags(unsigned long test, char *flags)
+ {
+ return ( test & (flags[0] + (flags[1]<<8) + (flags[2]<<16) + (flags[3]<<24)));
+ }
+
static int
ntlm_decode_msg(request_rec * r, struct ntlmssp_info *info,
unsigned char *raw_msg, unsigned msglen)
{
! int type = ntlm_msg_type(raw_msg, msglen);
!
! info->msg_type = type;
! switch (info->msg_type) {
case 1:
! return
! ntlm_msg1_gethostname(r, raw_msg, msglen, info->host)
! + ntlm_msg1_getdomainname(r, raw_msg, msglen, info->domain)
! + ntlm_msg1_getflags(r, raw_msg, msglen, info->msg1_flags);
case 3:
! ntlm_msg3_getntlen(r, raw_msg, msglen, &(info->nt_resp_actual_len));
! dump_flags(r, info->msg1_flags);
! return
! ntlm_msg3_getlm(r, raw_msg, msglen, info->lm)
+ ntlm_msg3_getnt(r, raw_msg, msglen, info->nt)
+ + ntlm_msg3_getusername_ascii(r, raw_msg, msglen, info->user)
+ + ntlm_msg3_gethostname_ascii(r, raw_msg, msglen, info->host)
+ + ntlm_msg3_getdomainname_ascii(r, raw_msg, msglen, info->domain);
+ // ap_log_rerror(APLOG_MARK, NTLM_DEBUG, r, "LEN %d NTH %s LMH %s", info->nt_resp_actual_len, info->nt , info->lm);
+ /* This is broken if the browser is only able to send UNICODE (need to keep some state from msg2) */
+ /* return
+ ntlm_msg3_getlm(r, raw_msg, msglen, info->lm)
+ + ntlm_msg3_getnt(r, raw_msg, msglen, info->nt)
+ ntlm_msg3_getusername(r, raw_msg, msglen, info->user)
+ ntlm_msg3_gethostname(r, raw_msg, msglen, info->host)
+ ntlm_msg3_getdomainname(r, raw_msg, msglen, info->domain);
+ */
}
return -1;
}
+ void
+ dump_flags(request_rec *r, char *flags)
+ {
+ unsigned long ulflags = flags[0] + (flags[1]<<8) + (flags[2]<<16) + (flags[3]<<24);
+ ap_log_rerror(APLOG_MARK, NTLM_DEBUG, r, "raw ul flags: %08lx", ulflags);
+ ap_log_rerror(APLOG_MARK, NTLM_DEBUG, r, "%sUNICODE", ulflags & UNICODE ? "" : "NO_");
+ ap_log_rerror(APLOG_MARK, NTLM_DEBUG, r, "%sASCII", ulflags & ASCII ? "" : "NO_");
+ ap_log_rerror(APLOG_MARK, NTLM_DEBUG, r, "%sREQUEST_TARGET", ulflags & REQUEST_TARGET ? "" : "NO_");
+ ap_log_rerror(APLOG_MARK, NTLM_DEBUG, r, "%sUSE_LM", ulflags & USE_LM ? "" : "NO_");
+ ap_log_rerror(APLOG_MARK, NTLM_DEBUG, r, "%sUSE_NTLM", ulflags & USE_NTLM ? "" : "NO_");
+ ap_log_rerror(APLOG_MARK, NTLM_DEBUG, r, "%sDOMAIN_SUPPLIED", ulflags & DOMAIN_SUPPLIED ? "" : "NO_");
+ ap_log_rerror(APLOG_MARK, NTLM_DEBUG, r, "%sWORKSTATION_SUPPLIED", ulflags & WORKSTATION_SUPPLIED ? "" : "NO_");
+ ap_log_rerror(APLOG_MARK, NTLM_DEBUG, r, "%sALWAYS_SIGN", ulflags & ALWAYS_SIGN ? "" : "NO_");
+ ap_log_rerror(APLOG_MARK, NTLM_DEBUG, r, "%sNTLM2", ulflags & NTLM2 ? "" : "NO_");
+ ap_log_rerror(APLOG_MARK, NTLM_DEBUG, r, "%sNON_NT_SESSION_KEY", ulflags & NON_NT_SESSION_KEY ? "" : "NO_");
+ ap_log_rerror(APLOG_MARK, NTLM_DEBUG, r, "%sHIGHEST_BIT", ulflags & UNKNOWN9 ? "" : "NO_");
+ }
+
static int
! ntlm_encode_msg2(request_rec *r, unsigned char *nonce, struct ntlm_msg2 *msg, ntlmssp_info_rec *ntlmssp)
{
memset(msg, 0, sizeof(struct ntlm_msg2));
strcpy(msg->protocol, "NTLMSSP");
msg->type = 0x02;
! set_little_endian_word(msg->dom_len, 0);
! set_little_endian_word(msg->dom_maxlen, 0);
! set_little_endian_word(msg->dom_offset, 0);
!
! set_little_endian_dword(msg->flags,ASCII|USE_LM|USE_NTLM|ALWAYS_SIGN|TARGET_DOMAIN|REQUEST_TARGET); // 0x00018286
!
memcpy(msg->nonce, nonce, sizeof(msg->nonce));
return 0;
}
Index: mod_ntlm_winbind.c
===================================================================
RCS file: /usr/cvsroot/source/packages/www/mod_ntlm_winbind/D/mod_ntlm_winbind.c,v
*** mod_ntlm_winbind.c 2002/10/23 17:53:12
--- mod_ntlm_winbind.c 2004/08/05 15:53:48
***************
*** 138,143 ****
--- 138,160 ----
{ NULL }
};
+ void
+ dump_ntlmssp_rec(request_rec *r, ntlmssp_info_rec *info)
+ {
+ ap_log_rerror(APLOG_MARK, NTLM_DEBUG, r,
+ "dump_ntlmssp_rec(): info struct\t%d", info);
+ ap_log_rerror(APLOG_MARK, NTLM_DEBUG, r,
+ "dump_ntlmssp_rec(): type\t%d", info->msg_type);
+ ap_log_rerror(APLOG_MARK, NTLM_DEBUG, r,
+ "dump_ntlmssp_rec(): user\t%s", info->user);
+ ap_log_rerror(APLOG_MARK, NTLM_DEBUG, r,
+ "dump_ntlmssp_rec(): host\t%s", info->host);
+ ap_log_rerror(APLOG_MARK, NTLM_DEBUG, r,
+ "dump_ntlmssp_rec(): domain\t%s", info->domain);
+ ap_log_rerror(APLOG_MARK, NTLM_DEBUG, r,
+ "dump_ntlmssp_rec(): actual nt len\t%d", info->nt_resp_actual_len);
+ }
+
/* Base 64 encode/decode wrapper functions */
static void *
***************
*** 179,188 ****
line = ap_pstrdup(r->pool, NTLM_AUTH_NAME);
- #ifdef WIN9X_TEST
- ap_table_set(r->err_headers_out, "WWW-Authenticate", "Negotiate");
- #endif
-
ap_table_add(r->err_headers_out,
r->proxyreq ? "Proxy-Authenticate" : "WWW-Authenticate",
line);
--- 196,201 ----
***************
*** 213,219 ****
#define RANDOM_DEV "/dev/urandom"
static int
! send_ntlm_challenge(request_rec * r, ntlm_config_rec * crec)
{
struct ntlm_msg2 msg;
unsigned char *challenge;
--- 226,232 ----
#define RANDOM_DEV "/dev/urandom"
static int
! send_ntlm_challenge(request_rec * r, ntlm_config_rec * crec, ntlmssp_info_rec *ntlmssp)
{
struct ntlm_msg2 msg;
unsigned char *challenge;
***************
*** 255,263 ****
/* Encode and send message */
! ntlm_encode_msg2(ntlm_connection->nonce, &msg);
challenge = uuencode_binary(r->pool, (unsigned char *) &msg, sizeof(msg));
ap_table_setn(r->err_headers_out,
r->proxyreq ? "Proxy-Authenticate" : "WWW-Authenticate",
--- 268,278 ----
/* Encode and send message */
! ntlm_encode_msg2(r, ntlm_connection->nonce, &msg, ntlmssp);
challenge = uuencode_binary(r->pool, (unsigned char *) &msg, sizeof(msg));
+ ap_table_setn(r->err_headers_out,
+ "Content-Length" , "0");
ap_table_setn(r->err_headers_out,
r->proxyreq ? "Proxy-Authenticate" : "WWW-Authenticate",
***************
*** 296,301 ****
--- 311,319 ----
foo);
return NULL;
}
+ ap_log_rerror(APLOG_MARK, NTLM_DEBUG, r,
+ "get_ntlm_header(): type: %d, host: \"%s\", user: \"%s\", domain: \"%s\"",
+ ntlmssp->msg_type, ntlmssp->host, ntlmssp->user, ntlmssp->domain);
return ntlmssp;
}
***************
*** 303,309 ****
/* Call winbind to authenticate a (user, domain, lm response, nt response)
tuple. */
! static NSS_STATUS winbind_authenticate_ntlm(ntlmssp_info_rec *ntlmssp)
{
struct winbindd_request request;
struct winbindd_response response;
--- 321,327 ----
/* Call winbind to authenticate a (user, domain, lm response, nt response)
tuple. */
! static NSS_STATUS winbind_authenticate_ntlm(ntlmssp_info_rec *ntlmssp, request_rec * r)
{
struct winbindd_request request;
struct winbindd_response response;
***************
*** 312,331 ****
ZERO_STRUCT(request);
ZERO_STRUCT(response);
! /* Fill request with DOMAIN\username, challenge and responses */
ap_snprintf(request.data.auth_crap.user,
! sizeof(request.data.auth_crap.user) - 1, "%s\\%s",
! ntlmssp->domain, ntlmssp->user);
memcpy(request.data.auth_crap.chal, ntlm_connection->nonce, 8);
memcpy(request.data.auth_crap.lm_resp, ntlmssp->lm, RESP_LEN);
- memcpy(request.data.auth_crap.nt_resp, ntlmssp->nt, RESP_LEN);
-
request.data.auth_crap.lm_resp_len = RESP_LEN;
- request.data.auth_crap.nt_resp_len = RESP_LEN;
/* Send request */
return winbindd_request(WINBINDD_PAM_AUTH_CRAP, &request, &response);
--- 330,354 ----
ZERO_STRUCT(request);
ZERO_STRUCT(response);
! /* Fill request with challenge and responses */
ap_snprintf(request.data.auth_crap.user,
! sizeof(request.data.auth_crap.user) - 1, "%s", ntlmssp->user);
! ap_snprintf(request.data.auth_crap.domain,
! sizeof(request.data.auth_crap.domain) - 1, "%s", ntlmssp->domain);
memcpy(request.data.auth_crap.chal, ntlm_connection->nonce, 8);
memcpy(request.data.auth_crap.lm_resp, ntlmssp->lm, RESP_LEN);
request.data.auth_crap.lm_resp_len = RESP_LEN;
+ /* 9X doesn't send NT response hash */
+ if ( ntlmssp->nt_resp_actual_len ) {
+ memcpy(request.data.auth_crap.nt_resp, ntlmssp->nt, ntlmssp->nt_resp_actual_len );
+ request.data.auth_crap.nt_resp_len = ntlmssp->nt_resp_actual_len;
+ } else
+ request.data.auth_crap.nt_resp_len = 0;
+
/* Send request */
return winbindd_request(WINBINDD_PAM_AUTH_CRAP, &request, &response);
***************
*** 487,493 ****
ZERO_STRUCT(response);
ap_snprintf(request.data.username, sizeof(request.data.username) - 1,
! "%s\\%s", ntlm_connection->domain, ntlm_connection->user);
result = winbindd_request(WINBINDD_GETGROUPS, &request, &response);
--- 510,518 ----
ZERO_STRUCT(response);
ap_snprintf(request.data.username, sizeof(request.data.username) - 1,
! "%s", ntlm_connection->user);
! ap_snprintf(request.domain_name, sizeof(request.domain_name) - 1,
! "%s", ntlm_connection->domain);
result = winbindd_request(WINBINDD_GETGROUPS, &request, &response);
***************
*** 537,544 ****
"silent reauthentication");
/* silently accept login with same credentials */
! r->connection->user = ap_pstrdup(r->connection->pool,
! ntlm_connection->user);
r->connection->ap_auth_type = ap_pstrdup(r->connection->pool,
NTLM_AUTH_NAME);
return OK;
--- 562,571 ----
"silent reauthentication");
/* silently accept login with same credentials */
! //r->connection->user = ap_pstrdup(r->connection->pool,
! // ntlm_connection->user);
! r->connection->user = ap_psprintf(r->connection->pool,"%s\\%s",
! ntlm_connection->domain,ntlm_connection->user);
r->connection->ap_auth_type = ap_pstrdup(r->connection->pool,
NTLM_AUTH_NAME);
return OK;
***************
*** 552,560 ****
ntlm_connection->password = ap_pcalloc(r->connection->pool, RESP_LEN);
memcpy(ntlm_connection->password, ntlmssp->nt, RESP_LEN);
! /* Send authenication request to winbind */
! result = winbind_authenticate_ntlm(ntlmssp);
ap_log_rerror(APLOG_MARK, NTLM_DEBUG, r, "winbind authenticate: %s",
wb_error(result));
--- 579,587 ----
ntlm_connection->password = ap_pcalloc(r->connection->pool, RESP_LEN);
memcpy(ntlm_connection->password, ntlmssp->nt, RESP_LEN);
! /* Send authentication request to winbind */
! result = winbind_authenticate_ntlm(ntlmssp, r);
ap_log_rerror(APLOG_MARK, NTLM_DEBUG, r, "winbind authenticate: %s",
wb_error(result));
***************
*** 572,578 ****
return HTTP_UNAUTHORIZED;
}
! /* Now check user is authorised to use the service */
result = winbind_authorise(r, crec, ntlmssp);
--- 599,605 ----
return HTTP_UNAUTHORIZED;
}
! /* Now check user is authorised to use the service *
result = winbind_authorise(r, crec, ntlmssp);
***************
*** 588,595 ****
ntlm_connection->auth_ok = 1;
! r->connection->user = ap_pstrdup(r->connection->pool,
! ntlm_connection->user);
r->connection->ap_auth_type = ap_pstrdup(r->connection->pool,
NTLM_AUTH_NAME);
--- 615,624 ----
ntlm_connection->auth_ok = 1;
! //r->connection->user = ap_pstrdup(r->connection->pool,
! // ntlm_connection->user);
! r->connection->user = ap_psprintf(r->connection->pool,"%s\\%s",
! ntlm_connection->domain,ntlm_connection->user);
r->connection->ap_auth_type = ap_pstrdup(r->connection->pool,
NTLM_AUTH_NAME);
***************
*** 624,634 ****
return HTTP_UNAUTHORIZED;
}
/* Handle message */
switch (ntlmssp->msg_type) {
case 1:
! return send_ntlm_challenge(r, crec);
case 3:
return ntlm_check_response(r, crec, ntlmssp);
}
--- 653,668 ----
return HTTP_UNAUTHORIZED;
}
+ if (ntlmssp->msg_type == 3 && ! ntlm_connection->sent_challenge ) {
+ ap_log_rerror(APLOG_MARK, NTLM_DEBUG, r, "BAD REQUEST [msg3 without msg1] %d %d", ntlmssp->msg_type, ntlm_connection);
+ return HTTP_BAD_REQUEST;
+ }
+
/* Handle message */
switch (ntlmssp->msg_type) {
case 1:
! return send_ntlm_challenge(r, crec, ntlmssp);
case 3:
return ntlm_check_response(r, crec, ntlmssp);
}
***************
*** 795,801 ****
/* Trust the authentication on an existing connection */
if (ntlm_connection && ntlm_connection->auth_ok) {
! r->connection->user = ntlm_connection->user;
r->connection->ap_auth_type = "NTLM";
return OK;
}
--- 829,837 ----
/* Trust the authentication on an existing connection */
if (ntlm_connection && ntlm_connection->auth_ok) {
! //r->connection->user = ntlm_connection->user;
! r->connection->user = ap_psprintf(r->connection->pool,"%s\\%s",
! ntlm_connection->domain,ntlm_connection->user);
r->connection->ap_auth_type = "NTLM";
return OK;
}
More information about the samba-technical
mailing list