[SCM] Samba Shared Repository - branch master updated

Andreas Schneider asn at samba.org
Tue Jul 25 11:18:03 UTC 2017


The branch, master has been updated
       via  4830902 s3:tests: Add tests for smbspool_krb5_wrapper
       via  dc15954 s3:client: Use KRB5CCNAME in smbspool_krb5_wrapper if set
       via  5c178eb s3:tests: Add test for smbspool
       via  d6518d7 s3:client: Only use kerberos if credential cache exists in smbspool
       via  7a73a13 s3:client: Make it possible use smbspool in selftest
       via  a553f12 s3:client: Fix the usage of argv in smbspool
       via  924e7f7 s3:printing: Fix setting the first jobnum
       via  a19b08c s3:printing: Do not segfault in vlp if no command has been specified
       via  a841745 uwrap: Update to version 1.2.4
      from  a420b1b selftest: Use NETLOGON_NEG_STRONG_KEYS constant in AuthLogTestsNetLogonBadCreds

https://git.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 483090200737d34d656b16f9aa2523a3cba7bb17
Author: Andreas Schneider <asn at samba.org>
Date:   Tue Jul 11 10:59:59 2017 +0200

    s3:tests: Add tests for smbspool_krb5_wrapper
    
    Signed-off-by: Andreas Schneider <asn at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>
    
    Autobuild-User(master): Andreas Schneider <asn at cryptomilk.org>
    Autobuild-Date(master): Tue Jul 25 13:17:13 CEST 2017 on sn-devel-144

commit dc15954196e237d10c0fe3e9dd30316e1704ce25
Author: Andreas Schneider <asn at samba.org>
Date:   Wed Jul 12 16:07:25 2017 +0200

    s3:client: Use KRB5CCNAME in smbspool_krb5_wrapper if set
    
    Signed-off-by: Andreas Schneider <asn at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>

commit 5c178ebc965ed5884082a962ffc86371a448dfa5
Author: Andreas Schneider <asn at samba.org>
Date:   Tue Jul 11 10:58:11 2017 +0200

    s3:tests: Add test for smbspool
    
    Signed-off-by: Andreas Schneider <asn at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Ralph Boehme <slow at samba.org>

commit d6518d74dda517c84f7a4a2fe3ad37857fb9d7b0
Author: Andreas Schneider <asn at samba.org>
Date:   Tue Jul 11 09:41:08 2017 +0200

    s3:client: Only use kerberos if credential cache exists in smbspool
    
    Signed-off-by: Andreas Schneider <asn at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>

commit 7a73a130d55d3369f2d465f8268fca65de29fd37
Author: Andreas Schneider <asn at samba.org>
Date:   Mon Jul 24 12:27:50 2017 +0200

    s3:client: Make it possible use smbspool in selftest
    
    Signed-off-by: Andreas Schneider <asn at samba.org>
    Reviewed-by: Ralph Boehme <slow at samba.org>

commit a553f12418a16c58b278745e3da6329ce24fe3c7
Author: Andreas Schneider <asn at samba.org>
Date:   Tue Jul 11 10:40:39 2017 +0200

    s3:client: Fix the usage of argv in smbspool
    
    We use argv[0] to print the name of the binary, but have shifted it
    away. Do not do that.
    
    Signed-off-by: Andreas Schneider <asn at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>

commit 924e7f7c80b203e147823f802926c323d9402248
Author: Andreas Schneider <asn at samba.org>
Date:   Wed Jul 12 13:14:08 2017 +0200

    s3:printing: Fix setting the first jobnum
    
    This is just something logical. The define is called first jobnum but
    the first one was always 101.
    
    Signed-off-by: Andreas Schneider <asn at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>

commit a19b08c9c315279bc0afec09a0a409de168084b4
Author: Andreas Schneider <asn at samba.org>
Date:   Wed Jul 12 13:07:08 2017 +0200

    s3:printing: Do not segfault in vlp if no command has been specified
    
    We should just print the usage() and return
    
    Signed-off-by: Andreas Schneider <asn at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>

