--- ../checkpassword-0.81-orig/Makefile Sat Nov 21 20:29:52 1998 +++ Makefile Thu Mar 23 14:28:39 2000 @@ -1,9 +1,54 @@ # Don't edit Makefile! Use conf-* for configuration. +MYSQL_LIBS=/usr/local/lib/mysql/libmysqlclient.a -lm +MYSQL_INCLUDE=-I/usr/local/include +LOGGING=-DO_NOT_LOG_SQL #-DO_NOT_LOG +PASSWORDS=-DO_USE_MYSQL_PASSWORDS SHELL=/bin/sh default: it +init_mysql.o: compile init_mysql.c auto_qmail.h + ./compile init_mysql.c $(MYSQL_INCLUDE) + +connect_mysql.o: compile connect_mysql.c + ./compile connect_mysql.c $(MYSQL_INCLUDE) + +getpw_mysql.o: compile getpw_mysql.c mysql_queries.h + ./compile getpw_mysql.c $(MYSQL_INCLUDE) $(LOGGING) $(PASSWORDS) + +do_query.o: compile do_query.c mysql_queries.h + ./compile do_query.c $(MYSQL_INCLUDE) $(LOGGING) + +mkmsg.o: compile mkmsg.c + ./compile mkmsg.c $(LOGGING) + +splog.o: compile splog.c + ./compile splog.c $(LOGGING) + +ptest.o: compile ptest.c + ./compile ptest.c + +ptest: load auto_qmail.o ptest.o init_mysql.o connect_mysql.o getpw_mysql.o \ +fmt_uint.o fmt_uint0.o fmt_ulong.o open_read.o \ +do_query.o mkmsg.o splog.o stralloc.a str.a getln.a substdio.a error.a alloc.a + ./load ptest auto_qmail.o init_mysql.o connect_mysql.o getpw_mysql.o \ + fmt_uint.o fmt_uint0.o fmt_ulong.o open_read.o \ + do_query.o mkmsg.o splog.o getln.a substdio.a stralloc.a str.a error.a \ + alloc.a $(MYSQL_LIBS) + +alloc.a: \ +makelib alloc.o alloc_re.o + ./makelib alloc.a alloc.o alloc_re.o + +alloc.o: \ +compile alloc.c alloc.h error.h + ./compile alloc.c + +alloc_re.o: \ +compile alloc_re.c alloc.h byte.h + ./compile alloc_re.c + auto-str: \ load auto-str.o substdio.a error.a str.a ./load auto-str substdio.a error.a str.a @@ -20,6 +65,18 @@ compile auto_home.c ./compile auto_home.c +auto_qmail.c: \ +auto-str conf-qmail + ./auto-str auto_qmail `head -1 conf-qmail` > auto_qmail.c + +auto_qmail.o: \ +compile auto_qmail.c + ./compile auto_qmail.c + +byte_chr.o: \ +compile byte_chr.c byte.h + ./compile byte_chr.c + byte_copy.o: \ compile byte_copy.c byte.h ./compile byte_copy.c @@ -28,14 +85,24 @@ compile byte_cr.c byte.h ./compile byte_cr.c +byte_diff.o: \ +compile byte_diff.c byte.h + ./compile byte_diff.c + check: \ it instcheck ./instcheck checkpassword: \ -load checkpassword.o prot.o shadow.lib crypt.lib s.lib - ./load checkpassword prot.o `cat shadow.lib` `cat \ - crypt.lib` `cat s.lib` +load checkpassword.o auto_qmail.o init_mysql.o connect_mysql.o getpw_mysql.o \ +do_query.o fmt_uint.o fmt_uint0.o fmt_ulong.o open_read.o mkmsg.o splog.o \ +prot.o shadow.lib crypt.lib s.lib stralloc.a str.a getln.a substdio.a error.a \ +alloc.a + ./load checkpassword auto_qmail.o init_mysql.o connect_mysql.o \ + getpw_mysql.o do_query.o fmt_uint.o fmt_uint0.o fmt_ulong.o \ + open_read.o mkmsg.o splog.o prot.o `cat shadow.lib` `cat \ + crypt.lib` `cat s.lib`getln.a substdio.a stralloc.a str.a error.a \ + alloc.a $(MYSQL_LIBS) checkpassword.0: \ checkpassword.8 @@ -79,6 +146,30 @@ compile error_str.c error.h ./compile error_str.c +fmt_uint.o: \ +compile fmt_uint.c fmt.h + ./compile fmt_uint.c + +fmt_uint0.o: \ +compile fmt_uint0.c fmt.h + ./compile fmt_uint0.c + +fmt_ulong.o: \ +compile fmt_ulong.c fmt.h + ./compile fmt_ulong.c + +getln.a: \ +makelib getln.o getln2.o + ./makelib getln.a getln.o getln2.o + +getln.o: \ +compile getln.c substdio.h byte.h stralloc.h gen_alloc.h getln.h + ./compile getln.c + +getln2.o: \ +compile getln2.c substdio.h stralloc.h gen_alloc.h byte.h getln.h + ./compile getln2.c + hasshsgr.h: \ chkshsgr warn-shsgr tryshsgr.c compile load ./chkshsgr || ( cat warn-shsgr; exit 1 ) @@ -173,7 +264,7 @@ ./compile open_trunc.c prog: \ -checkpassword +checkpassword ptest prot.o: \ compile prot.c hasshsgr.h prot.h @@ -198,12 +289,73 @@ rm -f tryshadow.o tryshadow str.a: \ -makelib str_len.o byte_copy.o byte_cr.o - ./makelib str.a str_len.o byte_copy.o byte_cr.o +makelib str_cpy.o str_diff.o str_len.o str_start.o byte_chr.o byte_diff.o \ +byte_copy.o byte_cr.o + ./makelib str.a str_cpy.o str_diff.o str_len.o str_start.o byte_chr.o \ + byte_diff.o byte_copy.o byte_cr.o + +str_cpy.o: \ +compile str_cpy.c str.h + ./compile str_cpy.c + +str_diff.o: \ +compile str_diff.c str.h + ./compile str_diff.c str_len.o: \ compile str_len.c str.h ./compile str_len.c + +str_start.o: \ +compile str_start.c str.h + ./compile str_start.c + +stralloc.a: \ +makelib stralloc_eady.o stralloc_pend.o stralloc_copy.o \ +stralloc_opys.o stralloc_opyb.o stralloc_cat.o stralloc_cats.o \ +stralloc_catb.o stralloc_arts.o + ./makelib stralloc.a stralloc_eady.o stralloc_pend.o \ + stralloc_copy.o stralloc_opys.o stralloc_opyb.o \ + stralloc_cat.o stralloc_cats.o stralloc_catb.o \ + stralloc_arts.o + +stralloc_arts.o: \ +compile stralloc_arts.c byte.h str.h stralloc.h gen_alloc.h + ./compile stralloc_arts.c + +stralloc_cat.o: \ +compile stralloc_cat.c byte.h stralloc.h gen_alloc.h + ./compile stralloc_cat.c + +stralloc_catb.o: \ +compile stralloc_catb.c stralloc.h gen_alloc.h byte.h + ./compile stralloc_catb.c + +stralloc_cats.o: \ +compile stralloc_cats.c byte.h str.h stralloc.h gen_alloc.h + ./compile stralloc_cats.c + +stralloc_copy.o: \ +compile stralloc_copy.c byte.h stralloc.h gen_alloc.h + ./compile stralloc_copy.c + +stralloc_eady.o: \ +compile stralloc_eady.c alloc.h stralloc.h gen_alloc.h \ +gen_allocdefs.h + ./compile stralloc_eady.c + +stralloc_opyb.o: \ +compile stralloc_opyb.c stralloc.h gen_alloc.h byte.h + ./compile stralloc_opyb.c + +stralloc_opys.o: \ +compile stralloc_opys.c byte.h str.h stralloc.h gen_alloc.h + ./compile stralloc_opys.c + +stralloc_pend.o: \ +compile stralloc_pend.c alloc.h stralloc.h gen_alloc.h \ +gen_allocdefs.h + ./compile stralloc_pend.c strerr.a: \ makelib strerr_sys.o strerr_die.o --- ../checkpassword-0.81-orig/alloc.c Thu Mar 23 14:12:38 2000 +++ alloc.c Thu Mar 23 13:37:49 2000 @@ -0,0 +1,32 @@ +#include "alloc.h" +#include "error.h" +extern char *malloc(); +extern void free(); + +#define ALIGNMENT 16 /* XXX: assuming that this alignment is enough */ +#define SPACE 4096 /* must be multiple of ALIGNMENT */ + +typedef union { char irrelevant[ALIGNMENT]; double d; } aligned; +static aligned realspace[SPACE / ALIGNMENT]; +#define space ((char *) realspace) +static unsigned int avail = SPACE; /* multiple of ALIGNMENT; 0<=avail<=SPACE */ + +/*@null@*//*@out@*/char *alloc(n) +unsigned int n; +{ + char *x; + n = ALIGNMENT + n - (n & (ALIGNMENT - 1)); /* XXX: could overflow */ + if (n <= avail) { avail -= n; return space + avail; } + x = malloc(n); + if (!x) errno = error_nomem; + return x; +} + +void alloc_free(x) +char *x; +{ + if (x >= space) + if (x < space + SPACE) + return; /* XXX: assuming that pointers are flat */ + free(x); +} --- ../checkpassword-0.81-orig/alloc.h Thu Mar 23 14:12:38 2000 +++ alloc.h Thu Mar 23 13:37:49 2000 @@ -0,0 +1,8 @@ +#ifndef ALLOC_H +#define ALLOC_H + +extern /*@null@*//*@out@*/char *alloc(); +extern void alloc_free(); +extern int alloc_re(); + +#endif --- ../checkpassword-0.81-orig/alloc_re.c Thu Mar 23 14:12:38 2000 +++ alloc_re.c Thu Mar 23 13:37:49 2000 @@ -0,0 +1,17 @@ +#include "alloc.h" +#include "byte.h" + +int alloc_re(x,m,n) +char **x; +unsigned int m; +unsigned int n; +{ + char *y; + + y = alloc(n); + if (!y) return 0; + byte_copy(y,m,*x); + alloc_free(*x); + *x = y; + return 1; +} --- ../checkpassword-0.81-orig/auto_qmail.h Thu Mar 23 14:12:38 2000 +++ auto_qmail.h Thu Mar 23 13:37:49 2000 @@ -0,0 +1,6 @@ +#ifndef AUTO_QMAIL_H +#define AUTO_QMAIL_H + +extern char auto_qmail[]; + +#endif --- ../checkpassword-0.81-orig/byte_chr.c Thu Mar 23 14:12:38 2000 +++ byte_chr.c Thu Mar 23 13:37:49 2000 @@ -0,0 +1,20 @@ +#include "byte.h" + +unsigned int byte_chr(s,n,c) +char *s; +register unsigned int n; +int c; +{ + register char ch; + register char *t; + + ch = c; + t = s; + for (;;) { + if (!n) break; if (*t == ch) break; ++t; --n; + if (!n) break; if (*t == ch) break; ++t; --n; + if (!n) break; if (*t == ch) break; ++t; --n; + if (!n) break; if (*t == ch) break; ++t; --n; + } + return t - s; +} --- ../checkpassword-0.81-orig/byte_diff.c Thu Mar 23 14:12:38 2000 +++ byte_diff.c Thu Mar 23 13:37:49 2000 @@ -0,0 +1,16 @@ +#include "byte.h" + +int byte_diff(s,n,t) +register char *s; +register unsigned int n; +register char *t; +{ + for (;;) { + if (!n) return 0; if (*s != *t) break; ++s; ++t; --n; + if (!n) return 0; if (*s != *t) break; ++s; ++t; --n; + if (!n) return 0; if (*s != *t) break; ++s; ++t; --n; + if (!n) return 0; if (*s != *t) break; ++s; ++t; --n; + } + return ((int)(unsigned int)(unsigned char) *s) + - ((int)(unsigned int)(unsigned char) *t); +} --- ../checkpassword-0.81-orig/checkpassword.c Sat Nov 21 20:29:52 1998 +++ checkpassword.c Thu Mar 23 13:37:49 2000 @@ -1,15 +1,14 @@ #include +#include "stralloc.h" extern int errno; extern char *crypt(); extern char *malloc(); +extern mkmsg(); extern char **environ; -int error_txtbsy = -#ifdef ETXTBSY -ETXTBSY; -#else --4; -#endif +stralloc message = { 0 }; + +extern int error_txtbsy; #include "prot.h" #include @@ -28,14 +27,18 @@ static struct userpw *upw; #endif -void doit(login) +int doit(login) char *login; { pw = getpwnam(login); if (pw) stored = pw->pw_passwd; else { - if (errno == error_txtbsy) _exit(111); + if (errno == error_txtbsy) { + mkmsg("couldn't get information for ", login); + _exit(111); + } + mkmsg("no such user ", login); _exit(1); } @@ -44,7 +47,11 @@ if (upw) stored = upw->upw_passwd; else - if (errno == error_txtbsy) _exit(111); + if (errno == error_txtbsy) { + _exit(111); + mkmsg("couldn't get information for ", login); + _exit(111); + } #endif #ifdef HASGETSPNAM @@ -52,7 +59,11 @@ if (spw) stored = spw->sp_pwdp; else - if (errno == error_txtbsy) _exit(111); + if (errno == error_txtbsy) { + _exit(111); + mkmsg("couldn't get information for ", login); + _exit(111); + } #endif } @@ -104,17 +115,37 @@ if (i == uplen) _exit(2); while (up[i++]) if (i == uplen) _exit(2); - doit(login); - - encrypted = crypt(password,stored); - - for (i = 0;i < sizeof(up);++i) up[i] = 0; - - if (!*stored || strcmp(encrypted,stored)) _exit(1); + pw = getpw_mysql(login, password); + if ((int) pw == -1) _exit(111); + if ((int) pw == 1) _exit(1); + if ((int) pw == 0) { + doit(login); + encrypted = crypt(password,stored); + + for (i = 0;i < sizeof(up);++i) up[i] = 0; + + if (!*stored) { + mkmsg("no such user ", pw->pw_name); + _exit(1); + } + if (str_diff(encrypted,stored)) { + mkmsg(pw->pw_name, " got system password wrong"); + _exit(1); + } + } - if (prot_gid((int) pw->pw_gid) == -1) _exit(1); - if (prot_uid((int) pw->pw_uid) == -1) _exit(1); - if (chdir(pw->pw_dir) == -1) _exit(111); + if (prot_gid((int) pw->pw_gid) == -1) { + mkmsg("evil gid for ", login); + _exit(1); + } + if (prot_uid((int) pw->pw_uid) == -1) { + mkmsg("evil uid for ", login); + _exit(1); + } + if (chdir(pw->pw_dir) == -1) { + mkmsg("can't cd ", pw->pw_dir); + _exit(111); + } numenv = 0; while (environ[numenv]) ++numenv; --- ../checkpassword-0.81-orig/conf-qmail Thu Mar 23 14:12:38 2000 +++ conf-qmail Thu Mar 23 14:28:33 2000 @@ -0,0 +1 @@ +/var/qmail --- ../checkpassword-0.81-orig/connect_mysql.c Thu Mar 23 14:12:38 2000 +++ connect_mysql.c Thu Mar 23 13:37:49 2000 @@ -0,0 +1,41 @@ +#include +#include "stralloc.h" + +#define TRIES 3 + +/* let's alloc our strallocs */ +extern stralloc DB_HOST; +extern stralloc DB_USER; +extern stralloc DB_PASS; +extern stralloc DB_NAME; +extern stralloc DB_SOCK; +extern stralloc DB_PORT; + +extern MYSQL dbh, *mysql; + +/* connect to the database */ +int connect_mysql() { + char *sock; + int i, port; + + if (mysql) return 1; + if (init_mysql() == -1) return -1; + if (DB_PORT.a > 0) port = atoi(DB_PORT.s); + else port = 0; + if (DB_SOCK.a > 0) sock = DB_SOCK.s; + else sock = (char) 0; + for (i = 0; i < TRIES; i++) { + mysql = mysql_real_connect(&dbh, DB_HOST.s, DB_USER.s, DB_PASS.s, DB_NAME.s, + port, sock, 0); + if (mysql) break; + splog("mysql-error", mysql_error(&dbh)); + sleep(3); + } + + if (i < TRIES) return 1; + else return 0; +} + +void disconnect_mysql() { + mysql_close(&dbh); +} --- ../checkpassword-0.81-orig/do_query.c Thu Mar 23 14:12:38 2000 +++ do_query.c Thu Mar 23 13:37:49 2000 @@ -0,0 +1,47 @@ +#include +#include "stralloc.h" + +extern MYSQL dbh, *mysql; +extern MYSQL_RES *result; + +extern splog(); + +/* run a given query and return 1 row only */ +MYSQL_ROW do_query(stralloc *query) { + int num; +#ifndef O_NOT_LOG_SQL + int i; + char *x; + stralloc showme = { 0 }; +#endif + + if (! connect_mysql()) return -1; +#ifndef O_NOT_LOG_SQL + if (! stralloc_ready(&showme, query->a)) goto carryon; + num = i = 0; + for (x = query->s; num < 2; x++) { + if (*x == '(' || *x == ')') num++; + if (! num) i++; + } + if (! stralloc_catb(&showme, query->s, i)) goto carryon; + if (! stralloc_cats(&showme, x)) goto carryon; + if (! stralloc_0(&showme)) goto carryon; + splog("qmail-mysql", showme.s); +carryon: +#endif + if (mysql_real_query(mysql, query->s, query->len) < 0) { + splog("mysql-error", mysql_error(&dbh)); + return -1; + } + if (! (result = mysql_store_result(mysql))) return -1; + + num = mysql_num_rows(result); + + if (num != 1) { + mysql_free_result(result); + return 0; + } + + return mysql_fetch_row(result); +} + --- ../checkpassword-0.81-orig/fmt.h Thu Mar 23 14:12:38 2000 +++ fmt.h Thu Mar 23 13:37:49 2000 @@ -0,0 +1,25 @@ +#ifndef FMT_H +#define FMT_H + +#define FMT_ULONG 40 /* enough space to hold 2^128 - 1 in decimal, plus \0 */ +#define FMT_LEN ((char *) 0) /* convenient abbreviation */ + +extern unsigned int fmt_uint(); +extern unsigned int fmt_uint0(); +extern unsigned int fmt_xint(); +extern unsigned int fmt_nbbint(); +extern unsigned int fmt_ushort(); +extern unsigned int fmt_xshort(); +extern unsigned int fmt_nbbshort(); +extern unsigned int fmt_ulong(); +extern unsigned int fmt_xlong(); +extern unsigned int fmt_nbblong(); + +extern unsigned int fmt_plusminus(); +extern unsigned int fmt_minus(); +extern unsigned int fmt_0x(); + +extern unsigned int fmt_str(); +extern unsigned int fmt_strn(); + +#endif --- ../checkpassword-0.81-orig/fmt_uint.c Thu Mar 23 14:12:38 2000 +++ fmt_uint.c Thu Mar 23 13:37:49 2000 @@ -0,0 +1,6 @@ +#include "fmt.h" + +unsigned int fmt_uint(s,u) register char *s; register unsigned int u; +{ + register unsigned long l; l = u; return fmt_ulong(s,l); +} --- ../checkpassword-0.81-orig/fmt_uint0.c Thu Mar 23 14:12:38 2000 +++ fmt_uint0.c Thu Mar 23 13:37:49 2000 @@ -0,0 +1,10 @@ +#include "fmt.h" + +unsigned int fmt_uint0(s,u,n) char *s; unsigned int u; unsigned int n; +{ + unsigned int len; + len = fmt_uint(FMT_LEN,u); + while (len < n) { if (s) *s++ = '0'; ++len; } + if (s) fmt_uint(s,u); + return len; +} --- ../checkpassword-0.81-orig/fmt_ulong.c Thu Mar 23 14:12:38 2000 +++ fmt_ulong.c Thu Mar 23 13:37:49 2000 @@ -0,0 +1,13 @@ +#include "fmt.h" + +unsigned int fmt_ulong(s,u) register char *s; register unsigned long u; +{ + register unsigned int len; register unsigned long q; + len = 1; q = u; + while (q > 9) { ++len; q /= 10; } + if (s) { + s += len; + do { *--s = '0' + (u % 10); u /= 10; } while(u); /* handles u == 0 */ + } + return len; +} --- ../checkpassword-0.81-orig/gen_alloc.h Thu Mar 23 14:12:38 2000 +++ gen_alloc.h Thu Mar 23 13:37:49 2000 @@ -0,0 +1,7 @@ +#ifndef GEN_ALLOC_H +#define GEN_ALLOC_H + +#define GEN_ALLOC_typedef(ta,type,field,len,a) \ + typedef struct ta { type *field; unsigned int len; unsigned int a; } ta; + +#endif --- ../checkpassword-0.81-orig/gen_allocdefs.h Thu Mar 23 14:12:38 2000 +++ gen_allocdefs.h Thu Mar 23 13:37:49 2000 @@ -0,0 +1,34 @@ +#ifndef GEN_ALLOC_DEFS_H +#define GEN_ALLOC_DEFS_H + +#define GEN_ALLOC_ready(ta,type,field,len,a,i,n,x,base,ta_ready) \ +int ta_ready(x,n) register ta *x; register unsigned int n; \ +{ register unsigned int i; \ + if (x->field) { \ + i = x->a; \ + if (n > i) { \ + x->a = base + n + (n >> 3); \ + if (alloc_re(&x->field,i * sizeof(type),x->a * sizeof(type))) return 1; \ + x->a = i; return 0; } \ + return 1; } \ + x->len = 0; \ + return !!(x->field = (type *) alloc((x->a = n) * sizeof(type))); } + +#define GEN_ALLOC_readyplus(ta,type,field,len,a,i,n,x,base,ta_rplus) \ +int ta_rplus(x,n) register ta *x; register unsigned int n; \ +{ register unsigned int i; \ + if (x->field) { \ + i = x->a; n += x->len; \ + if (n > i) { \ + x->a = base + n + (n >> 3); \ + if (alloc_re(&x->field,i * sizeof(type),x->a * sizeof(type))) return 1; \ + x->a = i; return 0; } \ + return 1; } \ + x->len = 0; \ + return !!(x->field = (type *) alloc((x->a = n) * sizeof(type))); } + +#define GEN_ALLOC_append(ta,type,field,len,a,i,n,x,base,ta_rplus,ta_append) \ +int ta_append(x,i) register ta *x; register type *i; \ +{ if (!ta_rplus(x,1)) return 0; x->field[x->len++] = *i; return 1; } + +#endif --- ../checkpassword-0.81-orig/getln.c Thu Mar 23 14:12:38 2000 +++ getln.c Thu Mar 23 13:37:49 2000 @@ -0,0 +1,20 @@ +#include "substdio.h" +#include "byte.h" +#include "stralloc.h" +#include "getln.h" + +int getln(ss,sa,match,sep) +register substdio *ss; +register stralloc *sa; +int *match; +int sep; +{ + char *cont; + unsigned int clen; + + if (getln2(ss,sa,&cont,&clen,sep) == -1) return -1; + if (!clen) { *match = 0; return 0; } + if (!stralloc_catb(sa,cont,clen)) return -1; + *match = 1; + return 0; +} --- ../checkpassword-0.81-orig/getln.h Thu Mar 23 14:12:38 2000 +++ getln.h Thu Mar 23 13:37:49 2000 @@ -0,0 +1,7 @@ +#ifndef GETLN_H +#define GETLN_H + +extern int getln(); +extern int getln2(); + +#endif --- ../checkpassword-0.81-orig/getln2.c Thu Mar 23 14:12:38 2000 +++ getln2.c Thu Mar 23 13:37:49 2000 @@ -0,0 +1,31 @@ +#include "substdio.h" +#include "stralloc.h" +#include "byte.h" +#include "getln.h" + +int getln2(ss,sa,cont,clen,sep) +register substdio *ss; +register stralloc *sa; +/*@out@*/char **cont; +/*@out@*/unsigned int *clen; +int sep; +{ + register char *x; + register unsigned int i; + int n; + + if (!stralloc_ready(sa,0)) return -1; + sa->len = 0; + + for (;;) { + n = substdio_feed(ss); + if (n < 0) return -1; + if (n == 0) { *clen = 0; return 0; } + x = substdio_PEEK(ss); + i = byte_chr(x,n,sep); + if (i < n) { substdio_SEEK(ss,*clen = i + 1); *cont = x; return 0; } + if (!stralloc_readyplus(sa,n)) return -1; + i = sa->len; + sa->len = i + substdio_get(ss,sa->s + i,n); + } +} --- ../checkpassword-0.81-orig/getpw_mysql.c Thu Mar 23 14:12:38 2000 +++ getpw_mysql.c Thu Mar 23 14:21:39 2000 @@ -0,0 +1,76 @@ +#include +#include +#include "mysql_queries.h" +#include "str.h" +#include "stralloc.h" + +stralloc user = { 0 }; +stralloc home = { 0 }; +stralloc shell = { 0 }; + +extern MYSQL dbh, *mysql; +extern MYSQL_RES *result; + +extern void splog(); +extern void mkmsg(); +extern MYSQL_ROW do_query(stralloc *query); + +struct passwd mypw; + +/* get a pw entry from the database */ +/* returns: struct passwd if the user logged in, 1 if the user got password */ +/* wrong or 2 if the user didn't exist (-1 on error) */ +struct passwd *getpw_mysql(char *username, char *pass) { + int i, len, uid, gid; + MYSQL_ROW row; + stralloc passwd = { 0 }; + stralloc query = { 0 }; + + i = str_len(username); + len = str_len(pass); + + if (! stralloc_ready(&user, 2 * i + 1)) return -1; + if (! stralloc_ready(&passwd, 2 * len + 1)) return -1; + len = str_len(POPSEL) + + mysql_escape_string(user.s, username, i) + + mysql_escape_string(passwd.s, pass, len) + 2; + if (! stralloc_ready(&query, len)) return -1; + if (! stralloc_cats(&query, POPSEL1)) return -1; + if (! stralloc_cats(&query, POPSEL2)) return -1; + if (! stralloc_cats(&query, passwd.s)) return -1; + if (! stralloc_cats(&query, POPSEL3)) return -1; + if (! stralloc_cats(&query, user.s)) return -1; + if (! stralloc_append(&query, "'")) return -1; + if (! stralloc_0(&query)) return -1; + + row = do_query(&query); + if ((int) row == -1) return -1; + if ((int) row == 0) { + mkmsg(username, " does not exist in database"); + return 0; + } + + if (str_diff(row[0], row[5])) { + mkmsg(username, " got password wrong"); + return 1; + } + + /* OK so we're assuming the database really does return ints */ + uid = atoi(row[1]); + gid = atoi(row[2]); + + if (! stralloc_ready(&home, str_len(row[3]))) return -1; + if (! stralloc_copys(&home, row[3])) return -1; + if (! stralloc_0(&home)) return -1; + if (! stralloc_ready(&shell, str_len(row[4]))) return -1; + if (! stralloc_copys(&shell, row[4])) return -1; + if (! stralloc_0(&shell)) return -1; + + mypw.pw_name = user.s; + mypw.pw_uid = uid; + mypw.pw_gid = gid; + mypw.pw_dir = home.s; + mypw.pw_shell = shell.s; + mkmsg("login by ", username); + return &mypw; +} --- ../checkpassword-0.81-orig/init_mysql.c Thu Mar 23 14:12:38 2000 +++ init_mysql.c Thu Mar 23 13:37:49 2000 @@ -0,0 +1,113 @@ +#include +#include +#include "auto_qmail.h" +#include "readwrite.h" +#include "str.h" +#include "stralloc.h" +#include "substdio.h" +#include "subfd.h" + +#define SQLSERVER "/control/sqlserver" + +/* let's alloc our strallocs */ +stralloc DB_HOST = { 0 }; +stralloc DB_USER = { 0 }; +stralloc DB_PASS = { 0 }; +stralloc DB_NAME = { 0 }; +stralloc DB_SOCK = { 0 }; +stralloc DB_PORT = { 0 }; + +static char inbuf[64]; +MYSQL dbh, *mysql; +MYSQL_RES *result; + +/* read the config file and decide which server the database is on, what */ +/* username and password we need to connect to it and which database to use */ +/* return -1 if a bad error occurred, 0 if everything was OK or 1 if not */ +int init_mysql() { + int i, error, file, match; + substdio ss; + stralloc filename = { 0 }; + stralloc buf = { 0 }; + + mysql = mysql_init(&dbh); + if (! mysql) return -1; + + /* get the filename of the sqlserver control file */ + i = str_len(SQLSERVER) + str_len(auto_qmail) + 1; + if (! stralloc_ready(&filename, i)) return -1; + if (! stralloc_cats(&filename, auto_qmail)) return -1; + if (! stralloc_cats(&filename, SQLSERVER)) return -1; + if (! stralloc_0(&filename)) return -1; + + /* try to open the file - much code robbed from control.c*/ + file = open_read(filename.s); + if (file == -1) { + substdio_puts(subfderr, "warning: could not open sqlserver file "); + substdio_puts(subfderr, filename.s); + substdio_putsflush(subfderr, "\n"); + return 0; + } + substdio_fdbuf(&ss, read, file, inbuf, sizeof(inbuf)); + + i = 0; + while (getln(&ss, &buf, &match, '\n') != -1) { + if (! match && ! buf.len) break; + buf.len--; + if (! stralloc_0(&buf)) break; + /* we consider only lines starting with the letters s,l,p or d */ + switch (buf.s[0]) { + case 's': + if (buf.s[1] == 'e') error = getconfig(&buf, "server", &DB_HOST); + else error = getconfig(&buf, "socket", &DB_SOCK); + break; + case 'l': error = getconfig(&buf, "login", &DB_USER); break; + case 'p': + if (buf.s[1] == 'a') error = getconfig(&buf, "password", &DB_PASS); + else error = getconfig(&buf, "port", &DB_PORT); + break; + case 'd': error = getconfig(&buf, "db", &DB_NAME); break; + default: continue; + } + if (error == -1) { + i = -1; + continue; + } + else i += error; + if (! match) break; + } + close(file); + + if (i == -1) + substdio_putsflush(subfderr, "warning: there were errors reading sqlserver file\n"); + else if (i > 0) { + substdio_putsflush(subfderr, "warning: bogus lines in sqlserver file\n"); + i = 0; + } + return i; +} + +/* read lines in the config file and grok entries of the form "x=y" or "x y" */ +/* got is the line in the file, expected is the parmeter we're checking for */ +/* and store is a stralloc to put the result into if it was found */ +int getconfig(stralloc *got, char *expected, stralloc *store) { + char *value, *x; + + x = got->s + str_len(expected); + value = x + 1; + /* we got a meaningful value */ + if (! stralloc_starts(&got, expected) && (*x == ' ' || *x == '=') && str_len(value) > 0) { + if (! stralloc_ready(store, str_len(value))) return -1; + if (! stralloc_cats(store, value)) return -1; + if (! stralloc_0(store)) return -1; + return 0; + } + /* oh dear, the line we got didn't contain what we expected it to */ + substdio_puts(subfderr, "error reading sqlserver file: expected '"); + substdio_puts(subfderr, expected); + substdio_puts(subfderr, "' but got '"); + substdio_puts(subfderr, got); + substdio_putsflush(subfderr, "'\n"); + /* of course, we might have been expecting the wrong thing... */ + return 1; +} --- ../checkpassword-0.81-orig/mkmsg.c Thu Mar 23 14:12:38 2000 +++ mkmsg.c Thu Mar 23 13:37:49 2000 @@ -0,0 +1,13 @@ +#include "stralloc.h" +extern stralloc message; + +void mkmsg(char *part1, char *part2) { +#ifndef O_NOT_LOG + if (! stralloc_ready(&message, str_len(part1) + str_len(part2) + 1)) return; + message.len = 0; + if (! stralloc_cats(&message, part1)) return; + if (! stralloc_cats(&message, part2)) return; + if (! stralloc_0(&message)) return; + splog("checkpassword", message.s); +#endif +} --- ../checkpassword-0.81-orig/mysql_queries.h Fri Feb 11 15:32:46 2000 +++ mysql_queries.h Fri Feb 11 14:34:22 2000 @@ -0,0 +1,18 @@ +/* choose whether to use MySQL passwords here */ +/* you must define O_USE_MYSQL_PASSWORDS or */ +/* O_USE_PLAINTEXT_PASSWORDS */ + +/* this select is for POP3 */ +#define POPSEL1 "select password, uid, gid, home, '/bin/false', " +#define POPSEL3 "') from mailbox where username='" +#ifdef O_USE_MYSQL_PASSWORDS +#define POPSEL2 "password('" +#else +#ifdef O_USE_PLAINTEXT_PASSWORDS +#define POPSEL2 "('" +#else +#define POPSEL2 "encrypt('" +#define POPSEL3 "', password) from mailbox where username='" +#endif +#endif +#define POPSEL POPSEL1 POPSEL2 POPSEL3 --- ../checkpassword-0.81-orig/ptest.c Thu Mar 23 14:12:38 2000 +++ ptest.c Thu Mar 23 13:37:49 2000 @@ -0,0 +1,24 @@ +#include +#include "stralloc.h" + +extern getpw_mysql(); +stralloc message = { 0 }; + +int main(int argc, char **argv) { + struct passwd *pw; + + if (argc < 3) { + puts("usage: ptest username password"); + return die(); + } + pw = getpw_mysql(argv[1], argv[2]); + if ((int) pw < 3) return die(); + printf("%s:*:%d:%d:%s:%s\n", pw->pw_name, pw->pw_uid, pw->pw_gid, + pw->pw_dir, pw->pw_shell); + return 0; +} + +int die() { + if (message.len) puts(message.s); + return 111; +} --- ../checkpassword-0.81-orig/scan.h Thu Mar 23 14:12:38 2000 +++ scan.h Thu Mar 23 13:37:49 2000 @@ -0,0 +1,27 @@ +#ifndef SCAN_H +#define SCAN_H + +extern unsigned int scan_uint(); +extern unsigned int scan_xint(); +extern unsigned int scan_nbbint(); +extern unsigned int scan_ushort(); +extern unsigned int scan_xshort(); +extern unsigned int scan_nbbshort(); +extern unsigned int scan_ulong(); +extern unsigned int scan_xlong(); +extern unsigned int scan_nbblong(); + +extern unsigned int scan_plusminus(); +extern unsigned int scan_0x(); + +extern unsigned int scan_whitenskip(); +extern unsigned int scan_nonwhitenskip(); +extern unsigned int scan_charsetnskip(); +extern unsigned int scan_noncharsetnskip(); + +extern unsigned int scan_strncmp(); +extern unsigned int scan_memcmp(); + +extern unsigned int scan_long(); + +#endif --- ../checkpassword-0.81-orig/splog.c Thu Mar 23 14:12:38 2000 +++ splog.c Thu Mar 23 13:37:49 2000 @@ -0,0 +1,75 @@ +#ifndef O_NOT_LOG +#include +#include +#include +#include "error.h" +#include "substdio.h" +#include "subfd.h" +#include "exit.h" +#include "str.h" +#include "scan.h" +#include "fmt.h" + +char fixedbuf[800]; /* syslog truncates long lines (or crashes); GPACIC */ +int bufpos = 0; /* 0 <= bufpos < sizeof(buf) */ +int flagcont = 0; +int priority; /* defined if flagcont */ +char stamp[FMT_ULONG + FMT_ULONG + 3]; /* defined if flagcont */ + +void stamp_make() +{ + struct timeval tv; + char *s; + gettimeofday(&tv,(struct timezone *) 0); + s = stamp; + s += fmt_ulong(s,(unsigned long) tv.tv_sec); + *s++ = '.'; + s += fmt_uint0(s,(unsigned int) tv.tv_usec,6); + *s = 0; +} + +void splogflush() +{ + if (bufpos) { + fixedbuf[bufpos] = 0; + if (flagcont) + syslog(priority,"%s+%s",stamp,fixedbuf); /* logger folds invisibly; GPACIC */ + else { + stamp_make(); + priority = LOG_INFO; + if (str_start(fixedbuf,"warning:")) priority = LOG_WARNING; + if (str_start(fixedbuf,"alert:")) priority = LOG_ALERT; + syslog(priority,"%s %s",stamp,fixedbuf); + flagcont = 1; + } + } + bufpos = 0; +} + +void splog(char *splogger, char *message) +{ + int i; + int max = sizeof(fixedbuf) - 1; + + openlog(splogger, 0, LOG_MAIL); + for (i = 0; *message != '\0' && i < max - 1; i++) { + if (*message == '\n') { splogflush(); flagcont = 0; continue; } + if (bufpos == max) splogflush(); + if ((*message < 32) || (*message > 126)) + *message = '?'; /* logger truncates at 0; GPACIC */ + fixedbuf[bufpos++] = *message++; + } + if (bufpos < max) { + i++; + fixedbuf[bufpos++] = '\n'; + splogflush(); + } + closelog(); + return; +/*if (i == max && *message != '\0') return 1;*/ +/*return 0;*/ +} +#else +void splog(char *splogger, char *message) { +} +#endif --- ../checkpassword-0.81-orig/str_cpy.c Thu Mar 23 14:12:38 2000 +++ str_cpy.c Thu Mar 23 13:37:49 2000 @@ -0,0 +1,16 @@ +#include "str.h" + +unsigned int str_copy(s,t) +register char *s; +register char *t; +{ + register int len; + + len = 0; + for (;;) { + if (!(*s = *t)) return len; ++s; ++t; ++len; + if (!(*s = *t)) return len; ++s; ++t; ++len; + if (!(*s = *t)) return len; ++s; ++t; ++len; + if (!(*s = *t)) return len; ++s; ++t; ++len; + } +} --- ../checkpassword-0.81-orig/str_diff.c Thu Mar 23 14:12:38 2000 +++ str_diff.c Thu Mar 23 13:37:49 2000 @@ -0,0 +1,17 @@ +#include "str.h" + +int str_diff(s,t) +register char *s; +register char *t; +{ + register char x; + + for (;;) { + x = *s; if (x != *t) break; if (!x) break; ++s; ++t; + x = *s; if (x != *t) break; if (!x) break; ++s; ++t; + x = *s; if (x != *t) break; if (!x) break; ++s; ++t; + x = *s; if (x != *t) break; if (!x) break; ++s; ++t; + } + return ((int)(unsigned int)(unsigned char) x) + - ((int)(unsigned int)(unsigned char) *t); +} --- ../checkpassword-0.81-orig/str_start.c Thu Mar 23 14:12:38 2000 +++ str_start.c Thu Mar 23 13:37:49 2000 @@ -0,0 +1,15 @@ +#include "str.h" + +int str_start(s,t) +register char *s; +register char *t; +{ + register char x; + + for (;;) { + x = *t++; if (!x) return 1; if (x != *s++) return 0; + x = *t++; if (!x) return 1; if (x != *s++) return 0; + x = *t++; if (!x) return 1; if (x != *s++) return 0; + x = *t++; if (!x) return 1; if (x != *s++) return 0; + } +} --- ../checkpassword-0.81-orig/stralloc.h Thu Mar 23 14:12:38 2000 +++ stralloc.h Thu Mar 23 13:37:49 2000 @@ -0,0 +1,21 @@ +#ifndef STRALLOC_H +#define STRALLOC_H + +#include "gen_alloc.h" + +GEN_ALLOC_typedef(stralloc,char,s,len,a) + +extern int stralloc_ready(); +extern int stralloc_readyplus(); +extern int stralloc_copy(); +extern int stralloc_cat(); +extern int stralloc_copys(); +extern int stralloc_cats(); +extern int stralloc_copyb(); +extern int stralloc_catb(); +extern int stralloc_append(); /* beware: this takes a pointer to 1 char */ +extern int stralloc_starts(); + +#define stralloc_0(sa) stralloc_append(sa,"") + +#endif --- ../checkpassword-0.81-orig/stralloc_arts.c Thu Mar 23 14:12:38 2000 +++ stralloc_arts.c Thu Mar 23 13:37:49 2000 @@ -0,0 +1,12 @@ +#include "byte.h" +#include "str.h" +#include "stralloc.h" + +int stralloc_starts(sa,s) +stralloc *sa; +char *s; +{ + int len; + len = str_len(s); + return (sa->len >= len) && byte_equal(s,len,sa->s); +} --- ../checkpassword-0.81-orig/stralloc_cat.c Thu Mar 23 14:12:38 2000 +++ stralloc_cat.c Thu Mar 23 13:37:49 2000 @@ -0,0 +1,9 @@ +#include "byte.h" +#include "stralloc.h" + +int stralloc_cat(sato,safrom) +stralloc *sato; +stralloc *safrom; +{ + return stralloc_catb(sato,safrom->s,safrom->len); +} --- ../checkpassword-0.81-orig/stralloc_catb.c Thu Mar 23 14:12:38 2000 +++ stralloc_catb.c Thu Mar 23 13:37:49 2000 @@ -0,0 +1,15 @@ +#include "stralloc.h" +#include "byte.h" + +int stralloc_catb(sa,s,n) +stralloc *sa; +char *s; +unsigned int n; +{ + if (!sa->s) return stralloc_copyb(sa,s,n); + if (!stralloc_readyplus(sa,n + 1)) return 0; + byte_copy(sa->s + sa->len,n,s); + sa->len += n; + sa->s[sa->len] = 'Z'; /* ``offensive programming'' */ + return 1; +} --- ../checkpassword-0.81-orig/stralloc_cats.c Thu Mar 23 14:12:38 2000 +++ stralloc_cats.c Thu Mar 23 13:37:49 2000 @@ -0,0 +1,10 @@ +#include "byte.h" +#include "str.h" +#include "stralloc.h" + +int stralloc_cats(sa,s) +stralloc *sa; +char *s; +{ + return stralloc_catb(sa,s,str_len(s)); +} --- ../checkpassword-0.81-orig/stralloc_copy.c Thu Mar 23 14:12:38 2000 +++ stralloc_copy.c Thu Mar 23 13:37:49 2000 @@ -0,0 +1,9 @@ +#include "byte.h" +#include "stralloc.h" + +int stralloc_copy(sato,safrom) +stralloc *sato; +stralloc *safrom; +{ + return stralloc_copyb(sato,safrom->s,safrom->len); +} --- ../checkpassword-0.81-orig/stralloc_eady.c Thu Mar 23 14:12:38 2000 +++ stralloc_eady.c Thu Mar 23 13:37:49 2000 @@ -0,0 +1,6 @@ +#include "alloc.h" +#include "stralloc.h" +#include "gen_allocdefs.h" + +GEN_ALLOC_ready(stralloc,char,s,len,a,i,n,x,30,stralloc_ready) +GEN_ALLOC_readyplus(stralloc,char,s,len,a,i,n,x,30,stralloc_readyplus) --- ../checkpassword-0.81-orig/stralloc_opyb.c Thu Mar 23 14:12:38 2000 +++ stralloc_opyb.c Thu Mar 23 13:37:49 2000 @@ -0,0 +1,14 @@ +#include "stralloc.h" +#include "byte.h" + +int stralloc_copyb(sa,s,n) +stralloc *sa; +char *s; +unsigned int n; +{ + if (!stralloc_ready(sa,n + 1)) return 0; + byte_copy(sa->s,n,s); + sa->len = n; + sa->s[n] = 'Z'; /* ``offensive programming'' */ + return 1; +} --- ../checkpassword-0.81-orig/stralloc_opys.c Thu Mar 23 14:12:38 2000 +++ stralloc_opys.c Thu Mar 23 13:37:49 2000 @@ -0,0 +1,10 @@ +#include "byte.h" +#include "str.h" +#include "stralloc.h" + +int stralloc_copys(sa,s) +stralloc *sa; +char *s; +{ + return stralloc_copyb(sa,s,str_len(s)); +} --- ../checkpassword-0.81-orig/stralloc_pend.c Thu Mar 23 14:12:38 2000 +++ stralloc_pend.c Thu Mar 23 13:37:49 2000 @@ -0,0 +1,5 @@ +#include "alloc.h" +#include "stralloc.h" +#include "gen_allocdefs.h" + +GEN_ALLOC_append(stralloc,char,s,len,a,i,n,x,30,stralloc_readyplus,stralloc_append)