diff --git Makefile Makefile index 0f0e31a..01b0d4e 100644 --- Makefile +++ Makefile @@ -4,6 +4,14 @@ SHELL=/bin/sh default: it +auto_destdir.c: \ +auto-str conf-destdir + ./auto-str auto_qmail `head -1 conf-destdir` > auto_destdir.c + +auto_destdir.o: \ +compile auto_destdir.c + ./compile auto_destdir.c + addresses.0: \ addresses.5 nroff -man addresses.5 > addresses.0 @@ -110,7 +118,7 @@ auto_split.o: \ compile auto_split.c ./compile auto_split.c -auto_uids.c: \ +auto_uids_orig.c: \ auto-uid auto-gid conf-users conf-groups ( ./auto-uid auto_uida `head -1 conf-users` \ &&./auto-uid auto_uidd `head -2 conf-users | tail -1` \ @@ -122,10 +130,10 @@ auto-uid auto-gid conf-users conf-groups &&./auto-uid auto_uids `head -8 conf-users | tail -1` \ &&./auto-gid auto_gidq `head -1 conf-groups` \ &&./auto-gid auto_gidn `head -2 conf-groups | tail -1` \ - ) > auto_uids.c.tmp && mv auto_uids.c.tmp auto_uids.c + ) > auto_uids_orig.c.tmp && mv auto_uids_orig.c.tmp auto_uids_orig.c auto_uids.o: \ -compile auto_uids.c +compile auto_uids.c auto_usergroupnames.h ./compile auto_uids.c auto_usera.c: \ @@ -136,6 +144,20 @@ auto_usera.o: \ compile auto_usera.c ./compile auto_usera.c +auto_usergroupnames.h: \ +auto-str conf-users conf-groups + ( ./auto-str auto_usera `head -1 conf-users` \ + &&./auto-str auto_userd `head -2 conf-users | tail -1` \ + &&./auto-str auto_userl `head -3 conf-users | tail -1` \ + &&./auto-str auto_usero `head -4 conf-users | tail -1` \ + &&./auto-str auto_userp `head -5 conf-users | tail -1` \ + &&./auto-str auto_userq `head -6 conf-users | tail -1` \ + &&./auto-str auto_userr `head -7 conf-users | tail -1` \ + &&./auto-str auto_users `head -8 conf-users | tail -1` \ + &&./auto-str auto_groupq `head -1 conf-groups` \ + &&./auto-str auto_groupn `head -2 conf-groups | tail -1` \ + ) > auto_usergroupnames.h.tmp && mv auto_usergroupnames.h.tmp auto_usergroupnames.h + binm1: \ binm1.sh conf-qmail cat binm1.sh \ @@ -701,8 +723,18 @@ hfield.o: \ compile hfield.c hfield.h ./compile hfield.c +hier_destdir.c: \ +hier.c + cat hier.c \ + | sed s}fake_uids\.h}auto_uids.h}g \ + > hier_destdir.c + +hier_destdir.o: \ +compile hier_destdir.c auto_qmail.h auto_split.h auto_uids.h fmt.h fifo.h + ./compile hier_destdir.c + hier.o: \ -compile hier.c auto_qmail.h auto_split.h auto_uids.h fmt.h fifo.h +compile hier.c auto_qmail.h auto_split.h fake_uids.h fmt.h fifo.h ./compile hier.c home: \ @@ -740,15 +772,15 @@ seek.h fork.h ./compile idedit.c install: \ -load install.o fifo.o hier.o auto_qmail.o auto_split.o auto_uids.o \ +load install.o fifo.o hier.o auto_destdir.o auto_split.o auto_uids.o \ strerr.a substdio.a open.a error.a str.a fs.a - ./load install fifo.o hier.o auto_qmail.o auto_split.o \ + ./load install fifo.o hier.o auto_destdir.o auto_split.o \ auto_uids.o strerr.a substdio.a open.a error.a str.a fs.a install-big: \ -load install-big.o fifo.o install.o auto_qmail.o auto_split.o \ +load install-big.o fifo.o install.o auto_destdir.o auto_split.o \ auto_uids.o strerr.a substdio.a open.a error.a str.a fs.a - ./load install-big fifo.o install.o auto_qmail.o \ + ./load install-big fifo.o install.o auto_destdir.o \ auto_split.o auto_uids.o strerr.a substdio.a open.a error.a \ str.a fs.a @@ -757,15 +789,26 @@ compile install-big.c auto_qmail.h auto_split.h auto_uids.h fmt.h \ fifo.h ./compile install-big.c +install-destdir: \ +load install-destdir.o fifo.o hier_destdir.o auto_qmail.o auto_split.o auto_uids.o \ +strerr.a substdio.a open.a error.a str.a fs.a env.a + ./load install-destdir fifo.o hier_destdir.o auto_qmail.o auto_split.o \ + auto_uids.o strerr.a substdio.a open.a error.a str.a fs.a env.a + +install-destdir.o: \ +compile install-destdir.c substdio.h strerr.h error.h open.h readwrite.h \ +exit.h str.h env.h + ./compile install-destdir.c + install.o: \ compile install.c substdio.h strerr.h error.h open.h readwrite.h \ exit.h ./compile install.c instcheck: \ -load instcheck.o fifo.o hier.o auto_qmail.o auto_split.o auto_uids.o \ +load instcheck.o fifo.o hier_destdir.o auto_qmail.o auto_split.o auto_uids.o \ strerr.a substdio.a error.a str.a fs.a - ./load instcheck fifo.o hier.o auto_qmail.o auto_split.o \ + ./load instcheck fifo.o hier_destdir.o auto_qmail.o auto_split.o \ auto_uids.o strerr.a substdio.a error.a str.a fs.a instcheck.o: \ diff --git TARGETS TARGETS index facdad7..59aec59 100644 --- TARGETS +++ TARGETS @@ -154,7 +154,6 @@ auto-uid.o auto-uid auto-gid.o auto-gid -auto_uids.c auto_uids.o qmail-lspawn qmail-getpw.o @@ -385,3 +384,10 @@ forgeries.0 man setup check +auto_destdir.c +auto_destdir.o +auto_usergroupnames.h +hier_destdir.c +hier_destdir.o +install-destdir.o +install-destdir diff --git auto_uids.c auto_uids.c new file mode 100644 index 0000000..820e518 --- /dev/null +++ auto_uids.c @@ -0,0 +1,54 @@ +#include +#include +#include +#include +#include "auto_uids.h" +#include "auto_usergroupnames.h" +#include "qlx.h" + +struct group *getgrnam(); +struct passwd *getpwnam(); + +static int ids[] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }; + +static int +name2uid(name) +char *name; +{ + struct passwd *pw; + pw = getpwnam(name); + if (!pw) _exit(QLX_NOALIAS); + return (int)(pw->pw_uid); +} + +static int +name2gid(name) +char *name; +{ + struct group *gr; + gr = getgrnam(name); + if (!gr) _exit(QLX_NOALIAS); + return (int)(gr->gr_gid); +} + +int +qmail_id_lookup(id) +int id; +{ + if (ids[id] >= 0) return ids[id]; + + switch(id) { + case ID_OWNER: ids[id] = name2uid(auto_usero); break; + case ID_ALIAS: ids[id] = name2uid(auto_usera); break; + case ID_DAEMON: ids[id] = name2uid(auto_userd); break; + case ID_LOG: ids[id] = name2uid(auto_userl); break; + case ID_PASSWD: ids[id] = name2uid(auto_userp); break; + case ID_QUEUE: ids[id] = name2uid(auto_userq); break; + case ID_REMOTE: ids[id] = name2uid(auto_userr); break; + case ID_SEND: ids[id] = name2uid(auto_users); break; + case ID_QMAIL: ids[id] = name2gid(auto_groupq); break; + case ID_NOFILES: ids[id] = name2gid(auto_groupn); break; + default: _exit(QLX_NOALIAS); + } + return ids[id]; +} diff --git auto_uids.h auto_uids.h index 1252ecb..882b597 100644 --- auto_uids.h +++ auto_uids.h @@ -1,16 +1,29 @@ #ifndef AUTO_UIDS_H #define AUTO_UIDS_H -extern int auto_uida; -extern int auto_uidd; -extern int auto_uidl; -extern int auto_uido; -extern int auto_uidp; -extern int auto_uidq; -extern int auto_uidr; -extern int auto_uids; +#define ID_OWNER 0 +#define ID_ALIAS 1 +#define ID_DAEMON 2 +#define ID_LOG 3 +#define ID_PASSWD 4 +#define ID_QUEUE 5 +#define ID_REMOTE 6 +#define ID_SEND 7 +#define ID_QMAIL 8 +#define ID_NOFILES 9 -extern int auto_gidn; -extern int auto_gidq; +#define auto_uido qmail_id_lookup(ID_OWNER) +#define auto_uida qmail_id_lookup(ID_ALIAS) +#define auto_uidd qmail_id_lookup(ID_DAEMON) +#define auto_uidl qmail_id_lookup(ID_LOG) +#define auto_uidp qmail_id_lookup(ID_PASSWD) +#define auto_uidq qmail_id_lookup(ID_QUEUE) +#define auto_uidr qmail_id_lookup(ID_REMOTE) +#define auto_uids qmail_id_lookup(ID_SEND) + +#define auto_gidq qmail_id_lookup(ID_QMAIL) +#define auto_gidn qmail_id_lookup(ID_NOFILES) + +extern int qmail_id_lookup(); #endif diff --git conf-destdir conf-destdir new file mode 100644 index 0000000..5720f2a --- /dev/null +++ conf-destdir @@ -0,0 +1,5 @@ +/var/tmp/qmail-destdir + +This is the qmail installation staging directory. It can be the same as +the qmail home directory (conf-qmail), if you want. If it's somewhere +else writable by non-root, you can build as non-root. diff --git fake_chown.h fake_chown.h new file mode 100644 index 0000000..b471d65 --- /dev/null +++ fake_chown.h @@ -0,0 +1,11 @@ +#ifndef FAKE_CHOWN_H +#define FAKE_CHOWN_H + +/* + * Included only by install.c, which we don't want setting permissions + * Permissions will be set by ./install-destdir + */ + +int chown(const char *p, unsigned int o, unsigned int g) { return 0; } + +#endif diff --git fake_uids.h fake_uids.h new file mode 100644 index 0000000..b76103e --- /dev/null +++ fake_uids.h @@ -0,0 +1,22 @@ +#ifndef FAKE_UIDS_H +#define FAKE_UIDS_H + +/* + * Included only by hier.c, which is linked only into ./install + * These values don't matter there, as it doesn't try to set permissions + * Permissions are set by ./install-destdir (linked with hier_destdir.c) + */ + +#define auto_uido -79 +#define auto_uida -78 +#define auto_uidd -77 +#define auto_uidl -76 +#define auto_uidp -75 +#define auto_uidq -74 +#define auto_uidr -73 +#define auto_uids -72 + +#define auto_gidq -71 +#define auto_gidn -70 + +#endif diff --git hier.c hier.c index 28e568d..df45c6e 100644 --- hier.c +++ hier.c @@ -1,6 +1,6 @@ #include "auto_qmail.h" #include "auto_split.h" -#include "auto_uids.h" +#include "fake_uids.h" #include "fmt.h" #include "fifo.h" diff --git install-destdir.c install-destdir.c new file mode 100644 index 0000000..ddafcd9 --- /dev/null +++ install-destdir.c @@ -0,0 +1,126 @@ +#include "substdio.h" +#include "strerr.h" +#include "error.h" +#include "open.h" +#include "readwrite.h" +#include "exit.h" +#include "str.h" +#include "env.h" + +extern void hier(); + +#define FATAL "install-destdir: fatal: " + +void h(home,uid,gid,mode) +char *home; +int uid; +int gid; +int mode; +{ + if (mkdir(home,0700) == -1) + if (errno != error_exist) + strerr_die4sys(111,FATAL,"unable to mkdir ",home,": "); + if (chown(home,uid,gid) == -1) + strerr_die4sys(111,FATAL,"unable to chown ",home,": "); + if (chmod(home,mode) == -1) + strerr_die4sys(111,FATAL,"unable to chmod ",home,": "); +} + +void d(home,subdir,uid,gid,mode) +char *home; +char *subdir; +int uid; +int gid; +int mode; +{ + if (chdir(home) == -1) + strerr_die4sys(111,FATAL,"unable to switch to ",home,": "); + if (mkdir(subdir,0700) == -1) + if (errno != error_exist) + strerr_die6sys(111,FATAL,"unable to mkdir ",home,"/",subdir,": "); + if (chown(subdir,uid,gid) == -1) + strerr_die6sys(111,FATAL,"unable to chown ",home,"/",subdir,": "); + if (chmod(subdir,mode) == -1) + strerr_die6sys(111,FATAL,"unable to chmod ",home,"/",subdir,": "); +} + +void p(home,fifo,uid,gid,mode) +char *home; +char *fifo; +int uid; +int gid; +int mode; +{ + if (chdir(home) == -1) + strerr_die4sys(111,FATAL,"unable to switch to ",home,": "); + if (fifo_make(fifo,0700) == -1) + if (errno != error_exist) + strerr_die6sys(111,FATAL,"unable to mkfifo ",home,"/",fifo,": "); + if (chown(fifo,uid,gid) == -1) + strerr_die6sys(111,FATAL,"unable to chown ",home,"/",fifo,": "); + if (chmod(fifo,mode) == -1) + strerr_die6sys(111,FATAL,"unable to chmod ",home,"/",fifo,": "); +} + +char outbuf[SUBSTDIO_OUTSIZE]; +substdio ssout; + +void c(home,subdir,file,uid,gid,mode) +char *home; +char *subdir; +char *file; +int uid; +int gid; +int mode; +{ + if (chdir(home) == -1) + strerr_die4sys(111,FATAL,"unable to switch to ",home,": "); + if (chdir(subdir) == -1) + strerr_die6sys(111,FATAL,"unable to switch to ",home,"/",subdir,": "); + if (chown(file,uid,gid) == -1) + strerr_die6sys(111,FATAL,"unable to chown .../",subdir,"/",file,": "); + if (chmod(file,mode) == -1) + strerr_die6sys(111,FATAL,"unable to chmod .../",subdir,"/",file,": "); +} + +void z(home,file,len,uid,gid,mode) +char *home; +char *file; +int len; +int uid; +int gid; +int mode; +{ + int fdout; + + if (chdir(home) == -1) + strerr_die4sys(111,FATAL,"unable to switch to ",home,": "); + + fdout = open_trunc(file); + if (fdout == -1) + strerr_die6sys(111,FATAL,"unable to write ",home,"/",file,": "); + substdio_fdbuf(&ssout,write,fdout,outbuf,sizeof outbuf); + + while (len-- > 0) + if (substdio_put(&ssout,"",1) == -1) + strerr_die6sys(111,FATAL,"unable to write ",home,"/",file,": "); + + if (substdio_flush(&ssout) == -1) + strerr_die6sys(111,FATAL,"unable to write ",home,"/",file,": "); + if (fsync(fdout) == -1) + strerr_die6sys(111,FATAL,"unable to write ",home,"/",file,": "); + if (close(fdout) == -1) /* NFS silliness */ + strerr_die6sys(111,FATAL,"unable to write ",home,"/",file,": "); + + if (chown(file,uid,gid) == -1) + strerr_die6sys(111,FATAL,"unable to chown ",home,"/",file,": "); + if (chmod(file,mode) == -1) + strerr_die6sys(111,FATAL,"unable to chmod ",home,"/",file,": "); +} + +void main() +{ + umask(077); + hier(); + _exit(0); +} diff --git install.c install.c index 95034f2..1c72225 100644 --- install.c +++ install.c @@ -4,6 +4,7 @@ #include "open.h" #include "readwrite.h" #include "exit.h" +#include "fake_chown.h" extern void hier();