[SCM] Samba Shared Repository - branch v3-2-test updated - initial-v3-2-test-2188-ge343593

Stefan Metzmacher metze at samba.org
Wed Feb 13 12:31:30 GMT 2008


The branch, v3-2-test has been updated
       via  e3435930a307cff3066fe2047ed8c5c48911f001 (commit)
       via  923cb37837d508d5355038e95ed1ac09c5869a89 (commit)
       via  72af96a320a97ce1a730d6e33d01950123d6a97c (commit)
       via  c5e6dd1ca9611e2830ff773875998c01bf779a64 (commit)
      from  60a4c8411b71f9f17956b51fd882f71273f5b0ca (commit)

http://gitweb.samba.org/?samba.git;a=shortlog;h=v3-2-test


- Log -----------------------------------------------------------------
commit e3435930a307cff3066fe2047ed8c5c48911f001
Author: Stefan Metzmacher <metze at samba.org>
Date:   Mon Feb 4 18:18:36 2008 +0100

    auth_winbind: use wbcAuthenticateUserEx()
    
    smbd doesn't need $(WBCOMMON_OBJ) anymore,
    it works with any libwbclient.so now
    and may talk to an older winbindd.
    
    metze

commit 923cb37837d508d5355038e95ed1ac09c5869a89
Author: Stefan Metzmacher <metze at samba.org>
Date:   Tue Jan 29 16:21:14 2008 +0100

    wbinfo: use wbcAuthenticateUserEx()
    
    metze

commit 72af96a320a97ce1a730d6e33d01950123d6a97c
Author: Stefan Metzmacher <metze at samba.org>
Date:   Thu Jan 24 14:05:59 2008 +0100

    libwbclient: add wbcAuthenticateUserEx() function
    
    This function will be used by auth_winbind.c.
    
    metze

commit c5e6dd1ca9611e2830ff773875998c01bf779a64
Author: Stefan Metzmacher <metze at samba.org>
Date:   Fri Jan 18 08:43:45 2008 +0100

    winbindd: add rids and other_sids arrays in WBFLAG_PAM_INFO3_TEXT mode
    
    metze

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

Summary of changes:
 source/Makefile.in                     |    5 +-
 source/auth/auth_util.c                |  233 +++++++++++++++++++++++++
 source/auth/auth_winbind.c             |  113 +++++--------
 source/nsswitch/libwbclient/wbc_pam.c  |  300 ++++++++++++++++++++++++++++++++
 source/nsswitch/libwbclient/wbclient.c |    2 +
 source/nsswitch/libwbclient/wbclient.h |  159 +++++++++++++++++-
 source/nsswitch/wbinfo.c               |   90 +++++-----
 source/winbindd/winbindd_pam.c         |   44 +++++-
 8 files changed, 825 insertions(+), 121 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source/Makefile.in b/source/Makefile.in
index f91bdf5..e1a6436 100644
--- a/source/Makefile.in
+++ b/source/Makefile.in
@@ -640,9 +640,8 @@ SMBD_OBJ_BASE = $(PARAM_WITHOUT_REG_OBJ) $(SMBD_OBJ_SRV) $(LIBSMB_OBJ) \
 		$(NOTIFY_OBJ) $(GROUPDB_OBJ) $(AUTH_OBJ) \
 		$(LIBMSRPC_OBJ) $(LIBMSRPC_GEN_OBJ) \
 		$(LIBADS_OBJ) $(KRBCLIENT_OBJ) $(LIBADS_SERVER_OBJ) \
-		$(REGISTRY_OBJ) $(POPT_LIB_OBJ) \
-		$(BUILDOPT_OBJ) $(SMBLDAP_OBJ) $(LDB_OBJ) $(LIBNET_OBJ) \
-		$(WBCOMMON_OBJ) @LIBWBCLIENT_STATIC@
+		$(REGISTRY_OBJ) $(POPT_LIB_OBJ) $(BUILDOPT_OBJ) \
+		$(SMBLDAP_OBJ) $(LDB_OBJ) $(LIBNET_OBJ) @LIBWBCLIENT_STATIC@
 
 PRINTING_OBJ = printing/pcap.o printing/print_svid.o printing/print_aix.o \
                printing/print_cups.o printing/print_generic.o \
