* Implemented backend daemon drop privileges after initialization to
run as non-privileged user
This commit is contained in:
parent
cacba627b5
commit
27fd99e7cd
61 changed files with 673 additions and 207 deletions
10
CHANGELOG.md
10
CHANGELOG.md
|
|
@ -3,11 +3,17 @@
|
||||||
## 4.2.0 (Expected: September)
|
## 4.2.0 (Expected: September)
|
||||||
|
|
||||||
### Major New features
|
### Major New features
|
||||||
* Backend daemon drops privileges after initialization (to not run as root)
|
* Backend daemon can drop privileges after initialization to run as non-privileged user
|
||||||
* New config option `CLICON_USER` with default value `clicon`
|
* 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 <user>` clixon_backend command-line option
|
* Can also be set with `-U <user>` 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)
|
### 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
|
* 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]`
|
* 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.
|
* Replaced JSON `null` with `[null]` as proper empty JSON leaf/leaf-list encoding.
|
||||||
|
|
|
||||||
|
|
@ -242,45 +242,94 @@ xmldb_drop_priv(clicon_handle h,
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Drop root privileges uid and gid to Clixon user/group
|
/*! 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] h Clicon handle
|
||||||
|
* @param[in] gid Group id (assume already known)
|
||||||
|
* @retval 0 OK
|
||||||
|
* @retval -1 Error
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
drop_priv(clicon_handle h,
|
check_drop_priv(clicon_handle h,
|
||||||
uid_t uid,
|
|
||||||
gid_t gid)
|
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_exists(h, "running") != 1)
|
||||||
if (xmldb_create(h, "running") < 0)
|
if (xmldb_create(h, "running") < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if (xmldb_drop_priv(h, "running", uid, gid) < 0)
|
if (xmldb_drop_priv(h, "running", newuid, gid) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if (xmldb_exists(h, "candidate") != 1)
|
if (xmldb_exists(h, "candidate") != 1)
|
||||||
if (xmldb_create(h, "candidate") < 0)
|
if (xmldb_create(h, "candidate") < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if (xmldb_drop_priv(h, "candidate", uid, gid) < 0)
|
if (xmldb_drop_priv(h, "candidate", newuid, gid) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if (xmldb_exists(h, "startup") != 1)
|
if (xmldb_exists(h, "startup") != 1)
|
||||||
if (xmldb_create(h, "startup") < 0)
|
if (xmldb_create(h, "startup") < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if (xmldb_drop_priv(h, "startup", uid, gid) < 0)
|
if (xmldb_drop_priv(h, "startup", newuid, gid) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
if (setgid(gid) == -1) {
|
if (setgid(gid) == -1) {
|
||||||
clicon_err(OE_DEMON, errno, "setgid %d", gid);
|
clicon_err(OE_DEMON, errno, "setgid %d", gid);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
if (setuid(uid) == -1) {
|
switch (priv_mode){
|
||||||
clicon_err(OE_DEMON, errno, "setuid %d", uid);
|
case PM_DROP_PERM:
|
||||||
|
if (drop_priv_perm(newuid) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
}
|
|
||||||
/* Verify you cannot regain root privileges */
|
/* Verify you cannot regain root privileges */
|
||||||
if (setuid(0) != -1){
|
if (setuid(0) != -1){
|
||||||
clicon_err(OE_DEMON, EPERM, "Could regain root privilieges");
|
clicon_err(OE_DEMON, EPERM, "Could regain root privilieges");
|
||||||
goto done;
|
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;
|
retval = 0;
|
||||||
done:
|
done:
|
||||||
return retval;
|
return retval;
|
||||||
|
|
@ -356,7 +405,7 @@ usage(clicon_handle h,
|
||||||
"\t-1\t\tRun once and then quit (dont wait for events)\n"
|
"\t-1\t\tRun once and then quit (dont wait for events)\n"
|
||||||
"\t-s <mode>\tSpecify backend startup mode: none|startup|running|init)\n"
|
"\t-s <mode>\tSpecify backend startup mode: none|startup|running|init)\n"
|
||||||
"\t-c <file>\tLoad extra xml configuration, but don't commit.\n"
|
"\t-c <file>\tLoad extra xml configuration, but don't commit.\n"
|
||||||
"\t-U <user>\tRun backend daemon as this user\n"
|
"\t-U <user>\tRun backend daemon as this user AND drop privileges permanently\n"
|
||||||
"\t-g <group>\tClient membership required to this group (default: %s)\n"
|
"\t-g <group>\tClient membership required to this group (default: %s)\n"
|
||||||
|
|
||||||
"\t-y <file>\tLoad yang spec file (override yang main module)\n"
|
"\t-y <file>\tLoad yang spec file (override yang main module)\n"
|
||||||
|
|
@ -382,7 +431,6 @@ main(int argc,
|
||||||
int once;
|
int once;
|
||||||
enum startup_mode_t startup_mode;
|
enum startup_mode_t startup_mode;
|
||||||
char *extraxml_file;
|
char *extraxml_file;
|
||||||
char *backend_user = NULL;
|
|
||||||
char *backend_group = NULL;
|
char *backend_group = NULL;
|
||||||
char *argv0 = argv[0];
|
char *argv0 = argv[0];
|
||||||
struct stat st;
|
struct stat st;
|
||||||
|
|
@ -403,7 +451,6 @@ main(int argc,
|
||||||
int ret;
|
int ret;
|
||||||
char *dir;
|
char *dir;
|
||||||
gid_t gid = -1;
|
gid_t gid = -1;
|
||||||
uid_t uid = -1;
|
|
||||||
|
|
||||||
/* In the startup, logs to stderr & syslog and debug flag set later */
|
/* In the startup, logs to stderr & syslog and debug flag set later */
|
||||||
clicon_log_init(__PROGRAM__, LOG_INFO, logdst);
|
clicon_log_init(__PROGRAM__, LOG_INFO, logdst);
|
||||||
|
|
@ -536,7 +583,9 @@ main(int argc,
|
||||||
extraxml_file = optarg;
|
extraxml_file = optarg;
|
||||||
break;
|
break;
|
||||||
case 'U': /* config user (for socket and drop privileges) */
|
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;
|
goto done;
|
||||||
break;
|
break;
|
||||||
case 'g': /* config socket group */
|
case 'g': /* config socket group */
|
||||||
|
|
@ -616,17 +665,6 @@ main(int argc,
|
||||||
if (sockfamily==AF_UNIX && lstat(sock, &st) == 0)
|
if (sockfamily==AF_UNIX && lstat(sock, &st) == 0)
|
||||||
unlink(sock);
|
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 */
|
/* Sanity check: backend group exists */
|
||||||
if ((backend_group = clicon_sock_group(h)) == NULL){
|
if ((backend_group = clicon_sock_group(h)) == NULL){
|
||||||
clicon_err(OE_FATAL, 0, "clicon_sock_group option not set");
|
clicon_err(OE_FATAL, 0, "clicon_sock_group option not set");
|
||||||
|
|
@ -636,11 +674,9 @@ main(int argc,
|
||||||
clicon_log(LOG_ERR, "'%s' does not seem to be a valid user group.\n" /* \n required here due to multi-line log */
|
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"
|
"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"
|
"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:"
|
"or create the group and add the user to it. Check documentation for how to do this on your platform",
|
||||||
" sudo groupadd %s\n"
|
backend_group,
|
||||||
" sudo usermod -a -G %s user\n",
|
clicon_configfile(h));
|
||||||
backend_group, clicon_configfile(h),
|
|
||||||
backend_group, backend_group);
|
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -845,9 +881,9 @@ main(int argc,
|
||||||
goto done;
|
goto done;
|
||||||
if (debug)
|
if (debug)
|
||||||
clicon_option_dump(h, debug);
|
clicon_option_dump(h, debug);
|
||||||
/* Drop root privileges (unless root) */
|
/* Depending on configure setting, privileges may be dropped here after
|
||||||
if (uid != 0)
|
* initializations */
|
||||||
if (drop_priv(h, uid, gid) < 0)
|
if (check_drop_priv(h, gid) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
if (stream_timer_setup(0, h) < 0)
|
if (stream_timer_setup(0, h) < 0)
|
||||||
|
|
|
||||||
|
|
@ -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'.
|
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.
|
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 <user>
|
sudo usermod -a -G clicon <user>
|
||||||
sudo usermod -a -G clicon www-data
|
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 <user> clicon
|
sudo adduser <user> clicon
|
||||||
```
|
```
|
||||||
(you may have to restart shell)
|
(you may have to restart shell)
|
||||||
|
|
|
||||||
|
|
@ -65,6 +65,7 @@
|
||||||
#define LIBCLIXON_API 1
|
#define LIBCLIXON_API 1
|
||||||
|
|
||||||
#include <clixon/clixon_sig.h>
|
#include <clixon/clixon_sig.h>
|
||||||
|
#include <clixon/clixon_uid.h>
|
||||||
#include <clixon/clixon_err.h>
|
#include <clixon/clixon_err.h>
|
||||||
#include <clixon/clixon_queue.h>
|
#include <clixon/clixon_queue.h>
|
||||||
#include <clixon/clixon_hash.h>
|
#include <clixon/clixon_hash.h>
|
||||||
|
|
|
||||||
|
|
@ -43,8 +43,4 @@ int clicon_file_dirent(const char *dir, struct dirent **ent,
|
||||||
|
|
||||||
int clicon_file_copy(char *src, char *target);
|
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_ */
|
#endif /* _CLIXON_FILE_H_ */
|
||||||
|
|
|
||||||
|
|
@ -73,6 +73,13 @@ enum startup_mode_t{
|
||||||
SM_INIT
|
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]
|
/*! Datastore cache behaviour, see clixon_datastore.[ch]
|
||||||
* See config option type datastore_cache in clixon-config.yang
|
* 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){
|
static inline char *clicon_sock_group(clicon_handle h){
|
||||||
return clicon_option_str(h, "CLICON_SOCK_GROUP");
|
return clicon_option_str(h, "CLICON_SOCK_GROUP");
|
||||||
}
|
}
|
||||||
static inline char *clicon_user(clicon_handle h){
|
static inline char *clicon_backend_user(clicon_handle h){
|
||||||
return clicon_option_str(h, "CLICON_USER");
|
return clicon_option_str(h, "CLICON_BACKEND_USER");
|
||||||
}
|
}
|
||||||
static inline char *clicon_backend_pidfile(clicon_handle h){
|
static inline char *clicon_backend_pidfile(clicon_handle h){
|
||||||
return clicon_option_str(h, "CLICON_BACKEND_PIDFILE");
|
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_sock_port(clicon_handle h);
|
||||||
int clicon_autocommit(clicon_handle h);
|
int clicon_autocommit(clicon_handle h);
|
||||||
int clicon_startup_mode(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 datastore_cache clicon_datastore_cache(clicon_handle h);
|
||||||
enum regexp_mode clicon_yang_regexp(clicon_handle h);
|
enum regexp_mode clicon_yang_regexp(clicon_handle h);
|
||||||
/*-- Specific option access functions for non-yang options --*/
|
/*-- Specific option access functions for non-yang options --*/
|
||||||
|
|
|
||||||
50
lib/clixon/clixon_uid.h
Normal file
50
lib/clixon/clixon_uid.h
Normal file
|
|
@ -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_ */
|
||||||
|
|
@ -66,7 +66,7 @@ CPPFLAGS = @CPPFLAGS@
|
||||||
|
|
||||||
INCLUDES = -I. @INCLUDES@ -I$(top_srcdir)/lib/clixon -I$(top_srcdir)/include -I$(top_srcdir)
|
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_string.c clixon_regex.c clixon_handle.c \
|
||||||
clixon_xml.c clixon_xml_sort.c clixon_xml_map.c clixon_file.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 \
|
clixon_json.c clixon_yang.c clixon_yang_type.c clixon_yang_module.c \
|
||||||
|
|
|
||||||
|
|
@ -43,14 +43,12 @@
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
#include <regex.h>
|
#include <regex.h>
|
||||||
#include <pwd.h>
|
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <grp.h>
|
|
||||||
|
|
||||||
/* cligen */
|
/* cligen */
|
||||||
#include <cligen/cligen.h>
|
#include <cligen/cligen.h>
|
||||||
|
|
@ -210,61 +208,3 @@ clicon_file_copy(char *src,
|
||||||
errno = err;
|
errno = err;
|
||||||
return retval;
|
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;
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -82,6 +82,15 @@
|
||||||
*/
|
*/
|
||||||
#define CLIXON_CONF_NS "http://clicon.org/config"
|
#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,
|
/* Mapping between Clicon startup modes string <--> constants,
|
||||||
see clixon-config.yang type startup_mode */
|
see clixon-config.yang type startup_mode */
|
||||||
static const map_str2int startup_mode_map[] = {
|
static const map_str2int startup_mode_map[] = {
|
||||||
|
|
@ -92,6 +101,32 @@ static const map_str2int startup_mode_map[] = {
|
||||||
{NULL, -1}
|
{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.
|
/*! Print registry on file. For debugging.
|
||||||
* @param[in] h Clicon handle
|
* @param[in] h Clicon handle
|
||||||
* @param[in] dbglevel Debug level
|
* @param[in] dbglevel Debug level
|
||||||
|
|
@ -453,6 +488,9 @@ clicon_option_int(clicon_handle h,
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Set option given as int.
|
/*! Set option given as int.
|
||||||
|
* @param[in] h Clicon handle
|
||||||
|
* @param[in] name Name of option to set
|
||||||
|
* @param[in] val Integer value
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
clicon_option_int_set(clicon_handle h,
|
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
|
/*! Get options as bool but stored as string
|
||||||
*
|
*
|
||||||
* @param[in] h clicon handle
|
* @param[in] h Clicon handle
|
||||||
* @param[in] name name of option
|
* @param[in] name name of option
|
||||||
* @retval 0 false, or does not exist, or does not have a boolean value
|
* @retval 0 false, or does not exist, or does not have a boolean value
|
||||||
* @retval 1 true
|
* @retval 1 true
|
||||||
|
|
@ -496,6 +534,9 @@ clicon_option_bool(clicon_handle h,
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Set option given as bool
|
/*! 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
|
int
|
||||||
clicon_option_bool_set(clicon_handle h,
|
clicon_option_bool_set(clicon_handle h,
|
||||||
|
|
@ -510,6 +551,8 @@ clicon_option_bool_set(clicon_handle h,
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Delete option
|
/*! Delete option
|
||||||
|
* @param[in] h Clicon handle
|
||||||
|
* @param[in] name Name of option to delete
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
clicon_option_del(clicon_handle h,
|
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
|
* But sometimes there are type conversions, etc which makes it more
|
||||||
* convenient to make wrapper functions. Or not?
|
* 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().
|
* 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@<date>.yang CLICON_CLI_GENMODEL
|
* @see clixon-config@<date>.yang CLICON_CLI_GENMODEL
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
|
|
@ -546,6 +591,8 @@ clicon_cli_genmodel(clicon_handle h)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Generate code for CLI completion of existing db symbols
|
/*! 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@<date>.yang CLICON_CLI_GENMODEL_COMPLETION
|
* @see clixon-config@<date>.yang CLICON_CLI_GENMODEL_COMPLETION
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
|
|
@ -559,14 +606,9 @@ clicon_cli_genmodel_completion(clicon_handle h)
|
||||||
return 0;
|
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
|
/*! How to generate and show CLI syntax: VARS|ALL
|
||||||
|
* @param[in] h Clicon handle
|
||||||
|
* @retval mode
|
||||||
* @see clixon-config@<date>.yang CLICON_CLI_GENMODEL_TYPE
|
* @see clixon-config@<date>.yang CLICON_CLI_GENMODEL_TYPE
|
||||||
*/
|
*/
|
||||||
enum genmodel_type
|
enum genmodel_type
|
||||||
|
|
@ -580,7 +622,9 @@ clicon_cli_genmodel_type(clicon_handle h)
|
||||||
return clicon_str2int(cli_genmodel_map, str);
|
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@<date>.yang CLICON_CLI_VARONLY
|
* @see clixon-config@<date>.yang CLICON_CLI_VARONLY
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
|
|
@ -596,6 +640,8 @@ clicon_cli_varonly(clicon_handle h)
|
||||||
|
|
||||||
/*! Get family of backend socket: AF_UNIX, AF_INET or AF_INET6
|
/*! Get family of backend socket: AF_UNIX, AF_INET or AF_INET6
|
||||||
* @see clixon-config@<date>.yang CLICON_SOCK_FAMILY
|
* @see clixon-config@<date>.yang CLICON_SOCK_FAMILY
|
||||||
|
* @param[in] h Clicon handle
|
||||||
|
* @retval fam Socket family
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
clicon_sock_family(clicon_handle h)
|
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
|
/*! 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@<date>.yang CLICON_SOCK_PORT
|
* @see clixon-config@<date>.yang CLICON_SOCK_PORT
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
|
|
@ -626,6 +674,8 @@ clicon_sock_port(clicon_handle h)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Set if all configuration changes are committed automatically
|
/*! Set if all configuration changes are committed automatically
|
||||||
|
* @param[in] h Clicon handle
|
||||||
|
* @retval flag Autocommit (or not)
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
clicon_autocommit(clicon_handle h)
|
clicon_autocommit(clicon_handle h)
|
||||||
|
|
@ -638,25 +688,37 @@ clicon_autocommit(clicon_handle h)
|
||||||
return 0;
|
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
|
int
|
||||||
clicon_startup_mode(clicon_handle h)
|
clicon_startup_mode(clicon_handle h)
|
||||||
{
|
{
|
||||||
char *mode;
|
char *mode;
|
||||||
|
|
||||||
if ((mode = clicon_option_str(h, "CLICON_STARTUP_MODE")) == NULL)
|
if ((mode = clicon_option_str(h, "CLICON_STARTUP_MODE")) == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
return clicon_str2int(startup_mode_map, mode);
|
return clicon_str2int(startup_mode_map, mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const map_str2int datastore_cache_map[] = {
|
/*! Which privileges drop method to use
|
||||||
{"nocache", DATASTORE_NOCACHE},
|
* @param[in] h Clicon handle
|
||||||
{"cache", DATASTORE_CACHE},
|
* @retval mode Privileges mode
|
||||||
{"cache-zerocopy", DATASTORE_CACHE_ZEROCOPY},
|
*/
|
||||||
{NULL, -1}
|
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
|
/*! Which datastore cache method to use
|
||||||
|
* @param[in] h Clicon handle
|
||||||
|
* @retval method Datastore cache method
|
||||||
* @see clixon-config@<date>.yang CLICON_DATASTORE_CACHE
|
* @see clixon-config@<date>.yang CLICON_DATASTORE_CACHE
|
||||||
*/
|
*/
|
||||||
enum datastore_cache
|
enum datastore_cache
|
||||||
|
|
@ -670,13 +732,9 @@ clicon_datastore_cache(clicon_handle h)
|
||||||
return clicon_str2int(datastore_cache_map, str);
|
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
|
/*! Which Yang regexp/pattern engine to use
|
||||||
|
* @param[in] h Clicon handle
|
||||||
|
* @retval mode Regexp engine to use
|
||||||
* @see clixon-config@<date>.yang CLICON_YANG_REGEXP
|
* @see clixon-config@<date>.yang CLICON_YANG_REGEXP
|
||||||
*/
|
*/
|
||||||
enum regexp_mode
|
enum regexp_mode
|
||||||
|
|
@ -696,7 +754,10 @@ clicon_yang_regexp(clicon_handle h)
|
||||||
* Such as handles to plugins, API:s and parsed structures
|
* 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
|
int
|
||||||
clicon_quiet_mode(clicon_handle h)
|
clicon_quiet_mode(clicon_handle h)
|
||||||
{
|
{
|
||||||
|
|
@ -705,8 +766,14 @@ clicon_quiet_mode(clicon_handle h)
|
||||||
return 0; /* default */
|
return 0; /* default */
|
||||||
return atoi(s);
|
return atoi(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*! Set quiet mode
|
||||||
|
* @param[in] h Clicon handle
|
||||||
|
* @param[in] val Flag value
|
||||||
|
*/
|
||||||
int
|
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);
|
return clicon_option_int_set(h, "CLICON_QUIET", val);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
200
lib/src/clixon_uid.c
Normal file
200
lib/src/clixon_uid.c
Normal file
|
|
@ -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 <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#define __USE_GNU /* For setresuid */
|
||||||
|
#include <unistd.h>
|
||||||
|
#undef __USE_GNU
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <syslog.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <grp.h>
|
||||||
|
#include <pwd.h>
|
||||||
|
|
||||||
|
/* 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;
|
||||||
|
}
|
||||||
|
|
@ -109,6 +109,14 @@ if [ ! -d $dir ]; then
|
||||||
mkdir $dir
|
mkdir $dir
|
||||||
fi
|
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
|
# 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
|
# have created some files (eg unix socket) in $dir and therefore cannot
|
||||||
# be deleted
|
# be deleted
|
||||||
|
|
|
||||||
|
|
@ -218,7 +218,7 @@ fi
|
||||||
|
|
||||||
new "Kill backend"
|
new "Kill backend"
|
||||||
# Check if premature kill
|
# Check if premature kill
|
||||||
pid=$(pgrep -u $BUSER -f clixon_backend)
|
pid=$(pgrep -u root -f clixon_backend)
|
||||||
if [ -z "$pid" ]; then
|
if [ -z "$pid" ]; then
|
||||||
err "backend already dead"
|
err "backend already dead"
|
||||||
fi
|
fi
|
||||||
|
|
|
||||||
|
|
@ -287,7 +287,7 @@ fi
|
||||||
|
|
||||||
new "Kill backend"
|
new "Kill backend"
|
||||||
# Check if premature kill
|
# Check if premature kill
|
||||||
pid=$(pgrep -u $BUSER -f clixon_backend)
|
pid=$(pgrep -u root -f clixon_backend)
|
||||||
if [ -z "$pid" ]; then
|
if [ -z "$pid" ]; then
|
||||||
err "backend already dead"
|
err "backend already dead"
|
||||||
fi
|
fi
|
||||||
|
|
|
||||||
|
|
@ -126,7 +126,7 @@ fi
|
||||||
|
|
||||||
new "Kill backend"
|
new "Kill backend"
|
||||||
# Check if premature kill
|
# Check if premature kill
|
||||||
pid=$(pgrep -u $BUSER -f clixon_backend)
|
pid=$(pgrep -u root -f clixon_backend)
|
||||||
if [ -z "$pid" ]; then
|
if [ -z "$pid" ]; then
|
||||||
err "backend already dead"
|
err "backend already dead"
|
||||||
fi
|
fi
|
||||||
|
|
|
||||||
|
|
@ -118,7 +118,7 @@ fi
|
||||||
|
|
||||||
new "Kill backend"
|
new "Kill backend"
|
||||||
# Check if premature kill
|
# Check if premature kill
|
||||||
pid=$(pgrep -u $BUSER -f clixon_backend)
|
pid=$(pgrep -u root -f clixon_backend)
|
||||||
if [ -z "$pid" ]; then
|
if [ -z "$pid" ]; then
|
||||||
err "backend already dead"
|
err "backend already dead"
|
||||||
fi
|
fi
|
||||||
|
|
|
||||||
|
|
@ -132,7 +132,7 @@ fi
|
||||||
|
|
||||||
new "Kill backend"
|
new "Kill backend"
|
||||||
# Check if premature kill
|
# Check if premature kill
|
||||||
pid=$(pgrep -u $BUSER -f clixon_backend)
|
pid=$(pgrep -u root -f clixon_backend)
|
||||||
if [ -z "$pid" ]; then
|
if [ -z "$pid" ]; then
|
||||||
err "backend already dead"
|
err "backend already dead"
|
||||||
fi
|
fi
|
||||||
|
|
|
||||||
|
|
@ -163,7 +163,7 @@ fi
|
||||||
|
|
||||||
new "Kill backend"
|
new "Kill backend"
|
||||||
# Check if premature kill
|
# Check if premature kill
|
||||||
pid=$(pgrep -u $BUSER -f clixon_backend)
|
pid=$(pgrep -u root -f clixon_backend)
|
||||||
if [ -z "$pid" ]; then
|
if [ -z "$pid" ]; then
|
||||||
err "backend already dead"
|
err "backend already dead"
|
||||||
fi
|
fi
|
||||||
|
|
|
||||||
|
|
@ -191,7 +191,7 @@ fi
|
||||||
|
|
||||||
new "Kill backend"
|
new "Kill backend"
|
||||||
# Check if premature kill
|
# Check if premature kill
|
||||||
pid=$(pgrep -u $BUSER -f clixon_backend)
|
pid=$(pgrep -u root -f clixon_backend)
|
||||||
if [ -z "$pid" ]; then
|
if [ -z "$pid" ]; then
|
||||||
err "backend already dead"
|
err "backend already dead"
|
||||||
fi
|
fi
|
||||||
|
|
|
||||||
|
|
@ -316,7 +316,7 @@ fi
|
||||||
|
|
||||||
new "Kill backend"
|
new "Kill backend"
|
||||||
# Check if premature kill
|
# Check if premature kill
|
||||||
pid=$(pgrep -u $BUSER -f clixon_backend)
|
pid=$(pgrep -u root -f clixon_backend)
|
||||||
if [ -z "$pid" ]; then
|
if [ -z "$pid" ]; then
|
||||||
err "backend already dead"
|
err "backend already dead"
|
||||||
fi
|
fi
|
||||||
|
|
|
||||||
|
|
@ -194,7 +194,7 @@ fi
|
||||||
|
|
||||||
new "Kill backend"
|
new "Kill backend"
|
||||||
# Check if premature kill
|
# Check if premature kill
|
||||||
pid=$(pgrep -u $BUSER -f clixon_backend)
|
pid=$(pgrep -u root -f clixon_backend)
|
||||||
if [ -z "$pid" ]; then
|
if [ -z "$pid" ]; then
|
||||||
err "backend already dead"
|
err "backend already dead"
|
||||||
fi
|
fi
|
||||||
|
|
|
||||||
|
|
@ -231,7 +231,7 @@ fi
|
||||||
|
|
||||||
new "Kill backend"
|
new "Kill backend"
|
||||||
# Check if premature kill
|
# Check if premature kill
|
||||||
pid=$(pgrep -u $BUSER -f clixon_backend)
|
pid=$(pgrep -u root -f clixon_backend)
|
||||||
if [ -z "$pid" ]; then
|
if [ -z "$pid" ]; then
|
||||||
err "backend already dead"
|
err "backend already dead"
|
||||||
fi
|
fi
|
||||||
|
|
|
||||||
|
|
@ -188,7 +188,7 @@ fi
|
||||||
|
|
||||||
new "Kill backend"
|
new "Kill backend"
|
||||||
# Check if premature kill
|
# Check if premature kill
|
||||||
pid=$(pgrep -u $BUSER -f clixon_backend)
|
pid=$(pgrep -u root -f clixon_backend)
|
||||||
if [ -z "$pid" ]; then
|
if [ -z "$pid" ]; then
|
||||||
err "backend already dead"
|
err "backend already dead"
|
||||||
fi
|
fi
|
||||||
|
|
|
||||||
|
|
@ -153,7 +153,7 @@ EOF
|
||||||
if [ $BE -ne 0 ]; then # Bring your own backend
|
if [ $BE -ne 0 ]; then # Bring your own backend
|
||||||
new "Kill backend"
|
new "Kill backend"
|
||||||
# Check if premature kill
|
# Check if premature kill
|
||||||
pid=$(pgrep -u $BUSER -f clixon_backend)
|
pid=$(pgrep -u root -f clixon_backend)
|
||||||
if [ -z "$pid" ]; then
|
if [ -z "$pid" ]; then
|
||||||
err "backend already dead"
|
err "backend already dead"
|
||||||
fi
|
fi
|
||||||
|
|
|
||||||
|
|
@ -216,7 +216,7 @@ fi
|
||||||
|
|
||||||
new "Kill backend"
|
new "Kill backend"
|
||||||
# Check if premature kill
|
# Check if premature kill
|
||||||
pid=$(pgrep -u $BUSER -f clixon_backend)
|
pid=$(pgrep -u root -f clixon_backend)
|
||||||
if [ -z "$pid" ]; then
|
if [ -z "$pid" ]; then
|
||||||
err "backend already dead"
|
err "backend already dead"
|
||||||
fi
|
fi
|
||||||
|
|
|
||||||
|
|
@ -279,7 +279,7 @@ fi
|
||||||
|
|
||||||
new "Kill backend"
|
new "Kill backend"
|
||||||
# Check if premature kill
|
# Check if premature kill
|
||||||
pid=$(pgrep -u $BUSER -f clixon_backend)
|
pid=$(pgrep -u root -f clixon_backend)
|
||||||
if [ -z "$pid" ]; then
|
if [ -z "$pid" ]; then
|
||||||
err "backend already dead"
|
err "backend already dead"
|
||||||
fi
|
fi
|
||||||
|
|
|
||||||
|
|
@ -258,7 +258,7 @@ fi
|
||||||
|
|
||||||
new "Kill backend"
|
new "Kill backend"
|
||||||
# Check if premature kill
|
# Check if premature kill
|
||||||
pid=$(pgrep -u $BUSER -f clixon_backend)
|
pid=$(pgrep -u root -f clixon_backend)
|
||||||
if [ -z "$pid" ]; then
|
if [ -z "$pid" ]; then
|
||||||
err "backend already dead"
|
err "backend already dead"
|
||||||
fi
|
fi
|
||||||
|
|
|
||||||
|
|
@ -223,7 +223,7 @@ fi
|
||||||
|
|
||||||
new "Kill backend"
|
new "Kill backend"
|
||||||
# Check if premature kill
|
# Check if premature kill
|
||||||
pid=$(pgrep -u $BUSER -f clixon_backend)
|
pid=$(pgrep -u root -f clixon_backend)
|
||||||
if [ -z "$pid" ]; then
|
if [ -z "$pid" ]; then
|
||||||
err "backend already dead"
|
err "backend already dead"
|
||||||
fi
|
fi
|
||||||
|
|
|
||||||
|
|
@ -211,7 +211,7 @@ fi
|
||||||
|
|
||||||
new "Kill backend"
|
new "Kill backend"
|
||||||
# Check if premature kill
|
# Check if premature kill
|
||||||
pid=$(pgrep -u $BUSER -f clixon_backend)
|
pid=$(pgrep -u root -f clixon_backend)
|
||||||
if [ -z "$pid" ]; then
|
if [ -z "$pid" ]; then
|
||||||
err "backend already dead"
|
err "backend already dead"
|
||||||
fi
|
fi
|
||||||
|
|
|
||||||
|
|
@ -395,7 +395,7 @@ fi
|
||||||
|
|
||||||
new "Kill backend"
|
new "Kill backend"
|
||||||
# Check if premature kill
|
# Check if premature kill
|
||||||
pid=$(pgrep -u $BUSER -f clixon_backend)
|
pid=$(pgrep -u root -f clixon_backend)
|
||||||
if [ -z "$pid" ]; then
|
if [ -z "$pid" ]; then
|
||||||
err "backend already dead"
|
err "backend already dead"
|
||||||
fi
|
fi
|
||||||
|
|
|
||||||
|
|
@ -743,7 +743,7 @@ expectfn "$clixon_cli -1f $cfg -l o set c threematch abcg" 255 '^CLI syntax erro
|
||||||
if [ $BE -ne 0 ]; then
|
if [ $BE -ne 0 ]; then
|
||||||
new "Kill backend"
|
new "Kill backend"
|
||||||
# Check if premature kill
|
# Check if premature kill
|
||||||
pid=$(pgrep -u $BUSER -f clixon_backend)
|
pid=$(pgrep -u root -f clixon_backend)
|
||||||
if [ -z "$pid" ]; then
|
if [ -z "$pid" ]; then
|
||||||
err "backend already dead"
|
err "backend already dead"
|
||||||
fi
|
fi
|
||||||
|
|
|
||||||
|
|
@ -237,7 +237,7 @@ fi
|
||||||
|
|
||||||
new "Kill backend"
|
new "Kill backend"
|
||||||
# Check if premature kill
|
# Check if premature kill
|
||||||
pid=$(pgrep -u $BUSER -f clixon_backend)
|
pid=$(pgrep -u root -f clixon_backend)
|
||||||
if [ -z "$pid" ]; then
|
if [ -z "$pid" ]; then
|
||||||
err "backend already dead"
|
err "backend already dead"
|
||||||
fi
|
fi
|
||||||
|
|
|
||||||
|
|
@ -145,7 +145,7 @@ fi
|
||||||
|
|
||||||
new "Kill backend"
|
new "Kill backend"
|
||||||
# Check if premature kill
|
# Check if premature kill
|
||||||
pid=$(pgrep -u $BUSER -f clixon_backend)
|
pid=$(pgrep -u root -f clixon_backend)
|
||||||
if [ -z "$pid" ]; then
|
if [ -z "$pid" ]; then
|
||||||
err "backend already dead"
|
err "backend already dead"
|
||||||
fi
|
fi
|
||||||
|
|
|
||||||
121
test/test_privileges.sh
Executable file
121
test/test_privileges.sh
Executable file
|
|
@ -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 <<EOF > $cfg
|
||||||
|
<clixon-config xmlns="http://clicon.org/config">
|
||||||
|
<CLICON_CONFIGFILE>$cfg</CLICON_CONFIGFILE>
|
||||||
|
<CLICON_YANG_DIR>/usr/local/share/clixon</CLICON_YANG_DIR>
|
||||||
|
<CLICON_YANG_MODULE_MAIN>clixon-example</CLICON_YANG_MODULE_MAIN>
|
||||||
|
<CLICON_SOCK>$dir/$APPNAME.sock</CLICON_SOCK>
|
||||||
|
<CLICON_BACKEND_PIDFILE>/var/tmp/$APPNAME.pidfile</CLICON_BACKEND_PIDFILE>
|
||||||
|
<CLICON_XMLDB_DIR>$dir</CLICON_XMLDB_DIR>
|
||||||
|
</clixon-config>
|
||||||
|
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
|
||||||
|
|
@ -278,7 +278,7 @@ fi
|
||||||
|
|
||||||
new "Kill backend"
|
new "Kill backend"
|
||||||
# Check if premature kill
|
# Check if premature kill
|
||||||
pid=$(pgrep -u $BUSER -f clixon_backend)
|
pid=$(pgrep -u root -f clixon_backend)
|
||||||
if [ -z "$pid" ]; then
|
if [ -z "$pid" ]; then
|
||||||
err "backend already dead"
|
err "backend already dead"
|
||||||
fi
|
fi
|
||||||
|
|
|
||||||
|
|
@ -200,7 +200,7 @@ fi
|
||||||
|
|
||||||
new "Kill backend"
|
new "Kill backend"
|
||||||
# Check if premature kill
|
# Check if premature kill
|
||||||
pid=$(pgrep -u $BUSER -f clixon_backend)
|
pid=$(pgrep -u root -f clixon_backend)
|
||||||
if [ -z "$pid" ]; then
|
if [ -z "$pid" ]; then
|
||||||
err "backend already dead"
|
err "backend already dead"
|
||||||
fi
|
fi
|
||||||
|
|
|
||||||
|
|
@ -116,7 +116,7 @@ fi
|
||||||
|
|
||||||
new "Kill backend"
|
new "Kill backend"
|
||||||
# Check if premature kill
|
# Check if premature kill
|
||||||
pid=$(pgrep -u $BUSER -f clixon_backend)
|
pid=$(pgrep -u root -f clixon_backend)
|
||||||
if [ -z "$pid" ]; then
|
if [ -z "$pid" ]; then
|
||||||
err "backend already dead"
|
err "backend already dead"
|
||||||
fi
|
fi
|
||||||
|
|
|
||||||
|
|
@ -261,7 +261,7 @@ fi
|
||||||
|
|
||||||
new "Kill backend"
|
new "Kill backend"
|
||||||
# Check if premature kill
|
# Check if premature kill
|
||||||
pid=$(pgrep -u $BUSER -f clixon_backend)
|
pid=$(pgrep -u root -f clixon_backend)
|
||||||
if [ -z "$pid" ]; then
|
if [ -z "$pid" ]; then
|
||||||
err "backend already dead"
|
err "backend already dead"
|
||||||
fi
|
fi
|
||||||
|
|
|
||||||
|
|
@ -157,7 +157,7 @@ fi
|
||||||
|
|
||||||
new "Kill backend"
|
new "Kill backend"
|
||||||
# Check if premature kill
|
# Check if premature kill
|
||||||
pid=$(pgrep -u $BUSER -f clixon_backend)
|
pid=$(pgrep -u root -f clixon_backend)
|
||||||
if [ -z "$pid" ]; then
|
if [ -z "$pid" ]; then
|
||||||
err "backend already dead"
|
err "backend already dead"
|
||||||
fi
|
fi
|
||||||
|
|
|
||||||
|
|
@ -209,7 +209,7 @@ fi
|
||||||
|
|
||||||
new "Kill backend"
|
new "Kill backend"
|
||||||
# Check if premature kill
|
# Check if premature kill
|
||||||
pid=$(pgrep -u $BUSER -f clixon_backend)
|
pid=$(pgrep -u root -f clixon_backend)
|
||||||
if [ -z "$pid" ]; then
|
if [ -z "$pid" ]; then
|
||||||
err "backend already dead"
|
err "backend already dead"
|
||||||
fi
|
fi
|
||||||
|
|
|
||||||
|
|
@ -89,7 +89,7 @@ testrun(){
|
||||||
if [ $BE -ne 0 ]; then
|
if [ $BE -ne 0 ]; then
|
||||||
new "Kill backend"
|
new "Kill backend"
|
||||||
# Check if premature kill
|
# Check if premature kill
|
||||||
pid=$(pgrep -u $BUSER -f clixon_backend)
|
pid=$(pgrep -u root -f clixon_backend)
|
||||||
if [ -z "$pid" ]; then
|
if [ -z "$pid" ]; then
|
||||||
err "backend already dead"
|
err "backend already dead"
|
||||||
fi
|
fi
|
||||||
|
|
@ -108,7 +108,7 @@ new "Check running and startup exists and are same"
|
||||||
if [ ! -f $dir/startup_db ]; then
|
if [ ! -f $dir/startup_db ]; then
|
||||||
err "startup should exist but does not"
|
err "startup should exist but does not"
|
||||||
fi
|
fi
|
||||||
echo "diff $dir/startup_db $dir/running_db"
|
|
||||||
d=$(sudo diff $dir/startup_db $dir/running_db)
|
d=$(sudo diff $dir/startup_db $dir/running_db)
|
||||||
if [ -n "$d" ]; then
|
if [ -n "$d" ]; then
|
||||||
err "running and startup should be equal" "$d"
|
err "running and startup should be equal" "$d"
|
||||||
|
|
@ -117,14 +117,12 @@ fi
|
||||||
# clear startup
|
# clear startup
|
||||||
sudo rm -f $dir/startup_db;
|
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 ""
|
testrun ""
|
||||||
|
|
||||||
new "Check startup is empty"
|
new "Check startup is empty"
|
||||||
if [ ! -f $dir/startup_db ]; then
|
if [ -f $dir/startup_db ]; then
|
||||||
err "startup does not exist"
|
err "startup should not exist"
|
||||||
fi
|
|
||||||
if [ -s $dir/startup_db ]; then
|
|
||||||
err "startup is not empty"
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
rm -rf $dir
|
rm -rf $dir
|
||||||
|
|
|
||||||
|
|
@ -164,7 +164,7 @@ fi
|
||||||
|
|
||||||
new "Kill backend"
|
new "Kill backend"
|
||||||
# Check if premature kill
|
# Check if premature kill
|
||||||
pid=$(pgrep -u $BUSER -f clixon_backend)
|
pid=$(pgrep -u root -f clixon_backend)
|
||||||
if [ -z "$pid" ]; then
|
if [ -z "$pid" ]; then
|
||||||
err "backend already dead"
|
err "backend already dead"
|
||||||
fi
|
fi
|
||||||
|
|
|
||||||
|
|
@ -102,7 +102,7 @@ testrun(){
|
||||||
|
|
||||||
new "Kill backend"
|
new "Kill backend"
|
||||||
# Check if premature kill
|
# Check if premature kill
|
||||||
pid=$(pgrep -u $BUSER -f clixon_backend)
|
pid=$(pgrep -u root -f clixon_backend)
|
||||||
if [ -z "$pid" ]; then
|
if [ -z "$pid" ]; then
|
||||||
err "backend already dead"
|
err "backend already dead"
|
||||||
fi
|
fi
|
||||||
|
|
|
||||||
|
|
@ -291,7 +291,7 @@ fi
|
||||||
|
|
||||||
new "Kill backend"
|
new "Kill backend"
|
||||||
# Check if premature kill
|
# Check if premature kill
|
||||||
pid=$(pgrep -u $BUSER -f clixon_backend)
|
pid=$(pgrep -u root -f clixon_backend)
|
||||||
if [ -z "$pid" ]; then
|
if [ -z "$pid" ]; then
|
||||||
err "backend already dead"
|
err "backend already dead"
|
||||||
fi
|
fi
|
||||||
|
|
|
||||||
|
|
@ -224,7 +224,7 @@ fi
|
||||||
|
|
||||||
new "Kill backend"
|
new "Kill backend"
|
||||||
# Check if premature kill
|
# Check if premature kill
|
||||||
pid=$(pgrep -u $BUSER -f clixon_backend)
|
pid=$(pgrep -u root -f clixon_backend)
|
||||||
if [ -z "$pid" ]; then
|
if [ -z "$pid" ]; then
|
||||||
err "backend already dead"
|
err "backend already dead"
|
||||||
fi
|
fi
|
||||||
|
|
|
||||||
|
|
@ -311,7 +311,7 @@ fi
|
||||||
|
|
||||||
new "Kill backend"
|
new "Kill backend"
|
||||||
# Check if premature kill
|
# Check if premature kill
|
||||||
pid=$(pgrep -u $BUSER -f clixon_backend)
|
pid=$(pgrep -u root -f clixon_backend)
|
||||||
if [ -z "$pid" ]; then
|
if [ -z "$pid" ]; then
|
||||||
err "backend already dead"
|
err "backend already dead"
|
||||||
fi
|
fi
|
||||||
|
|
|
||||||
|
|
@ -628,7 +628,7 @@ EOF
|
||||||
if [ $BE -ne 0 ]; then
|
if [ $BE -ne 0 ]; then
|
||||||
new "Kill backend"
|
new "Kill backend"
|
||||||
# Check if premature kill
|
# Check if premature kill
|
||||||
pid=$(pgrep -u $BUSER -f clixon_backend)
|
pid=$(pgrep -u root -f clixon_backend)
|
||||||
if [ -z "$pid" ]; then
|
if [ -z "$pid" ]; then
|
||||||
err "backend already dead"
|
err "backend already dead"
|
||||||
fi
|
fi
|
||||||
|
|
|
||||||
|
|
@ -306,7 +306,7 @@ testrange string "012" "01234567890" ""
|
||||||
if [ $BE -ne 0 ]; then
|
if [ $BE -ne 0 ]; then
|
||||||
new "Kill backend"
|
new "Kill backend"
|
||||||
# Check if premature kill
|
# Check if premature kill
|
||||||
pid=$(pgrep -u $BUSER -f clixon_backend)
|
pid=$(pgrep -u root -f clixon_backend)
|
||||||
if [ -z "$pid" ]; then
|
if [ -z "$pid" ]; then
|
||||||
err "backend already dead"
|
err "backend already dead"
|
||||||
fi
|
fi
|
||||||
|
|
|
||||||
|
|
@ -107,7 +107,7 @@ fi
|
||||||
|
|
||||||
new "Kill backend"
|
new "Kill backend"
|
||||||
# Check if premature kill
|
# Check if premature kill
|
||||||
pid=$(pgrep -u $BUSER -f clixon_backend)
|
pid=$(pgrep -u root -f clixon_backend)
|
||||||
if [ -z "$pid" ]; then
|
if [ -z "$pid" ]; then
|
||||||
err "backend already dead"
|
err "backend already dead"
|
||||||
fi
|
fi
|
||||||
|
|
|
||||||
|
|
@ -216,7 +216,7 @@ fi
|
||||||
|
|
||||||
new "Kill backend"
|
new "Kill backend"
|
||||||
# Check if premature kill
|
# Check if premature kill
|
||||||
pid=$(pgrep -u $BUSER -f clixon_backend)
|
pid=$(pgrep -u root -f clixon_backend)
|
||||||
if [ -z "$pid" ]; then
|
if [ -z "$pid" ]; then
|
||||||
err "backend already dead"
|
err "backend already dead"
|
||||||
fi
|
fi
|
||||||
|
|
|
||||||
|
|
@ -283,7 +283,7 @@ runtest(){
|
||||||
if [ $BE -ne 0 ]; then
|
if [ $BE -ne 0 ]; then
|
||||||
new "Kill backend"
|
new "Kill backend"
|
||||||
# Check if premature kill
|
# Check if premature kill
|
||||||
pid=$(pgrep -u $BUSER -f clixon_backend)
|
pid=$(pgrep -u root -f clixon_backend)
|
||||||
if [ -z "$pid" ]; then
|
if [ -z "$pid" ]; then
|
||||||
err "backend already dead"
|
err "backend already dead"
|
||||||
fi
|
fi
|
||||||
|
|
|
||||||
|
|
@ -274,7 +274,7 @@ stop_restconf
|
||||||
if [ $BE -ne 0 ]; then
|
if [ $BE -ne 0 ]; then
|
||||||
new "Kill backend"
|
new "Kill backend"
|
||||||
# Check if premature kill
|
# Check if premature kill
|
||||||
pid=$(pgrep -u $BUSER -f clixon_backend)
|
pid=$(pgrep -u root -f clixon_backend)
|
||||||
if [ -z "$pid" ]; then
|
if [ -z "$pid" ]; then
|
||||||
err "backend already dead"
|
err "backend already dead"
|
||||||
fi
|
fi
|
||||||
|
|
|
||||||
|
|
@ -285,7 +285,7 @@ testrun(){
|
||||||
if [ $BE -ne 0 ]; then
|
if [ $BE -ne 0 ]; then
|
||||||
new "Kill backend"
|
new "Kill backend"
|
||||||
# Check if premature kill
|
# Check if premature kill
|
||||||
pid=$(pgrep -u $BUSER -f clixon_backend)
|
pid=$(pgrep -u root -f clixon_backend)
|
||||||
if [ -z "$pid" ]; then
|
if [ -z "$pid" ]; then
|
||||||
err "backend already dead"
|
err "backend already dead"
|
||||||
fi
|
fi
|
||||||
|
|
|
||||||
|
|
@ -151,7 +151,7 @@ stop_restconf
|
||||||
if [ $BE -ne 0 ]; then
|
if [ $BE -ne 0 ]; then
|
||||||
new "Kill backend"
|
new "Kill backend"
|
||||||
# Check if premature kill
|
# Check if premature kill
|
||||||
pid=$(pgrep -u $BUSER -f clixon_backend)
|
pid=$(pgrep -u root -f clixon_backend)
|
||||||
if [ -z "$pid" ]; then
|
if [ -z "$pid" ]; then
|
||||||
err "backend already dead"
|
err "backend already dead"
|
||||||
fi
|
fi
|
||||||
|
|
|
||||||
|
|
@ -147,7 +147,7 @@ fi
|
||||||
|
|
||||||
new "Kill backend"
|
new "Kill backend"
|
||||||
# Check if premature kill
|
# Check if premature kill
|
||||||
pid=$(pgrep -u $BUSER -f clixon_backend)
|
pid=$(pgrep -u root -f clixon_backend)
|
||||||
if [ -z "$pid" ]; then
|
if [ -z "$pid" ]; then
|
||||||
err "backend already dead"
|
err "backend already dead"
|
||||||
fi
|
fi
|
||||||
|
|
|
||||||
|
|
@ -112,7 +112,7 @@ fi
|
||||||
|
|
||||||
new "Kill backend"
|
new "Kill backend"
|
||||||
# Check if premature kill
|
# Check if premature kill
|
||||||
pid=$(pgrep -u $BUSER -f clixon_backend)
|
pid=$(pgrep -u root -f clixon_backend)
|
||||||
if [ -z "$pid" ]; then
|
if [ -z "$pid" ]; then
|
||||||
err "backend already dead"
|
err "backend already dead"
|
||||||
fi
|
fi
|
||||||
|
|
|
||||||
|
|
@ -286,7 +286,7 @@ fi
|
||||||
|
|
||||||
new "Kill backend"
|
new "Kill backend"
|
||||||
# Check if premature kill
|
# Check if premature kill
|
||||||
pid=$(pgrep -u $BUSER -f clixon_backend)
|
pid=$(pgrep -u root -f clixon_backend)
|
||||||
if [ -z "$pid" ]; then
|
if [ -z "$pid" ]; then
|
||||||
err "backend already dead"
|
err "backend already dead"
|
||||||
fi
|
fi
|
||||||
|
|
|
||||||
|
|
@ -114,7 +114,7 @@ expecteof "$clixon_netconf -qf $cfg -D $DBG" 0 "<rpc><get-config><source><candid
|
||||||
if [ $BE -ne 0 ]; then
|
if [ $BE -ne 0 ]; then
|
||||||
new "Kill backend"
|
new "Kill backend"
|
||||||
# Check if premature kill
|
# Check if premature kill
|
||||||
pid=$(pgrep -u $BUSER -f clixon_backend)
|
pid=$(pgrep -u root -f clixon_backend)
|
||||||
if [ -z "$pid" ]; then
|
if [ -z "$pid" ]; then
|
||||||
err "backend already dead"
|
err "backend already dead"
|
||||||
fi
|
fi
|
||||||
|
|
|
||||||
|
|
@ -100,7 +100,7 @@ expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><edit-config><target><candidate/></
|
||||||
if [ $BE -ne 0 ]; then
|
if [ $BE -ne 0 ]; then
|
||||||
new "Kill backend"
|
new "Kill backend"
|
||||||
# Check if premature kill
|
# Check if premature kill
|
||||||
pid=$(pgrep -u $BUSER -f clixon_backend)
|
pid=$(pgrep -u root -f clixon_backend)
|
||||||
if [ -z "$pid" ]; then
|
if [ -z "$pid" ]; then
|
||||||
err "backend already dead"
|
err "backend already dead"
|
||||||
fi
|
fi
|
||||||
|
|
@ -149,7 +149,7 @@ expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><edit-config><target><candidate/></
|
||||||
if [ $BE -ne 0 ]; then
|
if [ $BE -ne 0 ]; then
|
||||||
new "Kill backend"
|
new "Kill backend"
|
||||||
# Check if premature kill
|
# Check if premature kill
|
||||||
pid=$(pgrep -u $BUSER -f clixon_backend)
|
pid=$(pgrep -u root -f clixon_backend)
|
||||||
if [ -z "$pid" ]; then
|
if [ -z "$pid" ]; then
|
||||||
err "backend already dead"
|
err "backend already dead"
|
||||||
fi
|
fi
|
||||||
|
|
@ -193,7 +193,7 @@ expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><edit-config><target><candidate/></
|
||||||
if [ $BE -ne 0 ]; then
|
if [ $BE -ne 0 ]; then
|
||||||
new "Kill backend"
|
new "Kill backend"
|
||||||
# Check if premature kill
|
# Check if premature kill
|
||||||
pid=$(pgrep -u $BUSER -f clixon_backend)
|
pid=$(pgrep -u root -f clixon_backend)
|
||||||
if [ -z "$pid" ]; then
|
if [ -z "$pid" ]; then
|
||||||
err "backend already dead"
|
err "backend already dead"
|
||||||
fi
|
fi
|
||||||
|
|
@ -237,7 +237,7 @@ expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><edit-config><target><candidate/></
|
||||||
if [ $BE -ne 0 ]; then
|
if [ $BE -ne 0 ]; then
|
||||||
new "Kill backend"
|
new "Kill backend"
|
||||||
# Check if premature kill
|
# Check if premature kill
|
||||||
pid=$(pgrep -u $BUSER -f clixon_backend)
|
pid=$(pgrep -u root -f clixon_backend)
|
||||||
if [ -z "$pid" ]; then
|
if [ -z "$pid" ]; then
|
||||||
err "backend already dead"
|
err "backend already dead"
|
||||||
fi
|
fi
|
||||||
|
|
@ -281,7 +281,7 @@ expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><edit-config><target><candidate/></
|
||||||
if [ $BE -ne 0 ]; then
|
if [ $BE -ne 0 ]; then
|
||||||
new "Kill backend"
|
new "Kill backend"
|
||||||
# Check if premature kill
|
# Check if premature kill
|
||||||
pid=$(pgrep -u $BUSER -f clixon_backend)
|
pid=$(pgrep -u root -f clixon_backend)
|
||||||
if [ -z "$pid" ]; then
|
if [ -z "$pid" ]; then
|
||||||
err "backend already dead"
|
err "backend already dead"
|
||||||
fi
|
fi
|
||||||
|
|
@ -326,7 +326,7 @@ expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><edit-config><target><candidate/></
|
||||||
if [ $BE -ne 0 ]; then
|
if [ $BE -ne 0 ]; then
|
||||||
new "Kill backend"
|
new "Kill backend"
|
||||||
# Check if premature kill
|
# Check if premature kill
|
||||||
pid=$(pgrep -u $BUSER -f clixon_backend)
|
pid=$(pgrep -u root -f clixon_backend)
|
||||||
if [ -z "$pid" ]; then
|
if [ -z "$pid" ]; then
|
||||||
err "backend already dead"
|
err "backend already dead"
|
||||||
fi
|
fi
|
||||||
|
|
@ -372,7 +372,7 @@ expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><edit-config><target><candidate/></
|
||||||
if [ $BE -ne 0 ]; then
|
if [ $BE -ne 0 ]; then
|
||||||
new "Kill backend"
|
new "Kill backend"
|
||||||
# Check if premature kill
|
# Check if premature kill
|
||||||
pid=$(pgrep -u $BUSER -f clixon_backend)
|
pid=$(pgrep -u root -f clixon_backend)
|
||||||
if [ -z "$pid" ]; then
|
if [ -z "$pid" ]; then
|
||||||
err "backend already dead"
|
err "backend already dead"
|
||||||
fi
|
fi
|
||||||
|
|
@ -418,7 +418,7 @@ expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><edit-config><target><candidate/></
|
||||||
if [ $BE -ne 0 ]; then
|
if [ $BE -ne 0 ]; then
|
||||||
new "Kill backend"
|
new "Kill backend"
|
||||||
# Check if premature kill
|
# Check if premature kill
|
||||||
pid=$(pgrep -u $BUSER -f clixon_backend)
|
pid=$(pgrep -u root -f clixon_backend)
|
||||||
if [ -z "$pid" ]; then
|
if [ -z "$pid" ]; then
|
||||||
err "backend already dead"
|
err "backend already dead"
|
||||||
fi
|
fi
|
||||||
|
|
|
||||||
|
|
@ -137,7 +137,7 @@ if [ $BE -eq 0 ]; then
|
||||||
fi
|
fi
|
||||||
new "Kill backend"
|
new "Kill backend"
|
||||||
# Check if premature kill
|
# Check if premature kill
|
||||||
pid=$(pgrep -u $BUSER -f clixon_backend)
|
pid=$(pgrep -u root -f clixon_backend)
|
||||||
if [ -z "$pid" ]; then
|
if [ -z "$pid" ]; then
|
||||||
err "backend already dead"
|
err "backend already dead"
|
||||||
fi
|
fi
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,8 @@ module clixon-config {
|
||||||
|
|
||||||
revision 2019-09-11 {
|
revision 2019-09-11 {
|
||||||
description
|
description
|
||||||
"Added: CLICON_USER: user that backend daemon drops privileges to";
|
"Added: CLICON_BACKEND_USER: drop of privileges to user,
|
||||||
|
CLICON_BACKEND_PRIVILEGES: how to drop privileges";
|
||||||
}
|
}
|
||||||
revision 2019-06-05 {
|
revision 2019-06-05 {
|
||||||
description
|
description
|
||||||
|
|
@ -183,6 +184,26 @@ module clixon-config {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
typedef priv_mode{
|
||||||
|
description
|
||||||
|
"Privilege mode, used for dropping (or not) priveleges to a non-provileged
|
||||||
|
user after initialization";
|
||||||
|
type enumeration{
|
||||||
|
enum none {
|
||||||
|
description
|
||||||
|
"Make no drop/change in privileges.";
|
||||||
|
}
|
||||||
|
enum drop_perm {
|
||||||
|
description
|
||||||
|
"After initialization, drop privileges permanently to a uid";
|
||||||
|
}
|
||||||
|
enum drop_temp {
|
||||||
|
description
|
||||||
|
"After initialization, drop privileges temporarily to a euid";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
container clixon-config {
|
container clixon-config {
|
||||||
leaf-list CLICON_FEATURE {
|
leaf-list CLICON_FEATURE {
|
||||||
description
|
description
|
||||||
|
|
@ -423,11 +444,25 @@ module clixon-config {
|
||||||
"Group membership to access clixon_backend unix socket and gid for
|
"Group membership to access clixon_backend unix socket and gid for
|
||||||
deamon";
|
deamon";
|
||||||
}
|
}
|
||||||
leaf CLICON_USER {
|
leaf CLICON_BACKEND_USER {
|
||||||
type string;
|
type string;
|
||||||
default "clicon";
|
|
||||||
description
|
description
|
||||||
"User to access clixon_backend unix socket and uid for deamon";
|
"User name for backend (both foreground and daemonized).
|
||||||
|
If you set this value the backend if started as root will lower
|
||||||
|
the privileges after initialization.
|
||||||
|
The ownership of files created by the backend will also be set to this
|
||||||
|
user (eg datastores).
|
||||||
|
It also sets the backend unix socket owner to this user, but its group
|
||||||
|
is set by CLICON_SOCK_GROUP.
|
||||||
|
See also CLICON_PRIVILEGES setting";
|
||||||
|
}
|
||||||
|
leaf CLICON_BACKEND_PRIVILEGES {
|
||||||
|
type priv_mode;
|
||||||
|
default none;
|
||||||
|
description
|
||||||
|
"Backend privileges mode.
|
||||||
|
If CLICON_BACKEND_USER user is set, mode can be set to drop_perm or
|
||||||
|
drop_temp.";
|
||||||
}
|
}
|
||||||
leaf CLICON_BACKEND_PIDFILE {
|
leaf CLICON_BACKEND_PIDFILE {
|
||||||
type string;
|
type string;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue