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