2001-08-15 04:31:49 +08:00
|
|
|
/*
|
|
|
|
* XXX: license?
|
|
|
|
*/
|
|
|
|
|
2001-07-23 03:32:00 +08:00
|
|
|
/*
|
|
|
|
* The modules contains code to support cray t3e and sv1 computers.
|
|
|
|
* It is here to minimize the modifcations to the openssh base code.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifdef _CRAY
|
|
|
|
|
|
|
|
#include <udb.h>
|
|
|
|
#include <tmpdir.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <sys/category.h>
|
|
|
|
#include <utmp.h>
|
|
|
|
#include <sys/jtab.h>
|
|
|
|
#include <signal.h>
|
2001-08-07 07:29:16 +08:00
|
|
|
#include <sys/priv.h>
|
|
|
|
#include <sys/secparm.h>
|
|
|
|
#include <sys/usrv.h>
|
|
|
|
#include <sys/sysv.h>
|
|
|
|
#include <sys/sectab.h>
|
2001-07-23 03:32:00 +08:00
|
|
|
#include <sys/stat.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <pwd.h>
|
|
|
|
#include <fcntl.h>
|
|
|
|
#include <errno.h>
|
|
|
|
|
2001-08-07 07:29:16 +08:00
|
|
|
#include "bsd-cray.h"
|
|
|
|
|
2001-08-15 04:31:49 +08:00
|
|
|
char cray_tmpdir[TPATHSIZ+1]; /* job TMPDIR path */
|
2001-07-23 03:32:00 +08:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Functions.
|
|
|
|
*/
|
|
|
|
void cray_retain_utmp(struct utmp *, int);
|
2001-08-15 05:02:15 +08:00
|
|
|
void cray_delete_tmpdir(char *, int, uid_t);
|
2001-07-23 03:32:00 +08:00
|
|
|
void cray_init_job(struct passwd *);
|
|
|
|
void cray_set_tmpdir(struct utmp *);
|
|
|
|
|
2001-08-07 07:29:16 +08:00
|
|
|
|
2001-08-15 04:31:49 +08:00
|
|
|
/*
|
2001-07-23 03:32:00 +08:00
|
|
|
* Orignal written by:
|
|
|
|
* Wayne Schroeder
|
|
|
|
* San Diego Supercomputer Center
|
|
|
|
* schroeder@sdsc.edu
|
|
|
|
*/
|
2001-08-07 07:29:16 +08:00
|
|
|
void
|
2001-07-23 03:32:00 +08:00
|
|
|
cray_setup(uid_t uid, char *username)
|
|
|
|
{
|
2001-08-15 04:31:49 +08:00
|
|
|
struct udb *p;
|
2001-07-23 03:32:00 +08:00
|
|
|
extern char *setlimits();
|
2001-08-15 04:31:49 +08:00
|
|
|
int i, j;
|
|
|
|
int accts[MAXVIDS];
|
|
|
|
int naccts;
|
|
|
|
int err;
|
|
|
|
char *sr;
|
|
|
|
int pid;
|
|
|
|
struct jtab jbuf;
|
|
|
|
int jid;
|
|
|
|
|
|
|
|
if ((jid = getjtab(&jbuf)) < 0)
|
|
|
|
fatal("getjtab: no jid");
|
|
|
|
|
|
|
|
err = setudb(); /* open and rewind the Cray User DataBase */
|
|
|
|
if (err != 0)
|
|
|
|
fatal("UDB open failure");
|
|
|
|
naccts = 0;
|
2001-08-07 07:29:16 +08:00
|
|
|
p = getudbnam(username);
|
2001-08-15 04:31:49 +08:00
|
|
|
if (p == NULL)
|
|
|
|
fatal("No UDB entry for %.100s", username);
|
|
|
|
if (uid != p->ue_uid)
|
2001-08-15 05:02:15 +08:00
|
|
|
fatal("UDB entry %.100s uid(%d) does not match uid %d",
|
|
|
|
username, (int) p->ue_uid, (int) uid);
|
2001-08-15 04:31:49 +08:00
|
|
|
for (j = 0; p->ue_acids[j] != -1 && j < MAXVIDS; j++) {
|
|
|
|
accts[naccts] = p->ue_acids[j];
|
|
|
|
naccts++;
|
|
|
|
}
|
|
|
|
endudb(); /* close the udb */
|
|
|
|
|
|
|
|
if (naccts != 0) {
|
|
|
|
/* Perhaps someday we'll prompt users who have multiple accounts
|
|
|
|
to let them pick one (like CRI's login does), but for now just set
|
|
|
|
the account to the first entry. */
|
|
|
|
if (acctid(0, accts[0]) < 0)
|
|
|
|
fatal("System call acctid failed, accts[0]=%d", accts[0]);
|
2001-08-07 07:29:16 +08:00
|
|
|
}
|
2001-07-23 03:32:00 +08:00
|
|
|
|
2001-08-15 04:31:49 +08:00
|
|
|
/* Now set limits, including CPU time for the (interactive) job and process,
|
|
|
|
and set up permissions (for chown etc), etc. This is via an internal CRI
|
|
|
|
routine, setlimits, used by CRI's login. */
|
2001-08-07 07:29:16 +08:00
|
|
|
|
2001-08-15 04:31:49 +08:00
|
|
|
pid = getpid();
|
|
|
|
sr = setlimits(username, C_PROC, pid, UDBRC_INTER);
|
|
|
|
if (sr != NULL)
|
|
|
|
fatal("%.200s", sr);
|
2001-08-07 07:29:16 +08:00
|
|
|
|
2001-08-15 04:31:49 +08:00
|
|
|
sr = setlimits(username, C_JOB, jid, UDBRC_INTER);
|
|
|
|
if (sr != NULL)
|
|
|
|
fatal("%.200s", sr);
|
2001-08-07 07:29:16 +08:00
|
|
|
|
2001-08-15 04:31:49 +08:00
|
|
|
}
|
2001-08-07 07:29:16 +08:00
|
|
|
|
2001-08-15 04:31:49 +08:00
|
|
|
/*
|
2001-08-07 07:29:16 +08:00
|
|
|
* The rc.* and /etc/sdaemon methods of starting a program on unicos/unicosmk
|
|
|
|
* can have pal privileges that sshd can inherit which
|
|
|
|
* could allow a user to su to root with out a password.
|
|
|
|
* This subroutine clears all privileges.
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
drop_cray_privs()
|
|
|
|
{
|
|
|
|
#if defined(_SC_CRAY_PRIV_SU)
|
2001-08-15 04:31:49 +08:00
|
|
|
priv_proc_t* privstate;
|
|
|
|
int result;
|
|
|
|
extern int priv_set_proc();
|
|
|
|
extern priv_proc_t* priv_init_proc();
|
|
|
|
struct usrv usrv;
|
2001-08-07 07:29:16 +08:00
|
|
|
|
|
|
|
/*
|
|
|
|
* If ether of theses two flags are not set
|
2001-08-15 04:31:49 +08:00
|
|
|
* then don't allow this version of ssh to run.
|
|
|
|
*/
|
|
|
|
if (!sysconf(_SC_CRAY_PRIV_SU))
|
|
|
|
fatal("Not PRIV_SU system.");
|
|
|
|
if (!sysconf(_SC_CRAY_POSIX_PRIV))
|
|
|
|
fatal("Not POSIX_PRIV.");
|
2001-08-07 07:29:16 +08:00
|
|
|
|
2001-08-15 04:31:49 +08:00
|
|
|
debug("Dropping privileges.");
|
2001-08-07 07:29:16 +08:00
|
|
|
|
|
|
|
memset(&usrv, 0, sizeof(usrv));
|
2001-08-15 04:31:49 +08:00
|
|
|
if (setusrv(&usrv) < 0)
|
2001-08-15 05:02:15 +08:00
|
|
|
fatal("%s(%d): setusrv(): %s", __FILE__, __LINE__,
|
2001-08-15 04:31:49 +08:00
|
|
|
strerror(errno));
|
2001-07-23 03:32:00 +08:00
|
|
|
|
2001-08-07 07:29:16 +08:00
|
|
|
if ((privstate = priv_init_proc()) != NULL) {
|
2001-08-15 04:31:49 +08:00
|
|
|
result = priv_set_proc(privstate);
|
|
|
|
if (result != 0 )
|
2001-08-15 05:02:15 +08:00
|
|
|
fatal("%s(%d): priv_set_proc(): %s",
|
2001-08-15 04:31:49 +08:00
|
|
|
__FILE__, __LINE__, strerror(errno));
|
|
|
|
priv_free_proc(privstate);
|
|
|
|
}
|
|
|
|
debug ("Privileges should be cleared...");
|
2001-08-07 07:29:16 +08:00
|
|
|
#else
|
2001-08-15 04:31:49 +08:00
|
|
|
/* XXX: do this differently */
|
|
|
|
# error Cray systems must be run with _SC_CRAY_PRIV_SU on!
|
2001-08-07 07:29:16 +08:00
|
|
|
#endif
|
2001-07-23 03:32:00 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Retain utmp/wtmp information - used by cray accounting.
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
cray_retain_utmp(struct utmp *ut, int pid)
|
|
|
|
{
|
|
|
|
int fd;
|
2001-08-15 04:31:49 +08:00
|
|
|
struct utmp utmp;
|
|
|
|
|
|
|
|
if ((fd = open(UTMP_FILE, O_RDONLY)) != -1) {
|
|
|
|
while (read(fd, (char *)&utmp, sizeof(utmp)) == sizeof(utmp)) {
|
|
|
|
if (pid == utmp.ut_pid) {
|
|
|
|
ut->ut_jid = utmp.ut_jid;
|
2001-08-15 04:54:52 +08:00
|
|
|
/* XXX: MIN_SIZEOF here? can this go in loginrec? */
|
|
|
|
strncpy(ut->ut_tpath, utmp.ut_tpath, sizeof(utmp.ut_tpath));
|
|
|
|
strncpy(ut->ut_host, utmp.ut_host, sizeof(utmp.ut_host));
|
|
|
|
strncpy(ut->ut_name, utmp.ut_name, sizeof(utmp.ut_name));
|
2001-08-15 04:31:49 +08:00
|
|
|
break;
|
2001-07-23 03:32:00 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
close(fd);
|
2001-08-15 04:31:49 +08:00
|
|
|
}
|
|
|
|
/* XXX: error message? */
|
2001-07-23 03:32:00 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* tmpdir support.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* find and delete jobs tmpdir.
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
cray_delete_tmpdir(char *login, int jid, uid_t uid)
|
|
|
|
{
|
|
|
|
int child;
|
2001-08-15 04:31:49 +08:00
|
|
|
static char jtmp[TPATHSIZ];
|
|
|
|
struct stat statbuf;
|
|
|
|
int c;
|
|
|
|
int wstat;
|
|
|
|
|
|
|
|
for (c = 'a'; c <= 'z'; c++) {
|
|
|
|
snprintf(jtmp, TPATHSIZ, "%s/jtmp.%06d%c", JTMPDIR, jid, c);
|
|
|
|
if (stat(jtmp, &statbuf) == 0 && statbuf.st_uid == uid)
|
|
|
|
break;
|
|
|
|
}
|
2001-07-23 03:32:00 +08:00
|
|
|
|
2001-08-15 04:31:49 +08:00
|
|
|
if (c > 'z')
|
|
|
|
return;
|
2001-07-23 03:32:00 +08:00
|
|
|
|
2001-08-15 04:31:49 +08:00
|
|
|
if ((child = fork()) == 0) {
|
2001-08-15 05:02:15 +08:00
|
|
|
execl(CLEANTMPCMD, CLEANTMPCMD, login, jtmp, (char *)NULL);
|
2001-08-15 04:31:49 +08:00
|
|
|
fatal("cray_delete_tmpdir: execl of CLEANTMPCMD failed");
|
|
|
|
}
|
2001-07-23 03:32:00 +08:00
|
|
|
|
2001-08-15 04:31:49 +08:00
|
|
|
while (waitpid(child, &wstat, 0) == -1 && errno == EINTR)
|
|
|
|
;
|
2001-07-23 03:32:00 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Remove tmpdir on job termination.
|
|
|
|
*/
|
|
|
|
void
|
2001-08-15 04:31:49 +08:00
|
|
|
cray_job_termination_handler(int sig)
|
2001-07-23 03:32:00 +08:00
|
|
|
{
|
|
|
|
int jid;
|
|
|
|
char *login = NULL;
|
|
|
|
struct jtab jtab;
|
|
|
|
|
|
|
|
debug("Received SIG JOB.");
|
|
|
|
|
|
|
|
if ((jid = waitjob(&jtab)) == -1 ||
|
2001-08-15 04:31:49 +08:00
|
|
|
(login = uid2nam(jtab.j_uid)) == NULL)
|
|
|
|
return;
|
2001-07-23 03:32:00 +08:00
|
|
|
|
|
|
|
cray_delete_tmpdir(login, jid, jtab.j_uid);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Set job id and create tmpdir directory.
|
|
|
|
*/
|
2001-08-15 04:31:49 +08:00
|
|
|
void
|
2001-07-23 03:32:00 +08:00
|
|
|
cray_init_job(struct passwd *pw)
|
2001-08-15 04:31:49 +08:00
|
|
|
{
|
|
|
|
int jid;
|
|
|
|
int c;
|
|
|
|
|
|
|
|
jid = setjob(pw->pw_uid, WJSIGNAL);
|
|
|
|
if (jid < 0)
|
|
|
|
fatal("System call setjob failure");
|
|
|
|
|
|
|
|
for (c = 'a'; c <= 'z'; c++) {
|
|
|
|
snprintf(cray_tmpdir, TPATHSIZ, "%s/jtmp.%06d%c", JTMPDIR, jid, c);
|
|
|
|
if (mkdir(cray_tmpdir, JTMPMODE) != 0)
|
|
|
|
continue;
|
|
|
|
if (chown(cray_tmpdir, pw->pw_uid, pw->pw_gid) != 0) {
|
|
|
|
rmdir(cray_tmpdir);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (c > 'z')
|
|
|
|
cray_tmpdir[0] = '\0';
|
|
|
|
}
|
2001-07-23 03:32:00 +08:00
|
|
|
|
|
|
|
void
|
|
|
|
cray_set_tmpdir(struct utmp *ut)
|
2001-08-15 04:31:49 +08:00
|
|
|
{
|
|
|
|
int jid;
|
|
|
|
struct jtab jbuf;
|
2001-07-23 03:32:00 +08:00
|
|
|
|
2001-08-15 04:31:49 +08:00
|
|
|
if ((jid = getjtab(&jbuf)) < 0)
|
|
|
|
return;
|
2001-07-23 03:32:00 +08:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Set jid and tmpdir in utmp record.
|
2001-08-15 04:31:49 +08:00
|
|
|
*/
|
2001-07-23 03:32:00 +08:00
|
|
|
ut->ut_jid = jid;
|
|
|
|
strncpy(ut->ut_tpath, cray_tmpdir, TPATHSIZ);
|
2001-08-15 04:31:49 +08:00
|
|
|
}
|
2001-07-23 03:32:00 +08:00
|
|
|
#endif
|