cifs-utils: convert setcifsacl to use the plugin interface
authorJeff Layton <jlayton@samba.org>
Fri, 7 Dec 2012 17:17:03 +0000 (12:17 -0500)
committerJeff Layton <jlayton@samba.org>
Wed, 19 Dec 2012 18:20:28 +0000 (13:20 -0500)
Add str_to_sid() functionality to the plugin API and have setcifsacl
use it.

Signed-off-by: Jeff Layton <jlayton@samba.org>
Makefile.am
cifsidmap.h
idmap_plugin.c
idmap_plugin.h
idmapwb.c
setcifsacl.c

index bc5e517a53073056df3ed537623f737a4c78f172..acace9c8c8a4318e0daa4a834296df9a97354e17 100644 (file)
@@ -62,9 +62,8 @@ getcifsacl_LDADD = -ldl
 man_MANS += getcifsacl.1
 
 bin_PROGRAMS += setcifsacl
-setcifsacl_SOURCES = setcifsacl.c
-setcifsacl_LDADD = $(WBCLIENT_LIBS)
-setcifsacl_CFLAGS = $(WBCLIENT_CFLAGS)
+setcifsacl_SOURCES = setcifsacl.c idmap_plugin.c
+setcifsacl_LDADD = -ldl
 man_MANS += setcifsacl.1
 endif
 
index c307333b64b41e25167b95c60f3c1b44d77150d2..f82e9902a120dba4e5dc54cc58cb465c62bd83c9 100644 (file)
@@ -71,12 +71,29 @@ struct cifs_sid {
  * @name   - return pointer for the name
  *
  * This function should convert the given cifs_sid to a string
- * representation in a heap-allocated buffer. The caller of this
- * function is expected to free "name" on success. Returns 0 on
- * success and non-zero on error.
+ * representation or mapped name in a heap-allocated buffer. The caller
+ * of this function is expected to free "name" on success. Returns 0 on
+ * success and non-zero on error. On error, the errmsg pointer passed
+ * in to the init_plugin function should point to an error string.
  *
  * int cifs_idmap_sid_to_str(void *handle, const struct cifs_sid *sid,
  *                             char **name);
  */
 
+/**
+ * cifs_idmap_str_to_sid - convert string to struct cifs_sid
+ * @handle - context handle
+ * @name   - pointer to name string to be converted
+ * @sid    - pointer to struct cifs_sid where result should go
+ *
+ * This function converts a name string or string representation of
+ * a SID to a struct cifs_sid. The cifs_sid should already be
+ * allocated. Returns 0 on success and non-zero on error. On error, the
+ * plugin should reset the errmsg pointer passed to the init_plugin
+ * function to an error string.
+ *
+ * int cifs_idmap_str_to_sid(void *handle, const char *name,
+ *                             struct cifs_sid *sid);
+ */
+
 #endif /* _CIFSIDMAP_H */
index 237c921d4f76fe13ce3c07fda6630dfbd2ef4c0b..55c766b646af5a342b4e05eb1d200b4863085cd9 100644 (file)
@@ -101,3 +101,17 @@ sid_to_str(void *handle, const struct cifs_sid *sid, char **name)
 
        return (*entry)(handle, sid, name);
 }
+
+int
+str_to_sid(void *handle, const char *name, struct cifs_sid *sid)
+{
+       int (*entry)(void *, const char *, struct cifs_sid *);
+
+       *(void **)(&entry) = resolve_symbol("cifs_idmap_str_to_sid");
+       if (!entry) {
+               plugin_errmsg = "cifs_idmap_str_to_sid not implemented";
+               return -ENOSYS;
+       }
+
+       return (*entry)(handle, name, sid);
+}
index 277bb127dfc3178fa0c0ab0791a0d7a15baa115b..51e3a768bf4bc40ec5151f1805ef8d13d17cf86d 100644 (file)
@@ -43,4 +43,7 @@ extern void exit_plugin(void *handle);
 /* Convert cifs_sid to a string. Caller must free *name on success */
 extern int sid_to_str(void *handle, const struct cifs_sid *sid, char **name);
 
+/* Convert string to cifs_sid. */
+extern int str_to_sid(void *handle, const char *name, struct cifs_sid *csid);
+
 #endif /* _IDMAP_PLUGIN_H */
index 858028f1704e8623768b5d310c442ab4a8631690..aa531504b10bdb0efc2e7d950d3ce96ea8ceb290 100644 (file)
--- a/idmapwb.c
+++ b/idmapwb.c
@@ -52,6 +52,25 @@ csid_to_wsid(struct wbcDomainSid *wsid, const struct cifs_sid *csid)
                wsid->sub_auths[i] = le32toh(csid->sub_auth[i]);
 }
 
+/*
+ * Winbind keeps wbcDomainSid fields in host-endian. Copy fields from the
+ * wsid to the csid, while converting the subauthority fields to LE.
+ */
+static void
+wsid_to_csid(struct cifs_sid *csid, struct wbcDomainSid *wsid)
+{
+       int i;
+       uint8_t num_subauth = (wsid->num_auths <= SID_MAX_SUB_AUTHORITIES) ?
+                               wsid->num_auths : SID_MAX_SUB_AUTHORITIES;
+
+       csid->revision = wsid->sid_rev_num;
+       csid->num_subauth = num_subauth;
+       for (i = 0; i < NUM_AUTHS; i++)
+               csid->authority[i] = wsid->id_auth[i];
+       for (i = 0; i < num_subauth; i++)
+               csid->sub_auth[i] = htole32(wsid->sub_auths[i]);
+}
+
 int
 cifs_idmap_sid_to_str(void *handle __attribute__ ((unused)),
                        const struct cifs_sid *csid, char **string)
@@ -97,6 +116,50 @@ out:
        return rc;
 }
 
+int
+cifs_idmap_str_to_sid(void *handle __attribute__ ((unused)),
+                       const char *orig, struct cifs_sid *csid)
+{
+       wbcErr wbcrc;
+       char *name, *domain, *sidstr;
+       enum wbcSidType type;
+       struct wbcDomainSid wsid;
+
+       sidstr = strdup(orig);
+       if (!sidstr) {
+               *plugin_errmsg = "Unable to copy string";
+               return -ENOMEM;
+       }
+
+       name = strchr(sidstr, '\\');
+       if (!name) {
+               /* might be a raw string representation of SID */
+               wbcrc = wbcStringToSid(sidstr, &wsid);
+               if (WBC_ERROR_IS_OK(wbcrc))
+                       goto convert_sid;
+
+               domain = "";
+               name = sidstr;
+       } else {
+               domain = sidstr;
+               *name = '\0';
+               ++name;
+       }
+
+       wbcrc = wbcLookupName(domain, name, &wsid, &type);
+       /* FIXME: map these to better POSIX error codes? */
+       if (!WBC_ERROR_IS_OK(wbcrc)) {
+               *plugin_errmsg = wbcErrorString(wbcrc);
+               free(sidstr);
+               return -EIO;
+       }
+
+convert_sid:
+       wsid_to_csid(csid, &wsid);
+       free(sidstr);
+       return 0;
+}
+
 /*
  * For the winbind plugin, we don't need to do anything special on
  * init or exit
index e8c10a9d8a7bab754e5e8170d3c2988052429241..211c1af35e0bf8c812826c6d47200e0ff2c8b394 100644 (file)
 #include <stdlib.h>
 #include <errno.h>
 #include <limits.h>
-#include <wbclient.h>
 #include <ctype.h>
 #include <sys/xattr.h>
+
 #include "cifsacl.h"
+#include "idmap_plugin.h"
 
 enum setcifsacl_actions {
        ActUnknown = -1,
@@ -46,6 +47,8 @@ enum setcifsacl_actions {
        ActSet
 };
 
+static void *plugin_handle;
+
 static void
 copy_cifs_sid(struct cifs_sid *dst, const struct cifs_sid *src)
 {
@@ -376,58 +379,6 @@ build_fetched_aces_err:
        return NULL;
 }
 
-/*
- * Winbind keeps wbcDomainSid fields in host-endian. Copy fields from the
- * wsid to the csid, while converting the subauthority fields to LE.
- */
-static void
-wsid_to_csid(struct cifs_sid *csid, struct wbcDomainSid *wsid)
-{
-       int i;
-
-       csid->revision = wsid->sid_rev_num;
-       csid->num_subauth = wsid->num_auths;
-       for (i = 0; i < NUM_AUTHS; i++)
-               csid->authority[i] = wsid->id_auth[i];
-       for (i = 0; i < wsid->num_auths; i++)
-               csid->sub_auth[i] = htole32(wsid->sub_auths[i]);
-}
-
-static int
-verify_ace_sid(char *sidstr, struct cifs_sid *csid)
-{
-       wbcErr rc;
-       char *name, *domain;
-       enum wbcSidType type;
-       struct wbcDomainSid wsid;
-
-       name = strchr(sidstr, '\\');
-       if (!name) {
-               /* might be a raw string representation of SID */
-               rc = wbcStringToSid(sidstr, &wsid);
-               if (WBC_ERROR_IS_OK(rc))
-                       goto convert_sid;
-
-               domain = "";
-               name = sidstr;
-       } else {
-               domain = sidstr;
-               *name = '\0';
-               ++name;
-       }
-
-       rc = wbcLookupName(domain, name, &wsid, &type);
-       if (!WBC_ERROR_IS_OK(rc)) {
-               printf("%s: Error converting %s\\%s to SID: %s\n",
-                       __func__, domain, name, wbcErrorString(rc));
-               return rc;
-       }
-
-convert_sid:
-       wsid_to_csid(csid, &wsid);
-       return 0;
-}
-
 static int
 verify_ace_type(char *typestr, uint8_t *typeval)
 {
@@ -612,8 +563,9 @@ build_cmdline_aces(char **arrptr, int numcaces)
                        goto build_cmdline_aces_ret;
                }
 
-               if (verify_ace_sid(acesid, &cacesptr[i]->sid)) {
-                       printf("%s: Invalid SID: %s\n", __func__, arrptr[i]);
+               if (str_to_sid(plugin_handle, acesid, &cacesptr[i]->sid)) {
+                       printf("%s: Invalid SID (%s): %s\n", __func__, arrptr[i],
+                               plugin_errmsg);
                        goto build_cmdline_aces_ret;
                }
 
@@ -809,6 +761,12 @@ main(const int argc, char *const argv[])
                return -1;
        }
 
+       if (init_plugin(&plugin_handle)) {
+               printf("ERROR: unable to initialize idmapping plugin: %s\n",
+                       plugin_errmsg);
+               return -1;
+       }
+
        numcaces = get_numcaces(ace_list);
 
        arrptr = parse_cmdline_aces(ace_list, numcaces);
@@ -865,6 +823,7 @@ cifsacl:
                printf("%s: setxattr error: %s\n", __func__, strerror(errno));
        goto setcifsacl_facenum_ret;
 
+       exit_plugin(plugin_handle);
        return 0;
 
 setcifsacl_action_ret:
@@ -887,5 +846,6 @@ setcifsacl_cmdlineparse_ret:
        free(arrptr);
 
 setcifsacl_numcaces_ret:
+       exit_plugin(plugin_handle);
        return -1;
 }