Advertisement
Guest User

rlogind fixed for OpenBSD 7.1

a guest
Jul 13th, 2022
96
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.81 KB | None | 0 0
  1. --- rlogind.c.ori 2002-02-16 22:27:31.000000000 +0100
  2. +++ rlogind.c 2022-07-13 15:28:48.533930437 +0200
  3. @@ -59,7 +59,7 @@
  4. #include <sys/ioctl.h>
  5. #include <signal.h>
  6. #include <termios.h>
  7. -
  8. +#include <netgroup.h>
  9. #include <sys/socket.h>
  10. #include <netinet/in.h>
  11. #include <netinet/in_systm.h>
  12. @@ -67,7 +67,7 @@
  13. #include <netinet/ip_var.h>
  14. #include <arpa/inet.h>
  15. #include <netdb.h>
  16. -
  17. +#include <ctype.h>
  18. #include <pwd.h>
  19. #include <syslog.h>
  20. #include <util.h>
  21. @@ -127,7 +127,7 @@
  22. int argc;
  23. char *argv[];
  24. {
  25. - extern int __check_rhosts_file;
  26. + //extern int __check_rhosts_file;
  27. struct sockaddr_storage from;
  28. int ch, fromlen, on;
  29.  
  30. @@ -140,7 +140,7 @@
  31. /* check_all = 1; */
  32. break;
  33. case 'l':
  34. - __check_rhosts_file = 0;
  35. + //__check_rhosts_file = 0;
  36. break;
  37. case 'n':
  38. keepalive = 0;
  39. @@ -189,6 +189,325 @@
  40. doit(0, (struct sockaddr *)&from);
  41. }
  42.  
  43. +static int __ivaliduser_sa(FILE *, struct sockaddr *, socklen_t,
  44. + const char *, const char *);
  45. +static int __icheckhost(struct sockaddr *, socklen_t, const char *);
  46. +static char *__gethostloop(struct sockaddr *, socklen_t);
  47. +static int iruserok_sa(const void *, int, int, const char *, const char *);
  48. +
  49. +int
  50. +iruserok_sa(const void *raddr, int rlen, int superuser, const char *ruser,
  51. + const char *luser)
  52. +{
  53. + struct sockaddr *sa;
  54. + char *cp;
  55. + struct stat sbuf;
  56. + struct passwd pwstore, *pwd;
  57. + FILE *hostf;
  58. + uid_t uid;
  59. + int first;
  60. + char pbuf[PATH_MAX], pwbuf[_PW_BUF_LEN];
  61. +
  62. + sa = (struct sockaddr *)raddr;
  63. + first = 1;
  64. + hostf = superuser ? NULL : fopen(_PATH_HEQUIV, "re");
  65. +again:
  66. + if (hostf) {
  67. + if (__ivaliduser_sa(hostf, sa, rlen, luser, ruser) == 0) {
  68. + (void)fclose(hostf);
  69. + return (0);
  70. + }
  71. + (void)fclose(hostf);
  72. + }
  73. + if (first == 1) {
  74. + int len;
  75. +
  76. + first = 0;
  77. + pwd = NULL;
  78. + getpwnam_r(luser, &pwstore, pwbuf, sizeof(pwbuf), &pwd);
  79. + if (pwd == NULL)
  80. + return (-1);
  81. + len = snprintf(pbuf, sizeof pbuf, "%s/.rhosts", pwd->pw_dir);
  82. + if (len < 0 || len >= sizeof pbuf)
  83. + return (-1);
  84. +
  85. + /*
  86. + * Change effective uid while opening .rhosts. If root and
  87. + * reading an NFS mounted file system, can't read files that
  88. + * are protected read/write owner only.
  89. + */
  90. + uid = geteuid();
  91. + (void)seteuid(pwd->pw_uid);
  92. + hostf = fopen(pbuf, "re");
  93. + (void)seteuid(uid);
  94. +
  95. + if (hostf == NULL)
  96. + return (-1);
  97. + /*
  98. + * If not a regular file, or is owned by someone other than
  99. + * user or root or if writeable by anyone but the owner, quit.
  100. + */
  101. + cp = NULL;
  102. + if (lstat(pbuf, &sbuf) == -1)
  103. + cp = ".rhosts lstat failed";
  104. + else if (!S_ISREG(sbuf.st_mode))
  105. + cp = ".rhosts not regular file";
  106. + else if (fstat(fileno(hostf), &sbuf) == -1)
  107. + cp = ".rhosts fstat failed";
  108. + else if (sbuf.st_uid && sbuf.st_uid != pwd->pw_uid)
  109. + cp = "bad .rhosts owner";
  110. + else if (sbuf.st_mode & (S_IWGRP|S_IWOTH))
  111. + cp = ".rhosts writable by other than owner";
  112. + /* If there were any problems, quit. */
  113. + if (cp) {
  114. + (void)fclose(hostf);
  115. + return (-1);
  116. + }
  117. + goto again;
  118. + }
  119. + return (-1);
  120. +}
  121. +
  122. +int
  123. +__ivaliduser_sa(FILE *hostf, struct sockaddr *raddr, socklen_t salen,
  124. + const char *luser, const char *ruser)
  125. +{
  126. + char *user, *p;
  127. + char *buf;
  128. + const char *auser, *ahost;
  129. + int hostok, userok;
  130. + char *rhost = (char *)-1;
  131. + char domain[HOST_NAME_MAX+1];
  132. + size_t buflen;
  133. +
  134. + getdomainname(domain, sizeof(domain));
  135. +
  136. + while ((buf = fgetln(hostf, &buflen))) {
  137. + p = buf;
  138. + if (*p == '#')
  139. + continue;
  140. + while (p < buf + buflen && *p != '\n' && *p != ' ' && *p != '\t') {
  141. + if (!isprint((unsigned char)*p))
  142. + goto bail;
  143. + *p = isupper((unsigned char)*p) ?
  144. + tolower((unsigned char)*p) : *p;
  145. + p++;
  146. + }
  147. + if (p >= buf + buflen)
  148. + continue;
  149. + if (*p == ' ' || *p == '\t') {
  150. + *p++ = '\0';
  151. + while (p < buf + buflen && (*p == ' ' || *p == '\t'))
  152. + p++;
  153. + if (p >= buf + buflen)
  154. + continue;
  155. + user = p;
  156. + while (p < buf + buflen && *p != '\n' && *p != ' ' &&
  157. + *p != '\t') {
  158. + if (!isprint((unsigned char)*p))
  159. + goto bail;
  160. + p++;
  161. + }
  162. + } else
  163. + user = p;
  164. + *p = '\0';
  165. +
  166. + if (p == buf)
  167. + continue;
  168. +
  169. + auser = *user ? user : luser;
  170. + ahost = buf;
  171. +
  172. + if (strlen(ahost) > HOST_NAME_MAX)
  173. + continue;
  174. +
  175. + /*
  176. + * innetgr() must lookup a hostname (we do not attempt
  177. + * to change the semantics so that netgroups may have
  178. + * #.#.#.# addresses in the list.)
  179. + */
  180. + if (ahost[0] == '+')
  181. + switch (ahost[1]) {
  182. + case '\0':
  183. + hostok = 1;
  184. + break;
  185. + case '@':
  186. + if (rhost == (char *)-1)
  187. + rhost = __gethostloop(raddr, salen);
  188. + hostok = 0;
  189. + if (rhost)
  190. + hostok = innetgr(&ahost[2], rhost,
  191. + NULL, domain);
  192. + break;
  193. + default:
  194. + hostok = __icheckhost(raddr, salen, &ahost[1]);
  195. + break;
  196. + }
  197. + else if (ahost[0] == '-')
  198. + switch (ahost[1]) {
  199. + case '\0':
  200. + hostok = -1;
  201. + break;
  202. + case '@':
  203. + if (rhost == (char *)-1)
  204. + rhost = __gethostloop(raddr, salen);
  205. + hostok = 0;
  206. + if (rhost)
  207. + hostok = -innetgr(&ahost[2], rhost,
  208. + NULL, domain);
  209. + break;
  210. + default:
  211. + hostok = -__icheckhost(raddr, salen, &ahost[1]);
  212. + break;
  213. + }
  214. + else
  215. + hostok = __icheckhost(raddr, salen, ahost);
  216. +
  217. +
  218. + if (auser[0] == '+')
  219. + switch (auser[1]) {
  220. + case '\0':
  221. + userok = 1;
  222. + break;
  223. + case '@':
  224. + userok = innetgr(&auser[2], NULL, ruser,
  225. + domain);
  226. + break;
  227. + default:
  228. + userok = strcmp(ruser, &auser[1]) ? 0 : 1;
  229. + break;
  230. + }
  231. + else if (auser[0] == '-')
  232. + switch (auser[1]) {
  233. + case '\0':
  234. + userok = -1;
  235. + break;
  236. + case '@':
  237. + userok = -innetgr(&auser[2], NULL, ruser,
  238. + domain);
  239. + break;
  240. + default:
  241. + userok = strcmp(ruser, &auser[1]) ? 0 : -1;
  242. + break;
  243. + }
  244. + else
  245. + userok = strcmp(ruser, auser) ? 0 : 1;
  246. +
  247. + /* Check if one component did not match */
  248. + if (hostok == 0 || userok == 0)
  249. + continue;
  250. +
  251. + /* Check if we got a forbidden pair */
  252. + if (userok <= -1 || hostok <= -1)
  253. + return (-1);
  254. +
  255. + /* Check if we got a valid pair */
  256. + if (hostok >= 1 && userok >= 1)
  257. + return (0);
  258. + }
  259. +bail:
  260. + return (-1);
  261. +}
  262. +
  263. +/*
  264. + * Returns "true" if match, 0 if no match. If we do not find any
  265. + * semblance of an A->PTR->A loop, allow a simple #.#.#.# match to work.
  266. + */
  267. +static int
  268. +__icheckhost(struct sockaddr *raddr, socklen_t salen, const char *lhost)
  269. +{
  270. + struct addrinfo hints, *res, *r;
  271. + char h1[NI_MAXHOST], h2[NI_MAXHOST];
  272. + int error;
  273. + const int niflags = NI_NUMERICHOST;
  274. +
  275. + h1[0] = '\0';
  276. + if (getnameinfo(raddr, salen, h1, sizeof(h1), NULL, 0,
  277. + niflags) != 0)
  278. + return (0);
  279. +
  280. + /* Resolve laddr into sockaddr */
  281. + memset(&hints, 0, sizeof(hints));
  282. + hints.ai_family = raddr->sa_family;
  283. + hints.ai_socktype = SOCK_DGRAM; /*dummy*/
  284. + res = NULL;
  285. + error = getaddrinfo(lhost, "0", &hints, &res);
  286. + if (error)
  287. + return (0);
  288. +
  289. + /*
  290. + * Try string comparisons between raddr and laddr.
  291. + */
  292. + for (r = res; r; r = r->ai_next) {
  293. + h2[0] = '\0';
  294. + if (getnameinfo(r->ai_addr, r->ai_addrlen, h2, sizeof(h2),
  295. + NULL, 0, niflags) != 0)
  296. + continue;
  297. + if (strcmp(h1, h2) == 0) {
  298. + freeaddrinfo(res);
  299. + return (1);
  300. + }
  301. + }
  302. +
  303. + /* No match. */
  304. + freeaddrinfo(res);
  305. + return (0);
  306. +}
  307. +
  308. +/*
  309. + * Return the hostname associated with the supplied address.
  310. + * Do a reverse lookup as well for security. If a loop cannot
  311. + * be found, pack the result of inet_ntoa() into the string.
  312. + */
  313. +static char *
  314. +__gethostloop(struct sockaddr *raddr, socklen_t salen)
  315. +{
  316. + static char remotehost[NI_MAXHOST];
  317. + char h1[NI_MAXHOST], h2[NI_MAXHOST];
  318. + struct addrinfo hints, *res, *r;
  319. + int error;
  320. + const int niflags = NI_NUMERICHOST;
  321. +
  322. + h1[0] = remotehost[0] = '\0';
  323. + if (getnameinfo(raddr, salen, remotehost, sizeof(remotehost),
  324. + NULL, 0, NI_NAMEREQD) != 0)
  325. + return (NULL);
  326. + if (getnameinfo(raddr, salen, h1, sizeof(h1), NULL, 0,
  327. + niflags) != 0)
  328. + return (NULL);
  329. +
  330. + /*
  331. + * Look up the name and check that the supplied
  332. + * address is in the list
  333. + */
  334. + memset(&hints, 0, sizeof(hints));
  335. + hints.ai_family = raddr->sa_family;
  336. + hints.ai_socktype = SOCK_DGRAM; /*dummy*/
  337. + hints.ai_flags = AI_CANONNAME;
  338. + res = NULL;
  339. + error = getaddrinfo(remotehost, "0", &hints, &res);
  340. + if (error)
  341. + return (NULL);
  342. +
  343. + for (r = res; r; r = r->ai_next) {
  344. + h2[0] = '\0';
  345. + if (getnameinfo(r->ai_addr, r->ai_addrlen, h2, sizeof(h2),
  346. + NULL, 0, niflags) != 0)
  347. + continue;
  348. + if (strcmp(h1, h2) == 0) {
  349. + freeaddrinfo(res);
  350. + return (remotehost);
  351. + }
  352. + }
  353. +
  354. + /*
  355. + * either the DNS adminstrator has made a configuration
  356. + * mistake, or someone has attempted to spoof us
  357. + */
  358. + freeaddrinfo(res);
  359. + return (NULL);
  360. +}
  361. +
  362. int child;
  363. int netf;
  364. char line[MAXPATHLEN];
  365.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement