On Mon, Sep 01, 2014 at 05:19:46PM +0200, Jakub Hrozek wrote:
> On Fri, Jun 27, 2014 at 09:44:34AM +0300, Noam Meltzer wrote:
> > Follow patches are the code implementing design document:
> > https://fedorahosted.org/sssd/wiki/DesignDocs/rpc.idmapd%20plugin
> > 
> > Changes compared to v2 of this patch:
> >  * rebase over rev. 8ca18752 (current master)
> >  * remove man pages from the patch (will be sent separately)
> >  * add new contact details for plugin author
> >  * code style
> >  * remove sss_nfs_make_request() wrapper
> >  * fix typo in reply_to_name(): REPLY_ID_OFFSET -> REPLY_NAME_OFFSET
> > 
> > Noam Meltzer (4):
> >   NEW CLIENT: plugin for NFSv4 rpc.idmapd
> >   NFSv4 client: (private) headers from libnfsidmap
> >   NFSv4 client: add to build system
> >   NFSv4 client: add to RPM spec
> > 
> >  Makefile.am                            |  24 ++
> >  configure.ac                           |  10 +
> >  contrib/sssd.spec.in                   |   7 +
> >  src/conf_macros.m4                     |  30 ++
> >  src/external/libnfsidmap.m4            |  17 +
> >  src/sss_client/nfs/nfsidmap_internal.h |  78 +++++
> >  src/sss_client/nfs/sss_nfs_client.c    | 571 
> > +++++++++++++++++++++++++++++++++
> >  7 files changed, 737 insertions(+)
> >  create mode 100644 src/external/libnfsidmap.m4
> >  create mode 100644 src/sss_client/nfs/nfsidmap_internal.h
> >  create mode 100644 src/sss_client/nfs/sss_nfs_client.c
> 
> Hi,
> 
> I asked Roland Mainz (CC-ed) to help us review the patches. Some of the
> discussion happened off-list, but I think the final ACK should be given
> on the list..

It just occured to me I should attach the final version of patches that
we discussed -- there were some minor changes (such as option renaming
and renaming of the plugin) that happened in my fedorapeople branch.
>From c10768162a4a893317b9f02c4b88aa2abe188358 Mon Sep 17 00:00:00 2001
From: Noam Meltzer <tsn...@gmail.com>
Date: Fri, 27 Jun 2014 05:44:35 +0000
Subject: [PATCH 1/4] NEW CLIENT: plugin for NFSv4 rpc.idmapd

Implementation of design document:
https://fedorahosted.org/sssd/wiki/DesignDocs/rpc.idmapd%20plugin
---
 src/sss_client/nfs/sss_nfs_client.c | 571 ++++++++++++++++++++++++++++++++++++
 1 file changed, 571 insertions(+)
 create mode 100644 src/sss_client/nfs/sss_nfs_client.c

diff --git a/src/sss_client/nfs/sss_nfs_client.c 
b/src/sss_client/nfs/sss_nfs_client.c
new file mode 100644
index 
0000000000000000000000000000000000000000..64cb67a8b75ec04c1d6fa03905f5427bbe6c1e82
--- /dev/null
+++ b/src/sss_client/nfs/sss_nfs_client.c
@@ -0,0 +1,571 @@
+/*
+   SSSD
+
+   NFS Client
+
+   Copyright (C) Noam Meltzer <n...@primarydata.com>    2013-2014
+   Copyright (C) Noam Meltzer <tsn...@gmail.com>        2014-
+
+   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/>.
+*/
+
+#define _GNU_SOURCE
+
+#include <stddef.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <errno.h>
+#include <string.h>
+
+#include <nfsidmap.h>
+#include "nfsidmap_internal.h"
+
+#include "sss_client/sss_cli.h"
+#include "sss_client/nss_mc.h"
+
+
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+#define PLUGIN_NAME                 "sss_nfs"
+#define CONF_SECTION                "sss_nfs"
+#define CONF_USE_MC                 "memcache"
+#define REPLY_ID_OFFSET             (8)
+#define REPLY_NAME_OFFSET           (REPLY_ID_OFFSET + 8)
+#define BUF_LEN                     (4096)
+#define USE_MC_DEFAULT              true
+
+
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+static char sss_nfs_plugin_name[]   = PLUGIN_NAME;
+static char nfs_conf_sect[]         = CONF_SECTION;
+static char nfs_conf_use_mc[]       = CONF_USE_MC;
+
+static bool nfs_use_mc              = USE_MC_DEFAULT;
+
+
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+/* Forward declarations */
+static int send_recv(uint8_t **repp, size_t *rep_lenp, enum sss_cli_command 
cmd,
+                     const void *req, size_t req_len);
+static int reply_to_id(id_t *idp, uint8_t *rep, size_t rep_len);
+static int reply_to_name(char *name, size_t len, uint8_t *rep, size_t rep_len);
+
+
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+/* get from memcache functions */
+static int get_uid_from_mc(id_t *uid, const char *name)
+{
+    int rc = 0;
+    struct passwd pwd;
+    char *buf = NULL;
+    char *p = NULL;
+    size_t buflen = 0;
+    size_t len = 0;
+
+    if (!nfs_use_mc) {
+        return -1;
+    }
+
+    sss_strnlen(name, SSS_NAME_MAX, &len);
+
+    do {
+        buflen += BUF_LEN;
+        if ((p = realloc(buf, buflen)) == NULL) {
+            rc = ENOMEM;
+            goto done;
+        }
+        buf = p;
+        rc = sss_nss_mc_getpwnam(name, len, &pwd, buf, buflen);
+    } while (rc == ERANGE);
+
+    if (rc == 0) {
+        IDMAP_LOG(1, ("found user %s in memcache", name));
+        *uid = pwd.pw_uid;
+    } else {
+        IDMAP_LOG(1, ("user %s not in memcache", name));
+    }
+
+done:
+    free(buf);
+    return rc;
+}
+
+static int get_gid_from_mc(id_t *gid, const char *name)
+{
+    int rc = 0;
+    struct group grp;
+    char *buf = NULL;
+    char *p = NULL;
+    size_t buflen = 0;
+    size_t len;
+
+    if (!nfs_use_mc) {
+        return -1;
+    }
+
+    sss_strnlen(name, SSS_NAME_MAX, &len);
+
+    do {
+        buflen += BUF_LEN;
+        if ((p = realloc(buf, buflen)) == NULL) {
+            rc = ENOMEM;
+            goto done;
+        }
+        buf = p;
+        rc = sss_nss_mc_getgrnam(name, len, &grp, buf, buflen);
+    } while (rc == ERANGE);
+
+    if (rc == 0) {
+        IDMAP_LOG(1, ("found group %s in memcache", name));
+        *gid = grp.gr_gid;
+    } else {
+        IDMAP_LOG(1, ("group %s not in memcache", name));
+    }
+
+done:
+    free(buf);
+    return rc;
+}
+
+static int get_user_from_mc(char *name, size_t len, uid_t uid)
+{
+    int rc;
+    struct passwd pwd;
+    char *buf = NULL;
+    char *p = NULL;
+    size_t buflen = 0;
+    size_t pw_name_len;
+
+    if (!nfs_use_mc) {
+        return -1;
+    }
+
+    do {
+        buflen += BUF_LEN;
+        if ((p = realloc(buf, buflen)) == NULL) {
+            rc = ENOMEM;
+            goto done;
+        }
+        buf = p;
+        rc = sss_nss_mc_getpwuid(uid, &pwd, buf, BUF_LEN);
+    } while (rc == ERANGE);
+
+    if (rc == 0) {
+        pw_name_len = strlen(pwd.pw_name) + 1;
+        if (pw_name_len > len) {
+            IDMAP_LOG(0, ("%s: reply too long; pw_name_len=%lu, len=%lu",
+                          __func__, pw_name_len, len));
+            rc = ENOBUFS;
+        }
+        IDMAP_LOG(1, ("found uid %i in memcache", uid));
+        memcpy(name, pwd.pw_name, pw_name_len);
+    } else {
+        IDMAP_LOG(1, ("uid %i not in memcache", uid));
+    }
+
+done:
+    free(buf);
+    return rc;
+}
+
+static int get_group_from_mc(char *name, size_t len, id_t gid)
+{
+    int rc;
+    struct group grp;
+    char *buf = NULL;
+    char *p = NULL;
+    size_t buflen = 0;
+    size_t gr_name_len;
+
+    if (!nfs_use_mc) {
+        return -1;
+    }
+
+    do {
+        buflen += BUF_LEN;
+        if ((p = realloc(buf, buflen)) == NULL) {
+            rc = ENOMEM;
+            goto done;
+        }
+        buf = p;
+        rc = sss_nss_mc_getgrgid(gid, &grp, buf, BUF_LEN);
+    } while (rc == ERANGE);
+
+    if (rc == 0) {
+        gr_name_len = strlen(grp.gr_name) + 1;
+        if (gr_name_len > len) {
+            IDMAP_LOG(0, ("%s: reply too long; gr_name_len=%lu, len=%lu",
+                          __func__, gr_name_len, len));
+            rc = ENOBUFS;
+        }
+        IDMAP_LOG(1, ("found gid %i in memcache", gid));
+        memcpy(name, grp.gr_name, gr_name_len);
+    } else {
+        IDMAP_LOG(1, ("gid %i not in memcache", gid));
+    }
+
+done:
+    free(buf);
+    return rc;
+}
+
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+static int name_to_id(const char *name, id_t *id, enum sss_cli_command cmd)
+{
+    int rc;
+    uint8_t *rep = NULL;
+    size_t rep_len = 0;
+    size_t name_len;
+
+    sss_strnlen(name, SSS_NAME_MAX, &name_len);
+
+    rc = send_recv(&rep, &rep_len, cmd, name, name_len + 1);
+    if (rc == 0) {
+        rc = reply_to_id(id, rep, rep_len);
+    }
+
+    free(rep);
+
+    return rc;
+}
+
+static int id_to_name(char *name, size_t len, id_t id,
+                      enum sss_cli_command cmd)
+{
+    int rc;
+    size_t rep_len = 0;
+    size_t req_len = sizeof(id_t);
+    uint8_t *rep = NULL;
+    uint8_t req[req_len];
+
+    memcpy(req, &id, req_len);
+    rc = send_recv(&rep, &rep_len, cmd, &req, req_len);
+    if (rc == 0) {
+        rc = reply_to_name(name, len, rep, rep_len);
+    }
+
+    free(rep);
+
+    return rc;
+}
+
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+static int send_recv(uint8_t **rep, size_t *rep_len, enum sss_cli_command cmd,
+                     const void *req, size_t req_len)
+{
+    int err = 0;
+    enum nss_status req_rc;
+    struct sss_cli_req_data rd;
+
+    rd.data = req;
+    rd.len = req_len;
+
+    sss_nss_lock();
+    req_rc = sss_nss_make_request(cmd, &rd, rep, rep_len, &err);
+    sss_nss_unlock();
+
+    if (req_rc == NSS_STATUS_NOTFOUND) {
+        return ENOENT;
+    }
+    if (req_rc != NSS_STATUS_SUCCESS) {
+        IDMAP_LOG(0, ("no-make-request; err=%i", err));
+        return EPIPE;
+    }
+
+    return 0;
+}
+
+static int reply_to_id(id_t *idp, uint8_t *rep, size_t rep_len)
+{
+    int rc = 0;
+    id_t id;
+    uint32_t num_results = 0;
+
+    if (rep_len < sizeof(uint32_t)) {
+        IDMAP_LOG(0, ("%s: reply too small; rep_len=%lu", __func__, rep_len));
+        rc = EBADMSG;
+        goto done;
+    }
+
+    SAFEALIGN_COPY_UINT32(&num_results, rep, NULL);
+    if (num_results > 1) {
+        IDMAP_LOG(0, ("%s: too many results (%lu)", __func__, num_results));
+        rc = EBADMSG;
+        goto done;
+    }
+    if (num_results == 0) {
+        rc = ENOENT;
+        goto done;
+    }
+    if (rep_len < sizeof(uint32_t) + REPLY_ID_OFFSET) {
+        IDMAP_LOG(0, ("%s: reply too small(2); rep_len=%lu", __func__,
+                      rep_len));
+        rc = EBADMSG;
+        goto done;
+    }
+
+    SAFEALIGN_COPY_UINT32(&id, rep + REPLY_ID_OFFSET, NULL);
+    *idp = id;
+
+done:
+    return rc;
+}
+
+static int reply_to_name(char *name, size_t len, uint8_t *rep, size_t rep_len)
+{
+    int rc = 0;
+    uint32_t num_results = 0;
+    const char *buf;
+    size_t buf_len;
+    size_t offset;
+
+    if (rep_len < sizeof(uint32_t)) {
+        IDMAP_LOG(0, ("%s: reply too small; rep_len=%lu", __func__, rep_len));
+        rc = EBADMSG;
+        goto done;
+    }
+
+    SAFEALIGN_COPY_UINT32(&num_results, rep, NULL);
+    if (num_results > 1) {
+        IDMAP_LOG(0, ("%s: too many results (%lu)", __func__, num_results));
+        rc = EBADMSG;
+        goto done;
+    }
+    if (num_results == 0) {
+        rc = ENOENT;
+        goto done;
+    }
+    if (rep_len < sizeof(uint32_t) + REPLY_NAME_OFFSET) {
+        IDMAP_LOG(0, ("%s: reply too small(2); rep_len=%lu", __func__,
+                      rep_len));
+        rc = EBADMSG;
+        goto done;
+    }
+
+    buf = (const char *)(rep + REPLY_NAME_OFFSET);
+    buf_len = rep_len - REPLY_NAME_OFFSET;
+    offset = 0;
+    rc = sss_readrep_copy_string(buf, &offset, &buf_len, &len, &name, NULL);
+    if (rc != 0) {
+        rc = -rc;
+    }
+
+done:
+    return rc;
+}
+
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+/* configuration parsing aids */
+static bool str_equal(const char *s1, const char *s2)
+{
+    bool res = false;
+    size_t len1;
+    size_t len2;
+
+    len1 = strlen(s1);
+    len2 = strlen(s2);
+
+    if (len1 == len2) {
+        res = (strncasecmp(s1, s2, len1) == 0);
+    }
+
+    return res;
+}
+
+static int nfs_conf_get_bool(char *sect, char *attr, int def)
+{
+    int res;
+    char *val;
+
+    res = def;
+    val = conf_get_str(sect, attr);
+    if (val) {
+        res = (str_equal("1", val) ||
+               str_equal("yes", val) ||
+               str_equal("true", val) ||
+               str_equal("on", val));
+    }
+
+    return res;
+}
+
+
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+/* libnfsidmap return-code aids */
+
+/*
+ * we only want to return 0 or ENOENT; otherwise libnfsidmap will stop
+ * translation instead of proceeding to the next translation plugin
+ */
+int normalise_rc(int rc) {
+    int res;
+
+    res = rc;
+    if (res != 0 && res != ENOENT) {
+        res = ENOENT;
+    }
+
+    return res;
+}
+
+/* log the actual rc from our code (to be used before normalising the rc) */
+void log_actual_rc(const char *trans_name, int rc) {
+    char tmp[80];
+    IDMAP_LOG(1, ("%s: rc=%i msg=%s", trans_name, rc,
+                  strerror_r(rc, tmp, sizeof(tmp))));
+}
+
+
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+/* The external interface */
+static int sss_nfs_init(void)
+{
+    nfs_use_mc = nfs_conf_get_bool(nfs_conf_sect, nfs_conf_use_mc,
+                                   USE_MC_DEFAULT);
+    IDMAP_LOG(1, ("%s: use memcache: %i", __func__, nfs_use_mc));
+
+    return 0;
+}
+
+static int sss_nfs_princ_to_ids(char *secname, char *princ, uid_t *uid,
+                                gid_t *gid, extra_mapping_params **ex)
+{
+    IDMAP_LOG(0, ("%s: not implemented", __func__));
+    return -ENOENT;
+}
+
+static int sss_nfs_name_to_uid(char *name, uid_t *uid)
+{
+    int rc;
+    size_t name_len = 0;
+
+    if (name == NULL) {
+        IDMAP_LOG(0, ("%s: name is null", __func__));
+        return -EINVAL;
+    }
+    if (uid == NULL) {
+        IDMAP_LOG(0, ("%s: uid is null", __func__));
+        return -EINVAL;
+    }
+
+    rc = sss_strnlen(name, SSS_NAME_MAX, &name_len);
+    if (rc != 0) {
+        IDMAP_LOG(0, ("%s: no-strnlen; rc=%i", __func__, rc));
+        return -rc;
+    }
+
+    rc = get_uid_from_mc(uid, name);
+    if (rc != 0) {
+        rc = name_to_id(name, uid, SSS_NSS_GETPWNAM);
+    }
+
+    log_actual_rc(__func__, rc);
+    rc = normalise_rc(rc);
+
+    return -rc;
+}
+
+static int sss_nfs_name_to_gid(char *name, gid_t *gid)
+{
+    int rc;
+    size_t name_len = 0;
+
+    if (name == NULL) {
+        IDMAP_LOG(0, ("%s: name is null", __func__));
+        return -EINVAL;
+    }
+    if (gid == NULL) {
+        IDMAP_LOG(0, ("%s: gid is null", __func__));
+        return -EINVAL;
+    }
+
+    rc = sss_strnlen(name, SSS_NAME_MAX, &name_len);
+    if (rc != 0) {
+        IDMAP_LOG(0, ("%s: no-strnlen; rc=%i", __func__, rc));
+        return -rc;
+    }
+
+    rc = get_gid_from_mc(gid, name);
+    if (rc != 0) {
+        rc = name_to_id(name, gid, SSS_NSS_GETGRNAM);
+    }
+
+    log_actual_rc(__func__, rc);
+    rc = normalise_rc(rc);
+
+    return -rc;
+}
+
+static int sss_nfs_uid_to_name(uid_t uid, char *domain, char *name, size_t len)
+{
+    int rc;
+
+    if (name == NULL) {
+        IDMAP_LOG(0, ("%s: name is null", __func__));
+        return -EINVAL;
+    }
+
+    rc = get_user_from_mc(name, len, uid);
+    if (rc != 0) {
+        rc = id_to_name(name, len, uid, SSS_NSS_GETPWUID);
+    }
+
+    log_actual_rc(__func__, rc);
+    rc = normalise_rc(rc);
+
+    return -rc;
+}
+
+static int sss_nfs_gid_to_name(gid_t gid, char *domain, char *name, size_t len)
+{
+    int rc;
+
+    if (name == NULL) {
+        IDMAP_LOG(0, ("%s: name is null", __func__));
+        return -EINVAL;
+    }
+
+    rc = get_group_from_mc(name, len, gid);
+    if (rc != 0) {
+        rc = id_to_name(name, len, gid, SSS_NSS_GETGRGID);
+    }
+
+    log_actual_rc(__func__, rc);
+    rc = normalise_rc(rc);
+
+    return -rc;
+}
+
+static int sss_nfs_gss_princ_to_grouplist(
+    char *secname, char *princ, gid_t *groups, int *ngroups,
+    extra_mapping_params **ex)
+{
+    IDMAP_LOG(0, ("%s: not implemented", __func__));
+    return -ENOENT;
+}
+
+static struct trans_func s_sss_nfs_trans = {
+    .name = sss_nfs_plugin_name,
+    .init = sss_nfs_init,
+    .princ_to_ids = sss_nfs_princ_to_ids,
+    .name_to_uid = sss_nfs_name_to_uid,
+    .name_to_gid = sss_nfs_name_to_gid,
+    .uid_to_name = sss_nfs_uid_to_name,
+    .gid_to_name = sss_nfs_gid_to_name,
+    .gss_princ_to_grouplist = sss_nfs_gss_princ_to_grouplist,
+};
+
+struct trans_func *libnfsidmap_plugin_init(void)
+{
+    return (&s_sss_nfs_trans);
+}
-- 
1.9.3

