Skip to content
Snippets Groups Projects
Select Git revision
  • acd59b65608989d4996a2f275cb1e91e3c65df2d
  • master default protected
  • rednatco-v2
  • rednatco
  • test
  • ntc-tube-uniform-color
  • ntc-tube-missing-atoms
  • restore-vertex-array-per-program
  • watlas2
  • dnatco_new
  • cleanup-old-nodejs
  • webmmb
  • fix_auth_seq_id
  • update_deps
  • ext_dev
  • ntc_balls
  • nci-2
  • plugin
  • bugfix-0.4.5
  • nci
  • servers
  • v0.5.0-dev.1
  • v0.4.5
  • v0.4.4
  • v0.4.3
  • v0.4.2
  • v0.4.1
  • v0.4.0
  • v0.3.12
  • v0.3.11
  • v0.3.10
  • v0.3.9
  • v0.3.8
  • v0.3.7
  • v0.3.6
  • v0.3.5
  • v0.3.4
  • v0.3.3
  • v0.3.2
  • v0.3.1
  • v0.3.0
41 results

sequence.ts

Blame
  • 20-DU-static-translation.patch 7.06 KiB
    Author: Jiri Horky <jiri.horky@cesnet.cz>
    Date: Mon, 23 Jul 2012 09:20:20 +0200
    Description: implementation of client side Static translation method
     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
    
    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,
     };