4
* (C) 2000 Antonino Iannella, Stellar-X Pty Ltd
5
* Released under GPL, see COPYING-2.0 for details.
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.
18
#include <sys/param.h>
25
/* Path to configuration file */
27
#define SYSCONFDIR "/usr/local/squid/etc"
29
#define CONFIGFILE SYSCONFDIR "/msntauth.conf"
31
/* Maximum number of servers to query. This number can be increased. */
35
extern char Denyuserpath[MAXPATHLEN]; /* MAXPATHLEN defined in param.h */
36
extern char Allowuserpath[MAXPATHLEN];
38
typedef struct _ServerTuple {
41
char domain[NTHOSTLEN];
44
ServerTuple ServerArray[MAXSERVERS]; /* Array of servers to query */
45
int Serversqueried = 0; /* Number of servers queried */
49
static void ProcessLine(char *);
50
static void AddServer(char *, char *, char *);
51
static int QueryServerForUser(int, char *, char *);
54
* Opens and reads the configuration file.
55
* Returns 0 on success, or 1 for error.
62
char Confbuf[2049]; /* Line reading buffer */
64
/* Initialise defaults */
67
memset(ServerArray, '\0', sizeof(ServerArray));
68
memset(Denyuserpath, '\0', MAXPATHLEN);
69
memset(Allowuserpath, '\0', MAXPATHLEN);
72
if ((ConfigFile = fopen(CONFIGFILE, "r")) == NULL) {
73
syslog(LOG_ERR, "OpenConfigFile: Failed to open %s.", CONFIGFILE);
74
syslog(LOG_ERR, "%s", strerror(errno));
77
/* Read in, one line at a time */
78
while (!feof(ConfigFile)) {
80
if (NULL == fgets(Confbuf, 2048, ConfigFile))
87
* Check that at least one server is being queried. Report error if not.
88
* Denied and allowed user files are hardcoded, so it's fine if they're
89
* not set in the confugration file.
91
if (Serversqueried == 0) {
92
syslog(LOG_ERR, "OpenConfigFile: No servers set in %s. At least one is needed.", CONFIGFILE);
99
/* Parses a configuration file line. */
102
ProcessLine(char *Linebuf)
109
/* Ignore empty lines */
110
if (strlen(Linebuf) == 0)
113
/* Break up on whitespaces */
114
if ((Directive = strtok(Linebuf, " \t\n")) == NULL)
117
/* Check for a comment line. If found, stop . */
118
if (Directive[0] == '#')
121
/* Check for server line. Check for 3 parameters. */
122
if (strcasecmp(Directive, "server") == 0) {
123
Param1 = strtok(NULL, " \t\n");
124
if (NULL == Param1) {
125
syslog(LOG_ERR, "ProcessLine: 'server' missing PDC parameter.");
128
Param2 = strtok(NULL, " \t\n");
129
if (NULL == Param2) {
130
syslog(LOG_ERR, "ProcessLine: 'server' missing BDC parameter.");
133
Param3 = strtok(NULL, " \t\n");
134
if (NULL == Param3) {
135
syslog(LOG_ERR, "ProcessLine: 'server' missing domain parameter.");
138
AddServer(Param1, Param2, Param3);
141
/* Check for denyusers line */
142
if (strcasecmp(Directive, "denyusers") == 0) {
143
Param1 = strtok(NULL, " \t\n");
145
if (NULL == Param1) {
146
syslog(LOG_ERR, "ProcessLine: A 'denyusers' line needs a filename parameter.");
149
memset(Denyuserpath, '\0', MAXPATHLEN);
150
strncpy(Denyuserpath, Param1, MAXPATHLEN - 1);
153
/* Check for allowusers line */
154
if (strcasecmp(Directive, "allowusers") == 0) {
155
Param1 = strtok(NULL, " \t\n");
157
if (NULL == Param1) {
158
syslog(LOG_ERR, "ProcessLine: An 'allowusers' line needs a filename parameter.");
161
memset(Allowuserpath, '\0', MAXPATHLEN);
162
strncpy(Allowuserpath, Param1, MAXPATHLEN - 1);
165
/* Reports error for unknown line */
166
syslog(LOG_ERR, "ProcessLine: Ignoring '%s' line.", Directive);
170
* Adds a server to query to the server array.
171
* Checks if the server IP is resolvable.
172
* Checks if the number of servers to query is not exceeded.
173
* Does not allow parameters longer than NTHOSTLEN.
177
AddServer(char *ParamPDC, char *ParamBDC, char *ParamDomain)
179
if (Serversqueried == MAXSERVERS) {
180
syslog(LOG_ERR, "AddServer: Ignoring '%s' server line; "
181
"too many servers.", ParamPDC);
184
if (gethostbyname(ParamPDC) == NULL) {
185
syslog(LOG_ERR, "AddServer: Ignoring host '%s'. "
186
"Cannot resolve its address.", ParamPDC);
189
if (gethostbyname(ParamBDC) == NULL) {
190
syslog(LOG_USER | LOG_ERR, "AddServer: Ignoring host '%s'. "
191
"Cannot resolve its address.", ParamBDC);
194
/* NOTE: ServerArray is zeroed in OpenConfigFile() */
195
assert(Serversqueried < MAXSERVERS);
196
strncpy(ServerArray[Serversqueried].pdc, ParamPDC, NTHOSTLEN - 1);
197
strncpy(ServerArray[Serversqueried].bdc, ParamBDC, NTHOSTLEN - 1);
198
strncpy(ServerArray[Serversqueried].domain, ParamDomain, NTHOSTLEN - 1);
203
* Cycles through all servers to query.
204
* Returns 0 if one server could authenticate the user.
205
* Returns 1 if no server authenticated the user.
209
QueryServers(char *username, char *password)
212
for (i = 0; i < Serversqueried; i++) {
213
if (0 == QueryServerForUser(i, username, password))
220
* Attempts to authenticate the user with one server.
221
* Logs syslog messages for different errors.
222
* Returns 0 on success, non-zero on failure.
225
/* Define for systems which don't support it, like Solaris */
227
#define LOG_AUTHPRIV LOG_AUTH
231
QueryServerForUser(int x, char *username, char *password)
235
result = Valid_User(username, password, ServerArray[x].pdc,
236
ServerArray[x].bdc, ServerArray[x].domain);
238
switch (result) { /* Write any helpful syslog messages */
242
syslog(LOG_AUTHPRIV | LOG_INFO, "Server error when checking %s.",
246
syslog(LOG_AUTHPRIV | LOG_INFO, "Protocol error when checking %s.",
250
syslog(LOG_AUTHPRIV | LOG_INFO, "Authentication failed for %s.",
258
/* Valid_User return codes -
260
* 0 - User authenticated successfully.
262
* 2 - Protocol error.
263
* 3 - Logon error; Incorrect password or username given.