---------------------
PatchSet 4075 
Date: 2002/04/26 19:52:06
Author: serassio
Branch: nt-2_5
Tag: (none) 
Log:
Added Group membership check to native NT NTLM authenticator

Members: 
	src/auth/ntlm/helpers/NTLMSSP-WIN32/libntlmssp.c:1.1.2.1->1.1.2.2 
	src/auth/ntlm/helpers/NTLMSSP-WIN32/libsspwin32.c:1.1.2.1->1.1.2.2 
	src/auth/ntlm/helpers/NTLMSSP-WIN32/ntlm.h:1.1.2.1->1.1.2.2 
	src/auth/ntlm/helpers/NTLMSSP-WIN32/ntlm_auth.c:1.1.2.1->1.1.2.2 
	src/auth/ntlm/helpers/NTLMSSP-WIN32/readme.txt:1.1->1.1.2.1 

Index: squid/src/auth/ntlm/helpers/NTLMSSP-WIN32/libntlmssp.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/auth/ntlm/helpers/NTLMSSP-WIN32/Attic/libntlmssp.c,v
retrieving revision 1.1.2.1
retrieving revision 1.1.2.2
diff -u -r1.1.2.1 -r1.1.2.2
--- squid/src/auth/ntlm/helpers/NTLMSSP-WIN32/libntlmssp.c	21 Apr 2002 20:35:06 -0000	1.1.2.1
+++ squid/src/auth/ntlm/helpers/NTLMSSP-WIN32/libntlmssp.c	26 Apr 2002 19:52:06 -0000	1.1.2.2
@@ -1,5 +1,6 @@
 /*
- * (C) 2000 Francesco Chemolli <kinkie@kame.usr.dsi.unimi.it>
+ * (C) 2002 Guido Serassio <serassio@libero.it>
+ * Based on previous work of Francesco Chemolli and Robert Collins
  * Distributed freely under the terms of the GNU General Public License,
  * version 2. See the file COPYING for licensing details
  *
@@ -17,6 +18,8 @@
 
 #include "squid.h"
 #include "ntlm.h"
+#include <assert.h>
+#include <lm.h>
 
 #ifdef DEBUG
 #define debug_dump_ntlmssp_flags dump_ntlmssp_flags
@@ -34,6 +37,75 @@
 static char lmencoded_empty_pass[ENCODED_PASS_LEN],
 	ntencoded_empty_pass[ENCODED_PASS_LEN];
 
+/* returns 1 on success, 0 on failure */
+int
+Valid_Group(char *UserName, char *Group)
+{
+    int result = FALSE;
+    WCHAR wszUserName[256];	// Unicode user name
+    WCHAR wszGroup[256];	// Unicode Group
+
+    LPLOCALGROUP_USERS_INFO_0 pBuf = NULL;
+    LPLOCALGROUP_USERS_INFO_0 pTmpBuf;
+    DWORD dwLevel = 0;
+    DWORD dwFlags = LG_INCLUDE_INDIRECT;
+    DWORD dwPrefMaxLen = -1;
+    DWORD dwEntriesRead = 0;
+    DWORD dwTotalEntries = 0;
+    NET_API_STATUS nStatus;
+    DWORD i;
+    DWORD dwTotalCount = 0;
+
+/* Convert ANSI User Name and Group to Unicode */
+
+    MultiByteToWideChar(CP_ACP, 0, UserName,
+	strlen(UserName) + 1, wszUserName,
+	sizeof(wszUserName) / sizeof(wszUserName[0]));
+    MultiByteToWideChar(CP_ACP, 0, Group,
+	strlen(Group) + 1, wszGroup, sizeof(wszGroup) / sizeof(wszGroup[0]));
+
+    /*
+     * Call the NetUserGetLocalGroups function 
+	 * specifying information level 0.
+	 * 
+	 * The LG_INCLUDE_INDIRECT flag specifies that the 
+	 * function should also return the names of the local 
+	 * groups in which the user is indirectly a member.
+	 */
+	nStatus = NetUserGetLocalGroups(NULL,
+	    wszUserName,
+	    dwLevel,
+	    dwFlags,
+	    (LPBYTE *) & pBuf, dwPrefMaxLen, &dwEntriesRead, &dwTotalEntries);
+	/*
+	 * If the call succeeds,
+	 */
+    if (nStatus == NERR_Success) {
+	if ((pTmpBuf = pBuf) != NULL) {
+	    for (i = 0; i < dwEntriesRead; i++) {
+		assert(pTmpBuf != NULL);
+		if (pTmpBuf == NULL) {
+		    result = FALSE;
+		    break;
+		}
+		if (wcscmp(pTmpBuf->lgrui0_name, wszGroup) == 0) {
+		    result = TRUE;
+		    break;
+		}
+		pTmpBuf++;
+		dwTotalCount++;
+	    }
+	}
+    } else
+	    result = FALSE;
+/*
+ * Free the allocated memory.
+ */
+    if (pBuf != NULL)
+	NetApiBufferFree(pBuf);
+    return result;
+}
+
 /* returns 0 on success, > 0 on failure */
 static int
 init_challenge(void)