diff --git a/source/auth/auth_util.c b/source/auth/auth_util.c
index ce47e94..6efd31d 100644
--- a/source/auth/auth_util.c
+++ b/source/auth/auth_util.c
@@ -1654,6 +1654,239 @@ NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx,
 	return NT_STATUS_OK;
 }
 
+/*****************************************************************************
+ Make a server_info struct from the wbcAuthUserInfo returned by a domain logon
+******************************************************************************/
+
+NTSTATUS make_server_info_wbcAuthUserInfo(TALLOC_CTX *mem_ctx,
+					  const char *sent_nt_username,
+					  const char *domain,
+					  const struct wbcAuthUserInfo *info,
+					  auth_serversupplied_info **server_info)
+{
+	char zeros[16];
+
+	NTSTATUS nt_status = NT_STATUS_OK;
+	char *found_username = NULL;
+	const char *nt_domain;
+	const char *nt_username;
+	struct samu *sam_account = NULL;
+	DOM_SID user_sid;
+	DOM_SID group_sid;
+	bool username_was_mapped;
+	uint32_t i;
+
+	uid_t uid = (uid_t)-1;
+	gid_t gid = (gid_t)-1;
+
+	auth_serversupplied_info *result;
+
+	result = make_server_info(NULL);
+	if (result == NULL) {
+		DEBUG(4, ("make_server_info failed!\n"));
+		return NT_STATUS_NO_MEMORY;
+	}
+
+	/*
+	   Here is where we should check the list of
+	   trusted domains, and verify that the SID
+	   matches.
+	*/
+
+	memcpy(&user_sid, &info->sids[0].sid, sizeof(user_sid));
+	memcpy(&group_sid, &info->sids[1].sid, sizeof(group_sid));
+
+	if (info->account_name) {
+		nt_username = talloc_strdup(result, info->account_name);
+	} else {
+		/* If the server didn't give us one, just use the one we sent
+		 * them */
+		nt_username = talloc_strdup(result, sent_nt_username);
+	}
+	if (!nt_username) {
+		TALLOC_FREE(result);
+		return NT_STATUS_NO_MEMORY;
+	}
+
+	if (info->domain_name) {
+		nt_domain = talloc_strdup(result, info->domain_name);
+	} else {
+		/* If the server didn't give us one, just use the one we sent
+		 * them */
+		nt_domain = talloc_strdup(result, domain);
+	}
+	if (!nt_domain) {
+		TALLOC_FREE(result);
+		return NT_STATUS_NO_MEMORY;
+	}
+
+	/* try to fill the SAM account..  If getpwnam() fails, then try the
+	   add user script (2.2.x behavior).
+
+	   We use the _unmapped_ username here in an attempt to provide
+	   consistent username mapping behavior between kerberos and NTLM[SSP]
+	   authentication in domain mode security.  I.E. Username mapping
+	   should be applied to the fully qualified username
+	   (e.g. DOMAIN\user) and not just the login name.  Yes this means we
+	   called map_username() unnecessarily in make_user_info_map() but
+	   that is how the current code is designed.  Making the change here
+	   is the least disruptive place.  -- jerry */
+
+	if ( !(sam_account = samu_new( result )) ) {
+		TALLOC_FREE(result);
+		return NT_STATUS_NO_MEMORY;
+	}
+
+	/* this call will try to create the user if necessary */
+
+	nt_status = fill_sam_account(result, nt_domain, sent_nt_username,
+				     &found_username, &uid, &gid, sam_account,
+				     &username_was_mapped);
+
+	/* if we still don't have a valid unix account check for
+	  'map to guest = bad uid' */
+
+	if (!NT_STATUS_IS_OK(nt_status)) {
+		TALLOC_FREE( result );
+		if ( lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_UID ) {
+			make_server_info_guest(server_info);
+			return NT_STATUS_OK;
+		}
+		return nt_status;
+	}
+
+	if (!pdb_set_nt_username(sam_account, nt_username, PDB_CHANGED)) {
+		TALLOC_FREE(result);
+		return NT_STATUS_NO_MEMORY;
+	}
+
+	if (!pdb_set_username(sam_account, nt_username, PDB_CHANGED)) {
+		TALLOC_FREE(result);
+		return NT_STATUS_NO_MEMORY;
+	}
+
+	if (!pdb_set_domain(sam_account, nt_domain, PDB_CHANGED)) {
+		TALLOC_FREE(result);
+		return NT_STATUS_NO_MEMORY;
+	}
+
+	if (!pdb_set_user_sid(sam_account, &user_sid, PDB_CHANGED)) {
+		TALLOC_FREE(result);
+		return NT_STATUS_UNSUCCESSFUL;
+	}
+
+	if (!pdb_set_group_sid(sam_account, &group_sid, PDB_CHANGED)) {
+		TALLOC_FREE(result);
+		return NT_STATUS_UNSUCCESSFUL;
+	}
+
+	if (!pdb_set_fullname(sam_account, info->full_name, PDB_CHANGED)) {
+		TALLOC_FREE(result);
+		return NT_STATUS_NO_MEMORY;
+	}
+
+	if (!pdb_set_logon_script(sam_account, info->logon_script, PDB_CHANGED)) {
+		TALLOC_FREE(result);
+		return NT_STATUS_NO_MEMORY;
+	}
+
+	if (!pdb_set_profile_path(sam_account, info->profile_path, PDB_CHANGED)) {
+		TALLOC_FREE(result);
+		return NT_STATUS_NO_MEMORY;
+	}
+
+	if (!pdb_set_homedir(sam_account, info->home_directory, PDB_CHANGED)) {
+		TALLOC_FREE(result);
+		return NT_STATUS_NO_MEMORY;
+	}
+
+	if (!pdb_set_dir_drive(sam_account, info->home_drive, PDB_CHANGED)) {
+		TALLOC_FREE(result);
+		return NT_STATUS_NO_MEMORY;
+	}
+
+	if (!pdb_set_acct_ctrl(sam_account, info->acct_flags, PDB_CHANGED)) {
+		TALLOC_FREE(result);
+		return NT_STATUS_NO_MEMORY;
+	}
+
+	if (!pdb_set_pass_last_set_time(
+		    sam_account,
+		    nt_time_to_unix(info->pass_last_set_time),
+		    PDB_CHANGED)) {
+		TALLOC_FREE(result);
+		return NT_STATUS_NO_MEMORY;
+	}
+
+	if (!pdb_set_pass_can_change_time(
+		    sam_account,
+		    nt_time_to_unix(info->pass_can_change_time),
+		    PDB_CHANGED)) {
+		TALLOC_FREE(result);
+		return NT_STATUS_NO_MEMORY;
+	}
+
+	if (!pdb_set_pass_must_change_time(
+		    sam_account,
+		    nt_time_to_unix(info->pass_must_change_time),
+		    PDB_CHANGED)) {
+		TALLOC_FREE(result);
+		return NT_STATUS_NO_MEMORY;
+	}
+
+	/* save this here to _net_sam_logon() doesn't fail (it assumes a
+	   valid struct samu) */
+
+	result->sam_account = sam_account;
+	result->unix_name = talloc_strdup(result, found_username);
+
+	result->login_server = talloc_strdup(result, info->logon_server);
+
+	/* Fill in the unix info we found on the way */
+
+	result->uid = uid;
+	result->gid = gid;
+
+	/* Create a 'combined' list of all SIDs we might want in the SD */
+
+	result->num_sids = info->num_sids - 2;
+	result->sids = talloc_array(result, DOM_SID, result->num_sids);
+	if (result->sids == NULL) {
+		TALLOC_FREE(result);
+		return NT_STATUS_NO_MEMORY;
+	}
+
+	for (i=0; i < result->num_sids; i++) {
+		memcpy(&result->sids[i], &info->sids[i+2].sid, sizeof(result->sids[i]));
+	}
+
+	/* ensure we are never given NULL session keys */
+
+	ZERO_STRUCT(zeros);
+
+	if (memcmp(info->user_session_key, zeros, sizeof(zeros)) == 0) {
+		result->user_session_key = data_blob_null;
+	} else {
+		result->user_session_key = data_blob_talloc(
+			result, info->user_session_key,
+			sizeof(info->user_session_key));
+	}
+
+	if (memcmp(info->lm_session_key, zeros, 8) == 0) {
+		result->lm_session_key = data_blob_null;
+	} else {
+		result->lm_session_key = data_blob_talloc(
+			result, info->lm_session_key,
+			sizeof(info->lm_session_key));
+	}
+
+	result->was_mapped = username_was_mapped;
+
+	*server_info = result;
+
+	return NT_STATUS_OK;
+}
+
 /***************************************************************************
  Free a user_info struct
 ***************************************************************************/
