2 * Copyright (c) 1985, 1993, 1994
3 * The Regents of the University of California. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
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 * 4. Neither the name of the University nor the names of its contributors
14 * may be used to endorse or promote products derived from this software
15 * without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 #include <sys/types.h>
40 #include <stdio_ext.h>
45 /* Experimentally off - libc_hidden_proto(strcat) */
46 /* Experimentally off - libc_hidden_proto(strchr) */
47 /* Experimentally off - libc_hidden_proto(strcmp) */
48 /* Experimentally off - libc_hidden_proto(strcpy) */
49 /* Experimentally off - libc_hidden_proto(strlen) */
50 /* Experimentally off - libc_hidden_proto(strcasecmp) */
51 /* Experimentally off - libc_hidden_proto(strncasecmp) */
52 /* libc_hidden_proto(getenv) */
53 /* libc_hidden_proto(printf) */
54 /* libc_hidden_proto(fstat) */
55 /* libc_hidden_proto(__fsetlocking) */
56 /* libc_hidden_proto(getgid) */
57 /* libc_hidden_proto(getuid) */
58 /* libc_hidden_proto(getegid) */
59 /* libc_hidden_proto(geteuid) */
60 /* libc_hidden_proto(gethostname) */
61 /* libc_hidden_proto(fileno) */
62 /* libc_hidden_proto(fopen) */
63 /* libc_hidden_proto(fclose) */
64 /* libc_hidden_proto(getc_unlocked) */
65 /* libc_hidden_proto(__fgetc_unlocked) */
68 /* #include "ftp_var.h" */
70 static int token (void);
81 static char tokval[100];
83 static const char tokstr[] =
85 #define TOK_DEFAULT_IDX 0
87 #define TOK_LOGIN_IDX (TOK_DEFAULT_IDX + sizeof "default")
89 #define TOK_PASSWORD_IDX (TOK_LOGIN_IDX + sizeof "login")
91 #define TOK_PASSWD_IDX (TOK_PASSWORD_IDX + sizeof "password")
93 #define TOK_ACCOUNT_IDX (TOK_PASSWD_IDX + sizeof "passwd")
95 #define TOK_MACHINE_IDX (TOK_ACCOUNT_IDX + sizeof "account")
97 #define TOK_MACDEF_IDX (TOK_MACHINE_IDX + sizeof "machine")
101 static const struct toktab {
105 { TOK_DEFAULT_IDX, DEFAULT },
106 { TOK_LOGIN_IDX, LOGIN },
107 { TOK_PASSWORD_IDX, PASSWD },
108 { TOK_PASSWD_IDX, PASSWD },
109 { TOK_ACCOUNT_IDX, ACCOUNT },
110 { TOK_MACHINE_IDX, MACHINE },
111 { TOK_MACDEF_IDX, MACDEF }
115 /* ruserpass - remote password check.
116 This function also exists in glibc but is undocumented */
117 /* libc_hidden_proto(ruserpass) */
118 int ruserpass(const char *host, const char **aname, const char **apass)
120 char *hdir, *buf, *tmp;
121 char myname[1024], *mydomain;
122 int t, usedefault = 0;
125 /* Give up when running a setuid or setgid app. */
126 if ((getuid() != geteuid()) || getgid() != getegid())
128 hdir = getenv("HOME");
130 /* If we can't get HOME, fail instead of trying ".",
131 which is no improvement. */
135 buf = alloca (strlen(hdir) + 8);
137 strcat(buf, "/.netrc");
138 cfile = fopen(buf, "r");
144 /* No threads use this stream. */
145 #ifdef __UCLIBC_HAS_THREADS__
146 __fsetlocking (cfile, FSETLOCKING_BYCALLER);
148 if (gethostname(myname, sizeof(myname)) < 0)
150 mydomain = strchr(myname, '.');
151 if (mydomain==NULL) {
152 mydomain=myname + strlen(myname);
155 while ((t = token())) switch(t) {
166 * Allow match either for user's input host name
167 * or official hostname. Also allow match of
168 * incompletely-specified host in local domain.
170 if (strcasecmp(host, tokval) == 0)
172 if ((tmp = strchr(host, '.')) != NULL &&
173 strcasecmp(tmp, mydomain) == 0 &&
174 strncasecmp(host, tokval, tmp - host) == 0 &&
175 tokval[tmp - host] == '\0')
180 while ((t = token()) && t != MACHINE && t != DEFAULT) switch(t) {
186 newp = malloc((unsigned) strlen(tokval) + 1);
189 printf(_("out of memory"));
192 *aname = strcpy(newp, tokval);
194 if (strcmp(*aname, tokval))
200 if (strcmp(*aname, "anonymous") &&
201 fstat(fileno(cfile), &stb) >= 0 &&
202 (stb.st_mode & 077) != 0) {
203 printf(_("Error: .netrc file is readable by others."));
204 printf(_("Remove password or make file unreadable by others."));
207 if (token() && *apass == 0) {
209 newp = malloc((unsigned) strlen(tokval) + 1);
212 printf(_("out of memory"));
215 *apass = strcpy(newp, tokval);
220 if (fstat(fileno(cfile), &stb) >= 0
221 && (stb.st_mode & 077) != 0) {
222 printf("Error: .netrc file is readable by others.");
223 printf("Remove account or make file unreadable by others.");
226 if (token() && *aacct == 0) {
227 *aacct = malloc((unsigned) strlen(tokval) + 1);
228 (void) strcpy(*aacct, tokval);
235 (void) fclose(cfile);
238 while ((c=getc_unlocked(cfile)) != EOF && c == ' '
240 if (c == EOF || c == '\n') {
241 printf("Missing macdef name argument.\n");
245 printf("Limit of 16 macros have already been defined\n");
248 tmp = macros[macnum].mac_name;
250 for (i=0; i < 8 && (c=getc_unlocked(cfile)) != EOF &&
255 printf("Macro definition missing null line terminator.\n");
260 while ((c=getc_unlocked(cfile)) != EOF
264 printf("Macro definition missing null line terminator.\n");
268 macros[macnum].mac_start = macbuf;
271 macros[macnum].mac_start = macros[macnum-1].mac_end + 1;
273 tmp = macros[macnum].mac_start;
274 while (tmp != macbuf + 4096) {
275 if ((c=getc_unlocked(cfile)) == EOF) {
276 printf("Macro definition missing null line terminator.\n");
281 if (*(tmp-1) == '\0') {
282 macros[macnum++].mac_end = tmp - 1;
289 if (tmp == macbuf + 4096) {
290 printf("4K macro buffer exceeded\n");
296 printf(_("Unknown .netrc keyword %s"), tokval);
302 (void) fclose(cfile);
305 (void) fclose(cfile);
308 libc_hidden_def(ruserpass)
317 if (feof_unlocked(cfile) || ferror_unlocked(cfile))
319 while ((c = getc_unlocked(cfile)) != EOF &&
320 (c == '\n' || c == '\t' || c == ' ' || c == ','))
326 while ((c = getc_unlocked(cfile)) != EOF && c != '"') {
328 c = getc_unlocked(cfile);
333 while ((c = getc_unlocked(cfile)) != EOF
334 && c != '\n' && c != '\t' && c != ' ' && c != ',') {
336 c = getc_unlocked(cfile);
343 for (i = 0; i < (int) (sizeof (toktab) / sizeof (toktab[0])); ++i)
344 if (!strcmp(&tokstr[toktab[i].tokstr_off], tokval))
345 return toktab[i].tval;