2 * Copyright (C) 1996-2023 The Squid Software Foundation and contributors
4 * Squid software is distributed under GPLv2+ license and includes
5 * contributions from numerous individuals and organizations.
6 * Please see the COPYING and CONTRIBUTORS files for details.
12 Modified to act as a Squid authenticator module.
13 Removed all Pike stuff.
14 Returns OK for a successful authentication, or ERR upon error.
16 Guido Serassio, Torino - Italy
19 Antonino Iannella 2000
24 * Distributed freely under the terms of the GNU General Public License,
25 * version 2 or later. See the file COPYING for licensing details
27 * This program is distributed in the hope that it will be useful,
28 * but WITHOUT ANY WARRANTY; without even the implied warranty of
29 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30 * GNU General Public License for more details.
32 * You should have received a copy of the GNU General Public License
33 * along with this program; if not, write to the Free Software
34 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
38 #include "auth/basic/SSPI/valid.h"
43 char Default_NTDomain
[DNLEN
+1] = NTV_DEFAULT_DOMAIN
;
44 const char * errormsg
;
46 const char NTV_SERVER_ERROR_MSG
[] = "Internal server error";
47 const char NTV_GROUP_ERROR_MSG
[] = "User not allowed to use this cache";
48 const char NTV_LOGON_ERROR_MSG
[] = "No such user or wrong password";
49 const char NTV_VALID_DOMAIN_SEPARATOR
[] = "\\/";
51 /* returns 1 on success, 0 on failure */
53 Valid_Group(char *UserName
, char *Group
)
56 WCHAR wszUserName
[256]; // Unicode user name
57 WCHAR wszGroup
[256]; // Unicode Group
59 LPLOCALGROUP_USERS_INFO_0 pBuf
= nullptr;
60 LPLOCALGROUP_USERS_INFO_0 pTmpBuf
;
62 DWORD dwFlags
= LG_INCLUDE_INDIRECT
;
63 DWORD dwPrefMaxLen
= -1;
64 DWORD dwEntriesRead
= 0;
65 DWORD dwTotalEntries
= 0;
66 NET_API_STATUS nStatus
;
68 DWORD dwTotalCount
= 0;
70 /* Convert ANSI User Name and Group to Unicode */
72 MultiByteToWideChar(CP_ACP
, 0, UserName
,
73 strlen(UserName
) + 1, wszUserName
,
74 sizeof(wszUserName
) / sizeof(wszUserName
[0]));
75 MultiByteToWideChar(CP_ACP
, 0, Group
,
76 strlen(Group
) + 1, wszGroup
, sizeof(wszGroup
) / sizeof(wszGroup
[0]));
79 * Call the NetUserGetLocalGroups function
80 * specifying information level 0.
82 * The LG_INCLUDE_INDIRECT flag specifies that the
83 * function should also return the names of the local
84 * groups in which the user is indirectly a member.
86 nStatus
= NetUserGetLocalGroups(nullptr,
90 (LPBYTE
*) & pBuf
, dwPrefMaxLen
, &dwEntriesRead
, &dwTotalEntries
);
92 * If the call succeeds,
94 if (nStatus
== NERR_Success
) {
95 if ((pTmpBuf
= pBuf
) != NULL
) {
96 for (i
= 0; i
< dwEntriesRead
; ++i
) {
97 if (pTmpBuf
== NULL
) {
101 if (wcscmp(pTmpBuf
->lgrui0_name
, wszGroup
) == 0) {
112 * Free the allocated memory.
115 NetApiBufferFree(pBuf
);
120 Valid_User(char *UserName
, char *Password
, char *)
122 int result
= NTV_SERVER_ERROR
;
125 char *domain_qualify
= nullptr;
126 char DomainUser
[256];
129 errormsg
= NTV_SERVER_ERROR_MSG
;
130 xstrncpy(NTDomain
, UserName
, sizeof(NTDomain
));
132 for (i
=0; i
< strlen(NTV_VALID_DOMAIN_SEPARATOR
); ++i
) {
133 if ((domain_qualify
= strchr(NTDomain
, NTV_VALID_DOMAIN_SEPARATOR
[i
])) != NULL
)
136 if (domain_qualify
== NULL
) {
137 strcpy(User
, NTDomain
);
138 strcpy(NTDomain
, Default_NTDomain
);
140 strcpy(User
, domain_qualify
+ 1);
141 domain_qualify
[0] = '\0';
143 /* Log the client on to the local computer. */
144 if (!SSP_LogonUser(User
, Password
, NTDomain
)) {
145 result
= NTV_LOGON_ERROR
;
146 errormsg
= NTV_LOGON_ERROR_MSG
;
147 debug("%s\n", errormsg
);
149 result
= NTV_NO_ERROR
;
150 if (strcmp(NTDomain
, NTV_DEFAULT_DOMAIN
) == 0)
151 strcpy(DomainUser
, User
);
153 strcpy(DomainUser
, NTDomain
);
154 strcat(DomainUser
, "\\");
155 strcat(DomainUser
, User
);
157 if (UseAllowedGroup
) {
158 if (!Valid_Group(DomainUser
, NTAllowedGroup
)) {
159 result
= NTV_GROUP_ERROR
;
160 errormsg
= NTV_GROUP_ERROR_MSG
;
161 debug("%s\n", errormsg
);
164 if (UseDisallowedGroup
) {
165 if (Valid_Group(DomainUser
, NTDisAllowedGroup
)) {
166 result
= NTV_GROUP_ERROR
;
167 errormsg
= NTV_GROUP_ERROR_MSG
;
168 debug("%s\n", errormsg
);