commit a841745166a54657e72247d2a20a04459e087084
Author: Andreas Schneider <asn at samba.org>
Date:   Thu Jul 13 08:57:13 2017 +0200

    uwrap: Update to version 1.2.4
    
    Signed-off-by: Andreas Schneider <asn at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>

-----------------------------------------------------------------------

Summary of changes:
 lib/uid_wrapper/uid_wrapper.c          |  303 +-
 lib/uid_wrapper/wscript                |    2 +-
 source3/client/smbspool.c              |  101 +-
 source3/client/smbspool_krb5_wrapper.c |    8 +
 source3/printing/tests/vlp.c           |   11 +-
 source3/script/tests/test_smbspool.sh  |  153 +
 source3/selftest/tests.py              |    3 +
 testdata/printing/example.ps           | 8374 ++++++++++++++++++++++++++++++++
 8 files changed, 8886 insertions(+), 69 deletions(-)
 create mode 100755 source3/script/tests/test_smbspool.sh
 create mode 100644 testdata/printing/example.ps


Changeset truncated at 500 lines:

diff --git a/lib/uid_wrapper/uid_wrapper.c b/lib/uid_wrapper/uid_wrapper.c
index 743d590..0d74d20 100644
--- a/lib/uid_wrapper/uid_wrapper.c
+++ b/lib/uid_wrapper/uid_wrapper.c
@@ -133,9 +133,6 @@ enum uwrap_dbglvl_e {
 	UWRAP_LOG_TRACE
 };
 
-#ifdef NDEBUG
-# define UWRAP_LOG(...)
-#else /* NDEBUG */
 static void uwrap_log(enum uwrap_dbglvl_e dbglvl, const char *function, const char *format, ...) PRINTF_ATTRIBUTE(3, 4);
 # define UWRAP_LOG(dbglvl, ...) uwrap_log((dbglvl), __func__, __VA_ARGS__)
 
@@ -145,42 +142,43 @@ static void uwrap_log(enum uwrap_dbglvl_e dbglvl, const char *function, const ch
 	va_list va;
 	const char *d;
 	unsigned int lvl = 0;
+	const char *prefix = "UWRAP";
 
 	d = getenv("UID_WRAPPER_DEBUGLEVEL");
 	if (d != NULL) {
 		lvl = atoi(d);
 	}
 
+	if (lvl < dbglvl) {
+		return;
+	}
+
 	va_start(va, format);
 	vsnprintf(buffer, sizeof(buffer), format, va);
 	va_end(va);
 
-	if (lvl >= dbglvl) {
-		const char *prefix = "UWRAP";
-		switch (dbglvl) {
-			case UWRAP_LOG_ERROR:
-				prefix = "UWRAP_ERROR";
-				break;
-			case UWRAP_LOG_WARN:
-				prefix = "UWRAP_WARN";
-				break;
-			case UWRAP_LOG_DEBUG:
-				prefix = "UWRAP_DEBUG";
-				break;
-			case UWRAP_LOG_TRACE:
-				prefix = "UWRAP_TRACE";
-				break;
-		}
-
-		fprintf(stderr,
-			"%s(%d) - %s: %s\n",
-			prefix,
-			(int)getpid(),
-			function,
-			buffer);
+	switch (dbglvl) {
+		case UWRAP_LOG_ERROR:
+			prefix = "UWRAP_ERROR";
+			break;
+		case UWRAP_LOG_WARN:
+			prefix = "UWRAP_WARN";
+			break;
+		case UWRAP_LOG_DEBUG:
+			prefix = "UWRAP_DEBUG";
+			break;
+		case UWRAP_LOG_TRACE:
+			prefix = "UWRAP_TRACE";
+			break;
 	}
+
+	fprintf(stderr,
+		"%s(%d) - %s: %s\n",
+		prefix,
+		(int)getpid(),
+		function,
+		buffer);
 }
-#endif /* NDEBUG */
 
 /*****************
  * LIBC
@@ -407,6 +405,13 @@ static void *uwrap_load_lib_handle(enum uwrap_lib lib)
 				if (handle != NULL) {
 					break;
 				}
+
+				/* glibc on Alpha and IA64 is libc.so.6.1 */
+				snprintf(soname, sizeof(soname), "libc.so.%d.1", i);
+				handle = dlopen(soname, flags);
+				if (handle != NULL) {
+					break;
+				}
 			}
 
 			uwrap.libc.handle = handle;
