Advertisement
Guest User

Untitled

a guest
Aug 4th, 2015
183
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 18.62 KB | None | 0 0
  1. diff --git a/usr.bin/doas/Makefile b/usr.bin/doas/Makefile
  2. index 809fe0b..6610edb 100644
  3. --- a/usr.bin/doas/Makefile
  4. +++ b/usr.bin/doas/Makefile
  5. @@ -1,14 +1,31 @@
  6. +# $NetBSD$
  7. # $OpenBSD: Makefile,v 1.1 2015/07/16 20:44:21 tedu Exp $
  8.  
  9. -SRCS= parse.y doas.c
  10. +.include <bsd.own.mk>
  11. +
  12. +USE_FORT?=yes
  13. +WARN= 4
  14.  
  15. PROG= doas
  16. +SRCS= parse.y doas.c
  17. MAN= doas.1 doas.conf.5
  18.  
  19. -BINOWN= root
  20. +BINOWN= root
  21. BINMODE=4555
  22.  
  23. -CFLAGS+= -I${.CURDIR}
  24. -COPTS+= -Wall
  25. +CPPFLAGS+=-I${.CURDIR}
  26. +CPPFLAGS+=-DHAVE_LOGIN_CAP_H
  27. +CPPFLAGS+=-DHAVE_INTTYPES_H
  28. +CPPFLAGS+=-DHAVE_REALLOCARR
  29. +CPPFLAGS+=-DHAVE_STRTOI
  30. +
  31. +DPADD+= ${LIBUTIL}
  32. +LDADD+= -lutil
  33. +
  34. +.if ${MKPAM} != "no"
  35. +CPPFLAGS+= -DUSE_PAM
  36. +LDADD+= -lpam ${PAM_STATIC_LDADD}
  37. +DPADD+= ${LIBPAM} ${PAM_STATIC_DPADD}
  38. +.endif
  39.  
  40. .include <bsd.prog.mk>
  41. diff --git a/usr.bin/doas/doas.1 b/usr.bin/doas/doas.1
  42. index b9bf0d3..2e33b54 100644
  43. --- a/usr.bin/doas/doas.1
  44. +++ b/usr.bin/doas/doas.1
  45. @@ -1,3 +1,4 @@
  46. +.\" $NetBSD$
  47. .\" $OpenBSD: doas.1,v 1.1 2015/07/16 20:44:21 tedu Exp $
  48. .\"
  49. .\"Copyright (c) 2015 Ted Unangst <tedu@openbsd.org>
  50. diff --git a/usr.bin/doas/doas.c b/usr.bin/doas/doas.c
  51. index 3570cca..7ef2d64 100644
  52. --- a/usr.bin/doas/doas.c
  53. +++ b/usr.bin/doas/doas.c
  54. @@ -1,3 +1,4 @@
  55. +/* $NetBSD$ */
  56. /* $OpenBSD: doas.c,v 1.6 2015/07/16 23:22:08 nicm Exp $ */
  57. /*
  58. * Copyright (c) 2015 Ted Unangst <tedu@openbsd.org>
  59. @@ -18,9 +19,10 @@
  60. #include <sys/types.h>
  61. #include <sys/stat.h>
  62.  
  63. +#if defined(HAVE_INTTYPES_H)
  64. +#include <inttypes.h>
  65. +#endif
  66. #include <limits.h>
  67. -#include <login_cap.h>
  68. -#include <bsd_auth.h>
  69. #include <string.h>
  70. #include <stdio.h>
  71. #include <stdlib.h>
  72. @@ -30,6 +32,21 @@
  73. #include <grp.h>
  74. #include <syslog.h>
  75.  
  76. +#if defined(HAVE_LOGIN_CAP_H)
  77. +#include <login_cap.h>
  78. +#endif
  79. +
  80. +#if defined(USE_BSD_AUTH)
  81. +#include <bsd_auth.h>
  82. +#endif
  83. +
  84. +#if defined(USE_PAM)
  85. +#include <security/pam_appl.h>
  86. +#include <security/openpam.h>
  87. +
  88. +static struct pam_conv pamc = { openpam_ttyconv, NULL };
  89. +#endif
  90. +
  91. #include "doas.h"
  92.  
  93. static void __dead
  94. @@ -40,7 +57,7 @@ usage(void)
  95. }
  96.  
  97. size_t
  98. -arraylen(const char **arr)
  99. +arraylen(const char * const *arr)
  100. {
  101. size_t cnt = 0;
  102. while (*arr) {
  103. @@ -54,15 +71,25 @@ static int
  104. parseuid(const char *s, uid_t *uid)
  105. {
  106. struct passwd *pw;
  107. +#if defined(HAVE_STRTONUM)
  108. const char *errstr;
  109. +#else
  110. + int error;
  111. +#endif
  112.  
  113. if ((pw = getpwnam(s)) != NULL) {
  114. *uid = pw->pw_uid;
  115. return 0;
  116. }
  117. +#if defined(HAVE_STRTONUM)
  118. *uid = strtonum(s, 0, UID_MAX, &errstr);
  119. if (errstr)
  120. return -1;
  121. +#else
  122. + *uid = strtoi(s, NULL, 10, 0, UID_MAX, &error);
  123. + if (error)
  124. + return -1;
  125. +#endif
  126. return 0;
  127. }
  128.  
  129. @@ -82,14 +109,24 @@ static gid_t
  130. strtogid(const char *s)
  131. {
  132. struct group *gr;
  133. - const char *errstr;
  134. gid_t gid;
  135. +#if defined(HAVE_STRTONUM)
  136. + const char *errstr;
  137. +#else
  138. + int error;
  139. +#endif
  140.  
  141. if ((gr = getgrnam(s)) != NULL)
  142. return gr->gr_gid;
  143. +#if defined(HAVE_STRTONUM)
  144. gid = strtonum(s, 0, GID_MAX, &errstr);
  145. if (errstr)
  146. return -1;
  147. +#else
  148. + gid = strtoi(s, NULL, 10, 0, GID_MAX, &error);
  149. + if (error)
  150. + return -1;
  151. +#endif
  152. return gid;
  153. }
  154.  
  155. @@ -101,7 +138,7 @@ match(uid_t uid, gid_t *groups, int ngroups, uid_t target, const char *cmd,
  156.  
  157. if (r->ident[0] == ':') {
  158. gid_t rgid = strtogid(r->ident + 1);
  159. - if (rgid == -1)
  160. + if (rgid == (gid_t)-1)
  161. return 0;
  162. for (i = 0; i < ngroups; i++) {
  163. if (rgid == groups[i])
  164. @@ -161,12 +198,12 @@ parseconfig(const char *filename)
  165. }
  166.  
  167. static int
  168. -copyenvhelper(const char **oldenvp, const char **safeset, int nsafe,
  169. +copyenvhelper(const char * const *oldenvp, const char **safeset, int nsafe,
  170. char **envp, int ei)
  171. {
  172. int i;
  173. for (i = 0; i < nsafe; i++) {
  174. - const char **oe = oldenvp;
  175. + const char * const *oe = oldenvp;
  176. while (*oe) {
  177. size_t len = strlen(safeset[i]);
  178. if (strncmp(*oe, safeset[i], len) == 0 &&
  179. @@ -182,9 +219,9 @@ copyenvhelper(const char **oldenvp, const char **safeset, int nsafe,
  180. }
  181.  
  182. static char **
  183. -copyenv(const char **oldenvp, struct rule *rule)
  184. +copyenv(const char * const *oldenvp, struct rule *rule)
  185. {
  186. - const char *safeset[] = {
  187. + static const char *safeset[] = {
  188. "DISPLAY", "HOME", "LOGNAME", "MAIL", "SHELL",
  189. "PATH", "TERM", "USER", "USERNAME",
  190. NULL,
  191. @@ -195,12 +232,18 @@ copyenv(const char **oldenvp, struct rule *rule)
  192. const char **extra;
  193. int ei;
  194. int i, j;
  195. -
  196. +
  197. if ((rule->options & KEEPENV) && !rule->envlist) {
  198. j = arraylen(oldenvp);
  199. +#if defined(HAVE_REALLOCARRAY)
  200. envp = reallocarray(NULL, j + 1, sizeof(char *));
  201. if (!envp)
  202. err(1, "reallocarray");
  203. +#else
  204. + envp = NULL;
  205. + if (reallocarr(&envp, j + 1, sizeof(char *)))
  206. + err(1, "reallocarr");
  207. +#endif
  208. for (i = 0; i < j; i++) {
  209. if (!(envp[i] = strdup(oldenvp[i])))
  210. err(1, "strdup");
  211. @@ -222,9 +265,15 @@ copyenv(const char **oldenvp, struct rule *rule)
  212. }
  213. }
  214.  
  215. +#if defined(HAVE_REALLOCARRAY)
  216. envp = reallocarray(NULL, nsafe + nextras + 1, sizeof(char *));
  217. if (!envp)
  218. err(1, "can't allocate new environment");
  219. +#else
  220. + envp = NULL;
  221. + if (reallocarr(&envp, nsafe + nextras + 1, sizeof(char *)))
  222. + err(1, "can't allocate new environment");
  223. +#endif
  224.  
  225. ei = 0;
  226. ei = copyenvhelper(oldenvp, safeset, nsafe, envp, ei);
  227. @@ -244,6 +293,8 @@ fail(void)
  228. int
  229. main(int argc, char **argv, char **envp)
  230. {
  231. + static const char *safepath = "/bin:/sbin:/usr/bin:/usr/sbin:"
  232. + "/usr/local/bin:/usr/local/sbin";
  233. char cmdline[1024];
  234. char myname[32];
  235. uid_t uid, target = 0;
  236. @@ -253,8 +304,11 @@ main(int argc, char **argv, char **envp)
  237. struct rule *rule;
  238. const char *cmd;
  239. int i, ch;
  240. - const char *safepath = "/bin:/sbin:/usr/bin:/usr/sbin:"
  241. - "/usr/local/bin:/usr/local/sbin";
  242. +#if defined(USE_PAM)
  243. + pam_handle_t *pamh = NULL;
  244. + int pam_err;
  245. + int pam_silent = PAM_SILENT;
  246. +#endif
  247.  
  248. parseconfig("/etc/doas.conf");
  249.  
  250. @@ -299,22 +353,84 @@ main(int argc, char **argv, char **envp)
  251. }
  252.  
  253. if (!(rule->options & NOPASS)) {
  254. +#if defined(USE_BSD_AUTH)
  255. if (!auth_userokay(myname, NULL, NULL, NULL)) {
  256. syslog(LOG_AUTHPRIV | LOG_NOTICE,
  257. "failed password for %s", myname);
  258. fail();
  259. }
  260. +#elif defined(USE_PAM)
  261. +#define PAM_END(msg) do { \
  262. + syslog(LOG_ERR, "%s: %s", msg, pam_strerror(pamh, pam_err)); \
  263. + warnx("%s: %s", msg, pam_strerror(pamh, pam_err)); \
  264. + pam_end(pamh, pam_err); \
  265. + exit(EXIT_FAILURE); \
  266. +} while (/*CONSTCOND*/0)
  267. +
  268. + pam_err = pam_start("doas", myname, &pamc, &pamh);
  269. + if (pam_err != PAM_SUCCESS) {
  270. + if (pamh != NULL)
  271. + PAM_END("pam_start");
  272. + syslog(LOG_ERR, "pam_start failed: %s",
  273. + pam_strerror(pamh, pam_err));
  274. + errx(EXIT_FAILURE, "pam_start failed");
  275. + }
  276. +
  277. + switch (pam_err = pam_authenticate(pamh, pam_silent)) {
  278. + case PAM_SUCCESS:
  279. + switch (pam_err = pam_acct_mgmt(pamh, pam_silent)) {
  280. + case PAM_SUCCESS:
  281. + break;
  282. +
  283. + case PAM_NEW_AUTHTOK_REQD:
  284. + pam_err = pam_chauthtok(pamh,
  285. + pam_silent|PAM_CHANGE_EXPIRED_AUTHTOK);
  286. + if (pam_err != PAM_SUCCESS)
  287. + PAM_END("pam_chauthtok");
  288. + break;
  289. +
  290. + case PAM_AUTH_ERR:
  291. + case PAM_USER_UNKNOWN:
  292. + case PAM_MAXTRIES:
  293. + syslog(LOG_AUTHPRIV | LOG_NOTICE,
  294. + "failed auth for %s", myname);
  295. + fail();
  296. + break;
  297. +
  298. + default:
  299. + PAM_END("pam_acct_mgmt");
  300. + break;
  301. + }
  302. + break;
  303. +
  304. + case PAM_AUTH_ERR:
  305. + case PAM_USER_UNKNOWN:
  306. + case PAM_MAXTRIES:
  307. + syslog(LOG_AUTHPRIV | LOG_NOTICE,
  308. + "failed auth for %s", myname);
  309. + fail();
  310. + break;
  311. +
  312. + default:
  313. + PAM_END("pam_authenticate");
  314. + break;
  315. + }
  316. + pam_end(pamh, pam_err);
  317. +#else
  318. +#error No auth module!
  319. +#endif
  320. }
  321. - envp = copyenv((const char **)envp, rule);
  322. + envp = copyenv((const char * const *)envp, rule);
  323.  
  324. pw = getpwuid(target);
  325. if (!pw)
  326. errx(1, "no passwd entry for target");
  327. +#if defined(HAVE_LOGIN_CAP_H)
  328. if (setusercontext(NULL, pw, target, LOGIN_SETGROUP |
  329. LOGIN_SETPRIORITY | LOGIN_SETRESOURCES | LOGIN_SETUMASK |
  330. LOGIN_SETUSER) != 0)
  331. errx(1, "failed to set user context for target");
  332. -
  333. +#endif
  334. syslog(LOG_AUTHPRIV | LOG_INFO, "%s ran command as %s: %s",
  335. myname, pw->pw_name, cmdline);
  336. setenv("PATH", safepath, 1);
  337. diff --git a/usr.bin/doas/doas.conf.5 b/usr.bin/doas/doas.conf.5
  338. index ddfdfd6..4fd85e2 100644
  339. --- a/usr.bin/doas/doas.conf.5
  340. +++ b/usr.bin/doas/doas.conf.5
  341. @@ -1,3 +1,4 @@
  342. +.\" $NetBSD$
  343. .\" $OpenBSD: doas.conf.5,v 1.2 2015/07/16 21:24:07 nicm Exp $
  344. .\"
  345. .\"Copyright (c) 2015 Ted Unangst <tedu@openbsd.org>
  346. diff --git a/usr.bin/doas/doas.h b/usr.bin/doas/doas.h
  347. index b6d0275..4af3fd2 100644
  348. --- a/usr.bin/doas/doas.h
  349. +++ b/usr.bin/doas/doas.h
  350. @@ -1,3 +1,4 @@
  351. +/* $NetBSD$ */
  352.  
  353. struct rule {
  354. int action;
  355. @@ -11,10 +12,30 @@ struct rule {
  356. extern struct rule **rules;
  357. extern int nrules, maxrules;
  358.  
  359. -size_t arraylen(const char **);
  360. +size_t arraylen(const char * const *);
  361.  
  362. #define PERMIT 1
  363. #define DENY 2
  364.  
  365. #define NOPASS 0x1
  366. #define KEEPENV 0x2
  367. +
  368. +#if !defined(HAVE_REALLOCARRAY) && !defined(HAVE_REALLOCARR)
  369. +int reallocarr(void *ptr, size_t num, size_t size);
  370. +#endif /* !HAVE_REALLOCARRAY && !HAVE_REALLOCARR */
  371. +
  372. +#if !defined(HAVE_STRTOI) && !defined(HAVE_STRTONUM)
  373. +#if defined(HAVE_INTTYPES_H)
  374. +#include <stdint.h>
  375. +#elif defined(HAVE_LONG_LONG_INT)
  376. +typedef long long intmax_t;
  377. +#else /* !HAVE_INTTYPES_H && !HAVE_LONG_LONG_INT */
  378. +typedef long intmax_t;
  379. +#endif /* HAVE_LONG_LONG_INT */
  380. +intmax_t strtoi(const char *nptr, char **endptr, int base, intmax_t lo,
  381. + intmax_t hi, int *rstatus);
  382. +#endif /* !HAVE_STRTOI && !HAVE_STRTONUM */
  383. +
  384. +#if !defined(HAVE_EXECVPE)
  385. +int execvpe(const char *file, char * const *argv, char * const *envp);
  386. +#endif /* !HAVE_EXECVPE */
  387. diff --git a/usr.bin/doas/execvpe.c b/usr.bin/doas/execvpe.c
  388. new file mode 100644
  389. index 0000000..4a74d4b
  390. --- /dev/null
  391. +++ b/usr.bin/doas/execvpe.c
  392. @@ -0,0 +1,48 @@
  393. +/* $NetBSD$ */
  394. +
  395. +/*-
  396. + * Copyright (C) 2015 NONAKA Kimihiro <nonakap@gmail.com>
  397. + * All rights reserved.
  398. + *
  399. + * Redistribution and use in source and binary forms, with or without
  400. + * modification, are permitted provided that the following conditions
  401. + * are met:
  402. + * 1. Redistributions of source code must retain the above copyright
  403. + * notice, this list of conditions and the following disclaimer.
  404. + * 2. Redistributions in binary form must reproduce the above copyright
  405. + * notice, this list of conditions and the following disclaimer in the
  406. + * documentation and/or other materials provided with the distribution.
  407. + *
  408. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  409. + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  410. + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  411. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  412. + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  413. + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  414. + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  415. + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  416. + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  417. + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  418. + */
  419. +
  420. +#include <unistd.h>
  421. +
  422. +#include "doas.h"
  423. +
  424. +#if !defined(HAVE_EXECVPE)
  425. +
  426. +extern char **environ;
  427. +
  428. +int
  429. +execvpe(const char *file, char * const *argv, char * const *envp)
  430. +{
  431. + char **oldenvp = environ;
  432. + int error;
  433. +
  434. + environ = (char **)(long)envp; /* XXX */
  435. + error = execvp(file, argv);
  436. + environ = oldenvp;
  437. + return error;
  438. +}
  439. +
  440. +#endif /* !HAVE_EXECVPE */
  441. diff --git a/usr.bin/doas/parse.y b/usr.bin/doas/parse.y
  442. index 089dc4f..9b084c2 100644
  443. --- a/usr.bin/doas/parse.y
  444. +++ b/usr.bin/doas/parse.y
  445. @@ -1,3 +1,4 @@
  446. +/* $NetBSD$ */
  447. /* $OpenBSD: parse.y,v 1.4 2015/07/16 23:02:56 nicm Exp $ */
  448. /*
  449. * Copyright (c) 2015 Ted Unangst <tedu@openbsd.org>
  450. @@ -23,6 +24,7 @@
  451. #include <stdarg.h>
  452. #include <stdio.h>
  453. #include <string.h>
  454. +#include <stdlib.h>
  455. #include <err.h>
  456.  
  457. #include "doas.h"
  458. @@ -77,8 +79,13 @@ rule: action ident target cmd {
  459. maxrules = 63;
  460. else
  461. maxrules *= 2;
  462. +#if defined(HAVE_REALLOCARRAY)
  463. if (!(rules = reallocarray(rules, maxrules, sizeof(*rules))))
  464. errx(1, "can't allocate rules");
  465. +#else
  466. + if (reallocarr(&rules, maxrules, sizeof(*rules)))
  467. + errx(1, "can't allocate rules");
  468. +#endif
  469. }
  470. rules[nrules++] = r;
  471. } ;
  472. @@ -116,8 +123,14 @@ envlist: /* empty */ {
  473. errx(1, "can't allocate envlist");
  474. } | envlist TSTRING {
  475. int nenv = arraylen($1.envlist);
  476. +#if defined(HAVE_REALLOCARRAY)
  477. if (!($$.envlist = reallocarray($1.envlist, nenv + 2, sizeof(char *))))
  478. errx(1, "can't allocate envlist");
  479. +#else
  480. + $$.envlist = $1.envlist;
  481. + if (reallocarr(&$$.envlist, nenv + 2, sizeof(char *)))
  482. + errx(1, "can't allocate envlist");
  483. +#endif
  484. $$.envlist[nenv] = $2.str;
  485. $$.envlist[nenv + 1] = NULL;
  486. }
  487. @@ -150,7 +163,7 @@ yyerror(const char *fmt, ...)
  488. verrx(1, fmt, va);
  489. }
  490.  
  491. -struct keyword {
  492. +static const struct keyword {
  493. const char *word;
  494. int token;
  495. } keywords[] = {
  496. @@ -206,7 +219,7 @@ eow:
  497. *p = 0;
  498. if (c != EOF)
  499. ungetc(c, yyfp);
  500. - for (i = 0; i < sizeof(keywords) / sizeof(keywords[0]); i++) {
  501. + for (i = 0; i < (int)(sizeof(keywords) / sizeof(keywords[0])); i++) {
  502. if (strcmp(buf, keywords[i].word) == 0)
  503. return keywords[i].token;
  504. }
  505. diff --git a/usr.bin/doas/reallocarr.c b/usr.bin/doas/reallocarr.c
  506. new file mode 100644
  507. index 0000000..342bba2
  508. --- /dev/null
  509. +++ b/usr.bin/doas/reallocarr.c
  510. @@ -0,0 +1,73 @@
  511. +/* $NetBSD$ */
  512. +/* NetBSD: reallocarr.c,v 1.2 2015/07/16 00:03:59 kamil Exp */
  513. +
  514. +/*-
  515. + * Copyright (c) 2015 Joerg Sonnenberger <joerg@NetBSD.org>.
  516. + * All rights reserved.
  517. + *
  518. + * Redistribution and use in source and binary forms, with or without
  519. + * modification, are permitted provided that the following conditions
  520. + * are met:
  521. + *
  522. + * 1. Redistributions of source code must retain the above copyright
  523. + * notice, this list of conditions and the following disclaimer.
  524. + * 2. Redistributions in binary form must reproduce the above copyright
  525. + * notice, this list of conditions and the following disclaimer in
  526. + * the documentation and/or other materials provided with the
  527. + * distribution.
  528. + *
  529. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  530. + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  531. + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  532. + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  533. + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  534. + * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
  535. + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  536. + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
  537. + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  538. + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  539. + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  540. + * SUCH DAMAGE.
  541. + */
  542. +
  543. +#include <errno.h>
  544. +/* Old POSIX has SIZE_MAX in limits.h */
  545. +#include <limits.h>
  546. +#include <stdint.h>
  547. +#include <stdlib.h>
  548. +#include <string.h>
  549. +
  550. +#include "doas.h"
  551. +
  552. +#if !defined(HAVE_REALLOCARR) && !defined(HAVE_REALLOCARRAY)
  553. +
  554. +int
  555. +reallocarr(void *ptr, size_t num, size_t size)
  556. +{
  557. + int saved_errno, result;
  558. + void *optr;
  559. + void *nptr;
  560. +
  561. + saved_errno = errno;
  562. + memcpy(&optr, ptr, sizeof(ptr));
  563. + if (num == 0 || size == 0) {
  564. + free(optr);
  565. + nptr = NULL;
  566. + memcpy(ptr, &nptr, sizeof(ptr));
  567. + errno = saved_errno;
  568. + return 0;
  569. + }
  570. + if ((num >= 65535 || size >= 65535) && num > SIZE_MAX / size)
  571. + return EOVERFLOW;
  572. + nptr = realloc(optr, num * size);
  573. + if (nptr == NULL) {
  574. + result = errno;
  575. + } else {
  576. + result = 0;
  577. + memcpy(ptr, &nptr, sizeof(ptr));
  578. + }
  579. + errno = saved_errno;
  580. + return result;
  581. +}
  582. +
  583. +#endif /* !HAVE_REALLOCARR && !HAVE_REALLOCARRAY */
  584. diff --git a/usr.bin/doas/strtoi.c b/usr.bin/doas/strtoi.c
  585. new file mode 100644
  586. index 0000000..ec6481f
  587. --- /dev/null
  588. +++ b/usr.bin/doas/strtoi.c
  589. @@ -0,0 +1,102 @@
  590. +/* $NetBSD$ */
  591. +/* NetBSD: _strtoi.h,v 1.2 2015/01/18 17:55:22 christos Exp */
  592. +
  593. +/*-
  594. + * Copyright (c) 1990, 1993
  595. + * The Regents of the University of California. All rights reserved.
  596. + *
  597. + * Redistribution and use in source and binary forms, with or without
  598. + * modification, are permitted provided that the following conditions
  599. + * are met:
  600. + * 1. Redistributions of source code must retain the above copyright
  601. + * notice, this list of conditions and the following disclaimer.
  602. + * 2. Redistributions in binary form must reproduce the above copyright
  603. + * notice, this list of conditions and the following disclaimer in the
  604. + * documentation and/or other materials provided with the distribution.
  605. + * 3. Neither the name of the University nor the names of its contributors
  606. + * may be used to endorse or promote products derived from this software
  607. + * without specific prior written permission.
  608. + *
  609. + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  610. + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  611. + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  612. + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  613. + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  614. + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  615. + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  616. + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  617. + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  618. + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  619. + * SUCH DAMAGE.
  620. + *
  621. + * Original version ID:
  622. + * NetBSD: src/lib/libc/locale/_wcstoul.h,v 1.2 2003/08/07 16:43:03 agc Exp
  623. + *
  624. + * Created by Kamil Rytarowski, based on ID:
  625. + * NetBSD: src/common/lib/libc/stdlib/_strtoul.h,v 1.7 2013/05/17 12:55:56 joerg Exp
  626. + */
  627. +
  628. +#if defined(HAVE_INTTYPES_H)
  629. +#include <inttypes.h>
  630. +#endif
  631. +#include <stdlib.h>
  632. +#include <errno.h>
  633. +
  634. +#include "doas.h"
  635. +
  636. +#if !defined(HAVE_STRTOI) && !defined(HAVE_STRTONUM)
  637. +
  638. +#if defined(HAVE_STRTOIMAX)
  639. +#define STRTOIMAX strtoimax
  640. +#elif defined(HAVE_STRTOLL)
  641. +#define STRTOIMAX strtoll
  642. +#else
  643. +#define STRTOIMAX strtol
  644. +#endif
  645. +
  646. +intmax_t
  647. +strtoi(const char *nptr, char **endptr, int base, intmax_t lo, intmax_t hi,
  648. + int *rstatus)
  649. +{
  650. + int serrno;
  651. + intmax_t im;
  652. + char *ep;
  653. + int rep;
  654. +
  655. + if (endptr == NULL)
  656. + endptr = &ep;
  657. + if (rstatus == NULL)
  658. + rstatus = &rep;
  659. +
  660. + serrno = errno;
  661. + errno = 0;
  662. +
  663. + im = STRTOIMAX(nptr, endptr, base);
  664. +
  665. + *rstatus = errno;
  666. + errno = serrno;
  667. +
  668. + if (*rstatus == 0) {
  669. + /* No digits were found */
  670. + if (nptr == *endptr)
  671. + *rstatus = ECANCELED;
  672. + /* There are further characters after number */
  673. + else if (**endptr != '\0')
  674. + *rstatus = ENOTSUP;
  675. + }
  676. +
  677. + if (im < lo) {
  678. + if (*rstatus == 0)
  679. + *rstatus = ERANGE;
  680. + return lo;
  681. + }
  682. + if (im > hi) {
  683. + if (*rstatus == 0)
  684. + *rstatus = ERANGE;
  685. + return hi;
  686. + }
  687. +
  688. + return im;
  689. +}
  690. +
  691. +#endif /* !HAVE_STRTOI && !HAVE_STRTONUM */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement