git: 097db30a8e03 - main - jail: Allow nested jail definitions.

From: Jamie Gritton <jamie_at_FreeBSD.org>
Date: Sun, 04 Jun 2023 00:46:25 UTC
The branch main has been updated by jamie:

URL: https://cgit.FreeBSD.org/src/commit/?id=097db30a8e0310ac28075787fb92ea40dad8b27b

commit 097db30a8e0310ac28075787fb92ea40dad8b27b
Author:     Jamie Gritton <jamie@FreeBSD.org>
AuthorDate: 2023-06-04 00:45:54 +0000
Commit:     Jamie Gritton <jamie@FreeBSD.org>
CommitDate: 2023-06-04 00:45:54 +0000

    jail: Allow nested jail definitions.
    
    Make the jail.conf specification recursive, with jail definitions
    allowed within a jail's parameter list, just as they are allowed
    at the top level.  Such inner jails are part of the outer jail's
    hierarchy, as if they were specified with hierarchical names.
---
 usr.sbin/jail/jailp.h     |  1 +
 usr.sbin/jail/jailparse.y | 65 +++++++++++++++++++++++++----------------------
 2 files changed, 36 insertions(+), 30 deletions(-)

diff --git a/usr.sbin/jail/jailp.h b/usr.sbin/jail/jailp.h
index 00865185fbd1..0325c2a101a4 100644
--- a/usr.sbin/jail/jailp.h
+++ b/usr.sbin/jail/jailp.h
@@ -176,6 +176,7 @@ struct cfjail {
 	struct cfparams		params;
 	struct cfdepends	dep[2];
 	struct cfjails		*queue;
+	struct cfjail		*cfparent;
 	struct cfparam		*intparams[IP_NPARAM];
 	struct cfstring		*comstring;
 	struct jailparam	*jp;
diff --git a/usr.sbin/jail/jailparse.y b/usr.sbin/jail/jailparse.y
index 9426444f0d09..44e2aacb457e 100644
--- a/usr.sbin/jail/jailparse.y
+++ b/usr.sbin/jail/jailparse.y
@@ -38,11 +38,12 @@ __FBSDID("$FreeBSD$");
 #ifdef DEBUG
 #define YYDEBUG 1
 #endif
+
+static struct cfjail *current_jail;
+static struct cfjail *global_jail;
 %}
 
 %union {
-	struct cfjail		*j;
-	struct cfparams		*pp;
 	struct cfparam		*p;
 	struct cfstrings	*ss;
 	struct cfstring		*s;
@@ -52,8 +53,6 @@ __FBSDID("$FreeBSD$");
 %token      PLEQ
 %token <cs> STR STR1 VAR VAR1
 
-%type <j>  jail
-%type <pp> param_l
 %type <p>  param name
 %type <ss> value
 %type <s>  string
@@ -61,46 +60,54 @@ __FBSDID("$FreeBSD$");
 %%
 
 /*
- * A config file is a series of jails (containing parameters) and jail-less
- * parameters which really belong to a global pseudo-jail.
+ * A config file is a list of jails and parameters.  Parameters are
+ * added to the current jail, otherwise to a global pesudo-jail.
  */
 conf	:
-	;
 	| conf jail
-	;
 	| conf param ';'
 	{
-		struct cfjail *j;
+		struct cfjail *j = current_jail;
 
-		j = TAILQ_LAST(&cfjails, cfjails);
-		if (!j || strcmp(j->name, "*")) {
-			j = add_jail();
-			j->name = estrdup("*");
+		if (j == NULL) {
+			if (global_jail == NULL) {
+				global_jail = add_jail();
+				global_jail->name = estrdup("*");
+			}
+			j = global_jail;
 		}
 		TAILQ_INSERT_TAIL(&j->params, $2, tq);
 	}
 	| conf ';'
+	;
 
-jail	: STR '{' param_l '}'
+jail	: jail_name '{' conf '}'
 	{
-		$$ = add_jail();
-		$$->name = $1;
-		TAILQ_CONCAT(&$$->params, $3, tq);
-		free($3);
+		current_jail = current_jail->cfparent;
 	}
 	;
 
-param_l	:
-	{
-		$$ = emalloc(sizeof(struct cfparams));
-		TAILQ_INIT($$);
-	}
-	| param_l param ';'
-	{
-		$$ = $1;
-		TAILQ_INSERT_TAIL($$, $2, tq);
+jail_name : STR
+	{
+		struct cfjail *j = add_jail();
+
+		if (current_jail == NULL)
+			j->name = $1;
+		else {
+			/*
+			 * A nested jail definition becomes
+			 * a hierarchically-named sub-jail.
+			 */
+			size_t parentlen = strlen(current_jail->name);
+			j->name = emalloc(parentlen + strlen($1) + 2);
+			strcpy(j->name, current_jail->name);
+			j->name[parentlen++] = '.';
+			strcpy(j->name + parentlen, $1);
+			free($1);
+		}
+		j->cfparent = current_jail;
+		current_jail = j;
 	}
-	| param_l ';'
 	;
 
 /*
@@ -131,8 +138,6 @@ param	: name
 		free($2);
 	}
 	| error
-	{
-	}
 	;
 
 /*