Subject: lib/901: missing ruserpass in libcompat
To: None <gnats-admin@NetBSD.ORG>
From: Alistair G. Crooks <agc@uts.amdahl.com>
List: netbsd-bugs
Date: 03/24/1995 01:50:05
>Number:         901
>Category:       lib
>Synopsis:       Missing ruserpass function in libcompat
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    lib-bug-people (Library Bug People)
>State:          open
>Class:          change-request
>Submitter-Id:   net
>Arrival-Date:   Fri Mar 24 01:50:03 1995
>Originator:     Alistair G. Crooks (agc@uts.amdahl.com)
>Organization:
		Amdahl
>Release:        18th March 1995 tar_files
>Environment:
		NetBSD/i386 1.0A
System: NetBSD rumpy.osg.uk.amdahl.com 1.0A NetBSD 1.0A (RUMPY) #0: Mon Mar 20 11:26:20 GMT 1995 root@rumpy.osg.uk.amdahl.com:/usr/src/sys/arch/i386/compile/RUMPY i386


>Description:
	ruserpass() is missing from libcompat
>How-To-Repeat:
	Try to compile a piece of software that uses rexec(3) using
	-lcompat. The compilation will fail with an undefined reference
	to ruserpass(). This reference is made by rexec.
>Fix:
	Apply the following diff.  I've taken the routine from ftp,
	and cleaned it up. This patch supercedes the previous whine
	I sent to the core team.

*** /usr/src/lib/libcompat/4.3/rexec.c.orig	Mon Nov 21 21:44:25 1994
--- /usr/src/lib/libcompat/4.3/rexec.c	Fri Mar 24 09:32:22 1995
***************
*** 37,42 ****
--- 37,44 ----
  
  #include <sys/types.h>
  #include <sys/socket.h>
+ #include <sys/param.h>
+ #include <sys/stat.h>
  
  #include <netinet/in.h>
  
***************
*** 44,54 ****
  #include <netdb.h>
  #include <string.h>
  #include <errno.h>
  
- extern	errno;
- char	*index();
  int	rexecoptions;
  char	*getpass(), *getlogin();
  
  rexec(ahost, rport, name, pass, cmd, fd2p)
  	char **ahost;
--- 46,293 ----
  #include <netdb.h>
  #include <string.h>
  #include <errno.h>
+ #include <ctype.h>
+ #include <err.h>
+ #include <stdlib.h>
+ #include <unistd.h>
  
  int	rexecoptions;
  char	*getpass(), *getlogin();
