* [PATCH v2 0/5] cifs-utils: plugin interface for SID to UID/GID mapping
@ 2012-12-18 14:10 Jeff Layton
[not found] ` <1355839848-24118-1-git-send-email-jlayton-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
2012-12-18 14:45 ` [PATCH v2 0/5] cifs-utils: plugin interface for SID to UID/GID mapping Stefan (metze) Metzmacher
0 siblings, 2 replies; 9+ messages in thread
From: Jeff Layton @ 2012-12-18 14:10 UTC (permalink / raw)
To: linux-cifs-u79uwXL29TY76Z2rM5mHXA; +Cc: samba-technical-w/Ol4Ecudpl8XjKLYN78aQ
This is the second official posting for the plugin interface. Major
changes since the last set are:
1/ There's a header file now that plugin implementers are expected to use
2/ New manpage for idmapwb.so and cleanups to the existing manpages to
discuss plugin configuration
3/ Better handling for the plugin_errmsg variable. A pointer to the
pointer is passed into the init_plugin routine, which allows the
setting of it in the context.
With this, I think I'm pretty close to something mergeable, but
comments and review are still appreciated.
Jeff Layton (5):
cifs-utils: struct cifs_sid definition to new cifsidmap.h header
cifs-utils: new plugin architecture for ID mapping code
cifs-utils: convert setcifsacl to use the plugin interface
cifs-utils: convert cifs.idmap to use plugin interface
cifs-utils: add a manpage for idmapwb
Makefile.am | 37 ++++--
cifs.idmap.8.in | 22 ++--
cifs.idmap.c | 93 +++++++--------
cifsacl.h | 12 +-
cifsidmap.h | 161 ++++++++++++++++++++++++++
configure.ac | 10 ++
getcifsacl.1 => getcifsacl.1.in | 5 +-
getcifsacl.c | 98 +++++++---------
idmap_plugin.c | 160 ++++++++++++++++++++++++++
idmap_plugin.h | 61 ++++++++++
idmapwb.8.in | 148 ++++++++++++++++++++++++
idmapwb.c | 242 ++++++++++++++++++++++++++++++++++++++++
idmapwb.pod | 26 +++++
setcifsacl.1 => setcifsacl.1.in | 6 +-
setcifsacl.c | 70 +++---------
15 files changed, 952 insertions(+), 199 deletions(-)
create mode 100644 cifsidmap.h
rename getcifsacl.1 => getcifsacl.1.in (87%)
create mode 100644 idmap_plugin.c
create mode 100644 idmap_plugin.h
create mode 100644 idmapwb.8.in
create mode 100644 idmapwb.c
create mode 100644 idmapwb.pod
rename setcifsacl.1 => setcifsacl.1.in (91%)
--
1.7.11.7
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH v2 1/5] cifs-utils: struct cifs_sid definition to new cifsidmap.h header
[not found] ` <1355839848-24118-1-git-send-email-jlayton-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
@ 2012-12-18 14:10 ` Jeff Layton
2012-12-18 14:10 ` [PATCH v2 2/5] cifs-utils: new plugin architecture for ID mapping code Jeff Layton
` (3 subsequent siblings)
4 siblings, 0 replies; 9+ messages in thread
From: Jeff Layton @ 2012-12-18 14:10 UTC (permalink / raw)
To: linux-cifs-u79uwXL29TY76Z2rM5mHXA; +Cc: samba-technical-w/Ol4Ecudpl8XjKLYN78aQ
People who want to build a plugin for the idmapping routines will need a
header to describe the data types that they need. Add a cifsidmap.h file
and move the struct cifs_sid definition into it, along with the
constants needed to describe it.
Signed-off-by: Jeff Layton <jlayton-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
---
Makefile.am | 1 +
cifsacl.h | 12 ++----------
cifsidmap.h | 37 +++++++++++++++++++++++++++++++++++++
3 files changed, 40 insertions(+), 10 deletions(-)
create mode 100644 cifsidmap.h
diff --git a/Makefile.am b/Makefile.am
index ff7a726..8964b37 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -7,6 +7,7 @@ mount_cifs_SOURCES = mount.cifs.c mtab.c resolve_host.c util.c
mount_cifs_LDADD = $(LIBCAP) $(CAPNG_LDADD) $(RT_LDADD)
man_MANS = mount.cifs.8
+include_HEADERS = cifsidmap.h
bin_PROGRAMS =
sbin_PROGRAMS =
diff --git a/cifsacl.h b/cifsacl.h
index 68fe0fd..ca72dd4 100644
--- a/cifsacl.h
+++ b/cifsacl.h
@@ -20,6 +20,8 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+#include "cifsidmap.h"
+
#ifndef _CIFSACL_H
#define _CIFSACL_H
@@ -96,9 +98,6 @@
#define COMPMASK 0x8
#define COMPALL (COMPSID|COMPTYPE|COMPFLAG|COMPMASK)
-#define NUM_AUTHS (6) /* number of authority fields */
-#define SID_MAX_SUB_AUTHORITIES (15) /* max number of sub authority fields */
-
/*
* While not indicated here, the structs below represent on-the-wire data
* structures. Any multi-byte values are expected to be little-endian!
@@ -114,13 +113,6 @@ struct cifs_ntsd {
uint32_t dacloffset;
} __attribute__((packed));
-struct cifs_sid {
- uint8_t revision; /* revision level */
- uint8_t num_subauth;
- uint8_t authority[NUM_AUTHS];
- uint32_t sub_auth[SID_MAX_SUB_AUTHORITIES];
-} __attribute__((packed));
-
struct cifs_ctrl_acl {
uint16_t revision; /* revision level */
uint16_t size;
diff --git a/cifsidmap.h b/cifsidmap.h
new file mode 100644
index 0000000..9907618
--- /dev/null
+++ b/cifsidmap.h
@@ -0,0 +1,37 @@
+/*
+ * ID Mapping Plugin interface for cifs-utils
+ * Copyright (C) 2012 Jeff Layton (jlayton-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include <stdint.h>
+
+#ifndef _CIFSIDMAP_H
+#define _CIFSIDMAP_H
+
+#define NUM_AUTHS (6) /* number of authority fields */
+#define SID_MAX_SUB_AUTHORITIES (15) /* max number of sub authority fields */
+
+/*
+ * Binary representation of a SID as presented to/from the kernel. Note that
+ * the sub_auth field is always stored in little-endian here.
+ */
+struct cifs_sid {
+ uint8_t revision; /* revision level */
+ uint8_t num_subauth;
+ uint8_t authority[NUM_AUTHS];
+ uint32_t sub_auth[SID_MAX_SUB_AUTHORITIES];
+} __attribute__((packed));
+
+#endif /* _CIFSIDMAP_H */
--
1.7.11.7
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH v2 2/5] cifs-utils: new plugin architecture for ID mapping code
[not found] ` <1355839848-24118-1-git-send-email-jlayton-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
2012-12-18 14:10 ` [PATCH v2 1/5] cifs-utils: struct cifs_sid definition to new cifsidmap.h header Jeff Layton
@ 2012-12-18 14:10 ` Jeff Layton
[not found] ` <1355839848-24118-3-git-send-email-jlayton-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
2012-12-18 14:10 ` [PATCH v2 3/5] cifs-utils: convert setcifsacl to use the plugin interface Jeff Layton
` (2 subsequent siblings)
4 siblings, 1 reply; 9+ messages in thread
From: Jeff Layton @ 2012-12-18 14:10 UTC (permalink / raw)
To: linux-cifs-u79uwXL29TY76Z2rM5mHXA; +Cc: samba-technical-w/Ol4Ecudpl8XjKLYN78aQ
Currently, the ACL-related tools in cifs-utils call into the wbclient
libs directly in order to do their bidding. The wbclient developers want
to get away from needing to configure winbind on the clients and instead
allow sssd to handle the mapping in most cases.
This patch represents an initial step in that direction. It adds a
plugin architecture for cifs-utils, adds wrappers around the calls into
libwbclient that find an idmap plugin library to use and then has it
call into that plugin to do the actual ID mapping.
The application will call into a set of routines that find the correct
plugin and dlopen() it. Currently the plugin is located in a well-known
location that is settable via autoconf. That location is intended to be
a symlink that points to the real plugin (generally under $pkglibdir).
The plugin will export a number of functions with well-known names. The
wrappers find those by using dlsym() and then call them.
Signed-off-by: Jeff Layton <jlayton-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
---
Makefile.am | 13 +++++--
cifsidmap.h | 45 ++++++++++++++++++++++
configure.ac | 9 +++++
getcifsacl.c | 98 +++++++++++++++++++++---------------------------
idmap_plugin.c | 99 +++++++++++++++++++++++++++++++++++++++++++++++++
idmap_plugin.h | 46 +++++++++++++++++++++++
idmapwb.c | 115 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
7 files changed, 367 insertions(+), 58 deletions(-)
create mode 100644 idmap_plugin.c
create mode 100644 idmap_plugin.h
create mode 100644 idmapwb.c
diff --git a/Makefile.am b/Makefile.am
index 8964b37..bc5e517 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -57,9 +57,8 @@ endif
if CONFIG_CIFSACL
bin_PROGRAMS += getcifsacl
-getcifsacl_SOURCES = getcifsacl.c
-getcifsacl_LDADD = $(WBCLIENT_LIBS)
-getcifsacl_CFLAGS = $(WBCLIENT_CFLAGS)
+getcifsacl_SOURCES = getcifsacl.c idmap_plugin.c
+getcifsacl_LDADD = -ldl
man_MANS += getcifsacl.1
bin_PROGRAMS += setcifsacl
@@ -69,4 +68,12 @@ setcifsacl_CFLAGS = $(WBCLIENT_CFLAGS)
man_MANS += setcifsacl.1
endif
+if CONFIG_PLUGIN
+plugindir = $(pkglibdir)
+plugin_PROGRAMS = idmapwb.so
+
+idmapwb.so: idmapwb.c
+ $(CC) $(CFLAGS) $(AM_CFLAGS) $(WBCLIENT_CFLAGS) $(LDFLAGS) -shared -fpic -o $@ $+ $(WBCLIENT_LIBS)
+endif
+
SUBDIRS = contrib
diff --git a/cifsidmap.h b/cifsidmap.h
index 9907618..c307333 100644
--- a/cifsidmap.h
+++ b/cifsidmap.h
@@ -34,4 +34,49 @@ struct cifs_sid {
uint32_t sub_auth[SID_MAX_SUB_AUTHORITIES];
} __attribute__((packed));
+/* Plugins should implement the following functions: */
+
+/**
+ * cifs_idmap_init_plugin - Initialize the plugin interface
+ * @handle - return pointer for an opaque handle
+ * @errmsg - pointer to error message pointer
+ *
+ * This function should do whatever is required to establish a context
+ * for later ID mapping operations. The "handle" is an opaque context
+ * cookie that will be passed in on subsequent ID mapping operations.
+ * The errmsg is used to pass back an error string both during the init
+ * and in subsequent idmapping functions. On any error, the plugin
+ * should point *errmsg at a string describing that error. Returns 0
+ * on success and non-zero on error.
+ *
+ * int cifs_idmap_init_plugin(void **handle, const char **errmsg);
+ */
+
+/**
+ * cifs_idmap_exit_plugin - Destroy an idmapping context
+ * @handle - context handle that should be destroyed
+ *
+ * When programs are finished with the idmapping plugin, they'll call
+ * this function to destroy any context that was created during the
+ * init_plugin. The handle passed back in was the one given by the init
+ * routine.
+ *
+ * void cifs_idmap_exit_plugin(void *handle);
+ */
+
+/**
+ * cifs_idmap_sid_to_str - convert cifs_sid to a string
+ * @handle - context handle
+ * @sid - pointer to a 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.
+ *
+ * int cifs_idmap_sid_to_str(void *handle, const struct cifs_sid *sid,
+ * char **name);
+ */
+
#endif /* _CIFSIDMAP_H */
diff --git a/configure.ac b/configure.ac
index b6791ab..9652ad2 100644
--- a/configure.ac
+++ b/configure.ac
@@ -52,6 +52,14 @@ AC_ARG_ENABLE(systemd,
enable_systemd=$enableval,
enable_systemd="maybe")
+# "with" options
+AC_ARG_WITH(idmap-plugin,
+ [AC_HELP_STRING([--with-idmap-plugin=/path/to/plugin],
+ [Define the path to the plugin that the idmapping infrastructure should use @<:@default=/etc/cifs-utils/idmap-plugin@:>@])],
+ pluginpath=$withval,
+ pluginpath="/etc/cifs-utils/idmap-plugin")
+AC_DEFINE_UNQUOTED(IDMAP_PLUGIN_PATH, "$pluginpath", [Location of plugin that ID mapping infrastructure should use. (usually a symlink to real plugin)])
+
# check for ROOTSBINDIR environment var
if test -z $ROOTSBINDIR; then
ROOTSBINDIR="/sbin"
@@ -230,6 +238,7 @@ AM_CONDITIONAL(CONFIG_CIFSUPCALL, [test "$enable_cifsupcall" != "no"])
AM_CONDITIONAL(CONFIG_CIFSCREDS, [test "$enable_cifscreds" != "no"])
AM_CONDITIONAL(CONFIG_CIFSIDMAP, [test "$enable_cifsidmap" != "no"])
AM_CONDITIONAL(CONFIG_CIFSACL, [test "$enable_cifsacl" != "no"])
+AM_CONDITIONAL(CONFIG_PLUGIN, [test "$enable_cifsidmap" != "no" -o "$enable_cifsacl" != "no"])
LIBCAP_NG_PATH
diff --git a/getcifsacl.c b/getcifsacl.c
index 550429c..c0b051d 100644
--- a/getcifsacl.c
+++ b/getcifsacl.c
@@ -33,10 +33,13 @@
#include <stddef.h>
#include <errno.h>
#include <limits.h>
-#include <wbclient.h>
#include <ctype.h>
#include <sys/xattr.h>
#include "cifsacl.h"
+#include "idmap_plugin.h"
+
+static void *plugin_handle;
+static bool plugin_loaded;
static void
print_each_ace_mask(uint32_t mask)
@@ -169,61 +172,33 @@ print_ace_type(uint8_t acetype, int raw)
}
}
-/*
- * Winbind keeps wbcDomainSid fields in host-endian. Copy fields from the
- * csid to the wsid, while converting the subauthority fields from LE.
- */
static void
-csid_to_wsid(struct wbcDomainSid *wsid, const struct cifs_sid *csid)
+print_sid(struct cifs_sid *csid, int raw)
{
- int i;
- uint8_t num_subauth = (csid->num_subauth <= WBC_MAXSUBAUTHS) ?
- csid->num_subauth : WBC_MAXSUBAUTHS;
-
- wsid->sid_rev_num = csid->revision;
- wsid->num_auths = num_subauth;
- for (i = 0; i < NUM_AUTHS; i++)
- wsid->id_auth[i] = csid->authority[i];
- for (i = 0; i < num_subauth; i++)
- wsid->sub_auths[i] = le32toh(csid->sub_auth[i]);
-}
-
-static void
-print_sid(struct cifs_sid *sidptr, int raw)
-{
- int i;
- wbcErr rc;
- char *domain_name = NULL;
- char *sidname = NULL;
- enum wbcSidType sntype;
+ int i, rc;
+ char *name;
unsigned long long id_auth_val;
- struct wbcDomainSid wsid;
- csid_to_wsid(&wsid, sidptr);
+ if (raw || !plugin_loaded)
+ goto print_sid_raw;
- if (raw)
+ rc = sid_to_str(plugin_handle, csid, &name);
+ if (rc)
goto print_sid_raw;
- rc = wbcLookupSid(&wsid, &domain_name, &sidname, &sntype);
- if (WBC_ERROR_IS_OK(rc)) {
- printf("%s", domain_name);
- if (strlen(domain_name))
- printf("%c", '\\');
- printf("%s", sidname);
- wbcFreeMemory(domain_name);
- wbcFreeMemory(sidname);
- return;
- }
+ printf("%s", name);
+ free(name);
+ return;
print_sid_raw:
- printf("S-%hhu", wsid.sid_rev_num);
+ printf("S-%hhu", csid->revision);
- id_auth_val = (unsigned long long)wsid.id_auth[5];
- id_auth_val += (unsigned long long)wsid.id_auth[4] << 8;
- id_auth_val += (unsigned long long)wsid.id_auth[3] << 16;
- id_auth_val += (unsigned long long)wsid.id_auth[2] << 24;
- id_auth_val += (unsigned long long)wsid.id_auth[1] << 32;
- id_auth_val += (unsigned long long)wsid.id_auth[0] << 48;
+ id_auth_val = (unsigned long long)csid->authority[5];
+ id_auth_val += (unsigned long long)csid->authority[4] << 8;
+ id_auth_val += (unsigned long long)csid->authority[3] << 16;
+ id_auth_val += (unsigned long long)csid->authority[2] << 24;
+ id_auth_val += (unsigned long long)csid->authority[1] << 32;
+ id_auth_val += (unsigned long long)csid->authority[0] << 48;
/*
* MS-DTYP states that if the authority is >= 2^32, then it should be
@@ -234,8 +209,8 @@ print_sid_raw:
else
printf("-0x%llx", id_auth_val);
- for (i = 0; i < wsid.num_auths; i++)
- printf("-%u", wsid.sub_auths[i]);
+ for (i = 0; i < csid->num_subauth; i++)
+ printf("-%u", csid->sub_auth[i]);
}
static void
@@ -368,7 +343,8 @@ getcifsacl_usage(const char *prog)
int
main(const int argc, char *const argv[])
{
- int c, raw = 0;
+ int c, ret = 0;
+ bool raw = false;
ssize_t attrlen;
size_t bufsize = BUFSIZE;
char *filename, *attrval;
@@ -379,7 +355,7 @@ main(const int argc, char *const argv[])
printf("Version: %s\n", VERSION);
goto out;
case 'r':
- raw = 1;
+ raw = true;
break;
default:
break;
@@ -392,20 +368,31 @@ main(const int argc, char *const argv[])
filename = argv[1];
else {
getcifsacl_usage(basename(argv[0]));
- return 0;
+ goto out;
+ }
+
+ if (!raw && !plugin_loaded) {
+ ret = init_plugin(&plugin_handle);
+ if (ret)
+ printf("WARNING: unable to initialize idmapping plugin: %s\n",
+ plugin_errmsg);
+ else
+ plugin_loaded = true;
}
cifsacl:
if (bufsize >= XATTR_SIZE_MAX) {
printf("buffer to allocate exceeds max size of %d\n",
XATTR_SIZE_MAX);
- return -1;
+ ret = -1;
+ goto out;
}
attrval = malloc(bufsize * sizeof(char));
if (!attrval) {
printf("error allocating memory for attribute value buffer\n");
- return -1;
+ ret = -1;
+ goto out;
}
attrlen = getxattr(filename, ATTRNAME, attrval, bufsize);
@@ -421,7 +408,8 @@ cifsacl:
parse_sec_desc((struct cifs_ntsd *)attrval, attrlen, raw);
free(attrval);
-
out:
- return 0;
+ if (plugin_loaded)
+ exit_plugin(plugin_handle);
+ return ret;
}
diff --git a/idmap_plugin.c b/idmap_plugin.c
new file mode 100644
index 0000000..4dbeca7
--- /dev/null
+++ b/idmap_plugin.c
@@ -0,0 +1,99 @@
+/*
+ * ID Mapping Plugin interface for cifs-utils
+ * Copyright (C) 2012 Jeff Layton (jlayton-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif /* HAVE_CONFIG_H */
+
+#include <dlfcn.h>
+#include <errno.h>
+#include <stdint.h>
+
+#include "cifsacl.h"
+
+const char *plugin_errmsg;
+static void *plugin;
+
+static void *
+resolve_symbol(const char *symbol_name)
+{
+ void *symbol;
+
+ dlerror();
+ symbol = dlsym(plugin, symbol_name);
+ if (!symbol)
+ plugin_errmsg = dlerror();
+ return symbol;
+}
+
+/*
+ * open the plugin. Note that we leave it open over the life of the
+ * program. It gets closed on exit.
+ */
+static int
+open_plugin(void)
+{
+ if (plugin)
+ return 0;
+
+ plugin = dlopen(IDMAP_PLUGIN_PATH, RTLD_LAZY);
+ if (!plugin) {
+ plugin_errmsg = dlerror();
+ return -EIO;
+ }
+
+ return 0;
+}
+
+int
+init_plugin(void **handle)
+{
+ int ret;
+ int (*init)(void **, const char **);
+
+ ret = open_plugin();
+ if (ret)
+ return ret;
+
+ init = resolve_symbol("cifs_idmap_init_plugin");
+ if (!init)
+ return -ENOSYS;
+ return (*init)(handle, &plugin_errmsg);
+}
+
+void
+exit_plugin(void *handle)
+{
+ int (*exit)(void *);
+
+ exit = resolve_symbol("cifs_idmap_exit_plugin");
+ if (exit)
+ (*exit)(handle);
+}
+
+int
+sid_to_str(void *handle, const struct cifs_sid *sid, char **name)
+{
+ int (*entry)(void *, const struct cifs_sid *, char **);
+
+ *(void **)(&entry) = resolve_symbol("cifs_idmap_sid_to_str");
+ if (!entry)
+ return -ENOSYS;
+
+ return (*entry)(handle, sid, name);
+}
diff --git a/idmap_plugin.h b/idmap_plugin.h
new file mode 100644
index 0000000..277bb12
--- /dev/null
+++ b/idmap_plugin.h
@@ -0,0 +1,46 @@
+/*
+ * ID Mapping Plugin interface for cifs-utils
+ * Copyright (C) 2012 Jeff Layton (jlayton-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cifsidmap.h"
+
+#ifndef _IDMAP_PLUGIN_H
+#define _IDMAP_PLUGIN_H
+
+/*
+ * On error, plugin functions will set this pointer to a string description
+ * of the error. The string should not be freed.
+ */
+extern const char *plugin_errmsg;
+
+/*
+ * External API. Programs should call this to use the plugin functionality.
+ */
+
+/*
+ * Initialize plugin. Returns an opaque handle that should be passed to
+ * other idmapping functions.
+ */
+extern int init_plugin(void **handle);
+
+/* Close out an init'ed handle */
+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);
+
+#endif /* _IDMAP_PLUGIN_H */
diff --git a/idmapwb.c b/idmapwb.c
new file mode 100644
index 0000000..858028f
--- /dev/null
+++ b/idmapwb.c
@@ -0,0 +1,115 @@
+/*
+ * Winbind ID Mapping Plugin
+ * Copyright (C) 2012 Jeff Layton (jlayton-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif /* HAVE_CONFIG_H */
+
+#include <stdint.h>
+#include <endian.h>
+#include <string.h>
+#include <errno.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <wbclient.h>
+
+#include "cifsidmap.h"
+
+static const char **plugin_errmsg;
+
+/*
+ * Winbind keeps wbcDomainSid fields in host-endian. Copy fields from the
+ * csid to the wsid, while converting the subauthority fields from LE.
+ */
+static void
+csid_to_wsid(struct wbcDomainSid *wsid, const struct cifs_sid *csid)
+{
+ int i;
+ uint8_t num_subauth = (csid->num_subauth <= WBC_MAXSUBAUTHS) ?
+ csid->num_subauth : WBC_MAXSUBAUTHS;
+
+ wsid->sid_rev_num = csid->revision;
+ wsid->num_auths = num_subauth;
+ for (i = 0; i < NUM_AUTHS; i++)
+ wsid->id_auth[i] = csid->authority[i];
+ for (i = 0; i < num_subauth; i++)
+ wsid->sub_auths[i] = le32toh(csid->sub_auth[i]);
+}
+
+int
+cifs_idmap_sid_to_str(void *handle __attribute__ ((unused)),
+ const struct cifs_sid *csid, char **string)
+{
+ int rc;
+ wbcErr wbcrc;
+ char *domain = NULL;
+ char *name = NULL;
+ enum wbcSidType sntype;
+ struct wbcDomainSid wsid;
+ size_t len;
+
+ csid_to_wsid(&wsid, csid);
+
+ wbcrc = wbcLookupSid(&wsid, &domain, &name, &sntype);
+ if (!WBC_ERROR_IS_OK(wbcrc)) {
+ *plugin_errmsg = wbcErrorString(wbcrc);
+ return -EIO;
+ }
+
+ /* +1 for '\\' and +1 for NULL terminator */
+ len = strlen(domain) + 1 + strlen(name) + 1;
+
+ *string = malloc(len);
+ if (!*string) {
+ *plugin_errmsg = "Unable to allocate memory";
+ rc = -ENOMEM;
+ goto out;
+ }
+
+ rc = snprintf(*string, len, "%s\\%s", domain, name);
+ if (rc >= (long)len) {
+ free(*string);
+ *plugin_errmsg = "Resulting string was truncated";
+ *string = NULL;
+ rc = -EIO;
+ } else {
+ rc = 0;
+ }
+out:
+ wbcFreeMemory(domain);
+ wbcFreeMemory(name);
+ return rc;
+}
+
+/*
+ * For the winbind plugin, we don't need to do anything special on
+ * init or exit
+ */
+int
+cifs_idmap_init_plugin(void **handle __attribute__((unused)), const char **errmsg)
+{
+ plugin_errmsg = errmsg;
+ return 0;
+}
+
+void
+cifs_idmap_exit_plugin(void *handle __attribute__((unused)))
+{
+ return;
+}
--
1.7.11.7
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH v2 3/5] cifs-utils: convert setcifsacl to use the plugin interface
[not found] ` <1355839848-24118-1-git-send-email-jlayton-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
2012-12-18 14:10 ` [PATCH v2 1/5] cifs-utils: struct cifs_sid definition to new cifsidmap.h header Jeff Layton
2012-12-18 14:10 ` [PATCH v2 2/5] cifs-utils: new plugin architecture for ID mapping code Jeff Layton
@ 2012-12-18 14:10 ` Jeff Layton
2012-12-18 14:10 ` [PATCH v2 4/5] cifs-utils: convert cifs.idmap to use " Jeff Layton
2012-12-18 14:10 ` [PATCH v2 5/5] cifs-utils: add a manpage for idmapwb Jeff Layton
4 siblings, 0 replies; 9+ messages in thread
From: Jeff Layton @ 2012-12-18 14:10 UTC (permalink / raw)
To: linux-cifs-u79uwXL29TY76Z2rM5mHXA; +Cc: samba-technical-w/Ol4Ecudpl8XjKLYN78aQ
Add str_to_sid() functionality to the plugin API and have setcifsacl
use it.
Signed-off-by: Jeff Layton <jlayton-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
---
Makefile.am | 5 ++---
cifsidmap.h | 23 ++++++++++++++++---
idmap_plugin.c | 12 ++++++++++
idmap_plugin.h | 3 +++
idmapwb.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++++
setcifsacl.c | 70 +++++++++++++---------------------------------------------
6 files changed, 115 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 4dbeca7..bef4e93 100644
--- a/idmap_plugin.c
+++ b/idmap_plugin.c
@@ -97,3 +97,15 @@ 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)
+ 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
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH v2 4/5] cifs-utils: convert cifs.idmap to use plugin interface
[not found] ` <1355839848-24118-1-git-send-email-jlayton-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
` (2 preceding siblings ...)
2012-12-18 14:10 ` [PATCH v2 3/5] cifs-utils: convert setcifsacl to use the plugin interface Jeff Layton
@ 2012-12-18 14:10 ` Jeff Layton
2012-12-18 14:10 ` [PATCH v2 5/5] cifs-utils: add a manpage for idmapwb Jeff Layton
4 siblings, 0 replies; 9+ messages in thread
From: Jeff Layton @ 2012-12-18 14:10 UTC (permalink / raw)
To: linux-cifs-u79uwXL29TY76Z2rM5mHXA; +Cc: samba-technical-w/Ol4Ecudpl8XjKLYN78aQ
Add routines for the various things that cifs.idmap needs and have it
call them.
Signed-off-by: Jeff Layton <jlayton-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
---
Makefile.am | 5 ++--
cifs.idmap.c | 93 +++++++++++++++++++++++++---------------------------------
cifsidmap.h | 68 ++++++++++++++++++++++++++++++++++++++++--
idmap_plugin.c | 49 +++++++++++++++++++++++++++++++
idmap_plugin.h | 12 ++++++++
idmapwb.c | 64 ++++++++++++++++++++++++++++++++++++++++
6 files changed, 232 insertions(+), 59 deletions(-)
diff --git a/Makefile.am b/Makefile.am
index acace9c..8836b47 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -41,9 +41,8 @@ endif
if CONFIG_CIFSIDMAP
sbin_PROGRAMS += cifs.idmap
-cifs_idmap_SOURCES = cifs.idmap.c
-cifs_idmap_LDADD = -lkeyutils $(WBCLIENT_LIBS)
-cifs_idmap_CFLAGS = $(WBCLIENT_CFLAGS)
+cifs_idmap_SOURCES = cifs.idmap.c idmap_plugin.c
+cifs_idmap_LDADD = -lkeyutils -ldl
man_MANS += cifs.idmap.8
cifs.idmap.8: cifs.idmap.8.in
diff --git a/cifs.idmap.c b/cifs.idmap.c
index 792ea58..285d87f 100644
--- a/cifs.idmap.c
+++ b/cifs.idmap.c
@@ -40,9 +40,11 @@
#include <stdlib.h>
#include <errno.h>
#include <limits.h>
-#include <wbclient.h>
#include "cifsacl.h"
+#include "idmap_plugin.h"
+
+static void *plugin_handle;
static const char *prog = "cifs.idmap";
@@ -101,31 +103,14 @@ str_to_uint(const char *src, unsigned int *dst)
return 0;
}
-/*
- * 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
cifs_idmap(const key_serial_t key, const char *key_descr)
{
uid_t uid = 0;
gid_t gid = 0;;
- wbcErr rc = 1;
+ int rc = 1;
char *sidstr = NULL;
- struct wbcDomainSid sid;
+ struct cifs_sid sid;
/*
* Use winbind to convert received string to a SID and lookup
@@ -137,15 +122,15 @@ cifs_idmap(const key_serial_t key, const char *key_descr)
*/
sidstr = strget(key_descr, "os:");
if (sidstr) {
- rc = wbcStringToSid(sidstr, &sid);
+ rc = str_to_sid(plugin_handle, sidstr, &sid);
if (rc)
- syslog(LOG_DEBUG, "Invalid owner string: %s, rc: %d",
- key_descr, rc);
+ syslog(LOG_DEBUG, "Unable to convert owner string %s "
+ "to SID: %s", key_descr, plugin_errmsg);
else {
- rc = wbcSidToUid(&sid, &uid);
+ rc = sid_to_uid(plugin_handle, &sid, &uid);
if (rc)
- syslog(LOG_DEBUG, "SID %s to uid wbc error: %d",
- key_descr, rc);
+ syslog(LOG_DEBUG, "Unable to convert %s to "
+ "UID: %s", key_descr, plugin_errmsg);
}
if (!rc) { /* SID has been mapped to an uid */
rc = keyctl_instantiate(key, &uid, sizeof(uid_t), 0);
@@ -159,15 +144,15 @@ cifs_idmap(const key_serial_t key, const char *key_descr)
sidstr = strget(key_descr, "gs:");
if (sidstr) {
- rc = wbcStringToSid(sidstr, &sid);
+ rc = str_to_sid(plugin_handle, sidstr, &sid);
if (rc)
- syslog(LOG_DEBUG, "Invalid group string: %s, rc: %d",
- key_descr, rc);
+ syslog(LOG_DEBUG, "Unable to convert group string %s "
+ "to SID: %s", key_descr, plugin_errmsg);
else {
- rc = wbcSidToGid(&sid, &gid);
+ rc = sid_to_gid(plugin_handle, &sid, &gid);
if (rc)
- syslog(LOG_DEBUG, "SID %s to gid wbc error: %d",
- key_descr, rc);
+ syslog(LOG_DEBUG, "Unable to convert %s to "
+ "GID: %s", key_descr, plugin_errmsg);
}
if (!rc) { /* SID has been mapped to a gid */
rc = keyctl_instantiate(key, &gid, sizeof(gid_t), 0);
@@ -189,15 +174,12 @@ cifs_idmap(const key_serial_t key, const char *key_descr)
}
syslog(LOG_DEBUG, "SID: %s, uid: %u", sidstr, uid);
- rc = wbcUidToSid(uid, &sid);
- if (rc)
- syslog(LOG_DEBUG, "uid %u to SID error: %d", uid, rc);
- if (!rc) {
- struct cifs_sid csid;
-
- /* SID has been mapped to a uid */
- wsid_to_csid(&csid, &sid);
- rc = keyctl_instantiate(key, &csid,
+ rc = uid_to_sid(plugin_handle, uid, &sid);
+ if (rc) {
+ syslog(LOG_DEBUG, "uid %u to SID error: %s", uid,
+ plugin_errmsg);
+ } else {
+ rc = keyctl_instantiate(key, &sid,
sizeof(struct cifs_sid), 0);
if (rc)
syslog(LOG_ERR, "%s: key inst: %s",
@@ -217,15 +199,12 @@ cifs_idmap(const key_serial_t key, const char *key_descr)
}
syslog(LOG_DEBUG, "SID: %s, gid: %u", sidstr, gid);
- rc = wbcGidToSid(gid, &sid);
- if (rc)
- syslog(LOG_DEBUG, "gid %u to SID error: %d", gid, rc);
- if (!rc) {
- struct cifs_sid csid;
-
- /* SID has been mapped to a gid */
- wsid_to_csid(&csid, &sid);
- rc = keyctl_instantiate(key, &csid,
+ rc = gid_to_sid(plugin_handle, gid, &sid);
+ if (rc) {
+ syslog(LOG_DEBUG, "gid %u to SID error: %s", gid,
+ plugin_errmsg);
+ } else {
+ rc = keyctl_instantiate(key, &sid,
sizeof(struct cifs_sid), 0);
if (rc)
syslog(LOG_ERR, "%s: key inst: %s",
@@ -294,25 +273,33 @@ int main(const int argc, char *const argv[])
goto out;
}
+ if (init_plugin(&plugin_handle)) {
+ plugin_handle = NULL;
+ syslog(LOG_ERR, "Unable to initialize ID mapping plugin: %s",
+ plugin_errmsg);
+ goto out;
+ }
+
/* set timeout on key */
rc = keyctl_set_timeout(key, timeout);
if (rc == -1) {
syslog(LOG_ERR, "unable to set key timeout: %s",
strerror(errno));
- goto out;
+ goto out_exit_plugin;
}
rc = keyctl_describe_alloc(key, &buf);
if (rc == -1) {
syslog(LOG_ERR, "keyctl_describe_alloc failed: %s",
strerror(errno));
- rc = 1;
- goto out;
+ goto out_exit_plugin;
}
syslog(LOG_DEBUG, "key description: %s", buf);
rc = cifs_idmap(key, buf);
+out_exit_plugin:
+ exit_plugin(plugin_handle);
out:
return rc;
}
diff --git a/cifsidmap.h b/cifsidmap.h
index f82e990..c63d0da 100644
--- a/cifsidmap.h
+++ b/cifsidmap.h
@@ -34,7 +34,9 @@ struct cifs_sid {
uint32_t sub_auth[SID_MAX_SUB_AUTHORITIES];
} __attribute__((packed));
-/* Plugins should implement the following functions: */
+/*
+ * Plugins should implement the following functions:
+ */
/**
* cifs_idmap_init_plugin - Initialize the plugin interface
@@ -74,7 +76,8 @@ struct cifs_sid {
* 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.
+ * in to the init_plugin function should point to an error string. The
+ * caller will not free the error string.
*
* int cifs_idmap_sid_to_str(void *handle, const struct cifs_sid *sid,
* char **name);
@@ -90,10 +93,69 @@ struct cifs_sid {
* 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.
+ * function to an error string. The caller will not free the error string.
*
* int cifs_idmap_str_to_sid(void *handle, const char *name,
* struct cifs_sid *sid);
*/
+/**
+ * cifs_idmap_sid_to_uid - convert struct cifs_sid to uid
+ * @handle - context handle
+ * @sid - pointer to struct cifs_sid to be converted
+ * @uid - pointer to uid_t where uid should be stored
+ *
+ * This function should map a struct cifs_sid to a uid. 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. The caller will not
+ * free the error string.
+ *
+ * int cifs_idmap_sid_to_uid(void *handle, const struct cifs_sid *sid,
+ * uid_t *uid);
+ */
+
+/**
+ * cifs_idmap_sid_to_gid - convert struct cifs_sid to gid
+ * @handle - context handle
+ * @sid - pointer to struct cifs_sid to be converted
+ * @gid - pointer to gid_t where gid should be stored
+ *
+ * This function should map a struct cifs_sid to a gid. 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. The caller will not
+ * free the error string.
+ *
+ * int cifs_idmap_sid_to_uid(void *handle, const struct cifs_sid *sid,
+ * gid_t *gid);
+ */
+
+/**
+ * cifs_idmap_uid_to_sid - convert uid to struct cifs_sid
+ * @handle - context handle
+ * @uid - uid_t to be converted to a SID
+ * @sid - pointer to struct cifs_sid where result should be stored
+ *
+ * This function should map a uid to a struct cifs_sid. 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. The caller will not
+ * free the error string.
+ *
+ * int cifs_idmap_uid_to_sid(void *handle, const uid_t uid,
+ * struct cifs_sid *sid);
+ */
+
+/**
+ * cifs_idmap_gid_to_sid - convert gid to struct cifs_sid
+ * @handle - context handle
+ * @gid - gid_t to be converted to a SID
+ * @sid - pointer to struct cifs_sid where result should be stored
+ *
+ * This function should map a gid to a struct cifs_sid. 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. The caller will not
+ * free the error string.
+ *
+ * int cifs_idmap_gid_to_sid(void *handle, const gid_t gid,
+ * struct cifs_sid *sid);
+ */
#endif /* _CIFSIDMAP_H */
diff --git a/idmap_plugin.c b/idmap_plugin.c
index bef4e93..bf95aca 100644
--- a/idmap_plugin.c
+++ b/idmap_plugin.c
@@ -23,6 +23,7 @@
#include <dlfcn.h>
#include <errno.h>
#include <stdint.h>
+#include <sys/types.h>
#include "cifsacl.h"
@@ -109,3 +110,51 @@ str_to_sid(void *handle, const char *name, struct cifs_sid *sid)
return (*entry)(handle, name, sid);
}
+
+int
+sid_to_uid(void *handle, const struct cifs_sid *sid, uid_t *uid)
+{
+ int (*entry)(void *handle, const struct cifs_sid *sid, uid_t *uid);
+
+ *(void **)(&entry) = resolve_symbol("cifs_idmap_sid_to_uid");
+ if (!entry)
+ return -ENOSYS;
+
+ return (*entry)(handle, sid, uid);
+}
+
+int
+sid_to_gid(void *handle, const struct cifs_sid *sid, gid_t *gid)
+{
+ int (*entry)(void *handle, const struct cifs_sid *sid, uid_t *gid);
+
+ *(void **)(&entry) = resolve_symbol("cifs_idmap_sid_to_gid");
+ if (!entry)
+ return -ENOSYS;
+
+ return (*entry)(handle, sid, gid);
+}
+
+int
+uid_to_sid(void *handle, const uid_t uid, struct cifs_sid *sid)
+{
+ int (*entry)(void *handle, const uid_t uid, struct cifs_sid *sid);
+
+ *(void **)(&entry) = resolve_symbol("cifs_idmap_uid_to_sid");
+ if (!entry)
+ return -ENOSYS;
+
+ return (*entry)(handle, uid, sid);
+}
+
+int
+gid_to_sid(void *handle, const gid_t gid, struct cifs_sid *sid)
+{
+ int (*entry)(void *handle, const gid_t gid, struct cifs_sid *sid);
+
+ *(void **)(&entry) = resolve_symbol("cifs_idmap_gid_to_sid");
+ if (!entry)
+ return -ENOSYS;
+
+ return (*entry)(handle, gid, sid);
+}
diff --git a/idmap_plugin.h b/idmap_plugin.h
index 51e3a76..d149414 100644
--- a/idmap_plugin.h
+++ b/idmap_plugin.h
@@ -46,4 +46,16 @@ 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);
+/* Convert cifs_sid to a UID */
+extern int sid_to_uid(void *handle, const struct cifs_sid *sid, uid_t *uid);
+
+/* Convert cifs_sid to a GID */
+extern int sid_to_gid(void *handle, const struct cifs_sid *sid, gid_t *gid);
+
+/* Convert UID to cifs_sid */
+extern int uid_to_sid(void *handle, const uid_t uid, struct cifs_sid *sid);
+
+/* Convert GID to cifs_sid */
+extern int gid_to_sid(void *handle, const gid_t gid, struct cifs_sid *sid);
+
#endif /* _IDMAP_PLUGIN_H */
diff --git a/idmapwb.c b/idmapwb.c
index aa53150..8d5e3f2 100644
--- a/idmapwb.c
+++ b/idmapwb.c
@@ -160,6 +160,70 @@ convert_sid:
return 0;
}
+int
+cifs_idmap_sid_to_uid(void *handle __attribute__((unused)),
+ const struct cifs_sid *csid, uid_t *uid)
+{
+ wbcErr wbcrc;
+ struct wbcDomainSid wsid;
+
+ csid_to_wsid(&wsid, csid);
+ wbcrc = wbcSidToUid(&wsid, uid);
+ if (!WBC_ERROR_IS_OK(wbcrc)) {
+ *plugin_errmsg = wbcErrorString(wbcrc);
+ return -EIO;
+ }
+ return 0;
+}
+
+int
+cifs_idmap_sid_to_gid(void *handle __attribute__((unused)),
+ const struct cifs_sid *csid, gid_t *gid)
+{
+ wbcErr wbcrc;
+ struct wbcDomainSid wsid;
+
+ csid_to_wsid(&wsid, csid);
+ wbcrc = wbcSidToGid(&wsid, gid);
+ if (!WBC_ERROR_IS_OK(wbcrc)) {
+ *plugin_errmsg = wbcErrorString(wbcrc);
+ return -EIO;
+ }
+ return 0;
+}
+
+int
+cifs_idmap_uid_to_sid(void *handle __attribute__((unused)),
+ const uid_t uid, struct cifs_sid *csid)
+{
+ wbcErr wbcrc;
+ struct wbcDomainSid wsid;
+
+ wbcrc = wbcUidToSid(uid, &wsid);
+ if (!WBC_ERROR_IS_OK(wbcrc)) {
+ *plugin_errmsg = wbcErrorString(wbcrc);
+ return -EIO;
+ }
+ wsid_to_csid(csid, &wsid);
+ return 0;
+}
+
+int
+cifs_idmap_gid_to_sid(void *handle __attribute__((unused)),
+ const gid_t gid, struct cifs_sid *csid)
+{
+ wbcErr wbcrc;
+ struct wbcDomainSid wsid;
+
+ wbcrc = wbcGidToSid(gid, &wsid);
+ if (!WBC_ERROR_IS_OK(wbcrc)) {
+ *plugin_errmsg = wbcErrorString(wbcrc);
+ return -EIO;
+ }
+ wsid_to_csid(csid, &wsid);
+ return 0;
+}
+
/*
* For the winbind plugin, we don't need to do anything special on
* init or exit
--
1.7.11.7
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH v2 5/5] cifs-utils: add a manpage for idmapwb
[not found] ` <1355839848-24118-1-git-send-email-jlayton-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
` (3 preceding siblings ...)
2012-12-18 14:10 ` [PATCH v2 4/5] cifs-utils: convert cifs.idmap to use " Jeff Layton
@ 2012-12-18 14:10 ` Jeff Layton
4 siblings, 0 replies; 9+ messages in thread
From: Jeff Layton @ 2012-12-18 14:10 UTC (permalink / raw)
To: linux-cifs-u79uwXL29TY76Z2rM5mHXA; +Cc: samba-technical-w/Ol4Ecudpl8XjKLYN78aQ
...and clean up references to winbind in various tool manpages.
Signed-off-by: Jeff Layton <jlayton-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
---
Makefile.am | 13 +++-
cifs.idmap.8.in | 22 +++---
configure.ac | 1 +
getcifsacl.1 => getcifsacl.1.in | 5 +-
idmapwb.8.in | 148 ++++++++++++++++++++++++++++++++++++++++
idmapwb.pod | 26 +++++++
setcifsacl.1 => setcifsacl.1.in | 6 +-
7 files changed, 204 insertions(+), 17 deletions(-)
rename getcifsacl.1 => getcifsacl.1.in (87%)
create mode 100644 idmapwb.8.in
create mode 100644 idmapwb.pod
rename setcifsacl.1 => setcifsacl.1.in (91%)
diff --git a/Makefile.am b/Makefile.am
index 8836b47..0275781 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -46,7 +46,7 @@ cifs_idmap_LDADD = -lkeyutils -ldl
man_MANS += cifs.idmap.8
cifs.idmap.8: cifs.idmap.8.in
- $(SED) 's,[@]sbindir@,$(sbindir),' $(srcdir)/$@.in > $@-t && mv $@-t $@
+ $(SED) -e 's,[@]sbindir@,$(sbindir),' -e 's,[@]pluginpath@,$(pluginpath),' $(srcdir)/$@.in > $@-t && mv $@-t $@
endif
clean-local-idmap:
@@ -60,18 +60,29 @@ getcifsacl_SOURCES = getcifsacl.c idmap_plugin.c
getcifsacl_LDADD = -ldl
man_MANS += getcifsacl.1
+getcifsacl.1: getcifsacl.1.in
+ $(SED) 's,[@]pluginpath@,$(pluginpath),' $(srcdir)/$@.in > $@-t && mv $@-t $@
+
bin_PROGRAMS += setcifsacl
setcifsacl_SOURCES = setcifsacl.c idmap_plugin.c
setcifsacl_LDADD = -ldl
man_MANS += setcifsacl.1
+
+setcifsacl.1: setcifsacl.1.in
+ $(SED) 's,[@]pluginpath@,$(pluginpath),' $(srcdir)/$@.in > $@-t && mv $@-t $@
endif
if CONFIG_PLUGIN
plugindir = $(pkglibdir)
plugin_PROGRAMS = idmapwb.so
+man_MANS += idmapwb.8
idmapwb.so: idmapwb.c
$(CC) $(CFLAGS) $(AM_CFLAGS) $(WBCLIENT_CFLAGS) $(LDFLAGS) -shared -fpic -o $@ $+ $(WBCLIENT_LIBS)
+
+idmapwb.8: idmapwb.8.in
+ $(SED) 's,[@]pluginpath@,$(pluginpath),' $(srcdir)/$@.in > $@-t && mv $@-t $@
+
endif
SUBDIRS = contrib
diff --git a/cifs.idmap.8.in b/cifs.idmap.8.in
index c022402..07863ba 100644
--- a/cifs.idmap.8.in
+++ b/cifs.idmap.8.in
@@ -32,18 +32,16 @@ cifs\&.idmap is a userspace helper program for the linux CIFS client filesystem\
cifs\&.idmap is generally intended to be run when the kernel calls request\-key(8)
for a particular key type\&. While it can be run directly from the command\-line, it is not generally intended to be run that way\&.
.PP
-cifs\&.idmap works in conjuction with winbind facility of Samba suite to map owner and group SIDs to uids and gids respectively\&. It is best utilized when
-.br
-\t\- a mount option of cifsacl is specified when mounting a cifs share
-.br
-\t\- winbind is specified as one of the search entries for passwd and group databases in file /etc/nsswitch\&.conf
-.br
-\t\- file smb.conf has winbind specific entries
-.br
-\t\- winbind daemon program is running
-.br
-.sp
-In case winbind and cifs.idmap facilities are unavailable, file objects in a mounted share are assigned uid and gid of the credentials of the process that mounted the share\&. So it is strongly recomemended to use mount options of uid and gid to specify a default uid and gid to map owner SIDs and group SIDs respectively in case services of winbind and cifs.idmap facility are unavailable\&.
+This program is only called if a share is mounted with the \fBcifsacl\fR mount
+option. The kernel will only upcall to do this conversion if that mount option
+is specified.
+.PP
+cifs.idmap relies on a plugin to handle the ID mapping. If it can't find the
+plugin then it will not work properly. The plugin (or a symlink to it) must be
+at \fB@pluginpath@\fR.
+.PP
+In the case where cifs.idmap or the plugin are unavailable, file objects in a mounted share are assigned uid and gid of the credentials of the process that mounted the share\&. It is strongly recomemended to use mount options of uid and gid to specify a default uid and gid to map owner SIDs and group SIDs in this
+situation.
.SH "OPTIONS"
.PP
--help|-h
diff --git a/configure.ac b/configure.ac
index 9652ad2..09ecca4 100644
--- a/configure.ac
+++ b/configure.ac
@@ -59,6 +59,7 @@ AC_ARG_WITH(idmap-plugin,
pluginpath=$withval,
pluginpath="/etc/cifs-utils/idmap-plugin")
AC_DEFINE_UNQUOTED(IDMAP_PLUGIN_PATH, "$pluginpath", [Location of plugin that ID mapping infrastructure should use. (usually a symlink to real plugin)])
+AC_SUBST([pluginpath])
# check for ROOTSBINDIR environment var
if test -z $ROOTSBINDIR; then
diff --git a/getcifsacl.1 b/getcifsacl.1.in
similarity index 87%
rename from getcifsacl.1
rename to getcifsacl.1.in
index ef0a296..fa09dc3 100644
--- a/getcifsacl.1
+++ b/getcifsacl.1.in
@@ -27,7 +27,9 @@ getcifsacl [\-v|\-r] {file system object}
.PP
This tool is part of the cifs-utils suite\&.
.PP
-getcifsacl is a userspace helper program for the Linux CIFS client file system. It is intended to display a security descriptor including ACL for a file system object. It is best utilized when an option of cifsacl is specified when mounting a cifs share in conjunction with winbind facility of Samba suite.
+getcifsacl is a userspace helper program for the Linux CIFS client file system. It is intended to display a security descriptor including ACL for a file system object.
+.PP
+This program uses a plugin to handle the mapping of SIDs to user and group names. \fB@pluginpath@\fR should be a symlink that points to the correct plugin to use.
.PP
Fields of an ACE such as SID, type, flags, and mask are displayed separated by /. Numeric values of type, flags, and mask are displayed in hexadecimal format.
.SH "OPTIONS"
@@ -46,7 +48,6 @@ Kernel support for getcifsacl/setcifsacl utilities was initially introduced in t
.SH "SEE ALSO"
.PP
\fBmount.cifs\fR(8),
-\fBwinbindd\fR(8),
\fBsetcifsacl\fR(1)
.PP
.SH "AUTHOR"
diff --git a/idmapwb.8.in b/idmapwb.8.in
new file mode 100644
index 0000000..ef6bf03
--- /dev/null
+++ b/idmapwb.8.in
@@ -0,0 +1,148 @@
+.\" Automatically generated by Pod::Man 2.25 (Pod::Simple 3.16)
+.\"
+.\" Standard preamble:
+.\" ========================================================================
+.de Sp \" Vertical space (when we can't use .PP)
+.if t .sp .5v
+.if n .sp
+..
+.de Vb \" Begin verbatim text
+.ft CW
+.nf
+.ne \\$1
+..
+.de Ve \" End verbatim text
+.ft R
+.fi
+..
+.\" Set up some character translations and predefined strings. \*(-- will
+.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left
+.\" double quote, and \*(R" will give a right double quote. \*(C+ will
+.\" give a nicer C++. Capital omega is used to do unbreakable dashes and
+.\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff,
+.\" nothing in troff, for use with C<>.
+.tr \(*W-
+.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
+.ie n \{\
+. ds -- \(*W-
+. ds PI pi
+. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
+. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch
+. ds L" ""
+. ds R" ""
+. ds C` ""
+. ds C' ""
+'br\}
+.el\{\
+. ds -- \|\(em\|
+. ds PI \(*p
+. ds L" ``
+. ds R" ''
+'br\}
+.\"
+.\" Escape single quotes in literal strings from groff's Unicode transform.
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\"
+.\" If the F register is turned on, we'll generate index entries on stderr for
+.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index
+.\" entries marked with X<> in POD. Of course, you'll have to process the
+.\" output yourself in some meaningful fashion.
+.ie \nF \{\
+. de IX
+. tm Index:\\$1\t\\n%\t"\\$2"
+..
+. nr % 0
+. rr F
+.\}
+.el \{\
+. de IX
+..
+.\}
+.\"
+.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2).
+.\" Fear. Run. Save yourself. No user-serviceable parts.
+. \" fudge factors for nroff and troff
+.if n \{\
+. ds #H 0
+. ds #V .8m
+. ds #F .3m
+. ds #[ \f1
+. ds #] \fP
+.\}
+.if t \{\
+. ds #H ((1u-(\\\\n(.fu%2u))*.13m)
+. ds #V .6m
+. ds #F 0
+. ds #[ \&
+. ds #] \&
+.\}
+. \" simple accents for nroff and troff
+.if n \{\
+. ds ' \&
+. ds ` \&
+. ds ^ \&
+. ds , \&
+. ds ~ ~
+. ds /
+.\}
+.if t \{\
+. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u"
+. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u'
+. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u'
+. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u'
+. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u'
+. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u'
+.\}
+. \" troff and (daisy-wheel) nroff accents
+.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V'
+.ds 8 \h'\*(#H'\(*b\h'-\*(#H'
+.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#]
+.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H'
+.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u'
+.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#]
+.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#]
+.ds ae a\h'-(\w'a'u*4/10)'e
+.ds Ae A\h'-(\w'A'u*4/10)'E
+. \" corrections for vroff
+.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u'
+.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u'
+. \" for low resolution devices (crt and lpr)
+.if \n(.H>23 .if \n(.V>19 \
+\{\
+. ds : e
+. ds 8 ss
+. ds o a
+. ds d- d\h'-1'\(ga
+. ds D- D\h'-1'\(hy
+. ds th \o'bp'
+. ds Th \o'LP'
+. ds ae ae
+. ds Ae AE
+.\}
+.rm #[ #] #H #V #F C
+.\" ========================================================================
+.\"
+.IX Title "IDMAPWB 8"
+.TH IDMAPWB 8 "2012-12-17" "" ""
+.\" For nroff, turn off justification. Always turn off hyphenation; it makes
+.\" way too many mistakes in technical documents.
+.if n .ad l
+.nh
+.SH "NAME"
+idmapwb.so \- winbind ID mapping plugin for cifs\-utils
+.SH "DESCRIPTION"
+.IX Header "DESCRIPTION"
+This plugin allows the utilities in cifs-utils to work in conjuction with
+the winbind facility of Samba suite. It handles several functions including
+mapping \s-1UID\s0 and \s-1GID\s0 to SIDs and vice versa.
+.PP
+Utilities are usually configured to use the correct plugin by creating a
+symlink at \f(CW@pluginpath\fR@ that points to the correct plugin that you wish
+to use.
+.PP
+This plugin requires that \fB\f(BIwinbindd\fB\|(8)\fR be properly configured and running.
+.SH "SEE ALSO \fIgetcifsacl\fP\|(1), \fIsetcifsacl\fP\|(1), \fIcifs.idmap\fP\|(8), \fIsamba\fP\|(7), \fIsmb.conf\fP\|(5), \fIwinbindd\fP\|(8)"
+.IX Header "SEE ALSO getcifsacl, setcifsacl, cifs.idmap, samba, smb.conf, winbindd"
+.SH "AUTHOR idmapwb.so was written by Jeff Layton <jlayton-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>"
+.IX Header "AUTHOR idmapwb.so was written by Jeff Layton <jlayton-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>"
diff --git a/idmapwb.pod b/idmapwb.pod
new file mode 100644
index 0000000..4cc2b5a
--- /dev/null
+++ b/idmapwb.pod
@@ -0,0 +1,26 @@
+# turn into a manpage with the following command:
+#
+# pod2man -s 8 -c '' -r '' --stderr idmapwb.pod > idmapwb.8.in
+#
+
+=head1 NAME
+
+idmapwb.so - winbind ID mapping plugin for cifs-utils
+
+=head1 DESCRIPTION
+
+This plugin allows the utilities in cifs-utils to work in conjuction with
+the winbind facility of Samba suite. It handles several functions including
+mapping UID and GID to SIDs and vice versa.
+
+Utilities are usually configured to use the correct plugin by creating a
+symlink at @pluginpath@ that points to the correct plugin that you wish
+to use.
+
+This plugin requires that B<winbindd(8)> be properly configured and running.
+
+=head1 SEE ALSO
+getcifsacl(1), setcifsacl(1), cifs.idmap(8), samba(7), smb.conf(5), winbindd(8)
+
+=head1 AUTHOR
+idmapwb.so was written by Jeff Layton <jlayton-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
diff --git a/setcifsacl.1 b/setcifsacl.1.in
similarity index 91%
rename from setcifsacl.1
rename to setcifsacl.1.in
index 3dd755c..5ede36a 100644
--- a/setcifsacl.1
+++ b/setcifsacl.1.in
@@ -27,7 +27,10 @@ setcifsacl [\-v|\-a|\-D|\-M|\-S] "{one or more ACEs}" {file system object}
.PP
This tool is part of the cifs-utils suite\&.
.PP
-setcifsacl is a userspace helper program for the Linux CIFS client file system. It is intended to alter an ACL of a security descriptor for a file system object. It is best utilized when an option of cifsacl is specified when mounting a cifs share in conjunction with winbind facility of Samba suite. Whether a security descriptor to be set is applied or not is determined by the CIFS/SMB server.
+setcifsacl is a userspace helper program for the Linux CIFS client file system. It is intended to alter an ACL of a security descriptor for a file system object.
+Whether a security descriptor to be set is applied or not is determined by the CIFS/SMB server.
+.PP
+This program uses a plugin to handle the mapping of user and group names to SIDs. \fB@pluginpath@\fR should be a symlink that points to the correct plugin to use.
.SH "OPTIONS"
.PP
-h
@@ -99,7 +102,6 @@ Kernel support for getcifsacl/setcifsacl utilities was initially introduced in t
.SH "SEE ALSO"
.PP
\fBmount.cifs\fR(8),
-\fBwinbindd\fR(8),
\fBgetcifsacl\fR(1)
.PP
.SH "AUTHOR"
--
1.7.11.7
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH v2 2/5] cifs-utils: new plugin architecture for ID mapping code
[not found] ` <1355839848-24118-3-git-send-email-jlayton-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
@ 2012-12-18 14:20 ` Jeff Layton
0 siblings, 0 replies; 9+ messages in thread
From: Jeff Layton @ 2012-12-18 14:20 UTC (permalink / raw)
To: linux-cifs-u79uwXL29TY76Z2rM5mHXA; +Cc: samba-technical-w/Ol4Ecudpl8XjKLYN78aQ
On Tue, 18 Dec 2012 09:10:45 -0500
Jeff Layton <jlayton-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org> wrote:
> Currently, the ACL-related tools in cifs-utils call into the wbclient
> libs directly in order to do their bidding. The wbclient developers want
> to get away from needing to configure winbind on the clients and instead
> allow sssd to handle the mapping in most cases.
>
> This patch represents an initial step in that direction. It adds a
> plugin architecture for cifs-utils, adds wrappers around the calls into
> libwbclient that find an idmap plugin library to use and then has it
> call into that plugin to do the actual ID mapping.
>
> The application will call into a set of routines that find the correct
> plugin and dlopen() it. Currently the plugin is located in a well-known
> location that is settable via autoconf. That location is intended to be
> a symlink that points to the real plugin (generally under $pkglibdir).
>
> The plugin will export a number of functions with well-known names. The
> wrappers find those by using dlsym() and then call them.
>
> Signed-off-by: Jeff Layton <jlayton-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
> ---
> Makefile.am | 13 +++++--
> cifsidmap.h | 45 ++++++++++++++++++++++
> configure.ac | 9 +++++
> getcifsacl.c | 98 +++++++++++++++++++++---------------------------
> idmap_plugin.c | 99 +++++++++++++++++++++++++++++++++++++++++++++++++
> idmap_plugin.h | 46 +++++++++++++++++++++++
> idmapwb.c | 115 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> 7 files changed, 367 insertions(+), 58 deletions(-)
> create mode 100644 idmap_plugin.c
> create mode 100644 idmap_plugin.h
> create mode 100644 idmapwb.c
>
> diff --git a/Makefile.am b/Makefile.am
> index 8964b37..bc5e517 100644
> --- a/Makefile.am
> +++ b/Makefile.am
> @@ -57,9 +57,8 @@ endif
>
> if CONFIG_CIFSACL
> bin_PROGRAMS += getcifsacl
> -getcifsacl_SOURCES = getcifsacl.c
> -getcifsacl_LDADD = $(WBCLIENT_LIBS)
> -getcifsacl_CFLAGS = $(WBCLIENT_CFLAGS)
> +getcifsacl_SOURCES = getcifsacl.c idmap_plugin.c
> +getcifsacl_LDADD = -ldl
> man_MANS += getcifsacl.1
>
> bin_PROGRAMS += setcifsacl
> @@ -69,4 +68,12 @@ setcifsacl_CFLAGS = $(WBCLIENT_CFLAGS)
> man_MANS += setcifsacl.1
> endif
>
> +if CONFIG_PLUGIN
> +plugindir = $(pkglibdir)
> +plugin_PROGRAMS = idmapwb.so
> +
> +idmapwb.so: idmapwb.c
> + $(CC) $(CFLAGS) $(AM_CFLAGS) $(WBCLIENT_CFLAGS) $(LDFLAGS) -shared -fpic -o $@ $+ $(WBCLIENT_LIBS)
> +endif
> +
> SUBDIRS = contrib
> diff --git a/cifsidmap.h b/cifsidmap.h
> index 9907618..c307333 100644
> --- a/cifsidmap.h
> +++ b/cifsidmap.h
> @@ -34,4 +34,49 @@ struct cifs_sid {
> uint32_t sub_auth[SID_MAX_SUB_AUTHORITIES];
> } __attribute__((packed));
>
> +/* Plugins should implement the following functions: */
> +
> +/**
> + * cifs_idmap_init_plugin - Initialize the plugin interface
> + * @handle - return pointer for an opaque handle
> + * @errmsg - pointer to error message pointer
> + *
> + * This function should do whatever is required to establish a context
> + * for later ID mapping operations. The "handle" is an opaque context
> + * cookie that will be passed in on subsequent ID mapping operations.
> + * The errmsg is used to pass back an error string both during the init
> + * and in subsequent idmapping functions. On any error, the plugin
> + * should point *errmsg at a string describing that error. Returns 0
> + * on success and non-zero on error.
> + *
> + * int cifs_idmap_init_plugin(void **handle, const char **errmsg);
> + */
> +
> +/**
> + * cifs_idmap_exit_plugin - Destroy an idmapping context
> + * @handle - context handle that should be destroyed
> + *
> + * When programs are finished with the idmapping plugin, they'll call
> + * this function to destroy any context that was created during the
> + * init_plugin. The handle passed back in was the one given by the init
> + * routine.
> + *
> + * void cifs_idmap_exit_plugin(void *handle);
> + */
> +
> +/**
> + * cifs_idmap_sid_to_str - convert cifs_sid to a string
> + * @handle - context handle
> + * @sid - pointer to a 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.
> + *
> + * int cifs_idmap_sid_to_str(void *handle, const struct cifs_sid *sid,
> + * char **name);
> + */
> +
> #endif /* _CIFSIDMAP_H */
> diff --git a/configure.ac b/configure.ac
> index b6791ab..9652ad2 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -52,6 +52,14 @@ AC_ARG_ENABLE(systemd,
> enable_systemd=$enableval,
> enable_systemd="maybe")
>
> +# "with" options
> +AC_ARG_WITH(idmap-plugin,
> + [AC_HELP_STRING([--with-idmap-plugin=/path/to/plugin],
> + [Define the path to the plugin that the idmapping infrastructure should use @<:@default=/etc/cifs-utils/idmap-plugin@:>@])],
> + pluginpath=$withval,
> + pluginpath="/etc/cifs-utils/idmap-plugin")
> +AC_DEFINE_UNQUOTED(IDMAP_PLUGIN_PATH, "$pluginpath", [Location of plugin that ID mapping infrastructure should use. (usually a symlink to real plugin)])
> +
> # check for ROOTSBINDIR environment var
> if test -z $ROOTSBINDIR; then
> ROOTSBINDIR="/sbin"
> @@ -230,6 +238,7 @@ AM_CONDITIONAL(CONFIG_CIFSUPCALL, [test "$enable_cifsupcall" != "no"])
> AM_CONDITIONAL(CONFIG_CIFSCREDS, [test "$enable_cifscreds" != "no"])
> AM_CONDITIONAL(CONFIG_CIFSIDMAP, [test "$enable_cifsidmap" != "no"])
> AM_CONDITIONAL(CONFIG_CIFSACL, [test "$enable_cifsacl" != "no"])
> +AM_CONDITIONAL(CONFIG_PLUGIN, [test "$enable_cifsidmap" != "no" -o "$enable_cifsacl" != "no"])
>
> LIBCAP_NG_PATH
>
> diff --git a/getcifsacl.c b/getcifsacl.c
> index 550429c..c0b051d 100644
> --- a/getcifsacl.c
> +++ b/getcifsacl.c
> @@ -33,10 +33,13 @@
> #include <stddef.h>
> #include <errno.h>
> #include <limits.h>
> -#include <wbclient.h>
> #include <ctype.h>
> #include <sys/xattr.h>
> #include "cifsacl.h"
> +#include "idmap_plugin.h"
> +
> +static void *plugin_handle;
> +static bool plugin_loaded;
>
> static void
> print_each_ace_mask(uint32_t mask)
> @@ -169,61 +172,33 @@ print_ace_type(uint8_t acetype, int raw)
> }
> }
>
> -/*
> - * Winbind keeps wbcDomainSid fields in host-endian. Copy fields from the
> - * csid to the wsid, while converting the subauthority fields from LE.
> - */
> static void
> -csid_to_wsid(struct wbcDomainSid *wsid, const struct cifs_sid *csid)
> +print_sid(struct cifs_sid *csid, int raw)
> {
> - int i;
> - uint8_t num_subauth = (csid->num_subauth <= WBC_MAXSUBAUTHS) ?
> - csid->num_subauth : WBC_MAXSUBAUTHS;
> -
> - wsid->sid_rev_num = csid->revision;
> - wsid->num_auths = num_subauth;
> - for (i = 0; i < NUM_AUTHS; i++)
> - wsid->id_auth[i] = csid->authority[i];
> - for (i = 0; i < num_subauth; i++)
> - wsid->sub_auths[i] = le32toh(csid->sub_auth[i]);
> -}
> -
> -static void
> -print_sid(struct cifs_sid *sidptr, int raw)
> -{
> - int i;
> - wbcErr rc;
> - char *domain_name = NULL;
> - char *sidname = NULL;
> - enum wbcSidType sntype;
> + int i, rc;
> + char *name;
> unsigned long long id_auth_val;
> - struct wbcDomainSid wsid;
>
> - csid_to_wsid(&wsid, sidptr);
> + if (raw || !plugin_loaded)
> + goto print_sid_raw;
>
> - if (raw)
> + rc = sid_to_str(plugin_handle, csid, &name);
> + if (rc)
> goto print_sid_raw;
>
> - rc = wbcLookupSid(&wsid, &domain_name, &sidname, &sntype);
> - if (WBC_ERROR_IS_OK(rc)) {
> - printf("%s", domain_name);
> - if (strlen(domain_name))
> - printf("%c", '\\');
> - printf("%s", sidname);
> - wbcFreeMemory(domain_name);
> - wbcFreeMemory(sidname);
> - return;
> - }
> + printf("%s", name);
> + free(name);
> + return;
>
> print_sid_raw:
> - printf("S-%hhu", wsid.sid_rev_num);
> + printf("S-%hhu", csid->revision);
>
> - id_auth_val = (unsigned long long)wsid.id_auth[5];
> - id_auth_val += (unsigned long long)wsid.id_auth[4] << 8;
> - id_auth_val += (unsigned long long)wsid.id_auth[3] << 16;
> - id_auth_val += (unsigned long long)wsid.id_auth[2] << 24;
> - id_auth_val += (unsigned long long)wsid.id_auth[1] << 32;
> - id_auth_val += (unsigned long long)wsid.id_auth[0] << 48;
> + id_auth_val = (unsigned long long)csid->authority[5];
> + id_auth_val += (unsigned long long)csid->authority[4] << 8;
> + id_auth_val += (unsigned long long)csid->authority[3] << 16;
> + id_auth_val += (unsigned long long)csid->authority[2] << 24;
> + id_auth_val += (unsigned long long)csid->authority[1] << 32;
> + id_auth_val += (unsigned long long)csid->authority[0] << 48;
>
> /*
> * MS-DTYP states that if the authority is >= 2^32, then it should be
> @@ -234,8 +209,8 @@ print_sid_raw:
> else
> printf("-0x%llx", id_auth_val);
>
> - for (i = 0; i < wsid.num_auths; i++)
> - printf("-%u", wsid.sub_auths[i]);
> + for (i = 0; i < csid->num_subauth; i++)
> + printf("-%u", csid->sub_auth[i]);
^^^^^^^^^^^
Hah, found a bug already. We need to convert the endianness of
csid->sub_auth[i] before printing it. Now fixed in my private tree, but
I'm not going to bother to resend unless there are larger changes
needed.
> }
>
> static void
> @@ -368,7 +343,8 @@ getcifsacl_usage(const char *prog)
> int
> main(const int argc, char *const argv[])
> {
> - int c, raw = 0;
> + int c, ret = 0;
> + bool raw = false;
> ssize_t attrlen;
> size_t bufsize = BUFSIZE;
> char *filename, *attrval;
> @@ -379,7 +355,7 @@ main(const int argc, char *const argv[])
> printf("Version: %s\n", VERSION);
> goto out;
> case 'r':
> - raw = 1;
> + raw = true;
> break;
> default:
> break;
> @@ -392,20 +368,31 @@ main(const int argc, char *const argv[])
> filename = argv[1];
> else {
> getcifsacl_usage(basename(argv[0]));
> - return 0;
> + goto out;
> + }
> +
> + if (!raw && !plugin_loaded) {
> + ret = init_plugin(&plugin_handle);
> + if (ret)
> + printf("WARNING: unable to initialize idmapping plugin: %s\n",
> + plugin_errmsg);
> + else
> + plugin_loaded = true;
> }
>
> cifsacl:
> if (bufsize >= XATTR_SIZE_MAX) {
> printf("buffer to allocate exceeds max size of %d\n",
> XATTR_SIZE_MAX);
> - return -1;
> + ret = -1;
> + goto out;
> }
>
> attrval = malloc(bufsize * sizeof(char));
> if (!attrval) {
> printf("error allocating memory for attribute value buffer\n");
> - return -1;
> + ret = -1;
> + goto out;
> }
>
> attrlen = getxattr(filename, ATTRNAME, attrval, bufsize);
> @@ -421,7 +408,8 @@ cifsacl:
> parse_sec_desc((struct cifs_ntsd *)attrval, attrlen, raw);
>
> free(attrval);
> -
> out:
> - return 0;
> + if (plugin_loaded)
> + exit_plugin(plugin_handle);
> + return ret;
> }
> diff --git a/idmap_plugin.c b/idmap_plugin.c
> new file mode 100644
> index 0000000..4dbeca7
> --- /dev/null
> +++ b/idmap_plugin.c
> @@ -0,0 +1,99 @@
> +/*
> + * ID Mapping Plugin interface for cifs-utils
> + * Copyright (C) 2012 Jeff Layton (jlayton-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org)
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 3 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program. If not, see <http://www.gnu.org/licenses/>.
> + */
> +
> +#ifdef HAVE_CONFIG_H
> +#include "config.h"
> +#endif /* HAVE_CONFIG_H */
> +
> +#include <dlfcn.h>
> +#include <errno.h>
> +#include <stdint.h>
> +
> +#include "cifsacl.h"
> +
> +const char *plugin_errmsg;
> +static void *plugin;
> +
> +static void *
> +resolve_symbol(const char *symbol_name)
> +{
> + void *symbol;
> +
> + dlerror();
> + symbol = dlsym(plugin, symbol_name);
> + if (!symbol)
> + plugin_errmsg = dlerror();
> + return symbol;
> +}
> +
> +/*
> + * open the plugin. Note that we leave it open over the life of the
> + * program. It gets closed on exit.
> + */
> +static int
> +open_plugin(void)
> +{
> + if (plugin)
> + return 0;
> +
> + plugin = dlopen(IDMAP_PLUGIN_PATH, RTLD_LAZY);
> + if (!plugin) {
> + plugin_errmsg = dlerror();
> + return -EIO;
> + }
> +
> + return 0;
> +}
> +
> +int
> +init_plugin(void **handle)
> +{
> + int ret;
> + int (*init)(void **, const char **);
> +
> + ret = open_plugin();
> + if (ret)
> + return ret;
> +
> + init = resolve_symbol("cifs_idmap_init_plugin");
> + if (!init)
> + return -ENOSYS;
> + return (*init)(handle, &plugin_errmsg);
> +}
> +
> +void
> +exit_plugin(void *handle)
> +{
> + int (*exit)(void *);
> +
> + exit = resolve_symbol("cifs_idmap_exit_plugin");
> + if (exit)
> + (*exit)(handle);
> +}
> +
> +int
> +sid_to_str(void *handle, const struct cifs_sid *sid, char **name)
> +{
> + int (*entry)(void *, const struct cifs_sid *, char **);
> +
> + *(void **)(&entry) = resolve_symbol("cifs_idmap_sid_to_str");
> + if (!entry)
> + return -ENOSYS;
> +
> + return (*entry)(handle, sid, name);
> +}
> diff --git a/idmap_plugin.h b/idmap_plugin.h
> new file mode 100644
> index 0000000..277bb12
> --- /dev/null
> +++ b/idmap_plugin.h
> @@ -0,0 +1,46 @@
> +/*
> + * ID Mapping Plugin interface for cifs-utils
> + * Copyright (C) 2012 Jeff Layton (jlayton-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org)
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 3 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program. If not, see <http://www.gnu.org/licenses/>.
> + */
> +
> +#include "cifsidmap.h"
> +
> +#ifndef _IDMAP_PLUGIN_H
> +#define _IDMAP_PLUGIN_H
> +
> +/*
> + * On error, plugin functions will set this pointer to a string description
> + * of the error. The string should not be freed.
> + */
> +extern const char *plugin_errmsg;
> +
> +/*
> + * External API. Programs should call this to use the plugin functionality.
> + */
> +
> +/*
> + * Initialize plugin. Returns an opaque handle that should be passed to
> + * other idmapping functions.
> + */
> +extern int init_plugin(void **handle);
> +
> +/* Close out an init'ed handle */
> +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);
> +
> +#endif /* _IDMAP_PLUGIN_H */
> diff --git a/idmapwb.c b/idmapwb.c
> new file mode 100644
> index 0000000..858028f
> --- /dev/null
> +++ b/idmapwb.c
> @@ -0,0 +1,115 @@
> +/*
> + * Winbind ID Mapping Plugin
> + * Copyright (C) 2012 Jeff Layton (jlayton-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org)
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 3 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program. If not, see <http://www.gnu.org/licenses/>.
> + */
> +
> +#ifdef HAVE_CONFIG_H
> +#include "config.h"
> +#endif /* HAVE_CONFIG_H */
> +
> +#include <stdint.h>
> +#include <endian.h>
> +#include <string.h>
> +#include <errno.h>
> +#include <stdbool.h>
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <wbclient.h>
> +
> +#include "cifsidmap.h"
> +
> +static const char **plugin_errmsg;
> +
> +/*
> + * Winbind keeps wbcDomainSid fields in host-endian. Copy fields from the
> + * csid to the wsid, while converting the subauthority fields from LE.
> + */
> +static void
> +csid_to_wsid(struct wbcDomainSid *wsid, const struct cifs_sid *csid)
> +{
> + int i;
> + uint8_t num_subauth = (csid->num_subauth <= WBC_MAXSUBAUTHS) ?
> + csid->num_subauth : WBC_MAXSUBAUTHS;
> +
> + wsid->sid_rev_num = csid->revision;
> + wsid->num_auths = num_subauth;
> + for (i = 0; i < NUM_AUTHS; i++)
> + wsid->id_auth[i] = csid->authority[i];
> + for (i = 0; i < num_subauth; i++)
> + wsid->sub_auths[i] = le32toh(csid->sub_auth[i]);
> +}
> +
> +int
> +cifs_idmap_sid_to_str(void *handle __attribute__ ((unused)),
> + const struct cifs_sid *csid, char **string)
> +{
> + int rc;
> + wbcErr wbcrc;
> + char *domain = NULL;
> + char *name = NULL;
> + enum wbcSidType sntype;
> + struct wbcDomainSid wsid;
> + size_t len;
> +
> + csid_to_wsid(&wsid, csid);
> +
> + wbcrc = wbcLookupSid(&wsid, &domain, &name, &sntype);
> + if (!WBC_ERROR_IS_OK(wbcrc)) {
> + *plugin_errmsg = wbcErrorString(wbcrc);
> + return -EIO;
> + }
> +
> + /* +1 for '\\' and +1 for NULL terminator */
> + len = strlen(domain) + 1 + strlen(name) + 1;
> +
> + *string = malloc(len);
> + if (!*string) {
> + *plugin_errmsg = "Unable to allocate memory";
> + rc = -ENOMEM;
> + goto out;
> + }
> +
> + rc = snprintf(*string, len, "%s\\%s", domain, name);
> + if (rc >= (long)len) {
> + free(*string);
> + *plugin_errmsg = "Resulting string was truncated";
> + *string = NULL;
> + rc = -EIO;
> + } else {
> + rc = 0;
> + }
> +out:
> + wbcFreeMemory(domain);
> + wbcFreeMemory(name);
> + return rc;
> +}
> +
> +/*
> + * For the winbind plugin, we don't need to do anything special on
> + * init or exit
> + */
> +int
> +cifs_idmap_init_plugin(void **handle __attribute__((unused)), const char **errmsg)
> +{
> + plugin_errmsg = errmsg;
> + return 0;
> +}
> +
> +void
> +cifs_idmap_exit_plugin(void *handle __attribute__((unused)))
> +{
> + return;
> +}
--
Jeff Layton <jlayton-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v2 0/5] cifs-utils: plugin interface for SID to UID/GID mapping
2012-12-18 14:10 [PATCH v2 0/5] cifs-utils: plugin interface for SID to UID/GID mapping Jeff Layton
[not found] ` <1355839848-24118-1-git-send-email-jlayton-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
@ 2012-12-18 14:45 ` Stefan (metze) Metzmacher
[not found] ` <50D0817D.5040508-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
1 sibling, 1 reply; 9+ messages in thread
From: Stefan (metze) Metzmacher @ 2012-12-18 14:45 UTC (permalink / raw)
To: Jeff Layton; +Cc: linux-cifs, samba-technical
[-- Attachment #1: Type: text/plain, Size: 2535 bytes --]
Hi Jeff,
I didn't look at the whole patchset in detail, but I think
such a new API should support IDMAP_BOTH, which means that
a sid can resolve into a uid and a gid at the same time.
This is very important as it allows groups to own files
e.g. BUILTIN\Administrators is likely to be the owner of a lot
of files. And it's the only way to support the 'sIDHistory' for users.
metze
> This is the second official posting for the plugin interface. Major
> changes since the last set are:
>
> 1/ There's a header file now that plugin implementers are expected to use
>
> 2/ New manpage for idmapwb.so and cleanups to the existing manpages to
> discuss plugin configuration
>
> 3/ Better handling for the plugin_errmsg variable. A pointer to the
> pointer is passed into the init_plugin routine, which allows the
> setting of it in the context.
>
> With this, I think I'm pretty close to something mergeable, but
> comments and review are still appreciated.
>
> Jeff Layton (5):
> cifs-utils: struct cifs_sid definition to new cifsidmap.h header
> cifs-utils: new plugin architecture for ID mapping code
> cifs-utils: convert setcifsacl to use the plugin interface
> cifs-utils: convert cifs.idmap to use plugin interface
> cifs-utils: add a manpage for idmapwb
>
> Makefile.am | 37 ++++--
> cifs.idmap.8.in | 22 ++--
> cifs.idmap.c | 93 +++++++--------
> cifsacl.h | 12 +-
> cifsidmap.h | 161 ++++++++++++++++++++++++++
> configure.ac | 10 ++
> getcifsacl.1 => getcifsacl.1.in | 5 +-
> getcifsacl.c | 98 +++++++---------
> idmap_plugin.c | 160 ++++++++++++++++++++++++++
> idmap_plugin.h | 61 ++++++++++
> idmapwb.8.in | 148 ++++++++++++++++++++++++
> idmapwb.c | 242 ++++++++++++++++++++++++++++++++++++++++
> idmapwb.pod | 26 +++++
> setcifsacl.1 => setcifsacl.1.in | 6 +-
> setcifsacl.c | 70 +++---------
> 15 files changed, 952 insertions(+), 199 deletions(-)
> create mode 100644 cifsidmap.h
> rename getcifsacl.1 => getcifsacl.1.in (87%)
> create mode 100644 idmap_plugin.c
> create mode 100644 idmap_plugin.h
> create mode 100644 idmapwb.8.in
> create mode 100644 idmapwb.c
> create mode 100644 idmapwb.pod
> rename setcifsacl.1 => setcifsacl.1.in (91%)
>
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 261 bytes --]
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v2 0/5] cifs-utils: plugin interface for SID to UID/GID mapping
[not found] ` <50D0817D.5040508-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
@ 2012-12-18 15:04 ` Jeff Layton
0 siblings, 0 replies; 9+ messages in thread
From: Jeff Layton @ 2012-12-18 15:04 UTC (permalink / raw)
To: Stefan (metze) Metzmacher
Cc: linux-cifs-u79uwXL29TY76Z2rM5mHXA,
samba-technical-w/Ol4Ecudpl8XjKLYN78aQ
[-- Attachment #1: Type: text/plain, Size: 994 bytes --]
On Tue, 18 Dec 2012 15:45:17 +0100
"Stefan (metze) Metzmacher" <metze-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org> wrote:
> Hi Jeff,
>
> I didn't look at the whole patchset in detail, but I think
> such a new API should support IDMAP_BOTH, which means that
> a sid can resolve into a uid and a gid at the same time.
>
> This is very important as it allows groups to own files
> e.g. BUILTIN\Administrators is likely to be the owner of a lot
> of files. And it's the only way to support the 'sIDHistory' for users.
>
> metze
>
I'm not sure I understand how that would work. The situation is often
going to be something like this:
"The kernel has an ACL that it has fetched from the server. That ACL
has a SIDs in it that are designated as the user and group owner. The
goal is to turn those into the st_uid and st_gid values as presented by
stat()."
So...how does IDMAP_BOTH come into play here?
--
Jeff Layton <jlayton-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2012-12-18 15:04 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-12-18 14:10 [PATCH v2 0/5] cifs-utils: plugin interface for SID to UID/GID mapping Jeff Layton
[not found] ` <1355839848-24118-1-git-send-email-jlayton-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
2012-12-18 14:10 ` [PATCH v2 1/5] cifs-utils: struct cifs_sid definition to new cifsidmap.h header Jeff Layton
2012-12-18 14:10 ` [PATCH v2 2/5] cifs-utils: new plugin architecture for ID mapping code Jeff Layton
[not found] ` <1355839848-24118-3-git-send-email-jlayton-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
2012-12-18 14:20 ` Jeff Layton
2012-12-18 14:10 ` [PATCH v2 3/5] cifs-utils: convert setcifsacl to use the plugin interface Jeff Layton
2012-12-18 14:10 ` [PATCH v2 4/5] cifs-utils: convert cifs.idmap to use " Jeff Layton
2012-12-18 14:10 ` [PATCH v2 5/5] cifs-utils: add a manpage for idmapwb Jeff Layton
2012-12-18 14:45 ` [PATCH v2 0/5] cifs-utils: plugin interface for SID to UID/GID mapping Stefan (metze) Metzmacher
[not found] ` <50D0817D.5040508-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
2012-12-18 15:04 ` Jeff Layton
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.