This is a discussion on [courier-users] authsqlite within the Courier-Imap forums, part of the Mail Servers and Related category; This is an OpenPGP/MIME signed message (RFC 2440 and 3156) --===============1473658569== Content-Type: multipart/signed; micalg=pgp-sha1; protocol=&...
|
|||||||
| FAQ | Members List | Calendar | Search | Today's Posts | Mark Forums Read |
|
|||
|
This is an OpenPGP/MIME signed message (RFC 2440 and 3156)
--===============1473658569== Content-Type: multipart/signed; micalg=pgp-sha1; protocol="application/pgp-signature"; boundary="------------enigA850BAB8FE598EA66D9461B0" This is an OpenPGP/MIME signed message (RFC 2440 and 3156) --------------enigA850BAB8FE598EA66D9461B0 Content-Type: multipart/mixed; boundary="------------060002000708030204000906" This is a multi-part message in MIME format. --------------060002000708030204000906 Content-Type: text/plain; charset=ISO-8859-15; format=flowed Content-Transfer-Encoding: quoted-printable Hi folks! I've written a backend for authlib to sqlite3. It's not complete yet, tho= ugh, there are still sever{e,al} security checks missing, which I'll fix after= - wards. Now: what exactly needs to be done to integrate it into the source? Sorry= for asking such a question, but I mainly develop in Python and have no cl= ue about the authlib source structure. Greetings, Fabiano --------------060002000708030204000906 Content-Type: text/plain; name="authsqlite.c" Content-Transfer-Encoding: quoted-printable Content-Disposition: inline; filename="authsqlite.c" #include <errno.h> #include <string.h> #include <stdlib.h> #include <stdarg.h> #include <sqlite3.h> #include "auth.h" #include "authstaticlist.h" #if HAVE_CONFIG_H #include "courier_auth_config.h" #endif #if HAVE_HMACLIB #include "libhmac/hmac.h" #include "cramlib.h" #endif typedef struct authinfo authinfo; typedef int* (*callback)(authinfo*, void*); typedef void (*enumcallback) (const char*, uid_t, gid_t, const char*, const char*, void*); static int auth_sqlite( const char *service, const char *authtype, char *authdata, callback *cb, void *cbarg); static int auth_sqlite_no_vrfy( const char *user, const char *service, callback *cb, void *cbarg); static void auth_sqlite_exit( void); static int auth_sqlite_chgpwd( const char *service, const char *user, const char *oldpwd, const char *newpwd); static void auth_sqlite_idle( void); static void auth_sqlite_enum( enumcallback *cb, void *cbarg); static struct authstaticinfo authsqlite_info=3D{ "authsqlite", auth_sqlite, auth_sqlite_no_vrfy, auth_sqlite_exit, auth_sqlite_chgpwd, auth_sqlite_idle, auth_sqlite_enum, }; static sqlite3 *db; char *errmsg=3DNULL; int rc; char *dbfilename, *emailfld, *uidfld, *gidfld, *homefld, *maildirfld, *passwdfld, *clearpwfld, *optionsfld, *fullnamefld, *quotafld, *table, *pop3table, *imaptable, *smtptable, *userfmt, *pop3userfmt, *imapuserfmt, *smtpuserfmt, *usersfmt, *pop3usersfmt, *imapusersfmt, *smtpusersfmt, *updatefmt, *pop3updatefmt, *imapupdatefmt, *smtpupdatefmt; void err(char *fmt, ...) { va_list args; va_start(args,fmt); vprintf(fmt, args); va_end(args); } static char* concat( char *first, char *next, ...) { va_list args1, args2; int retlen=3D0; char *p,*ret,*retend; =09 retlen =3D strlen(first) + strlen(next); va_start(args1, next); va_copy(args2, args1); while (p=3Dva_arg(args1, char*)) retlen +=3D strlen(p); va_end(args1); ret =3D (char*) malloc(sizeof(char)*retlen); retend =3D ret; while (p=3Dva_arg(args2, char*)) { strcpy(retend,p); retend-=3D1; } va_end(args2); return ret; } static struct { char *svc; char *userfmt; char *usersfmt; char *updatefmt; int userlen; int userslen; int updatelen; } svc_stmt[] =3D { {"NONE",0}, {"pop3",0}, {"imap",0}, {"smtp",0}, }; extern struct authstaticinfo *courier_authsqlite_init( void) { char *tmp; #define VAR(x,def) (tmp=3Dread_env(#x)) ? tmp : def dbfilename =3D VAR(DBFILENAME,"/etc/courier/authsqlite.db"); emailfld =3D VAR(EMAIL,"email"); uidfld =3D VAR(UID,"uid"); gidfld =3D VAR(GID,"gid"); homefld =3D VAR(HOMEFLD,"home"); maildirfld =3D VAR(MAILDIR,"maildir"); passwdfld =3D VAR(PASSWD,"passwd"); clearpwfld =3D VAR(CLEARPW,"clearpw"); optionsfld =3D VAR(OPTIONS,"options"); fullnamefld =3D VAR(FULLNAME,"fullname"); quotafld =3D VAR(QUOTA,"quota"); table =3D VAR(TABLE,"users"); pop3table =3D VAR(POP3TABLE,table); imaptable =3D VAR(IMAPTABLE,table); smtptable =3D VAR(SMTPTABLE,table); #undef VAR userfmt =3D concat("select ",emailfld,", ",uidfld,", ",gidfld,", ",homef= ld, ", ",maildirfld,", ",passwdfld,", ",clearpwfld,", ",optionsfld,", ", fullnamefld,", ",quotafld," from ",table," where ",emailfld,"=3D%s", NU= LL); pop3userfmt =3D concat("select ",emailfld,", ",uidfld,", ",gidfld,", ",h= omefld, ", ",maildirfld,", ",passwdfld,", ",clearpwfld,", ",optionsfld,", ", fullnamefld,", ",quotafld," from ",pop3table," where ",emailfld,"=3D%s"= , NULL); imapuserfmt =3D concat("select ",emailfld,", ",uidfld,", ",gidfld,", ",h= omefld, ", ",maildirfld,", ",passwdfld,", ",clearpwfld,", ",optionsfld,", ", fullnamefld,", ",quotafld," from ",imaptable," where ",emailfld,"=3D%s"= , NULL); smtpuserfmt =3D concat("select ",emailfld,", ",uidfld,", ",gidfld,", ",h= omefld, ", ",maildirfld,", ",passwdfld,", ",clearpwfld,", ",optionsfld,", ", fullnamefld,", ",quotafld," from ",smtptable," where ",emailfld,"=3D%s"= , NULL); usersfmt =3D concat("select ",emailfld,", ",uidfld,", ",gidfld,", ",home= fld, ", ",maildirfld,", ",passwdfld,", ",clearpwfld,", ",optionsfld,", ", fullnamefld,", ",quotafld," from ",table, NULL); pop3usersfmt =3D concat("select ",emailfld,", ",uidfld,", ",gidfld,", ",= homefld, ", ",maildirfld,", ",passwdfld,", ",clearpwfld,", ",optionsfld,", ", fullnamefld,", ",quotafld," from ",pop3table, NULL); imapusersfmt =3D concat("select ",emailfld,", ",uidfld,", ",gidfld,", ",= homefld, ", ",maildirfld,", ",passwdfld,", ",clearpwfld,", ",optionsfld,", ", fullnamefld,", ",quotafld," from ",imaptable, NULL); smtpusersfmt =3D concat("select ",emailfld,", ",uidfld,", ",gidfld,", ",= homefld, ", ",maildirfld,", ",passwdfld,", ",clearpwfld,", ",optionsfld,", ", fullnamefld,", ",quotafld," from ",smtptable, NULL); updatefmt =3D concat("update ",table, " set ", passwdfld,"=3D%s", " where ",emailfld,"=3D%s", NULL); pop3updatefmt =3D concat("update ",pop3table, " set ", passwdfld,"=3D%s"= , " where ",emailfld,"=3D%s", NULL); imapupdatefmt =3D concat("update ",imaptable, " set ", passwdfld,"=3D%s"= , " where ",emailfld,"=3D%s", NULL); smtpupdatefmt =3D concat("update ",smtptable, " set ", passwdfld,"=3D%s"= , " where ",emailfld,"=3D%s", NULL); svc_stmt[0].userfmt =3D userfmt; svc_stmt[0].usersfmt =3D usersfmt; svc_stmt[0].updatefmt =3D updatefmt; svc_stmt[0].userlen =3D strlen(userfmt); svc_stmt[0].userslen =3D strlen(usersfmt); svc_stmt[0].updatelen =3D strlen(updatefmt); svc_stmt[1].userfmt =3D pop3userfmt; svc_stmt[1].usersfmt =3D pop3usersfmt; svc_stmt[1].updatefmt =3D pop3updatefmt; svc_stmt[1].userlen =3D strlen(pop3userfmt); svc_stmt[1].userslen =3D strlen(pop3usersfmt); svc_stmt[1].updatelen =3D strlen(pop3updatefmt); svc_stmt[2].userfmt =3D imapuserfmt; svc_stmt[2].usersfmt =3D imapusersfmt; svc_stmt[2].updatefmt =3D imapupdatefmt; svc_stmt[2].userlen =3D strlen(imapuserfmt); svc_stmt[2].userslen =3D strlen(imapusersfmt); svc_stmt[2].updatelen =3D strlen(imapupdatefmt); svc_stmt[3].userfmt =3D smtpuserfmt; svc_stmt[3].usersfmt =3D smtpusersfmt; svc_stmt[3].updatefmt =3D smtpupdatefmt; svc_stmt[3].userlen =3D strlen(smtpuserfmt); svc_stmt[3].userslen =3D strlen(smtpusersfmt); svc_stmt[3].updatelen =3D strlen(smtpupdatefmt); /* open db connection */ if (sqlite3_open(dbfilename, &db)) { sqlite3_close(db); return NULL; } return &authsqlite_info; } static int get_user( char *user, char *service, char ***res, int *r, int *c, char **e) { int i; char *sql; if (!strcmp(service, svc_stmt[1].svc)) i=3D1; else if (!strcmp(service,svc_stmt[2].svc)) i=3D2; else if (!strcmp(service,svc_stmt[3].svc)) i=3D3; else { *e =3D "invalid service"; return 1; } sql =3D (char*) malloc(svc_stmt[i].userlen+strlen(user)); if (sprintf(&sql,svc_stmt[i].userfmt,user)=3D=3D-1) { *e =3D "sprintf failed!"; return 5; } if (sqlite3_get_table(db, sql, &res, &r, &c, NULL)!=3DSQLITE_OK) { *e =3D "SQL statement failed"; sqlite3_free_table(&res); return 2; } if (*r=3D=3D0) { *e =3D "user not found"; sqlite3_free_table(&res); return 3; } if (*r>1) { *e =3D "ambiguous user name"; sqlite3_free_table(&res); return 4; } return 0; } static int get_users( char *service, char ***res, int *r, int *c, char **e) { int i; if (!strcmp(service, svc_stmt[1].svc)) i=3D1; else if (!strcmp(service,svc_stmt[2].svc)) i=3D2; else if (!strcmp(service,svc_stmt[3].svc)) i=3D3; else { *e =3D "invalid service"; return 1; } if (sqlite3_get_table(db, svc_stmt[i].usersfmt, &res, &r, &c, NULL) !=3DSQLITE_OK) { *e =3D "SQL statement failed"; sqlite3_free_table(&res); return 2; } return 0; } static int get_user_errhnd( char *svc, char **res, int errval, char *mesg) { if (errval=3D=3D1 || errval=3D=3D3) { err("error getting user: %s", mesg); errno=3DEINVAL; return -1; } else if (errval=3D=3D2 || errval=3D=3D4) { err("error getting user: %s", mesg); errno=3DEPERM; return 1; } } static int get_users_errhnd( char *svc, char **res, int errval, char *mesg) { err("error getting users: %s", mesg); return errval; } static int auth_sqlite_common( const char *user, const char *pass, const char *service, callback *cb, void *cbarg) { char **res; int r,c,ret; char *e; authinfo info =3D {0}; if (!(ret=3Dget_user(user,service,&res,&r,&c,&e))) { return get_user_errhnd(service,res,ret,e); } info.sysusername =3D NULL; info.address =3D res[1][0]; info.sysuserid =3D strtol(res[1][1], NULL, 0); info.sysgroupid =3D strtol(res[1][2], NULL, 0); info.homedir =3D res[1][3] ; info.maildir =3D res[1][4]; info.passwd =3D res[1][5]; info.clearpasswd =3D res[1][6]; info.options =3D res[1][7]; info.fullname =3D res[1][8]; info.quota =3D res[1][9]; return (*cb)(&info, cbarg); } static int auth_sqlite( const char *service, const char *authtype, char *authdata, callback *cb, void *cbarg) { if (strcmp(authtype, AUTHTYPE_LOGIN) =3D=3D 0) { const char *user, *pass; if ((user=3Dstrtok(authdata, "\n")) =3D=3D NULL || (pass=3Dstrtok(0, "\n")) =3D=3D NULL) { errno=3DEPERM; return (-1); } return auth_sqlite_common(user, pass, service, cb, cbarg); } #if HAVE_HMACLIB struct cram_callback_info cci; if (auth_get_cram(authtype, authdata, &cci)) return (-1); cci.callback_func =3D cb; cci.callback_arg =3D cbarg; return auth_sqlite_common(cci.user, NULL, service, cb, (void*)&cci); #else return -1; #endif } static int auth_sqlite_no_vrfy( const char *user, const char *service, callback *cb, void *cbarg) { return auth_sqlite_common(user, NULL, service, cb, cbarg); } static void auth_sqlite_exit( void) { sqlite3_close(db); } static int auth_sqlite_chgpwd( const char *service, const char *user, const char *oldpw, const char *newpw) { /* TODO */ char **res; int r,c,ret,i; char *e; if (!(ret=3Dget_user(user,service,&res,&r,&c,&e))) { return get_user_errhnd(service,res,ret,e); } if (res[1][5]) { // crypted pw if (authcheckpassword(oldpw,res[1][5])) { err("wrong password for user %s", user); errno=3DEPERM; return 1; } } else if (res[1][6]) { // clear pw if (strcmp(oldpw,res[1][6])) { err("wrong password for user %s", user); errno=3DEPERM; return 1; } } else { err("clear pw and crypted pw unset"); errno=3DEPERM; return 1; } char *newcryptpw =3D authcryptpasswd(newpw,res[1][5]); char *sql; if (!strcmp(service, svc_stmt[1].svc)) i=3D1; else if (!strcmp(service,svc_stmt[2].svc)) i=3D2; else if (!strcmp(service,svc_stmt[3].svc)) i=3D3; else { err("invalid service: %s",service); errno=3DEPERM; return 2; } sql =3D (char*) malloc(svc_stmt[i].updatelen+strlen(user)); if (sprintf(&sql,svc_stmt[i].updatefmt,user)=3D=3D-1) { err("sprintf failed!"); errno=3DEPERM; return 3; } if (sqlite3_exec(db,sql,NULL,NULL,&errmsg)!=3DSQLITE_ OK) { err("error updating passwd: %s", errmsg); sqlite3_free(errmsg); errno=3DEPERM; return 1; } sqlite3_free_table(res); /* passwd successfully changed */ return 0; } static void auth_sqlite_idle( void) { return; } static void auth_sqlite_enum( enumcallback *cb, void *cbarg) { /* TODO */ char **res,*e,*svc=3DNULL; int pop3used=3D0, imapused=3D0, smtpused=3D0, r,c,ret,i; if (!strcmp(usersfmt,pop3usersfmt)) pop3used=3D1; if (!strcmp(usersfmt,imapusersfmt)) imapused=3D1; if (!strcmp(usersfmt,smtpusersfmt)) smtpused=3D1; if (pop3used) { if (!(ret=3Dget_users("pop3",&res,&r,&c,&e))) { get_users_errhnd("pop3",res,ret,e); return; } for (i=3D1;i<=3Dr;i++) { (*cb)(res[i][0], strtol(res[i][1], NULL, 0), strtol(res[i][2], NULL, 0), res[i][3], res[i][4], cbarg); } sqlite3_free_table(res); } if (imapused) { if (!(ret=3Dget_users("imap",&res,&r,&c,&e))) { get_users_errhnd("imap",res,ret,e); return; } for (i=3D1;i<=3Dr;i++) { (*cb)(res[i][0], strtol(res[i][1], NULL, 0), strtol(res[i][2], NULL, 0), res[i][3], res[i][4], cbarg); } sqlite3_free_table(res); } if (smtpused) { if (!(ret=3Dget_users("smtp",&res,&r,&c,&e))) { get_users_errhnd("smtp",res,ret,e); return; } for (i=3D1;i<=3Dr;i++) { (*cb)(res[i][0], strtol(res[i][1], NULL, 0), strtol(res[i][2], NULL, 0), res[i][3], res[i][4], cbarg); } sqlite3_free_table(res); } if (!pop3used) svc=3D"pop3"; else if (!imapused) svc=3D"imap"; else if (!smtpused) svc=3D"smtp"; if (!svc) { if (!(ret=3Dget_users(svc,&res,&r,&c,&e))) { get_users_errhnd(svc,res,ret,e); return; } for (i=3D1;i<=3Dr;i++) { (*cb)(res[i][0], strtol(res[i][1], NULL, 0), strtol(res[i][2], NULL, 0), res[i][3], res[i][4], cbarg); } sqlite3_free_table(res); } sqlite3_free_table(res); (*cb)(NULL, 0, 0, NULL, NULL, cbarg); return; } --------------060002000708030204000906-- --------------enigA850BAB8FE598EA66D9461B0 Content-Type: application/pgp-signature; name="signature.asc" Content-Description: OpenPGP digital signature Content-Disposition: attachment; filename="signature.asc" -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.8 (Darwin) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iEYEARECAAYFAkgPaM0ACgkQrxVzXk9cDowieQCeKQRlfvkNhX guJ/G1gufiUVjS HSEAn31GIkWilDhWroH5oGO/dZuoXWCe =yj0T -----END PGP SIGNATURE----- --------------enigA850BAB8FE598EA66D9461B0-- --===============1473658569== Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline ------------------------------------------------------------------------- This SF.net email is sponsored by the 2008 JavaOne(SM) Conference Don't miss this year's exciting event. There's still time to save $100. Use priority code J8TL2D2. http://ad.doubleclick.net/clk;198757...un.com/javaone --===============1473658569== Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline _______________________________________________ courier-users mailing list courier-users@lists.sourceforge.net Unsubscribe: https://lists.sourceforge.net/lists/.../courier-users --===============1473658569==-- |