[PATCH v3 3/6] cifs-utils: convert setcifsacl to use the plugin interface

Jeff Layton jlayton at samba.org
Thu Dec 20 05:50:30 MST 2012


Add str_to_sid() functionality to the plugin API and have setcifsacl
use it.

Signed-off-by: Jeff Layton <jlayton at samba.org>
---
 Makefile.am    |  5 ++---
 cifsidmap.h    | 23 ++++++++++++++++---
 idmap_plugin.c | 14 ++++++++++++
 idmap_plugin.h |  3 +++
 idmapwb.c      | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 setcifsacl.c   | 70 +++++++++++++---------------------------------------------
 6 files changed, 117 insertions(+), 61 deletions(-)

diff --git a/Makefile.am b/Makefile.am
index bc5e517..acace9c 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -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
 
diff --git a/cifsidmap.h b/cifsidmap.h
index c307333..f82e990 100644
--- a/cifsidmap.h
+++ b/cifsidmap.h
@@ -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 */
diff --git a/idmap_plugin.c b/idmap_plugin.c
index 237c921..55c766b 100644
--- a/idmap_plugin.c
+++ b/idmap_plugin.c
@@ -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);
+}
diff --git a/idmap_plugin.h b/idmap_plugin.h
index 277bb12..51e3a76 100644
--- a/idmap_plugin.h
+++ b/idmap_plugin.h
@@ -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 */
diff --git a/idmapwb.c b/idmapwb.c
index 858028f..aa53150 100644
--- 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
diff --git a/setcifsacl.c b/setcifsacl.c
index e8c10a9..211c1af 100644
--- a/setcifsacl.c
+++ b/setcifsacl.c
@@ -33,10 +33,11 @@
 #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;
 }
-- 
1.7.11.7



More information about the samba-technical mailing list