From 1a0c9cd4e6a9d68be1cded0a64b05a02513b88e8 Mon Sep 17 00:00:00 2001 From: yumaojun <719118794@qq.com> Date: Tue, 24 Nov 2015 22:03:58 +0800 Subject: [PATCH] =?UTF-8?q?1.=20=E6=96=B0=E5=A2=9E=20PermSudo=E8=A1=A8,=20?= =?UTF-8?q?=E7=94=A8=E4=BA=8E=E8=AE=B0=E5=BD=95=20sudo=E5=88=AB=E5=90=8D?= =?UTF-8?q?=202.=20=E5=AE=9E=E7=8E=B0Sudo=E8=A1=A8=E5=AF=B9=E5=BA=94?= =?UTF-8?q?=E7=9A=84=20=E6=B7=BB=E5=8A=A0=EF=BC=8C=E6=98=BE=E7=A4=BA?= =?UTF-8?q?=EF=BC=8C=E6=9B=B4=E6=96=B0=EF=BC=8C=E5=88=A0=E9=99=A4=E9=A1=B5?= =?UTF-8?q?=E9=9D=A2=203.=20=E6=B7=BB=E5=8A=A0=E8=A7=92=E8=89=B2=E6=97=B6?= =?UTF-8?q?=EF=BC=8C=E9=9C=80=E8=A6=81=E9=80=89=E6=8B=A9=E5=AF=B9=E5=BA=94?= =?UTF-8?q?=E7=9A=84=20sudo=E5=88=AB=E5=90=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- jperm/ansible_api.py | 67 +++++++++----- jperm/models.py | 17 +++- jperm/urls.py | 5 +- jperm/utils.py | 25 +++++ jperm/views.py | 136 +++++++++++++++++++++++++++- jumpserver/templatetags/mytags.py | 9 ++ templates/jperm/perm_role_add.html | 11 +++ templates/jperm/perm_role_edit.html | 11 +++ templates/jperm/perm_role_list.html | 3 + templates/jperm/perm_sudo_add.html | 120 ++++++++++++++++++++++++ templates/jperm/perm_sudo_edit.html | 120 ++++++++++++++++++++++++ templates/jperm/perm_sudo_list.html | 112 +++++++++++++++++++++++ templates/jperm/role_sudo.j2 | 126 ++++++++++++++++++++++++++ templates/nav.html | 4 +- 14 files changed, 737 insertions(+), 29 deletions(-) create mode 100644 templates/jperm/perm_sudo_add.html create mode 100644 templates/jperm/perm_sudo_edit.html create mode 100644 templates/jperm/perm_sudo_list.html create mode 100644 templates/jperm/role_sudo.j2 diff --git a/jperm/ansible_api.py b/jperm/ansible_api.py index 3a8b50c61..ee7c2ddee 100644 --- a/jperm/ansible_api.py +++ b/jperm/ansible_api.py @@ -20,7 +20,6 @@ API_DIR = os.path.dirname(os.path.abspath(__file__)) ANSIBLE_DIR = os.path.join(API_DIR, 'playbooks') - class AnsibleError(StandardError): """ the base AnsibleError which contains error(required), @@ -44,7 +43,7 @@ class CommandValueError(AnsibleError): super(CommandValueError, self).__init__('value:invalid', field, message) -class MyInventory(object): +class MyInventory(Inventory): """ this is my ansible inventory object. """ @@ -65,7 +64,7 @@ class MyInventory(object): self.inventory = Inventory(host_list=[]) self.gen_inventory() - def add_group(self, hosts, groupname, groupvars=None): + def my_add_group(self, hosts, groupname, groupvars=None): """ add hosts to a group """ @@ -83,11 +82,13 @@ class MyInventory(object): hostport = host.get("port") username = host.get("username") password = host.get("password") + sudo_password = host.get("sudo_password") my_host = Host(name=hostname, port=hostport) my_host.set_variable('ansible_ssh_host', hostname) my_host.set_variable('ansible_ssh_port', hostport) my_host.set_variable('ansible_ssh_user', username) my_host.set_variable('ansible_ssh_pass', password) + # set other variables for key, value in host.iteritems(): if key not in ["hostname", "port", "username", "password"]: @@ -102,10 +103,10 @@ class MyInventory(object): add hosts to inventory. """ if isinstance(self.resource, list): - self.add_group(self.resource, 'default_group') + self.my_add_group(self.resource, 'default_group') elif isinstance(self.resource, dict): for groupname, hosts_and_vars in self.resource.iteritems(): - self.add_group(hosts_and_vars.get("hosts"), groupname, hosts_and_vars.get("vars")) + self.my_add_group(hosts_and_vars.get("hosts"), groupname, hosts_and_vars.get("vars")) class Command(MyInventory): @@ -125,7 +126,7 @@ class Command(MyInventory): if module_name not in ["raw", "command", "shell"]: raise CommandValueError("module_name", - "module_name must be of the 'raw, command, shell'") + "module_name must be of the 'raw, command, shell'") hoc = Runner(module_name=module_name, module_args=command, timeout=timeout, @@ -136,15 +137,17 @@ class Command(MyInventory): ) self.results = hoc.run() + ret = {} if self.stdout: - return {"ok": self.stdout} + ret["ok"] = self.stdout else: msg = [] if self.stderr: msg.append(self.stderr) if self.dark: msg.append(self.dark) - return {"failed": msg} + ret["failed"] = msg + return ret @property def raw_results(self): @@ -206,7 +209,14 @@ class Tasks(Command): def __init__(self, *args, **kwargs): super(Tasks, self).__init__(*args, **kwargs) - def __run(self, module_args, module_name="command", timeout=5, forks=10, group='default_group', pattern='*'): + def __run(self, + module_args, + module_name="command", + timeout=5, + forks=10, + group='default_group', + pattern='*', + ): """ run command from andible ad-hoc. command : 必须是一个需要执行的命令字符串, 比如 @@ -219,6 +229,7 @@ class Tasks(Command): subset=group, pattern=pattern, forks=forks, + become=False, ) self.results = hoc.run() @@ -272,7 +283,7 @@ class Tasks(Command): module_args = 'user="%s" key="{{ lookup("file", "%s") }}" state="absent"' % (user, key_path) self.__run(module_args, "authorized_key") - return {"status": "failed","msg": self.msg} if self.msg else {"status": "ok"} + return {"status": "failed", "msg": self.msg} if self.msg else {"status": "ok"} def add_user(self, username, password): """ @@ -310,7 +321,8 @@ class Tasks(Command): delete a host user. """ module_args = 'name=%s state=absent remove=yes move_home=yes force=yes' % (username) - self.__run(module_args, "user") + self.__run(module_args, + "user",) return {"status": "failed","msg": self.msg} if self.msg else {"status": "ok"} @@ -386,9 +398,15 @@ class Tasks(Command): "product_sn": setup.get("ansible_product_serial") } - return {"status": "failed", "msg": self.msg} if self.msg else {"status": "ok", "result": result} - + return {"failed": self.msg, "ok": result} + def push_sudo(self, role_custo, role_name, role_chosen): + """ + use template to render pushed sudoers file + :return: + """ + module_args = 'src=%s dest=%s owner=root group=root mode=0440' % (username, encrypt_pass) + self.__run(module_args, "template") class CustomAggregateStats(callbacks.AggregateStats): @@ -440,12 +458,12 @@ class MyPlaybook(MyInventory): playbook_path = os.path.join(ANSIBLE_DIR, playbook_relational_path) pb = PlayBook( - playbook = playbook_path, - stats = stats, - callbacks = playbook_cb, - runner_callbacks = runner_cb, - inventory = self.inventory, - extra_vars = extra_vars, + playbook=playbook_path, + stats=stats, + callbacks=playbook_cb, + runner_callbacks=runner_cb, + inventory=self.inventory, + extra_vars=extra_vars, check=False) self.results = pb.run() @@ -475,9 +493,14 @@ if __name__ == "__main__": # }, # } - resource = [{"hostname": "127.0.0.1", "port": "22", "username": "yumaojun", "password": "yusky0902"}] - command = Command(resource) - print command.run("who") + resource = [{"hostname": "127.0.0.1", "port": "22", "username": "yumaojun", "password": "yusky0902", + # "ansible_become": "yes", + # "ansible_become_method": "sudo", + # # "ansible_become_user": "root", + # "ansible_become_pass": "yusky0902", + }] + cmd = Command(resource) + print cmd.run('ls') # resource = [{"hostname": "192.168.10.148", "port": "22", "username": "root", "password": "xxx"}] # task = Tasks(resource) diff --git a/jperm/models.py b/jperm/models.py index dc8643b67..019411f9b 100644 --- a/jperm/models.py +++ b/jperm/models.py @@ -19,12 +19,23 @@ class SysUser(models.Model): comment = models.CharField(max_length=100, null=True, blank=True, default='') +class PermSudo(models.Model): + name = models.CharField(max_length=100, unique=True) + date_added = models.DateTimeField(auto_now=True) + commands = models.TextField() + comment = models.CharField(max_length=100, null=True, blank=True, default='') + + def __unicode__(self): + return self.name + + class PermRole(models.Model): name = models.CharField(max_length=100, unique=True) comment = models.CharField(max_length=100, null=True, blank=True, default='') password = models.CharField(max_length=100) key_path = models.CharField(max_length=100) date_added = models.DateTimeField(auto_now=True) + sudo = models.ManyToManyField(PermSudo, related_name='perm_role') def __unicode__(self): return self.name @@ -41,4 +52,8 @@ class PermRule(models.Model): role = models.ManyToManyField(PermRole, related_name='perm_rule') def __unicode__(self): - return self.name \ No newline at end of file + return self.name + + + + diff --git a/jperm/urls.py b/jperm/urls.py index aa80f7f75..e382a2a2c 100644 --- a/jperm/urls.py +++ b/jperm/urls.py @@ -13,7 +13,10 @@ urlpatterns = patterns('jperm.views', (r'^role/perm_role_detail/$', perm_role_detail), (r'^role/perm_role_edit/$', perm_role_edit), (r'^role/perm_role_push/$', perm_role_push), - + (r'^sudo/$', perm_sudo_list), + (r'^sudo/perm_sudo_add/$', perm_sudo_add), + (r'^sudo/perm_sudo_delete/$', perm_sudo_delete), + (r'^sudo/perm_sudo_edit/$', perm_sudo_edit), (r'^log/$', log), (r'^sys_user_add/$', sys_user_add), diff --git a/jperm/utils.py b/jperm/utils.py index 63054b30b..ea68488a8 100644 --- a/jperm/utils.py +++ b/jperm/utils.py @@ -6,6 +6,8 @@ import os.path from paramiko.rsakey import RSAKey from os import chmod, makedirs from uuid import uuid4 +from django.template.loader import get_template +from django.template import Context from jumpserver.settings import KEY_DIR @@ -62,6 +64,29 @@ def gen_keys(): return key_path_dir +def gen_sudo(role_custom, role_name, role_chosen): + """ + 生成sudo file, 仅测试了cenos7 + role_custom: 自定义支持的sudo 命令 格式: 'CMD1, CMD2, CMD3, ...' + role_name: role name + role_chosen: 选择那些sudo的命令别名: +     NETWORKING, SOFTWARE, SERVICES, STORAGE, +     DELEGATING, PROCESSES, LOCATE, DRIVERS + :return: + """ + sudo_file_basename = os.path.join(os.path.dirname(KEY_DIR), 'role_sudo_file') + makedirs(sudo_file_basename) + sudo_file_path = os.path.join(sudo_file_basename, role_name) + + t = get_template('role_sudo.j2') + content = t.render(Context({"role_custom": role_custom, + "role_name": role_name, + "role_chosen": role_chosen, + })) + with open(sudo_file_path, 'w') as f: + f.write(content) + return sudo_file_path + if __name__ == "__main__": diff --git a/jperm/views.py b/jperm/views.py index f961a8e07..7c4f59c82 100644 --- a/jperm/views.py +++ b/jperm/views.py @@ -9,7 +9,7 @@ from juser.user_api import gen_ssh_key from juser.models import User, UserGroup from jasset.models import Asset, AssetGroup -from jperm.models import PermRole, PermRule +from jperm.models import PermRole, PermRule, PermSudo from jumpserver.models import Setting from jperm.utils import updates_dict, gen_keys, get_rand_pass @@ -259,19 +259,24 @@ def perm_role_add(request): if request.method == "GET": default_password = get_rand_pass() + sudos = PermSudo.objects.all() return my_render('jperm/perm_role_add.html', locals(), request) elif request.method == "POST": - # 获取参数: name, comment + # 获取参数: name, comment, sudo name = request.POST.get("role_name") comment = request.POST.get("role_comment") password = request.POST.get("role_password") + sudos_name = request.POST.getlist("sudo_name") + sudos_obj = [PermSudo.objects.get(name=sudo_name) for sudo_name in sudos_name] encrypt_pass = CRYPTOR.encrypt(password) # 生成随机密码,生成秘钥对 key_path = gen_keys() role = PermRole(name=name, comment=comment, password=encrypt_pass, key_path=key_path) role.save() + role.sudo = sudos_obj + role.save() msg = u"添加角色: %s" % name # 渲染 刷新数据 @@ -350,6 +355,7 @@ def perm_role_edit(request): role_id = request.GET.get("id") role = PermRole.objects.get(id=role_id) role_pass = CRYPTOR.decrypt(role.password) + role_sudos = role.sudo.all() if request.method == "GET": return my_render('jperm/perm_role_edit.html', locals(), request) @@ -359,11 +365,14 @@ def perm_role_edit(request): role_password = request.POST.get("role_password") encrypt_role_pass = CRYPTOR.encrypt(role_password) role_comment = request.POST.get("role_comment") + role_sudo_names = request.POST.getlist("sudo_name") + role_sudos = [PermSudo.objects.get(name=sudo_name) for sudo_name in role_sudo_names] # 写入数据库 role.name = role_name role.password = encrypt_role_pass role.comment = role_comment + role.sudo = role_sudos role.save() msg = u"更新系统角色: %s" % role.name @@ -380,8 +389,6 @@ def perm_role_edit(request): return my_render('jperm/perm_role_list.html', locals(), request) - - @require_role('admin') def perm_role_push(request): """ @@ -461,6 +468,127 @@ def perm_role_push(request): return HttpResponse(u"推送系统角色: %s" % ','.join(role_names)) +@require_role('admin') +def perm_sudo_list(request): + """ + list sudo commands alias + :param request: + :return: + """ + # 渲染数据 + header_title, path1, path2 = "Sudo命令", "别名管理", "查看别名" + + # 获取所有sudo 命令别名 + sudos_list = PermSudo.objects.all() + + # TODO: 搜索和分页 + keyword = request.GET.get('search', '') + if keyword: + sudos_list = sudos_list.filter(Q(name=keyword)) + + sudos_list, p, sudos, page_range, current_page, show_first, show_end = pages(sudos_list, request) + + return my_render('jperm/perm_sudo_list.html', locals(), request) + + +@require_role('admin') +def perm_sudo_add(request): + """ + list sudo commands alias + :param request: + :return: + """ + # 渲染数据 + header_title, path1, path2 = "Sudo命令", "别名管理", "添加别名" + + if request.method == "GET": + return my_render('jperm/perm_sudo_add.html', locals(), request) + + elif request.method == "POST": + # 获取参数: name, comment + name = request.POST.get("sudo_name") + comment = request.POST.get("sudo_comment") + commands = request.POST.get("sudo_commands") + + sudo = PermSudo(name=name, comment=comment, commands=commands) + sudo.save() + + msg = u"添加Sudo命令别名: %s" % name + # 渲染数据 + header_title, path1, path2 = "Sudo命令", "别名管理", "查看别名" + # 获取所有sudo 命令别名 + sudos_list = PermSudo.objects.all() + + # TODO: 搜索和分页 + keyword = request.GET.get('search', '') + if keyword: + roles_list = sudos_list.filter(Q(name=keyword)) + + sudos_list, p, sudos, page_range, current_page, show_first, show_end = pages(sudos_list, request) + + return my_render('jperm/perm_sudo_list.html', locals(), request) + else: + return HttpResponse(u"不支持该操作") + + +@require_role('admin') +def perm_sudo_edit(request): + """ + list sudo commands alias + :param request: + :return: + """ + # 渲染数据 + header_title, path1, path2 = "Sudo命令", "别名管理", "编辑别名" + + sudo_id = request.GET.get("id") + sudo = PermSudo.objects.get(id=sudo_id) + if request.method == "GET": + return my_render('jperm/perm_sudo_edit.html', locals(), request) + + if request.method == "POST": + name = request.POST.get("sudo_name") + commands = request.POST.get("sudo_commands") + comment = request.POST.get("sudo_comment") + sudo.name = name + sudo.commands = commands + sudo.comment = comment + sudo.save() + + msg = u"更新命令别名: %s" % name + # 渲染数据 + header_title, path1, path2 = "Sudo命令", "别名管理", "查看别名" + # 获取所有sudo 命令别名 + sudos_list = PermSudo.objects.all() + # TODO: 搜索和分页 + keyword = request.GET.get('search', '') + if keyword: + sudos_list = sudos_list.filter(Q(name=keyword)) + sudos_list, p, sudos, page_range, current_page, show_first, show_end = pages(sudos_list, request) + return my_render('jperm/perm_sudo_list.html', locals(), request) + + +@require_role('admin') +def perm_sudo_delete(request): + """ + list sudo commands alias + :param request: + :return: + """ + if request.method == "POST": + # 获取参数删除的role对象 + sudo_id = request.POST.get("id") + sudo = PermSudo.objects.get(id=sudo_id) + # 数据库里删除记录 + sudo.delete() + return HttpResponse(u"删除角色: %s" % sudo.name) + else: + return HttpResponse(u"不支持该操作") + + + + + diff --git a/jumpserver/templatetags/mytags.py b/jumpserver/templatetags/mytags.py index 8dcdf377c..e99c30f05 100644 --- a/jumpserver/templatetags/mytags.py +++ b/jumpserver/templatetags/mytags.py @@ -226,3 +226,12 @@ def ip_str_to_list(ip_str): ip str to list """ return ip_str.split(',') + + +@register.filter(name='role_contain_which_sudos') +def role_contain_which_sudos(role): + """ + get role sudo commands + """ + sudo_names = [sudo.name for sudo in role.sudo.all()] + return ','.join(sudo_names) diff --git a/templates/jperm/perm_role_add.html b/templates/jperm/perm_role_add.html index 243452db0..1f534ac2a 100644 --- a/templates/jperm/perm_role_add.html +++ b/templates/jperm/perm_role_add.html @@ -47,6 +47,17 @@
+
+ +
+ +
+
+
diff --git a/templates/jperm/perm_role_edit.html b/templates/jperm/perm_role_edit.html index 3b5637560..b1a5cb50c 100644 --- a/templates/jperm/perm_role_edit.html +++ b/templates/jperm/perm_role_edit.html @@ -47,6 +47,17 @@
+
+ +
+ +
+
+
diff --git a/templates/jperm/perm_role_list.html b/templates/jperm/perm_role_list.html index 045012ccd..060af1760 100644 --- a/templates/jperm/perm_role_list.html +++ b/templates/jperm/perm_role_list.html @@ -53,6 +53,7 @@ 名称 备注 创建时间 + sudo别名 操作 @@ -62,6 +63,7 @@ {{ role.name }} {{ role.comment }} {{ role.date_added | date:"Y-m-d H:i:s"}} + {{ role | role_contain_which_sudos }} 详情 编辑 @@ -99,6 +101,7 @@ function remove_role(role_id){ del_row.remove() }, error: function (msg) { + console.log(msg) alert("失败: " + msg) } }); diff --git a/templates/jperm/perm_sudo_add.html b/templates/jperm/perm_sudo_add.html new file mode 100644 index 000000000..8df34a5ce --- /dev/null +++ b/templates/jperm/perm_sudo_add.html @@ -0,0 +1,120 @@ +{% extends 'base.html' %} +{% block self_head_css_js %} + + + +{% endblock %} +{% load mytags %} +{% block content %} + {% include 'nav_cat_bar.html' %} +
+
+
+
+
+
填写基本信息
+ +
+
+
+ {% if error %} +
{{ error }}
+ {% endif %} + {% if msg %} +
{{ msg }}
+ {% endif %} +
+ +
+ +
+
+
+
+ +
+ +
+
+
+
+ +
+ +
+
+
+
+
+ + +
+
+
+
+
+
+
+
+{% endblock %} +{% block self_footer_js %} + + + +{% endblock %} + diff --git a/templates/jperm/perm_sudo_edit.html b/templates/jperm/perm_sudo_edit.html new file mode 100644 index 000000000..42621b93a --- /dev/null +++ b/templates/jperm/perm_sudo_edit.html @@ -0,0 +1,120 @@ +{% extends 'base.html' %} +{% block self_head_css_js %} + + + +{% endblock %} +{% load mytags %} +{% block content %} + {% include 'nav_cat_bar.html' %} +
+
+
+
+
+
填写基本信息
+ +
+
+
+ {% if error %} +
{{ error }}
+ {% endif %} + {% if msg %} +
{{ msg }}
+ {% endif %} +
+ +
+ +
+
+
+
+ +
+ +
+
+
+
+ +
+ +
+
+
+
+
+ + +
+
+
+
+
+
+
+
+{% endblock %} +{% block self_footer_js %} + + + +{% endblock %} + diff --git a/templates/jperm/perm_sudo_list.html b/templates/jperm/perm_sudo_list.html new file mode 100644 index 000000000..43f13ec10 --- /dev/null +++ b/templates/jperm/perm_sudo_list.html @@ -0,0 +1,112 @@ +{% extends 'base.html' %} +{% load mytags %} +{% block content %} +{% include 'nav_cat_bar.html' %} + +
+
+
+
+
+ {% if error %} +
{{ error }}
+ {% endif %} + {% if msg %} +
{{ msg }}
+ {% endif %} +
+
+
所有Sudo命令别名
+ +
+ +
+
+ 添加别名 + 删除所选 + +
+ + + + + + + + + + + + {% for sudo in sudos %} + + + + + + + {% endfor %} + +
命令别名 系统命令创建时间操作
{{ sudo.name }} {{ sudo.commands }} {{ sudo.date_added | date:"Y-m-d H:i:s"}} +{# 详情#} + 编辑 + +
+
+
+
+ Showing {{ users.start_index }} to {{ users.end_index }} of {{ p.count }} entries +
+
+ {% include 'paginator.html' %} +
+
+
+
+
+
+ + + + + +{% endblock %} + + diff --git a/templates/jperm/role_sudo.j2 b/templates/jperm/role_sudo.j2 new file mode 100644 index 000000000..ae6e5924c --- /dev/null +++ b/templates/jperm/role_sudo.j2 @@ -0,0 +1,126 @@ +## Sudoers allows particular users to run various commands as +## the root user, without needing the root password. +## +## Examples are provided at the bottom of the file for collections +## of related commands, which can then be delegated out to particular +## users or groups. +## +## This file must be edited with the 'visudo' command. + +## Host Aliases +## Groups of machines. You may prefer to use hostnames (perhaps using +## wildcards for entire domains) or IP addresses instead. +# Host_Alias FILESERVERS = fs1, fs2 +# Host_Alias MAILSERVERS = smtp, smtp2 + +## User Aliases +## These aren't often necessary, as you can use regular groups +## (ie, from files, LDAP, NIS, etc) in this file - just use %groupname +## rather than USERALIAS +# User_Alias ADMINS = jsmith, mikem + + +## Command Aliases +## These are groups of related commands... + +## Networking +Cmnd_Alias NETWORKING = /sbin/route, /sbin/ifconfig, /bin/ping, /sbin/dhclient, /usr/bin/net, /sbin/iptables, /usr/bin/rfcomm, /usr/bin/wvdial, /sbin/iwconfig, /sbin/mii-tool + +## Installation and management of software +Cmnd_Alias SOFTWARE = /bin/rpm, /usr/bin/up2date, /usr/bin/yum + +## Services +Cmnd_Alias SERVICES = /sbin/service, /sbin/chkconfig + +## Updating the locate database +Cmnd_Alias LOCATE = /usr/bin/updatedb + +## Storage +Cmnd_Alias STORAGE = /sbin/fdisk, /sbin/sfdisk, /sbin/parted, /sbin/partprobe, /bin/mount, /bin/umount + +## Delegating permissions +Cmnd_Alias DELEGATING = /bin/chown, /bin/chmod, /bin/chgrp + +## Processes +Cmnd_Alias PROCESSES = /bin/nice, /bin/kill, /usr/bin/kill, /usr/bin/killall + +## Drivers +Cmnd_Alias DRIVERS = /sbin/modprobe + +## Custom +{% if {{ role_custom }} %} +{% Cmnd_Alias CUSTOM = {{ role_custom }} %} +{% endif %} + +# Defaults specification + +# +# Disable "ssh hostname sudo ", because it will show the password in clear. +# You have to run "ssh -t hostname sudo ". +# +Defaults requiretty + +# +# Refuse to run if unable to disable echo on the tty. This setting should also be +# changed in order to be able to use sudo without a tty. See requiretty above. +# +Defaults !visiblepw + +# +# Preserving HOME has security implications since many programs +# use it when searching for configuration files. Note that HOME +# is already set when the the env_reset option is enabled, so +# this option is only effective for configurations where either +# env_reset is disabled or HOME is present in the env_keep list. +# +Defaults always_set_home + +Defaults env_reset +Defaults env_keep = "COLORS DISPLAY HOSTNAME HISTSIZE INPUTRC KDEDIR LS_COLORS" +Defaults env_keep += "MAIL PS1 PS2 QTDIR USERNAME LANG LC_ADDRESS LC_CTYPE" +Defaults env_keep += "LC_COLLATE LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES" +Defaults env_keep += "LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER LC_TELEPHONE" +Defaults env_keep += "LC_TIME LC_ALL LANGUAGE LINGUAS _XKB_CHARSET XAUTHORITY" + +# +# Adding HOME to env_keep may enable a user to run unrestricted +# commands via sudo. +# +# Defaults env_keep += "HOME" + +Defaults secure_path = /sbin:/bin:/usr/sbin:/usr/bin + +## Next comes the main part: which users can run what software on +## which machines (the sudoers file can be shared between multiple +## systems). +## Syntax: +## +## user MACHINE=COMMANDS +## +## The COMMANDS section may have other options added to it. +## +## Allow root to run any commands anywhere +root ALL=(ALL) ALL + +{{ role_name }} ALL = {{ role_chosen }} + + +## Allows members of the 'sys' group to run networking, software, +## service management apps and more. +# %sys ALL = NETWORKING, SOFTWARE, SERVICES, STORAGE, DELEGATING, PROCESSES, LOCATE, DRIVERS + +## Allows people in group wheel to run all commands +%wheel ALL=(ALL) ALL + +## Same thing without a password +# %wheel ALL=(ALL) NOPASSWD: ALL + +## Allows members of the users group to mount and unmount the +## cdrom as root +# %users ALL=/sbin/mount /mnt/cdrom, /sbin/umount /mnt/cdrom + +## Allows members of the users group to shutdown this system +# %users localhost=/sbin/shutdown -h now + +## Read drop-in files from /etc/sudoers.d (the # here does not mean a comment) +#includedir /etc/sudoers.d diff --git a/templates/nav.html b/templates/nav.html index 3f3e76d42..9ad1fb753 100644 --- a/templates/nav.html +++ b/templates/nav.html @@ -32,10 +32,12 @@
  • 授权规则
  • -
  • 系统角色
  • +
  • + Sudo命令 +
  • 权限审批
  • 授权记录