[2761] in Kerberos-V5-bugs

home help back first fref pref prev next nref lref last post

krb5-appl/448: SunOS login not setting /dev ownership

daemon@ATHENA.MIT.EDU (vwelch@ncsa.uiuc.edu)
Wed Jul 23 17:35:24 1997

Resent-From: gnats@rt-11.MIT.EDU (GNATS Management)
Resent-To: krb5-unassigned@RT-11.MIT.EDU
Resent-Reply-To: krb5-bugs@MIT.EDU, vwelch@ncsa.uiuc.edu
Date: Wed, 23 Jul 1997 16:30:10 -0500
From: vwelch@ncsa.uiuc.edu
Reply-To: vwelch@ncsa.uiuc.edu
To: krb5-bugs@MIT.EDU
Cc: vwelch@ncsa.uiuc.edu


>Number:         448
>Category:       krb5-appl
>Synopsis:       Login under SunOS doesn't set ownership of devices
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    krb5-unassigned
>State:          open
>Class:          sw-bug
>Submitter-Id:   unknown
>Arrival-Date:   Wed Jul 23 17:31:01 EDT 1997
>Last-Modified:
>Originator:     Von Welch
>Organization:

------------------------------------------------------------------------
Von Welch          Senior Network Engineer          vwelch@ncsa.uiuc.edu
          National Center for Supercomputing Applications
------------------------------------------------------------------------
>Release:        1.0pl1
>Environment:
System: SunOS computer 5.4 Generic_101945-29 sun4m sparc


>Description:

login.krb5 doesn't parse /etc/fbtab (under SunOS 4.x) or /etc/logindevperm
(under Solaris) and set the ownership of specified files (e.g. /dev/mouse,
/dev/kbd, /dev/fb) to the user logging in.

This results in X failing when a user logs into the console and tries to
start it.

>How-To-Repeat:

Replace /bin/login with /bin/login.krb5, log in on the console and try to
start X.

>Fix:

Apply the following patch, and run util/reconf. login.krb5 has to be linked
with -lc before -lucb or readdir() chops off the first two characters
of all the filenames.

diff -r -c src.orig/appl/bsd/configure.in src/appl/bsd/configure.in
*** src.orig/appl/bsd/configure.in	Fri Jun 20 14:54:57 1997
--- src/appl/bsd/configure.in	Wed Jul 23 10:06:45 1997
***************
*** 10,16 ****
  	LOGINLIBS="$LOGINLIBS -L$with_afs/lib -L$with_afs/lib/afs -lauth -lsys -lrx -llwp -lsys"
  	case $krb5_cv_host in
  	*-*-solaris*)
! 		LOGINLIBS="$LOGINLIBS -L/usr/ucblib -lucb -R/usr/ucblib"
  		;;
  	*-*-hpux*)
  		LOGINLIBS="$LOGINLIBS -lBSD"
--- 10,16 ----
  	LOGINLIBS="$LOGINLIBS -L$with_afs/lib -L$with_afs/lib/afs -lauth -lsys -lrx -llwp -lsys"
  	case $krb5_cv_host in
  	*-*-solaris*)
! 		LOGINLIBS="$LOGINLIBS -lc -L/usr/ucblib -lucb -R/usr/ucblib"
  		;;
  	*-*-hpux*)
  		LOGINLIBS="$LOGINLIBS -lBSD"
diff -r -c src.orig/appl/bsd/login.c src/appl/bsd/login.c
*** src.orig/appl/bsd/login.c	Thu May  1 11:07:51 1997
--- src/appl/bsd/login.c	Wed Jul 23 10:06:30 1997
***************
*** 134,139 ****
--- 134,146 ----
  #define NO_INIT_CC
  #endif
  
+ #ifdef sun
+ /* Under solaris: gcc defines __svr4__, cc doesn't define bsd */
+ #if defined(__svr4__) || !defined(bsd)
+ #define solaris
+ #endif /* __svr4 || !bsd */
+ #endif /* sun */
+ 
  #include <errno.h>
  #ifdef HAVE_TTYENT_H
  #include <ttyent.h>
***************
*** 251,256 ****
--- 258,267 ----
  #define TAB3 0
  #endif
  
+ #ifdef solaris
+ #include <dirent.h>
+ #endif /* solaris */
+ 
  #define	TTYGRPNAME	"tty"		/* name of group to own ttys */
  
  #define	MOTDFILE	"/etc/motd"
***************
*** 1665,1670 ****
--- 1676,1686 ----
  		(void)ioctl(0, TIOCSWINSZ, (char *)&win);
  	}
  
+ #if defined(sun)
+ 	/* Set owner/group/permissions of framebuffer devices */
+ 	(void) set_fb_attrs(ttyn, pwd->pw_uid, pwd->pw_gid);
+ #endif
+ 
  	(void)chown(ttyn, pwd->pw_uid,
  	    (gr = getgrnam(TTYGRPNAME)) ? gr->gr_gid : pwd->pw_gid);
  
***************
*** 2225,2230 ****
--- 2241,2249 ----
  	register int ch;
  	register char *p;
  	static char nbuf[UT_NAMESIZE + 1];
+ #ifdef solaris
+ 	char *ttyprompt = NULL;
+ #endif
  
  #ifdef sgi
  	/*
***************
*** 2235,2240 ****
--- 2254,2268 ----
  	putchar('\0');
  #endif
  	for (;;) {
+ #ifdef solaris
+ 		/*
+ 		 * getty prints 'login:' for us, so we want to avoid printing
+ 		 * it again. getty also sets the environment variable TTYPROMPT
+ 		 * so if it is present, don't print the login prompt.
+ 		 */
+ 		ttyprompt = getenv("TTYPROMPT");
+ 		if ((ttyprompt == NULL) || (*ttyprompt == '\0'))
+ #endif /* solaris */
  		printf("login: ");
  		for (p = nbuf; (ch = getchar()) != '\n'; ) {
  			if (ch == EOF)
***************
*** 2657,2659 ****
--- 2685,2819 ----
      enduserdb();
  }
  #endif
