From 72494e601ee6027873494f7ee7aff03d9170e3eb Mon Sep 17 00:00:00 2001
From: Jeremy Allison <jra@samba.org>
Date: Mon, 16 Jun 2014 22:49:29 -0700
Subject: [PATCH 1/5] PATCHSET21: s3: auth: Add some const to the struct
 netr_SamInfo3 * arguments of copy_netr_SamInfo3() and
 make_server_info_info3()

Both functions only read from the struct netr_SamInfo3 * argument.

Signed-off-by: Jeremy Allison <jra@samba.org>
Reviewed-by: Richard Sharpe <realrichardsharpe@gmail.com>
Reviewed-by: Simo Sorce <idra@samba.org>
(cherry picked from commit c2411767adb5ce48a4619349075f6f8faae41aab)

Conflicts:
	source3/auth/proto.h
---
 source3/auth/auth_util.c   | 2 +-
 source3/auth/proto.h       | 4 ++--
 source3/auth/server_info.c | 2 +-
 3 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/source3/auth/auth_util.c b/source3/auth/auth_util.c
index 1f1fed9..a548b7b 100644
--- a/source3/auth/auth_util.c
+++ b/source3/auth/auth_util.c
@@ -1195,7 +1195,7 @@ NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx,
				const char *sent_nt_username,
				const char *domain,
				struct auth_serversupplied_info **server_info,
-				struct netr_SamInfo3 *info3)
+				const struct netr_SamInfo3 *info3)
 {
	static const char zeros[16] = {0, };

diff --git a/source3/auth/proto.h b/source3/auth/proto.h
index fccabc4..c851722 100644
--- a/source3/auth/proto.h
+++ b/source3/auth/proto.h
@@ -173,7 +173,7 @@ NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx,
				const char *sent_nt_username,
				const char *domain,
				struct auth_serversupplied_info **server_info,
-				struct netr_SamInfo3 *info3);
+				const struct netr_SamInfo3 *info3);
 struct wbcAuthUserInfo;
 NTSTATUS make_server_info_wbcAuthUserInfo(TALLOC_CTX *mem_ctx,
					  const char *sent_nt_username,
@@ -233,7 +233,7 @@ NTSTATUS passwd_to_SamInfo3(TALLOC_CTX *mem_ctx,
			    const struct passwd *pwd,
			    struct netr_SamInfo3 **pinfo3);
 struct netr_SamInfo3 *copy_netr_SamInfo3(TALLOC_CTX *mem_ctx,
-					 struct netr_SamInfo3 *orig);
+					 const struct netr_SamInfo3 *orig);
 struct netr_SamInfo3 *wbcAuthUserInfo_to_netr_SamInfo3(TALLOC_CTX *mem_ctx,
					const struct wbcAuthUserInfo *info);