@@ -808,17 +813,103 @@ int pthread_create(pthread_t *thread,
  * UWRAP ID HANDLING
  *********************************************************/
 
+#define GROUP_STRING_SIZE 16384
+#define GROUP_MAX_COUNT (GROUP_STRING_SIZE / (10 + 1))
+
+/**
+ * This function exports all the IDs of the current user so if
+ * we fork and then exec we can setup uid_wrapper in the new process
+ * with those IDs.
+ */
+static void uwrap_export_ids(struct uwrap_thread *id)
+{
+	char groups_str[GROUP_STRING_SIZE] = {0};
+	size_t groups_str_size = sizeof(groups_str);
+	char unsigned_str[16] = {0}; /* We need 10 + 1 (+ 1) */
+	int i;
+
+	/* UIDS */
+	snprintf(unsigned_str, sizeof(unsigned_str), "%u", id->ruid);
+	setenv("UID_WRAPPER_INITIAL_RUID", unsigned_str, 1);
+
+	snprintf(unsigned_str, sizeof(unsigned_str), "%u", id->euid);
+	setenv("UID_WRAPPER_INITIAL_EUID", unsigned_str, 1);
+
+	snprintf(unsigned_str, sizeof(unsigned_str), "%u", id->suid);
+	setenv("UID_WRAPPER_INITIAL_SUID", unsigned_str, 1);
+
+	/* GIDS */
+	snprintf(unsigned_str, sizeof(unsigned_str), "%u", id->rgid);
+	setenv("UID_WRAPPER_INITIAL_RGID", unsigned_str, 1);
+
+	snprintf(unsigned_str, sizeof(unsigned_str), "%u", id->egid);
+	setenv("UID_WRAPPER_INITIAL_EGID", unsigned_str, 1);
+
+	snprintf(unsigned_str, sizeof(unsigned_str), "%u", id->sgid);
+	setenv("UID_WRAPPER_INITIAL_SGID", unsigned_str, 1);
+
+	if (id->ngroups > GROUP_MAX_COUNT) {
+		UWRAP_LOG(UWRAP_LOG_ERROR,
+			  "ERROR: Number of groups (%u) exceeds maximum value "
+			  "uid_wrapper can handle (%u).",
+			  id->ngroups,
+			  GROUP_MAX_COUNT);
+		exit(-1);
+	}
+
+	/* GROUPS */
+	for (i = 0; i < id->ngroups; i++) {
+		size_t groups_str_len = strlen(groups_str);
+		size_t groups_str_avail = groups_str_size - groups_str_len - 1;
+		int len;
+
+		len = snprintf(unsigned_str, sizeof(unsigned_str), ",%u", id->groups[i]);
+		if (len <= 1) {
+			UWRAP_LOG(UWRAP_LOG_ERROR,
+				  "snprintf failed for groups[%d]=%u",
+				  i,
+				  id->groups[i]);
+			break;
+		}
+		if (((size_t)len) >= groups_str_avail) {
+			UWRAP_LOG(UWRAP_LOG_ERROR,
+				  "groups env string is to small for %d groups",
+				  i);
+			break;
+		}
+
+		len = snprintf(groups_str + groups_str_len,
+			       groups_str_size - groups_str_len,
+			       "%s",
+			       i == 0 ? unsigned_str + 1 : unsigned_str);
+		if (len < 1) {
+			UWRAP_LOG(UWRAP_LOG_ERROR,
+				  "snprintf failed to create groups string at groups[%d]=%u",
+				  i,
+				  id->groups[i]);
+			break;
+		}
+	}
+
+	if (id->ngroups == i) {
+		setenv("UID_WRAPPER_INITIAL_GROUPS", groups_str, 1);
+
+		snprintf(unsigned_str, sizeof(unsigned_str), "%u", id->ngroups);
+		setenv("UID_WRAPPER_INITIAL_GROUPS_COUNT", unsigned_str, 1);
+	}
+}
+
 static void uwrap_thread_prepare(void)
 {
 	struct uwrap_thread *id = uwrap_tls_id;
 
+	UWRAP_LOCK_ALL;
+
 	/* uid_wrapper is loaded but not enabled */
 	if (id == NULL) {
 		return;
 	}
 
-	UWRAP_LOCK_ALL;
-
 	/*
 	 * What happens if another atfork prepare functions calls a uwrap
 	 * function? So disable it in case another atfork prepare function
@@ -834,6 +925,7 @@ static void uwrap_thread_parent(void)
 
 	/* uid_wrapper is loaded but not enabled */
 	if (id == NULL) {
+		UWRAP_UNLOCK_ALL;
 		return;
 	}
 
@@ -849,6 +941,7 @@ static void uwrap_thread_child(void)
 
 	/* uid_wrapper is loaded but not enabled */
 	if (id == NULL) {
+		UWRAP_UNLOCK_ALL;
 		return;
 	}
 
@@ -872,11 +965,119 @@ static void uwrap_thread_child(void)
 		u = uwrap.ids;
 	}
 
+	uwrap_export_ids(id);
+
 	id->enabled = true;
 
 	UWRAP_UNLOCK_ALL;
 }
 
