Update to latest upstream patches

- fix link of libwbclient
- add pam_cifscreds module and manpage

Signed-off-by: Jeff Layton <jlayton@redhat.com>
This commit is contained in:
Jeff Layton 2013-12-13 08:28:09 -05:00
parent a78ee49fd2
commit 143499a82c
5 changed files with 1445 additions and 3 deletions

View File

@ -0,0 +1,36 @@
From 2152ccc3d61e5248c70360020a0aa279a24f852c Mon Sep 17 00:00:00 2001
From: Jeff Layton <jlayton@samba.org>
Date: Sat, 7 Dec 2013 08:54:59 -0500
Subject: [cifs-utils PATCH] autoconf: fix link of libwbclient
It's currently getting added to $LIBS and being linked into places that
we don't need it.
Signed-off-by: Jeff Layton <jlayton@samba.org>
---
aclocal/idmap.m4 | 2 ++
1 file changed, 2 insertions(+)
diff --git a/aclocal/idmap.m4 b/aclocal/idmap.m4
index c5727f6..3ccdae3 100644
--- a/aclocal/idmap.m4
+++ b/aclocal/idmap.m4
@@ -21,6 +21,7 @@ fi
if test $enable_cifsacl != "no" -o $enable_cifsacl != "no"; then
ac_wbc_save_LDFLAGS="$LDFLAGS"
+ ac_wbc_save_LIBS="$LIBS"
LDFLAGS="$LDFLAGS $WBCLIENT_LIBS"
AC_CHECK_LIB(wbclient, wbcSidsToUnixIds, , [
if test "$enable_cifsidmap" = "yes"; then
@@ -37,6 +38,7 @@ if test $enable_cifsacl != "no" -o $enable_cifsacl != "no"; then
fi
])
LDFLAGS=$ac_wbc_save_LDFLAGS
+ LIBS=$ac_wbc_save_LIBS
fi
if test $enable_cifsacl != "no"; then
--
1.8.4.2

View File

