2 ** Copyright 2012 Double Precision, Inc. See COPYING for
3 ** distribution information.
11 #include <sys/types.h>
15 #include "authsqlite.h"
16 #include "authsqliterc.h"
18 #include "courierauthdebug.h"
20 #define err courier_auth_err
21 #define GET(c) ((c) < (n) && columns[(c)] ? columns[(c)]:"")
23 static const char *read_env(const char *env
)
25 return authgetconfig(AUTHSQLITERC
, env
);
28 static sqlite3
*dbh
=0;
37 p
=read_env("SQLITE_DATABASE");
45 if (sqlite3_open_v2(p
, &dbh
, SQLITE_OPEN_READWRITE
, NULL
) != SQLITE_OK
)
49 err("sqllite3_open(%s): %s", p
, sqlite3_errmsg(dbh
));
59 void auth_sqlite_cleanup()
68 static char *escape_str(const char *c
, size_t n
)
70 char *p
=malloc(n
+1), *q
;
81 q
=sqlite3_mprintf("%q", p
);
94 static struct authsqliteuserinfo ui
={0, 0, 0, 0, 0, 0, 0, 0};
116 memset(&ui
, 0, sizeof(ui
));
119 static int select_callback(void *dummy
, int n
, char **columns
, char **names
)
123 err("Multiple rows returned");
131 err("Query came back with fewer than 6 columns");
135 if ((ui
.username
=strdup(GET(0))) == NULL
136 || (ui
.cryptpw
=strdup(GET(1))) == NULL
137 || (ui
.clearpw
=strdup(GET(2))) == NULL
138 || (ui
.home
=strdup(GET(5))) == NULL
139 || (ui
.maildir
=strdup(GET(6))) == NULL
140 || (ui
.quota
=strdup(GET(7))) == NULL
141 || (ui
.fullname
=strdup(GET(8))) == NULL
142 || (ui
.options
=strdup(GET(9))) == NULL
)
154 struct authsqliteuserinfo
*auth_sqlite_getuserinfo(const char *username
,
157 const char *defdomain
=NULL
;
160 const char *select_clause
;
162 #define DEFAULT_SELECT_QUERY "SELECT %s, %s, %s, %s, %s, %s, %s, %s, %s, %s FROM %s WHERE %s = '%s%s%s' %s%s%s", \
163 login_field, crypt_field, clear_field, uid_field,\
164 gid_field, home_field, maildir_field, quota_field,\
165 name_field, options_field, user_table, login_field,\
167 has_domain || !*defdomain ? "":"@", has_domain ? "":defdomain, \
168 *where_clause ? " AND (":"", where_clause,\
169 *where_clause ? ")":""
176 select_clause
=read_env("SQLITE_SELECT_CLAUSE");
177 defdomain
=read_env("DEFAULT_DOMAIN");
178 if (!defdomain
) defdomain
="";
180 if (!select_clause
) /* siefca@pld.org.pl */
182 const char *user_table
,
194 char *username_escaped
;
199 user_table
=read_env("SQLITE_USER_TABLE");
203 err("authsqlite: SQLITE_USER_TABLE not set in "
208 crypt_field
=read_env("SQLITE_CRYPT_PWFIELD");
209 clear_field
=read_env("SQLITE_CLEAR_PWFIELD");
210 name_field
=read_env("SQLITE_NAME_FIELD");
212 if (!crypt_field
&& !clear_field
)
214 err("authsqlite: SQLITE_CRYPT_PWFIELD and "
215 "SQLITE_CLEAR_PWFIELD not set in " AUTHSQLITERC
".");
218 if (!crypt_field
) crypt_field
="\"\"";
219 if (!clear_field
) clear_field
="\"\"";
220 if (!name_field
) name_field
="\"\"";
222 uid_field
= read_env("SQLITE_UID_FIELD");
223 if (!uid_field
) uid_field
= "uid";
225 gid_field
= read_env("SQLITE_GID_FIELD");
226 if (!gid_field
) gid_field
= "gid";
228 login_field
= read_env("SQLITE_LOGIN_FIELD");
229 if (!login_field
) login_field
= "id";
231 home_field
= read_env("SQLITE_HOME_FIELD");
232 if (!home_field
) home_field
= "home";
234 maildir_field
=read_env(service
&& strcmp(service
, "courier")==0
235 ? "SQLITE_DEFAULTDELIVERY"
236 : "SQLITE_MAILDIR_FIELD");
237 if (!maildir_field
) maildir_field
="\"\"";
239 quota_field
=read_env("SQLITE_QUOTA_FIELD");
240 if (!quota_field
) quota_field
="\"\"";
242 options_field
=read_env("SQLITE_AUXOPTIONS_FIELD");
243 if (!options_field
) options_field
="\"\"";
245 where_clause
=read_env("SQLITE_WHERE_CLAUSE");
246 if (!where_clause
) where_clause
= "";
248 username_escaped
=escape_str(username
, strlen(username
));
250 if (!username_escaped
)
256 has_domain
=strchr(username
, '@') != NULL
;
258 query_size
=snprintf(dummy_buf
, 1, DEFAULT_SELECT_QUERY
);
260 querybuf
=malloc(query_size
+1);
264 free(username_escaped
);
269 snprintf(querybuf
, query_size
+1, DEFAULT_SELECT_QUERY
);
270 free(username_escaped
);
275 /* siefca@pld.org.pl */
276 querybuf
=auth_parse_select_clause (escape_str
,
277 select_clause
, username
,
281 DPRINTF("parse_select_clause failed (DEFAULT_DOMAIN not set?)");
286 DPRINTF("SQL query: %s", querybuf
);
289 if (sqlite3_exec(dbh
, querybuf
, select_callback
,
290 NULL
, &errmsg
) != SQLITE_OK
)
295 sqlite3_free(errmsg
);
306 sqlite3_free(errmsg
);
312 static int dummy_callback(void *dummy
, int n
, char **columns
, char **names
)
317 int auth_sqlite_setpass(const char *user
, const char *pass
,
327 const char *clear_field
=NULL
,
333 *chpass_clause
=NULL
; /* siefca@pld.org.pl */
335 if (!do_connect()) return (-1);
337 if (!(newpass_crypt
=authcryptpasswd(pass
, oldpass
)))
340 clear_escaped
=escape_str(pass
, strlen(pass
));
349 crypt_escaped
=escape_str(newpass_crypt
, strlen(newpass_crypt
));
359 /* siefca@pld.org.pl */
360 chpass_clause
=read_env("SQLITE_CHPASS_CLAUSE");
361 defdomain
=read_env("DEFAULT_DOMAIN");
362 user_table
=read_env("SQLITE_USER_TABLE");
365 int has_domain
=strchr(user
, '@') != NULL
;
366 char *username_escaped
;
370 username_escaped
=escape_str(user
, strlen(user
));
372 if (!username_escaped
)
381 login_field
= read_env("SQLITE_LOGIN_FIELD");
382 if (!login_field
) login_field
= "id";
383 crypt_field
=read_env("SQLITE_CRYPT_PWFIELD");
384 clear_field
=read_env("SQLITE_CLEAR_PWFIELD");
385 where_clause
=read_env("SQLITE_WHERE_CLAUSE");
399 #define DEFAULT_SETPASS_UPDATE \
400 "UPDATE %s SET %s%s%s%s %s %s%s%s%s WHERE %s='%s%s%s' %s%s%s", \
402 *clear_field ? clear_field:"", \
403 *clear_field ? "='":"", \
404 *clear_field ? clear_escaped:"", \
405 *clear_field ? "'":"", \
407 *clear_field && *crypt_field ? ",":"", \
409 *crypt_field ? crypt_field:"", \
410 *crypt_field ? "='":"", \
411 *crypt_field ? crypt_escaped:"", \
412 *crypt_field ? "'":"", \
415 has_domain || !*defdomain ? "":"@", \
416 has_domain ? "":defdomain, \
417 *where_clause ? " AND (":"", where_clause, \
418 *where_clause ? ")":""
421 sql_buf_size
=snprintf(dummy_buf
, 1, DEFAULT_SETPASS_UPDATE
);
423 sql_buf
=malloc(sql_buf_size
+1);
426 snprintf(sql_buf
, sql_buf_size
+1,
427 DEFAULT_SETPASS_UPDATE
);
429 free(username_escaped
);
433 sql_buf
=auth_parse_chpass_clause(escape_str
, chpass_clause
,
444 if (courier_authdebug_login_level
>= 2)
446 DPRINTF("setpass SQL: %s", sql_buf
);
451 if (sqlite3_exec(dbh
, sql_buf
, dummy_callback
,
452 NULL
, &errmsg
) != SQLITE_OK
)
458 if (sqlite3_changes(dbh
) > 0)
460 DPRINTF("authsqllite: password updated");
465 DPRINTF("authsqllite: password not updated");
472 sqlite3_free(errmsg
);
479 struct enumerate_user_cb
{
481 void (*cb_func
)(const char *name
,
491 static int enumerate_callback(void *closure
,
492 int n
, char **columns
, char **names
)
494 struct enumerate_user_cb
*cb
=(struct enumerate_user_cb
*)closure
;
496 const char *username
;
504 uid
=atol(GET(1)); /* FIXME use strtol to validate */
510 if (maildir
&& !*maildir
)
513 if (options
&& !*options
)
516 (*cb
->cb_func
)(username
, uid
, gid
, homedir
,
517 maildir
, options
, cb
->void_arg
);
521 void auth_sqlite_enumerate( void(*cb_func
)(const char *name
,
530 const char *defdomain
, *select_clause
;
533 struct enumerate_user_cb cb
;
536 cb
.void_arg
=void_arg
;
538 if (!do_connect()) return;
542 select_clause
=read_env("SQLITE_ENUMERATE_CLAUSE");
543 defdomain
=read_env("DEFAULT_DOMAIN");
544 if (!defdomain
|| !defdomain
[0])
545 defdomain
="*"; /* otherwise parse_select_clause fails */
549 const char *user_table
,
560 user_table
=read_env("SQLITE_USER_TABLE");
564 err("authsqlite: SQLITE_USER_TABLE not set in "
569 uid_field
= read_env("SQLITE_UID_FIELD");
570 if (!uid_field
) uid_field
= "uid";
572 gid_field
= read_env("SQLITE_GID_FIELD");
573 if (!gid_field
) gid_field
= "gid";
575 login_field
= read_env("SQLITE_LOGIN_FIELD");
576 if (!login_field
) login_field
= "id";
578 home_field
= read_env("SQLITE_HOME_FIELD");
579 if (!home_field
) home_field
= "home";
581 maildir_field
=read_env("SQLITE_MAILDIR_FIELD");
582 if (!maildir_field
) maildir_field
="\"\"";
584 options_field
=read_env("SQLITE_AUXOPTIONS_FIELD");
585 if (!options_field
) options_field
="\"\"";
587 where_clause
=read_env("SQLITE_WHERE_CLAUSE");
588 if (!where_clause
) where_clause
= "";
591 #define DEFAULT_ENUMERATE_QUERY \
592 "SELECT %s, %s, %s, %s, %s, %s FROM %s %s%s",\
593 login_field, uid_field, gid_field, \
594 home_field, maildir_field, \
595 options_field, user_table, \
596 *where_clause ? " WHERE ":"", \
599 query_len
=snprintf(dummy_buf
, 1, DEFAULT_ENUMERATE_QUERY
);
601 querybuf
=malloc(query_len
+1);
609 snprintf(querybuf
, query_len
+1, DEFAULT_ENUMERATE_QUERY
);
613 /* siefca@pld.org.pl */
614 querybuf
=auth_parse_select_clause (escape_str
,
616 defdomain
, "enumerate");
619 DPRINTF("authsqlite: parse_select_clause failed");
623 DPRINTF("authsqlite: enumerate query: %s", querybuf
);
627 sqlite3_exec(dbh
, querybuf
, enumerate_callback
, &cb
, &errmsg
);
632 sqlite3_free(errmsg
);
636 (*cb
.cb_func
)(NULL
, 0, 0, NULL
, NULL
, NULL
, cb
.void_arg
);