00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include <sys/types.h>
00015 #include <string.h>
00016 #include <stdio.h>
00017 #include <ctype.h>
00018 #include <limits.h>
00019 #include <pwd.h>
00020 #include <net/hton.h>
00021 #include <net/gen/in.h>
00022 #include <net/gen/netdb.h>
00023 #include <net/gen/inet.h>
00024 #include <net/gen/socket.h>
00025 #include <net/gen/nameser.h>
00026
00027
00028 int __check_rhosts_file = 1;
00029
00030 static int cidr_aton(char *word, ipaddr_t *addr, ipaddr_t *mask)
00031
00032 {
00033 char *slash;
00034 int r;
00035 static char S32[]= "/32";
00036
00037 if (*word == 0) return 0;
00038
00039 if ((slash= strchr(word, '/')) == NULL) slash= S32;
00040
00041 *slash= 0;
00042 r= inet_aton(word, addr);
00043 *slash++= '/';
00044 if (!r) return 0;
00045
00046 r= 0;
00047 while ((*slash - '0') < 10u) {
00048 r= 10*r + (*slash++ - '0');
00049 if (r > 32) return 0;
00050 }
00051 if (*slash != 0 || slash[-1] == '/') return 0;
00052 *mask= htonl(r == 0 ? 0L : (0xFFFFFFFFUL >> (32 - r)) << (32 - r));
00053 return 1;
00054 }
00055
00056 static int match(const char *word, const char *pattern)
00057
00058 {
00059 unsigned cw, cp;
00060 #define lc(c, d) ((((c)= (d)) - 'A') <= ('Z' - 'A') ? (c)+= ('a' - 'A') : 0)
00061
00062 for (;;) {
00063 lc(cw, *word);
00064 lc(cp, *pattern);
00065
00066 if (cp == '*') {
00067 do pattern++; while (*pattern == '*');
00068 lc(cp, *pattern);
00069 if (cp == 0) return 1;
00070
00071 while (cw != 0) {
00072 if (cw == cp && match(word+1, pattern+1)) return 1;
00073 word++;
00074 lc(cw, *word);
00075 }
00076 return 0;
00077 } else
00078 if (cw == 0 || cp == 0) {
00079 return cw == cp;
00080 } else
00081 if (cw == cp) {
00082 word++;
00083 pattern++;
00084 } else {
00085 return 0;
00086 }
00087 }
00088 #undef lc
00089 }
00090
00091 static int get_name(ipaddr_t addr, char *name)
00092
00093
00094
00095
00096 {
00097 struct hostent *he;
00098 int ok, i;
00099
00100 ok= 0;
00101 he= gethostbyaddr((char *) &addr, sizeof(addr), AF_INET);
00102 if (he != NULL) {
00103 strcpy(name, he->h_name);
00104 he= gethostbyname(name);
00105
00106 if (he != NULL && he->h_addrtype == AF_INET) {
00107 for (i= 0; he->h_addr_list[i] != NULL; i++) {
00108 if (memcmp(he->h_addr_list[i], &addr, sizeof(addr)) == 0) {
00109 ok= 1;
00110 break;
00111 }
00112 }
00113 }
00114 }
00115 strcpy(name, ok ? he->h_name : inet_ntoa(addr));
00116 return ok;
00117 }
00118
00119 int __ivaliduser(FILE *hostf, unsigned long raddr,
00120 const char *luser, const char *ruser)
00121 {
00122 register char *p;
00123 char buf[MAXDNAME + 128];
00124 char rhost[MAXDNAME];
00125 char *word[2];
00126 int i, ch, got_name;
00127 ipaddr_t addr, mask;
00128
00129 got_name = -1;
00130
00131 while (fgets(buf, sizeof(buf), hostf)) {
00132
00133 if (strchr(buf, '\n') == NULL) {
00134 while ((ch = fgetc(hostf)) != '\n' && ch != EOF);
00135 continue;
00136 }
00137 i = 0;
00138 p = buf;
00139 for (;;) {
00140 while (isspace(*p)) *p++ = '\0';
00141 if (*p == '\0') break;
00142 if (i < 2) word[i] = p;
00143 i++;
00144 while (*p != '\0' && !isspace(*p)) p++;
00145 }
00146 if (i != 1 && i != 2) continue;
00147 if (word[0][0] == '#') continue;
00148 if (strcmp(ruser, i == 2 ? word[1] : luser) != 0) continue;
00149
00150 if (cidr_aton(word[0], &addr, &mask)) {
00151 if (((raddr ^ addr) & mask) == 0) return (0);
00152 continue;
00153 }
00154
00155 if (got_name == -1) got_name = get_name(raddr, rhost);
00156 if (match(rhost, word[0])) return (0);
00157 }
00158 return (-1);
00159 }
00160
00161 int iruserok(unsigned long raddr, int superuser,
00162 const char *ruser, const char *luser)
00163 {
00164
00165 struct passwd *pwd;
00166 FILE *hostf;
00167 int i, r;
00168 char pbuf[PATH_MAX];
00169
00170 for (i = 0; i < 2; i++) {
00171 if (i == 0) {
00172 strcpy(pbuf, _PATH_HEQUIV);
00173 } else {
00174 if (!__check_rhosts_file) return (-1);
00175 if ((pwd = getpwnam(luser)) == NULL) return (-1);
00176 (void)strcpy(pbuf, pwd->pw_dir);
00177 (void)strcat(pbuf, "/.rhosts");
00178 }
00179
00180 if ((hostf = fopen(pbuf, "r")) == NULL) return (-1);
00181
00182 r = __ivaliduser(hostf, raddr, luser, ruser);
00183 (void)fclose(hostf);
00184 if (r == 0) return (0);
00185 }
00186 return (-1);
00187 }