Sorry, the previously posted patch was needlessly complicated. The attached patch just contains the Kerberos-related stuff.
-- Luke
Index: configure.in =================================================================== RCS file: /cvsroot/samba/source/configure.in,v retrieving revision 1.397 diff -u -r1.397 configure.in --- configure.in 1 Feb 2003 11:00:39 -0000 1.397 +++ configure.in 2 Feb 2003 12:12:47 -0000 @@ -2198,6 +2198,8 @@ ######################################################## # now see if we can find the gssapi libs in standard paths + AC_CHECK_LIB(gssapi, gss_display_status, [LIBS="$LIBS -lgssapi"; + AC_DEFINE(HAVE_GSSAPI,1,[Whether GSSAPI is available])]) AC_CHECK_LIB(gssapi_krb5, gss_display_status, [LIBS="$LIBS -lgssapi_krb5"; AC_DEFINE(HAVE_GSSAPI,1,[Whether GSSAPI is available])]) Index: libads/kerberos_verify.c =================================================================== RCS file: /cvsroot/samba/source/libads/kerberos_verify.c,v retrieving revision 1.5 diff -u -r1.5 kerberos_verify.c --- libads/kerberos_verify.c 11 Jan 2003 03:29:31 -0000 1.5 +++ libads/kerberos_verify.c 2 Feb 2003 12:12:48 -0000 @@ -3,7 +3,7 @@ kerberos utility library Copyright (C) Andrew Tridgell 2001 Copyright (C) Remus Koos 2001 - + Copyright (C) Luke Howard 2003 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -29,25 +29,28 @@ authorization_data if available */ NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket, - char **principal, DATA_BLOB *auth_data) + char **principal, DATA_BLOB *auth_data, + uint8 session_key[16]) { krb5_context context; krb5_auth_context auth_context = NULL; krb5_keytab keytab = NULL; krb5_data packet; krb5_ticket *tkt = NULL; - krb5_data salt; - krb5_encrypt_block eblock; int ret, i; +#ifndef XAD krb5_keyblock * key; krb5_principal host_princ; char *host_princ_s; fstring myname; char *password_s; +#endif krb5_data password; - krb5_enctype *enctypes = NULL; - BOOL auth_ok = False; + krb5_keyblock *skey; +#ifdef XAD + /* We would rather use the keytab. */ +#else if (!secrets_init()) { DEBUG(1,("secrets_init failed\n")); return NT_STATUS_LOGON_FAILURE; @@ -61,6 +64,7 @@ password.data = password_s; password.length = strlen(password_s); +#endif /* XAD */ ret = krb5_init_context(&context); if (ret) { @@ -83,6 +87,7 @@ return NT_STATUS_LOGON_FAILURE; } +#ifndef XAD fstrcpy(myname, global_myname()); strlower(myname); asprintf(&host_princ_s, "HOST/%s@%s", myname, lp_realm()); @@ -92,69 +97,58 @@ return NT_STATUS_LOGON_FAILURE; } - ret = krb5_principal2salt(context, host_princ, &salt); - if (ret) { - DEBUG(1,("krb5_principal2salt failed (%s)\n", error_message(ret))); - return NT_STATUS_LOGON_FAILURE; - } - if (!(key = (krb5_keyblock *)malloc(sizeof(*key)))) { return NT_STATUS_NO_MEMORY; } - if ((ret = krb5_get_permitted_enctypes(context, &enctypes))) { - DEBUG(1,("krb5_get_permitted_enctypes failed (%s)\n", - error_message(ret))); - return NT_STATUS_LOGON_FAILURE; + ret = create_kerberos_key_from_string(context, host_princ, &password, key); + if (ret) { + continue; } - /* we need to setup a auth context with each possible encoding type in turn */ - for (i=0;enctypes[i];i++) { - krb5_use_enctype(context, &eblock, enctypes[i]); - - ret = krb5_string_to_key(context, &eblock, key, &password, &salt); - if (ret) { - continue; - } + krb5_auth_con_setuseruserkey(context, auth_context, key); +#endif /* XAD */ - krb5_auth_con_setuseruserkey(context, auth_context, key); + packet.length = ticket->length; + packet.data = (krb5_pointer)ticket->data; - packet.length = ticket->length; - packet.data = (krb5_pointer)ticket->data; - - if (!(ret = krb5_rd_req(context, &auth_context, &packet, - NULL, keytab, NULL, &tkt))) { - krb5_free_ktypes(context, enctypes); - auth_ok = True; - break; - } - } - - if (!auth_ok) { + if ((ret = krb5_rd_req(context, &auth_context, &packet, + NULL, keytab, NULL, &tkt))) { DEBUG(3,("krb5_rd_req with auth failed (%s)\n", error_message(ret))); return NT_STATUS_LOGON_FAILURE; } -#if 0 - file_save("/tmp/ticket.dat", ticket->data, ticket->length); -#endif - - - if (tkt->enc_part2) { - *auth_data = data_blob(tkt->enc_part2->authorization_data[0]->contents, - tkt->enc_part2->authorization_data[0]->length); + memset(session_key, 0, 16); +#ifdef XAD + skey = NULL; + krb5_auth_con_getremotesubkey(context, auth_context, &skey); + if (skey == NULL) { + krb5_auth_con_getlocalsubkey(context, auth_context, &skey); + } + if (skey == NULL) { + krb5_auth_con_getkey(context, auth_context, &skey); + } + if (skey != NULL) { + if (skey->keytype != KEYTYPE_ARCFOUR && skey->keytype != +KEYTYPE_ARCFOUR_56) { + DEBUG(3,("could not extract RC4 session key from Kerberos +authenticator: " + "incorrect key type (%d)\n", skey->keytype)); + } else { + if (skey->keyvalue.length == 16) { + memcpy(session_key, skey->keyvalue.data, +skey->keyvalue.length); + DEBUG(3,("extracted RC4 session key from Kerberos +authenticator\n")); + } else { + DEBUG(3,("could not extract RC4 session key from +Kerberos authenticator: " + "incorrect length (%d bytes)\n", +skey->keyvalue.length)); + } + } + krb5_free_keyblock(context, skey); } +#endif /* XAD */ -#if 0 - if (tkt->enc_part2) { - file_save("/tmp/authdata.dat", - tkt->enc_part2->authorization_data[0]->contents, - tkt->enc_part2->authorization_data[0]->length); - } -#endif + get_auth_data_from_tkt(auth_data, tkt); - if ((ret = krb5_unparse_name(context, tkt->enc_part2->client, principal))) { + if ((ret = krb5_unparse_name(context, get_principal_from_tkt(tkt), +principal))) { DEBUG(3,("krb5_unparse_name failed (%s)\n", error_message(ret))); return NT_STATUS_LOGON_FAILURE; @@ -163,4 +157,5 @@ return NT_STATUS_OK; } -#endif +#endif /* HAVE_KRB5 */ + Index: smbd/sesssetup.c =================================================================== RCS file: /cvsroot/samba/source/smbd/sesssetup.c,v retrieving revision 1.85 diff -u -r1.85 sesssetup.c --- smbd/sesssetup.c 28 Jan 2003 11:51:55 -0000 1.85 +++ smbd/sesssetup.c 2 Feb 2003 12:12:50 -0000 @@ -148,6 +148,7 @@ DATA_BLOB auth_data; auth_serversupplied_info *server_info = NULL; ADS_STRUCT *ads; + uint8 session_key[16]; if (!spnego_parse_krb5_wrap(*secblob, &ticket)) { return ERROR_NT(NT_STATUS_LOGON_FAILURE); @@ -161,7 +162,7 @@ ads->auth.realm = strdup(lp_realm()); - ret = ads_verify_ticket(ads, &ticket, &client, &auth_data); + ret = ads_verify_ticket(ads, &ticket, &client, &auth_data, session_key); if (!NT_STATUS_IS_OK(ret)) { DEBUG(1,("Failed to verify incoming ticket!\n")); ads_destroy(&ads); @@ -218,7 +219,10 @@ DEBUG(1,("make_server_info_from_pw failed!\n")); return ERROR_NT(ret); } - + + /* Copy out the session key from the AP_REQ. */ + memcpy(server_info->session_key, session_key, sizeof(session_key)); + sess_vuid = register_vuid(server_info, user); free(user);
-- Luke Howard | PADL Software Pty Ltd | www.padl.com