summaryrefslogtreecommitdiffhomepage
path: root/src/nxt_conf_validation.c
diff options
context:
space:
mode:
authorKonstantin Pavlov <thresh@nginx.com>2019-09-19 19:04:16 +0300
committerKonstantin Pavlov <thresh@nginx.com>2019-09-19 19:04:16 +0300
commitdeb26fa47a9ab1b358938134a8ced8bbc4a083e1 (patch)
tree0bedf8829f003fa4c0101e3421b7184acc1c8343 /src/nxt_conf_validation.c
parentfcb1f851d0b5d1774a6cb876288ea29cfef58618 (diff)
parentdb777d1e7f607d1b0f01dfb73ad0bac12987202b (diff)
downloadunit-deb26fa47a9ab1b358938134a8ced8bbc4a083e1.tar.gz
unit-deb26fa47a9ab1b358938134a8ced8bbc4a083e1.tar.bz2
Merged with the default branch.
Diffstat (limited to '')
-rw-r--r--src/nxt_conf_validation.c432
1 files changed, 365 insertions, 67 deletions
diff --git a/src/nxt_conf_validation.c b/src/nxt_conf_validation.c
index ca8ec62e..c934b10b 100644
--- a/src/nxt_conf_validation.c
+++ b/src/nxt_conf_validation.c
@@ -8,6 +8,7 @@
#include <nxt_conf.h>
#include <nxt_cert.h>
#include <nxt_router.h>
+#include <nxt_http.h>
typedef enum {
@@ -39,15 +40,18 @@ typedef nxt_int_t (*nxt_conf_vldt_member_t)(nxt_conf_validation_t *vldt,
nxt_conf_value_t *value);
typedef nxt_int_t (*nxt_conf_vldt_element_t)(nxt_conf_validation_t *vldt,
nxt_conf_value_t *value);
-typedef nxt_int_t (*nxt_conf_vldt_system_t)(nxt_conf_validation_t *vldt,
- char *name);
-
static nxt_int_t nxt_conf_vldt_type(nxt_conf_validation_t *vldt,
nxt_str_t *name, nxt_conf_value_t *value, nxt_conf_vldt_type_t type);
static nxt_int_t nxt_conf_vldt_error(nxt_conf_validation_t *vldt,
const char *fmt, ...);
+static nxt_int_t nxt_conf_vldt_mtypes(nxt_conf_validation_t *vldt,
+ nxt_conf_value_t *value, void *data);
+static nxt_int_t nxt_conf_vldt_mtypes_type(nxt_conf_validation_t *vldt,
+ nxt_str_t *name, nxt_conf_value_t *value);
+static nxt_int_t nxt_conf_vldt_mtypes_extension(nxt_conf_validation_t *vldt,
+ nxt_conf_value_t *value);
static nxt_int_t nxt_conf_vldt_listener(nxt_conf_validation_t *vldt,
nxt_str_t *name, nxt_conf_value_t *value);
#if (NXT_TLS)
@@ -86,10 +90,6 @@ static nxt_int_t nxt_conf_vldt_object_iterator(nxt_conf_validation_t *vldt,
nxt_conf_value_t *value, void *data);
static nxt_int_t nxt_conf_vldt_array_iterator(nxt_conf_validation_t *vldt,
nxt_conf_value_t *value, void *data);
-static nxt_int_t nxt_conf_vldt_system(nxt_conf_validation_t *vldt,
- nxt_conf_value_t *value, void *data);
-static nxt_int_t nxt_conf_vldt_user(nxt_conf_validation_t *vldt, char *name);
-static nxt_int_t nxt_conf_vldt_group(nxt_conf_validation_t *vldt, char *name);
static nxt_int_t nxt_conf_vldt_environment(nxt_conf_validation_t *vldt,
nxt_str_t *name, nxt_conf_value_t *value);
static nxt_int_t nxt_conf_vldt_argument(nxt_conf_validation_t *vldt,
@@ -101,6 +101,21 @@ static nxt_int_t nxt_conf_vldt_java_classpath(nxt_conf_validation_t *vldt,
static nxt_int_t nxt_conf_vldt_java_option(nxt_conf_validation_t *vldt,
nxt_conf_value_t *value);
+static nxt_int_t
+nxt_conf_vldt_isolation(nxt_conf_validation_t *vldt, nxt_conf_value_t *value,
+ void *data);
+static nxt_int_t
+nxt_conf_vldt_clone_namespaces(nxt_conf_validation_t *vldt,
+ nxt_conf_value_t *value, void *data);
+
+#if (NXT_HAVE_CLONE_NEWUSER)
+static nxt_int_t nxt_conf_vldt_clone_procmap(nxt_conf_validation_t *vldt,
+ const char* mapfile, nxt_conf_value_t *value);
+static nxt_int_t nxt_conf_vldt_clone_uidmap(nxt_conf_validation_t *vldt,
+ nxt_conf_value_t *value);
+static nxt_int_t nxt_conf_vldt_clone_gidmap(nxt_conf_validation_t *vldt,
+ nxt_conf_value_t *value);
+#endif
static nxt_conf_vldt_object_t nxt_conf_vldt_websocket_members[] = {
{ nxt_string("read_timeout"),
@@ -122,6 +137,16 @@ static nxt_conf_vldt_object_t nxt_conf_vldt_websocket_members[] = {
};
+static nxt_conf_vldt_object_t nxt_conf_vldt_static_members[] = {
+ { nxt_string("mime_types"),
+ NXT_CONF_VLDT_OBJECT,
+ &nxt_conf_vldt_mtypes,
+ NULL },
+
+ NXT_CONF_VLDT_END
+};
+
+
static nxt_conf_vldt_object_t nxt_conf_vldt_http_members[] = {
{ nxt_string("header_read_timeout"),
NXT_CONF_VLDT_INTEGER,
@@ -153,6 +178,11 @@ static nxt_conf_vldt_object_t nxt_conf_vldt_http_members[] = {
&nxt_conf_vldt_object,
(void *) &nxt_conf_vldt_websocket_members },
+ { nxt_string("static"),
+ NXT_CONF_VLDT_OBJECT,
+ &nxt_conf_vldt_object,
+ (void *) &nxt_conf_vldt_static_members },
+
NXT_CONF_VLDT_END
};
@@ -281,6 +311,11 @@ static nxt_conf_vldt_object_t nxt_conf_vldt_action_members[] = {
&nxt_conf_vldt_pass,
NULL },
+ { nxt_string("share"),
+ NXT_CONF_VLDT_STRING,
+ NULL,
+ NULL },
+
NXT_CONF_VLDT_END
};
@@ -340,6 +375,100 @@ static nxt_conf_vldt_object_t nxt_conf_vldt_app_processes_members[] = {
};
+static nxt_conf_vldt_object_t nxt_conf_vldt_app_namespaces_members[] = {
+
+#if (NXT_HAVE_CLONE_NEWUSER)
+ { nxt_string("credential"),
+ NXT_CONF_VLDT_BOOLEAN,
+ NULL,
+ NULL },
+#endif
+
+#if (NXT_HAVE_CLONE_NEWPID)
+ { nxt_string("pid"),
+ NXT_CONF_VLDT_BOOLEAN,
+ NULL,
+ NULL },
+#endif
+
+#if (NXT_HAVE_CLONE_NEWNET)
+ { nxt_string("network"),
+ NXT_CONF_VLDT_BOOLEAN,
+ NULL,
+ NULL },
+#endif
+
+#if (NXT_HAVE_CLONE_NEWNS)
+ { nxt_string("mount"),
+ NXT_CONF_VLDT_BOOLEAN,
+ NULL,
+ NULL },
+#endif
+
+#if (NXT_HAVE_CLONE_NEWUTS)
+ { nxt_string("uname"),
+ NXT_CONF_VLDT_BOOLEAN,
+ NULL,
+ NULL },
+#endif
+
+#if (NXT_HAVE_CLONE_NEWCGROUP)
+ { nxt_string("cgroup"),
+ NXT_CONF_VLDT_BOOLEAN,
+ NULL,
+ NULL },
+#endif
+
+ NXT_CONF_VLDT_END
+};
+
+
+#if (NXT_HAVE_CLONE_NEWUSER)
+
+static nxt_conf_vldt_object_t nxt_conf_vldt_app_procmap_members[] = {
+ { nxt_string("container"),
+ NXT_CONF_VLDT_INTEGER,
+ NULL,
+ NULL },
+
+ { nxt_string("host"),
+ NXT_CONF_VLDT_INTEGER,
+ NULL,
+ NULL },
+
+ { nxt_string("size"),
+ NXT_CONF_VLDT_INTEGER,
+ NULL,
+ NULL },
+};
+
+#endif
+
+
+static nxt_conf_vldt_object_t nxt_conf_vldt_app_isolation_members[] = {
+ { nxt_string("namespaces"),
+ NXT_CONF_VLDT_OBJECT,
+ &nxt_conf_vldt_clone_namespaces,
+ (void *) &nxt_conf_vldt_app_namespaces_members },
+
+#if (NXT_HAVE_CLONE_NEWUSER)
+
+ { nxt_string("uidmap"),
+ NXT_CONF_VLDT_ARRAY,
+ &nxt_conf_vldt_array_iterator,
+ (void *) &nxt_conf_vldt_clone_uidmap },
+
+ { nxt_string("gidmap"),
+ NXT_CONF_VLDT_ARRAY,
+ &nxt_conf_vldt_array_iterator,
+ (void *) &nxt_conf_vldt_clone_gidmap },
+
+#endif
+
+ NXT_CONF_VLDT_END
+};
+
+
static nxt_conf_vldt_object_t nxt_conf_vldt_common_members[] = {
{ nxt_string("type"),
NXT_CONF_VLDT_STRING,
@@ -358,13 +487,13 @@ static nxt_conf_vldt_object_t nxt_conf_vldt_common_members[] = {
{ nxt_string("user"),
NXT_CONF_VLDT_STRING,
- nxt_conf_vldt_system,
- (void *) &nxt_conf_vldt_user },
+ NULL,
+ NULL },
{ nxt_string("group"),
NXT_CONF_VLDT_STRING,
- nxt_conf_vldt_system,
- (void *) &nxt_conf_vldt_group },
+ NULL,
+ NULL },
{ nxt_string("working_directory"),
NXT_CONF_VLDT_STRING,
@@ -376,6 +505,11 @@ static nxt_conf_vldt_object_t nxt_conf_vldt_common_members[] = {
&nxt_conf_vldt_object_iterator,
(void *) &nxt_conf_vldt_environment },
+ { nxt_string("isolation"),
+ NXT_CONF_VLDT_OBJECT,
+ &nxt_conf_vldt_isolation,
+ (void *) &nxt_conf_vldt_app_isolation_members },
+
NXT_CONF_VLDT_END
};
@@ -628,6 +762,108 @@ nxt_conf_vldt_error(nxt_conf_validation_t *vldt, const char *fmt, ...)
}
+typedef struct {
+ nxt_mp_t *pool;
+ nxt_str_t *type;
+ nxt_lvlhsh_t hash;
+} nxt_conf_vldt_mtypes_ctx_t;
+
+
+static nxt_int_t
+nxt_conf_vldt_mtypes(nxt_conf_validation_t *vldt, nxt_conf_value_t *value,
+ void *data)
+{
+ nxt_int_t ret;
+ nxt_conf_vldt_mtypes_ctx_t ctx;
+
+ ctx.pool = nxt_mp_create(1024, 128, 256, 32);
+ if (nxt_slow_path(ctx.pool == NULL)) {
+ return NXT_ERROR;
+ }
+
+ nxt_lvlhsh_init(&ctx.hash);
+
+ vldt->ctx = &ctx;
+
+ ret = nxt_conf_vldt_object_iterator(vldt, value,
+ &nxt_conf_vldt_mtypes_type);
+
+ vldt->ctx = NULL;
+
+ nxt_mp_destroy(ctx.pool);
+
+ return ret;
+}
+
+
+static nxt_int_t
+nxt_conf_vldt_mtypes_type(nxt_conf_validation_t *vldt, nxt_str_t *name,
+ nxt_conf_value_t *value)
+{
+ nxt_int_t ret;
+ nxt_conf_vldt_mtypes_ctx_t *ctx;
+
+ ret = nxt_conf_vldt_type(vldt, name, value,
+ NXT_CONF_VLDT_STRING|NXT_CONF_VLDT_ARRAY);
+ if (ret != NXT_OK) {
+ return ret;
+ }
+
+ ctx = vldt->ctx;
+
+ ctx->type = nxt_mp_get(ctx->pool, sizeof(nxt_str_t));
+ if (nxt_slow_path(ctx->type == NULL)) {
+ return NXT_ERROR;
+ }
+
+ *ctx->type = *name;
+
+ if (nxt_conf_type(value) == NXT_CONF_ARRAY) {
+ return nxt_conf_vldt_array_iterator(vldt, value,
+ &nxt_conf_vldt_mtypes_extension);
+ }
+
+ /* NXT_CONF_STRING */
+
+ return nxt_conf_vldt_mtypes_extension(vldt, value);
+}
+
+
+static nxt_int_t
+nxt_conf_vldt_mtypes_extension(nxt_conf_validation_t *vldt,
+ nxt_conf_value_t *value)
+{
+ nxt_str_t ext, *dup_type;
+ nxt_conf_vldt_mtypes_ctx_t *ctx;
+
+ ctx = vldt->ctx;
+
+ if (nxt_conf_type(value) != NXT_CONF_STRING) {
+ return nxt_conf_vldt_error(vldt, "The \"%V\" MIME type array must "
+ "contain only strings.", ctx->type);
+ }
+
+ nxt_conf_get_string(value, &ext);
+
+ if (ext.length == 0) {
+ return nxt_conf_vldt_error(vldt, "An empty file extension for "
+ "the \"%V\" MIME type.", ctx->type);
+ }
+
+ dup_type = nxt_http_static_mtypes_hash_find(&ctx->hash, &ext);
+
+ if (dup_type != NULL) {
+ return nxt_conf_vldt_error(vldt, "The \"%V\" file extension has been "
+ "declared for \"%V\" and \"%V\" "
+ "MIME types at the same time.",
+ &ext, dup_type, ctx->type);
+ }
+
+ return nxt_http_static_mtypes_hash_add(ctx->pool, &ctx->hash,
+ &ext, ctx->type);
+}
+
+
static nxt_int_t
nxt_conf_vldt_listener(nxt_conf_validation_t *vldt, nxt_str_t *name,
nxt_conf_value_t *value)
@@ -1252,106 +1488,168 @@ nxt_conf_vldt_array_iterator(nxt_conf_validation_t *vldt,
static nxt_int_t
-nxt_conf_vldt_system(nxt_conf_validation_t *vldt, nxt_conf_value_t *value,
- void *data)
+nxt_conf_vldt_environment(nxt_conf_validation_t *vldt, nxt_str_t *name,
+ nxt_conf_value_t *value)
{
- size_t length;
- nxt_str_t name;
- nxt_conf_vldt_system_t validator;
- char string[32];
+ nxt_str_t str;
- /* The cast is required by Sun C. */
- validator = (nxt_conf_vldt_system_t) data;
+ if (name->length == 0) {
+ return nxt_conf_vldt_error(vldt,
+ "The environment name must not be empty.");
+ }
- nxt_conf_get_string(value, &name);
+ if (nxt_memchr(name->start, '\0', name->length) != NULL) {
+ return nxt_conf_vldt_error(vldt, "The environment name must not "
+ "contain null character.");
+ }
- length = name.length + 1;
- length = nxt_min(length, sizeof(string));
+ if (nxt_memchr(name->start, '=', name->length) != NULL) {
+ return nxt_conf_vldt_error(vldt, "The environment name must not "
+ "contain '=' character.");
+ }
- nxt_cpystrn((u_char *) string, name.start, length);
+ if (nxt_conf_type(value) != NXT_CONF_STRING) {
+ return nxt_conf_vldt_error(vldt, "The \"%V\" environment value must be "
+ "a string.", name);
+ }
+
+ nxt_conf_get_string(value, &str);
- return validator(vldt, string);
+ if (nxt_memchr(str.start, '\0', str.length) != NULL) {
+ return nxt_conf_vldt_error(vldt, "The \"%V\" environment value must "
+ "not contain null character.", name);
+ }
+
+ return NXT_OK;
}
static nxt_int_t
-nxt_conf_vldt_user(nxt_conf_validation_t *vldt, char *user)
+nxt_conf_vldt_clone_namespaces(nxt_conf_validation_t *vldt, nxt_conf_value_t *value,
+ void *data)
{
- struct passwd *pwd;
+ return nxt_conf_vldt_object(vldt, value, data);
+}
- nxt_errno = 0;
- pwd = getpwnam(user);
+static nxt_int_t
+nxt_conf_vldt_isolation(nxt_conf_validation_t *vldt, nxt_conf_value_t *value,
+ void *data)
+{
+ return nxt_conf_vldt_object(vldt, value, data);
+}
- if (pwd != NULL) {
- return NXT_OK;
- }
- if (nxt_errno == 0) {
- return nxt_conf_vldt_error(vldt, "User \"%s\" is not found.", user);
- }
+#if (NXT_HAVE_CLONE_NEWUSER)
+
+typedef struct {
+ nxt_int_t container;
+ nxt_int_t host;
+ nxt_int_t size;
+} nxt_conf_vldt_clone_procmap_conf_t;
- return NXT_ERROR;
-}
+
+static nxt_conf_map_t nxt_conf_vldt_clone_procmap_conf_map[] = {
+ {
+ nxt_string("container"),
+ NXT_CONF_MAP_INT32,
+ offsetof(nxt_conf_vldt_clone_procmap_conf_t, container),
+ },
+
+ {
+ nxt_string("host"),
+ NXT_CONF_MAP_INT32,
+ offsetof(nxt_conf_vldt_clone_procmap_conf_t, host),
+ },
+
+ {
+ nxt_string("size"),
+ NXT_CONF_MAP_INT32,
+ offsetof(nxt_conf_vldt_clone_procmap_conf_t, size),
+ },
+
+};
static nxt_int_t
-nxt_conf_vldt_group(nxt_conf_validation_t *vldt, char *group)
+nxt_conf_vldt_clone_procmap(nxt_conf_validation_t *vldt, const char *mapfile,
+ nxt_conf_value_t *value)
{
- struct group *grp;
+ nxt_int_t ret;
+ nxt_conf_vldt_clone_procmap_conf_t procmap;
- nxt_errno = 0;
+ procmap.container = -1;
+ procmap.host = -1;
+ procmap.size = -1;
- grp = getgrnam(group);
+ ret = nxt_conf_map_object(vldt->pool, value,
+ nxt_conf_vldt_clone_procmap_conf_map,
+ nxt_nitems(nxt_conf_vldt_clone_procmap_conf_map),
+ &procmap);
+ if (ret != NXT_OK) {
+ return ret;
+ }
- if (grp != NULL) {
- return NXT_OK;
+ if (procmap.container == -1) {
+ return nxt_conf_vldt_error(vldt, "The %s requires the "
+ "\"container\" field set.", mapfile);
}
- if (nxt_errno == 0) {
- return nxt_conf_vldt_error(vldt, "Group \"%s\" is not found.", group);
+ if (procmap.host == -1) {
+ return nxt_conf_vldt_error(vldt, "The %s requires the "
+ "\"host\" field set.", mapfile);
}
- return NXT_ERROR;
+ if (procmap.size == -1) {
+ return nxt_conf_vldt_error(vldt, "The %s requires the "
+ "\"size\" field set.", mapfile);
+ }
+
+ return NXT_OK;
}
static nxt_int_t
-nxt_conf_vldt_environment(nxt_conf_validation_t *vldt, nxt_str_t *name,
- nxt_conf_value_t *value)
+nxt_conf_vldt_clone_uidmap(nxt_conf_validation_t *vldt, nxt_conf_value_t *value)
{
- nxt_str_t str;
+ nxt_int_t ret;
- if (name->length == 0) {
- return nxt_conf_vldt_error(vldt,
- "The environment name must not be empty.");
+ if (nxt_conf_type(value) != NXT_CONF_OBJECT) {
+ return nxt_conf_vldt_error(vldt, "The \"uidmap\" array "
+ "must contain only object values.");
}
- if (nxt_memchr(name->start, '\0', name->length) != NULL) {
- return nxt_conf_vldt_error(vldt, "The environment name must not "
- "contain null character.");
+ ret = nxt_conf_vldt_object(vldt, value,
+ (void *) nxt_conf_vldt_app_procmap_members);
+ if (nxt_slow_path(ret != NXT_OK)) {
+ return ret;
}
- if (nxt_memchr(name->start, '=', name->length) != NULL) {
- return nxt_conf_vldt_error(vldt, "The environment name must not "
- "contain '=' character.");
- }
+ return nxt_conf_vldt_clone_procmap(vldt, "uid_map", value);
+}
- if (nxt_conf_type(value) != NXT_CONF_STRING) {
- return nxt_conf_vldt_error(vldt, "The \"%V\" environment value must be "
- "a string.", name);
- }
- nxt_conf_get_string(value, &str);
+static nxt_int_t
+nxt_conf_vldt_clone_gidmap(nxt_conf_validation_t *vldt, nxt_conf_value_t *value)
+{
+ nxt_int_t ret;
- if (nxt_memchr(str.start, '\0', str.length) != NULL) {
- return nxt_conf_vldt_error(vldt, "The \"%V\" environment value must "
- "not contain null character.", name);
+ if (nxt_conf_type(value) != NXT_CONF_OBJECT) {
+ return nxt_conf_vldt_error(vldt, "The \"gidmap\" array "
+ "must contain only object values.");
}
- return NXT_OK;
+ ret = nxt_conf_vldt_object(vldt, value,
+ (void *) nxt_conf_vldt_app_procmap_members);
+ if (nxt_slow_path(ret != NXT_OK)) {
+ return ret;
+ }
+
+ return nxt_conf_vldt_clone_procmap(vldt, "gid_map", value);
}
+#endif
+
static nxt_int_t
nxt_conf_vldt_argument(nxt_conf_validation_t *vldt, nxt_conf_value_t *value)