Re: [PATCH] cifs-utils: Create new binary cifs.idmap for sid to uid/gid mapping (try #4)

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Tue, 24 May 2011 20:39:26 -0500
Shirish Pargaonkar <shirishpargaonkar@xxxxxxxxx> wrote:

> On Tue, May 24, 2011 at 1:52 PM, Jeff Layton <jlayton@xxxxxxxxxx> wrote:
> > On Mon, 23 May 2011 09:42:44 -0500
> > shirishpargaonkar@xxxxxxxxx wrote:
> >
> >> From: Shirish Pargaonkar <shirishpargaonkar@xxxxxxxxx>
> >>
> >> Handle cifs.idmap type of key. Extract a SID string from the description
> >> and map it to either an uid or gid using winbind APIs.
> >> If that fails (e.g. because winbind is not installed/running or winbind
> >> returns an error), kernel assigns uid and gid (from mount superblock).
> >>
> >> Enable including winbind header files and idmapping code conditional
> >> to winbind devel rpms (header and library).
> >>
> >> An entry such as this
> >>
> >> create Âcifs.idmap  *    *        /usr/sbin/cifs.idmap %k
> >>
> >> is needed in the file /etc/request-key.conf.
> >>
> >>
> >> Signed-off-by: Shirish Pargaonkar <shirishpargaonkar@xxxxxxxxx>
> >> ---
> >> ÂMakefile.am   Â|  11 +++-
> >> Âaclocal/idmap.m4 | Â 45 ++++++++++++
> >> Âcifs.idmap.c   | Â197 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
> >> Âcifs.upcall.c  Â|  Â1 -
> >> Âconfigure.ac   |  20 +++++-
> >> Â5 files changed, 270 insertions(+), 4 deletions(-)
> >> Âcreate mode 100644 aclocal/idmap.m4
> >> Âcreate mode 100644 cifs.idmap.c
> >>
> >> diff --git a/Makefile.am b/Makefile.am
> >> index 67a0190..c6eeb22 100644
> >> --- a/Makefile.am
> >> +++ b/Makefile.am
> >> @@ -8,8 +8,10 @@ mount_cifs_LDADD = $(LIBCAP) $(CAPNG_LDADD)
> >>
> >> Âman_MANS = mount.cifs.8
> >>
> >> +sbin_PROGRAMS =
> >> +
> >> Âif CONFIG_CIFSUPCALL
> >> -sbin_PROGRAMS = cifs.upcall
> >> +sbin_PROGRAMS += cifs.upcall
> >> Âcifs_upcall_SOURCES = cifs.upcall.c data_blob.c asn1.c spnego.c util.c
> >> Âcifs_upcall_LDADD = -ltalloc -lkeyutils $(KRB5_LDADD)
> >> Âman_MANS += cifs.upcall.8
> >> @@ -30,3 +32,10 @@ bin_PROGRAMS = cifscreds
> >> Âcifscreds_SOURCES = cifscreds.c resolve_host.c util.c
> >> Âcifscreds_LDADD = -lkeyutils
> >> Âendif
> >> +
> >> +if CONFIG_CIFSIDMAP
> >> +sbin_PROGRAMS += cifs.idmap
> >> +cifs_idmap_SOURCES = cifs.idmap.c
> >> +cifs_idmap_LDADD = -lkeyutils $(WINB_LDADD)
> >> +endif
> >> +
> >
> > ^^^ nit: don't add extra newline
> >
> >> diff --git a/aclocal/idmap.m4 b/aclocal/idmap.m4
> >> new file mode 100644
> >> index 0000000..211d372
> >> --- /dev/null
> >> +++ b/aclocal/idmap.m4
> >> @@ -0,0 +1,45 @@
> >> +dnl Headers needed by wbclient.h
> >> +dnl
> >> +AC_DEFUN([AC_WBCH_COMPL],[
> >> +[
> >> +#ifdef HAVE_STDINT_H
> >> +#include <stdint.h>
> >> +#endif
> >> +]
> >> +[#ifdef HAVE_STDBOOL_H
> >> +#include <stdbool.h>
> >> +#endif
> >> +]
> >> +[#ifdef HAVE_STDIO_H
> >> +#include <stdio.h>
> >> +#endif
> >> +]
> >> +[#ifdef HAVE_STDLIB_H
> >> +#include <stdlib.h>
> >> +#endif
> >> +]
> >> +[#ifdef HAVE_ERRNO_H
> >> +#include <errno.h>
> >> +#endif
> >> +]])
> >> +
> >> +dnl Check for wbclient.h header and libwbclietn.so
> >> +dnl
> >> +AC_DEFUN([AC_TEST_WBCHL],[
> >> +if test $enable_cifsidmap != "no"; then
> >> + Â Â AC_CHECK_HEADERS([wbclient.h], , [
> >> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â if test "$enable_cifsidmap" = "yes"; then
> >> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â AC_MSG_ERROR([wbclient.h not found, consider installing libwbclient-devel.])
> >> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â else
> >> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â AC_MSG_WARN([wbclient.h not found, consider installing libwbclient-devel. Disabling cifs.idmap.])
> >> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â enable_cifsidmap="no"
> >> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â fi
> >> + Â Â Â Â Â Â Â Â Â Â ], [ AC_WBCH_COMPL ])
> >> +fi
> >> +
> >> +if test $enable_cifsidmap != "no"; then
> >> + Â Â AC_CHECK_LIB([wbclient], [wbcStringToSid],
> >> + Â Â Â Â Â Â [ WINB_LDADD='-lwbclient' ] [ AC_DEFINE(HAVE_LIBWBCLIENT, 1, ["Define var have_libwbclient"]) ], [AC_MSG_ERROR([No functioning wbclient library found!])])
> >> + Â Â AC_SUBST(WINB_LDADD)
> >> +fi
> >> +])
> >> diff --git a/cifs.idmap.c b/cifs.idmap.c
> >> new file mode 100644
> >> index 0000000..ea24824
> >> --- /dev/null
> >> +++ b/cifs.idmap.c
> >> @@ -0,0 +1,197 @@
> >> +/*
> >> +* CIFS idmap helper.
> >> +* Copyright (C) Shirish Pargaonkar (shirishp@xxxxxxxxxx) 2011
> >> +*
> >> +* Used by /sbin/request-key.conf for handling
> >> +* cifs upcall for SID to uig/gid and uid/gid to SID mapping.
> >> +* You should have keyutils installed and add
> >> +* this lines to /etc/request-key.conf file:
> >> +
> >> + Â Âcreate cifs.idmap * * /usr/local/sbin/cifs.idmap %k
> >> +
> >> +* 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 2 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, write to the Free Software
> >> +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
> >> +*/
> >> +
> >> +#ifdef HAVE_CONFIG_H
> >> +#include "config.h"
> >> +#endif /* HAVE_CONFIG_H */
> >> +
> >> +#include <string.h>
> >> +#include <getopt.h>
> >> +#include <syslog.h>
> >> +#include <dirent.h>
> >> +#include <sys/types.h>
> >> +#include <sys/stat.h>
> >> +#include <unistd.h>
> >> +#include <keyutils.h>
> >> +#include <stdint.h>
> >> +#include <stdbool.h>
> >> +#include <stdio.h>
> >> +#include <stdlib.h>
> >> +#include <errno.h>
> >> +#include <limits.h>
> >> +#include <wbclient.h>
> >> +
> >> +static const char *prog = "cifs.idmap";
> >> +
> >> +static void usage(void)
> >> +{
> >> + Â Â fprintf(stderr, "Usage: %s key_serial\n", prog);
> >> +}
> >> +
> >> +char *strget(const char *str, char *substr)
> >> +{
> >> + Â Â int len, sublen, retlen;
> >> + Â Â char *retstr, *substrptr;
> >> +
> >> + Â Â sublen = strlen(substr);
> >> + Â Â substrptr = strstr(str, substr);
> >> + Â Â if (substrptr) {
> >> + Â Â Â Â Â Â len = strlen(substrptr);
> >> + Â Â Â Â Â Â substrptr += sublen;
> >> +
> >> + Â Â Â Â Â Â retlen = len - sublen;
> >> + Â Â Â Â Â Â if (retlen > 0) {
> >> + Â Â Â Â Â Â Â Â Â Â retstr = malloc(retlen + 1);
> >> + Â Â Â Â Â Â Â Â Â Â if (retstr) {
> >> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â strncpy(retstr, substrptr, retlen);
> >> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â return retstr;
> >> + Â Â Â Â Â Â Â Â Â Â }
> >> + Â Â Â Â Â Â }
> >> + Â Â }
> >> +
> >> + Â Â return NULL;
> >> +}
> >> +
> >> +static int
> >> +cifs_idmap(const key_serial_t key, const char *key_descr)
> >> +{
> >> + Â Â uid_t uid = 0;
> >> + Â Â gid_t gid = 0;;
> >> + Â Â wbcErr rc = 1;
> >> + Â Â char *sidstr = NULL;
> >> + Â Â struct wbcDomainSid sid;
> >> + Â Â struct passwd *pw;
> >> + Â Â struct group *gr;
> >> +
> >> + Â Â /*
> >> + Â Â Â* Use winbind to convert received string to a SID and lookup
> >> + Â Â Â* name and map that SID to an uid. ÂIf either of these
> >> + Â Â Â* function calls return with an error, return an error the
> >> + Â Â Â* upcall caller. ÂOtherwise instanticate a key using that uid.
> >> + Â Â Â*
> >> + Â Â Â* The same applies to SID and gid mapping.
> >> + Â Â Â*/
> >> + Â Â sidstr = strget(key_descr, "os:");
> >> + Â Â if (sidstr) {
> >> + Â Â Â Â Â Â rc = wbcStringToSid(sidstr, &sid);
> >> + Â Â Â Â Â Â if (rc)
> >> + Â Â Â Â Â Â Â Â Â Â syslog(LOG_DEBUG, "Invalid owner string: %s, rc: %d",
> >> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â key_descr, rc);
> >> + Â Â Â Â Â Â else {
> >> + Â Â Â Â Â Â Â Â Â Â rc = wbcSidToUid(&sid, &uid);
> >> + Â Â Â Â Â Â Â Â Â Â if (rc)
> >> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â syslog(LOG_DEBUG, "SID %s to uid wbc error: %d",
> >> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â key_descr, rc);
> >> + Â Â Â Â Â Â }
> >> + Â Â Â Â Â Â if (!rc) { /* SID has been mapped to an uid */
> >> + Â Â Â Â Â Â Â Â Â Â rc = keyctl_instantiate(key, &uid, sizeof(uid_t), 0);
> >> + Â Â Â Â Â Â Â Â Â Â if (rc)
> >> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â syslog(LOG_ERR, "%s: key inst: %s",
> >> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â __func__, strerror(errno));
> >> + Â Â Â Â Â Â }
> >> +
> >> + Â Â Â Â Â Â goto cifs_idmap_ret;
> >> + Â Â }
> >> +
> >> + Â Â sidstr = strget(key_descr, "gs:");
> >> + Â Â if (sidstr) {
> >> + Â Â Â Â Â Â rc = wbcStringToSid(sidstr, &sid);
> >> + Â Â Â Â Â Â if (rc)
> >> + Â Â Â Â Â Â Â Â Â Â syslog(LOG_DEBUG, "Invalid group string: %s, rc: %d",
> >> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â key_descr, rc);
> >> + Â Â Â Â Â Â else {
> >> + Â Â Â Â Â Â Â Â Â Â rc = wbcSidToGid(&sid, &gid);
> >> + Â Â Â Â Â Â Â Â Â Â if (rc)
> >> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â syslog(LOG_DEBUG, "SID %s to gid wbc error: %d",
> >> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â key_descr, rc);
> >> + Â Â Â Â Â Â }
> >> + Â Â Â Â Â Â if (!rc) { /* SID has been mapped to a gid */
> >> + Â Â Â Â Â Â Â Â Â Â rc = keyctl_instantiate(key, &gid, sizeof(gid_t), 0);
> >> + Â Â Â Â Â Â Â Â Â Â if (rc)
> >> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â syslog(LOG_ERR, "%s: key inst: %s",
> >> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â __func__, strerror(errno));
> >> + Â Â Â Â Â Â }
> >> +
> >> + Â Â Â Â Â Â goto cifs_idmap_ret;
> >> + Â Â }
> >> +
> >> + Â Â syslog(LOG_DEBUG, "Invalid key: %s", key_descr);
> >> +
> >> +cifs_idmap_ret:
> >> + Â Â if (sidstr)
> >> + Â Â Â Â Â Â free(sidstr);
> >> +
> >> + Â Â return rc;
> >> +}
> >> +
> >> +int main(const int argc, char *const argv[])
> >> +{
> >> + Â Â int c;
> >> + Â Â long rc = 1;
> >> + Â Â key_serial_t key = 0;
> >> + Â Â char *buf;
> >> +
> >> + Â Â openlog(prog, 0, LOG_DAEMON);
> >> +
> >> + Â Â while ((c = getopt_long(argc, argv, "v", NULL, NULL)) != -1) {
> >> + Â Â Â Â Â Â switch (c) {
> >> + Â Â Â Â Â Â case 'v':
> >> + Â Â Â Â Â Â Â Â Â Â printf("version: %s\n", VERSION);
> >> + Â Â Â Â Â Â Â Â Â Â goto out;
> >> + Â Â Â Â Â Â default:
> >> + Â Â Â Â Â Â Â Â Â Â syslog(LOG_ERR, "unknown option: %c", c);
> >> + Â Â Â Â Â Â Â Â Â Â goto out;
> >> + Â Â Â Â Â Â }
> >> + Â Â }
> >> +
> >> + Â Â /* is there a key? */
> >> + Â Â if (argc <= optind) {
> >> + Â Â Â Â Â Â usage();
> >> + Â Â Â Â Â Â goto out;
> >> + Â Â }
> >> +
> >> + Â Â /* get key and keyring values */
> >> + Â Â errno = 0;
> >> + Â Â key = strtol(argv[optind], NULL, 10);
> >> + Â Â if (errno != 0) {
> >> + Â Â Â Â Â Â key = 0;
> >> + Â Â Â Â Â Â syslog(LOG_ERR, "Invalid key format: %s", strerror(errno));
> >> + Â Â Â Â Â Â goto out;
> >> + Â Â }
> >> +
> >> + Â Â rc = keyctl_describe_alloc(key, &buf);
> >> + Â Â if (rc == -1) {
> >> + Â Â Â Â Â Â syslog(LOG_ERR, "keyctl_describe_alloc failed: %s",
> >> + Â Â Â Â Â Â Â Â Â Âstrerror(errno));
> >> + Â Â Â Â Â Â rc = 1;
> >> + Â Â Â Â Â Â goto out;
> >> + Â Â }
> >> +
> >> + Â Â syslog(LOG_DEBUG, "key description: %s", buf);
> >> +
> >> + Â Â if ((strncmp(buf, "cifs.idmap", sizeof("cifs.idmap") - 1) == 0))
> >> + Â Â Â Â Â Â rc = cifs_idmap(key, buf);
> >> +out:
> >> + Â Â return rc;
> >> +}
> >
> >
> > Program looks fine, I think...
> >
> >> diff --git a/cifs.upcall.c b/cifs.upcall.c
> >> index 479517c..de92092 100644
> >> --- a/cifs.upcall.c
> >> +++ b/cifs.upcall.c
> >> @@ -749,7 +749,6 @@ static int ip_to_fqdn(const char *addrstr, char *host, size_t hostlen)
> >>
> >> Âstatic void usage(void)
> >> Â{
> >> - Â Â syslog(LOG_INFO, "Usage: %s [-t] [-v] [-l] key_serial", prog);
> >> Â Â Â fprintf(stderr, "Usage: %s [-t] [-v] [-l] key_serial\n", prog);
> >> Â}
> >>
> > Â Â Â Â Â Â Â Â^^^^^^^^^^^^
> > This belongs in a separate patch. I've gone ahead and queued one up.
> >
> >> diff --git a/configure.ac b/configure.ac
> >> index e0e2a60..906bc2d 100644
> >> --- a/configure.ac
> >> +++ b/configure.ac
> >> @@ -22,13 +22,19 @@ AC_ARG_ENABLE(cifscreds,
> >> Â Â Â enable_cifscreds=$enableval,
> >> Â Â Â enable_cifscreds="no")
> >>
> >> +AC_ARG_ENABLE(cifsidmap,
> >> + Â Â [AC_HELP_STRING([--enable-cifsidmap],
> >> + Â Â Â Â Â Â Â Â Â Â [Create cifs.idmap binary @<:@default=yes@:>@])],
> >> + Â Â enable_cifsidmap=$enableval,
> >> + Â Â enable_cifsidmap="maybe")
> >> +
> >> Â# Checks for programs.
> >> ÂAC_PROG_CC
> >> ÂAC_PROG_SED
> >> ÂAC_GNU_SOURCE
> >>
> >> Â# Checks for header files.
> >> -AC_CHECK_HEADERS([arpa/inet.h ctype.h fcntl.h inttypes.h limits.h mntent.h netdb.h stddef.h stdint.h stdlib.h string.h strings.h sys/mount.h sys/param.h sys/socket.h sys/time.h syslog.h unistd.h], , [AC_MSG_ERROR([necessary header(s) not found])])
> >> +AC_CHECK_HEADERS([arpa/inet.h ctype.h fcntl.h inttypes.h limits.h mntent.h netdb.h stddef.h stdint.h stdbool.h stdlib.h stdio.h errno.h string.h strings.h sys/mount.h sys/param.h sys/socket.h sys/time.h syslog.h unistd.h], , [AC_MSG_ERROR([necessary header(s) not found])])
> >>
> >> Âif test $enable_cifsupcall != "no"; then
> >> Â Â Â AC_CHECK_HEADERS([krb5.h krb5/krb5.h])
> >> @@ -72,7 +78,7 @@ if test $enable_cifsupcall != "no"; then
> >> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â fi
> >> Â Â Â Â Â Â Â Â Â Â Â ])
> >> Âfi
> >> -if test $enable_cifsupcall != "no"; then
> >> +if test $enable_cifsupcall != "no" -o $enable_cifsidmap != "no"; then
> >> Â Â Â AC_CHECK_HEADERS([keyutils.h], , [
> >> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â if test "$enable_cifsupcall" = "yes"; then
> >> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â AC_MSG_ERROR([keyutils.h not found, consider installing keyutils-libs-devel.])
> >> @@ -80,6 +86,12 @@ if test $enable_cifsupcall != "no"; then
> >> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â AC_MSG_WARN([keyutils.h not found, consider installing keyutils-libs-devel. Disabling cifs.upcall.])
> >> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â enable_cifsupcall="no"
> >> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â fi
> >> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â if test "$enable_cifsidmap" = "yes"; then
> >> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â AC_MSG_ERROR([keyutils.h not found, consider installing keyutils-libs-devel.])
> >> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â else
> >> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â AC_MSG_WARN([keyutils.h not found, consider installing keyutils-libs-devel. Disabling cifs.idmap.])
> >> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â enable_cifsidmap="no"
> >> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â fi
> >> Â Â Â Â Â Â Â Â Â Â Â ])
> >> Âfi
> >> Âif test $enable_cifsupcall != "no"; then
> >> @@ -89,6 +101,9 @@ if test $enable_cifsupcall != "no"; then
> >> Â Â Â AC_SUBST(KRB5_LDADD)
> >> Âfi
> >>
> >> +# checks for wbclient.h and libwbclient.so library
> >> +AC_TEST_WBCHL
> >> +
> >> Âif test $enable_cifscreds = "yes"; then
> >> Â Â Â AC_CHECK_HEADERS([keyutils.h], , [AC_MSG_ERROR([keyutils.h not found, consider installing keyutils-libs-devel.])])
> >> Âfi
> >> @@ -140,6 +155,7 @@ LIBS=$cu_saved_libs
> >>
> >> ÂAM_CONDITIONAL(CONFIG_CIFSUPCALL, [test "$enable_cifsupcall" != "no"])
> >> ÂAM_CONDITIONAL(CONFIG_CIFSCREDS, [test "$enable_cifscreds" = "yes"])
> >> +AM_CONDITIONAL(CONFIG_CIFSIDMAP, [test "$enable_cifsidmap" != "no"])
> >>
> >> ÂLIBCAP_NG_PATH
> >>
> >
> > At this point, I'm not quite comfortable enabling this by default given
> > that there is no documentation. Any objection to merging the following
> > modified patch instead?
> >
> > -------------------------[snip]-------------------------
> >
> > [PATCH] cifs-utils: Create new binary cifs.idmap for sid to uid/gid mapping (try #4)
> >
> > Handle cifs.idmap type of key. Extract a SID string from the description
> > and map it to either an uid or gid using winbind APIs.
> > If that fails (e.g. because winbind is not installed/running or winbind
> > returns an error), kernel assigns uid and gid (from mount superblock).
> >
> > Enable including winbind header files and idmapping code conditional
> > to winbind devel rpms (header and library).
> >
> > An entry such as this
> >
> > create Âcifs.idmap  *    *        /usr/sbin/cifs.idmap %k
> >
> > is needed in the file /etc/request-key.conf.
> >
> > [Note: Modified to not build new tool by default, and to fix up some
> > Â Â Â whitespace munging]
> >
> > Modified-by: Jeff Layton <jlayton@xxxxxxxxxx>
> > Signed-off-by: Shirish Pargaonkar <shirishpargaonkar@xxxxxxxxx>
> > ---
> > ÂMakefile.am   Â|  10 +++-
> > Âaclocal/idmap.m4 | Â 45 ++++++++++++
> > Âcifs.idmap.c   | Â197 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
> > Âconfigure.ac   |  17 ++++-
> > Â4 files changed, 266 insertions(+), 3 deletions(-)
> > Âcreate mode 100644 aclocal/idmap.m4
> > Âcreate mode 100644 cifs.idmap.c
> >
> > diff --git a/Makefile.am b/Makefile.am
> > index 67a0190..6046369 100644
> > --- a/Makefile.am
> > +++ b/Makefile.am
> > @@ -8,8 +8,10 @@ mount_cifs_LDADD = $(LIBCAP) $(CAPNG_LDADD)
> >
> > Âman_MANS = mount.cifs.8
> >
> > +sbin_PROGRAMS =
> > +
> > Âif CONFIG_CIFSUPCALL
> > -sbin_PROGRAMS = cifs.upcall
> > +sbin_PROGRAMS += cifs.upcall
> > Âcifs_upcall_SOURCES = cifs.upcall.c data_blob.c asn1.c spnego.c util.c
> > Âcifs_upcall_LDADD = -ltalloc -lkeyutils $(KRB5_LDADD)
> > Âman_MANS += cifs.upcall.8
> > @@ -30,3 +32,9 @@ bin_PROGRAMS = cifscreds
> > Âcifscreds_SOURCES = cifscreds.c resolve_host.c util.c
> > Âcifscreds_LDADD = -lkeyutils
> > Âendif
> > +
> > +if CONFIG_CIFSIDMAP
> > +sbin_PROGRAMS += cifs.idmap
> > +cifs_idmap_SOURCES = cifs.idmap.c
> > +cifs_idmap_LDADD = -lkeyutils $(WINB_LDADD)
> > +endif
> > diff --git a/aclocal/idmap.m4 b/aclocal/idmap.m4
> > new file mode 100644
> > index 0000000..211d372
> > --- /dev/null
> > +++ b/aclocal/idmap.m4
> > @@ -0,0 +1,45 @@
> > +dnl Headers needed by wbclient.h
> > +dnl
> > +AC_DEFUN([AC_WBCH_COMPL],[
> > +[
> > +#ifdef HAVE_STDINT_H
> > +#include <stdint.h>
> > +#endif
> > +]
> > +[#ifdef HAVE_STDBOOL_H
> > +#include <stdbool.h>
> > +#endif
> > +]
> > +[#ifdef HAVE_STDIO_H
> > +#include <stdio.h>
> > +#endif
> > +]
> > +[#ifdef HAVE_STDLIB_H
> > +#include <stdlib.h>
> > +#endif
> > +]
> > +[#ifdef HAVE_ERRNO_H
> > +#include <errno.h>
> > +#endif
> > +]])
> > +
> > +dnl Check for wbclient.h header and libwbclietn.so
> > +dnl
> > +AC_DEFUN([AC_TEST_WBCHL],[
> > +if test $enable_cifsidmap != "no"; then
> > + Â Â Â AC_CHECK_HEADERS([wbclient.h], , [
> > + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â if test "$enable_cifsidmap" = "yes"; then
> > + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â AC_MSG_ERROR([wbclient.h not found, consider installing libwbclient-devel.])
> > + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â else
> > + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â AC_MSG_WARN([wbclient.h not found, consider installing libwbclient-devel. Disabling cifs.idmap.])
> > + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â enable_cifsidmap="no"
> > + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â fi
> > + Â Â Â Â Â Â Â Â Â Â Â ], [ AC_WBCH_COMPL ])
> > +fi
> > +
> > +if test $enable_cifsidmap != "no"; then
> > + Â Â Â AC_CHECK_LIB([wbclient], [wbcStringToSid],
> > + Â Â Â Â Â Â Â [ WINB_LDADD='-lwbclient' ] [ AC_DEFINE(HAVE_LIBWBCLIENT, 1, ["Define var have_libwbclient"]) ], [AC_MSG_ERROR([No functioning wbclient library found!])])
> > + Â Â Â AC_SUBST(WINB_LDADD)
> > +fi
> > +])
> > diff --git a/cifs.idmap.c b/cifs.idmap.c
> > new file mode 100644
> > index 0000000..ea24824
> > --- /dev/null
> > +++ b/cifs.idmap.c
> > @@ -0,0 +1,197 @@
> > +/*
> > +* CIFS idmap helper.
> > +* Copyright (C) Shirish Pargaonkar (shirishp@xxxxxxxxxx) 2011
> > +*
> > +* Used by /sbin/request-key.conf for handling
> > +* cifs upcall for SID to uig/gid and uid/gid to SID mapping.
> > +* You should have keyutils installed and add
> > +* this lines to /etc/request-key.conf file:
> > +
> > + Â Âcreate cifs.idmap * * /usr/local/sbin/cifs.idmap %k
> > +
> > +* 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 2 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, write to the Free Software
> > +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
> > +*/
> > +
> > +#ifdef HAVE_CONFIG_H
> > +#include "config.h"
> > +#endif /* HAVE_CONFIG_H */
> > +
> > +#include <string.h>
> > +#include <getopt.h>
> > +#include <syslog.h>
> > +#include <dirent.h>
> > +#include <sys/types.h>
> > +#include <sys/stat.h>
> > +#include <unistd.h>
> > +#include <keyutils.h>
> > +#include <stdint.h>
> > +#include <stdbool.h>
> > +#include <stdio.h>
> > +#include <stdlib.h>
> > +#include <errno.h>
> > +#include <limits.h>
> > +#include <wbclient.h>
> > +
> > +static const char *prog = "cifs.idmap";
> > +
> > +static void usage(void)
> > +{
> > + Â Â Â fprintf(stderr, "Usage: %s key_serial\n", prog);
> > +}
> > +
> > +char *strget(const char *str, char *substr)
> > +{
> > + Â Â Â int len, sublen, retlen;
> > + Â Â Â char *retstr, *substrptr;
> > +
> > + Â Â Â sublen = strlen(substr);
> > + Â Â Â substrptr = strstr(str, substr);
> > + Â Â Â if (substrptr) {
> > + Â Â Â Â Â Â Â len = strlen(substrptr);
> > + Â Â Â Â Â Â Â substrptr += sublen;
> > +
> > + Â Â Â Â Â Â Â retlen = len - sublen;
> > + Â Â Â Â Â Â Â if (retlen > 0) {
> > + Â Â Â Â Â Â Â Â Â Â Â retstr = malloc(retlen + 1);
> > + Â Â Â Â Â Â Â Â Â Â Â if (retstr) {
> > + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â strncpy(retstr, substrptr, retlen);
> > + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â return retstr;
> > + Â Â Â Â Â Â Â Â Â Â Â }
> > + Â Â Â Â Â Â Â }
> > + Â Â Â }
> > +
> > + Â Â Â return NULL;
> > +}
> > +
> > +static int
> > +cifs_idmap(const key_serial_t key, const char *key_descr)
> > +{
> > + Â Â Â uid_t uid = 0;
> > + Â Â Â gid_t gid = 0;;
> > + Â Â Â wbcErr rc = 1;
> > + Â Â Â char *sidstr = NULL;
> > + Â Â Â struct wbcDomainSid sid;
> > + Â Â Â struct passwd *pw;
> > + Â Â Â struct group *gr;
> > +
> > + Â Â Â /*
> > + Â Â Â Â* Use winbind to convert received string to a SID and lookup
> > + Â Â Â Â* name and map that SID to an uid. ÂIf either of these
> > + Â Â Â Â* function calls return with an error, return an error the
> > + Â Â Â Â* upcall caller. ÂOtherwise instanticate a key using that uid.
> > + Â Â Â Â*
> > + Â Â Â Â* The same applies to SID and gid mapping.
> > + Â Â Â Â*/
> > + Â Â Â sidstr = strget(key_descr, "os:");
> > + Â Â Â if (sidstr) {
> > + Â Â Â Â Â Â Â rc = wbcStringToSid(sidstr, &sid);
> > + Â Â Â Â Â Â Â if (rc)
> > + Â Â Â Â Â Â Â Â Â Â Â syslog(LOG_DEBUG, "Invalid owner string: %s, rc: %d",
> > + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â key_descr, rc);
> > + Â Â Â Â Â Â Â else {
> > + Â Â Â Â Â Â Â Â Â Â Â rc = wbcSidToUid(&sid, &uid);
> > + Â Â Â Â Â Â Â Â Â Â Â if (rc)
> > + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â syslog(LOG_DEBUG, "SID %s to uid wbc error: %d",
> > + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â key_descr, rc);
> > + Â Â Â Â Â Â Â }
> > + Â Â Â Â Â Â Â if (!rc) { /* SID has been mapped to an uid */
> > + Â Â Â Â Â Â Â Â Â Â Â rc = keyctl_instantiate(key, &uid, sizeof(uid_t), 0);
> > + Â Â Â Â Â Â Â Â Â Â Â if (rc)
> > + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â syslog(LOG_ERR, "%s: key inst: %s",
> > + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â __func__, strerror(errno));
> > + Â Â Â Â Â Â Â }
> > +
> > + Â Â Â Â Â Â Â goto cifs_idmap_ret;
> > + Â Â Â }
> > +
> > + Â Â Â sidstr = strget(key_descr, "gs:");
> > + Â Â Â if (sidstr) {
> > + Â Â Â Â Â Â Â rc = wbcStringToSid(sidstr, &sid);
> > + Â Â Â Â Â Â Â if (rc)
> > + Â Â Â Â Â Â Â Â Â Â Â syslog(LOG_DEBUG, "Invalid group string: %s, rc: %d",
> > + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â key_descr, rc);
> > + Â Â Â Â Â Â Â else {
> > + Â Â Â Â Â Â Â Â Â Â Â rc = wbcSidToGid(&sid, &gid);
> > + Â Â Â Â Â Â Â Â Â Â Â if (rc)
> > + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â syslog(LOG_DEBUG, "SID %s to gid wbc error: %d",
> > + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â key_descr, rc);
> > + Â Â Â Â Â Â Â }
> > + Â Â Â Â Â Â Â if (!rc) { /* SID has been mapped to a gid */
> > + Â Â Â Â Â Â Â Â Â Â Â rc = keyctl_instantiate(key, &gid, sizeof(gid_t), 0);
> > + Â Â Â Â Â Â Â Â Â Â Â if (rc)
> > + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â syslog(LOG_ERR, "%s: key inst: %s",
> > + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â __func__, strerror(errno));
> > + Â Â Â Â Â Â Â }
> > +
> > + Â Â Â Â Â Â Â goto cifs_idmap_ret;
> > + Â Â Â }
> > +
> > + Â Â Â syslog(LOG_DEBUG, "Invalid key: %s", key_descr);
> > +
> > +cifs_idmap_ret:
> > + Â Â Â if (sidstr)
> > + Â Â Â Â Â Â Â free(sidstr);
> > +
> > + Â Â Â return rc;
> > +}
> > +
> > +int main(const int argc, char *const argv[])
> > +{
> > + Â Â Â int c;
> > + Â Â Â long rc = 1;
> > + Â Â Â key_serial_t key = 0;
> > + Â Â Â char *buf;
> > +
> > + Â Â Â openlog(prog, 0, LOG_DAEMON);
> > +
> > + Â Â Â while ((c = getopt_long(argc, argv, "v", NULL, NULL)) != -1) {
> > + Â Â Â Â Â Â Â switch (c) {
> > + Â Â Â Â Â Â Â case 'v':
> > + Â Â Â Â Â Â Â Â Â Â Â printf("version: %s\n", VERSION);
> > + Â Â Â Â Â Â Â Â Â Â Â goto out;
> > + Â Â Â Â Â Â Â default:
> > + Â Â Â Â Â Â Â Â Â Â Â syslog(LOG_ERR, "unknown option: %c", c);
> > + Â Â Â Â Â Â Â Â Â Â Â goto out;
> > + Â Â Â Â Â Â Â }
> > + Â Â Â }
> > +
> > + Â Â Â /* is there a key? */
> > + Â Â Â if (argc <= optind) {
> > + Â Â Â Â Â Â Â usage();
> > + Â Â Â Â Â Â Â goto out;
> > + Â Â Â }
> > +
> > + Â Â Â /* get key and keyring values */
> > + Â Â Â errno = 0;
> > + Â Â Â key = strtol(argv[optind], NULL, 10);
> > + Â Â Â if (errno != 0) {
> > + Â Â Â Â Â Â Â key = 0;
> > + Â Â Â Â Â Â Â syslog(LOG_ERR, "Invalid key format: %s", strerror(errno));
> > + Â Â Â Â Â Â Â goto out;
> > + Â Â Â }
> > +
> > + Â Â Â rc = keyctl_describe_alloc(key, &buf);
> > + Â Â Â if (rc == -1) {
> > + Â Â Â Â Â Â Â syslog(LOG_ERR, "keyctl_describe_alloc failed: %s",
> > + Â Â Â Â Â Â Â Â Â Â Âstrerror(errno));
> > + Â Â Â Â Â Â Â rc = 1;
> > + Â Â Â Â Â Â Â goto out;
> > + Â Â Â }
> > +
> > + Â Â Â syslog(LOG_DEBUG, "key description: %s", buf);
> > +
> > + Â Â Â if ((strncmp(buf, "cifs.idmap", sizeof("cifs.idmap") - 1) == 0))
> > + Â Â Â Â Â Â Â rc = cifs_idmap(key, buf);
> > +out:
> > + Â Â Â return rc;
> > +}
> > diff --git a/configure.ac b/configure.ac
> > index e0e2a60..6cac703 100644
> > --- a/configure.ac
> > +++ b/configure.ac
> > @@ -22,13 +22,19 @@ AC_ARG_ENABLE(cifscreds,
> > Â Â Â Âenable_cifscreds=$enableval,
> > Â Â Â Âenable_cifscreds="no")
> >
> > +AC_ARG_ENABLE(cifsidmap,
> > + Â Â Â [AC_HELP_STRING([--enable-cifsidmap],
> > + Â Â Â Â Â Â Â Â Â Â Â [Create cifs.idmap binary @<:@default=no@:>@])],
> > + Â Â Â enable_cifsidmap=$enableval,
> > + Â Â Â enable_cifsidmap="no")
> > +
> > Â# Checks for programs.
> > ÂAC_PROG_CC
> > ÂAC_PROG_SED
> > ÂAC_GNU_SOURCE
> >
> > Â# Checks for header files.
> > -AC_CHECK_HEADERS([arpa/inet.h ctype.h fcntl.h inttypes.h limits.h mntent.h netdb.h stddef.h stdint.h stdlib.h string.h strings.h sys/mount.h sys/param.h sys/socket.h sys/time.h syslog.h unistd.h], , [AC_MSG_ERROR([necessary header(s) not found])])
> > +AC_CHECK_HEADERS([arpa/inet.h ctype.h fcntl.h inttypes.h limits.h mntent.h netdb.h stddef.h stdint.h stdbool.h stdlib.h stdio.h errno.h string.h strings.h sys/mount.h sys/param.h sys/socket.h sys/time.h syslog.h unistd.h], , [AC_MSG_ERROR([necessary header(s) not found])])
> >
> > Âif test $enable_cifsupcall != "no"; then
> > Â Â Â ÂAC_CHECK_HEADERS([krb5.h krb5/krb5.h])
> > @@ -72,7 +78,7 @@ if test $enable_cifsupcall != "no"; then
> > Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Âfi
> > Â Â Â Â Â Â Â Â Â Â Â Â])
> > Âfi
> > -if test $enable_cifsupcall != "no"; then
> > +if test $enable_cifsupcall != "no" -o $enable_cifsidmap != "no"; then
> > Â Â Â ÂAC_CHECK_HEADERS([keyutils.h], , [
> > Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Âif test "$enable_cifsupcall" = "yes"; then
> > Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â ÂAC_MSG_ERROR([keyutils.h not found, consider installing keyutils-libs-devel.])
> > @@ -80,6 +86,9 @@ if test $enable_cifsupcall != "no"; then
> > Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â ÂAC_MSG_WARN([keyutils.h not found, consider installing keyutils-libs-devel. Disabling cifs.upcall.])
> > Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Âenable_cifsupcall="no"
> > Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Âfi
> > + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â if test "$enable_cifsidmap" = "yes"; then
> > + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â AC_MSG_ERROR([keyutils.h not found, consider installing keyutils-libs-devel.])
> > + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â fi
> > Â Â Â Â Â Â Â Â Â Â Â Â])
> > Âfi
> > Âif test $enable_cifsupcall != "no"; then
> > @@ -89,6 +98,9 @@ if test $enable_cifsupcall != "no"; then
> > Â Â Â ÂAC_SUBST(KRB5_LDADD)
> > Âfi
> >
> > +# checks for wbclient.h and libwbclient.so library
> > +AC_TEST_WBCHL
> > +
> > Âif test $enable_cifscreds = "yes"; then
> > Â Â Â ÂAC_CHECK_HEADERS([keyutils.h], , [AC_MSG_ERROR([keyutils.h not found, consider installing keyutils-libs-devel.])])
> > Âfi
> > @@ -140,6 +152,7 @@ LIBS=$cu_saved_libs
> >
> > ÂAM_CONDITIONAL(CONFIG_CIFSUPCALL, [test "$enable_cifsupcall" != "no"])
> > ÂAM_CONDITIONAL(CONFIG_CIFSCREDS, [test "$enable_cifscreds" = "yes"])
> 
> > +AM_CONDITIONAL(CONFIG_CIFSIDMAP, [test "$enable_cifsidmap" = "yes"])
> 
> Jeff, this modified patch looks fine. I will soon get in the man page,
> related changes, along with changing this line to != 'no' to complete
> all the changes necessary for id mapping.
> 

Ok, committed along with a patch to remove a couple of unused
variables. I'll probably ship the next release with this set to "no".
We can discuss changing that afterward since this has implications for
people packaging cifs-utils.

-- 
Jeff Layton <jlayton@xxxxxxxxxx>
--
To unsubscribe from this list: send the line "unsubscribe linux-cifs" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux