Update to 6.3 release
Signed-off-by: Jeff Layton <jlayton@redhat.com>
This commit is contained in:
parent
abadd4b034
commit
217f0bb091
1
.gitignore
vendored
1
.gitignore
vendored
@ -17,3 +17,4 @@ cifs-utils-4.6.tar.bz2
|
||||
/cifs-utils-6.0.tar.bz2
|
||||
/cifs-utils-6.1.tar.bz2
|
||||
/cifs-utils-6.2.tar.bz2
|
||||
/cifs-utils-6.3.tar.bz2
|
||||
|
@ -1,30 +0,0 @@
|
||||
From 3aa83995d7c0ef632fe0af3d032e48691a5ce781 Mon Sep 17 00:00:00 2001
|
||||
From: Jeff Layton <jlayton@samba.org>
|
||||
Date: Sun, 13 Oct 2013 21:07:28 -0400
|
||||
Subject: [PATCH] asn1: fix use-after-free in asn1_write
|
||||
|
||||
If the talloc_realloc() fails, asn1_write calls talloc_free on the
|
||||
context and then immediately dereferences the pointer.
|
||||
|
||||
Fix this by skipping the talloc_free here. Let the caller handle it.
|
||||
|
||||
Signed-off-by: Jeff Layton <jlayton@samba.org>
|
||||
---
|
||||
asn1.c | 1 -
|
||||
1 file changed, 1 deletion(-)
|
||||
|
||||
diff --git a/asn1.c b/asn1.c
|
||||
index ea50a23..4c0e480 100644
|
||||
--- a/asn1.c
|
||||
+++ b/asn1.c
|
||||
@@ -47,7 +47,6 @@ bool asn1_write(struct asn1_data *data, const void *p, int len)
|
||||
uint8_t *newp;
|
||||
newp = talloc_realloc(data, data->data, uint8_t, data->ofs+len);
|
||||
if (!newp) {
|
||||
- asn1_free(data);
|
||||
data->has_error = true;
|
||||
return false;
|
||||
}
|
||||
--
|
||||
1.8.3.1
|
||||
|
@ -1,36 +0,0 @@
|
||||
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
|
||||
|
@ -1,50 +0,0 @@
|
||||
From 99d2a5a4517216a63cfdeef3ee30656938b3a98e Mon Sep 17 00:00:00 2001
|
||||
From: Jeff Layton <jlayton@samba.org>
|
||||
Date: Tue, 8 Oct 2013 21:07:24 -0400
|
||||
Subject: [PATCH] get/setcifsacl: fix bad bit-shifts
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
A Coverity scan turned up this warning:
|
||||
|
||||
1. cifs-utils-6.2/setcifsacl.c:578:result_independent_of_operands – "(x & 0xff0000000000ULL) >> 48" is 0 regardless of the values of its operands. This occurs as the operand of assignment.
|
||||
|
||||
...which is entirely true. That shift should be 40 bits, not 48. Also
|
||||
fix a similar bug in getcifsacl.c.
|
||||
|
||||
Signed-off-by: Jeff Layton <jlayton@samba.org>
|
||||
---
|
||||
getcifsacl.c | 2 +-
|
||||
setcifsacl.c | 2 +-
|
||||
2 files changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/getcifsacl.c b/getcifsacl.c
|
||||
index b8998ef..33f36b4 100644
|
||||
--- a/getcifsacl.c
|
||||
+++ b/getcifsacl.c
|
||||
@@ -198,7 +198,7 @@ print_sid_raw:
|
||||
id_auth_val += (unsigned long long)csid->authority[3] << 16;
|
||||
id_auth_val += (unsigned long long)csid->authority[2] << 24;
|
||||
id_auth_val += (unsigned long long)csid->authority[1] << 32;
|
||||
- id_auth_val += (unsigned long long)csid->authority[0] << 48;
|
||||
+ id_auth_val += (unsigned long long)csid->authority[0] << 40;
|
||||
|
||||
/*
|
||||
* MS-DTYP states that if the authority is >= 2^32, then it should be
|
||||
diff --git a/setcifsacl.c b/setcifsacl.c
|
||||
index ce708eb..7eeeaa6 100644
|
||||
--- a/setcifsacl.c
|
||||
+++ b/setcifsacl.c
|
||||
@@ -575,7 +575,7 @@ raw_str_to_sid(const char *str, struct cifs_sid *csid)
|
||||
csid->authority[3] = (x & 0x000000ff0000ULL) >> 16;
|
||||
csid->authority[2] = (x & 0x0000ff000000ULL) >> 24;
|
||||
csid->authority[1] = (x & 0x00ff00000000ULL) >> 32;
|
||||
- csid->authority[0] = (x & 0xff0000000000ULL) >> 48;
|
||||
+ csid->authority[0] = (x & 0xff0000000000ULL) >> 40;
|
||||
|
||||
/* now read the the subauthorities and store as __le32 vals */
|
||||
p = q + 1;
|
||||
--
|
||||
1.8.3.1
|
||||
|
@ -1,862 +0,0 @@
|
||||
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
|
||||
|
@ -1,38 +0,0 @@
|
||||
From 930b724e784c28bd1b3024f7fc6ca24cdac82a4d Mon Sep 17 00:00:00 2001
|
||||
From: Jeff Layton <jlayton@samba.org>
|
||||
Date: Wed, 9 Oct 2013 08:14:21 -0400
|
||||
Subject: [PATCH] getcifsacl: remove some dead code
|
||||
|
||||
Coverity says:
|
||||
|
||||
Error: DEADCODE (CWE-561): [#def5]
|
||||
cifs-utils-6.2/getcifsacl.c:101: assignment: Assigning: "mflags" = "false".
|
||||
cifs-utils-6.2/getcifsacl.c:109: const: At condition "mflags", the value of "mflags" must be equal to 0.
|
||||
cifs-utils-6.2/getcifsacl.c:109: dead_error_condition: The condition "mflags" cannot be true.
|
||||
cifs-utils-6.2/getcifsacl.c:110: dead_error_line: Execution cannot reach this statement "printf("|");".
|
||||
|
||||
Acked-by: Shirish Pargaonkar <shirishpargaonkar@gmail.com>
|
||||
Signed-off-by: Jeff Layton <jlayton@samba.org>
|
||||
---
|
||||
getcifsacl.c | 5 +----
|
||||
1 file changed, 1 insertion(+), 4 deletions(-)
|
||||
|
||||
diff --git a/getcifsacl.c b/getcifsacl.c
|
||||
index 33f36b4..f08cdea 100644
|
||||
--- a/getcifsacl.c
|
||||
+++ b/getcifsacl.c
|
||||
@@ -106,10 +106,7 @@ print_ace_flags(uint8_t flags, int raw)
|
||||
}
|
||||
|
||||
if (flags & OBJECT_INHERIT_FLAG) {
|
||||
- if (mflags)
|
||||
- printf("|");
|
||||
- else
|
||||
- mflags = true;
|
||||
+ mflags = true;
|
||||
printf("OI");
|
||||
}
|
||||
if (flags & CONTAINER_INHERIT_FLAG) {
|
||||
--
|
||||
1.8.3.1
|
||||
|
@ -1,718 +0,0 @@
|
||||
From e877c21f5e2394c8325955c645f214b8868317c8 Mon Sep 17 00:00:00 2001
|
||||
From: Jeff Layton <jlayton@samba.org>
|
||||
Date: Wed, 9 Oct 2013 08:17:49 -0400
|
||||
Subject: [PATCH] asn1: remove some usused functions
|
||||
|
||||
This cuts 30k out of the cifs.upcall binary on my x86_64 box.
|
||||
|
||||
Signed-off-by: Jeff Layton <jlayton@samba.org>
|
||||
---
|
||||
asn1.c | 638 -----------------------------------------------------------------
|
||||
asn1.h | 37 ----
|
||||
2 files changed, 675 deletions(-)
|
||||
|
||||
diff --git a/asn1.c b/asn1.c
|
||||
index a00c474..ea50a23 100644
|
||||
--- a/asn1.c
|
||||
+++ b/asn1.c
|
||||
@@ -140,83 +140,6 @@ bool asn1_pop_tag(struct asn1_data *data)
|
||||
return true;
|
||||
}
|
||||
|
||||
-/* "i" is the one's complement representation, as is the normal result of an
|
||||
- * implicit signed->unsigned conversion */
|
||||
-
|
||||
-static bool push_int_bigendian(struct asn1_data *data, unsigned int i, bool negative)
|
||||
-{
|
||||
- uint8_t lowest = i & 0xFF;
|
||||
-
|
||||
- i = i >> 8;
|
||||
- if (i != 0)
|
||||
- if (!push_int_bigendian(data, i, negative))
|
||||
- return false;
|
||||
-
|
||||
- if (data->nesting->start+1 == data->ofs) {
|
||||
-
|
||||
- /* We did not write anything yet, looking at the highest
|
||||
- * valued byte */
|
||||
-
|
||||
- if (negative) {
|
||||
- /* Don't write leading 0xff's */
|
||||
- if (lowest == 0xFF)
|
||||
- return true;
|
||||
-
|
||||
- if ((lowest & 0x80) == 0) {
|
||||
- /* The only exception for a leading 0xff is if
|
||||
- * the highest bit is 0, which would indicate
|
||||
- * a positive value */
|
||||
- if (!asn1_write_uint8(data, 0xff))
|
||||
- return false;
|
||||
- }
|
||||
- } else {
|
||||
- if (lowest & 0x80) {
|
||||
- /* The highest bit of a positive integer is 1,
|
||||
- * this would indicate a negative number. Push
|
||||
- * a 0 to indicate a positive one */
|
||||
- if (!asn1_write_uint8(data, 0))
|
||||
- return false;
|
||||
- }
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- return asn1_write_uint8(data, lowest);
|
||||
-}
|
||||
-
|
||||
-/* write an Integer without the tag framing. Needed for example for the LDAP
|
||||
- * Abandon Operation */
|
||||
-
|
||||
-bool asn1_write_implicit_Integer(struct asn1_data *data, int i)
|
||||
-{
|
||||
- if (i == -1) {
|
||||
- /* -1 is special as it consists of all-0xff bytes. In
|
||||
- push_int_bigendian this is the only case that is not
|
||||
- properly handled, as all 0xff bytes would be handled as
|
||||
- leading ones to be ignored. */
|
||||
- return asn1_write_uint8(data, 0xff);
|
||||
- } else {
|
||||
- return push_int_bigendian(data, i, i<0);
|
||||
- }
|
||||
-}
|
||||
-
|
||||
-
|
||||
-/* write an integer */
|
||||
-bool asn1_write_Integer(struct asn1_data *data, int i)
|
||||
-{
|
||||
- if (!asn1_push_tag(data, ASN1_INTEGER)) return false;
|
||||
- if (!asn1_write_implicit_Integer(data, i)) return false;
|
||||
- return asn1_pop_tag(data);
|
||||
-}
|
||||
-
|
||||
-/* write a BIT STRING */
|
||||
-bool asn1_write_BitString(struct asn1_data *data, const void *p, size_t length, uint8_t padding)
|
||||
-{
|
||||
- if (!asn1_push_tag(data, ASN1_BIT_STRING)) return false;
|
||||
- if (!asn1_write_uint8(data, padding)) return false;
|
||||
- if (!asn1_write(data, p, length)) return false;
|
||||
- return asn1_pop_tag(data);
|
||||
-}
|
||||
-
|
||||
bool ber_write_OID_String(TALLOC_CTX *mem_ctx, DATA_BLOB *blob, const char *OID)
|
||||
{
|
||||
unsigned int v, v2;
|
||||
@@ -291,564 +214,3 @@ bool asn1_write_OctetString(struct asn1_data *data, const void *p, size_t length
|
||||
return !data->has_error;
|
||||
}
|
||||
|
||||
-/* write a LDAP string */
|
||||
-bool asn1_write_LDAPString(struct asn1_data *data, const char *s)
|
||||
-{
|
||||
- asn1_write(data, s, strlen(s));
|
||||
- return !data->has_error;
|
||||
-}
|
||||
-
|
||||
-/* write a LDAP string from a DATA_BLOB */
|
||||
-bool asn1_write_DATA_BLOB_LDAPString(struct asn1_data *data, const DATA_BLOB *s)
|
||||
-{
|
||||
- asn1_write(data, s->data, s->length);
|
||||
- return !data->has_error;
|
||||
-}
|
||||
-
|
||||
-/* write a general string */
|
||||
-bool asn1_write_GeneralString(struct asn1_data *data, const char *s)
|
||||
-{
|
||||
- asn1_push_tag(data, ASN1_GENERAL_STRING);
|
||||
- asn1_write_LDAPString(data, s);
|
||||
- asn1_pop_tag(data);
|
||||
- return !data->has_error;
|
||||
-}
|
||||
-
|
||||
-bool asn1_write_ContextSimple(struct asn1_data *data, uint8_t num, DATA_BLOB *blob)
|
||||
-{
|
||||
- asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(num));
|
||||
- asn1_write(data, blob->data, blob->length);
|
||||
- asn1_pop_tag(data);
|
||||
- return !data->has_error;
|
||||
-}
|
||||
-
|
||||
-/* write a BOOLEAN */
|
||||
-bool asn1_write_BOOLEAN(struct asn1_data *data, bool v)
|
||||
-{
|
||||
- asn1_push_tag(data, ASN1_BOOLEAN);
|
||||
- asn1_write_uint8(data, v ? 0xFF : 0);
|
||||
- asn1_pop_tag(data);
|
||||
- return !data->has_error;
|
||||
-}
|
||||
-
|
||||
-bool asn1_read_BOOLEAN(struct asn1_data *data, bool *v)
|
||||
-{
|
||||
- uint8_t tmp = 0;
|
||||
- asn1_start_tag(data, ASN1_BOOLEAN);
|
||||
- asn1_read_uint8(data, &tmp);
|
||||
- if (tmp == 0xFF) {
|
||||
- *v = true;
|
||||
- } else {
|
||||
- *v = false;
|
||||
- }
|
||||
- asn1_end_tag(data);
|
||||
- return !data->has_error;
|
||||
-}
|
||||
-
|
||||
-/* write a BOOLEAN in a simple context */
|
||||
-bool asn1_write_BOOLEAN_context(struct asn1_data *data, bool v, int context)
|
||||
-{
|
||||
- asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(context));
|
||||
- asn1_write_uint8(data, v ? 0xFF : 0);
|
||||
- asn1_pop_tag(data);
|
||||
- return !data->has_error;
|
||||
-}
|
||||
-
|
||||
-bool asn1_read_BOOLEAN_context(struct asn1_data *data, bool *v, int context)
|
||||
-{
|
||||
- uint8_t tmp = 0;
|
||||
- asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(context));
|
||||
- asn1_read_uint8(data, &tmp);
|
||||
- if (tmp == 0xFF) {
|
||||
- *v = true;
|
||||
- } else {
|
||||
- *v = false;
|
||||
- }
|
||||
- asn1_end_tag(data);
|
||||
- return !data->has_error;
|
||||
-}
|
||||
-
|
||||
-/* check a BOOLEAN */
|
||||
-bool asn1_check_BOOLEAN(struct asn1_data *data, bool v)
|
||||
-{
|
||||
- uint8_t b = 0;
|
||||
-
|
||||
- asn1_read_uint8(data, &b);
|
||||
- if (b != ASN1_BOOLEAN) {
|
||||
- data->has_error = true;
|
||||
- return false;
|
||||
- }
|
||||
- asn1_read_uint8(data, &b);
|
||||
- if (b != v) {
|
||||
- data->has_error = true;
|
||||
- return false;
|
||||
- }
|
||||
- return !data->has_error;
|
||||
-}
|
||||
-
|
||||
-
|
||||
-/* load a struct asn1_data structure with a lump of data, ready to be parsed */
|
||||
-bool asn1_load(struct asn1_data *data, DATA_BLOB blob)
|
||||
-{
|
||||
- ZERO_STRUCTP(data);
|
||||
- data->data = (uint8_t *)talloc_memdup(data, blob.data, blob.length);
|
||||
- if (!data->data) {
|
||||
- data->has_error = true;
|
||||
- return false;
|
||||
- }
|
||||
- data->length = blob.length;
|
||||
- return true;
|
||||
-}
|
||||
-
|
||||
-/* Peek into an ASN1 buffer, not advancing the pointer */
|
||||
-bool asn1_peek(struct asn1_data *data, void *p, int len)
|
||||
-{
|
||||
- if (data->has_error)
|
||||
- return false;
|
||||
-
|
||||
- if (len < 0 || data->ofs + len < data->ofs || data->ofs + len < len)
|
||||
- return false;
|
||||
-
|
||||
- if ((size_t)data->ofs + len > data->length) {
|
||||
- /* we need to mark the buffer as consumed, so the caller knows
|
||||
- this was an out of data error, and not a decode error */
|
||||
- data->ofs = data->length;
|
||||
- return false;
|
||||
- }
|
||||
-
|
||||
- memcpy(p, data->data + data->ofs, len);
|
||||
- return true;
|
||||
-}
|
||||
-
|
||||
-/* read from a ASN1 buffer, advancing the buffer pointer */
|
||||
-bool asn1_read(struct asn1_data *data, void *p, int len)
|
||||
-{
|
||||
- if (!asn1_peek(data, p, len)) {
|
||||
- data->has_error = true;
|
||||
- return false;
|
||||
- }
|
||||
-
|
||||
- data->ofs += len;
|
||||
- return true;
|
||||
-}
|
||||
-
|
||||
-/* read a uint8_t from a ASN1 buffer */
|
||||
-bool asn1_read_uint8(struct asn1_data *data, uint8_t *v)
|
||||
-{
|
||||
- return asn1_read(data, v, 1);
|
||||
-}
|
||||
-
|
||||
-bool asn1_peek_uint8(struct asn1_data *data, uint8_t *v)
|
||||
-{
|
||||
- return asn1_peek(data, v, 1);
|
||||
-}
|
||||
-
|
||||
-bool asn1_peek_tag(struct asn1_data *data, uint8_t tag)
|
||||
-{
|
||||
- uint8_t b;
|
||||
-
|
||||
- if (asn1_tag_remaining(data) <= 0) {
|
||||
- return false;
|
||||
- }
|
||||
-
|
||||
- if (!asn1_peek_uint8(data, &b))
|
||||
- return false;
|
||||
-
|
||||
- return (b == tag);
|
||||
-}
|
||||
-
|
||||
-/* start reading a nested asn1 structure */
|
||||
-bool asn1_start_tag(struct asn1_data *data, uint8_t tag)
|
||||
-{
|
||||
- uint8_t b;
|
||||
- struct nesting *nesting;
|
||||
-
|
||||
- if (!asn1_read_uint8(data, &b))
|
||||
- return false;
|
||||
-
|
||||
- if (b != tag) {
|
||||
- data->has_error = true;
|
||||
- return false;
|
||||
- }
|
||||
- nesting = talloc(data, struct nesting);
|
||||
- if (!nesting) {
|
||||
- data->has_error = true;
|
||||
- return false;
|
||||
- }
|
||||
-
|
||||
- if (!asn1_read_uint8(data, &b)) {
|
||||
- return false;
|
||||
- }
|
||||
-
|
||||
- if (b & 0x80) {
|
||||
- int n = b & 0x7f;
|
||||
- if (!asn1_read_uint8(data, &b))
|
||||
- return false;
|
||||
- nesting->taglen = b;
|
||||
- while (n > 1) {
|
||||
- if (!asn1_read_uint8(data, &b))
|
||||
- return false;
|
||||
- nesting->taglen = (nesting->taglen << 8) | b;
|
||||
- n--;
|
||||
- }
|
||||
- } else {
|
||||
- nesting->taglen = b;
|
||||
- }
|
||||
- nesting->start = data->ofs;
|
||||
- nesting->next = data->nesting;
|
||||
- data->nesting = nesting;
|
||||
- if (asn1_tag_remaining(data) == -1) {
|
||||
- return false;
|
||||
- }
|
||||
- return !data->has_error;
|
||||
-}
|
||||
-
|
||||
-/* stop reading a tag */
|
||||
-bool asn1_end_tag(struct asn1_data *data)
|
||||
-{
|
||||
- struct nesting *nesting;
|
||||
-
|
||||
- /* make sure we read it all */
|
||||
- if (asn1_tag_remaining(data) != 0) {
|
||||
- data->has_error = true;
|
||||
- return false;
|
||||
- }
|
||||
-
|
||||
- nesting = data->nesting;
|
||||
-
|
||||
- if (!nesting) {
|
||||
- data->has_error = true;
|
||||
- return false;
|
||||
- }
|
||||
-
|
||||
- data->nesting = nesting->next;
|
||||
- talloc_free(nesting);
|
||||
- return true;
|
||||
-}
|
||||
-
|
||||
-/* work out how many bytes are left in this nested tag */
|
||||
-int asn1_tag_remaining(struct asn1_data *data)
|
||||
-{
|
||||
- int remaining;
|
||||
- if (data->has_error) {
|
||||
- return -1;
|
||||
- }
|
||||
-
|
||||
- if (!data->nesting) {
|
||||
- data->has_error = true;
|
||||
- return -1;
|
||||
- }
|
||||
- remaining = data->nesting->taglen - (data->ofs - data->nesting->start);
|
||||
- if (remaining < 0) {
|
||||
- data->has_error = true;
|
||||
- return -1;
|
||||
- }
|
||||
- if ((size_t)remaining > data->length - data->ofs) {
|
||||
- data->has_error = true;
|
||||
- return -1;
|
||||
- }
|
||||
- return remaining;
|
||||
-}
|
||||
-
|
||||
-/**
|
||||
- * Internal implementation for reading binary OIDs
|
||||
- * Reading is done as far in the buffer as valid OID
|
||||
- * till buffer ends or not valid sub-identifier is found.
|
||||
- */
|
||||
-static bool _ber_read_OID_String_impl(TALLOC_CTX *mem_ctx, DATA_BLOB blob,
|
||||
- const char **OID, size_t *bytes_eaten)
|
||||
-{
|
||||
- unsigned int i;
|
||||
- uint8_t *b;
|
||||
- unsigned int v;
|
||||
- char *tmp_oid = NULL;
|
||||
-
|
||||
- if (blob.length < 2) return false;
|
||||
-
|
||||
- b = blob.data;
|
||||
-
|
||||
- tmp_oid = talloc_asprintf(mem_ctx, "%u", b[0]/40);
|
||||
- if (!tmp_oid) goto nomem;
|
||||
- tmp_oid = talloc_asprintf_append_buffer(tmp_oid, ".%u", b[0]%40);
|
||||
- if (!tmp_oid) goto nomem;
|
||||
-
|
||||
- for(i = 1, v = 0; i < blob.length; i++) {
|
||||
- v = (v<<7) | (b[i]&0x7f);
|
||||
- if ( ! (b[i] & 0x80)) {
|
||||
- tmp_oid = talloc_asprintf_append_buffer(tmp_oid, ".%u", v);
|
||||
- v = 0;
|
||||
- if (bytes_eaten)
|
||||
- *bytes_eaten = i+1;
|
||||
- }
|
||||
- if (!tmp_oid) goto nomem;
|
||||
- }
|
||||
-
|
||||
- *OID = tmp_oid;
|
||||
- return true;
|
||||
-
|
||||
-nomem:
|
||||
- return false;
|
||||
-}
|
||||
-
|
||||
-/* read an object ID from a data blob */
|
||||
-bool ber_read_OID_String(TALLOC_CTX *mem_ctx, DATA_BLOB blob, const char **OID)
|
||||
-{
|
||||
- size_t bytes_eaten = 0;
|
||||
-
|
||||
- if (!_ber_read_OID_String_impl(mem_ctx, blob, OID, &bytes_eaten))
|
||||
- return false;
|
||||
-
|
||||
- return (bytes_eaten == blob.length);
|
||||
-}
|
||||
-
|
||||
-/* read an object ID from a ASN1 buffer */
|
||||
-bool asn1_read_OID(struct asn1_data *data, TALLOC_CTX *mem_ctx, const char **OID)
|
||||
-{
|
||||
- DATA_BLOB blob;
|
||||
- int len;
|
||||
-
|
||||
- if (!asn1_start_tag(data, ASN1_OID)) return false;
|
||||
-
|
||||
- len = asn1_tag_remaining(data);
|
||||
- if (len < 0) {
|
||||
- data->has_error = true;
|
||||
- return false;
|
||||
- }
|
||||
-
|
||||
- blob = data_blob(NULL, len);
|
||||
- if (!blob.data) {
|
||||
- data->has_error = true;
|
||||
- return false;
|
||||
- }
|
||||
-
|
||||
- asn1_read(data, blob.data, len);
|
||||
- asn1_end_tag(data);
|
||||
- if (data->has_error) {
|
||||
- data_blob_free(&blob);
|
||||
- return false;
|
||||
- }
|
||||
-
|
||||
- if (!ber_read_OID_String(mem_ctx, blob, OID)) {
|
||||
- data->has_error = true;
|
||||
- data_blob_free(&blob);
|
||||
- return false;
|
||||
- }
|
||||
-
|
||||
- data_blob_free(&blob);
|
||||
- return true;
|
||||
-}
|
||||
-
|
||||
-/* check that the next object ID is correct */
|
||||
-bool asn1_check_OID(struct asn1_data *data, const char *OID)
|
||||
-{
|
||||
- const char *id;
|
||||
-
|
||||
- if (!asn1_read_OID(data, data, &id)) return false;
|
||||
-
|
||||
- if (strcmp(id, OID) != 0) {
|
||||
- talloc_free(discard_const(id));
|
||||
- data->has_error = true;
|
||||
- return false;
|
||||
- }
|
||||
- talloc_free(discard_const(id));
|
||||
- return true;
|
||||
-}
|
||||
-
|
||||
-/* read a LDAPString from a ASN1 buffer */
|
||||
-bool asn1_read_LDAPString(struct asn1_data *data, TALLOC_CTX *mem_ctx, char **s)
|
||||
-{
|
||||
- int len;
|
||||
- len = asn1_tag_remaining(data);
|
||||
- if (len < 0) {
|
||||
- data->has_error = true;
|
||||
- return false;
|
||||
- }
|
||||
- *s = talloc_array(mem_ctx, char, len+1);
|
||||
- if (! *s) {
|
||||
- data->has_error = true;
|
||||
- return false;
|
||||
- }
|
||||
- asn1_read(data, *s, len);
|
||||
- (*s)[len] = 0;
|
||||
- return !data->has_error;
|
||||
-}
|
||||
-
|
||||
-
|
||||
-/* read a GeneralString from a ASN1 buffer */
|
||||
-bool asn1_read_GeneralString(struct asn1_data *data, TALLOC_CTX *mem_ctx, char **s)
|
||||
-{
|
||||
- if (!asn1_start_tag(data, ASN1_GENERAL_STRING)) return false;
|
||||
- if (!asn1_read_LDAPString(data, mem_ctx, s)) return false;
|
||||
- return asn1_end_tag(data);
|
||||
-}
|
||||
-
|
||||
-
|
||||
-/* read a octet string blob */
|
||||
-bool asn1_read_OctetString(struct asn1_data *data, TALLOC_CTX *mem_ctx, DATA_BLOB *blob)
|
||||
-{
|
||||
- int len;
|
||||
- ZERO_STRUCTP(blob);
|
||||
- if (!asn1_start_tag(data, ASN1_OCTET_STRING)) return false;
|
||||
- len = asn1_tag_remaining(data);
|
||||
- if (len < 0) {
|
||||
- data->has_error = true;
|
||||
- return false;
|
||||
- }
|
||||
- *blob = data_blob_talloc(mem_ctx, NULL, len+1);
|
||||
- if (!blob->data) {
|
||||
- data->has_error = true;
|
||||
- return false;
|
||||
- }
|
||||
- asn1_read(data, blob->data, len);
|
||||
- asn1_end_tag(data);
|
||||
- blob->length--;
|
||||
- blob->data[len] = 0;
|
||||
-
|
||||
- if (data->has_error) {
|
||||
- data_blob_free(blob);
|
||||
- *blob = data_blob_null;
|
||||
- return false;
|
||||
- }
|
||||
- return true;
|
||||
-}
|
||||
-
|
||||
-bool asn1_read_ContextSimple(struct asn1_data *data, uint8_t num, DATA_BLOB *blob)
|
||||
-{
|
||||
- int len;
|
||||
- ZERO_STRUCTP(blob);
|
||||
- if (!asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(num))) return false;
|
||||
- len = asn1_tag_remaining(data);
|
||||
- if (len < 0) {
|
||||
- data->has_error = true;
|
||||
- return false;
|
||||
- }
|
||||
- *blob = data_blob(NULL, len);
|
||||
- if ((len != 0) && (!blob->data)) {
|
||||
- data->has_error = true;
|
||||
- return false;
|
||||
- }
|
||||
- asn1_read(data, blob->data, len);
|
||||
- asn1_end_tag(data);
|
||||
- return !data->has_error;
|
||||
-}
|
||||
-
|
||||
-/* read an integer without tag*/
|
||||
-bool asn1_read_implicit_Integer(struct asn1_data *data, int *i)
|
||||
-{
|
||||
- uint8_t b;
|
||||
- *i = 0;
|
||||
-
|
||||
- while (!data->has_error && asn1_tag_remaining(data)>0) {
|
||||
- if (!asn1_read_uint8(data, &b)) return false;
|
||||
- *i = (*i << 8) + b;
|
||||
- }
|
||||
- return !data->has_error;
|
||||
-
|
||||
-}
|
||||
-
|
||||
-/* read an integer */
|
||||
-bool asn1_read_Integer(struct asn1_data *data, int *i)
|
||||
-{
|
||||
- *i = 0;
|
||||
-
|
||||
- if (!asn1_start_tag(data, ASN1_INTEGER)) return false;
|
||||
- if (!asn1_read_implicit_Integer(data, i)) return false;
|
||||
- return asn1_end_tag(data);
|
||||
-}
|
||||
-
|
||||
-/* read a BIT STRING */
|
||||
-bool asn1_read_BitString(struct asn1_data *data, TALLOC_CTX *mem_ctx, DATA_BLOB *blob, uint8_t *padding)
|
||||
-{
|
||||
- int len;
|
||||
- ZERO_STRUCTP(blob);
|
||||
- if (!asn1_start_tag(data, ASN1_BIT_STRING)) return false;
|
||||
- len = asn1_tag_remaining(data);
|
||||
- if (len < 0) {
|
||||
- data->has_error = true;
|
||||
- return false;
|
||||
- }
|
||||
- if (!asn1_read_uint8(data, padding)) return false;
|
||||
-
|
||||
- *blob = data_blob_talloc(mem_ctx, NULL, len);
|
||||
- if (!blob->data) {
|
||||
- data->has_error = true;
|
||||
- return false;
|
||||
- }
|
||||
- if (asn1_read(data, blob->data, len - 1)) {
|
||||
- blob->length--;
|
||||
- blob->data[len] = 0;
|
||||
- asn1_end_tag(data);
|
||||
- }
|
||||
-
|
||||
- if (data->has_error) {
|
||||
- data_blob_free(blob);
|
||||
- *blob = data_blob_null;
|
||||
- *padding = 0;
|
||||
- return false;
|
||||
- }
|
||||
- return true;
|
||||
-}
|
||||
-
|
||||
-/* read an integer */
|
||||
-bool asn1_read_enumerated(struct asn1_data *data, int *v)
|
||||
-{
|
||||
- *v = 0;
|
||||
-
|
||||
- if (!asn1_start_tag(data, ASN1_ENUMERATED)) return false;
|
||||
- while (!data->has_error && asn1_tag_remaining(data)>0) {
|
||||
- uint8_t b;
|
||||
- asn1_read_uint8(data, &b);
|
||||
- *v = (*v << 8) + b;
|
||||
- }
|
||||
- return asn1_end_tag(data);
|
||||
-}
|
||||
-
|
||||
-/* check a enumerated value is correct */
|
||||
-bool asn1_check_enumerated(struct asn1_data *data, int v)
|
||||
-{
|
||||
- uint8_t b;
|
||||
- if (!asn1_start_tag(data, ASN1_ENUMERATED)) return false;
|
||||
- asn1_read_uint8(data, &b);
|
||||
- asn1_end_tag(data);
|
||||
-
|
||||
- if (v != b)
|
||||
- data->has_error = false;
|
||||
-
|
||||
- return !data->has_error;
|
||||
-}
|
||||
-
|
||||
-/* write an enumerated value to the stream */
|
||||
-bool asn1_write_enumerated(struct asn1_data *data, uint8_t v)
|
||||
-{
|
||||
- if (!asn1_push_tag(data, ASN1_ENUMERATED)) return false;
|
||||
- asn1_write_uint8(data, v);
|
||||
- asn1_pop_tag(data);
|
||||
- return !data->has_error;
|
||||
-}
|
||||
-
|
||||
-/*
|
||||
- Get us the data just written without copying
|
||||
-*/
|
||||
-bool asn1_blob(const struct asn1_data *asn1, DATA_BLOB *blob)
|
||||
-{
|
||||
- if (asn1->has_error) {
|
||||
- return false;
|
||||
- }
|
||||
- if (asn1->nesting != NULL) {
|
||||
- return false;
|
||||
- }
|
||||
- blob->data = asn1->data;
|
||||
- blob->length = asn1->length;
|
||||
- return true;
|
||||
-}
|
||||
-
|
||||
-/*
|
||||
- Fill in an asn1 struct without making a copy
|
||||
-*/
|
||||
-void asn1_load_nocopy(struct asn1_data *data, uint8_t *buf, size_t len)
|
||||
-{
|
||||
- ZERO_STRUCTP(data);
|
||||
- data->data = buf;
|
||||
- data->length = len;
|
||||
-}
|
||||
-
|
||||
diff --git a/asn1.h b/asn1.h
|
||||
index 615041f..a773885 100644
|
||||
--- a/asn1.h
|
||||
+++ b/asn1.h
|
||||
@@ -58,44 +58,7 @@ bool asn1_write(struct asn1_data *data, const void *p, int len);
|
||||
bool asn1_write_uint8(struct asn1_data *data, uint8_t v);
|
||||
bool asn1_push_tag(struct asn1_data *data, uint8_t tag);
|
||||
bool asn1_pop_tag(struct asn1_data *data);
|
||||
-bool asn1_write_implicit_Integer(struct asn1_data *data, int i);
|
||||
-bool asn1_write_Integer(struct asn1_data *data, int i);
|
||||
-bool asn1_write_BitString(struct asn1_data *data, const void *p, size_t length, uint8_t padding);
|
||||
bool ber_write_OID_String(TALLOC_CTX *mem_ctx, DATA_BLOB *blob, const char *OID);
|
||||
bool asn1_write_OID(struct asn1_data *data, const char *OID);
|
||||
bool asn1_write_OctetString(struct asn1_data *data, const void *p, size_t length);
|
||||
-bool asn1_write_LDAPString(struct asn1_data *data, const char *s);
|
||||
-bool asn1_write_DATA_BLOB_LDAPString(struct asn1_data *data, const DATA_BLOB *s);
|
||||
-bool asn1_write_GeneralString(struct asn1_data *data, const char *s);
|
||||
-bool asn1_write_ContextSimple(struct asn1_data *data, uint8_t num, DATA_BLOB *blob);
|
||||
-bool asn1_write_BOOLEAN(struct asn1_data *data, bool v);
|
||||
-bool asn1_read_BOOLEAN(struct asn1_data *data, bool *v);
|
||||
-bool asn1_check_BOOLEAN(struct asn1_data *data, bool v);
|
||||
-bool asn1_write_BOOLEAN_context(struct asn1_data *data, bool v, int context);
|
||||
-bool asn1_read_BOOLEAN_context(struct asn1_data *data, bool *v, int context);
|
||||
-bool asn1_load(struct asn1_data *data, DATA_BLOB blob);
|
||||
-bool asn1_peek(struct asn1_data *data, void *p, int len);
|
||||
-bool asn1_read(struct asn1_data *data, void *p, int len);
|
||||
-bool asn1_read_uint8(struct asn1_data *data, uint8_t *v);
|
||||
-bool asn1_peek_uint8(struct asn1_data *data, uint8_t *v);
|
||||
-bool asn1_peek_tag(struct asn1_data *data, uint8_t tag);
|
||||
-bool asn1_start_tag(struct asn1_data *data, uint8_t tag);
|
||||
-bool asn1_end_tag(struct asn1_data *data);
|
||||
-int asn1_tag_remaining(struct asn1_data *data);
|
||||
-bool ber_read_OID_String(TALLOC_CTX *mem_ctx, DATA_BLOB blob, const char **OID);
|
||||
-bool asn1_read_OID(struct asn1_data *data, TALLOC_CTX *mem_ctx, const char **OID);
|
||||
-bool asn1_check_OID(struct asn1_data *data, const char *OID);
|
||||
-bool asn1_read_LDAPString(struct asn1_data *data, TALLOC_CTX *mem_ctx, char **s);
|
||||
-bool asn1_read_GeneralString(struct asn1_data *data, TALLOC_CTX *mem_ctx, char **s);
|
||||
-bool asn1_read_OctetString(struct asn1_data *data, TALLOC_CTX *mem_ctx, DATA_BLOB *blob);
|
||||
-bool asn1_read_ContextSimple(struct asn1_data *data, uint8_t num, DATA_BLOB *blob);
|
||||
-bool asn1_read_implicit_Integer(struct asn1_data *data, int *i);
|
||||
-bool asn1_read_Integer(struct asn1_data *data, int *i);
|
||||
-bool asn1_read_BitString(struct asn1_data *data, TALLOC_CTX *mem_ctx, DATA_BLOB *blob, uint8_t *padding);
|
||||
-bool asn1_read_enumerated(struct asn1_data *data, int *v);
|
||||
-bool asn1_check_enumerated(struct asn1_data *data, int v);
|
||||
-bool asn1_write_enumerated(struct asn1_data *data, uint8_t v);
|
||||
-bool asn1_blob(const struct asn1_data *asn1, DATA_BLOB *blob);
|
||||
-void asn1_load_nocopy(struct asn1_data *data, uint8_t *buf, size_t len);
|
||||
-
|
||||
#endif /* _ASN_1_H */
|
||||
--
|
||||
1.8.3.1
|
||||
|
@ -1,197 +0,0 @@
|
||||
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
|
||||
|
@ -1,276 +0,0 @@
|
||||
From 9f1c0722a3e20047bcffe3a43f229e891da8c01b Mon Sep 17 00:00:00 2001
|
||||
From: Jeff Layton <jlayton@samba.org>
|
||||
Date: Wed, 9 Oct 2013 09:05:22 -0400
|
||||
Subject: [PATCH] data_blob: clean out unused functions
|
||||
|
||||
Cut another 6k or so out of the cifs.upcall binary.
|
||||
|
||||
Signed-off-by: Jeff Layton <jlayton@samba.org>
|
||||
---
|
||||
data_blob.c | 168 ------------------------------------------------------------
|
||||
data_blob.h | 62 ----------------------
|
||||
2 files changed, 230 deletions(-)
|
||||
|
||||
diff --git a/data_blob.c b/data_blob.c
|
||||
index 16c78ce..834d810 100644
|
||||
--- a/data_blob.c
|
||||
+++ b/data_blob.c
|
||||
@@ -71,18 +71,6 @@ _PUBLIC_ DATA_BLOB data_blob_talloc_named(TALLOC_CTX *mem_ctx, const void *p, si
|
||||
}
|
||||
|
||||
/**
|
||||
- construct a zero data blob, using supplied TALLOC_CTX.
|
||||
- use this sparingly as it initialises data - better to initialise
|
||||
- yourself if you want specific data in the blob
|
||||
-**/
|
||||
-_PUBLIC_ DATA_BLOB data_blob_talloc_zero(TALLOC_CTX *mem_ctx, size_t length)
|
||||
-{
|
||||
- DATA_BLOB blob = data_blob_talloc(mem_ctx, NULL, length);
|
||||
- data_blob_clear(&blob);
|
||||
- return blob;
|
||||
-}
|
||||
-
|
||||
-/**
|
||||
free a data blob
|
||||
**/
|
||||
_PUBLIC_ void data_blob_free(DATA_BLOB *d)
|
||||
@@ -94,159 +82,3 @@ _PUBLIC_ void data_blob_free(DATA_BLOB *d)
|
||||
}
|
||||
}
|
||||
|
||||
-/**
|
||||
-clear a DATA_BLOB's contents
|
||||
-**/
|
||||
-_PUBLIC_ void data_blob_clear(DATA_BLOB *d)
|
||||
-{
|
||||
- if (d->data) {
|
||||
- memset(d->data, 0, d->length);
|
||||
- }
|
||||
-}
|
||||
-
|
||||
-/**
|
||||
-free a data blob and clear its contents
|
||||
-**/
|
||||
-_PUBLIC_ void data_blob_clear_free(DATA_BLOB *d)
|
||||
-{
|
||||
- data_blob_clear(d);
|
||||
- data_blob_free(d);
|
||||
-}
|
||||
-
|
||||
-
|
||||
-/**
|
||||
-check if two data blobs are equal
|
||||
-**/
|
||||
-_PUBLIC_ int data_blob_cmp(const DATA_BLOB *d1, const DATA_BLOB *d2)
|
||||
-{
|
||||
- int ret;
|
||||
- if (d1->data == NULL && d2->data != NULL) {
|
||||
- return -1;
|
||||
- }
|
||||
- if (d1->data != NULL && d2->data == NULL) {
|
||||
- return 1;
|
||||
- }
|
||||
- if (d1->data == d2->data) {
|
||||
- return d1->length - d2->length;
|
||||
- }
|
||||
- ret = memcmp(d1->data, d2->data, MIN(d1->length, d2->length));
|
||||
- if (ret == 0) {
|
||||
- return d1->length - d2->length;
|
||||
- }
|
||||
- return ret;
|
||||
-}
|
||||
-
|
||||
-/**
|
||||
-print the data_blob as hex string
|
||||
-**/
|
||||
-_PUBLIC_ char *data_blob_hex_string_lower(TALLOC_CTX *mem_ctx, const DATA_BLOB *blob)
|
||||
-{
|
||||
- unsigned int i;
|
||||
- char *hex_string;
|
||||
-
|
||||
- hex_string = talloc_array(mem_ctx, char, (blob->length*2)+1);
|
||||
- if (!hex_string) {
|
||||
- return NULL;
|
||||
- }
|
||||
-
|
||||
- /* this must be lowercase or w2k8 cannot join a samba domain,
|
||||
- as this routine is used to encode extended DNs and windows
|
||||
- only accepts lowercase hexadecimal numbers */
|
||||
- for (i = 0; i < blob->length; i++)
|
||||
- slprintf(&hex_string[i*2], 3, "%02x", blob->data[i]);
|
||||
-
|
||||
- hex_string[(blob->length*2)] = '\0';
|
||||
- return hex_string;
|
||||
-}
|
||||
-
|
||||
-_PUBLIC_ char *data_blob_hex_string_upper(TALLOC_CTX *mem_ctx, const DATA_BLOB *blob)
|
||||
-{
|
||||
- unsigned int i;
|
||||
- char *hex_string;
|
||||
-
|
||||
- hex_string = talloc_array(mem_ctx, char, (blob->length*2)+1);
|
||||
- if (!hex_string) {
|
||||
- return NULL;
|
||||
- }
|
||||
-
|
||||
- for (i = 0; i < blob->length; i++)
|
||||
- slprintf(&hex_string[i*2], 3, "%02X", blob->data[i]);
|
||||
-
|
||||
- hex_string[(blob->length*2)] = '\0';
|
||||
- return hex_string;
|
||||
-}
|
||||
-
|
||||
-/**
|
||||
- useful for constructing data blobs in test suites, while
|
||||
- avoiding const warnings
|
||||
-**/
|
||||
-_PUBLIC_ DATA_BLOB data_blob_string_const(const char *str)
|
||||
-{
|
||||
- DATA_BLOB blob;
|
||||
- blob.data = discard_const_p(uint8_t, str);
|
||||
- blob.length = str ? strlen(str) : 0;
|
||||
- return blob;
|
||||
-}
|
||||
-
|
||||
-/**
|
||||
- useful for constructing data blobs in test suites, while
|
||||
- avoiding const warnings
|
||||
-**/
|
||||
-_PUBLIC_ DATA_BLOB data_blob_string_const_null(const char *str)
|
||||
-{
|
||||
- DATA_BLOB blob;
|
||||
- blob.data = discard_const_p(uint8_t, str);
|
||||
- blob.length = str ? strlen(str)+1 : 0;
|
||||
- return blob;
|
||||
-}
|
||||
-
|
||||
-/**
|
||||
- * Create a new data blob from const data
|
||||
- */
|
||||
-
|
||||
-_PUBLIC_ DATA_BLOB data_blob_const(const void *p, size_t length)
|
||||
-{
|
||||
- DATA_BLOB blob;
|
||||
- blob.data = discard_const_p(uint8_t, p);
|
||||
- blob.length = length;
|
||||
- return blob;
|
||||
-}
|
||||
-
|
||||
-
|
||||
-/**
|
||||
- realloc a data_blob
|
||||
-**/
|
||||
-_PUBLIC_ bool data_blob_realloc(TALLOC_CTX *mem_ctx, DATA_BLOB *blob, size_t length)
|
||||
-{
|
||||
- blob->data = talloc_realloc(mem_ctx, blob->data, uint8_t, length);
|
||||
- if (blob->data == NULL)
|
||||
- return false;
|
||||
- blob->length = length;
|
||||
- return true;
|
||||
-}
|
||||
-
|
||||
-
|
||||
-/**
|
||||
- append some data to a data blob
|
||||
-**/
|
||||
-_PUBLIC_ bool data_blob_append(TALLOC_CTX *mem_ctx, DATA_BLOB *blob,
|
||||
- const void *p, size_t length)
|
||||
-{
|
||||
- size_t old_len = blob->length;
|
||||
- size_t new_len = old_len + length;
|
||||
- if (new_len < length || new_len < old_len) {
|
||||
- return false;
|
||||
- }
|
||||
-
|
||||
- if ((const uint8_t *)p + length < (const uint8_t *)p) {
|
||||
- return false;
|
||||
- }
|
||||
-
|
||||
- if (!data_blob_realloc(mem_ctx, blob, new_len)) {
|
||||
- return false;
|
||||
- }
|
||||
-
|
||||
- memcpy(blob->data + old_len, p, length);
|
||||
- return true;
|
||||
-}
|
||||
-
|
||||
diff --git a/data_blob.h b/data_blob.h
|
||||
index 83e6cd5..ccdf30d 100644
|
||||
--- a/data_blob.h
|
||||
+++ b/data_blob.h
|
||||
@@ -61,72 +61,10 @@ _PUBLIC_ DATA_BLOB data_blob_named(const void *p, size_t length, const char *nam
|
||||
_PUBLIC_ DATA_BLOB data_blob_talloc_named(TALLOC_CTX *mem_ctx, const void *p, size_t length, const char *name);
|
||||
|
||||
/**
|
||||
- construct a zero data blob, using supplied TALLOC_CTX.
|
||||
- use this sparingly as it initialises data - better to initialise
|
||||
- yourself if you want specific data in the blob
|
||||
-**/
|
||||
-_PUBLIC_ DATA_BLOB data_blob_talloc_zero(TALLOC_CTX *mem_ctx, size_t length);
|
||||
-
|
||||
-/**
|
||||
free a data blob
|
||||
**/
|
||||
_PUBLIC_ void data_blob_free(DATA_BLOB *d);
|
||||
|
||||
-/**
|
||||
-clear a DATA_BLOB's contents
|
||||
-**/
|
||||
-_PUBLIC_ void data_blob_clear(DATA_BLOB *d);
|
||||
-
|
||||
-/**
|
||||
-free a data blob and clear its contents
|
||||
-**/
|
||||
-_PUBLIC_ void data_blob_clear_free(DATA_BLOB *d);
|
||||
-
|
||||
-/**
|
||||
-check if two data blobs are equal
|
||||
-**/
|
||||
-_PUBLIC_ int data_blob_cmp(const DATA_BLOB *d1, const DATA_BLOB *d2);
|
||||
-
|
||||
-/**
|
||||
-print the data_blob as hex string
|
||||
-**/
|
||||
-_PUBLIC_ char *data_blob_hex_string_upper(TALLOC_CTX *mem_ctx, const DATA_BLOB *blob);
|
||||
-
|
||||
-/**
|
||||
-print the data_blob as hex string
|
||||
-**/
|
||||
-_PUBLIC_ char *data_blob_hex_string_lower(TALLOC_CTX *mem_ctx, const DATA_BLOB *blob);
|
||||
-
|
||||
-/**
|
||||
- useful for constructing data blobs in test suites, while
|
||||
- avoiding const warnings
|
||||
-**/
|
||||
-_PUBLIC_ DATA_BLOB data_blob_string_const(const char *str);
|
||||
-
|
||||
-/**
|
||||
- useful for constructing data blobs in test suites, while
|
||||
- avoiding const warnings
|
||||
-
|
||||
- includes the terminating null character (as opposed to data_blo_string_const)
|
||||
-**/
|
||||
-_PUBLIC_ DATA_BLOB data_blob_string_const_null(const char *str);
|
||||
-
|
||||
-/**
|
||||
- * Create a new data blob from const data
|
||||
- */
|
||||
-_PUBLIC_ DATA_BLOB data_blob_const(const void *p, size_t length);
|
||||
-
|
||||
-/**
|
||||
- realloc a data_blob
|
||||
-**/
|
||||
-_PUBLIC_ bool data_blob_realloc(TALLOC_CTX *mem_ctx, DATA_BLOB *blob, size_t length);
|
||||
-
|
||||
-/**
|
||||
- append some data to a data blob
|
||||
-**/
|
||||
-_PUBLIC_ bool data_blob_append(TALLOC_CTX *mem_ctx, DATA_BLOB *blob,
|
||||
- const void *p, size_t length);
|
||||
-
|
||||
extern const DATA_BLOB data_blob_null;
|
||||
|
||||
#endif /* _SAMBA_DATABLOB_H_ */
|
||||
--
|
||||
1.8.3.1
|
||||
|
@ -1,332 +0,0 @@
|
||||
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
|
||||
|
@ -1,100 +0,0 @@
|
||||
From 7e2e95d0c84bd6960c46f1fa1c8227c50dd7a4b3 Mon Sep 17 00:00:00 2001
|
||||
From: Jeff Layton <jlayton@samba.org>
|
||||
Date: Thu, 10 Oct 2013 22:05:05 -0400
|
||||
Subject: [PATCH] mount.cifs: fix bad free() of string returned by dirname()
|
||||
|
||||
Coverity says:
|
||||
|
||||
Error: CPPCHECK_WARNING: [#def10]
|
||||
cifs-utils-6.2/mount.cifs.c:1518: error[memleakOnRealloc]: Common realloc mistake: 'mtabdir' nulled but not freed upon failure
|
||||
|
||||
del_mtab has a number of bugs in handling of allocated memory:
|
||||
|
||||
a) the return value of strdup() is not checked
|
||||
|
||||
b) It calls realloc() on a pointer that wasn't returned by an allocation
|
||||
function (e.g. malloc, calloc, etc.)
|
||||
|
||||
c) If realloc() fails, it doesn't call free() on the original memory
|
||||
returned by strdup()
|
||||
|
||||
Fix all of these bugs and add newlines to the end of the error messages
|
||||
in del_mtab.
|
||||
|
||||
Signed-off-by: Jeff Layton <jlayton@samba.org>
|
||||
---
|
||||
mount.cifs.c | 29 ++++++++++++++++++-----------
|
||||
1 file changed, 18 insertions(+), 11 deletions(-)
|
||||
|
||||
diff --git a/mount.cifs.c b/mount.cifs.c
|
||||
index 7206dcb..497665d 100644
|
||||
--- a/mount.cifs.c
|
||||
+++ b/mount.cifs.c
|
||||
@@ -1508,23 +1508,29 @@ add_mtab_exit:
|
||||
static int
|
||||
del_mtab(char *mountpoint)
|
||||
{
|
||||
- int tmprc, rc = 0;
|
||||
+ int len, tmprc, rc = 0;
|
||||
FILE *mnttmp, *mntmtab;
|
||||
struct mntent *mountent;
|
||||
- char *mtabfile, *mtabdir, *mtabtmpfile;
|
||||
+ char *mtabfile, *mtabdir, *mtabtmpfile = NULL;
|
||||
|
||||
mtabfile = strdup(MOUNTED);
|
||||
- mtabdir = dirname(mtabfile);
|
||||
- mtabdir = realloc(mtabdir, strlen(mtabdir) + strlen(MNT_TMP_FILE) + 2);
|
||||
- if (!mtabdir) {
|
||||
- fprintf(stderr, "del_mtab: cannot determine current mtab path");
|
||||
+ if (!mtabfile) {
|
||||
+ fprintf(stderr, "del_mtab: cannot strdup MOUNTED\n");
|
||||
rc = EX_FILEIO;
|
||||
goto del_mtab_exit;
|
||||
}
|
||||
|
||||
- mtabtmpfile = strcat(mtabdir, MNT_TMP_FILE);
|
||||
+ mtabdir = dirname(mtabfile);
|
||||
+ len = strlen(mtabdir) + strlen(MNT_TMP_FILE);
|
||||
+ mtabtmpfile = malloc(len + 1);
|
||||
if (!mtabtmpfile) {
|
||||
- fprintf(stderr, "del_mtab: cannot allocate memory to tmp file");
|
||||
+ fprintf(stderr, "del_mtab: cannot allocate memory to tmp file\n");
|
||||
+ rc = EX_FILEIO;
|
||||
+ goto del_mtab_exit;
|
||||
+ }
|
||||
+
|
||||
+ if (sprintf(mtabtmpfile, "%s%s", mtabdir, MNT_TMP_FILE) != len) {
|
||||
+ fprintf(stderr, "del_mtab: error writing new string\n");
|
||||
rc = EX_FILEIO;
|
||||
goto del_mtab_exit;
|
||||
}
|
||||
@@ -1532,14 +1538,14 @@ del_mtab(char *mountpoint)
|
||||
atexit(unlock_mtab);
|
||||
rc = lock_mtab();
|
||||
if (rc) {
|
||||
- fprintf(stderr, "del_mtab: cannot lock mtab");
|
||||
+ fprintf(stderr, "del_mtab: cannot lock mtab\n");
|
||||
rc = EX_FILEIO;
|
||||
goto del_mtab_exit;
|
||||
}
|
||||
|
||||
mtabtmpfile = mktemp(mtabtmpfile);
|
||||
if (!mtabtmpfile) {
|
||||
- fprintf(stderr, "del_mtab: cannot setup tmp file destination");
|
||||
+ fprintf(stderr, "del_mtab: cannot setup tmp file destination\n");
|
||||
rc = EX_FILEIO;
|
||||
goto del_mtab_exit;
|
||||
}
|
||||
@@ -1587,7 +1593,8 @@ del_mtab(char *mountpoint)
|
||||
|
||||
del_mtab_exit:
|
||||
unlock_mtab();
|
||||
- free(mtabdir);
|
||||
+ free(mtabtmpfile);
|
||||
+ free(mtabfile);
|
||||
return rc;
|
||||
|
||||
del_mtab_error:
|
||||
--
|
||||
1.8.3.1
|
||||
|
@ -2,8 +2,8 @@
|
||||
%define pre_release %nil
|
||||
|
||||
Name: cifs-utils
|
||||
Version: 6.2
|
||||
Release: 5%{pre_release}%{?dist}
|
||||
Version: 6.3
|
||||
Release: 1%{pre_release}%{?dist}
|
||||
Summary: Utilities for mounting and managing CIFS mounts
|
||||
|
||||
Group: System Environment/Daemons
|
||||
@ -18,17 +18,6 @@ Requires(post): /usr/sbin/alternatives
|
||||
Requires(preun): /usr/sbin/alternatives
|
||||
|
||||
Source0: ftp://ftp.samba.org/pub/linux-cifs/cifs-utils/%{name}-%{version}%{pre_release}.tar.bz2
|
||||
Patch1: 0001-get-setcifsacl-fix-bad-bit-shifts.patch
|
||||
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
|
||||
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
|
||||
@ -63,16 +52,6 @@ provide these credentials to the kernel automatically at login.
|
||||
|
||||
%prep
|
||||
%setup -q -n %{name}-%{version}%{pre_release}
|
||||
%patch1 -p1
|
||||
%patch2 -p1
|
||||
%patch3 -p1
|
||||
%patch4 -p1
|
||||
%patch5 -p1
|
||||
%patch6 -p1
|
||||
%patch7 -p1
|
||||
%patch8 -p1
|
||||
%patch9 -p1
|
||||
%patch10 -p1
|
||||
|
||||
%build
|
||||
autoreconf -i
|
||||
@ -127,6 +106,9 @@ fi
|
||||
%{_mandir}/man8/pam_cifscreds.8.gz
|
||||
|
||||
%changelog
|
||||
* Thu Jan 09 2014 Jeff Layton <jlayton@redhat.com> 6.3-1
|
||||
- update to 6.3 release
|
||||
|
||||
* Fri Dec 13 2013 Jeff Layton <jlayton@redhat.com> 6.2-5
|
||||
- fix linking of wbclient
|
||||
- add pam_cifscreds module and manpage
|
||||
|
Loading…
Reference in New Issue
Block a user