>From 48f3b728293dd296b03b69679dbfad01dd3f806f Mon Sep 17 00:00:00 2001
From: Noam Meltzer <tsn...@gmail.com>
Date: Fri, 27 Jun 2014 05:44:36 +0000
Subject: [PATCH 2/4] NFSv4 client: (private) headers from libnfsidmap

The private headers are needed in order to:
nfsidmap_internal.h:
* definition of struct trans_func
* prototype for logger function
cfg.h + queue.h:
* prototype(s) for accessing rpc.idmpad configuration file
---
 src/sss_client/nfs/nfsidmap_internal.h | 78 ++++++++++++++++++++++++++++++++++
 1 file changed, 78 insertions(+)
 create mode 100644 src/sss_client/nfs/nfsidmap_internal.h

diff --git a/src/sss_client/nfs/nfsidmap_internal.h 
b/src/sss_client/nfs/nfsidmap_internal.h
new file mode 100644
index 
0000000000000000000000000000000000000000..b75bc8335def3977750bb75fd407849b3e15660d
--- /dev/null
+++ b/src/sss_client/nfs/nfsidmap_internal.h
@@ -0,0 +1,78 @@
+/*
+ *  nfsidmap_internal.h
+ *
+ *  nfs idmapping library, primarily for nfs4 client/server kernel idmapping
+ *  and for userland nfs4 idmapping by acl libraries.
+ *
+ *  Copyright (c) 2004 The Regents of the University of Michigan.
+ *  All rights reserved.
+ *
+ *  Andy Adamson <and...@umich.edu>
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the University nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ *  DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ *  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ *  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ *  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ *  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ *  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+char *get_default_domain(void);
+struct conf_list *get_local_realms(void);
+
+typedef struct trans_func * (*libnfsidmap_plugin_init_t)(void);
+
+struct trans_func {
+       char *name;
+       int (*init)(void);
+       int (*princ_to_ids)(char *secname, char *princ, uid_t *uid, gid_t *gid,
+               extra_mapping_params **ex);
+       int (*name_to_uid)(char *name, uid_t *uid);
+       int (*name_to_gid)(char *name, gid_t *gid);
+       int (*uid_to_name)(uid_t uid, char *domain, char *name, size_t len);
+       int (*gid_to_name)(gid_t gid, char *domain, char *name, size_t len);
+       int (*gss_princ_to_grouplist)(char *secname, char *princ, gid_t *groups,
+               int *ngroups, extra_mapping_params **ex);
+};
+
+struct mapping_plugin {
+       void *dl_handle;
+       struct trans_func *trans;
+};
+
+typedef enum {
+       IDTYPE_USER = 1,
+       IDTYPE_GROUP = 2
+} idtypes;
+
+extern int idmap_verbosity;
+extern nfs4_idmap_log_function_t idmap_log_func;
+/* Level zero always prints, others print depending on verbosity level */
+#define IDMAP_LOG(LVL, MSG) \
+       do { if (LVL <= idmap_verbosity) (*idmap_log_func)MSG; } while (0)
+
+
+/*
+ * from libnfsidmap's cfg.h (same license as above)
+ * Copyright (c) 1998, 1999, 2001 Niklas Hallqvist.  All rights reserved.
+ * Copyright (c) 2000, 2003 H�kan Olsson.  All rights reserved.
+ */
+extern char    *conf_get_str(char *, char *);
-- 
1.9.3

