---------------------
PatchSet 493 
Date: 2000/08/03 12:46:24
Author: kinkie
Branch: ntlm
Tag: (none) 
Log:
Third-party library, mostly extracted from Samba, with a few minor changes.

Members: 
	ntlm_auth_modules/NTLMSSP/smbval/Makefile.in:1.1->1.1.2.1 
	ntlm_auth_modules/NTLMSSP/smbval/byteorder.h:1.1->1.1.2.1 
	ntlm_auth_modules/NTLMSSP/smbval/config.h:1.1->1.1.2.1 
	ntlm_auth_modules/NTLMSSP/smbval/md4.c:1.1->1.1.2.1 
	ntlm_auth_modules/NTLMSSP/smbval/rfcnb-common.h:1.1->1.1.2.1 
	ntlm_auth_modules/NTLMSSP/smbval/rfcnb-error.h:1.1->1.1.2.1 
	ntlm_auth_modules/NTLMSSP/smbval/rfcnb-io.c:1.1->1.1.2.1 
	ntlm_auth_modules/NTLMSSP/smbval/rfcnb-io.h:1.1->1.1.2.1 
	ntlm_auth_modules/NTLMSSP/smbval/rfcnb-priv.h:1.1->1.1.2.1 
	ntlm_auth_modules/NTLMSSP/smbval/rfcnb-util.c:1.1->1.1.2.1 
	ntlm_auth_modules/NTLMSSP/smbval/rfcnb-util.h:1.1->1.1.2.1 
	ntlm_auth_modules/NTLMSSP/smbval/rfcnb.h:1.1->1.1.2.1 
	ntlm_auth_modules/NTLMSSP/smbval/session.c:1.1->1.1.2.1 
	ntlm_auth_modules/NTLMSSP/smbval/smbdes.c:1.1->1.1.2.1 
	ntlm_auth_modules/NTLMSSP/smbval/smbencrypt.c:1.1->1.1.2.1 
	ntlm_auth_modules/NTLMSSP/smbval/smblib-common.h:1.1->1.1.2.1 
	ntlm_auth_modules/NTLMSSP/smbval/smblib-priv.h:1.1->1.1.2.1 
	ntlm_auth_modules/NTLMSSP/smbval/smblib-util.c:1.1->1.1.2.1 
	ntlm_auth_modules/NTLMSSP/smbval/smblib.c:1.1->1.1.2.1 
	ntlm_auth_modules/NTLMSSP/smbval/smblib.h:1.1->1.1.2.1 
	ntlm_auth_modules/NTLMSSP/smbval/std-defines.h:1.1->1.1.2.1 
	ntlm_auth_modules/NTLMSSP/smbval/std-includes.h:1.1->1.1.2.1 
	ntlm_auth_modules/NTLMSSP/smbval/valid.c:1.1->1.1.2.1 
	ntlm_auth_modules/NTLMSSP/smbval/valid.h:1.1->1.1.2.1 

