]> git.ipfire.org Git - thirdparty/squid.git/blob - helpers/basic_auth/MSNT/confload.cc
SourceFormat Enforcement
[thirdparty/squid.git] / helpers / basic_auth / MSNT / confload.cc
1 /*
2 * Copyright (C) 1996-2014 The Squid Software Foundation and contributors
3 *
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.
7 */
8
9 /*
10 * confload.c
11 * (C) 2000 Antonino Iannella, Stellar-X Pty Ltd
12 * Released under GPL, see COPYING-2.0 for details.
13 *
14 * These routines load the msntauth configuration file.
15 * It stores the servers to query, sets the denied and
16 * allowed user files, and provides the
17 * authenticating function.
18 */
19
20 /* Squid provides a number of portability overrides */
21 #include "squid.h"
22
23 #include <cassert>
24 #include <cerrno>
25 #include <cstdlib>
26 #include <cstring>
27 #include <syslog.h>
28 #include <sys/param.h>
29 #include <netdb.h>
30
31 #include "msntauth.h"
32 #include "valid.h"
33
34 /* Path to configuration file */
35 #ifndef SYSCONFDIR
36 #define SYSCONFDIR "/usr/local/squid/etc"
37 #endif
38 #define CONFIGFILE SYSCONFDIR "/msntauth.conf"
39
40 /* Maximum number of servers to query. This number can be increased. */
41 #define MAXSERVERS 5
42 #define NTHOSTLEN 65
43
44 extern char Denyuserpath[MAXPATHLEN]; /* MAXPATHLEN defined in param.h */
45 extern char Allowuserpath[MAXPATHLEN];
46
47 typedef struct _ServerTuple {
48 char pdc[NTHOSTLEN];
49 char bdc[NTHOSTLEN];
50 char domain[NTHOSTLEN];
51 } ServerTuple;
52
53 ServerTuple ServerArray[MAXSERVERS]; /* Array of servers to query */
54 int Serversqueried = 0; /* Number of servers queried */
55
56 /* Declarations */
57
58 static void ProcessLine(char *);
59 static void AddServer(char *, char *, char *);
60 static int QueryServerForUser(int, char *, char *);
61
62 /*
63 * Opens and reads the configuration file.
64 * Returns 0 on success, or 1 for error.
65 */
66
67 int
68 OpenConfigFile(void)
69 {
70 FILE *ConfigFile;
71 char Confbuf[2049]; /* Line reading buffer */
72
73 /* Initialise defaults */
74
75 Serversqueried = 0;
76 memset(ServerArray, '\0', sizeof(ServerArray));
77 memset(Denyuserpath, '\0', MAXPATHLEN);
78 memset(Allowuserpath, '\0', MAXPATHLEN);
79
80 /* Open file */
81 if ((ConfigFile = fopen(CONFIGFILE, "r")) == NULL) {
82 syslog(LOG_ERR, "OpenConfigFile: Failed to open %s.", CONFIGFILE);
83 syslog(LOG_ERR, "%s", strerror(errno));
84 return 1;
85 }
86 /* Read in, one line at a time */
87 while (!feof(ConfigFile)) {
88 Confbuf[0] = '\0';
89 if (NULL == fgets(Confbuf, 2048, ConfigFile))
90 break;
91 Confbuf[2048] = '\0';
92 ProcessLine(Confbuf);
93 }
94 fclose(ConfigFile);
95
96 /*
97 * Check that at least one server is being queried. Report error if not.
98 * Denied and allowed user files are hardcoded, so it's fine if they're
99 * not set in the confugration file.
100 */
101 if (Serversqueried == 0) {
102 syslog(LOG_ERR, "OpenConfigFile: No servers set in %s. At least one is needed.", CONFIGFILE);
103 return 1;
104 }
105 return 0;
106 }
107
108 /* Parses a configuration file line. */
109
110 static void
111 ProcessLine(char *Linebuf)
112 {
113 char *Directive;
114 char *Param1;
115 char *Param2;
116 char *Param3;
117
118 /* Ignore empty lines */
119 if (strlen(Linebuf) == 0)
120 return;
121
122 /* Break up on whitespaces */
123 if ((Directive = strtok(Linebuf, " \t\n")) == NULL)
124 return;
125
126 /* Check for a comment line. If found, stop . */
127 if (Directive[0] == '#')
128 return;
129
130 /* Check for server line. Check for 3 parameters. */
131 if (strcmp(Directive, "server") == 0) {
132 Param1 = strtok(NULL, " \t\n");
133 if (NULL == Param1) {
134 syslog(LOG_ERR, "ProcessLine: 'server' missing PDC parameter.");
135 return;
136 }
137 Param2 = strtok(NULL, " \t\n");
138 if (NULL == Param2) {
139 syslog(LOG_ERR, "ProcessLine: 'server' missing BDC parameter.");
140 return;
141 }
142 Param3 = strtok(NULL, " \t\n");
143 if (NULL == Param3) {
144 syslog(LOG_ERR, "ProcessLine: 'server' missing domain parameter.");
145 return;
146 }
147 AddServer(Param1, Param2, Param3);
148 return;
149 }
150 /* Check for denyusers line */
151 if (strcmp(Directive, "denyusers") == 0) {
152 Param1 = strtok(NULL, " \t\n");
153
154 if (NULL == Param1) {
155 syslog(LOG_ERR, "ProcessLine: A 'denyusers' line needs a filename parameter.");
156 return;
157 }
158 memset(Denyuserpath, '\0', MAXPATHLEN);
159 strncpy(Denyuserpath, Param1, MAXPATHLEN - 1);
160 return;
161 }
162 /* Check for allowusers line */
163 if (strcmp(Directive, "allowusers") == 0) {
164 Param1 = strtok(NULL, " \t\n");
165
166 if (NULL == Param1) {
167 syslog(LOG_ERR, "ProcessLine: An 'allowusers' line needs a filename parameter.");
168 return;
169 }
170 memset(Allowuserpath, '\0', MAXPATHLEN);
171 strncpy(Allowuserpath, Param1, MAXPATHLEN - 1);
172 return;
173 }
174 /* Reports error for unknown line */
175 syslog(LOG_ERR, "ProcessLine: Ignoring '%s' line.", Directive);
176 }
177
178 /*
179 * Adds a server to query to the server array.
180 * Checks if the server IP is resolvable.
181 * Checks if the number of servers to query is not exceeded.
182 * Does not allow parameters longer than NTHOSTLEN.
183 */
184
185 void
186 AddServer(char *ParamPDC, char *ParamBDC, char *ParamDomain)
187 {
188 if (Serversqueried == MAXSERVERS) {
189 syslog(LOG_ERR, "AddServer: Ignoring '%s' server line; "
190 "too many servers.", ParamPDC);
191 return;
192 }
193 if (gethostbyname(ParamPDC) == NULL) {
194 syslog(LOG_ERR, "AddServer: Ignoring host '%s'. "
195 "Cannot resolve its address.", ParamPDC);
196 return;
197 }
198 if (gethostbyname(ParamBDC) == NULL) {
199 syslog(LOG_USER | LOG_ERR, "AddServer: Ignoring host '%s'. "
200 "Cannot resolve its address.", ParamBDC);
201 return;
202 }
203 /* NOTE: ServerArray is zeroed in OpenConfigFile() */
204 assert(Serversqueried < MAXSERVERS);
205 strncpy(ServerArray[Serversqueried].pdc, ParamPDC, NTHOSTLEN - 1);
206 strncpy(ServerArray[Serversqueried].bdc, ParamBDC, NTHOSTLEN - 1);
207 strncpy(ServerArray[Serversqueried].domain, ParamDomain, NTHOSTLEN - 1);
208 ++Serversqueried;
209 }
210
211 /*
212 * Cycles through all servers to query.
213 * Returns 0 if one server could authenticate the user.
214 * Returns 1 if no server authenticated the user.
215 */
216
217 int
218 QueryServers(char *username, char *password)
219 {
220 int i;
221 for (i = 0; i < Serversqueried; ++i) {
222 if (0 == QueryServerForUser(i, username, password))
223 return 0;
224 }
225 return 1;
226 }
227
228 /*
229 * Attempts to authenticate the user with one server.
230 * Logs syslog messages for different errors.
231 * Returns 0 on success, non-zero on failure.
232 */
233
234 /* Define for systems which don't support it, like Solaris */
235 #ifndef LOG_AUTHPRIV
236 #define LOG_AUTHPRIV LOG_AUTH
237 #endif
238
239 static int
240 QueryServerForUser(int x, char *username, char *password)
241 {
242 int result = 1;
243
244 result = Valid_User(username, password, ServerArray[x].pdc,
245 ServerArray[x].bdc, ServerArray[x].domain);
246
247 switch (result) { /* Write any helpful syslog messages */
248 case 0:
249 break;
250 case 1:
251 syslog(LOG_AUTHPRIV | LOG_INFO, "Server error when checking %s.",
252 username);
253 break;
254 case 2:
255 syslog(LOG_AUTHPRIV | LOG_INFO, "Protocol error when checking %s.",
256 username);
257 break;
258 case 3:
259 syslog(LOG_AUTHPRIV | LOG_INFO, "Authentication failed for %s.",
260 username);
261 break;
262 }
263
264 return result;
265 }
266
267 /* Valid_User return codes -
268 *
269 * 0 - User authenticated successfully.
270 * 1 - Server error.
271 * 2 - Protocol error.
272 * 3 - Logon error; Incorrect password or username given.
273 */
274