On Thu, 2013-11-07 at 13:21 -0200, Leonidas Da Silva Barbosa wrote: > Signed-off-by: Leonidas Da Silva Barbosa <leosilva@xxxxxxxxxxxxxxxxxx> 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) -- selinux mailing list selinux@xxxxxxxxxxxxxxxxxxxxxxx https://admin.fedoraproject.org/mailman/listinfo/selinux