The following pull request was submitted through Github.
It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/3625

This e-mail was sent by the LXC bot, direct replies will not reach the author
unless they happen to be subscribed to this list.

=== Description (from pull-request) ===
Closes #3188 
From 3fca6f3222a98a5f186d3ad94f111fecb83b8596 Mon Sep 17 00:00:00 2001
From: Alberto Donato <[email protected]>
Date: Wed, 2 Aug 2017 11:03:04 +0200
Subject: [PATCH] shift xattr ACLs uid/gid

Signed-off-by: Alberto Donato <[email protected]>
---
 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)
_______________________________________________
lxc-devel mailing list
[email protected]
http://lists.linuxcontainers.org/listinfo/lxc-devel

Reply via email to