1*0Sstevel@tonic-gate /*
2*0Sstevel@tonic-gate  * $Id: bsd-cray.c,v 1.8 2002/09/26 00:38:51 tim Exp $
3*0Sstevel@tonic-gate  *
4*0Sstevel@tonic-gate  * bsd-cray.c
5*0Sstevel@tonic-gate  *
6*0Sstevel@tonic-gate  * Copyright (c) 2002, Cray Inc.  (Wendy Palm <wendyp@cray.com>)
7*0Sstevel@tonic-gate  * Significant portions provided by
8*0Sstevel@tonic-gate  *          Wayne Schroeder, SDSC <schroeder@sdsc.edu>
9*0Sstevel@tonic-gate  *          William Jones, UTexas <jones@tacc.utexas.edu>
10*0Sstevel@tonic-gate  *
11*0Sstevel@tonic-gate  * Redistribution and use in source and binary forms, with or without
12*0Sstevel@tonic-gate  * modification, are permitted provided that the following conditions
13*0Sstevel@tonic-gate  * are met:
14*0Sstevel@tonic-gate  * 1. Redistributions of source code must retain the above copyright
15*0Sstevel@tonic-gate  *    notice, this list of conditions and the following disclaimer.
16*0Sstevel@tonic-gate  * 2. Redistributions in binary form must reproduce the above copyright
17*0Sstevel@tonic-gate  *    notice, this list of conditions and the following disclaimer in the
18*0Sstevel@tonic-gate  *    documentation and/or other materials provided with the distribution.
19*0Sstevel@tonic-gate  *
20*0Sstevel@tonic-gate  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21*0Sstevel@tonic-gate  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22*0Sstevel@tonic-gate  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23*0Sstevel@tonic-gate  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
24*0Sstevel@tonic-gate  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25*0Sstevel@tonic-gate  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26*0Sstevel@tonic-gate  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27*0Sstevel@tonic-gate  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28*0Sstevel@tonic-gate  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29*0Sstevel@tonic-gate  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30*0Sstevel@tonic-gate  *
31*0Sstevel@tonic-gate  * Created: Apr 22 16.34:00 2002 wp
32*0Sstevel@tonic-gate  *
33*0Sstevel@tonic-gate  * This file contains functions required for proper execution
34*0Sstevel@tonic-gate  * on UNICOS systems.
35*0Sstevel@tonic-gate  *
36*0Sstevel@tonic-gate  */
37*0Sstevel@tonic-gate 
38*0Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
39*0Sstevel@tonic-gate 
40*0Sstevel@tonic-gate #include "includes.h"
41*0Sstevel@tonic-gate 
42*0Sstevel@tonic-gate #ifdef _UNICOS
43*0Sstevel@tonic-gate 
44*0Sstevel@tonic-gate #include <udb.h>
45*0Sstevel@tonic-gate #include <tmpdir.h>
46*0Sstevel@tonic-gate #include <unistd.h>
47*0Sstevel@tonic-gate #include <sys/category.h>
48*0Sstevel@tonic-gate #include <utmp.h>
49*0Sstevel@tonic-gate #include <sys/jtab.h>
50*0Sstevel@tonic-gate #include <signal.h>
51*0Sstevel@tonic-gate #include <sys/priv.h>
52*0Sstevel@tonic-gate #include <sys/secparm.h>
53*0Sstevel@tonic-gate #include <sys/tfm.h>
54*0Sstevel@tonic-gate #include <sys/usrv.h>
55*0Sstevel@tonic-gate #include <sys/sysv.h>
56*0Sstevel@tonic-gate #include <sys/sectab.h>
57*0Sstevel@tonic-gate #include <sys/secstat.h>
58*0Sstevel@tonic-gate #include <sys/stat.h>
59*0Sstevel@tonic-gate #include <sys/session.h>
60*0Sstevel@tonic-gate #include <stdlib.h>
61*0Sstevel@tonic-gate #include <pwd.h>
62*0Sstevel@tonic-gate #include <fcntl.h>
63*0Sstevel@tonic-gate #include <errno.h>
64*0Sstevel@tonic-gate #include <ia.h>
65*0Sstevel@tonic-gate #include <urm.h>
66*0Sstevel@tonic-gate #include "ssh.h"
67*0Sstevel@tonic-gate #include "log.h"
68*0Sstevel@tonic-gate #include "servconf.h"
69*0Sstevel@tonic-gate #include "bsd-cray.h"
70*0Sstevel@tonic-gate 
71*0Sstevel@tonic-gate #define MAXACID 80
72*0Sstevel@tonic-gate 
73*0Sstevel@tonic-gate extern ServerOptions options;
74*0Sstevel@tonic-gate 
75*0Sstevel@tonic-gate char cray_tmpdir[TPATHSIZ+1];		    /* job TMPDIR path */
76*0Sstevel@tonic-gate 
77*0Sstevel@tonic-gate struct		sysv sysv;	/* system security structure */
78*0Sstevel@tonic-gate struct		usrv usrv;      /* user   security structure */
79*0Sstevel@tonic-gate 
80*0Sstevel@tonic-gate /*
81*0Sstevel@tonic-gate  * Functions.
82*0Sstevel@tonic-gate  */
83*0Sstevel@tonic-gate void cray_retain_utmp(struct utmp *, int);
84*0Sstevel@tonic-gate void cray_delete_tmpdir(char *, int, uid_t);
85*0Sstevel@tonic-gate void cray_init_job(struct passwd *);
86*0Sstevel@tonic-gate void cray_set_tmpdir(struct utmp *);
87*0Sstevel@tonic-gate void cray_login_failure(char *, int);
88*0Sstevel@tonic-gate int cray_setup(uid_t, char *, const char *);
89*0Sstevel@tonic-gate int cray_access_denied(char *);
90*0Sstevel@tonic-gate 
91*0Sstevel@tonic-gate void
cray_login_failure(char * username,int errcode)92*0Sstevel@tonic-gate cray_login_failure(char *username, int errcode)
93*0Sstevel@tonic-gate {
94*0Sstevel@tonic-gate 	struct udb	*ueptr;		/* UDB pointer for username */
95*0Sstevel@tonic-gate 	ia_failure_t	fsent;		/* ia_failure structure */
96*0Sstevel@tonic-gate 	ia_failure_ret_t fret;		/* ia_failure return stuff */
97*0Sstevel@tonic-gate 	struct jtab	jtab;		/* job table structure */
98*0Sstevel@tonic-gate 	int		jid = 0;	/* job id */
99*0Sstevel@tonic-gate 
100*0Sstevel@tonic-gate 	if ((jid = getjtab(&jtab)) < 0) {
101*0Sstevel@tonic-gate 		debug("cray_login_failure(): getjtab error");
102*0Sstevel@tonic-gate 	}
103*0Sstevel@tonic-gate 	getsysudb();
104*0Sstevel@tonic-gate 	if ((ueptr = getudbnam(username)) == UDB_NULL) {
105*0Sstevel@tonic-gate 		debug("cray_login_failure(): getudbname() returned NULL");
106*0Sstevel@tonic-gate 	}
107*0Sstevel@tonic-gate 	endudb();
108*0Sstevel@tonic-gate 	fsent.revision	= 0;
109*0Sstevel@tonic-gate 	fsent.uname	= username;
110*0Sstevel@tonic-gate 	fsent.host	= (char *)get_canonical_hostname(options.verify_reverse_mapping);
111*0Sstevel@tonic-gate 	fsent.ttyn	= "sshd";
112*0Sstevel@tonic-gate 	fsent.caller	= IA_SSHD;
113*0Sstevel@tonic-gate 	fsent.flags	= IA_INTERACTIVE;
114*0Sstevel@tonic-gate 	fsent.ueptr	= ueptr;
115*0Sstevel@tonic-gate 	fsent.jid	= jid;
116*0Sstevel@tonic-gate 	fsent.errcode	= errcode;
117*0Sstevel@tonic-gate 	fsent.pwdp	= NULL;
118*0Sstevel@tonic-gate 	fsent.exitcode	= 0;	/* dont exit in ia_failure() */
119*0Sstevel@tonic-gate 
120*0Sstevel@tonic-gate 	fret.revision	= 0;
121*0Sstevel@tonic-gate 	fret.normal	= 0;
122*0Sstevel@tonic-gate 
123*0Sstevel@tonic-gate 	/*
124*0Sstevel@tonic-gate 	 * Call ia_failure because of an login failure.
125*0Sstevel@tonic-gate 	 */
126*0Sstevel@tonic-gate 	ia_failure(&fsent,&fret);
127*0Sstevel@tonic-gate }
128*0Sstevel@tonic-gate 
129*0Sstevel@tonic-gate /*
130*0Sstevel@tonic-gate  *  Cray access denied
131*0Sstevel@tonic-gate  */
132*0Sstevel@tonic-gate int
cray_access_denied(char * username)133*0Sstevel@tonic-gate cray_access_denied(char *username)
134*0Sstevel@tonic-gate {
135*0Sstevel@tonic-gate 	struct udb	*ueptr;		/* UDB pointer for username */
136*0Sstevel@tonic-gate 	int 		errcode;	/* IA errorcode */
137*0Sstevel@tonic-gate 
138*0Sstevel@tonic-gate 	errcode = 0;
139*0Sstevel@tonic-gate 	getsysudb();
140*0Sstevel@tonic-gate 	if ((ueptr = getudbnam(username)) == UDB_NULL) {
141*0Sstevel@tonic-gate 		debug("cray_login_failure(): getudbname() returned NULL");
142*0Sstevel@tonic-gate 	}
143*0Sstevel@tonic-gate 	endudb();
144*0Sstevel@tonic-gate 	if (ueptr && ueptr->ue_disabled)
145*0Sstevel@tonic-gate 		errcode = IA_DISABLED;
146*0Sstevel@tonic-gate 	if (errcode)
147*0Sstevel@tonic-gate 		cray_login_failure(username, errcode);
148*0Sstevel@tonic-gate 	return (errcode);
149*0Sstevel@tonic-gate }
150*0Sstevel@tonic-gate 
151*0Sstevel@tonic-gate int
cray_setup(uid_t uid,char * username,const char * command)152*0Sstevel@tonic-gate cray_setup (uid_t uid, char *username, const char *command)
153*0Sstevel@tonic-gate {
154*0Sstevel@tonic-gate 	extern struct udb *getudb();
155*0Sstevel@tonic-gate 	extern char *setlimits();
156*0Sstevel@tonic-gate 
157*0Sstevel@tonic-gate 	int err;                      /* error return */
158*0Sstevel@tonic-gate 	time_t		system_time;	/* current system clock */
159*0Sstevel@tonic-gate 	time_t		expiration_time; /* password expiration time */
160*0Sstevel@tonic-gate 	int		maxattempts;	/* maximum no. of failed login attempts */
161*0Sstevel@tonic-gate 	int		SecureSys;	/* unicos security flag */
162*0Sstevel@tonic-gate 	int		minslevel = 0;	/* system minimum security level */
163*0Sstevel@tonic-gate 	int		i, j;
164*0Sstevel@tonic-gate 	int		valid_acct = -1; /* flag for reading valid acct */
165*0Sstevel@tonic-gate 	char acct_name[MAXACID]  = { "" }; /* used to read acct name */
166*0Sstevel@tonic-gate 	struct		jtab jtab;	/* Job table struct */
167*0Sstevel@tonic-gate 	struct		udb ue;		/* udb entry for logging-in user */
168*0Sstevel@tonic-gate 	struct		udb *up;	/* pointer to UDB entry */
169*0Sstevel@tonic-gate 	struct		secstat secinfo; /* file  security attributes */
170*0Sstevel@tonic-gate 	struct          servprov init_info; /* used for sesscntl() call */
171*0Sstevel@tonic-gate 	int		jid;		/* job ID */
172*0Sstevel@tonic-gate 	int		pid;		/* process ID */
173*0Sstevel@tonic-gate 	char		*sr;            /* status return from setlimits() */
174*0Sstevel@tonic-gate 	char		*ttyn = NULL;	/* ttyname or command name*/
175*0Sstevel@tonic-gate 	char		hostname[MAXHOSTNAMELEN];
176*0Sstevel@tonic-gate 	passwd_t	pwdacm,
177*0Sstevel@tonic-gate 			pwddialup,
178*0Sstevel@tonic-gate 			pwdudb,
179*0Sstevel@tonic-gate 			pwdwal,
180*0Sstevel@tonic-gate 			pwddce;		/* passwd stuff for ia_user */
181*0Sstevel@tonic-gate 	ia_user_ret_t	uret;		/* stuff returned from ia_user */
182*0Sstevel@tonic-gate 	ia_user_t	usent;		/* ia_user main structure */
183*0Sstevel@tonic-gate 	int		ia_rcode;	/* ia_user return code */
184*0Sstevel@tonic-gate 	ia_failure_t	fsent;		/* ia_failure structure */
185*0Sstevel@tonic-gate 	ia_failure_ret_t fret;		/* ia_failure return stuff */
186*0Sstevel@tonic-gate 	ia_success_t	ssent;		/* ia_success structure */
187*0Sstevel@tonic-gate 	ia_success_ret_t sret;		/* ia_success return stuff */
188*0Sstevel@tonic-gate 	int		ia_mlsrcode;    /* ia_mlsuser return code */
189*0Sstevel@tonic-gate 	int		secstatrc;      /* [f]secstat return code */
190*0Sstevel@tonic-gate 
191*0Sstevel@tonic-gate 	if (SecureSys = (int)sysconf(_SC_CRAY_SECURE_SYS)) {
192*0Sstevel@tonic-gate 		getsysv(&sysv, sizeof(struct sysv));
193*0Sstevel@tonic-gate 		minslevel = sysv.sy_minlvl;
194*0Sstevel@tonic-gate 		if (getusrv(&usrv) < 0) {
195*0Sstevel@tonic-gate 			debug("getusrv() failed, errno = %d",errno);
196*0Sstevel@tonic-gate 			exit(1);
197*0Sstevel@tonic-gate 		}
198*0Sstevel@tonic-gate 	}
199*0Sstevel@tonic-gate 	hostname[0] = '\0';
200*0Sstevel@tonic-gate 	strncpy(hostname,
201*0Sstevel@tonic-gate 	   (char *)get_canonical_hostname(options.verify_reverse_mapping),
202*0Sstevel@tonic-gate 	   MAXHOSTNAMELEN);
203*0Sstevel@tonic-gate         /*
204*0Sstevel@tonic-gate          *  Fetch user's UDB entry.
205*0Sstevel@tonic-gate          */
206*0Sstevel@tonic-gate         getsysudb();
207*0Sstevel@tonic-gate         if ((up = getudbnam(username)) == UDB_NULL) {
208*0Sstevel@tonic-gate                 debug("cannot fetch user's UDB entry");
209*0Sstevel@tonic-gate                 exit(1);
210*0Sstevel@tonic-gate         }
211*0Sstevel@tonic-gate 
212*0Sstevel@tonic-gate         /*
213*0Sstevel@tonic-gate          *  Prevent any possible fudging so perform a data
214*0Sstevel@tonic-gate          *  safety check and compare the supplied uid against
215*0Sstevel@tonic-gate          *  the udb's uid.
216*0Sstevel@tonic-gate          */
217*0Sstevel@tonic-gate         if (up->ue_uid != uid) {
218*0Sstevel@tonic-gate                 debug("IA uid missmatch");
219*0Sstevel@tonic-gate                 exit(1);
220*0Sstevel@tonic-gate         }
221*0Sstevel@tonic-gate 	endudb();
222*0Sstevel@tonic-gate 
223*0Sstevel@tonic-gate 	if ((jid = getjtab (&jtab)) < 0) {
224*0Sstevel@tonic-gate 		debug("getjtab");
225*0Sstevel@tonic-gate 		return -1;
226*0Sstevel@tonic-gate 	}
227*0Sstevel@tonic-gate 	pid = getpid();
228*0Sstevel@tonic-gate 	ttyn = ttyname(0);
229*0Sstevel@tonic-gate 	if (SecureSys) {
230*0Sstevel@tonic-gate 		if (ttyn) {
231*0Sstevel@tonic-gate 			secstatrc = secstat(ttyn, &secinfo);
232*0Sstevel@tonic-gate 		} else {
233*0Sstevel@tonic-gate 			secstatrc = fsecstat(1, &secinfo);
234*0Sstevel@tonic-gate 		}
235*0Sstevel@tonic-gate 		if (secstatrc == 0) {
236*0Sstevel@tonic-gate 			debug("[f]secstat() successful");
237*0Sstevel@tonic-gate 		} else {
238*0Sstevel@tonic-gate 			debug("[f]secstat() error, rc = %d", secstatrc);
239*0Sstevel@tonic-gate 			exit(1);
240*0Sstevel@tonic-gate 		}
241*0Sstevel@tonic-gate 	}
242*0Sstevel@tonic-gate 	if ((ttyn == NULL) && ((char *)command != NULL))
243*0Sstevel@tonic-gate 		ttyn = (char *)command;
244*0Sstevel@tonic-gate         /*
245*0Sstevel@tonic-gate          *  Initialize all structures to call ia_user
246*0Sstevel@tonic-gate          */
247*0Sstevel@tonic-gate         usent.revision = 0;
248*0Sstevel@tonic-gate         usent.uname    = username;
249*0Sstevel@tonic-gate         usent.host     = hostname;
250*0Sstevel@tonic-gate         usent.ttyn     = ttyn;
251*0Sstevel@tonic-gate         usent.caller   = IA_SSHD;
252*0Sstevel@tonic-gate         usent.pswdlist = &pwdacm;
253*0Sstevel@tonic-gate         usent.ueptr    = &ue;
254*0Sstevel@tonic-gate         usent.flags    = IA_INTERACTIVE | IA_FFLAG;
255*0Sstevel@tonic-gate         pwdacm.atype   = IA_SECURID;
256*0Sstevel@tonic-gate         pwdacm.pwdp    = NULL;
257*0Sstevel@tonic-gate         pwdacm.next    = &pwdudb;
258*0Sstevel@tonic-gate 
259*0Sstevel@tonic-gate         pwdudb.atype   = IA_UDB;
260*0Sstevel@tonic-gate         pwdudb.pwdp    = NULL;
261*0Sstevel@tonic-gate         pwdudb.next    = &pwddce;
262*0Sstevel@tonic-gate 
263*0Sstevel@tonic-gate         pwddce.atype   = IA_DCE;
264*0Sstevel@tonic-gate         pwddce.pwdp    = NULL;
265*0Sstevel@tonic-gate         pwddce.next    = &pwddialup;
266*0Sstevel@tonic-gate 
267*0Sstevel@tonic-gate         pwddialup.atype = IA_DIALUP;
268*0Sstevel@tonic-gate         pwddialup.pwdp  = NULL;
269*0Sstevel@tonic-gate         /* pwddialup.next  = &pwdwal; */
270*0Sstevel@tonic-gate         pwddialup.next  = NULL;
271*0Sstevel@tonic-gate 
272*0Sstevel@tonic-gate         pwdwal.atype = IA_WAL;
273*0Sstevel@tonic-gate         pwdwal.pwdp  = NULL;
274*0Sstevel@tonic-gate         pwdwal.next  = NULL;
275*0Sstevel@tonic-gate 
276*0Sstevel@tonic-gate         uret.revision = 0;
277*0Sstevel@tonic-gate         uret.pswd     = NULL;
278*0Sstevel@tonic-gate         uret.normal   = 0;
279*0Sstevel@tonic-gate 
280*0Sstevel@tonic-gate         ia_rcode = ia_user(&usent, &uret);
281*0Sstevel@tonic-gate 
282*0Sstevel@tonic-gate         switch (ia_rcode) {
283*0Sstevel@tonic-gate                 /*
284*0Sstevel@tonic-gate                  *  These are acceptable return codes from ia_user()
285*0Sstevel@tonic-gate                  */
286*0Sstevel@tonic-gate                 case IA_UDBWEEK:        /* Password Expires in 1 week */
287*0Sstevel@tonic-gate 		     expiration_time = ue.ue_pwage.time + ue.ue_pwage.maxage;
288*0Sstevel@tonic-gate 		     printf ("WARNING - your current password will expire %s\n",
289*0Sstevel@tonic-gate                      ctime((const time_t *)&expiration_time));
290*0Sstevel@tonic-gate                      break;
291*0Sstevel@tonic-gate                 case IA_UDBEXPIRED:
292*0Sstevel@tonic-gate 		     if (ttyname(0) != NULL) {
293*0Sstevel@tonic-gate 		     /* Force a password change */
294*0Sstevel@tonic-gate 		         printf("Your password has expired; Choose a new one.\n");
295*0Sstevel@tonic-gate 		         execl("/bin/passwd", "passwd", username, 0);
296*0Sstevel@tonic-gate 		         exit(9);
297*0Sstevel@tonic-gate 		     }
298*0Sstevel@tonic-gate 
299*0Sstevel@tonic-gate 		     break;
300*0Sstevel@tonic-gate                 case IA_NORMAL:         /* Normal Return Code */
301*0Sstevel@tonic-gate                      break;
302*0Sstevel@tonic-gate                 case IA_BACKDOOR:
303*0Sstevel@tonic-gate                      strcpy(ue.ue_name, "root");
304*0Sstevel@tonic-gate                      strcpy(ue.ue_passwd, "");
305*0Sstevel@tonic-gate                      strcpy(ue.ue_dir, "/");
306*0Sstevel@tonic-gate                      strcpy(ue.ue_shell, "/bin/sh");
307*0Sstevel@tonic-gate                      strcpy(ue.ue_age, "");
308*0Sstevel@tonic-gate                      strcpy(ue.ue_comment, "");
309*0Sstevel@tonic-gate                      strcpy(ue.ue_loghost, "");
310*0Sstevel@tonic-gate                      strcpy(ue.ue_logline, "");
311*0Sstevel@tonic-gate                      ue.ue_uid=-1;
312*0Sstevel@tonic-gate                      ue.ue_nice[UDBRC_INTER]=0;
313*0Sstevel@tonic-gate                      for (i=0;i<MAXVIDS;i++)
314*0Sstevel@tonic-gate                          ue.ue_gids[i]=0;
315*0Sstevel@tonic-gate                      ue.ue_logfails=0;
316*0Sstevel@tonic-gate                      ue.ue_minlvl=minslevel;
317*0Sstevel@tonic-gate                      ue.ue_maxlvl=minslevel;
318*0Sstevel@tonic-gate                      ue.ue_deflvl=minslevel;
319*0Sstevel@tonic-gate                      ue.ue_defcomps=0;
320*0Sstevel@tonic-gate                      ue.ue_comparts=0;
321*0Sstevel@tonic-gate                      ue.ue_permits=0;
322*0Sstevel@tonic-gate                      ue.ue_trap=0;
323*0Sstevel@tonic-gate                      ue.ue_disabled=0;
324*0Sstevel@tonic-gate                      ue.ue_logtime=0;
325*0Sstevel@tonic-gate                      break;
326*0Sstevel@tonic-gate                 case IA_CONSOLE:        /* Superuser not from Console */
327*0Sstevel@tonic-gate 		case IA_TRUSTED:	/* Trusted user */
328*0Sstevel@tonic-gate 		     if (options.permit_root_login > PERMIT_NO)
329*0Sstevel@tonic-gate                      	break;		/* Accept root login */
330*0Sstevel@tonic-gate    	        default:
331*0Sstevel@tonic-gate                 /*
332*0Sstevel@tonic-gate                  *  These are failed return codes from ia_user()
333*0Sstevel@tonic-gate                  */
334*0Sstevel@tonic-gate 		     switch (ia_rcode)
335*0Sstevel@tonic-gate 		       {
336*0Sstevel@tonic-gate 		       case IA_BADAUTH:
337*0Sstevel@tonic-gate 			 printf ("Bad authorization, access denied.\n");
338*0Sstevel@tonic-gate 			 break;
339*0Sstevel@tonic-gate 		       case IA_DIALUPERR:
340*0Sstevel@tonic-gate 			 break;
341*0Sstevel@tonic-gate 		       case IA_DISABLED:
342*0Sstevel@tonic-gate 			 printf ("Your login has been disabled. Contact the system ");
343*0Sstevel@tonic-gate 			 printf ("administrator for assistance.\n");
344*0Sstevel@tonic-gate 			 break;
345*0Sstevel@tonic-gate 		       case IA_GETSYSV:
346*0Sstevel@tonic-gate 			 printf ("getsysv() failed - errno = %d\n", errno);
347*0Sstevel@tonic-gate 			 break;
348*0Sstevel@tonic-gate 		       case IA_LOCALHOST:
349*0Sstevel@tonic-gate 			 break;
350*0Sstevel@tonic-gate 		       case IA_MAXLOGS:
351*0Sstevel@tonic-gate 			 printf ("Maximum number of failed login attempts exceeded.\n");
352*0Sstevel@tonic-gate 			 printf ("Access denied.\n");
353*0Sstevel@tonic-gate 			 break;
354*0Sstevel@tonic-gate 		       case IA_NOPASS:
355*0Sstevel@tonic-gate 			 break;
356*0Sstevel@tonic-gate 		       case IA_PUBLIC:
357*0Sstevel@tonic-gate 			 break;
358*0Sstevel@tonic-gate 		       case IA_SECURIDERR:
359*0Sstevel@tonic-gate 			 break;
360*0Sstevel@tonic-gate 		       case IA_CONSOLE:
361*0Sstevel@tonic-gate 			 break;
362*0Sstevel@tonic-gate 		       case IA_TRUSTED:
363*0Sstevel@tonic-gate 			 break;
364*0Sstevel@tonic-gate 		       case IA_UDBERR:
365*0Sstevel@tonic-gate 			 break;
366*0Sstevel@tonic-gate 		       case IA_UDBPWDNULL:
367*0Sstevel@tonic-gate 			 /*
368*0Sstevel@tonic-gate 			  * NULL password not allowed on MLS systems
369*0Sstevel@tonic-gate 			  */
370*0Sstevel@tonic-gate 			 if (SecureSys) {
371*0Sstevel@tonic-gate 			   printf("NULL Password not allowed on MLS systems.\n");
372*0Sstevel@tonic-gate 			 }
373*0Sstevel@tonic-gate 			 break;
374*0Sstevel@tonic-gate 		       case IA_UNKNOWN:
375*0Sstevel@tonic-gate 			 break;
376*0Sstevel@tonic-gate 		       case IA_UNKNOWNYP:
377*0Sstevel@tonic-gate 			 break;
378*0Sstevel@tonic-gate 		       case IA_WALERR:
379*0Sstevel@tonic-gate 			 break;
380*0Sstevel@tonic-gate 		       default:
381*0Sstevel@tonic-gate 			 /* nothing special */
382*0Sstevel@tonic-gate 			 ;
383*0Sstevel@tonic-gate 		       }   /* 2. switch  (ia_rcode) */
384*0Sstevel@tonic-gate 		     /*
385*0Sstevel@tonic-gate 		      *  Authentication failed.
386*0Sstevel@tonic-gate 		      */
387*0Sstevel@tonic-gate 		     printf("sshd: Login incorrect, (0%o)\n",
388*0Sstevel@tonic-gate 			    ia_rcode-IA_ERRORCODE);
389*0Sstevel@tonic-gate 
390*0Sstevel@tonic-gate 		     /*
391*0Sstevel@tonic-gate 		      *  Initialize structure for ia_failure
392*0Sstevel@tonic-gate 		      *  which will exit.
393*0Sstevel@tonic-gate 		      */
394*0Sstevel@tonic-gate 		     fsent.revision = 0;
395*0Sstevel@tonic-gate 		     fsent.uname    = username;
396*0Sstevel@tonic-gate 		     fsent.host     = hostname;
397*0Sstevel@tonic-gate 		     fsent.ttyn     = ttyn;
398*0Sstevel@tonic-gate 		     fsent.caller   = IA_SSHD;
399*0Sstevel@tonic-gate 		     fsent.flags    = IA_INTERACTIVE;
400*0Sstevel@tonic-gate 		     fsent.ueptr    = &ue;
401*0Sstevel@tonic-gate 		     fsent.jid      = jid;
402*0Sstevel@tonic-gate 		     fsent.errcode  = ia_rcode;
403*0Sstevel@tonic-gate 		     fsent.pwdp     = uret.pswd;
404*0Sstevel@tonic-gate 		     fsent.exitcode = 1;
405*0Sstevel@tonic-gate 
406*0Sstevel@tonic-gate 		     fret.revision  = 0;
407*0Sstevel@tonic-gate 		     fret.normal    = 0;
408*0Sstevel@tonic-gate 
409*0Sstevel@tonic-gate 		     /*
410*0Sstevel@tonic-gate 		      *  Call ia_failure because of an IA failure.
411*0Sstevel@tonic-gate 		      *  There is no return because ia_failure exits.
412*0Sstevel@tonic-gate 		      */
413*0Sstevel@tonic-gate 
414*0Sstevel@tonic-gate 		     ia_failure(&fsent,&fret);
415*0Sstevel@tonic-gate 
416*0Sstevel@tonic-gate 		     exit(1);
417*0Sstevel@tonic-gate 	}   /* 1. switch  (ia_rcode) */
418*0Sstevel@tonic-gate 	ia_mlsrcode = IA_NORMAL;
419*0Sstevel@tonic-gate 	if (SecureSys) {
420*0Sstevel@tonic-gate 		debug("calling ia_mlsuser()");
421*0Sstevel@tonic-gate 		ia_mlsrcode = ia_mlsuser (&ue, &secinfo, &usrv, NULL, 0);
422*0Sstevel@tonic-gate 	}
423*0Sstevel@tonic-gate 	if (ia_mlsrcode != IA_NORMAL) {
424*0Sstevel@tonic-gate 		printf("sshd: Login incorrect, (0%o)\n",
425*0Sstevel@tonic-gate 		ia_mlsrcode-IA_ERRORCODE);
426*0Sstevel@tonic-gate 		/*
427*0Sstevel@tonic-gate  		 *  Initialize structure for ia_failure
428*0Sstevel@tonic-gate  		 *  which will exit.
429*0Sstevel@tonic-gate 		*/
430*0Sstevel@tonic-gate 		fsent.revision = 0;
431*0Sstevel@tonic-gate 		fsent.uname    = username;
432*0Sstevel@tonic-gate 		fsent.host     = hostname;
433*0Sstevel@tonic-gate 		fsent.ttyn     = ttyn;
434*0Sstevel@tonic-gate 		fsent.caller   = IA_SSHD;
435*0Sstevel@tonic-gate 		fsent.flags    = IA_INTERACTIVE;
436*0Sstevel@tonic-gate 		fsent.ueptr    = &ue;
437*0Sstevel@tonic-gate 		fsent.jid      = jid;
438*0Sstevel@tonic-gate 		fsent.errcode  = ia_mlsrcode;
439*0Sstevel@tonic-gate 		fsent.pwdp     = uret.pswd;
440*0Sstevel@tonic-gate 		fsent.exitcode = 1;
441*0Sstevel@tonic-gate 		fret.revision  = 0;
442*0Sstevel@tonic-gate 		fret.normal    = 0;
443*0Sstevel@tonic-gate 
444*0Sstevel@tonic-gate 		/*
445*0Sstevel@tonic-gate 		*  Call ia_failure because of an IA failure.
446*0Sstevel@tonic-gate 		*  There is no return because ia_failure exits.
447*0Sstevel@tonic-gate 		*/
448*0Sstevel@tonic-gate 		ia_failure(&fsent,&fret);
449*0Sstevel@tonic-gate 		exit(1);
450*0Sstevel@tonic-gate 	}
451*0Sstevel@tonic-gate 
452*0Sstevel@tonic-gate         /* Provide login status information */
453*0Sstevel@tonic-gate         if (options.print_lastlog && ue.ue_logtime != 0) {
454*0Sstevel@tonic-gate             printf("Last successful login was : %.*s ",
455*0Sstevel@tonic-gate                     19, (char *)ctime(&ue.ue_logtime));
456*0Sstevel@tonic-gate 
457*0Sstevel@tonic-gate            if (*ue.ue_loghost != '\0')
458*0Sstevel@tonic-gate                 printf("from %.*s\n", sizeof(ue.ue_loghost), ue.ue_loghost);
459*0Sstevel@tonic-gate 
460*0Sstevel@tonic-gate             else printf("on %.*s\n", sizeof(ue.ue_logline), ue.ue_logline);
461*0Sstevel@tonic-gate 
462*0Sstevel@tonic-gate             if ( SecureSys && (ue.ue_logfails != 0))
463*0Sstevel@tonic-gate                 printf("  followed by %d failed attempts\n", ue.ue_logfails);
464*0Sstevel@tonic-gate         }
465*0Sstevel@tonic-gate 
466*0Sstevel@tonic-gate 
467*0Sstevel@tonic-gate 	/*
468*0Sstevel@tonic-gate 	 * Call ia_success to process successful I/A.
469*0Sstevel@tonic-gate 	 */
470*0Sstevel@tonic-gate 	ssent.revision = 0;
471*0Sstevel@tonic-gate 	ssent.uname = username;
472*0Sstevel@tonic-gate 	ssent.host = hostname;
473*0Sstevel@tonic-gate 	ssent.ttyn = ttyn;
474*0Sstevel@tonic-gate 	ssent.caller = IA_SSHD;
475*0Sstevel@tonic-gate 	ssent.flags = IA_INTERACTIVE;
476*0Sstevel@tonic-gate 	ssent.ueptr = &ue;
477*0Sstevel@tonic-gate 	ssent.jid = jid;
478*0Sstevel@tonic-gate 	ssent.errcode = ia_rcode;
479*0Sstevel@tonic-gate 	ssent.us = NULL;
480*0Sstevel@tonic-gate 	ssent.time = 1;      		 /* Set ue_logtime */
481*0Sstevel@tonic-gate 
482*0Sstevel@tonic-gate 	sret.revision = 0;
483*0Sstevel@tonic-gate 	sret.normal = 0;
484*0Sstevel@tonic-gate 
485*0Sstevel@tonic-gate 	ia_success(&ssent,&sret);
486*0Sstevel@tonic-gate 
487*0Sstevel@tonic-gate         /*
488*0Sstevel@tonic-gate          * Query for account, iff > 1 valid acid & askacid permbit
489*0Sstevel@tonic-gate          */
490*0Sstevel@tonic-gate         if (((ue.ue_permbits & PERMBITS_ACCTID) ||
491*0Sstevel@tonic-gate              (ue.ue_acids[0] >= 0) && (ue.ue_acids[1] >= 0)) &&
492*0Sstevel@tonic-gate             ue.ue_permbits & PERMBITS_ASKACID) {
493*0Sstevel@tonic-gate 		if (ttyname(0) != NULL) {
494*0Sstevel@tonic-gate 		  debug("cray_setup: ttyname true case, %.100s", ttyname);
495*0Sstevel@tonic-gate                   while (valid_acct == -1) {
496*0Sstevel@tonic-gate                         printf("Account (? for available accounts)"
497*0Sstevel@tonic-gate                                " [%s]: ", acid2nam(ue.ue_acids[0]));
498*0Sstevel@tonic-gate                         gets(acct_name);
499*0Sstevel@tonic-gate                         switch (acct_name[0]) {
500*0Sstevel@tonic-gate                         case EOF:
501*0Sstevel@tonic-gate                                 exit(0);
502*0Sstevel@tonic-gate                                 break;
503*0Sstevel@tonic-gate                         case '\0':
504*0Sstevel@tonic-gate                                 valid_acct = ue.ue_acids[0];
505*0Sstevel@tonic-gate                                 strcpy(acct_name, acid2nam(valid_acct));
506*0Sstevel@tonic-gate                                 break;
507*0Sstevel@tonic-gate                         case '?':
508*0Sstevel@tonic-gate                                 /* Print the list 3 wide */
509*0Sstevel@tonic-gate                                 for (i = 0, j = 0; i < MAXVIDS; i++) {
510*0Sstevel@tonic-gate                                         if (ue.ue_acids[i] == -1) {
511*0Sstevel@tonic-gate                                                 printf("\n");
512*0Sstevel@tonic-gate                                                 break;
513*0Sstevel@tonic-gate                                         }
514*0Sstevel@tonic-gate                                         if (++j == 4) {
515*0Sstevel@tonic-gate                                                 j = 1;
516*0Sstevel@tonic-gate                                                 printf("\n");
517*0Sstevel@tonic-gate                                         }
518*0Sstevel@tonic-gate                                         printf(" %s",
519*0Sstevel@tonic-gate                                                acid2nam(ue.ue_acids[i]));
520*0Sstevel@tonic-gate                                 }
521*0Sstevel@tonic-gate                                 if (ue.ue_permbits & PERMBITS_ACCTID)
522*0Sstevel@tonic-gate                                         printf("\"acctid\" permbit also allows"
523*0Sstevel@tonic-gate                                                " you to select any valid "
524*0Sstevel@tonic-gate                                                "account name.\n");
525*0Sstevel@tonic-gate                                 printf("\n");
526*0Sstevel@tonic-gate                                 break;
527*0Sstevel@tonic-gate                         default:
528*0Sstevel@tonic-gate                                 if ((valid_acct = nam2acid(acct_name)) == -1)                                        printf("Account id not found for"
529*0Sstevel@tonic-gate                                                " account name \"%s\"\n\n",
530*0Sstevel@tonic-gate                                                acct_name);
531*0Sstevel@tonic-gate                                 break;
532*0Sstevel@tonic-gate                         }
533*0Sstevel@tonic-gate                         /*
534*0Sstevel@tonic-gate                          * If an account was given, search the user's
535*0Sstevel@tonic-gate                          * acids array to verify they can use this account.
536*0Sstevel@tonic-gate                          */
537*0Sstevel@tonic-gate                         if ((valid_acct != -1) &&
538*0Sstevel@tonic-gate                             !(ue.ue_permbits & PERMBITS_ACCTID)) {
539*0Sstevel@tonic-gate                                 for (i = 0; i < MAXVIDS; i++) {
540*0Sstevel@tonic-gate                                         if (ue.ue_acids[i] == -1)
541*0Sstevel@tonic-gate                                                 break;
542*0Sstevel@tonic-gate                                         if (valid_acct == ue.ue_acids[i])
543*0Sstevel@tonic-gate                                                 break;
544*0Sstevel@tonic-gate                                 }
545*0Sstevel@tonic-gate                                 if (i == MAXVIDS ||
546*0Sstevel@tonic-gate                                     ue.ue_acids[i] == -1) {
547*0Sstevel@tonic-gate                                         fprintf(stderr, "Cannot set"
548*0Sstevel@tonic-gate                                                 " account name to "
549*0Sstevel@tonic-gate                                                 "\"%s\", permission "
550*0Sstevel@tonic-gate                                                 "denied\n\n", acct_name);
551*0Sstevel@tonic-gate                                         valid_acct = -1;
552*0Sstevel@tonic-gate                                 }
553*0Sstevel@tonic-gate                         }
554*0Sstevel@tonic-gate                   }
555*0Sstevel@tonic-gate 		} else {
556*0Sstevel@tonic-gate 			/*
557*0Sstevel@tonic-gate 			 * The client isn't connected to a terminal and can't
558*0Sstevel@tonic-gate 			 * respond to an acid prompt.  Use default acid.
559*0Sstevel@tonic-gate 			 */
560*0Sstevel@tonic-gate 			debug("cray_setup: ttyname false case, %.100s", ttyname);
561*0Sstevel@tonic-gate 			valid_acct = ue.ue_acids[0];
562*0Sstevel@tonic-gate 		}
563*0Sstevel@tonic-gate         } else {
564*0Sstevel@tonic-gate                 /*
565*0Sstevel@tonic-gate                  * The user doesn't have the askacid permbit set or
566*0Sstevel@tonic-gate                  * only has one valid account to use.
567*0Sstevel@tonic-gate                  */
568*0Sstevel@tonic-gate                 valid_acct = ue.ue_acids[0];
569*0Sstevel@tonic-gate         }
570*0Sstevel@tonic-gate         if (acctid(0, valid_acct) < 0) {
571*0Sstevel@tonic-gate                 printf ("Bad account id: %d\n", valid_acct);
572*0Sstevel@tonic-gate                 exit(1);
573*0Sstevel@tonic-gate         }
574*0Sstevel@tonic-gate 
575*0Sstevel@tonic-gate /* set up shares and quotas */
576*0Sstevel@tonic-gate /* Now set shares, quotas, limits, including CPU time for the (interactive)
577*0Sstevel@tonic-gate  * job and process, and set up permissions (for chown etc), etc.
578*0Sstevel@tonic-gate  */
579*0Sstevel@tonic-gate 	if (setshares(ue.ue_uid, valid_acct, printf, 0, 0)) {
580*0Sstevel@tonic-gate 		printf("Unable to give %d shares to <%s>(%d/%d)\n", ue.ue_shares, ue.ue_name, ue.ue_uid, valid_acct);
581*0Sstevel@tonic-gate 		exit(1);
582*0Sstevel@tonic-gate         }
583*0Sstevel@tonic-gate 
584*0Sstevel@tonic-gate 	sr = setlimits(username, C_PROC, pid, UDBRC_INTER);
585*0Sstevel@tonic-gate 	if (sr != NULL) {
586*0Sstevel@tonic-gate 		debug("%.200s", sr);
587*0Sstevel@tonic-gate 		exit(1);
588*0Sstevel@tonic-gate 	}
589*0Sstevel@tonic-gate 	sr = setlimits(username, C_JOB, jid, UDBRC_INTER);
590*0Sstevel@tonic-gate 	if (sr != NULL) {
591*0Sstevel@tonic-gate 		debug("%.200s", sr);
592*0Sstevel@tonic-gate 		exit(1);
593*0Sstevel@tonic-gate 	}
594*0Sstevel@tonic-gate 	/*
595*0Sstevel@tonic-gate  	 * Place the service provider information into
596*0Sstevel@tonic-gate 	 * the session table (Unicos) or job table (Unicos/mk).
597*0Sstevel@tonic-gate 	 * There exist double defines for the job/session table in
598*0Sstevel@tonic-gate 	 * unicos/mk (jtab.h) so no need for a compile time switch.
599*0Sstevel@tonic-gate 	 */
600*0Sstevel@tonic-gate 	bzero((char *)&init_info, sizeof(struct servprov));
601*0Sstevel@tonic-gate 	init_info.s_sessinit.si_id  = URM_SPT_LOGIN;
602*0Sstevel@tonic-gate 	init_info.s_sessinit.si_pid = getpid();
603*0Sstevel@tonic-gate 	init_info.s_sessinit.si_sid = jid;
604*0Sstevel@tonic-gate 	init_info.s_routing.seqno = 0;
605*0Sstevel@tonic-gate 	init_info.s_routing.iadrs = 0;
606*0Sstevel@tonic-gate 	sesscntl(0, S_SETSERVPO, (int)&init_info);
607*0Sstevel@tonic-gate 
608*0Sstevel@tonic-gate 	/*
609*0Sstevel@tonic-gate 	 * Set user and controlling tty security attributes.
610*0Sstevel@tonic-gate 	 */
611*0Sstevel@tonic-gate 	if (SecureSys) {
612*0Sstevel@tonic-gate 		if (setusrv(&usrv) == -1) {
613*0Sstevel@tonic-gate 			debug("setusrv() failed, errno = %d",errno);
614*0Sstevel@tonic-gate 			exit(1);
615*0Sstevel@tonic-gate 		}
616*0Sstevel@tonic-gate 	}
617*0Sstevel@tonic-gate 
618*0Sstevel@tonic-gate         return(0);
619*0Sstevel@tonic-gate }
620*0Sstevel@tonic-gate 
621*0Sstevel@tonic-gate /*
622*0Sstevel@tonic-gate  * The rc.* and /etc/sdaemon methods of starting a program on unicos/unicosmk
623*0Sstevel@tonic-gate  * can have pal privileges that sshd can inherit which
624*0Sstevel@tonic-gate  * could allow a user to su to root with out a password.
625*0Sstevel@tonic-gate  * This subroutine clears all privileges.
626*0Sstevel@tonic-gate  */
627*0Sstevel@tonic-gate void
drop_cray_privs()628*0Sstevel@tonic-gate drop_cray_privs()
629*0Sstevel@tonic-gate {
630*0Sstevel@tonic-gate #if defined(_SC_CRAY_PRIV_SU)
631*0Sstevel@tonic-gate 	priv_proc_t*		  privstate;
632*0Sstevel@tonic-gate 	int			  result;
633*0Sstevel@tonic-gate 	extern	    int		  priv_set_proc();
634*0Sstevel@tonic-gate 	extern	    priv_proc_t*  priv_init_proc();
635*0Sstevel@tonic-gate 
636*0Sstevel@tonic-gate 	/*
637*0Sstevel@tonic-gate 	 * If ether of theses two flags are not set
638*0Sstevel@tonic-gate 	 * then don't allow this version of ssh to run.
639*0Sstevel@tonic-gate 	 */
640*0Sstevel@tonic-gate 	if (!sysconf(_SC_CRAY_PRIV_SU))
641*0Sstevel@tonic-gate 		fatal("Not PRIV_SU system.");
642*0Sstevel@tonic-gate 	if (!sysconf(_SC_CRAY_POSIX_PRIV))
643*0Sstevel@tonic-gate 		fatal("Not POSIX_PRIV.");
644*0Sstevel@tonic-gate 
645*0Sstevel@tonic-gate 	debug("Setting MLS labels.");;
646*0Sstevel@tonic-gate 
647*0Sstevel@tonic-gate 	if (sysconf(_SC_CRAY_SECURE_MAC)) {
648*0Sstevel@tonic-gate 		usrv.sv_minlvl = SYSLOW;
649*0Sstevel@tonic-gate 		usrv.sv_actlvl = SYSHIGH;
650*0Sstevel@tonic-gate 		usrv.sv_maxlvl = SYSHIGH;
651*0Sstevel@tonic-gate 	} else {
652*0Sstevel@tonic-gate 		usrv.sv_minlvl = sysv.sy_minlvl;
653*0Sstevel@tonic-gate 		usrv.sv_actlvl = sysv.sy_minlvl;
654*0Sstevel@tonic-gate 		usrv.sv_maxlvl = sysv.sy_maxlvl;
655*0Sstevel@tonic-gate 	}
656*0Sstevel@tonic-gate 	usrv.sv_actcmp = 0;
657*0Sstevel@tonic-gate 	usrv.sv_valcmp = sysv.sy_valcmp;
658*0Sstevel@tonic-gate 
659*0Sstevel@tonic-gate 	usrv.sv_intcat = TFM_SYSTEM;
660*0Sstevel@tonic-gate 	usrv.sv_valcat |= (TFM_SYSTEM | TFM_SYSFILE);
661*0Sstevel@tonic-gate 
662*0Sstevel@tonic-gate 	if (setusrv(&usrv) < 0)
663*0Sstevel@tonic-gate 		fatal("%s(%d): setusrv(): %s", __FILE__, __LINE__,
664*0Sstevel@tonic-gate 		    strerror(errno));
665*0Sstevel@tonic-gate 
666*0Sstevel@tonic-gate 	if ((privstate = priv_init_proc()) != NULL) {
667*0Sstevel@tonic-gate 		result = priv_set_proc(privstate);
668*0Sstevel@tonic-gate 		if (result != 0 )
669*0Sstevel@tonic-gate 			fatal("%s(%d): priv_set_proc(): %s",
670*0Sstevel@tonic-gate 			    __FILE__, __LINE__, strerror(errno));
671*0Sstevel@tonic-gate 		priv_free_proc(privstate);
672*0Sstevel@tonic-gate 	}
673*0Sstevel@tonic-gate 	debug ("Privileges should be cleared...");
674*0Sstevel@tonic-gate #else
675*0Sstevel@tonic-gate 	/* XXX: do this differently */
676*0Sstevel@tonic-gate #	error Cray systems must be run with _SC_CRAY_PRIV_SU on!
677*0Sstevel@tonic-gate #endif
678*0Sstevel@tonic-gate }
679*0Sstevel@tonic-gate 
680*0Sstevel@tonic-gate 
681*0Sstevel@tonic-gate /*
682*0Sstevel@tonic-gate  *  Retain utmp/wtmp information - used by cray accounting.
683*0Sstevel@tonic-gate  */
684*0Sstevel@tonic-gate void
cray_retain_utmp(struct utmp * ut,int pid)685*0Sstevel@tonic-gate cray_retain_utmp(struct utmp *ut, int pid)
686*0Sstevel@tonic-gate {
687*0Sstevel@tonic-gate 	int fd;
688*0Sstevel@tonic-gate 	struct utmp utmp;
689*0Sstevel@tonic-gate 
690*0Sstevel@tonic-gate 	if ((fd = open(UTMP_FILE, O_RDONLY)) != -1) {
691*0Sstevel@tonic-gate 		while (read(fd, (char *)&utmp, sizeof(utmp)) == sizeof(utmp)) {
692*0Sstevel@tonic-gate 			if (pid == utmp.ut_pid) {
693*0Sstevel@tonic-gate 				ut->ut_jid = utmp.ut_jid;
694*0Sstevel@tonic-gate 				strncpy(ut->ut_tpath, utmp.ut_tpath, sizeof(utmp.ut_tpath));
695*0Sstevel@tonic-gate 				strncpy(ut->ut_host, utmp.ut_host, sizeof(utmp.ut_host));
696*0Sstevel@tonic-gate 				strncpy(ut->ut_name, utmp.ut_name, sizeof(utmp.ut_name));
697*0Sstevel@tonic-gate 				break;
698*0Sstevel@tonic-gate 			}
699*0Sstevel@tonic-gate 		}
700*0Sstevel@tonic-gate 		close(fd);
701*0Sstevel@tonic-gate 	}
702*0Sstevel@tonic-gate 	else
703*0Sstevel@tonic-gate 	fatal("Unable to open utmp file");
704*0Sstevel@tonic-gate }
705*0Sstevel@tonic-gate 
706*0Sstevel@tonic-gate /*
707*0Sstevel@tonic-gate  * tmpdir support.
708*0Sstevel@tonic-gate  */
709*0Sstevel@tonic-gate 
710*0Sstevel@tonic-gate /*
711*0Sstevel@tonic-gate  * find and delete jobs tmpdir.
712*0Sstevel@tonic-gate  */
713*0Sstevel@tonic-gate void
cray_delete_tmpdir(char * login,int jid,uid_t uid)714*0Sstevel@tonic-gate cray_delete_tmpdir(char *login, int jid, uid_t uid)
715*0Sstevel@tonic-gate {
716*0Sstevel@tonic-gate 	int child;
717*0Sstevel@tonic-gate 	static char jtmp[TPATHSIZ];
718*0Sstevel@tonic-gate 	struct stat statbuf;
719*0Sstevel@tonic-gate 	int c;
720*0Sstevel@tonic-gate 	int wstat;
721*0Sstevel@tonic-gate 
722*0Sstevel@tonic-gate 	for (c = 'a'; c <= 'z'; c++) {
723*0Sstevel@tonic-gate 		snprintf(jtmp, TPATHSIZ, "%s/jtmp.%06d%c", JTMPDIR, jid, c);
724*0Sstevel@tonic-gate 		if (stat(jtmp, &statbuf) == 0 && statbuf.st_uid == uid)
725*0Sstevel@tonic-gate 			break;
726*0Sstevel@tonic-gate 	}
727*0Sstevel@tonic-gate 
728*0Sstevel@tonic-gate 	if (c > 'z')
729*0Sstevel@tonic-gate 		return;
730*0Sstevel@tonic-gate 
731*0Sstevel@tonic-gate 	if ((child = fork()) == 0) {
732*0Sstevel@tonic-gate 		execl(CLEANTMPCMD, CLEANTMPCMD, login, jtmp, (char *)NULL);
733*0Sstevel@tonic-gate 		fatal("cray_delete_tmpdir: execl of CLEANTMPCMD failed");
734*0Sstevel@tonic-gate 	}
735*0Sstevel@tonic-gate 
736*0Sstevel@tonic-gate 	while (waitpid(child, &wstat, 0) == -1 && errno == EINTR)
737*0Sstevel@tonic-gate 		;
738*0Sstevel@tonic-gate }
739*0Sstevel@tonic-gate 
740*0Sstevel@tonic-gate /*
741*0Sstevel@tonic-gate  * Remove tmpdir on job termination.
742*0Sstevel@tonic-gate  */
743*0Sstevel@tonic-gate void
cray_job_termination_handler(int sig)744*0Sstevel@tonic-gate cray_job_termination_handler(int sig)
745*0Sstevel@tonic-gate {
746*0Sstevel@tonic-gate 	int jid;
747*0Sstevel@tonic-gate 	char *login = NULL;
748*0Sstevel@tonic-gate 	struct jtab jtab;
749*0Sstevel@tonic-gate 
750*0Sstevel@tonic-gate 	debug("received signal %d",sig);
751*0Sstevel@tonic-gate 
752*0Sstevel@tonic-gate 	if ((jid = waitjob(&jtab)) == -1 ||
753*0Sstevel@tonic-gate 	    (login = uid2nam(jtab.j_uid)) == NULL)
754*0Sstevel@tonic-gate 		return;
755*0Sstevel@tonic-gate 
756*0Sstevel@tonic-gate 	cray_delete_tmpdir(login, jid, jtab.j_uid);
757*0Sstevel@tonic-gate }
758*0Sstevel@tonic-gate 
759*0Sstevel@tonic-gate /*
760*0Sstevel@tonic-gate  * Set job id and create tmpdir directory.
761*0Sstevel@tonic-gate  */
762*0Sstevel@tonic-gate void
cray_init_job(struct passwd * pw)763*0Sstevel@tonic-gate cray_init_job(struct passwd *pw)
764*0Sstevel@tonic-gate {
765*0Sstevel@tonic-gate 	int jid;
766*0Sstevel@tonic-gate 	int c;
767*0Sstevel@tonic-gate 
768*0Sstevel@tonic-gate 	jid = setjob(pw->pw_uid, WJSIGNAL);
769*0Sstevel@tonic-gate 	if (jid < 0)
770*0Sstevel@tonic-gate 		fatal("System call setjob failure");
771*0Sstevel@tonic-gate 
772*0Sstevel@tonic-gate 	for (c = 'a'; c <= 'z'; c++) {
773*0Sstevel@tonic-gate 		snprintf(cray_tmpdir, TPATHSIZ, "%s/jtmp.%06d%c", JTMPDIR, jid, c);
774*0Sstevel@tonic-gate 		if (mkdir(cray_tmpdir, JTMPMODE) != 0)
775*0Sstevel@tonic-gate 			continue;
776*0Sstevel@tonic-gate 		if (chown(cray_tmpdir,	pw->pw_uid, pw->pw_gid) != 0) {
777*0Sstevel@tonic-gate 			rmdir(cray_tmpdir);
778*0Sstevel@tonic-gate 			continue;
779*0Sstevel@tonic-gate 		}
780*0Sstevel@tonic-gate 		break;
781*0Sstevel@tonic-gate 	}
782*0Sstevel@tonic-gate 
783*0Sstevel@tonic-gate 	if (c > 'z')
784*0Sstevel@tonic-gate 		cray_tmpdir[0] = '\0';
785*0Sstevel@tonic-gate }
786*0Sstevel@tonic-gate 
787*0Sstevel@tonic-gate void
cray_set_tmpdir(struct utmp * ut)788*0Sstevel@tonic-gate cray_set_tmpdir(struct utmp *ut)
789*0Sstevel@tonic-gate {
790*0Sstevel@tonic-gate 	int jid;
791*0Sstevel@tonic-gate 	struct jtab jbuf;
792*0Sstevel@tonic-gate 
793*0Sstevel@tonic-gate 	if ((jid = getjtab(&jbuf)) < 0)
794*0Sstevel@tonic-gate 		return;
795*0Sstevel@tonic-gate 
796*0Sstevel@tonic-gate 	/*
797*0Sstevel@tonic-gate 	 * Set jid and tmpdir in utmp record.
798*0Sstevel@tonic-gate 	 */
799*0Sstevel@tonic-gate 	ut->ut_jid = jid;
800*0Sstevel@tonic-gate 	strncpy(ut->ut_tpath, cray_tmpdir, TPATHSIZ);
801*0Sstevel@tonic-gate }
802*0Sstevel@tonic-gate #endif
803