(linenum→info "unix/slp.c:2238")

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