[Kimchi-devel] [PATCH V8] add a method to fix search permissions
Aline Manera
alinefm at linux.vnet.ibm.com
Wed Jan 29 23:55:36 UTC 2014
On 01/28/2014 12:37 PM, shaohef at linux.vnet.ibm.com wrote:
> From: ShaoHe Feng <shaohef at linux.vnet.ibm.com>
>
> If the user of path is the same user of "qemu-kvm", then set the fix
> the permission directly.
>
> Or just use setfacl to set the path search permission just for "qemu-kvm"
> user.
>
> We do not fix the permission for others.
>
> Usage:
> check_path_permission("/tmp/need/to/fix/path", username)
> fix_path_permission("/tmp/need/to/fix/path", username)
>
> test:
> $ mkdir -p a/b/c
> $ echo "test" > a/b/c/f
> $ sudo chmod a-xr -R a/b/c/f
>
> $ sudo PYTHONPATH=./src python -c '
> from kimchi.utils import *
> path = "a/b/c/f"
> print check_path_permission(path, "qemu")
> '
>
> $ sudo PYTHONPATH=./src python -c '
> from kimchi.utils import *
> path = "a/b/c/f"
> print fix_path_permission(path, "qemu")
> '
>
> $ cat a/b/c/f
>
> Signed-off-by: ShaoHe Feng <shaohef at linux.vnet.ibm.com>
> Signed-off-by: Aline Manera <alinefm at linux.vnet.ibm.com>
> Signed-off-by: Royce Lv <lvroyce at linux.vnet.ibm.com>
> ---
> src/kimchi/utils.py | 149 ++++++++++++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 149 insertions(+)
>
> diff --git a/src/kimchi/utils.py b/src/kimchi/utils.py
> index 0e66214..39a6cf6 100644
> --- a/src/kimchi/utils.py
> +++ b/src/kimchi/utils.py
> @@ -22,7 +22,11 @@
> #
>
> import cherrypy
> +import grp
> import os
> +import pwd
> +import re
> +import stat
> import subprocess
> import urllib2
>
> @@ -179,3 +183,148 @@ def patch_find_nfs_target(nfs_server):
> target['type'] = 'nfs'
> target['host_name'] = nfs_server
> return targets
> +
> +
> +def name_uid(user):
> + return pwd.getpwnam(user).pw_uid
> +
> +
> +def get_group_ids(user):
> + gids = [g.gr_gid for g in grp.getgrall() if user in g.gr_mem]
> + gid = pwd.getpwnam(user).pw_gid
> + gids.append(grp.getgrgid(gid).gr_gid)
> + return gids
> +
> +
> +def get_groups(user):
> + gids = get_group_ids(user)
> + return [grp.getgrgid(gid).gr_name for gid in gids]
> +
> +
> +def run_setfacl_set_attr(path, attr="x", user="qemu"):
> + set_user = ["setfacl", "--modify", "user:%s:%s" % (user, attr), path]
> + out, error, ret = run_command(set_user)
> + return ret == 0
> +
> +
> +def run_getfacl(path, attr="x", user="qemu", groups=[]):
> + attr = "".join(map(lambda x, y: x if y else ".", ["r", "w", "x"],
> + [b in attr for b in ["r", "w", "x"]]))
> + cmd = ["getfacl", path]
> + out, error, ret = run_command(cmd)
> + if out and ret == 0:
> + res = re.findall("user:%s:%s" % (user, attr), out)
> + if res:
> + return True
> + res = re.findall("(?<=group:)(.*)(?=:%s)" % attr,
> + out) if groups else []
> + return list(set(res) & set(groups)) != []
> + return False
> +
> +
> +def set_x_on_path(path, who="other"):
> + S_IXWHO = ((stat.S_IXUSR if who == "user" else None) or
> + (stat.S_IXGRP if who == "group" else None) or
> + (stat.S_IXOTH if who == "other" else None))
> +
> + if S_IXWHO is None:
> + return False
> + mode = os.stat(path).st_mode | S_IXWHO
> + os.chmod(path, mode)
> + ret = os.stat(path).st_mode == mode
> + if not ret:
> + kimchi_log.debug("faild to set +x attribute on %s", path)
> + return ret
> +
I think we don't need it.
The ISO image will be only read.
> +
> +def set_r_on_path(path, who="other"):
> + S_IXWHO = ((stat.S_IRUSR if who == "user" else None) or
> + (stat.S_IRGRP if who == "group" else None) or
> + (stat.S_IROTH if who == "other" else None))
> +
> + if S_IXWHO is None:
> + return False
> + mode = os.stat(path).st_mode | S_IXWHO
> + os.chmod(path, mode)
> + ret = os.stat(path).st_mode == mode
> + if not ret:
> + kimchi_log.debug("faild to set +x attribute on %s", path)
> + return ret
> +
> +
> +def get_x_on_path(path, uid, gids=[]):
> + try:
> + st = os.stat(path)
> + mode = st.st_mode
> + return ((uid == st.st_uid and mode & stat.S_IXUSR == stat.S_IXUSR) or
> + (st.st_gid in gids and mode & stat.S_IXGRP == stat.S_IXGRP) or
> + mode & stat.S_IXOTH == stat.S_IXOTH)
> + except OSError as e:
> + kimchi_log.error("faild to get x attribute on %s as user id: %s. %s",
> + path, uid, e.message)
> + return False
> +
> +
> +def get_r_on_path(path, uid, gids=[]):
> + try:
> + st = os.stat(path)
> + mode = st.st_mode
> + return ((uid == st.st_uid and mode & stat.S_IRUSR == stat.S_IRUSR) or
> + (st.st_gid in gids and mode & stat.S_IRGRP == stat.S_IRGRP) or
> + mode & stat.S_IROTH == stat.S_IROTH)
> + except OSError as e:
> + kimchi_log.error("faild to get r attribute on %s as user id: %s. %s",
> + path, uid, e.message)
> + return False
> +
> +
> +def check_path_permission(path, user='qemu', groups=[]):
> + f = path if os.path.isfile(path) else None
> + groups = groups if groups else get_groups(user)
> + gids = [grp.getgrnam(group).gr_gid for group in groups] if groups else []
> + uid = name_uid(user)
> + path = os.path.abspath(path)
> + path = os.path.dirname(path) if f else path
> + paths = path.split("/")
> + paths = paths[1:]
> + path = "/"
> + for p in paths:
> + path = os.path.join(path, p)
> + if not (get_x_on_path(path, uid, gids) or
> + run_getfacl(path, 'x', user, groups)):
> + return False
> +
I don't think we need to check x permission
> + return (f is not None and
> + (get_r_on_path(f, uid, gids) or
> + run_getfacl(f, 'r', user, groups)) or
> + False)
> +
> +
> +def fix_path_permission(path, user='qemu', groups=[]):
> + f = path if os.path.isfile(path) else None
> + groups = groups if groups else get_groups(user)
> + gids = [grp.getgrnam(group).gr_gid for group in groups] if groups else []
> + uid = name_uid(user)
> + path = os.path.abspath(path)
> + path = os.path.dirname(path) if f else path
> + paths = path.split("/")
> + paths = paths[1:]
> + path = "/"
> + for p in paths:
> + path = os.path.join(path, p)
> + st = os.stat(path)
> + who = 'user' if st.st_uid == uid else None
> + if not (get_x_on_path(path, uid, gids) or
> + run_getfacl(path, 'x', user, groups) or
> + set_x_on_path(path, who) or
> + run_setfacl_set_attr(path, 'x', user)):
> + return False
> +
> + st = os.stat(f)
> + who = 'user' if st.st_uid == uid else None
> + return (f is not None and
> + (get_r_on_path(f, uid, gids) or
> + run_getfacl(f, 'r', user, groups) or
> + set_r_on_path(f, who) or
> + run_setfacl_set_attr(f, 'r', user)) or
> + False)
More information about the Kimchi-devel
mailing list