commit 8a7159aa1b000593ffe89ca8d7477e6373764aaf
Author:     Günther Deschner <gd@samba.org>
AuthorDate: Tue Jul 15 14:16:56 2014 +0200
Commit:     Andreas Schneider <asn@samba.org>
CommitDate: Tue Jul 15 15:25:27 2014 +0200

    PATCHSET14 s3-rpc_client: return info3 in rpccli_netlogon_password_logon().
    
    Guenther
    
    Signed-off-by: Günther Deschner <gd@samba.org>
    Pair-Programmed-With: Andreas Schneider <asn@samba.org>
    Reviewed-by: Andreas Schneider <asn@samba.org>
---
 source3/rpc_client/cli_netlogon.c | 100 +++++++++++++++++++++-----------------
 source3/rpc_client/cli_netlogon.h |   3 +-
 source3/rpcclient/cmd_netlogon.c  |   3 +-
 3 files changed, 60 insertions(+), 46 deletions(-)

diff --git a/source3/rpc_client/cli_netlogon.c b/source3/rpc_client/cli_netlogon.c
index c69a933..9454226 100644
--- a/source3/rpc_client/cli_netlogon.c
+++ b/source3/rpc_client/cli_netlogon.c
@@ -153,6 +153,53 @@ NTSTATUS rpccli_netlogon_setup_creds(struct rpc_pipe_client *cli,
 	return NT_STATUS_OK;
 }
 
