[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