[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(¶ms, &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