BSD 4_4 release
[unix-history] / usr / src / usr.bin / ftp / ruserpass.c
index a3bfa83..1247b8d 100644 (file)
@@ -1,62 +1,60 @@
 /*
 /*
- * Copyright (c) 1985 Regents of the University of California.
- * All rights reserved.
+ * Copyright (c) 1985, 1993
+ *     The Regents of the University of California.  All rights reserved.
  *
  *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by the University of California, Berkeley.  The name of the
- * University may not be used to endorse or promote products derived
- * from this software without specific prior written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
  */
 
 #ifndef lint
  */
 
 #ifndef lint
-static char sccsid[] = "@(#)ruserpass.c        1.6 (Berkeley) %G%";
+static char sccsid[] = "@(#)ruserpass.c        8.1 (Berkeley) 6/6/93";
 #endif /* not lint */
 
 #endif /* not lint */
 
-struct macel {
-       char mac_name[9];       /* macro name */
-       char *mac_start;        /* start of macro in macbuf */
-       char *mac_end;          /* end of macro in macbuf */
-};
-
-extern int macnum, proxy;                      /* number of defined macros */
-extern struct macel macros[16], *macpt;
-extern char macbuf[4096];
-
 #include <sys/types.h>
 #include <stdio.h>
 #include <utmp.h>
 #include <ctype.h>
 #include <sys/stat.h>
 #include <errno.h>
 #include <sys/types.h>
 #include <stdio.h>
 #include <utmp.h>
 #include <ctype.h>
 #include <sys/stat.h>
 #include <errno.h>
+#include "ftp_var.h"
 
 char   *renvlook(), *malloc(), *index(), *getenv(), *getpass(), *getlogin();
 char   *strcpy();
 struct utmp *getutmp();
 static FILE *cfile;
 
 
 char   *renvlook(), *malloc(), *index(), *getenv(), *getpass(), *getlogin();
 char   *strcpy();
 struct utmp *getutmp();
 static FILE *cfile;
 
-ruserpass(host, aname, apass, aacct)
-       char *host, **aname, **apass, **aacct;
-{
-
-       /* renv(host, aname, apass, aacct);
-       if (*aname == 0 || *apass == 0) */
-               return(rnetrc(host, aname, apass, aacct));
-}
-
 #define        DEFAULT 1
 #define        LOGIN   2
 #define        PASSWD  3
 #define        ACCOUNT 4
 #define MACDEF  5
 #define        ID      10
 #define        DEFAULT 1
 #define        LOGIN   2
 #define        PASSWD  3
 #define        ACCOUNT 4
 #define MACDEF  5
 #define        ID      10
-#define        MACHINE 11
+#define        MACH    11
 
 static char tokval[100];
 
 
 static char tokval[100];
 
@@ -67,20 +65,21 @@ static struct toktab {
        "default",      DEFAULT,
        "login",        LOGIN,
        "password",     PASSWD,
        "default",      DEFAULT,
        "login",        LOGIN,
        "password",     PASSWD,
+       "passwd",       PASSWD,
        "account",      ACCOUNT,
        "account",      ACCOUNT,
-       "machine",      MACHINE,
+       "machine",      MACH,
        "macdef",       MACDEF,
        0,              0
 };
 
        "macdef",       MACDEF,
        0,              0
 };
 
-static
-rnetrc(host, aname, apass, aacct)
+ruserpass(host, aname, apass, aacct)
        char *host, **aname, **apass, **aacct;
 {
        char *hdir, buf[BUFSIZ], *tmp;
        char *host, **aname, **apass, **aacct;
 {
        char *hdir, buf[BUFSIZ], *tmp;
-       int t, i, c;
+       char myname[MAXHOSTNAMELEN], *mydomain;
+       int t, i, c, usedefault = 0;
        struct stat stb;
        struct stat stb;
-       extern int errno;
+       static int token();
 
        hdir = getenv("HOME");
        if (hdir == NULL)
 
        hdir = getenv("HOME");
        if (hdir == NULL)
@@ -92,17 +91,44 @@ rnetrc(host, aname, apass, aacct)
                        perror(buf);
                return(0);
        }
                        perror(buf);
                return(0);
        }
