We're using a custom version of Heimdal, so I may have left out
a few things that prevent it from building on a normal system.
Please let me know if I have and I'll fix the patch. It is also
untested right now, so you may wish to wait until I've had time
to test it before applying it. :-)

There is no auto-detection; you must configure with -DHEIMDAL.
You may also need to comment out the /usr/kerberos check in
configure.in if building on a RedHat system.

regards,

-- Luke

Index: configure.in
===================================================================
RCS file: /cvsroot/samba/source/configure.in,v
retrieving revision 1.355
diff -u -r1.355 configure.in
--- configure.in        5 Oct 2002 00:41:16 -0000       1.355
+++ configure.in        9 Oct 2002 07:51:53 -0000
 
   # now check for krb5.h. Some systems have the libraries without the headers!
   # note that this check is done here to allow for different kerberos
@@ -2008,8 +2008,8 @@
   AC_CHECK_HEADERS(krb5.h)
 
   # now check for gssapi headers.  This is also done here to allow for
-  # different kerberos include paths
-  AC_CHECK_HEADERS(gssapi/gssapi_generic.h gssapi/gssapi.h)
+  # different kerberos include paths (Heimdal included)
+  AC_CHECK_HEADERS(gssapi.h gssapi/gssapi_generic.h gssapi/gssapi.h)
 
   ##################################################################
   # we might need the k5crypto and com_err libraries on some systems
Index: include/includes.h
===================================================================
RCS file: /cvsroot/samba/source/include/includes.h,v
retrieving revision 1.280
diff -u -r1.280 includes.h
--- include/includes.h  18 Sep 2002 19:06:58 -0000      1.280
+++ include/includes.h  9 Oct 2002 07:51:53 -0000
@@ -397,6 +397,9 @@
 #endif
 
 #if HAVE_KRB5_H
+#ifdef HEIMDAL
+#define __MD5_H__
+#endif
 #include <krb5.h>
 #else
 #undef HAVE_KRB5
@@ -410,6 +413,12 @@
 #include <ldap.h>
 #else
 #undef HAVE_LDAP
+#endif
+
+#if HAVE_GSSAPI_H
+#include <gssapi.h>
+#else
+#undef HAVE_KRB5
 #endif
 
 #if HAVE_GSSAPI_GSSAPI_H
Index: libads/kerberos_verify.c
===================================================================
RCS file: /cvsroot/samba/source/libads/kerberos_verify.c,v
retrieving revision 1.3
diff -u -r1.3 kerberos_verify.c
--- libads/kerberos_verify.c    4 Oct 2002 07:41:56 -0000       1.3
+++ libads/kerberos_verify.c    9 Oct 2002 07:51:54 -0000
@@ -24,6 +24,27 @@
 
 #ifdef HAVE_KRB5
 
+#if defined(HEIMDAL) && !defined(XAD)
+/*
+ * This function is not in the Heimdal mainline.
+ */
+krb5_error_code krb5_set_real_time(krb5_context context,
+                                  int32_t seconds, int32_t microseconds)
+{   
+       krb5_error_code ret;
+       int32_t sec, usec;
+
+       ret = krb5_us_timeofday(context, &sec, &usec);
+       if (ret)
+               return ret;
+
+       context->kdc_sec_offset = seconds - sec;
+       context->kdc_usec_offset = microseconds - usec;
+
+       return 0;
+}
+#endif /* HEIMDAL && !XAD */
+
 /*
   verify an incoming ticket and parse out the principal name and 
   authorization_data if available 
@@ -36,10 +57,14 @@
        krb5_keytab keytab = NULL;
        krb5_data packet;
        krb5_ticket *tkt = NULL;
+#ifdef HEIMDAL
+       krb5_salt salt;
+#else
        krb5_data salt;
        krb5_encrypt_block eblock;
+#endif /* HEIMDAL */
        int ret, i;
-       krb5_keyblock * key;
+       krb5_keyblock *key;
        krb5_principal host_princ;
        char *host_princ_s;
        extern pstring global_myname;
@@ -48,6 +73,9 @@
        krb5_data password;
        krb5_enctype *enctypes = NULL;
 
+#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 +89,7 @@
 
        password.data = password_s;
        password.length = strlen(password_s);
+#endif /* XAD */
 
        ret = krb5_init_context(&context);
        if (ret) {
@@ -92,39 +121,68 @@
                return NT_STATUS_LOGON_FAILURE;
        }
 
+#ifdef HEIMDAL
+       ret = krb5_get_pw_salt(context, host_princ, &salt);
+       if (ret) {
+               DEBUG(1,("krb5_get_pw_salt failed (%s)\n", error_message(ret)));
+               return NT_STATUS_LOGON_FAILURE;
+       }
+#else
        ret = krb5_principal2salt(context, host_princ, &salt);
        if (ret) {
                DEBUG(1,("krb5_principal2salt failed (%s)\n", error_message(ret)));
                return NT_STATUS_LOGON_FAILURE;
        }
+#endif /* HEIMDAL */
     
        if (!(key = (krb5_keyblock *)malloc(sizeof(*key)))) {
                return NT_STATUS_NO_MEMORY;
        }