diff --git a/source/auth/auth_winbind.c b/source/auth/auth_winbind.c
index b24aa3a..26a1b7f 100644
--- a/source/auth/auth_winbind.c
+++ b/source/auth/auth_winbind.c
@@ -25,31 +25,6 @@
 #undef DBGC_CLASS
 #define DBGC_CLASS DBGC_AUTH
 
-static NTSTATUS get_info3_from_ndr(TALLOC_CTX *mem_ctx, struct winbindd_response *response, NET_USER_INFO_3 *info3)
-{
-	uint8 *info3_ndr;
-	size_t len = response->length - sizeof(struct winbindd_response);
-	prs_struct ps;
-	if (len > 0) {
-		info3_ndr = (uint8 *)response->extra_data.data;
-		if (!prs_init(&ps, len, mem_ctx, UNMARSHALL)) {
-			return NT_STATUS_NO_MEMORY;
-		}
-		prs_copy_data_in(&ps, (char *)info3_ndr, len);
-		prs_set_offset(&ps,0);
-		if (!net_io_user_info3("", info3, &ps, 1, 3, False)) {
-			DEBUG(2, ("get_info3_from_ndr: could not parse info3 struct!\n"));
-			return NT_STATUS_UNSUCCESSFUL;
-		}
-		prs_mem_free(&ps);
-
-		return NT_STATUS_OK;
-	} else {
-		DEBUG(2, ("get_info3_from_ndr: No info3 struct found!\n"));
-		return NT_STATUS_UNSUCCESSFUL;
-	}
-}
-
 /* Authenticate a user with a challenge/response */
 
 static NTSTATUS check_winbind_security(const struct auth_context *auth_context,
@@ -58,11 +33,11 @@ static NTSTATUS check_winbind_security(const struct auth_context *auth_context,
 				       const auth_usersupplied_info *user_info, 
 				       auth_serversupplied_info **server_info)
 {
-	struct winbindd_request request;
-	struct winbindd_response response;
-        NSS_STATUS result;
 	NTSTATUS nt_status;
-        NET_USER_INFO_3 info3;
+	wbcErr wbc_status;
+	struct wbcAuthUserParams params;
+	struct wbcAuthUserInfo *info = NULL;
+	struct wbcAuthErrorInfo *err = NULL;
 
 	if (!user_info) {
 		return NT_STATUS_INVALID_PARAMETER;
@@ -82,36 +57,34 @@ static NTSTATUS check_winbind_security(const struct auth_context *auth_context,
 
 	/* Send off request */
 
-	ZERO_STRUCT(request);
-	ZERO_STRUCT(response);
+	params.account_name	= user_info->smb_name;
+	params.domain_name	= user_info->domain;
+	params.workstation_name	= user_info->wksta_name;
 
-	request.flags = WBFLAG_PAM_INFO3_NDR;
+	params.flags		= 0;
+	params.parameter_control= user_info->logon_parameters;
 
-	request.data.auth_crap.logon_parameters = user_info->logon_parameters;
+	params.level		= WBC_AUTH_USER_LEVEL_RESPONSE;
 
-	fstrcpy(request.data.auth_crap.user, user_info->smb_name);
-	fstrcpy(request.data.auth_crap.domain, user_info->domain);
-	fstrcpy(request.data.auth_crap.workstation, user_info->wksta_name);
+	memcpy(params.password.response.challenge,
+	       auth_context->challenge.data,
+	       sizeof(params.password.response.challenge));
 
-	memcpy(request.data.auth_crap.chal, auth_context->challenge.data, sizeof(request.data.auth_crap.chal));
-	
-	request.data.auth_crap.lm_resp_len = MIN(user_info->lm_resp.length, 
-						 sizeof(request.data.auth_crap.lm_resp));
-	request.data.auth_crap.nt_resp_len = MIN(user_info->nt_resp.length, 
-						 sizeof(request.data.auth_crap.nt_resp));
-	
-	memcpy(request.data.auth_crap.lm_resp, user_info->lm_resp.data, 
-	       request.data.auth_crap.lm_resp_len);
-	memcpy(request.data.auth_crap.nt_resp, user_info->nt_resp.data, 
-	       request.data.auth_crap.nt_resp_len);
+	params.password.response.nt_length	= user_info->nt_resp.length;
+	params.password.response.nt_data	= user_info->nt_resp.data;
+	params.password.response.lm_length	= user_info->lm_resp.length;
+	params.password.response.lm_data	= user_info->lm_resp.data;
 
 	/* we are contacting the privileged pipe */
 	become_root();
-	result = winbindd_priv_request_response(WINBINDD_PAM_AUTH_CRAP,
-						&request, &response);
+	wbc_status = wbcAuthenticateUserEx(&params, &info, &err);
 	unbecome_root();
 
-	if ( result == NSS_STATUS_UNAVAIL )  {
+	if (wbc_status == WBC_ERR_NO_MEMORY) {
+		return NT_STATUS_NO_MEMORY;
+	}
+
+	if (wbc_status == WBC_ERR_WINBIND_NOT_AVAILABLE) {
 		struct auth_methods *auth_method =
 			(struct auth_methods *)my_private_data;
 
@@ -123,27 +96,29 @@ static NTSTATUS check_winbind_security(const struct auth_context *auth_context,
 			DEBUG(0,("check_winbind_security: ERROR!  my_private_data == NULL!\n"));
 	}
 
-	nt_status = NT_STATUS(response.data.auth.nt_status);
-
-	if (result == NSS_STATUS_SUCCESS && response.extra_data.data) {
-		if (NT_STATUS_IS_OK(nt_status)) {
-			if (NT_STATUS_IS_OK(nt_status = get_info3_from_ndr(mem_ctx, &response, &info3))) { 
-				nt_status = make_server_info_info3(mem_ctx, 
-					user_info->smb_name, user_info->domain, 
-					server_info, &info3); 
-			}
-			
-			if (NT_STATUS_IS_OK(nt_status)) {
-				if (user_info->was_mapped) {
-					(*server_info)->was_mapped = user_info->was_mapped;
-				}
-			}
-		}
-	} else if (NT_STATUS_IS_OK(nt_status)) {
-		nt_status = NT_STATUS_NO_LOGON_SERVERS;
+	if (wbc_status == WBC_ERR_AUTH_ERROR) {
+		nt_status = NT_STATUS(err->nt_status);
+		wbcFreeMemory(err);
+		return nt_status;
+	}
+
+	if (!WBC_ERROR_IS_OK(wbc_status)) {
+		return NT_STATUS_LOGON_FAILURE;
+	}
+
+	nt_status = make_server_info_wbcAuthUserInfo(mem_ctx,
+						     user_info->smb_name,
+						     user_info->domain,
+						     info, server_info);
+	wbcFreeMemory(info);
+	if (!NT_STATUS_IS_OK(nt_status)) {
+		return nt_status;
+	}
+
+	if (user_info->was_mapped) {
+		(*server_info)->was_mapped = user_info->was_mapped;
 	}
 
-	SAFE_FREE(response.extra_data.data);
         return nt_status;
 }
 
diff --git a/source/nsswitch/libwbclient/wbc_pam.c b/source/nsswitch/libwbclient/wbc_pam.c
index 7f7c7b8..e7bcdfe 100644
--- a/source/nsswitch/libwbclient/wbc_pam.c
+++ b/source/nsswitch/libwbclient/wbc_pam.c
@@ -63,3 +63,303 @@ wbcErr wbcAuthenticateUser(const char *username,
 done:
 	return wbc_status;
 }
+
+static wbcErr wbc_create_auth_info(TALLOC_CTX *mem_ctx,
+				   const struct winbindd_response *resp,
+				   struct wbcAuthUserInfo **_i)
+{
+	wbcErr wbc_status = WBC_ERR_SUCCESS;
+	struct wbcAuthUserInfo *i;
+	struct wbcDomainSid domain_sid;
+	char *p;
+	uint32_t sn = 0;
+	uint32_t j;
+
+	i = talloc(mem_ctx, struct wbcAuthUserInfo);
+	BAIL_ON_PTR_ERROR(i, wbc_status);
+
+	i->user_flags	= resp->data.auth.info3.user_flgs;
+
+	i->account_name	= talloc_strdup(i, resp->data.auth.info3.user_name);
+	BAIL_ON_PTR_ERROR(i->account_name, wbc_status);
+	i->user_principal= NULL;
+	i->full_name	= talloc_strdup(i, resp->data.auth.info3.full_name);
+	BAIL_ON_PTR_ERROR(i->full_name, wbc_status);
+	i->domain_name	= talloc_strdup(i, resp->data.auth.info3.logon_dom);
+	BAIL_ON_PTR_ERROR(i->domain_name, wbc_status);
+	i->dns_domain_name= NULL;
+
+	i->acct_flags	= resp->data.auth.info3.acct_flags;
+	memcpy(i->user_session_key,
+	       resp->data.auth.user_session_key,
+	       sizeof(i->user_session_key));
+	memcpy(i->lm_session_key,
+	       resp->data.auth.first_8_lm_hash,
+	       sizeof(i->lm_session_key));
+
+	i->logon_count		= resp->data.auth.info3.logon_count;
+	i->bad_password_count	= resp->data.auth.info3.bad_pw_count;
+
+	i->logon_time		= resp->data.auth.info3.logon_time;
+	i->logoff_time		= resp->data.auth.info3.logoff_time;
+	i->kickoff_time		= resp->data.auth.info3.kickoff_time;
+	i->pass_last_set_time	= resp->data.auth.info3.pass_last_set_time;
+	i->pass_can_change_time	= resp->data.auth.info3.pass_can_change_time;
+	i->pass_must_change_time= resp->data.auth.info3.pass_must_change_time;
+
+	i->logon_server	= talloc_strdup(i, resp->data.auth.info3.logon_srv);
+	BAIL_ON_PTR_ERROR(i->logon_server, wbc_status);
+	i->logon_script	= talloc_strdup(i, resp->data.auth.info3.logon_script);
+	BAIL_ON_PTR_ERROR(i->logon_script, wbc_status);
+	i->profile_path	= talloc_strdup(i, resp->data.auth.info3.profile_path);
+	BAIL_ON_PTR_ERROR(i->profile_path, wbc_status);
+	i->home_directory= talloc_strdup(i, resp->data.auth.info3.home_dir);
+	BAIL_ON_PTR_ERROR(i->home_directory, wbc_status);
+	i->home_drive	= talloc_strdup(i, resp->data.auth.info3.dir_drive);
+	BAIL_ON_PTR_ERROR(i->home_drive, wbc_status);
+
+	i->num_sids	= 2;
+	i->num_sids 	+= resp->data.auth.info3.num_groups;
+	i->num_sids	+= resp->data.auth.info3.num_other_sids;
+
+	i->sids	= talloc_array(i, struct wbcSidWithAttr, i->num_sids);
+	BAIL_ON_PTR_ERROR(i->sids, wbc_status);
+
+	wbc_status = wbcStringToSid(resp->data.auth.info3.dom_sid,
+				    &domain_sid);
+	BAIL_ON_WBC_ERROR(wbc_status);
+
+#define _SID_COMPOSE(s, d, r, a) { \
+	(s).sid = d; \
+	if ((s).sid.num_auths < MAXSUBAUTHS) { \
+		(s).sid.sub_auths[(s).sid.num_auths++] = r; \
+	} else { \
+		wbc_status = WBC_ERR_INVALID_SID; \
+		BAIL_ON_WBC_ERROR(wbc_status); \
+	} \
+	(s).attributes = a; \


-- 
Samba Shared Repository


More information about the samba-cvs mailing list