gensec_krb5_start() fails silently with tlocal_addr / tremote_addr is IPv6

Stefan Metzmacher metze at samba.org
Fri Jul 2 07:51:27 UTC 2021


Hi Lorenz,

> The function gensec_krb5_start() returns NT_STATUS_INTERNAL_ERROR when
> tlocal_addr / tremote_addr are IPv6. No debug messages are generated in
> this case and nothing obvious shows up in strace. Only thing i see in
> logs even with log level 10 are the following lines:
> 
> 
>     Starting GENSEC mechanism krb5
>     Failed to start GENSEC server mech krb5: NT_STATUS_INTERNAL_ERROR
> 
> 
> As a result things like kpasswd do not work.

I guess our 'kpasswd' server is broken currently and doesn't answer
to password change requests, is that the problem your having?

It would be great if you could file a bug at https://bugzilla.samba.org/
with these details.

> Loking through the samba source there are not so many code paths through
> gensec_krb5_start() without any DEBUG statements. Thus I believe what
> happens is the following (from gensec_krb.c, see [1]).
> 
> 		sockaddr_ret = tsocket_address_bsd_sockaddr(
> 			tlocal_addr, &addr.u.sa, sizeof(addr.u.sa));
> 		if (sockaddr_ret < 0) {
> 			talloc_free(gensec_krb5_state);
> 			return NT_STATUS_INTERNAL_ERROR;
> 		}
> 
> When tlocal_addr is IPv6, then sockaddr_ret will return an error.
> Looking at other examples of tsocket_address_bsd_sockaddr it seems that
> most of them use sizeof(struct sockaddr_storage) for the last param
> except the one call shown above.
> 
> I suspect that this might be the problem. Consider the following test
> program:
> 
> $ cat <<EOF > /tmp/test.c
> #include <netinet/in.h>
> #include <stdio.h>
> #include <sys/socket.h>
> #include <sys/un.h>
> #include <unistd.h>
> 
> #define sockaddr_storage sockaddr_in6
> struct samba_sockaddr {
> 	socklen_t sa_socklen;
> 	union {
> 		struct sockaddr sa;
> 		struct sockaddr_in in;
> 		struct sockaddr_in6 in6;
> 		struct sockaddr_un un;
> 		struct sockaddr_storage ss;
> 	} u;
> };
> 
> int main(void) {
>         struct samba_sockaddr addr;
>         printf("sizeof(addr.u.sa): %ld\n", sizeof(addr.u.sa));
>         printf("sizeof(struct sockaddr_storage): %ld\n",
> 		sizeof(struct sockaddr_storage));
> 	return 0;
> }
> 
> EOF
> 
> On my machine, this produces the following output:
> 
> ./a.out 
> sizeof(addr.u.sa): 16
> sizeof(struct sockaddr_storage): 28

This is actually the sizeof sockaddr_in6, because of the '#define sockaddr_storage sockaddr_in6',
but it doesn't really matter here :-)

Thanks for the report! I think this commit should fix it:
https://gitlab.com/samba-team/devel/samba/-/commit/9c3aef25b1d92ea94d7400d8e4fab176cdb83187

Can you please test it?

Thanks!
metze

-------------- next part --------------
A non-text attachment was scrubbed...
Name: OpenPGP_signature
Type: application/pgp-signature
Size: 833 bytes
Desc: OpenPGP digital signature
URL: <http://lists.samba.org/pipermail/samba-technical/attachments/20210702/36c4ad43/OpenPGP_signature.sig>


More information about the samba-technical mailing list