+static NTSTATUS map_validation_to_info3(TALLOC_CTX *mem_ctx,
+					uint16_t validation_level,
+					union netr_Validation *validation,
+					struct netr_SamInfo3 **info3_p)
+{
+	struct netr_SamInfo3 *info3;
+	NTSTATUS status;
+
+	if (validation == NULL) {
+		return NT_STATUS_INVALID_PARAMETER;
+	}
+
+	switch (validation_level) {
+	case 3:
+		if (validation->sam3 == NULL) {
+			return NT_STATUS_INVALID_PARAMETER;
+		}
+
+		info3 = talloc_move(mem_ctx, &validation->sam3);
+		break;
+	case 6:
+		if (validation->sam6 == NULL) {
+			return NT_STATUS_INVALID_PARAMETER;
+		}
+
+		info3 = talloc_zero(mem_ctx, struct netr_SamInfo3);
+		if (info3 == NULL) {
+			return NT_STATUS_NO_MEMORY;
+		}
+		status = copy_netr_SamBaseInfo(info3, &validation->sam6->base, &info3->base);
+		if (!NT_STATUS_IS_OK(status)) {
+			TALLOC_FREE(info3);
+			return status;
+		}
+
+		info3->sidcount = validation->sam6->sidcount;
+		info3->sids = talloc_move(info3, &validation->sam6->sids);
+		break;
+	default:
+		return NT_STATUS_BAD_VALIDATION_CLASS;
+	}
+
+	*info3_p = info3;
+
+	return NT_STATUS_OK;
+}
+
 /* Logon domain user */
 
 NTSTATUS rpccli_netlogon_sam_logon(struct rpc_pipe_client *cli,
@@ -163,7 +210,8 @@ NTSTATUS rpccli_netlogon_sam_logon(struct rpc_pipe_client *cli,
 				   const char *password,
 				   const char *workstation,
 				   uint16_t validation_level,
-				   int logon_type)
+				   int logon_type,
+				   struct netr_SamInfo3 **info3)
 {
 	NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
 	NTSTATUS status;
@@ -298,54 +346,18 @@ NTSTATUS rpccli_netlogon_sam_logon(struct rpc_pipe_client *cli,
 		return NT_STATUS_ACCESS_DENIED;
 	}
 
-	return result;
-}
-
-static NTSTATUS map_validation_to_info3(TALLOC_CTX *mem_ctx,
-					uint16_t validation_level,
-					union netr_Validation *validation,
-					struct netr_SamInfo3 **info3_p)
-{
-	struct netr_SamInfo3 *info3;
-	NTSTATUS status;
-
-	if (validation == NULL) {
-		return NT_STATUS_INVALID_PARAMETER;
+	if (!NT_STATUS_IS_OK(result)) {
+		return result;
 	}
 
-	switch (validation_level) {
-	case 3:
-		if (validation->sam3 == NULL) {
-			return NT_STATUS_INVALID_PARAMETER;
-		}
-
-		info3 = talloc_move(mem_ctx, &validation->sam3);
-		break;
-	case 6:
-		if (validation->sam6 == NULL) {
-			return NT_STATUS_INVALID_PARAMETER;
-		}
-
-		info3 = talloc_zero(mem_ctx, struct netr_SamInfo3);
-		if (info3 == NULL) {
-			return NT_STATUS_NO_MEMORY;
-		}
-		status = copy_netr_SamBaseInfo(info3, &validation->sam6->base, &info3->base);
-		if (!NT_STATUS_IS_OK(status)) {
-			TALLOC_FREE(info3);
-			return status;
-		}
+	netlogon_creds_decrypt_samlogon(cli->dc, validation_level, &validation);
 
-		info3->sidcount = validation->sam6->sidcount;
-		info3->sids = talloc_move(info3, &validation->sam6->sids);
-		break;
-	default:
-		return NT_STATUS_BAD_VALIDATION_CLASS;
+	result = map_validation_to_info3(mem_ctx, validation_level, &validation, info3);
+	if (!NT_STATUS_IS_OK(result)) {
+		return result;
 	}
 
-	*info3_p = info3;
-
-	return NT_STATUS_OK;
+	return result;
 }
 
 /**
diff --git a/source3/rpc_client/cli_netlogon.h b/source3/rpc_client/cli_netlogon.h
index ad59d5b..9c6cbc8 100644
--- a/source3/rpc_client/cli_netlogon.h
+++ b/source3/rpc_client/cli_netlogon.h
@@ -41,7 +41,8 @@ NTSTATUS rpccli_netlogon_sam_logon(struct rpc_pipe_client *cli,
 				   const char *password,
 				   const char *workstation,
 				   uint16_t validation_level,
-				   int logon_type);
+				   int logon_type,
+				   struct netr_SamInfo3 **info3);
 NTSTATUS rpccli_netlogon_sam_network_logon(struct rpc_pipe_client *cli,
 					   TALLOC_CTX *mem_ctx,
 					   uint32 logon_parameters,
diff --git a/source3/rpcclient/cmd_netlogon.c b/source3/rpcclient/cmd_netlogon.c
index 63057ac..e285145 100644
--- a/source3/rpcclient/cmd_netlogon.c
+++ b/source3/rpcclient/cmd_netlogon.c
@@ -724,6 +724,7 @@ static NTSTATUS cmd_netlogon_sam_logon(struct rpc_pipe_client *cli,
 	uint16_t validation_level = 3;
 	uint32 logon_param = 0;
 	const char *workstation = NULL;
+	struct netr_SamInfo3 *info3 = NULL;
 
 	/* Check arguments */
 
@@ -750,7 +751,7 @@ static NTSTATUS cmd_netlogon_sam_logon(struct rpc_pipe_client *cli,
 
 	/* Perform the sam logon */
 
-	result = rpccli_netlogon_sam_logon(cli, mem_ctx, logon_param, lp_workgroup(), username, password, workstation, validation_level, logon_type);
+	result = rpccli_netlogon_sam_logon(cli, mem_ctx, logon_param, lp_workgroup(), username, password, workstation, validation_level, logon_type, &info3);
 
 	if (!NT_STATUS_IS_OK(result))
 		goto done;
commit 53c404ade6d660c449a9dddb56aa80dc6d5ea920
Author:     Günther Deschner <gd@samba.org>
AuthorDate: Tue Jul 15 14:25:19 2014 +0200
Commit:     Andreas Schneider <asn@samba.org>
CommitDate: Tue Jul 15 15:25:29 2014 +0200

    PATCHSET14 s3-winbindd: call interactive samlogon via rpccli_netlogon_password_logon.
    
    Guenther
    
    Signed-off-by: Guenther Deschner <gd@samba.org>
    Pair-Programmed-With: Andreas Schneider <asn@samba.org>
    Reviewed-by: Andreas Schneider <asn@samba.org>
---
 source3/winbindd/winbindd_pam.c | 20 +++++++++++++++++++-
 1 file changed, 19 insertions(+), 1 deletion(-)

diff --git a/source3/winbindd/winbindd_pam.c b/source3/winbindd/winbindd_pam.c
index 125e393..2b31d54 100644
--- a/source3/winbindd/winbindd_pam.c
+++ b/source3/winbindd/winbindd_pam.c
@@ -1152,11 +1152,13 @@ static NTSTATUS winbind_samlogon_retry_loop(struct winbindd_domain *domain,
 					    uint32_t logon_parameters,
 					    const char *server,
 					    const char *username,
+					    const char *password,
 					    const char *domainname,
 					    const char *workstation,
 					    const uint8_t chal[8],
 					    DATA_BLOB lm_response,
 					    DATA_BLOB nt_response,
+					    bool interactive,
 					    struct netr_SamInfo3 **info3)
 {
 	int attempts = 0;
@@ -1269,7 +1271,19 @@ static NTSTATUS winbind_samlogon_retry_loop(struct winbindd_domain *domain,
 			domain->can_do_validation6 = false;
 		}
 
-		if (domain->can_do_samlogon_ex && domain->can_do_validation6) {
+		if (interactive && username != NULL && password != NULL) {
+			result = rpccli_netlogon_sam_logon(
+					netlogon_pipe,
+					mem_ctx,
+					logon_parameters,
+					domainname,
+					username,
+					password,
+					workstation,
+					3, /* FIXME */
+					NetlogonInteractiveInformation,
+					info3);
+		} else if (domain->can_do_samlogon_ex && domain->can_do_validation6) {
 			result = rpccli_netlogon_sam_network_logon_ex(
 					netlogon_pipe,
 					mem_ctx,
@@ -1453,11 +1467,13 @@ static NTSTATUS winbindd_dual_pam_auth_samlogon(TALLOC_CTX *mem_ctx,
 					     0,
 					     domain->dcname,
 					     name_user,
+					     pass,
 					     name_domain,
 					     global_myname(),
 					     chal,
 					     lm_resp,
 					     nt_resp,
+					     true,
 					     &my_info3);
 	if (!NT_STATUS_IS_OK(result)) {
 		goto done;
@@ -1874,12 +1890,14 @@ enum winbindd_result winbindd_dual_pam_auth_crap(struct winbindd_domain *domain,
 					     state->request->data.auth_crap.logon_parameters,
 					     domain->dcname,
 					     name_user,
+					     NULL, /* password */
 					     name_domain,
 					     /* Bug #3248 - found by Stefan Burkei. */
 					     workstation, /* We carefully set this above so use it... */
 					     state->request->data.auth_crap.chal,
 					     lm_resp,
 					     nt_resp,
+					     false, /* interactive */
 					     &info3);
 	if (!NT_STATUS_IS_OK(result)) {
 		goto done;
commit f73d1b92b78c4c3f23f411807273e3d09d39c10a
Author:     Günther Deschner <gd@samba.org>
AuthorDate: Mon Jul 7 17:14:37 2014 +0200
Commit:     Andreas Schneider <asn@samba.org>
CommitDate: Tue Jul 15 15:25:30 2014 +0200

    PATCHSET14 s3-winbindd: add wcache_query_user_fullname().
    
    This helper function is used to query the full name of a cached user object (for
    further gecos processing).
    
    Thanks to Matt Rogers <mrogers@redhat.com>.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=10440
    
    Guenther
    
    Pair-Programmed-With: Andreas Schneider <asn@samba.org>
    Signed-off-by: Günther Deschner <gd@samba.org>
    Reviewed-by: Andreas Schneider <asn@samba.org>
---
 source3/winbindd/winbindd_cache.c | 34 ++++++++++++++++++++++++++++++++++
 source3/winbindd/winbindd_proto.h |  4 ++++
 2 files changed, 38 insertions(+)

diff --git a/source3/winbindd/winbindd_cache.c b/source3/winbindd/winbindd_cache.c
index 0a65953..82c8087 100644
--- a/source3/winbindd/winbindd_cache.c
+++ b/source3/winbindd/winbindd_cache.c
@@ -2282,6 +2282,40 @@ NTSTATUS wcache_query_user(struct winbindd_domain *domain,
 	return status;
 }
 
+
+/**
+* @brief Query a fullname from the username cache (for further gecos processing)
+*
+* @param domain		A pointer to the winbindd_domain struct.
+* @param mem_ctx	The talloc context.
+* @param user_sid	The user sid.
+* @param full_name	A pointer to the full_name string.
+*
+* @return NTSTATUS code
+*/
+NTSTATUS wcache_query_user_fullname(struct winbindd_domain *domain,
+				    TALLOC_CTX *mem_ctx,
+				    const struct dom_sid *user_sid,
+				    const char **full_name)
+{
+	NTSTATUS status;
+	struct wbint_userinfo info;
+
+	status = wcache_query_user(domain, mem_ctx, user_sid, &info);
+	if (!NT_STATUS_IS_OK(status)) {
+		return status;
+	}
+
+	if (info.full_name != NULL) {
+		*full_name = talloc_strdup(mem_ctx, info.full_name);
+		if (*full_name == NULL) {
+			return NT_STATUS_NO_MEMORY;
+		}
+	}
+
+	return NT_STATUS_OK;
+}
+
 /* Lookup user information from a rid */
 static NTSTATUS query_user(struct winbindd_domain *domain,
 			   TALLOC_CTX *mem_ctx,
diff --git a/source3/winbindd/winbindd_proto.h b/source3/winbindd/winbindd_proto.h
index 82176b2..585853e 100644
--- a/source3/winbindd/winbindd_proto.h
+++ b/source3/winbindd/winbindd_proto.h
@@ -103,6 +103,10 @@ NTSTATUS wcache_query_user(struct winbindd_domain *domain,
 			   TALLOC_CTX *mem_ctx,
 			   const struct dom_sid *user_sid,
 			   struct wbint_userinfo *info);
+NTSTATUS wcache_query_user_fullname(struct winbindd_domain *domain,
+				    TALLOC_CTX *mem_ctx,
+				    const struct dom_sid *user_sid,
+				    const char **full_name);
 NTSTATUS wcache_lookup_useraliases(struct winbindd_domain *domain,
 				   TALLOC_CTX *mem_ctx,
 				   uint32 num_sids, const struct dom_sid *sids,
commit d4d04c269ade1e96f84b71e60a1c6c322eec5514
Author:     Günther Deschner <gd@samba.org>
AuthorDate: Mon Jul 7 17:16:32 2014 +0200
Commit:     Andreas Schneider <asn@samba.org>
CommitDate: Tue Jul 15 15:25:31 2014 +0200

    PATCHSET14 s3-winbindd: use wcache_query_user_fullname after inspecting samlogon cache.
    
    The reason for this followup query is that very often the samlogon cache only
    contains a info3 netlogon user structure that has been retrieved during a
    netlogon samlogon authentication using "network" logon level. With that logon
    level only a few info3 fields are filled in; the user's fullname is never filled
    in that case. This is problematic when the cache is used to fill in the user's
    gecos field (for NSS queries). When we have retrieved the user's fullname during
    other queries, reuse it from the other caches.
    
    Thanks to Matt Rogers <mrogers@redhat.com>.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=10440
    
    Guenther
    
    Pair-Programmed-With: Andreas Schneider <asn@samba.org>
    Signed-off-by: Guenther Deschner <gd@samba.org>
    Reviewed-by: Andreas Schneider <asn@samba.org>
---
 source3/winbindd/winbindd_ads.c   |  8 ++++++++
 source3/winbindd/winbindd_msrpc.c |  8 ++++++++
 source3/winbindd/winbindd_pam.c   | 41 +++++++++++++++++++++++++++++++++++++++
 3 files changed, 57 insertions(+)

diff --git a/source3/winbindd/winbindd_ads.c b/source3/winbindd/winbindd_ads.c
index 3099ff0..7d960fc 100644
--- a/source3/winbindd/winbindd_ads.c
+++ b/source3/winbindd/winbindd_ads.c
@@ -515,6 +515,14 @@ static NTSTATUS query_user(struct winbindd_domain *domain,
 
 		TALLOC_FREE(user);
 
+		if (info->full_name == NULL) {
+			/* this might fail so we dont check the return code */
+			wcache_query_user_fullname(domain,
+						   mem_ctx,
+						   sid,
+						   &info->full_name);
+		}
+
 		return NT_STATUS_OK;
 	}
 
diff --git a/source3/winbindd/winbindd_msrpc.c b/source3/winbindd/winbindd_msrpc.c
index b426884..eae822c 100644
--- a/source3/winbindd/winbindd_msrpc.c
+++ b/source3/winbindd/winbindd_msrpc.c
@@ -439,6 +439,14 @@ static NTSTATUS msrpc_query_user(struct winbindd_domain *domain,
 		user_info->full_name = talloc_strdup(user_info,
 						     user->base.full_name.string);
 
+		if (user_info->full_name == NULL) {
+			/* this might fail so we dont check the return code */
+			wcache_query_user_fullname(domain,
+						   mem_ctx,
+						   user_sid,
+						   &user_info->full_name);
+		}
+
 		status = NT_STATUS_OK;
 		goto done;
 	}
diff --git a/source3/winbindd/winbindd_pam.c b/source3/winbindd/winbindd_pam.c
index 2b31d54..86b352e 100644
--- a/source3/winbindd/winbindd_pam.c
+++ b/source3/winbindd/winbindd_pam.c
@@ -1739,6 +1739,26 @@ process_result:
 		sid_compose(&user_sid, info3->base.domain_sid,
 			    info3->base.rid);
 
+		if (info3->base.full_name.string == NULL) {
+			struct netr_SamInfo3 *cached_info3;
+
+			cached_info3 = netsamlogon_cache_get(state->mem_ctx,
+							     &user_sid);
+			if (cached_info3 != NULL &&
+			    cached_info3->base.full_name.string != NULL) {
+				info3->base.full_name.string =
+					talloc_strdup(info3,
+						      cached_info3->base.full_name.string);
+			} else {
+
+				/* this might fail so we dont check the return code */
+				wcache_query_user_fullname(domain,
+						info3,
+						&user_sid,
+						&info3->base.full_name.string);
+			}
+		}
+
 		wcache_invalidate_samlogon(find_domain_from_name(name_domain),
 					   &user_sid);
 		netsamlogon_cache_store(name_user, info3);
@@ -1910,6 +1930,27 @@ process_result:
 
 		sid_compose(&user_sid, info3->base.domain_sid,
 			    info3->base.rid);
+
+		if (info3->base.full_name.string == NULL) {
+			struct netr_SamInfo3 *cached_info3;
+
+			cached_info3 = netsamlogon_cache_get(state->mem_ctx,
+							     &user_sid);
+			if (cached_info3 != NULL &&
+			    cached_info3->base.full_name.string != NULL) {
+				info3->base.full_name.string =
+					talloc_strdup(info3,
+						      cached_info3->base.full_name.string);
+			} else {
+
+				/* this might fail so we dont check the return code */
+				wcache_query_user_fullname(domain,
+						info3,
+						&user_sid,
+						&info3->base.full_name.string);
+			}
+		}
+
 		wcache_invalidate_samlogon(find_domain_from_name(name_domain),
 					   &user_sid);
 		netsamlogon_cache_store(name_user, info3);
commit 7a38729ac2b93d0bd8c2450821cfcedff6fa3f53
Author:     Günther Deschner <gd@samba.org>
AuthorDate: Wed Jul 9 13:36:06 2014 +0200
Commit:     Andreas Schneider <asn@samba.org>
CommitDate: Tue Jul 15 15:25:32 2014 +0200

    PATCHSET14 samlogon_cache: use a talloc_stackframe inside netsamlogon_cache_store.
    
    Guenther
    
    Signed-off-by: Günther Deschner <gd@samba.org>
    Reviewed-by: Andreas Schneider <asn@samba.org>
---
 source3/libsmb/samlogon_cache.c | 13 ++++---------
 1 file changed, 4 insertions(+), 9 deletions(-)

diff --git a/source3/libsmb/samlogon_cache.c b/source3/libsmb/samlogon_cache.c
index 590c950..4281965 100644
--- a/source3/libsmb/samlogon_cache.c
+++ b/source3/libsmb/samlogon_cache.c
@@ -132,7 +132,7 @@ bool netsamlogon_cache_store(const char *username, struct netr_SamInfo3 *info3)
 	bool result = false;
 	struct dom_sid	user_sid;
 	time_t t = time(NULL);
-	TALLOC_CTX *mem_ctx;
+	TALLOC_CTX *tmp_ctx = talloc_stackframe();
 	DATA_BLOB blob;
 	enum ndr_err_code ndr_err;
 	struct netsamlogoncache_entry r;
@@ -156,11 +156,6 @@ bool netsamlogon_cache_store(const char *username, struct netr_SamInfo3 *info3)
 
 	/* Prepare data */
 
-	if (!(mem_ctx = TALLOC_P( NULL, int))) {
-		DEBUG(0,("netsamlogon_cache_store: talloc() failed!\n"));
-		return false;
-	}
-
 	/* only Samba fills in the username, not sure why NT doesn't */
 	/* so we fill it in since winbindd_getpwnam() makes use of it */
 
@@ -175,11 +170,11 @@ bool netsamlogon_cache_store(const char *username, struct netr_SamInfo3 *info3)
 		NDR_PRINT_DEBUG(netsamlogoncache_entry, &r);
 	}
 
-	ndr_err = ndr_push_struct_blob(&blob, mem_ctx, &r,
+	ndr_err = ndr_push_struct_blob(&blob, tmp_ctx, &r,
 				       (ndr_push_flags_fn_t)ndr_push_netsamlogoncache_entry);
 	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
 		DEBUG(0,("netsamlogon_cache_store: failed to push entry to cache\n"));
-		TALLOC_FREE(mem_ctx);
+		TALLOC_FREE(tmp_ctx);
 		return false;
 	}
 
@@ -190,7 +185,7 @@ bool netsamlogon_cache_store(const char *username, struct netr_SamInfo3 *info3)
 		result = true;
 	}
 
-	TALLOC_FREE(mem_ctx);
+	TALLOC_FREE(tmp_ctx);
 
 	return result;
 }
commit f89b793bd672a66f5e75ade33467f6621545f0d4
Author:     Andreas Schneider <asn@samba.org>
AuthorDate: Thu Jul 3 16:17:46 2014 +0200
Commit:     Andreas Schneider <asn@samba.org>
CommitDate: Tue Jul 15 15:25:32 2014 +0200

    PATCHSET14 samlogon_cache: avoid overwriting info3->base.full_name.string.
    
    This field servers as a source for the gecos field. We should not overwrite it
    when a info3 struct from a samlogon network level gets saved in which case this
    field is always NULL.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=10440
    
    Signed-off-by: Andreas Schneider <asn@samba.org>
    Reviewed-by: Guenther Deschner <gd@samba.org>
---
 source3/libsmb/samlogon_cache.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/source3/libsmb/samlogon_cache.c b/source3/libsmb/samlogon_cache.c
index 4281965..8a3dbd2 100644
--- a/source3/libsmb/samlogon_cache.c
+++ b/source3/libsmb/samlogon_cache.c
@@ -156,6 +156,20 @@ bool netsamlogon_cache_store(const char *username, struct netr_SamInfo3 *info3)
 
 	/* Prepare data */
 
+	if (info3->base.full_name.string == NULL) {
+		struct netr_SamInfo3 *cached_info3;
+		const char *full_name = NULL;
+
+		cached_info3 = netsamlogon_cache_get(tmp_ctx, &user_sid);
+		if (cached_info3 != NULL) {
+			full_name = cached_info3->base.full_name.string;
+		}
+
+		if (full_name != NULL) {
+			info3->base.full_name.string = talloc_strdup(info3, full_name);
+		}
+	}
+
 	/* only Samba fills in the username, not sure why NT doesn't */
 	/* so we fill it in since winbindd_getpwnam() makes use of it */
 
commit 8fcaeecf174a1c9088c84f271e2859f75e9a5101
Author:     Andreas Schneider <asn@samba.org>
AuthorDate: Thu Jul 3 16:19:42 2014 +0200
Commit:     Andreas Schneider <asn@samba.org>
CommitDate: Tue Jul 15 15:25:33 2014 +0200

    PATCHSET14 s3-winbind: Don't set the gecos field to NULL.
    
    The value is loaded from the cache anyway. So it will be set to NULL if
    it is not available.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=10440
    
    Signed-off-by: Andreas Schneider <asn@samba.org>
    Reviewed-by: Guenther Deschner <gd@samba.org>
---
 source3/winbindd/nss_info_template.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/source3/winbindd/nss_info_template.c b/source3/winbindd/nss_info_template.c
index 5fdfd9b..de93803 100644
--- a/source3/winbindd/nss_info_template.c
+++ b/source3/winbindd/nss_info_template.c
@@ -48,7 +48,6 @@ static NTSTATUS nss_template_get_info( struct nss_domain_entry *e,
 	  username */
 	*homedir = talloc_strdup( ctx, lp_template_homedir() );
 	*shell   = talloc_strdup( ctx, lp_template_shell() );
-	*gecos   = NULL;
 
 	if ( !*homedir || !*shell ) {
 		return NT_STATUS_NO_MEMORY;
commit d32503872aec4fca41056b2d9d9bbb6b15ce9701
Author:     Günther Deschner <gd@samba.org>
AuthorDate: Tue Jul 15 16:21:08 2014 +0200
Commit:     Andreas Schneider <asn@samba.org>
CommitDate: Tue Jul 15 16:24:59 2014 +0200

    PATCHSET14 s3-rpc_client: add rpccli_netlogon_sam_logon_ex().
    
    This function deals with interactive samlogon and does a dcerpc_netr_SamLogonEx
    call (w/o credential chaining).
    
    Guenther
    
    Signed-off-by: Günther Deschner <gd@samba.org>
---
 source3/rpc_client/cli_netlogon.c | 152 ++++++++++++++++++++++++++++++++++++++
 source3/rpc_client/cli_netlogon.h |  10 +++
 2 files changed, 162 insertions(+)

diff --git a/source3/rpc_client/cli_netlogon.c b/source3/rpc_client/cli_netlogon.c
index 9454226..0290944 100644
--- a/source3/rpc_client/cli_netlogon.c
+++ b/source3/rpc_client/cli_netlogon.c
@@ -360,6 +360,158 @@ NTSTATUS rpccli_netlogon_sam_logon(struct rpc_pipe_client *cli,
 	return result;
 }
 
+/* Logon domain user */
+
+NTSTATUS rpccli_netlogon_sam_logon_ex(struct rpc_pipe_client *cli,
+				      TALLOC_CTX *mem_ctx,
+				      uint32 logon_parameters,
+				      const char *domain,
+				      const char *username,
+				      const char *password,
+				      const char *workstation,
+				      uint16_t validation_level,
+				      int logon_type,
+				      struct netr_SamInfo3 **info3)
+{
+	NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+	NTSTATUS status;
+	struct netr_Authenticator ret_creds;
+	union netr_LogonLevel *logon;
+	union netr_Validation validation;
+	uint8_t authoritative;
+	fstring clnt_name_slash;
+	struct dcerpc_binding_handle *b = cli->binding_handle;
+	uint32_t flags = 0;
+
+	ZERO_STRUCT(ret_creds);
+
+	logon = TALLOC_ZERO_P(mem_ctx, union netr_LogonLevel);
+	if (!logon) {
+		return NT_STATUS_NO_MEMORY;
+	}
+
+	if (workstation) {
+		fstr_sprintf( clnt_name_slash, "\\\\%s", workstation );
+	} else {
+		fstr_sprintf( clnt_name_slash, "\\\\%s", global_myname() );
+	}
+
+	/* Initialise input parameters */
+
+	switch (logon_type) {
+	case NetlogonInteractiveInformation: {
+
+		struct netr_PasswordInfo *password_info;
+
+		struct samr_Password lmpassword;
+		struct samr_Password ntpassword;
+
+		password_info = TALLOC_ZERO_P(mem_ctx, struct netr_PasswordInfo);
+		if (!password_info) {
+			return NT_STATUS_NO_MEMORY;
+		}
+
+		nt_lm_owf_gen(password, ntpassword.hash, lmpassword.hash);
+
+		if (cli->dc->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
+			netlogon_creds_arcfour_crypt(cli->dc, lmpassword.hash, 16);
+			netlogon_creds_arcfour_crypt(cli->dc, ntpassword.hash, 16);
+		} else {
+			netlogon_creds_des_encrypt(cli->dc, &lmpassword);
+			netlogon_creds_des_encrypt(cli->dc, &ntpassword);
+		}
+
+		password_info->identity_info.domain_name.string		= domain;
+		password_info->identity_info.parameter_control		= logon_parameters;
+		password_info->identity_info.logon_id_low		= 0xdead;
+		password_info->identity_info.logon_id_high		= 0xbeef;
+		password_info->identity_info.account_name.string	= username;
+		password_info->identity_info.workstation.string		= clnt_name_slash;
+
+		password_info->lmpassword = lmpassword;
+		password_info->ntpassword = ntpassword;
+
+		logon->password = password_info;
+
+		break;
+	}
+	case NetlogonNetworkInformation: {
+		struct netr_NetworkInfo *network_info;
+		uint8 chal[8];
+		unsigned char local_lm_response[24];
+		unsigned char local_nt_response[24];
+		struct netr_ChallengeResponse lm;
+		struct netr_ChallengeResponse nt;
+
+		ZERO_STRUCT(lm);
+		ZERO_STRUCT(nt);
+
+		network_info = TALLOC_ZERO_P(mem_ctx, struct netr_NetworkInfo);
+		if (!network_info) {
+			return NT_STATUS_NO_MEMORY;
+		}
+
+		generate_random_buffer(chal, 8);
+
+		SMBencrypt(password, chal, local_lm_response);
+		SMBNTencrypt(password, chal, local_nt_response);
+
+		lm.length = 24;
+		lm.data = local_lm_response;
+
+		nt.length = 24;
+		nt.data = local_nt_response;
+
+		network_info->identity_info.domain_name.string		= domain;
+		network_info->identity_info.parameter_control		= logon_parameters;
+		network_info->identity_info.logon_id_low		= 0xdead;
+		network_info->identity_info.logon_id_high		= 0xbeef;
+		network_info->identity_info.account_name.string		= username;
+		network_info->identity_info.workstation.string		= clnt_name_slash;
+
+		memcpy(network_info->challenge, chal, 8);
+		network_info->nt = nt;
+		network_info->lm = lm;
+
+		logon->network = network_info;
+
+		break;
+	}
+	default:
+		DEBUG(0, ("switch value %d not supported\n",
+			logon_type));
+		return NT_STATUS_INVALID_INFO_CLASS;
+	}
+
+	status = dcerpc_netr_LogonSamLogonEx(b, mem_ctx,
+					     cli->srv_name_slash,
+					     global_myname(),
+					     logon_type,
+					     logon,
+					     validation_level,
+					     &validation,
+					     &authoritative,
+					     &flags,
+					     &result);
+	if (!NT_STATUS_IS_OK(status)) {
+		return status;
+	}
+
+	if (!NT_STATUS_IS_OK(result)) {
+		return result;
+	}
+
+	netlogon_creds_decrypt_samlogon(cli->dc, validation_level, &validation);
+
+	result = map_validation_to_info3(mem_ctx, validation_level, &validation, info3);
+	if (!NT_STATUS_IS_OK(result)) {
+		return result;
+	}
+
+	return result;
+}
+
+
 /**
  * Logon domain user with an 'network' SAM logon
  *
diff --git a/source3/rpc_client/cli_netlogon.h b/source3/rpc_client/cli_netlogon.h
index 9c6cbc8..3763843 100644
--- a/source3/rpc_client/cli_netlogon.h
+++ b/source3/rpc_client/cli_netlogon.h
@@ -43,6 +43,16 @@ NTSTATUS rpccli_netlogon_sam_logon(struct rpc_pipe_client *cli,
 				   uint16_t validation_level,
 				   int logon_type,
 				   struct netr_SamInfo3 **info3);
+NTSTATUS rpccli_netlogon_sam_logon_ex(struct rpc_pipe_client *cli,
+				      TALLOC_CTX *mem_ctx,
+				      uint32 logon_parameters,
+				      const char *domain,
+				      const char *username,
+				      const char *password,
+				      const char *workstation,
+				      uint16_t validation_level,
+				      int logon_type,
+				      struct netr_SamInfo3 **info3);
 NTSTATUS rpccli_netlogon_sam_network_logon(struct rpc_pipe_client *cli,
 					   TALLOC_CTX *mem_ctx,
 					   uint32 logon_parameters,
commit f39f18e062207427ea436c85a7c721629a38bc0d
Author:     Günther Deschner <gd@samba.org>
AuthorDate: Tue Jul 15 16:22:15 2014 +0200
Commit:     Andreas Schneider <asn@samba.org>
CommitDate: Tue Jul 15 16:25:04 2014 +0200

    PATCHSET14 s3-winbindd: prefer to do a rpccli_netlogon_sam_logon_ex if we can.
    
    Guenther
    
    Signed-off-by: Günther Deschner <gd@samba.org>
---
 source3/winbindd/winbindd_pam.c | 36 +++++++++++++++++++++++++-----------
 1 file changed, 25 insertions(+), 11 deletions(-)

diff --git a/source3/winbindd/winbindd_pam.c b/source3/winbindd/winbindd_pam.c
index 86b352e..e838ac6 100644
--- a/source3/winbindd/winbindd_pam.c
+++ b/source3/winbindd/winbindd_pam.c
@@ -1272,17 +1272,31 @@ static NTSTATUS winbind_samlogon_retry_loop(struct winbindd_domain *domain,
 		}
 
 		if (interactive && username != NULL && password != NULL) {
-			result = rpccli_netlogon_sam_logon(
-					netlogon_pipe,
-					mem_ctx,
-					logon_parameters,
-					domainname,
-					username,
-					password,
-					workstation,
-					3, /* FIXME */
-					NetlogonInteractiveInformation,
-					info3);
+			if (domain->can_do_samlogon_ex && domain->can_do_validation6) {
+				result = rpccli_netlogon_sam_logon_ex(
+						netlogon_pipe,
+						mem_ctx,
+						logon_parameters,
+						domainname,
+						username,
+						password,
+						workstation,
+						6,
+						NetlogonInteractiveInformation,
+						info3);
+			} else {
+				result = rpccli_netlogon_sam_logon(
+						netlogon_pipe,
+						mem_ctx,
+						logon_parameters,
+						domainname,
+						username,
+						password,
+						workstation,
+						domain->can_do_validation6 ? 6 : 3,
+						NetlogonInteractiveInformation,
+						info3);
+			}
 		} else if (domain->can_do_samlogon_ex && domain->can_do_validation6) {
 			result = rpccli_netlogon_sam_network_logon_ex(
 					netlogon_pipe,
From fa58aff691268b021ba4dde1eb580d0387b917e1 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn@samba.org>
Date: Wed, 20 Aug 2014 15:51:21 +0200
Subject: [PATCH] PATCHSET14: Reset netlogon pipe for interactive samlogon_ex.

---
 source3/winbindd/winbindd_pam.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/source3/winbindd/winbindd_pam.c b/source3/winbindd/winbindd_pam.c
index e838ac6..5316232 100644
--- a/source3/winbindd/winbindd_pam.c
+++ b/source3/winbindd/winbindd_pam.c
@@ -1297,6 +1297,18 @@ static NTSTATUS winbind_samlogon_retry_loop(struct winbindd_domain *domain,
 						NetlogonInteractiveInformation,
 						info3);
 			}
+
+			if (NT_STATUS_EQUAL(result, NT_STATUS_WRONG_PASSWORD)) {
+				/*
+				 * HACK: This is a 3.6 hack that we get a new
+				 * session_key to do a successfuly interactive
+				 * logon
+				 */
+				TALLOC_FREE(domain->conn.netlogon_pipe);
+				attempts += 1;
+				retry = true;
+				continue;
+			}
 		} else if (domain->can_do_samlogon_ex && domain->can_do_validation6) {
 			result = rpccli_netlogon_sam_network_logon_ex(
 					netlogon_pipe,
-- 
1.9.3

