1 /*
2 * Copyright (c) 1985 Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms are permitted
6 * provided that the above copyright notice and this paragraph are
7 * duplicated in all such forms and that any documentation,
8 * advertising materials, and other materials related to such
9 * distribution and use acknowledge that the software was developed
10 * by the University of California, Berkeley. The name of the
11 * University may not be used to endorse or promote products derived
12 * from this software without specific prior written permission.
13 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
16 */
17
18 #include "precomp.h"
19
20 #ifndef lint
21 static char sccsid[] = "@(#)ruserpass.c 5.1 (Berkeley) 3/1/89";
22 #endif /* not lint */
23
24 struct utmp *getutmp();
25 static FILE *cfile;
26
27 #ifndef MAXHOSTNAMELEN
28 #define MAXHOSTNAMELEN 64
29 #endif
30
31 #define DEFAULT 1
32 #define LOGIN 2
33 #define PASSWD 3
34 #define ACCOUNT 4
35 #define MACDEF 5
36 #define ID 10
37 #define MACH 11
38
39 static char tokval[100];
40
41 static struct toktab {
42 const char *tokstr;
43 int tval;
44 } toktab[]= {
45 {"default", DEFAULT},
46 {"login", LOGIN},
47 {"password", PASSWD},
48 {"passwd", PASSWD},
49 {"account", ACCOUNT},
50 {"machine", MACH},
51 {"macdef", MACDEF},
52 {0, 0}
53 };
54
55 extern char *hostname;
56 static int token(void);
57
ruserpass(const char * host,char ** aname,char ** apass,char ** aacct)58 int ruserpass(const char *host, char **aname, char **apass, char **aacct)
59 {
60 const char *hdir, *mydomain;
61 char buf[BUFSIZ], *tmp;
62 char myname[MAXHOSTNAMELEN];
63 int t, i, c, usedefault = 0;
64 struct stat stb;
65
66 hdir = getenv("HOME");
67 if (hdir == NULL)
68 hdir = ".";
69 (void) sprintf(buf, "%s/.netrc", hdir);
70 cfile = fopen(buf, "r");
71 if (cfile == NULL) {
72 if (errno != ENOENT)
73 perror(buf);
74 return(0);
75 }
76
77
78 if (gethostname(myname, sizeof(myname)) < 0)
79 myname[0] = '\0';
80 if ((mydomain = index(myname, '.')) == NULL)
81 mydomain = "";
82 next:
83 while ((t = token())) switch(t) {
84
85 case DEFAULT:
86 usedefault = 1;
87 /* FALL THROUGH */
88
89 case MACH:
90 if (!usedefault) {
91 if (token() != ID)
92 continue;
93 /*
94 * Allow match either for user's input host name
95 * or official hostname. Also allow match of
96 * incompletely-specified host in local domain.
97 */
98 if (strcasecmp(host, tokval) == 0)
99 goto match;
100 if (strcasecmp(hostname, tokval) == 0)
101 goto match;
102 if ((tmp = index(hostname, '.')) != NULL &&
103 strcasecmp(tmp, mydomain) == 0 &&
104 strncasecmp(hostname, tokval, tmp - hostname) == 0 &&
105 tokval[tmp - hostname] == '\0')
106 goto match;
107 if ((tmp = index(host, '.')) != NULL &&
108 strcasecmp(tmp, mydomain) == 0 &&
109 strncasecmp(host, tokval, tmp - host) == 0 &&
110 tokval[tmp - host] == '\0')
111 goto match;
112 continue;
113 }
114 match:
115 while ((t = token()) && t != MACH && t != DEFAULT) switch(t) {
116
117 case LOGIN:
118 if (token()) {
119 if (*aname == 0) {
120 *aname = malloc((unsigned) strlen(tokval) + 1);
121 (void) strcpy(*aname, tokval);
122 } else {
123 if (strcmp(*aname, tokval))
124 goto next;
125 }
126 }
127 break;
128 case PASSWD:
129 if (strcmp(*aname, "anonymous") &&
130 fstat(fileno(cfile), &stb) >= 0 &&
131 (stb.st_mode & 077) != 0) {
132 fprintf(stderr, "Error - .netrc file not correct mode.\n");
133 fprintf(stderr, "Remove password or correct mode.\n");
134 goto bad;
135 }
136 if (token() && *apass == 0) {
137 *apass = malloc((unsigned) strlen(tokval) + 1);
138 (void) strcpy(*apass, tokval);
139 }
140 break;
141 case ACCOUNT:
142 if (fstat(fileno(cfile), &stb) >= 0
143 && (stb.st_mode & 077) != 0) {
144 fprintf(stderr, "Error - .netrc file not correct mode.\n");
145 fprintf(stderr, "Remove account or correct mode.\n");
146 goto bad;
147 }
148 if (token() && *aacct == 0) {
149 *aacct = malloc((unsigned) strlen(tokval) + 1);
150 (void) strcpy(*aacct, tokval);
151 }
152 break;
153 case MACDEF:
154 if (proxy) {
155 (void) fclose(cfile);
156 return(0);
157 }
158 while ((c=getc(cfile)) != EOF && (c == ' ' || c == '\t'));
159 if (c == EOF || c == '\n') {
160 printf("Missing macdef name argument.\n");
161 goto bad;
162 }
163 if (macnum == 16) {
164 printf("Limit of 16 macros have already been defined\n");
165 goto bad;
166 }
167 tmp = macros[macnum].mac_name;
168 *tmp++ = c;
169 for (i=0; i < 8 && (c=getc(cfile)) != EOF &&
170 !isspace(c); ++i) {
171 *tmp++ = c;
172 }
173 if (c == EOF) {
174 printf("Macro definition missing null line terminator.\n");
175 goto bad;
176 }
177 *tmp = '\0';
178 if (c != '\n') {
179 while ((c=getc(cfile)) != EOF && c != '\n');
180 }
181 if (c == EOF) {
182 printf("Macro definition missing null line terminator.\n");
183 goto bad;
184 }
185 if (macnum == 0) {
186 macros[macnum].mac_start = macbuf;
187 }
188 else {
189 macros[macnum].mac_start = macros[macnum-1].mac_end + 1;
190 }
191 tmp = macros[macnum].mac_start;
192 while (tmp != macbuf + 4096) {
193 if ((c=getc(cfile)) == EOF) {
194 printf("Macro definition missing null line terminator.\n");
195 goto bad;
196 }
197 *tmp = c;
198 if (*tmp == '\n') {
199 if (*(tmp-1) == '\0') {
200 macros[macnum++].mac_end = tmp - 1;
201 break;
202 }
203 *tmp = '\0';
204 }
205 tmp++;
206 }
207 if (tmp == macbuf + 4096) {
208 printf("4K macro buffer exceeded\n");
209 goto bad;
210 }
211 break;
212 default:
213 fprintf(stderr, "Unknown .netrc keyword %s\n", tokval);
214 break;
215 }
216 goto done;
217 }
218 done:
219 (void) fclose(cfile);
220 return(0);
221 bad:
222 (void) fclose(cfile);
223 return(-1);
224 }
225
token(void)226 static int token(void)
227 {
228 char *cp;
229 int c;
230 struct toktab *t;
231
232 if (feof(cfile))
233 return (0);
234 while ((c = getc(cfile)) != EOF &&
235 (c == '\r' || c == '\n' || c == '\t' || c == ' ' || c == ','))
236 continue;
237 if (c == EOF)
238 return (0);
239 cp = tokval;
240 if (c == '"') {
241 while ((c = getc(cfile)) != EOF && c != '"') {
242 if (c == '\\')
243 c = getc(cfile);
244 *cp++ = c;
245 }
246 } else {
247 *cp++ = c;
248 while ((c = getc(cfile)) != EOF
249 && c != '\n' && c != '\t' && c != ' ' && c != ',' && c != '\r') {
250 if (c == '\\')
251 c = getc(cfile);
252 *cp++ = c;
253 }
254 }
255 *cp = 0;
256 if (tokval[0] == 0)
257 return (0);
258 for (t = toktab; t->tokstr; t++)
259 if (!strcmp(t->tokstr, tokval))
260 return (t->tval);
261 return (ID);
262 }
263