From: Steve Dickson <SteveD@redhat.com>
To: Jiri Horky <jiri.horky@gmail.com>
Cc: linux-nfs@vger.kernel.org, du@cesnet.cz
Subject: Re: [PATCH] libnfsidmap: implementation of client side Static translation method.
Date: Wed, 01 Aug 2012 13:56:00 -0400 [thread overview]
Message-ID: <50196DB0.7090405@RedHat.com> (raw)
In-Reply-To: <1343028020-10587-1-git-send-email-jiri.horky@gmail.com>
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,
> };
next prev parent reply other threads:[~2012-08-01 18:40 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-07-23 7:20 [PATCH] libnfsidmap: implementation of client side Static translation method Jiri Horky
2012-08-01 17:56 ` Steve Dickson [this message]
-- strict thread matches above, loose matches on Subject: below --
2012-07-22 20:33 Jiri Horky
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=50196DB0.7090405@RedHat.com \
--to=steved@redhat.com \
--cc=du@cesnet.cz \
--cc=jiri.horky@gmail.com \
--cc=linux-nfs@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).