@@ -207,6 +279,21 @@
 	return NULL;
     }
     *(user - 1) = '\\';		/* hack. Performing, but ugly. */
+    
+    if (UseAllowedGroup) {
+	if (!Valid_Group(credentials, NTAllowedGroup)) {
+	    ntlm_errno = NTLM_BAD_NTGROUP;
+	    debug("User %s not in allowed Group %s\n", credentials, NTAllowedGroup);
+	    return NULL;
+	}
+    }
+    if (UseDisallowedGroup) {
+	if (Valid_Group(credentials, NTDisAllowedGroup)) {
+	    ntlm_errno = NTLM_BAD_NTGROUP;
+	    debug("User %s is in denied Group %s\n", credentials, NTDisAllowedGroup);
+	    return NULL;
+	}
+    }
 
     debug("credentials: %s\n", credentials);
     return credentials;
Index: squid/src/auth/ntlm/helpers/NTLMSSP-WIN32/libsspwin32.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/auth/ntlm/helpers/NTLMSSP-WIN32/Attic/libsspwin32.c,v
retrieving revision 1.1.2.1
retrieving revision 1.1.2.2
diff -u -r1.1.2.1 -r1.1.2.2
--- squid/src/auth/ntlm/helpers/NTLMSSP-WIN32/libsspwin32.c	21 Apr 2002 20:35:06 -0000	1.1.2.1
+++ squid/src/auth/ntlm/helpers/NTLMSSP-WIN32/libsspwin32.c	26 Apr 2002 19:52:07 -0000	1.1.2.2
@@ -1,16 +1,19 @@
-   /////////////////////////////////////////////////////////////////////////////// 
-  // 
-  //  SSPI Authentication Sample
-  // 
-  //  This program demonstrates how to use SSPI to authenticate user credentials.
-  // 
-  //  THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
-  //  ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED
-  //  TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
-  //  PARTICULAR PURPOSE.
-  // 
-  //  Copyright (C) 2001.  Microsoft Corporation.  All rights reserved.
-  /////////////////////////////////////////////////////////////////////////////// 
+/*
+ * (C) 2002 Guido Serassio <serassio@libero.it>
+ * Based on previous work of Francesco Chemolli, Robert Collins
+ *
+ * Distributed freely under the terms of the GNU General Public License,
+ * version 2. See the file COPYING for licensing details
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
+ */
  
 #include "squid.h"
 #include "ntlm.h"
@@ -27,23 +30,21 @@
 static HMODULE hModule = NULL;
 SECURITY_STATUS ss = SEC_E_OK;
  
