|
|
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;
}