>From 9ec8cd169c78b4740acf3545fe0b3292785368f4 Mon Sep 17 00:00:00 2001
From: Noam Meltzer <tsn...@gmail.com>
Date: Fri, 27 Jun 2014 05:44:37 +0000
Subject: [PATCH 3/4] NFSv4 client: add to build system

---
 Makefile.am                 | 24 ++++++++++++++++++++++++
 configure.ac                | 10 ++++++++++
 src/conf_macros.m4          | 30 ++++++++++++++++++++++++++++++
 src/external/libnfsidmap.m4 | 17 +++++++++++++++++
 4 files changed, 81 insertions(+)
 create mode 100644 src/external/libnfsidmap.m4

diff --git a/Makefile.am b/Makefile.am
index 
4c3dc35d234899d3198ab297f2c2a4895f442b13..727ae2dd3afe24904394b2af9b9bdc850dc0d059
 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -50,6 +50,7 @@ localedir = @localedir@
 nsslibdir = @nsslibdir@
 pamlibdir = @pammoddir@
 autofslibdir = @appmodpath@
+nfslibdir = @nfsidmaplibdir@
 
 dbpath = @dbpath@
 pluginpath = @pluginpath@
@@ -578,6 +579,7 @@ dist_noinst_HEADERS = \
     src/sss_client/libwbclient/wbc_err_internal.h \
     src/sss_client/libwbclient/wbclient_internal.h \
     src/sss_client/libwbclient/wbc_sssd_internal.h \