+/*
+ * This initializes uid_wrapper with the IDs exported to the environment. Those
+ * are normally set after we forked and executed.
+ */
+static void uwrap_init_env(struct uwrap_thread *id)
+{
+	const char *env;
+	int ngroups = 0;
+
+	env = getenv("UID_WRAPPER_INITIAL_RUID");
+	if (env != NULL && env[0] != '\0') {
+		UWRAP_LOG(UWRAP_LOG_DEBUG, "Initialize ruid with %s", env);
+		id->ruid = strtoul(env, (char **)NULL, 10);
+		unsetenv("UID_WRAPPER_INITIAL_RUID");
+	}
+
+	env = getenv("UID_WRAPPER_INITIAL_EUID");
+	if (env != NULL && env[0] != '\0') {
+		UWRAP_LOG(UWRAP_LOG_DEBUG, "Initalize euid with %s", env);
+		id->euid = strtoul(env, (char **)NULL, 10);
+		unsetenv("UID_WRAPPER_INITIAL_EUID");
+	}
+
+	env = getenv("UID_WRAPPER_INITIAL_SUID");
+	if (env != NULL && env[0] != '\0') {
+		UWRAP_LOG(UWRAP_LOG_DEBUG, "Initalize suid with %s", env);
+		id->suid = strtoul(env, (char **)NULL, 10);
+		unsetenv("UID_WRAPPER_INITIAL_SUID");
+	}
+
+	env = getenv("UID_WRAPPER_INITIAL_RGID");
+	if (env != NULL && env[0] != '\0') {
+		UWRAP_LOG(UWRAP_LOG_DEBUG, "Initialize ruid with %s", env);
+		id->rgid = strtoul(env, (char **)NULL, 10);
+		unsetenv("UID_WRAPPER_INITIAL_RGID");
+	}
+
+	env = getenv("UID_WRAPPER_INITIAL_EGID");
+	if (env != NULL && env[0] != '\0') {
+		UWRAP_LOG(UWRAP_LOG_DEBUG, "Initalize egid with %s", env);
+		id->egid = strtoul(env, (char **)NULL, 10);
+		unsetenv("UID_WRAPPER_INITIAL_EGID");
+	}
+
+	env = getenv("UID_WRAPPER_INITIAL_SGID");
+	if (env != NULL && env[0] != '\0') {
+		UWRAP_LOG(UWRAP_LOG_DEBUG, "Initalize sgid with %s", env);
+		id->sgid = strtoul(env, (char **)NULL, 10);
+		unsetenv("UID_WRAPPER_INITIAL_SGID");
+	}
+
+	env = getenv("UID_WRAPPER_INITIAL_GROUPS_COUNT");
+	if (env != NULL && env[0] != '\0') {
+		ngroups = strtol(env, (char **)NULL, 10);
+		unsetenv("UID_WRAPPER_INITIAL_GROUPS_COUNT");
+	}
+
+	if (ngroups > 0 && ngroups < GROUP_MAX_COUNT) {
+		int i = 0;
+
+		id->ngroups = 0;
+
+		free(id->groups);
+		id->groups = malloc(sizeof(gid_t) * ngroups);
+		if (id->groups == NULL) {
+			UWRAP_LOG(UWRAP_LOG_ERROR,
+				  "Unable to allocate memory");
+			exit(-1);
+		}
+
+		env = getenv("UID_WRAPPER_INITIAL_GROUPS");
+		if (env != NULL && env[0] != '\0') {
+			char *groups_str = NULL;
+			char *saveptr = NULL;
+			const char *p = NULL;
+
+			groups_str = strdup(env);
+			if (groups_str == NULL) {
+				exit(-1);
+			}
+
+			p = strtok_r(groups_str, ",", &saveptr);
+			while (p != NULL) {
+				id->groups[i] = strtol(p, (char **)NULL, 10);
+				i++;
+
+				p = strtok_r(NULL, ",", &saveptr);
+			}
+			SAFE_FREE(groups_str);
+		}
+
+		if (i != ngroups) {
+			UWRAP_LOG(UWRAP_LOG_ERROR,
+				  "ERROR: The number of groups (%u) passed, "
+				  "does not match the number of groups (%u) "
+				  "we parsed.",
+				  ngroups,
+				  i);
+			exit(-1);
+		}
+
+		UWRAP_LOG(UWRAP_LOG_DEBUG, "Initalize groups with %s", env);
+		id->ngroups = ngroups;
+	}
+}
+
 static void uwrap_init(void)
 {
 	const char *env;
@@ -965,6 +1166,8 @@ static void uwrap_init(void)
 			}
 		}
 