+ 
+ /*
+  * Options and other state info.
+  */
+ struct macel {
+ 	char mac_name[9];	/* macro name */
+ 	char *mac_start;	/* start of macro in macbuf */
+ 	char *mac_end;		/* end of macro in macbuf */
+ };
+ 
+ int macnum;			/* number of defined macros */
+ struct macel macros[16];
+ char macbuf[4096];
+ 
+ static	FILE *cfile;
+ 
+ #define	DEFAULT	1
+ #define	LOGIN	2
+ #define	PASSWD	3
+ #define	ACCOUNT 4
+ #define MACDEF  5
+ #define	ID	10
+ #define	MACH	11
+ 
+ static char tokval[100];
+ 
+ static struct toktab {
+ 	char *tokstr;
+ 	int tval;
+ } toktab[]= {
+ 	{ "default",	DEFAULT },
+ 	{ "login",	LOGIN },
+ 	{ "password",	PASSWD },
+ 	{ "passwd",	PASSWD },
+ 	{ "account",	ACCOUNT },
+ 	{ "machine",	MACH },
+ 	{ "macdef",	MACDEF },
+ 	{ NULL,		0 }
+ };
+ 
+ static int
+ token()
+ {
+ 	char *cp;
+ 	int c;
+ 	struct toktab *t;
+ 
+ 	if (feof(cfile) || ferror(cfile))
+ 		return (0);
+ 	while ((c = getc(cfile)) != EOF &&
+ 	    (c == '\n' || c == '\t' || c == ' ' || c == ','))
+ 		continue;
+ 	if (c == EOF)
+ 		return (0);
+ 	cp = tokval;
+ 	if (c == '"') {
+ 		while ((c = getc(cfile)) != EOF && c != '"') {
+ 			if (c == '\\')
+ 				c = getc(cfile);
+ 			*cp++ = c;
+ 		}
+ 	} else {
+ 		*cp++ = c;
+ 		while ((c = getc(cfile)) != EOF
+ 		    && c != '\n' && c != '\t' && c != ' ' && c != ',') {
+ 			if (c == '\\')
+ 				c = getc(cfile);
+ 			*cp++ = c;
+ 		}
+ 	}
+ 	*cp = 0;
+ 	if (tokval[0] == 0)
+ 		return (0);
+ 	for (t = toktab; t->tokstr; t++)
+ 		if (!strcmp(t->tokstr, tokval))
+ 			return (t->tval);
+ 	return (ID);
+ }
+ 
+ static int
+ ruserpass(host, aname, apass, aacct)
+ 	char *host, **aname, **apass, **aacct;
+ {
+ 	char *hdir, buf[BUFSIZ], *tmp;
+ 	char myname[MAXHOSTNAMELEN], *mydomain;
+ 	int t, i, c, usedefault = 0;
+ 	struct stat stb;
+ 
+ 	hdir = getenv("HOME");
+ 	if (hdir == NULL)
+ 		hdir = ".";
+ 	(void) sprintf(buf, "%s/.netrc", hdir);
+ 	cfile = fopen(buf, "r");
+ 	if (cfile == NULL) {
+ 		if (errno != ENOENT)
+ 			warn("%s", buf);
+ 		return (0);
+ 	}
+ 	if (gethostname(myname, sizeof(myname)) < 0)
+ 		myname[0] = '\0';
+ 	if ((mydomain = strchr(myname, '.')) == NULL)
+ 		mydomain = "";
+ next:
+ 	while ((t = token())) switch(t) {
+ 
+ 	case DEFAULT:
+ 		usedefault = 1;
+ 		/* FALL THROUGH */
+ 
+ 	case MACH:
+ 		if (!usedefault) {
+ 			if (token() != ID)
+ 				continue;
+ 			/*
+ 			 * Allow match either for user's input host name
+ 			 * or official hostname.  Also allow match of 
+ 			 * incompletely-specified host in local domain.
+ 			 */
+ 			if (strcasecmp(host, tokval) == 0)
+ 				goto match;
+ 			if ((tmp = strchr(host, '.')) != NULL &&
+ 			    strcasecmp(tmp, mydomain) == 0 &&
+ 			    strncasecmp(host, tokval, tmp - host) == 0 &&
+ 			    tokval[tmp - host] == '\0')
+ 				goto match;
+ 			continue;
+ 		}
+ 	match:
+ 		while ((t = token()) && t != MACH && t != DEFAULT) switch(t) {
+ 
+ 		case LOGIN:
+ 			if (token())
+ 				if (*aname == 0) { 
+ 					*aname = malloc((unsigned) strlen(tokval) + 1);
+ 					(void) strcpy(*aname, tokval);
+ 				} else {
+ 					if (strcmp(*aname, tokval))
+ 						goto next;
+ 				}
+ 			break;
+ 		case PASSWD:
+ 			if ((*aname == 0 || strcmp(*aname, "anonymous")) &&
+ 			    fstat(fileno(cfile), &stb) >= 0 &&
+ 			    (stb.st_mode & 077) != 0) {
+ 	warnx("Error: .netrc file is readable by others.");
+ 	warnx("Remove password or make file unreadable by others.");
+ 				goto bad;
+ 			}
+ 			if (token() && *apass == 0) {
+ 				*apass = malloc((unsigned) strlen(tokval) + 1);
+ 				(void) strcpy(*apass, tokval);
+ 			}
+ 			break;
+ 		case ACCOUNT:
+ 			if (fstat(fileno(cfile), &stb) >= 0
+ 			    && (stb.st_mode & 077) != 0) {
+ 	warnx("Error: .netrc file is readable by others.");
+ 	warnx("Remove account or make file unreadable by others.");
+ 				goto bad;
+ 			}
+ 			if (token() && *aacct == 0) {
+ 				*aacct = malloc((unsigned) strlen(tokval) + 1);
+ 				(void) strcpy(*aacct, tokval);
+ 			}
+ 			break;
+ 		case MACDEF:
+ 			while ((c=getc(cfile)) != EOF &&
+ 						(c == ' ' || c == '\t'))
+ 				;
+ 			if (c == EOF || c == '\n') {
+ 				printf("Missing macdef name argument.\n");
+ 				goto bad;
+ 			}
+ 			if (macnum == 16) {
+ 				printf("Limit of 16 macros have already been defined\n");
+ 				goto bad;
+ 			}
+ 			tmp = macros[macnum].mac_name;
+ 			*tmp++ = c;
+ 			for (i=0; i < 8 && (c=getc(cfile)) != EOF &&
+ 			    !isspace(c); ++i) {
+ 				*tmp++ = c;
+ 			}
+ 			if (c == EOF) {
+ 				printf("Macro definition missing null line terminator.\n");
+ 				goto bad;
+ 			}
+ 			*tmp = '\0';
+ 			if (c != '\n') {
+ 				while ((c=getc(cfile)) != EOF && c != '\n');
+ 			}
+ 			if (c == EOF) {
+ 				printf("Macro definition missing null line terminator.\n");
+ 				goto bad;
+ 			}
+ 			if (macnum == 0) {
+ 				macros[macnum].mac_start = macbuf;
+ 			}
+ 			else {
+ 				macros[macnum].mac_start = macros[macnum-1].mac_end + 1;
+ 			}
+ 			tmp = macros[macnum].mac_start;
+ 			while (tmp != macbuf + 4096) {
+ 				if ((c=getc(cfile)) == EOF) {
+ 				printf("Macro definition missing null line terminator.\n");
+ 					goto bad;
+ 				}
+ 				*tmp = c;
+ 				if (*tmp == '\n') {
+ 					if (*(tmp-1) == '\0') {
+ 					   macros[macnum++].mac_end = tmp - 1;
+ 					   break;
+ 					}
+ 					*tmp = '\0';
+ 				}
+ 				tmp++;
+ 			}
+ 			if (tmp == macbuf + 4096) {
+ 				printf("4K macro buffer exceeded\n");
+ 				goto bad;
+ 			}
+ 			break;
+ 		default:
+ 			warnx("Unknown .netrc keyword %s", tokval);
+ 			break;
+ 		}
+ 		goto done;
+ 	}
+ done:
+ 	(void) fclose(cfile);
+ 	return (0);
+ bad:
+ 	(void) fclose(cfile);
+ 	return (-1);
+ }
  
  rexec(ahost, rport, name, pass, cmd, fd2p)
  	char **ahost;
>Audit-Trail:
>Unformatted:

To: gnats-bugs@NetBSD.ORG
Subject: Missing ruserpass function in libcompat
From: agc@uts.amdahl.com
Reply-To: agc@uts.amdahl.com