|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T i
Length: 16005 (0x3e85) Types: TextFile Names: »init.c«
└─⟦a0efdde77⟧ Bits:30001252 EUUGD11 Tape, 1987 Spring Conference Helsinki └─⟦this⟧ »EUUGD11/euug-87hel/sec8/mcp/src/init.c«
#include <stdio.h> #include <sys/file.h> #include <sys/types.h> #include <pwd.h> #include <grp.h> #include <lastlog.h> #include <strings.h> #include <errno.h> #include "sysdep.h" #include "macros.h" #include "mem.h" #include "sort.h" #include "lists.h" #include "save.h" #include "sig.h" #include "class.h" #include "account.h" #include "command.h" #include "groupmap.h" #include "range.h" #ifdef SENDMAIL #include "alias.h" #endif #ifdef sun # ifdef DOFILES /* * Lint complains about all the unused functions declared in netdb.h * and mntent.h... but these functions are >>declared<< NOT * >>defined<< so lint should SHUT UP about this!! Since it doesn't, * we work around its ignorance. */ # ifndef lint # include <mntent.h> # include <netdb.h> # else struct servent { char *s_name; /* official service name */ char **s_aliases; /* alias list */ int s_port; /* port # */ char *s_proto; /* protocol to use */ }; struct servent *getservbyname(); # define MNTTAB "/etc/fstab" struct mntent{ char *mnt_fsname; /* name of mounted file system */ char *mnt_dir; /* file system path prefix */ char *mnt_type; /* MNTTYPE_* */ char *mnt_opts; /* MNTOPT* */ int mnt_freq; /* dump frequency, in days */ int mnt_passno; /* pass number on parallel fsck */ }; struct mntent *getmntent(); FILE *setmntent(); # endif lint # endif DOFILES #endif sun static char *e1 = "password file has more lines than accounts file."; static char *e2 = "accounts file has more lines than password file."; static char *e3 = "line %d: login name not the same in accounts/passwd."; extern struct lastlog *getlluid(), *getllent(); extern struct list YesNo, Titles, Suffixes, History; extern char *sprintf(), *getpass(); #ifdef BSD4_3 uid_t geteuid(), getuid(); char *getwd(); time_t time(); #endif #ifdef SENDMAIL extern addalias(), addtoalias(), bindclass(), bindgroup(), bindsig(); extern desalias(); extern rmalias(), rmfromalias(), ubindclass(), ubindgroup(), ubindsig(); extern updalias(); #endif #ifdef HELPDIR extern descommand(), whatis(); #endif extern addclass(), addgroup(), addrange(), addsig(); extern addtoclass(), addtogroup(); extern addtosig(), adduser(), addvig(); extern ckpchanges(); extern deschanges(), desclass(); extern descryos(), desdeadbeats(), desgroup(), desinactives(), desrange(); extern dessig(), desuser(), disableuser(), exitmcp(); extern freezedeadbeats(), freezeinactives(), freezeuser(); extern listgeneric(), listcryos(); extern listdeadbeats(), listinactives(); extern loadfile(), pausemcp(), rmclass(); extern rmcryos(), rmfromclass(), rmfromgroup(), rmfromsig(); extern rmgroup(); extern rmrange(), rmsig(), rmuser(), rmvig(), savechanges(), saveandexit(); extern shellescape(); extern updclass(), updgroup(), updrange(), updsig(), upduser(); struct command Ctable[] = { #ifdef SENDMAIL { "add-alias", addalias, 1 }, #endif { "add-class", addclass, 1 }, { "add-group", addgroup, 1 }, { "add-range", addrange, 1 }, { "add-sig", addsig, 1 }, #ifdef SENDMAIL { "add-to-alias", addtoalias, 1 }, #endif { "add-to-class", addtoclass, 1 }, { "add-to-group", addtogroup, 1 }, { "add-to-sig", addtosig, 1 }, { "add-user", adduser, 1 }, { "add-vig", addvig, 1 }, #ifdef SENDMAIL { "bind-group", bindgroup, 1 }, { "bind-class", bindclass, 1 }, { "bind-sig", bindsig, 1 }, #endif { "checkpoint-changes", ckpchanges, 1 }, #ifdef SENDMAIL { "describe-alias", desalias, 0 }, #endif { "describe-class", desclass, 0 }, { "describe-changes", deschanges, 1 }, #ifdef HELPDIR { "describe-command", descommand, 0 }, #endif { "describe-cryos", descryos, 0 }, { "describe-deadbeats", desdeadbeats, 0 }, { "describe-group", desgroup, 0 }, { "describe-inactives", desinactives, 0 }, { "describe-range", desrange, 0 }, { "describe-sig", dessig, 0 }, { "describe-user", desuser, 0 }, { "disable-user", disableuser, 1 }, { "exit-mcp", exitmcp, 0 }, { "freeze-deadbeats", freezedeadbeats, 1 }, { "freeze-inactives", freezeinactives, 1 }, { "freeze-user", freezeuser, 1 }, #ifdef SENDMAIL { "list-aliases", listgeneric, 0 }, #endif { "list-classes", listgeneric, 0 }, { "list-commands", listgeneric, 0 }, { "list-cryos", listcryos, 0 }, { "list-deadbeats", listdeadbeats, 0 }, { "list-groups", listgeneric, 0 }, { "list-inactives", listinactives, 0 }, { "list-ranges", listgeneric, 0 }, { "list-sigs", listgeneric, 0 }, { "list-users", listgeneric, 0 }, { "list-vigs", listgeneric, 0 }, { "load-file", loadfile, 1 }, { "pause-mcp", pausemcp, 0 }, #ifdef SENDMAIL { "remove-alias", rmalias, 1 }, #endif { "remove-class", rmclass, 1 }, { "remove-cryos", rmcryos, 1 }, #ifdef SENDMAIL { "remove-from-alias", rmfromalias, 1 }, #endif { "remove-from-class", rmfromclass, 1 }, { "remove-from-group", rmfromgroup, 1 }, { "remove-from-sig", rmfromsig, 1 }, { "remove-group", rmgroup, 1 }, { "remove-range", rmrange, 1 }, { "remove-sig", rmsig, 1 }, { "remove-user", rmuser, 1 }, { "remove-vig", rmvig, 1 }, { "save-and-exit", saveandexit, 1 }, { "save-changes", savechanges, 1 }, { "shell-escape", shellescape, 0 }, #ifdef SENDMAIL { "unbind-group", ubindgroup, 1 }, { "unbind-class", ubindclass, 1 }, { "unbind-sig", ubindsig, 1 }, { "update-alias", updalias, 1 }, #endif { "update-class", updclass, 1 }, { "update-group", updgroup, 1 }, { "update-range", updrange, 1 }, { "update-sig", updsig, 1 }, { "update-user", upduser, 1 }, #ifdef HELPDIR { "what-is", whatis, 0 }, #endif { (char *) 0, (int (*)())0, 0 } }; #ifdef HELPDIR static char *TermTable[] = { # ifdef SENDMAIL "alias", # endif "class", "cryo", "deadbeat", "gid", "inactive", "range", "sig", "uid", "vig", (char *)0 }; #endif struct list TempLists; /* list of lists to freed */ #ifdef SENDMAIL struct list Aliases; /* alias name completion list */ struct list AliasList; /* list of alias structures */ #endif struct list AllCommands; /* complete list of mcp commands */ struct list Commands; /* commands this user is allowed */ struct list Users; /* user name completion list */ struct list AccountList; /* list of account structures */ struct list Classes; /* class name completion list */ struct list ClassList; /* list of class structures */ struct list Groups; /* group name completion list */ struct list GroupMapList; /* list of groupmap structures */ struct list Ranges; /* range name completion list */ struct list RangeList; /* list of range structures */ struct list Sigs; /* sig name completion list */ struct list SigList; /* list of sig structures */ struct list Jobs; /* list of job structures */ #ifdef HELPDIR struct list Terms; /* list of terms mcp can define */ #endif struct list Shells; /* list of shells (from SHELLFILE) */ struct list Vigs; /* vig completion list */ struct list Null_List; /* empty list */ int ModBits; /* flags denoting modified files */ int DevTty; /* descriptor for diagnostic output and prompts. DevTty = 2 for non- interactive runs. */ time_t PWLockTime; /* last modify time for /etc/passwd */ int root; /* is this the super-user? */ int kids; /* current # of child processes */ int NCommands; /* # of commands user can execute */ addr DEF_SHELL; /* default shell */ char Working_Directory[LONG_BUF]; /* current working driectory */ #ifdef sun int IsRemote; /* must we use remote commands */ char HostName[MEDIUM_BUF]; /* current hostname */ # ifdef DOFILES char FileServer[MEDIUM_BUF]; /* hostname of file server */ char MountDirectory[MEDIUM_BUF]; /* remote mount point */ char RemotePassword[SHORT_BUF]; /* root password of fileserver */ u_short ExecTcpPort; /* port for exec/tcp service */ # endif #endif init_lists(interactive) int interactive; { FILE *fp; flexaddr p; #ifdef SENDMAIL struct alias al, *al2; struct groupmap *gm2; #endif struct account ac, *ac2; struct passwd *pw; struct group *gr; struct groupmap gm; struct sig sg, *sg2; struct class cs, *cs2; struct range rg, *rg2; struct lastlog *ll; char buf[LONG_BUF], errmsg[LONG_BUF], sh[MEDIUM_BUF], *cp; int indx, lineno = 0; if (interactive) msg("Loading password and accounts..."); (void) setpwent(); (void) setacent(); (void) setllent(); while ((pw = getpwent()) != (struct passwd *)0) { ac2 = getacent(); if (!ac2) fatal(e1); lineno++; if (!eq((char *)ac2->ac_name, pw->pw_name)) { (void) sprintf(errmsg, e3, lineno); fatal(errmsg); } ac.ac_uid = pw->pw_uid; ac.ac_gid = pw->pw_gid; savestr((char **)&ac.ac_name, pw->pw_name); savestr((char **)&ac.ac_gecos, pw->pw_gecos); savestr((char **)&ac.ac_passwd, pw->pw_passwd); savestr((char **)&ac.ac_dir, pw->pw_dir); savestr((char **)&ac.ac_shell, pw->pw_shell); savestr((char **)&ac.ac_realname, (char *)ac2->ac_realname); savestr((char **)&ac.ac_id, (char *)ac2->ac_id); duplist(&ac.ac_groups, &ac2->ac_groups); duplist(&ac.ac_classes, &ac2->ac_classes); duplist(&ac.ac_sigs, &ac2->ac_sigs); #ifdef SENDMAIL duplist(&ac.ac_aliases, &ac2->ac_aliases); #endif ll = getlluid(ac.ac_uid); bcopy(&ac.ac_ll, ll, sizeof (struct lastlog)); genlistadd(&AccountList, (addr)&ac, sizeof (struct account)); strlistadd(&Users, pw->pw_name); } (void) endpwent(); endllent(); if (getacent()) fatal(e2); (void) endacent(); if (interactive) msg("Loading groups..."); zerolist(&gm.gm_aliases); (void) setgrent(); while ((gr = getgrent()) != (struct group *)0) { zerolist(&gm.gm_mem); #ifdef SENDMAIL zerolist(&gm.gm_aliases); #endif gm.gm_gid = gr->gr_gid; savestr(&gm.gm_name, gr->gr_name); savestr(&gm.gm_passwd, gr->gr_passwd); for (indx=0; gr->gr_mem[indx]; indx++) strlistadd(&gm.gm_mem, gr->gr_mem[indx]); sort_list(&gm.gm_mem, pstrcmp); genlistadd(&GroupMapList, (addr)&gm, sizeof(struct groupmap)); strlistadd(&Groups, gr->gr_name); } (void) endgrent(); if (interactive) msg("Loading classes..."); #ifdef SENDMAIL zerolist(&cs.cs_aliases); #endif setcsent(); while (cs2 = getcsent()) { savestr(&cs.cs_name, cs2->cs_name); savestr(&cs.cs_desc, cs2->cs_desc); cs.cs_dsize = cs2->cs_dsize; cs.cs_exptime = cs2->cs_exptime; genlistadd(&ClassList, (addr)&cs, sizeof (struct class)); strlistadd(&Classes, cs.cs_name); } endcsent(); if (interactive) msg("Loading sigs..."); #ifdef SENDMAIL zerolist(&sg.sg_aliases); #endif setsgent(); while (sg2 = getsgent()) { savestr(&sg.sg_name, sg2->sg_name); savestr(&sg.sg_desc, sg2->sg_desc); sg.sg_dsize = sg2->sg_dsize; sg.sg_exptime = sg2->sg_exptime; genlistadd(&SigList, (addr)&sg, sizeof (struct sig)); strlistadd(&Sigs, sg.sg_name); } endsgent(); if (interactive) msg("Loading range table..."); setrgent(); while (rg2 = getrgent()) { savestr(&rg.rg_name, rg2->rg_name); rg.rg_mode = rg2->rg_mode; rg.rg_from = rg2->rg_from; rg.rg_to = rg2->rg_to; genlistadd(&RangeList, (addr)&rg, sizeof (struct range)); strlistadd(&Ranges, rg.rg_name); } endrgent(); if (interactive) msg("Loading vigs..."); fp = fopen(VIGFILE, "r"); if (fp != NULL) { while (fscanf(fp, "%s", buf) != EOF) strlistadd(&Vigs, buf); (void) fclose(fp); } #ifdef SENDMAIL /* * Must sort here so that get{cs,gm,sg}nam() calls will work. */ if (interactive) msg("Loading and binding sendmail aliases..."); sort_list(&Groups, pstrcmp); sort_list(&ClassList, classcmp); sort_list(&SigList, sigcmp); setalent(); while (al2 = getalent()) { savestr(&al.al_name, al2->al_name); duplist(&al.al_addresses, &al2->al_addresses); duplist(&al.al_groups, &al2->al_groups); duplist(&al.al_classes, &al2->al_classes); duplist(&al.al_sigs, &al2->al_sigs); genlistadd(&AliasList, (addr)&al, sizeof (struct alias)); strlistadd(&Aliases, al.al_name); for (indx=0; indx < al.al_groups.l_count; indx++) { cp = (char *)al.al_groups.l_list[indx]; gm2 = getgmnam(cp); if (!gm2) continue; strlistadd(&gm2->gm_aliases, al.al_name); sort_list(&gm2->gm_aliases, pstrcmp); } for (indx=0; indx < al.al_classes.l_count; indx++) { cp = (char *)al.al_classes.l_list[indx]; cs2 = getcsnam(cp); if (!cs2) continue; strlistadd(&cs2->cs_aliases, al.al_name); sort_list(&cs2->cs_aliases, pstrcmp); } for (indx=0; indx < al.al_sigs.l_count; indx++) { cp = (char *)al.al_sigs.l_list[indx]; sg2 = getsgnam(cp); if (!sg2) continue; strlistadd(&sg2->sg_aliases, al.al_name); sort_list(&sg2->sg_aliases, pstrcmp); } } endalent(); #endif /* * If this is not an interactive session there is no need * to initialize the lists that are only used when mcp * is running interactively. */ if (!interactive) goto sort_em; msg("Commands..."); for (indx=0; Ctable[indx].c_name; indx++) { if (root || !Ctable[indx].c_su) strlistadd(&Commands, Ctable[indx].c_name); strlistadd(&AllCommands, Ctable[indx].c_name); } NCommands = indx; qsort((char *)Ctable, NCommands, sizeof (struct command), commcmp); #ifdef HELPDIR msg("Building term table..."); for (indx=0; TermTable[indx]; indx++) strlistadd(&Terms, TermTable[indx]); #endif msg("Loading shell table..."); fp = fopen(SHELLFILE, "r"); if (fp != NULL) { while (fgets(buf, LONG_BUF, fp) != NULL) { cp = index(buf, '#'); if (cp) *cp = '\0'; if (sscanf(buf, "%s", sh) != 1) continue; strlistadd(&Shells, sh); } (void) fclose(fp); } p.p_cp = (Shells.l_count ? (char *) Shells.l_list[0] : "/bin/sh"); DEF_SHELL = p.p_ap; sort_em: if (interactive) msg("Sorting lists..."); sort_list(&AccountList, acctcmp); sort_list(&GroupMapList, gmapcmp); sort_list(&Users, pstrcmp); sort_list(&Classes, pstrcmp); sort_list(&Sigs, pstrcmp); sort_list(&Ranges, pstrcmp); sort_list(&RangeList, rangecmp); sort_list(&Vigs, pstrcmp); #ifdef SENDMAIL sort_list(&AliasList, aliascmp); sort_list(&Aliases, pstrcmp); #else sort_list(&Groups, pstrcmp); sort_list(&ClassList, classcmp); sort_list(&SigList, sigcmp); #endif if (interactive) { sort_list(&Titles, pstrcmp); sort_list(&Suffixes, pstrcmp); sort_list(&YesNo, pstrcmp); sort_list(&Shells, pstrcmp); sort_list(&Commands, pstrcmp); sort_list(&AllCommands, pstrcmp); #ifdef HELPDIR sort_list(&Terms, pstrcmp); #endif msg("and..."); zerolist(&History); zerolist(&TempLists); msg(""); } return; } init_tty(interactive) int interactive; { extern int errno; long lseek(); if (!interactive) { DevTty = 2; return; } if ((DevTty = open("/dev/tty", O_RDWR)) < 0) { perror("/dev/tty"); goodbye(1); } if (lseek(0, 0L, L_INCR) == -1) { if (errno == ESPIPE) err("mcp reading from a pipe..."); } else if (!isatty(0)) err("mcp reading from a file..."); return; } init_identities() { #ifdef sun # ifdef DOFILES FILE *mnf; struct mntent *mn; struct servent *sv; char *cp, prompt[MEDIUM_BUF]; # endif #endif root = !(getuid() && geteuid()); if (!getwd(Working_Directory)) fatal1("getwd() failed!?: %s", Working_Directory); srandom(getpid() + getppid() + time((time_t *)0)); #ifdef sun if (gethostname(HostName, MEDIUM_BUF) == -1) { perr("gethostname"); fatal("mcp: Sorry, but I must have a hostname."); } # ifdef DOFILES if (!root) return; mnf = setmntent(MNTTAB, "r"); if (mnf == NULL) { fatal1("can't open %s", MNTTAB); goodbye(1); } while (mn = getmntent(mnf)) if (eq(mn->mnt_dir, USERDIR)) break; if (mn && eq(mn->mnt_type, "nfs")) { cp = index(mn->mnt_fsname, ':'); *cp++ = '\0'; (void) strcpy(FileServer, mn->mnt_fsname); (void) strcpy(MountDirectory, cp); sv = getservbyname("exec", "tcp"); if (!sv) fatal("mcp: can't find service exec/tcp"); ExecTcpPort = sv->s_port; /* root is not trusted over the network */ (void) sprintf(prompt, "Root password on %s:", FileServer); cp = getpass(prompt); (void) strcpy(RemotePassword, cp); if (DoRemote("/bin/true") == 0) fatal("Sorry"); IsRemote = 1; } (void) endmntent(mnf); # endif #endif return; }