linux-nfs.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] libnfsidmap: implementation of client side Static translation method
@ 2012-07-22 20:33 Jiri Horky
  0 siblings, 0 replies; 3+ messages in thread
From: Jiri Horky @ 2012-07-22 20:33 UTC (permalink / raw)
  To: linux-nfs; +Cc: Steve Dickson, du@cesnet.cz

[-- Attachment #1: Type: text/plain, Size: 270 bytes --]

Implementation of client side Static translation method in libnfsidmap. 
Since the [Static] section in idmapd.conf does not distinguish between 
user and group mappings we try both cases for each defined mapping. The 
code caches id->name mappings in the init function.

[-- Attachment #2: libnfsidmap.static.client.patch --]
[-- Type: text/plain, Size: 6879 bytes --]

diff --git a/static.c b/static.c
index fffd458..8be87e8 100644
--- a/static.c
+++ b/static.c
@@ -40,6 +40,7 @@
 #include <grp.h>
 #include <errno.h>
 
+#include "queue.h"
 #include "cfg.h"
 #include "nfsidmap.h"
 #include "nfsidmap_internal.h"
@@ -57,6 +58,40 @@ struct pwbuf {
 	char buf[1];
 };
 
+struct grbuf {
+	struct group grbuf;
+	char buf[1];
+};
+
+struct uid_mapping {
+	LIST_ENTRY (uid_mapping) link;
+	uid_t uid;
+	char * principal;
+	char * localname;
+};
+
+struct gid_mapping {
+	LIST_ENTRY (gid_mapping) link;
+	gid_t gid;
+	char * principal;
+	char * localgroup;
+};
+
+static __inline__ u_int8_t uid_hash (uid_t uid)
+{
+	return uid % 256;
+}
+
+static __inline__ u_int8_t gid_hash (gid_t gid)
+{
+	return gid % 256;
+}
+
+//Hash tables of uid and guids to principals mappings.
+//We reuse some queue/hash functions from cfg.c.
+LIST_HEAD (uid_mappings, uid_mapping) uid_mappings[256];
+LIST_HEAD (gid_mappings, gid_mapping) gid_mappings[256];
+
 static struct passwd *static_getpwnam(const char *name, const char *domain,
 				      int *err_p)
 {
@@ -75,12 +110,9 @@ static struct passwd *static_getpwnam(const char *name, const char *domain,
 	localname = conf_get_str("Static", (char *)name);
 	if (!localname) {
 		err = ENOENT;
-		goto err;
+		goto err_free_buf;
 	}
 
-	IDMAP_LOG(4, ("static_getpwnam: name '%s' mapped to '%s'\n",
-		  name, localname));
-
 again:
 	err = getpwnam_r(localname, &buf->pwbuf, buf->buf, buflen, &pw);
 
@@ -91,12 +123,15 @@ again:
 		if (err == 0)
 			err = ENOENT;
 
-		IDMAP_LOG(0, ("static_getpwnam: name '%s' not found\n",
-			  localname));
+		IDMAP_LOG(0, ("static_getpwnam: localname '%s' for '%s' not found\n",
+		  localname, name));
 
 		goto err_free_buf;
 	}
 
+	IDMAP_LOG(4, ("static_getpwnam: name '%s' mapped to '%s'\n",
+		  name, localname));
+
 	*err_p = 0;
 	return pw;
 
@@ -107,6 +142,56 @@ err:
 	return NULL;
 }
 
+static struct group *static_getgrnam(const char *name, const char *domain,
+				      int *err_p)
+{
+	struct group *gr;
+	struct grbuf *buf;
+	size_t buflen = sysconf(_SC_GETGR_R_SIZE_MAX);
+	char *localgroup;
+	int err;
+
+	buf = malloc(sizeof(*buf) + buflen);
+	if (!buf) {
+		err = ENOMEM;
+		goto err;
+	}
+
+	localgroup = conf_get_str("Static", (char *)name);
+	if (!localgroup) {
+		err = ENOENT;
+		goto err_free_buf;
+	}
+
+again:
+	err = getgrnam_r(localgroup, &buf->grbuf, buf->buf, buflen, &gr);
+
+	if (err == EINTR)
+		goto again;
+
+	if (!gr) {
+		if (err == 0)
+			err = ENOENT;
+
+		IDMAP_LOG(0, ("static_getgrnam: local group '%s' for '%s' not found\n",
+			  localgroup, name));
+
+		goto err_free_buf;
+	}
+
+	IDMAP_LOG(4, ("static_getgrnam: group '%s' mapped to '%s'\n",
+		  name, localgroup));
+
+	*err_p = 0;
+	return gr;
+
+err_free_buf:
+	free(buf);
+err:
+	*err_p = err;
+	return NULL;
+}
+
 static int static_gss_princ_to_ids(char *secname, char *princ,
 				   uid_t *uid, uid_t *gid,
 				   extra_mapping_params **ex)
@@ -151,14 +236,173 @@ static int static_gss_princ_to_grouplist(char *secname, char *princ,
 	return -err;
 }
 
+static int static_name_to_uid(char *name, uid_t *uid)
+{
+	struct passwd *pw;
+	int err;
+
+	pw = static_getpwnam(name, NULL, &err);
+
+	if (pw) {
+		*uid = pw->pw_uid;
+		free(pw);
+	}
+
+	return -err;
+}
+
+static int static_name_to_gid(char *name, gid_t *gid)
+{
+	struct group *gr;
+	int err;
+
+	gr = static_getgrnam(name, NULL, &err);
+
+	if (gr) {
+		*gid = gr->gr_gid;
+		free(gr);
+	}
+
+	return -err;
+}
+
+static int static_uid_to_name(uid_t uid, char *domain, char *name, size_t len)
+{
+	struct passwd *pw;
+	struct uid_mapping * um;
+
+	for (um = LIST_FIRST (&uid_mappings[uid_hash (uid)]); um;
+		um = LIST_NEXT (um, link)) {
+		if (um->uid == uid) {
+			strcpy(name, um->principal);
+			return 0;
+		}
+	}
+
+	return -ENOENT;
+}
+
+static int static_gid_to_name(gid_t gid, char *domain, char *name, size_t len)
+{
+	struct group *gr;
+	struct gid_mapping * gm;
+
+	for (gm = LIST_FIRST (&gid_mappings[gid_hash (gid)]); gm;
+		gm = LIST_NEXT (gm, link)) {
+		if (gm->gid == gid) {
+			strcpy(name, gm->principal);
+			return 0;
+		}
+	}
+
+	return -ENOENT;
+}
+
+/*
+ * We buffer all UID's for which static mappings is defined in advance, so the
+ * uid_to_name functions will be fast enough.
+ */
+
+static int static_init() {	
+	int err;
+	uid_t uid;
+	struct conf_list * princ_list = NULL;
+	struct conf_list_node * cln, *next;
+	struct uid_mapping * unode;
+	struct gid_mapping * gnode;
+	struct passwd * pw = NULL;
+	struct group * gr = NULL;
+	unsigned int i;
+
+	//init hash_table first
+	for (i = 0; i < sizeof uid_mappings / sizeof uid_mappings[0]; i++)
+		LIST_INIT (&uid_mappings[i]);
+
+	//get all principals for which we have mappings
+	princ_list = conf_get_tag_list("Static");
+
+	if (!princ_list) {
+		return -ENOENT;
+	}
+
+	/* As we can not distinguish between mappings for users and groups, we try to
+	 * resolve all mappings for both cases.
+	 */
+
+	//resolve uid of localname account for all such principals and cache it
+	for (cln = TAILQ_FIRST (&princ_list->fields); cln; cln = next) 
+	{ 
+		next = TAILQ_NEXT (cln, link); 
+
+		pw = static_getpwnam(cln->field, NULL, &err);
+		if (!pw) {
+			continue;
+		}
+		
+		unode = calloc (1, sizeof *unode);
+		if (!unode)
+		{
+			warnx("static_init: calloc (1, %lu) failed",
+				(unsigned long)sizeof *unode);
+			free(pw);
+			return -ENOMEM;
+		}
+		unode->uid = pw->pw_uid;
+		unode->principal = strdup(cln->field);
+
+		unode->localname = conf_get_str("Static", cln->field);
+		if (!unode->localname) {
+			free(pw);
+			return -ENOENT;
+		}
+
+		free(pw);
+
+		LIST_INSERT_HEAD (&uid_mappings[uid_hash(unode->uid)], unode, link);
+	}
+
+	//resolve gid of localgroup accounts and cache it
+	for (cln = TAILQ_FIRST (&princ_list->fields); cln; cln = next) 
+	{ 
+		next = TAILQ_NEXT (cln, link); 
+
+		gr = static_getgrnam(cln->field, NULL, &err);
+		if (!pw) {
+			continue;
+		}
+		
+		gnode = calloc (1, sizeof *gnode);
+		if (!gnode)
+		{
+			warnx("static_init: calloc (1, %lu) failed",
+				(unsigned long)sizeof *gnode);
+			free(pw);
+			return -ENOMEM;
+		}
+		gnode->gid = pw->pw_uid;
+		gnode->principal = strdup(cln->field);
+
+		gnode->localgroup = conf_get_str("Static", cln->field);
+		if (!gnode->localgroup) {
+			free(pw);
+			return -ENOENT;
+		}
+
+		free(pw);
+
+		LIST_INSERT_HEAD (&gid_mappings[gid_hash(gnode->gid)], gnode, link);
+	}
+	return 0;
+}
+
 
 struct trans_func static_trans = {
 	.name			= "static",
-	.init			= NULL,
-	.name_to_uid		= NULL,
-	.name_to_gid		= NULL,
-	.uid_to_name		= NULL,
-	.gid_to_name		= NULL,
+	.init			= static_init,
+	.name_to_uid		= static_name_to_uid,
+	.name_to_gid		= static_name_to_gid,
+	.uid_to_name		= static_uid_to_name,
+	.gid_to_name		= static_gid_to_name,
 	.princ_to_ids		= static_gss_princ_to_ids,
 	.gss_princ_to_grouplist	= static_gss_princ_to_grouplist,
 };

^ permalink raw reply related	[flat|nested] 3+ messages in thread

* [PATCH] libnfsidmap: implementation of client side Static translation method.
@ 2012-07-23  7:20 Jiri Horky
  2012-08-01 17:56 ` Steve Dickson
  0 siblings, 1 reply; 3+ messages in thread
From: Jiri Horky @ 2012-07-23  7:20 UTC (permalink / raw)
  To: linux-nfs, linux-nfs; +Cc: du, Jiri Horky, SteveD

Since the [Static] section in idmapd.conf does not distinguish between user
and group mappings we try both cases for each defined mapping. The code caches
id->name mappings in the init function

Signed-off-by: Jiri Horky <jiri.horky@gmail.com>
---
 static.c |  266 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
 1 files changed, 255 insertions(+), 11 deletions(-)

diff --git a/static.c b/static.c
index fffd458..8be87e8 100644
--- a/static.c
+++ b/static.c
@@ -40,6 +40,7 @@
 #include <grp.h>
 #include <errno.h>
 
+#include "queue.h"
 #include "cfg.h"
 #include "nfsidmap.h"
 #include "nfsidmap_internal.h"
@@ -57,6 +58,40 @@ struct pwbuf {
 	char buf[1];
 };
 
+struct grbuf {
+	struct group grbuf;
+	char buf[1];
+};
+
+struct uid_mapping {
+	LIST_ENTRY (uid_mapping) link;
+	uid_t uid;
+	char * principal;
+	char * localname;
+};
+
+struct gid_mapping {
+	LIST_ENTRY (gid_mapping) link;
+	gid_t gid;
+	char * principal;
+	char * localgroup;
+};
+
+static __inline__ u_int8_t uid_hash (uid_t uid)
+{
+	return uid % 256;
+}
+
+static __inline__ u_int8_t gid_hash (gid_t gid)
+{
+	return gid % 256;
+}
+
+//Hash tables of uid and guids to principals mappings.
+//We reuse some queue/hash functions from cfg.c.
+LIST_HEAD (uid_mappings, uid_mapping) uid_mappings[256];
+LIST_HEAD (gid_mappings, gid_mapping) gid_mappings[256];
+
 static struct passwd *static_getpwnam(const char *name, const char *domain,
 				      int *err_p)
 {
@@ -75,12 +110,9 @@ static struct passwd *static_getpwnam(const char *name, const char *domain,
 	localname = conf_get_str("Static", (char *)name);
 	if (!localname) {
 		err = ENOENT;
-		goto err;
+		goto err_free_buf;
 	}
 
-	IDMAP_LOG(4, ("static_getpwnam: name '%s' mapped to '%s'\n",
-		  name, localname));
-
 again:
 	err = getpwnam_r(localname, &buf->pwbuf, buf->buf, buflen, &pw);
 
@@ -91,12 +123,15 @@ again:
 		if (err == 0)
 			err = ENOENT;
 
-		IDMAP_LOG(0, ("static_getpwnam: name '%s' not found\n",
-			  localname));
+		IDMAP_LOG(0, ("static_getpwnam: localname '%s' for '%s' not found\n",
+		  localname, name));
 
 		goto err_free_buf;
 	}
 
+	IDMAP_LOG(4, ("static_getpwnam: name '%s' mapped to '%s'\n",
+		  name, localname));
+
 	*err_p = 0;
 	return pw;
 
@@ -107,6 +142,56 @@ err:
 	return NULL;
 }
 
+static struct group *static_getgrnam(const char *name, const char *domain,
+				      int *err_p)
+{
+	struct group *gr;
+	struct grbuf *buf;
+	size_t buflen = sysconf(_SC_GETGR_R_SIZE_MAX);
+	char *localgroup;
+	int err;
+
+	buf = malloc(sizeof(*buf) + buflen);
+	if (!buf) {
+		err = ENOMEM;
+		goto err;
+	}
+
+	localgroup = conf_get_str("Static", (char *)name);
+	if (!localgroup) {
+		err = ENOENT;
+		goto err_free_buf;
+	}
+
+again:
+	err = getgrnam_r(localgroup, &buf->grbuf, buf->buf, buflen, &gr);
+
+	if (err == EINTR)
+		goto again;
+
+	if (!gr) {
+		if (err == 0)
+			err = ENOENT;
+
+		IDMAP_LOG(0, ("static_getgrnam: local group '%s' for '%s' not found\n",
+			  localgroup, name));
+
+		goto err_free_buf;
+	}
+
+	IDMAP_LOG(4, ("static_getgrnam: group '%s' mapped to '%s'\n",
+		  name, localgroup));
+
+	*err_p = 0;
+	return gr;
+
+err_free_buf:
+	free(buf);
+err:
+	*err_p = err;
+	return NULL;
+}
+
 static int static_gss_princ_to_ids(char *secname, char *princ,
 				   uid_t *uid, uid_t *gid,
 				   extra_mapping_params **ex)
@@ -151,14 +236,173 @@ static int static_gss_princ_to_grouplist(char *secname, char *princ,
 	return -err;
 }
 
+static int static_name_to_uid(char *name, uid_t *uid)
+{
+	struct passwd *pw;
+	int err;
+
+	pw = static_getpwnam(name, NULL, &err);
+
+	if (pw) {
+		*uid = pw->pw_uid;
+		free(pw);
+	}
+
+	return -err;
+}
+
+static int static_name_to_gid(char *name, gid_t *gid)
+{
+	struct group *gr;
+	int err;
+
+	gr = static_getgrnam(name, NULL, &err);
+
+	if (gr) {
+		*gid = gr->gr_gid;
+		free(gr);
+	}
+
+	return -err;
+}
+
+static int static_uid_to_name(uid_t uid, char *domain, char *name, size_t len)
+{
+	struct passwd *pw;
+	struct uid_mapping * um;
+
+	for (um = LIST_FIRST (&uid_mappings[uid_hash (uid)]); um;
+		um = LIST_NEXT (um, link)) {
+		if (um->uid == uid) {
+			strcpy(name, um->principal);
+			return 0;
+		}
+	}
+
+	return -ENOENT;
+}
+
+static int static_gid_to_name(gid_t gid, char *domain, char *name, size_t len)
+{
+	struct group *gr;
+	struct gid_mapping * gm;
+
+	for (gm = LIST_FIRST (&gid_mappings[gid_hash (gid)]); gm;
+		gm = LIST_NEXT (gm, link)) {
+		if (gm->gid == gid) {
+			strcpy(name, gm->principal);
+			return 0;
+		}
+	}
+
+	return -ENOENT;
+}
+
+/*
+ * We buffer all UID's for which static mappings is defined in advance, so the
+ * uid_to_name functions will be fast enough.
+ */
+
+static int static_init() {	
+	int err;
+	uid_t uid;
+	struct conf_list * princ_list = NULL;
+	struct conf_list_node * cln, *next;
+	struct uid_mapping * unode;
+	struct gid_mapping * gnode;
+	struct passwd * pw = NULL;
+	struct group * gr = NULL;
+	unsigned int i;
+
+	//init hash_table first
+	for (i = 0; i < sizeof uid_mappings / sizeof uid_mappings[0]; i++)
+		LIST_INIT (&uid_mappings[i]);
+
+	//get all principals for which we have mappings
+	princ_list = conf_get_tag_list("Static");
+
+	if (!princ_list) {
+		return -ENOENT;
+	}
+
+	/* As we can not distinguish between mappings for users and groups, we try to
+	 * resolve all mappings for both cases.
+	 */
+
+	//resolve uid of localname account for all such principals and cache it
+	for (cln = TAILQ_FIRST (&princ_list->fields); cln; cln = next) 
+	{ 
+		next = TAILQ_NEXT (cln, link); 
+
+		pw = static_getpwnam(cln->field, NULL, &err);
+		if (!pw) {
+			continue;
+		}
+		
+		unode = calloc (1, sizeof *unode);
+		if (!unode)
+		{
+			warnx("static_init: calloc (1, %lu) failed",
+				(unsigned long)sizeof *unode);
+			free(pw);
+			return -ENOMEM;
+		}
+		unode->uid = pw->pw_uid;
+		unode->principal = strdup(cln->field);
+
+		unode->localname = conf_get_str("Static", cln->field);
+		if (!unode->localname) {
+			free(pw);
+			return -ENOENT;
+		}
+
+		free(pw);
+
+		LIST_INSERT_HEAD (&uid_mappings[uid_hash(unode->uid)], unode, link);
+	}
+
+	//resolve gid of localgroup accounts and cache it
+	for (cln = TAILQ_FIRST (&princ_list->fields); cln; cln = next) 
+	{ 
+		next = TAILQ_NEXT (cln, link); 
+
+		gr = static_getgrnam(cln->field, NULL, &err);
+		if (!pw) {
+			continue;
+		}
+		
+		gnode = calloc (1, sizeof *gnode);
+		if (!gnode)
+		{
+			warnx("static_init: calloc (1, %lu) failed",
+				(unsigned long)sizeof *gnode);
+			free(pw);
+			return -ENOMEM;
+		}
+		gnode->gid = pw->pw_uid;
+		gnode->principal = strdup(cln->field);
+
+		gnode->localgroup = conf_get_str("Static", cln->field);
+		if (!gnode->localgroup) {
+			free(pw);
+			return -ENOENT;
+		}
+
+		free(pw);
+
+		LIST_INSERT_HEAD (&gid_mappings[gid_hash(gnode->gid)], gnode, link);
+	}
+	return 0;
+}
+
 
 struct trans_func static_trans = {
 	.name			= "static",
-	.init			= NULL,
-	.name_to_uid		= NULL,
-	.name_to_gid		= NULL,
-	.uid_to_name		= NULL,
-	.gid_to_name		= NULL,
+	.init			= static_init,
+	.name_to_uid		= static_name_to_uid,
+	.name_to_gid		= static_name_to_gid,
+	.uid_to_name		= static_uid_to_name,
+	.gid_to_name		= static_gid_to_name,
 	.princ_to_ids		= static_gss_princ_to_ids,
 	.gss_princ_to_grouplist	= static_gss_princ_to_grouplist,
 };
-- 
1.7.3.4


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH] libnfsidmap: implementation of client side Static translation method.
  2012-07-23  7:20 [PATCH] libnfsidmap: implementation of client side Static translation method Jiri Horky
@ 2012-08-01 17:56 ` Steve Dickson
  0 siblings, 0 replies; 3+ messages in thread
From: Steve Dickson @ 2012-08-01 17:56 UTC (permalink / raw)
  To: Jiri Horky; +Cc: linux-nfs, du



On 07/23/2012 03:20 AM, Jiri Horky wrote:
> Since the [Static] section in idmapd.conf does not distinguish between user
> and group mappings we try both cases for each defined mapping. The code caches
> id->name mappings in the init function
> 
> Signed-off-by: Jiri Horky <jiri.horky@gmail.com>
Committed... My apologizes on taking so long to get this done....

steved.

> ---
>  static.c |  266 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
>  1 files changed, 255 insertions(+), 11 deletions(-)
> 
> diff --git a/static.c b/static.c
> index fffd458..8be87e8 100644
> --- a/static.c
> +++ b/static.c
> @@ -40,6 +40,7 @@
>  #include <grp.h>
>  #include <errno.h>
>  
> +#include "queue.h"
>  #include "cfg.h"
>  #include "nfsidmap.h"
>  #include "nfsidmap_internal.h"
> @@ -57,6 +58,40 @@ struct pwbuf {
>  	char buf[1];
>  };
>  
> +struct grbuf {
> +	struct group grbuf;
> +	char buf[1];
> +};
> +
> +struct uid_mapping {
> +	LIST_ENTRY (uid_mapping) link;
> +	uid_t uid;
> +	char * principal;
> +	char * localname;
> +};
> +
> +struct gid_mapping {
> +	LIST_ENTRY (gid_mapping) link;
> +	gid_t gid;
> +	char * principal;
> +	char * localgroup;
> +};
> +
> +static __inline__ u_int8_t uid_hash (uid_t uid)
> +{
> +	return uid % 256;
> +}
> +
> +static __inline__ u_int8_t gid_hash (gid_t gid)
> +{
> +	return gid % 256;
> +}
> +
> +//Hash tables of uid and guids to principals mappings.
> +//We reuse some queue/hash functions from cfg.c.
> +LIST_HEAD (uid_mappings, uid_mapping) uid_mappings[256];
> +LIST_HEAD (gid_mappings, gid_mapping) gid_mappings[256];
> +
>  static struct passwd *static_getpwnam(const char *name, const char *domain,
>  				      int *err_p)
>  {
> @@ -75,12 +110,9 @@ static struct passwd *static_getpwnam(const char *name, const char *domain,
>  	localname = conf_get_str("Static", (char *)name);
>  	if (!localname) {
>  		err = ENOENT;
> -		goto err;
> +		goto err_free_buf;
>  	}
>  
> -	IDMAP_LOG(4, ("static_getpwnam: name '%s' mapped to '%s'\n",
> -		  name, localname));
> -
>  again:
>  	err = getpwnam_r(localname, &buf->pwbuf, buf->buf, buflen, &pw);
>  
> @@ -91,12 +123,15 @@ again:
>  		if (err == 0)
>  			err = ENOENT;
>  
> -		IDMAP_LOG(0, ("static_getpwnam: name '%s' not found\n",
> -			  localname));
> +		IDMAP_LOG(0, ("static_getpwnam: localname '%s' for '%s' not found\n",
> +		  localname, name));
>  
>  		goto err_free_buf;
>  	}
>  
> +	IDMAP_LOG(4, ("static_getpwnam: name '%s' mapped to '%s'\n",
> +		  name, localname));
> +
>  	*err_p = 0;
>  	return pw;
>  
> @@ -107,6 +142,56 @@ err:
>  	return NULL;
>  }
>  
> +static struct group *static_getgrnam(const char *name, const char *domain,
> +				      int *err_p)
> +{
> +	struct group *gr;
> +	struct grbuf *buf;
> +	size_t buflen = sysconf(_SC_GETGR_R_SIZE_MAX);
> +	char *localgroup;
> +	int err;
> +
> +	buf = malloc(sizeof(*buf) + buflen);
> +	if (!buf) {
> +		err = ENOMEM;
> +		goto err;
> +	}
> +
> +	localgroup = conf_get_str("Static", (char *)name);
> +	if (!localgroup) {
> +		err = ENOENT;
> +		goto err_free_buf;
> +	}
> +
> +again:
> +	err = getgrnam_r(localgroup, &buf->grbuf, buf->buf, buflen, &gr);
> +
> +	if (err == EINTR)
> +		goto again;
> +
> +	if (!gr) {
> +		if (err == 0)
> +			err = ENOENT;
> +
> +		IDMAP_LOG(0, ("static_getgrnam: local group '%s' for '%s' not found\n",
> +			  localgroup, name));
> +
> +		goto err_free_buf;
> +	}
> +
> +	IDMAP_LOG(4, ("static_getgrnam: group '%s' mapped to '%s'\n",
> +		  name, localgroup));
> +
> +	*err_p = 0;
> +	return gr;
> +
> +err_free_buf:
> +	free(buf);
> +err:
> +	*err_p = err;
> +	return NULL;
> +}
> +
>  static int static_gss_princ_to_ids(char *secname, char *princ,
>  				   uid_t *uid, uid_t *gid,
>  				   extra_mapping_params **ex)
> @@ -151,14 +236,173 @@ static int static_gss_princ_to_grouplist(char *secname, char *princ,
>  	return -err;
>  }
>  
> +static int static_name_to_uid(char *name, uid_t *uid)
> +{
> +	struct passwd *pw;
> +	int err;
> +
> +	pw = static_getpwnam(name, NULL, &err);
> +
> +	if (pw) {
> +		*uid = pw->pw_uid;
> +		free(pw);
> +	}
> +
> +	return -err;
> +}
> +
> +static int static_name_to_gid(char *name, gid_t *gid)
> +{
> +	struct group *gr;
> +	int err;
> +
> +	gr = static_getgrnam(name, NULL, &err);
> +
> +	if (gr) {
> +		*gid = gr->gr_gid;
> +		free(gr);
> +	}
> +
> +	return -err;
> +}
> +
> +static int static_uid_to_name(uid_t uid, char *domain, char *name, size_t len)
> +{
> +	struct passwd *pw;
> +	struct uid_mapping * um;
> +
> +	for (um = LIST_FIRST (&uid_mappings[uid_hash (uid)]); um;
> +		um = LIST_NEXT (um, link)) {
> +		if (um->uid == uid) {
> +			strcpy(name, um->principal);
> +			return 0;
> +		}
> +	}
> +
> +	return -ENOENT;
> +}
> +
> +static int static_gid_to_name(gid_t gid, char *domain, char *name, size_t len)
> +{
> +	struct group *gr;
> +	struct gid_mapping * gm;
> +
> +	for (gm = LIST_FIRST (&gid_mappings[gid_hash (gid)]); gm;
> +		gm = LIST_NEXT (gm, link)) {
> +		if (gm->gid == gid) {
> +			strcpy(name, gm->principal);
> +			return 0;
> +		}
> +	}
> +
> +	return -ENOENT;
> +}
> +
> +/*
> + * We buffer all UID's for which static mappings is defined in advance, so the
> + * uid_to_name functions will be fast enough.
> + */
> +
> +static int static_init() {	
> +	int err;
> +	uid_t uid;
> +	struct conf_list * princ_list = NULL;
> +	struct conf_list_node * cln, *next;
> +	struct uid_mapping * unode;
> +	struct gid_mapping * gnode;
> +	struct passwd * pw = NULL;
> +	struct group * gr = NULL;
> +	unsigned int i;
> +
> +	//init hash_table first
> +	for (i = 0; i < sizeof uid_mappings / sizeof uid_mappings[0]; i++)
> +		LIST_INIT (&uid_mappings[i]);
> +
> +	//get all principals for which we have mappings
> +	princ_list = conf_get_tag_list("Static");
> +
> +	if (!princ_list) {
> +		return -ENOENT;
> +	}
> +
> +	/* As we can not distinguish between mappings for users and groups, we try to
> +	 * resolve all mappings for both cases.
> +	 */
> +
> +	//resolve uid of localname account for all such principals and cache it
> +	for (cln = TAILQ_FIRST (&princ_list->fields); cln; cln = next) 
> +	{ 
> +		next = TAILQ_NEXT (cln, link); 
> +
> +		pw = static_getpwnam(cln->field, NULL, &err);
> +		if (!pw) {
> +			continue;
> +		}
> +		
> +		unode = calloc (1, sizeof *unode);
> +		if (!unode)
> +		{
> +			warnx("static_init: calloc (1, %lu) failed",
> +				(unsigned long)sizeof *unode);
> +			free(pw);
> +			return -ENOMEM;
> +		}
> +		unode->uid = pw->pw_uid;
> +		unode->principal = strdup(cln->field);
> +
> +		unode->localname = conf_get_str("Static", cln->field);
> +		if (!unode->localname) {
> +			free(pw);
> +			return -ENOENT;
> +		}
> +
> +		free(pw);
> +
> +		LIST_INSERT_HEAD (&uid_mappings[uid_hash(unode->uid)], unode, link);
> +	}
> +
> +	//resolve gid of localgroup accounts and cache it
> +	for (cln = TAILQ_FIRST (&princ_list->fields); cln; cln = next) 
> +	{ 
> +		next = TAILQ_NEXT (cln, link); 
> +
> +		gr = static_getgrnam(cln->field, NULL, &err);
> +		if (!pw) {
> +			continue;
> +		}
> +		
> +		gnode = calloc (1, sizeof *gnode);
> +		if (!gnode)
> +		{
> +			warnx("static_init: calloc (1, %lu) failed",
> +				(unsigned long)sizeof *gnode);
> +			free(pw);
> +			return -ENOMEM;
> +		}
> +		gnode->gid = pw->pw_uid;
> +		gnode->principal = strdup(cln->field);
> +
> +		gnode->localgroup = conf_get_str("Static", cln->field);
> +		if (!gnode->localgroup) {
> +			free(pw);
> +			return -ENOENT;
> +		}
> +
> +		free(pw);
> +
> +		LIST_INSERT_HEAD (&gid_mappings[gid_hash(gnode->gid)], gnode, link);
> +	}
> +	return 0;
> +}
> +
>  
>  struct trans_func static_trans = {
>  	.name			= "static",
> -	.init			= NULL,
> -	.name_to_uid		= NULL,
> -	.name_to_gid		= NULL,
> -	.uid_to_name		= NULL,
> -	.gid_to_name		= NULL,
> +	.init			= static_init,
> +	.name_to_uid		= static_name_to_uid,
> +	.name_to_gid		= static_name_to_gid,
> +	.uid_to_name		= static_uid_to_name,
> +	.gid_to_name		= static_gid_to_name,
>  	.princ_to_ids		= static_gss_princ_to_ids,
>  	.gss_princ_to_grouplist	= static_gss_princ_to_grouplist,
>  };

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2012-08-01 18:40 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-07-23  7:20 [PATCH] libnfsidmap: implementation of client side Static translation method Jiri Horky
2012-08-01 17:56 ` Steve Dickson
  -- strict thread matches above, loose matches on Subject: below --
2012-07-22 20:33 Jiri Horky

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).