[PATCH 1/5] adding seadmin support
Dominick Grift
dominick.grift at gmail.com
Thu Nov 7 17:37:58 UTC 2013
On Thu, 2013-11-07 at 13:21 -0200, Leonidas Da Silva Barbosa wrote:
> Signed-off-by: Leonidas Da Silva Barbosa <leosilva at linux.vnet.ibm.com>
I am not for this solution but for the sake of argument you will find
enclosed in-line some comments.
The idea is nice, but a admin could script this up in a heartbeat
> ---
> policycoreutils/sepolicy/sepolicy/seadmin.py | 83 ++++++++++++++++++++++++++++
> 1 file changed, 83 insertions(+)
> create mode 100644 policycoreutils/sepolicy/sepolicy/seadmin.py
>
> diff --git a/policycoreutils/sepolicy/sepolicy/seadmin.py b/policycoreutils/sepolicy/sepolicy/seadmin.py
> new file mode 100644
> index 0000000..96cab8a
> --- /dev/null
> +++ b/policycoreutils/sepolicy/sepolicy/seadmin.py
> @@ -0,0 +1,83 @@
> +#! /usr/bin/python -Es
> +
> +import os
> +import sys
> +import selinux
> +import seobject
> +import sepolicy
> +
> +from shutil import copy2
> +from os import chmod as set_permissions
> +from selinux import selinux_user_contexts_path, selinux_policy_root
> +
> +# PATH to staff_u that will be base to new users created.
> +STAFF_U = "staff_u"
this is very generic and inflexible in my opinion. I would probably have
implemented a configuration file where admin can set
"default_admin_selinux_identity=", and additionally a
admin_selinux_identity option to override the default
hard coding this to staff_u is asking for problems in my view
because lets say you want to create two admins webadm, and mailadm. If
you use staff_u id for both then you have a problem. because staff_u is
then associated with both the webadm_r, as well as the mailadm_r role
So how are you going to specify then that joe is associated with webadm.
and jane is associated with mailadm?
> +COMMON_PATH = selinux_user_contexts_path()
> +
> +# These are constants used to create SEADM user to an Isolate Admin environment.
> +SELEVEL = "s0"
> +PREFIX = "user"
> +SERANGE = "s0-s0:c0.c1023"
not sure about level, and range. I would probably implement this in a
config file as well (just like above with default_admin_login_identity)
and i would probably use SystemLow for default level, and
SystemLow-SystemHigh for default range because if i am correct that
might be expanded properly, even if you have the mls policy model loaded
hardcoding this in the way you do is asking for problem in my view
> +
> +SUDOERS_PATH = "/etc/sudoers.d/"
> +SUDOERS_ENTRY = "\n%s ALL=(ALL) ROLE=%s TYPE=%s %s"
I would probably deal with the ALL=(ALL) better
by default it should probably be $HOSTNAME=(root), maybe that could be
implemented in a config file as well, and then a option to override the
defaults. ALL=(ALL) is a bit too generic in my view
> +
> +# Initialize adm roles list.
> +ADM_ROLES = [adm_r for adm_r in sepolicy.get_all_roles() if (adm_r[:-2]).
> + endswith('adm')]
> +# Initialize a dictionary of se_adm_users with adm_role as key.
> +ADM_USERS = {key: 'se_'+key[:-2]+'_u' for key in ADM_ROLES}
> +
> +__user = seobject.seluserRecords()
> +__link = seobject.loginRecords()
> +
> +
> +def create_user(adm_role, login, user=None):
> + import pwd
> + try:
> + pwd.getpwnam(login)
> + except KeyError:
> + print("User/Login %s doesn't exist" % login)
> + sys.exit(1)
> +
> + if adm_role in ADM_ROLES:
> + seadm_user = ADM_USERS[adm_role] if not user else user
> + roles = "staff_r {role1} {role2}".format(role1=adm_role,
> + role2="system_r" if adm_role == "sysadm_r" else "")
> +
> + if not seadm_user in sepolicy.get_all_users():
> + __user.add(seadm_user, roles.split(), SELEVEL,
> + SERANGE, PREFIX)
> + copy2(COMMON_PATH+STAFF_U, COMMON_PATH+seadm_user)
> + else:
> + print("%s is not an ADM_ROLE" % adm_role)
> + sys.exit(1)
> +
> +
> +def modify_user(seadm_user, roles):
> + if seadm_user in sepolicy.get_all_users():
> + __user.modify(seadm_user, roles.split(), SELEVEL,
> + SERANGE, PREFIX)
> + else:
> + print("SELinux user not found")
> + sys.exit(1)
> +
> +# sepolicy admin -d -user se_auditadm_u -login leosilva
> +def delete_user(seadm_user, login):
> + if seadm_user in sepolicy.get_all_users():
> + __link.delete(login)
> + __user.delete(seadm_user)
> +
> + else:
> + print("SELinux user not found")
> +
> +
> +def create_link(adm_role, login, commands, user=None):
> + seadm_user = ADM_USERS[adm_role] if not user else user
> + adm_domain = adm_role.replace("_r", "_t")
> +
> + __link.add(login, seadm_user, SERANGE)
> + with open(SUDOERS_PATH+login, 'a') as f:
> + f.write(SUDOERS_ENTRY % (login, adm_role, adm_domain, commands))
> +
> + set_permissions(SUDOERS_PATH+login, 0440)
More information about the selinux
mailing list