-       
+
+#ifdef HEIMDAL
+       if ((ret = krb5_get_default_in_tkt_etypes(context, &enctypes))) {
+               DEBUG(1,("krb5_get_default_in_tkt_etypes failed (%s)\n", 
+                        error_message(ret)));
+               return NT_STATUS_LOGON_FAILURE;
+       }
+#else
        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;
        }
+#endif /* HEIMDAL */
 
        /* we need to setup a auth context with each possible encoding type in turn */
        for (i=0;enctypes[i];i++) {
+#ifndef XAD
+#ifdef HEIMDAL
+               ret = krb5_string_to_key_salt(context, enctypes[i], password_s, salt, 
+key);
+               if (ret) {
+                       DEBUG(1,("krb5_string_to_key failed (%s)\n", 
+error_message(ret)));
+                       return NT_STATUS_LOGON_FAILURE;
+               }
+               krb5_auth_con_setkey(context, auth_context, key);
+#else
                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 /* HEIMDAL */
+#endif /* XAD */
                packet.length = ticket->length;
                packet.data = (krb5_pointer)ticket->data;
 
                if (!(ret = krb5_rd_req(context, &auth_context, &packet, 
                                       NULL, keytab, NULL, &tkt))) {
+#ifdef HEIMDAL
+                       free(enctypes);
+#else
                        krb5_free_ktypes(context, enctypes);
+#endif /* HEIMDAL */
                        break;
                }
        }
@@ -135,16 +193,25 @@
                return NT_STATUS_LOGON_FAILURE;
        }
 
+#ifdef HEIMDAL
+       if (tkt->ticket.authorization_data && tkt->ticket.authorization_data->len) {
+               *auth_data = 
+data_blob(tkt->ticket.authorization_data->val->ad_data.data,
+                                      
+tkt->ticket.authorization_data->val->ad_data.length);
+       }
+       if ((ret = krb5_unparse_name(context, tkt->client, principal))) {
+               DEBUG(3,("krb5_unparse_name failed (%s)\n", 
+                        error_message(ret)));
+               return NT_STATUS_LOGON_FAILURE;
+       }
+#else
 #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);
        }
-
 #if 0
        if (tkt->enc_part2) {
                file_save("/tmp/authdata.dat", 
@@ -158,6 +225,7 @@
                         error_message(ret)));
                return NT_STATUS_LOGON_FAILURE;
        }
+#endif /* HEIMDAL */
 
        return NT_STATUS_OK;
 }
Index: libads/krb5_setpw.c
===================================================================
RCS file: /cvsroot/samba/source/libads/krb5_setpw.c,v
retrieving revision 1.9
diff -u -r1.9 krb5_setpw.c
--- libads/krb5_setpw.c 28 Sep 2002 14:42:32 -0000      1.9
+++ libads/krb5_setpw.c 9 Oct 2002 07:51:54 -0000
@@ -172,10 +172,10 @@
        
        p = packet->data;
        
-       if (packet->data[0] == 0x7e || packet->data[0] == 0x5e) {
+       if (((char *)packet->data)[0] == 0x7e || ((char *)packet->data)[0] == 0x5e) {
                /* it's an error packet. We should parse it ... */
                DEBUG(1,("Got error packet 0x%x from kpasswd server\n",
-                        packet->data[0]));
+                        ((char *)packet->data)[0]));
                return KRB5KRB_AP_ERR_MODIFIED;
        }
        
@@ -196,7 +196,7 @@
        
        ap_rep.length = RSVAL(p, 0); p += 2;
        
