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