-// Function pointers
-ACCEPT_SECURITY_CONTEXT_FN	_AcceptSecurityContext     = NULL;
-ACQUIRE_CREDENTIALS_HANDLE_FN	_AcquireCredentialsHandle  = NULL;
-COMPLETE_AUTH_TOKEN_FN           _CompleteAuthToken         = NULL;
-DELETE_SECURITY_CONTEXT_FN       _DeleteSecurityContext     = NULL;
-FREE_CONTEXT_BUFFER_FN           _FreeContextBuffer         = NULL;
-FREE_CREDENTIALS_HANDLE_FN       _FreeCredentialsHandle     = NULL;
-INITIALIZE_SECURITY_CONTEXT_FN   _InitializeSecurityContext = NULL;
-QUERY_SECURITY_PACKAGE_INFO_FN   _QuerySecurityPackageInfo  = NULL;
+/* Function pointers */
+ACCEPT_SECURITY_CONTEXT_FN _AcceptSecurityContext = NULL;
+ACQUIRE_CREDENTIALS_HANDLE_FN _AcquireCredentialsHandle = NULL;
+COMPLETE_AUTH_TOKEN_FN _CompleteAuthToken = NULL;
+DELETE_SECURITY_CONTEXT_FN _DeleteSecurityContext = NULL;
+FREE_CONTEXT_BUFFER_FN _FreeContextBuffer = NULL;
+FREE_CREDENTIALS_HANDLE_FN _FreeCredentialsHandle = NULL;
+INITIALIZE_SECURITY_CONTEXT_FN _InitializeSecurityContext = NULL;
+QUERY_SECURITY_PACKAGE_INFO_FN _QuerySecurityPackageInfo = NULL;
  
-/////////////////////////////////////////////////////////////////////////////// 
  
 void UnloadSecurityDll(void)
 {
     if (hModule)
 	FreeLibrary(hModule);
- 
     _AcceptSecurityContext      = NULL;
     _AcquireCredentialsHandle   = NULL;
     _CompleteAuthToken          = NULL;
@@ -55,7 +56,6 @@
     hModule = NULL;
 }
  
