diff options
author | Andrew Bartlett <abartlet@samba.org> | 2006-01-02 22:00:40 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 13:49:37 -0500 |
commit | 8cd5930a4b021cbee10edbefd3629dae028de052 (patch) | |
tree | 1f6aed89d2d5f3cafc61123f25f65f79259dc7ca /source4/auth/gensec/gensec_krb5.c | |
parent | 2d9bd9b3a5b8cd76835e120dcf4442c072f95eda (diff) | |
download | samba-8cd5930a4b021cbee10edbefd3629dae028de052.tar.gz samba-8cd5930a4b021cbee10edbefd3629dae028de052.tar.bz2 samba-8cd5930a4b021cbee10edbefd3629dae028de052.zip |
r12682: This patch finally fixes our kpasswdd implementation to be compatible
with clients compiled against the MIT Kerberos implementation. (Which
checks for address in KRB-PRIV packets, hence my comments on socket
functions earlier today).
It also fixes the 'set password' operation to behave correctly (it was
previously a no-op).
This allows Samba3 to join Samba4. Some winbindd operations even work,
which I think is a good step forward. There is naturally a lot of work
to do, but I wanted at least the very basics of Samba3 domain membership
to be available for the tech preview.
Andrew Bartlett
(This used to be commit 4e80a557f9c68b01ac6d5bb05716fe5b3fd400d4)
Diffstat (limited to 'source4/auth/gensec/gensec_krb5.c')
-rw-r--r-- | source4/auth/gensec/gensec_krb5.c | 78 |
1 files changed, 74 insertions, 4 deletions
diff --git a/source4/auth/gensec/gensec_krb5.c b/source4/auth/gensec/gensec_krb5.c index 161690f665..478ebcfbf0 100644 --- a/source4/auth/gensec/gensec_krb5.c +++ b/source4/auth/gensec/gensec_krb5.c @@ -29,6 +29,8 @@ #include "auth/kerberos/kerberos.h" #include "librpc/gen_ndr/ndr_krb5pac.h" #include "auth/auth.h" +#include "system/network.h" +#include "lib/socket/socket.h" enum GENSEC_KRB5_STATE { GENSEC_KRB5_SERVER_START, @@ -85,7 +87,10 @@ static NTSTATUS gensec_krb5_start(struct gensec_security *gensec_security) krb5_error_code ret; struct gensec_krb5_state *gensec_krb5_state; struct cli_credentials *creds; - + const char *my_addr, *peer_addr; + int my_port, peer_port; + krb5_address my_krb5_addr, peer_krb5_addr; + creds = gensec_get_credentials(gensec_security); if (!creds) { return NT_STATUS_INVALID_PARAMETER; @@ -133,6 +138,70 @@ static NTSTATUS gensec_krb5_start(struct gensec_security *gensec_security) return NT_STATUS_INTERNAL_ERROR; } + my_addr = gensec_get_my_addr(gensec_security, &my_port); + if (my_addr) { + struct sockaddr_in sock_addr; + struct ipv4_addr addr; + + /* TODO: This really should be in a utility function somewhere */ + ZERO_STRUCT(sock_addr); +#ifdef HAVE_SOCK_SIN_LEN + sock_addr.sin_len = sizeof(sock_addr); +#endif + addr = interpret_addr2(my_addr); + sock_addr.sin_addr.s_addr = addr.addr; + sock_addr.sin_port = htons(my_port); + sock_addr.sin_family = PF_INET; + + ret = krb5_sockaddr2address(gensec_krb5_state->smb_krb5_context->krb5_context, + (struct sockaddr *)&sock_addr, &my_krb5_addr); + if (ret) { + DEBUG(1,("gensec_krb5_start: krb5_sockaddr2address (local) failed (%s)\n", + smb_get_krb5_error_message(gensec_krb5_state->smb_krb5_context->krb5_context, + ret, gensec_krb5_state))); + talloc_free(gensec_krb5_state); + return NT_STATUS_INTERNAL_ERROR; + } + } + + peer_addr = gensec_get_my_addr(gensec_security, &peer_port); + if (peer_addr) { + struct sockaddr_in sock_addr; + struct ipv4_addr addr; + + /* TODO: This really should be in a utility function somewhere */ + ZERO_STRUCT(sock_addr); +#ifdef HAVE_SOCK_SIN_LEN + sock_addr.sin_len = sizeof(sock_addr); +#endif + addr = interpret_addr2(peer_addr); + sock_addr.sin_addr.s_addr = addr.addr; + sock_addr.sin_port = htons(peer_port); + sock_addr.sin_family = PF_INET; + + ret = krb5_sockaddr2address(gensec_krb5_state->smb_krb5_context->krb5_context, + (struct sockaddr *)&sock_addr, &peer_krb5_addr); + if (ret) { + DEBUG(1,("gensec_krb5_start: krb5_sockaddr2address (local) failed (%s)\n", + smb_get_krb5_error_message(gensec_krb5_state->smb_krb5_context->krb5_context, + ret, gensec_krb5_state))); + talloc_free(gensec_krb5_state); + return NT_STATUS_INTERNAL_ERROR; + } + } + + ret = krb5_auth_con_setaddrs(gensec_krb5_state->smb_krb5_context->krb5_context, + gensec_krb5_state->auth_context, + my_addr ? &my_krb5_addr : NULL, + peer_addr ? &peer_krb5_addr : NULL); + if (ret) { + DEBUG(1,("gensec_krb5_start: krb5_auth_con_setaddrs failed (%s)\n", + smb_get_krb5_error_message(gensec_krb5_state->smb_krb5_context->krb5_context, + ret, gensec_krb5_state))); + talloc_free(gensec_krb5_state); + return NT_STATUS_INTERNAL_ERROR; + } + return NT_STATUS_OK; } @@ -425,11 +494,12 @@ static NTSTATUS gensec_krb5_update(struct gensec_security *gensec_security, } return nt_status; } + case GENSEC_KRB5_DONE: - return NT_STATUS_OK; + default: + /* Asking too many times... */ + return NT_STATUS_INVALID_PARAMETER; } - - return NT_STATUS_INVALID_PARAMETER; } static NTSTATUS gensec_krb5_session_key(struct gensec_security *gensec_security, |