@ -0,0 +1,862 @@
From cbbcd6e71c0a58e79236670463b9eb3f00347021 Mon Sep 17 00:00:00 2001
From: Orion Poplawski <orion@nwra.com>
Date: Wed, 13 Nov 2013 13:53:30 -0700
Subject: [cifs-utils PATCH] cifscreds: create PAM module to insert credentials
at login
Split out some of the cifscreds key handling routines into a separate
file, and then link that in to both cifscreds and the new PAM module.
Fix up autoconf to handle building this automatically.
Signed-off-by: Orion Poplawski <orion@nwra.com>
---
Makefile.am | 11 +-
cifscreds.c | 49 +----
cifskey.c | 52 ++++++
cifskey.h | 47 +++++
configure.ac | 24 ++-
pam_cifscreds.c | 550 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
6 files changed, 681 insertions(+), 52 deletions(-)
create mode 100644 cifskey.c
create mode 100644 cifskey.h
create mode 100644 pam_cifscreds.c
diff --git a/Makefile.am b/Makefile.am
index 6407520..6e86cd3 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -34,7 +34,7 @@ endif
if CONFIG_CIFSCREDS
bin_PROGRAMS += cifscreds
-cifscreds_SOURCES = cifscreds.c resolve_host.c util.c
+cifscreds_SOURCES = cifscreds.c cifskey.c resolve_host.c util.c
cifscreds_LDADD = -lkeyutils
man_MANS += cifscreds.1
endif
@@ -91,4 +91,13 @@ idmapwb.8: idmapwb.8.in
endif
+if CONFIG_PAM
+pamdir = $(libdir)/security
+
+pam_PROGRAMS = pam_cifscreds.so
+
+pam_cifscreds.so: pam_cifscreds.c cifskey.c resolve_host.c util.c
+ $(CC) $(CFLAGS) $(AM_CFLAGS) $(LDFLAGS) -shared -fpic -o $@ $+ -lpam -lkeyutils
+endif
+
SUBDIRS = contrib
diff --git a/cifscreds.c b/cifscreds.c
index 60be4e5..fa05dc8 100644
--- a/cifscreds.c
+++ b/cifscreds.c
@@ -29,35 +29,16 @@
#include <keyutils.h>
#include <getopt.h>
#include <errno.h>
+#include "cifskey.h"
#include "mount.h"
#include "resolve_host.h"
#include "util.h"
#define THIS_PROGRAM_NAME "cifscreds"
-#define KEY_PREFIX "cifs"
/* max length of appropriate command */
#define MAX_COMMAND_SIZE 32
-/* max length of username, password and domain name */
-#define MAX_USERNAME_SIZE 32
-#define MOUNT_PASSWD_SIZE 128
-#define MAX_DOMAIN_SIZE 64
-
-/*
- * disallowed characters for user and domain names. See:
- * http://technet.microsoft.com/en-us/library/bb726984.aspx
- * http://support.microsoft.com/kb/909264
- */
-#define USER_DISALLOWED_CHARS "\\/\"[]:|<>+=;,?*"
-#define DOMAIN_DISALLOWED_CHARS "\\/:*?\"<>|"
-
-/* destination keyring */
-#define DEST_KEYRING KEY_SPEC_SESSION_KEYRING
-#define CIFS_KEY_TYPE "logon"
-#define CIFS_KEY_PERMS (KEY_POS_VIEW|KEY_POS_WRITE|KEY_POS_SEARCH| \
- KEY_USR_VIEW|KEY_USR_WRITE|KEY_USR_SEARCH)
-
struct cmdarg {
char *host;
char *user;
@@ -106,17 +87,6 @@ usage(void)
return EXIT_FAILURE;
}
-/* search a specific key in keyring */
-static key_serial_t
-key_search(const char *addr, char keytype)
-{
- char desc[INET6_ADDRSTRLEN + sizeof(KEY_PREFIX) + 4];
-
- sprintf(desc, "%s:%c:%s", KEY_PREFIX, keytype, addr);
-
- return keyctl_search(DEST_KEYRING, CIFS_KEY_TYPE, desc, 0);
-}
-
/* search all program's keys in keyring */
static key_serial_t key_search_all(void)
{
@@ -170,23 +140,6 @@ key_search_all_out:
return ret;
}
-/* add or update a specific key to keyring */
-static key_serial_t
-key_add(const char *addr, const char *user, const char *pass, char keytype)
-{
- int len;
- char desc[INET6_ADDRSTRLEN + sizeof(KEY_PREFIX) + 4];
- char val[MOUNT_PASSWD_SIZE + MAX_USERNAME_SIZE + 2];
-
- /* set key description */
- sprintf(desc, "%s:%c:%s", KEY_PREFIX, keytype, addr);
-
- /* set payload contents */
- len = sprintf(val, "%s:%s", user, pass);
-
- return add_key(CIFS_KEY_TYPE, desc, val, len + 1, DEST_KEYRING);
-}
-
/* add command handler */
static int cifscreds_add(struct cmdarg *arg)
{
diff --git a/cifskey.c b/cifskey.c
new file mode 100644
index 0000000..7716c42
--- /dev/null
+++ b/cifskey.c
@@ -0,0 +1,52 @@
+/*
+ * Credentials stashing routines for Linux CIFS VFS (virtual filesystem)
+ * Copyright (C) 2010 Jeff Layton (jlayton@samba.org)
+ * Copyright (C) 2010 Igor Druzhinin (jaxbrigs@gmail.com)
+ *
+ * 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/>.
+ */
+
+#include <sys/types.h>
+#include <keyutils.h>
+#include <stdio.h>
+#include "cifskey.h"
+#include "resolve_host.h"
+
+/* search a specific key in keyring */
+key_serial_t
+key_search(const char *addr, char keytype)
+{
+ char desc[INET6_ADDRSTRLEN + sizeof(KEY_PREFIX) + 4];
+
+ sprintf(desc, "%s:%c:%s", KEY_PREFIX, keytype, addr);
+
+ return keyctl_search(DEST_KEYRING, CIFS_KEY_TYPE, desc, 0);
+}
+
+/* add or update a specific key to keyring */
+key_serial_t
+key_add(const char *addr, const char *user, const char *pass, char keytype)
+{
+ int len;
+ char desc[INET6_ADDRSTRLEN + sizeof(KEY_PREFIX) + 4];
+ char val[MOUNT_PASSWD_SIZE + MAX_USERNAME_SIZE + 2];
+
+ /* set key description */
+ sprintf(desc, "%s:%c:%s", KEY_PREFIX, keytype, addr);
+
+ /* set payload contents */
+ len = sprintf(val, "%s:%s", user, pass);
+
+ return add_key(CIFS_KEY_TYPE, desc, val, len + 1, DEST_KEYRING);
+}
diff --git a/cifskey.h b/cifskey.h
new file mode 100644
index 0000000..ed0c469
--- /dev/null
+++ b/cifskey.h
@@ -0,0 +1,47 @@
+/*
+ * Credentials stashing utility for Linux CIFS VFS (virtual filesystem) definitions
+ * Copyright (C) 2010 Jeff Layton (jlayton@samba.org)
+ * Copyright (C) 2010 Igor Druzhinin (jaxbrigs@gmail.com)
+ *
+ * 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/>.
+ */
+
+#ifndef _CIFSKEY_H
+#define _CIFSKEY_H
+
+#define KEY_PREFIX "cifs"
+
+/* max length of username, password and domain name */
+#define MAX_USERNAME_SIZE 32
+#define MOUNT_PASSWD_SIZE 128
+#define MAX_DOMAIN_SIZE 64
+
+/*
+ * disallowed characters for user and domain names. See:
+ * http://technet.microsoft.com/en-us/library/bb726984.aspx
+ * http://support.microsoft.com/kb/909264
+ */
+#define USER_DISALLOWED_CHARS "\\/\"[]:|<>+=;,?*"
+#define DOMAIN_DISALLOWED_CHARS "\\/:*?\"<>|"
+
+/* destination keyring */
+#define DEST_KEYRING KEY_SPEC_SESSION_KEYRING
+#define CIFS_KEY_TYPE "logon"
+#define CIFS_KEY_PERMS (KEY_POS_VIEW|KEY_POS_WRITE|KEY_POS_SEARCH| \
+ KEY_USR_VIEW|KEY_USR_WRITE|KEY_USR_SEARCH)
+
+key_serial_t key_search(const char *addr, char keytype);
+key_serial_t key_add(const char *addr, const char *user, const char *pass, char keytype);
+
+#endif /* _CIFSKEY_H */
diff --git a/configure.ac b/configure.ac
index c5b2244..4a9cb6d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -40,6 +40,11 @@ AC_ARG_ENABLE(cifsacl,
enable_cifsacl=$enableval,
enable_cifsacl="maybe")
+AC_ARG_ENABLE(pam,
+ [AS_HELP_STRING([--enable-pam],[Create cifscreds PAM module @<:@default=yes@:>@])],
+ enable_pam=$enableval,
+ enable_pam="maybe")
+
AC_ARG_ENABLE(systemd,
[AS_HELP_STRING([--enable-systemd],[Enable systemd specific behavior for mount.cifs @<:@default=yes@:>@])],
enable_systemd=$enableval,
@@ -190,18 +195,30 @@ AC_TEST_WBCHL
# test for presence of WBC_ID_TYPE_BOTH enum value
AC_TEST_WBC_IDMAP_BOTH
-if test $enable_cifscreds != "no"; then
+if test $enable_cifscreds != "no" -o $enable_pam != "no"; then
AC_CHECK_HEADERS([keyutils.h], , [
- if test $enable_cifscreds = "yes"; then
+ if test $enable_cifscreds = "yes" -o $enable_pam = "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 cifscreds.])
+ AC_MSG_WARN([keyutils.h not found, consider installing keyutils-libs-devel. Disabling cifscreds and cifscreds PAM module.])
enable_cifscreds="no"
+ enable_pam="no"
fi
])
fi
+if test $enable_pam != "no"; then
+ AC_CHECK_HEADERS([security/pam_appl.h], , [
+
+ if test $enable_pam = "yes"; then
+ AC_MSG_ERROR([security/pam_appl.h not found, consider installing keyutils-libs-devel.])
+ else
+ AC_MSG_WARN([security/pam_appl.h not found, consider installing pam-devel. Disabling cifscreds PAM module.])
+ enable_pam="no"
+ fi
+ ])
+fi
# ugly, but I'm not sure how to check for functions in a library that's not in $LIBS
cu_saved_libs=$LIBS
@@ -231,6 +248,7 @@ AM_CONDITIONAL(CONFIG_CIFSUPCALL, [test "$enable_cifsupcall" != "no"])
AM_CONDITIONAL(CONFIG_CIFSCREDS, [test "$enable_cifscreds" != "no"])
AM_CONDITIONAL(CONFIG_CIFSIDMAP, [test "$enable_cifsidmap" != "no"])
AM_CONDITIONAL(CONFIG_CIFSACL, [test "$enable_cifsacl" != "no"])
+AM_CONDITIONAL(CONFIG_PAM, [test "$enable_pam" != "no"])
AM_CONDITIONAL(CONFIG_PLUGIN, [test "$enable_cifsidmap" != "no" -o "$enable_cifsacl" != "no"])
LIBCAP_NG_PATH
diff --git a/pam_cifscreds.c b/pam_cifscreds.c
new file mode 100644
index 0000000..1385146
--- /dev/null
+++ b/pam_cifscreds.c
@@ -0,0 +1,550 @@
+/*
+ * Copyright (C) 2013 Orion Poplawski <orion@cora.nwra.com>
+ *
+ * based on gkr-pam-module.c, Copyright (C) 2007 Stef Walter
+ *
+ * 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, write to the Free Software
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif /* HAVE_CONFIG_H */
+
+#include <assert.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <syslog.h>
+#include <sys/types.h>
+/*
+#include <signal.h>
+#include <unistd.h>
+#include <sys/wait.h>
+*/
+
+#include <keyutils.h>
+
+#include <security/pam_appl.h>
+#include <security/pam_modules.h>
+#include <security/pam_ext.h>
+
+#include "cifskey.h"
+#include "mount.h"
+#include "resolve_host.h"
+#include "util.h"
+
+/**
+ * Flags that can be passed to the PAM module
+ */
+enum {
+ ARG_DOMAIN = 1 << 0, /** Set domain password */
+ ARG_DEBUG = 1 << 1 /** Print debug messages */
+};
+
+/**
+ * Parse the arguments passed to the PAM module.
+ *
+ * @param ph PAM handle
+ * @param argc number of arguments
+ * @param argv array of arguments
+ * @param kwalletopener kwalletopener argument, path to the kwalletopener binary
+ * @return ORed flags that have been parsed
+ */
+static uint parse_args (pam_handle_t *ph, int argc, const char **argv, const char **hostdomain)
+{
+ uint args = 0;
+ const void *svc;
+ int i;
+ const char *host = NULL;
+ const char *domain = NULL;
+
+ svc = NULL;
+ if (pam_get_item (ph, PAM_SERVICE, &svc) != PAM_SUCCESS) {
+ svc = NULL;
+ }
+
+ size_t host_len = strlen("host=");
+ size_t domain_len = strlen("domain=");
+
+ /* Parse the arguments */
+ for (i = 0; i < argc; i++) {
+ if (strncmp(argv[i], "host=", host_len) == 0) {
+ host = (argv[i]) + host_len;
+ if (*host == '\0') {
+ host = NULL;
+ pam_syslog(ph, LOG_ERR, ""
+ "host= specification missing argument");
+ } else {
+ *hostdomain = host;
+ }
+ } else if (strncmp(argv[i], "domain=", domain_len) == 0) {
+ domain = (argv[i]) + domain_len;
+ if (*domain == '\0') {
+ domain = NULL;
+ pam_syslog(ph, LOG_ERR, ""
+ "domain= specification missing argument");
+ } else {
+ *hostdomain = domain;
+ args |= ARG_DOMAIN;
+ }
+ } else if (strcmp(argv[i], "debug") == 0) {
+ args |= ARG_DEBUG;
+ } else {
+ pam_syslog(ph, LOG_ERR, "invalid option %s",
+ argv[i]);
+ }
+ }
+
+ if (host && domain) {
+ pam_syslog(ph, LOG_ERR, "cannot specify both host= and "
+ "domain= arguments");
+ }
+
+ return args;
+}
+
+static void
+free_password (char *password)
+{
+ volatile char *vp;
+ size_t len;
+
+ if (!password) {
+ return;
+ }
+
+ /* Defeats some optimizations */
+ len = strlen (password);
+ memset (password, 0xAA, len);
+ memset (password, 0xBB, len);
+
+ /* Defeats others */
+ vp = (volatile char*)password;
+ while (*vp) {
+ *(vp++) = 0xAA;
+ }
+
+ free (password);
+}
+
+static void
+cleanup_free_password (pam_handle_t *ph, void *data, int pam_end_status)
+{
+ free_password (data);
+}
+
+/**
+ * Set the cifs credentials
+ *
+ * @param ph PAM handle
+ * @param user
+ * @param password
+ * @param args ORed flags for this module
+ * @param hostdomain hostname or domainname
+ */
+static int cifscreds_pam_add(pam_handle_t *ph, const char *user, const char *password,
+ uint args, const char *hostdomain)
+{
+ int ret = PAM_SUCCESS;
+ char addrstr[MAX_ADDR_LIST_LEN];
+ char *currentaddress, *nextaddress;
+ char keytype = ((args & ARG_DOMAIN) == ARG_DOMAIN) ? 'd' : 'a';
+
+ assert(user);
+ assert(password);
+ assert(hostdomain);
+
+ if (keytype == 'd') {
+ if (strpbrk(hostdomain, DOMAIN_DISALLOWED_CHARS)) {
+ pam_syslog(ph, LOG_ERR, "Domain name contains invalid characters");
+ return PAM_SERVICE_ERR;
+ }
+ strlcpy(addrstr, hostdomain, MAX_ADDR_LIST_LEN);
+ } else {
+ ret = resolve_host(hostdomain, addrstr);
+ }
+
+ switch (ret) {
+ case EX_USAGE:
+ pam_syslog(ph, LOG_ERR, "Could not resolve address for %s", hostdomain);
+ return PAM_SERVICE_ERR;
+
+ case EX_SYSERR:
+ pam_syslog(ph, LOG_ERR, "Problem parsing address list");
+ return PAM_SERVICE_ERR;
+ }
+
+ if (strpbrk(user, USER_DISALLOWED_CHARS)) {
+ pam_syslog(ph, LOG_ERR, "Incorrect username");
+ return PAM_SERVICE_ERR;
+ }
+
+ /* search for same credentials stashed for current host */
+ currentaddress = addrstr;
+ nextaddress = strchr(currentaddress, ',');
+ if (nextaddress)
+ *nextaddress++ = '\0';
+
+ while (currentaddress) {
+ if (key_search(currentaddress, keytype) > 0) {
+ pam_syslog(ph, LOG_WARNING, "You already have stashed credentials "
+ "for %s (%s)", currentaddress, hostdomain);
+
+ return PAM_SERVICE_ERR;
+ }
+
+ currentaddress = nextaddress;
+ if (currentaddress) {
+ *(currentaddress - 1) = ',';
+ nextaddress = strchr(currentaddress, ',');
+ if (nextaddress)
+ *nextaddress++ = '\0';
+ }
+ }
+
+ /* Set the password */
+ currentaddress = addrstr;
+ nextaddress = strchr(currentaddress, ',');
+ if (nextaddress)
+ *nextaddress++ = '\0';
+
+ while (currentaddress) {
+ key_serial_t key = key_add(currentaddress, user, password, keytype);
+ if (key <= 0) {
+ pam_syslog(ph, LOG_ERR, "error: Add credential key for %s",
+ currentaddress);
+ } else {
+ if ((args & ARG_DEBUG) == ARG_DEBUG) {
+ pam_syslog(ph, LOG_DEBUG, "credential key for \\\\%s\\%s added",
+ currentaddress, user);
+ }
+ if (keyctl(KEYCTL_SETPERM, key, CIFS_KEY_PERMS) < 0) {
+ pam_syslog(ph, LOG_ERR,"error: Setting permissons "
+ "on key, attempt to delete...");
+
+ if (keyctl(KEYCTL_UNLINK, key, DEST_KEYRING) < 0) {
+ pam_syslog(ph, LOG_ERR, "error: Deleting key from "
+ "keyring for %s (%s)",
+ currentaddress, hostdomain);
+ }
+ }
+ }
+
+ currentaddress = nextaddress;
+ if (currentaddress) {
+ nextaddress = strchr(currentaddress, ',');
+ if (nextaddress)
+ *nextaddress++ = '\0';
+ }
+ }
+
+ return PAM_SUCCESS;
+}
+
+/**
+ * Update the cifs credentials
+ *
+ * @param ph PAM handle
+ * @param user
+ * @param password
+ * @param args ORed flags for this module
+ * @param hostdomain hostname or domainname
+ */
+static int cifscreds_pam_update(pam_handle_t *ph, const char *user, const char *password,
+ uint args, const char *hostdomain)
+{
+ int ret = PAM_SUCCESS;
+ char addrstr[MAX_ADDR_LIST_LEN];
+ char *currentaddress, *nextaddress;
+ char *addrs[16];
+ int id, count = 0;
+ char keytype = ((args & ARG_DOMAIN) == ARG_DOMAIN) ? 'd' : 'a';
+
+ assert(user);
+ assert(password);
+ assert(hostdomain);
+
+ if (keytype == 'd') {
+ if (strpbrk(hostdomain, DOMAIN_DISALLOWED_CHARS)) {
+ pam_syslog(ph, LOG_ERR, "Domain name contains invalid characters");
+ return PAM_SERVICE_ERR;
+ }
+ strlcpy(addrstr, hostdomain, MAX_ADDR_LIST_LEN);
+ } else {
+ ret = resolve_host(hostdomain, addrstr);
+ }
+
+ switch (ret) {
+ case EX_USAGE:
+ pam_syslog(ph, LOG_ERR, "Could not resolve address for %s", hostdomain);
+ return PAM_SERVICE_ERR;
+
+ case EX_SYSERR:
+ pam_syslog(ph, LOG_ERR, "Problem parsing address list");
+ return PAM_SERVICE_ERR;
+ }
+
+ if (strpbrk(user, USER_DISALLOWED_CHARS)) {
+ pam_syslog(ph, LOG_ERR, "Incorrect username");
+ return PAM_SERVICE_ERR;
+ }
+
+ /* search for necessary credentials stashed in session keyring */
+ currentaddress = addrstr;
+ nextaddress = strchr(currentaddress, ',');
+ if (nextaddress)
+ *nextaddress++ = '\0';
+
+ while (currentaddress) {
+ if (key_search(currentaddress, keytype) > 0) {
+ addrs[count] = currentaddress;
+ count++;
+ }
+
+ currentaddress = nextaddress;
+ if (currentaddress) {
+ nextaddress = strchr(currentaddress, ',');
+ if (nextaddress)
+ *nextaddress++ = '\0';
+ }
+ }
+
+ if (!count) {
+ pam_syslog(ph, LOG_ERR, "You have no same stached credentials for %s", hostdomain);
+ return PAM_SERVICE_ERR;
+ }
+
+ for (id = 0; id < count; id++) {
+ key_serial_t key = key_add(currentaddress, user, password, keytype);
+ if (key <= 0) {
+ pam_syslog(ph, LOG_ERR, "error: Update credential key for %s",
+ currentaddress);
+ }
+ }
+
+ return PAM_SUCCESS;
+}
+
+/**
+ * PAM function called during authentication.
+ *
+ * This function first tries to get a password from PAM. Afterwards two
+ * scenarios are possible:
+ *
+ * - A session is already available which usually means that the user is already
+ * logged on and PAM has been used inside the screensaver. In that case, no need to
+ * do anything(?).
+ *
+ * - A session is not yet available. Store the password inside PAM data so
+ * it can be retrieved during pam_open_session to set the credentials.
+ *
+ * @param ph PAM handle
+ * @param unused unused
+ * @param argc number of arguments for this PAM module
+ * @param argv array of arguments for this PAM module
+ * @return any of the PAM return values
+ */
+PAM_EXTERN int pam_sm_authenticate(pam_handle_t *ph, int unused, int argc, const char **argv)
+{
+ const char *hostdomain;
+ const char *user;
+ const char *password;
+ uint args;
+ int ret;
+
+ args = parse_args(ph, argc, argv, &hostdomain);
+
+ /* Figure out and/or prompt for the user name */
+ ret = pam_get_user(ph, &user, NULL);
+ if (ret != PAM_SUCCESS || !user) {
+ pam_syslog(ph, LOG_ERR, "couldn't get the user name: %s",
+ pam_strerror(ph, ret));
+ return PAM_SERVICE_ERR;
+ }
+
+ /* Lookup the password */
+ ret = pam_get_item(ph, PAM_AUTHTOK, (const void**)&password);
+ if (ret != PAM_SUCCESS || password == NULL) {
+ if (ret == PAM_SUCCESS) {
+ pam_syslog(ph, LOG_WARNING, "no password is available for user");
+ } else {
+ pam_syslog(ph, LOG_WARNING, "no password is available for user: %s",
+ pam_strerror(ph, ret));
+ }
+ return PAM_SUCCESS;
+ }
+
+ /* set password as pam data and launch during open_session. */
+ if (pam_set_data(ph, "cifscreds_password", strdup(password), cleanup_free_password) != PAM_SUCCESS) {
+ pam_syslog(ph, LOG_ERR, "error storing password");
+ return PAM_AUTHTOK_RECOVER_ERR;
+ }
+
+ if ((args & ARG_DEBUG) == ARG_DEBUG) {
+ pam_syslog(ph, LOG_DEBUG, "password stored");
+ }
+
+ return PAM_SUCCESS;
+}
+
+/**
+ * PAM function called during opening the session.
+ *
+ * Retrieves the password stored during authentication from PAM data, then uses
+ * it set the cifs key.
+ *
+ * @param ph PAM handle
+ * @param flags currently unused, TODO: check for silent flag
+ * @param argc number of arguments for this PAM module
+ * @param argv array of arguments for this PAM module
+ * @return any of the PAM return values
+ */
+PAM_EXTERN int pam_sm_open_session(pam_handle_t *ph, int flags, int argc, const char **argv)
+{
+ const char *user = NULL;
+ const char *password = NULL;
+ const char *hostdomain = NULL;
+ uint args;
+ int retval;
+ key_serial_t ses_key, uses_key;
+
+ args = parse_args(ph, argc, argv, &hostdomain);
+
+ /* Figure out the user name */
+ retval = pam_get_user(ph, &user, NULL);
+ if (retval != PAM_SUCCESS || !user) {
+ pam_syslog(ph, LOG_ERR, "couldn't get the user name: %s",
+ pam_strerror(ph, retval));
+ return PAM_SERVICE_ERR;
+ }
+
+ /* retrieve the stored password */
+ if (pam_get_data(ph, "cifscreds_password", (const void**)&password) != PAM_SUCCESS) {
+ /*
+ * No password, no worries, maybe this (PAM using) application
+ * didn't do authentication, or is hopeless and wants to call
+ * different PAM callbacks from different processes.
+ *
+ *
+ */
+ password = NULL;
+ if ((args & ARG_DEBUG) == ARG_DEBUG) {
+ pam_syslog(ph, LOG_DEBUG, "no stored password found");
+ }
+ return PAM_SUCCESS;
+ }
+
+ /* make sure we have a host or domain name */
+ if (!hostdomain) {
+ pam_syslog(ph, LOG_ERR, "one of host= or domain= must be specified");
+ return PAM_SERVICE_ERR;
+ }
+
+ /* make sure there is a session keyring */
+ ses_key = keyctl_get_keyring_ID(KEY_SPEC_SESSION_KEYRING, 0);
+ if (ses_key == -1) {
+ if (errno == ENOKEY)
+ pam_syslog(ph, LOG_ERR, "you have no session keyring. "
+ "Consider using pam_keyinit to "
+ "install one.");
+ else
+ pam_syslog(ph, LOG_ERR, "unable to query session "
+ "keyring: %s", strerror(errno));
+ }
+
+ /* A problem querying the user-session keyring isn't fatal. */
+ uses_key = keyctl_get_keyring_ID(KEY_SPEC_USER_SESSION_KEYRING, 0);
+ if ((uses_key >= 0) && (ses_key == uses_key))
+ pam_syslog(ph, LOG_ERR, "you have no persistent session "
+ "keyring. cifscreds keys will not persist.");
+
+ return cifscreds_pam_add(ph, user, password, args, hostdomain);
+}
+
+/**
+ * This is called when the PAM session is closed.
+ *
+ * Currently it does nothing. The session closing should remove the passwords
+ *
+ * @param ph PAM handle
+ * @param flags currently unused, TODO: check for silent flag
+ * @param argc number of arguments for this PAM module
+ * @param argv array of arguments for this PAM module
+ * @return PAM_SUCCESS
+ */
+PAM_EXTERN int pam_sm_close_session(pam_handle_t *ph, int flags, int argc, const char **argv)
+{
+ return PAM_SUCCESS;
+}
+
+/**
+ * This is called when pam_set_cred() is invoked.
+ *
+ * @param ph PAM handle
+ * @param flags currently unused, TODO: check for silent flag
+ * @param argc number of arguments for this PAM module
+ * @param argv array of arguments for this PAM module
+ * @return PAM_SUCCESS
+ */
+PAM_EXTERN int pam_sm_setcred(pam_handle_t *ph, int flags, int argc, const char **argv)
+{
+ return PAM_SUCCESS;
+}
+
+/**
+ * This is called when the user's password is changed
+ *
+ * @param ph PAM handle
+ * @param flags currently unused, TODO: check for silent flag
+ * @param argc number of arguments for this PAM module
+ * @param argv array of arguments for this PAM module
+ * @return PAM_SUCCESS
+ */
+PAM_EXTERN int
+pam_sm_chauthtok (pam_handle_t *ph, int flags, int argc, const char **argv)
+{
+ const char *hostdomain = NULL;
+ const char *user = NULL;
+ const char *password = NULL;
+ uint args;
+ int ret;
+
+ args = parse_args(ph, argc, argv, &hostdomain);
+
+ if (flags & PAM_UPDATE_AUTHTOK) {
+ /* Figure out the user name */
+ ret = pam_get_user(ph, &user, NULL);
+ if (ret != PAM_SUCCESS) {
+ pam_syslog(ph, LOG_ERR, "couldn't get the user name: %s",
+ pam_strerror (ph, ret));
+ return PAM_SERVICE_ERR;
+ }
+
+ ret = pam_get_item(ph, PAM_AUTHTOK, (const void**)&password);
+ if (ret != PAM_SUCCESS || password == NULL) {
+ if (ret == PAM_SUCCESS) {
+ pam_syslog(ph, LOG_WARNING, "no password is available for user");
+ } else {
+ pam_syslog(ph, LOG_WARNING, "no password is available for user: %s",
+ pam_strerror(ph, ret));
+ }
+ return PAM_AUTHTOK_RECOVER_ERR;
+ }
+
+ return cifscreds_pam_update(ph, user, password, args, hostdomain);
+ }
+ else
+ return PAM_IGNORE;
+}
--
1.8.4.2

View File

@ -0,0 +1,197 @@
From d12443fdd268e547412683d43dc03f266260f7c8 Mon Sep 17 00:00:00 2001
From: Jeff Layton <jlayton@samba.org>
Date: Sat, 7 Dec 2013 06:52:26 -0500
Subject: [cifs-utils PATCH] cifscreds: fix up some whitespace, typos and build
warnings in pam_cifscreds.c
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
gcc -g -O2 -Wall -Wextra -D_FORTIFY_SOURCE=2 -fpie -pie -Wl,-z,relro,-z,now -shared -fpic -o pam_cifscreds.so pam_cifscreds.c cifskey.c resolve_host.c util.c -lpam -lkeyutils
pam_cifscreds.c: In function cleanup_free_password:
pam_cifscreds.c:143:38: warning: unused parameter ph [-Wunused-parameter]
cleanup_free_password (pam_handle_t *ph, void *data, int pam_end_status)
^
pam_cifscreds.c:143:58: warning: unused parameter pam_end_status [-Wunused-parameter]
cleanup_free_password (pam_handle_t *ph, void *data, int pam_end_status)
^
pam_cifscreds.c: In function cifscreds_pam_update:
pam_cifscreds.c:271:8: warning: variable addrs set but not used [-Wunused-but-set-variable]
char *addrs[16];
^
pam_cifscreds.c: In function pam_sm_authenticate:
pam_cifscreds.c:359:58: warning: unused parameter unused [-Wunused-parameter]
PAM_EXTERN int pam_sm_authenticate(pam_handle_t *ph, int unused, int argc, const char **argv)
^
pam_cifscreds.c: In function pam_sm_open_session:
pam_cifscreds.c:414:58: warning: unused parameter flags [-Wunused-parameter]
PAM_EXTERN int pam_sm_open_session(pam_handle_t *ph, int flags, int argc, const char **argv)
^
pam_cifscreds.c: In function pam_sm_close_session:
pam_cifscreds.c:487:51: warning: unused parameter ph [-Wunused-parameter]
PAM_EXTERN int pam_sm_close_session(pam_handle_t *ph, int flags, int argc, const char **argv)
^
pam_cifscreds.c:487:59: warning: unused parameter flags [-Wunused-parameter]
PAM_EXTERN int pam_sm_close_session(pam_handle_t *ph, int flags, int argc, const char **argv)
^
pam_cifscreds.c:487:70: warning: unused parameter argc [-Wunused-parameter]
PAM_EXTERN int pam_sm_close_session(pam_handle_t *ph, int flags, int argc, const char **argv)
^
pam_cifscreds.c:487:89: warning: unused parameter argv [-Wunused-parameter]
PAM_EXTERN int pam_sm_close_session(pam_handle_t *ph, int flags, int argc, const char **argv)
^
pam_cifscreds.c: In function pam_sm_setcred:
pam_cifscreds.c:501:45: warning: unused parameter ph [-Wunused-parameter]
PAM_EXTERN int pam_sm_setcred(pam_handle_t *ph, int flags, int argc, const char **argv)
^
pam_cifscreds.c:501:53: warning: unused parameter flags [-Wunused-parameter]
PAM_EXTERN int pam_sm_setcred(pam_handle_t *ph, int flags, int argc, const char **argv)
^
pam_cifscreds.c:501:64: warning: unused parameter argc [-Wunused-parameter]
PAM_EXTERN int pam_sm_setcred(pam_handle_t *ph, int flags, int argc, const char **argv)
^
pam_cifscreds.c:501:83: warning: unused parameter argv [-Wunused-parameter]
PAM_EXTERN int pam_sm_setcred(pam_handle_t *ph, int flags, int argc, const char **argv)
^
Signed-off-by: Jeff Layton <jlayton@samba.org>
---
pam_cifscreds.c | 34 +++++++++++++++-------------------
1 file changed, 15 insertions(+), 19 deletions(-)
diff --git a/pam_cifscreds.c b/pam_cifscreds.c
index 1385146..e0d8a55 100644
--- a/pam_cifscreds.c
+++ b/pam_cifscreds.c
@@ -140,7 +140,8 @@ free_password (char *password)
}
static void
-cleanup_free_password (pam_handle_t *ph, void *data, int pam_end_status)
+cleanup_free_password (pam_handle_t *ph __attribute__((unused)), void *data,
+ int pam_end_status __attribute__((unused)))
{
free_password (data);
}
@@ -268,7 +269,6 @@ static int cifscreds_pam_update(pam_handle_t *ph, const char *user, const char *
int ret = PAM_SUCCESS;
char addrstr[MAX_ADDR_LIST_LEN];
char *currentaddress, *nextaddress;
- char *addrs[16];
int id, count = 0;
char keytype = ((args & ARG_DOMAIN) == ARG_DOMAIN) ? 'd' : 'a';
@@ -308,10 +308,8 @@ static int cifscreds_pam_update(pam_handle_t *ph, const char *user, const char *
*nextaddress++ = '\0';
while (currentaddress) {
- if (key_search(currentaddress, keytype) > 0) {
- addrs[count] = currentaddress;
+ if (key_search(currentaddress, keytype) > 0)
count++;
- }
currentaddress = nextaddress;
if (currentaddress) {
@@ -322,7 +320,7 @@ static int cifscreds_pam_update(pam_handle_t *ph, const char *user, const char *
}
if (!count) {
- pam_syslog(ph, LOG_ERR, "You have no same stached credentials for %s", hostdomain);
+ pam_syslog(ph, LOG_ERR, "You have no same stashed credentials for %s", hostdomain);
return PAM_SERVICE_ERR;
}
@@ -344,7 +342,7 @@ static int cifscreds_pam_update(pam_handle_t *ph, const char *user, const char *
* scenarios are possible:
*
* - A session is already available which usually means that the user is already
- * logged on and PAM has been used inside the screensaver. In that case, no need to
+ * logged on and PAM has been used inside the screensaver. In that case, no need to
* do anything(?).
*
* - A session is not yet available. Store the password inside PAM data so
@@ -356,7 +354,7 @@ static int cifscreds_pam_update(pam_handle_t *ph, const char *user, const char *
* @param argv array of arguments for this PAM module
* @return any of the PAM return values
*/
-PAM_EXTERN int pam_sm_authenticate(pam_handle_t *ph, int unused, int argc, const char **argv)
+PAM_EXTERN int pam_sm_authenticate(pam_handle_t *ph, int unused __attribute__((unused)), int argc, const char **argv)
{
const char *hostdomain;
const char *user;
@@ -365,7 +363,7 @@ PAM_EXTERN int pam_sm_authenticate(pam_handle_t *ph, int unused, int argc, const
int ret;
args = parse_args(ph, argc, argv, &hostdomain);
-
+
/* Figure out and/or prompt for the user name */
ret = pam_get_user(ph, &user, NULL);
if (ret != PAM_SUCCESS || !user) {
@@ -411,7 +409,7 @@ PAM_EXTERN int pam_sm_authenticate(pam_handle_t *ph, int unused, int argc, const
* @param argv array of arguments for this PAM module
* @return any of the PAM return values
*/
-PAM_EXTERN int pam_sm_open_session(pam_handle_t *ph, int flags, int argc, const char **argv)
+PAM_EXTERN int pam_sm_open_session(pam_handle_t *ph, int flags __attribute__((unused)), int argc, const char **argv)
{
const char *user = NULL;
const char *password = NULL;
@@ -484,7 +482,7 @@ PAM_EXTERN int pam_sm_open_session(pam_handle_t *ph, int flags, int argc, const
* @param argv array of arguments for this PAM module
* @return PAM_SUCCESS
*/
-PAM_EXTERN int pam_sm_close_session(pam_handle_t *ph, int flags, int argc, const char **argv)
+PAM_EXTERN int pam_sm_close_session(pam_handle_t *ph __attribute__((unused)), int flags __attribute__((unused)), int argc __attribute__((unused)), const char **argv __attribute__((unused)))
{
return PAM_SUCCESS;
}
@@ -498,7 +496,7 @@ PAM_EXTERN int pam_sm_close_session(pam_handle_t *ph, int flags, int argc, const
* @param argv array of arguments for this PAM module
* @return PAM_SUCCESS
*/
-PAM_EXTERN int pam_sm_setcred(pam_handle_t *ph, int flags, int argc, const char **argv)
+PAM_EXTERN int pam_sm_setcred(pam_handle_t *ph __attribute__((unused)), int flags __attribute__((unused)), int argc __attribute__((unused)), const char **argv __attribute__((unused)))
{
return PAM_SUCCESS;
}
@@ -520,15 +518,14 @@ pam_sm_chauthtok (pam_handle_t *ph, int flags, int argc, const char **argv)
const char *password = NULL;
uint args;
int ret;
-
+
args = parse_args(ph, argc, argv, &hostdomain);
if (flags & PAM_UPDATE_AUTHTOK) {
/* Figure out the user name */
ret = pam_get_user(ph, &user, NULL);
if (ret != PAM_SUCCESS) {
- pam_syslog(ph, LOG_ERR, "couldn't get the user name: %s",
- pam_strerror (ph, ret));
+ pam_syslog(ph, LOG_ERR, "couldn't get the user name: %s", pam_strerror (ph, ret));
return PAM_SERVICE_ERR;
}
@@ -537,14 +534,13 @@ pam_sm_chauthtok (pam_handle_t *ph, int flags, int argc, const char **argv)
if (ret == PAM_SUCCESS) {
pam_syslog(ph, LOG_WARNING, "no password is available for user");
} else {
- pam_syslog(ph, LOG_WARNING, "no password is available for user: %s",
- pam_strerror(ph, ret));
+ pam_syslog(ph, LOG_WARNING, "no password is available for user: %s", pam_strerror(ph, ret));
}
return PAM_AUTHTOK_RECOVER_ERR;
}
-
+
return cifscreds_pam_update(ph, user, password, args, hostdomain);
}
- else
+ else
return PAM_IGNORE;
}
--
1.8.4.2

View File

@ -0,0 +1,332 @@
From ba68b6b98dee147478041c9bade6df3df176af62 Mon Sep 17 00:00:00 2001
From: Orion Poplawski <orion@nwra.com>
Date: Tue, 10 Dec 2013 14:09:26 -0700
Subject: [cifs-utils PATCH] manpage: add pam_cifscreds.8 man page
Signed-off-by: Orion Poplawski <orion@nwra.com>
---
Makefile.am | 1 +
pam_cifscreds.8 | 207 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
pam_cifscreds.pod | 84 ++++++++++++++++++++++
3 files changed, 292 insertions(+)
create mode 100644 pam_cifscreds.8
create mode 100644 pam_cifscreds.pod
diff --git a/Makefile.am b/Makefile.am
index 6e86cd3..a3fb413 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -98,6 +98,7 @@ pam_PROGRAMS = pam_cifscreds.so
pam_cifscreds.so: pam_cifscreds.c cifskey.c resolve_host.c util.c
$(CC) $(CFLAGS) $(AM_CFLAGS) $(LDFLAGS) -shared -fpic -o $@ $+ -lpam -lkeyutils
+man_MANS += pam_cifscreds.8
endif
SUBDIRS = contrib
diff --git a/pam_cifscreds.8 b/pam_cifscreds.8
new file mode 100644
index 0000000..619cc7c
--- /dev/null
+++ b/pam_cifscreds.8
@@ -0,0 +1,207 @@
+.\" Automatically generated by Pod::Man 2.27 (Pod::Simple 3.28)
+.\"
+.\" Standard preamble:
+.\" ========================================================================
+.de Sp \" Vertical space (when we can't use .PP)
+.if t .sp .5v
+.if n .sp
+..
+.de Vb \" Begin verbatim text
+.ft CW
+.nf
+.ne \\$1
+..
+.de Ve \" End verbatim text
+.ft R
+.fi
+..
+.\" Set up some character translations and predefined strings. \*(-- will
+.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left
+.\" double quote, and \*(R" will give a right double quote. \*(C+ will
+.\" give a nicer C++. Capital omega is used to do unbreakable dashes and
+.\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff,
+.\" nothing in troff, for use with C<>.
+.tr \(*W-
+.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
+.ie n \{\
+. ds -- \(*W-
+. ds PI pi
+. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
+. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch
+. ds L" ""
+. ds R" ""
+. ds C` ""
+. ds C' ""
+'br\}
+.el\{\
+. ds -- \|\(em\|
+. ds PI \(*p
+. ds L" ``
+. ds R" ''
+. ds C`
+. ds C'
+'br\}
+.\"
+.\" Escape single quotes in literal strings from groff's Unicode transform.
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\"
+.\" If the F register is turned on, we'll generate index entries on stderr for
+.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index
+.\" entries marked with X<> in POD. Of course, you'll have to process the
+.\" output yourself in some meaningful fashion.
+.\"
+.\" Avoid warning from groff about undefined register 'F'.
+.de IX
+..
+.nr rF 0
+.if \n(.g .if rF .nr rF 1
+.if (\n(rF:(\n(.g==0)) \{
+. if \nF \{
+. de IX
+. tm Index:\\$1\t\\n%\t"\\$2"
+..
+. if !\nF==2 \{
+. nr % 0
+. nr F 2
+. \}
+. \}
+.\}
+.rr rF
+.\"
+.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2).
+.\" Fear. Run. Save yourself. No user-serviceable parts.
+. \" fudge factors for nroff and troff
+.if n \{\
+. ds #H 0
+. ds #V .8m
+. ds #F .3m
+. ds #[ \f1
+. ds #] \fP
+.\}
+.if t \{\
+. ds #H ((1u-(\\\\n(.fu%2u))*.13m)
+. ds #V .6m
+. ds #F 0
+. ds #[ \&
+. ds #] \&
+.\}
+. \" simple accents for nroff and troff
+.if n \{\
+. ds ' \&
+. ds ` \&
+. ds ^ \&
+. ds , \&
+. ds ~ ~
+. ds /
+.\}
+.if t \{\
+. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u"
+. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u'
+. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u'
+. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u'
+. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u'
+. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u'
+.\}
+. \" troff and (daisy-wheel) nroff accents
+.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V'
+.ds 8 \h'\*(#H'\(*b\h'-\*(#H'
+.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#]
+.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H'
+.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u'
+.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#]
+.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#]
+.ds ae a\h'-(\w'a'u*4/10)'e
+.ds Ae A\h'-(\w'A'u*4/10)'E
+. \" corrections for vroff
+.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u'
+.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u'
+. \" for low resolution devices (crt and lpr)
+.if \n(.H>23 .if \n(.V>19 \
+\{\
+. ds : e
+. ds 8 ss
+. ds o a
+. ds d- d\h'-1'\(ga
+. ds D- D\h'-1'\(hy
+. ds th \o'bp'
+. ds Th \o'LP'
+. ds ae ae
+. ds Ae AE
+.\}
+.rm #[ #] #H #V #F C
+.\" ========================================================================
+.\"
+.IX Title "PAM_CIFSCREDS 8"
+.TH PAM_CIFSCREDS 8 "2013-12-13" "" ""
+.\" For nroff, turn off justification. Always turn off hyphenation; it makes
+.\" way too many mistakes in technical documents.
+.if n .ad l
+.nh
+.SH "NAME"
+pam_cifscreds \- PAM module to manage NTLM credentials in kernel keyring
+.SH "SYNOPSIS"
+.IX Header "SYNOPSIS"
+Edit the \s-1PAM\s0 configuration files for the systems that you want to
+automatically register \s-1NTLM\s0 credentials for, e.g. /etc/pam.d/login,
+and modify as follows:
+.PP
+.Vb 5
+\& ...
+\& auth substack system\-auth
+\& +++ auth optional pam_cifscreds.so
+\& auth include postlogin
+\& ...
+\&
+\& ...
+\& session include system\-auth
+\& +++ session optional pam_cifscreds.so domain=DOMAIN
+\& session include postlogin
+\& ...
+.Ve
+.PP
+Change \s-1DOMAIN\s0 to the name of you Windows domain, or use host= as
+described below.
+.SH "DESCRIPTION"
+.IX Header "DESCRIPTION"
+The \fBpam_cifscreds\fR \s-1PAM\s0 module is a tool for automatically adding
+credentials (username and password) for the purpose of establishing
+sessions in multiuser mounts.
+.PP
+When a cifs filesystem is mounted with the \*(L"multiuser\*(R" option, and does
+not use krb5 authentication, it needs to be able to get the credentials
+for each user from somewhere. The \fBpam_cifscreds\fR module can be used
+to provide these credentials to the kernel automatically at login.
+.PP
+In the session section of the \s-1PAM\s0 configuration file, the module can
+either an \s-1NT\s0 domain name or a list of hostname or addresses.
+.SH "OPTIONS"
+.IX Header "OPTIONS"
+\&\fBpam_cifscreds\fR supports a couple options which can be set in the \s-1PAM\s0
+configuration files. You must have one (and only one) of domain= or
+host=.
+.IP "\fBdebug\fR" 4
+.IX Item "debug"
+Turns on some extra debug logging.
+.IP "\fBdomain\fR=<\s-1NT\s0 domain name>" 4
+.IX Item "domain=<NT domain name>"
+Credentials will be added for the specified \s-1NT\s0 domain name.
+.IP "\fBhost\fR=<hostname or \s-1IP\s0 address>[,...]" 4
+.IX Item "host=<hostname or IP address>[,...]"
+Credentials will be added for the specified hostnames or \s-1IP\s0 addresses.
+.SH "NOTES"
+.IX Header "NOTES"
+The pam_cifscreds \s-1PAM\s0 module requires a kernel built with support for
+the \fBlogin\fR key type. That key type was added in v3.3 in mainline Linux
+kernels.
+.PP
+Since \fBpam_cifscreds\fR adds keys to the session keyring, it is highly
+recommended that one use \fBpam_keyinit\fR to ensure that a session keyring
+is established at login time.
+.SH "SEE ALSO"
+.IX Header "SEE ALSO"
+\&\fIcifscreds\fR\|(1), \fIpam_keyinit\fR\|(8)
+.SH "AUTHOR"
+.IX Header "AUTHOR"
+The pam_cifscreds \s-1PAM\s0 module was developed by Orion Poplawski
+<orion@nwra.com>.
diff --git a/pam_cifscreds.pod b/pam_cifscreds.pod
new file mode 100644
index 0000000..c032416
--- /dev/null
+++ b/pam_cifscreds.pod
@@ -0,0 +1,84 @@
+# turn into a manpage with the following command:
+#
+# pod2man -s 8 -c '' -r '' --stderr pam_cifscreds.pod > pam_cifscreds.8
+#
+
+=head1 NAME
+
+pam_cifscreds - PAM module to manage NTLM credentials in kernel keyring
+
+=head1 SYNOPSIS
+
+Edit the PAM configuration files for the systems that you want to
+automatically register NTLM credentials for, e.g. /etc/pam.d/login,
+and modify as follows:
+
+ ...
+ auth substack system-auth
+ +++ auth optional pam_cifscreds.so
+ auth include postlogin
+ ...
+
+ ...
+ session include system-auth
+ +++ session optional pam_cifscreds.so domain=DOMAIN
+ session include postlogin
+ ...
+
+Change DOMAIN to the name of you Windows domain, or use host= as
+described below.
+
+=head1 DESCRIPTION
+
+The B<pam_cifscreds> PAM module is a tool for automatically adding
+credentials (username and password) for the purpose of establishing
+sessions in multiuser mounts.
+
+When a cifs filesystem is mounted with the "multiuser" option, and does
+not use krb5 authentication, it needs to be able to get the credentials
+for each user from somewhere. The B<pam_cifscreds> module can be used
+to provide these credentials to the kernel automatically at login.
+
+In the session section of the PAM configuration file, the module can
+either an NT domain name or a list of hostname or addresses.
+
+=head1 OPTIONS
+
+B<pam_cifscreds> supports a couple options which can be set in the PAM
+configuration files. You must have one (and only one) of domain= or
+host=.
+
+=over
+
+=item B<debug>
+
+Turns on some extra debug logging.
+
+=item B<domain>=<NT domain name>
+
+Credentials will be added for the specified NT domain name.
+
+=item B<host>=<hostname or IP address>[,...]
+
+Credentials will be added for the specified hostnames or IP addresses.
+
+=back
+
+=head1 NOTES
+
+The pam_cifscreds PAM module requires a kernel built with support for
+the B<login> key type. That key type was added in v3.3 in mainline Linux
+kernels.
+
+Since B<pam_cifscreds> adds keys to the session keyring, it is highly
+recommended that one use B<pam_keyinit> to ensure that a session keyring
+is established at login time.
+
+=head1 SEE ALSO
+
+cifscreds(1), pam_keyinit(8)
+
+=head1 AUTHOR
+
+The pam_cifscreds PAM module was developed by Orion Poplawski
+<orion@nwra.com>.
--
1.8.4.2

View File

@ -3,7 +3,7 @@
Name: cifs-utils
Version: 6.2
Release: 4%{pre_release}%{?dist}
Release: 5%{pre_release}%{?dist}
Summary: Utilities for mounting and managing CIFS mounts
Group: System Environment/Daemons
@ -11,7 +11,7 @@ License: GPLv3
URL: http://linux-cifs.samba.org/cifs-utils/
BuildRoot: %{_tmppath}/%{name}-%{version}%{pre_release}-%{release}-root-%(%{__id_u} -n)
BuildRequires: libcap-ng-devel libtalloc-devel krb5-devel keyutils-libs-devel autoconf automake libwbclient-devel
BuildRequires: libcap-ng-devel libtalloc-devel krb5-devel keyutils-libs-devel autoconf automake libwbclient-devel pam-devel
Requires: keyutils
Requires(post): /usr/sbin/alternatives
@ -23,7 +23,12 @@ Patch2: 0002-getcifsacl-remove-some-dead-code.patch
Patch3: 0003-asn1-remove-some-usused-functions.patch
Patch4: 0004-data_blob-clean-out-unused-functions.patch
Patch5: 0005-mount.cifs-fix-bad-free-of-string-returned-by-dirnam.patch
Patch6: 0001-asn1-fix-use-after-free-in-asn1_write.patch
Patch6: 0001-asn1-fix-use-after-free-in-asn1_write.patch
Patch7: 0001-autoconf-fix-link-of-libwbclient.patch
Patch8: 0002-cifscreds-create-PAM-module-to-insert-credentials-at.patch
Patch9: 0003-cifscreds-fix-up-some-whitespace-typos-and-build-war.patch
Patch10: 0004-manpage-add-pam_cifscreds.8-man-page.patch
%description
The SMB/CIFS protocol is a standard file sharing protocol widely deployed
@ -50,6 +55,10 @@ necessary for building ID mapping plugins for cifs-utils.
%patch4 -p1
%patch5 -p1
%patch6 -p1
%patch7 -p1
%patch8 -p1
%patch9 -p1
%patch10 -p1
%build
%configure --prefix=/usr ROOTSBINDIR=%{_sbindir}
@ -76,6 +85,7 @@ rm -rf %{buildroot}
%{_sbindir}/cifs.upcall
%{_sbindir}/cifs.idmap
%{_libdir}/%{name}/idmapwb.so
%{_libdir}/security/pam_cifscreds.so
%{_mandir}/man1/getcifsacl.1.gz
%{_mandir}/man1/setcifsacl.1.gz
%{_mandir}/man1/cifscreds.1.gz
@ -83,6 +93,7 @@ rm -rf %{buildroot}
%{_mandir}/man8/cifs.idmap.8.gz
%{_mandir}/man8/mount.cifs.8.gz
%{_mandir}/man8/idmapwb.8.gz
%{_mandir}/man8/pam_cifscreds.8.gz
%ghost %{_sysconfdir}/cifs-utils/idmap-plugin
%config(noreplace) %{_sysconfdir}/request-key.d/cifs.idmap.conf
%config(noreplace) %{_sysconfdir}/request-key.d/cifs.spnego.conf
@ -99,6 +110,10 @@ fi
%{_includedir}/cifsidmap.h
%changelog
* Fri Dec 13 2013 Jeff Layton <jlayton@redhat.com> 6.2-5
- fix linking of wbclient
- add pam_cifscreds module and manpage
* Mon Oct 14 2013 Jeff Layton <jlayton@redhat.com> 6.2-4
- fix use-after-free in asn1_write