From 4a2dfbf3c94c8fc4c2cbcbea3b138c5a9674f951 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?G=C3=BCnther=20Deschner?= <gd@samba.org>
Date: Tue, 14 Apr 2009 01:08:23 +0200
Subject: [PATCH 01/13] s4-smbtorture: print SPOOLSS_JOB_CONTROL flags in
 RPC-SPOOLSS test.

Guenther
---
 source4/torture/rpc/spoolss.c | 33 ++++++++++++++++++++++++++++++++-
 1 file changed, 32 insertions(+), 1 deletion(-)

diff --git a/source4/torture/rpc/spoolss.c b/source4/torture/rpc/spoolss.c
index b1889704a73..d17b3c7b609 100644
--- a/source4/torture/rpc/spoolss.c
+++ b/source4/torture/rpc/spoolss.c
@@ -1101,7 +1101,38 @@ static bool test_SetJob(struct torture_context *tctx,
 	r.in.ctr	= NULL;
 	r.in.command	= command;
 
-	torture_comment(tctx, "Testing SetJob\n");
+	switch (command) {
+	case SPOOLSS_JOB_CONTROL_PAUSE:
+		torture_comment(tctx, "Testing SetJob: SPOOLSS_JOB_CONTROL_PAUSE\n");
+		break;
+	case SPOOLSS_JOB_CONTROL_RESUME:
+		torture_comment(tctx, "Testing SetJob: SPOOLSS_JOB_CONTROL_RESUME\n");
+		break;
+	case SPOOLSS_JOB_CONTROL_CANCEL:
+		torture_comment(tctx, "Testing SetJob: SPOOLSS_JOB_CONTROL_CANCEL\n");
+		break;
+	case SPOOLSS_JOB_CONTROL_RESTART:
+		torture_comment(tctx, "Testing SetJob: SPOOLSS_JOB_CONTROL_RESTART\n");
+		break;
+	case SPOOLSS_JOB_CONTROL_DELETE:
+		torture_comment(tctx, "Testing SetJob: SPOOLSS_JOB_CONTROL_DELETE\n");
+		break;
+	case SPOOLSS_JOB_CONTROL_SEND_TO_PRINTER:
+		torture_comment(tctx, "Testing SetJob: SPOOLSS_JOB_CONTROL_SEND_TO_PRINTER\n");
+		break;
+	case SPOOLSS_JOB_CONTROL_LAST_PAGE_EJECTED:
+		torture_comment(tctx, "Testing SetJob: SPOOLSS_JOB_CONTROL_LAST_PAGE_EJECTED\n");
+		break;
+	case SPOOLSS_JOB_CONTROL_RETAIN:
+		torture_comment(tctx, "Testing SetJob: SPOOLSS_JOB_CONTROL_RETAIN\n");
+		break;
+	case SPOOLSS_JOB_CONTROL_RELEASE:
+		torture_comment(tctx, "Testing SetJob: SPOOLSS_JOB_CONTROL_RELEASE\n");
+		break;
+	default:
+		torture_comment(tctx, "Testing SetJob\n");
+		break;
+	}
 
 	status = dcerpc_spoolss_SetJob(p, tctx, &r);
 	torture_assert_ntstatus_ok(tctx, status, "SetJob failed");

From e3ceb0c65333cb870463971021e3af24d82abf26 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?G=C3=BCnther=20Deschner?= <gd@samba.org>
Date: Tue, 14 Apr 2009 12:00:39 +0200
Subject: [PATCH 02/13] s3-spoolss: remove unused dup_nt_devicemode().

Guenther
---
 source3/include/proto.h        |  1 -
 source3/printing/nt_printing.c | 28 ----------------------------
 2 files changed, 29 deletions(-)

diff --git a/source3/include/proto.h b/source3/include/proto.h
index b8ba8c03ada..25e81fde11f 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -4843,7 +4843,6 @@ WERROR move_driver_to_download_area(struct pipes_struct *p,
 int pack_devicemode(NT_DEVICEMODE *nt_devmode, uint8 *buf, int buflen);
 uint32 del_a_printer(const char *sharename);
 NT_DEVICEMODE *construct_nt_devicemode(const fstring default_devicename);
-NT_DEVICEMODE *dup_nt_devicemode(NT_DEVICEMODE *nt_devicemode);
 void free_nt_devicemode(NT_DEVICEMODE **devmode_ptr);
 int unpack_devicemode(NT_DEVICEMODE **nt_devmode, const uint8 *buf, int buflen);
 int add_new_printer_key( NT_PRINTER_DATA *data, const char *name );
diff --git a/source3/printing/nt_printing.c b/source3/printing/nt_printing.c
index c20171b0496..f3b938e6ff4 100644
--- a/source3/printing/nt_printing.c
+++ b/source3/printing/nt_printing.c
@@ -2731,34 +2731,6 @@ NT_DEVICEMODE *construct_nt_devicemode(const fstring default_devicename)
 	return nt_devmode;
 }
 
-/****************************************************************************
- Deepcopy an NT devicemode.
-****************************************************************************/
-
-NT_DEVICEMODE *dup_nt_devicemode(NT_DEVICEMODE *nt_devicemode)
-{
-	NT_DEVICEMODE *new_nt_devicemode = NULL;
-
-	if ( !nt_devicemode )
-		return NULL;
-
-	if ((new_nt_devicemode = (NT_DEVICEMODE *)memdup(nt_devicemode, sizeof(NT_DEVICEMODE))) == NULL) {
-		DEBUG(0,("dup_nt_devicemode: malloc fail.\n"));
-		return NULL;
-	}
-
-	new_nt_devicemode->nt_dev_private = NULL;
-	if (nt_devicemode->nt_dev_private != NULL) {
-		if ((new_nt_devicemode->nt_dev_private = (uint8 *)memdup(nt_devicemode->nt_dev_private, nt_devicemode->driverextra)) == NULL) {
-			SAFE_FREE(new_nt_devicemode);
-			DEBUG(0,("dup_nt_devicemode: malloc fail.\n"));
-			return NULL;
-        }
-	}
-
-	return new_nt_devicemode;
-}
-
 /****************************************************************************
  Clean up and deallocate a (maybe partially) allocated NT_DEVICEMODE.
 ****************************************************************************/

From fa302020ee39bf39bf324983cf8e381232691e76 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?G=C3=BCnther=20Deschner?= <gd@samba.org>
Date: Tue, 14 Apr 2009 12:08:55 +0200
Subject: [PATCH 03/13] s3-svcctl: fix memcpy in _svcctl_EnumServicesStatusW().

Make sure we are not copying more than what we have as valid data.

Fix from Jeremy. Thanks a lot for watching this so closely!

Guenther
---
 source3/rpc_server/srv_svcctl_nt.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/source3/rpc_server/srv_svcctl_nt.c b/source3/rpc_server/srv_svcctl_nt.c
index 0b0ef83bee9..d73f73f9ecc 100644
--- a/source3/rpc_server/srv_svcctl_nt.c
+++ b/source3/rpc_server/srv_svcctl_nt.c
@@ -464,9 +464,8 @@ WERROR _svcctl_EnumServicesStatusW(pipes_struct *p,
 		if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
 			return ntstatus_to_werror(ndr_map_error2ntstatus(ndr_err));
 		}
-
 		blob = ndr_push_blob(ndr);
-		memcpy(r->out.service, blob.data, r->in.offered);
+		memcpy(r->out.service, blob.data, MIN(blob.length, r->in.offered));
 	}
 
 	*r->out.needed			= (buffer_size > r->in.offered) ? buffer_size : r->in.offered;