+       if (gethostname(myname, sizeof(myname)) < 0)
+               myname[0] = '\0';
+       if ((mydomain = index(myname, '.')) == NULL)
+               mydomain = "";
 next:
        while ((t = token())) switch(t) {
 
        case DEFAULT:
 next:
        while ((t = token())) switch(t) {
 
        case DEFAULT:
-               (void) token();
-               continue;
+               usedefault = 1;
+               /* FALL THROUGH */
 
 
-       case MACHINE:
-               if (token() != ID || strcmp(host, tokval))
+       case MACH:
+               if (!usedefault) {
+                       if (token() != ID)
+                               continue;
+                       /*
+                        * Allow match either for user's input host name
+                        * or official hostname.  Also allow match of 
+                        * incompletely-specified host in local domain.
+                        */
+                       if (strcasecmp(host, tokval) == 0)
+                               goto match;
+                       if (strcasecmp(hostname, tokval) == 0)
+                               goto match;
+                       if ((tmp = index(hostname, '.')) != NULL &&
+                           strcasecmp(tmp, mydomain) == 0 &&
+                           strncasecmp(hostname, tokval, tmp-hostname) == 0 &&
+                           tokval[tmp - hostname] == '\0')
+                               goto match;
+                       if ((tmp = index(host, '.')) != NULL &&
+                           strcasecmp(tmp, mydomain) == 0 &&
+                           strncasecmp(host, tokval, tmp - host) == 0 &&
+                           tokval[tmp - host] == '\0')
+                               goto match;
                        continue;
                        continue;
-               while ((t = token()) && t != MACHINE) switch(t) {
+               }
+       match:
+               while ((t = token()) && t != MACH && t != DEFAULT) switch(t) {
 
                case LOGIN:
                        if (token())
 
                case LOGIN:
                        if (token())
@@ -115,11 +141,13 @@ next:
                                }
                        break;
                case PASSWD:
                                }
                        break;
                case PASSWD:
-                       if (fstat(fileno(cfile), &stb) >= 0
-                           && (stb.st_mode & 077) != 0) {
-       fprintf(stderr, "Error - .netrc file not correct mode.\n");
-       fprintf(stderr, "Remove password or correct mode.\n");
-                               return(-1);
+                       if (strcmp(*aname, "anonymous") &&
+                           fstat(fileno(cfile), &stb) >= 0 &&
+                           (stb.st_mode & 077) != 0) {
+       fprintf(stderr, "Error: .netrc file is readable by others.\n");
+       fprintf(stderr, 
+               "Remove password or make file unreadable by others.\n\n");
+                               goto bad;
                        }
                        if (token() && *apass == 0) {
                                *apass = malloc((unsigned) strlen(tokval) + 1);
                        }
                        if (token() && *apass == 0) {
                                *apass = malloc((unsigned) strlen(tokval) + 1);
@@ -129,9 +157,10 @@ next:
                case ACCOUNT:
                        if (fstat(fileno(cfile), &stb) >= 0
                            && (stb.st_mode & 077) != 0) {
                case ACCOUNT:
                        if (fstat(fileno(cfile), &stb) >= 0
                            && (stb.st_mode & 077) != 0) {
-       fprintf(stderr, "Error - .netrc file not correct mode.\n");
-       fprintf(stderr, "Remove account or correct mode.\n");
-                               return(-1);
+       fprintf(stderr, "Error: .netrc file is readable by others.\n");
+       fprintf(stderr, 
+               "Remove account or make file unreadable by others.\n\n");
+                               goto bad;
                        }
                        if (token() && *aacct == 0) {
                                *aacct = malloc((unsigned) strlen(tokval) + 1);
                        }
                        if (token() && *aacct == 0) {
                                *aacct = malloc((unsigned) strlen(tokval) + 1);
@@ -140,16 +169,17 @@ next:
                        break;
                case MACDEF:
                        if (proxy) {
                        break;
                case MACDEF:
                        if (proxy) {
+                               (void) fclose(cfile);
                                return(0);
                        }
                        while ((c=getc(cfile)) != EOF && c == ' ' || c == '\t');
                        if (c == EOF || c == '\n') {
                                printf("Missing macdef name argument.\n");
                                return(0);
                        }
                        while ((c=getc(cfile)) != EOF && c == ' ' || c == '\t');
                        if (c == EOF || c == '\n') {
                                printf("Missing macdef name argument.\n");
-                               return(-1);
+                               goto bad;
                        }
                        if (macnum == 16) {
                                printf("Limit of 16 macros have already been defined\n");
                        }
                        if (macnum == 16) {
                                printf("Limit of 16 macros have already been defined\n");
-                               return(-1);
+                               goto bad;
                        }
                        tmp = macros[macnum].mac_name;
                        *tmp++ = c;
                        }
                        tmp = macros[macnum].mac_name;
                        *tmp++ = c;
@@ -159,7 +189,7 @@ next:
                        }
                        if (c == EOF) {
                                printf("Macro definition missing null line terminator.\n");
                        }
                        if (c == EOF) {
                                printf("Macro definition missing null line terminator.\n");
-                               return(-1);
+                               goto bad;
                        }
                        *tmp = '\0';
                        if (c != '\n') {
                        }
                        *tmp = '\0';
                        if (c != '\n') {
@@ -167,7 +197,7 @@ next:
                        }
                        if (c == EOF) {
                                printf("Macro definition missing null line terminator.\n");
                        }
                        if (c == EOF) {
                                printf("Macro definition missing null line terminator.\n");
-                               return(-1);
+                               goto bad;
                        }
                        if (macnum == 0) {
                                macros[macnum].mac_start = macbuf;
                        }
                        if (macnum == 0) {
                                macros[macnum].mac_start = macbuf;
@@ -179,7 +209,7 @@ next:
                        while (tmp != macbuf + 4096) {
                                if ((c=getc(cfile)) == EOF) {
                                printf("Macro definition missing null line terminator.\n");
                        while (tmp != macbuf + 4096) {
                                if ((c=getc(cfile)) == EOF) {
                                printf("Macro definition missing null line terminator.\n");
-                                       return(-1);
+                                       goto bad;
                                }
                                *tmp = c;
                                if (*tmp == '\n') {
                                }
                                *tmp = c;
                                if (*tmp == '\n') {
@@ -193,7 +223,7 @@ next:
                        }
                        if (tmp == macbuf + 4096) {
                                printf("4K macro buffer exceeded\n");
                        }
                        if (tmp == macbuf + 4096) {
                                printf("4K macro buffer exceeded\n");
-                               return(-1);
+                               goto bad;
                        }
                        break;
                default:
                        }
                        break;
                default:
@@ -205,6 +235,9 @@ next:
 done:
        (void) fclose(cfile);
        return(0);
 done:
        (void) fclose(cfile);
        return(0);
+bad:
+       (void) fclose(cfile);
+       return(-1);
 }
 
 static
 }
 
 static
@@ -214,7 +247,7 @@ token()
        int c;
        struct toktab *t;
 
        int c;
        struct toktab *t;
 
-       if (feof(cfile))
+       if (feof(cfile) || ferror(cfile))
                return (0);
        while ((c = getc(cfile)) != EOF &&
            (c == '\n' || c == '\t' || c == ' ' || c == ','))
                return (0);
        while ((c = getc(cfile)) != EOF &&
            (c == '\n' || c == '\t' || c == ' ' || c == ','))