[lxc-devel] [lxd/master] Implement shifting of UID/GID in ACL xattrs

albertodonato on Github lxc-bot at linuxcontainers.org
Wed Aug 2 15:17:48 UTC 2017


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 314 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20170802/981bc8e6/attachment.bin>
-------------- next part --------------
From 3fca6f3222a98a5f186d3ad94f111fecb83b8596 Mon Sep 17 00:00:00 2001
From: Alberto Donato <alberto.donato at canonical.com>
Date: Wed, 2 Aug 2017 11:03:04 +0200
Subject: [PATCH] shift xattr ACLs uid/gid

Signed-off-by: Alberto Donato <alberto.donato at canonical.com>
---
 shared/idmapset_linux.go |  4 +++
 shared/util_linux.go     | 80 +++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 83 insertions(+), 1 deletion(-)

diff --git a/shared/idmapset_linux.go b/shared/idmapset_linux.go
index 7a8648aba..15555eb58 100644
--- a/shared/idmapset_linux.go
+++ b/shared/idmapset_linux.go
@@ -501,6 +501,10 @@ func (set *IdmapSet) doUidshiftIntoContainer(dir string, testmode bool, how stri
 			if err != nil {
 				return err
 			}
+			err = ShiftACL(dir, path, int(uid), int(gid), int(newuid), int(newgid))
+			if err != nil {
+				return err
+			}
 		}
 		return nil
 	}
diff --git a/shared/util_linux.go b/shared/util_linux.go
index 62225f8a1..8486f4319 100644
--- a/shared/util_linux.go
+++ b/shared/util_linux.go
@@ -19,7 +19,7 @@ import (
 	"github.com/lxc/lxd/shared/logger"
 )
 
-// #cgo LDFLAGS: -lutil -lpthread
+// #cgo LDFLAGS: -lutil -lpthread -lacl
 /*
 #define _GNU_SOURCE
 #include <errno.h>
@@ -36,6 +36,7 @@ import (
 #include <sys/stat.h>
 #include <sys/types.h>
 #include <sys/un.h>
+#include <acl/libacl.h>
 
 #ifndef AT_SYMLINK_FOLLOW
 #define AT_SYMLINK_FOLLOW    0x400
@@ -193,6 +194,69 @@ int shiftowner(char *basepath, char *path, int uid, int gid) {
 	return 0;
 }
 
+int shiftacl(char *basepath, char *path, int uid, int gid, int new_uid, int new_gid) {
+	struct stat sb;
+	acl_t acl;
+
+	acl = acl_get_file(path, ACL_TYPE_ACCESS);
+	if (acl == NULL) {
+		return 0;
+	}
+
+	if (lstat(path, &sb) > 0) {
+		perror("stat failed");
+		return -1;
+	}
+	if (S_ISLNK(sb.st_mode)) {
+		return 0;
+	}
+
+
+	for (int entry_id = ACL_FIRST_ENTRY; ; entry_id = ACL_NEXT_ENTRY) {
+		acl_entry_t ent;
+		acl_tag_t tag;
+		id_t *id_p;
+		id_t new_id;
+		int update_acl = 0;
+
+		if (acl_get_entry(acl, entry_id, &ent) != 1) {
+			break;
+		}
+
+		if (acl_get_tag_type(ent, &tag) == -1) {
+			perror("failed acl_get_tag_type");
+			return 1;
+		}
+
+		id_p = acl_get_qualifier(ent);
+		if (id_p == NULL) {
+			continue;
+		}
+		switch(tag) {
+			case ACL_USER:
+				new_id = *id_p - uid + new_uid;
+				update_acl = 1;
+				break;
+
+			case ACL_GROUP:
+				new_id = *id_p - gid + new_gid;
+				update_acl = 1;
+				break;
+		}
+
+		if (update_acl) {
+			acl_set_qualifier(ent, &new_id);
+			if (acl_set_file(path, ACL_TYPE_ACCESS, acl) == -1) {
+				perror("acl_set_file failed");
+				acl_free(id_p);
+				return 1;
+			}
+		}
+		acl_free(id_p);
+	}
+	return 0;
+}
+
 int get_poll_revents(int lfd, int timeout, int flags, int *revents, int *saved_errno)
 {
 	int ret;
@@ -252,6 +316,20 @@ func ShiftOwner(basepath string, path string, uid int, gid int) error {
 	return nil
 }
 
+func ShiftACL(basepath string, path string, uid int, gid int, newUid int, newGid int) error {
+	cbasepath := C.CString(basepath)
+	defer C.free(unsafe.Pointer(cbasepath))
+
+	cpath := C.CString(path)
+	defer C.free(unsafe.Pointer(cpath))
+
+	r := C.shiftacl(cbasepath, cpath, C.int(uid), C.int(gid), C.int(newUid), C.int(newGid))
+	if r != 0 {
+		return fmt.Errorf("Failed to change ACLs on: %s", path)
+	}
+	return nil
+}
+
 func OpenPty(uid, gid int64) (master *os.File, slave *os.File, err error) {
 	fd_master := C.int(-1)
 	fd_slave := C.int(-1)


More information about the lxc-devel mailing list