From a2ef1fee69771f58c27604ef213405031f42ff96 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?G=C3=BCnther=20Deschner?= <gd@samba.org>
Date: Tue, 14 Apr 2009 12:10:22 +0200
Subject: [PATCH 04/13] s4-smbtorture: make sure samba3 does not regress in
 EnumServicesStatusW call.

Guenther
---
 source4/torture/rpc/svcctl.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/source4/torture/rpc/svcctl.c b/source4/torture/rpc/svcctl.c
index e38e8daba1f..631e367c3bc 100644
--- a/source4/torture/rpc/svcctl.c
+++ b/source4/torture/rpc/svcctl.c
@@ -374,6 +374,9 @@ static bool test_EnumServicesStatus(struct torture_context *tctx, struct dcerpc_
 
 	for(i = 0; i < services_returned; i++) {
 
+		torture_assert(tctx, service[i].service_name,
+			"Service without name returned!");
+
 		printf("%-20s   \"%s\", Type: %d, State: %d\n",
 			service[i].service_name, service[i].display_name,
 			service[i].status.type, service[i].status.state);

From 74707e8e8e1be2cbaa71fb0442957be2e663cbde Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze@samba.org>
Date: Tue, 14 Apr 2009 12:45:48 +0200
Subject: [PATCH 05/13] socket_wrapper: fix the build on systems without ipv6
 support

metze
---
 lib/socket_wrapper/socket_wrapper.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/lib/socket_wrapper/socket_wrapper.c b/lib/socket_wrapper/socket_wrapper.c
index d3853de50d0..d809d8a500d 100644
--- a/lib/socket_wrapper/socket_wrapper.c
+++ b/lib/socket_wrapper/socket_wrapper.c
@@ -1102,8 +1102,10 @@ static uint8_t *swrap_marshall_packet(struct socket_info *si,
 	switch (si->family) {
 	case AF_INET:
 		break;
+#ifdef HAVE_IPV6
 	case AF_INET6:
 		break;
+#endif
 	default:
 		return NULL;
 	}

From 1b9384a11f2957bcfbe9f23e023c79535d4a7bc9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?G=C3=BCnther=20Deschner?= <gd@samba.org>
Date: Tue, 14 Apr 2009 14:55:24 +0200
Subject: [PATCH 06/13] s3-nsswitch: fix make test_wbpad.

Guenther
---
 source3/script/tests/wb_pad.sh | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/source3/script/tests/wb_pad.sh b/source3/script/tests/wb_pad.sh
index f1f5ca24c4d..10cedc897de 100755
--- a/source3/script/tests/wb_pad.sh
+++ b/source3/script/tests/wb_pad.sh
@@ -46,7 +46,7 @@ cleanup() {
 	rmdir $tempdir
 }
 
-cflags="-I. -I./../lib/replace -Iinclude"
+cflags="-I. -I../ -I./../lib/replace -Iinclude"
 ${CC:-gcc} -m32 $RPM_OPT_FLAGS $CFLAGS -o $tempdir/wb_pad_32 $cflags $tempdir/wb_pad.c
 if [ $? -ne 0 ]; then
 	cleanup

From 48f14949b1b9a377c2af489032de02a0fe4d118b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?G=C3=BCnther=20Deschner?= <gd@samba.org>
Date: Tue, 14 Apr 2009 16:27:05 +0200
Subject: [PATCH 07/13] libwbclient: Fix undocumented arguments doxygen
 warnings.

Guenther
(cherry picked from commit f2b3fbf0c04a6f9484853da263174a472eb6bb6d)
---
 nsswitch/libwbclient/wbclient.h | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/nsswitch/libwbclient/wbclient.h b/nsswitch/libwbclient/wbclient.h
index 9d29951ae52..d3c1b634f5e 100644
--- a/nsswitch/libwbclient/wbclient.h
+++ b/nsswitch/libwbclient/wbclient.h
@@ -495,7 +495,7 @@ struct wbcDomainControllerInfoEx {
 /**
  * @brief Free library allocated memory
  *
- * @param *p Pointer to free
+ * @param * Pointer to free
  *
  * @return void
  **/
@@ -520,7 +520,7 @@ wbcErr wbcSidToString(const struct wbcDomainSid *sid,
 /**
  * @brief Convert a character string to a binary SID
  *
- * @param *str          Character string in the form of S-...
+ * @param *sid_string   Character string in the form of S-...
  * @param sid           Resulting binary SID
  *
  * @return #wbcErr
@@ -546,7 +546,7 @@ wbcErr wbcGuidToString(const struct wbcGuid *guid,
 /**
  * @brief Convert a character string to a binary GUID
  *
- * @param *str          Character string
+ * @param *guid_string  Character string
  * @param guid          Resulting binary GUID
  *
  * @return #wbcErr
@@ -572,7 +572,7 @@ wbcErr wbcInterfaceDetails(struct wbcInterfaceDetails **details);
 /**
  * @brief Convert a domain and name to SID
  *
- * @param domain      Domain name (possibly "")
+ * @param dom_name    Domain name (possibly "")
  * @param name        User or group name
  * @param *sid        Pointer to the resolved domain SID
  * @param *name_type  Pointer to the SID type
@@ -588,9 +588,9 @@ wbcErr wbcLookupName(const char *dom_name,
  * @brief Convert a SID to a domain and name
  *
  * @param *sid        Pointer to the domain SID to be resolved
- * @param pdomain     Resolved Domain name (possibly "")
- * @param pname       Resolved User or group name
- * @param *pname_type Pointer to the resolved SID type
+ * @param domain     Resolved Domain name (possibly "")
+ * @param name       Resolved User or group name
+ * @param *name_type Pointer to the resolved SID type
  *
  * @return #wbcErr
  **/
@@ -959,7 +959,7 @@ wbcErr wbcGetGroups(const char *account,
  * @brief Lookup the current status of a trusted domain
  *
  * @param domain      Domain to query
- * @param *dinfo       Pointer to returned domain_info struct
+ * @param *info       Pointer to returned domain_info struct
  *
  * @return #wbcErr
  **/

From 27a3118bcf6105848e8200c15ebab910831f73c6 Mon Sep 17 00:00:00 2001
From: Jeremy Allison <jra@samba.org>
Date: Tue, 14 Apr 2009 12:23:22 -0700
Subject: [PATCH 08/13] Make talloc_stack threadsafe using TLS. Volker please
 check. Passes make test and basic valgrind testing. Jeremy.

---
 lib/util/config.mk              |  1 +
 lib/util/smb_threads.c          | 19 +++++--
 lib/util/smb_threads_internal.h |  5 +-
 lib/util/talloc_stack.c         | 93 ++++++++++++++++++++++++++-------
 4 files changed, 93 insertions(+), 25 deletions(-)

diff --git a/lib/util/config.mk b/lib/util/config.mk
index 7835fed9118..1b620d1464c 100644
--- a/lib/util/config.mk
+++ b/lib/util/config.mk
@@ -27,6 +27,7 @@ LIBSAMBA-UTIL_OBJ_FILES = $(addprefix $(libutilsrcdir)/, \
 		become_daemon.o \
 		rbtree.o \
 		talloc_stack.o \
+		smb_threads.o \
 		params.o)
 
 PUBLIC_HEADERS += $(addprefix $(libutilsrcdir)/, util.h \
diff --git a/lib/util/smb_threads.c b/lib/util/smb_threads.c
index 84dec4d874a..8e0e1cd9157 100644
--- a/lib/util/smb_threads.c
+++ b/lib/util/smb_threads.c
@@ -50,8 +50,19 @@ int smb_thread_set_functions(const struct smb_thread_functions *tf)
 
 	global_tfp = tf;
 
+#if defined(PARANOID_MALLOC_CHECKER)
+#ifdef malloc
+#undef malloc
+#endif
+#endif
+
 	/* Here we initialize any static locks we're using. */
-	global_lock_array = (void **)SMB_MALLOC_ARRAY(void *, NUM_GLOBAL_LOCKS);
+	global_lock_array = (void **)malloc(sizeof(void *) *NUM_GLOBAL_LOCKS);
+
+#if defined(PARANOID_MALLOC_CHECKER)
+#define malloc(s) __ERROR_DONT_USE_MALLOC_DIRECTLY
+#endif
+
 	if (global_lock_array == NULL) {
 		return ENOMEM;
 	}
@@ -62,9 +73,11 @@ int smb_thread_set_functions(const struct smb_thread_functions *tf)
 			SAFE_FREE(global_lock_array);
 			return ENOMEM;
 		}
-		global_tfp->create_mutex(name,
+		if (global_tfp->create_mutex(name,
 				&global_lock_array[i],
-				__location__);
+				__location__)) {
+			smb_panic("smb_thread_set_functions: create mutexes failed");
+		}
 		SAFE_FREE(name);
 	}
 
diff --git a/lib/util/smb_threads_internal.h b/lib/util/smb_threads_internal.h
index 3208bc27e13..ad05aae9a5e 100644
--- a/lib/util/smb_threads_internal.h
+++ b/lib/util/smb_threads_internal.h
@@ -44,9 +44,10 @@
 	} while (0)
 
 #define SMB_THREAD_SET_TLS(key, val) \
-	(global_tfp ? global_tfp->set_tls((key),(val),__location__) : 0)
+	(global_tfp ? global_tfp->set_tls((key),(val),__location__) : \
+		((key) = (val), 0))
 
 #define SMB_THREAD_GET_TLS(key) \
-	(global_tfp ? global_tfp->get_tls((key), __location__) : NULL)
+	(global_tfp ? global_tfp->get_tls((key), __location__) : (key))
 
 #endif
diff --git a/lib/util/talloc_stack.c b/lib/util/talloc_stack.c
index 2f3ea11377f..a9b6e033ceb 100644
--- a/lib/util/talloc_stack.c
+++ b/lib/util/talloc_stack.c
@@ -2,6 +2,7 @@
    Unix SMB/CIFS implementation.
    Implement a stack of talloc contexts
    Copyright (C) Volker Lendecke 2007
+   Copyright (C) Jeremy Allison 2009 - made thread safe.
 
    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
@@ -38,22 +39,65 @@
 
 #include "includes.h"
 
-static int talloc_stacksize;
-static int talloc_stack_arraysize;
-static TALLOC_CTX **talloc_stack;
+struct talloc_stackframe {
+	int talloc_stacksize;
+	int talloc_stack_arraysize;
+	TALLOC_CTX **talloc_stack;
+};
+
+/*
+ * In the single threaded case this is a pointer
+ * to the global talloc_stackframe. In the MT-case
+ * this is the pointer to the thread-specific key
+ * used to look up the per-thread talloc_stackframe
+ * pointer.
+ */
+
+static void *global_ts;
+
+static struct talloc_stackframe *talloc_stackframe_init(void)
+{
+#if defined(PARANOID_MALLOC_CHECKER)
+#ifdef malloc
+#undef malloc
+#endif
+#endif
+	struct talloc_stackframe *ts =
+		(struct talloc_stackframe *)malloc(sizeof(struct talloc_stackframe));
+#if defined(PARANOID_MALLOC_CHECKER)
+#define malloc(s) __ERROR_DONT_USE_MALLOC_DIRECTLY
+#endif
+
+	if (!ts) {
+		smb_panic("talloc_stackframe_init malloc failed");
+	}
+
+	ZERO_STRUCTP(ts);
+
+	if (SMB_THREAD_CREATE_TLS("talloc_stackframe", global_ts)) {
+		smb_panic("talloc_stackframe_init create_tls failed");
+	}
+
+	if (SMB_THREAD_SET_TLS(global_ts, ts)) {
+		smb_panic("talloc_stackframe_init set_tls failed");
+	}
+	return ts;
+}
 
 static int talloc_pop(TALLOC_CTX *frame)
 {
+	struct talloc_stackframe *ts =
+		(struct talloc_stackframe *)SMB_THREAD_GET_TLS(global_ts);
 	int i;
 
-	for (i=talloc_stacksize-1; i>0; i--) {
-		if (frame == talloc_stack[i]) {
+	for (i=ts->talloc_stacksize-1; i>0; i--) {
+		if (frame == ts->talloc_stack[i]) {
 			break;
 		}
-		talloc_free(talloc_stack[i]);
+		talloc_free(ts->talloc_stack[i]);
 	}
 
-	talloc_stacksize = i;
+	ts->talloc_stacksize = i;
 	return 0;
 }
 
@@ -67,22 +111,27 @@ static int talloc_pop(TALLOC_CTX *frame)
 static TALLOC_CTX *talloc_stackframe_internal(size_t poolsize)
 {
 	TALLOC_CTX **tmp, *top, *parent;
+	struct talloc_stackframe *ts =
+		(struct talloc_stackframe *)SMB_THREAD_GET_TLS(global_ts);
 
-	if (talloc_stack_arraysize < talloc_stacksize + 1) {
-		tmp = talloc_realloc(NULL, talloc_stack, TALLOC_CTX *,
-					   talloc_stacksize + 1);
+	if (ts == NULL) {
+		ts = talloc_stackframe_init();
+	}
+
+	if (ts->talloc_stack_arraysize < ts->talloc_stacksize + 1) {
+		tmp = talloc_realloc(NULL, ts->talloc_stack, TALLOC_CTX *,
+					   ts->talloc_stacksize + 1);
 		if (tmp == NULL) {
 			goto fail;
 		}
-		talloc_stack = tmp;
-		talloc_stack_arraysize = talloc_stacksize + 1;
+		ts->talloc_stack = tmp;
+		ts->talloc_stack_arraysize = ts->talloc_stacksize + 1;
         }
 
-	if (talloc_stacksize == 0) {
-		parent = talloc_stack;
-	}
-	else {
-		parent = talloc_stack[talloc_stacksize-1];
+	if (ts->talloc_stacksize == 0) {
+		parent = ts->talloc_stack;
+	} else {
+		parent = ts->talloc_stack[ts->talloc_stacksize-1];
 	}
 
 	if (poolsize) {
@@ -97,7 +146,7 @@ static TALLOC_CTX *talloc_stackframe_internal(size_t poolsize)
 
 	talloc_set_destructor(top, talloc_pop);
 
-	talloc_stack[talloc_stacksize++] = top;
+	ts->talloc_stack[ts->talloc_stacksize++] = top;
 	return top;
 
  fail:
@@ -121,10 +170,14 @@ TALLOC_CTX *talloc_stackframe_pool(size_t poolsize)
 
 TALLOC_CTX *talloc_tos(void)
 {
-	if (talloc_stacksize == 0) {
+	struct talloc_stackframe *ts =
+		(struct talloc_stackframe *)SMB_THREAD_GET_TLS(global_ts);
+
+	if (ts == NULL) {
 		talloc_stackframe();
+		ts = (struct talloc_stackframe *)SMB_THREAD_GET_TLS(global_ts);
 		DEBUG(0, ("no talloc stackframe around, leaking memory\n"));
 	}
 
-	return talloc_stack[talloc_stacksize-1];
+	return ts->talloc_stack[ts->talloc_stacksize-1];
 }

From 0f1b402848d987f691d6376a624373380e7e2ce6 Mon Sep 17 00:00:00 2001
From: Jeremy Allison <jra@samba.org>
Date: Tue, 14 Apr 2009 13:02:29 -0700
Subject: [PATCH 09/13] Try and fix the S4 build - include thread includes.
 Jeremy.

---
 source4/include/includes.h | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/source4/include/includes.h b/source4/include/includes.h
index d9b7759e7e9..4862a62e22c 100644
--- a/source4/include/includes.h
+++ b/source4/include/includes.h
@@ -64,6 +64,10 @@
 /* String routines */
 #include "../lib/util/safe_string.h"
 
+/* Thread functions. */
+#include "../lib/util/smb_threads.h"
+#include "../lib/util/smb_threads_internal.h"
+
 #if 0
 /* darn, we can't do this now that we don't link the ldb tools to all the smb libs */
 #define TALLOC_ABORT(reason) smb_panic(reason)

From ca3de0103b545c86c8507dfc7d042f1838d5dfb2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?G=C3=BCnther=20Deschner?= <gd@samba.org>
Date: Tue, 14 Apr 2009 22:39:36 +0200
Subject: [PATCH 10/13] netdomjoin-gui: make sure to grey out change fields
 when not running as root.

Guenther
---
 .../examples/netdomjoin-gui/netdomjoin-gui.c      | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/source3/lib/netapi/examples/netdomjoin-gui/netdomjoin-gui.c b/source3/lib/netapi/examples/netdomjoin-gui/netdomjoin-gui.c
index 40a6e415ebf..8164b7456b3 100644
--- a/source3/lib/netapi/examples/netdomjoin-gui/netdomjoin-gui.c
+++ b/source3/lib/netapi/examples/netdomjoin-gui/netdomjoin-gui.c
@@ -78,6 +78,7 @@ typedef struct join_state {
 	gboolean hostname_changed;
 	uint32_t stored_num_ous;
 	char *target_hostname;
+	uid_t uid;
 } join_state;
 
 static void debug(const char *format, ...)
@@ -1440,6 +1441,10 @@ static int draw_main_window(struct join_state *state)
 		/* Entry */
 		entry = gtk_entry_new();
 		gtk_entry_set_max_length(GTK_ENTRY(entry), 256);
+
+		if (state->uid != 0) {
+			gtk_widget_set_sensitive(GTK_WIDGET(entry), FALSE);
+		}
 		g_signal_connect(G_OBJECT(entry), "changed",
 				 G_CALLBACK(callback_enter_computer_description_and_unlock),
 				 state);
@@ -1526,6 +1531,9 @@ static int draw_main_window(struct join_state *state)
 			 G_CALLBACK(callback_do_change),
 			 (gpointer)state);
 	gtk_box_pack_start(GTK_BOX(bbox), button, TRUE, TRUE, 0);
+	if (state->uid != 0) {
+		gtk_widget_set_sensitive(GTK_WIDGET(button), FALSE);
+	}
 	gtk_widget_show(button);
 
 	/* Label (hidden) */
@@ -1533,6 +1541,11 @@ static int draw_main_window(struct join_state *state)
 	gtk_label_set_line_wrap(GTK_LABEL(state->label_reboot), TRUE);
 	gtk_misc_set_alignment(GTK_MISC(state->label_reboot), 0, 0);
 	gtk_box_pack_start(GTK_BOX(vbox), state->label_reboot, TRUE, TRUE, 0);
+	if (state->uid != 0) {
+		gtk_label_set_text(GTK_LABEL(state->label_reboot),
+			   "You cannot change computer description as you're not running with root permissions");
+	}
+
 	gtk_widget_show(state->label_reboot);
 
 #if 0
@@ -1763,6 +1776,8 @@ static int initialize_join_state(struct join_state *state,
 		return -1;
 	}
 
+	state->uid = geteuid();
+
 	state->ctx = ctx;
 
 	return 0;

From 4721be488ceb8229d564e4b63ca9937603394e51 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?G=C3=BCnther=20Deschner?= <gd@samba.org>
Date: Tue, 14 Apr 2009 23:19:25 +0200
Subject: [PATCH 11/13] s3-spoolss: Fix format of description string in
 spoolss_PrinterInfo1.

This is what windows does and should get us closer to show the appropriate
printer location string in explorer.

Guenther
---
 source3/rpc_server/srv_spoolss_nt.c | 16 ++++++----------
 1 file changed, 6 insertions(+), 10 deletions(-)

diff --git a/source3/rpc_server/srv_spoolss_nt.c b/source3/rpc_server/srv_spoolss_nt.c
index effbb922666..d114152f64a 100644
--- a/source3/rpc_server/srv_spoolss_nt.c
+++ b/source3/rpc_server/srv_spoolss_nt.c
@@ -4128,25 +4128,21 @@ static WERROR construct_printer_info1(TALLOC_CTX *mem_ctx,
 				      struct spoolss_PrinterInfo1 *r,
 				      int snum)
 {
-	char *chaine = NULL;
 	r->flags		= flags;
 
+	r->description		= talloc_asprintf(mem_ctx, "%s,%s,%s",
+						  ntprinter->info_2->printername,
+						  ntprinter->info_2->drivername,
+						  ntprinter->info_2->location);
+	W_ERROR_HAVE_NO_MEMORY(r->description);
+
 	if (*ntprinter->info_2->comment == '\0') {
 		r->comment	= talloc_strdup(mem_ctx, lp_comment(snum));
-		chaine = talloc_asprintf(mem_ctx,
-				"%s,%s,%s", ntprinter->info_2->printername,
-				ntprinter->info_2->drivername, lp_comment(snum));
 	} else {
 		r->comment	= talloc_strdup(mem_ctx, ntprinter->info_2->comment); /* saved comment */
-		chaine = talloc_asprintf(mem_ctx,
-				"%s,%s,%s", ntprinter->info_2->printername,
-				ntprinter->info_2->drivername, ntprinter->info_2->comment);
 	}
-	W_ERROR_HAVE_NO_MEMORY(chaine);
 	W_ERROR_HAVE_NO_MEMORY(r->comment);
 
-	r->description		= talloc_strdup(mem_ctx, chaine);
-	W_ERROR_HAVE_NO_MEMORY(r->description);
 	r->name			= talloc_strdup(mem_ctx, ntprinter->info_2->printername);
 	W_ERROR_HAVE_NO_MEMORY(r->name);
 

From 8e06e945b6b03db825862f2f057f0dfe13ade3a2 Mon Sep 17 00:00:00 2001
From: Jeremy Allison <jra@samba.org>
Date: Tue, 14 Apr 2009 15:19:39 -0700
Subject: [PATCH 12/13] Ensure a tls key is only generated once - wrap create &
 destroy in a mutex. Change the function names to add _once to the tls_create
 & tls_destroy to make this obvious. Jeremy.

---
 lib/util/smb_threads.c          |  9 ++--
 lib/util/smb_threads.h          | 84 ++++++++++++++++++++-------------
 lib/util/smb_threads_internal.h | 16 +++++--
 lib/util/talloc_stack.c         |  2 +-
 4 files changed, 71 insertions(+), 40 deletions(-)

diff --git a/lib/util/smb_threads.c b/lib/util/smb_threads.c
index 8e0e1cd9157..fa2d8da1865 100644
--- a/lib/util/smb_threads.c
+++ b/lib/util/smb_threads.c
@@ -25,8 +25,6 @@
 
 #include "includes.h"
 
-#define NUM_GLOBAL_LOCKS 1
-
 /*********************************************************
  Functions to vector the locking primitives used internally
  by libsmbclient.
@@ -94,14 +92,18 @@ int smb_thread_set_functions(const struct smb_thread_functions *tf)
 
 SMB_THREADS_DEF_PTHREAD_IMPLEMENTATION(tf);
 
+void *pkey = NULL;
+
 /* Test function. */
 int test_threads(void)
 {
 	int ret;
 	void *plock = NULL;
-
 	smb_thread_set_functions(&tf);
 
+	if ((ret = SMB_THREAD_CREATE_TLS_ONCE("test_tls", pkey)) != 0) {
+		printf("Create tls once error: %d\n", ret);
+	}
 	if ((ret = SMB_THREAD_CREATE_MUTEX("test", plock)) != 0) {
 		printf("Create lock error: %d\n", ret);
 	}
@@ -112,6 +114,7 @@ int test_threads(void)
 		printf("unlock error: %d\n", ret);
 	}
 	SMB_THREAD_DESTROY_MUTEX(plock);
+	SMB_THREAD_DESTROY_TLS_ONCE(pkey);
 
 	return 0;
 }
diff --git a/lib/util/smb_threads.h b/lib/util/smb_threads.h
index 2ca163be9a7..945e93803a3 100644
--- a/lib/util/smb_threads.h
+++ b/lib/util/smb_threads.h
@@ -36,10 +36,10 @@ struct smb_thread_functions {
 			const char *location);
 
 	/* Thread local storage. */
-	int (*create_tls)(const char *keyname,
+	int (*create_tls_once)(const char *keyname,
 			void **ppkey,
 			const char *location);
-	void (*destroy_tls)(void *pkey,
+	void (*destroy_tls_once)(void **pkey,
 			const char *location);
 	int (*set_tls)(void *pkey, const void *pval, const char *location);
 	void *(*get_tls)(void *pkey, const char *location);
@@ -53,49 +53,69 @@ extern const struct smb_thread_functions *global_tfp;
  \
 static int smb_create_mutex_pthread(const char *lockname, void **pplock, const char *location) \
 { \
-        pthread_mutex_t *pmut = (pthread_mutex_t *)malloc(sizeof(pthread_mutex_t)); \
-        if (!pmut) { \
-                return ENOMEM; \
-        } \
-        pthread_mutex_init(pmut, NULL); \
-        *pplock = (void *)pmut; \
-        return 0; \
+	pthread_mutex_t *pmut = (pthread_mutex_t *)malloc(sizeof(pthread_mutex_t)); \
+	if (!pmut) { \
+		return ENOMEM; \
+	} \
+	pthread_mutex_init(pmut, NULL); \
+	*pplock = (void *)pmut; \
+	return 0; \
 } \
  \
 static void smb_destroy_mutex_pthread(void *plock, const char *location) \
 { \
-        pthread_mutex_destroy((pthread_mutex_t *)plock); \
+	pthread_mutex_destroy((pthread_mutex_t *)plock); \
 	free(plock); \
 } \
  \
 static int smb_lock_pthread(void *plock, enum smb_thread_lock_type lock_type, const char *location) \
 { \
-        if (lock_type == SMB_THREAD_UNLOCK) { \
-                return pthread_mutex_unlock((pthread_mutex_t *)plock); \
-        } else { \
-                return pthread_mutex_lock((pthread_mutex_t *)plock); \
-        } \
+	if (lock_type == SMB_THREAD_UNLOCK) { \
+		return pthread_mutex_unlock((pthread_mutex_t *)plock); \
+	} else { \
+		return pthread_mutex_lock((pthread_mutex_t *)plock); \
+	} \
 } \
  \
-static int smb_create_tls_pthread(const char *keyname, void **ppkey, const char *location) \
+static pthread_mutex_t create_tls_mutex = PTHREAD_MUTEX_INITIALIZER; \
+ \
+static int smb_create_tls_once_pthread(const char *keyname, void **ppkey, const char *location) \
 { \
-        int ret; \
-        pthread_key_t *pkey = (pthread_key_t *)malloc(sizeof(pthread_key_t)); \
-        if (!pkey) { \
-                return ENOMEM; \
-        } \
-        ret = pthread_key_create(pkey, NULL); \
-        if (ret) { \
-                return ret; \
-        } \
-        *ppkey = (void *)pkey; \
-        return 0; \
+	int ret; \
+	pthread_key_t *pkey; \
+	ret = pthread_mutex_lock(&create_tls_mutex); \
+	if (ret) { \
+		return ret; \
+	} \
+	if (*ppkey) { \
+		pthread_mutex_unlock(&create_tls_mutex); \
+		return 0; \
+	} \
+	pkey = (pthread_key_t *)malloc(sizeof(pthread_key_t)); \
+	if (!pkey) { \
+		pthread_mutex_unlock(&create_tls_mutex); \
+		return ENOMEM; \
+	} \
+	ret = pthread_key_create(pkey, NULL); \
+	if (ret) { \
+		free(pkey); \
+		pthread_mutex_unlock(&create_tls_mutex); \
+		return ret; \
+	} \
+	*ppkey = (void *)pkey; \
+	pthread_mutex_unlock(&create_tls_mutex); \
+	return 0; \
 } \
  \
-static void smb_destroy_tls_pthread(void *pkey, const char *location) \
+static void smb_destroy_tls_once_pthread(void **ppkey, const char *location) \
 { \
-        pthread_key_delete(*(pthread_key_t *)pkey); \
-        free(pkey); \
+	pthread_mutex_lock(&create_tls_mutex); \
+	if (*ppkey) { \
+		pthread_key_delete(*(pthread_key_t *)ppkey); \
+		free(*ppkey); \
+		*ppkey = NULL; \
+	} \
+	pthread_mutex_unlock(&create_tls_mutex); \
 } \
  \
 static int smb_set_tls_pthread(void *pkey, const void *pval, const char *location) \
@@ -112,8 +132,8 @@ static const struct smb_thread_functions (tf) = { \
                         smb_create_mutex_pthread, \
                         smb_destroy_mutex_pthread, \
                         smb_lock_pthread, \
-                        smb_create_tls_pthread, \
-                        smb_destroy_tls_pthread, \
+                        smb_create_tls_once_pthread, \
+                        smb_destroy_tls_once_pthread, \
                         smb_set_tls_pthread, \
                         smb_get_tls_pthread }
 
diff --git a/lib/util/smb_threads_internal.h b/lib/util/smb_threads_internal.h
index ad05aae9a5e..58c6fe3f99a 100644
--- a/lib/util/smb_threads_internal.h
+++ b/lib/util/smb_threads_internal.h
@@ -33,13 +33,13 @@
 #define SMB_THREAD_LOCK(plock, type) \
 	(global_tfp ? global_tfp->lock_mutex((plock), (type), __location__) : 0)
 
-#define SMB_THREAD_CREATE_TLS(keyname, key) \
-	(global_tfp ? global_tfp->create_tls((keyname), &(key), __location__) : 0)
+#define SMB_THREAD_CREATE_TLS_ONCE(keyname, key) \
+	(global_tfp ? global_tfp->create_tls_once((keyname), &(key), __location__) : 0)
 
-#define SMB_THREAD_DESTROY_TLS(key) \
+#define SMB_THREAD_DESTROY_TLS_ONCE(key) \
 	do { \
 		if (global_tfp) { \
-			global_tfp->destroy_tls(key); \
+			global_tfp->destroy_tls_once(&(key), __location__); \
 		}; \
 	} while (0)
 
@@ -50,4 +50,12 @@
 #define SMB_THREAD_GET_TLS(key) \
 	(global_tfp ? global_tfp->get_tls((key), __location__) : (key))
 
+/*
+ * Global thread lock list.
+ */
+
+#define NUM_GLOBAL_LOCKS 1
+
+#define GLOBAL_LOCK(locknum) (global_lock_array ? global_lock_array[(locknum)] : NULL)
+
 #endif
diff --git a/lib/util/talloc_stack.c b/lib/util/talloc_stack.c
index a9b6e033ceb..f572dd6c77c 100644
--- a/lib/util/talloc_stack.c
+++ b/lib/util/talloc_stack.c
@@ -74,7 +74,7 @@ static struct talloc_stackframe *talloc_stackframe_init(void)
 
 	ZERO_STRUCTP(ts);
 
-	if (SMB_THREAD_CREATE_TLS("talloc_stackframe", global_ts)) {
+	if (SMB_THREAD_CREATE_TLS_ONCE("talloc_stackframe", global_ts)) {
 		smb_panic("talloc_stackframe_init create_tls failed");
 	}
 

From 92d321006d1748ac47cf9b52330212f4ae03f502 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Matthias=20Dieter=20Walln=C3=B6fer?= <mwallnoefer@yahoo.de>
Date: Tue, 14 Apr 2009 10:08:42 +1000
Subject: [PATCH 13/13] Enable software rollout through AD

This enables the sofware rollout feature in Samba4

Signed-off-by: Andrew Bartlett <abartlet@samba.org>
---
 source4/setup/provision_group_policy.ldif | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/source4/setup/provision_group_policy.ldif b/source4/setup/provision_group_policy.ldif
index 0f3e1f15f9d..98c09b997e7 100644
--- a/source4/setup/provision_group_policy.ldif
+++ b/source4/setup/provision_group_policy.ldif
@@ -1,3 +1,13 @@
+dn: CN=Default Domain Policy,CN=System,${DOMAINDN}
+objectClass: top
+objectClass: domainPolicy
+isCriticalSystemObject: TRUE
+
+dn: CN=AppCategories,CN=Default Domain Policy,CN=System,${DOMAINDN}
+objectClass: top
+objectClass: classStore
+isCriticalSystemObject: TRUE
+
 dn: CN={${POLICYGUID}},CN=Policies,CN=System,${DOMAINDN}
 objectClass: top
 objectClass: container