xref: /onnv-gate/usr/src/lib/libbc/libc/net/ruserpass.c (revision 0:68f95e015346)
1*0Sstevel@tonic-gate /*
2*0Sstevel@tonic-gate  * CDDL HEADER START
3*0Sstevel@tonic-gate  *
4*0Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*0Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*0Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*0Sstevel@tonic-gate  * with the License.
8*0Sstevel@tonic-gate  *
9*0Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*0Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*0Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*0Sstevel@tonic-gate  * and limitations under the License.
13*0Sstevel@tonic-gate  *
14*0Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*0Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*0Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*0Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*0Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*0Sstevel@tonic-gate  *
20*0Sstevel@tonic-gate  * CDDL HEADER END
21*0Sstevel@tonic-gate  */
22*0Sstevel@tonic-gate /*
23*0Sstevel@tonic-gate  * Copyright 1989 Sun Microsystems, Inc.  All rights reserved.
24*0Sstevel@tonic-gate  * Use is subject to license terms.
25*0Sstevel@tonic-gate  */
26*0Sstevel@tonic-gate 
27*0Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
28*0Sstevel@tonic-gate 	 /* from UCB 4.2 82/10/10 */
29*0Sstevel@tonic-gate 
30*0Sstevel@tonic-gate #include <stdio.h>
31*0Sstevel@tonic-gate #include <ctype.h>
32*0Sstevel@tonic-gate #include <sys/types.h>
33*0Sstevel@tonic-gate #include <sys/stat.h>
34*0Sstevel@tonic-gate #include <errno.h>
35*0Sstevel@tonic-gate 
36*0Sstevel@tonic-gate char	*malloc(), *index(), *getenv(), *getpass(), *getlogin();
37*0Sstevel@tonic-gate 
38*0Sstevel@tonic-gate #define	DEFAULT	1
39*0Sstevel@tonic-gate #define	LOGIN	2
40*0Sstevel@tonic-gate #define	PASSWD	3
41*0Sstevel@tonic-gate #define	NOTIFY	4
42*0Sstevel@tonic-gate #define	WRITE	5
43*0Sstevel@tonic-gate #define	YES	6
44*0Sstevel@tonic-gate #define	NO	7
45*0Sstevel@tonic-gate #define	COMMAND	8
46*0Sstevel@tonic-gate #define	FORCE	9
47*0Sstevel@tonic-gate #define	ID	10
48*0Sstevel@tonic-gate #define	MACHINE	11
49*0Sstevel@tonic-gate 
50*0Sstevel@tonic-gate #define	MAXTOKEN  11
51*0Sstevel@tonic-gate #define NTOKENS	(MAXTOKEN - 1 + 2 + 1)	/* two duplicates and null, minus id */
52*0Sstevel@tonic-gate 
53*0Sstevel@tonic-gate static struct ruserdata {
54*0Sstevel@tonic-gate 	char tokval[100];
55*0Sstevel@tonic-gate 	struct toktab {
56*0Sstevel@tonic-gate 		char *tokstr;
57*0Sstevel@tonic-gate 		int tval;
58*0Sstevel@tonic-gate 	} toktab[NTOKENS];
59*0Sstevel@tonic-gate 	FILE *cfile;
60*0Sstevel@tonic-gate } *ruserdata, *_ruserdata();
61*0Sstevel@tonic-gate 
62*0Sstevel@tonic-gate 
63*0Sstevel@tonic-gate static struct ruserdata *
64*0Sstevel@tonic-gate _ruserdata()
65*0Sstevel@tonic-gate {
66*0Sstevel@tonic-gate 	register struct ruserdata *d = ruserdata;
67*0Sstevel@tonic-gate 	struct toktab *t;
68*0Sstevel@tonic-gate 
69*0Sstevel@tonic-gate 	if (d == 0) {
70*0Sstevel@tonic-gate 		if ((d = (struct ruserdata *)
71*0Sstevel@tonic-gate 			calloc(1, sizeof(struct ruserdata))) == NULL) {
72*0Sstevel@tonic-gate 				return(NULL);
73*0Sstevel@tonic-gate 		}
74*0Sstevel@tonic-gate 		ruserdata = d;
75*0Sstevel@tonic-gate 		t = d->toktab;
76*0Sstevel@tonic-gate 		t->tokstr = "default";  t++->tval = DEFAULT;
77*0Sstevel@tonic-gate 		t->tokstr = "login";    t++->tval = LOGIN;
78*0Sstevel@tonic-gate 		t->tokstr = "password"; t++->tval = PASSWD;
79*0Sstevel@tonic-gate 		t->tokstr = "notify";   t++->tval = NOTIFY;
80*0Sstevel@tonic-gate 		t->tokstr = "write";    t++->tval = WRITE;
81*0Sstevel@tonic-gate 		t->tokstr = "yes";      t++->tval = YES;
82*0Sstevel@tonic-gate 		t->tokstr = "y";        t++->tval = YES;
83*0Sstevel@tonic-gate 		t->tokstr = "no";       t++->tval = NO;
84*0Sstevel@tonic-gate 		t->tokstr = "n";        t++->tval = NO;
85*0Sstevel@tonic-gate 		t->tokstr = "command";  t++->tval = COMMAND;
86*0Sstevel@tonic-gate 		t->tokstr = "force";    t++->tval = FORCE;
87*0Sstevel@tonic-gate 		t->tokstr = "machine";  t++->tval = MACHINE;
88*0Sstevel@tonic-gate 		t->tokstr = 0;          t->tval = 0;
89*0Sstevel@tonic-gate 	}
90*0Sstevel@tonic-gate 	return(d);
91*0Sstevel@tonic-gate }
92*0Sstevel@tonic-gate 
93*0Sstevel@tonic-gate 
94*0Sstevel@tonic-gate _ruserpass(host, aname, apass)
95*0Sstevel@tonic-gate 	char *host, **aname, **apass;
96*0Sstevel@tonic-gate {
97*0Sstevel@tonic-gate 
98*0Sstevel@tonic-gate 	if (*aname == 0 || *apass == 0)
99*0Sstevel@tonic-gate 		rnetrc(host, aname, apass);
100*0Sstevel@tonic-gate 	if (*aname == 0) {
101*0Sstevel@tonic-gate 		char *myname = getlogin();
102*0Sstevel@tonic-gate 		*aname = malloc(16);
103*0Sstevel@tonic-gate 		printf("Name (%s:%s): ", host, myname);
104*0Sstevel@tonic-gate 		fflush(stdout);
105*0Sstevel@tonic-gate 		if (read(2, *aname, 16) <= 0)
106*0Sstevel@tonic-gate 			exit(1);
107*0Sstevel@tonic-gate 		if ((*aname)[0] == '\n')
108*0Sstevel@tonic-gate 			*aname = myname;
109*0Sstevel@tonic-gate 		else
110*0Sstevel@tonic-gate 			if (index(*aname, '\n'))
111*0Sstevel@tonic-gate 				*index(*aname, '\n') = 0;
112*0Sstevel@tonic-gate 	}
113*0Sstevel@tonic-gate 	if (*aname && *apass == 0) {
114*0Sstevel@tonic-gate 		printf("Password (%s:%s): ", host, *aname);
115*0Sstevel@tonic-gate 		fflush(stdout);
116*0Sstevel@tonic-gate 		*apass = getpass("");
117*0Sstevel@tonic-gate 	}
118*0Sstevel@tonic-gate }
119*0Sstevel@tonic-gate 
120*0Sstevel@tonic-gate 
121*0Sstevel@tonic-gate static
122*0Sstevel@tonic-gate rnetrc(host, aname, apass)
123*0Sstevel@tonic-gate 	char *host, **aname, **apass;
124*0Sstevel@tonic-gate {
125*0Sstevel@tonic-gate 	register struct ruserdata *d = _ruserdata();
126*0Sstevel@tonic-gate 	char *hdir, buf[BUFSIZ];
127*0Sstevel@tonic-gate 	int t;
128*0Sstevel@tonic-gate 	struct stat stb;
129*0Sstevel@tonic-gate 	extern int errno;
130*0Sstevel@tonic-gate 
131*0Sstevel@tonic-gate 	if (d == 0)
132*0Sstevel@tonic-gate 		return;
133*0Sstevel@tonic-gate 
134*0Sstevel@tonic-gate 	hdir = getenv("HOME");
135*0Sstevel@tonic-gate 	if (hdir == NULL)
136*0Sstevel@tonic-gate 		hdir = ".";
137*0Sstevel@tonic-gate 	sprintf(buf, "%s/.netrc", hdir);
138*0Sstevel@tonic-gate 	d->cfile = fopen(buf, "r");
139*0Sstevel@tonic-gate 	if (d->cfile == NULL) {
140*0Sstevel@tonic-gate 		if (errno != ENOENT)
141*0Sstevel@tonic-gate 			perror(buf);
142*0Sstevel@tonic-gate 		return;
143*0Sstevel@tonic-gate 	}
144*0Sstevel@tonic-gate next:
145*0Sstevel@tonic-gate 	while ((t = token())) switch(t) {
146*0Sstevel@tonic-gate 
147*0Sstevel@tonic-gate 	case DEFAULT:
148*0Sstevel@tonic-gate 		(void) token();
149*0Sstevel@tonic-gate 		continue;
150*0Sstevel@tonic-gate 
151*0Sstevel@tonic-gate 	case MACHINE:
152*0Sstevel@tonic-gate 		if (token() != ID || strcmp(host, d->tokval))
153*0Sstevel@tonic-gate 			continue;
154*0Sstevel@tonic-gate 		while ((t = token()) && t != MACHINE) switch(t) {
155*0Sstevel@tonic-gate 
156*0Sstevel@tonic-gate 		case LOGIN:
157*0Sstevel@tonic-gate 			if (token())
158*0Sstevel@tonic-gate 				if (*aname == 0) {
159*0Sstevel@tonic-gate 					*aname = malloc(strlen(d->tokval) + 1);
160*0Sstevel@tonic-gate 					strcpy(*aname, d->tokval);
161*0Sstevel@tonic-gate 				} else {
162*0Sstevel@tonic-gate 					if (strcmp(*aname, d->tokval))
163*0Sstevel@tonic-gate 						goto next;
164*0Sstevel@tonic-gate 				}
165*0Sstevel@tonic-gate 			break;
166*0Sstevel@tonic-gate 		case PASSWD:
167*0Sstevel@tonic-gate 			if (fstat(fileno(d->cfile), &stb) >= 0
168*0Sstevel@tonic-gate 			    && (stb.st_mode & 077) != 0) {
169*0Sstevel@tonic-gate 	fprintf(stderr, "Error - .netrc file not correct mode.\n");
170*0Sstevel@tonic-gate 	fprintf(stderr, "Remove password or correct mode.\n");
171*0Sstevel@tonic-gate 				exit(1);
172*0Sstevel@tonic-gate 			}
173*0Sstevel@tonic-gate 			if (token() && *apass == 0) {
174*0Sstevel@tonic-gate 				*apass = malloc(strlen(d->tokval) + 1);
175*0Sstevel@tonic-gate 				strcpy(*apass, d->tokval);
176*0Sstevel@tonic-gate 			}
177*0Sstevel@tonic-gate 			break;
178*0Sstevel@tonic-gate 		case COMMAND:
179*0Sstevel@tonic-gate 		case NOTIFY:
180*0Sstevel@tonic-gate 		case WRITE:
181*0Sstevel@tonic-gate 		case FORCE:
182*0Sstevel@tonic-gate 			(void) token();
183*0Sstevel@tonic-gate 			break;
184*0Sstevel@tonic-gate 		default:
185*0Sstevel@tonic-gate 	fprintf(stderr, "Unknown .netrc option %s\n", d->tokval);
186*0Sstevel@tonic-gate 			break;
187*0Sstevel@tonic-gate 		}
188*0Sstevel@tonic-gate 		goto done;
189*0Sstevel@tonic-gate 	}
190*0Sstevel@tonic-gate done:
191*0Sstevel@tonic-gate 	fclose(d->cfile);
192*0Sstevel@tonic-gate }
193*0Sstevel@tonic-gate 
194*0Sstevel@tonic-gate static
195*0Sstevel@tonic-gate token()
196*0Sstevel@tonic-gate {
197*0Sstevel@tonic-gate 	register struct ruserdata *d = _ruserdata();
198*0Sstevel@tonic-gate 	char *cp;
199*0Sstevel@tonic-gate 	int c;
200*0Sstevel@tonic-gate 	struct toktab *t;
201*0Sstevel@tonic-gate 
202*0Sstevel@tonic-gate 	if (d == 0)
203*0Sstevel@tonic-gate 		return(0);
204*0Sstevel@tonic-gate 
205*0Sstevel@tonic-gate 	if (feof(d->cfile))
206*0Sstevel@tonic-gate 		return (0);
207*0Sstevel@tonic-gate 	while ((c = getc(d->cfile)) != EOF &&
208*0Sstevel@tonic-gate 	    (c == '\n' || c == '\t' || c == ' ' || c == ','))
209*0Sstevel@tonic-gate 		continue;
210*0Sstevel@tonic-gate 	if (c == EOF)
211*0Sstevel@tonic-gate 		return (0);
212*0Sstevel@tonic-gate 	cp = d->tokval;
213*0Sstevel@tonic-gate 	if (c == '"') {
214*0Sstevel@tonic-gate 		while ((c = getc(d->cfile)) != EOF && c != '"') {
215*0Sstevel@tonic-gate 			if (c == '\\')
216*0Sstevel@tonic-gate 				c = getc(d->cfile);
217*0Sstevel@tonic-gate 			*cp++ = c;
218*0Sstevel@tonic-gate 		}
219*0Sstevel@tonic-gate 	} else {
220*0Sstevel@tonic-gate 		*cp++ = c;
221*0Sstevel@tonic-gate 		while ((c = getc(d->cfile)) != EOF
222*0Sstevel@tonic-gate 		    && c != '\n' && c != '\t' && c != ' ' && c != ',') {
223*0Sstevel@tonic-gate 			if (c == '\\')
224*0Sstevel@tonic-gate 				c = getc(d->cfile);
225*0Sstevel@tonic-gate 			*cp++ = c;
226*0Sstevel@tonic-gate 		}
227*0Sstevel@tonic-gate 	}
228*0Sstevel@tonic-gate 	*cp = 0;
229*0Sstevel@tonic-gate 	if (d->tokval[0] == 0)
230*0Sstevel@tonic-gate 		return (0);
231*0Sstevel@tonic-gate 	for (t = d->toktab; t->tokstr; t++)
232*0Sstevel@tonic-gate 		if (!strcmp(t->tokstr, d->tokval))
233*0Sstevel@tonic-gate 			return (t->tval);
234*0Sstevel@tonic-gate 	return (ID);
235*0Sstevel@tonic-gate }
236*0Sstevel@tonic-gate 
237