/* creat_mbox.c * * This is a program to create a mailbox in a user's directory. * It is separate from the main mail programs (send and msg) to * minimize the amount of code which must run as the superuser. * * Note: THIS PROGRAM MUST BE OWNED BY THE SUPERUSER AND MUST * RUN WITH THE SET-USER-ID BIT SET. * * To eliminate hacking, the program is passed just the name of * the user for whom the mailbox is to be created. It searches * the password file to find the user's home directory, then * checks to see if that user has a .mail.init file. If so, * it gets the mailbox name from the file; otherwise it defaults * to the name ".mail". In either case, it then verifies that the * user does not already have a file of that name before * creating one. The new mailbox is created with mode 0622 * (read/write for owner, write only for everyone else) and its * owner is set to the user's uid. */ #include "rqfile.h" #include "init_rec.h" #define true 1 #define false 0 char mailbox[64]; char pwbuf[512]; char *pwptr; int pwcount; int pwfd; struct status { char s_minor; char s_major; int s_number; int s_mode; char s_nlinks; char s_uid; char s_gid; char s_size0; int s_size1; int s_addr[8]; int s_actime[2]; int s_modtime[2]; } statb; int uid, gid; struct init_rec inir; main (argc, argv) int argc; char *argv[]; { char initfile[64]; int infd; if (argc != 2) exit (1); if ((pwfd = open ("/etc/passwd", 0)) < 0) exit (1); if (!findlocal (argv[1])) exit (1); stcat ("/", mailbox); stcpy (mailbox, initfile); stcat (INITFILE, initfile); if ((infd = open (initfile, 0)) >= 0) { read (infd, &inir, sizeof (inir)); close (infd); stcat (inir.in_mail, mailbox); } else stcat (".mail", mailbox); if (stat (mailbox, &statb) < 0) { close (creat (mailbox, 0622)); chown (mailbox, (gid << 8)| (uid & 0377)); exit (0); } exit (1); } /* name: findlocal function: To ascertain whether or not someone is a local user, and if they are, to find the name of their root directory. algorithm: Rewind the password file. Search it for a line starting with the user name. If found: extract all the info about uid, gid mailbox, etc. return. Else, continue the search. Announce that he isn't a known user. parameters: *char pointer to null terminated user name. returns: boolean whether or not he was found. globals: pwfd uid gid mailbox pwcount calls: getpwchar seek (system) called by: send history: Written by Mark Kampe Modified by Lauren Weinstein, 3/12/79 */ findlocal(name) char *name; { register char *np; register char pwc; /* rewind the password file */ seek(pwfd,0,0); pwcount = 0; pwc = 1; while(pwc > 0) { np = name; /* search for a line starting with name */ for(pwc = getpwchar(); pwc == *np++; pwc = getpwchar()); if ((pwc == ':') && (*--np == '\000')) goto gotuser; while( (pwc != '\n') && (pwc > 0) ) pwc = getpwchar(); } return(false); gotuser: /* extract all neat info from pw entry */ for(pwc = getpwchar(); pwc != ':'; pwc = getpwchar()); /* we have skipped over the password */ for(uid = 0; (pwc = getpwchar()) != ':'; uid =+ (9*uid) + pwc - '0'); for(gid = 0; (pwc = getpwchar()) != ':'; gid =+ (9*gid) + pwc - '0'); for(pwc = getpwchar(); pwc != ':'; pwc = getpwchar ()); np = mailbox; for(pwc = getpwchar(); pwc != ':'; pwc = getpwchar()) *np++ = pwc; *np = '\000'; return(true); } getpwchar() { tryagain: if (pwcount > 0) { pwcount--; return(*pwptr++); } else { pwcount = read(pwfd,pwbuf,512); if (pwcount <= 0) return(-1); pwptr = pwbuf; goto tryagain; } } stcat(latter,former) char *latter,*former; { register char *fp,*lp; fp = former; lp = latter; while (*fp++); fp--; while (*fp++ = *lp++); } stcpy(latter,former) char *latter,*former; { register char *fp,*lp; fp = former; lp = latter; while (*fp++ = *lp++); }