+ 
+ #if defined(sun)
+ /*
+  * set_fb_attrs -- change owner/group/permissions of framebuffers
+  *		   listed in /etc/fbtab.
+  *
+  * Note:
+  * Exiting from set_fb_attrs upon error is not advisable
+  * since it would disable logins on console devices.
+  *
+  * File format:
+  * console mode device_name[:device_name ...]
+  * # begins a comment and may appear anywhere on a line.
+  *
+  * Example:
+  * /dev/console 0660 /dev/fb:/dev/cgtwo0:/dev/bwtwo0
+  * /dev/console 0660 /dev/gpone0a:/dev/gpone0b
+  *
+  * Description:
+  * The example above sets the owner/group/permissions of the listed
+  * devices to uid/gid/0660 if ttyn is /dev/console
+  */
+ 
+ #define	FIELD_DELIMS 	" \t\n"
+ #define	COLON 		":"
+ #define COLON_C         ':'
+ #define WILDCARD        "/*"
+ #define WILDCARD_LEN    2
+ #define MAX_LINELEN     256
+ #ifdef solaris
+ #define FBTAB           "/etc/logindevperm"
+ #else /* solaris */
+ #define FBTAB           "/etc/fbtab"
+ #endif /* solaris */
+ 
+ 
+ set_fb_attrs(ttyn, uid, gid)
+ 	char *ttyn;
+ 	int uid;
+ 	int gid;
+ {
+ 	char line[MAX_LINELEN];
+ 	char *console;
+ 	char *mode_str;
+ 	char *dev_list;
+ 	char *device;
+ 	char *ptr;
+ 	int  mode;
+ 	long strtol();
+ 	FILE *fp;
+ 
+ 	if ((fp = fopen(FBTAB, "r")) == NULL)
+ 		return;
+ 	while (fgets(line, MAX_LINELEN, fp)) {
+ 		if (ptr = strchr(line, '#'))
+ 			*ptr = '\0';	/* handle comments */
+ 		if ((console = strtok(line, FIELD_DELIMS)) == NULL)
+ 			continue;	/* ignore blank lines */
+ 		if (strcmp(console, ttyn) != 0)
+ 			continue;	/* ignore non-consoles */
+ 		mode_str = strtok((char *)NULL, FIELD_DELIMS);
+ 		if (mode_str == NULL) {
+ 			(void) fprintf(stderr, "%s: invalid entry -- %s\n",
+ 				FBTAB, line);
+ 			continue;
+ 		}
+ 		/* convert string to octal value */
+ 		mode = (int) strtol(mode_str, (char **)NULL, 8);
+ 		if (mode < 0 || mode > 0777) {
+ 			(void) fprintf(stderr, "%s: invalid mode -- %s\n",
+ 				FBTAB, mode_str);
+ 			continue;
+ 		}
+ 		dev_list = strtok((char *)NULL, FIELD_DELIMS);
+ 		if (dev_list == NULL) {
+ 			(void) fprintf(stderr, "%s: %s -- empty device list\n",
+ 				FBTAB, console);
+ 			continue;
+ 		}
+ #ifdef solaris
+ 		device = strtok(dev_list, COLON);
+ 		while (device) {
+ 		    ptr = strstr(device, WILDCARD);
+ 		    if (ptr && 
+ 			(strlen(device) - (ptr - &device[0])) == WILDCARD_LEN){
+ 			/* The device was a (legally-specified) directory. */
+ 			DIR           *dev_dir;
+ 			struct dirent *dir_e;
+ 			char dev_file[MAXPATHLEN];
+ 			
+ 			*ptr = '\0'; /* Remove the wildcard from the dir name. */
+ 
+ 			if ((dev_dir = opendir(device)) == (DIR *) NULL) {
+ 			    syslog(LOG_ERR, "bad device %s%s in %s, ignored",
+ 				   device, WILDCARD, FBTAB);
+ 			    continue;
+ 			}
+ 			
+ 			/* Directory is open; alter its files. */
+ 			/* Must link with /usr/lib/libc.a before 
+ 			   /usr/ucblib/libucb.a or the d_name structs
+ 			   miss the first two characters of the filename */
+ 			while (dir_e = readdir(dev_dir)) {
+ 			    if (strcmp(dir_e->d_name, "..") &&
+ 				strcmp(dir_e->d_name, ".")) {
+ 				strcpy(dev_file, device);
+ 				strcat(dev_file, "/");
+ 				strcat(dev_file, dir_e->d_name);
+ 
+ 				(void) chown(dev_file, uid, gid);
+ 				(void) chmod(dev_file, mode);
+ 			    }
+ 			}
+ 			(void) closedir(dev_dir);
+ 		    } else {
+ 			/* 'device' was not a directory, so we can just do it. */
+ 			(void) chown(device, uid, gid);
+ 			(void) chmod(device, mode);
+ 		    }
+ 		    device = strtok((char *)NULL, COLON); /* Move thru list. */
+ #else /* solaris */
+ 		device = strtok(dev_list, COLON);
+ 		while (device) {
+ 			(void) chown(device, uid, gid);
+ 			(void) chmod(device, mode);
+ 			device = strtok((char *)NULL, COLON);
+ #endif /* solaris */
+ 		}
+ 	}
+ 	(void) fclose(fp);
+ }
+ #endif /* sun */
>Audit-Trail:
>Unformatted:

home help back first fref pref prev next nref lref last post