Re: [libvirt] [PATCH v5 2/3] virfile: Introduce internal API for managing ACL

2013-03-28 Thread Daniel P. Berrange
On Thu, Mar 21, 2013 at 05:50:48PM +0100, Michal Privoznik wrote:
 For now, only three APIs are implemented:
 virFileGetACL to retrieve permission for a specific user
 virFileSetACL for setting requested permissions for a specific user,
 virFileRemoveACL to remove those permissions.
 ---
 diff to v4:
 -drop errno setting
 
 diff to v3:
 -set errno=ENOSYS when building without WITH_ATTR for easier check within 
 callee.
 -ACL mask is deleted prior recalc as after removing our entry, mask may be not
  required anymore.
 
 diff to v2:
 -Introduced m4 macro to check for libacl
 -new virFileGetACL API
 -ACL mask recalc offloaded to libacl 
  configure.ac |   2 +
  libvirt.spec.in  |   1 +
  m4/virt-acl.m4   |   9 +++
  src/Makefile.am  |   4 +-
  src/libvirt_private.syms |   3 +
  src/util/virfile.c   | 190 
 +++
  src/util/virfile.h   |  14 
  7 files changed, 221 insertions(+), 2 deletions(-)
  create mode 100644 m4/virt-acl.m4

ACK

Daniel
-- 
|: http://berrange.com  -o-http://www.flickr.com/photos/dberrange/ :|
|: http://libvirt.org  -o- http://virt-manager.org :|
|: http://autobuild.org   -o- http://search.cpan.org/~danberr/ :|
|: http://entangle-photo.org   -o-   http://live.gnome.org/gtk-vnc :|

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH v5 2/3] virfile: Introduce internal API for managing ACL

2013-03-21 Thread Michal Privoznik
For now, only three APIs are implemented:
virFileGetACL to retrieve permission for a specific user
virFileSetACL for setting requested permissions for a specific user,
virFileRemoveACL to remove those permissions.
---
diff to v4:
-drop errno setting

diff to v3:
-set errno=ENOSYS when building without WITH_ATTR for easier check within 
callee.
-ACL mask is deleted prior recalc as after removing our entry, mask may be not
 required anymore.

diff to v2:
-Introduced m4 macro to check for libacl
-new virFileGetACL API
-ACL mask recalc offloaded to libacl 
 configure.ac |   2 +
 libvirt.spec.in  |   1 +
 m4/virt-acl.m4   |   9 +++
 src/Makefile.am  |   4 +-
 src/libvirt_private.syms |   3 +
 src/util/virfile.c   | 190 +++
 src/util/virfile.h   |  14 
 7 files changed, 221 insertions(+), 2 deletions(-)
 create mode 100644 m4/virt-acl.m4

diff --git a/configure.ac b/configure.ac
index 9d366e9..4e6627c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -142,6 +142,7 @@ AC_MSG_RESULT([$VERSION_SCRIPT_FLAGS])
 
 LIBVIRT_COMPILE_WARNINGS
 
+LIBVIRT_CHECK_ACL
 LIBVIRT_CHECK_APPARMOR
 LIBVIRT_CHECK_ATTR
 LIBVIRT_CHECK_AUDIT
@@ -2462,6 +2463,7 @@ fi
 AC_MSG_NOTICE([])
 AC_MSG_NOTICE([Libraries])
 AC_MSG_NOTICE([])
+LIBVIRT_RESULT_ACL
 LIBVIRT_RESULT_APPARMOR
 LIBVIRT_RESULT_ATTR
 LIBVIRT_RESULT_AUDIT
diff --git a/libvirt.spec.in b/libvirt.spec.in
index 9fb753a..222674d 100644
--- a/libvirt.spec.in
+++ b/libvirt.spec.in
@@ -411,6 +411,7 @@ BuildRequires: gettext
 BuildRequires: libtasn1-devel
 BuildRequires: gnutls-devel
 BuildRequires: libattr-devel
+BuildRequires: libacl-devel
 %if 0%{?fedora} = 12 || 0%{?rhel} = 6
 # for augparse, optionally used in testing
 BuildRequires: augeas
