From 173e6040feb0da33253c3d4fddf6e76d8b3bd35a Mon Sep 17 00:00:00 2001 From: Joachim Wiberg Date: Thu, 13 Jun 2024 17:19:09 +0200 Subject: [PATCH] confd: allow non-admin users to use the CLI, NACM rules apply With this patch, users not in the NACM admin group and a login shell set to clish can now log in to the CLI. Prior to this change only members of the UNIX group 'wheel' could open the klishd socket. The patch adds another group, 'sys-cli', which acts as a capability for users. An admin user (member of the admin group) will now be member of both the UNIX 'wheel' and 'sys-cli' groups. A non-admin user that has shell set to 'clish' will only be member of the 'sys-cli' group. Other users will not be mapped to any UNIX group and have only permissions set in NACM. Signed-off-by: Joachim Wiberg --- package/klish/klish.hash | 2 +- package/klish/klish.mk | 2 +- .../skeleton-init-finit/skeleton/etc/group | 1 + .../skeleton-init-finit/skeleton/etc/passwd | 1 + .../skeleton-init-finit/skeleton/etc/shadow | 1 + src/confd/src/ietf-system.c | 76 +++++++++++++------ 6 files changed, 58 insertions(+), 25 deletions(-) diff --git a/package/klish/klish.hash b/package/klish/klish.hash index 63a9c1ce..7fad7f0b 100644 --- a/package/klish/klish.hash +++ b/package/klish/klish.hash @@ -1,3 +1,3 @@ # Locally calculated sha256 9d9d33b873917ca5d0bdcc47a36d2fd385971ab0c045d1472fcadf95ee5bcf5b LICENCE -sha256 edb7b9a53d57d87756a99fa25c4af3d6219bed9a863541e672580a2d1f6e7052 klish-b898fdd9a128adaad3a5c92d8dd7baac2085df1b-br1.tar.gz +sha256 c80c2b7eee248d80989fd6218068fe89457d034e3da6db8f0f18cad509e8d52d klish-4afbb469613071503f38c21d54efde97dec86109-br1.tar.gz diff --git a/package/klish/klish.mk b/package/klish/klish.mk index 7dfbb70c..b16b5014 100644 --- a/package/klish/klish.mk +++ b/package/klish/klish.mk @@ -4,7 +4,7 @@ # ################################################################################ -KLISH_VERSION = b898fdd9a128adaad3a5c92d8dd7baac2085df1b +KLISH_VERSION = 4afbb469613071503f38c21d54efde97dec86109 KLISH_SITE = https://github.com/kernelkit/klish.git #KLISH_VERSION = tags/3.0.0 #KLISH_SITE = https://src.libcode.org/pkun/klish.git diff --git a/package/skeleton-init-finit/skeleton/etc/group b/package/skeleton-init-finit/skeleton/etc/group index f20d375c..2614592d 100644 --- a/package/skeleton-init-finit/skeleton/etc/group +++ b/package/skeleton-init-finit/skeleton/etc/group @@ -20,6 +20,7 @@ backup:x:34: utmp:x:43: plugdev:x:46: lock:x:54: +sys-cli:x:60: netdev:x:82: users:x:100: nobody:x:65534: diff --git a/package/skeleton-init-finit/skeleton/etc/passwd b/package/skeleton-init-finit/skeleton/etc/passwd index 03092d75..a2c662ba 100644 --- a/package/skeleton-init-finit/skeleton/etc/passwd +++ b/package/skeleton-init-finit/skeleton/etc/passwd @@ -6,4 +6,5 @@ sync:x:4:100:sync:/bin:/bin/sync mail:x:8:8:mail:/var/spool/mail:/bin/false www-data:x:33:33:www-data:/var/www:/bin/false backup:x:34:34:backup:/var/backups:/bin/false +sys-cli:x:60:60:CLI capability:/var:/bin/false nobody:x:65534:65534:nobody:/home:/bin/false diff --git a/package/skeleton-init-finit/skeleton/etc/shadow b/package/skeleton-init-finit/skeleton/etc/shadow index c5b4a870..820b8fee 100644 --- a/package/skeleton-init-finit/skeleton/etc/shadow +++ b/package/skeleton-init-finit/skeleton/etc/shadow @@ -5,5 +5,6 @@ sys:*::::::: sync:*::::::: mail:*::::::: www-data:*::::::: +sys-cli:*::::::: backup:*::::::: nobody:*::::::: diff --git a/src/confd/src/ietf-system.c b/src/confd/src/ietf-system.c index 01fd4e7d..02064c44 100644 --- a/src/confd/src/ietf-system.c +++ b/src/confd/src/ietf-system.c @@ -584,6 +584,50 @@ fail: return rc; } +static bool is_group_member(const char *user, const char *group) +{ + /* Check if user is already in group */ + if (!systemf("grep %s /etc/group |grep %s", group, user)) + return true; + + return false; +} + +static void add_group(const char *user, const char *group) +{ + bool is_already = is_group_member(user, group); + + if (is_already) + return; /* already group member */ + + if (systemf("adduser %s %s", user, group)) + ERROR("Failed giving user %s UNIX %s permissions.", user, group); + else + NOTE("User %s added to UNIX %s group.", user, group); +} + +static void del_group(const char *user, const char *group) +{ + bool is_already = is_group_member(user, group); + + if (!is_already) + return; /* not member of group */ + + if (systemf("delgroup %s %s", user, group)) + ERROR("Failed removing user %s from UNIX %s group.", user, group); + else + NOTE("User %s removed from UNIX %s group.", user, group); +} + +/* Users with a valid shell are also allowed CLI access */ +static void adjust_access(const char *user, const char *shell) +{ + if (strcmp(shell, "/bin/false")) + add_group(user, "sys-cli"); + else + del_group(user, "sys-cli"); +} + /* XXX: Currently Infix only has admin and non-admins as a group */ static bool is_admin_user(sr_session_ctx_t *session, const char *user) { @@ -764,6 +808,8 @@ static int sys_call_adduser(sr_session_ctx_t *sess, char *name, uid_t uid, gid_t * any SSH public keys have been installed. */ err = systemv_silent(args); + if (!err) + adjust_access(name, shell); free(shell); return err; @@ -860,6 +906,8 @@ static int set_shell(const char *user, const char *shell) FILE *fp = NULL; int fd = -1; + adjust_access(user, shell); + setpwent(); fp = fopen(_PATH_PASSWD "+", "w"); @@ -1237,34 +1285,16 @@ static int change_nacm(sr_session_ctx_t *session, uint32_t sub_id, const char *m for (size_t i = 0; i < user_count; i++) { const char *user = users[i].data.string_val; bool is_admin = is_admin_user(session, user); - bool is_already = false; char *shell; - /* Check if user is already in group */ - if (!systemf("grep wheel /etc/group |grep %s", user)) - is_already = true; - - if (is_admin) { - if (is_already) - continue; /* already admin */ - - if (systemf("adduser %s wheel", user)) - ERROR("Failed giving user %s UNIX sysadmin permissions.", user); - else - NOTE("User %s added to UNIX sysadmin group.", user); - } else { - if (!is_already) - continue; /* not member of wheel */ - - if (systemf("delgroup %s wheel", user)) - ERROR("Failed removing user %s from UNIX sysadmin group.", user); - else - NOTE("User %s removed from UNIX sysadmin group.", user); - } - shell = sys_find_usable_shell(session, (char *)user, is_admin); if (set_shell(user, shell)) ERROR("Failed adjusting shell for user %s", user); + + if (is_admin) + add_group(user, "wheel"); + else + del_group(user, "wheel"); } cleanup: