]>
Commit | Line | Data |
---|---|---|
0fe2d1c5 | 1 | diff -ur courier-imap-1.3.12.orig/authlib/authmysqllib.c courier-imap-1.3.12/authlib/authmysqllib.c |
2 | --- courier-imap-1.3.12.orig/authlib/authmysqllib.c Mon Aug 6 05:12:39 2001 | |
0b0a7302 | 3 | +++ courier-imap-1.3.12/authlib/authmysqllib.c Wed Dec 26 05:46:05 2001 |
4 | @@ -3,7 +3,6 @@ | |
5 | ** distribution information. | |
6 | */ | |
7 | ||
8 | - | |
9 | #include <stdio.h> | |
10 | #include <stdlib.h> | |
11 | #include <string.h> | |
12 | @@ -20,6 +19,17 @@ | |
0fe2d1c5 | 13 | |
14 | static const char rcsid[]="$Id$"; | |
15 | ||
0b0a7302 | 16 | +struct var_data { |
0fe2d1c5 | 17 | + const char *name; |
18 | + const char *value; | |
19 | + const size_t size; | |
0b0a7302 | 20 | + size_t value_length; |
21 | + } ; /* siefca@pld.org.pl */ | |
22 | + | |
23 | +typedef size_t (*parsefunc)(const char *, size_t, struct var_data *); | |
24 | +parsefunc ParsePlugin_build = NULL; /* siefca@pld.org.pl */ | |
25 | + | |
0fe2d1c5 | 26 | + |
27 | static const char *read_env(const char *env) | |
28 | { | |
29 | static char *mysqlauth=0; | |
0b0a7302 | 30 | @@ -51,7 +61,13 @@ |
0fe2d1c5 | 31 | |
32 | for (i=0; i<mysqlauth_size; i++) | |
33 | if (mysqlauth[i] == '\n') | |
34 | - mysqlauth[i]=0; | |
35 | + { /* siefca@pld.org.pl */ | |
0b0a7302 | 36 | + if (!i || mysqlauth[i-1] != '\\') |
37 | + mysqlauth[i] ='\0'; | |
0fe2d1c5 | 38 | + else |
0b0a7302 | 39 | + mysqlauth[i] = |
40 | + mysqlauth[i-1] = ' '; | |
0fe2d1c5 | 41 | + } |
42 | fclose(f); | |
43 | } | |
44 | ||
0b0a7302 | 45 | @@ -199,17 +215,356 @@ |
0fe2d1c5 | 46 | strcat(strcpy(p, "@"), defdomain); |
47 | } | |
48 | ||
49 | +/* siefca@pld.org.pl */ | |
0b0a7302 | 50 | +static const char *get_var_value (const char *begin, size_t len, |
51 | + struct var_data *vd) | |
0fe2d1c5 | 52 | +{ |
0b0a7302 | 53 | +struct var_data *vdp; |
0fe2d1c5 | 54 | + |
0b0a7302 | 55 | + for (vdp=vd; vdp->name; vdp++) |
56 | + if (vdp->size == len+1 && | |
57 | + !strncmp(begin, vdp->name, len)) | |
58 | + { | |
59 | + if (vdp->value) | |
60 | + return (vdp->value); | |
61 | + else | |
62 | + return ""; | |
63 | + } | |
64 | + | |
65 | + fprintf (stderr, "authmysql: unknown substitution variable " | |
66 | + "$(%.*s)\n", len, begin); | |
67 | + | |
68 | + return NULL; | |
69 | +} | |
0fe2d1c5 | 70 | + |
0b0a7302 | 71 | +/* siefca@pld.org.pl */ |
72 | +static size_t parse_core (const char *source, struct var_data *vd, | |
73 | + parsefunc outfn, char *result) | |
74 | +{ | |
75 | +size_t counter = 0, | |
76 | + s = 0, | |
77 | + v_size = 0, | |
78 | + t_size = 0; | |
79 | +const char *p, *q, *e, | |
80 | + *v_begin, *v_end, | |
81 | + *t_begin, *t_end, | |
82 | + *var_value; | |
83 | + | |
84 | + if (!source) | |
85 | + source = ""; | |
86 | + if (result) | |
87 | + *result = '\0'; | |
88 | + | |
89 | + q = source; | |
90 | + while ( (p=strstr(q, "$(")) ) | |
0fe2d1c5 | 91 | + { |
0b0a7302 | 92 | + e = strchr (p, ')'); |
93 | + if (!e) | |
0fe2d1c5 | 94 | + { |
0b0a7302 | 95 | + fprintf (stderr, "authmysql: syntax error in " |
96 | + "substitution variable " | |
97 | + "- no closing bracket!\n" | |
98 | + "authmysql: bad variable begins " | |
99 | + "with: %.*s...\n", 20, p); | |
100 | + return -1; | |
0fe2d1c5 | 101 | + } |
0b0a7302 | 102 | + |
103 | + /* | |
104 | + ** | |
105 | + ** __________sometext$(variable_name)_________ | |
106 | + ** | | | | | |
107 | + ** t_begin' t_end' `v_begin `v_end | |
108 | + ** | |
109 | + */ | |
110 | + | |
111 | + v_begin = p+2; /* variable field ptr */ | |
112 | + v_end = e-1; /* variable field last character */ | |
113 | + v_size = v_end-v_begin+1;/* variable field length */ | |
114 | + | |
115 | + t_begin = q; /* text field ptr */ | |
116 | + t_end = p-1; /* text field last character */ | |
117 | + t_size = t_end-t_begin+1;/* text field length */ | |
118 | + | |
119 | + if (result) /* function building mode */ | |
0fe2d1c5 | 120 | + { |
0b0a7302 | 121 | + var_value = get_var_value (v_begin, v_size, vd); |
122 | + if (!var_value) return -1; | |
123 | + strncat (result, t_begin, t_size); | |
124 | + strcat (result, var_value); | |
0fe2d1c5 | 125 | + } |
0b0a7302 | 126 | + else /* function counting mode */ |
127 | + { | |
128 | + s = outfn (v_begin, v_size, vd); | |
129 | + if (s == -1) return -1; | |
130 | + counter += s; | |
0fe2d1c5 | 131 | + } |
0b0a7302 | 132 | + q = e + 1; |
133 | + } | |
134 | + | |
135 | + if (result) | |
136 | + strcat(result, q); | |
137 | + | |
138 | + return counter; | |
139 | +} | |
140 | + | |
141 | +/* siefca@pld.org.pl */ | |
142 | +size_t ParsePlugin_variable_len (const char *begin, size_t len, | |
143 | + struct var_data *vd) | |
144 | +{ | |
145 | + return (len + 3); | |
146 | +} | |
147 | + | |
148 | +/* siefca@pld.org.pl */ | |
149 | +size_t ParsePlugin_validate (const char *begin, size_t len, | |
150 | + struct var_data *vd) | |
151 | +{ | |
152 | +struct var_data *vdp; | |
153 | + | |
154 | + if (!len) | |
155 | + { | |
156 | + fprintf (stderr, "authmysql: unknown empty substitution " | |
157 | + "variable - aborting\n"); | |
158 | + return -1; | |
0fe2d1c5 | 159 | + } |
0b0a7302 | 160 | + |
161 | + if (!begin || !vd) /* should never happend */ | |
162 | + { | |
163 | + fprintf (stderr, "authmysql: critical error while " | |
164 | + "parsing substitution variable\n"); | |
165 | + return -1; | |
166 | + } | |
167 | + | |
168 | + if (len > 32) | |
169 | + { | |
170 | + fprintf (stderr, "authmysql: variable name too long " | |
171 | + "while parsing substitution\n" | |
172 | + "authmysql: name begins with " | |
173 | + "$(%.*s...\n", 32, begin); | |
174 | + return -1; | |
175 | + } | |
176 | + | |
177 | + for (vdp=vd; vdp->name; vdp++) | |
178 | + if (vdp->size == len+1 && | |
179 | + !strncmp(begin, vdp->name, len)) | |
180 | + return 0; | |
181 | + | |
182 | + fprintf (stderr, "authmysql: unknown substitution variable " | |
183 | + "$(%.*s)\n", len, begin); | |
184 | + return -1; | |
185 | +} | |
186 | + | |
187 | +/* siefca@pld.org.pl */ | |
188 | +size_t ParsePlugin_value_len (const char *begin, size_t len, | |
189 | + struct var_data *vd) | |
190 | +{ | |
191 | +struct var_data *vdp; | |
192 | + | |
193 | + for (vdp=vd; vdp->name; vdp++) | |
194 | + if (vdp->size == len+1 && | |
195 | + !strncmp(begin, vdp->name, len)) | |
0fe2d1c5 | 196 | + { |
0b0a7302 | 197 | + if (!vdp->value) /* should never happend */ |
198 | + return 0; | |
199 | + if (!vdp->value_length) /* length cache */ | |
200 | + vdp->value_length = strlen (vdp->value); | |
201 | + return (vdp->value_length); | |
0fe2d1c5 | 202 | + } |
0fe2d1c5 | 203 | + |
0b0a7302 | 204 | + fprintf (stderr, "authmysql: missing variable while calculating values " |
205 | + "for substitution!\n"); | |
206 | + | |
207 | + return -1; | |
0fe2d1c5 | 208 | +} |
209 | + | |
210 | +/* siefca@pld.org.pl */ | |
0b0a7302 | 211 | +static char *parse_string (const char *source, struct var_data *vd) |
212 | +{ | |
213 | +char *output_buf; | |
214 | +size_t buf_size, | |
215 | + variables_size, | |
216 | + values_size; | |
217 | + | |
218 | + if (source == NULL || *source == '\0' || | |
219 | + vd == NULL || vd[0].name == NULL) | |
220 | + { | |
221 | + fprintf (stderr, "authmysql: source clause is empty " | |
222 | + "- this is critical error\n"); | |
223 | + return NULL; | |
224 | + } | |
225 | + | |
226 | + /* phase 1 - check for bad variables */ | |
227 | + if ((parse_core (source, vd, ParsePlugin_validate, NULL)) != 0) | |
228 | + return NULL; | |
229 | + | |
230 | + /* phase 2 - calculate output buffer space */ | |
231 | + values_size = parse_core (source, vd, ParsePlugin_value_len, NULL); | |
232 | + variables_size = parse_core (source, vd, ParsePlugin_variable_len, NULL); | |
233 | + if (variables_size == -1 || values_size == -1) return NULL; | |
234 | + buf_size = 2 + (strlen(source)) + values_size - variables_size; | |
235 | + | |
236 | + /* phase 3 - allocate memory */ | |
237 | + output_buf = malloc (buf_size); | |
238 | + if (!output_buf) | |
239 | + { | |
240 | + perror ("malloc"); | |
241 | + return NULL; | |
242 | + } | |
243 | + | |
244 | + /* phase 4 - build the output string */ | |
245 | + if ((parse_core (source, vd, ParsePlugin_build, output_buf)) != 0) | |
246 | + { | |
247 | + free (output_buf); | |
248 | + return NULL; | |
249 | + } | |
250 | + | |
251 | + return output_buf; | |
252 | +} | |
253 | + | |
254 | +/* siefca@pld.org.pl */ | |
0fe2d1c5 | 255 | +static const char *get_localpart (const char *username) |
256 | +{ | |
0b0a7302 | 257 | +char *p; |
258 | +static char localpart_buf[130]; | |
0fe2d1c5 | 259 | + |
260 | + if (!username || *username == '\0') return NULL; | |
261 | + p = strchr(username,'@'); | |
262 | + if (p) | |
263 | + { | |
264 | + if (p-username > 128) return NULL; | |
265 | + strncpy (localpart_buf, username, p-username); | |
266 | + } | |
267 | + else | |
268 | + { | |
269 | + if ((strlen(username)) > 128) return NULL; | |
270 | + strcpy (localpart_buf, username); | |
271 | + } | |
272 | + | |
273 | + for (p = localpart_buf; *p; p++) | |
0b0a7302 | 274 | + if (*p == '\"' || *p == '\\' || |
275 | + *p == '\'' || (int)(unsigned char)*p < ' ') | |
0fe2d1c5 | 276 | + *p=' '; |
0b0a7302 | 277 | + |
0fe2d1c5 | 278 | + return localpart_buf; |
279 | +} | |
280 | + | |
281 | +/* siefca@pld.org.pl */ | |
282 | +static const char *get_domain (const char *username, const char *defdomain) | |
283 | +{ | |
0b0a7302 | 284 | +static char domain_buf[260]; |
285 | +char *p, *q; | |
0fe2d1c5 | 286 | + |
287 | + if (!username || *username == '\0') return NULL; | |
288 | + p = strchr(username,'@'); | |
289 | + | |
290 | + if (p && *(p+1)) | |
291 | + { | |
292 | + p++; | |
293 | + if ((strlen(p)) > 256) return NULL; | |
294 | + for (q=domain_buf; *p; p++, q++) | |
0b0a7302 | 295 | + if (*p == '\"' || *p == '\\' || |
296 | + *p == '\'' || (int)(unsigned char)*p < ' ') | |
297 | + *p=' '; | |
0fe2d1c5 | 298 | + else |
299 | + *q=*p; | |
300 | + *q='\0'; | |
301 | + return domain_buf; | |
302 | + } | |
303 | + if (defdomain && *defdomain) return defdomain; | |
304 | + | |
305 | + return NULL; | |
306 | +} | |
307 | + | |
308 | +/* siefca@pld.org.pl */ | |
0b0a7302 | 309 | + |
310 | +static const char *validate_password (const char *password) | |
311 | +{ | |
312 | +static char pass_buf[260]; | |
313 | +const char *p; | |
314 | +char *q; | |
315 | + | |
316 | + if (!password || *password == '\0') return NULL; | |
317 | + | |
318 | + if ((strlen(password)) > 256) return NULL; | |
319 | + strcpy (pass_buf, password); | |
320 | + for (p=password,q=pass_buf; *p != '\0'; p++, q++) | |
321 | + { | |
322 | + if (*p == '\"' || *p == '\\' || *p == '\'') | |
323 | + *q++ = '\\'; | |
324 | + *q = *p; | |
325 | + } | |
326 | + | |
327 | + *q = '\0'; | |
328 | + | |
329 | + return pass_buf; | |
330 | +} | |
331 | + | |
332 | + | |
333 | +/* siefca@pld.org.pl */ | |
0fe2d1c5 | 334 | +static char *parse_select_clause (const char *clause, const char *username, |
335 | + const char *defdomain) | |
336 | +{ | |
337 | +static struct var_data vd[]={ | |
0b0a7302 | 338 | + {"local_part", NULL, sizeof("local_part"), 0}, |
339 | + {"domain", NULL, sizeof("domain"), 0}, | |
340 | + {NULL, NULL, 0, 0}}; | |
0fe2d1c5 | 341 | + |
342 | + if (clause == NULL || *clause == '\0' || | |
343 | + !username || *username == '\0') return NULL; | |
344 | + | |
0b0a7302 | 345 | + vd[0].value = get_localpart (username); |
346 | + vd[1].value = get_domain (username, defdomain); | |
0fe2d1c5 | 347 | + if (!vd[0].value || !vd[1].value) return NULL; |
348 | + | |
0b0a7302 | 349 | + return (parse_string (clause, vd)); |
0fe2d1c5 | 350 | +} |
351 | + | |
352 | +/* siefca@pld.org.pl */ | |
353 | +static char *parse_chpass_clause (const char *clause, const char *username, | |
354 | + const char *defdomain, const char *newpass, | |
355 | + const char *newpass_crypt) | |
356 | +{ | |
357 | +static struct var_data vd[]={ | |
0b0a7302 | 358 | + {"local_part", NULL, sizeof("local_part"), 0}, |
359 | + {"domain", NULL, sizeof("domain"), 0}, | |
360 | + {"newpass", NULL, sizeof("newpass"), 0}, | |
361 | + {"newpass_crypt", NULL, sizeof("newpass_crypt"), 0}, | |
362 | + {NULL, NULL, 0, 0}}; | |
0fe2d1c5 | 363 | + |
364 | + if (clause == NULL || *clause == '\0' || | |
365 | + !username || *username == '\0' || | |
366 | + !newpass || *newpass == '\0' || | |
367 | + !newpass_crypt || *newpass_crypt == '\0') return NULL; | |
368 | + | |
0b0a7302 | 369 | + vd[0].value = get_localpart (username); |
370 | + vd[1].value = get_domain (username, defdomain); | |
371 | + vd[2].value = validate_password (newpass); | |
372 | + vd[3].value = validate_password (newpass_crypt); | |
373 | + | |
374 | + if (!vd[0].value || !vd[1].value || | |
375 | + !vd[2].value || !vd[3].value) return NULL; | |
0fe2d1c5 | 376 | + |
0b0a7302 | 377 | + return (parse_string (clause, vd)); |
0fe2d1c5 | 378 | +} |
0fe2d1c5 | 379 | + |
380 | struct authmysqluserinfo *auth_mysql_getuserinfo(const char *username) | |
381 | { | |
382 | -const char *user_table; | |
383 | -const char *defdomain; | |
384 | +const char *user_table =NULL; | |
385 | +const char *defdomain =NULL; | |
386 | char *querybuf, *p; | |
387 | MYSQL_ROW row; | |
388 | MYSQL_RES *result; | |
389 | ||
390 | -const char *crypt_field, *clear_field, *maildir_field, *home_field, | |
391 | - *name_field, | |
392 | - *login_field, *uid_field, *gid_field, *quota_field, *where_clause; | |
393 | +const char *crypt_field =NULL, | |
394 | + *clear_field =NULL, | |
395 | + *maildir_field =NULL, | |
396 | + *home_field =NULL, | |
397 | + *name_field =NULL, | |
398 | + *login_field =NULL, | |
399 | + *uid_field =NULL, | |
400 | + *gid_field =NULL, | |
401 | + *quota_field =NULL, | |
402 | + *where_clause =NULL, | |
403 | + *select_clause =NULL; /* siefca@pld.org.pl */ | |
404 | ||
405 | static const char query[]= | |
406 | "SELECT %s, %s, %s, %s, %s, %s, %s, %s, %s FROM %s WHERE %s = \""; | |
0b0a7302 | 407 | @@ -232,79 +587,95 @@ |
0fe2d1c5 | 408 | free(ui.fullname); |
409 | memset(&ui, 0, sizeof(ui)); | |
410 | ||
411 | - user_table=read_env("MYSQL_USER_TABLE"); | |
412 | - defdomain=read_env("DEFAULT_DOMAIN"); | |
413 | - | |
414 | - if (!user_table) | |
415 | + select_clause=read_env("MYSQL_SELECT_CLAUSE"); | |
416 | + defdomain=read_env("DEFAULT_DOMAIN"); | |
417 | + | |
418 | + if (!select_clause) /* siefca@pld.org.pl */ | |
419 | { | |
420 | - fprintf(stderr, "authmysql: MYSQL_USER_TABLE not set in " | |
421 | - AUTHMYSQLRC ".\n"); | |
422 | - return (0); | |
423 | - } | |
424 | + user_table=read_env("MYSQL_USER_TABLE"); | |
425 | ||
426 | - crypt_field=read_env("MYSQL_CRYPT_PWFIELD"); | |
427 | - clear_field=read_env("MYSQL_CLEAR_PWFIELD"); | |
428 | - name_field=read_env("MYSQL_NAME_FIELD"); | |
429 | + if (!user_table) | |
430 | + { | |
431 | + fprintf(stderr, "authmysql: MYSQL_USER_TABLE not set in " | |
432 | + AUTHMYSQLRC ".\n"); | |
433 | + return (0); | |
434 | + } | |
435 | ||
436 | - if (!crypt_field && !clear_field) | |
437 | - { | |
438 | - fprintf(stderr, | |
439 | - "authmysql: MYSQL_CRYPT_PWFIELD and " | |
440 | - "MYSQL_CLEAR_PWFIELD not set in " AUTHMYSQLRC ".\n"); | |
441 | - return (0); | |
442 | - } | |
443 | - if (!crypt_field) crypt_field="\"\""; | |
444 | - if (!clear_field) clear_field="\"\""; | |
445 | - if (!name_field) name_field="\"\""; | |
446 | + crypt_field=read_env("MYSQL_CRYPT_PWFIELD"); | |
447 | + clear_field=read_env("MYSQL_CLEAR_PWFIELD"); | |
448 | + name_field=read_env("MYSQL_NAME_FIELD"); | |
449 | ||
450 | - uid_field = read_env("MYSQL_UID_FIELD"); | |
451 | - if (!uid_field) uid_field = "uid"; | |
452 | + if (!crypt_field && !clear_field) | |
453 | + { | |
454 | + fprintf(stderr, | |
455 | + "authmysql: MYSQL_CRYPT_PWFIELD and " | |
456 | + "MYSQL_CLEAR_PWFIELD not set in " AUTHMYSQLRC ".\n"); | |
457 | + return (0); | |
458 | + } | |
459 | + if (!crypt_field) crypt_field="\"\""; | |
460 | + if (!clear_field) clear_field="\"\""; | |
461 | + if (!name_field) name_field="\"\""; | |
0fe2d1c5 | 462 | |
463 | - gid_field = read_env("MYSQL_GID_FIELD"); | |
464 | - if (!gid_field) gid_field = "gid"; | |
0b0a7302 | 465 | + uid_field = read_env("MYSQL_UID_FIELD"); |
466 | + if (!uid_field) uid_field = "uid"; | |
0fe2d1c5 | 467 | |
468 | - login_field = read_env("MYSQL_LOGIN_FIELD"); | |
469 | - if (!login_field) login_field = "id"; | |
0b0a7302 | 470 | + gid_field = read_env("MYSQL_GID_FIELD"); |
471 | + if (!gid_field) gid_field = "gid"; | |
0fe2d1c5 | 472 | |
473 | - home_field = read_env("MYSQL_HOME_FIELD"); | |
474 | - if (!home_field) home_field = "home"; | |
0b0a7302 | 475 | + login_field = read_env("MYSQL_LOGIN_FIELD"); |
476 | + if (!login_field) login_field = "id"; | |
0fe2d1c5 | 477 | |
478 | - maildir_field=read_env("MYSQL_MAILDIR_FIELD"); | |
479 | - if (!maildir_field) maildir_field="\"\""; | |
0b0a7302 | 480 | + home_field = read_env("MYSQL_HOME_FIELD"); |
481 | + if (!home_field) home_field = "home"; | |
0fe2d1c5 | 482 | |
483 | - quota_field=read_env("MYSQL_QUOTA_FIELD"); | |
484 | - if (!quota_field) quota_field="\"\""; | |
0b0a7302 | 485 | + maildir_field=read_env("MYSQL_MAILDIR_FIELD"); |
486 | + if (!maildir_field) maildir_field="\"\""; | |
0fe2d1c5 | 487 | |
488 | - where_clause=read_env("MYSQL_WHERE_CLAUSE"); | |
489 | - if (!where_clause) where_clause = ""; | |
0b0a7302 | 490 | + quota_field=read_env("MYSQL_QUOTA_FIELD"); |
491 | + if (!quota_field) quota_field="\"\""; | |
492 | + | |
0fe2d1c5 | 493 | + where_clause=read_env("MYSQL_WHERE_CLAUSE"); |
494 | + if (!where_clause) where_clause = ""; | |
495 | + } | |
496 | ||
497 | if (!defdomain) defdomain=""; | |
498 | ||
499 | - querybuf=malloc(sizeof(query) + 100 + strlen(user_table) + strlen(defdomain) | |
500 | - + strlen(crypt_field) + strlen(clear_field) + strlen(maildir_field) | |
501 | - + strlen(uid_field) + strlen(gid_field) + 2 * strlen(login_field) | |
502 | - + strlen(home_field) + strlen(quota_field) + strlen(where_clause) | |
0b0a7302 | 503 | - + strlen(name_field)); |
504 | - if (!querybuf) | |
0fe2d1c5 | 505 | + if (!select_clause) /* siefca@pld.org.pl */ |
0b0a7302 | 506 | { |
507 | - perror("malloc"); | |
508 | - return (0); | |
509 | - } | |
0fe2d1c5 | 510 | + querybuf=malloc(sizeof(query) + 100 + strlen(user_table) + strlen(defdomain) |
511 | + + strlen(crypt_field) + strlen(clear_field) + strlen(maildir_field) | |
512 | + + strlen(uid_field) + strlen(gid_field) + 2 * strlen(login_field) | |
513 | + + strlen(home_field) + strlen(quota_field) + strlen(where_clause) | |
0b0a7302 | 514 | + + strlen(name_field)); |
515 | ||
516 | - sprintf(querybuf, query, login_field, crypt_field, clear_field, | |
517 | - uid_field, gid_field, home_field, maildir_field, quota_field, | |
518 | - name_field, user_table, login_field); | |
519 | - p=querybuf+strlen(querybuf); | |
0fe2d1c5 | 520 | + if (!querybuf) |
521 | + { | |
522 | + perror("malloc"); | |
523 | + return (0); | |
524 | + } | |
525 | + | |
526 | + sprintf(querybuf, query, login_field, crypt_field, clear_field, | |
527 | + uid_field, gid_field, home_field, maildir_field, quota_field, | |
528 | + name_field, user_table, login_field); | |
529 | + | |
530 | + p=querybuf+strlen(querybuf); | |
0b0a7302 | 531 | |
532 | - append_username(p, username, defdomain); | |
533 | - strcat(p, "\""); | |
0fe2d1c5 | 534 | + append_username(p, username, defdomain); |
535 | + strcat(p, "\""); | |
0b0a7302 | 536 | |
537 | - if (strcmp(where_clause, "")) { | |
538 | - strcat(p, " AND ("); | |
539 | - strcat(p, where_clause); | |
540 | - strcat(p, ")"); | |
0fe2d1c5 | 541 | + if (strcmp(where_clause, "")) { |
542 | + strcat(p, " AND ("); | |
543 | + strcat(p, where_clause); | |
544 | + strcat(p, ")"); | |
545 | + } | |
0b0a7302 | 546 | } |
547 | - | |
0fe2d1c5 | 548 | + else |
0b0a7302 | 549 | + { |
0fe2d1c5 | 550 | + /* siefca@pld.org.pl */ |
551 | + querybuf=parse_select_clause (select_clause, username, defdomain); | |
552 | + if (!querybuf) return 0; | |
0b0a7302 | 553 | + } |
554 | + | |
0fe2d1c5 | 555 | if (mysql_query (mysql, querybuf)) |
556 | { | |
557 | /* <o.blasnik@nextra.de> */ | |
0b0a7302 | 558 | @@ -379,12 +750,13 @@ |
0fe2d1c5 | 559 | const char *comma; |
560 | int rc=0; | |
561 | ||
562 | - const char *clear_field; | |
563 | - const char *crypt_field; | |
564 | - const char *defdomain; | |
565 | - const char *where_clause; | |
566 | - const char *user_table; | |
567 | - const char *login_field; | |
568 | + const char *clear_field =NULL, | |
569 | + *crypt_field =NULL, | |
570 | + *defdomain =NULL, | |
571 | + *where_clause =NULL, | |
572 | + *user_table =NULL, | |
573 | + *login_field =NULL, | |
574 | + *chpass_clause =NULL; /* siefca@pld.org.pl */ | |
575 | ||
576 | if (!mysql) | |
577 | return (-1); | |
0b0a7302 | 578 | @@ -412,21 +784,34 @@ |
0fe2d1c5 | 579 | ++l; |
580 | } | |
581 | ||
582 | - login_field = read_env("MYSQL_LOGIN_FIELD"); | |
583 | - if (!login_field) login_field = "id"; | |
584 | - crypt_field=read_env("MYSQL_CRYPT_PWFIELD"); | |
585 | - clear_field=read_env("MYSQL_CLEAR_PWFIELD"); | |
586 | + /* siefca@pld.org.pl */ | |
587 | + chpass_clause=read_env("MYSQL_CHPASS_CLAUSE"); | |
588 | defdomain=read_env("DEFAULT_DOMAIN"); | |
589 | - where_clause=read_env("MYSQL_WHERE_CLAUSE"); | |
590 | user_table=read_env("MYSQL_USER_TABLE"); | |
591 | - | |
592 | - sql_buf=malloc(strlen(crypt_field ? crypt_field:"") | |
593 | - + strlen(clear_field ? clear_field:"") | |
594 | - + strlen(defdomain ? defdomain:"") | |
595 | - + strlen(login_field) + l + strlen(newpass_crypt) | |
596 | - + strlen(user_table) | |
597 | - + strlen(where_clause ? where_clause:"") | |
598 | - + 200); | |
599 | + if (!chpass_clause) | |
600 | + { | |
601 | + login_field = read_env("MYSQL_LOGIN_FIELD"); | |
602 | + if (!login_field) login_field = "id"; | |
603 | + crypt_field=read_env("MYSQL_CRYPT_PWFIELD"); | |
604 | + clear_field=read_env("MYSQL_CLEAR_PWFIELD"); | |
605 | + where_clause=read_env("MYSQL_WHERE_CLAUSE"); | |
606 | + sql_buf=malloc(strlen(crypt_field ? crypt_field:"") | |
607 | + + strlen(clear_field ? clear_field:"") | |
608 | + + strlen(defdomain ? defdomain:"") | |
609 | + + strlen(login_field) + l + strlen(newpass_crypt) | |
610 | + + strlen(user_table) | |
611 | + + strlen(where_clause ? where_clause:"") | |
612 | + + 200); | |
613 | + } | |
614 | + else | |
615 | + { | |
616 | + sql_buf=parse_chpass_clause(chpass_clause, | |
617 | + user, | |
618 | + defdomain, | |
619 | + pass, | |
620 | + newpass_crypt); | |
621 | + } | |
622 | + | |
623 | ||
624 | if (!sql_buf) | |
625 | { | |
0b0a7302 | 626 | @@ -434,53 +819,57 @@ |
0fe2d1c5 | 627 | return (-1); |
628 | } | |
629 | ||
630 | - sprintf(sql_buf, "UPDATE %s SET", user_table); | |
631 | - | |
632 | - comma=""; | |
633 | - | |
634 | - if (clear_field && *clear_field) | |
635 | + if (!chpass_clause) /*siefca@pld.org.pl */ | |
636 | { | |
637 | - char *q; | |
638 | + sprintf(sql_buf, "UPDATE %s SET", user_table); | |
639 | ||
640 | - strcat(strcat(strcat(sql_buf, " "), clear_field), | |
641 | - "=\""); | |
642 | + comma=""; | |
643 | ||
644 | - q=sql_buf+strlen(sql_buf); | |
645 | - while (*pass) | |
646 | + if (clear_field && *clear_field) | |
647 | { | |
648 | - if (*pass == '"' || *pass == '\\') | |
649 | - *q++= '\\'; | |
650 | - *q++ = *pass++; | |
651 | + char *q; | |
652 | + | |
653 | + strcat(strcat(strcat(sql_buf, " "), clear_field), | |
654 | + "=\""); | |
655 | + | |
656 | + q=sql_buf+strlen(sql_buf); | |
657 | + while (*pass) | |
658 | + { | |
659 | + if (*pass == '"' || *pass == '\\') | |
660 | + *q++= '\\'; | |
661 | + *q++ = *pass++; | |
662 | + } | |
663 | + strcpy(q, "\""); | |
664 | + comma=", "; | |
665 | } | |
666 | - strcpy(q, "\""); | |
667 | - comma=", "; | |
668 | - } | |
669 | ||
670 | - if (crypt_field && *crypt_field) | |
671 | - { | |
672 | - strcat(strcat(strcat(strcat(strcat(strcat(sql_buf, comma), | |
673 | - " "), | |
674 | - crypt_field), | |
675 | - "=\""), | |
676 | - newpass_crypt_ptr), | |
677 | - "\""); | |
678 | - } | |
679 | - free(newpass_crypt); | |
680 | + if (crypt_field && *crypt_field) | |
681 | + { | |
682 | + strcat(strcat(strcat(strcat(strcat(strcat(sql_buf, comma), | |
683 | + " "), | |
684 | + crypt_field), | |
685 | + "=\""), | |
686 | + newpass_crypt_ptr), | |
687 | + "\""); | |
688 | + } | |
689 | + free(newpass_crypt); | |
690 | ||
691 | - strcat(strcat(strcat(sql_buf, " WHERE "), | |
692 | - login_field), | |
693 | - "=\""); | |
694 | + strcat(strcat(strcat(sql_buf, " WHERE "), | |
695 | + login_field), | |
696 | + "=\""); | |
697 | ||
698 | - append_username(sql_buf+strlen(sql_buf), user, defdomain); | |
699 | + append_username(sql_buf+strlen(sql_buf), user, defdomain); | |
700 | ||
701 | - strcat(sql_buf, "\""); | |
702 | + strcat(sql_buf, "\""); | |
703 | ||
704 | - if (where_clause && *where_clause) | |
705 | - { | |
706 | - strcat(sql_buf, " AND ("); | |
707 | - strcat(sql_buf, where_clause); | |
708 | - strcat(sql_buf, ")"); | |
709 | - } | |
710 | + if (where_clause && *where_clause) | |
711 | + { | |
712 | + strcat(sql_buf, " AND ("); | |
713 | + strcat(sql_buf, where_clause); | |
714 | + strcat(sql_buf, ")"); | |
715 | + } | |
716 | + | |
717 | + } /* end of: if (!chpass_clause) */ | |
718 | ||
719 | if (mysql_query (mysql, sql_buf)) | |
720 | { | |
721 | diff -ur courier-imap-1.3.12.orig/authlib/authmysqlrc courier-imap-1.3.12/authlib/authmysqlrc | |
722 | --- courier-imap-1.3.12.orig/authlib/authmysqlrc Sun Oct 7 18:32:56 2001 | |
0b0a7302 | 723 | +++ courier-imap-1.3.12/authlib/authmysqlrc Thu Dec 27 03:43:47 2001 |
724 | @@ -141,4 +141,65 @@ | |
0fe2d1c5 | 725 | # |
726 | # MYSQL_WHERE_CLAUSE server='mailhost.example.com' | |
727 | ||
728 | - | |
729 | +##NAME: MYSQL_SELECT_CLAUSE:0 | |
730 | +# | |
731 | +# (EXPERIMENTAL) | |
732 | +# This is optional, MYSQL_SELECT_CLAUSE can be set when you have a database, | |
733 | +# which is structuraly different from proposed. The fixed string will | |
734 | +# be used to do a SELECT operation on database, which should return fields | |
0b0a7302 | 735 | +# in order specified bellow: |
0fe2d1c5 | 736 | +# |
737 | +# username, cryptpw, uid, gid, clearpw, home, maildir, quota, fullname | |
738 | +# | |
739 | +# Enabling this option causes ignorance of any other field-related | |
740 | +# options, excluding default domain. | |
741 | +# | |
742 | +# There are two variables, which you can use. Substitution will be made | |
743 | +# for them, so you can put entered username (local part) and domain name | |
0b0a7302 | 744 | +# in the right place of your query. These variables are: |
745 | +# $(local_part) and $(domain) | |
0fe2d1c5 | 746 | +# |
747 | +# If a $(domain) is empty (not given by the remote user) the default domain | |
748 | +# name is used in its place. | |
749 | +# | |
750 | +# This example is a little bit modified adaptation of vmail-sql | |
751 | +# database scheme: | |
0b0a7302 | 752 | +# |
753 | +# MYSQL_SELECT_CLAUSE SELECT popbox.local_part, \ | |
0fe2d1c5 | 754 | +# CONCAT('{MD5}', popbox.password_hash), \ |
755 | +# domain.uid, \ | |
756 | +# domain.gid, \ | |
757 | +# popbox.clearpw, \ | |
758 | +# CONCAT(domain.path, '/', popbox.mbox_name), \ | |
759 | +# '', \ | |
760 | +# domain.quota, \ | |
761 | +# '', \ | |
762 | +# FROM popbox, domain \ | |
763 | +# WHERE popbox.local_part = '$(local_part)' \ | |
764 | +# AND popbox.domain_name = '$(domain)' \ | |
765 | +# AND popbox.domain_name = domain.domain_name | |
766 | +# | |
767 | +##NAME: MYSQL_CHPASS_CLAUSE:0 | |
768 | +# | |
769 | +# (EXPERIMENTAL) | |
770 | +# This is optional, MYSQL_CHPASS_CLAUSE can be set when you have a database, | |
771 | +# which is structuraly different from proposed. The fixed string will | |
772 | +# be used to do an UPDATE operation on database. In other words, it is | |
773 | +# used, when changing password. | |
774 | +# | |
775 | +# There are four variables, which you can use. Substitution will be made | |
776 | +# for them, so you can put entered username (local part) and domain name | |
777 | +# in the right place of your query. There variables are: | |
778 | +# $(local_part) , $(domain) , $(newpass) , $(newpass_crypt) | |
779 | +# | |
780 | +# If a $(domain) is empty (not given by the remote user) the default domain | |
781 | +# name is used in its place. | |
782 | +# $(newpass) contains plain password | |
783 | +# $(newpass_crypt) contains its crypted form | |
784 | +# | |
785 | +# MYSQL_CHPASS_CLAUSE UPDATE popbox \ | |
786 | +# SET clearpw='$(newpass)', \ | |
787 | +# password_hash='$(newpass_crypt)' \ | |
788 | +# WHERE local_part='$(local_part)' \ | |
789 | +# AND domain_name='$(domain)' | |
790 | +# |