Blame SOURCES/sudo-1.8.25-ipa-hostname.patch

e7179e
From e99082e05b9f0dd0e0f47fa1d2e1b9d922ea8c4c Mon Sep 17 00:00:00 2001
e7179e
From: "Todd C. Miller" <Todd.Miller@sudo.ws>
e7179e
Date: Thu, 15 Aug 2019 14:20:12 -0600
e7179e
Subject: [PATCH] Fix special handling of ipa_hostname that was lost in sudo
e7179e
 1.8.24. We now include the long and short hostname in sudo parser container.
e7179e
e7179e
---
e7179e
 plugins/sudoers/file.c  |   2 +-
e7179e
 plugins/sudoers/gram.c  | 215 ++++++++++++++++++++--------------------
e7179e
 plugins/sudoers/gram.y  |   9 +-
e7179e
 plugins/sudoers/ldap.c  |   2 +-
e7179e
 plugins/sudoers/match.c |  23 +++--
e7179e
 plugins/sudoers/parse.h |   3 +-
e7179e
 plugins/sudoers/sssd.c  |   7 +-
e7179e
 7 files changed, 140 insertions(+), 121 deletions(-)
e7179e
e7179e
diff --git a/plugins/sudoers/file.c b/plugins/sudoers/file.c
e7179e
index fff78a19..5028ce01 100644
e7179e
--- a/plugins/sudoers/file.c
e7179e
+++ b/plugins/sudoers/file.c
e7179e
@@ -85,7 +85,7 @@ sudo_file_open(struct sudo_nss *nss)
e7179e
     if (handle != NULL) {
e7179e
 	handle->fp = open_sudoers(sudoers_file, false, NULL);
e7179e
 	if (handle->fp != NULL) {
e7179e
-	    init_parse_tree(&handle->parse_tree);
e7179e
+	    init_parse_tree(&handle->parse_tree, NULL, NULL);
e7179e
 	} else {
e7179e
 	    free(handle);
e7179e
 	    handle = NULL;
e7179e
diff --git a/plugins/sudoers/gram.c b/plugins/sudoers/gram.c
e7179e
index 343e4299..6545e129 100644
e7179e
--- a/plugins/sudoers/gram.c
e7179e
+++ b/plugins/sudoers/gram.c
e7179e
@@ -106,7 +106,9 @@ char *errorfile = NULL;
e7179e
 struct sudoers_parse_tree parsed_policy = {
e7179e
     TAILQ_HEAD_INITIALIZER(parsed_policy.userspecs),
e7179e
     TAILQ_HEAD_INITIALIZER(parsed_policy.defaults),
e7179e
-    NULL /* aliases */
e7179e
+    NULL, /* aliases */
e7179e
+    NULL, /* lhost */
e7179e
+    NULL /* shost */
e7179e
 };
e7179e
 
e7179e
 /*
e7179e
@@ -118,7 +120,7 @@ static bool add_userspec(struct member *, struct privilege *);
e7179e
 static struct defaults *new_default(char *, char *, short);
e7179e
 static struct member *new_member(char *, int);
e7179e
 static struct command_digest *new_digest(int, char *);
e7179e
-#line 80 "gram.y"
e7179e
+#line 82 "gram.y"
e7179e
 #ifndef YYSTYPE_DEFINED
e7179e
 #define YYSTYPE_DEFINED
e7179e
 typedef union {
e7179e
@@ -135,7 +137,7 @@ typedef union {
e7179e
     int tok;
e7179e
 } YYSTYPE;
e7179e
 #endif /* YYSTYPE_DEFINED */
e7179e
-#line 133 "gram.c"
e7179e
+#line 135 "gram.c"
e7179e
 #define COMMAND 257
e7179e
 #define ALIAS 258
e7179e
 #define DEFVAR 259
e7179e
@@ -675,7 +677,7 @@ short *yysslim;
e7179e
 YYSTYPE *yyvs;
e7179e
 unsigned int yystacksize;
e7179e
 int yyparse(void);
e7179e
-#line 906 "gram.y"
e7179e
+#line 908 "gram.y"
e7179e
 void
e7179e
 sudoerserror(const char *s)
e7179e
 {
e7179e
@@ -1019,11 +1021,14 @@ free_userspec(struct userspec *us)
e7179e
  * Initialized a sudoers parse tree.
e7179e
  */
e7179e
 void
e7179e
-init_parse_tree(struct sudoers_parse_tree *parse_tree)
e7179e
+init_parse_tree(struct sudoers_parse_tree *parse_tree, const char *lhost,
e7179e
+    const char *shost)
e7179e
 {
e7179e
     TAILQ_INIT(&parse_tree->userspecs);
e7179e
     TAILQ_INIT(&parse_tree->defaults);
e7179e
     parse_tree->aliases = NULL;
e7179e
+    parse_tree->shost = shost;
e7179e
+    parse_tree->lhost = lhost;
e7179e
 }
e7179e
 
e7179e
 /*
e7179e
@@ -1100,7 +1105,7 @@ init_options(struct command_options *opts)
e7179e
     opts->limitprivs = NULL;
e7179e
 #endif
e7179e
 }
e7179e
-#line 1046 "gram.c"
e7179e
+#line 1051 "gram.c"
e7179e
 /* allocate initial stack or double stack size, up to YYMAXDEPTH */
e7179e
 #if defined(__cplusplus) || defined(__STDC__)
e7179e
 static int yygrowstack(void)
e7179e
@@ -1309,23 +1314,23 @@ yyparse()
e7179e
     switch (yyn)
e7179e
     {
e7179e
 case 1:
e7179e
-#line 178 "gram.y"
e7179e
+#line 180 "gram.y"
e7179e
 { ; }
e7179e
 break;
e7179e
 case 5:
e7179e
-#line 186 "gram.y"
e7179e
+#line 188 "gram.y"
e7179e
 {
e7179e
 			    ;
e7179e
 			}
e7179e
 break;
e7179e
 case 6:
e7179e
-#line 189 "gram.y"
e7179e
+#line 191 "gram.y"
e7179e
 {
e7179e
 			    yyerrok;
e7179e
 			}
e7179e
 break;
e7179e
 case 7:
e7179e
-#line 192 "gram.y"
e7179e
+#line 194 "gram.y"
e7179e
 {
e7179e
 			    if (!add_userspec(yyvsp[-1].member, yyvsp[0].privilege)) {
e7179e
 				sudoerserror(N_("unable to allocate memory"));
e7179e
@@ -1334,73 +1339,73 @@ case 7:
e7179e
 			}
e7179e
 break;
e7179e
 case 8:
e7179e
-#line 198 "gram.y"
e7179e
+#line 200 "gram.y"
e7179e
 {
e7179e
 			    ;
e7179e
 			}
e7179e
 break;
e7179e
 case 9:
e7179e
-#line 201 "gram.y"
e7179e
+#line 203 "gram.y"
e7179e
 {
e7179e
 			    ;
e7179e
 			}
e7179e
 break;
e7179e
 case 10:
e7179e
-#line 204 "gram.y"
e7179e
+#line 206 "gram.y"
e7179e
 {
e7179e
 			    ;
e7179e
 			}
e7179e
 break;
e7179e
 case 11:
e7179e
-#line 207 "gram.y"
e7179e
+#line 209 "gram.y"
e7179e
 {
e7179e
 			    ;
e7179e
 			}
e7179e
 break;
e7179e
 case 12:
e7179e
-#line 210 "gram.y"
e7179e
+#line 212 "gram.y"
e7179e
 {
e7179e
 			    if (!add_defaults(DEFAULTS, NULL, yyvsp[0].defaults))
e7179e
 				YYERROR;
e7179e
 			}
e7179e
 break;
e7179e
 case 13:
e7179e
-#line 214 "gram.y"
e7179e
+#line 216 "gram.y"
e7179e
 {
e7179e
 			    if (!add_defaults(DEFAULTS_USER, yyvsp[-1].member, yyvsp[0].defaults))
e7179e
 				YYERROR;
e7179e
 			}
e7179e
 break;
e7179e
 case 14:
e7179e
-#line 218 "gram.y"
e7179e
+#line 220 "gram.y"
e7179e
 {
e7179e
 			    if (!add_defaults(DEFAULTS_RUNAS, yyvsp[-1].member, yyvsp[0].defaults))
e7179e
 				YYERROR;
e7179e
 			}
e7179e
 break;
e7179e
 case 15:
e7179e
-#line 222 "gram.y"
e7179e
+#line 224 "gram.y"
e7179e
 {
e7179e
 			    if (!add_defaults(DEFAULTS_HOST, yyvsp[-1].member, yyvsp[0].defaults))
e7179e
 				YYERROR;
e7179e
 			}
e7179e
 break;
e7179e
 case 16:
e7179e
-#line 226 "gram.y"
e7179e
+#line 228 "gram.y"
e7179e
 {
e7179e
 			    if (!add_defaults(DEFAULTS_CMND, yyvsp[-1].member, yyvsp[0].defaults))
e7179e
 				YYERROR;
e7179e
 			}
e7179e
 break;
e7179e
 case 18:
e7179e
-#line 233 "gram.y"
e7179e
+#line 235 "gram.y"
e7179e
 {
e7179e
 			    HLTQ_CONCAT(yyvsp[-2].defaults, yyvsp[0].defaults, entries);
e7179e
 			    yyval.defaults = yyvsp[-2].defaults;
e7179e
 			}
e7179e
 break;
e7179e
 case 19:
e7179e
-#line 239 "gram.y"
e7179e
+#line 241 "gram.y"
e7179e
 {
e7179e
 			    yyval.defaults = new_default(yyvsp[0].string, NULL, true);
e7179e
 			    if (yyval.defaults == NULL) {
e7179e
@@ -1410,7 +1415,7 @@ case 19:
e7179e
 			}
e7179e
 break;
e7179e
 case 20:
e7179e
-#line 246 "gram.y"
e7179e
+#line 248 "gram.y"
e7179e
 {
e7179e
 			    yyval.defaults = new_default(yyvsp[0].string, NULL, false);
e7179e
 			    if (yyval.defaults == NULL) {
e7179e
@@ -1420,7 +1425,7 @@ case 20:
e7179e
 			}
e7179e
 break;
e7179e
 case 21:
e7179e
-#line 253 "gram.y"
e7179e
+#line 255 "gram.y"
e7179e
 {
e7179e
 			    yyval.defaults = new_default(yyvsp[-2].string, yyvsp[0].string, true);
e7179e
 			    if (yyval.defaults == NULL) {
e7179e
@@ -1430,7 +1435,7 @@ case 21:
e7179e
 			}
e7179e
 break;
e7179e
 case 22:
e7179e
-#line 260 "gram.y"
e7179e
+#line 262 "gram.y"
e7179e
 {
e7179e
 			    yyval.defaults = new_default(yyvsp[-2].string, yyvsp[0].string, '+');
e7179e
 			    if (yyval.defaults == NULL) {
e7179e
@@ -1440,7 +1445,7 @@ case 22:
e7179e
 			}
e7179e
 break;
e7179e
 case 23:
e7179e
-#line 267 "gram.y"
e7179e
+#line 269 "gram.y"
e7179e
 {
e7179e
 			    yyval.defaults = new_default(yyvsp[-2].string, yyvsp[0].string, '-');
e7179e
 			    if (yyval.defaults == NULL) {
e7179e
@@ -1450,14 +1455,14 @@ case 23:
e7179e
 			}
e7179e
 break;
e7179e
 case 25:
e7179e
-#line 277 "gram.y"
e7179e
+#line 279 "gram.y"
e7179e
 {
e7179e
 			    HLTQ_CONCAT(yyvsp[-2].privilege, yyvsp[0].privilege, entries);
e7179e
 			    yyval.privilege = yyvsp[-2].privilege;
e7179e
 			}
e7179e
 break;
e7179e
 case 26:
e7179e
-#line 283 "gram.y"
e7179e
+#line 285 "gram.y"
e7179e
 {
e7179e
 			    struct privilege *p = calloc(1, sizeof(*p));
e7179e
 			    if (p == NULL) {
e7179e
@@ -1472,21 +1477,21 @@ case 26:
e7179e
 			}
e7179e
 break;
e7179e
 case 27:
e7179e
-#line 297 "gram.y"
e7179e
+#line 299 "gram.y"
e7179e
 {
e7179e
 			    yyval.member = yyvsp[0].member;
e7179e
 			    yyval.member->negated = false;
e7179e
 			}
e7179e
 break;
e7179e
 case 28:
e7179e
-#line 301 "gram.y"
e7179e
+#line 303 "gram.y"
e7179e
 {
e7179e
 			    yyval.member = yyvsp[0].member;
e7179e
 			    yyval.member->negated = true;
e7179e
 			}
e7179e
 break;
e7179e
 case 29:
e7179e
-#line 307 "gram.y"
e7179e
+#line 309 "gram.y"
e7179e
 {
e7179e
 			    yyval.member = new_member(yyvsp[0].string, ALIAS);
e7179e
 			    if (yyval.member == NULL) {
e7179e
@@ -1496,7 +1501,7 @@ case 29:
e7179e
 			}
e7179e
 break;
e7179e
 case 30:
e7179e
-#line 314 "gram.y"
e7179e
+#line 316 "gram.y"
e7179e
 {
e7179e
 			    yyval.member = new_member(NULL, ALL);
e7179e
 			    if (yyval.member == NULL) {
e7179e
@@ -1506,7 +1511,7 @@ case 30:
e7179e
 			}
e7179e
 break;
e7179e
 case 31:
e7179e
-#line 321 "gram.y"
e7179e
+#line 323 "gram.y"
e7179e
 {
e7179e
 			    yyval.member = new_member(yyvsp[0].string, NETGROUP);
e7179e
 			    if (yyval.member == NULL) {
e7179e
@@ -1516,7 +1521,7 @@ case 31:
e7179e
 			}
e7179e
 break;
e7179e
 case 32:
e7179e
-#line 328 "gram.y"
e7179e
+#line 330 "gram.y"
e7179e
 {
e7179e
 			    yyval.member = new_member(yyvsp[0].string, NTWKADDR);
e7179e
 			    if (yyval.member == NULL) {
e7179e
@@ -1526,7 +1531,7 @@ case 32:
e7179e
 			}
e7179e
 break;
e7179e
 case 33:
e7179e
-#line 335 "gram.y"
e7179e
+#line 337 "gram.y"
e7179e
 {
e7179e
 			    yyval.member = new_member(yyvsp[0].string, WORD);
e7179e
 			    if (yyval.member == NULL) {
e7179e
@@ -1536,7 +1541,7 @@ case 33:
e7179e
 			}
e7179e
 break;
e7179e
 case 35:
e7179e
-#line 345 "gram.y"
e7179e
+#line 347 "gram.y"
e7179e
 {
e7179e
 			    struct cmndspec *prev;
e7179e
 			    prev = HLTQ_LAST(yyvsp[-2].cmndspec, cmndspec, entries);
e7179e
@@ -1590,7 +1595,7 @@ case 35:
e7179e
 			}
e7179e
 break;
e7179e
 case 36:
e7179e
-#line 398 "gram.y"
e7179e
+#line 400 "gram.y"
e7179e
 {
e7179e
 			    struct cmndspec *cs = calloc(1, sizeof(*cs));
e7179e
 			    if (cs == NULL) {
e7179e
@@ -1642,7 +1647,7 @@ case 36:
e7179e
 			}
e7179e
 break;
e7179e
 case 37:
e7179e
-#line 449 "gram.y"
e7179e
+#line 451 "gram.y"
e7179e
 {
e7179e
 			    yyval.digest = new_digest(SUDO_DIGEST_SHA224, yyvsp[0].string);
e7179e
 			    if (yyval.digest == NULL) {
e7179e
@@ -1652,7 +1657,7 @@ case 37:
e7179e
 			}
e7179e
 break;
e7179e
 case 38:
e7179e
-#line 456 "gram.y"
e7179e
+#line 458 "gram.y"
e7179e
 {
e7179e
 			    yyval.digest = new_digest(SUDO_DIGEST_SHA256, yyvsp[0].string);
e7179e
 			    if (yyval.digest == NULL) {
e7179e
@@ -1662,7 +1667,7 @@ case 38:
e7179e
 			}
e7179e
 break;
e7179e
 case 39:
e7179e
-#line 463 "gram.y"
e7179e
+#line 465 "gram.y"
e7179e
 {
e7179e
 			    yyval.digest = new_digest(SUDO_DIGEST_SHA384, yyvsp[0].string);
e7179e
 			    if (yyval.digest == NULL) {
e7179e
@@ -1672,7 +1677,7 @@ case 39:
e7179e
 			}
e7179e
 break;
e7179e
 case 40:
e7179e
-#line 470 "gram.y"
e7179e
+#line 472 "gram.y"
e7179e
 {
e7179e
 			    yyval.digest = new_digest(SUDO_DIGEST_SHA512, yyvsp[0].string);
e7179e
 			    if (yyval.digest == NULL) {
e7179e
@@ -1682,13 +1687,13 @@ case 40:
e7179e
 			}
e7179e
 break;
e7179e
 case 41:
e7179e
-#line 479 "gram.y"
e7179e
+#line 481 "gram.y"
e7179e
 {
e7179e
 			    yyval.member = yyvsp[0].member;
e7179e
 			}
e7179e
 break;
e7179e
 case 42:
e7179e
-#line 482 "gram.y"
e7179e
+#line 484 "gram.y"
e7179e
 {
e7179e
 			    if (yyvsp[0].member->type != COMMAND) {
e7179e
 				sudoerserror(N_("a digest requires a path name"));
e7179e
@@ -1700,75 +1705,75 @@ case 42:
e7179e
 			}
e7179e
 break;
e7179e
 case 43:
e7179e
-#line 493 "gram.y"
e7179e
+#line 495 "gram.y"
e7179e
 {
e7179e
 			    yyval.member = yyvsp[0].member;
e7179e
 			    yyval.member->negated = false;
e7179e
 			}
e7179e
 break;
e7179e
 case 44:
e7179e
-#line 497 "gram.y"
e7179e
+#line 499 "gram.y"
e7179e
 {
e7179e
 			    yyval.member = yyvsp[0].member;
e7179e
 			    yyval.member->negated = true;
e7179e
 			}
e7179e
 break;
e7179e
 case 45:
e7179e
-#line 503 "gram.y"
e7179e
+#line 505 "gram.y"
e7179e
 {
e7179e
 			    yyval.string = yyvsp[0].string;
e7179e
 			}
e7179e
 break;
e7179e
 case 46:
e7179e
-#line 508 "gram.y"
e7179e
+#line 510 "gram.y"
e7179e
 {
e7179e
 			    yyval.string = yyvsp[0].string;
e7179e
 			}
e7179e
 break;
e7179e
 case 47:
e7179e
-#line 512 "gram.y"
e7179e
+#line 514 "gram.y"
e7179e
 {
e7179e
 			    yyval.string = yyvsp[0].string;
e7179e
 			}
e7179e
 break;
e7179e
 case 48:
e7179e
-#line 517 "gram.y"
e7179e
+#line 519 "gram.y"
e7179e
 {
e7179e
 			    yyval.string = yyvsp[0].string;
e7179e
 			}
e7179e
 break;
e7179e
 case 49:
e7179e
-#line 522 "gram.y"
e7179e
+#line 524 "gram.y"
e7179e
 {
e7179e
 			    yyval.string = yyvsp[0].string;
e7179e
 			}
e7179e
 break;
e7179e
 case 50:
e7179e
-#line 527 "gram.y"
e7179e
+#line 529 "gram.y"
e7179e
 {
e7179e
 			    yyval.string = yyvsp[0].string;
e7179e
 			}
e7179e
 break;
e7179e
 case 51:
e7179e
-#line 531 "gram.y"
e7179e
+#line 533 "gram.y"
e7179e
 {
e7179e
 			    yyval.string = yyvsp[0].string;
e7179e
 			}
e7179e
 break;
e7179e
 case 52:
e7179e
-#line 536 "gram.y"
e7179e
+#line 538 "gram.y"
e7179e
 {
e7179e
 			    yyval.runas = NULL;
e7179e
 			}
e7179e
 break;
e7179e
 case 53:
e7179e
-#line 539 "gram.y"
e7179e
+#line 541 "gram.y"
e7179e
 {
e7179e
 			    yyval.runas = yyvsp[-1].runas;
e7179e
 			}
e7179e
 break;
e7179e
 case 54:
e7179e
-#line 544 "gram.y"
e7179e
+#line 546 "gram.y"
e7179e
 {
e7179e
 			    yyval.runas = calloc(1, sizeof(struct runascontainer));
e7179e
 			    if (yyval.runas != NULL) {
e7179e
@@ -1786,7 +1791,7 @@ case 54:
e7179e
 			}
e7179e
 break;
e7179e
 case 55:
e7179e
-#line 559 "gram.y"
e7179e
+#line 561 "gram.y"
e7179e
 {
e7179e
 			    yyval.runas = calloc(1, sizeof(struct runascontainer));
e7179e
 			    if (yyval.runas == NULL) {
e7179e
@@ -1798,7 +1803,7 @@ case 55:
e7179e
 			}
e7179e
 break;
e7179e
 case 56:
e7179e
-#line 568 "gram.y"
e7179e
+#line 570 "gram.y"
e7179e
 {
e7179e
 			    yyval.runas = calloc(1, sizeof(struct runascontainer));
e7179e
 			    if (yyval.runas == NULL) {
e7179e
@@ -1810,7 +1815,7 @@ case 56:
e7179e
 			}
e7179e
 break;
e7179e
 case 57:
e7179e
-#line 577 "gram.y"
e7179e
+#line 579 "gram.y"
e7179e
 {
e7179e
 			    yyval.runas = calloc(1, sizeof(struct runascontainer));
e7179e
 			    if (yyval.runas == NULL) {
e7179e
@@ -1822,7 +1827,7 @@ case 57:
e7179e
 			}
e7179e
 break;
e7179e
 case 58:
e7179e
-#line 586 "gram.y"
e7179e
+#line 588 "gram.y"
e7179e
 {
e7179e
 			    yyval.runas = calloc(1, sizeof(struct runascontainer));
e7179e
 			    if (yyval.runas != NULL) {
e7179e
@@ -1840,13 +1845,13 @@ case 58:
e7179e
 			}
e7179e
 break;
e7179e
 case 59:
e7179e
-#line 603 "gram.y"
e7179e
+#line 605 "gram.y"
e7179e
 {
e7179e
 			    init_options(&yyval.options);
e7179e
 			}
e7179e
 break;
e7179e
 case 60:
e7179e
-#line 606 "gram.y"
e7179e
+#line 608 "gram.y"
e7179e
 {
e7179e
 			    yyval.options.notbefore = parse_gentime(yyvsp[0].string);
e7179e
 			    free(yyvsp[0].string);
e7179e
@@ -1857,7 +1862,7 @@ case 60:
e7179e
 			}
e7179e
 break;
e7179e
 case 61:
e7179e
-#line 614 "gram.y"
e7179e
+#line 616 "gram.y"
e7179e
 {
e7179e
 			    yyval.options.notafter = parse_gentime(yyvsp[0].string);
e7179e
 			    free(yyvsp[0].string);
e7179e
@@ -1868,7 +1873,7 @@ case 61:
e7179e
 			}
e7179e
 break;
e7179e
 case 62:
e7179e
-#line 622 "gram.y"
e7179e
+#line 624 "gram.y"
e7179e
 {
e7179e
 			    yyval.options.timeout = parse_timeout(yyvsp[0].string);
e7179e
 			    free(yyvsp[0].string);
e7179e
@@ -1882,7 +1887,7 @@ case 62:
e7179e
 			}
e7179e
 break;
e7179e
 case 63:
e7179e
-#line 633 "gram.y"
e7179e
+#line 635 "gram.y"
e7179e
 {
e7179e
 #ifdef HAVE_SELINUX
e7179e
 			    free(yyval.options.role);
e7179e
@@ -1891,7 +1896,7 @@ case 63:
e7179e
 			}
e7179e
 break;
e7179e
 case 64:
e7179e
-#line 639 "gram.y"
e7179e
+#line 641 "gram.y"
e7179e
 {
e7179e
 #ifdef HAVE_SELINUX
e7179e
 			    free(yyval.options.type);
e7179e
@@ -1900,7 +1905,7 @@ case 64:
e7179e
 			}
e7179e
 break;
e7179e
 case 65:
e7179e
-#line 645 "gram.y"
e7179e
+#line 647 "gram.y"
e7179e
 {
e7179e
 #ifdef HAVE_PRIV_SET
e7179e
 			    free(yyval.options.privs);
e7179e
@@ -1909,7 +1914,7 @@ case 65:
e7179e
 			}
e7179e
 break;
e7179e
 case 66:
e7179e
-#line 651 "gram.y"
e7179e
+#line 653 "gram.y"
e7179e
 {
e7179e
 #ifdef HAVE_PRIV_SET
e7179e
 			    free(yyval.options.limitprivs);
e7179e
@@ -1918,97 +1923,97 @@ case 66:
e7179e
 			}
e7179e
 break;
e7179e
 case 67:
e7179e
-#line 659 "gram.y"
e7179e
+#line 661 "gram.y"
e7179e
 {
e7179e
 			    TAGS_INIT(yyval.tag);
e7179e
 			}
e7179e
 break;
e7179e
 case 68:
e7179e
-#line 662 "gram.y"
e7179e
+#line 664 "gram.y"
e7179e
 {
e7179e
 			    yyval.tag.nopasswd = true;
e7179e
 			}
e7179e
 break;
e7179e
 case 69:
e7179e
-#line 665 "gram.y"
e7179e
+#line 667 "gram.y"
e7179e
 {
e7179e
 			    yyval.tag.nopasswd = false;
e7179e
 			}
e7179e
 break;
e7179e
 case 70:
e7179e
-#line 668 "gram.y"
e7179e
+#line 670 "gram.y"
e7179e
 {
e7179e
 			    yyval.tag.noexec = true;
e7179e
 			}
e7179e
 break;
e7179e
 case 71:
e7179e
-#line 671 "gram.y"
e7179e
+#line 673 "gram.y"
e7179e
 {
e7179e
 			    yyval.tag.noexec = false;
e7179e
 			}
e7179e
 break;
e7179e
 case 72:
e7179e
-#line 674 "gram.y"
e7179e
+#line 676 "gram.y"
e7179e
 {
e7179e
 			    yyval.tag.setenv = true;
e7179e
 			}
e7179e
 break;
e7179e
 case 73:
e7179e
-#line 677 "gram.y"
e7179e
+#line 679 "gram.y"
e7179e
 {
e7179e
 			    yyval.tag.setenv = false;
e7179e
 			}
e7179e
 break;
e7179e
 case 74:
e7179e
-#line 680 "gram.y"
e7179e
+#line 682 "gram.y"
e7179e
 {
e7179e
 			    yyval.tag.log_input = true;
e7179e
 			}
e7179e
 break;
e7179e
 case 75:
e7179e
-#line 683 "gram.y"
e7179e
+#line 685 "gram.y"
e7179e
 {
e7179e
 			    yyval.tag.log_input = false;
e7179e
 			}
e7179e
 break;
e7179e
 case 76:
e7179e
-#line 686 "gram.y"
e7179e
+#line 688 "gram.y"
e7179e
 {
e7179e
 			    yyval.tag.log_output = true;
e7179e
 			}
e7179e
 break;
e7179e
 case 77:
e7179e
-#line 689 "gram.y"
e7179e
+#line 691 "gram.y"
e7179e
 {
e7179e
 			    yyval.tag.log_output = false;
e7179e
 			}
e7179e
 break;
e7179e
 case 78:
e7179e
-#line 692 "gram.y"
e7179e
+#line 694 "gram.y"
e7179e
 {
e7179e
 			    yyval.tag.follow = true;
e7179e
 			}
e7179e
 break;
e7179e
 case 79:
e7179e
-#line 695 "gram.y"
e7179e
+#line 697 "gram.y"
e7179e
 {
e7179e
 			    yyval.tag.follow = false;
e7179e
 			}
e7179e
 break;
e7179e
 case 80:
e7179e
-#line 698 "gram.y"
e7179e
+#line 700 "gram.y"
e7179e
 {
e7179e
 			    yyval.tag.send_mail = true;
e7179e
 			}
e7179e
 break;
e7179e
 case 81:
e7179e
-#line 701 "gram.y"
e7179e
+#line 703 "gram.y"
e7179e
 {
e7179e
 			    yyval.tag.send_mail = false;
e7179e
 			}
e7179e
 break;
e7179e
 case 82:
e7179e
-#line 706 "gram.y"
e7179e
+#line 708 "gram.y"
e7179e
 {
e7179e
 			    yyval.member = new_member(NULL, ALL);
e7179e
 			    if (yyval.member == NULL) {
e7179e
@@ -2018,7 +2023,7 @@ case 82:
e7179e
 			}
e7179e
 break;
e7179e
 case 83:
e7179e
-#line 713 "gram.y"
e7179e
+#line 715 "gram.y"
e7179e
 {
e7179e
 			    yyval.member = new_member(yyvsp[0].string, ALIAS);
e7179e
 			    if (yyval.member == NULL) {
e7179e
@@ -2028,7 +2033,7 @@ case 83:
e7179e
 			}
e7179e
 break;
e7179e
 case 84:
e7179e
-#line 720 "gram.y"
e7179e
+#line 722 "gram.y"
e7179e
 {
e7179e
 			    struct sudo_command *c = calloc(1, sizeof(*c));
e7179e
 			    if (c == NULL) {
e7179e
@@ -2046,7 +2051,7 @@ case 84:
e7179e
 			}
e7179e
 break;
e7179e
 case 87:
e7179e
-#line 741 "gram.y"
e7179e
+#line 743 "gram.y"
e7179e
 {
e7179e
 			    const char *s;
e7179e
 			    s = alias_add(&parsed_policy, yyvsp[-2].string, HOSTALIAS,
e7179e
@@ -2058,14 +2063,14 @@ case 87:
e7179e
 			}
e7179e
 break;
e7179e
 case 89:
e7179e
-#line 753 "gram.y"
e7179e
+#line 755 "gram.y"
e7179e
 {
e7179e
 			    HLTQ_CONCAT(yyvsp[-2].member, yyvsp[0].member, entries);
e7179e
 			    yyval.member = yyvsp[-2].member;
e7179e
 			}
e7179e
 break;
e7179e
 case 92:
e7179e
-#line 763 "gram.y"
e7179e
+#line 765 "gram.y"
e7179e
 {
e7179e
 			    const char *s;
e7179e
 			    s = alias_add(&parsed_policy, yyvsp[-2].string, CMNDALIAS,
e7179e
@@ -2077,14 +2082,14 @@ case 92:
e7179e
 			}
e7179e
 break;
e7179e
 case 94:
e7179e
-#line 775 "gram.y"
e7179e
+#line 777 "gram.y"
e7179e
 {
e7179e
 			    HLTQ_CONCAT(yyvsp[-2].member, yyvsp[0].member, entries);
e7179e
 			    yyval.member = yyvsp[-2].member;
e7179e
 			}
e7179e
 break;
e7179e
 case 97:
e7179e
-#line 785 "gram.y"
e7179e
+#line 787 "gram.y"
e7179e
 {
e7179e
 			    const char *s;
e7179e
 			    s = alias_add(&parsed_policy, yyvsp[-2].string, RUNASALIAS,
e7179e
@@ -2096,7 +2101,7 @@ case 97:
e7179e
 			}
e7179e
 break;
e7179e
 case 100:
e7179e
-#line 800 "gram.y"
e7179e
+#line 802 "gram.y"
e7179e
 {
e7179e
 			    const char *s;
e7179e
 			    s = alias_add(&parsed_policy, yyvsp[-2].string, USERALIAS,
e7179e
@@ -2108,28 +2113,28 @@ case 100:
e7179e
 			}
e7179e
 break;
e7179e
 case 102:
e7179e
-#line 812 "gram.y"
e7179e
+#line 814 "gram.y"
e7179e
 {
e7179e
 			    HLTQ_CONCAT(yyvsp[-2].member, yyvsp[0].member, entries);
e7179e
 			    yyval.member = yyvsp[-2].member;
e7179e
 			}
e7179e
 break;
e7179e
 case 103:
e7179e
-#line 818 "gram.y"
e7179e
+#line 820 "gram.y"
e7179e
 {
e7179e
 			    yyval.member = yyvsp[0].member;
e7179e
 			    yyval.member->negated = false;
e7179e
 			}
e7179e
 break;
e7179e
 case 104:
e7179e
-#line 822 "gram.y"
e7179e
+#line 824 "gram.y"
e7179e
 {
e7179e
 			    yyval.member = yyvsp[0].member;
e7179e
 			    yyval.member->negated = true;
e7179e
 			}
e7179e
 break;
e7179e
 case 105:
e7179e
-#line 828 "gram.y"
e7179e
+#line 830 "gram.y"
e7179e
 {
e7179e
 			    yyval.member = new_member(yyvsp[0].string, ALIAS);
e7179e
 			    if (yyval.member == NULL) {
e7179e
@@ -2139,7 +2144,7 @@ case 105:
e7179e
 			}
e7179e
 break;
e7179e
 case 106:
e7179e
-#line 835 "gram.y"
e7179e
+#line 837 "gram.y"
e7179e
 {
e7179e
 			    yyval.member = new_member(NULL, ALL);
e7179e
 			    if (yyval.member == NULL) {
e7179e
@@ -2149,7 +2154,7 @@ case 106:
e7179e
 			}
e7179e
 break;
e7179e
 case 107:
e7179e
-#line 842 "gram.y"
e7179e
+#line 844 "gram.y"
e7179e
 {
e7179e
 			    yyval.member = new_member(yyvsp[0].string, NETGROUP);
e7179e
 			    if (yyval.member == NULL) {
e7179e
@@ -2159,7 +2164,7 @@ case 107:
e7179e
 			}
e7179e
 break;
e7179e
 case 108:
e7179e
-#line 849 "gram.y"
e7179e
+#line 851 "gram.y"
e7179e
 {
e7179e
 			    yyval.member = new_member(yyvsp[0].string, USERGROUP);
e7179e
 			    if (yyval.member == NULL) {
e7179e
@@ -2169,7 +2174,7 @@ case 108:
e7179e
 			}
e7179e
 break;
e7179e
 case 109:
e7179e
-#line 856 "gram.y"
e7179e
+#line 858 "gram.y"
e7179e
 {
e7179e
 			    yyval.member = new_member(yyvsp[0].string, WORD);
e7179e
 			    if (yyval.member == NULL) {
e7179e
@@ -2179,28 +2184,28 @@ case 109:
e7179e
 			}
e7179e
 break;
e7179e
 case 111:
e7179e
-#line 866 "gram.y"
e7179e
+#line 868 "gram.y"
e7179e
 {
e7179e
 			    HLTQ_CONCAT(yyvsp[-2].member, yyvsp[0].member, entries);
e7179e
 			    yyval.member = yyvsp[-2].member;
e7179e
 			}
e7179e
 break;
e7179e
 case 112:
e7179e
-#line 872 "gram.y"
e7179e
+#line 874 "gram.y"
e7179e
 {
e7179e
 			    yyval.member = yyvsp[0].member;
e7179e
 			    yyval.member->negated = false;
e7179e
 			}
e7179e
 break;
e7179e
 case 113:
e7179e
-#line 876 "gram.y"
e7179e
+#line 878 "gram.y"
e7179e
 {
e7179e
 			    yyval.member = yyvsp[0].member;
e7179e
 			    yyval.member->negated = true;
e7179e
 			}
e7179e
 break;
e7179e
 case 114:
e7179e
-#line 882 "gram.y"
e7179e
+#line 884 "gram.y"
e7179e
 {
e7179e
 			    yyval.member = new_member(yyvsp[0].string, ALIAS);
e7179e
 			    if (yyval.member == NULL) {
e7179e
@@ -2210,7 +2215,7 @@ case 114:
e7179e
 			}
e7179e
 break;
e7179e
 case 115:
e7179e
-#line 889 "gram.y"
e7179e
+#line 891 "gram.y"
e7179e
 {
e7179e
 			    yyval.member = new_member(NULL, ALL);
e7179e
 			    if (yyval.member == NULL) {
e7179e
@@ -2220,7 +2225,7 @@ case 115:
e7179e
 			}
e7179e
 break;
e7179e
 case 116:
e7179e
-#line 896 "gram.y"
e7179e
+#line 898 "gram.y"
e7179e
 {
e7179e
 			    yyval.member = new_member(yyvsp[0].string, WORD);
e7179e
 			    if (yyval.member == NULL) {
e7179e
@@ -2229,7 +2234,7 @@ case 116:
e7179e
 			    }
e7179e
 			}
e7179e
 break;
e7179e
-#line 2175 "gram.c"
e7179e
+#line 2180 "gram.c"
e7179e
     }
e7179e
     yyssp -= yym;
e7179e
     yystate = *yyssp;
e7179e
diff --git a/plugins/sudoers/gram.y b/plugins/sudoers/gram.y
e7179e
index 6f437062..e4a0b6d3 100644
e7179e
--- a/plugins/sudoers/gram.y
e7179e
+++ b/plugins/sudoers/gram.y
e7179e
@@ -63,7 +63,9 @@ char *errorfile = NULL;
e7179e
 struct sudoers_parse_tree parsed_policy = {
e7179e
     TAILQ_HEAD_INITIALIZER(parsed_policy.userspecs),
e7179e
     TAILQ_HEAD_INITIALIZER(parsed_policy.defaults),
e7179e
-    NULL /* aliases */
e7179e
+    NULL, /* aliases */
e7179e
+    NULL, /* lhost */
e7179e
+    NULL /* shost */
e7179e
 };
e7179e
 
e7179e
 /*
e7179e
@@ -1246,11 +1248,14 @@ free_userspec(struct userspec *us)
e7179e
  * Initialized a sudoers parse tree.
e7179e
  */
e7179e
 void
e7179e
-init_parse_tree(struct sudoers_parse_tree *parse_tree)
e7179e
+init_parse_tree(struct sudoers_parse_tree *parse_tree, const char *lhost,
e7179e
+    const char *shost)
e7179e
 {
e7179e
     TAILQ_INIT(&parse_tree->userspecs);
e7179e
     TAILQ_INIT(&parse_tree->defaults);
e7179e
     parse_tree->aliases = NULL;
e7179e
+    parse_tree->shost = shost;
e7179e
+    parse_tree->lhost = lhost;
e7179e
 }
e7179e
 
e7179e
 /*
e7179e
diff --git a/plugins/sudoers/ldap.c b/plugins/sudoers/ldap.c
e7179e
index 3bbd2523..1a4212bf 100644
e7179e
--- a/plugins/sudoers/ldap.c
e7179e
+++ b/plugins/sudoers/ldap.c
e7179e
@@ -1665,7 +1665,7 @@ sudo_ldap_open(struct sudo_nss *nss)
e7179e
     }
e7179e
     handle->ld = ld;
e7179e
     /* handle->pw = NULL; */
e7179e
-    init_parse_tree(&handle->parse_tree);
e7179e
+    init_parse_tree(&handle->parse_tree, NULL, NULL);
e7179e
     nss->handle = handle;
e7179e
 
e7179e
 done:
e7179e
diff --git a/plugins/sudoers/match.c b/plugins/sudoers/match.c
e7179e
index 1936d4b0..165a8f75 100644
e7179e
--- a/plugins/sudoers/match.c
e7179e
+++ b/plugins/sudoers/match.c
e7179e
@@ -72,8 +72,10 @@ int
e7179e
 user_matches(struct sudoers_parse_tree *parse_tree, const struct passwd *pw,
e7179e
     const struct member *m)
e7179e
 {
e7179e
-    struct alias *a;
e7179e
+    const char *lhost = parse_tree->lhost ? parse_tree->lhost : user_runhost;
e7179e
+    const char *shost = parse_tree->shost ? parse_tree->shost : user_srunhost;
e7179e
     int matched = UNSPEC;
e7179e
+    struct alias *a;
e7179e
     debug_decl(user_matches, SUDOERS_DEBUG_MATCH)
e7179e
 
e7179e
     switch (m->type) {
e7179e
@@ -82,8 +84,8 @@ user_matches(struct sudoers_parse_tree *parse_tree, const struct passwd *pw,
e7179e
 	    break;
e7179e
 	case NETGROUP:
e7179e
 	    if (netgr_matches(m->name,
e7179e
-		def_netgroup_tuple ? user_runhost : NULL,
e7179e
-		def_netgroup_tuple ? user_srunhost : NULL, pw->pw_name))
e7179e
+		def_netgroup_tuple ? lhost : NULL,
e7179e
+		def_netgroup_tuple ? shost : NULL, pw->pw_name))
e7179e
 		matched = !m->negated;
e7179e
 	    break;
e7179e
 	case USERGROUP:
e7179e
@@ -153,11 +155,13 @@ runaslist_matches(struct sudoers_parse_tree *parse_tree,
e7179e
     const struct member_list *user_list, const struct member_list *group_list,
e7179e
     struct member **matching_user, struct member **matching_group)
e7179e
 {
e7179e
+    const char *lhost = parse_tree->lhost ? parse_tree->lhost : user_runhost;
e7179e
+    const char *shost = parse_tree->shost ? parse_tree->shost : user_srunhost;
e7179e
+    int user_matched = UNSPEC;
e7179e
+    int group_matched = UNSPEC;
e7179e
     struct member *m;
e7179e
     struct alias *a;
e7179e
     int rc;
e7179e
-    int user_matched = UNSPEC;
e7179e
-    int group_matched = UNSPEC;
e7179e
     debug_decl(runaslist_matches, SUDOERS_DEBUG_MATCH)
e7179e
 
e7179e
     if (ISSET(sudo_user.flags, RUNAS_USER_SPECIFIED) || !ISSET(sudo_user.flags, RUNAS_GROUP_SPECIFIED)) {
e7179e
@@ -175,8 +179,8 @@ runaslist_matches(struct sudoers_parse_tree *parse_tree,
e7179e
 			break;
e7179e
 		    case NETGROUP:
e7179e
 			if (netgr_matches(m->name,
e7179e
-			    def_netgroup_tuple ? user_runhost : NULL,
e7179e
-			    def_netgroup_tuple ? user_srunhost : NULL,
e7179e
+			    def_netgroup_tuple ? lhost : NULL,
e7179e
+			    def_netgroup_tuple ? shost : NULL,
e7179e
 			    runas_pw->pw_name))
e7179e
 			    user_matched = !m->negated;
e7179e
 			break;
e7179e
@@ -309,7 +313,10 @@ int
e7179e
 hostlist_matches(struct sudoers_parse_tree *parse_tree, const struct passwd *pw,
e7179e
     const struct member_list *list)
e7179e
 {
e7179e
-    return hostlist_matches_int(parse_tree, pw, user_runhost, user_srunhost, list);
e7179e
+    const char *lhost = parse_tree->lhost ? parse_tree->lhost : user_runhost;
e7179e
+    const char *shost = parse_tree->shost ? parse_tree->shost : user_srunhost;
e7179e
+
e7179e
+    return hostlist_matches_int(parse_tree, pw, lhost, shost, list);
e7179e
 }
e7179e
 
e7179e
 /*
e7179e
diff --git a/plugins/sudoers/parse.h b/plugins/sudoers/parse.h
e7179e
index 30813f6d..f5961f7f 100644
e7179e
--- a/plugins/sudoers/parse.h
e7179e
+++ b/plugins/sudoers/parse.h
e7179e
@@ -272,6 +272,7 @@ struct sudoers_parse_tree {
e7179e
     struct userspec_list userspecs;
e7179e
     struct defaults_list defaults;
e7179e
     struct rbtree *aliases;
e7179e
+    const char *shost, *lhost;
e7179e
 };
e7179e
 
e7179e
 /* alias.c */
e7179e
@@ -297,7 +298,7 @@ void free_userspec(struct userspec *us);
e7179e
 void free_userspecs(struct userspec_list *usl);
e7179e
 void free_default(struct defaults *def, struct member_list **binding);
e7179e
 void free_defaults(struct defaults_list *defs);
e7179e
-void init_parse_tree(struct sudoers_parse_tree *parse_tree);
e7179e
+void init_parse_tree(struct sudoers_parse_tree *parse_tree, const char *shost, const char *lhost);
e7179e
 void free_parse_tree(struct sudoers_parse_tree *parse_tree);
e7179e
 void reparent_parse_tree(struct sudoers_parse_tree *new_tree);
e7179e
 
e7179e
diff --git a/plugins/sudoers/sssd.c b/plugins/sudoers/sssd.c
e7179e
index 4f4464a6..69f6c1f9 100644
e7179e
--- a/plugins/sudoers/sssd.c
e7179e
+++ b/plugins/sudoers/sssd.c
e7179e
@@ -554,7 +554,6 @@ sudo_sss_open(struct sudo_nss *nss)
e7179e
 	sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
e7179e
 	debug_return_int(ENOMEM);
e7179e
     }
e7179e
-    init_parse_tree(&handle->parse_tree);
e7179e
 
e7179e
     /* Load symbols */
e7179e
     handle->ssslib = sudo_dso_load(path, SUDO_DSO_LAZY);
e7179e
@@ -612,8 +611,6 @@ sudo_sss_open(struct sudo_nss *nss)
e7179e
 	debug_return_int(EFAULT);
e7179e
     }
e7179e
 
e7179e
-    nss->handle = handle;
e7179e
-
e7179e
     /*
e7179e
      * If runhost is the same as the local host, check for ipa_hostname
e7179e
      * in sssd.conf and use it in preference to user_runhost.
e7179e
@@ -625,6 +622,10 @@ sudo_sss_open(struct sudo_nss *nss)
e7179e
 	}
e7179e
     }
e7179e
 
e7179e
+    /* The "parse tree" contains userspecs, defaults, aliases and hostnames. */
e7179e
+    init_parse_tree(&handle->parse_tree, handle->ipa_host, handle->ipa_shost);
e7179e
+    nss->handle = handle;
e7179e
+
e7179e
     sudo_debug_printf(SUDO_DEBUG_DEBUG, "handle=%p", handle);
e7179e
 
e7179e
     debug_return_int(0);