]>
Commit | Line | Data |
---|---|---|
94439e4e | 1 | |
2 | /* | |
3 | * confload.c | |
4 | * (C) 2000 Antonino Iannella, Stellar-X Pty Ltd | |
5 | * Released under GPL, see COPYING-2.0 for details. | |
26ac0430 | 6 | * |
94439e4e | 7 | * These routines load the msntauth configuration file. |
8 | * It stores the servers to query, sets the denied and | |
26ac0430 | 9 | * allowed user files, and provides the |
94439e4e | 10 | * authenticating function. |
11 | */ | |
12 | ||
24389fa4 | 13 | /* Squid provides a number of portability overrides */ |
f7f3304a | 14 | #include "squid.h" |
24389fa4 | 15 | |
94439e4e | 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> | |
6d73604c | 22 | #include <netdb.h> |
eb073b3b | 23 | #include <assert.h> |
94439e4e | 24 | |
b40a659a | 25 | #include "msntauth.h" |
26 | #include "valid.h" | |
27 | ||
eb073b3b | 28 | /* Path to configuration file */ |
90528dba | 29 | #ifndef SYSCONFDIR |
30 | #define SYSCONFDIR "/usr/local/squid/etc" | |
31 | #endif | |
32 | #define CONFIGFILE SYSCONFDIR "/msntauth.conf" | |
94439e4e | 33 | |
eb073b3b | 34 | /* Maximum number of servers to query. This number can be increased. */ |
35 | #define MAXSERVERS 5 | |
94439e4e | 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 | ||
b40a659a | 52 | static void ProcessLine(char *); |
53 | static void AddServer(char *, char *, char *); | |
54 | static int QueryServerForUser(int, char *, char *); | |
94439e4e | 55 | |
56 | /* | |
57 | * Opens and reads the configuration file. | |
58 | * Returns 0 on success, or 1 for error. | |
59 | */ | |
60 | ||
61 | int | |
b40a659a | 62 | OpenConfigFile(void) |
94439e4e | 63 | { |
64 | FILE *ConfigFile; | |
65 | char Confbuf[2049]; /* Line reading buffer */ | |
66 | ||
67 | /* Initialise defaults */ | |
68 | ||
69 | Serversqueried = 0; | |
eb073b3b | 70 | memset(ServerArray, '\0', sizeof(ServerArray)); |
71 | memset(Denyuserpath, '\0', MAXPATHLEN); | |
72 | memset(Allowuserpath, '\0', MAXPATHLEN); | |
94439e4e | 73 | |
74 | /* Open file */ | |
75 | if ((ConfigFile = fopen(CONFIGFILE, "r")) == NULL) { | |
26ac0430 AJ |
76 | syslog(LOG_ERR, "OpenConfigFile: Failed to open %s.", CONFIGFILE); |
77 | syslog(LOG_ERR, "%s", strerror(errno)); | |
78 | return 1; | |
94439e4e | 79 | } |
80 | /* Read in, one line at a time */ | |
94439e4e | 81 | while (!feof(ConfigFile)) { |
26ac0430 AJ |
82 | Confbuf[0] = '\0'; |
83 | if (NULL == fgets(Confbuf, 2048, ConfigFile)) | |
84 | break; | |
85 | Confbuf[2048] = '\0'; | |
86 | ProcessLine(Confbuf); | |
94439e4e | 87 | } |
88 | ||
eb073b3b | 89 | /* |
90 | * Check that at least one server is being queried. Report error if not. | |
94439e4e | 91 | * Denied and allowed user files are hardcoded, so it's fine if they're |
eb073b3b | 92 | * not set in the confugration file. |
93 | */ | |
94439e4e | 94 | if (Serversqueried == 0) { |
26ac0430 AJ |
95 | syslog(LOG_ERR, "OpenConfigFile: No servers set in %s. At least one is needed.", CONFIGFILE); |
96 | return 1; | |
94439e4e | 97 | } |
98 | fclose(ConfigFile); | |
99 | return 0; | |
100 | } | |
101 | ||
102 | /* Parses a configuration file line. */ | |
103 | ||
b40a659a | 104 | static void |
94439e4e | 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) | |
26ac0430 | 114 | return; |
94439e4e | 115 | |
116 | /* Break up on whitespaces */ | |
117 | if ((Directive = strtok(Linebuf, " \t\n")) == NULL) | |
26ac0430 | 118 | return; |
94439e4e | 119 | |
120 | /* Check for a comment line. If found, stop . */ | |
121 | if (Directive[0] == '#') | |
26ac0430 | 122 | return; |
94439e4e | 123 | |
124 | /* Check for server line. Check for 3 parameters. */ | |
125 | if (strcasecmp(Directive, "server") == 0) { | |
26ac0430 AJ |
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; | |
94439e4e | 143 | } |
144 | /* Check for denyusers line */ | |
145 | if (strcasecmp(Directive, "denyusers") == 0) { | |
26ac0430 AJ |
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; | |
94439e4e | 155 | } |
156 | /* Check for allowusers line */ | |
157 | if (strcasecmp(Directive, "allowusers") == 0) { | |
26ac0430 AJ |
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; | |
94439e4e | 167 | } |
168 | /* Reports error for unknown line */ | |
eb073b3b | 169 | syslog(LOG_ERR, "ProcessLine: Ignoring '%s' line.", Directive); |
94439e4e | 170 | } |
171 | ||
172 | /* | |
173 | * Adds a server to query to the server array. | |
6d73604c | 174 | * Checks if the server IP is resolvable. |
94439e4e | 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 | { | |
eb073b3b | 182 | if (Serversqueried == MAXSERVERS) { |
26ac0430 AJ |
183 | syslog(LOG_ERR, "AddServer: Ignoring '%s' server line; " |
184 | "too many servers.", ParamPDC); | |
185 | return; | |
6d73604c | 186 | } |
eb073b3b | 187 | if (gethostbyname(ParamPDC) == NULL) { |
26ac0430 AJ |
188 | syslog(LOG_ERR, "AddServer: Ignoring host '%s'. " |
189 | "Cannot resolve its address.", ParamPDC); | |
190 | return; | |
6d73604c | 191 | } |
eb073b3b | 192 | if (gethostbyname(ParamBDC) == NULL) { |
26ac0430 AJ |
193 | syslog(LOG_USER | LOG_ERR, "AddServer: Ignoring host '%s'. " |
194 | "Cannot resolve its address.", ParamBDC); | |
195 | return; | |
94439e4e | 196 | } |
eb073b3b | 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); | |
94439e4e | 202 | Serversqueried++; |
94439e4e | 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 | { | |
eb073b3b | 214 | int i; |
215 | for (i = 0; i < Serversqueried; i++) { | |
26ac0430 AJ |
216 | if (0 == QueryServerForUser(i, username, password)) |
217 | return 0; | |
94439e4e | 218 | } |
eb073b3b | 219 | return 1; |
94439e4e | 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 | ||
6d73604c | 228 | /* Define for systems which don't support it, like Solaris */ |
229 | #ifndef LOG_AUTHPRIV | |
230 | #define LOG_AUTHPRIV LOG_AUTH | |
231 | #endif | |
232 | ||
eb073b3b | 233 | static int |
94439e4e | 234 | QueryServerForUser(int x, char *username, char *password) |
235 | { | |
236 | int result = 1; | |
237 | ||
238 | result = Valid_User(username, password, ServerArray[x].pdc, | |
26ac0430 | 239 | ServerArray[x].bdc, ServerArray[x].domain); |
94439e4e | 240 | |
241 | switch (result) { /* Write any helpful syslog messages */ | |
242 | case 0: | |
26ac0430 | 243 | break; |
94439e4e | 244 | case 1: |
26ac0430 AJ |
245 | syslog(LOG_AUTHPRIV | LOG_INFO, "Server error when checking %s.", |
246 | username); | |
247 | break; | |
94439e4e | 248 | case 2: |
26ac0430 AJ |
249 | syslog(LOG_AUTHPRIV | LOG_INFO, "Protocol error when checking %s.", |
250 | username); | |
251 | break; | |
94439e4e | 252 | case 3: |
26ac0430 AJ |
253 | syslog(LOG_AUTHPRIV | LOG_INFO, "Authentication failed for %s.", |
254 | username); | |
255 | break; | |
94439e4e | 256 | } |
257 | ||
258 | return result; | |
259 | } | |
260 | ||
261 | /* Valid_User return codes - | |
26ac0430 | 262 | * |
94439e4e | 263 | * 0 - User authenticated successfully. |
264 | * 1 - Server error. | |
265 | * 2 - Protocol error. | |
266 | * 3 - Logon error; Incorrect password or username given. | |
267 | */ |