+    src/sss_client/nfs/nfsidmap_internal.h \
     src/lib/idmap/sss_idmap_private.h \
     src/lib/sifp/sss_sifp_private.h \
     src/tests/cmocka/test_utils.h \
@@ -2041,6 +2043,28 @@ libnss_sss_la_LDFLAGS = \
     -version-info 2:0:0 \
     -Wl,--version-script,$(srcdir)/src/sss_client/sss_nss.exports
 
+if BUILD_NFS_IDMAP
+nfslib_LTLIBRARIES = sss.la
+sss_la_SOURCES = \
+    src/sss_client/common.c \
+    src/sss_client/nss_mc_common.c \
+    src/util/io.c \
+    src/util/murmurhash3.c \
+    src/sss_client/nss_mc_passwd.c \
+    src/sss_client/nss_mc_group.c \
+    src/sss_client/nfs/sss_nfs_client.c \
+    $(NULL)
+sss_la_CFLAGS = $(AM_CFLAGS)
+sss_la_LIBADD = \
+    $(CLIENT_LIBS) \
+    $(NFSIDMAP_LIBS) \
+    $(NULL)
+sss_la_LDFLAGS = \
+    -module \
+    -avoid-version \
+    $(NULL)
+endif
+
 pamlib_LTLIBRARIES = pam_sss.la
 pam_sss_la_SOURCES = \
     src/sss_client/pam_sss.c \
