126053Sminshall /* 2*62012Sbostic * Copyright (c) 1985, 1993 3*62012Sbostic * The Regents of the University of California. All rights reserved. 433737Sbostic * 542666Sbostic * %sccs.include.redist.c% 626053Sminshall */ 726053Sminshall 826053Sminshall #ifndef lint 9*62012Sbostic static char sccsid[] = "@(#)ruserpass.c 8.1 (Berkeley) 06/06/93"; 1033737Sbostic #endif /* not lint */ 1126053Sminshall 1235631Sbostic #include <sys/types.h> 1326053Sminshall #include <stdio.h> 1426053Sminshall #include <utmp.h> 1526053Sminshall #include <ctype.h> 1626053Sminshall #include <sys/stat.h> 1726053Sminshall #include <errno.h> 1836940Skarels #include "ftp_var.h" 1926053Sminshall 2026053Sminshall char *renvlook(), *malloc(), *index(), *getenv(), *getpass(), *getlogin(); 2126498Sminshall char *strcpy(); 2226053Sminshall struct utmp *getutmp(); 2326053Sminshall static FILE *cfile; 2426053Sminshall 2526053Sminshall #define DEFAULT 1 2626053Sminshall #define LOGIN 2 2726053Sminshall #define PASSWD 3 2826053Sminshall #define ACCOUNT 4 2926053Sminshall #define MACDEF 5 3026053Sminshall #define ID 10 3136940Skarels #define MACH 11 3226053Sminshall 3326053Sminshall static char tokval[100]; 3426053Sminshall 3526053Sminshall static struct toktab { 3626053Sminshall char *tokstr; 3726053Sminshall int tval; 3826053Sminshall } toktab[]= { 3926053Sminshall "default", DEFAULT, 4026053Sminshall "login", LOGIN, 4126053Sminshall "password", PASSWD, 4236940Skarels "passwd", PASSWD, 4326053Sminshall "account", ACCOUNT, 4436940Skarels "machine", MACH, 4526053Sminshall "macdef", MACDEF, 4626053Sminshall 0, 0 4726053Sminshall }; 4826053Sminshall 4936940Skarels ruserpass(host, aname, apass, aacct) 5026053Sminshall char *host, **aname, **apass, **aacct; 5126053Sminshall { 5226498Sminshall char *hdir, buf[BUFSIZ], *tmp; 5336940Skarels char myname[MAXHOSTNAMELEN], *mydomain; 5436935Skarels int t, i, c, usedefault = 0; 5526053Sminshall struct stat stb; 5646828Sbostic static int token(); 5726053Sminshall 5826053Sminshall hdir = getenv("HOME"); 5926053Sminshall if (hdir == NULL) 6026053Sminshall hdir = "."; 6126498Sminshall (void) sprintf(buf, "%s/.netrc", hdir); 6226053Sminshall cfile = fopen(buf, "r"); 6326053Sminshall if (cfile == NULL) { 6426053Sminshall if (errno != ENOENT) 6526053Sminshall perror(buf); 6626053Sminshall return(0); 6726053Sminshall } 6836940Skarels if (gethostname(myname, sizeof(myname)) < 0) 6936940Skarels myname[0] = '\0'; 7036940Skarels if ((mydomain = index(myname, '.')) == NULL) 7136940Skarels mydomain = ""; 7226053Sminshall next: 7326053Sminshall while ((t = token())) switch(t) { 7426053Sminshall 7526053Sminshall case DEFAULT: 7636935Skarels usedefault = 1; 7736935Skarels /* FALL THROUGH */ 7826053Sminshall 7936940Skarels case MACH: 8036940Skarels if (!usedefault) { 8136940Skarels if (token() != ID) 8236940Skarels continue; 8336940Skarels /* 8436940Skarels * Allow match either for user's input host name 8536940Skarels * or official hostname. Also allow match of 8636940Skarels * incompletely-specified host in local domain. 8736940Skarels */ 8836940Skarels if (strcasecmp(host, tokval) == 0) 8936940Skarels goto match; 9036940Skarels if (strcasecmp(hostname, tokval) == 0) 9136940Skarels goto match; 9236940Skarels if ((tmp = index(hostname, '.')) != NULL && 9336940Skarels strcasecmp(tmp, mydomain) == 0 && 9436940Skarels strncasecmp(hostname, tokval, tmp-hostname) == 0 && 9536940Skarels tokval[tmp - hostname] == '\0') 9636940Skarels goto match; 9736940Skarels if ((tmp = index(host, '.')) != NULL && 9836940Skarels strcasecmp(tmp, mydomain) == 0 && 9936940Skarels strncasecmp(host, tokval, tmp - host) == 0 && 10036940Skarels tokval[tmp - host] == '\0') 10136940Skarels goto match; 10226053Sminshall continue; 10336940Skarels } 10436940Skarels match: 10536940Skarels while ((t = token()) && t != MACH && t != DEFAULT) switch(t) { 10626053Sminshall 10726053Sminshall case LOGIN: 10826053Sminshall if (token()) 10926053Sminshall if (*aname == 0) { 11026498Sminshall *aname = malloc((unsigned) strlen(tokval) + 1); 11126498Sminshall (void) strcpy(*aname, tokval); 11226053Sminshall } else { 11326053Sminshall if (strcmp(*aname, tokval)) 11426053Sminshall goto next; 11526053Sminshall } 11626053Sminshall break; 11726053Sminshall case PASSWD: 11836940Skarels if (strcmp(*aname, "anonymous") && 11936940Skarels fstat(fileno(cfile), &stb) >= 0 && 12036940Skarels (stb.st_mode & 077) != 0) { 12154057Sandrew fprintf(stderr, "Error: .netrc file is readable by others.\n"); 12254057Sandrew fprintf(stderr, 12354057Sandrew "Remove password or make file unreadable by others.\n\n"); 12436940Skarels goto bad; 12526053Sminshall } 12626053Sminshall if (token() && *apass == 0) { 12726498Sminshall *apass = malloc((unsigned) strlen(tokval) + 1); 12826498Sminshall (void) strcpy(*apass, tokval); 12926053Sminshall } 13026053Sminshall break; 13126053Sminshall case ACCOUNT: 13226053Sminshall if (fstat(fileno(cfile), &stb) >= 0 13326053Sminshall && (stb.st_mode & 077) != 0) { 13454057Sandrew fprintf(stderr, "Error: .netrc file is readable by others.\n"); 13554057Sandrew fprintf(stderr, 13654057Sandrew "Remove account or make file unreadable by others.\n\n"); 13736940Skarels goto bad; 13826053Sminshall } 13926053Sminshall if (token() && *aacct == 0) { 14026498Sminshall *aacct = malloc((unsigned) strlen(tokval) + 1); 14126498Sminshall (void) strcpy(*aacct, tokval); 14226053Sminshall } 14326053Sminshall break; 14426053Sminshall case MACDEF: 14526053Sminshall if (proxy) { 14636940Skarels (void) fclose(cfile); 14726053Sminshall return(0); 14826053Sminshall } 14926053Sminshall while ((c=getc(cfile)) != EOF && c == ' ' || c == '\t'); 15026053Sminshall if (c == EOF || c == '\n') { 15126053Sminshall printf("Missing macdef name argument.\n"); 15236940Skarels goto bad; 15326053Sminshall } 15426053Sminshall if (macnum == 16) { 15526053Sminshall printf("Limit of 16 macros have already been defined\n"); 15636940Skarels goto bad; 15726053Sminshall } 15826053Sminshall tmp = macros[macnum].mac_name; 15926053Sminshall *tmp++ = c; 16026053Sminshall for (i=0; i < 8 && (c=getc(cfile)) != EOF && 16126053Sminshall !isspace(c); ++i) { 16226053Sminshall *tmp++ = c; 16326053Sminshall } 16426053Sminshall if (c == EOF) { 16526053Sminshall printf("Macro definition missing null line terminator.\n"); 16636940Skarels goto bad; 16726053Sminshall } 16826053Sminshall *tmp = '\0'; 16926053Sminshall if (c != '\n') { 17026053Sminshall while ((c=getc(cfile)) != EOF && c != '\n'); 17126053Sminshall } 17226053Sminshall if (c == EOF) { 17326053Sminshall printf("Macro definition missing null line terminator.\n"); 17436940Skarels goto bad; 17526053Sminshall } 17626053Sminshall if (macnum == 0) { 17726053Sminshall macros[macnum].mac_start = macbuf; 17826053Sminshall } 17926053Sminshall else { 18026053Sminshall macros[macnum].mac_start = macros[macnum-1].mac_end + 1; 18126053Sminshall } 18226053Sminshall tmp = macros[macnum].mac_start; 18326053Sminshall while (tmp != macbuf + 4096) { 18426053Sminshall if ((c=getc(cfile)) == EOF) { 18526053Sminshall printf("Macro definition missing null line terminator.\n"); 18636940Skarels goto bad; 18726053Sminshall } 18826053Sminshall *tmp = c; 18926053Sminshall if (*tmp == '\n') { 19026053Sminshall if (*(tmp-1) == '\0') { 19126053Sminshall macros[macnum++].mac_end = tmp - 1; 19226053Sminshall break; 19326053Sminshall } 19426053Sminshall *tmp = '\0'; 19526053Sminshall } 19626053Sminshall tmp++; 19726053Sminshall } 19826053Sminshall if (tmp == macbuf + 4096) { 19926053Sminshall printf("4K macro buffer exceeded\n"); 20036940Skarels goto bad; 20126053Sminshall } 20226053Sminshall break; 20326053Sminshall default: 20426054Sminshall fprintf(stderr, "Unknown .netrc keyword %s\n", tokval); 20526053Sminshall break; 20626053Sminshall } 20726053Sminshall goto done; 20826053Sminshall } 20926053Sminshall done: 21026498Sminshall (void) fclose(cfile); 21126498Sminshall return(0); 21236940Skarels bad: 21336940Skarels (void) fclose(cfile); 21436940Skarels return(-1); 21526053Sminshall } 21626053Sminshall 21726053Sminshall static 21826053Sminshall token() 21926053Sminshall { 22026053Sminshall char *cp; 22126053Sminshall int c; 22226053Sminshall struct toktab *t; 22326053Sminshall 22454057Sandrew if (feof(cfile) || ferror(cfile)) 22526053Sminshall return (0); 22626053Sminshall while ((c = getc(cfile)) != EOF && 22726053Sminshall (c == '\n' || c == '\t' || c == ' ' || c == ',')) 22826053Sminshall continue; 22926053Sminshall if (c == EOF) 23026053Sminshall return (0); 23126053Sminshall cp = tokval; 23226053Sminshall if (c == '"') { 23326053Sminshall while ((c = getc(cfile)) != EOF && c != '"') { 23426053Sminshall if (c == '\\') 23526053Sminshall c = getc(cfile); 23626053Sminshall *cp++ = c; 23726053Sminshall } 23826053Sminshall } else { 23926053Sminshall *cp++ = c; 24026053Sminshall while ((c = getc(cfile)) != EOF 24126053Sminshall && c != '\n' && c != '\t' && c != ' ' && c != ',') { 24226053Sminshall if (c == '\\') 24326053Sminshall c = getc(cfile); 24426053Sminshall *cp++ = c; 24526053Sminshall } 24626053Sminshall } 24726053Sminshall *cp = 0; 24826053Sminshall if (tokval[0] == 0) 24926053Sminshall return (0); 25026053Sminshall for (t = toktab; t->tokstr; t++) 25126053Sminshall if (!strcmp(t->tokstr, tokval)) 25226053Sminshall return (t->tval); 25326053Sminshall return (ID); 25426053Sminshall } 255