Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 13 Nov 1999 05:09:42 -0500 (EST)
From:      danh@wzrd.com
To:        FreeBSD-gnats-submit@freebsd.org
Subject:   ports/14859: OpenSSH and login.conf
Message-ID:  <19991113100942.924765D01E@mail.wzrd.com>

next in thread | raw e-mail | index | archive | help

>Number:         14859
>Category:       ports
>Synopsis:       OpenSSH has no support for the login class capability database.
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-ports
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Sat Nov 13 02:10:01 PST 1999
>Closed-Date:
>Last-Modified:
>Originator:     Dan Harnett
>Release:        FreeBSD 3.3-STABLE i386
>Organization:
Wizard Communication Systems
>Environment:

	OpenSSH 1.2 port as of Nov. 8th. under FreeBSD 3.3-STABLE.

>Description:

	There currently is no support in this port for the login class
	capability database (a.k.a. /etc/login.conf).  Also there is no
	check done for expired passwords or accounts.

	I've added some support for it, but it could be more.  It covers
	some of the basics.  Expired passwords and accounts are treated
	as bad logins with this patch. 

>How-To-Repeat:

	Install the OpenSSH port.

>Fix:
	
diff -ur sshd.c.orig sshd.c
--- sshd.c.orig	Sat Nov 13 01:03:28 1999
+++ sshd.c	Sat Nov 13 04:39:44 1999
@@ -39,6 +39,10 @@
 int deny_severity = LOG_WARNING;
 #endif /* LIBWRAP */
 
+#include <login_cap.h>
+#define MOTD		"/etc/motd"
+#define NOLOGIN		"/var/run/nologin"
+
 #ifndef O_NOCTTY
 #define O_NOCTTY	0
 #endif
@@ -923,6 +927,7 @@
 allowed_user(struct passwd *pw)
 {
   struct group *grp;
+  struct timeval tv;
   int i;
 
   /* Shouldn't be called if pw is NULL, but better safe than sorry... */
@@ -986,6 +991,17 @@
         }
     }
 
+  if (pw->pw_change || pw->pw_expire) 
+    {
+      gettimeofday(&tv, NULL);
+
+      if ((pw->pw_change >= tv.tv_sec) 
+	   || pw->pw_expire >= tv.tv_sec)
+	{
+	  return 0;
+	}
+    }
+
   /* We found no reason not to let this user try to log on... */
   return 1;
 }
@@ -1070,6 +1086,9 @@
   pwcopy.pw_gid = pw->pw_gid;
   pwcopy.pw_dir = xstrdup(pw->pw_dir);
   pwcopy.pw_shell = xstrdup(pw->pw_shell);
+  pwcopy.pw_class = xstrdup(pw->pw_class);
+  pwcopy.pw_change = pw->pw_change;
+  pwcopy.pw_expire = pw->pw_expire;
   pw = &pwcopy;
 
   /* If we are not running as root, the user must have the same uid as the
@@ -1398,7 +1417,7 @@
   gid_t tty_gid;
   mode_t tty_mode;
   int n_bytes;
-  
+
   /* Cancel the alarm we set to limit the time taken for authentication. */
   alarm(0);
 
@@ -1797,6 +1816,8 @@
   struct sockaddr_in from;
   int fromlen;
   struct pty_cleanup_context cleanup_context;
+  char *motd;
+  login_cap_t *lc;
 
   /* Get remote host name. */
   hostname = get_canonical_hostname();
@@ -1856,10 +1877,17 @@
       record_login(pid, ttyname, pw->pw_name, pw->pw_uid, hostname, 
 		   &from);
 
+      if ((lc = login_getpwclass(pw)) == NULL)
+	{
+	  lc = login_getclassbyname(NULL, pw);
+	}
+
       /* Check if .hushlogin exists. */
       snprintf(line, sizeof line, "%.200s/.hushlogin", pw->pw_dir);
       quiet_login = stat(line, &st) >= 0;
-      
+
+      quiet_login = login_getcapbool(lc, "hushlogin", quiet_login);
+
       /* If the user has logged in before, display the time of last login. 
          However, don't display anything extra if a command has been 
 	 specified (so that ssh can be used to execute commands on a remote
@@ -1887,7 +1915,9 @@
           !options.use_login)
 	{
 	  /* Print /etc/motd if it exists. */
-	  f = fopen("/etc/motd", "r");
+	  motd = login_getcapstr(lc, "welcome", MOTD, MOTD);
+	  f = fopen(motd, "r");
+
 	  if (f)
 	    {
 	      while (fgets(line, sizeof(line), f))
@@ -1896,6 +1926,8 @@
 	    }
 	}
 
+      login_close(lc);
+
       /* Do common processing for the child, such as execing the command. */
       do_child(command, pw, term, display, auth_proto, auth_data, ttyname);
       /*NOTREACHED*/
@@ -2047,21 +2079,44 @@
   extern char **environ;
   struct stat st;
   char *argv[10];
+  login_cap_t *lc;
+  char *nologin;
 
-  /* Check /etc/nologin. */
-  f = fopen("/etc/nologin", "r");
-  if (f)
-    { /* /etc/nologin exists.  Print its contents and exit. */
-      while (fgets(buf, sizeof(buf), f))
-	fputs(buf, stderr);
-      fclose(f);
-      if (pw->pw_uid != 0)
-	exit(254);
+  if ((lc = login_getpwclass(pw)) == NULL)
+    {
+      lc = login_getclassbyname(NULL, pw);
+    }
+
+  /* Check for nologin file. */
+  if ( !login_getcapbool(lc, "ignorenologin", 0) )
+    {
+    nologin = login_getcapstr(lc, "nologin", NOLOGIN, NOLOGIN);
+    f = fopen(nologin, "r");
+    if (f)
+      { /* If nologin file exists.  Print its contents and exit. */
+	while (fgets(buf, sizeof(buf), f))
+	  fputs(buf, stderr);
+	fclose(f);
+	if (pw->pw_uid != 0)
+	  exit(254);
+      }
     }
 
   /* Set login name in the kernel. */
   if (setlogin(pw->pw_name) < 0)
     error("setlogin failed: %s", strerror(errno));
+
+  /* Set resource limits, priority, and umask.  Everything else
+     seems to be set elsewhere (login, uid, gid, path, environment). */
+  if (setusercontext(lc, pw, pw->pw_uid, 
+	LOGIN_SETRESOURCES | LOGIN_SETPRIORITY | LOGIN_SETUMASK) == -1) 
+    {
+      log("setusercontext FAILED: name='%s', class='%s', error: %s", 
+	pw->pw_name, pw->pw_class, strerror(errno));
+      exit(254);
+    }
+
+  login_close(lc);
 
   /* Set uid, gid, and groups. */
   /* Login(1) does this as well, and it needs uid 0 for the "-h" switch,

>Release-Note:
>Audit-Trail:
>Unformatted:


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-ports" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?19991113100942.924765D01E>