source: trunk/libs/newlib/src/newlib/libc/sys/linux/net/ruserpass.c

Last change on this file was 444, checked in by satin@…, 6 years ago

add newlib,libalmos-mkh, restructure shared_syscalls.h and mini-libc

File size: 8.4 KB
Line 
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 * 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.
16 *
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
27 * SUCH DAMAGE.
28 */
29
30#if defined(LIBC_SCCS) && !defined(lint)
31static char sccsid[] = "@(#)ruserpass.c 8.3 (Berkeley) 4/2/94";
32#endif /* not lint */
33
34#include <sys/types.h>
35#include <sys/stat.h>
36
37#include <ctype.h>
38#include <err.h>
39#include <errno.h>
40#include <netdb.h>
41#include <stdio.h>
42#include <stdio_ext.h>
43#include <stdlib.h>
44#include <string.h>
45#include <unistd.h>
46#include <libintl.h>
47#include "local.h"
48
49/* #include "ftp_var.h" */
50
51static  int token (void);
52static  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
62static char tokval[100];
63
64static const char tokstr[] =
65{
66#define TOK_DEFAULT_IDX 0
67  "default\0"
68#define TOK_LOGIN_IDX   (TOK_DEFAULT_IDX + sizeof "default")
69  "login\0"
70#define TOK_PASSWORD_IDX (TOK_LOGIN_IDX + sizeof "login")
71  "password\0"
72#define TOK_PASSWD_IDX  (TOK_PASSWORD_IDX + sizeof "password")
73  "passwd\0"
74#define TOK_ACCOUNT_IDX (TOK_PASSWD_IDX + sizeof "passwd")
75  "account\0"
76#define TOK_MACHINE_IDX (TOK_ACCOUNT_IDX + sizeof "account")
77  "machine\0"
78#define TOK_MACDEF_IDX  (TOK_MACHINE_IDX + sizeof "machine")
79  "macdef"
80};
81
82static const struct toktab {
83        int tokstr_off;
84        int tval;
85} toktab[]= {
86        { TOK_DEFAULT_IDX,      DEFAULT },
87        { TOK_LOGIN_IDX,        LOGIN },
88        { TOK_PASSWORD_IDX,     PASSWD },
89        { TOK_PASSWD_IDX,       PASSWD },
90        { TOK_ACCOUNT_IDX,      ACCOUNT },
91        { TOK_MACHINE_IDX,      MACHINE },
92        { TOK_MACDEF_IDX,       MACDEF }
93};
94
95
96#define warnx(x) fprintf(stderr, x)
97#define warnx2(x, y) fprintf(stderr, x, y)
98
99int
100ruserpass(host, aname, apass)
101        const char *host, **aname, **apass;
102{
103        char *hdir, *buf, *tmp;
104        char myname[1024], *mydomain;
105        int t, usedefault = 0;
106        struct stat64 stb;
107
108        hdir = getenv("HOME");
109        if (hdir == NULL) {
110                /* If we can't get HOME, fail instead of trying ".",
111                   which is no improvement. This really should call
112                   getpwuid(getuid()).  */
113                /*hdir = ".";*/
114                return -1;
115        }
116
117        buf = alloca (strlen (hdir) + 8);
118
119        stpcpy (stpcpy (buf, hdir), "/.netrc");
120        cfile = fopen(buf, "rc");
121        if (cfile == NULL) {
122                if (errno != ENOENT) {
123                        char *t = asprintf("%s", buf);
124                        perror(t);
125                }
126                return (0);
127        }
128        /* No threads use this stream.  */
129        __fsetlocking (cfile, FSETLOCKING_BYCALLER);
130        if (__gethostname(myname, sizeof(myname)) < 0)
131                myname[0] = '\0';
132        tmp = strchr(myname, '.');
133        if (tmp == NULL)
134                tmp = myname + strlen(myname);
135        mydomain = tmp;
136next:
137        while ((t = token())) switch(t) {
138
139        case DEFAULT:
140                usedefault = 1;
141                /* FALL THROUGH */
142
143        case MACHINE:
144                if (!usedefault) {
145                        if (token() != ID)
146                                continue;
147                        /*
148                         * Allow match either for user's input host name
149                         * or official hostname.  Also allow match of
150                         * incompletely-specified host in local domain.
151                         */
152                        if (strcasecmp(host, tokval) == 0)
153                                goto match;
154/*                      if (strcasecmp(hostname, tokval) == 0)
155                                goto match;
156                        if ((tmp = strchr(hostname, '.')) != NULL &&
157                            strcasecmp(tmp, mydomain) == 0 &&
158                            strncasecmp(hostname, tokval, tmp-hostname) == 0 &&
159                            tokval[tmp - hostname] == '\0')
160                                goto match; */
161                        if ((tmp = strchr(host, '.')) != NULL &&
162                            strcasecmp(tmp, mydomain) == 0 &&
163                            strncasecmp(host, tokval, tmp - host) == 0 &&
164                            tokval[tmp - host] == '\0')
165                                goto match;
166                        continue;
167                }
168        match:
169                while ((t = token()) && t != MACHINE && t != DEFAULT) switch(t) {
170
171                case LOGIN:
172                        if (token()) {
173                                if (*aname == 0) {
174                                  char *newp;
175                                  newp = malloc((unsigned) strlen(tokval) + 1);
176                                  if (newp == NULL)
177                                    {
178                                      warnx(_("out of memory"));
179                                      goto bad;
180                                    }
181                                  *aname = strcpy(newp, tokval);
182                                } else {
183                                        if (strcmp(*aname, tokval))
184                                                goto next;
185                                }
186                        }
187                        break;
188                case PASSWD:
189                        if (strcmp(*aname, "anonymous") &&
190                            fstat64(fileno(cfile), &stb) >= 0 &&
191                            (stb.st_mode & 077) != 0) {
192        warnx(_("Error: .netrc file is readable by others."));
193        warnx(_("Remove password or make file unreadable by others."));
194                                goto bad;
195                        }
196                        if (token() && *apass == 0) {
197                                char *newp;
198                                newp = malloc((unsigned) strlen(tokval) + 1);
199                                if (newp == NULL)
200                                  {
201                                    warnx(_("out of memory"));
202                                    goto bad;
203                                  }
204                                *apass = strcpy(newp, tokval);
205                        }
206                        break;
207                case ACCOUNT:
208#if 0
209                        if (fstat64(fileno(cfile), &stb) >= 0
210                            && (stb.st_mode & 077) != 0) {
211        warnx("Error: .netrc file is readable by others.");
212        warnx("Remove account or make file unreadable by others.");
213                                goto bad;
214                        }
215                        if (token() && *aacct == 0) {
216                                *aacct = malloc((unsigned) strlen(tokval) + 1);
217                                (void) strcpy(*aacct, tokval);
218                        }
219#endif
220                        break;
221                case MACDEF:
222#if 0
223                        if (proxy) {
224                                (void) fclose(cfile);
225                                return (0);
226                        }
227                        while ((c=getc_unlocked(cfile)) != EOF && c == ' '
228                               || c == '\t');
229                        if (c == EOF || c == '\n') {
230                                printf("Missing macdef name argument.\n");
231                                goto bad;
232                        }
233                        if (macnum == 16) {
234                                printf("Limit of 16 macros have already been defined\n");
235                                goto bad;
236                        }
237                        tmp = macros[macnum].mac_name;
238                        *tmp++ = c;
239                        for (i=0; i < 8 && (c=getc_unlocked(cfile)) != EOF &&
240                            !isspace(c); ++i) {
241                                *tmp++ = c;
242                        }
243                        if (c == EOF) {
244                                printf("Macro definition missing null line terminator.\n");
245                                goto bad;
246                        }
247                        *tmp = '\0';
248                        if (c != '\n') {
249                                while ((c=getc_unlocked(cfile)) != EOF
250                                       && c != '\n');
251                        }
252                        if (c == EOF) {
253                                printf("Macro definition missing null line terminator.\n");
254                                goto bad;
255                        }
256                        if (macnum == 0) {
257                                macros[macnum].mac_start = macbuf;
258                        }
259                        else {
260                                macros[macnum].mac_start = macros[macnum-1].mac_end + 1;
261                        }
262                        tmp = macros[macnum].mac_start;
263                        while (tmp != macbuf + 4096) {
264                                if ((c=getc_unlocked(cfile)) == EOF) {
265                                printf("Macro definition missing null line terminator.\n");
266                                        goto bad;
267                                }
268                                *tmp = c;
269                                if (*tmp == '\n') {
270                                        if (*(tmp-1) == '\0') {
271                                           macros[macnum++].mac_end = tmp - 1;
272                                           break;
273                                        }
274                                        *tmp = '\0';
275                                }
276                                tmp++;
277                        }
278                        if (tmp == macbuf + 4096) {
279                                printf("4K macro buffer exceeded\n");
280                                goto bad;
281                        }
282#endif
283                        break;
284                default:
285                        warnx2(_("Unknown .netrc keyword %s"), tokval);
286                        break;
287                }
288                goto done;
289        }
290done:
291        (void) fclose(cfile);
292        return (0);
293bad:
294        (void) fclose(cfile);
295        return (-1);
296}
297libc_hidden_def (ruserpass)
298
299static int
300token()
301{
302        char *cp;
303        int c;
304        int i;
305
306        if (feof(cfile) || ferror(cfile))
307                return (0);
308        while ((c = getc_unlocked(cfile)) != EOF &&
309            (c == '\n' || c == '\t' || c == ' ' || c == ','))
310                continue;
311        if (c == EOF)
312                return (0);
313        cp = tokval;
314        if (c == '"') {
315                while ((c = getc_unlocked(cfile)) != EOF && c != '"') {
316                        if (c == '\\')
317                                c = getc_unlocked(cfile);
318                        *cp++ = c;
319                }
320        } else {
321                *cp++ = c;
322                while ((c = getc_unlocked(cfile)) != EOF
323                    && c != '\n' && c != '\t' && c != ' ' && c != ',') {
324                        if (c == '\\')
325                                c = getc_unlocked(cfile);
326                        *cp++ = c;
327                }
328        }
329        *cp = 0;
330        if (tokval[0] == 0)
331                return (0);
332        for (i = 0; i < (int) (sizeof (toktab) / sizeof (toktab[0])); ++i)
333                if (!strcmp(&tokstr[toktab[i].tokstr_off], tokval))
334                        return toktab[i].tval;
335        return (ID);
336}
Note: See TracBrowser for help on using the repository browser.