Incorporated from BIND-4.9.3-BETA26.
[kopensolaris-gnu/glibc.git] / inet / ruserpass.c
1 /*
2  * Copyright (c) 1985, 1993, 1994
3  *      The Regents of the University of California.  All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 3. All advertising materials mentioning features or use of this software
14  *    must display the following acknowledgement:
15  *      This product includes software developed by the University of
16  *      California, Berkeley and its contributors.
17  * 4. Neither the name of the University nor the names of its contributors
18  *    may be used to endorse or promote products derived from this software
19  *    without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31  * SUCH DAMAGE.
32  */
33
34 #ifndef lint
35 static char sccsid[] = "@(#)ruserpass.c 8.3 (Berkeley) 4/2/94";
36 #endif /* not lint */
37
38 #include <sys/types.h>
39 #include <sys/stat.h>
40
41 #include <ctype.h>
42 /*#include <err.h> */
43 #include <errno.h>
44 #include <stdio.h>
45 #include <stdlib.h>
46 #include <string.h>
47 #include <unistd.h>
48
49 /* #include "ftp_var.h" */
50
51 static  int token __P((void));
52 static  FILE *cfile;
53
54 #define DEFAULT 1
55 #define LOGIN   2
56 #define PASSWD  3
57 #define ACCOUNT 4
58 #define MACDEF  5
59 #define ID      10
60 #define MACHINE 11
61
62 static char tokval[100];
63
64 static struct toktab {
65         char *tokstr;
66         int tval;
67 } toktab[]= {
68         { "default",    DEFAULT },
69         { "login",      LOGIN },
70         { "password",   PASSWD },
71         { "passwd",     PASSWD },
72         { "account",    ACCOUNT },
73         { "machine",    MACHINE },
74         { "macdef",     MACDEF },
75         { NULL,         0 }
76 };
77
78
79
80 int
81 ruserpass(host, aname, apass)
82         char *host, **aname, **apass;
83 {
84         char *hdir, buf[BUFSIZ], *tmp;
85         char myname[1024], *mydomain;
86         int t, i, c, usedefault = 0;
87         struct stat stb;
88
89         hdir = getenv("HOME");
90         if (hdir == NULL)
91                 hdir = ".";
92         (void) sprintf(buf, "%s/.netrc", hdir);
93         cfile = fopen(buf, "r");
94         if (cfile == NULL) {
95 /*              if (errno != ENOENT)
96                         warn("%s", buf);*/
97                 return (0);
98         }
99         if (gethostname(myname, sizeof(myname)) < 0)
100                 myname[0] = '\0';
101         if ((mydomain = strchr(myname, '.')) == NULL)
102                 mydomain = "";
103 next:
104         while ((t = token())) switch(t) {
105
106         case DEFAULT:
107                 usedefault = 1;
108                 /* FALL THROUGH */
109
110         case MACHINE:
111                 if (!usedefault) {
112                         if (token() != ID)
113                                 continue;
114                         /*
115                          * Allow match either for user's input host name
116                          * or official hostname.  Also allow match of 
117                          * incompletely-specified host in local domain.
118                          */
119                         if (strcasecmp(host, tokval) == 0)
120                                 goto match;
121 /*                      if (strcasecmp(hostname, tokval) == 0)
122                                 goto match; 
123                         if ((tmp = strchr(hostname, '.')) != NULL &&
124                             strcasecmp(tmp, mydomain) == 0 &&
125                             strncasecmp(hostname, tokval, tmp-hostname) == 0 &&
126                             tokval[tmp - hostname] == '\0')
127                                 goto match; */
128                         if ((tmp = strchr(host, '.')) != NULL &&
129                             strcasecmp(tmp, mydomain) == 0 &&
130                             strncasecmp(host, tokval, tmp - host) == 0 &&
131                             tokval[tmp - host] == '\0')
132                                 goto match;
133                         continue;
134                 }
135         match:
136                 while ((t = token()) && t != MACHINE && t != DEFAULT) switch(t) {
137
138                 case LOGIN:
139                         if (token())
140                                 if (*aname == 0) { 
141                                         *aname = malloc((unsigned) strlen(tokval) + 1);
142                                         (void) strcpy(*aname, tokval);
143                                 } else {
144                                         if (strcmp(*aname, tokval))
145                                                 goto next;
146                                 }
147                         break;
148                 case PASSWD:
149                         if (strcmp(*aname, "anonymous") &&
150                             fstat(fileno(cfile), &stb) >= 0 &&
151                             (stb.st_mode & 077) != 0) {
152 /*      warnx("Error: .netrc file is readable by others.");
153         warnx("Remove password or make file unreadable by others.");*/
154                                 goto bad;
155                         }
156                         if (token() && *apass == 0) {
157                                 *apass = malloc((unsigned) strlen(tokval) + 1);
158                                 (void) strcpy(*apass, tokval);
159                         }
160                         break;
161                 case ACCOUNT:
162 #if 0
163                         if (fstat(fileno(cfile), &stb) >= 0
164                             && (stb.st_mode & 077) != 0) {
165         warnx("Error: .netrc file is readable by others.");
166         warnx("Remove account or make file unreadable by others.");
167                                 goto bad;
168                         }
169                         if (token() && *aacct == 0) {
170                                 *aacct = malloc((unsigned) strlen(tokval) + 1);
171                                 (void) strcpy(*aacct, tokval);
172                         }
173 #endif
174                         break;
175                 case MACDEF:
176 #if 0
177                         if (proxy) {
178                                 (void) fclose(cfile);
179                                 return (0);
180                         } 
181                         while ((c=getc(cfile)) != EOF && c == ' ' || c == '\t');
182                         if (c == EOF || c == '\n') {
183                                 printf("Missing macdef name argument.\n");
184                                 goto bad;
185                         }
186                         if (macnum == 16) {
187                                 printf("Limit of 16 macros have already been defined\n");
188                                 goto bad;
189                         }
190                         tmp = macros[macnum].mac_name;
191                         *tmp++ = c;
192                         for (i=0; i < 8 && (c=getc(cfile)) != EOF &&
193                             !isspace(c); ++i) {
194                                 *tmp++ = c;
195                         }
196                         if (c == EOF) {
197                                 printf("Macro definition missing null line terminator.\n");
198                                 goto bad;
199                         }
200                         *tmp = '\0';
201                         if (c != '\n') {
202                                 while ((c=getc(cfile)) != EOF && c != '\n');
203                         }
204                         if (c == EOF) {
205                                 printf("Macro definition missing null line terminator.\n");
206                                 goto bad;
207                         }
208                         if (macnum == 0) {
209                                 macros[macnum].mac_start = macbuf;
210                         }
211                         else {
212                                 macros[macnum].mac_start = macros[macnum-1].mac_end + 1;
213                         }
214                         tmp = macros[macnum].mac_start;
215                         while (tmp != macbuf + 4096) {
216                                 if ((c=getc(cfile)) == EOF) {
217                                 printf("Macro definition missing null line terminator.\n");
218                                         goto bad;
219                                 }
220                                 *tmp = c;
221                                 if (*tmp == '\n') {
222                                         if (*(tmp-1) == '\0') {
223                                            macros[macnum++].mac_end = tmp - 1;
224                                            break;
225                                         }
226                                         *tmp = '\0';
227                                 }
228                                 tmp++;
229                         }
230                         if (tmp == macbuf + 4096) {
231                                 printf("4K macro buffer exceeded\n");
232                                 goto bad;
233                         }
234 #endif
235                         break;
236                 default:
237 /*                      warnx("Unknown .netrc keyword %s", tokval);*/
238                         break;
239                 }
240                 goto done;
241         }
242 done:
243         (void) fclose(cfile);
244         return (0);
245 bad:
246         (void) fclose(cfile);
247         return (-1);
248 }
249
250 static int
251 token()
252 {
253         char *cp;
254         int c;
255         struct toktab *t;
256
257         if (feof(cfile) || ferror(cfile))
258                 return (0);
259         while ((c = getc(cfile)) != EOF &&
260             (c == '\n' || c == '\t' || c == ' ' || c == ','))
261                 continue;
262         if (c == EOF)
263                 return (0);
264         cp = tokval;
265         if (c == '"') {
266                 while ((c = getc(cfile)) != EOF && c != '"') {
267                         if (c == '\\')
268                                 c = getc(cfile);
269                         *cp++ = c;
270                 }
271         } else {
272                 *cp++ = c;
273                 while ((c = getc(cfile)) != EOF
274                     && c != '\n' && c != '\t' && c != ' ' && c != ',') {
275                         if (c == '\\')
276                                 c = getc(cfile);
277                         *cp++ = c;
278                 }
279         }
280         *cp = 0;
281         if (tokval[0] == 0)
282                 return (0);
283         for (t = toktab; t->tokstr; t++)
284                 if (!strcmp(t->tokstr, tokval))
285                         return (t->tval);
286         return (ID);
287 }