+		uwrap_init_env(id);
+
 		id->enabled = true;
 
 		UWRAP_LOG(UWRAP_LOG_DEBUG,
@@ -975,7 +1178,7 @@ static void uwrap_init(void)
 
 	UWRAP_UNLOCK(uwrap_id);
 
-	UWRAP_LOG(UWRAP_LOG_DEBUG, "Succeccfully initialized uid_wrapper");
+	UWRAP_LOG(UWRAP_LOG_DEBUG, "Successfully initialized uid_wrapper");
 }
 
 bool uid_wrapper_enabled(void)
@@ -1148,9 +1351,7 @@ static int uwrap_setreuid_args(uid_t ruid, uid_t euid,
 
 static int uwrap_setreuid_thread(uid_t ruid, uid_t euid)
 {
-#ifndef NDEBUG
 	struct uwrap_thread *id = uwrap_tls_id;
-#endif
 	uid_t new_ruid = -1, new_euid = -1, new_suid = -1;
 	int rc;
 
@@ -1169,9 +1370,7 @@ static int uwrap_setreuid_thread(uid_t ruid, uid_t euid)
 #ifdef HAVE_SETREUID
 static int uwrap_setreuid(uid_t ruid, uid_t euid)
 {
-#ifndef NDEBUG
 	struct uwrap_thread *id = uwrap_tls_id;
-#endif
 	uid_t new_ruid = -1, new_euid = -1, new_suid = -1;
 	int rc;
 
@@ -1435,9 +1634,7 @@ static int uwrap_setregid_args(gid_t rgid, gid_t egid,
 
 static int uwrap_setregid_thread(gid_t rgid, gid_t egid)
 {
-#ifndef NDEBUG
 	struct uwrap_thread *id = uwrap_tls_id;
-#endif
 	gid_t new_rgid = -1, new_egid = -1, new_sgid = -1;
 	int rc;
 
@@ -1456,9 +1653,7 @@ static int uwrap_setregid_thread(gid_t rgid, gid_t egid)
 #ifdef HAVE_SETREGID
 static int uwrap_setregid(gid_t rgid, gid_t egid)
 {
-#ifndef NDEBUG
 	struct uwrap_thread *id = uwrap_tls_id;
-#endif
 	gid_t new_rgid = -1, new_egid = -1, new_sgid = -1;
 	int rc;
 
@@ -1894,7 +2089,11 @@ static long int uwrap_syscall (long int sysno, va_list vp)
 
 	switch (sysno) {
 		/* gid */
+#ifdef __alpha__
+		case SYS_getxgid:
+#else
 		case SYS_getgid:
+#endif
 #ifdef HAVE_LINUX_32BIT_SYSCALLS
 		case SYS_getgid32:
 #endif
@@ -1963,7 +2162,11 @@ static long int uwrap_syscall (long int sysno, va_list vp)
 #endif /* SYS_getresgid && HAVE_GETRESGID */
 
 		/* uid */
+#ifdef __alpha__
+		case SYS_getxuid:
+#else
 		case SYS_getuid:
+#endif
 #ifdef HAVE_LINUX_32BIT_SYSCALLS
 		case SYS_getuid32:
 #endif
@@ -2088,8 +2291,30 @@ long int syscall (long int sysno, ...)
 /****************************
  * CONSTRUCTOR
  ***************************/
+
 void uwrap_constructor(void)
 {
+	char *glibc_malloc_lock_bug;
+
+	/*
+	 * This is a workaround for a bug in glibc < 2.24:
+	 *
+	 * The child handler for the malloc() function is called and locks the
+	 * mutex. Then our child handler is called and we try to call setenv().
+	 * setenv() wants to malloc and tries to aquire the lock for malloc and
+	 * we end up in a deadlock.
+	 *
+	 * So as a workaround we need to call malloc once before we setup the
+	 * handlers.
+	 *
+	 * See https://sourceware.org/bugzilla/show_bug.cgi?id=16742
+	 */
+	glibc_malloc_lock_bug = malloc(1);
+	if (glibc_malloc_lock_bug == NULL) {
+		exit(-1);
+	}
+	glibc_malloc_lock_bug[0] = '\0';
+
 	/*
 	* If we hold a lock and the application forks, then the child
 	* is not able to unlock the mutex and we are in a deadlock.
@@ -2099,6 +2324,8 @@ void uwrap_constructor(void)
 		       &uwrap_thread_parent,
 		       &uwrap_thread_child);
 
+	free(glibc_malloc_lock_bug);
+
 	/* Here is safe place to call uwrap_init() and initialize data
 	 * for main process.
 	 */
diff --git a/lib/uid_wrapper/wscript b/lib/uid_wrapper/wscript
index e958b0c..9c1c009 100644
--- a/lib/uid_wrapper/wscript
+++ b/lib/uid_wrapper/wscript
@@ -3,7 +3,7 @@
 import Options
 import os, sys
 
-VERSION="1.2.1"
+VERSION="1.2.4"
 
 def configure(conf):
     if conf.CHECK_BUNDLED_SYSTEM('uid_wrapper', minversion=VERSION, set_target=False):
diff --git a/source3/client/smbspool.c b/source3/client/smbspool.c
index 49241c7..3b732c9 100644
--- a/source3/client/smbspool.c
+++ b/source3/client/smbspool.c
@@ -25,7 +25,9 @@
 #include "includes.h"
 #include "system/filesys.h"
 #include "system/passwd.h"
+#include "system/kerberos.h"
 #include "libsmb/libsmb.h"
+#include "lib/param/param.h"
 
 /*
  * Starting with CUPS 1.3, Kerberos support is provided by cupsd including
@@ -96,20 +98,11 @@ main(int argc,			/* I - Number of command-line arguments */
 	int             tries = 0;
 	bool		need_auth = true;
 	const char     *dev_uri;
+	const char     *config_file = NULL;
 	TALLOC_CTX     *frame = talloc_stackframe();
 
 	null_str[0] = '\0';
 
-	/*
-	 * we expect the URI in argv[0]. Detect the case where it is in
-	 * argv[1] and cope
-	 */


-- 
Samba Shared Repository



More information about the samba-cvs mailing list