diff --git a/configure.ac b/configure.ac
index 
d20cb9ca20c927c9e08d2eb3fbacdc9bfd78345b..42d8e5a07066162e39bc812bcfd079e97ae2e273
 100644
--- a/configure.ac
+++ b/configure.ac
@@ -85,6 +85,13 @@ AC_ARG_ENABLE([pammoddir], 
[AS_HELP_STRING([--enable-pammoddir],
               [pammoddir=$libdir/security])
 AC_SUBST(pammoddir)
 
+#Set the NFSv4 idmapd library install path
+AC_ARG_ENABLE([nfsidmaplibdir], [AS_HELP_STRING([--enable-nfsidmaplibdir],
+                                        [Where to install libnfsidmap 
libraries ($libdir/libnfsidmap)])],
+              [nfsidmaplibdir=$enableval],
+              [nfsidmaplibdir=$libdir/libnfsidmap])
+AC_SUBST(nfsidmaplibdir)
+
 #Include here cause WITH_INIT_DIR requires $osname set in platform.m4
 m4_include([src/external/platform.m4])
 
@@ -123,6 +130,8 @@ WITH_IFP
 WITH_CRYPTO
 WITH_SYSLOG
 WITH_SAMBA
+WITH_NFS
+WITH_NFS_LIB_PATH
 
 m4_include([src/external/pkg.m4])
 m4_include([src/external/libpopt.m4])
@@ -156,6 +165,7 @@ m4_include([src/external/inotify.m4])
 m4_include([src/external/samba.m4])
 m4_include([src/external/sasl.m4])
 m4_include([src/external/configlib.m4])
+m4_include([src/external/libnfsidmap.m4])
 
 if test x$build_config_lib = xyes; then
     m4_include([src/external/libaugeas.m4])
diff --git a/src/conf_macros.m4 b/src/conf_macros.m4
index 
3c9827b4d4e1750fc06af8ab8b69ecf99226a8f6..8f8479459594283696f09c3ea9d79be3229ef3e8
 100644
--- a/src/conf_macros.m4
+++ b/src/conf_macros.m4
@@ -691,3 +691,33 @@ AC_ARG_ENABLE([dbus-tests],
               [build_dbus_tests=$enableval],
               [build_dbus_tests=yes])
 AM_CONDITIONAL([BUILD_DBUS_TESTS], [test x$build_dbus_tests = xyes])
+
+AC_DEFUN([WITH_NFS],
+  [ AC_ARG_WITH([nfs_idmap],
+                [AC_HELP_STRING([--with-nfsv4-idmapd-plugin],
+                                [Whether to build with NFSv4 IDMAP support 
[yes]]
+                               )
+                ],
+                [with_nfs_idmap=$withval],
+                with_nfs_idmap=yes
+               )
+
+    if test x"$with_nfs_idmap" = xyes; then
+        AC_DEFINE(BUILD_NFS_IDMAP, 1, [whether to build with NFSv4 IDMAP 
support])
+    fi
+    AM_CONDITIONAL([BUILD_NFS_IDMAP], [test x"$with_nfs_idmap" = xyes])
+  ])
+
+AC_DEFUN([WITH_NFS_LIB_PATH],
+  [ AC_ARG_WITH([nfs-lib-path],
+                [AC_HELP_STRING([--with-nfs-lib-path=<path>],
+                                [Path to the nfs library [${libdir}]]
+                               )
+                ]
+               )
+    nfslibpath="${libdir}"
+    if test x"$with_nfs_lib_path" != x; then
+        nfslibpath=$with_nfs_lib_path
+    fi
+    AC_SUBST(nfslibpath)
+  ])
diff --git a/src/external/libnfsidmap.m4 b/src/external/libnfsidmap.m4
new file mode 100644
index 
0000000000000000000000000000000000000000..5bb6d8684732e1d38e1c802dfaedf0ebba281285
--- /dev/null
+++ b/src/external/libnfsidmap.m4
@@ -0,0 +1,17 @@
+AC_SUBST(NFSIDMAP_OBJ)
+AC_SUBST(NFSIDMAP_CFLAGS)
+AC_SUBST(NFSIDMAP_LIBS)
+
+PKG_CHECK_MODULES([NFSIDMAP], [libnfsidmap], [found_nfsidmap=yes],
+                 [found_nfsidmap=no])
+
+SSS_AC_EXPAND_LIB_DIR()
+AS_IF([test x"$with_nfs" = xyes -a x"$found_nfsidmap" != xyes],
+    [AC_CHECK_HEADER([nfsidmap.h],
+        [AC_CHECK_LIB([nfsidmap],
+                      [nfs4_init_name_mapping],
+                      [NFSIDMAP_LIBS="-L$sss_extra_libdir -lnfsidmap"],
+                      [AC_MSG_ERROR([libnfsidmap missing 
nfs4_init_name_mapping])],
+                      [-L$sss_extra_libdir])],
+        [AC_MSG_ERROR([libnfsidmap header files are not installed])])]
+)
-- 
1.9.3

>From 43950b49293dcc3c89cfd7cd9774416be6aa44bd Mon Sep 17 00:00:00 2001
From: Noam Meltzer <tsn...@gmail.com>
Date: Fri, 27 Jun 2014 05:44:38 +0000
Subject: [PATCH 4/4] NFSv4 client: add to RPM spec

---
 contrib/sssd.spec.in | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/contrib/sssd.spec.in b/contrib/sssd.spec.in
index 
770a0c7d6b3c4394e9268d933eef190409989565..118fa447afc7101f192a12e12670b019ae4b0902
 100644
--- a/contrib/sssd.spec.in
+++ b/contrib/sssd.spec.in
@@ -139,6 +139,11 @@ BuildRequires: systemd-devel
 %if (0%{?with_cifs_utils_plugin} == 1)
 BuildRequires: cifs-utils-devel
 %endif
+%if ((0%{?fedora} >= 15) || (0%{?rhel} >= 7))
+BuildRequires: libnfsidmap-devel
+%else
+BuildRequires: nfs-utils-lib-devel
+%endif
 
 # RHEL 5 is too old to support samba4 and the PAC responder
 %if !0%{?is_rhel5}
@@ -469,6 +474,7 @@ autoreconf -ivf
     --with-krb5-rcache-dir=%{_localstatedir}/cache/krb5rcache \
     --enable-nsslibdir=/%{_lib} \
     --enable-pammoddir=/%{_lib}/security \
+    --enable-nfsidmaplibdir=%{_libdir}/libnfsidmap \
     --disable-static \
     --disable-rpath \
     %{?with_ccache} \
@@ -618,6 +624,7 @@ rm -rf $RPM_BUILD_ROOT
 # 3rd party application libraries
 %{_libdir}/sssd/modules/libsss_autofs.so
 %{_libdir}/libsss_sudo.so
+%{_libdir}/libnfsidmap/sss.so
 
 %{ldb_modulesdir}/memberof.so
 %{_bindir}/sss_ssh_authorizedkeys
-- 
1.9.3

_______________________________________________
sssd-devel mailing list
sssd-devel@lists.fedorahosted.org
https://lists.fedorahosted.org/mailman/listinfo/sssd-devel

Reply via email to