diff --git a/source3/auth/server_info.c b/source3/auth/server_info.c
index e627892..63b4989 100644
--- a/source3/auth/server_info.c
+++ b/source3/auth/server_info.c
@@ -632,7 +632,7 @@ done:
	} } while(0)

 struct netr_SamInfo3 *copy_netr_SamInfo3(TALLOC_CTX *mem_ctx,
-					 struct netr_SamInfo3 *orig)
+					 const struct netr_SamInfo3 *orig)
 {
	struct netr_SamInfo3 *info3;
	unsigned int i;
--
2.1.0


From 1afd41a9cc31acdff66ab084ba89913c8a239a0f Mon Sep 17 00:00:00 2001
From: Jeremy Allison <jra@samba.org>
Date: Mon, 16 Jun 2014 22:54:45 -0700
Subject: [PATCH 2/5] PATCHSET21: s3: auth: Change make_server_info_info3() to
 take a const struct netr_SamInfo3 pointer instead of a struct PAC_LOGON_INFO.

make_server_info_info3() only reads from the info3 pointer.

Signed-off-by: Jeremy Allison <jra@samba.org>
Reviewed-by: Richard Sharpe <realrichardsharpe@gmail.com>
Reviewed-by: Simo Sorce <idra@samba.org>
(cherry picked from commit 527f7b54388713acaaf7b66c718cc0f7114fc368)

Conflicts:
	source3/auth/auth_generic.c
	source3/auth/proto.h
	source3/auth/user_krb5.c
---
 source3/auth/proto.h     | 2 +-
 source3/auth/user_krb5.c | 8 ++++----
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/source3/auth/proto.h b/source3/auth/proto.h
index c851722..0ab32a7 100644
--- a/source3/auth/proto.h
+++ b/source3/auth/proto.h
@@ -305,7 +305,7 @@ NTSTATUS make_server_info_krb5(TALLOC_CTX *mem_ctx,
				char *ntdomain,
				char *username,
				struct passwd *pw,
-				struct PAC_LOGON_INFO *logon_info,
+				const struct netr_SamInfo3 *info3,
				bool mapped_to_guest,
				struct auth_serversupplied_info **server_info);

diff --git a/source3/auth/user_krb5.c b/source3/auth/user_krb5.c
index 1e5254e..fde2f48 100644
--- a/source3/auth/user_krb5.c
+++ b/source3/auth/user_krb5.c
@@ -184,7 +184,7 @@ NTSTATUS make_server_info_krb5(TALLOC_CTX *mem_ctx,
				char *ntdomain,
				char *username,
				struct passwd *pw,
-				struct PAC_LOGON_INFO *logon_info,
+				const struct netr_SamInfo3 *info3,
				bool mapped_to_guest,
				struct auth_serversupplied_info **server_info)
 {
@@ -198,14 +198,14 @@ NTSTATUS make_server_info_krb5(TALLOC_CTX *mem_ctx,
			return status;
		}

-	} else if (logon_info) {
+	} else if (info3) {
		/* pass the unmapped username here since map_username()
		   will be called again in make_server_info_info3() */

		status = make_server_info_info3(mem_ctx,
						ntuser, ntdomain,
						server_info,
-						&logon_info->info3);
+						info3);
		if (!NT_STATUS_IS_OK(status)) {
			DEBUG(1, ("make_server_info_info3 failed: %s!\n",
				  nt_errstr(status)));
@@ -284,7 +284,7 @@ NTSTATUS make_server_info_krb5(TALLOC_CTX *mem_ctx,
				char *ntdomain,
				char *username,
				struct passwd *pw,
-				struct PAC_LOGON_INFO *logon_info,
+				const struct netr_SamInfo3 *info3,
				bool mapped_to_guest,
				struct auth_serversupplied_info **server_info)
 {
--
2.1.0


From 08bf07ec03537aedbd7beb359cf9274be2882edf Mon Sep 17 00:00:00 2001
From: Jeremy Allison <jra@samba.org>
Date: Mon, 16 Jun 2014 23:11:58 -0700
Subject: [PATCH 3/5] PATCHSET21: s3: auth: Add
 create_info3_from_pac_logon_info() to create a new info3 and merge resource
 group SIDs into it.

Originally written by Richard Sharpe Richard Sharpe <realrichardsharpe@gmail.com>.

Signed-off-by: Jeremy Allison <jra@samba.org>
Reviewed-by: Richard Sharpe <realrichardsharpe@gmail.com>
Reviewed-by: Simo Sorce <idra@samba.org>
(cherry picked from commit db775c68ccbed0252abf092b5cb811e8f5fa9bb6)
---
 source3/auth/proto.h       |  5 ++-
 source3/auth/server_info.c | 78 ++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 82 insertions(+), 1 deletion(-)

diff --git a/source3/auth/proto.h b/source3/auth/proto.h
index 0ab32a7..4335cf8 100644
--- a/source3/auth/proto.h
+++ b/source3/auth/proto.h
@@ -209,6 +209,7 @@ NTSTATUS auth_winbind_init(void);
 struct netr_SamInfo2;
 struct netr_SamInfo3;
 struct netr_SamInfo6;
+struct PAC_LOGON_INFO;

 struct auth_serversupplied_info *make_server_info(TALLOC_CTX *mem_ctx);
 NTSTATUS serverinfo_to_SamInfo2(struct auth_serversupplied_info *server_info,
@@ -223,6 +224,9 @@ NTSTATUS serverinfo_to_SamInfo6(struct auth_serversupplied_info *server_info,
				uint8_t *pipe_session_key,
				size_t pipe_session_key_len,
				struct netr_SamInfo6 *sam6);
+NTSTATUS create_info3_from_pac_logon_info(TALLOC_CTX *mem_ctx,
+                                        const struct PAC_LOGON_INFO *logon_info,
+                                        struct netr_SamInfo3 **pp_info3);
 NTSTATUS samu_to_SamInfo3(TALLOC_CTX *mem_ctx,
			  struct samu *samu,
			  const char *login_server,
@@ -289,7 +293,6 @@ bool user_in_netgroup(TALLOC_CTX *ctx, const char *user, const char *ngname);
 bool user_in_list(TALLOC_CTX *ctx, const char *user,const char **list);

 /* The following definitions come from auth/user_krb5.c  */
-struct PAC_LOGON_INFO;
 NTSTATUS get_user_from_kerberos_info(TALLOC_CTX *mem_ctx,
				     const char *cli_name,
				     const char *princ_name,
diff --git a/source3/auth/server_info.c b/source3/auth/server_info.c
index 63b4989..1fd9317 100644
--- a/source3/auth/server_info.c
+++ b/source3/auth/server_info.c
@@ -21,6 +21,7 @@
 #include "auth.h"
 #include "../lib/crypto/arcfour.h"
 #include "../librpc/gen_ndr/netlogon.h"
+#include "../librpc/gen_ndr/krb5pac.h"
 #include "../libcli/security/security.h"
 #include "rpc_client/util_netlogon.h"
 #include "nsswitch/libwbclient/wbclient.h"
@@ -293,6 +294,83 @@ static NTSTATUS group_sids_to_info3(struct netr_SamInfo3 *info3,
	return NT_STATUS_OK;
 }

+/*
+ * Merge resource SIDs, if any, into the passed in info3 structure.
+ */
+
+static NTSTATUS merge_resource_sids(const struct PAC_LOGON_INFO *logon_info,
+				struct netr_SamInfo3 *info3)
+{
+	uint32_t i = 0;
+
+	if (!(logon_info->info3.base.user_flags & NETLOGON_RESOURCE_GROUPS)) {
+		return NT_STATUS_OK;
+	}
+
+	/*
+	 * If there are any resource groups (SID Compression) add
+	 * them to the extra sids portion of the info3 in the PAC.
+	 *
+	 * This makes the info3 look like it would if we got the info
+	 * from the DC rather than the PAC.
+	 */
+
+	/*
+	 * Construct a SID for each RID in the list and then append it
+	 * to the info3.
+	 */
+	for (i = 0; i < logon_info->res_groups.count; i++) {
+		NTSTATUS status;
+		struct dom_sid new_sid;
+		uint32_t attributes = logon_info->res_groups.rids[i].attributes;
+
+		sid_compose(&new_sid,
+			logon_info->res_group_dom_sid,
+			logon_info->res_groups.rids[i].rid);
+
+		DEBUG(10, ("Adding SID %s to extra SIDS\n",
+			sid_string_dbg(&new_sid)));
+
+		status = append_netr_SidAttr(info3, &info3->sids,
+					&info3->sidcount,
+					&new_sid,
+					attributes);
+		if (!NT_STATUS_IS_OK(status)) {
+			DEBUG(1, ("failed to append SID %s to extra SIDS: %s\n",
+				sid_string_dbg(&new_sid),
+				nt_errstr(status)));
+			return status;
+		}
+	}
+
+	return NT_STATUS_OK;
+}
+
+/*
+ * Create a copy of an info3 struct from the struct PAC_LOGON_INFO,
+ * then merge resource SIDs, if any, into it. If successful return
+ * the created info3 struct.
+ */
+
+NTSTATUS create_info3_from_pac_logon_info(TALLOC_CTX *mem_ctx,
+					const struct PAC_LOGON_INFO *logon_info,
+					struct netr_SamInfo3 **pp_info3)
+{
+	NTSTATUS status;
+	struct netr_SamInfo3 *info3 = copy_netr_SamInfo3(mem_ctx,
+					&logon_info->info3);
+	if (info3 == NULL) {
+		return NT_STATUS_NO_MEMORY;
+	}
+	status = merge_resource_sids(logon_info, info3);
+	if (!NT_STATUS_IS_OK(status)) {
+		TALLOC_FREE(info3);
+		return status;
+	}
+	*pp_info3 = info3;
+	return NT_STATUS_OK;
+}
+
 #define RET_NOMEM(ptr) do { \
	if (!ptr) { \
		TALLOC_FREE(info3); \
--
2.1.0


From 86d58108db53958f05d559b2d2a20185ef2deb55 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn@cryptomilk.org>
Date: Wed, 4 Mar 2015 17:45:39 +0100
Subject: [PATCH 4/5] PATCHSET21: s3-winbind: Merge resource groups from a
 trusted PAC into the sid array.

This is a backport of db775c68ccbed0252abf092b5cb811e8f5fa9bb6.
---
 source3/winbindd/winbindd_pam.c | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/source3/winbindd/winbindd_pam.c b/source3/winbindd/winbindd_pam.c
index 5316232..b1838a6 100644
--- a/source3/winbindd/winbindd_pam.c
+++ b/source3/winbindd/winbindd_pam.c
@@ -546,6 +546,7 @@ static NTSTATUS winbindd_raw_kerberos_login(TALLOC_CTX *mem_ctx,
	time_t time_offset = 0;
	const char *user_ccache_file;
	struct PAC_LOGON_INFO *logon_info = NULL;
+	struct netr_SamInfo3 *info3_copy = NULL;

	*info3 = NULL;

@@ -624,7 +625,14 @@ static NTSTATUS winbindd_raw_kerberos_login(TALLOC_CTX *mem_ctx,
		goto failed;
	}

-	*info3 = &logon_info->info3;
+	result = create_info3_from_pac_logon_info(mem_ctx,
+						  logon_info,
+						  &info3_copy);
+	if (!NT_STATUS_IS_OK(result)) {
+		return result;
+	}
+
+	*info3 = info3_copy;

	DEBUG(10,("winbindd_raw_kerberos_login: winbindd validated ticket of %s\n",
		principal_s));
--
2.1.0


From 40731d512ba1ee0502bdbdd831c4154f967d9f3e Mon Sep 17 00:00:00 2001
From: Michael Adam <obnox@samba.org>
Date: Mon, 9 Mar 2015 15:15:37 +0100
Subject: [PATCH 5/5] PATCHSET21: s3-winbind: Fix chached user group lookup of
 trusted domains.

If a user group lookup has aleady been done before with a machine
account we did always return the incomplete information from the cache.
This patch makes sure we return the correct group information from the
netsamlogon cache.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=11143

Pair-Programmed-With: Andreas Schneider <asn@samba.org>
Signed-off-by: Michael Adam <obnox@samba.org>
Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Volker Lendecke <vl@samba.org>

(cherry picked from commit f5d0204bfa1eb641fe7697613c1f773b6a7e65de)
---
 source3/winbindd/wb_lookupusergroups.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/source3/winbindd/wb_lookupusergroups.c b/source3/winbindd/wb_lookupusergroups.c
index aeffc17..1bb7081 100644
--- a/source3/winbindd/wb_lookupusergroups.c
+++ b/source3/winbindd/wb_lookupusergroups.c
@@ -37,6 +37,7 @@ struct tevent_req *wb_lookupusergroups_send(TALLOC_CTX *mem_ctx,
 {
	struct tevent_req *req, *subreq;
	struct wb_lookupusergroups_state *state;
+	NTSTATUS status;

	req = tevent_req_create(mem_ctx, &state,
				struct wb_lookupusergroups_state);
@@ -45,6 +46,16 @@ struct tevent_req *wb_lookupusergroups_send(TALLOC_CTX *mem_ctx,
	}
	sid_copy(&state->sid, sid);

+	status = lookup_usergroups_cached(NULL,
+					  state,
+					  &state->sid,
+					  &state->sids.num_sids,
+					  &state->sids.sids);
+	if (NT_STATUS_IS_OK(status)) {
+		tevent_req_done(req);
+		return tevent_req_post(req, ev);
+	}
+
	subreq = dcerpc_wbint_LookupUserGroups_send(
		state, ev, dom_child_handle(domain), &state->sid, &state->sids);
	if (tevent_req_nomem(subreq, req)) {
--
2.1.0
