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