diff options
author | Tiago de Bem Natel de Moura <t.nateldemoura@f5.com> | 2019-09-19 15:25:23 +0300 |
---|---|---|
committer | Tiago de Bem Natel de Moura <t.nateldemoura@f5.com> | 2019-09-19 15:25:23 +0300 |
commit | c554941b4f826d83d92d5ca8d7713bea4167896e (patch) | |
tree | 86afb0a5efc790e1852124426acb73d8164341af /src/nxt_conf_validation.c | |
parent | 6346e641eef4aacf92e81e0f1ea4f42ed1e62834 (diff) | |
download | unit-c554941b4f826d83d92d5ca8d7713bea4167896e.tar.gz unit-c554941b4f826d83d92d5ca8d7713bea4167896e.tar.bz2 |
Initial applications isolation support using Linux namespaces.
Diffstat (limited to '')
-rw-r--r-- | src/nxt_conf_validation.c | 303 |
1 files changed, 236 insertions, 67 deletions
diff --git a/src/nxt_conf_validation.c b/src/nxt_conf_validation.c index ca8ec62e..078ddd17 100644 --- a/src/nxt_conf_validation.c +++ b/src/nxt_conf_validation.c @@ -39,9 +39,6 @@ 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); @@ -86,10 +83,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 +94,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"), @@ -340,6 +348,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 +460,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 +478,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 }; @@ -1252,106 +1359,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; + + if (name->length == 0) { + return nxt_conf_vldt_error(vldt, + "The environment name must not be empty."); + } - /* The cast is required by Sun C. */ - validator = (nxt_conf_vldt_system_t) data; + if (nxt_memchr(name->start, '\0', name->length) != NULL) { + return nxt_conf_vldt_error(vldt, "The environment name must not " + "contain null character."); + } - nxt_conf_get_string(value, &name); + if (nxt_memchr(name->start, '=', name->length) != NULL) { + return nxt_conf_vldt_error(vldt, "The environment name must not " + "contain '=' character."); + } + + if (nxt_conf_type(value) != NXT_CONF_STRING) { + return nxt_conf_vldt_error(vldt, "The \"%V\" environment value must be " + "a string.", name); + } - length = name.length + 1; - length = nxt_min(length, sizeof(string)); + nxt_conf_get_string(value, &str); - nxt_cpystrn((u_char *) string, name.start, length); + 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 validator(vldt, string); + 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) - return NXT_ERROR; -} +typedef struct { + nxt_int_t container; + nxt_int_t host; + nxt_int_t size; +} nxt_conf_vldt_clone_procmap_conf_t; + + +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) |