--- source/configure.in 22 Feb 2003 12:19:18 -0000 1.409 +++ source/configure.in 24 Feb 2003 06:04:25 -0000 @@ -627,6 +627,15 @@ fi ############################################ +# support for using Kerberos keytab instead of secrets database + +AC_ARG_ENABLE(keytab, +[ --enable-keytab Turn on support for Kerberos keytabs in lieu of secrets DB (default=no)], + [if eval "test x$enable_keytab = xyes"; then + AC_DEFINE(USE_KEYTAB,1,[Use Kerberos keytab]) + fi]) + +############################################ # we need dlopen/dlclose/dlsym/dlerror for PAM, the password database plugins and the plugin loading code AC_SEARCH_LIBS(dlopen, [dl]) # dlopen/dlclose/dlsym/dlerror will be checked again later and defines will be set then --- source/passdb/secrets.c 1 Feb 2003 04:39:15 -0000 1.54 +++ source/passdb/secrets.c 24 Feb 2003 06:04:26 -0000 @@ -221,6 +221,72 @@ return True; } +#ifdef USE_KEYTAB +/************************************************************************ + Read local secret from the keytab +************************************************************************/ + +static BOOL secrets_fetch_keytab_password(uint8 ret_pwd[16], time_t *pass_last_set_time) +{ + char spn[MAXHOSTNAMELEN + 2], *p; + krb5_context context; + krb5_error_code ret; + krb5_principal princ; + krb5_keyblock *key; + + ret = krb5_init_context(&context); + if (ret) { + DEBUG(1, ("secrets_fetch_keytab_password: failed to initialize Kerberos context\n")); + return False; + } + + spn[sizeof(spn) - 1] = '\0'; + if (gethostname(spn, sizeof(spn) - 2) < 0) { + DEBUG(1, ("secrets_fetch_keytab_password: could not determine local hostname\n")); + krb5_free_context(context); + return False; + } + + for (p = spn; *p && *p != '.'; p++) + *p = toupper(*p); + *p++ = '$'; + *p = '\0'; + + ret = krb5_parse_name(context, spn, &princ); + if (ret) { + DEBUG(1, ("secrets_fetch_keytab_password: failed to parse name %s\n", spn)); + krb5_free_context(context); + return False; + } + +#ifdef ENCTYPE_ARCFOUR_HMAC + ret = krb5_kt_read_service_key(context, NULL, princ, 0, ENCTYPE_ARCFOUR_HMAC, &key); +#elif defined(HAVE_ENCTYPE_ARCFOUR_HMAC_MD5) + ret = krb5_kt_read_service_key(context, NULL, princ, 0, ENCTYPE_ARCFOUR_HMAC_MD5, &key); +#else +#error ENCTYPE_ARCFOUR_HMAC or ENCTYPE_ARCFOUR_HMAC_MD5 required for keytab secret storage +#endif + if (ret) { + DEBUG(1, ("secrets_fetch_keytab_password: failed to read secret for %s\n", spn)); + krb5_free_context(context); + return False; + } + if (key->keyvalue.length != 16) { + DEBUG(1, ("secrets_fetch_keytab_password: key is incorrect length\n")); + krb5_free_context(context); + return False; + } + + memcpy(ret_pwd, key->keyvalue.data, key->keyvalue.length); + time(pass_last_set_time); /* XXX */ + + krb5_free_keyblock(context, key); + krb5_free_context(context); + + return True; +} +#endif /* USE_KEYTAB */ + /************************************************************************ Routine to get the trust account password for a domain. The user of this function must have locked the trust password file using @@ -243,6 +309,12 @@ pass_last_set_time = 0; return True; } + +#ifdef USE_KEYTAB + if (is_myworkgroup(domain)) { + return secrets_fetch_keytab_password(ret_pwd, pass_last_set_time); + } +#endif /* USE_KEYTAB */ if (!(pass = secrets_fetch(trust_keystr(domain), &size))) { DEBUG(5, ("secrets_fetch failed!\n")); --- source/libsmb/clikrb5.c 2003-07-02 00:32:55.000000000 +0200 +++ source/libsmb/clikrb5.c 2003-07-02 00:37:22.000000000 +0200 @@ -316,11 +316,13 @@ krb5_enctype enc_types[] = { #ifdef ENCTYPE_ARCFOUR_HMAC ENCTYPE_ARCFOUR_HMAC, +#elif defined(HAVE_ENCTYPE_ARCFOUR_HMAC_MD5) + ENCTYPE_ARCFOUR_HMAC_MD5, #endif ENCTYPE_DES_CBC_MD5, ENCTYPE_DES_CBC_CRC, ENCTYPE_NULL}; - + retval = krb5_init_context(&context); if (retval) { DEBUG(1,("krb5_init_context failed (%s)\n", @@ -367,24 +369,26 @@ BOOL get_krb5_smb_session_key(krb5_context context, krb5_auth_context auth_context, uint8 session_key[16]) { -#ifdef ENCTYPE_ARCFOUR_HMAC krb5_keyblock *skey; -#endif BOOL ret = False; memset(session_key, 0, 16); -#ifdef ENCTYPE_ARCFOUR_HMAC +#if defined(ENCTYPE_ARCFOUR_HMAC) || defined(HAVE_ENCTYPE_ARCFOUR_HMAC_MD5) if (krb5_auth_con_getremotesubkey(context, auth_context, &skey) == 0 && skey != NULL) { if (KRB5_KEY_TYPE(skey) == +# ifdef ENCTYPE_ARCFOUR_HMAC ENCTYPE_ARCFOUR_HMAC +# else + ENCTYPE_ARCFOUR_HMAC_MD5 +# endif /* ENCTYPE_ARCFOUR_HMAC */ && KRB5_KEY_LENGTH(skey) == 16) { memcpy(session_key, KRB5_KEY_DATA(skey), KRB5_KEY_LENGTH(skey)); ret = True; } krb5_free_keyblock(context, skey); } -#endif /* ENCTYPE_ARCFOUR_HMAC */ +#endif /* ENCTYPE_ARCFOUR_HMAC || HAVE_ENCTYPE_ARCFOUR_HMAC_MD5 */ return ret; } @@ -395,5 +399,12 @@ DEBUG(0,("NO KERBEROS SUPPORT\n")); return data_blob(NULL, 0); } +BOOL krb5_get_smb_session_key(krb5_context context, krb5_auth_context ac, uint8 session_key[16]) + { + DEBUG(0,("NO KERBEROS SUPPORT\n")); + memset(session_key, 0, 16); + return False; + } + //#endif #endif --- source/libads/kerberos_verify.c 2003-06-28 23:40:55.000000000 +0200 +++ source/libads/kerberos_verify.c 2003-07-02 00:50:13.000000000 +0200 @@ -38,7 +38,9 @@ krb5_keytab keytab = NULL; krb5_data packet; krb5_ticket *tkt = NULL; - int ret, i; + int ret; +#ifndef USE_KEYTAB + int i; krb5_keyblock * key; krb5_principal host_princ; char *host_princ_s; @@ -46,8 +48,10 @@ char *password_s; krb5_data password; krb5_enctype *enctypes = NULL; +#endif /* USE_KEYTAB */ BOOL auth_ok = False; +#ifndef USE_KEYTAB if (!secrets_init()) { DEBUG(1,("secrets_init failed\n")); return NT_STATUS_LOGON_FAILURE; @@ -61,6 +65,7 @@ password.data = password_s; password.length = strlen(password_s); +#endif /* USE_KEYTAB */ ret = krb5_init_context(&context); if (ret) { @@ -82,7 +87,16 @@ DEBUG(1,("krb5_auth_con_init failed (%s)\n", error_message(ret))); return NT_STATUS_LOGON_FAILURE; } +#ifdef USE_KEYTAB + packet.length = ticket->length; + packet.data = (krb5_pointer)ticket->data; + if (!(ret = krb5_rd_req(context, &auth_context, &packet, + NULL, keytab, NULL, &tkt))) { + auth_ok = True; + } + +#else fstrcpy(myname, global_myname()); strlower(myname); asprintf(&host_princ_s, "HOST/%s@%s", myname, lp_realm()); @@ -121,6 +135,9 @@ } } + SAFE_FREE(key); +#endif /* USE_KEYTAB */ + if (!auth_ok) { DEBUG(3,("krb5_rd_req with auth failed (%s)\n", error_message(ret))); --- source/Makefile.in 2003-07-01 23:35:49.000000000 +0200 +++ source/Makefile.in 2003-07-02 01:20:09.000000000 +0200 @@ -806,7 +806,7 @@ bin/pdbedit@EXEEXT@: $(PDBEDIT_OBJ) @BUILD_POPT@ bin/.dummy @echo Linking $@ - @$(CC) $(FLAGS) -o $@ $(IDMAP_LIBS) $(PDBEDIT_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) @POPTLIBS@ $(PASSDBLIBS) + @$(CC) $(FLAGS) -o $@ $(IDMAP_LIBS) $(PDBEDIT_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) @POPTLIBS@ $(PASSDBLIBS) $(KRB5LIBS) bin/samtest@EXEEXT@: $(SAMTEST_OBJ) @BUILD_POPT@ bin/.dummy @echo Linking $@ @@ -1062,7 +1062,7 @@ bin/wbinfo@EXEEXT@: $(WBINFO_OBJ) @BUILD_POPT@ bin/.dummy @echo Linking $@ - @$(LINK) -o $@ $(WBINFO_OBJ) $(LIBS) @POPTLIBS@ + @$(LINK) -o $@ $(WBINFO_OBJ) $(LIBS) @POPTLIBS@ $(KRB5LIBS) bin/ntlm_auth@EXEEXT@: $(NTLM_AUTH_OBJ) $(PARAM_OBJ) $(LIB_OBJ) \ $(UBIQX_OBJ) @BUILD_POPT@ bin/.dummy