diff --git a/CHANGELOG.md b/CHANGELOG.md index 53090e85..11d8c7a7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,11 +3,17 @@ ## 4.2.0 (Expected: September) ### Major New features -* Backend daemon drops privileges after initialization (to not run as root) - * New config option `CLICON_USER` with default value `clicon` +* Backend daemon can drop privileges after initialization to run as non-privileged user + * You can start as root and drop privileges either permanently or temporary + * Controlled by options: CLICON_BACKEND_USER and CLICON_BACKEND_PRIVELEGES * Can also be set with `-U ` clixon_backend command-line option + * If dropped temporary, you can restore privileges with `restore_priv()` ### API changes on existing features (you may need to change your code) +* Typical installation should now add a `clicon` user (as well as group) +* New clixon-config@2019-09-11.yang revision + * Added: CLICON_BACKEND_USER: drop of privileges to user, + * Added: CLICON_BACKEND_PRIVELEGES: how to drop privileges * Restconf top-level operations GET root resource modified to comply with RFC 8040 Sec 3.1 * non-pretty print remove all spaces, eg `{"operations":{"clixon-example:client-rpc":[null]` * Replaced JSON `null` with `[null]` as proper empty JSON leaf/leaf-list encoding. diff --git a/apps/backend/backend_main.c b/apps/backend/backend_main.c index ac5a6e3d..40db2848 100644 --- a/apps/backend/backend_main.c +++ b/apps/backend/backend_main.c @@ -242,45 +242,94 @@ xmldb_drop_priv(clicon_handle h, return retval; } -/*! Drop root privileges uid and gid to Clixon user/group - * @param[in] h Clicon handle +/*! Drop root privileges uid and gid to Clixon user/group and + * + * If config options are right, drop process uid/guid privileges and change some + * file ownerships. + * "Right" means: + * - uid is currently 0 (started as root) + * - CLICON_BACKEND_USER is set + * - CLICON_BACKEND_PRIVILEGES is not "none" + * @param[in] h Clicon handle + * @param[in] gid Group id (assume already known) + * @retval 0 OK + * @retval -1 Error */ static int -drop_priv(clicon_handle h, - uid_t uid, - gid_t gid) +check_drop_priv(clicon_handle h, + gid_t gid) { - int retval = -1; - + int retval = -1; + uid_t uid; + uid_t newuid = -1; + enum priv_mode_t priv_mode = PM_NONE; + char *backend_user = NULL; + + /* Get privileges mode (for dropping privileges) */ + priv_mode = clicon_backend_privileges_mode(h); + if (priv_mode == PM_NONE) + goto ok; + + /* From here, drop privileges */ + /* Check backend user exists */ + if ((backend_user = clicon_backend_user(h)) == NULL){ + clicon_err(OE_DEMON, EPERM, "Privileges cannot be dropped without specifying CLICON_BACKEND_USER\n"); + goto done; + } + /* Get (wanted) new backend user id */ + if (name2uid(backend_user, &newuid) < 0){ + clicon_err(OE_DEMON, errno, "'%s' is not a valid user .\n", backend_user); + goto done; + } + /* get current backend userid, if already at this level OK */ + if ((uid = getuid()) == newuid) + goto ok; + if (uid != 0){ + clicon_err(OE_DEMON, EPERM, "Privileges can only be dropped from root user (uid is %u)\n", uid); + goto done; + } + /* When dropping priveleges, datastores are created if they do not exist. + * But when drops are not made, datastores are created on demand. + * XXX: move the creation to top-level so they are always created at init? + */ if (xmldb_exists(h, "running") != 1) if (xmldb_create(h, "running") < 0) goto done; - if (xmldb_drop_priv(h, "running", uid, gid) < 0) + if (xmldb_drop_priv(h, "running", newuid, gid) < 0) goto done; if (xmldb_exists(h, "candidate") != 1) if (xmldb_create(h, "candidate") < 0) goto done; - if (xmldb_drop_priv(h, "candidate", uid, gid) < 0) + if (xmldb_drop_priv(h, "candidate", newuid, gid) < 0) goto done; if (xmldb_exists(h, "startup") != 1) if (xmldb_create(h, "startup") < 0) goto done; - if (xmldb_drop_priv(h, "startup", uid, gid) < 0) + if (xmldb_drop_priv(h, "startup", newuid, gid) < 0) goto done; if (setgid(gid) == -1) { clicon_err(OE_DEMON, errno, "setgid %d", gid); goto done; } - if (setuid(uid) == -1) { - clicon_err(OE_DEMON, errno, "setuid %d", uid); - goto done; - } - /* Verify you cannot regain root privileges */ - if (setuid(0) != -1){ - clicon_err(OE_DEMON, EPERM, "Could regain root privilieges"); - goto done; + switch (priv_mode){ + case PM_DROP_PERM: + if (drop_priv_perm(newuid) < 0) + goto done; + /* Verify you cannot regain root privileges */ + if (setuid(0) != -1){ + clicon_err(OE_DEMON, EPERM, "Could regain root privilieges"); + goto done; + } + break; + case PM_DROP_TEMP: + if (drop_priv_temp(newuid) < 0) + goto done; + break; + case PM_NONE: + break; /* catched above */ } + ok: retval = 0; done: return retval; @@ -356,7 +405,7 @@ usage(clicon_handle h, "\t-1\t\tRun once and then quit (dont wait for events)\n" "\t-s \tSpecify backend startup mode: none|startup|running|init)\n" "\t-c \tLoad extra xml configuration, but don't commit.\n" - "\t-U \tRun backend daemon as this user\n" + "\t-U \tRun backend daemon as this user AND drop privileges permanently\n" "\t-g \tClient membership required to this group (default: %s)\n" "\t-y \tLoad yang spec file (override yang main module)\n" @@ -382,7 +431,6 @@ main(int argc, int once; enum startup_mode_t startup_mode; char *extraxml_file; - char *backend_user = NULL; char *backend_group = NULL; char *argv0 = argv[0]; struct stat st; @@ -403,7 +451,6 @@ main(int argc, int ret; char *dir; gid_t gid = -1; - uid_t uid = -1; /* In the startup, logs to stderr & syslog and debug flag set later */ clicon_log_init(__PROGRAM__, LOG_INFO, logdst); @@ -536,7 +583,9 @@ main(int argc, extraxml_file = optarg; break; case 'U': /* config user (for socket and drop privileges) */ - if (clicon_option_add(h, "CLICON_SOCK", optarg) < 0) + if (clicon_option_add(h, "CLICON_USER", optarg) < 0) + goto done; + if (clicon_option_add(h, "CLICON_BACKEND_PRIVILEGES", "drop_permanent") < 0) goto done; break; case 'g': /* config socket group */ @@ -616,17 +665,6 @@ main(int argc, if (sockfamily==AF_UNIX && lstat(sock, &st) == 0) unlink(sock); - /* XXX maybe only if !foreground */ - /* Sanity check: backend user exists */ - if ((backend_user = clicon_user(h)) == NULL){ - clicon_err(OE_FATAL, 0, "clicon_user option not set"); - return -1; - } - if (name2uid(backend_user, &uid) < 0){ - clicon_log(LOG_ERR, "'%s' does not seem to be a valid user .\n", backend_user); - goto done; - } - /* Sanity check: backend group exists */ if ((backend_group = clicon_sock_group(h)) == NULL){ clicon_err(OE_FATAL, 0, "clicon_sock_group option not set"); @@ -634,13 +672,11 @@ main(int argc, } if (group_name2gid(backend_group, &gid) < 0){ clicon_log(LOG_ERR, "'%s' does not seem to be a valid user group.\n" /* \n required here due to multi-line log */ - "The config demon requires a valid group to create a server UNIX socket\n" - "Define a valid CLICON_SOCK_GROUP in %s or via the -g option\n" - "or create the group and add the user to it. On linux for example:" - " sudo groupadd %s\n" - " sudo usermod -a -G %s user\n", - backend_group, clicon_configfile(h), - backend_group, backend_group); + "The config demon requires a valid group to create a server UNIX socket\n" + "Define a valid CLICON_SOCK_GROUP in %s or via the -g option\n" + "or create the group and add the user to it. Check documentation for how to do this on your platform", + backend_group, + clicon_configfile(h)); goto done; } @@ -845,10 +881,10 @@ main(int argc, goto done; if (debug) clicon_option_dump(h, debug); - /* Drop root privileges (unless root) */ - if (uid != 0) - if (drop_priv(h, uid, gid) < 0) - goto done; + /* Depending on configure setting, privileges may be dropped here after + * initializations */ + if (check_drop_priv(h, gid) < 0) + goto done; if (stream_timer_setup(0, h) < 0) goto done; diff --git a/doc/FAQ.md b/doc/FAQ.md index 2ebebe5f..6c0cccc1 100644 --- a/doc/FAQ.md +++ b/doc/FAQ.md @@ -106,15 +106,15 @@ Define a valid CLICON_SOCK_GROUP in the config file or via the -g option or create the group and add the user to it. The default group is 'clicon'. Add yourself and www-data, if you intend to use restconf. -Using groupadd and usermod: +Using useradd and usermod: ``` - sudo groupadd clicon # + sudo useradd clicon # sudo usermod -a -G clicon sudo usermod -a -G clicon www-data ``` -Using addgroup and adduser (eg on busybox): +Using adduser (eg on busybox): ``` - sudo addgroup clicon + sudo adduser -D -H clicon sudo adduser clicon ``` (you may have to restart shell) diff --git a/lib/clixon/clixon.h.in b/lib/clixon/clixon.h.in index a13800fd..b1c81efa 100644 --- a/lib/clixon/clixon.h.in +++ b/lib/clixon/clixon.h.in @@ -65,6 +65,7 @@ #define LIBCLIXON_API 1 #include +#include #include #include #include diff --git a/lib/clixon/clixon_file.h b/lib/clixon/clixon_file.h index d9e6be98..b06c4899 100644 --- a/lib/clixon/clixon_file.h +++ b/lib/clixon/clixon_file.h @@ -43,8 +43,4 @@ int clicon_file_dirent(const char *dir, struct dirent **ent, int clicon_file_copy(char *src, char *target); -int group_name2gid(const char *name, gid_t *gid); - -int name2uid(const char *name, uid_t *uid); - #endif /* _CLIXON_FILE_H_ */ diff --git a/lib/clixon/clixon_options.h b/lib/clixon/clixon_options.h index 956677aa..04fd6a61 100644 --- a/lib/clixon/clixon_options.h +++ b/lib/clixon/clixon_options.h @@ -73,6 +73,13 @@ enum startup_mode_t{ SM_INIT }; +/*! See clixon-config.yang type priv_mode (privileges mode) */ +enum priv_mode_t{ + PM_NONE=0, /* Make no drop/change in privileges */ + PM_DROP_PERM, /* Drop privileges permanently */ + PM_DROP_TEMP, /* Drop privileges temporary */ +}; + /*! Datastore cache behaviour, see clixon_datastore.[ch] * See config option type datastore_cache in clixon-config.yang */ @@ -167,8 +174,8 @@ static inline char *clicon_sock(clicon_handle h){ static inline char *clicon_sock_group(clicon_handle h){ return clicon_option_str(h, "CLICON_SOCK_GROUP"); } -static inline char *clicon_user(clicon_handle h){ - return clicon_option_str(h, "CLICON_USER"); +static inline char *clicon_backend_user(clicon_handle h){ + return clicon_option_str(h, "CLICON_BACKEND_USER"); } static inline char *clicon_backend_pidfile(clicon_handle h){ return clicon_option_str(h, "CLICON_BACKEND_PIDFILE"); @@ -186,6 +193,7 @@ int clicon_sock_family(clicon_handle h); int clicon_sock_port(clicon_handle h); int clicon_autocommit(clicon_handle h); int clicon_startup_mode(clicon_handle h); +int clicon_backend_privileges_mode(clicon_handle h); enum datastore_cache clicon_datastore_cache(clicon_handle h); enum regexp_mode clicon_yang_regexp(clicon_handle h); /*-- Specific option access functions for non-yang options --*/ diff --git a/lib/clixon/clixon_uid.h b/lib/clixon/clixon_uid.h new file mode 100644 index 00000000..8c5bd902 --- /dev/null +++ b/lib/clixon/clixon_uid.h @@ -0,0 +1,50 @@ +/* + * + ***** BEGIN LICENSE BLOCK ***** + + Copyright (C) 2009-2019 Olof Hagsand and Benny Holmgren + + This file is part of CLIXON. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + Alternatively, the contents of this file may be used under the terms of + the GNU General Public License Version 3 or later (the "GPL"), + in which case the provisions of the GPL are applicable instead + of those above. If you wish to allow use of your version of this file only + under the terms of the GPL, and not to allow others to + use your version of this file under the terms of Apache License version 2, + indicate your decision by deleting the provisions above and replace them with + the notice and other provisions required by the GPL. If you do not delete + the provisions above, a recipient may use your version of this file under + the terms of any one of the Apache License version 2 or the GPL. + + ***** END LICENSE BLOCK ***** + + * uid, gid, privileges + */ + +#ifndef _CLIXON_UID_H_ +#define _CLIXON_UID_H_ + +/* + * Prototypes + */ +int group_name2gid(const char *name, gid_t *gid); + +int name2uid(const char *name, uid_t *uid); +int drop_priv_temp(uid_t new_uid); +int drop_priv_perm(uid_t new_uid); +int restore_priv(void); + +#endif /* _CLIXON_UID_H_ */ diff --git a/lib/src/Makefile.in b/lib/src/Makefile.in index ef2c4d21..ab660014 100644 --- a/lib/src/Makefile.in +++ b/lib/src/Makefile.in @@ -66,7 +66,7 @@ CPPFLAGS = @CPPFLAGS@ INCLUDES = -I. @INCLUDES@ -I$(top_srcdir)/lib/clixon -I$(top_srcdir)/include -I$(top_srcdir) -SRC = clixon_sig.c clixon_log.c clixon_err.c clixon_event.c \ +SRC = clixon_sig.c clixon_uid.c clixon_log.c clixon_err.c clixon_event.c \ clixon_string.c clixon_regex.c clixon_handle.c \ clixon_xml.c clixon_xml_sort.c clixon_xml_map.c clixon_file.c \ clixon_json.c clixon_yang.c clixon_yang_type.c clixon_yang_module.c \ diff --git a/lib/src/clixon_file.c b/lib/src/clixon_file.c index ff0e0e2e..59ead2f8 100644 --- a/lib/src/clixon_file.c +++ b/lib/src/clixon_file.c @@ -43,14 +43,12 @@ #include #include #include -#include #include #include #include #include #include #include -#include /* cligen */ #include @@ -210,61 +208,3 @@ clicon_file_copy(char *src, errno = err; return retval; } - - -/*! Translate group name to gid. Return -1 if error or not found. - * @param[in] name Name of group - * @param[out] gid Group id - * @retval 0 OK - * @retval -1 Error. or not found - */ -int -group_name2gid(const char *name, - gid_t *gid) -{ - int retval = -1; - char buf[1024]; - struct group g0; - struct group *gr = &g0; - struct group *gtmp; - - gr = &g0; - /* This leaks memory in ubuntu */ - if (getgrnam_r(name, gr, buf, sizeof(buf), >mp) < 0){ - clicon_err(OE_UNIX, errno, "getgrnam_r(%s)", name); - goto done; - } - if (gtmp == NULL){ - clicon_err(OE_UNIX, 0, "No such group: %s", name); - goto done; - } - if (gid) - *gid = gr->gr_gid; - retval = 0; - done: - return retval; -} - -int -name2uid(const char *name, - uid_t *uid) -{ - int retval = -1; - char buf[1024]; - struct passwd pwbuf; - struct passwd *pwbufp = NULL; - - if (getpwnam_r(name, &pwbuf, buf, sizeof(buf), &pwbufp) != 0){ - clicon_err(OE_UNIX, errno, "getpwnam_r(%s)", name); - goto done; - } - if (pwbufp == NULL){ - clicon_err(OE_UNIX, 0, "No such user: %s", name); - goto done; - } - if (uid) - *uid = pwbufp->pw_uid; - retval = 0; - done: - return retval; -} diff --git a/lib/src/clixon_options.c b/lib/src/clixon_options.c index 49bc70c1..5ebe3c83 100644 --- a/lib/src/clixon_options.c +++ b/lib/src/clixon_options.c @@ -82,6 +82,15 @@ */ #define CLIXON_CONF_NS "http://clicon.org/config" +/* Mapping between Cli generation from Yang string <--> constants, + see clixon-config.yang type cli_genmodel_type */ +static const map_str2int cli_genmodel_map[] = { + {"NONE", GT_NONE}, + {"VARS", GT_VARS}, + {"ALL", GT_ALL}, + {NULL, -1} +}; + /* Mapping between Clicon startup modes string <--> constants, see clixon-config.yang type startup_mode */ static const map_str2int startup_mode_map[] = { @@ -92,6 +101,32 @@ static const map_str2int startup_mode_map[] = { {NULL, -1} }; +/* Mapping between Clicon privilegese modes string <--> constants, + * see clixon-config.yang type priv_mode */ +static const map_str2int priv_mode_map[] = { + {"none", PM_NONE}, + {"drop_perm", PM_DROP_PERM}, + {"drop_temp", PM_DROP_TEMP}, + {NULL, -1} +}; + +/* Mapping between datastore cache string <--> constants, + * see clixon-config.yang type datastore_cache */ +static const map_str2int datastore_cache_map[] = { + {"nocache", DATASTORE_NOCACHE}, + {"cache", DATASTORE_CACHE}, + {"cache-zerocopy", DATASTORE_CACHE_ZEROCOPY}, + {NULL, -1} +}; + +/* Mapping between regular expression type string <--> constants, + * see clixon-config.yang type regexp_mode */ +static const map_str2int yang_regexp_map[] = { + {"posix", REGEXP_POSIX}, + {"libxml2", REGEXP_LIBXML2}, + {NULL, -1} +}; + /*! Print registry on file. For debugging. * @param[in] h Clicon handle * @param[in] dbglevel Debug level @@ -453,6 +488,9 @@ clicon_option_int(clicon_handle h, } /*! Set option given as int. + * @param[in] h Clicon handle + * @param[in] name Name of option to set + * @param[in] val Integer value */ int clicon_option_int_set(clicon_handle h, @@ -468,7 +506,7 @@ clicon_option_int_set(clicon_handle h, /*! Get options as bool but stored as string * - * @param[in] h clicon handle + * @param[in] h Clicon handle * @param[in] name name of option * @retval 0 false, or does not exist, or does not have a boolean value * @retval 1 true @@ -496,6 +534,9 @@ clicon_option_bool(clicon_handle h, } /*! Set option given as bool + * @param[in] h Clicon handle + * @param[in] name Name of option to set + * @param[in] val Boolean value, 0 or 1 */ int clicon_option_bool_set(clicon_handle h, @@ -510,6 +551,8 @@ clicon_option_bool_set(clicon_handle h, } /*! Delete option + * @param[in] h Clicon handle + * @param[in] name Name of option to delete */ int clicon_option_del(clicon_handle h, @@ -530,8 +573,10 @@ clicon_option_del(clicon_handle h, * But sometimes there are type conversions, etc which makes it more * convenient to make wrapper functions. Or not? *-----------------------------------------------------------------*/ -/*! Whether to generate CLIgen syntax from datamodel or not (0 or 1) +/*! Wether to generate CLIgen syntax from datamodel or not (0 or 1) * Must be used with a previous clicon_option_exists(). + * @param[in] h Clicon handle + * @retval flag If set, generate CLI code from yang model, otherwise not * @see clixon-config@.yang CLICON_CLI_GENMODEL */ int @@ -546,6 +591,8 @@ clicon_cli_genmodel(clicon_handle h) } /*! Generate code for CLI completion of existing db symbols + * @param[in] h Clicon handle + * @retval flag If set, generate auto-complete CLI specs * @see clixon-config@.yang CLICON_CLI_GENMODEL_COMPLETION */ int @@ -559,14 +606,9 @@ clicon_cli_genmodel_completion(clicon_handle h) return 0; } -static const map_str2int cli_genmodel_map[] = { - {"NONE", GT_NONE}, - {"VARS", GT_VARS}, - {"ALL", GT_ALL}, - {NULL, -1} -}; - /*! How to generate and show CLI syntax: VARS|ALL + * @param[in] h Clicon handle + * @retval mode * @see clixon-config@.yang CLICON_CLI_GENMODEL_TYPE */ enum genmodel_type @@ -580,7 +622,9 @@ clicon_cli_genmodel_type(clicon_handle h) return clicon_str2int(cli_genmodel_map, str); } -/*! Get Dont include keys in cvec in cli vars callbacks +/*! Get "do not include keys in cvec" in cli vars callbacks + * @param[in] h Clicon handle + * @retval flag If set, get only vars * @see clixon-config@.yang CLICON_CLI_VARONLY */ int @@ -596,6 +640,8 @@ clicon_cli_varonly(clicon_handle h) /*! Get family of backend socket: AF_UNIX, AF_INET or AF_INET6 * @see clixon-config@.yang CLICON_SOCK_FAMILY + * @param[in] h Clicon handle + * @retval fam Socket family */ int clicon_sock_family(clicon_handle h) @@ -613,6 +659,8 @@ clicon_sock_family(clicon_handle h) } /*! Get port for backend socket in case of AF_INET or AF_INET6 + * @param[in] h Clicon handle + * @retval port Socket port * @see clixon-config@.yang CLICON_SOCK_PORT */ int @@ -626,6 +674,8 @@ clicon_sock_port(clicon_handle h) } /*! Set if all configuration changes are committed automatically + * @param[in] h Clicon handle + * @retval flag Autocommit (or not) */ int clicon_autocommit(clicon_handle h) @@ -638,25 +688,37 @@ clicon_autocommit(clicon_handle h) return 0; } -/*! Which method to boot/start clicon backen +/*! Which method to boot/start clicon backend + * @param[in] h Clicon handle + * @retval mode Startup mode */ int clicon_startup_mode(clicon_handle h) { char *mode; + if ((mode = clicon_option_str(h, "CLICON_STARTUP_MODE")) == NULL) return -1; return clicon_str2int(startup_mode_map, mode); } -static const map_str2int datastore_cache_map[] = { - {"nocache", DATASTORE_NOCACHE}, - {"cache", DATASTORE_CACHE}, - {"cache-zerocopy", DATASTORE_CACHE_ZEROCOPY}, - {NULL, -1} -}; +/*! Which privileges drop method to use + * @param[in] h Clicon handle + * @retval mode Privileges mode + */ +int +clicon_backend_privileges_mode(clicon_handle h) +{ + char *mode; + + if ((mode = clicon_option_str(h, "CLICON_BACKEND_PRIVILEGES")) == NULL) + return -1; + return clicon_str2int(priv_mode_map, mode); +} /*! Which datastore cache method to use + * @param[in] h Clicon handle + * @retval method Datastore cache method * @see clixon-config@.yang CLICON_DATASTORE_CACHE */ enum datastore_cache @@ -670,13 +732,9 @@ clicon_datastore_cache(clicon_handle h) return clicon_str2int(datastore_cache_map, str); } -static const map_str2int yang_regexp_map[] = { - {"posix", REGEXP_POSIX}, - {"libxml2", REGEXP_LIBXML2}, - {NULL, -1} -}; - /*! Which Yang regexp/pattern engine to use + * @param[in] h Clicon handle + * @retval mode Regexp engine to use * @see clixon-config@.yang CLICON_YANG_REGEXP */ enum regexp_mode @@ -696,7 +754,10 @@ clicon_yang_regexp(clicon_handle h) * Such as handles to plugins, API:s and parsed structures *--------------------------------------------------------------------*/ -/* eg -q option, dont print notifications on stdout */ +/*! Get quiet mode eg -q option, do not print notifications on stdout + * @param[in] h Clicon handle + * @retval flag quiet mode on or off + */ int clicon_quiet_mode(clicon_handle h) { @@ -705,8 +766,14 @@ clicon_quiet_mode(clicon_handle h) return 0; /* default */ return atoi(s); } + +/*! Set quiet mode + * @param[in] h Clicon handle + * @param[in] val Flag value + */ int -clicon_quiet_mode_set(clicon_handle h, int val) +clicon_quiet_mode_set(clicon_handle h, + int val) { return clicon_option_int_set(h, "CLICON_QUIET", val); } diff --git a/lib/src/clixon_uid.c b/lib/src/clixon_uid.c new file mode 100644 index 00000000..515f0988 --- /dev/null +++ b/lib/src/clixon_uid.c @@ -0,0 +1,200 @@ +/* + * + ***** BEGIN LICENSE BLOCK ***** + + Copyright (C) 2009-2019 Olof Hagsand and Benny Holmgren + + This file is part of CLIXON. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + Alternatively, the contents of this file may be used under the terms of + the GNU General Public License Version 3 or later (the "GPL"), + in which case the provisions of the GPL are applicable instead + of those above. If you wish to allow use of your version of this file only + under the terms of the GPL, and not to allow others to + use your version of this file under the terms of Apache License version 2, + indicate your decision by deleting the provisions above and replace them with + the notice and other provisions required by the GPL. If you do not delete + the provisions above, a recipient may use your version of this file under + the terms of any one of the Apache License version 2 or the GPL. + + ***** END LICENSE BLOCK ***** + + * uid, gid, privileges + */ + +#ifdef HAVE_CONFIG_H +#include "clixon_config.h" /* generated by config & autoconf */ +#endif + +#include +#include +#include +#define __USE_GNU /* For setresuid */ +#include +#undef __USE_GNU +#include +#include +#include +#include +#include +#include + +/* clicon */ +#include "clixon_err.h" +#include "clixon_log.h" +#include "clixon_uid.h" + +/*! Translate group name to gid. Return -1 if error or not found. + * @param[in] name Name of group + * @param[out] gid Group id + * @retval 0 OK + * @retval -1 Error. or not found + */ +int +group_name2gid(const char *name, + gid_t *gid) +{ + int retval = -1; + char buf[1024]; + struct group g0; + struct group *gr = &g0; + struct group *gtmp; + + gr = &g0; + /* This leaks memory in ubuntu */ + if (getgrnam_r(name, gr, buf, sizeof(buf), >mp) < 0){ + clicon_err(OE_UNIX, errno, "getgrnam_r(%s)", name); + goto done; + } + if (gtmp == NULL){ + clicon_err(OE_UNIX, 0, "No such group: %s", name); + goto done; + } + if (gid) + *gid = gr->gr_gid; + retval = 0; + done: + return retval; +} + +/*! Translate user name to uid. Return -1 if error or not found. + * @param[in] name Name of user + * @param[out] uid User id + * @retval 0 OK + * @retval -1 Error. or not found + */ +int +name2uid(const char *name, + uid_t *uid) +{ + int retval = -1; + char buf[1024]; + struct passwd pwbuf; + struct passwd *pwbufp = NULL; + + if (getpwnam_r(name, &pwbuf, buf, sizeof(buf), &pwbufp) != 0){ + clicon_err(OE_UNIX, errno, "getpwnam_r(%s)", name); + goto done; + } + if (pwbufp == NULL){ + clicon_err(OE_UNIX, 0, "No such user: %s", name); + goto done; + } + if (uid) + *uid = pwbufp->pw_uid; + retval = 0; + done: + return retval; +} + +/* Privileges drop perm, temp and restore + * @see https://www.usenix.org/legacy/events/sec02/full_papers/chen/chen.pdf + */ + /*! Temporarily drop privileges + * @param[in] new_uid + */ +int +drop_priv_temp(uid_t new_uid) +{ + int retval = -1; + + if (setresuid(-1, new_uid, geteuid()) < 0){ + clicon_err(OE_UNIX, errno, "setresuid"); + goto done; + } + if (geteuid() != new_uid){ + clicon_err(OE_UNIX, errno, "geteuid"); + goto done; + } + retval = 0; + done: + return retval; +} + +/*! Permanently drop privileges + * @param[in] new_uid + */ +int +drop_priv_perm(uid_t new_uid) +{ + int retval = -1; + uid_t ruid; + uid_t euid; + uid_t suid; + + if (setresuid(new_uid, new_uid, new_uid) < 0){ + clicon_err(OE_UNIX, errno, "setresuid"); + goto done; + } + if (getresuid(&ruid, &euid, &suid) < 0){ + clicon_err(OE_UNIX, errno, "getresuid"); + goto done; + } + if (ruid != new_uid || + euid != new_uid || + suid != new_uid){ + clicon_err(OE_UNIX, EINVAL, "Non-matching uid"); + goto done; + } + retval = 0; + done: + return retval; +} + +/*! Restore privileges to saved level */ +int +restore_priv(void) +{ + int retval = -1; + uid_t ruid; + uid_t euid; + uid_t suid; + + if (getresuid(&ruid, &euid, &suid) < 0){ + clicon_err(OE_UNIX, errno, "setresuid"); + goto done; + } + if (setresuid(-1, suid, -1) < 0){ + clicon_err(OE_UNIX, errno, "setresuid"); + goto done; + } + if (geteuid() != suid){ + clicon_err(OE_UNIX, EINVAL, "Non-matching uid"); + goto done; + } + retval = 0; + done: + return retval; +} diff --git a/test/lib.sh b/test/lib.sh index 2b23d721..c7dafc01 100755 --- a/test/lib.sh +++ b/test/lib.sh @@ -109,6 +109,14 @@ if [ ! -d $dir ]; then mkdir $dir fi +# Some tests may set owner of testdir to something strange and quit, need +# to reset to me +if [ ! -G $dir ]; then + u=$(whoami) + sudo chown $u $dir + sudo chgrp $u $dir +fi + # If you bring your own backend BE=0 (it is already started),the backend may # have created some files (eg unix socket) in $dir and therefore cannot # be deleted diff --git a/test/test_augment.sh b/test/test_augment.sh index d991f52e..313aa8ca 100755 --- a/test/test_augment.sh +++ b/test/test_augment.sh @@ -218,7 +218,7 @@ fi new "Kill backend" # Check if premature kill -pid=$(pgrep -u $BUSER -f clixon_backend) +pid=$(pgrep -u root -f clixon_backend) if [ -z "$pid" ]; then err "backend already dead" fi diff --git a/test/test_choice.sh b/test/test_choice.sh index d90c3401..94fd2ae5 100755 --- a/test/test_choice.sh +++ b/test/test_choice.sh @@ -287,7 +287,7 @@ fi new "Kill backend" # Check if premature kill -pid=$(pgrep -u $BUSER -f clixon_backend) +pid=$(pgrep -u root -f clixon_backend) if [ -z "$pid" ]; then err "backend already dead" fi diff --git a/test/test_cli.sh b/test/test_cli.sh index c54f6106..43799944 100755 --- a/test/test_cli.sh +++ b/test/test_cli.sh @@ -126,7 +126,7 @@ fi new "Kill backend" # Check if premature kill -pid=$(pgrep -u $BUSER -f clixon_backend) +pid=$(pgrep -u root -f clixon_backend) if [ -z "$pid" ]; then err "backend already dead" fi diff --git a/test/test_cli_history.sh b/test/test_cli_history.sh index 00ba3946..562a1ad0 100755 --- a/test/test_cli_history.sh +++ b/test/test_cli_history.sh @@ -118,7 +118,7 @@ fi new "Kill backend" # Check if premature kill -pid=$(pgrep -u $BUSER -f clixon_backend) +pid=$(pgrep -u root -f clixon_backend) if [ -z "$pid" ]; then err "backend already dead" fi diff --git a/test/test_cli_multikey.sh b/test/test_cli_multikey.sh index 1dd67038..c1a54b23 100755 --- a/test/test_cli_multikey.sh +++ b/test/test_cli_multikey.sh @@ -132,7 +132,7 @@ fi new "Kill backend" # Check if premature kill -pid=$(pgrep -u $BUSER -f clixon_backend) +pid=$(pgrep -u root -f clixon_backend) if [ -z "$pid" ]; then err "backend already dead" fi diff --git a/test/test_copy_config.sh b/test/test_copy_config.sh index a2e735d0..eb2b9bca 100755 --- a/test/test_copy_config.sh +++ b/test/test_copy_config.sh @@ -163,7 +163,7 @@ fi new "Kill backend" # Check if premature kill -pid=$(pgrep -u $BUSER -f clixon_backend) +pid=$(pgrep -u root -f clixon_backend) if [ -z "$pid" ]; then err "backend already dead" fi diff --git a/test/test_feature.sh b/test/test_feature.sh index 1b298566..306b202e 100755 --- a/test/test_feature.sh +++ b/test/test_feature.sh @@ -191,7 +191,7 @@ fi new "Kill backend" # Check if premature kill -pid=$(pgrep -u $BUSER -f clixon_backend) +pid=$(pgrep -u root -f clixon_backend) if [ -z "$pid" ]; then err "backend already dead" fi diff --git a/test/test_identity.sh b/test/test_identity.sh index 3d04ccfc..9023aaca 100755 --- a/test/test_identity.sh +++ b/test/test_identity.sh @@ -316,7 +316,7 @@ fi new "Kill backend" # Check if premature kill -pid=$(pgrep -u $BUSER -f clixon_backend) +pid=$(pgrep -u root -f clixon_backend) if [ -z "$pid" ]; then err "backend already dead" fi diff --git a/test/test_leafref.sh b/test/test_leafref.sh index be4b9b9e..f599fce4 100755 --- a/test/test_leafref.sh +++ b/test/test_leafref.sh @@ -194,7 +194,7 @@ fi new "Kill backend" # Check if premature kill -pid=$(pgrep -u $BUSER -f clixon_backend) +pid=$(pgrep -u root -f clixon_backend) if [ -z "$pid" ]; then err "backend already dead" fi diff --git a/test/test_minmax.sh b/test/test_minmax.sh index cdd06e24..13a84fc7 100755 --- a/test/test_minmax.sh +++ b/test/test_minmax.sh @@ -231,7 +231,7 @@ fi new "Kill backend" # Check if premature kill -pid=$(pgrep -u $BUSER -f clixon_backend) +pid=$(pgrep -u root -f clixon_backend) if [ -z "$pid" ]; then err "backend already dead" fi diff --git a/test/test_nacm.sh b/test/test_nacm.sh index 58014812..892360c7 100755 --- a/test/test_nacm.sh +++ b/test/test_nacm.sh @@ -188,7 +188,7 @@ fi new "Kill backend" # Check if premature kill -pid=$(pgrep -u $BUSER -f clixon_backend) +pid=$(pgrep -u root -f clixon_backend) if [ -z "$pid" ]; then err "backend already dead" fi diff --git a/test/test_nacm_default.sh b/test/test_nacm_default.sh index b47b189d..08d5c096 100755 --- a/test/test_nacm_default.sh +++ b/test/test_nacm_default.sh @@ -153,7 +153,7 @@ EOF if [ $BE -ne 0 ]; then # Bring your own backend new "Kill backend" # Check if premature kill - pid=$(pgrep -u $BUSER -f clixon_backend) + pid=$(pgrep -u root -f clixon_backend) if [ -z "$pid" ]; then err "backend already dead" fi diff --git a/test/test_nacm_ext.sh b/test/test_nacm_ext.sh index 6ab37b73..b56a740f 100755 --- a/test/test_nacm_ext.sh +++ b/test/test_nacm_ext.sh @@ -216,7 +216,7 @@ fi new "Kill backend" # Check if premature kill -pid=$(pgrep -u $BUSER -f clixon_backend) +pid=$(pgrep -u root -f clixon_backend) if [ -z "$pid" ]; then err "backend already dead" fi diff --git a/test/test_nacm_module_read.sh b/test/test_nacm_module_read.sh index 8dc1a5b5..9e1e32ed 100755 --- a/test/test_nacm_module_read.sh +++ b/test/test_nacm_module_read.sh @@ -279,7 +279,7 @@ fi new "Kill backend" # Check if premature kill -pid=$(pgrep -u $BUSER -f clixon_backend) +pid=$(pgrep -u root -f clixon_backend) if [ -z "$pid" ]; then err "backend already dead" fi diff --git a/test/test_nacm_module_write.sh b/test/test_nacm_module_write.sh index 58686e8d..4661ee73 100755 --- a/test/test_nacm_module_write.sh +++ b/test/test_nacm_module_write.sh @@ -258,7 +258,7 @@ fi new "Kill backend" # Check if premature kill -pid=$(pgrep -u $BUSER -f clixon_backend) +pid=$(pgrep -u root -f clixon_backend) if [ -z "$pid" ]; then err "backend already dead" fi diff --git a/test/test_nacm_protocol.sh b/test/test_nacm_protocol.sh index af31ef86..c51aeaea 100755 --- a/test/test_nacm_protocol.sh +++ b/test/test_nacm_protocol.sh @@ -223,7 +223,7 @@ fi new "Kill backend" # Check if premature kill -pid=$(pgrep -u $BUSER -f clixon_backend) +pid=$(pgrep -u root -f clixon_backend) if [ -z "$pid" ]; then err "backend already dead" fi diff --git a/test/test_netconf.sh b/test/test_netconf.sh index cdb2d5f1..4d091e90 100755 --- a/test/test_netconf.sh +++ b/test/test_netconf.sh @@ -211,7 +211,7 @@ fi new "Kill backend" # Check if premature kill -pid=$(pgrep -u $BUSER -f clixon_backend) +pid=$(pgrep -u root -f clixon_backend) if [ -z "$pid" ]; then err "backend already dead" fi diff --git a/test/test_order.sh b/test/test_order.sh index dac0d190..29d72bf8 100755 --- a/test/test_order.sh +++ b/test/test_order.sh @@ -395,7 +395,7 @@ fi new "Kill backend" # Check if premature kill -pid=$(pgrep -u $BUSER -f clixon_backend) +pid=$(pgrep -u root -f clixon_backend) if [ -z "$pid" ]; then err "backend already dead" fi diff --git a/test/test_pattern.sh b/test/test_pattern.sh index af28f8e5..d8ef0fee 100755 --- a/test/test_pattern.sh +++ b/test/test_pattern.sh @@ -743,7 +743,7 @@ expectfn "$clixon_cli -1f $cfg -l o set c threematch abcg" 255 '^CLI syntax erro if [ $BE -ne 0 ]; then new "Kill backend" # Check if premature kill - pid=$(pgrep -u $BUSER -f clixon_backend) + pid=$(pgrep -u root -f clixon_backend) if [ -z "$pid" ]; then err "backend already dead" fi diff --git a/test/test_perf.sh b/test/test_perf.sh index 3055e243..f9337909 100755 --- a/test/test_perf.sh +++ b/test/test_perf.sh @@ -237,7 +237,7 @@ fi new "Kill backend" # Check if premature kill -pid=$(pgrep -u $BUSER -f clixon_backend) +pid=$(pgrep -u root -f clixon_backend) if [ -z "$pid" ]; then err "backend already dead" fi diff --git a/test/test_perf_state.sh b/test/test_perf_state.sh index d0003626..c017da1c 100755 --- a/test/test_perf_state.sh +++ b/test/test_perf_state.sh @@ -145,7 +145,7 @@ fi new "Kill backend" # Check if premature kill -pid=$(pgrep -u $BUSER -f clixon_backend) +pid=$(pgrep -u root -f clixon_backend) if [ -z "$pid" ]; then err "backend already dead" fi diff --git a/test/test_privileges.sh b/test/test_privileges.sh new file mode 100755 index 00000000..42ddd332 --- /dev/null +++ b/test/test_privileges.sh @@ -0,0 +1,121 @@ +#!/bin/bash +# Start clixon backend as root and unprivileged user (clicon) +# Drop privileges from root to clicon +# Test could do more: +# - test file ownership +# - drop_temp check if you can restore + +# Magic line must be first in script (see README.md) +s="$_" ; . ./lib.sh || if [ "$s" = $0 ]; then exit 0; else return 0; fi + +APPNAME=example + +cfg=$dir/conf_startup.xml + +if [ $valgrindtest -ne 0 ]; then + return -1 # skip +fi + +# Here $dir is created by the user that runs the script + +cat < $cfg + + $cfg + /usr/local/share/clixon + clixon-example + $dir/$APPNAME.sock + /var/tmp/$APPNAME.pidfile + $dir + +EOF + + +# Create a pre-set running, startup and (extra) config. +# The configs are identified by an interface called run, startup, extra. +# Depending on startup mode (init, none, running, or startup) +# expect different output of an initial get-config of running +testrun(){ + startuser=$1 + beuser=$2 + expectuser=$3 + priv_mode=$4 + expecterr=$5 + + # change owner (recursively) of all files in the test dir + sudo chown -R $startuser $dir + + # change group (recursively) of all files in the test dir + sudo chgrp -R $startuser $dir + + # kill old backend (if any) + new "kill old backend" + sudo clixon_backend -zf $cfg + if [ $? -ne 0 ]; then + err + fi + # Kill all backends regardless of user or pid files (we mess with them in this test) + sudo pkill clixon_backend + + # start backend as user + + new "start backend -f $cfg -s init -D $DBG -o CLICON_BACKEND_PRIVILEGES=$priv_mode -o CLICON_BACKEND_USER=$beuser" + sudo -u $startuser $clixon_backend -f $cfg -s init -D $DBG -o CLICON_BACKEND_PRIVILEGES=$priv_mode -o CLICON_BACKEND_USER=$beuser + if [ $? -ne 0 ]; then + err + fi + + pid=$(pgrep -f clixon_backend) + if [ $? -ne 0 ]; then + if [ $expecterr -eq 1 ]; then + return 0 + fi + err + fi + new "waiting" + wait_backend + + if [ $expecterr -eq 1 ]; then + err "Expected error" + fi + + # Get uid now, and compare with expected user + u=$(ps -p $pid -uh | awk '{print $1}') + if [ $u != $expectuser ]; then + err "$expectuser but user is $u" + fi + + new "Kill backend" + # Check if premature kill + pid=$(pgrep -f clixon_backend) + if [ -z "$pid" ]; then + err "backend already dead" + fi + # kill backend + stop_backend -f $cfg +} # testrun + +new "Start as non-privileged user, expect same" +testrun $BUSER $BUSER $BUSER none 0 + +new "Start as privileged user , expect same" +testrun root root root none 0 + +new "Start as privileged user, drop privileges permanent" +testrun root $BUSER $BUSER drop_perm 0 + +new "Start as privileged user, drop privileges temporary" +testrun root $BUSER $BUSER drop_temp 0 + +new "Start as root, drop to root (strange usecase)" +testrun root root root drop_perm 0 + +new "Start as root, drop to root (strange usecase)" +testrun root root root drop_perm 0 + +new "Start as root, set user but dont drop (expect still root)" +testrun root $BUSER root none 0 + +new "Start as non-privileged, try to drop" +testrun $(whoami) $BUSER $BUSER drop_perm 1 + +sudo rm -rf $dir diff --git a/test/test_restconf.sh b/test/test_restconf.sh index 21fd6c8a..3e3dee4f 100755 --- a/test/test_restconf.sh +++ b/test/test_restconf.sh @@ -278,7 +278,7 @@ fi new "Kill backend" # Check if premature kill -pid=$(pgrep -u $BUSER -f clixon_backend) +pid=$(pgrep -u root -f clixon_backend) if [ -z "$pid" ]; then err "backend already dead" fi diff --git a/test/test_restconf2.sh b/test/test_restconf2.sh index bc3c7906..88ab5fa5 100755 --- a/test/test_restconf2.sh +++ b/test/test_restconf2.sh @@ -200,7 +200,7 @@ fi new "Kill backend" # Check if premature kill -pid=$(pgrep -u $BUSER -f clixon_backend) +pid=$(pgrep -u root -f clixon_backend) if [ -z "$pid" ]; then err "backend already dead" fi diff --git a/test/test_restconf_err.sh b/test/test_restconf_err.sh index 8db0e8f1..53a64db2 100755 --- a/test/test_restconf_err.sh +++ b/test/test_restconf_err.sh @@ -116,7 +116,7 @@ fi new "Kill backend" # Check if premature kill -pid=$(pgrep -u $BUSER -f clixon_backend) +pid=$(pgrep -u root -f clixon_backend) if [ -z "$pid" ]; then err "backend already dead" fi diff --git a/test/test_restconf_jukebox.sh b/test/test_restconf_jukebox.sh index fa151cdd..dbf5d274 100755 --- a/test/test_restconf_jukebox.sh +++ b/test/test_restconf_jukebox.sh @@ -261,7 +261,7 @@ fi new "Kill backend" # Check if premature kill -pid=$(pgrep -u $BUSER -f clixon_backend) +pid=$(pgrep -u root -f clixon_backend) if [ -z "$pid" ]; then err "backend already dead" fi diff --git a/test/test_restconf_listkey.sh b/test/test_restconf_listkey.sh index 67495a36..7afd61ea 100755 --- a/test/test_restconf_listkey.sh +++ b/test/test_restconf_listkey.sh @@ -157,7 +157,7 @@ fi new "Kill backend" # Check if premature kill -pid=$(pgrep -u $BUSER -f clixon_backend) +pid=$(pgrep -u root -f clixon_backend) if [ -z "$pid" ]; then err "backend already dead" fi diff --git a/test/test_restconf_patch.sh b/test/test_restconf_patch.sh index 6f2d9acd..5d7ae5cd 100755 --- a/test/test_restconf_patch.sh +++ b/test/test_restconf_patch.sh @@ -209,7 +209,7 @@ fi new "Kill backend" # Check if premature kill -pid=$(pgrep -u $BUSER -f clixon_backend) +pid=$(pgrep -u root -f clixon_backend) if [ -z "$pid" ]; then err "backend already dead" fi diff --git a/test/test_restconf_startup.sh b/test/test_restconf_startup.sh index 318d2785..2c3c94bc 100755 --- a/test/test_restconf_startup.sh +++ b/test/test_restconf_startup.sh @@ -89,7 +89,7 @@ testrun(){ if [ $BE -ne 0 ]; then new "Kill backend" # Check if premature kill - pid=$(pgrep -u $BUSER -f clixon_backend) + pid=$(pgrep -u root -f clixon_backend) if [ -z "$pid" ]; then err "backend already dead" fi @@ -108,7 +108,7 @@ new "Check running and startup exists and are same" if [ ! -f $dir/startup_db ]; then err "startup should exist but does not" fi -echo "diff $dir/startup_db $dir/running_db" + d=$(sudo diff $dir/startup_db $dir/running_db) if [ -n "$d" ]; then err "running and startup should be equal" "$d" @@ -117,14 +117,12 @@ fi # clear startup sudo rm -f $dir/startup_db; -new "Run without startup option, check running is copied" +new "Run without startup option, check running is not copied" testrun "" new "Check startup is empty" -if [ ! -f $dir/startup_db ]; then - err "startup does not exist" -fi -if [ -s $dir/startup_db ]; then - err "startup is not empty" +if [ -f $dir/startup_db ]; then + err "startup should not exist" fi + rm -rf $dir diff --git a/test/test_rpc.sh b/test/test_rpc.sh index 285cb158..91d22e21 100755 --- a/test/test_rpc.sh +++ b/test/test_rpc.sh @@ -164,7 +164,7 @@ fi new "Kill backend" # Check if premature kill -pid=$(pgrep -u $BUSER -f clixon_backend) +pid=$(pgrep -u root -f clixon_backend) if [ -z "$pid" ]; then err "backend already dead" fi diff --git a/test/test_startup.sh b/test/test_startup.sh index 724a85d0..301086ff 100755 --- a/test/test_startup.sh +++ b/test/test_startup.sh @@ -102,7 +102,7 @@ testrun(){ new "Kill backend" # Check if premature kill - pid=$(pgrep -u $BUSER -f clixon_backend) + pid=$(pgrep -u root -f clixon_backend) if [ -z "$pid" ]; then err "backend already dead" fi diff --git a/test/test_stream.sh b/test/test_stream.sh index 1a710ed9..fce98856 100755 --- a/test/test_stream.sh +++ b/test/test_stream.sh @@ -291,7 +291,7 @@ fi new "Kill backend" # Check if premature kill -pid=$(pgrep -u $BUSER -f clixon_backend) +pid=$(pgrep -u root -f clixon_backend) if [ -z "$pid" ]; then err "backend already dead" fi diff --git a/test/test_submodule.sh b/test/test_submodule.sh index 580e3e2b..76fd86b1 100755 --- a/test/test_submodule.sh +++ b/test/test_submodule.sh @@ -224,7 +224,7 @@ fi new "Kill backend" # Check if premature kill -pid=$(pgrep -u $BUSER -f clixon_backend) +pid=$(pgrep -u root -f clixon_backend) if [ -z "$pid" ]; then err "backend already dead" fi diff --git a/test/test_transaction.sh b/test/test_transaction.sh index 2d565a97..828fd7d7 100755 --- a/test/test_transaction.sh +++ b/test/test_transaction.sh @@ -311,7 +311,7 @@ fi new "Kill backend" # Check if premature kill -pid=$(pgrep -u $BUSER -f clixon_backend) +pid=$(pgrep -u root -f clixon_backend) if [ -z "$pid" ]; then err "backend already dead" fi diff --git a/test/test_type.sh b/test/test_type.sh index 356e5f39..075e90fa 100755 --- a/test/test_type.sh +++ b/test/test_type.sh @@ -628,7 +628,7 @@ EOF if [ $BE -ne 0 ]; then new "Kill backend" # Check if premature kill - pid=$(pgrep -u $BUSER -f clixon_backend) + pid=$(pgrep -u root -f clixon_backend) if [ -z "$pid" ]; then err "backend already dead" fi diff --git a/test/test_type_range.sh b/test/test_type_range.sh index 778c1709..1886c1fc 100755 --- a/test/test_type_range.sh +++ b/test/test_type_range.sh @@ -306,7 +306,7 @@ testrange string "012" "01234567890" "" if [ $BE -ne 0 ]; then new "Kill backend" # Check if premature kill - pid=$(pgrep -u $BUSER -f clixon_backend) + pid=$(pgrep -u root -f clixon_backend) if [ -z "$pid" ]; then err "backend already dead" fi diff --git a/test/test_union.sh b/test/test_union.sh index 8796f708..5fa4530d 100755 --- a/test/test_union.sh +++ b/test/test_union.sh @@ -107,7 +107,7 @@ fi new "Kill backend" # Check if premature kill -pid=$(pgrep -u $BUSER -f clixon_backend) +pid=$(pgrep -u root -f clixon_backend) if [ -z "$pid" ]; then err "backend already dead" fi diff --git a/test/test_unique.sh b/test/test_unique.sh index 635a5ef1..c0c74339 100755 --- a/test/test_unique.sh +++ b/test/test_unique.sh @@ -216,7 +216,7 @@ fi new "Kill backend" # Check if premature kill -pid=$(pgrep -u $BUSER -f clixon_backend) +pid=$(pgrep -u root -f clixon_backend) if [ -z "$pid" ]; then err "backend already dead" fi diff --git a/test/test_upgrade.sh b/test/test_upgrade.sh index f8e301ee..bf5804b9 100755 --- a/test/test_upgrade.sh +++ b/test/test_upgrade.sh @@ -283,7 +283,7 @@ runtest(){ if [ $BE -ne 0 ]; then new "Kill backend" # Check if premature kill - pid=$(pgrep -u $BUSER -f clixon_backend) + pid=$(pgrep -u root -f clixon_backend) if [ -z "$pid" ]; then err "backend already dead" fi diff --git a/test/test_upgrade_auto.sh b/test/test_upgrade_auto.sh index 577a498f..d088391f 100755 --- a/test/test_upgrade_auto.sh +++ b/test/test_upgrade_auto.sh @@ -274,7 +274,7 @@ stop_restconf if [ $BE -ne 0 ]; then new "Kill backend" # Check if premature kill - pid=$(pgrep -u $BUSER -f clixon_backend) + pid=$(pgrep -u root -f clixon_backend) if [ -z "$pid" ]; then err "backend already dead" fi diff --git a/test/test_upgrade_interfaces.sh b/test/test_upgrade_interfaces.sh index 6a9ddc6c..023894c8 100755 --- a/test/test_upgrade_interfaces.sh +++ b/test/test_upgrade_interfaces.sh @@ -285,7 +285,7 @@ testrun(){ if [ $BE -ne 0 ]; then new "Kill backend" # Check if premature kill - pid=$(pgrep -u $BUSER -f clixon_backend) + pid=$(pgrep -u root -f clixon_backend) if [ -z "$pid" ]; then err "backend already dead" fi diff --git a/test/test_upgrade_repair.sh b/test/test_upgrade_repair.sh index c06be7c8..0ed324e1 100755 --- a/test/test_upgrade_repair.sh +++ b/test/test_upgrade_repair.sh @@ -151,7 +151,7 @@ stop_restconf if [ $BE -ne 0 ]; then new "Kill backend" # Check if premature kill - pid=$(pgrep -u $BUSER -f clixon_backend) + pid=$(pgrep -u root -f clixon_backend) if [ -z "$pid" ]; then err "backend already dead" fi diff --git a/test/test_when_must.sh b/test/test_when_must.sh index 33a89f5f..740095b8 100755 --- a/test/test_when_must.sh +++ b/test/test_when_must.sh @@ -147,7 +147,7 @@ fi new "Kill backend" # Check if premature kill -pid=$(pgrep -u $BUSER -f clixon_backend) +pid=$(pgrep -u root -f clixon_backend) if [ -z "$pid" ]; then err "backend already dead" fi diff --git a/test/test_with_default.sh b/test/test_with_default.sh index d1ce2eda..c5419cae 100755 --- a/test/test_with_default.sh +++ b/test/test_with_default.sh @@ -112,7 +112,7 @@ fi new "Kill backend" # Check if premature kill -pid=$(pgrep -u $BUSER -f clixon_backend) +pid=$(pgrep -u root -f clixon_backend) if [ -z "$pid" ]; then err "backend already dead" fi diff --git a/test/test_yang.sh b/test/test_yang.sh index 172ddd42..fe8cb73c 100755 --- a/test/test_yang.sh +++ b/test/test_yang.sh @@ -286,7 +286,7 @@ fi new "Kill backend" # Check if premature kill -pid=$(pgrep -u $BUSER -f clixon_backend) +pid=$(pgrep -u root -f clixon_backend) if [ -z "$pid" ]; then err "backend already dead" fi diff --git a/test/test_yang_extension.sh b/test/test_yang_extension.sh index 8847a9d0..f15c60b7 100755 --- a/test/test_yang_extension.sh +++ b/test/test_yang_extension.sh @@ -114,7 +114,7 @@ expecteof "$clixon_netconf -qf $cfg -D $DBG" 0 "