-       if (p + ap_rep.length >= packet->data + packet->length) {
+       if (p + ap_rep.length >= (char *)packet->data + packet->length) {
                DEBUG(1,("ptr beyond end of packet from kpasswd server\n"));
                return KRB5KRB_AP_ERR_MODIFIED;
        }
@@ -219,7 +219,7 @@
        krb5_free_ap_rep_enc_part(context, ap_rep_enc);
        
        cipherresult.data = p;
-       cipherresult.length = (packet->data + packet->length) - p;
+       cipherresult.length = ((char*)packet->data + packet->length) - p;
                
        ret = krb5_rd_priv(context, auth_context, &cipherresult, &clearresult,
                           &replay);
@@ -352,13 +352,21 @@
        getpeername(sock, &remote_addr, &addr_len);
        addr_len = sizeof(local_addr);
        getsockname(sock, &local_addr, &addr_len);
-       
-       remote_kaddr.addrtype = ADDRTYPE_INET;
-       remote_kaddr.length = sizeof(((struct sockaddr_in *)&remote_addr)->sin_addr);
-       remote_kaddr.contents = (char *)&(((struct sockaddr_in 
*)&remote_addr)->sin_addr);
-       local_kaddr.addrtype = ADDRTYPE_INET;
-       local_kaddr.length = sizeof(((struct sockaddr_in *)&local_addr)->sin_addr);
-       local_kaddr.contents = (char *)&(((struct sockaddr_in 
*)&local_addr)->sin_addr);
+
+#ifdef HEIMDAL
+       remote_kaddr.addr_type = KRB5_ADDRESS_INET;
+#else
+       remote_kaddr.addr_type = ADDRTYPE_INET;
+#endif
+       remote_kaddr.address.length = sizeof(((struct sockaddr_in 
+*)&remote_addr)->sin_addr);
+       remote_kaddr.address.data = (char *)&(((struct sockaddr_in 
+*)&remote_addr)->sin_addr);
+#ifdef HEIMDAL
+       local_kaddr.addr_type = KRB5_ADDRESS_INET;
+#else
+       local_kaddr.addr_type = ADDRTYPE_INET;
+#endif
+       local_kaddr.address.length = sizeof(((struct sockaddr_in 
+*)&local_addr)->sin_addr);
+       local_kaddr.address.data = (char *)&(((struct sockaddr_in 
+*)&local_addr)->sin_addr);
 
        ret = krb5_auth_con_setaddrs(context, auth_context, &local_kaddr, NULL);
        if (ret) {
Index: libads/sasl.c
===================================================================
RCS file: /cvsroot/samba/source/libads/sasl.c,v
retrieving revision 1.10
diff -u -r1.10 sasl.c
--- libads/sasl.c       28 Sep 2002 14:42:32 -0000      1.10
+++ libads/sasl.c       9 Oct 2002 07:51:54 -0000
@@ -243,7 +243,11 @@
           servers realm, regardless of our realm */
        asprintf(&sname, "ldap/%s@%s", ads->config.ldap_server_name, 
ads->config.realm);
        krb5_init_context(&ctx);
+#ifdef HEIMDAL
+       krb5_set_default_in_tkt_etypes(ctx, enc_types);
+#else
        krb5_set_default_tgs_ktypes(ctx, enc_types);
+#endif
        krb5_parse_name(ctx, sname, &principal);
        free(sname);
        krb5_free_context(ctx); 
Index: libsmb/clikrb5.c
===================================================================
RCS file: /cvsroot/samba/source/libsmb/clikrb5.c,v
retrieving revision 1.19
diff -u -r1.19 clikrb5.c
--- libsmb/clikrb5.c    18 Sep 2002 01:40:13 -0000      1.19
+++ libsmb/clikrb5.c    9 Oct 2002 07:51:54 -0000
@@ -126,11 +126,19 @@
                goto failed;
        }
 
+#ifdef HEIMDAL
+       if ((retval = krb5_set_default_in_tkt_etypes(context, enc_types))) {
+               DEBUG(1,("krb5_set_default_tgs_ktypes failed (%s)\n",
+                        error_message(retval)));
+               goto failed;
+       }
+#else
        if ((retval = krb5_set_default_tgs_ktypes(context, enc_types))) {
                DEBUG(1,("krb5_set_default_tgs_ktypes failed (%s)\n",
                         error_message(retval)));
                goto failed;
        }
+#endif
 
        if ((retval = krb5_mk_req2(context, 
                                   &auth_context, 
Index: utils/net_lookup.c
===================================================================
RCS file: /cvsroot/samba/source/utils/net_lookup.c,v
retrieving revision 1.6
diff -u -r1.6 net_lookup.c
--- utils/net_lookup.c  5 Aug 2002 02:47:46 -0000       1.6
+++ utils/net_lookup.c  9 Oct 2002 07:51:54 -0000
@@ -175,6 +175,10 @@
        int num_kdcs,i;
        krb5_data realm;
        char **realms;
+#ifdef HEIMDAL
+       krb5_krbhst_handle handle;
+       krb5_krbhst_info *hinfo;
+#endif /* HEIMDAL */
 
        rc = krb5_init_context(&ctx);
        if (rc) {
@@ -200,6 +204,20 @@
                realm.length = strlen(realm.data);
        }
 
+#ifdef HEIMDAL
+       rc = krb5_krbhst_init(ctx, realm.data, KRB5_KRBHST_KDC, &handle);
+       if (rc) {
+               DEBUG(1, ("krb5_krbhst_init failed (%s)\n", error_message(rc)));
+               return -1;
+       }
+       while ((rc = krb5_krbhst_next(ctx, handle, &hinfo) == 0)) {
+               if (hinfo->ai->ai_family == AF_INET) {
+                       struct in_addr in;
+                       memcpy(&in, hinfo->ai->ai_addr, MIN(sizeof(in), 
+hinfo->ai->ai_addrlen));
+                       d_printf("%s:%hd\n", inet_ntoa(in), hinfo->port);
+               }
+       }
+#else
        rc = krb5_locate_kdc(ctx, &realm, &addrs, &num_kdcs, 0);
        if (rc) {
                DEBUG(1, ("krb5_locate_kdc failed (%s)\n", error_message(rc)));
@@ -209,6 +227,7 @@
                if (addrs[i].sin_family == AF_INET) 
                        d_printf("%s:%hd\n", inet_ntoa(addrs[i].sin_addr),
                                 ntohs(addrs[i].sin_port));
+#endif /* HEIMDAL */
        return 0;
 
 #endif 
--
Luke Howard | PADL Software Pty Ltd | www.padl.com

Reply via email to