1 /* 2 * Copyright (c) 1985 Regents of the University of California. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms are permitted 6 * provided that the above copyright notice and this paragraph are 7 * duplicated in all such forms and that any documentation, 8 * advertising materials, and other materials related to such 9 * distribution and use acknowledge that the software was developed 10 * by the University of California, Berkeley. The name of the 11 * University may not be used to endorse or promote products derived 12 * from this software without specific prior written permission. 13 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 14 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 15 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 16 */ 17 18 #include "precomp.h" 19 20 #ifndef lint 21 static char sccsid[] = "@(#)ruserpass.c 5.1 (Berkeley) 3/1/89"; 22 #endif /* not lint */ 23 24 struct utmp *getutmp(); 25 static FILE *cfile; 26 27 #ifndef MAXHOSTNAMELEN 28 #define MAXHOSTNAMELEN 64 29 #endif 30 31 #define DEFAULT 1 32 #define LOGIN 2 33 #define PASSWD 3 34 #define ACCOUNT 4 35 #define MACDEF 5 36 #define ID 10 37 #define MACH 11 38 39 static char tokval[100]; 40 41 static struct toktab { 42 const char *tokstr; 43 int tval; 44 } toktab[]= { 45 {"default", DEFAULT}, 46 {"login", LOGIN}, 47 {"password", PASSWD}, 48 {"passwd", PASSWD}, 49 {"account", ACCOUNT}, 50 {"machine", MACH}, 51 {"macdef", MACDEF}, 52 {0, 0} 53 }; 54 55 extern char *hostname; 56 static int token(void); 57 58 int ruserpass(const char *host, char **aname, char **apass, char **aacct) 59 { 60 const char *hdir, *mydomain; 61 char buf[BUFSIZ], *tmp; 62 char myname[MAXHOSTNAMELEN]; 63 int t, i, c, usedefault = 0; 64 struct stat stb; 65 66 hdir = getenv("HOME"); 67 if (hdir == NULL) 68 hdir = "."; 69 (void) sprintf(buf, "%s/.netrc", hdir); 70 cfile = fopen(buf, "r"); 71 if (cfile == NULL) { 72 if (errno != ENOENT) 73 perror(buf); 74 return(0); 75 } 76 77 78 if (gethostname(myname, sizeof(myname)) < 0) 79 myname[0] = '\0'; 80 if ((mydomain = index(myname, '.')) == NULL) 81 mydomain = ""; 82 next: 83 while ((t = token())) switch(t) { 84 85 case DEFAULT: 86 usedefault = 1; 87 /* FALL THROUGH */ 88 89 case MACH: 90 if (!usedefault) { 91 if (token() != ID) 92 continue; 93 /* 94 * Allow match either for user's input host name 95 * or official hostname. Also allow match of 96 * incompletely-specified host in local domain. 97 */ 98 if (strcasecmp(host, tokval) == 0) 99 goto match; 100 if (strcasecmp(hostname, tokval) == 0) 101 goto match; 102 if ((tmp = index(hostname, '.')) != NULL && 103 strcasecmp(tmp, mydomain) == 0 && 104 strncasecmp(hostname, tokval, tmp - hostname) == 0 && 105 tokval[tmp - hostname] == '\0') 106 goto match; 107 if ((tmp = index(host, '.')) != NULL && 108 strcasecmp(tmp, mydomain) == 0 && 109 strncasecmp(host, tokval, tmp - host) == 0 && 110 tokval[tmp - host] == '\0') 111 goto match; 112 continue; 113 } 114 match: 115 while ((t = token()) && t != MACH && t != DEFAULT) switch(t) { 116 117 case LOGIN: 118 if (token()) { 119 if (*aname == 0) { 120 *aname = malloc((unsigned) strlen(tokval) + 1); 121 (void) strcpy(*aname, tokval); 122 } else { 123 if (strcmp(*aname, tokval)) 124 goto next; 125 } 126 } 127 break; 128 case PASSWD: 129 if (strcmp(*aname, "anonymous") && 130 fstat(fileno(cfile), &stb) >= 0 && 131 (stb.st_mode & 077) != 0) { 132 fprintf(stderr, "Error - .netrc file not correct mode.\n"); 133 fprintf(stderr, "Remove password or correct mode.\n"); 134 goto bad; 135 } 136 if (token() && *apass == 0) { 137 *apass = malloc((unsigned) strlen(tokval) + 1); 138 (void) strcpy(*apass, tokval); 139 } 140 break; 141 case ACCOUNT: 142 if (fstat(fileno(cfile), &stb) >= 0 143 && (stb.st_mode & 077) != 0) { 144 fprintf(stderr, "Error - .netrc file not correct mode.\n"); 145 fprintf(stderr, "Remove account or correct mode.\n"); 146 goto bad; 147 } 148 if (token() && *aacct == 0) { 149 *aacct = malloc((unsigned) strlen(tokval) + 1); 150 (void) strcpy(*aacct, tokval); 151 } 152 break; 153 case MACDEF: 154 if (proxy) { 155 (void) fclose(cfile); 156 return(0); 157 } 158 while ((c=getc(cfile)) != EOF && (c == ' ' || c == '\t')); 159 if (c == EOF || c == '\n') { 160 printf("Missing macdef name argument.\n"); 161 goto bad; 162 } 163 if (macnum == 16) { 164 printf("Limit of 16 macros have already been defined\n"); 165 goto bad; 166 } 167 tmp = macros[macnum].mac_name; 168 *tmp++ = c; 169 for (i=0; i < 8 && (c=getc(cfile)) != EOF && 170 !isspace(c); ++i) { 171 *tmp++ = c; 172 } 173 if (c == EOF) { 174 printf("Macro definition missing null line terminator.\n"); 175 goto bad; 176 } 177 *tmp = '\0'; 178 if (c != '\n') { 179 while ((c=getc(cfile)) != EOF && c != '\n'); 180 } 181 if (c == EOF) { 182 printf("Macro definition missing null line terminator.\n"); 183 goto bad; 184 } 185 if (macnum == 0) { 186 macros[macnum].mac_start = macbuf; 187 } 188 else { 189 macros[macnum].mac_start = macros[macnum-1].mac_end + 1; 190 } 191 tmp = macros[macnum].mac_start; 192 while (tmp != macbuf + 4096) { 193 if ((c=getc(cfile)) == EOF) { 194 printf("Macro definition missing null line terminator.\n"); 195 goto bad; 196 } 197 *tmp = c; 198 if (*tmp == '\n') { 199 if (*(tmp-1) == '\0') { 200 macros[macnum++].mac_end = tmp - 1; 201 break; 202 } 203 *tmp = '\0'; 204 } 205 tmp++; 206 } 207 if (tmp == macbuf + 4096) { 208 printf("4K macro buffer exceeded\n"); 209 goto bad; 210 } 211 break; 212 default: 213 fprintf(stderr, "Unknown .netrc keyword %s\n", tokval); 214 break; 215 } 216 goto done; 217 } 218 done: 219 (void) fclose(cfile); 220 return(0); 221 bad: 222 (void) fclose(cfile); 223 return(-1); 224 } 225 226 static int token(void) 227 { 228 char *cp; 229 int c; 230 struct toktab *t; 231 232 if (feof(cfile)) 233 return (0); 234 while ((c = getc(cfile)) != EOF && 235 (c == '\r' || c == '\n' || c == '\t' || c == ' ' || c == ',')) 236 continue; 237 if (c == EOF) 238 return (0); 239 cp = tokval; 240 if (c == '"') { 241 while ((c = getc(cfile)) != EOF && c != '"') { 242 if (c == '\\') 243 c = getc(cfile); 244 *cp++ = c; 245 } 246 } else { 247 *cp++ = c; 248 while ((c = getc(cfile)) != EOF 249 && c != '\n' && c != '\t' && c != ' ' && c != ',' && c != '\r') { 250 if (c == '\\') 251 c = getc(cfile); 252 *cp++ = c; 253 } 254 } 255 *cp = 0; 256 if (tokval[0] == 0) 257 return (0); 258 for (t = toktab; t->tokstr; t++) 259 if (!strcmp(t->tokstr, tokval)) 260 return (t->tval); 261 return (ID); 262 } 263