diff --git a/m4/virt-acl.m4 b/m4/virt-acl.m4
new file mode 100644
index 000..7f16dca
--- /dev/null
+++ b/m4/virt-acl.m4
@@ -0,0 +1,9 @@
+dnl The libacl.so library
+
+AC_DEFUN([LIBVIRT_CHECK_ACL],[
+  LIBVIRT_CHECK_LIB([ACL], [acl], [acl_init], [sys/acl.h])
+])
+
+AC_DEFUN([LIBVIRT_RESULT_ACL],[
+  LIBVIRT_RESULT_LIB([ACL])
+])
diff --git a/src/Makefile.am b/src/Makefile.am
index 3f69d39..921ef94 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -768,11 +768,11 @@ libvirt_util_la_SOURCES = 
\
$(UTIL_SOURCES)
 libvirt_util_la_CFLAGS = $(CAPNG_CFLAGS) $(YAJL_CFLAGS) $(LIBNL_CFLAGS) \
$(AM_CFLAGS) $(AUDIT_CFLAGS) $(DEVMAPPER_CFLAGS) \
-   $(DBUS_CFLAGS) $(LDEXP_LIBM) $(NUMACTL_CFLAGS)
+   $(DBUS_CFLAGS) $(LDEXP_LIBM) $(NUMACTL_CFLAGS) $(ACL_CFLAGS)
 libvirt_util_la_LIBADD = $(CAPNG_LIBS) $(YAJL_LIBS) $(LIBNL_LIBS) \
$(THREAD_LIBS) $(AUDIT_LIBS) $(DEVMAPPER_LIBS) \
$(LIB_CLOCK_GETTIME) $(DBUS_LIBS) $(MSCOM_LIBS) $(LIBXML_LIBS) \
-   $(SECDRIVER_LIBS) $(NUMACTL_LIBS)
+   $(SECDRIVER_LIBS) $(NUMACTL_LIBS) $(ACL_LIBS)
 
 
 noinst_LTLIBRARIES += libvirt_conf.la
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index fd57fa0..db20591 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1253,10 +1253,13 @@ virFileClose;
 virFileDirectFdFlag;
 virFileFclose;
 virFileFdopen;
+virFileGetACL;
 virFileGetAttr;
 virFileLoopDeviceAssociate;
+virFileRemoveACL;
 virFileRemoveAttr;
 virFileRewrite;
+virFileSetACL;
 virFileSetAttr;
 virFileTouch;
 virFileUpdatePerm;
diff --git a/src/util/virfile.c b/src/util/virfile.c
index 2409db4..f8f0e20 100644
--- a/src/util/virfile.c
+++ b/src/util/virfile.c
@@ -41,6 +41,10 @@
 # include attr/xattr.h
 #endif
 
+#ifdef WITH_ACL
+# include acl/libacl.h
+#endif
+
 #include vircommand.h
 #include configmake.h
 #include viralloc.h
@@ -749,3 +753,189 @@ virFileRemoveAttr(const char *file ATTRIBUTE_UNUSED,
 return -1;
 }
 #endif /* WITH_ATTR */
+
+#ifdef WITH_ACL
+static acl_entry_t
+virFileACLFindEntry(acl_t acl, acl_tag_t type, id_t id)
+{
+acl_entry_t ent;
+acl_tag_t e_type;
+id_t *e_id_p;
+
+/* acl_get_entry returns 1 if there's an entry in @acl */
+if (acl_get_entry(acl, ACL_FIRST_ENTRY, ent) != 1)
+return NULL;
+
+do {
+acl_get_tag_type(ent, e_type);
+if (e_type == type) {
+if (id == ACL_UNDEFINED_ID)
+return ent;
+
+if (!(e_id_p = acl_get_qualifier(ent)))
+return NULL;
+if (*e_id_p == id) {
+acl_free(e_id_p);
+return ent;
+}
+acl_free(e_id_p);
+}
+} while (acl_get_entry(acl, ACL_NEXT_ENTRY, ent) == 1);
+
+return NULL;
+}
+
+static void
+virFileACLSetPerms(acl_entry_t ent, mode_t perms)
+{
+acl_permset_t set;
+
+acl_get_permset(ent, set);
+if (perms  S_IRUSR)
+acl_add_perm(set, ACL_READ);
+else
+acl_delete_perm(set, ACL_READ);
+if (perms  S_IWUSR)
+acl_add_perm(set, ACL_WRITE);
+else
+acl_delete_perm(set,