bsd-cray.c revision 98937
198937Sdes/* 298937Sdes * $Id: bsd-cray.c,v 1.6 2002/05/15 16:39:51 mouring Exp $ 398937Sdes * 498937Sdes * bsd-cray.c 598937Sdes * 698937Sdes * Copyright (c) 2002, Cray Inc. (Wendy Palm <wendyp@cray.com>) 798937Sdes * Significant portions provided by 898937Sdes * Wayne Schroeder, SDSC <schroeder@sdsc.edu> 998937Sdes * William Jones, UTexas <jones@tacc.utexas.edu> 1098937Sdes * 1198937Sdes * Redistribution and use in source and binary forms, with or without 1298937Sdes * modification, are permitted provided that the following conditions 1398937Sdes * are met: 1498937Sdes * 1. Redistributions of source code must retain the above copyright 1598937Sdes * notice, this list of conditions and the following disclaimer. 1698937Sdes * 2. Redistributions in binary form must reproduce the above copyright 1798937Sdes * notice, this list of conditions and the following disclaimer in the 1898937Sdes * documentation and/or other materials provided with the distribution. 1998937Sdes * 2098937Sdes * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 2198937Sdes * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 2298937Sdes * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 2398937Sdes * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 2498937Sdes * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 2598937Sdes * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2698937Sdes * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2798937Sdes * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2898937Sdes * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 2998937Sdes * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3098937Sdes * 3198937Sdes * Created: Apr 22 16.34:00 2002 wp 3298937Sdes * 3398937Sdes * This file contains functions required for proper execution 3498937Sdes * on UNICOS systems. 3598937Sdes * 3698937Sdes */ 3798937Sdes 3898937Sdes#ifdef _CRAY 3998937Sdes#include <udb.h> 4098937Sdes#include <tmpdir.h> 4198937Sdes#include <unistd.h> 4298937Sdes#include <sys/category.h> 4398937Sdes#include <utmp.h> 4498937Sdes#include <sys/jtab.h> 4598937Sdes#include <signal.h> 4698937Sdes#include <sys/priv.h> 4798937Sdes#include <sys/secparm.h> 4898937Sdes#include <sys/usrv.h> 4998937Sdes#include <sys/sysv.h> 5098937Sdes#include <sys/sectab.h> 5198937Sdes#include <sys/stat.h> 5298937Sdes#include <stdlib.h> 5398937Sdes#include <pwd.h> 5498937Sdes#include <fcntl.h> 5598937Sdes#include <errno.h> 5698937Sdes 5798937Sdes#include "bsd-cray.h" 5898937Sdes 5998937Sdeschar cray_tmpdir[TPATHSIZ+1]; /* job TMPDIR path */ 6098937Sdes 6198937Sdes/* 6298937Sdes * Functions. 6398937Sdes */ 6498937Sdesvoid cray_retain_utmp(struct utmp *, int); 6598937Sdesvoid cray_delete_tmpdir(char *, int, uid_t); 6698937Sdesvoid cray_init_job(struct passwd *); 6798937Sdesvoid cray_set_tmpdir(struct utmp *); 6898937Sdes 6998937Sdes 7098937Sdes/* 7198937Sdes * Orignal written by: 7298937Sdes * Wayne Schroeder 7398937Sdes * San Diego Supercomputer Center 7498937Sdes * schroeder@sdsc.edu 7598937Sdes*/ 7698937Sdesvoid 7798937Sdescray_setup(uid_t uid, char *username) 7898937Sdes{ 7998937Sdes struct udb *p; 8098937Sdes extern char *setlimits(); 8198937Sdes int i, j; 8298937Sdes int accts[MAXVIDS]; 8398937Sdes int naccts; 8498937Sdes int err; 8598937Sdes char *sr; 8698937Sdes int pid; 8798937Sdes struct jtab jbuf; 8898937Sdes int jid; 8998937Sdes 9098937Sdes if ((jid = getjtab(&jbuf)) < 0) 9198937Sdes fatal("getjtab: no jid"); 9298937Sdes 9398937Sdes err = setudb(); /* open and rewind the Cray User DataBase */ 9498937Sdes if (err != 0) 9598937Sdes fatal("UDB open failure"); 9698937Sdes naccts = 0; 9798937Sdes p = getudbnam(username); 9898937Sdes if (p == NULL) 9998937Sdes fatal("No UDB entry for %.100s", username); 10098937Sdes if (uid != p->ue_uid) 10198937Sdes fatal("UDB entry %.100s uid(%d) does not match uid %d", 10298937Sdes username, (int) p->ue_uid, (int) uid); 10398937Sdes for (j = 0; p->ue_acids[j] != -1 && j < MAXVIDS; j++) { 10498937Sdes accts[naccts] = p->ue_acids[j]; 10598937Sdes naccts++; 10698937Sdes } 10798937Sdes endudb(); /* close the udb */ 10898937Sdes 10998937Sdes if (naccts != 0) { 11098937Sdes /* Perhaps someday we'll prompt users who have multiple accounts 11198937Sdes to let them pick one (like CRI's login does), but for now just set 11298937Sdes the account to the first entry. */ 11398937Sdes if (acctid(0, accts[0]) < 0) 11498937Sdes fatal("System call acctid failed, accts[0]=%d", accts[0]); 11598937Sdes } 11698937Sdes 11798937Sdes /* Now set limits, including CPU time for the (interactive) job and process, 11898937Sdes and set up permissions (for chown etc), etc. This is via an internal CRI 11998937Sdes routine, setlimits, used by CRI's login. */ 12098937Sdes 12198937Sdes pid = getpid(); 12298937Sdes sr = setlimits(username, C_PROC, pid, UDBRC_INTER); 12398937Sdes if (sr != NULL) 12498937Sdes fatal("%.200s", sr); 12598937Sdes 12698937Sdes sr = setlimits(username, C_JOB, jid, UDBRC_INTER); 12798937Sdes if (sr != NULL) 12898937Sdes fatal("%.200s", sr); 12998937Sdes 13098937Sdes} 13198937Sdes 13298937Sdes/* 13398937Sdes * The rc.* and /etc/sdaemon methods of starting a program on unicos/unicosmk 13498937Sdes * can have pal privileges that sshd can inherit which 13598937Sdes * could allow a user to su to root with out a password. 13698937Sdes * This subroutine clears all privileges. 13798937Sdes */ 13898937Sdesvoid 13998937Sdesdrop_cray_privs() 14098937Sdes{ 14198937Sdes#if defined(_SC_CRAY_PRIV_SU) 14298937Sdes priv_proc_t* privstate; 14398937Sdes int result; 14498937Sdes extern int priv_set_proc(); 14598937Sdes extern priv_proc_t* priv_init_proc(); 14698937Sdes struct usrv usrv; 14798937Sdes 14898937Sdes /* 14998937Sdes * If ether of theses two flags are not set 15098937Sdes * then don't allow this version of ssh to run. 15198937Sdes */ 15298937Sdes if (!sysconf(_SC_CRAY_PRIV_SU)) 15398937Sdes fatal("Not PRIV_SU system."); 15498937Sdes if (!sysconf(_SC_CRAY_POSIX_PRIV)) 15598937Sdes fatal("Not POSIX_PRIV."); 15698937Sdes 15798937Sdes debug("Dropping privileges."); 15898937Sdes 15998937Sdes memset(&usrv, 0, sizeof(usrv)); 16098937Sdes if (setusrv(&usrv) < 0) 16198937Sdes fatal("%s(%d): setusrv(): %s", __FILE__, __LINE__, 16298937Sdes strerror(errno)); 16398937Sdes 16498937Sdes if ((privstate = priv_init_proc()) != NULL) { 16598937Sdes result = priv_set_proc(privstate); 16698937Sdes if (result != 0 ) 16798937Sdes fatal("%s(%d): priv_set_proc(): %s", 16898937Sdes __FILE__, __LINE__, strerror(errno)); 16998937Sdes priv_free_proc(privstate); 17098937Sdes } 17198937Sdes debug ("Privileges should be cleared..."); 17298937Sdes#else 17398937Sdes /* XXX: do this differently */ 17498937Sdes# error Cray systems must be run with _SC_CRAY_PRIV_SU on! 17598937Sdes#endif 17698937Sdes} 17798937Sdes 17898937Sdes 17998937Sdes/* 18098937Sdes * Retain utmp/wtmp information - used by cray accounting. 18198937Sdes */ 18298937Sdesvoid 18398937Sdescray_retain_utmp(struct utmp *ut, int pid) 18498937Sdes{ 18598937Sdes int fd; 18698937Sdes struct utmp utmp; 18798937Sdes 18898937Sdes if ((fd = open(UTMP_FILE, O_RDONLY)) != -1) { 18998937Sdes while (read(fd, (char *)&utmp, sizeof(utmp)) == sizeof(utmp)) { 19098937Sdes if (pid == utmp.ut_pid) { 19198937Sdes ut->ut_jid = utmp.ut_jid; 19298937Sdes /* XXX: MIN_SIZEOF here? can this go in loginrec? */ 19398937Sdes strncpy(ut->ut_tpath, utmp.ut_tpath, sizeof(utmp.ut_tpath)); 19498937Sdes strncpy(ut->ut_host, utmp.ut_host, sizeof(utmp.ut_host)); 19598937Sdes strncpy(ut->ut_name, utmp.ut_name, sizeof(utmp.ut_name)); 19698937Sdes break; 19798937Sdes } 19898937Sdes } 19998937Sdes close(fd); 20098937Sdes } 20198937Sdes /* XXX: error message? */ 20298937Sdes} 20398937Sdes 20498937Sdes/* 20598937Sdes * tmpdir support. 20698937Sdes */ 20798937Sdes 20898937Sdes/* 20998937Sdes * find and delete jobs tmpdir. 21098937Sdes */ 21198937Sdesvoid 21298937Sdescray_delete_tmpdir(char *login, int jid, uid_t uid) 21398937Sdes{ 21498937Sdes int child; 21598937Sdes static char jtmp[TPATHSIZ]; 21698937Sdes struct stat statbuf; 21798937Sdes int c; 21898937Sdes int wstat; 21998937Sdes 22098937Sdes for (c = 'a'; c <= 'z'; c++) { 22198937Sdes snprintf(jtmp, TPATHSIZ, "%s/jtmp.%06d%c", JTMPDIR, jid, c); 22298937Sdes if (stat(jtmp, &statbuf) == 0 && statbuf.st_uid == uid) 22398937Sdes break; 22498937Sdes } 22598937Sdes 22698937Sdes if (c > 'z') 22798937Sdes return; 22898937Sdes 22998937Sdes if ((child = fork()) == 0) { 23098937Sdes execl(CLEANTMPCMD, CLEANTMPCMD, login, jtmp, (char *)NULL); 23198937Sdes fatal("cray_delete_tmpdir: execl of CLEANTMPCMD failed"); 23298937Sdes } 23398937Sdes 23498937Sdes while (waitpid(child, &wstat, 0) == -1 && errno == EINTR) 23598937Sdes ; 23698937Sdes} 23798937Sdes 23898937Sdes/* 23998937Sdes * Remove tmpdir on job termination. 24098937Sdes */ 24198937Sdesvoid 24298937Sdescray_job_termination_handler(int sig) 24398937Sdes{ 24498937Sdes int jid; 24598937Sdes char *login = NULL; 24698937Sdes struct jtab jtab; 24798937Sdes 24898937Sdes debug("Received SIG JOB."); 24998937Sdes 25098937Sdes if ((jid = waitjob(&jtab)) == -1 || 25198937Sdes (login = uid2nam(jtab.j_uid)) == NULL) 25298937Sdes return; 25398937Sdes 25498937Sdes cray_delete_tmpdir(login, jid, jtab.j_uid); 25598937Sdes} 25698937Sdes 25798937Sdes/* 25898937Sdes * Set job id and create tmpdir directory. 25998937Sdes */ 26098937Sdesvoid 26198937Sdescray_init_job(struct passwd *pw) 26298937Sdes{ 26398937Sdes int jid; 26498937Sdes int c; 26598937Sdes 26698937Sdes jid = setjob(pw->pw_uid, WJSIGNAL); 26798937Sdes if (jid < 0) 26898937Sdes fatal("System call setjob failure"); 26998937Sdes 27098937Sdes for (c = 'a'; c <= 'z'; c++) { 27198937Sdes snprintf(cray_tmpdir, TPATHSIZ, "%s/jtmp.%06d%c", JTMPDIR, jid, c); 27298937Sdes if (mkdir(cray_tmpdir, JTMPMODE) != 0) 27398937Sdes continue; 27498937Sdes if (chown(cray_tmpdir, pw->pw_uid, pw->pw_gid) != 0) { 27598937Sdes rmdir(cray_tmpdir); 27698937Sdes continue; 27798937Sdes } 27898937Sdes break; 27998937Sdes } 28098937Sdes 28198937Sdes if (c > 'z') 28298937Sdes cray_tmpdir[0] = '\0'; 28398937Sdes} 28498937Sdes 28598937Sdesvoid 28698937Sdescray_set_tmpdir(struct utmp *ut) 28798937Sdes{ 28898937Sdes int jid; 28998937Sdes struct jtab jbuf; 29098937Sdes 29198937Sdes if ((jid = getjtab(&jbuf)) < 0) 29298937Sdes return; 29398937Sdes 29498937Sdes /* 29598937Sdes * Set jid and tmpdir in utmp record. 29698937Sdes */ 29798937Sdes ut->ut_jid = jid; 29898937Sdes strncpy(ut->ut_tpath, cray_tmpdir, TPATHSIZ); 29998937Sdes} 30098937Sdes#endif 301