-/////////////////////////////////////////////////////////////////////////////// 
  
 HMODULE LoadSecurityDll(void) 
 {
Index: squid/src/auth/ntlm/helpers/NTLMSSP-WIN32/ntlm.h
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/auth/ntlm/helpers/NTLMSSP-WIN32/Attic/ntlm.h,v
retrieving revision 1.1.2.1
retrieving revision 1.1.2.2
diff -u -r1.1.2.1 -r1.1.2.2
--- squid/src/auth/ntlm/helpers/NTLMSSP-WIN32/ntlm.h	21 Apr 2002 20:35:06 -0000	1.1.2.1
+++ squid/src/auth/ntlm/helpers/NTLMSSP-WIN32/ntlm.h	26 Apr 2002 19:52:07 -0000	1.1.2.2
@@ -1,6 +1,6 @@
 /*
- * (C) 2000 Francesco Chemolli <kinkie@kame.usr.dsi.unimi.it>,
- *        inspired by previous work by Andrew Doran <ad@interlude.eu.org>
+ * (C) 2002 Guido Serassio <serassio@libero.it>
+ * Based on previous work of Francesco Chemolli, Robert Collins and Andrew Doran
  *
  * Distributed freely under the terms of the GNU General Public License,
  * version 2. See the file COPYING for licensing details
@@ -31,9 +31,15 @@
 /*
  * define this if you want debugging
  */
+#ifdef _SQUID_MSWIN_
+#ifdef _DEBUG
+#define DEBUG
+#endif
+#else
 #ifndef DEBUG
 #define DEBUG
 #endif
+#endif
 
 #define DEAD_DC_RETRY_INTERVAL 30
 
@@ -44,7 +50,6 @@
 #define WINNT_SECURITY_DLL "security.dll"
 #define WIN9X_SECURITY_DLL "secur32.dll"
 
-
 /* Debugging stuff */
 
 #ifdef __GNUC__			/* this is really a gcc-ism */
@@ -66,6 +71,7 @@
 static void
 debug(char *format,...) 
 {
+#ifdef DEBUG
 #ifdef _SQUID_MSWIN_
     if (debug_enabled) {
 	va_list args;
@@ -76,10 +82,10 @@
 	fprintf(stderr, "\n");
 	va_end(args);
     }
-#endif
+#endif /* _SQUID_MSWIN_ */
+#endif /* DEBUG */
 }
-
-#endif
+#endif /* __GNUC__ */
 
 
 /* A couple of harmless helper macros */
@@ -91,7 +97,12 @@
 #define SEND2(X,Y) debug("sending '" X "' to squid\n",Y); printf(X "\n",Y);
 #endif
 
+extern char * NTAllowedGroup;
+extern char * NTDisAllowedGroup;
+extern int UseDisallowedGroup;
+extern int UseAllowedGroup;
 extern int ntlm_errno;
+
 #define NTLM_NO_ERROR SEC_E_OK
 #define NTLM_SERVER_ERROR SEC_E_NOT_SUPPORTED
 #define NTLM_PROTOCOL_ERROR SEC_E_INCOMPLETE_MESSAGE
@@ -99,6 +110,7 @@
 #define NTLM_UNTRUSTED_DOMAIN SEC_E_NO_AUTHENTICATING_AUTHORITY
 #define NTLM_BAD_PROTOCOL SEC_E_BAD_PKGID
 #define NTLM_NOT_CONNECTED SEC_E_SECPKG_NOT_FOUND
+#define NTLM_BAD_NTGROUP -1
 
 HMODULE LoadSecurityDll(void);
 void UnloadSecurityDll(void);
Index: squid/src/auth/ntlm/helpers/NTLMSSP-WIN32/ntlm_auth.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/auth/ntlm/helpers/NTLMSSP-WIN32/Attic/ntlm_auth.c,v
retrieving revision 1.1.2.1
retrieving revision 1.1.2.2
diff -u -r1.1.2.1 -r1.1.2.2
--- squid/src/auth/ntlm/helpers/NTLMSSP-WIN32/ntlm_auth.c	21 Apr 2002 20:35:06 -0000	1.1.2.1
+++ squid/src/auth/ntlm/helpers/NTLMSSP-WIN32/ntlm_auth.c	26 Apr 2002 19:52:07 -0000	1.1.2.2
@@ -1,5 +1,6 @@
 /*
- * (C) 2000 Francesco Chemolli <kinkie@kame.usr.dsi.unimi.it>
+ * (C) 2002 Guido Serassio <serassio@libero.it>
+ * Based on previous work of Francesco Chemolli and Robert Collins
  * Distributed freely under the terms of the GNU General Public License,
  * version 2. See the file COPYING for licensing details
  *
@@ -36,9 +37,7 @@
 char * NTAllowedGroup;
 char * NTDisAllowedGroup;
 int UseDisallowedGroup = 0;
-
-
-
+int UseAllowedGroup = 0;
 
 /* makes a null-terminated string upper-case. Changes CONTENTS! */
 void
@@ -98,7 +97,7 @@
 usage()
 {
     fprintf(stderr,
-	"%s usage:\n%s [-d] -A UserGroup [-D UserGroup]\n"
+	"%s usage:\n%s [-d] [-A UserGroup] [-D UserGroup]\n"
 	"-d enables debugging statements if DEBUG was defined at build-time.\n"
 	"-l if specified, changes behavior on failures to last-ditch.\n"
 	"-A specify the Windows Local Group name allowed to authenticate.\n"
@@ -116,6 +115,7 @@
 	case 'A':
 	    safe_free(NTAllowedGroup);
 	    NTAllowedGroup=xstrdup(optarg);
+	    UseAllowedGroup = 1;
 	    break;
 	case 'D':
 	    safe_free(NTDisAllowedGroup);
@@ -212,94 +212,24 @@
 	    return;
 	    /* notreached */
 	case NTLM_AUTHENTICATE:
-	    /* check against the DC */
+	    /* check against SSPI */
 	    plen = strlen(buf) * 3 / 4;		/* we only need it here. Optimization */
 	    cred = ntlm_check_auth((ntlm_authenticate *) decoded, plen);
 	    if (cred == NULL) {
-//		int smblib_err, smb_errorclass, smb_errorcode, nb_error;
-		if (ntlm_errno == NTLM_LOGON_ERROR) {	/* hackish */
-			SEND("NA Logon Failure");
-			return;
-		}
-		else {
-			SEND("NA SSPI Error");
-			return;
+		switch (ntlm_errno) {
+		case NTLM_LOGON_ERROR:
+		    SEND("NA Logon Failure");
+		    return;
+		case NTLM_BAD_NTGROUP:
+		    SEND("NA Incorrect Group Membership");
+		    return;
+		case NTLM_UNTRUSTED_DOMAIN:
+		    SEND("NA No authority could be contacted for authentication");
+		    return;
+		default:
+		    SEND("NA SSPI Error");
+		    return;
 		}
-		/* there was an error. We have two errno's to look at.
-		 * libntlmssp's erno is insufficient, we'll have to look at
-		 * the actual SMB library error codes, to acually figure
-		 * out what's happening. The thing has braindamaged interfacess..*/
-//		smblib_err = SMB_Get_Last_Error();
-//		smb_errorclass = SMBlib_Error_Class(SMB_Get_Last_SMB_Err());
-//		smb_errorcode = SMBlib_Error_Code(SMB_Get_Last_SMB_Err());
-//		nb_error = RFCNB_Get_Last_Error();
-//		debug("No creds. SMBlib error %d, SMB error class %d, SMB error code %d, NB error %d\n",
-//		    smblib_err, smb_errorclass, smb_errorcode, nb_error);
-		/* Should I use smblib_err? Actually it seems I can do as well
-		 * without it.. */
-//		if (nb_error != 0) {	/* netbios-level error */
-//		    send_bh_or_ld("NetBios error!",
-//			(ntlm_authenticate *) decoded, plen);
-//		    fprintf(stderr, "NetBios error code %d (%s)\n", nb_error,
-//			RFCNB_Error_Strings[abs(nb_error)]);
-//		    return;
-//		}
-//		switch (smb_errorclass) {
-//		case SMBC_SUCCESS:
-//		    debug("Huh? Got a SMB success code but could check auth..");
-//		    SEND("NA Authentication failed");
-		    /*
-		     * send_bh_or_ld("SMB success, but no creds. Internal error?",
-		     * (ntlm_authenticate *) decoded, plen);
-		     */
-//		    return;
-//		case SMBC_ERRDOS:
-		    /*this is the most important one for errors */
-//		    debug("DOS error\n");
-//		    switch (smb_errorcode) {
-			/* two categories matter to us: those which could be
-			 * server errors, and those which are auth errors */
-//		    case SMBD_noaccess:	/* 5 */
-//			SEND("NA Access denied");
-//			return;
-//		    case SMBD_badformat:
-//			SEND("NA bad format in authentication packet");
-//			return;
-//		    case SMBD_badaccess:
-//			SEND("NA Bad access request");
-//			return;
-//		    case SMBD_baddata:
-//			SEND("NA Bad Data");
-//			return;
-//		    default:
-//			send_bh_or_ld("DOS Error",
-//			    (ntlm_authenticate *) decoded, plen);
-//			return;
-//		    }
-//		case SMBC_ERRSRV:	/* server errors */
-//		    debug("Server error");
-//		    switch (smb_errorcode) {
-//			/* mostly same as above */
-//		    case SMBV_badpw:
-//			SEND("NA Bad password");
-//			return;
-//		    case SMBV_access:
-//			SEND("NA Server access error");
-//			return;
-//		    default:
-//			send_bh_or_ld("Server Error",
-//			    (ntlm_authenticate *) decoded, plen);
-//			return;
-//		    }
-//		case SMBC_ERRHRD:	/* hardware errors don't really matter */
-//		    send_bh_or_ld("Domain Controller Hardware error",
-//			(ntlm_authenticate *) decoded, plen);
-//		    return;
-//		case SMBC_ERRCMD:
-//		    send_bh_or_ld("Domain Controller Command Error",
-//			(ntlm_authenticate *) decoded, plen);
-//		    return;
-//		}
 	    }
 	    lc(cred);		/* let's lowercase them for our convenience */
 	    SEND2("AF %s", cred);
--- /dev/null	Wed Feb 14 00:55:47 2007
+++ squid/src/auth/ntlm/helpers/NTLMSSP-WIN32/readme.txt	Wed Feb 14 00:58:19 2007
@@ -0,0 +1,12 @@
+ntlm_auth.exe
+
+Native Windows NTLM authenticator for Squid 2.5
+
+Usage:
+
+ntlm_auth [-d] [-A UserGroup] [-D UserGroup]
+
+-d enables debugging statements if DEBUG was defined at build-time.
+-l if specified, changes behavior on failures to last-ditch.
+-A can specify a Windows Local Group name allowed to authenticate.
+-D can specify a Windows Local Group name not allowed to authenticate.
