aboutsummaryrefslogtreecommitdiff
path: root/crypto/kerberosIV/appl/bsd/login.c
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/kerberosIV/appl/bsd/login.c')
-rw-r--r--crypto/kerberosIV/appl/bsd/login.c266
1 files changed, 191 insertions, 75 deletions
diff --git a/crypto/kerberosIV/appl/bsd/login.c b/crypto/kerberosIV/appl/bsd/login.c
index c436f8db98bb..702c5ff15776 100644
--- a/crypto/kerberosIV/appl/bsd/login.c
+++ b/crypto/kerberosIV/appl/bsd/login.c
@@ -38,10 +38,18 @@
*/
#include "bsd_locl.h"
+#ifdef HAVE_CAPABILITY_H
+#include <capability.h>
+#endif
+#ifdef HAVE_SYS_CAPABILITY_H
+#include <sys/capability.h>
+#endif
-RCSID("$Id: login.c,v 1.104 1997/05/20 20:35:06 assar Exp $");
+RCSID("$Id: login.c,v 1.120.2.2 1999/09/02 08:55:26 joda Exp $");
+#ifdef OTP
#include <otp.h>
+#endif
#include "sysv_default.h"
#ifdef SYSV_SHADOW
@@ -93,22 +101,20 @@ static char rusername[100], lusername[100];
static int
change_passwd(struct passwd *who)
{
- int status;
- int pid;
- int wpid;
+ int status;
+ pid_t pid;
- switch (pid = fork()) {
- case -1:
- warn("fork /bin/passwd");
- sleepexit(1);
- case 0:
- execlp("/bin/passwd", "passwd", who->pw_name, (char *) 0);
- _exit(1);
- default:
- while ((wpid = wait(&status)) != -1 && wpid != pid)
- /* void */ ;
- return (status);
- }
+ switch (pid = fork()) {
+ case -1:
+ warn("fork /bin/passwd");
+ sleepexit(1);
+ case 0:
+ execlp("/bin/passwd", "passwd", who->pw_name, (char *) 0);
+ _exit(1);
+ default:
+ waitpid(pid, &status, 0);
+ return (status);
+ }
}
#ifndef NO_MOTD /* message of the day stuff */
@@ -177,7 +183,9 @@ main(int argc, char **argv)
char localhost[MaxHostNameLen];
char full_hostname[MaxHostNameLen];
int auth_level = AUTH_NONE;
+#ifdef OTP
OtpContext otp_ctx;
+#endif
int mask = 022; /* Default umask (set below) */
int maxtrys = 5; /* Default number of allowed failed logins */
@@ -210,7 +218,7 @@ main(int argc, char **argv)
*full_hostname = '\0';
domain = NULL;
- if (k_gethostname(localhost, sizeof(localhost)) < 0)
+ if (gethostname(localhost, sizeof(localhost)) < 0)
syslog(LOG_ERR, "couldn't get local hostname: %m");
else
domain = strchr(localhost, '.');
@@ -222,8 +230,10 @@ main(int argc, char **argv)
case 'a':
if (strcmp (optarg, "none") == 0)
auth_level = AUTH_NONE;
+#ifdef OTP
else if (strcmp (optarg, "otp") == 0)
auth_level = AUTH_OTP;
+#endif
else
warnx ("bad value for -a: %s", optarg);
break;
@@ -240,7 +250,9 @@ main(int argc, char **argv)
if (uid)
errx(1, "-h option: %s", strerror(EPERM));
hflag = 1;
- strncpy(full_hostname, optarg, sizeof(full_hostname)-1);
+ strcpy_truncate(full_hostname,
+ optarg,
+ sizeof(full_hostname));
if (domain && (p = strchr(optarg, '.')) &&
strcasecmp(p, domain) == 0)
*p = 0;
@@ -263,7 +275,9 @@ main(int argc, char **argv)
exit(1);
}
rflag = 1;
- strncpy(full_hostname, optarg, sizeof(full_hostname)-1);
+ strcpy_truncate(full_hostname,
+ optarg,
+ sizeof(full_hostname));
if (domain && (p = strchr(optarg, '.')) &&
strcasecmp(p, domain) == 0)
*p = 0;
@@ -275,8 +289,11 @@ main(int argc, char **argv)
if (!uid)
syslog(LOG_ERR, "invalid flag %c", ch);
fprintf(stderr,
- "usage: login [-fp] [-a otp]"
- "[-h hostname | -r hostname] [username]\n");
+ "usage: login [-fp]"
+#ifdef OTP
+ " [-a otp]"
+#endif
+ " [-h hostname | -r hostname] [username]\n");
exit(1);
}
argc -= optind;
@@ -366,7 +383,7 @@ main(int argc, char **argv)
badlogin(tbuf);
failures = 0;
}
- strcpy(tbuf, username);
+ strcpy_truncate(tbuf, username, sizeof(tbuf));
pwd = paranoid_getpwnam (username);
@@ -394,11 +411,14 @@ main(int argc, char **argv)
setpriority(PRIO_PROCESS, 0, -4);
+#ifdef OTP
if (otp_challenge (&otp_ctx, username,
ss, sizeof(ss)) == 0)
snprintf (prompt, sizeof(prompt), "%s's %s Password: ",
username, ss);
- else {
+ else
+#endif
+ {
if (auth_level == AUTH_NONE)
snprintf(prompt, sizeof(prompt), "%s's Password: ",
username);
@@ -406,9 +426,11 @@ main(int argc, char **argv)
char *s;
rval = 1;
+#ifdef OTP
s = otp_error(&otp_ctx);
if(s)
printf ("OTP: %s\n", s);
+#endif
continue;
}
}
@@ -419,9 +441,12 @@ main(int argc, char **argv)
/* Verify it somehow */
+#ifdef OTP
if (otp_verify_user (&otp_ctx, passwd) == 0)
rval = 0;
- else if (pwd == NULL)
+ else
+#endif
+ if (pwd == NULL)
;
else if (auth_level == AUTH_NONE) {
uid_t pwd_uid = pwd->pw_uid;
@@ -445,8 +470,10 @@ main(int argc, char **argv)
char *s;
rval = 1;
+#ifdef OTP
if ((s = otp_error(&otp_ctx)))
printf ("OTP: %s\n", s);
+#endif
}
memset (passwd, 0, sizeof(passwd));
@@ -507,28 +534,45 @@ main(int argc, char **argv)
struct udb *udb;
long t;
const long maxcpu = 46116860184; /* some random constant */
+
+ if(setjob(pwd->pw_uid, 0) < 0)
+ warn("setjob");
+
udb = getudbnam(pwd->pw_name);
- if(udb == UDB_NULL){
- warnx("Failed to get UDB entry.");
- exit(1);
- }
+ if(udb == UDB_NULL)
+ errx(1, "Failed to get UDB entry.");
+
+ /* per process cpu limit */
t = udb->ue_pcpulim[UDBRC_INTER];
if(t == 0 || t > maxcpu)
t = CPUUNLIM;
else
- t *= 100 * CLOCKS_PER_SEC;
+ t *= CLK_TCK;
if(limit(C_PROC, 0, L_CPU, t) < 0)
- warn("limit C_PROC");
+ warn("limit process cpu");
+ /* per process memory limit */
+ if(limit(C_PROC, 0, L_MEM, udb->ue_pmemlim[UDBRC_INTER]) < 0)
+ warn("limit process memory");
+
+ /* per job cpu limit */
t = udb->ue_jcpulim[UDBRC_INTER];
if(t == 0 || t > maxcpu)
t = CPUUNLIM;
else
- t *= 100 * CLOCKS_PER_SEC;
+ t *= CLK_TCK;
+
+ if(limit(C_JOB, 0, L_CPU, t) < 0)
+ warn("limit job cpu");
+
+ /* per job processor limit */
+ if(limit(C_JOB, 0, L_CPROC, udb->ue_jproclim[UDBRC_INTER]) < 0)
+ warn("limit job processors");
- if(limit(C_JOBPROCS, 0, L_CPU, t) < 0)
- warn("limit C_JOBPROCS");
+ /* per job memory limit */
+ if(limit(C_JOB, 0, L_MEM, udb->ue_jmemlim[UDBRC_INTER]) < 0)
+ warn("limit job memory");
nice(udb->ue_nice[UDBRC_INTER]);
}
@@ -590,9 +634,11 @@ main(int argc, char **argv)
*/
login_fbtab(tty, pwd->pw_uid, pwd->pw_gid);
- chown(ttyn, pwd->pw_uid,
- (gr = getgrnam(TTYGRPNAME)) ? gr->gr_gid : pwd->pw_gid);
- chmod(ttyn, S_IRUSR | S_IWUSR | S_IWGRP);
+ if (chown(ttyn, pwd->pw_uid,
+ (gr = getgrnam(TTYGRPNAME)) ? gr->gr_gid : pwd->pw_gid) < 0)
+ err(1, "chown tty failed");
+ if (chmod(ttyn, S_IRUSR | S_IWUSR | S_IWGRP) < 0)
+ err(1, "chmod tty failed");
setgid(pwd->pw_gid);
initgroups(username, pwd->pw_gid);
@@ -608,7 +654,7 @@ main(int argc, char **argv)
* that LD_* and IFS are never preserved.
*/
if (term[0] == '\0')
- strncpy(term, stypeof(tty), sizeof(term));
+ strcpy_truncate(term, stypeof(tty), sizeof(term));
/* set up a somewhat censored environment. */
sysv_newenv(argc, argv, pwd, term, pflag);
#ifdef KERBEROS
@@ -620,12 +666,13 @@ main(int argc, char **argv)
syslog(LOG_INFO, "DIALUP %s, %s", tty, pwd->pw_name);
/* If fflag is on, assume caller/authenticator has logged root login. */
- if (rootlogin && fflag == 0)
+ if (rootlogin && fflag == 0) {
if (hostname)
syslog(LOG_NOTICE, "ROOT LOGIN (%s) ON %s FROM %s",
username, tty, hostname);
else
syslog(LOG_NOTICE, "ROOT LOGIN (%s) ON %s", username, tty);
+ }
#ifdef KERBEROS
if (!quietlog && notickets == 1 && !noticketsdontcomplain)
@@ -668,7 +715,7 @@ main(int argc, char **argv)
#endif /* NO_MOTD */
#ifdef LOGIN_ACCESS
- if (login_access(pwd->pw_name, hostname ? full_hostname : tty) == 0) {
+ if (login_access(pwd, hostname ? full_hostname : tty) == 0) {
printf("Permission denied\n");
if (hostname)
syslog(LOG_NOTICE, "%s LOGIN REFUSED FROM %s",
@@ -683,11 +730,12 @@ main(int argc, char **argv)
signal(SIGALRM, SIG_DFL);
signal(SIGQUIT, SIG_DFL);
signal(SIGINT, SIG_DFL);
+#ifdef SIGTSTP
signal(SIGTSTP, SIG_IGN);
+#endif
- tbuf[0] = '-';
- strcpy(tbuf + 1, (p = strrchr(pwd->pw_shell, '/')) ?
- p + 1 : pwd->pw_shell);
+ p = strrchr(pwd->pw_shell, '/');
+ snprintf (tbuf, sizeof(tbuf), "-%s", p ? p + 1 : pwd->pw_shell);
#ifdef HAVE_SETLOGIN
if (setlogin(pwd->pw_name) < 0)
@@ -703,6 +751,35 @@ main(int argc, char **argv)
spwd = getspnam (username);
endspent ();
#endif
+ /* perhaps work some magic */
+ if(do_osfc2_magic(pwd->pw_uid))
+ sleepexit(1);
+#if defined(HAVE_SGI_GETCAPABILITYBYNAME) && defined(HAVE_CAP_SET_PROC)
+ /* XXX SGI capability hack IRIX 6.x (x >= 0?) has something
+ called capabilities, that allow you to give away
+ permissions (such as chown) to specific processes. From 6.5
+ this is default on, and the default capability set seems to
+ not always be the empty set. The problem is that the
+ runtime linker refuses to do just about anything if the
+ process has *any* capabilities set, so we have to remove
+ them here (unless otherwise instructed by /etc/capability).
+ In IRIX < 6.5, these functions was called sgi_cap_setproc,
+ etc, but we ignore this fact (it works anyway). */
+ {
+ struct user_cap *ucap = sgi_getcapabilitybyname(pwd->pw_name);
+ cap_t cap;
+ if(ucap == NULL)
+ cap = cap_from_text("all=");
+ else
+ cap = cap_from_text(ucap->ca_default);
+ if(cap == NULL)
+ err(1, "cap_from_text");
+ if(cap_set_proc(cap) < 0)
+ err(1, "cap_set_proc");
+ cap_free(cap);
+ free(ucap);
+ }
+#endif
/* Discard permissions last so can't get killed and drop core. */
{
int uid = rootlogin ? 0 : pwd->pw_uid;
@@ -742,10 +819,18 @@ main(int argc, char **argv)
if (k_hasafs()) {
char cell[64];
+#ifdef _AIX
+ /* XXX this is a fix for a bug in AFS for AIX 4.3, w/o
+ this hack the kernel crashes on the following
+ pioctl... */
+ char *pw_dir = strdup(pwd->pw_dir);
+#else
+ char *pw_dir = pwd->pw_dir;
+#endif
k_setpag();
- if(k_afs_cell_of_file(pwd->pw_dir, cell, sizeof(cell)) == 0)
- k_afsklog(cell, 0);
- k_afsklog(0, 0);
+ if(k_afs_cell_of_file(pw_dir, cell, sizeof(cell)) == 0)
+ krb_afslog(cell, 0);
+ krb_afslog(0, 0);
}
execlp(pwd->pw_shell, tbuf, 0);
@@ -768,46 +853,77 @@ main(int argc, char **argv)
static void
getloginname(int prompt)
{
- int ch;
- char *p;
- static char nbuf[NBUFSIZ];
+ int ch;
+ char *p;
+ static char nbuf[NBUFSIZ];
- for (;;) {
- if (prompt)
- if (ttyprompt && *ttyprompt)
- printf("%s", ttyprompt);
- else
- printf("login: ");
- prompt = 1;
- for (p = nbuf; (ch = getchar()) != '\n'; ) {
- if (ch == EOF) {
- badlogin(username);
- exit(0);
- }
- if (p < nbuf + (NBUFSIZ - 1))
- *p++ = ch;
- }
- if (p > nbuf)
- if (nbuf[0] == '-')
- warnx("login names may not start with '-'.");
- else {
- *p = '\0';
- username = nbuf;
- break;
- }
+ for (;;) {
+ if (prompt) {
+ if (ttyprompt && *ttyprompt)
+ printf("%s", ttyprompt);
+ else
+ printf("login: ");
+ }
+ prompt = 1;
+ for (p = nbuf; (ch = getchar()) != '\n'; ) {
+ if (ch == EOF) {
+ badlogin(username);
+ exit(0);
+ }
+ if (p < nbuf + (NBUFSIZ - 1))
+ *p++ = ch;
}
+ if (p > nbuf) {
+ if (nbuf[0] == '-')
+ warnx("login names may not start with '-'.");
+ else {
+ *p = '\0';
+ username = nbuf;
+ break;
+ }
+ }
+ }
+}
+
+static int
+find_in_etc_securetty (char *ttyn)
+{
+ FILE *f;
+ char buf[128];
+ int ret = 0;
+
+ f = fopen (_PATH_ETC_SECURETTY, "r");
+ if (f == NULL)
+ return 0;
+ while (fgets(buf, sizeof(buf), f) != NULL) {
+ if(buf[strlen(buf) - 1] == '\n')
+ buf[strlen(buf) - 1] = '\0';
+ if (strcmp (buf, ttyn) == 0) {
+ ret = 1;
+ break;
+ }
+ }
+ fclose(f);
+ return ret;
}
static int
rootterm(char *ttyn)
{
-#ifndef HAVE_TTYENT_H
- return (default_console == 0 || strcmp(default_console, ttyname(0)) == 0);
-#else
+#ifdef HAVE_TTYENT_H
+ {
struct ttyent *t;
- return ((t = getttynam(ttyn)) && t->ty_status & TTY_SECURE);
+ t = getttynam (ttyn);
+ if (t && t->ty_status & TTY_SECURE)
+ return 1;
+ }
#endif
+ if (find_in_etc_securetty(ttyn))
+ return 1;
+ if (default_console == 0 || strcmp(default_console, ttyn) == 0)
+ return 1;
+ return 0;
}
static RETSIGTYPE