--- /dev/null	Wed Feb 14 00:44:43 2007
+++ squid/ntlm_auth_modules/NTLMSSP/smbval/Makefile.in	Wed Feb 14 00:45:14 2007
@@ -0,0 +1,49 @@
+# makefile for smblib
+# Type make system, where system is ULTRIX, DU, DECOSF1, Solaris etc
+
+prefix		= @prefix@
+exec_prefix	= @exec_prefix@
+exec_suffix	= @exec_suffix@
+top_srcdir	= @top_srcdir@
+bindir		= @bindir@
+srcdir		= @srcdir@
+VPATH		= @srcdir@
+
+CC              = @CC@
+MAKEDEPEND      = @MAKEDEPEND@
+INSTALL         = @INSTALL@
+INSTALL_BIN     = @INSTALL_PROGRAM@
+INSTALL_FILE    = @INSTALL_DATA@
+RANLIB          = @RANLIB@
+AC_CFLAGS       = @CFLAGS@
+LDFLAGS         = @LDFLAGS@
+XTRA_LIBS       = @XTRA_LIBS@
+RM              = @RM@
+AR		= @AR@
+
+CFLAGS		= $(AC_CFLAGS) $(INCLUDE) $(DEFINES)
+# CFLAGS = -fpic -g
+
+INCLUDES = smblib.h smblib-priv.h
+
+RFCNB = session.o rfcnb-util.o rfcnb-io.o
+
+OBJS = smblib.o smblib-util.o file.o smb-errors.o exper.o smblib-api.o smbencrypt.o smbdes.o md4.o
+
+VALIDATE = valid.o session.o rfcnb-util.o \
+           rfcnb-io.o smblib-util.o smblib.o smbencrypt.o smbdes.o md4.o
+
+.SUFFIXES: .c .o .h
+
+dummy: all
+
+smbvalid.a:	$(VALIDATE) 
+	$(AR) rcs smbvalid.a $(VALIDATE)
+
+all: smbvalid.a
+
+.c.o:	$(INCLUDES)
+
+clean:
+	$(RM) -f *.o smbvalid.a *~
+
--- /dev/null	Wed Feb 14 00:44:43 2007
+++ squid/ntlm_auth_modules/NTLMSSP/smbval/byteorder.h	Wed Feb 14 00:45:14 2007
@@ -0,0 +1,80 @@
+/* 
+   Unix SMB/Netbios implementation.
+   Version 1.9.
+   SMB Byte handling
+   Copyright (C) Andrew Tridgell 1992-1995
+   
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+   
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+   
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+/*
+   This file implements macros for machine independent short and 
+   int manipulation
+*/
+
+#undef CAREFUL_ALIGNMENT
+
+/* we know that the 386 can handle misalignment and has the "right" 
+   byteorder */
+#ifdef __i386__
+#define CAREFUL_ALIGNMENT 0
+#endif
+
+#ifndef CAREFUL_ALIGNMENT
+#define CAREFUL_ALIGNMENT 1
+#endif
+
+#define CVAL(buf,pos) (((unsigned char *)(buf))[pos])
+#define PVAL(buf,pos) ((unsigned)CVAL(buf,pos))
+#define SCVAL(buf,pos,val) (CVAL(buf,pos) = (val))
+
+
+#if CAREFUL_ALIGNMENT
+#define SVAL(buf,pos) (PVAL(buf,pos)|PVAL(buf,(pos)+1)<<8)
+#define IVAL(buf,pos) (SVAL(buf,pos)|SVAL(buf,(pos)+2)<<16)
+#define SSVALX(buf,pos,val) (CVAL(buf,pos)=(val)&0xFF,CVAL(buf,pos+1)=(val)>>8)
+#define SIVALX(buf,pos,val) (SSVALX(buf,pos,val&0xFFFF),SSVALX(buf,pos+2,val>>16))
+#define SVALS(buf,pos) ((int16)SVAL(buf,pos))
+#define IVALS(buf,pos) ((int32)IVAL(buf,pos))
+#define SSVAL(buf,pos,val) SSVALX((buf),(pos),((uint16)(val)))
+#define SIVAL(buf,pos,val) SIVALX((buf),(pos),((uint32)(val)))
+#define SSVALS(buf,pos,val) SSVALX((buf),(pos),((int16)(val)))
+#define SIVALS(buf,pos,val) SIVALX((buf),(pos),((int32)(val)))
+#else
+/* this handles things for architectures like the 386 that can handle
+   alignment errors */
+/*
+   WARNING: This section is dependent on the length of int16 and int32
+   being correct 
+*/
+#define SVAL(buf,pos) (*(uint16 *)((char *)(buf) + (pos)))
+#define IVAL(buf,pos) (*(uint32 *)((char *)(buf) + (pos)))
+#define SVALS(buf,pos) (*(int16 *)((char *)(buf) + (pos)))
+#define IVALS(buf,pos) (*(int32 *)((char *)(buf) + (pos)))
+#define SSVAL(buf,pos,val) SVAL(buf,pos)=((uint16)(val))
+#define SIVAL(buf,pos,val) IVAL(buf,pos)=((uint32)(val))
+#define SSVALS(buf,pos,val) SVALS(buf,pos)=((int16)(val))
+#define SIVALS(buf,pos,val) IVALS(buf,pos)=((int32)(val))
+#endif
+
+
+/* now the reverse routines - these are used in nmb packets (mostly) */
+#define SREV(x) ((((x)&0xFF)<<8) | (((x)>>8)&0xFF))
+#define IREV(x) ((SREV(x)<<16) | (SREV((x)>>16)))
+
+#define RSVAL(buf,pos) SREV(SVAL(buf,pos))
+#define RIVAL(buf,pos) IREV(IVAL(buf,pos))
+#define RSSVAL(buf,pos,val) SSVAL(buf,pos,SREV(val))
+#define RSIVAL(buf,pos,val) SIVAL(buf,pos,IREV(val))
--- /dev/null	Wed Feb 14 00:44:43 2007
+++ squid/ntlm_auth_modules/NTLMSSP/smbval/config.h	Wed Feb 14 00:45:14 2007
@@ -0,0 +1,5 @@
+/* Define to empty if the keyword does not work.  */
+/* #undef const */
+
+
+
--- /dev/null	Wed Feb 14 00:44:43 2007
+++ squid/ntlm_auth_modules/NTLMSSP/smbval/md4.c	Wed Feb 14 00:45:14 2007
@@ -0,0 +1,172 @@
+/* 
+   Unix SMB/Netbios implementation.
+   Version 1.9.
+   a implementation of MD4 designed for use in the SMB authentication protocol
+   Copyright (C) Andrew Tridgell 1997
+   
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+   
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+   
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+
+/* NOTE: This code makes no attempt to be fast! 
+
+   It assumes that a int is at least 32 bits long
+*/
+#include <string.h>
+
+typedef unsigned int uint32;
+
+static uint32 A, B, C, D;
+
+static uint32 F(uint32 X, uint32 Y, uint32 Z)
+{
+	return (X&Y) | ((~X)&Z);
+}
+
+static uint32 G(uint32 X, uint32 Y, uint32 Z)
+{
+	return (X&Y) | (X&Z) | (Y&Z); 
+}
+
+static uint32 H(uint32 X, uint32 Y, uint32 Z)
+{
+	return X^Y^Z;
+}
+
+static uint32 lshift(uint32 x, int s)
+{
+	x &= 0xFFFFFFFF;
+	return ((x<<s)&0xFFFFFFFF) | (x>>(32-s));
+}
+
+#define ROUND1(a,b,c,d,k,s) a = lshift(a + F(b,c,d) + X[k], s)
+#define ROUND2(a,b,c,d,k,s) a = lshift(a + G(b,c,d) + X[k] + (uint32)0x5A827999,s)
+#define ROUND3(a,b,c,d,k,s) a = lshift(a + H(b,c,d) + X[k] + (uint32)0x6ED9EBA1,s)
+
+/* this applies md4 to 64 byte chunks */
+static void mdfour64(uint32 *M)
+{
+	int j;
+	uint32 AA, BB, CC, DD;
+	uint32 X[16];
+
+	for (j=0;j<16;j++)
+		X[j] = M[j];
+
+	AA = A; BB = B; CC = C; DD = D;
+
+        ROUND1(A,B,C,D,  0,  3);  ROUND1(D,A,B,C,  1,  7);  
+	ROUND1(C,D,A,B,  2, 11);  ROUND1(B,C,D,A,  3, 19);
+        ROUND1(A,B,C,D,  4,  3);  ROUND1(D,A,B,C,  5,  7);  
+	ROUND1(C,D,A,B,  6, 11);  ROUND1(B,C,D,A,  7, 19);
+        ROUND1(A,B,C,D,  8,  3);  ROUND1(D,A,B,C,  9,  7);  
+	ROUND1(C,D,A,B, 10, 11);  ROUND1(B,C,D,A, 11, 19);
+        ROUND1(A,B,C,D, 12,  3);  ROUND1(D,A,B,C, 13,  7);  
+	ROUND1(C,D,A,B, 14, 11);  ROUND1(B,C,D,A, 15, 19);	
+
+        ROUND2(A,B,C,D,  0,  3);  ROUND2(D,A,B,C,  4,  5);  
+	ROUND2(C,D,A,B,  8,  9);  ROUND2(B,C,D,A, 12, 13);
+        ROUND2(A,B,C,D,  1,  3);  ROUND2(D,A,B,C,  5,  5);  
+	ROUND2(C,D,A,B,  9,  9);  ROUND2(B,C,D,A, 13, 13);
+        ROUND2(A,B,C,D,  2,  3);  ROUND2(D,A,B,C,  6,  5);  
+	ROUND2(C,D,A,B, 10,  9);  ROUND2(B,C,D,A, 14, 13);
+        ROUND2(A,B,C,D,  3,  3);  ROUND2(D,A,B,C,  7,  5);  
+	ROUND2(C,D,A,B, 11,  9);  ROUND2(B,C,D,A, 15, 13);
+
+	ROUND3(A,B,C,D,  0,  3);  ROUND3(D,A,B,C,  8,  9);  
+	ROUND3(C,D,A,B,  4, 11);  ROUND3(B,C,D,A, 12, 15);
+        ROUND3(A,B,C,D,  2,  3);  ROUND3(D,A,B,C, 10,  9);  
+	ROUND3(C,D,A,B,  6, 11);  ROUND3(B,C,D,A, 14, 15);
+        ROUND3(A,B,C,D,  1,  3);  ROUND3(D,A,B,C,  9,  9);  
+	ROUND3(C,D,A,B,  5, 11);  ROUND3(B,C,D,A, 13, 15);
+        ROUND3(A,B,C,D,  3,  3);  ROUND3(D,A,B,C, 11,  9);  
+	ROUND3(C,D,A,B,  7, 11);  ROUND3(B,C,D,A, 15, 15);
+
+	A += AA; B += BB; C += CC; D += DD;
+	
+	A &= 0xFFFFFFFF; B &= 0xFFFFFFFF;
+	C &= 0xFFFFFFFF; D &= 0xFFFFFFFF;
+
+	for (j=0;j<16;j++)
+		X[j] = 0;
+}
+
+static void copy64(uint32 *M, unsigned char *in)
+{
+	int i;
+
+	for (i=0;i<16;i++)
+		M[i] = (in[i*4+3]<<24) | (in[i*4+2]<<16) |
+			(in[i*4+1]<<8) | (in[i*4+0]<<0);
+}
+
+static void copy4(unsigned char *out,uint32 x)
+{
+	out[0] = x&0xFF;
+	out[1] = (x>>8)&0xFF;
+	out[2] = (x>>16)&0xFF;
+	out[3] = (x>>24)&0xFF;
+}
+
+/* produce a md4 message digest from data of length n bytes */
+void mdfour(unsigned char *out, unsigned char *in, int n)
+{
+	unsigned char buf[128];
+	uint32 M[16];
+	uint32 b = n * 8;
+	int i;
+
+	A = 0x67452301;
+	B = 0xefcdab89;
+	C = 0x98badcfe;
+	D = 0x10325476;
+
+	while (n > 64) {
+		copy64(M, in);
+		mdfour64(M);
+		in += 64;
+		n -= 64;
+	}
+
+	for (i=0;i<128;i++)
+		buf[i] = 0;
+	memcpy(buf, in, n);
+	buf[n] = 0x80;
+	
+	if (n <= 55) {
+		copy4(buf+56, b);
+		copy64(M, buf);
+		mdfour64(M);
+	} else {
+		copy4(buf+120, b); 
+		copy64(M, buf);
+		mdfour64(M);
+		copy64(M, buf+64);
+		mdfour64(M);
+	}
+
+	for (i=0;i<128;i++)
+		buf[i] = 0;
+	copy64(M, buf);
+
+	copy4(out, A);
+	copy4(out+4, B);
+	copy4(out+8, C);
+	copy4(out+12, D);
+
+	A = B = C = D = 0;
+}
+
+
--- /dev/null	Wed Feb 14 00:44:43 2007
+++ squid/ntlm_auth_modules/NTLMSSP/smbval/rfcnb-common.h	Wed Feb 14 00:45:14 2007
@@ -0,0 +1,36 @@
+/* UNIX RFCNB (RFC1001/RFC1002) NetBIOS implementation
+
+   Version 1.0
+   RFCNB Common Structures etc Defines
+
+   Copyright (C) Richard Sharpe 1996
+
+*/
+
+/*
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+   
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+   
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+/* A data structure we need */
+
+typedef struct RFCNB_Pkt {
+
+  char * data;			/* The data in this portion */
+  int len;
+  struct RFCNB_Pkt *next;
+
+} RFCNB_Pkt;
+
+
--- /dev/null	Wed Feb 14 00:44:43 2007
+++ squid/ntlm_auth_modules/NTLMSSP/smbval/rfcnb-error.h	Wed Feb 14 00:45:14 2007
@@ -0,0 +1,75 @@
+/* UNIX RFCNB (RFC1001/RFC1002) NetBIOS implementation
+
+   Version 1.0
+   RFCNB Error Response Defines
+
+   Copyright (C) Richard Sharpe 1996
+
+*/
+
+/*
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+   
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+   
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+/* Error responses */
+
+#define RFCNBE_Bad -1          /* Bad response */
+#define RFCNBE_OK 0
+
+/* these should follow the spec ... is there one ?*/
+
+#define RFCNBE_NoSpace 1       /* Could not allocate space for a struct */
+#define RFCNBE_BadName 2       /* Could not translate a name            */
+#define RFCNBE_BadRead 3       /* Read sys call failed                  */
+#define RFCNBE_BadWrite 4      /* Write Sys call failed                 */
+#define RFCNBE_ProtErr 5       /* Protocol Error                        */
+#define RFCNBE_ConGone 6       /* Connection dropped                    */
+#define RFCNBE_BadHandle 7     /* Handle passed was bad                 */
+#define RFCNBE_BadSocket 8     /* Problems creating socket              */
+#define RFCNBE_ConnectFailed 9 /* Connect failed                        */
+#define RFCNBE_CallRejNLOCN 10 /* Call rejected, not listening on CN    */
+#define RFCNBE_CallRejNLFCN 11 /* Call rejected, not listening for CN   */
+#define RFCNBE_CallRejCNNP  12 /* Call rejected, called name not present */
+#define RFCNBE_CallRejInfRes 13/* Call rejetced, name ok, no resources   */
+#define RFCNBE_CallRejUnSpec 14/* Call rejected, unspecified error      */
+#define RFCNBE_BadParam      15/* Bad parameters passed ...             */
+#define RFCNBE_Timeout       16/* IO Timed out                          */
+
+/* Text strings for the error responses                                 */
+
+static char *RFCNB_Error_Strings[] = {
+
+  "RFCNBE_OK: Routine completed successfully.",
+  "RFCNBE_NoSpace: No space available for a malloc call.",
+  "RFCNBE_BadName: NetBIOS name could not be translated to IP address.",
+  "RFCNBE_BadRead: Read system call returned an error. Check errno.",
+  "RFCNBE_BadWrite: Write system call returned an error. Check errno.",
+  "RFCNBE_ProtErr: A protocol error has occurred.",
+  "RFCNBE_ConGone: Connection dropped during a read or write system call.",
+  "RFCNBE_BadHandle: Bad connection handle passed.",
+  "RFCNBE_BadSocket: Problems creating socket.",
+  "RFCNBE_ConnectFailed: Connection failed. See errno.",
+  "RFCNBE_CallRejNLOCN: Call rejected. Not listening on called name.",
+  "RFCNBE_CallRejNLFCN: Call rejected. Not listening for called name.",
+  "RFCNBE_CallRejCNNP: Call rejected. Called name not present.",
+  "RFCNBE_CallRejInfRes: Call rejected. Name present, but insufficient resources.",
+  "RFCNBE_CallRejUnSpec: Call rejected. Unspecified error.",
+  "RFCNBE_BadParam: Bad parameters passed to a routine.",
+  "RFCNBE_Timeout: IO Operation timed out ..."
+
+};
+
+
+
--- /dev/null	Wed Feb 14 00:44:43 2007
+++ squid/ntlm_auth_modules/NTLMSSP/smbval/rfcnb-io.c	Wed Feb 14 00:45:14 2007
@@ -0,0 +1,409 @@
+/* UNIX RFCNB (RFC1001/RFC1002) NEtBIOS implementation
+
+   Version 1.0
+   RFCNB IO Routines ...
+
+   Copyright (C) Richard Sharpe 1996
+
+*/
+
+/*
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+   
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+   
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+/* #include <features.h> */
+#include "std-includes.h"
+#include "rfcnb-priv.h"
+#include "rfcnb-util.h"
+#include "rfcnb-io.h"
+#include <sys/uio.h>
+#include <sys/signal.h>
+#include <string.h>
+
+int RFCNB_Timeout = 0;    /* Timeout in seconds ... */
+
+void rfcnb_alarm(int sig)
+
+{
+
+  fprintf(stderr, "IO Timed out ...\n");
+
+}
+
+/* Set timeout value and setup signal handling */
+
+int RFCNB_Set_Timeout(int seconds)
+
+{
+  int temp;
+  /* If we are on a Bezerkeley system, use sigvec, else sigaction */
+#ifndef SA_RESTART
+  struct sigvec invec, outvec; 
+#else
+  struct sigaction inact, outact;
+#endif
+
+  RFCNB_Timeout = seconds;
+
+  if (RFCNB_Timeout > 0) { /* Set up handler to ignore but not restart */
+
+#ifndef SA_RESTART
+    invec.sv_handler = (void (*)())rfcnb_alarm;
+    invec.sv_mask = 0;
+    invec.sv_flags = SV_INTERRUPT;
+
+    if (sigvec(SIGALRM, &invec, &outvec)  < 0)
+      return(-1);
+#else
+    inact.sa_handler = (void (*)())rfcnb_alarm;
+    sigemptyset(&inact.sa_mask);
+    inact.sa_flags = 0;    /* Don't restart */
+
+    if (sigaction(SIGALRM, &inact, &outact) < 0)
+      return(-1);
+
+#endif
+
+  }
+
+  return(0);
+
+}
+
+/* Discard the rest of an incoming packet as we do not have space for it
+   in the buffer we allocated or were passed ...                         */
+
+int RFCNB_Discard_Rest(struct RFCNB_Con *con, int len)
+
+{ char temp[100];   /* Read into here */
+  int rest, this_read, bytes_read;
+
+  /* len is the amount we should read */
+
+#ifdef RFCNB_DEBUG
+  fprintf(stderr, "Discard_Rest called to discard: %i\n", len);
+#endif
+
+  rest = len;
+
+  while (rest > 0) {
+
+    this_read = (rest > sizeof(temp)?sizeof(temp):rest);
+
+    bytes_read = read(con -> fd, temp, this_read);
+
+    if (bytes_read <= 0) { /* Error so return */
+
+      if (bytes_read < 0) 
+	RFCNB_errno = RFCNBE_BadRead;
+      else
+	RFCNB_errno = RFCNBE_ConGone;
+
+      RFCNB_saved_errno = errno;
+      return(RFCNBE_Bad);
+
+    }
+    
+    rest = rest - bytes_read;
+
+  }
+
+  return(0);
+
+}
+
+
+/* Send an RFCNB packet to the connection.
+
+   We just send each of the blocks linked together ... 
+
+   If we can, try to send it as one iovec ... 
+
+*/
+
+int RFCNB_Put_Pkt(struct RFCNB_Con *con, struct RFCNB_Pkt *pkt, int len)
+
+{ int len_sent, tot_sent, this_len;
+  struct RFCNB_Pkt *pkt_ptr;
+  char *this_data;
+  int i;
+  struct iovec io_list[10];          /* We should never have more      */
+                                     /* If we do, this will blow up ...*/
+
+  /* Try to send the data ... We only send as many bytes as len claims */
+  /* We should try to stuff it into an IOVEC and send as one write     */
+
+
+  pkt_ptr = pkt;
+  len_sent =  tot_sent = 0;             /* Nothing sent so far */
+  i = 0;
+
+  while ((pkt_ptr != NULL) & (i < 10)) {  /* Watch that magic number! */
+
+    this_len = pkt_ptr -> len;
+    this_data = pkt_ptr -> data;
+    if ((tot_sent + this_len) > len) 
+      this_len = len - tot_sent;        /* Adjust so we don't send too much */
+
+    /* Now plug into the iovec ... */
+
+    io_list[i].iov_len = this_len;
+    io_list[i].iov_base = this_data;
+    i++;
+
+    tot_sent += this_len;
+
+    if (tot_sent == len) break;   /* Let's not send too much */
+
+    pkt_ptr = pkt_ptr -> next;
+
+  }
+
+#ifdef RFCNB_DEBUG
+  fprintf(stderr, "Frags = %i, tot_sent = %i\n", i, tot_sent);
+#endif
+
+  /* Set up an alarm if timeouts are set ... */
+
+  if (RFCNB_Timeout > 0) 
+    alarm(RFCNB_Timeout);
+
+  if ((len_sent = writev(con -> fd, io_list, i)) < 0) { /* An error */
+
+    con -> rfc_errno = errno;
+    if (errno == EINTR)  /* We were interrupted ... */
+      RFCNB_errno = RFCNBE_Timeout;
+    else
+      RFCNB_errno = RFCNBE_BadWrite;
+    RFCNB_saved_errno = errno;
+    return(RFCNBE_Bad);
+
+  }
+
+  if (len_sent < tot_sent) { /* Less than we wanted */
+    if (errno == EINTR)      /* We were interrupted */
+      RFCNB_errno = RFCNBE_Timeout;
+    else
+      RFCNB_errno = RFCNBE_BadWrite;
+    RFCNB_saved_errno = errno;
+    return(RFCNBE_Bad);
+  }
+
+  if (RFCNB_Timeout > 0)
+    alarm(0);                /* Reset that sucker */
+
+#ifdef RFCNB_DEBUG
+
+  fprintf(stderr, "Len sent = %i ...\n", len_sent);
+  RFCNB_Print_Pkt(stderr, "sent", pkt, len_sent); /* Print what send ... */
+
+#endif
+
+  return(len_sent);
+
+}
+
+/* Read an RFCNB packet off the connection. 
+
+   We read the first 4 bytes, that tells us the length, then read the
+   rest. We should implement a timeout, but we don't just yet 
+
+*/
+
+
+int RFCNB_Get_Pkt(struct RFCNB_Con *con, struct RFCNB_Pkt *pkt, int len)
+
+{ int read_len, pkt_len;
+  char hdr[RFCNB_Pkt_Hdr_Len];      /* Local space for the header */
+  struct RFCNB_Pkt *pkt_frag;
+  int more, this_time, offset, frag_len, this_len;
+  BOOL seen_keep_alive = TRUE;
+
+  /* Read that header straight into the buffer */
+
+  if (len < RFCNB_Pkt_Hdr_Len) { /* What a bozo */
+
+#ifdef RFCNB_DEBUG
+    fprintf(stderr, "Trying to read less than a packet:");
+    perror("");
+#endif
+    RFCNB_errno = RFCNBE_BadParam;
+    return(RFCNBE_Bad);
+
+  }
+
+  /* We discard keep alives here ... */
+
+  if (RFCNB_Timeout > 0) 
+    alarm(RFCNB_Timeout);
+
+  while (seen_keep_alive) {
+
+    if ((read_len = read(con -> fd, hdr, sizeof(hdr))) < 0) { /* Problems */
+#ifdef RFCNB_DEBUG
+      fprintf(stderr, "Reading the packet, we got:");
+      perror("");
+#endif
+      if (errno == EINTR)
+	RFCNB_errno = RFCNBE_Timeout;
+      else
+	RFCNB_errno = RFCNBE_BadRead;
+      RFCNB_saved_errno = errno;
+      return(RFCNBE_Bad);
+
+    }
+
+    /* Now we check out what we got */
+
+    if (read_len == 0) { /* Connection closed, send back eof?  */
+
+#ifdef RFCNB_DEBUG
+      fprintf(stderr, "Connection closed reading\n");
+#endif 
+
+      if (errno == EINTR) 
+	RFCNB_errno = RFCNBE_Timeout;
+      else
+	RFCNB_errno = RFCNBE_ConGone;
+      RFCNB_saved_errno = errno;
+      return(RFCNBE_Bad);
+
+    }
+
+    if (RFCNB_Pkt_Type(hdr) == RFCNB_SESSION_KEEP_ALIVE) {
+
+#ifdef RFCNB_DEBUG
+      fprintf(stderr, "RFCNB KEEP ALIVE received\n");
+#endif
+      
+    }
+    else {
+      seen_keep_alive = FALSE;
+    }
+
+  }
+ 
+  /* What if we got less than or equal to a hdr size in bytes? */
+
+  if (read_len < sizeof(hdr)) { /* We got a small packet */
+
+    /* Now we need to copy the hdr portion we got into the supplied packet */
+
+    memcpy(pkt -> data, hdr, read_len);  /*Copy data */
+
+#ifdef RFCNB_DEBUG
+    RFCNB_Print_Pkt(stderr, "rcvd", pkt, read_len);
+#endif
+
+    return(read_len);
+
+  }
+
+  /* Now, if we got at least a hdr size, alloc space for rest, if we need it */
+
+  pkt_len = RFCNB_Pkt_Len(hdr);
+
+#ifdef RFCNB_DEBUG
+  fprintf(stderr, "Reading Pkt: Length = %i\n", pkt_len);
+#endif  
+
+  /* Now copy in the hdr */
+
+  memcpy(pkt -> data, hdr, sizeof(hdr));
+
+  /* Get the rest of the packet ... first figure out how big our buf is? */
+  /* And make sure that we handle the fragments properly ... Sure should */
+  /* use an iovec ...                                                    */
+
+  if (len < pkt_len)            /* Only get as much as we have space for */
+    more = len - RFCNB_Pkt_Hdr_Len;
+  else
+    more = pkt_len;
+
+  this_time = 0;
+
+  /* We read for each fragment ... */
+
+  if (pkt -> len == read_len){     /* If this frag was exact size */
+    pkt_frag = pkt -> next;        /* Stick next lot in next frag */
+    offset = 0;                    /* then we start at 0 in next  */
+  }
+  else {
+    pkt_frag = pkt;                /* Otherwise use rest of this frag */
+    offset = RFCNB_Pkt_Hdr_Len;    /* Otherwise skip the header       */
+  }
+
+  frag_len = pkt_frag -> len;
+
+  if (more <= frag_len)     /* If len left to get less than frag space */
+    this_len = more;        /* Get the rest ...                        */
+  else
+    this_len = frag_len - offset;
+
+  while (more > 0) {
+
+    if ((this_time = read(con -> fd, (pkt_frag -> data) + offset, this_len)) <= 0) { /* Problems */
+
+      if (errno == EINTR) {
+
+	RFCNB_errno = RFCNB_Timeout;
+
+      }
+      else {
+	if (this_time < 0)
+	  RFCNB_errno = RFCNBE_BadRead;
+	else
+	  RFCNB_errno = RFCNBE_ConGone;
+      }
+
+      RFCNB_saved_errno = errno;
+      return(RFCNBE_Bad);
+
+    }
+
+#ifdef RFCNB_DEBUG
+    fprintf(stderr, "Frag_Len = %i, this_time = %i, this_len = %i, more = %i\n", frag_len,
+                    this_time, this_len, more);
+#endif
+
+    read_len = read_len + this_time;  /* How much have we read ... */
+
+    /* Now set up the next part */
+
+    if (pkt_frag -> next == NULL) break;       /* That's it here */
+
+    pkt_frag = pkt_frag -> next;
+    this_len = pkt_frag -> len;
+    offset = 0;
+
+    more = more - this_time;
+
+  }
+
+#ifdef RFCNB_DEBUG
+  fprintf(stderr,"Pkt Len = %i, read_len = %i\n", pkt_len, read_len);
+  RFCNB_Print_Pkt(stderr, "rcvd", pkt, read_len + sizeof(hdr));
+#endif
+
+  if (read_len < (pkt_len + sizeof(hdr))) {  /* Discard the rest */
+
+    return(RFCNB_Discard_Rest(con, (pkt_len + sizeof(hdr)) - read_len));
+
+  }
+
+  if (RFCNB_Timeout > 0)
+    alarm(0);                /* Reset that sucker */
+
+  return(read_len + sizeof(RFCNB_Hdr));
+}
--- /dev/null	Wed Feb 14 00:44:43 2007
+++ squid/ntlm_auth_modules/NTLMSSP/smbval/rfcnb-io.h	Wed Feb 14 00:45:14 2007
@@ -0,0 +1,28 @@
+/* UNIX RFCNB (RFC1001/RFC1002) NetBIOS implementation
+
+   Version 1.0
+   RFCNB IO Routines Defines
+
+   Copyright (C) Richard Sharpe 1996
+
+*/
+
+/*
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+   
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+   
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+int RFCNB_Put_Pkt(struct RFCNB_Con *con, struct RFCNB_Pkt *pkt, int len);
+
+int RFCNB_Get_Pkt(struct RFCNB_Con *con, struct RFCNB_Pkt *pkt, int len);
--- /dev/null	Wed Feb 14 00:44:43 2007
+++ squid/ntlm_auth_modules/NTLMSSP/smbval/rfcnb-priv.h	Wed Feb 14 00:45:14 2007
@@ -0,0 +1,151 @@
+/* UNIX RFCNB (RFC1001/RFC1002) NetBIOS implementation
+
+   Version 1.0
+   RFCNB Defines
+
+   Copyright (C) Richard Sharpe 1996
+
+*/
+
+/*
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+   
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+   
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+/* Defines we need */
+
+typedef unsigned short uint16;
+
+#define GLOBAL extern
+
+#include "rfcnb-error.h"
+#include "rfcnb-common.h"
+#include "byteorder.h"
+
+#ifdef RFCNB_PORT
+#define RFCNB_Default_Port RFCNB_PORT
+#else
+#define RFCNB_Default_Port 139
+#endif
+
+#define RFCNB_MAX_STATS 1
+
+/* Protocol defines we need */
+
+#define RFCNB_SESSION_MESSAGE 0
+#define RFCNB_SESSION_REQUEST 0x81
+#define RFCNB_SESSION_ACK 0x82
+#define RFCNB_SESSION_REJ 0x83
+#define RFCNB_SESSION_RETARGET 0x84
+#define RFCNB_SESSION_KEEP_ALIVE 0x85
+
+/* Structures      */
+
+typedef struct redirect_addr * redirect_ptr;
+
+struct redirect_addr {
+
+  struct in_addr ip_addr;
+  int port;
+  redirect_ptr next;
+
+};
+
+typedef struct RFCNB_Con {
+
+  int fd;                     /* File descripter for TCP/IP connection */
+  int rfc_errno;                  /* last error                            */
+  int timeout;		      /* How many milli-secs before IO times out */
+  int redirects;	      /* How many times we were redirected     */
+  struct redirect_addr *redirect_list;  /* First is first address */
+  struct redirect_addr *last_addr;
+
+} RFCNB_Con;
+
+typedef char RFCNB_Hdr[4]; /* The header is 4 bytes long with  */
+                                    /* char[0] as the type, char[1] the */
+			            /* flags, and char[2..3] the length */
+
+/* Macros to extract things from the header. These are for portability
+   between architecture types where we are worried about byte order     */
+
+#define RFCNB_Pkt_Hdr_Len        4
+#define RFCNB_Pkt_Sess_Len       72
+#define RFCNB_Pkt_Retarg_Len     10
+#define RFCNB_Pkt_Nack_Len       5
+#define RFCNB_Pkt_Type_Offset    0
+#define RFCNB_Pkt_Flags_Offset   1
+#define RFCNB_Pkt_Len_Offset     2   /* Length is 2 bytes plus a flag bit */
+#define RFCNB_Pkt_N1Len_Offset   4
+#define RFCNB_Pkt_Called_Offset  5
+#define RFCNB_Pkt_N2Len_Offset   38
+#define RFCNB_Pkt_Calling_Offset 39
+#define RFCNB_Pkt_Error_Offset   4
+#define RFCNB_Pkt_IP_Offset      4
+#define RFCNB_Pkt_Port_Offset    8
+
+/* The next macro isolates the length of a packet, including the bit in the
+   flags                                                                   */
+
+#define RFCNB_Pkt_Len(p)  (PVAL(p, 3) | (PVAL(p, 2) << 8) |     \
+                          ((PVAL(p, RFCNB_Pkt_Flags_Offset) & 0x01) << 16))
+
+#define RFCNB_Put_Pkt_Len(p, v) (p[1] = ((v >> 16) & 1)); \
+				(p[2] = ((v >> 8) & 0xFF)); \
+				(p[3] = (v & 0xFF));
+
+#define RFCNB_Pkt_Type(p) (CVAL(p, RFCNB_Pkt_Type_Offset))
+
+/*typedef struct RFCNB_Hdr {
+
+  unsigned char type;
+  unsigned char flags;
+  int16 len;
+
+  } RFCNB_Hdr;
+
+typedef struct RFCNB_Sess_Pkt {
+    unsigned char type;
+    unsigned char flags;
+    int16 length;
+    unsigned char n1_len;
+    char called_name[33];
+    unsigned char n2_len;
+    char calling_name[33];
+  } RFCNB_Sess_Pkt;
+
+
+typedef struct RFCNB_Nack_Pkt {
+
+  struct RFCNB_Hdr hdr;
+  unsigned char error;
+ 
+  } RFCNB_Nack_Pkt;
+
+typedef struct RFCNB_Retarget_Pkt {
+
+  struct RFCNB_Hdr hdr;
+  int dest_ip;
+  unsigned char port;
+
+  } RFCNB_Redir_Pkt; */
+
+/* Static variables */
+
+/* Only declare this if not defined */
+
+#ifndef RFCNB_ERRNO
+extern int RFCNB_errno;
+extern int RFCNB_saved_errno;    /* Save this from point of error */
+#endif
--- /dev/null	Wed Feb 14 00:44:43 2007
+++ squid/ntlm_auth_modules/NTLMSSP/smbval/rfcnb-util.c	Wed Feb 14 00:45:14 2007
@@ -0,0 +1,535 @@
+/* UNIX RFCNB (RFC1001/RFC1002) NetBIOS implementation
+
+   Version 1.0
+   RFCNB Utility Routines ...
+
+   Copyright (C) Richard Sharpe 1996
+
+*/
+
+/*
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+   
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+   
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include <string.h>
+#include <malloc.h>
+
+#include "std-includes.h"
+#include "rfcnb-priv.h"
+#include "rfcnb-util.h"
+#include "rfcnb-io.h"
+
+extern void (*Prot_Print_Routine)(); /* Pointer to protocol print routine */
+
+/* Convert name and pad to 16 chars as needed */
+/* Name 1 is a C string with null termination, name 2 may not be */
+/* If SysName is true, then put a <00> on end, else space>       */
+
+void RFCNB_CvtPad_Name(char *name1, char *name2)
+
+{ char c, c1, c2;
+  int i, len;
+
+  len = strlen(name1);
+
+  for (i = 0; i < 16; i++) {
+
+    if (i >= len) {
+
+     c1 = 'C'; c2 = 'A'; /* CA is a space */
+ 
+    } else {
+
+      c = name1[i];
+      c1 = (char)((int)c/16 + (int)'A');
+      c2 = (char)((int)c%16 + (int)'A');
+    }
+
+    name2[i*2] = c1;
+    name2[i*2+1] = c2;
+
+  }
+
+  name2[32] = 0;   /* Put in the nll ...*/
+
+}
+
+/* Converts an Ascii NB Name (16 chars) to an RFCNB Name (32 chars)
+   Uses the encoding in RFC1001. Each nibble of byte is added to 'A'
+   to produce the next byte in the name.
+
+   This routine assumes that AName is 16 bytes long and that NBName has 
+   space for 32 chars, so be careful ... 
+
+*/
+
+void RFCNB_AName_To_NBName(char *AName, char *NBName)
+
+{ char c, c1, c2;
+  int i;
+
+  for (i=0; i < 16; i++) {
+
+    c = AName[i];
+
+    c1 = (char)((c >> 4) + 'A');
+    c2 = (char)((c & 0xF) + 'A');
+
+    NBName[i*2] = c1;
+    NBName[i*2+1] = c2;
+  }
+
+  NBName[32] = 0; /* Put in a null */
+
+}
+
+/* Do the reverse of the above ... */
+
+void RFCNB_NBName_To_AName(char *NBName, char *AName)
+
+{ char c, c1, c2;
+  int i;
+
+  for (i=0; i < 16; i++) {
+
+    c1 = NBName[i*2];
+    c2 = NBName[i*2+1];
+
+    c = (char)(((int)c1 - (int)'A') * 16 + ((int)c2 - (int)'A'));
+
+    AName[i] = c;
+
+  }
+
+  AName[i] = 0;   /* Put a null on the end ... */
+
+}
+
+/* Print a string of bytes in HEX etc */
+
+void RFCNB_Print_Hex(FILE *fd, struct RFCNB_Pkt *pkt, int Offset, int Len)
+
+{ char c1, c2, outbuf1[33];
+  unsigned char c;
+  int i, j;
+  struct RFCNB_Pkt *pkt_ptr = pkt;
+  static char Hex_List[17] = "0123456789ABCDEF";
+
+  j = 0;
+
+  /* We only want to print as much as sepcified in Len */
+
+  while (pkt_ptr != NULL) {
+
+    for (i = 0; 
+	 i < ((Len > (pkt_ptr -> len)?pkt_ptr -> len:Len) - Offset); 
+	 i++) {
+
+      c = pkt_ptr -> data[i + Offset];
+      c1 = Hex_List[c >> 4];
+      c2 = Hex_List[c & 0xF];
+
+      outbuf1[j++] = c1; outbuf1[j++] = c2;
+
+      if (j == 32){ /* Print and reset */
+	outbuf1[j] = 0;
+	fprintf(fd, "    %s\n", outbuf1);
+	j = 0;
+      }
+
+    }
+
+    Offset = 0;
+    Len = Len - pkt_ptr -> len;   /* Reduce amount by this much */
+    pkt_ptr = pkt_ptr -> next;
+
+  }
+
+  /* Print last lot in the buffer ... */
+
+  if (j > 0) {
+
+    outbuf1[j] = 0;
+    fprintf(fd, "    %s\n", outbuf1);
+
+  }
+
+  fprintf(fd, "\n");
+
+}
+
+/* Get a packet of size n */
+
+struct RFCNB_Pkt *RFCNB_Alloc_Pkt(int n)
+
+{ RFCNB_Pkt *pkt;
+
+  if ((pkt = (struct RFCNB_Pkt *)malloc(sizeof(struct RFCNB_Pkt))) == NULL) {
+
+    RFCNB_errno = RFCNBE_NoSpace;
+    RFCNB_saved_errno = errno;
+    return(NULL);
+
+  }
+
+  pkt -> next = NULL;
+  pkt -> len = n;
+
+  if (n == 0) return(pkt);
+
+  if ((pkt -> data = (char *)malloc(n)) == NULL) {
+
+    RFCNB_errno = RFCNBE_NoSpace;
+    RFCNB_saved_errno = errno;
+    free(pkt);
+    return(NULL);
+
+  }
+
+  return(pkt);
+
+}
+
+/* Free up a packet */
+
+int RFCNB_Free_Pkt(struct RFCNB_Pkt *pkt)
+
+{ struct RFCNB_Pkt *pkt_next; char *data_ptr;
+
+  while (pkt != NULL) {
+
+    pkt_next = pkt -> next;
+
+    data_ptr = pkt -> data;
+
+    if (data_ptr != NULL)
+      free(data_ptr);
+
+    free(pkt);
+
+    pkt = pkt_next;
+
+  }
+
+}
+
+/* Print an RFCNB packet */
+
+void RFCNB_Print_Pkt(FILE *fd, char *dirn, struct RFCNB_Pkt *pkt, int len)
+
+{ char lname[17];
+
+  /* We assume that the first fragment is the RFCNB Header  */
+  /* We should loop through the fragments printing them out */
+
+  fprintf(fd, "RFCNB Pkt %s:", dirn);
+
+  switch (RFCNB_Pkt_Type(pkt -> data)) {
+
+  case RFCNB_SESSION_MESSAGE: 
+
+    fprintf(fd, "SESSION MESSAGE: Length = %i\n", RFCNB_Pkt_Len(pkt -> data));
+    RFCNB_Print_Hex(fd, pkt, RFCNB_Pkt_Hdr_Len, 
+#ifdef RFCNB_PRINT_DATA
+		    RFCNB_Pkt_Len(pkt -> data) - RFCNB_Pkt_Hdr_Len);
+#else
+                    40);
+#endif
+
+  if (Prot_Print_Routine != 0) { /* Print the rest of the packet */
+	
+    Prot_Print_Routine(fd, strcmp(dirn, "sent"), pkt, RFCNB_Pkt_Hdr_Len,
+		       RFCNB_Pkt_Len(pkt -> data) - RFCNB_Pkt_Hdr_Len);
+
+      }
+
+      break;
+
+ case RFCNB_SESSION_REQUEST:
+
+      fprintf(fd, "SESSION REQUEST: Length = %i\n",
+		  RFCNB_Pkt_Len(pkt -> data));
+      RFCNB_NBName_To_AName((char *)(pkt -> data + RFCNB_Pkt_Called_Offset), lname);
+      fprintf(fd, "  Called Name: %s\n", lname);
+      RFCNB_NBName_To_AName((char *)(pkt -> data + RFCNB_Pkt_Calling_Offset), lname);
+      fprintf(fd, "  Calling Name: %s\n", lname);
+
+      break;
+
+ case RFCNB_SESSION_ACK:
+
+      fprintf(fd, "RFCNB SESSION ACK: Length = %i\n",
+		  RFCNB_Pkt_Len(pkt -> data));
+
+      break;
+
+ case RFCNB_SESSION_REJ:
+      fprintf(fd, "RFCNB SESSION REJECT: Length = %i\n", 
+		  RFCNB_Pkt_Len(pkt -> data));
+
+      if (RFCNB_Pkt_Len(pkt -> data) < 1) {
+	fprintf(fd, "   Protocol Error, short Reject packet!\n");
+      }
+      else {
+	fprintf(fd, "   Error = %x\n", CVAL(pkt -> data, RFCNB_Pkt_Error_Offset));
+      }
+
+      break;
+
+ case RFCNB_SESSION_RETARGET:
+
+      fprintf(fd, "RFCNB SESSION RETARGET: Length = %i\n",
+		  RFCNB_Pkt_Len(pkt -> data));
+
+      /* Print out the IP address etc and the port? */
+
+      break;
+
+ case RFCNB_SESSION_KEEP_ALIVE:
+
+      fprintf(fd, "RFCNB SESSION KEEP ALIVE: Length = %i\n",
+	      RFCNB_Pkt_Len(pkt -> data));
+      break;
+
+    default:
+
+      break;
+  }
+
+}
+
+/* Resolve a name into an address */
+
+int RFCNB_Name_To_IP(char *host, struct in_addr *Dest_IP)
+
+{ int addr;         /* Assumes IP4, 32 bit network addresses */
+  struct hostent *hp;
+
+        /* Use inet_addr to try to convert the address */
+
+  if ((addr = inet_addr(host)) == INADDR_NONE) { /* Oh well, a good try :-) */
+
+        /* Now try a name look up with gethostbyname */
+
+    if ((hp = gethostbyname(host)) == NULL) { /* Not in DNS */
+
+        /* Try NetBIOS name lookup, how the hell do we do that? */
+
+      RFCNB_errno = RFCNBE_BadName;   /* Is this right? */
+      RFCNB_saved_errno = errno;
+      return(RFCNBE_Bad);
+
+    }
+    else {  /* We got a name */
+
+       memcpy((void *)Dest_IP, (void *)hp -> h_addr_list[0], sizeof(struct in_addr));
+
+    }
+  }
+  else { /* It was an IP address */
+
+    memcpy((void *)Dest_IP, (void *)&addr, sizeof(struct in_addr));
+
+  }
+
+  return 0;
+
+}
+
+/* Disconnect the TCP connection to the server */
+
+int RFCNB_Close(int socket)
+
+{
+
+  close(socket);
+
+  /* If we want to do error recovery, here is where we put it */
+
+  return 0;
+
+}
+
+/* Connect to the server specified in the IP address.
+   Not sure how to handle socket options etc.         */
+
+int RFCNB_IP_Connect(struct in_addr Dest_IP, int port)
+
+{ struct sockaddr_in Socket;
+  int fd;
+
+  /* Create a socket */
+
+  if ((fd = socket(PF_INET, SOCK_STREAM, 0)) < 0) { /* Handle the error */
+
+    RFCNB_errno = RFCNBE_BadSocket;
+    RFCNB_saved_errno = errno;
+    return(RFCNBE_Bad);
+    } 
+
+  bzero((char *)&Socket, sizeof(Socket));
+  memcpy((char *)&Socket.sin_addr, (char *)&Dest_IP, sizeof(Dest_IP));
+
+  Socket.sin_port = htons(port);
+  Socket.sin_family = PF_INET;
+
+  /* Now connect to the destination */
+
+  if (connect(fd, (struct sockaddr *)&Socket, sizeof(Socket)) < 0) { /* Error */
+
+    close(fd);
+    RFCNB_errno = RFCNBE_ConnectFailed;
+    RFCNB_saved_errno = errno;
+    return(RFCNBE_Bad);
+    }
+
+  return(fd);
+
+}
+
+/* handle the details of establishing the RFCNB session with remote 
+   end 
+
+*/
+
+int RFCNB_Session_Req(struct RFCNB_Con *con, 
+		      char *Called_Name, 
+		      char *Calling_Name,
+		      BOOL *redirect,
+		      struct in_addr *Dest_IP,
+		      int * port)
+
+{ char *sess_pkt;
+
+  /* Response packet should be no more than 9 bytes, make 16 jic */
+
+  char ln1[16], ln2[16], n1[32], n2[32], resp[16];
+  int len;
+  struct RFCNB_Pkt *pkt, res_pkt;
+
+  /* We build and send the session request, then read the response */
+
+  pkt = RFCNB_Alloc_Pkt(RFCNB_Pkt_Sess_Len);
+
+  if (pkt == NULL) {
+
+    return(RFCNBE_Bad);  /* Leave the error that RFCNB_Alloc_Pkt gives) */
+
+  }
+
+  sess_pkt = pkt -> data;    /* Get pointer to packet proper */
+
+  sess_pkt[RFCNB_Pkt_Type_Offset]  = RFCNB_SESSION_REQUEST;
+  RFCNB_Put_Pkt_Len(sess_pkt, RFCNB_Pkt_Sess_Len-RFCNB_Pkt_Hdr_Len);
+  sess_pkt[RFCNB_Pkt_N1Len_Offset] = 32;
+  sess_pkt[RFCNB_Pkt_N2Len_Offset] = 32;
+
+  RFCNB_CvtPad_Name(Called_Name, (sess_pkt + RFCNB_Pkt_Called_Offset));
+  RFCNB_CvtPad_Name(Calling_Name, (sess_pkt + RFCNB_Pkt_Calling_Offset));
+
+  /* Now send the packet */
+
+#ifdef RFCNB_DEBUG
+
+  fprintf(stderr, "Sending packet: ");
+  
+#endif
+
+  if ((len = RFCNB_Put_Pkt(con, pkt, RFCNB_Pkt_Sess_Len)) < 0) {
+
+    return(RFCNBE_Bad);       /* Should be able to write that lot ... */
+
+    }
+
+#ifdef RFCNB_DEBUG
+
+  fprintf(stderr, "Getting packet.\n");
+
+#endif
+
+  res_pkt.data = resp;
+  res_pkt.len  = sizeof(resp);
+  res_pkt.next = NULL;
+
+  if ((len = RFCNB_Get_Pkt(con, &res_pkt, sizeof(resp))) < 0) {
+
+    return(RFCNBE_Bad);
+
+  }
+
+  /* Now analyze the packet ... */
+
+  switch (RFCNB_Pkt_Type(resp)) {
+
+    case RFCNB_SESSION_REJ:         /* Didnt like us ... too bad */
+
+      /* Why did we get rejected ? */
+    
+      switch (CVAL(resp,RFCNB_Pkt_Error_Offset)) {
+
+      case 0x80: 
+	RFCNB_errno = RFCNBE_CallRejNLOCN;
+	break;
+      case 0x81:
+	RFCNB_errno = RFCNBE_CallRejNLFCN;
+	break;
+      case 0x82:
+	RFCNB_errno = RFCNBE_CallRejCNNP;
+	break;
+      case 0x83:
+	RFCNB_errno = RFCNBE_CallRejInfRes;
+	break;
+      case 0x8F:
+	RFCNB_errno = RFCNBE_CallRejUnSpec;
+	break;
+      default:
+	RFCNB_errno = RFCNBE_ProtErr;
+	break;
+      }
+
+      return(RFCNBE_Bad);
+      break;
+
+    case RFCNB_SESSION_ACK:        /* Got what we wanted ...      */
+
+      return(0);
+      break;
+
+    case RFCNB_SESSION_RETARGET:   /* Go elsewhere                */
+
+      *redirect = TRUE;       /* Copy port and ip addr       */
+
+      memcpy(Dest_IP, (resp + RFCNB_Pkt_IP_Offset), sizeof(struct in_addr));
+      *port = SVAL(resp, RFCNB_Pkt_Port_Offset);
+
+      return(0);
+      break;
+
+    default:  /* A protocol error */
+
+      RFCNB_errno = RFCNBE_ProtErr;
+      return(RFCNBE_Bad);
+      break;
+    }
+}
+
+
+
+
+
+
+
+
+
--- /dev/null	Wed Feb 14 00:44:43 2007
+++ squid/ntlm_auth_modules/NTLMSSP/smbval/rfcnb-util.h	Wed Feb 14 00:45:14 2007
@@ -0,0 +1,50 @@
+/* UNIX RFCNB (RFC1001/RFC1002) NetBIOS implementation
+
+   Version 1.0
+   RFCNB Utility Defines
+
+   Copyright (C) Richard Sharpe 1996
+
+*/
+
+/*
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+   
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+   
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+void RFCNB_CvtPad_Name(char *name1, char *name2);
+
+void RFCNB_AName_To_NBName(char *AName, char *NBName);
+
+void RFCNB_NBName_To_AName(char *NBName, char *AName);
+
+void RFCNB_Print_Hex(FILE *fd, struct RFCNB_Pkt *pkt, int Offset, int Len);
+
+struct RFCNB_Pkt *RFCNB_Alloc_Pkt(int n);
+
+void RFCNB_Print_Pkt(FILE *fd, char *dirn, struct RFCNB_Pkt *pkt, int len);
+
+int RFCNB_Name_To_IP(char *host, struct in_addr *Dest_IP);
+
+int RFCNB_Close(int socket);
+
+int RFCNB_IP_Connect(struct in_addr Dest_IP, int port);
+
+int RFCNB_Session_Req(struct RFCNB_Con *con, 
+		      char *Called_Name, 
+		      char *Calling_Name,
+		      BOOL *redirect,
+		      struct in_addr *Dest_IP,
+		      int * port);
+
--- /dev/null	Wed Feb 14 00:44:43 2007
+++ squid/ntlm_auth_modules/NTLMSSP/smbval/rfcnb.h	Wed Feb 14 00:45:14 2007
@@ -0,0 +1,50 @@
+/* UNIX RFCNB (RFC1001/RFC1002) NetBIOS implementation
+
+   Version 1.0
+   RFCNB Defines
+
+   Copyright (C) Richard Sharpe 1996
+
+*/
+
+/*
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+   
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+   
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+/* Error responses */
+
+#include "rfcnb-error.h"
+#include "rfcnb-common.h"
+
+/* Defines we need */
+
+#define RFCNB_Default_Port 139
+
+/* Definition of routines we define */
+
+void *RFCNB_Call(char *Called_Name, char *Calling_Name, char *Called_Address,
+		 int port);
+
+int RFCNB_Send(void *Con_Handle, struct RFCNB_Pkt *Data, int Length);
+
+int RFCNB_Recv(void *Con_Handle, struct RFCNB_Pkt *Data, int Length);
+
+int RFCNB_Hangup(void *con_Handle);
+
+void *RFCNB_Listen();
+
+void RFCNB_Get_Error(char *buffer, int buf_len);
+
+struct RFCNB_Pkt *RFCNB_Alloc_Pkt(int n);
--- /dev/null	Wed Feb 14 00:44:43 2007
+++ squid/ntlm_auth_modules/NTLMSSP/smbval/session.c	Wed Feb 14 00:45:14 2007
@@ -0,0 +1,368 @@
+/* UNIX RFCNB (RFC1001/RFC1002) NetBIOS implementation
+
+   Version 1.0
+   Session Routines ...
+
+   Copyright (C) Richard Sharpe 1996
+
+*/
+
+/*
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+   
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+   
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include <malloc.h>
+#include <string.h>
+
+int RFCNB_errno = 0;
+int RFCNB_saved_errno = 0;
+#define RFCNB_ERRNO
+
+#include "std-includes.h"
+#include <netinet/tcp.h>
+#include "rfcnb-priv.h"
+#include "rfcnb-util.h"
+
+int RFCNB_Stats[RFCNB_MAX_STATS];
+
+void (*Prot_Print_Routine)() = NULL;      /* Pointer to print routine */
+
+/* Set up a session with a remote name. We are passed Called_Name as a
+   string which we convert to a NetBIOS name, ie space terminated, up to
+   16 characters only if we need to. If Called_Address is not empty, then
+   we use it to connect to the remote end, but put in Called_Name ... Called 
+   Address can be a DNS based name, or a TCP/IP address ...
+*/
+
+void *RFCNB_Call(char *Called_Name, char *Calling_Name, char *Called_Address,
+		 int port)
+
+{ struct RFCNB_Con *con;
+  struct in_addr Dest_IP;
+  int Client;
+  BOOL redirect; struct redirect_addr *redir_addr;
+  char *Service_Address;
+
+  /* Now, we really should look up the port in /etc/services ... */
+
+  if (port == 0) port = RFCNB_Default_Port;
+
+  /* Create a connection structure first */
+
+  if ((con = (struct RFCNB_Con *)malloc(sizeof(struct RFCNB_Con))) == NULL) { /* Error in size */
+
+    RFCNB_errno = RFCNBE_NoSpace;
+    RFCNB_saved_errno = errno;
+    return(NULL);
+
+    }
+ 
+  con -> fd = -0;             /* no descriptor yet */
+  con -> rfc_errno = 0;           /* no error yet */
+  con -> timeout = 0;         /* no timeout   */
+  con -> redirects = 0;
+  con -> redirect_list = NULL; /* Fix bug still in version 0.50 */
+
+  /* Resolve that name into an IP address */
+
+  Service_Address = Called_Name;
+  if (strcmp(Called_Address, "") != 0) { /* If the Called Address = "" */
+    Service_Address = Called_Address;
+  }
+
+  if ((errno = RFCNB_Name_To_IP(Service_Address, &Dest_IP)) < 0) { /* Error */
+
+    /* No need to modify RFCNB_errno as it was done by RFCNB_Name_To_IP */
+
+    return(NULL);
+
+    }
+
+  /* Now connect to the remote end */
+
+  redirect = TRUE;     /* Fudge this one so we go once through */
+
+  while (redirect) {   /* Connect and get session info etc */
+
+    redirect = FALSE;  /* Assume all OK */
+
+    /* Build the redirect info. First one is first addr called */
+    /* And tack it onto the list of addresses we called        */
+
+    if ((redir_addr = (struct redirect_addr *)malloc(sizeof(struct redirect_addr))) == NULL) { /* Could not get space */
+      
+      RFCNB_errno = RFCNBE_NoSpace;
+      RFCNB_saved_errno = errno;
+      return(NULL);
+
+    }
+
+    memcpy((char *)&(redir_addr -> ip_addr), (char *)&Dest_IP, sizeof(Dest_IP));
+    redir_addr -> port = port;
+    redir_addr -> next = NULL;
+
+    if (con -> redirect_list == NULL) { /* Stick on head */
+
+      con -> redirect_list = con -> last_addr = redir_addr;
+
+    } else {
+
+      con -> last_addr -> next = redir_addr;
+      con -> last_addr = redir_addr;
+
+    }
+
+    /* Now, make that connection */
+
+    if ((Client = RFCNB_IP_Connect(Dest_IP, port)) < 0) { /* Error */
+
+      /* No need to modify RFCNB_errno as it was done by RFCNB_IP_Connect */
+
+      return(NULL);
+
+      }
+
+    con -> fd = Client;
+
+    /* Now send and handle the RFCNB session request              */
+    /* If we get a redirect, we will comeback with redirect true 
+       and a new IP address in DEST_IP                            */
+
+    if ((errno = RFCNB_Session_Req(con, 
+				   Called_Name,
+   				   Calling_Name,
+				   &redirect, &Dest_IP, &port)) < 0) {
+
+      /* No need to modify RFCNB_errno as it was done by RFCNB_Session.. */
+
+      return(NULL);
+
+      }
+
+    if (redirect) {
+
+      /* We have to close the connection, and then try again */
+
+      (con -> redirects)++;
+
+      RFCNB_Close(con -> fd);  /* Close it */
+
+      }
+    }
+
+  return(con);
+
+}
+
+/* We send a packet to the other end ... for the moment, we treat the 
+   data as a series of pointers to blocks of data ... we should check the
+   length ... */
+
+int RFCNB_Send(struct RFCNB_Con *Con_Handle, struct RFCNB_Pkt *udata, int Length)
+
+{ struct RFCNB_Pkt *pkt; char *hdr;
+  int len;
+
+  /* Plug in the header and send the data */
+
+  pkt = RFCNB_Alloc_Pkt(RFCNB_Pkt_Hdr_Len);
+
+  if (pkt == NULL) {
+
+    RFCNB_errno = RFCNBE_NoSpace;
+    RFCNB_saved_errno = errno;
+    return(RFCNBE_Bad);
+
+  }
+
+  pkt -> next = udata;   /* The user data we want to send */
+
+  hdr = pkt -> data;
+
+  /* Following crap is for portability across multiple UNIX machines */
+
+  *(hdr + RFCNB_Pkt_Type_Offset)  = RFCNB_SESSION_MESSAGE;
+  RFCNB_Put_Pkt_Len(hdr, Length);
+
+#ifdef RFCNB_DEBUG
+
+  fprintf(stderr, "Sending packet: ");
+  
+#endif
+
+  if ((len = RFCNB_Put_Pkt(Con_Handle, pkt, Length + RFCNB_Pkt_Hdr_Len)) < 0) {
+
+    /* No need to change RFCNB_errno as it was done by put_pkt ...     */
+
+    return(RFCNBE_Bad);   /* Should be able to write that lot ... */
+    
+  }
+
+  /* Now we have sent that lot, let's get rid of the RFCNB Header and return */
+
+  pkt -> next = NULL;
+
+  RFCNB_Free_Pkt(pkt);
+
+  return(len);
+
+}
+
+/* We pick up a message from the internet ... We have to worry about 
+   non-message packets ...                                           */
+
+int RFCNB_Recv(void *con_Handle, struct RFCNB_Pkt *Data, int Length)
+
+{ struct RFCNB_Pkt *pkt; struct RFCNB_Hdr *hdr;
+  int ret_len;
+
+  if (con_Handle == NULL){
+
+    RFCNB_errno = RFCNBE_BadHandle;
+    RFCNB_saved_errno = errno;
+    return(RFCNBE_Bad);
+
+  }
+
+  /* Now get a packet from below. We allocate a header first */
+
+  /* Plug in the header and send the data */
+
+  pkt = RFCNB_Alloc_Pkt(RFCNB_Pkt_Hdr_Len);
+
+  if (pkt == NULL) {
+
+    RFCNB_errno = RFCNBE_NoSpace;
+    RFCNB_saved_errno = errno;
+    return(RFCNBE_Bad);
+
+  }
+
+  pkt -> next = Data;  /* Plug in the data portion */
+
+  if ((ret_len = RFCNB_Get_Pkt(con_Handle, pkt, Length + RFCNB_Pkt_Hdr_Len)) < 0) {
+
+#ifdef RFCNB_DEBUG
+    fprintf(stderr, "Bad packet return in RFCNB_Recv... \n");
+#endif
+
+    return(RFCNBE_Bad);
+
+  }
+
+  /* We should check that we go a message and not a keep alive */
+
+  pkt -> next = NULL;
+
+  RFCNB_Free_Pkt(pkt);
+
+  return(ret_len);
+
+}
+
+/* We just disconnect from the other end, as there is nothing in the RFCNB */
+/* protocol that specifies any exchange as far as I can see                */
+
+int RFCNB_Hangup(struct RFCNB_Con *con_Handle)
+
+{
+
+  if (con_Handle != NULL) {
+    RFCNB_Close(con_Handle -> fd);  /* Could this fail? */
+    free(con_Handle);
+  }
+
+  return 0;
+
+
+}
+
+/* Set TCP_NODELAY on the socket                                          */
+
+int RFCNB_Set_Sock_NoDelay(struct RFCNB_Con *con_Handle, BOOL yn)
+
+{
+
+  return(setsockopt(con_Handle -> fd, IPPROTO_TCP, TCP_NODELAY, 
+		    (char *)&yn, sizeof(yn)));
+
+}
+
+
+/* Listen for a connection on a port???, when                             */
+/* the connection comes in, we return with the connection                 */
+
+void *RFCNB_Listen()
+
+{
+
+}
+
+/* Pick up the last error response as a string, hmmm, this routine should */
+/* have been different ...                                                */
+
+void RFCNB_Get_Error(char *buffer, int buf_len)
+
+{
+
+  if (RFCNB_saved_errno <= 0) {
+    sprintf(buffer, "%s", RFCNB_Error_Strings[RFCNB_errno]);
+  }
+  else {
+    sprintf(buffer, "%s\n\terrno:%s", RFCNB_Error_Strings[RFCNB_errno],
+	    strerror(RFCNB_saved_errno));
+  }
+
+}
+
+/* Pick up the last error response and returns as a code                 */
+
+int RFCNB_Get_Last_Error()
+
+{
+
+  return(RFCNB_errno);
+
+}
+
+/* Pick up saved errno as well */
+
+int RFCNB_Get_Last_Errno()
+
+{
+
+  return(RFCNB_saved_errno);
+
+}
+
+/* Pick up the last error response and return in string ...             */
+
+int RFCNB_Get_Error_Msg(int code, char *msg_buf, int len)
+
+{
+
+  strncpy(msg_buf, RFCNB_Error_Strings[abs(code)], len);
+
+}
+
+/* Register a higher level protocol print routine */
+
+void RFCNB_Register_Print_Routine(void (*fn)())
+
+{
+
+  Prot_Print_Routine = fn;
+
+}
--- /dev/null	Wed Feb 14 00:44:43 2007
+++ squid/ntlm_auth_modules/NTLMSSP/smbval/smbdes.c	Wed Feb 14 00:45:14 2007
@@ -0,0 +1,337 @@
+/* 
+   Unix SMB/Netbios implementation.
+   Version 1.9.
+
+   a partial implementation of DES designed for use in the 
+   SMB authentication protocol
+
+   Copyright (C) Andrew Tridgell 1997
+   
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+   
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+   
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+
+/* NOTES: 
+
+   This code makes no attempt to be fast! In fact, it is a very
+   slow implementation 
+
+   This code is NOT a complete DES implementation. It implements only
+   the minimum necessary for SMB authentication, as used by all SMB
+   products (including every copy of Microsoft Windows95 ever sold)
+
+   In particular, it can only do a unchained forward DES pass. This
+   means it is not possible to use this code for encryption/decryption
+   of data, instead it is only useful as a "hash" algorithm.
+
+   There is no entry point into this code that allows normal DES operation.
+
+   I believe this means that this code does not come under ITAR
+   regulations but this is NOT a legal opinion. If you are concerned
+   about the applicability of ITAR regulations to this code then you
+   should confirm it for yourself (and maybe let me know if you come
+   up with a different answer to the one above)
+*/
+
+
+
+static int perm1[56] = {57, 49, 41, 33, 25, 17,  9,
+			 1, 58, 50, 42, 34, 26, 18,
+			10,  2, 59, 51, 43, 35, 27,
+			19, 11,  3, 60, 52, 44, 36,
+			63, 55, 47, 39, 31, 23, 15,
+			 7, 62, 54, 46, 38, 30, 22,
+			14,  6, 61, 53, 45, 37, 29,
+			21, 13,  5, 28, 20, 12,  4};
+
+static int perm2[48] = {14, 17, 11, 24,  1,  5,
+                         3, 28, 15,  6, 21, 10,
+                        23, 19, 12,  4, 26,  8,
+                        16,  7, 27, 20, 13,  2,
+                        41, 52, 31, 37, 47, 55,
+                        30, 40, 51, 45, 33, 48,
+                        44, 49, 39, 56, 34, 53,
+                        46, 42, 50, 36, 29, 32};
+
+static int perm3[64] = {58, 50, 42, 34, 26, 18, 10,  2,
+			60, 52, 44, 36, 28, 20, 12,  4,
+			62, 54, 46, 38, 30, 22, 14,  6,
+			64, 56, 48, 40, 32, 24, 16,  8,
+			57, 49, 41, 33, 25, 17,  9,  1,
+			59, 51, 43, 35, 27, 19, 11,  3,
+			61, 53, 45, 37, 29, 21, 13,  5,
+			63, 55, 47, 39, 31, 23, 15,  7};
+
+static int perm4[48] = {   32,  1,  2,  3,  4,  5,
+                            4,  5,  6,  7,  8,  9,
+                            8,  9, 10, 11, 12, 13,
+                           12, 13, 14, 15, 16, 17,
+                           16, 17, 18, 19, 20, 21,
+                           20, 21, 22, 23, 24, 25,
+                           24, 25, 26, 27, 28, 29,
+                           28, 29, 30, 31, 32,  1};
+
+static int perm5[32] = {      16,  7, 20, 21,
+                              29, 12, 28, 17,
+                               1, 15, 23, 26,
+                               5, 18, 31, 10,
+                               2,  8, 24, 14,
+                              32, 27,  3,  9,
+                              19, 13, 30,  6,
+                              22, 11,  4, 25};
+
+
+static int perm6[64] ={ 40,  8, 48, 16, 56, 24, 64, 32,
+                        39,  7, 47, 15, 55, 23, 63, 31,
+                        38,  6, 46, 14, 54, 22, 62, 30,
+                        37,  5, 45, 13, 53, 21, 61, 29,
+                        36,  4, 44, 12, 52, 20, 60, 28,
+                        35,  3, 43, 11, 51, 19, 59, 27,
+                        34,  2, 42, 10, 50, 18, 58, 26,
+                        33,  1, 41,  9, 49, 17, 57, 25};
+
+
+static int sc[16] = {1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1};
+
+static int sbox[8][4][16] = {
+	{{14,  4, 13,  1,  2, 15, 11,  8,  3, 10,  6, 12,  5,  9,  0,  7},
+	 {0, 15,  7,  4, 14,  2, 13,  1, 10,  6, 12, 11,  9,  5,  3,  8},
+	 {4,  1, 14,  8, 13,  6,  2, 11, 15, 12,  9,  7,  3, 10,  5,  0},
+	 {15, 12,  8,  2,  4,  9,  1,  7,  5, 11,  3, 14, 10,  0,  6, 13}},
+
+	{{15,  1,  8, 14,  6, 11,  3,  4,  9,  7,  2, 13, 12,  0,  5, 10},
+	 {3, 13,  4,  7, 15,  2,  8, 14, 12,  0,  1, 10,  6,  9, 11,  5},
+	 {0, 14,  7, 11, 10,  4, 13,  1,  5,  8, 12,  6,  9,  3,  2, 15},
+	 {13,  8, 10,  1,  3, 15,  4,  2, 11,  6,  7, 12,  0,  5, 14,  9}},
+
+	{{10,  0,  9, 14,  6,  3, 15,  5,  1, 13, 12,  7, 11,  4,  2,  8},
+	 {13,  7,  0,  9,  3,  4,  6, 10,  2,  8,  5, 14, 12, 11, 15,  1},
+	 {13,  6,  4,  9,  8, 15,  3,  0, 11,  1,  2, 12,  5, 10, 14,  7},
+	 {1, 10, 13,  0,  6,  9,  8,  7,  4, 15, 14,  3, 11,  5,  2, 12}},
+
+	{{7, 13, 14,  3,  0,  6,  9, 10,  1,  2,  8,  5, 11, 12,  4, 15},
+	 {13,  8, 11,  5,  6, 15,  0,  3,  4,  7,  2, 12,  1, 10, 14,  9},
+	 {10,  6,  9,  0, 12, 11,  7, 13, 15,  1,  3, 14,  5,  2,  8,  4},
+	 {3, 15,  0,  6, 10,  1, 13,  8,  9,  4,  5, 11, 12,  7,  2, 14}},
+
+	{{2, 12,  4,  1,  7, 10, 11,  6,  8,  5,  3, 15, 13,  0, 14,  9},
+	 {14, 11,  2, 12,  4,  7, 13,  1,  5,  0, 15, 10,  3,  9,  8,  6},
+	 {4,  2,  1, 11, 10, 13,  7,  8, 15,  9, 12,  5,  6,  3,  0, 14},
+	 {11,  8, 12,  7,  1, 14,  2, 13,  6, 15,  0,  9, 10,  4,  5,  3}},
+
+	{{12,  1, 10, 15,  9,  2,  6,  8,  0, 13,  3,  4, 14,  7,  5, 11},
+	 {10, 15,  4,  2,  7, 12,  9,  5,  6,  1, 13, 14,  0, 11,  3,  8},
+	 {9, 14, 15,  5,  2,  8, 12,  3,  7,  0,  4, 10,  1, 13, 11,  6},
+	 {4,  3,  2, 12,  9,  5, 15, 10, 11, 14,  1,  7,  6,  0,  8, 13}},
+
+	{{4, 11,  2, 14, 15,  0,  8, 13,  3, 12,  9,  7,  5, 10,  6,  1},
+	 {13,  0, 11,  7,  4,  9,  1, 10, 14,  3,  5, 12,  2, 15,  8,  6},
+	 {1,  4, 11, 13, 12,  3,  7, 14, 10, 15,  6,  8,  0,  5,  9,  2},
+	 {6, 11, 13,  8,  1,  4, 10,  7,  9,  5,  0, 15, 14,  2,  3, 12}},
+
+	{{13,  2,  8,  4,  6, 15, 11,  1, 10,  9,  3, 14,  5,  0, 12,  7},
+	 {1, 15, 13,  8, 10,  3,  7,  4, 12,  5,  6, 11,  0, 14,  9,  2},
+	 {7, 11,  4,  1,  9, 12, 14,  2,  0,  6, 10, 13, 15,  3,  5,  8},
+	 {2,  1, 14,  7,  4, 10,  8, 13, 15, 12,  9,  0,  3,  5,  6, 11}}};
+
+static void permute(char *out, char *in, int *p, int n)
+{
+	int i;
+	for (i=0;i<n;i++)
+		out[i] = in[p[i]-1];
+}
+
+static void lshift(char *d, int count, int n)
+{
+	char out[64];
+	int i;
+	for (i=0;i<n;i++)
+		out[i] = d[(i+count)%n];
+	for (i=0;i<n;i++)
+		d[i] = out[i];
+}
+
+static void concat(char *out, char *in1, char *in2, int l1, int l2)
+{
+	while (l1--)
+		*out++ = *in1++;
+	while (l2--)
+		*out++ = *in2++;
+}
+
+static void xor(char *out, char *in1, char *in2, int n)
+{
+	int i;
+	for (i=0;i<n;i++)
+		out[i] = in1[i] ^ in2[i];
+}
+
+static void dohash(char *out, char *in, char *key)
+{
+	int i, j, k;
+	char pk1[56];
+	char c[28];
+	char d[28];
+	char cd[56];
+	char ki[16][48];
+	char pd1[64];
+	char l[32], r[32];
+	char rl[64];
+
+	permute(pk1, key, perm1, 56);
+
+	for (i=0;i<28;i++)
+		c[i] = pk1[i];
+	for (i=0;i<28;i++)
+		d[i] = pk1[i+28];
+
+	for (i=0;i<16;i++) {
+		lshift(c, sc[i], 28);
+		lshift(d, sc[i], 28);
+
+		concat(cd, c, d, 28, 28); 
+		permute(ki[i], cd, perm2, 48); 
+	}
+
+	permute(pd1, in, perm3, 64);
+
+	for (j=0;j<32;j++) {
+		l[j] = pd1[j];
+		r[j] = pd1[j+32];
+	}
+
+	for (i=0;i<16;i++) {
+		char er[48];
+		char erk[48];
+		char b[8][6];
+		char cb[32];
+		char pcb[32];
+		char r2[32];
+
+		permute(er, r, perm4, 48);
+
+		xor(erk, er, ki[i], 48);
+
+		for (j=0;j<8;j++)
+			for (k=0;k<6;k++)
+				b[j][k] = erk[j*6 + k];
+
+		for (j=0;j<8;j++) {
+			int m, n;
+			m = (b[j][0]<<1) | b[j][5];
+
+			n = (b[j][1]<<3) | (b[j][2]<<2) | (b[j][3]<<1) | b[j][4]; 
+
+			for (k=0;k<4;k++) 
+				b[j][k] = (sbox[j][m][n] & (1<<(3-k)))?1:0; 
+		}
+
+		for (j=0;j<8;j++)
+			for (k=0;k<4;k++)
+				cb[j*4+k] = b[j][k];
+		permute(pcb, cb, perm5, 32);
+
+		xor(r2, l, pcb, 32);
+
+		for (j=0;j<32;j++)
+			l[j] = r[j];
+
+		for (j=0;j<32;j++)
+			r[j] = r2[j];
+	}
+
+	concat(rl, r, l, 32, 32);
+
+	permute(out, rl, perm6, 64);
+}
+
+static void str_to_key(unsigned char *str,unsigned char *key)
+{
+	int i;
+
+	key[0] = str[0]>>1;
+	key[1] = ((str[0]&0x01)<<6) | (str[1]>>2);
+	key[2] = ((str[1]&0x03)<<5) | (str[2]>>3);
+	key[3] = ((str[2]&0x07)<<4) | (str[3]>>4);
+	key[4] = ((str[3]&0x0F)<<3) | (str[4]>>5);
+	key[5] = ((str[4]&0x1F)<<2) | (str[5]>>6);
+	key[6] = ((str[5]&0x3F)<<1) | (str[6]>>7);
+	key[7] = str[6]&0x7F;
+	for (i=0;i<8;i++) {
+		key[i] = (key[i]<<1);
+	}
+}
+
+
+static void smbhash(unsigned char *out, unsigned char *in, unsigned char *key)
+{
+	int i;
+	char outb[64];
+	char inb[64];
+	char keyb[64];
+	unsigned char key2[8];
+
+	str_to_key(key, key2);
+
+	for (i=0;i<64;i++) {
+		inb[i] = (in[i/8] & (1<<(7-(i%8)))) ? 1 : 0;
+		keyb[i] = (key2[i/8] & (1<<(7-(i%8)))) ? 1 : 0;
+		outb[i] = 0;
+	}
+
+	dohash(outb, inb, keyb);
+
+	for (i=0;i<8;i++) {
+		out[i] = 0;
+	}
+
+	for (i=0;i<64;i++) {
+		if (outb[i])
+			out[i/8] |= (1<<(7-(i%8)));
+	}
+}
+
+void E_P16(unsigned char *p14,unsigned char *p16)
+{
+	unsigned char sp8[8] = {0x4b, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25};
+	smbhash(p16, sp8, p14);
+	smbhash(p16+8, sp8, p14+7);
+}
+
+void E_P24(unsigned char *p21, unsigned char *c8, unsigned char *p24)
+{
+	smbhash(p24, c8, p21);
+	smbhash(p24+8, c8, p21+7);
+	smbhash(p24+16, c8, p21+14);
+}
+
+void cred_hash1(unsigned char *out,unsigned char *in,unsigned char *key)
+{
+	unsigned char buf[8];
+
+	smbhash(buf, in, key);
+	smbhash(out, buf, key+9);
+}
+
+void cred_hash2(unsigned char *out,unsigned char *in,unsigned char *key)
+{
+	unsigned char buf[8];
+	static unsigned char key2[8];
+
+	smbhash(buf, in, key);
+	key2[0] = key[7];
+	smbhash(out, buf, key2);
+}
+
--- /dev/null	Wed Feb 14 00:44:43 2007
+++ squid/ntlm_auth_modules/NTLMSSP/smbval/smbencrypt.c	Wed Feb 14 00:45:14 2007
@@ -0,0 +1,196 @@
+/* 
+   Unix SMB/Netbios implementation.
+   Version 1.9.
+   SMB parameters and setup
+   Copyright (C) Andrew Tridgell 1992-1997
+   Modified by Jeremy Allison 1995.
+   
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+   
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+   
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include <string.h>
+#include <arpa/inet.h>
+#include <dirent.h>
+#include <string.h>
+#include <sys/vfs.h>
+#include <netinet/in.h>
+
+#include "smblib-priv.h"
+#define uchar unsigned char
+extern int DEBUGLEVEL;
+
+#include "byteorder.h"
+
+char *StrnCpy(char *dest,char *src,int n);
+void strupper(char *s);
+
+/*
+   This implements the X/Open SMB password encryption
+   It takes a password, a 8 byte "crypt key" and puts 24 bytes of 
+   encrypted password into p24 */
+void SMBencrypt(uchar *passwd, uchar *c8, uchar *p24)
+{
+  uchar p14[15], p21[21];
+
+  memset(p21,'\0',21);
+  memset(p14,'\0',14);
+  StrnCpy((char *)p14,(char *)passwd,14);
+
+  strupper((char *)p14);
+  E_P16(p14, p21); 
+  E_P24(p21, c8, p24);
+}
+
+/* Routines for Windows NT MD4 Hash functions. */
+static int _my_wcslen(int16 *str)
+{
+	int len = 0;
+	while(*str++ != 0)
+		len++;
+	return len;
+}
+
+/*
+ * Convert a string into an NT UNICODE string.
+ * Note that regardless of processor type 
+ * this must be in intel (little-endian)
+ * format.
+ */
+ 
+static int _my_mbstowcs(int16 *dst, uchar *src, int len)
+{
+	int i;
+	int16 val;
+ 
+	for(i = 0; i < len; i++) {
+		val = *src;
+		SSVAL(dst,0,val);
+		dst++;
+		src++;
+		if(val == 0)
+			break;
+	}
+	return i;
+}
+
+/* 
+ * Creates the MD4 Hash of the users password in NT UNICODE.
+ */
+ 
+void E_md4hash(uchar *passwd, uchar *p16)
+{
+	int len;
+	int16 wpwd[129];
+	
+	/* Password cannot be longer than 128 characters */
+	len = strlen((char *)passwd);
+	if(len > 128)
+		len = 128;
+	/* Password must be converted to NT unicode */
+	_my_mbstowcs(wpwd, passwd, len);
+	wpwd[len] = 0; /* Ensure string is null terminated */
+	/* Calculate length in bytes */
+	len = _my_wcslen(wpwd) * sizeof(int16);
+
+	mdfour(p16, (unsigned char *)wpwd, len);
+}
+
+/* Does the NT MD4 hash then des encryption. */
+ 
+void SMBNTencrypt(uchar *passwd, uchar *c8, uchar *p24)
+{
+	uchar p21[21];
+ 
+	memset(p21,'\0',21);
+ 
+	E_md4hash(passwd, p21);    
+	E_P24(p21, c8, p24);
+}
+
+/* Does both the NT and LM owfs of a user's password */
+
+void nt_lm_owf_gen(char *pwd, char *nt_p16, char *p16)
+{
+	char passwd[130];
+	StrnCpy(passwd, pwd, sizeof(passwd)-1);
+
+	/* Calculate the MD4 hash (NT compatible) of the password */
+	memset(nt_p16, '\0', 16);
+	E_md4hash((uchar *)passwd, (uchar *)nt_p16);
+
+	/* Mangle the passwords into Lanman format */
+	passwd[14] = '\0';
+	strupper(passwd);
+
+	/* Calculate the SMB (lanman) hash functions of the password */
+
+	memset(p16, '\0', 16);
+	E_P16((uchar *) passwd, (uchar *)p16);
+
+	/* clear out local copy of user's password (just being paranoid). */
+	bzero(passwd, sizeof(passwd));
+}
+
+/****************************************************************************
+line strncpy but always null terminates. Make sure there is room!
+****************************************************************************/
+char *StrnCpy(char *dest,char *src,int n)
+{
+  char *d = dest;
+  if (!dest) return(NULL);
+  if (!src) {
+    *dest = 0;
+    return(dest);
+  }
+  while (n-- && (*d++ = *src++)) ;
+  *d = 0;
+  return(dest);
+}
+
+void strupper(char *s)
+{
+  while (*s)
+  {
+    /*
+#if !defined(KANJI_WIN95_COMPATIBILITY)
+    if(lp_client_code_page() == KANJI_CODEPAGE)
+    {
+      
+      if (is_shift_jis (*s))
+      {
+        if (is_sj_lower (s[0], s[1]))
+          s[1] = sj_toupper2 (s[1]);
+        s += 2;
+      }
+      else if (is_kana (*s))
+      {
+        s++;
+      }
+      else
+      {
+        if (islower(*s))                           
+	  *s = toupper(*s);
+        s++;
+      }
+    }
+    else
+#endif */ /* KANJI_WIN95_COMPATIBILITY */
+    {
+      if (islower(*s))
+        *s = toupper(*s);
+      s++;
+    }
+  }
+}                      
--- /dev/null	Wed Feb 14 00:44:43 2007
+++ squid/ntlm_auth_modules/NTLMSSP/smbval/smblib-common.h	Wed Feb 14 00:45:14 2007
@@ -0,0 +1,184 @@
+/* UNIX SMBlib NetBIOS implementation
+
+   Version 1.0
+   SMBlib Common Defines
+
+   Copyright (C) Richard Sharpe 1996
+
+*/
+
+/*
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+   
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+   
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+/* To get the error class we want the first 8 bits */
+/* Because we just grab 4bytes from the SMB header, we have to re-order */
+/* here, but it makes the NtStatus part easier in future                */
+
+#define SMBlib_Error_Class(p) (p & 0x000000FF)
+
+/* To get the error code, we want the bottom 16 bits */
+
+#define SMBlib_Error_Code(p) (((unsigned int)p & 0xFFFF0000) >>16)
+
+/* Error CLASS codes and etc ... */
+
+#define SMBC_SUCCESS        0
+#define SMBC_ERRDOS         0x01
+#define SMBC_ERRSRV         0x02
+#define SMBC_ERRHRD         0x03
+#define SMBC_ERRCMD         0xFF
+
+/* Success error codes    */
+
+#define SMBS_BUFFERED       0x54
+#define SMBS_LOGGED         0x55
+#define SMBS_DISPLAYED      0x56
+
+/* ERRDOS Error codes     */
+
+#define SMBD_badfunc        0x01
+#define SMBD_badfile        0x02
+#define SMBD_badpath        0x03
+#define SMBD_nofids         0x04
+#define SMBD_noaccess       0x05
+#define SMBD_badfid         0x06
+#define SMBD_badmcb         0x07
+#define SMBD_nomem          0x08
+#define SMBD_badmem         0x09
+#define SMBD_badenv         0x0A
+#define SMBD_badformat      0x0B
+#define SMBD_badaccess      0x0C
+#define SMBD_baddata        0x0D
+#define SMBD_reserved       0x0E
+#define SMBD_baddrive       0x0F
+#define SMBD_remcd          0x10
+#define SMBD_diffdevice     0x11
+#define SMBD_nofiles        0x12
+#define SMBD_badshare       0x20
+#define SMBD_errlock        0x21
+#define SMBD_filexists      0x50
+
+/* Server errors ... */
+
+#define SMBV_error          0x01         /* Generic error */
+#define SMBV_badpw          0x02
+#define SMBV_badtype        0x03
+#define SMBV_access         0x04
+#define SMBV_invnid         0x05
+#define SMBV_invnetname     0x06
+#define SMBV_invdevice      0x07
+#define SMBV_qfull          0x31
+#define SMBV_qtoobig        0x32
+#define SMBV_qeof           0x33
+#define SMBV_invpfid        0x34
+#define SMBV_paused         0x51
+#define SMBV_msgoff         0x52
+#define SMBV_noroom         0x53
+#define SMBV_rmuns          0x57
+#define SMBV_nosupport      0xFFFF
+
+/* Hardware error codes ... */
+
+#define SMBH_nowrite        0x13
+#define SMBH_badunit        0x14
+#define SMBH_notready       0x15
+#define SMBH_badcmd         0x16
+#define SMBH_data           0x17
+#define SMBH_badreq         0x18
+#define SMBH_seek           0x19
+#define SMBH_badmedia       0x1A
+#define SMBH_badsector      0x1B
+#define SMBH_nopaper        0x1C
+#define SMBH_write          0x1D
+#define SMBH_read           0x1E
+#define SMBH_general        0x1F
+#define SMBH_badshare       0x20
+
+/* Access mode defines ... */
+
+#define SMB_AMODE_WTRU      0x4000
+#define SMB_AMODE_NOCACHE   0x1000
+#define SMB_AMODE_COMPAT    0x0000
+#define SMB_AMODE_DENYRWX   0x0010
+#define SMB_AMODE_DENYW     0x0020
+#define SMB_AMODE_DENYRX    0x0030
+#define SMB_AMODE_DENYNONE  0x0040
+#define SMB_AMODE_OPENR     0x0000
+#define SMB_AMODE_OPENW     0x0001
+#define SMB_AMODE_OPENRW    0x0002
+#define SMB_AMODE_OPENX     0x0003
+#define SMB_AMODE_FCBOPEN   0x00FF
+#define SMB_AMODE_LOCUNKN   0x0000
+#define SMB_AMODE_LOCMSEQ   0x0100
+#define SMB_AMODE_LOCMRAN   0x0200
+#define SMB_AMODE_LOCRAL    0x0300
+
+/* File attribute encoding ... */
+
+#define SMB_FA_ORD          0x00
+#define SMB_FA_ROF          0x01
+#define SMB_FA_HID          0x02
+#define SMB_FA_SYS          0x04
+#define SMB_FA_VOL          0x08
+#define SMB_FA_DIR          0x10
+#define SMB_FA_ARC          0x20
+
+/* Define the protocol types ... */
+
+#define SMB_P_Unknown      -1        /* Hmmm, is this smart? */
+#define SMB_P_Core         0
+#define SMB_P_CorePlus     1
+#define SMB_P_DOSLanMan1   2
+#define SMB_P_LanMan1      3
+#define SMB_P_DOSLanMan2   4 
+#define SMB_P_LanMan2      5
+#define SMB_P_DOSLanMan2_1 6
+#define SMB_P_LanMan2_1    7
+#define SMB_P_NT1          8
+
+/* SMBlib return codes */
+/* We want something that indicates whether or not the return code was a   */
+/* remote error, a local error in SMBlib or returned from lower layer ...  */
+/* Wonder if this will work ...                                            */
+/* SMBlibE_Remote = 1 indicates remote error                               */
+/* SMBlibE_ values < 0 indicate local error with more info available       */
+/* SMBlibE_ values >1 indicate local from SMBlib code errors?              */
+
+#define SMBlibE_Success 0
+#define SMBlibE_Remote  1    /* Remote error, get more info from con        */
+#define SMBlibE_BAD     -1
+#define SMBlibE_LowerLayer 2 /* Lower layer error                           */
+#define SMBlibE_NotImpl 3    /* Function not yet implemented                */
+#define SMBlibE_ProtLow 4    /* Protocol negotiated does not support req    */
+#define SMBlibE_NoSpace 5    /* No space to allocate a structure            */
+#define SMBlibE_BadParam 6   /* Bad parameters                              */
+#define SMBlibE_NegNoProt 7  /* None of our protocols was liked             */
+#define SMBlibE_SendFailed 8 /* Sending an SMB failed                       */
+#define SMBlibE_RecvFailed 9 /* Receiving an SMB failed                     */
+#define SMBlibE_GuestOnly 10 /* Logged in as guest                          */
+#define SMBlibE_CallFailed 11 /* Call remote end failed                     */
+#define SMBlibE_ProtUnknown 12 /* Protocol unknown                          */
+#define SMBlibE_NoSuchMsg  13 /* Keep this up to date                       */
+
+typedef struct {                       /* A structure for a Dirent */
+
+  unsigned char resume_key[21];        /* Don't touch this          */
+  unsigned char file_attributes;       /* Attributes of file        */
+  unsigned int date_time;              /* date and time of last mod */
+  unsigned int size;
+  char filename[13];                   /* The name of the file      */
+
+} SMB_CP_dirent;
--- /dev/null	Wed Feb 14 00:44:43 2007
+++ squid/ntlm_auth_modules/NTLMSSP/smbval/smblib-priv.h	Wed Feb 14 00:45:14 2007
@@ -0,0 +1,624 @@
+/* UNIX SMBlib NetBIOS implementation
+
+   Version 1.0
+   SMBlib private Defines
+
+   Copyright (C) Richard Sharpe 1996
+
+*/
+
+/*
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+   
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+   
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "std-defines.h"
+#include "smblib-common.h"
+#include <sys/types.h>
+#include <unistd.h>
+
+typedef unsigned short uint16;
+typedef unsigned int   uint32;
+
+#include "byteorder.h"     /* Hmmm ... hot good */
+
+#define max(a,b) (a < b ? b : a)
+
+#define SMB_DEF_IDF 0x424D53FF        /* "\377SMB" */
+ 
+/* Core protocol commands */
+
+#define SMBmkdir      0x00   /* create directory */
+#define SMBrmdir      0x01   /* delete directory */
+#define SMBopen       0x02   /* open file */
+#define SMBcreate     0x03   /* create file */
+#define SMBclose      0x04   /* close file */
+#define SMBflush      0x05   /* flush file */
+#define SMBunlink     0x06   /* delete file */
+#define SMBmv         0x07   /* rename file */
+#define SMBgetatr     0x08   /* get file attributes */
+#define SMBsetatr     0x09   /* set file attributes */
+#define SMBread       0x0A   /* read from file */
+#define SMBwrite      0x0B   /* write to file */
+#define SMBlock       0x0C   /* lock byte range */
+#define SMBunlock     0x0D   /* unlock byte range */
+#define SMBctemp      0x0E   /* create temporary file */
+#define SMBmknew      0x0F   /* make new file */
+#define SMBchkpth     0x10   /* check directory path */
+#define SMBexit       0x11   /* process exit */
+#define SMBlseek      0x12   /* seek */
+#define SMBtcon       0x70   /* tree connect */
+#define SMBtdis       0x71   /* tree disconnect */
+#define SMBnegprot    0x72   /* negotiate protocol */
+#define SMBdskattr    0x80   /* get disk attributes */
+#define SMBsearch     0x81   /* search directory */
+#define SMBsplopen    0xC0   /* open print spool file */
+#define SMBsplwr      0xC1   /* write to print spool file */
+#define SMBsplclose   0xC2   /* close print spool file */
+#define SMBsplretq    0xC3   /* return print queue */
+#define SMBsends      0xD0   /* send single block message */
+#define SMBsendb      0xD1   /* send broadcast message */
+#define SMBfwdname    0xD2   /* forward user name */
+#define SMBcancelf    0xD3   /* cancel forward */
+#define SMBgetmac     0xD4   /* get machine name */
+#define SMBsendstrt   0xD5   /* send start of multi-block message */
+#define SMBsendend    0xD6   /* send end of multi-block message */
+#define SMBsendtxt    0xD7   /* send text of multi-block message */
+
+/* CorePlus protocol                                        */
+
+#define SMBlockread   0x13  /* Lock a range and read it */
+#define SMBwriteunlock 0x14 /* Unlock a range and then write */
+#define SMBreadbraw   0x1a  /* read a block of data without smb header ohead*/
+#define SMBwritebraw  0x1d  /* write a block of data without smb header ohead*/
+#define SMBwritec     0x20  /* secondary write request */
+#define SMBwriteclose 0x2c  /* write a file and then close it */
+
+/* DOS Extended Protocol                                    */
+
+#define SMBreadBraw      0x1A   /* read block raw */
+#define SMBreadBmpx      0x1B   /* read block multiplexed */
+#define SMBreadBs        0x1C   /* read block (secondary response) */
+#define SMBwriteBraw     0x1D   /* write block raw */
+#define SMBwriteBmpx     0x1E   /* write block multiplexed */
+#define SMBwriteBs       0x1F   /* write block (secondary request) */
+#define SMBwriteC        0x20   /* write complete response */
+#define SMBsetattrE      0x22   /* set file attributes expanded */
+#define SMBgetattrE      0x23   /* get file attributes expanded */
+#define SMBlockingX      0x24   /* lock/unlock byte ranges and X */
+#define SMBtrans         0x25   /* transaction - name, bytes in/out */
+#define SMBtranss        0x26   /* transaction (secondary request/response) */
+#define SMBioctl         0x27   /* IOCTL */
+#define SMBioctls        0x28   /* IOCTL  (secondary request/response) */
+#define SMBcopy          0x29   /* copy */
+#define SMBmove          0x2A   /* move */
+#define SMBecho          0x2B   /* echo */
+#define SMBopenX         0x2D   /* open and X */
+#define SMBreadX         0x2E   /* read and X */
+#define SMBwriteX        0x2F   /* write and X */
+#define SMBsesssetupX    0x73   /* Session Set Up & X (including User Logon) */
+#define SMBtconX         0x75   /* tree connect and X */
+#define SMBffirst        0x82   /* find first */
+#define SMBfunique       0x83   /* find unique */
+#define SMBfclose        0x84   /* find close */
+#define SMBinvalid       0xFE   /* invalid command */
+
+/* Any more ? */
+
+#define SMBdatablockID     0x01  /* A data block identifier */
+#define SMBdialectID       0x02  /* A dialect id            */
+#define SMBpathnameID      0x03  /* A pathname ID           */
+#define SMBasciiID         0x04  /* An ascii string ID      */
+#define SMBvariableblockID 0x05  /* A variable block ID     */
+
+/* some other defines we need */
+
+/* Flags defines ... */
+
+#define SMB_FLG2_NON_DOS    0x01 /* We know non dos names             */
+#define SMB_FLG2_EXT_ATR    0x02 /* We know about Extended Attributes */
+#define SMB_FLG2_LNG_NAM    0x04 /* Long names ?                      */
+
+typedef unsigned short WORD;
+typedef unsigned short UWORD;
+typedef unsigned int ULONG;
+typedef unsigned char BYTE;
+typedef unsigned char UCHAR;
+
+/* Some macros to allow access to actual packet data so that we */
+/* can change the underlying representation of packets.         */
+/*                                                              */
+/* The current formats vying for attention are a fragment       */
+/* approach where the SMB header is a fragment linked to the    */
+/* data portion with the transport protocol (rfcnb or whatever) */
+/* being linked on the front.                                   */
+/*                                                              */
+/* The other approach is where the whole packet is one array    */
+/* of bytes with space allowed on the front for the packet      */
+/* headers.                                                     */
+
+#define SMB_Hdr(p) (char *)(p -> data)
+
+/* SMB Hdr def for File Sharing Protocol? From MS and Intel,    */
+/* Intel PN 138446 Doc Version 2.0, Nov 7, 1988. This def also  */
+/* applies to LANMAN1.0 as well as the Core Protocol            */
+/* The spec states that wct and bcc must be present, even if 0  */
+
+/* We define these as offsets into a char SMB[] array for the   */
+/* sake of portability                                          */
+
+/* NOTE!. Some of the lenght defines, SMB_<protreq>_len do not include */
+/* the data that follows in the SMB packet, so the code will have to   */
+/* take that into account.                                             */
+
+#define SMB_hdr_idf_offset    0          /* 0xFF,'SMB' 0-3 */
+#define SMB_hdr_com_offset    4          /* BYTE       4   */
+#define SMB_hdr_rcls_offset   5          /* BYTE       5   */
+#define SMB_hdr_reh_offset    6          /* BYTE       6   */
+#define SMB_hdr_err_offset    7          /* WORD       7   */
+#define SMB_hdr_reb_offset    9          /* BYTE       9   */
+#define SMB_hdr_flg_offset    9          /* same as reb ...*/
+#define SMB_hdr_res_offset    10         /* 7 WORDs    10  */
+#define SMB_hdr_res0_offset   10         /* WORD       10  */
+#define SMB_hdr_flg2_offset   10         /* WORD           */
+#define SMB_hdr_res1_offset   12         /* WORD       12  */
+#define SMB_hdr_res2_offset   14
+#define SMB_hdr_res3_offset   16
+#define SMB_hdr_res4_offset   18
+#define SMB_hdr_res5_offset   20
+#define SMB_hdr_res6_offset   22
+#define SMB_hdr_tid_offset    24
+#define SMB_hdr_pid_offset    26
+#define SMB_hdr_uid_offset    28
+#define SMB_hdr_mid_offset    30
+#define SMB_hdr_wct_offset    32
+
+#define SMB_hdr_len           33        /* 33 byte header?      */
+
+#define SMB_hdr_axc_offset    33        /* AndX Command         */
+#define SMB_hdr_axr_offset    34        /* AndX Reserved        */
+#define SMB_hdr_axo_offset    35     /* Offset from start to WCT of AndX cmd */
+
+/* Format of the Negotiate Protocol SMB */
+
+#define SMB_negp_bcc_offset   33
+#define SMB_negp_buf_offset   35        /* Where the buffer starts   */
+#define SMB_negp_len          35        /* plus the data             */
+
+/* Format of the Negotiate Response SMB, for CoreProtocol, LM1.2 and */
+/* NT LM 0.12. wct will be 1 for CoreProtocol, 13 for LM 1.2, and 17 */
+/* for NT LM 0.12                                                    */
+
+#define SMB_negrCP_idx_offset   33        /* Response to the neg req */
+#define SMB_negrCP_bcc_offset   35
+#define SMB_negrLM_idx_offset   33        /* dialect index           */
+#define SMB_negrLM_sec_offset   35        /* Security mode           */
+#define SMB_sec_user_mask       0x01      /* 0 = share, 1 = user     */
+#define SMB_sec_encrypt_mask    0x02      /* pick out encrypt        */
+#define SMB_negrLM_mbs_offset   37        /* max buffer size         */
+#define SMB_negrLM_mmc_offset   39        /* max mpx count           */
+#define SMB_negrLM_mnv_offset   41        /* max number of VCs       */
+#define SMB_negrLM_rm_offset    43        /* raw mode support bit vec*/
+#define SMB_read_raw_mask       0x01
+#define SMB_write_raw_mask      0x02
+#define SMB_negrLM_sk_offset    45        /* session key, 32 bits    */
+#define SMB_negrLM_st_offset    49        /* Current server time     */
+#define SMB_negrLM_sd_offset    51        /* Current server date     */
+#define SMB_negrLM_stz_offset   53        /* Server Time Zone        */
+#define SMB_negrLM_ekl_offset   55        /* encryption key length   */
+#define SMB_negrLM_res_offset   57        /* reserved                */
+#define SMB_negrLM_bcc_offset   59        /* bcc                     */
+#define SMB_negrLM_len          61        /* 61 bytes ?              */
+#define SMB_negrLM_buf_offset   61        /* Where the fun begins    */
+
+#define SMB_negrNTLM_idx_offset 33        /* Selected protocol       */
+#define SMB_negrNTLM_sec_offset 35        /* Security more           */
+#define SMB_negrNTLM_mmc_offset 36        /* Different format above  */
+#define SMB_negrNTLM_mnv_offset 38        /* Max VCs                 */
+#define SMB_negrNTLM_mbs_offset 40        /* MBS now a long          */
+#define SMB_negrNTLM_mrs_offset 44        /* Max raw size            */
+#define SMB_negrNTLM_sk_offset  48        /* Session Key             */
+#define SMB_negrNTLM_cap_offset 52        /* Capabilities            */
+#define SMB_negrNTLM_stl_offset 56        /* Server time low         */
+#define SMB_negrNTLM_sth_offset 60        /* Server time high        */
+#define SMB_negrNTLM_stz_offset 64        /* Server time zone        */
+#define SMB_negrNTLM_ekl_offset 66        /* Encrypt key len         */
+#define SMB_negrNTLM_bcc_offset 67        /* Bcc                     */
+#define SMB_negrNTLM_len        69
+#define SMB_negrNTLM_buf_offset 69
+
+/* Offsets related to Tree Connect                                      */
+
+#define SMB_tcon_bcc_offset     33
+#define SMB_tcon_buf_offset     35        /* where the data is for tcon */
+#define SMB_tcon_len            35        /* plus the data              */
+
+#define SMB_tconr_mbs_offset    33        /* max buffer size         */
+#define SMB_tconr_tid_offset    35        /* returned tree id        */
+#define SMB_tconr_bcc_offset    37       
+#define SMB_tconr_len           39 
+
+#define SMB_tconx_axc_offset    33        /* And X Command                */
+#define SMB_tconx_axr_offset    34        /* reserved                     */
+#define SMB_tconx_axo_offset    35        /* Next command offset          */
+#define SMB_tconx_flg_offset    37        /* Flags, bit0=1 means disc TID */
+#define SMB_tconx_pwl_offset    39        /* Password length              */
+#define SMB_tconx_bcc_offset    41        /* bcc                          */
+#define SMB_tconx_buf_offset    43        /* buffer                       */
+#define SMB_tconx_len           43        /* up to data ...               */
+
+#define SMB_tconxr_axc_offset   33        /* Where the AndX Command is    */
+#define SMB_tconxr_axr_offset   34        /* Reserved                     */
+#define SMB_tconxr_axo_offset   35        /* AndX offset location         */
+
+/* Offsets related to tree_disconnect                                  */
+
+#define SMB_tdis_bcc_offset     33        /* bcc                     */
+#define SMB_tdis_len            35        /* total len               */
+
+#define SMB_tdisr_bcc_offset    33        /* bcc                     */
+#define SMB_tdisr_len           35
+
+/* Offsets related to Open Request                                     */
+
+#define SMB_open_mod_offset     33        /* Mode to open with       */
+#define SMB_open_atr_offset     35        /* Attributes of file      */
+#define SMB_open_bcc_offset     37        /* bcc                     */
+#define SMB_open_buf_offset     39        /* File name               */
+#define SMB_open_len            39        /* Plus the file name      */
+
+#define SMB_openx_axc_offset    33        /* Next command            */
+#define SMB_openx_axr_offset    34        /* Reserved                */
+#define SMB_openx_axo_offset    35        /* offset of next wct      */
+#define SMB_openx_flg_offset    37        /* Flags, bit0 = need more info */
+                                          /* bit1 = exclusive oplock */
+                                          /* bit2 = batch oplock     */
+#define SMB_openx_mod_offset    39        /* mode to open with       */
+#define SMB_openx_atr_offset    41        /* search attributes       */
+#define SMB_openx_fat_offset    43        /* File attributes         */
+#define SMB_openx_tim_offset    45        /* time and date of creat  */
+#define SMB_openx_ofn_offset    49        /* Open function           */
+#define SMB_openx_als_offset    51        /* Space to allocate on    */
+#define SMB_openx_res_offset    55        /* reserved                */
+#define SMB_openx_bcc_offset    63        /* bcc                     */
+#define SMB_openx_buf_offset    65        /* Where file name goes    */
+#define SMB_openx_len           65
+
+#define SMB_openr_fid_offset    33        /* FID returned            */
+#define SMB_openr_atr_offset    35        /* Attributes opened with  */
+#define SMB_openr_tim_offset    37        /* Last mod time of file   */
+#define SMB_openr_fsz_offset    41        /* File size 4 bytes       */
+#define SMB_openr_acc_offset    45        /* Access allowed          */
+#define SMB_openr_bcc_offset    47
+#define SMB_openr_len           49
+
+#define SMB_openxr_axc_offset   33        /* And X command           */
+#define SMB_openxr_axr_offset   34        /* reserved                */
+#define SMB_openxr_axo_offset   35        /* offset to next command  */
+#define SMB_openxr_fid_offset   37        /* FID returned            */
+#define SMB_openxr_fat_offset   39        /* File attributes returned*/
+#define SMB_openxr_tim_offset   41        /* File creation date etc  */
+#define SMB_openxr_fsz_offset   45        /* Size of file            */
+#define SMB_openxr_acc_offset   49        /* Access granted          */
+
+#define SMB_clos_fid_offset     33        /* FID to close            */
+#define SMB_clos_tim_offset     35        /* Last mod time           */
+#define SMB_clos_bcc_offset     39        /* bcc                     */        
+#define SMB_clos_len            41
+
+/* Offsets related to Write requests                                 */
+
+#define SMB_write_fid_offset    33        /* FID to write            */
+#define SMB_write_cnt_offset    35        /* bytes to write          */
+#define SMB_write_ofs_offset    37        /* location to write to    */
+#define SMB_write_clf_offset    41        /* advisory count left     */
+#define SMB_write_bcc_offset    43        /* bcc = data bytes + 3    */
+#define SMB_write_buf_offset    45        /* Data=0x01, len, data    */
+#define SMB_write_len           45        /* plus the data ...       */
+
+#define SMB_writr_cnt_offset    33        /* Count of bytes written  */
+#define SMB_writr_bcc_offset    35        /* bcc                     */
+#define SMB_writr_len           37
+
+/* Offsets related to read requests */
+
+#define SMB_read_fid_offset     33        /* FID of file to read     */
+#define SMB_read_cnt_offset     35        /* count of words to read  */
+#define SMB_read_ofs_offset     37        /* Where to read from      */
+#define SMB_read_clf_offset     41        /* Advisory count to go    */
+#define SMB_read_bcc_offset     43
+#define SMB_read_len            45
+
+#define SMB_readr_cnt_offset    33        /* Count of bytes returned */
+#define SMB_readr_res_offset    35        /* 4 shorts reserved, 8 bytes */
+#define SMB_readr_bcc_offset    43        /* bcc                     */
+#define SMB_readr_bff_offset    45        /* buffer format char = 0x01 */
+#define SMB_readr_len_offset    46        /* buffer len              */
+#define SMB_readr_len           45        /* length of the readr before data */
+
+/* Offsets for Create file                                           */
+
+#define SMB_creat_atr_offset    33        /* Attributes of new file ... */
+#define SMB_creat_tim_offset    35        /* Time of creation           */
+#define SMB_creat_dat_offset    37        /* 4004BCE :-)                */
+#define SMB_creat_bcc_offset    39        /* bcc                        */
+#define SMB_creat_buf_offset    41
+#define SMB_creat_len           41        /* Before the data            */
+
+#define SMB_creatr_fid_offset   33        /* FID of created file        */
+
+/* Offsets for Delete file                                           */
+
+#define SMB_delet_sat_offset    33        /* search attribites          */
+#define SMB_delet_bcc_offset    35        /* bcc                        */
+#define SMB_delet_buf_offset    37
+#define SMB_delet_len           37
+
+/* Offsets for SESSION_SETUP_ANDX for both LM and NT LM protocols    */
+
+#define SMB_ssetpLM_mbs_offset  37        /* Max buffer Size, allow for AndX */
+#define SMB_ssetpLM_mmc_offset  39        /* max multiplex count             */
+#define SMB_ssetpLM_vcn_offset  41        /* VC number if new VC             */
+#define SMB_ssetpLM_snk_offset  43        /* Session Key                     */
+#define SMB_ssetpLM_pwl_offset  47        /* password length                 */
+#define SMB_ssetpLM_res_offset  49        /* reserved                        */
+#define SMB_ssetpLM_bcc_offset  53        /* bcc                             */
+#define SMB_ssetpLM_len         55        /* before data ...                 */
+#define SMB_ssetpLM_buf_offset  55
+
+#define SMB_ssetpNTLM_mbs_offset 37       /* Max Buffer Size for NT LM 0.12  */
+                                          /* and above                       */
+#define SMB_ssetpNTLM_mmc_offset 39       /* Max Multiplex count             */
+#define SMB_ssetpNTLM_vcn_offset 41       /* VC Number                       */
+#define SMB_ssetpNTLM_snk_offset 43       /* Session key                     */
+#define SMB_ssetpNTLM_cipl_offset 47      /* Case Insensitive PW Len         */
+#define SMB_ssetpNTLM_cspl_offset 49      /* Unicode pw len                  */
+#define SMB_ssetpNTLM_res_offset 51       /* reserved                        */
+#define SMB_ssetpNTLM_cap_offset 55       /* server capabilities             */
+#define SMB_ssetpNTLM_bcc_offset 59       /* bcc                             */
+#define SMB_ssetpNTLM_len        61       /* before data                     */
+#define SMB_ssetpNTLM_buf_offset 61
+
+#define SMB_ssetpr_axo_offset  35         /* Offset of next response ...    */
+#define SMB_ssetpr_act_offset  37         /* action, bit 0 = 1 => guest     */
+#define SMB_ssetpr_bcc_offset  39         /* bcc                            */
+#define SMB_ssetpr_buf_offset  41         /* Native OS etc                  */
+
+/* Offsets for SMB create directory                                         */
+
+#define SMB_creatdir_bcc_offset 33        /* only a bcc here                */
+#define SMB_creatdir_buf_offset 35        /* Where things start             */
+#define SMB_creatdir_len        35
+
+/* Offsets for SMB delete directory                                         */
+
+#define SMB_deletdir_bcc_offset 33        /* only a bcc here                */
+#define SMB_deletdir_buf_offset 35        /* where things start             */
+#define SMB_deletdir_len        35
+
+/* Offsets for SMB check directory                                          */
+
+#define SMB_checkdir_bcc_offset 33        /* Only a bcc here                */
+#define SMB_checkdir_buf_offset 35        /* where things start             */
+#define SMB_checkdir_len        35
+
+/* Offsets for SMB search                                                   */
+
+#define SMB_search_mdc_offset   33        /* Max Dir ents to return         */
+#define SMB_search_atr_offset   35        /* Search attributes              */
+#define SMB_search_bcc_offset   37        /* bcc                            */
+#define SMB_search_buf_offset   39        /* where the action is            */
+#define SMB_search_len          39
+
+#define SMB_searchr_dec_offset  33        /* Dir ents returned              */
+#define SMB_searchr_bcc_offset  35        /* bcc                            */
+#define SMB_searchr_buf_offset  37        /* Where the action starts        */
+#define SMB_searchr_len         37        /* before the dir ents            */
+
+#define SMB_searchr_dirent_len  43        /* 53 bytes                       */
+
+/* Defines for SMB transact and transact2 calls                             */
+
+#define SMB_trans_tpc_offset    33        /* Total param count              */
+#define SMB_trans_tdc_offset    35        /* total Data count               */
+#define SMB_trans_mpc_offset    37        /* Max params bytes to return     */
+#define SMB_trans_mdc_offset    39        /* Max data bytes to return       */
+#define SMB_trans_msc_offset    41        /* Max setup words to return      */
+#define SMB_trans_rs1_offset    42        /* Reserved byte                  */
+#define SMB_trans_flg_offset    43        /* flags                          */
+#define SMB_trans_tmo_offset    45        /* Timeout, long                  */
+#define SMB_trans_rs2_offset    49        /* Next reserved                  */
+#define SMB_trans_pbc_offset    51        /* Param Byte count in buf        */
+#define SMB_trans_pbo_offset    53        /* Offset to param bytes          */
+#define SMB_trans_dbc_offset    55        /* Data byte count in buf         */
+#define SMB_trans_dbo_offset    57        /* Data byte offset               */
+#define SMB_trans_suc_offset    59        /* Setup count - byte             */
+#define SMB_trans_rs3_offset    60        /* Reserved to pad ...            */
+#define SMB_trans_len           61        /* Up to setup, still need bcc    */
+
+#define SMB_transr_tpc_offset   33        /* Total param bytes returned     */
+#define SMB_transr_tdc_offset   35
+#define SMB_transr_rs1_offset   37
+#define SMB_transr_pbc_offset   39
+#define SMB_transr_pbo_offset   41
+#define SMB_transr_pdi_offset   43        /* parameter displacement         */
+#define SMB_transr_dbc_offset   45
+#define SMB_transr_dbo_offset   47
+#define SMB_transr_ddi_offset   49
+#define SMB_transr_suc_offset   51
+#define SMB_transr_rs2_offset   52
+#define SMB_transr_len          53
+
+/* Bit masks for SMB Capabilities ...                       */
+
+#define SMB_cap_raw_mode         0x0001
+#define SMB_cap_mpx_mode         0x0002
+#define SMB_cap_unicode          0x0004
+#define SMB_cap_large_files      0x0008
+#define SMB_cap_nt_smbs          0x0010
+#define SMB_rpc_remote_apis      0x0020
+#define SMB_cap_nt_status        0x0040
+#define SMB_cap_level_II_oplocks 0x0080
+#define SMB_cap_lock_and_read    0x0100
+#define SMB_cap_nt_find          0x0200
+
+/* SMB LANMAN api call defines */
+
+#define SMB_LMapi_SetUserInfo     0x0072
+#define SMB_LMapi_UserPasswordSet 0x0073
+ 
+/* Structures and defines we use in the client interface */
+
+/* The protocols we might support. Perhaps a bit ambitious, as only RFCNB */
+/* has any support so far 0(sometimes called NBT)                         */
+
+typedef enum {SMB_RFCNB, SMB_IPXNB, SMB_NETBEUI, SMB_X25} SMB_Transport_Types;
+
+typedef enum {SMB_Con_FShare, SMB_Con_PShare, SMB_Con_IPC} SMB_Con_Types;
+
+typedef enum {SMB_State_NoState, SMB_State_Stopped, SMB_State_Started} SMB_State_Types;
+
+/* The following two arrays need to be in step!              */
+/* We must make it possible for callers to specify these ... */
+
+
+static char *SMB_Prots[] = {"PC NETWORK PROGRAM 1.0", 
+			    "MICROSOFT NETWORKS 1.03",
+			    "MICROSOFT NETWORKS 3.0",
+			    "DOS LANMAN1.0",
+			    "LANMAN1.0",
+			    "DOS LM1.2X002",
+			    "LM1.2X002",
+			    "DOS LANMAN2.1",
+			    "LANMAN2.1",
+			    "Samba",
+			    "NT LM 0.12",
+			    "NT LANMAN 1.0",
+			    NULL};
+
+static int SMB_Types[] = {SMB_P_Core,
+                          SMB_P_CorePlus,
+			  SMB_P_DOSLanMan1,
+			  SMB_P_DOSLanMan1,
+	                  SMB_P_LanMan1,
+			  SMB_P_DOSLanMan2,
+		          SMB_P_LanMan2,
+	 	          SMB_P_LanMan2_1,
+		          SMB_P_LanMan2_1,
+		          SMB_P_NT1,
+		          SMB_P_NT1,
+		          SMB_P_NT1,
+		          -1};
+
+typedef struct SMB_Status {
+
+  union {
+    struct {
+      unsigned char ErrorClass;
+      unsigned char Reserved;
+      unsigned short Error;
+    } DosError;
+    unsigned int NtStatus;
+  } status;
+} SMB_Status;
+
+typedef struct SMB_Tree_Structure * SMB_Tree_Handle;
+
+typedef struct SMB_Connect_Def * SMB_Handle_Type;
+
+struct SMB_Connect_Def {
+
+  SMB_Handle_Type Next_Con, Prev_Con;          /* Next and previous conn */
+  int protocol;                                /* What is the protocol   */
+  int prot_IDX;                                /* And what is the index  */
+  void *Trans_Connect;                         /* The connection         */
+
+  /* All these strings should be malloc'd */
+
+  char service[80], username[80], password[80], desthost[80], sock_options[80];
+  char address[80], myname[80];
+
+  SMB_Tree_Handle first_tree, last_tree;  /* List of trees on this server */
+
+  int gid;         /* Group ID, do we need it?                      */
+  int mid;         /* Multiplex ID? We might need one per con       */
+  int pid;         /* Process ID                                    */
+
+  int uid;         /* Authenticated user id.                        */
+
+                   /* It is pretty clear that we need to bust some of */
+                   /* these out into a per TCon record, as there may  */
+                   /* be multiple TCon's per server, etc ... later    */
+
+  int port;        /* port to use in case not default, this is a TCPism! */
+
+  int max_xmit;    /* Max xmit permitted by server                  */
+  int Security;    /* 0 = share, 1 = user                           */
+  int Raw_Support; /* bit 0 = 1 = Read Raw supported, 1 = 1 Write raw */
+  BOOL encrypt_passwords; /* FALSE = don't                          */ 
+  int MaxMPX, MaxVC, MaxRaw;
+  unsigned int SessionKey, Capabilities;
+  int SvrTZ;                                 /* Server Time Zone */
+  int Encrypt_Key_Len;
+  char Encrypt_Key[80], Domain[80], PDomain[80], OSName[80], LMType[40];
+  char Svr_OS[80], Svr_LMType[80], Svr_PDom[80];
+
+};
+
+#define SMBLIB_DEFAULT_DOMAIN "STAFF"
+#define SMBLIB_DEFAULT_OSNAME "UNIX of some type"
+#define SMBLIB_DEFAULT_LMTYPE "SMBlib LM2.1 minus a bit"
+#define SMBLIB_MAX_XMIT 65535
+
+#define SMB_Sec_Mode_Share 0
+#define SMB_Sec_Mode_User  1
+
+/* A Tree_Structure                       */
+
+struct SMB_Tree_Structure {
+
+  SMB_Tree_Handle next, prev;
+  SMB_Handle_Type con;
+  char path[129];
+  char device_type[20];
+  int mbs;                   /* Local MBS */
+  int tid;
+
+};
+
+typedef struct SMB_File_Def SMB_File;
+
+struct SMB_File_Def {
+
+  SMB_Tree_Handle tree;
+  char filename[256];          /* We should malloc this ... */
+  UWORD fid;
+  unsigned int lastmod;
+  unsigned int size;           /* Could blow up if 64bit files supported */
+  UWORD access;
+  off_t fileloc;
+
+};
+
+/* global Variables for the library */
+
+extern SMB_State_Types SMBlib_State;
+
+#ifndef SMBLIB_ERRNO
+extern int SMBlib_errno;
+extern int SMBlib_SMB_Error;          /* last Error             */
+#endif
+
+SMB_Tree_Handle SMB_TreeConnect(SMB_Handle_Type con, SMB_Tree_Handle tree,
+				char *path, char *password, char *dev);
--- /dev/null	Wed Feb 14 00:44:43 2007
+++ squid/ntlm_auth_modules/NTLMSSP/smbval/smblib-util.c	Wed Feb 14 00:45:14 2007
@@ -0,0 +1,790 @@
+/* UNIX SMBlib NetBIOS implementation
+
+   Version 1.0
+   SMBlib Utility Routines
+
+   Copyright (C) Richard Sharpe 1996
+
+*/
+
+/*
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+   
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+   
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "smblib-priv.h"
+#include <malloc.h>
+
+#include "rfcnb.h"
+
+/* Print out an SMB pkt in all its gory detail ... */
+
+void SMB_Print_Pkt(FILE fd, RFCNB_Pkt *pkt, BOOL command, int Offset, int Len)
+
+{
+
+  /* Well, just how do we do this ... print it I suppose */
+
+  /* Print out the SMB header ...                        */
+
+  /* Print the command                                   */
+
+  /* Print the other bits in the header                  */
+
+
+  /* etc                                                 */
+
+}
+
+/* Convert a DOS Date_Time to a local host type date time for printing */
+
+char *SMB_DOSTimToStr(int DOS_time)
+
+{ static char SMB_Time_Temp[48];
+  int DOS_sec, DOS_min, DOS_hour, DOS_day, DOS_month, DOS_year;
+
+  SMB_Time_Temp[0] = 0;
+
+  DOS_sec   = (DOS_time & 0x001F) * 2;
+  DOS_min   = (DOS_time & 0x07E0) >> 5;   
+  DOS_hour  = ((DOS_time & 0xF800) >> 11);
+
+  DOS_day   = (DOS_time & 0x001F0000) >> 16;
+  DOS_month = (DOS_time & 0x01E00000) >> 21;
+  DOS_year  = ((DOS_time & 0xFE000000) >> 25) + 80;
+
+  sprintf(SMB_Time_Temp, "%2d/%02d/%2d %2d:%02d:%02d", DOS_day, DOS_month,
+	                 DOS_year, DOS_hour, DOS_min, DOS_sec);
+
+  return(SMB_Time_Temp);
+
+}
+
+/* Convert an attribute byte/word etc to a string ... We return a pointer
+   to a static string which we guarantee is long enough. If verbose is 
+   true, we print out long form of strings ...                            */
+
+char *SMB_AtrToStr(int attribs, BOOL verbose)
+
+{ static char SMB_Attrib_Temp[128];
+
+  SMB_Attrib_Temp[0] = 0;
+
+  if (attribs & SMB_FA_ROF) 
+    strcat(SMB_Attrib_Temp, (verbose?"Read Only ":"R"));
+
+  if (attribs & SMB_FA_HID) 
+    strcat(SMB_Attrib_Temp, (verbose?"Hidden ":"H"));
+
+  if (attribs & SMB_FA_SYS) 
+    strcat(SMB_Attrib_Temp, (verbose?"System ":"S"));
+
+  if (attribs & SMB_FA_VOL) 
+    strcat(SMB_Attrib_Temp, (verbose?"Volume ":"V"));
+
+  if (attribs & SMB_FA_DIR) 
+    strcat(SMB_Attrib_Temp, (verbose?"Directory ":"D"));
+
+  if (attribs & SMB_FA_ARC) 
+    strcat(SMB_Attrib_Temp, (verbose?"Archive ":"A"));
+
+  return(SMB_Attrib_Temp);
+
+}
+
+/* Pick up the Max Buffer Size from the Tree Structure ... */
+
+int SMB_Get_Tree_MBS(SMB_Tree_Handle tree)
+
+{
+  if (tree != NULL) {
+    return(tree -> mbs);
+  }
+  else {
+    return(SMBlibE_BAD);
+  }
+}
+
+/* Pick up the Max buffer size */
+
+int SMB_Get_Max_Buf_Siz(SMB_Handle_Type Con_Handle)
+
+{
+  if (Con_Handle != NULL) {
+    return(Con_Handle -> max_xmit);
+  }
+  else {
+    return(SMBlibE_BAD);
+  }
+
+}
+/* Pickup the protocol index from the connection structure                 */
+
+int SMB_Get_Protocol_IDX(SMB_Handle_Type Con_Handle)
+
+{
+  if (Con_Handle != NULL) {
+    return(Con_Handle -> prot_IDX);
+  }
+  else {
+    return(0xFFFF);  /* Invalid protocol */
+  }
+
+}
+
+/* Pick up the protocol from the connection structure                       */
+
+int SMB_Get_Protocol(SMB_Handle_Type Con_Handle)
+
+{
+  if (Con_Handle != NULL) {
+    return(Con_Handle -> protocol);
+  }
+  else {
+    return(0xFFFF);  /* Invalid protocol */
+  }
+
+}
+
+/* Figure out what protocol was accepted, given the list of dialect strings */
+/* We offered, and the index back from the server. We allow for a user      */
+/* supplied list, and assume that it is a subset of our list                */
+
+int SMB_Figure_Protocol(char *dialects[], int prot_index)
+
+{ int i;
+
+  if (dialects == SMB_Prots) { /* The jobs is easy, just index into table */
+
+    return(SMB_Types[prot_index]);
+  }
+  else { /* Search through SMB_Prots looking for a match */
+
+    for (i = 0; SMB_Prots[i] != NULL; i++) {
+
+      if (strcmp(dialects[prot_index], SMB_Prots[i]) == 0) { /* A match */
+
+	return(SMB_Types[i]);
+
+      }
+
+    }
+
+    /* If we got here, then we are in trouble, because the protocol was not */
+    /* One we understand ...                                                */
+
+    return(SMB_P_Unknown);
+
+  }
+
+}
+
+
+/* Negotiate the protocol we will use from the list passed in Prots       */
+/* we return the index of the accepted protocol in NegProt, -1 indicates  */
+/* none acceptible, and our return value is 0 if ok, <0 if problems       */
+
+int SMB_Negotiate(SMB_Handle_Type Con_Handle, char *Prots[])
+
+{ struct SMB_Neg_Prot_Def *prot_pkt;
+  struct SMB_Neg_Prot_Resp_Def *resp_pkt;
+  struct RFCNB_Pkt *pkt;
+  int prots_len, i, pkt_len, prot, alloc_len;
+  char *p;
+
+  /* Figure out how long the prot list will be and allocate space for it */
+
+  prots_len = 0;
+
+  for (i = 0; Prots[i] != NULL; i++) {
+
+    prots_len = prots_len + strlen(Prots[i]) + 2; /* Account for null etc */
+
+  }
+
+  /* The -1 accounts for the one byte smb_buf we have because some systems */
+  /* don't like char msg_buf[]                                             */
+
+  pkt_len = SMB_negp_len + prots_len;
+
+  /* Make sure that the pkt len is long enough for the max response ...   */
+  /* Which is a problem, because the encryption key len eec may be long   */
+
+  if (pkt_len < (SMB_hdr_wct_offset + (19 * 2) + 40)) {
+
+    alloc_len = SMB_hdr_wct_offset + (19 * 2) + 40;
+
+  }
+  else {
+
+    alloc_len = pkt_len;
+
+  }
+
+  pkt = (struct RFCNB_Pkt *)RFCNB_Alloc_Pkt(alloc_len);
+
+  if (pkt == NULL) {
+
+    SMBlib_errno = SMBlibE_NoSpace;
+    return(SMBlibE_BAD);
+
+  }
+
+  /* Now plug in the bits we need */
+
+  bzero(SMB_Hdr(pkt), SMB_negp_len);
+  SIVAL(SMB_Hdr(pkt), SMB_hdr_idf_offset, SMB_DEF_IDF);  /* Plunk in IDF */
+  *(SMB_Hdr(pkt) + SMB_hdr_com_offset) = SMBnegprot;
+  SSVAL(SMB_Hdr(pkt), SMB_hdr_pid_offset, Con_Handle -> pid);
+  SSVAL(SMB_Hdr(pkt), SMB_hdr_tid_offset, 0);
+  SSVAL(SMB_Hdr(pkt), SMB_hdr_mid_offset, Con_Handle -> mid);
+  SSVAL(SMB_Hdr(pkt), SMB_hdr_uid_offset, Con_Handle -> uid);
+  *(SMB_Hdr(pkt) + SMB_hdr_wct_offset) = 0;
+
+  SSVAL(SMB_Hdr(pkt), SMB_negp_bcc_offset, prots_len);
+
+  /* Now copy the prot strings in with the right stuff */
+
+  p = (char *)(SMB_Hdr(pkt) + SMB_negp_buf_offset);
+
+  for (i = 0; Prots[i] != NULL; i++) {
+
+    *p = SMBdialectID;
+    strcpy(p + 1, Prots[i]);
+    p = p + strlen(Prots[i]) + 2; /* Adjust len of p for null plus dialectID */
+
+  }
+
+  /* Now send the packet and sit back ... */
+
+  if (RFCNB_Send(Con_Handle -> Trans_Connect, pkt, pkt_len) < 0){
+
+
+#ifdef DEBUG
+    fprintf(stderr, "Error sending negotiate protocol\n");
+#endif
+
+    RFCNB_Free_Pkt(pkt);
+    SMBlib_errno = -SMBlibE_SendFailed; /* Failed, check lower layer errno */
+    return(SMBlibE_BAD);
+
+  }
+
+  /* Now get the response ... */
+
+  if (RFCNB_Recv(Con_Handle -> Trans_Connect, pkt, alloc_len) < 0) {
+
+#ifdef DEBUG
+    fprintf(stderr, "Error receiving response to negotiate\n");
+#endif
+
+    RFCNB_Free_Pkt(pkt);
+    SMBlib_errno = -SMBlibE_RecvFailed; /* Failed, check lower layer errno */
+    return(SMBlibE_BAD);
+
+  }
+
+  if (CVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset) != SMBC_SUCCESS) {  /* Process error */
+
+#ifdef DEBUG
+    fprintf(stderr, "SMB_Negotiate failed with errorclass = %i, Error Code = %i\n",
+	    CVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset),
+	    SVAL(SMB_Hdr(pkt), SMB_hdr_err_offset));
+#endif
+
+    SMBlib_SMB_Error = IVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset);
+    RFCNB_Free_Pkt(pkt);
+    SMBlib_errno = SMBlibE_Remote;
+    return(SMBlibE_BAD);
+
+  }
+  
+  if (SVAL(SMB_Hdr(pkt), SMB_negrCP_idx_offset) == 0xFFFF) {
+
+#ifdef DEBUG
+    fprintf(stderr, "None of our protocols was accepted ... ");
+#endif
+
+    RFCNB_Free_Pkt(pkt);
+    SMBlib_errno = SMBlibE_NegNoProt;
+    return(SMBlibE_BAD);
+
+  }
+
+  /* Now, unpack the info from the response, if any and evaluate the proto */
+  /* selected. We must make sure it is one we like ...                     */
+
+  Con_Handle -> prot_IDX = prot = SVAL(SMB_Hdr(pkt), SMB_negrCP_idx_offset);
+  Con_Handle -> protocol = SMB_Figure_Protocol(Prots, prot);
+
+  if (Con_Handle -> protocol == SMB_P_Unknown) { /* No good ... */
+
+    RFCNB_Free_Pkt(pkt);
+    SMBlib_errno = SMBlibE_ProtUnknown;
+    return(SMBlibE_BAD);
+
+  }
+  
+  switch (CVAL(SMB_Hdr(pkt), SMB_hdr_wct_offset)) {
+
+  case 0x01:      /* No more info ... */
+
+    break;
+
+  case 13:        /* Up to and including LanMan 2.1 */
+
+    Con_Handle -> Security = SVAL(SMB_Hdr(pkt), SMB_negrLM_sec_offset);
+    Con_Handle -> encrypt_passwords = ((Con_Handle -> Security & SMB_sec_encrypt_mask) != 0x00);
+    Con_Handle -> Security = Con_Handle -> Security & SMB_sec_user_mask;
+
+    Con_Handle -> max_xmit = SVAL(SMB_Hdr(pkt), SMB_negrLM_mbs_offset);
+    Con_Handle -> MaxMPX = SVAL(SMB_Hdr(pkt), SMB_negrLM_mmc_offset);
+    Con_Handle -> MaxVC = SVAL(SMB_Hdr(pkt), SMB_negrLM_mnv_offset);
+    Con_Handle -> Raw_Support = SVAL(SMB_Hdr(pkt), SMB_negrLM_rm_offset);
+    Con_Handle -> SessionKey = IVAL(SMB_Hdr(pkt), SMB_negrLM_sk_offset);
+    Con_Handle -> SvrTZ = SVAL(SMB_Hdr(pkt), SMB_negrLM_stz_offset);
+    Con_Handle -> Encrypt_Key_Len = SVAL(SMB_Hdr(pkt), SMB_negrLM_ekl_offset);
+    
+    p = (SMB_Hdr(pkt) + SMB_negrLM_buf_offset);
+    fprintf(stderr, "%d", (char *)(SMB_Hdr(pkt) + SMB_negrLM_buf_offset));
+    memcpy(Con_Handle->Encrypt_Key, p, 8);
+
+    p = (SMB_Hdr(pkt) + SMB_negrLM_buf_offset + Con_Handle -> Encrypt_Key_Len);
+
+    strncpy(p, Con_Handle -> Svr_PDom, sizeof(Con_Handle -> Svr_PDom) - 1);
+
+    break;
+
+  case 17:        /* NT LM 0.12 and LN LM 1.0 */
+
+    Con_Handle -> Security = SVAL(SMB_Hdr(pkt), SMB_negrNTLM_sec_offset);
+    Con_Handle -> encrypt_passwords = ((Con_Handle -> Security & SMB_sec_encrypt_mask) != 0x00);
+    Con_Handle -> Security = Con_Handle -> Security & SMB_sec_user_mask;
+
+    Con_Handle -> max_xmit = IVAL(SMB_Hdr(pkt), SMB_negrNTLM_mbs_offset);
+    Con_Handle -> MaxMPX = SVAL(SMB_Hdr(pkt), SMB_negrNTLM_mmc_offset);
+    Con_Handle -> MaxVC = SVAL(SMB_Hdr(pkt), SMB_negrNTLM_mnv_offset);
+    Con_Handle -> MaxRaw = IVAL(SMB_Hdr(pkt), SMB_negrNTLM_mrs_offset);
+    Con_Handle -> SessionKey = IVAL(SMB_Hdr(pkt), SMB_negrNTLM_sk_offset);
+    Con_Handle -> SvrTZ = SVAL(SMB_Hdr(pkt), SMB_negrNTLM_stz_offset);
+    Con_Handle -> Encrypt_Key_Len = CVAL(SMB_Hdr(pkt), SMB_negrNTLM_ekl_offset);
+
+    p = (SMB_Hdr(pkt) + SMB_negrNTLM_buf_offset );
+    memcpy(Con_Handle -> Encrypt_Key, p, 8);
+    p = (SMB_Hdr(pkt) + SMB_negrNTLM_buf_offset + Con_Handle -> Encrypt_Key_Len);
+
+    strncpy(p, Con_Handle -> Svr_PDom, sizeof(Con_Handle -> Svr_PDom) - 1);
+
+    break;
+
+  default:
+
+#ifdef DEBUG
+    fprintf(stderr, "Unknown NegProt response format ... Ignored\n");
+    fprintf(stderr, "  wct = %i\n", CVAL(SMB_Hdr(pkt), SMB_hdr_wct_offset));
+#endif
+
+    break;
+  }
+
+#ifdef DEBUG
+  fprintf(stderr, "Protocol selected is: %i:%s\n", prot, Prots[prot]);
+#endif
+
+  RFCNB_Free_Pkt(pkt);
+  return(0);
+
+}
+
+/* Get our hostname */
+
+void SMB_Get_My_Name(char *name, int len)
+
+{ int loc;
+
+  if (gethostname(name, len) < 0) { /* Error getting name */
+
+    strncpy(name, "unknown", len);
+
+    /* Should check the error */
+
+#ifdef DEBUG
+    fprintf(stderr, "gethostname in SMB_Get_My_Name returned error:");
+    perror("");
+#endif
+
+  }
+
+  /* only keep the portion up to the first "." */
+
+
+}
+
+/* Send a TCON to the remote server ...               */
+
+SMB_Tree_Handle SMB_TreeConnect(SMB_Handle_Type Con_Handle, 
+				SMB_Tree_Handle Tree_Handle,
+				char *path, 
+				char *password,
+				char *device)
+
+{ struct RFCNB_Pkt *pkt;
+  int param_len, i, pkt_len;
+  char *p;
+  SMB_Tree_Handle tree;
+
+  /* Figure out how much space is needed for path, password, dev ... */
+
+  if (path == NULL | password == NULL | device == NULL) {
+
+#ifdef DEBUG
+    fprintf(stderr, "Bad parameter passed to SMB_TreeConnect\n");
+#endif
+
+    SMBlib_errno = SMBlibE_BadParam;
+    return(NULL);
+
+  }
+
+  /* The + 2 is because of the \0 and the marker ...                    */
+
+  param_len = strlen(path) + 2 + strlen(password) + 2 + strlen(device) + 2;
+
+  /* The -1 accounts for the one byte smb_buf we have because some systems */
+  /* don't like char msg_buf[]                                             */
+
+  pkt_len = SMB_tcon_len + param_len;
+
+  pkt = (struct RFCNB_Pkt *)RFCNB_Alloc_Pkt(pkt_len);
+
+  if (pkt == NULL) {
+
+    SMBlib_errno = SMBlibE_NoSpace;
+    return(NULL); /* Should handle the error */
+
+  }
+
+  /* Now allocate a tree for this to go into ... */
+
+  if (Tree_Handle == NULL) {
+
+    tree = (SMB_Tree_Handle)malloc(sizeof(struct SMB_Tree_Structure));
+
+    if (tree == NULL) {
+    
+      RFCNB_Free_Pkt(pkt);
+      SMBlib_errno = SMBlibE_NoSpace;
+      return(NULL);
+      
+    }
+  }
+  else {
+
+    tree = Tree_Handle;
+
+  }
+
+  tree -> next = tree -> prev = NULL;
+  tree -> con = Con_Handle;
+  strncpy(tree -> path, path, sizeof(tree -> path));
+  strncpy(tree -> device_type, device, sizeof(tree -> device_type));
+
+  /* Now plug in the values ... */
+
+  bzero(SMB_Hdr(pkt), SMB_tcon_len);
+  SIVAL(SMB_Hdr(pkt), SMB_hdr_idf_offset, SMB_DEF_IDF);  /* Plunk in IDF */
+  *(SMB_Hdr(pkt) + SMB_hdr_com_offset) = SMBtcon;
+  SSVAL(SMB_Hdr(pkt), SMB_hdr_pid_offset, Con_Handle -> pid);
+  SSVAL(SMB_Hdr(pkt), SMB_hdr_tid_offset, 0);
+  SSVAL(SMB_Hdr(pkt), SMB_hdr_mid_offset, Con_Handle -> mid);
+  SSVAL(SMB_Hdr(pkt), SMB_hdr_uid_offset, Con_Handle -> uid);
+  *(SMB_Hdr(pkt) + SMB_hdr_wct_offset) = 0;
+
+  SSVAL(SMB_Hdr(pkt), SMB_tcon_bcc_offset, param_len);
+
+  /* Now copy the param strings in with the right stuff */
+
+  p = (char *)(SMB_Hdr(pkt) + SMB_tcon_buf_offset);
+  *p = SMBasciiID;
+  strcpy(p + 1, path);
+  p = p + strlen(path) + 2;
+  *p = SMBasciiID;
+  strcpy(p + 1, password);
+  p = p + strlen(password) + 2;
+  *p = SMBasciiID;
+  strcpy(p + 1, device);
+
+  /* Now send the packet and sit back ... */
+
+  if (RFCNB_Send(Con_Handle -> Trans_Connect, pkt, pkt_len) < 0){
+
+#ifdef DEBUG
+    fprintf(stderr, "Error sending TCon request\n");
+#endif
+
+    if (Tree_Handle == NULL)
+      free(tree);
+    RFCNB_Free_Pkt(pkt);
+    SMBlib_errno = -SMBlibE_SendFailed;
+    return(NULL);
+
+  }
+
+  /* Now get the response ... */
+
+  if (RFCNB_Recv(Con_Handle -> Trans_Connect, pkt, pkt_len) < 0) {
+
+#ifdef DEBUG
+    fprintf(stderr, "Error receiving response to TCon\n");
+#endif
+
+    if (Tree_Handle == NULL) 
+      free(tree);
+    RFCNB_Free_Pkt(pkt);
+    SMBlib_errno = -SMBlibE_RecvFailed;
+    return(NULL);
+
+  }
+
+  /* Check out the response type ... */
+
+  if (CVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset) != SMBC_SUCCESS) {  /* Process error */
+
+#ifdef DEBUG
+    fprintf(stderr, "SMB_TCon failed with errorclass = %i, Error Code = %i\n",
+	    CVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset),
+	    SVAL(SMB_Hdr(pkt), SMB_hdr_err_offset));
+#endif
+
+    if (Tree_Handle == NULL)
+      free(tree);
+    SMBlib_SMB_Error = IVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset);
+    RFCNB_Free_Pkt(pkt);
+    SMBlib_errno = SMBlibE_Remote;
+    return(NULL);
+
+  }
+
+  tree -> tid = SVAL(SMB_Hdr(pkt), SMB_tconr_tid_offset);
+  tree -> mbs = SVAL(SMB_Hdr(pkt), SMB_tconr_mbs_offset);
+
+#ifdef DEBUG
+  fprintf(stderr, "TConn succeeded, with TID=%i, Max Xmit=%i\n",
+                 tree -> tid, tree -> mbs);
+#endif
+
+  /* Now link the Tree to the Server Structure ... */
+
+  if (Con_Handle -> first_tree == NULL) {
+
+    Con_Handle -> first_tree == tree;
+    Con_Handle -> last_tree == tree;
+
+  }
+  else {
+
+    Con_Handle -> last_tree -> next = tree;
+    tree -> prev = Con_Handle -> last_tree;
+    Con_Handle -> last_tree = tree;
+
+  }
+
+  RFCNB_Free_Pkt(pkt);
+  return(tree); 
+
+}
+
+int SMB_TreeDisconnect(SMB_Tree_Handle Tree_Handle, BOOL discard)
+
+{ struct RFCNB_Pkt *pkt;
+  int pkt_len;
+
+  pkt_len = SMB_tdis_len;
+
+  pkt = (struct RFCNB_Pkt *)RFCNB_Alloc_Pkt(pkt_len);
+
+  if (pkt == NULL) {
+
+    SMBlib_errno = SMBlibE_NoSpace;
+    return(SMBlibE_BAD); /* Should handle the error */
+
+  }
+
+  /* Now plug in the values ... */
+
+  bzero(SMB_Hdr(pkt), SMB_tdis_len);
+  SIVAL(SMB_Hdr(pkt), SMB_hdr_idf_offset, SMB_DEF_IDF);  /* Plunk in IDF */
+  *(SMB_Hdr(pkt) + SMB_hdr_com_offset) = SMBtdis;
+  SSVAL(SMB_Hdr(pkt), SMB_hdr_pid_offset, Tree_Handle -> con -> pid);
+  SSVAL(SMB_Hdr(pkt), SMB_hdr_mid_offset, Tree_Handle -> con -> mid);
+  SSVAL(SMB_Hdr(pkt), SMB_hdr_uid_offset, Tree_Handle -> con -> uid);
+  *(SMB_Hdr(pkt) + SMB_hdr_wct_offset) = 0;
+
+  SSVAL(SMB_Hdr(pkt), SMB_hdr_tid_offset, Tree_Handle -> tid);
+  SSVAL(SMB_Hdr(pkt), SMB_tcon_bcc_offset, 0);
+
+  /* Now send the packet and sit back ... */
+
+  if (RFCNB_Send(Tree_Handle -> con -> Trans_Connect, pkt, pkt_len) < 0){
+
+#ifdef DEBUG
+    fprintf(stderr, "Error sending TDis request\n");
+#endif
+
+    RFCNB_Free_Pkt(pkt);
+    SMBlib_errno = -SMBlibE_SendFailed;
+    return(SMBlibE_BAD);
+
+  }
+
+  /* Now get the response ... */
+
+  if (RFCNB_Recv(Tree_Handle -> con -> Trans_Connect, pkt, pkt_len) < 0) {
+
+#ifdef DEBUG
+    fprintf(stderr, "Error receiving response to TCon\n");
+#endif
+
+    RFCNB_Free_Pkt(pkt);
+    SMBlib_errno = -SMBlibE_RecvFailed;
+    return(SMBlibE_BAD);
+
+  }
+
+  /* Check out the response type ... */
+
+  if (CVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset) != SMBC_SUCCESS) {  /* Process error */
+
+#ifdef DEBUG
+    fprintf(stderr, "SMB_TDis failed with errorclass = %i, Error Code = %i\n",
+	    CVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset),
+	    SVAL(SMB_Hdr(pkt), SMB_hdr_err_offset));
+#endif
+
+    SMBlib_SMB_Error = IVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset);
+    RFCNB_Free_Pkt(pkt);
+    SMBlib_errno = SMBlibE_Remote;
+    return(SMBlibE_BAD);
+
+  }
+
+  Tree_Handle -> tid = 0xFFFF;        /* Invalid TID */
+  Tree_Handle -> mbs = 0;             /* Invalid     */
+
+#ifdef DEBUG
+
+  fprintf(stderr, "Tree disconnect successful ...\n");
+
+#endif
+
+  /* What about the tree handle ? */
+
+  if (discard == TRUE) { /* Unlink it and free it ... */
+
+    if (Tree_Handle -> next == NULL)
+      Tree_Handle -> con -> first_tree = Tree_Handle -> prev;
+    else
+      Tree_Handle -> next -> prev = Tree_Handle -> prev;
+
+    if (Tree_Handle -> prev == NULL)
+      Tree_Handle -> con -> last_tree = Tree_Handle -> next;
+    else
+      Tree_Handle -> prev -> next = Tree_Handle -> next;
+
+  }
+
+  RFCNB_Free_Pkt(pkt);
+  return(0);
+
+}
+
+/* Pick up the last LMBlib error ... */
+
+int SMB_Get_Last_Error()
+
+{
+
+  return(SMBlib_errno);
+
+}
+
+/* Pick up the last error returned in an SMB packet          */
+/* We will need macros to extract error class and error code */
+
+int SMB_Get_Last_SMB_Err()
+
+{
+
+  return(SMBlib_SMB_Error);
+
+}
+
+/* Pick up the error message associated with an error from SMBlib  */
+
+/* Keep this table in sync with the message codes in smblib-common.h */
+
+static char *SMBlib_Error_Messages[] = {
+
+  "Request completed sucessfully.",
+  "Server returned a non-zero SMB Error Class and Code.",
+  "A lower layer protocol error occurred.",
+  "Function not yet implemented.",
+  "The protocol negotiated does not support the request.",
+  "No space available for operation.",
+  "One or more bad parameters passed.",
+  "None of the protocols we offered were accepted.",
+  "The attempt to send an SMB request failed. See protocol error info.",
+  "The attempt to get an SMB response failed. See protocol error info.",
+  "The logon request failed, but you were logged in as guest.",
+  "The attempt to call the remote server failed. See protocol error info.",
+  "The protocol dialect specified in a NegProt and accepted by the server is unknown.",
+  /* This next one simplifies error handling */
+  "No such error code.",
+  NULL};
+
+int SMB_Get_Error_Msg(int msg, char *msgbuf, int len)
+
+{
+
+  if (msg >= 0) {
+
+    strncpy(msgbuf, 
+	    SMBlib_Error_Messages[msg>SMBlibE_NoSuchMsg?SMBlibE_NoSuchMsg:msg],
+	    len - 1);
+    msgbuf[len - 1] = 0; /* Make sure it is a string */
+  }
+  else { /* Add the lower layer message ... */
+
+    char prot_msg[1024];
+
+    msg = -msg;   /* Make it positive */
+
+    strncpy(msgbuf,
+	    SMBlib_Error_Messages[msg>SMBlibE_NoSuchMsg?SMBlibE_NoSuchMsg:msg],
+	    len - 1);
+
+    msgbuf[len - 1] = 0; /* make sure it is a string */
+
+    if (strlen(msgbuf) < len) { /* If there is space, put rest in */
+
+      strncat(msgbuf, "\n\t", len - strlen(msgbuf));
+
+      RFCNB_Get_Error(prot_msg, sizeof(prot_msg) - 1);
+
+      strncat(msgbuf, prot_msg, len - strlen(msgbuf));
+
+    }
+  }
+
+}
--- /dev/null	Wed Feb 14 00:44:43 2007
+++ squid/ntlm_auth_modules/NTLMSSP/smbval/smblib.c	Wed Feb 14 00:45:14 2007
@@ -0,0 +1,570 @@
+/* UNIX SMBlib NetBIOS implementation
+
+   Version 1.0
+   SMBlib Routines
+
+   Copyright (C) Richard Sharpe 1996
+
+*/
+
+/*
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+   
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+   
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "config.h"
+#include <malloc.h>
+
+int SMBlib_errno;
+int SMBlib_SMB_Error;
+#define SMBLIB_ERRNO
+#define uchar unsigned char
+#include "smblib-priv.h"
+
+#include "rfcnb.h"
+
+#include <signal.h>
+
+SMB_State_Types SMBlib_State;
+
+/* Initialize the SMBlib package     */
+
+int SMB_Init()
+
+{
+
+  SMBlib_State = SMB_State_Started;
+
+  signal(SIGPIPE, SIG_IGN);   /* Ignore these ... */
+
+/* If SMBLIB_Instrument is defines, turn on the instrumentation stuff */
+#ifdef SMBLIB_INSTRUMENT
+
+  SMBlib_Instrument_Init();
+
+#endif
+
+  return 0;
+
+}
+
+int SMB_Term()
+
+{
+
+#ifdef SMBLIB_INSTRUMENT
+
+  SMBlib_Instrument_Term();       /* Clean up and print results */
+
+#endif
+
+  return 0;
+
+}
+
+/* SMB_Create: Create a connection structure and return for later use */
+/* We have other helper routines to set variables                     */
+
+SMB_Handle_Type SMB_Create_Con_Handle()
+
+{
+
+  SMBlib_errno = SMBlibE_NotImpl;
+  return(NULL);
+
+}
+
+int SMBlib_Set_Sock_NoDelay(SMB_Handle_Type Con_Handle, BOOL yn)
+
+{
+
+
+  if (RFCNB_Set_Sock_NoDelay(Con_Handle -> Trans_Connect, yn) < 0) {
+
+#ifdef DEBUG
+#endif
+
+    fprintf(stderr, "Setting no-delay on TCP socket failed ...\n");
+
+  }
+
+  return(0);
+
+}
+
+/* SMB_Connect_Server: Connect to a server, but don't negotiate protocol */
+/* or anything else ...                                                  */
+
+SMB_Handle_Type SMB_Connect_Server(SMB_Handle_Type Con_Handle,
+				   char *server, char *NTdomain)
+
+{ SMB_Handle_Type con;
+  char temp[80], called[80], calling[80], *address;
+  int i;
+
+  /* Get a connection structure if one does not exist */
+
+  con = Con_Handle;
+
+  if (Con_Handle == NULL) {
+
+    if ((con = (struct SMB_Connect_Def *)malloc(sizeof(struct SMB_Connect_Def))) == NULL) {
+
+
+      SMBlib_errno = SMBlibE_NoSpace;
+      return NULL;
+    }
+
+  }
+
+  /* Init some things ... */
+
+  strcpy(con -> service, "");
+  strcpy(con -> username, "");
+  strcpy(con -> password, "");
+  strcpy(con -> sock_options, "");
+  strcpy(con -> address, "");
+  strcpy(con -> desthost, server);
+  strcpy(con -> PDomain, NTdomain);
+  strcpy(con -> OSName, SMBLIB_DEFAULT_OSNAME);
+  strcpy(con -> LMType, SMBLIB_DEFAULT_LMTYPE);
+  con -> first_tree = con -> last_tree = NULL; 
+
+  SMB_Get_My_Name(con -> myname, sizeof(con -> myname));
+
+  con -> port = 0;                    /* No port selected */
+
+  /* Get some things we need for the SMB Header */
+
+  con -> pid = getpid();
+  con -> mid = con -> pid;      /* This will do for now ... */
+  con -> uid = 0;               /* Until we have done a logon, no uid ... */ 
+  con -> gid = getgid();
+
+  /* Now connect to the remote end, but first upper case the name of the
+     service we are going to call, sine some servers want it in uppercase */
+
+  for (i=0; i < strlen(server); i++)
+    called[i] = toupper(server[i]);
+		       
+  called[strlen(server)] = 0;    /* Make it a string */
+
+  for (i=0; i < strlen(con -> myname); i++)
+    calling[i] = toupper(con -> myname[i]);
+		       
+  calling[strlen(con -> myname)] = 0;    /* Make it a string */
+
+  if (strcmp(con -> address, "") == 0)
+    address = con -> desthost;
+  else
+    address = con -> address;
+
+  con -> Trans_Connect = RFCNB_Call(called,
+				    calling,
+				    address, /* Protocol specific */
+				    con -> port);
+
+  /* Did we get one? */
+
+  if (con -> Trans_Connect == NULL) {
+
+    if (Con_Handle == NULL) {
+      Con_Handle = NULL;
+      free(con);
+    }
+    SMBlib_errno = -SMBlibE_CallFailed;
+    return NULL;
+
+  }
+
+  return(con);
+
+}
+
+/* SMB_Connect: Connect to the indicated server                       */
+/* If Con_Handle == NULL then create a handle and connect, otherwise  */
+/* use the handle passed                                              */
+
+char *SMB_Prots_Restrict[] = {"PC NETWORK PROGRAM 1.0",
+			      NULL};
+
+
+SMB_Handle_Type SMB_Connect(SMB_Handle_Type Con_Handle,
+			    SMB_Tree_Handle *tree,
+			    char *service, 
+			    char *username, 
+			    char *password)
+
+{ SMB_Handle_Type con;
+  char *host, *address;
+  char temp[80], called[80], calling[80];
+  int i;
+
+  /* Get a connection structure if one does not exist */
+
+  con = Con_Handle;
+
+  if (Con_Handle == NULL) {
+
+    if ((con = (struct SMB_Connect_Def *)malloc(sizeof(struct SMB_Connect_Def))) == NULL) {
+
+      SMBlib_errno = SMBlibE_NoSpace;
+      return NULL;
+    }
+
+  }
+
+  /* Init some things ... */
+
+  strcpy(con -> service, service);
+  strcpy(con -> username, username);
+  strcpy(con -> password, password);
+  strcpy(con -> sock_options, "");
+  strcpy(con -> address, "");
+  strcpy(con -> PDomain, SMBLIB_DEFAULT_DOMAIN);
+  strcpy(con -> OSName, SMBLIB_DEFAULT_OSNAME);
+  strcpy(con -> LMType, SMBLIB_DEFAULT_LMTYPE);
+  con -> first_tree = con -> last_tree = NULL;
+
+  SMB_Get_My_Name(con -> myname, sizeof(con -> myname));
+
+  con -> port = 0;                    /* No port selected */
+
+  /* Get some things we need for the SMB Header */
+
+  con -> pid = getpid();
+  con -> mid = con -> pid;      /* This will do for now ... */
+  con -> uid = 0;               /* Until we have done a logon, no uid */
+  con -> gid = getgid();
+
+  /* Now figure out the host portion of the service */
+
+  strcpy(temp, service);
+  host = (char *)strtok(temp, "/\\");     /* Separate host name portion */
+  strcpy(con -> desthost, host);
+
+  /* Now connect to the remote end, but first upper case the name of the
+     service we are going to call, sine some servers want it in uppercase */
+
+  for (i=0; i < strlen(host); i++)
+    called[i] = toupper(host[i]);
+		       
+  called[strlen(host)] = 0;    /* Make it a string */
+
+  for (i=0; i < strlen(con -> myname); i++)
+    calling[i] = toupper(con -> myname[i]);
+		       
+  calling[strlen(con -> myname)] = 0;    /* Make it a string */
+
+  if (strcmp(con -> address, "") == 0)
+    address = con -> desthost;
+  else
+    address = con -> address;
+
+  con -> Trans_Connect = RFCNB_Call(called,
+				    calling,
+				    address, /* Protocol specific */
+				    con -> port);
+
+  /* Did we get one? */
+
+  if (con -> Trans_Connect == NULL) {
+
+    if (Con_Handle == NULL) {
+      free(con);
+      Con_Handle = NULL;
+    }
+    SMBlib_errno = -SMBlibE_CallFailed;
+    return NULL;
+
+  }
+
+  /* Now, negotiate the protocol */
+
+  if (SMB_Negotiate(con, SMB_Prots_Restrict) < 0) {
+
+    /* Hmmm what should we do here ... We have a connection, but could not
+       negotiate ...                                                      */
+
+    return NULL;
+
+  }
+
+  /* Now connect to the service ... */
+
+  if ((*tree = SMB_TreeConnect(con, NULL, service, password, "A:")) == NULL) {
+
+    return NULL;
+
+  }
+
+  return(con);
+
+}
+
+/* Logon to the server. That is, do a session setup if we can. We do not do */
+/* Unicode yet!                                                             */
+
+int SMB_Logon_Server(SMB_Handle_Type Con_Handle, char *UserName, 
+		     char *PassWord, int precrypted)
+
+{ struct RFCNB_Pkt *pkt;
+  int param_len, i, pkt_len, pass_len,a;
+  char *p, pword[128];
+
+  /* First we need a packet etc ... but we need to know what protocol has  */
+  /* been negotiated to figure out if we can do it and what SMB format to  */
+  /* use ...                                                               */
+
+  if (Con_Handle -> protocol < SMB_P_LanMan1) {
+
+    SMBlib_errno = SMBlibE_ProtLow;
+    return(SMBlibE_BAD);
+
+  }
+
+  if (precrypted) {
+      pass_len=24;
+      memcpy(pword, PassWord, 24);
+  } else {
+      strcpy(pword, PassWord);
+      if (Con_Handle -> encrypt_passwords)
+      {
+          pass_len=24;
+          SMBencrypt((uchar *) PassWord, (uchar *)Con_Handle -> Encrypt_Key,(uchar *)pword);
+      } else pass_len=strlen(pword);
+  }
+
+  /* Now build the correct structure */
+
+  if (Con_Handle -> protocol < SMB_P_NT1) {
+
+    param_len = strlen(UserName) + 1 + pass_len + 1 + 
+                strlen(Con_Handle -> PDomain) + 1 + 
+	        strlen(Con_Handle -> OSName) + 1;
+
+    pkt_len = SMB_ssetpLM_len + param_len;
+
+    pkt = (struct RFCNB_Pkt *)RFCNB_Alloc_Pkt(pkt_len);
+
+    if (pkt == NULL) {
+
+      SMBlib_errno = SMBlibE_NoSpace;
+      return(SMBlibE_BAD); /* Should handle the error */
+
+    }
+
+    bzero(SMB_Hdr(pkt), SMB_ssetpLM_len);
+    SIVAL(SMB_Hdr(pkt), SMB_hdr_idf_offset, SMB_DEF_IDF);  /* Plunk in IDF */
+    *(SMB_Hdr(pkt) + SMB_hdr_com_offset) = SMBsesssetupX;
+    SSVAL(SMB_Hdr(pkt), SMB_hdr_pid_offset, Con_Handle -> pid);
+    SSVAL(SMB_Hdr(pkt), SMB_hdr_tid_offset, 0);
+    SSVAL(SMB_Hdr(pkt), SMB_hdr_mid_offset, Con_Handle -> mid);
+    SSVAL(SMB_Hdr(pkt), SMB_hdr_uid_offset, Con_Handle -> uid);
+    *(SMB_Hdr(pkt) + SMB_hdr_wct_offset) = 10;
+    *(SMB_Hdr(pkt) + SMB_hdr_axc_offset) = 0xFF;    /* No extra command */
+    SSVAL(SMB_Hdr(pkt), SMB_hdr_axo_offset, 0);
+
+    SSVAL(SMB_Hdr(pkt), SMB_ssetpLM_mbs_offset, SMBLIB_MAX_XMIT);
+    SSVAL(SMB_Hdr(pkt), SMB_ssetpLM_mmc_offset, 2);
+    SSVAL(SMB_Hdr(pkt), SMB_ssetpLM_vcn_offset, Con_Handle -> pid);
+    SIVAL(SMB_Hdr(pkt), SMB_ssetpLM_snk_offset, 0);
+    SSVAL(SMB_Hdr(pkt), SMB_ssetpLM_pwl_offset, pass_len + 1);
+    SIVAL(SMB_Hdr(pkt), SMB_ssetpLM_res_offset, 0);
+    SSVAL(SMB_Hdr(pkt), SMB_ssetpLM_bcc_offset, param_len);
+
+    /* Now copy the param strings in with the right stuff */
+
+    p = (char *)(SMB_Hdr(pkt) + SMB_ssetpLM_buf_offset);
+
+    /* Copy  in password, then the rest. Password has a null at end */
+
+    memcpy(p, pword, pass_len);
+
+    p = p + pass_len + 1;
+
+    strcpy(p, UserName);
+    p = p + strlen(UserName);
+    *p = 0;
+
+    p = p + 1;
+
+    strcpy(p, Con_Handle -> PDomain);
+    p = p + strlen(Con_Handle -> PDomain);
+    *p = 0;
+    p = p + 1;
+
+    strcpy(p, Con_Handle -> OSName);
+    p = p + strlen(Con_Handle -> OSName);
+    *p = 0;
+
+  }
+  else {
+
+    /* We don't admit to UNICODE support ... */
+
+    param_len = strlen(UserName) + 1 + pass_len + 
+                strlen(Con_Handle -> PDomain) + 1 + 
+	        strlen(Con_Handle -> OSName) + 1 +
+		strlen(Con_Handle -> LMType) + 1;
+
+    pkt_len = SMB_ssetpNTLM_len + param_len;
+
+    pkt = (struct RFCNB_Pkt *)RFCNB_Alloc_Pkt(pkt_len);
+
+    if (pkt == NULL) {
+
+      SMBlib_errno = SMBlibE_NoSpace;
+      return(-1); /* Should handle the error */
+
+    }
+
+    bzero(SMB_Hdr(pkt), SMB_ssetpNTLM_len);
+    SIVAL(SMB_Hdr(pkt), SMB_hdr_idf_offset, SMB_DEF_IDF);  /* Plunk in IDF */
+    *(SMB_Hdr(pkt) + SMB_hdr_com_offset) = SMBsesssetupX;
+    SSVAL(SMB_Hdr(pkt), SMB_hdr_pid_offset, Con_Handle -> pid);
+    SSVAL(SMB_Hdr(pkt), SMB_hdr_tid_offset, 0);
+    SSVAL(SMB_Hdr(pkt), SMB_hdr_mid_offset, Con_Handle -> mid);
+    SSVAL(SMB_Hdr(pkt), SMB_hdr_uid_offset, Con_Handle -> uid);
+    *(SMB_Hdr(pkt) + SMB_hdr_wct_offset) = 13;
+    *(SMB_Hdr(pkt) + SMB_hdr_axc_offset) = 0xFF;    /* No extra command */
+    SSVAL(SMB_Hdr(pkt), SMB_hdr_axo_offset, 0);
+
+    SSVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_mbs_offset, SMBLIB_MAX_XMIT);
+    SSVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_mmc_offset, 0);
+    SSVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_vcn_offset, 0);
+    SIVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_snk_offset, 0);
+    SSVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_cipl_offset, pass_len);
+    SSVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_cspl_offset, 0);
+    SIVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_res_offset, 0);
+    SIVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_cap_offset, 0);
+    SSVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_bcc_offset, param_len);
+
+    /* Now copy the param strings in with the right stuff */
+
+    p = (char *)(SMB_Hdr(pkt) + SMB_ssetpNTLM_buf_offset);
+
+    /* Copy  in password, then the rest. Password has no null at end */
+
+    memcpy(p, pword, pass_len);
+
+    p = p + pass_len;
+
+    strcpy(p, UserName);
+    p = p + strlen(UserName);
+    *p = 0;
+
+    p = p + 1;
+
+    strcpy(p, Con_Handle -> PDomain);
+    p = p + strlen(Con_Handle -> PDomain);
+  *p = 0;
+    p = p + 1;
+
+    strcpy(p, Con_Handle -> OSName);
+    p = p + strlen(Con_Handle -> OSName);
+    *p = 0;
+    p = p + 1;
+
+    strcpy(p, Con_Handle -> LMType);
+    p = p + strlen(Con_Handle -> LMType);
+    *p = 0;
+
+  }
+
+  /* Now send it and get a response */
+
+  if (RFCNB_Send(Con_Handle -> Trans_Connect, pkt, pkt_len) < 0){
+
+#ifdef DEBUG
+    fprintf(stderr, "Error sending SessSetupX request\n");
+#endif
+
+    RFCNB_Free_Pkt(pkt);
+    SMBlib_errno = SMBlibE_SendFailed;
+    return(SMBlibE_BAD);
+
+  }
+
+  /* Now get the response ... */
+
+  if (RFCNB_Recv(Con_Handle -> Trans_Connect, pkt, pkt_len) < 0) {
+
+#ifdef DEBUG
+    fprintf(stderr, "Error receiving response to SessSetupAndX\n");
+#endif
+
+    RFCNB_Free_Pkt(pkt);
+    SMBlib_errno = SMBlibE_RecvFailed;
+    return(SMBlibE_BAD);
+
+  }
+
+  /* Check out the response type ... */
+
+  if (CVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset) != SMBC_SUCCESS) {  /* Process error */
+
+#ifdef DEBUG
+    fprintf(stderr, "SMB_SessSetupAndX failed with errorclass = %i, Error Code = %i\n",
+	    CVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset),
+	    SVAL(SMB_Hdr(pkt), SMB_hdr_err_offset));
+#endif
+
+    SMBlib_SMB_Error = IVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset);
+    RFCNB_Free_Pkt(pkt);
+    SMBlib_errno = SMBlibE_Remote;
+    return(SMBlibE_BAD);
+
+  }
+/** @@@ mdz: check for guest login { **/
+       if (SVAL(SMB_Hdr(pkt), SMB_ssetpr_act_offset) & 0x1)
+       {
+               /* do we allow guest login? NO! */
+               return(SMBlibE_BAD);
+ 
+       }
+ /** @@@ mdz: } **/
+
+
+#ifdef DEBUG
+  fprintf(stderr, "SessSetupAndX response. Action = %i\n", 
+          SVAL(SMB_Hdr(pkt), SMB_ssetpr_act_offset));
+#endif
+
+  /* Now pick up the UID for future reference ... */
+
+  Con_Handle -> uid = SVAL(SMB_Hdr(pkt), SMB_hdr_uid_offset);
+  RFCNB_Free_Pkt(pkt);
+
+  return(0);
+
+}
+
+
+/* Disconnect from the server, and disconnect all tree connects */
+
+int SMB_Discon(SMB_Handle_Type Con_Handle, BOOL KeepHandle)
+
+{
+
+  /* We just disconnect the connection for now ... */
+
+  RFCNB_Hangup(Con_Handle -> Trans_Connect);
+
+  if (!KeepHandle)
+    free(Con_Handle);
+
+  return(0);
+
+}
--- /dev/null	Wed Feb 14 00:44:43 2007
+++ squid/ntlm_auth_modules/NTLMSSP/smbval/smblib.h	Wed Feb 14 00:45:14 2007
@@ -0,0 +1,97 @@
+/* UNIX SMBlib NetBIOS implementation
+
+   Version 1.0
+   SMBlib Defines
+
+   Copyright (C) Richard Sharpe 1996
+
+*/
+
+/*
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+   
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+   
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "std-defines.h"
+#include "smblib-common.h"
+
+/* Just define all the entry points */
+
+/* Create a handle to allow us to set/override some parameters ...       */
+
+void *SMB_Create_Con_Handle();
+
+/* Connect to a server, but do not do a tree con etc ... */
+
+void *SMB_Connect_Server(void *Con, char *server, char *NTdomain);
+
+/* Connect to a server and give us back a handle. If Con == NULL, create */
+/* The handle and populate it with defaults                              */
+
+void *SMB_Connect(void *Con, void **tree, 
+		  char *name, char *User, char *Password);
+
+/* Negotiate a protocol                                                  */
+
+int SMB_Negotiate(void *Con_Handle, char *Prots[]);
+
+/* Connect to a tree ...                                                 */
+
+void *SMB_TreeConnect(void *con_handle, void *tree_handle, 
+		      char *path, char *password, char *dev);
+
+/* Disconnect a tree ...                                                 */
+
+int SMB_TreeDisconect(void *tree_handle);
+
+/* Open a file                                                           */
+
+void *SMB_Open(void *tree_handle,
+	       void *file_handle,
+	       char *file_name,
+	       unsigned short mode,
+	       unsigned short search); 
+
+/* Close a file                                                          */
+
+int SMB_Close(void *file_handle);
+
+/* Disconnect from server. Has flag to specify whether or not we keep the */
+/* handle.                                                                */
+
+int SMB_Discon(void *Con, BOOL KeepHandle);
+
+void *SMB_Create(void *Tree_Handle,
+	       void *File_Handle, 
+	       char *file_name, 
+  	       short search);
+
+int SMB_Delete(void *tree, char *file_name, short search);
+
+int SMB_Create_Dir(void *tree, char *dir_name);
+
+int SMB_Delete_Dir(void *tree, char *dir_name);
+
+int SMB_Check_Dir(void *tree, char *dir_name);
+
+int SMB_Get_Last_Error();
+
+int SMB_Get_Last_SMB_Err();
+
+int SMB_Get_Error_Msg(int msg, char *msgbuf, int len);
+
+void *SMB_Logon_And_TCon(void *con, void *tree, char *user, char *pass,
+			 char *service, char *st);
+
+#define SMBLIB_DEFAULT_DOMAIN "anydom"
--- /dev/null	Wed Feb 14 00:44:43 2007
+++ squid/ntlm_auth_modules/NTLMSSP/smbval/std-defines.h	Wed Feb 14 00:45:14 2007
@@ -0,0 +1,40 @@
+/* RFCNB Standard includes ... */
+/*
+
+   SMBlib Standard Includes
+
+   Copyright (C) 1996, Richard Sharpe
+
+/* One day we will conditionalize these on OS types ... */
+
+/*
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+   
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+   
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#define BOOL int
+typedef short int16;
+
+#include <netdb.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <signal.h>
+#include <errno.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <strings.h>
+
+#define TRUE 1
+#define FALSE 0
--- /dev/null	Wed Feb 14 00:44:43 2007
+++ squid/ntlm_auth_modules/NTLMSSP/smbval/std-includes.h	Wed Feb 14 00:45:14 2007
@@ -0,0 +1,45 @@
+/* RFCNB Standard includes ... */
+/*
+
+   RFCNB Standard Includes
+
+   Copyright (C) 1996, Richard Sharpe
+
+ One day we will conditionalize these on OS types ... */
+
+/*
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+   
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+   
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#define BOOL int
+typedef short int16;
+
+#include <netdb.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <signal.h>
+#include <errno.h>
+#include <stdio.h>
+#include <unistd.h>
+
+#define TRUE 1
+#define FALSE 0
+
+/* Pick up define for INADDR_NONE */
+
+#ifndef INADDR_NONE
+#define INADDR_NONE -1
+#endif
--- /dev/null	Wed Feb 14 00:44:43 2007
+++ squid/ntlm_auth_modules/NTLMSSP/smbval/valid.c	Wed Feb 14 00:45:14 2007
@@ -0,0 +1,104 @@
+#include <sys/types.h>
+#include <unistd.h>
+#include <syslog.h>
+#include "smblib-priv.h"
+#include "valid.h"
+
+SMB_Handle_Type SMB_Connect_Server(void *, char *, char *);
+
+int Valid_User(char *USERNAME,char *PASSWORD,char *SERVER,char *BACKUP, char *DOMAIN)
+{
+	int pass_is_precrypted_p=0;
+  char *SMB_Prots[] = {
+/* 		"PC NETWORK PROGRAM 1.0", */
+/* 		"MICROSOFT NETWORKS 1.03", */
+/* 		"MICROSOFT NETWORKS 3.0", */
+		"LANMAN1.0",
+		"LM1.2X002",
+		"Samba",
+/* 		"NT LM 0.12", */
+/* 		"NT LANMAN 1.0", */
+		NULL};
+  SMB_Handle_Type con;
+
+  SMB_Init();
+  con = SMB_Connect_Server(NULL, SERVER, DOMAIN);
+  if (con == NULL) { /* Error ... */
+   con = SMB_Connect_Server(NULL, BACKUP, DOMAIN);
+   if (con == NULL) {
+   	return(NTV_SERVER_ERROR);   
+   }
+  }
+  if (SMB_Negotiate(con, SMB_Prots) < 0) { /* An error */
+    SMB_Discon(con,0);
+    return(NTV_PROTOCOL_ERROR);
+  }
+  /* Test for a server in share level mode do not authenticate against it */
+  if (con -> Security == 0)
+    {
+      SMB_Discon(con,0);
+      return(NTV_PROTOCOL_ERROR);
+    }
+
+  if (SMB_Logon_Server(con, USERNAME, PASSWORD, pass_is_precrypted_p) < 0) {
+    SMB_Discon(con,0);
+    return(NTV_LOGON_ERROR);
+  }
+  
+  SMB_Discon(con,0);
+  return(NTV_NO_ERROR);
+}
+
+void *NTLM_Connect(char *SERVER,char *BACKUP, char *DOMAIN, char *nonce)
+{
+  char *SMB_Prots[] = {
+/* 		"PC NETWORK PROGRAM 1.0", */
+/* 		"MICROSOFT NETWORKS 1.03", */
+/* 		"MICROSOFT NETWORKS 3.0", */
+		"LANMAN1.0",
+		"LM1.2X002",
+		"Samba",
+/* 		"NT LM 0.12", */
+/* 		"NT LANMAN 1.0", */
+		NULL};
+  SMB_Handle_Type con;
+
+  SMB_Init();
+  con = SMB_Connect_Server(NULL, SERVER, DOMAIN);
+  if (con == NULL) { /* Error ... */
+   con = SMB_Connect_Server(NULL, BACKUP, DOMAIN);
+   if (con == NULL) {
+   	return(NULL);
+   }
+  }
+  if (SMB_Negotiate(con, SMB_Prots) < 0) { /* An error */
+    SMB_Discon(con,0);
+    return(NULL);
+  }
+  /* Test for a server in share level mode do not authenticate against it */
+  if (con -> Security == 0)
+    {
+      SMB_Discon(con,0);
+      return(NULL);
+    }
+
+  memcpy(nonce, con -> Encrypt_Key, 8);
+     
+  return (con);
+}
+
+int NTLM_Auth(void *handle, char *USERNAME,char *PASSWORD,int flag)
+{
+  SMB_Handle_Type con = handle;
+
+  if (SMB_Logon_Server(con, USERNAME, PASSWORD, flag) < 0) {
+    return(NTV_LOGON_ERROR);
+  }
+  return(NTV_NO_ERROR);
+}
+
+void NTLM_Disconnect(void *handle)
+{
+  SMB_Handle_Type con = handle;
+  SMB_Discon(con);
+}
--- /dev/null	Wed Feb 14 00:44:43 2007
+++ squid/ntlm_auth_modules/NTLMSSP/smbval/valid.h	Wed Feb 14 00:45:14 2007
@@ -0,0 +1,15 @@
+#ifndef _VALID_H_
+#define _VALID_H_
+/* SMB User verification function */
+
+#define NTV_NO_ERROR 0
+#define NTV_SERVER_ERROR 1
+#define NTV_PROTOCOL_ERROR 2
+#define NTV_LOGON_ERROR 3
+
+int Valid_User(char *USERNAME,char *PASSWORD,char *SERVER, char *BACKUP, char *DOMAIN);
+void *NTLM_Connect(char *SERVER, char *BACKUP, char *DOMAIN, char *nonce);
+int NTLM_Auth(void *handle, char *USERNAME,char *PASSWORD, int flag);
+void NTLM_Disconnect(void *handle);
+
+#endif
