diff options
Diffstat (limited to 'source/libads')
-rw-r--r-- | source/libads/ads_struct.c | 19 | ||||
-rw-r--r-- | source/libads/authdata.c | 617 | ||||
-rw-r--r-- | source/libads/config.m4 | 442 | ||||
-rw-r--r-- | source/libads/kerberos.c | 39 | ||||
-rw-r--r-- | source/libads/kerberos_verify.c | 156 | ||||
-rw-r--r-- | source/libads/krb5_setpw.c | 2 | ||||
-rw-r--r-- | source/libads/ldap.c | 23 | ||||
-rw-r--r-- | source/libads/util.c | 61 |
8 files changed, 647 insertions, 712 deletions
diff --git a/source/libads/ads_struct.c b/source/libads/ads_struct.c index 92f37093f46..9774968e121 100644 --- a/source/libads/ads_struct.c +++ b/source/libads/ads_struct.c @@ -102,21 +102,21 @@ ADS_STRUCT *ads_init(const char *realm, ads->server.foreign = 1; } - /* the caller will own the memory by default */ - ads->is_mine = 1; - return ads; } +/* a simpler ads_init() interface using all defaults */ +ADS_STRUCT *ads_init_simple(void) +{ + return ads_init(NULL, NULL, NULL); +} + /* free the memory used by the ADS structure initialized with 'ads_init(...)' */ void ads_destroy(ADS_STRUCT **ads) { if (ads && *ads) { - BOOL is_mine; - - is_mine = (*ads)->is_mine; #if HAVE_LDAP if ((*ads)->ld) ldap_unbind((*ads)->ld); #endif @@ -133,11 +133,8 @@ void ads_destroy(ADS_STRUCT **ads) SAFE_FREE((*ads)->config.realm); SAFE_FREE((*ads)->config.bind_path); SAFE_FREE((*ads)->config.ldap_server_name); - - - ZERO_STRUCTP(*ads); - if ( is_mine ) - SAFE_FREE(*ads); + ZERO_STRUCTP(*ads); + SAFE_FREE(*ads); } } diff --git a/source/libads/authdata.c b/source/libads/authdata.c deleted file mode 100644 index 29170af377e..00000000000 --- a/source/libads/authdata.c +++ /dev/null @@ -1,617 +0,0 @@ -/* - Unix SMB/CIFS implementation. - kerberos authorization data (PAC) utility library - Copyright (C) Jim McDonough <jmcd@us.ibm.com> 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 - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#include "includes.h" - -#ifdef HAVE_KRB5 - -static DATA_BLOB unwrap_pac(DATA_BLOB *auth_data) -{ - DATA_BLOB pac_contents; - ASN1_DATA data; - int data_type; - - asn1_load(&data, *auth_data); - asn1_start_tag(&data, ASN1_SEQUENCE(0)); - asn1_start_tag(&data, ASN1_SEQUENCE(0)); - asn1_start_tag(&data, ASN1_CONTEXT(0)); - asn1_read_Integer(&data, &data_type); - asn1_end_tag(&data); - asn1_start_tag(&data, ASN1_CONTEXT(1)); - asn1_read_OctetString(&data, &pac_contents); - asn1_end_tag(&data); - asn1_end_tag(&data); - asn1_end_tag(&data); - asn1_free(&data); - return pac_contents; -} - -static BOOL pac_io_unknown_type_10(const char *desc, UNKNOWN_TYPE_10 *type_10, - prs_struct *ps, int depth) -{ - if (NULL == type_10) - return False; - - prs_debug(ps, depth, desc, "pac_io_unknown_type_10"); - depth++; - - if (!smb_io_time("unknown_time", &type_10->unknown_time, ps, depth)) - return False; - - if (!prs_uint16("len", ps, depth, &type_10->len)) - return False; - - if (UNMARSHALLING(ps) && type_10->len) { - type_10->username = (uint16 *) prs_alloc_mem(ps, type_10->len); - if (!type_10->username) { - DEBUG(3, ("No memory available\n")); - return False; - } - } - - if (!prs_uint16s(True, "name", ps, depth, type_10->username, - (type_10->len / sizeof(uint16)))) - return False; - - return True; - -} - - -static BOOL pac_io_krb_sids(const char *desc, KRB_SID_AND_ATTRS *sid_and_attr, - prs_struct *ps, int depth) -{ - if (NULL == sid_and_attr) - return False; - - prs_debug(ps, depth, desc, "pac_io_krb_sids"); - depth++; - - if (UNMARSHALLING(ps)) { - sid_and_attr->sid = - (DOM_SID2 * ) prs_alloc_mem(ps, sizeof(DOM_SID2)); - if (!sid_and_attr->sid) { - DEBUG(3, ("No memory available\n")); - return False; - } - } - - if(!smb_io_dom_sid2("sid", sid_and_attr->sid, ps, depth)) - return False; - - return True; -} - - -static BOOL pac_io_krb_attrs(const char *desc, KRB_SID_AND_ATTRS *sid_and_attr, - prs_struct *ps, int depth) -{ - if (NULL == sid_and_attr) - return False; - - prs_debug(ps, depth, desc, "pac_io_krb_attrs"); - depth++; - - if (!prs_uint32("sid_ptr", ps, depth, &sid_and_attr->sid_ptr)) - return False; - if (!prs_uint32("attrs", ps, depth, &sid_and_attr->attrs)) - return False; - - return True; -} - -static BOOL pac_io_krb_sid_and_attr_array(const char *desc, - KRB_SID_AND_ATTR_ARRAY *array, - uint32 num, - prs_struct *ps, int depth) -{ - int i; - - if (NULL == array) - return False; - - prs_debug(ps, depth, desc, "pac_io_krb_sid_and_attr_array"); - depth++; - - - if (!prs_uint32("count", ps, depth, &array->count)) - return False; - - if (UNMARSHALLING(ps)) { - array->krb_sid_and_attrs = (KRB_SID_AND_ATTRS *) - prs_alloc_mem(ps, sizeof(KRB_SID_AND_ATTRS) * num); - if (!array->krb_sid_and_attrs) { - DEBUG(3, ("No memory available\n")); - return False; - } - } - - for (i=0; i<num; i++) { - if (!pac_io_krb_attrs(desc, - &array->krb_sid_and_attrs[i], - ps, depth)) - return False; - - } - for (i=0; i<num; i++) { - if (!pac_io_krb_sids(desc, - &array->krb_sid_and_attrs[i], - ps, depth)) - return False; - - } - - return True; - -} - -static BOOL pac_io_group_membership(const char *desc, - GROUP_MEMBERSHIP *membership, - prs_struct *ps, int depth) -{ - if (NULL == membership) - return False; - - prs_debug(ps, depth, desc, "pac_io_group_membership"); - depth++; - - if (!prs_uint32("rid", ps, depth, &membership->rid)) - return False; - if (!prs_uint32("attrs", ps, depth, &membership->attrs)) - return False; - - return True; -} - - -static BOOL pac_io_group_membership_array(const char *desc, - GROUP_MEMBERSHIP_ARRAY *array, - uint32 num, - prs_struct *ps, int depth) -{ - int i; - - if (NULL == array) - return False; - - prs_debug(ps, depth, desc, "pac_io_group_membership_array"); - depth++; - - - if (!prs_uint32("count", ps, depth, &array->count)) - return False; - - if (UNMARSHALLING(ps)) { - array->group_membership = (GROUP_MEMBERSHIP *) - prs_alloc_mem(ps, sizeof(GROUP_MEMBERSHIP) * num); - if (!array->group_membership) { - DEBUG(3, ("No memory available\n")); - return False; - } - } - - for (i=0; i<num; i++) { - if (!pac_io_group_membership(desc, - &array->group_membership[i], - ps, depth)) - return False; - - } - - return True; - -} - -static BOOL pac_io_pac_logon_info(const char *desc, PAC_LOGON_INFO *info, - prs_struct *ps, int depth) -{ - uint32 garbage; - if (NULL == info) - return False; - - prs_debug(ps, depth, desc, "pac_io_pac_logon_info"); - depth++; - - if (!prs_uint32("unknown", ps, depth, &garbage)) - return False; - if (!prs_uint32("unknown", ps, depth, &garbage)) - return False; - if (!prs_uint32("bufferlen", ps, depth, &garbage)) - return False; - if (!prs_uint32("bufferlenhi", ps, depth, &garbage)) - return False; - if (!prs_uint32("pointer", ps, depth, &garbage)) - return False; - - if (!smb_io_time("logon_time", &info->logon_time, ps, depth)) - return False; - if (!smb_io_time("logoff_time", &info->logoff_time, ps, depth)) - return False; - if (!smb_io_time("kickoff_time", &info->kickoff_time, ps, depth)) - return False; - if (!smb_io_time("pass_last_set_time", &info->pass_last_set_time, - ps, depth)) - return False; - if (!smb_io_time("pass_can_change_time", &info->pass_can_change_time, - ps, depth)) - return False; - if (!smb_io_time("pass_must_change_time", &info->pass_must_change_time, - ps, depth)) - return False; - - if (!smb_io_unihdr("hdr_user_name", &info->hdr_user_name, ps, depth)) - return False; - if (!smb_io_unihdr("hdr_full_name", &info->hdr_full_name, ps, depth)) - return False; - if (!smb_io_unihdr("hdr_logon_script", &info->hdr_logon_script, - ps, depth)) - return False; - if (!smb_io_unihdr("hdr_profile_path", &info->hdr_profile_path, - ps, depth)) - return False; - if (!smb_io_unihdr("hdr_home_dir", &info->hdr_home_dir, ps, depth)) - return False; - if (!smb_io_unihdr("hdr_dir_drive", &info->hdr_dir_drive, ps, depth)) - return False; - - if (!prs_uint16("logon_count", ps, depth, &info->logon_count)) - return False; - if (!prs_uint16("reserved12", ps, depth, &info->reserved12)) - return False; - if (!prs_uint32("user_rid", ps, depth, &info->user_rid)) - return False; - if (!prs_uint32("group_rid", ps, depth, &info->group_rid)) - return False; - if (!prs_uint32("group_count", ps, depth, &info->group_count)) - return False; - /* I haven't seen this contain anything yet, but when it does - we will have to make sure we decode the contents in the middle - all the unistr2s ... */ - if (!prs_uint32("group_mem_ptr", ps, depth, - &info->group_membership_ptr)) - return False; - if (!prs_uint32("user_flags", ps, depth, &info->user_flags)) - return False; - - if (!prs_uint32("reserved13.0", ps, depth, &info->reserved13[0])) - return False; - if (!prs_uint32("reserved13.1", ps, depth, &info->reserved13[1])) - return False; - if (!prs_uint32("reserved13.2", ps, depth, &info->reserved13[2])) - return False; - if (!prs_uint32("reserved13.3", ps, depth, &info->reserved13[3])) - return False; - - if (!smb_io_unihdr("hdr_dom_controller", - &info->hdr_dom_controller, ps, depth)) - return False; - if (!smb_io_unihdr("hdr_dom_name", &info->hdr_dom_name, ps, depth)) - return False; - - /* this should be followed, but just get ptr for now */ - if (!prs_uint32("ptr_dom_sid", ps, depth, &info->ptr_dom_sid)) - return False; - - if (!prs_uint32("reserved16.0", ps, depth, &info->reserved16[0])) - return False; - if (!prs_uint32("reserved16.1", ps, depth, &info->reserved16[1])) - return False; - - /* might be acb_info */ - if (!prs_uint32("reserved17", ps, depth, &info->reserved17)) - return False; - - - if (!prs_uint32("reserved18.0", ps, depth, &info->reserved18[0])) - return False; - if (!prs_uint32("reserved18.1", ps, depth, &info->reserved18[1])) - return False; - if (!prs_uint32("reserved18.2", ps, depth, &info->reserved18[2])) - return False; - if (!prs_uint32("reserved18.3", ps, depth, &info->reserved18[3])) - return False; - if (!prs_uint32("reserved18.4", ps, depth, &info->reserved18[4])) - return False; - if (!prs_uint32("reserved18.5", ps, depth, &info->reserved18[5])) - return False; - if (!prs_uint32("reserved18.6", ps, depth, &info->reserved18[6])) - return False; - - if (!prs_uint32("sid_count", ps, depth, &info->sid_count)) - return False; - if (!prs_uint32("ptr_extra_sids", ps, depth, &info->ptr_extra_sids)) - return False; - if (!prs_uint32("ptr_res_group_dom_sid", ps, depth, - &info->ptr_res_group_dom_sid)) - return False; - if (!prs_uint32("res_group_count", ps, depth, &info->res_group_count)) - return False; - if (!prs_uint32("ptr_res_groups", ps, depth, &info->ptr_res_groups)) - return False; - - if(!smb_io_unistr2("uni_user_name", &info->uni_user_name, - info->hdr_user_name.buffer, ps, depth)) - return False; - if(!smb_io_unistr2("uni_full_name", &info->uni_full_name, - info->hdr_full_name.buffer, ps, depth)) - return False; - if(!smb_io_unistr2("uni_logon_script", &info->uni_logon_script, - info->hdr_logon_script.buffer, ps, depth)) - return False; - if(!smb_io_unistr2("uni_profile_path", &info->uni_profile_path, - info->hdr_profile_path.buffer, ps, depth)) - return False; - if(!smb_io_unistr2("uni_home_dir", &info->uni_home_dir, - info->hdr_home_dir.buffer, ps, depth)) - return False; - if(!smb_io_unistr2("uni_dir_drive", &info->uni_dir_drive, - info->hdr_dir_drive.buffer, ps, depth)) - return False; - - if (info->group_membership_ptr) { - if (!pac_io_group_membership_array("group membership", - &info->groups, - info->group_count, - ps, depth)) - return False; - } - - - if(!smb_io_unistr2("uni_dom_controller", &info->uni_dom_controller, - info->hdr_dom_controller.buffer, ps, depth)) - return False; - if(!smb_io_unistr2("uni_dom_name", &info->uni_dom_name, - info->hdr_dom_name.buffer, ps, depth)) - return False; - - if(info->ptr_dom_sid) - if(!smb_io_dom_sid2("dom_sid", &info->dom_sid, ps, depth)) - return False; - - - if (info->sid_count && info->ptr_extra_sids) - if (!pac_io_krb_sid_and_attr_array("extra_sids", - &info->extra_sids, - info->sid_count, - ps, depth)) - return False; - - if (info->ptr_res_group_dom_sid) - if (!smb_io_dom_sid2("res_group_dom_sid", - &info->res_group_dom_sid, ps, depth)) - return False; - - if (info->ptr_res_groups) - if (!pac_io_group_membership_array("res group membership", - &info->res_groups, - info->res_group_count, - ps, depth)) - return False; - - return True; -} - - -static BOOL pac_io_pac_signature_data(const char *desc, - PAC_SIGNATURE_DATA *data, uint32 length, - prs_struct *ps, int depth) -{ - uint32 siglen = length - sizeof(uint32); - if (NULL == data) - return False; - - prs_debug(ps, depth, desc, "pac_io_pac_signature_data"); - depth++; - - if (!prs_uint32("type", ps, depth, &data->type)) - return False; - if (UNMARSHALLING(ps)) { - data->signature = (unsigned char *)prs_alloc_mem(ps, siglen); - if (!data->signature) { - DEBUG(3, ("No memory available\n")); - return False; - } - } - if (!prs_uint8s(False, "signature", ps, depth, data->signature,siglen)) - return False; - - return True; -} - -static BOOL pac_io_pac_info_hdr_ctr(const char *desc, PAC_INFO_HDR *hdr, - prs_struct *ps, int depth) -{ - if (NULL == hdr) - return False; - - prs_debug(ps, depth, desc, "pac_io_pac_info_hdr_ctr"); - depth++; - - if (!prs_align(ps)) - return False; - - if (hdr->offset != prs_offset(ps)) { - DEBUG(5, ("offset in header(x%x) and data(x%x) do not match\n", - hdr->offset, prs_offset(ps))); - prs_set_offset(ps, hdr->offset); - } - - if (UNMARSHALLING(ps) && hdr->size > 0) { - hdr->ctr = (PAC_INFO_CTR *) - prs_alloc_mem(ps, sizeof(PAC_INFO_CTR)); - if (!hdr->ctr) { - DEBUG(3, ("No memory available\n")); - return False; - } - } - - switch(hdr->type) { - case PAC_TYPE_LOGON_INFO: - DEBUG(5, ("PAC_TYPE_LOGON_INFO\n")); - if (UNMARSHALLING(ps)) - hdr->ctr->pac.logon_info = (PAC_LOGON_INFO *) - prs_alloc_mem(ps, sizeof(PAC_LOGON_INFO)); - if (!hdr->ctr->pac.logon_info) { - DEBUG(3, ("No memory available\n")); - return False; - } - if (!pac_io_pac_logon_info(desc, hdr->ctr->pac.logon_info, - ps, depth)) - return False; - break; - - case PAC_TYPE_SERVER_CHECKSUM: - DEBUG(5, ("PAC_TYPE_SERVER_CHECKSUM\n")); - if (UNMARSHALLING(ps)) - hdr->ctr->pac.srv_cksum = (PAC_SIGNATURE_DATA *) - prs_alloc_mem(ps, sizeof(PAC_SIGNATURE_DATA)); - if (!hdr->ctr->pac.srv_cksum) { - DEBUG(3, ("No memory available\n")); - return False; - } - if (!pac_io_pac_signature_data(desc, hdr->ctr->pac.srv_cksum, - hdr->size, ps, depth)) - return False; - break; - - case PAC_TYPE_PRIVSVR_CHECKSUM: - DEBUG(5, ("PAC_TYPE_PRIVSVR_CHECKSUM\n")); - if (UNMARSHALLING(ps)) - hdr->ctr->pac.privsrv_cksum = (PAC_SIGNATURE_DATA *) - prs_alloc_mem(ps, sizeof(PAC_SIGNATURE_DATA)); - if (!hdr->ctr->pac.privsrv_cksum) { - DEBUG(3, ("No memory available\n")); - return False; - } - if (!pac_io_pac_signature_data(desc, - hdr->ctr->pac.privsrv_cksum, - hdr->size, ps, depth)) - return False; - break; - - case PAC_TYPE_UNKNOWN_10: - DEBUG(5, ("PAC_TYPE_UNKNOWN_10\n")); - if (UNMARSHALLING(ps)) - hdr->ctr->pac.type_10 = (UNKNOWN_TYPE_10 *) - prs_alloc_mem(ps, sizeof(UNKNOWN_TYPE_10)); - if (!hdr->ctr->pac.type_10) { - DEBUG(3, ("No memory available\n")); - return False; - } - if (!pac_io_unknown_type_10(desc, hdr->ctr->pac.type_10, - ps, depth)) - return False; - break; - - default: - /* dont' know, so we need to skip it */ - DEBUG(3, ("unknown PAC type %d\n", hdr->type)); - prs_set_offset(ps, prs_offset(ps) + hdr->size); - } - - return True; -} - -static BOOL pac_io_pac_info_hdr(const char *desc, PAC_INFO_HDR *hdr, - prs_struct *ps, int depth) -{ - if (NULL == hdr) - return False; - - prs_debug(ps, depth, desc, "pac_io_pac_info_hdr"); - depth++; - - if (!prs_align(ps)) - return False; - if (!prs_uint32("type", ps, depth, &hdr->type)) - return False; - if (!prs_uint32("size", ps, depth, &hdr->size)) - return False; - if (!prs_uint32("offset", ps, depth, &hdr->offset)) - return False; - if (!prs_uint32("offsethi", ps, depth, &hdr->offsethi)) - return False; - - return True; -} - -static BOOL pac_io_pac_data(const char *desc, PAC_DATA *data, - prs_struct *ps, int depth) -{ - int i; - - if (NULL == data) - return False; - - prs_debug(ps, depth, desc, "pac_io_pac_data"); - depth++; - - if (!prs_align(ps)) - return False; - if (!prs_uint32("num_buffers", ps, depth, &data->num_buffers)) - return False; - if (!prs_uint32("version", ps, depth, &data->version)) - return False; - - if (UNMARSHALLING(ps) && data->num_buffers > 0) { - if ((data->pac_info_hdr_ptr = (PAC_INFO_HDR *) - prs_alloc_mem(ps, sizeof(PAC_INFO_HDR) * - data->num_buffers)) == NULL) { - return False; - } - } - - for (i=0; i<data->num_buffers; i++) { - if (!pac_io_pac_info_hdr(desc, &data->pac_info_hdr_ptr[i], ps, - depth)) - return False; - } - - for (i=0; i<data->num_buffers; i++) { - if (!pac_io_pac_info_hdr_ctr(desc, &data->pac_info_hdr_ptr[i], - ps, depth)) - return False; - } - - return True; -} - -PAC_DATA *decode_pac_data(DATA_BLOB *auth_data, TALLOC_CTX *ctx) -{ - DATA_BLOB pac_data_blob = unwrap_pac(auth_data); - prs_struct ps; - PAC_DATA *pac_data; - - DEBUG(5,("dump_pac_data\n")); - prs_init(&ps, pac_data_blob.length, ctx, UNMARSHALL); - prs_copy_data_in(&ps, (char *)pac_data_blob.data, pac_data_blob.length); - prs_set_offset(&ps, 0); - - data_blob_free(&pac_data_blob); - - pac_data = (PAC_DATA *) talloc_zero(ctx, sizeof(PAC_DATA)); - pac_io_pac_data("pac data", pac_data, &ps, 0); - - prs_mem_free(&ps); - - return pac_data; -} - -#endif diff --git a/source/libads/config.m4 b/source/libads/config.m4 new file mode 100644 index 00000000000..a7a882f0484 --- /dev/null +++ b/source/libads/config.m4 @@ -0,0 +1,442 @@ +######################################################## +# Compile with LDAP support? + +LDAP_LIBS="" +AC_SUBST(LDAP_LIBS) +with_ldap_support=auto +AC_MSG_CHECKING([for LDAP support]) + +AC_ARG_WITH(ldap, +[ --with-ldap LDAP support (default yes)], +[ case "$withval" in + yes|no) + with_ldap_support=$withval + ;; + esac ]) + +AC_MSG_RESULT($with_ldap_support) + +if test x"$with_ldap_support" != x"no"; then + + ################################################################## + # first test for ldap.h and lber.h + # (ldap.h is required for this test) + AC_CHECK_HEADERS(ldap.h lber.h) + + if test x"$ac_cv_header_ldap_h" != x"yes"; then + if test x"$with_ldap_support" = x"yes"; then + AC_MSG_ERROR(ldap.h is needed for LDAP support) + else + AC_MSG_WARN(ldap.h is needed for LDAP support) + fi + + with_ldap_support=no + fi +fi + +if test x"$with_ldap_support" != x"no"; then + ac_save_LIBS=$LIBS + + ################################################################## + # we might need the lber lib on some systems. To avoid link errors + # this test must be before the libldap test + AC_CHECK_LIB_EXT(lber, LDAP_LIBS, ber_scanf) + + ######################################################## + # now see if we can find the ldap libs in standard paths + AC_CHECK_LIB_EXT(ldap, LDAP_LIBS, ldap_init) + + AC_CHECK_FUNC_EXT(ldap_domain2hostlist,$LDAP_LIBS) + + ######################################################## + # If we have LDAP, does it's rebind procedure take 2 or 3 arguments? + # Check found in pam_ldap 145. + AC_CHECK_FUNC_EXT(ldap_set_rebind_proc,$LDAP_LIBS) + + LIBS="$LIBS $LDAP_LIBS" + AC_CACHE_CHECK(whether ldap_set_rebind_proc takes 3 arguments, smb_ldap_cv_ldap_set_rebind_proc, [ + AC_TRY_COMPILE([ + #include <lber.h> + #include <ldap.h>], + [ldap_set_rebind_proc(0, 0, 0);], + [smb_ldap_cv_ldap_set_rebind_proc=3], + [smb_ldap_cv_ldap_set_rebind_proc=2] + ) + ]) + + AC_DEFINE_UNQUOTED(LDAP_SET_REBIND_PROC_ARGS, $smb_ldap_cv_ldap_set_rebind_proc, [Number of arguments to ldap_set_rebind_proc]) + + AC_CHECK_FUNC_EXT(ldap_initialize,$LDAP_LIBS) + + if test x"$ac_cv_lib_ext_ldap_ldap_init" = x"yes" -a x"$ac_cv_func_ext_ldap_domain2hostlist" = x"yes"; then + AC_DEFINE(HAVE_LDAP,1,[Whether ldap is available]) + with_ldap_support=yes + AC_MSG_CHECKING(whether LDAP support is used) + AC_MSG_RESULT(yes) + else + if test x"$with_ldap_support" = x"yes"; then + AC_MSG_ERROR(libldap is needed for LDAP support) + else + AC_MSG_WARN(libldap is needed for LDAP support) + fi + + LDAP_LIBS="" + with_ldap_support=no + fi + LIBS=$ac_save_LIBS +fi + + +################################################# +# active directory support + +KRB5_LIBS="" +AC_SUBST(KRB5_LIBS) +with_ads_support=auto +AC_MSG_CHECKING([for Active Directory and krb5 support]) + +AC_ARG_WITH(ads, +[ --with-ads Active Directory support (default auto)], +[ case "$withval" in + yes|no) + with_ads_support="$withval" + ;; + esac ]) + +AC_MSG_RESULT($with_ads_support) + +if test x"$with_ldap_support" != x"yes"; then + if test x"$with_ads_support" = x"yes"; then + AC_MSG_ERROR(Active Directory Support requires LDAP support) + elif test x"$with_ads_support" != x"no"; then + AC_MSG_WARN(Active Directory Support requires LDAP support) + fi + with_ads_support=no +fi + +if test x"$with_ads_support" != x"no"; then + FOUND_KRB5=no + # Do no harm to the values of CFLAGS and LIBS while testing for + # Kerberos support. + + ################################################# + # check for krb5-config from recent MIT and Heimdal kerberos 5 + AC_PATH_PROG(KRB5_CONFIG, krb5-config) + AC_MSG_CHECKING(for working krb5-config) + if test -x "$KRB5_CONFIG"; then + ac_save_CFLAGS=$CFLAGS + CFLAGS="";export CFLAGS + ac_save_LDFLAGS=$LDFLAGS + LDFLAGS="";export LDFLAGS + KRB5_LIBS="`$KRB5_CONFIG --libs gssapi`" + KRB5_CFLAGS="`$KRB5_CONFIG --cflags | sed s/@INCLUDE_des@//`" + KRB5_CPPFLAGS="`$KRB5_CONFIG --cflags | sed s/@INCLUDE_des@//`" + CFLAGS=$ac_save_CFLAGS;export CFLAGS + LDFLAGS=$ac_save_LDFLAGS;export LDFLAGS + FOUND_KRB5=yes + AC_MSG_RESULT(yes) + else + AC_MSG_RESULT(no. Fallback to previous krb5 detection strategy) + fi + + if test x$FOUND_KRB5 = x"no"; then + ################################################# + # check for location of Kerberos 5 install + AC_MSG_CHECKING(for kerberos 5 install path) + AC_ARG_WITH(krb5, + [ --with-krb5=base-dir Locate Kerberos 5 support (default=/usr)], + [ case "$withval" in + no) + AC_MSG_RESULT(no krb5-path given) + ;; + yes) + AC_MSG_RESULT(/usr) + FOUND_KRB5=yes + ;; + *) + AC_MSG_RESULT($withval) + KRB5_CFLAGS="-I$withval/include" + KRB5_CPPFLAGS="-I$withval/include" + KRB5_LDFLAGS="-L$withval/lib" + FOUND_KRB5=yes + ;; + esac ], + AC_MSG_RESULT(no krb5-path given) + ) + fi + + if test x$FOUND_KRB5 = x"no"; then + ################################################# + # see if this box has the SuSE location for the heimdal krb implementation + AC_MSG_CHECKING(for /usr/include/heimdal) + if test -d /usr/include/heimdal; then + if test -f /usr/lib/heimdal/lib/libkrb5.a; then + KRB5_CFLAGS="-I/usr/include/heimdal" + KRB5_CPPFLAGS="-I/usr/include/heimdal" + KRB5_LDFLAGS="-L/usr/lib/heimdal/lib" + AC_MSG_RESULT(yes) + else + KRB5_CFLAGS="-I/usr/include/heimdal" + KRB5_CPPFLAGS="-I/usr/include/heimdal" + AC_MSG_RESULT(yes) + fi + else + AC_MSG_RESULT(no) + fi + fi + + if test x$FOUND_KRB5 = x"no"; then + ################################################# + # see if this box has the RedHat location for kerberos + AC_MSG_CHECKING(for /usr/kerberos) + if test -d /usr/kerberos -a -f /usr/kerberos/lib/libkrb5.a; then + KRB5_LDFLAGS="-L/usr/kerberos/lib" + KRB5_CFLAGS="-I/usr/kerberos/include" + KRB5_CPPFLAGS="-I/usr/kerberos/include" + AC_MSG_RESULT(yes) + else + AC_MSG_RESULT(no) + fi + fi + + ac_save_CFLAGS=$CFLAGS + ac_save_CPPFLAGS=$CPPFLAGS + ac_save_LDFLAGS=$LDFLAGS + + CFLAGS="$CFLAGS $KRB5_CFLAGS" + CPPFLAGS="$CPPFLAGS $KRB5_CPPFLAGS" + LDFLAGS="$LDFLAGS $KRB5_LDFLAGS" + + KRB5_LIBS="$KRB5_LDFLAGS $KRB5_LIBS" + + # 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 + # include paths + AC_CHECK_HEADERS(krb5.h) + + if test x"$ac_cv_header_krb5_h" = x"no"; then + + # Give a warning if AD support was not explicitly requested, + # i.e with_ads_support = auto, otherwise die with an error. + + if test x"$with_ads_support" = x"yes"; then + AC_MSG_ERROR([Active Directory cannot be supported without krb5.h]) + else + AC_MSG_WARN([Active Directory cannot be supported without krb5.h]) + fi + + # Turn off AD support and restore CFLAGS and LIBS variables + + with_ads_support="no" + + CFLAGS=$ac_save_CFLAGS + CPPFLAGS=$ac_save_CPPFLAGS + LDFLAGS=$ac_save_LDFLAGS + fi +fi + +# Now we have determined whether we really want ADS support + +if test x"$with_ads_support" != x"no"; then + ac_save_LIBS=$LIBS + + # now check for gssapi headers. This is also done here to allow for + # different kerberos include paths + AC_CHECK_HEADERS(gssapi.h gssapi/gssapi_generic.h gssapi/gssapi.h com_err.h) + + ################################################################## + # we might need the k5crypto and com_err libraries on some systems + AC_CHECK_LIB_EXT(com_err, KRB5_LIBS, _et_list) + AC_CHECK_LIB_EXT(k5crypto, KRB5_LIBS, krb5_encrypt_data) + + # Heimdal checks. + AC_CHECK_LIB_EXT(crypto, KRB5_LIBS, des_set_key) + AC_CHECK_LIB_EXT(asn1, KRB5_LIBS, copy_Authenticator) + AC_CHECK_LIB_EXT(roken, KRB5_LIBS, roken_getaddrinfo_hostspec) + + # Heimdal checks. On static Heimdal gssapi must be linked before krb5. + AC_CHECK_LIB_EXT(gssapi, KRB5_LIBS, gss_display_status,[],[], + AC_DEFINE(HAVE_GSSAPI,1,[Whether GSSAPI is available])) + + ######################################################## + # now see if we can find the krb5 libs in standard paths + # or as specified above + AC_CHECK_LIB_EXT(krb5, KRB5_LIBS, krb5_mk_req_extended) + + ######################################################## + # now see if we can find the gssapi libs in standard paths + AC_CHECK_LIB_EXT(gssapi_krb5, KRB5_LIBS,gss_display_status,[],[], + AC_DEFINE(HAVE_GSSAPI,1,[Whether GSSAPI is available])) + + AC_CHECK_FUNC_EXT(krb5_set_real_time, $KRB5_LIBS) + AC_CHECK_FUNC_EXT(krb5_set_default_in_tkt_etypes, $KRB5_LIBS) + AC_CHECK_FUNC_EXT(krb5_set_default_tgs_ktypes, $KRB5_LIBS) + AC_CHECK_FUNC_EXT(krb5_principal2salt, $KRB5_LIBS) + AC_CHECK_FUNC_EXT(krb5_use_enctype, $KRB5_LIBS) + AC_CHECK_FUNC_EXT(krb5_string_to_key, $KRB5_LIBS) + AC_CHECK_FUNC_EXT(krb5_get_pw_salt, $KRB5_LIBS) + AC_CHECK_FUNC_EXT(krb5_string_to_key_salt, $KRB5_LIBS) + AC_CHECK_FUNC_EXT(krb5_auth_con_setkey, $KRB5_LIBS) + AC_CHECK_FUNC_EXT(krb5_auth_con_setuseruserkey, $KRB5_LIBS) + AC_CHECK_FUNC_EXT(krb5_locate_kdc, $KRB5_LIBS) + AC_CHECK_FUNC_EXT(krb5_get_permitted_enctypes, $KRB5_LIBS) + AC_CHECK_FUNC_EXT(krb5_get_default_in_tkt_etypes, $KRB5_LIBS) + AC_CHECK_FUNC_EXT(krb5_free_ktypes, $KRB5_LIBS) + AC_CHECK_FUNC_EXT(krb5_free_data_contents, $KRB5_LIBS) + AC_CHECK_FUNC_EXT(krb5_principal_get_comp_string, $KRB5_LIBS) + + LIBS="$LIBS $KRB5_LIBS" + + AC_CACHE_CHECK([for addrtype in krb5_address], + samba_cv_HAVE_ADDRTYPE_IN_KRB5_ADDRESS,[ + AC_TRY_COMPILE([#include <krb5.h>], + [krb5_address kaddr; kaddr.addrtype = ADDRTYPE_INET;], + samba_cv_HAVE_ADDRTYPE_IN_KRB5_ADDRESS=yes, + samba_cv_HAVE_ADDRTYPE_IN_KRB5_ADDRESS=no)]) + + if test x"$samba_cv_HAVE_ADDRTYPE_IN_KRB5_ADDRESS" = x"yes"; then + AC_DEFINE(HAVE_ADDRTYPE_IN_KRB5_ADDRESS,1, + [Whether the krb5_address struct has a addrtype property]) + fi + + AC_CACHE_CHECK([for addr_type in krb5_address], + samba_cv_HAVE_ADDR_TYPE_IN_KRB5_ADDRESS,[ + AC_TRY_COMPILE([#include <krb5.h>], + [krb5_address kaddr; kaddr.addr_type = KRB5_ADDRESS_INET;], + samba_cv_HAVE_ADDR_TYPE_IN_KRB5_ADDRESS=yes, + samba_cv_HAVE_ADDR_TYPE_IN_KRB5_ADDRESS=no)]) + + if test x"$samba_cv_HAVE_ADDR_TYPE_IN_KRB5_ADDRESS" = x"yes"; then + AC_DEFINE(HAVE_ADDR_TYPE_IN_KRB5_ADDRESS,1, + [Whether the krb5_address struct has a addr_type property]) + fi + + AC_CACHE_CHECK([for enc_part2 in krb5_ticket], + samba_cv_HAVE_KRB5_TKT_ENC_PART2, + [AC_TRY_COMPILE([#include <krb5.h>], + [krb5_ticket tkt; tkt.enc_part2->authorization_data[0]->contents = NULL;], + samba_cv_HAVE_KRB5_TKT_ENC_PART2=yes,samba_cv_HAVE_KRB5_TKT_ENC_PART2=no)]) + + if test x"$samba_cv_HAVE_KRB5_TKT_ENC_PART2" = x"yes"; then + AC_DEFINE(HAVE_KRB5_TKT_ENC_PART2,1, + [Whether the krb5_ticket struct has a enc_part2 property]) + fi + + AC_CACHE_CHECK([for keyvalue in krb5_keyblock], + samba_cv_HAVE_KRB5_KEYBLOCK_KEYVALUE,[ + AC_TRY_COMPILE([#include <krb5.h>], + [krb5_keyblock key; key.keyvalue.data = NULL;], + samba_cv_HAVE_KRB5_KEYBLOCK_KEYVALUE=yes, + samba_cv_HAVE_KRB5_KEYBLOCK_KEYVALUE=no)]) + + if test x"$samba_cv_HAVE_KRB5_KEYBLOCK_KEYVALUE" = x"yes"; then + AC_DEFINE(HAVE_KRB5_KEYBLOCK_KEYVALUE,1, + [Whether the krb5_keyblock struct has a keyvalue property]) + fi + + AC_CACHE_CHECK([for ENCTYPE_ARCFOUR_HMAC_MD5], + samba_cv_HAVE_ENCTYPE_ARCFOUR_HMAC_MD5,[ + AC_TRY_COMPILE([#include <krb5.h>], + [krb5_enctype enctype; enctype = ENCTYPE_ARCFOUR_HMAC_MD5;], + samba_cv_HAVE_ENCTYPE_ARCFOUR_HMAC_MD5=yes, + samba_cv_HAVE_ENCTYPE_ARCFOUR_HMAC_MD5=no)]) + AC_CACHE_CHECK([for KEYTYPE_ARCFOUR_56], + samba_cv_HAVE_KEYTYPE_ARCFOUR_56,[ + AC_TRY_COMPILE([#include <krb5.h>], + [krb5_keytype keytype; keytype = KEYTYPE_ARCFOUR_56;], + samba_cv_HAVE_KEYTYPE_ARCFOUR_56=yes, + samba_cv_HAVE_KEYTYPE_ARCFOUR_56=no)]) +# Heimdals with KEYTYPE_ARCFOUR but not KEYTYPE_ARCFOUR_56 are broken +# w.r.t. arcfour and windows, so we must not enable it here + if test x"$samba_cv_HAVE_ENCTYPE_ARCFOUR_HMAC_MD5" = x"yes" -a\ + x"$samba_cv_HAVE_KEYTYPE_ARCFOUR_56" = x"yes"; then + AC_DEFINE(HAVE_ENCTYPE_ARCFOUR_HMAC_MD5,1, + [Whether the ENCTYPE_ARCFOUR_HMAC_MD5 key type is available]) + fi + + AC_CACHE_CHECK([for AP_OPTS_USE_SUBKEY], + samba_cv_HAVE_AP_OPTS_USE_SUBKEY,[ + AC_TRY_COMPILE([#include <krb5.h>], + [krb5_flags ap_options; ap_options = AP_OPTS_USE_SUBKEY;], + samba_cv_HAVE_AP_OPTS_USE_SUBKEY=yes, + samba_cv_HAVE_AP_OPTS_USE_SUBKEY=no)]) + + if test x"$samba_cv_HAVE_AP_OPTS_USE_SUBKEY" = x"yes"; then + AC_DEFINE(HAVE_AP_OPTS_USE_SUBKEY,1, + [Whether the AP_OPTS_USE_SUBKEY ap option is available]) + fi + + AC_CACHE_CHECK([for the krb5_princ_component macro], + samba_cv_HAVE_KRB5_PRINC_COMPONENT,[ + AC_TRY_LINK([#include <krb5.h>], + [const krb5_data *pkdata; krb5_context context; krb5_principal principal; pkdata = krb5_princ_component(context, principal, 0);], + samba_cv_HAVE_KRB5_PRINC_COMPONENT=yes, + samba_cv_HAVE_KRB5_PRINC_COMPONENT=no)]) + + if test x"$samba_cv_HAVE_KRB5_PRINC_COMPONENT" = x"yes"; then + AC_DEFINE(HAVE_KRB5_PRINC_COMPONENT,1, + [Whether krb5_princ_component is available]) + fi + + AC_CACHE_CHECK([for memory keytab support], + samba_cv_HAVE_MEMORY_KEYTAB,[ + AC_TRY_RUN([ +#include<krb5.h> + main() + { + krb5_context context; + krb5_keytab keytab; + + krb5_init_context(&context); + if (krb5_kt_resolve(context, "MEMORY:", &keytab)) + exit(1); + exit(0); + }], + samba_cv_HAVE_MEMORY_KEYTAB=yes, + samba_cv_HAVE_MEMORY_KEYTAB=no)]) + + if test x"$samba_cv_HAVE_MEMORY_KEYTAB" = x"yes"; then + AC_DEFINE(HAVE_MEMORY_KEYTAB,1, + [Whether in-memory keytabs are supported]) + fi + + AC_CACHE_CHECK([for key in krb5_keytab_entry], + samba_cv_HAVE_KRB5_KEYTAB_ENTRY_KEY,[ + AC_TRY_COMPILE([#include <krb5.h>], + [krb5_keytab_entry entry; krb5_keyblock e; entry.key = e;], + samba_cv_HAVE_KRB5_KEYTAB_ENTRY_KEY=yes, + samba_cv_HAVE_KRB5_KEYTAB_ENTRY_KEY=no)]) + + if test x"$samba_cv_HAVE_KRB5_KEYTAB_ENTRY_KEY" = x"yes"; then + AC_DEFINE(HAVE_KRB5_KEYTAB_ENTRY_KEY,1, + [Whether krb5_keytab_entry has key member]) + fi + + AC_CACHE_CHECK([for keyblock in krb5_keytab_entry], + samba_cv_HAVE_KRB5_KEYTAB_ENTRY_KEYBLOCK,[ + AC_TRY_COMPILE([#include <krb5.h>], + [krb5_keytab_entry entry; entry.keyblock.keytype = 0;], + samba_cv_HAVE_KRB5_KEYTAB_ENTRY_KEYBLOCK=yes, + samba_cv_HAVE_KRB5_KEYTAB_ENTRY_KEYBLOCK=no)]) + + if test x"$samba_cv_HAVE_KRB5_KEYTAB_ENTRY_KEYBLOCK" = x"yes"; then + AC_DEFINE(HAVE_KRB5_KEYTAB_ENTRY_KEYBLOCK,1, + [Whether krb5_keytab_entry has keyblock member]) + fi + + if test x"$ac_cv_lib_ext_krb5_krb5_mk_req_extended" = x"yes"; then + AC_DEFINE(HAVE_KRB5,1,[Whether to have KRB5 support]) + AC_DEFINE(WITH_ADS,1,[Whether to include Active Directory support]) + AC_MSG_CHECKING(whether Active Directory and KRB5 support is used) + AC_MSG_RESULT(yes) + else + if test x"$with_ads_support" = x"yes"; then + AC_MSG_ERROR(libkrb5 is needed for Active Directory support) + else + AC_MSG_WARN(libkrb5 is needed for Active Directory support) + fi + KRB5_LIBS="" + with_ads_support=no + fi + LIBS="$ac_save_LIBS" +fi diff --git a/source/libads/kerberos.c b/source/libads/kerberos.c index 70f6f3386c7..bef2febaefd 100644 --- a/source/libads/kerberos.c +++ b/source/libads/kerberos.c @@ -54,7 +54,7 @@ kerb_prompter(krb5_context ctx, void *data, simulate a kinit, putting the tgt in the default cache location remus@snapserver.com */ -int kerberos_kinit_password(const char *principal, const char *password, int time_offset, time_t *expire_time) +int kerberos_kinit_password(const char *principal, const char *password, int time_offset) { krb5_context ctx; krb5_error_code code = 0; @@ -102,9 +102,6 @@ int kerberos_kinit_password(const char *principal, const char *password, int tim return code; } - if (expire_time) - *expire_time = (time_t) my_creds.times.endtime; - krb5_cc_close(ctx, cc); krb5_free_cred_contents(ctx, &my_creds); krb5_free_principal(ctx, me); @@ -129,7 +126,7 @@ int ads_kinit_password(ADS_STRUCT *ads) return KRB5_LIBOS_CANTREADPWD; } - ret = kerberos_kinit_password(s, ads->auth.password, ads->auth.time_offset, &ads->auth.expire); + ret = kerberos_kinit_password(s, ads->auth.password, ads->auth.time_offset); if (ret) { DEBUG(0,("kerberos_kinit_password %s failed: %s\n", @@ -139,37 +136,5 @@ int ads_kinit_password(ADS_STRUCT *ads) return ret; } -int ads_kdestroy(const char *cc_name) -{ - krb5_error_code code; - krb5_context ctx; - krb5_ccache cc; - - if ((code = krb5_init_context (&ctx))) { - DEBUG(3, ("ads_kdestroy: kdb5_init_context rc=%d\n", code)); - return code; - } - - if (!cc_name) { - if ((code = krb5_cc_default(ctx, &cc))) { - krb5_free_context(ctx); - return code; - } - } else { - if ((code = krb5_cc_resolve(ctx, cc_name, &cc))) { - DEBUG(3, ("ads_kdestroy: krb5_cc_resolve rc=%d\n", - code)); - krb5_free_context(ctx); - return code; - } - } - - if ((code = krb5_cc_destroy (ctx, cc))) { - DEBUG(3, ("ads_kdestroy: krb5_cc_destroy rc=%d\n", code)); - } - - krb5_free_context (ctx); - return code; -} #endif diff --git a/source/libads/kerberos_verify.c b/source/libads/kerberos_verify.c index 47559c1abb7..8b319ee5544 100644 --- a/source/libads/kerberos_verify.c +++ b/source/libads/kerberos_verify.c @@ -26,6 +26,135 @@ #ifdef HAVE_KRB5 +static void free_keytab(krb5_context context, krb5_keytab keytab) +{ + int ret=0; + + if (keytab) + ret = krb5_kt_close(context, keytab); + if (ret) { + DEBUG(3, ("krb5_kt_close failed (%s)\n", + error_message(ret))); + } +} + +#ifdef HAVE_MEMORY_KEYTAB +static krb5_error_code create_keytab(krb5_context context, + krb5_principal host_princ, + char *host_princ_s, + krb5_data password, + krb5_enctype *enctypes, + krb5_keytab *keytab, + char *keytab_name) +{ + krb5_keytab_entry entry; + krb5_kvno kvno = 1; + krb5_error_code ret; + krb5_keyblock *key; + int i; + + DEBUG(10,("creating keytab: %s\n", keytab_name)); + ret = krb5_kt_resolve(context, keytab_name, keytab); + if (ret) + return ret; + + if (!(key = (krb5_keyblock *)malloc(sizeof(*key)))) { + return ENOMEM; + } + + /* add keytab entries for all encryption types */ + for ( i=0; enctypes[i]; i++ ) { + + if (create_kerberos_key_from_string(context, host_princ, &password, key, enctypes[i])) { + continue; + } + + entry.principal = host_princ; + entry.vno = kvno; + +#if !defined(HAVE_KRB5_KEYTAB_ENTRY_KEY) && !defined(HAVE_KRB5_KEYTAB_ENTRY_KEYBLOCK) +#error krb5_keytab_entry has no key or keyblock member +#endif + +#ifdef HAVE_KRB5_KEYTAB_ENTRY_KEY /* MIT */ + entry.key = *key; +#endif + +#ifdef HAVE_KRB5_KEYTAB_ENTRY_KEYBLOCK /* Heimdal */ + entry.keyblock = *key; +#endif + + DEBUG(10,("adding keytab-entry for (%s) with encryption type (%d)\n", + host_princ_s, enctypes[i])); + ret = krb5_kt_add_entry(context, *keytab, &entry); + if (ret) { + DEBUG(1,("adding entry to keytab failed (%s)\n", + error_message(ret))); + free_keytab(context, *keytab); + return ret; + } + } + krb5_free_keyblock(context, key); + + return 0; +} +#endif + +static BOOL setup_keytab(krb5_context context, + krb5_principal host_princ, + char *host_princ_s, + krb5_data password, + krb5_enctype *enctypes, + krb5_keytab *keytab) +{ + char *keytab_name = NULL; + krb5_error_code ret; + + /* check if we have to setup a keytab - not currently enabled + I've put this in so that the else block below functions + the same way that it will when this code is turned on */ + if (0 /* will later be *lp_keytab() */) { + + /* use a file-keytab */ + asprintf(&keytab_name, "%s:%s", + "" + /* KRB5_KT_FILE_PREFIX, "FILE" or + "WRFILE" depending on HEeimdal or MIT */, + "" /* will later be lp_keytab() */); + + DEBUG(10,("will use filebased keytab: %s\n", keytab_name)); + ret = krb5_kt_resolve(context, keytab_name, keytab); + if (ret) { + DEBUG(3,("cannot resolve keytab name %s (%s)\n", + keytab_name, + error_message(ret))); + SAFE_FREE(keytab_name); + return False; + } + + } + +#if defined(HAVE_MEMORY_KEYTAB) + else { + + /* setup a in-memory-keytab */ + asprintf(&keytab_name, "MEMORY:"); + + ret = create_keytab(context, host_princ, host_princ_s, password, enctypes, + keytab, keytab_name); + if (ret) { + DEBUG(3,("unable to create MEMORY: keytab (%s)\n", + error_message(ret))); + SAFE_FREE(keytab_name); + return False; + } + } +#endif + SAFE_FREE(keytab_name); + return True; +} + + /* verify an incoming ticket and parse out the principal name and authorization_data if available @@ -38,6 +167,7 @@ NTSTATUS ads_verify_ticket(const char *realm, const DATA_BLOB *ticket, NTSTATUS sret = NT_STATUS_LOGON_FAILURE; krb5_context context = NULL; krb5_auth_context auth_context = NULL; + krb5_keytab keytab = NULL; krb5_data packet; krb5_ticket *tkt = NULL; krb5_rcache rcache = NULL; @@ -47,7 +177,6 @@ NTSTATUS ads_verify_ticket(const char *realm, const DATA_BLOB *ticket, krb5_principal host_princ; char *host_princ_s = NULL; BOOL free_host_princ = False; - BOOL got_replay_mutex = False; fstring myname; char *password_s = NULL; @@ -151,8 +280,13 @@ NTSTATUS ads_verify_ticket(const char *realm, const DATA_BLOB *ticket, goto out; } - got_replay_mutex = True; - + if (!setup_keytab(context, host_princ, host_princ_s, password, + enctypes, &keytab)) { + DEBUG(3,("ads_verify_ticket: unable to setup keytab\n")); + sret = NT_STATUS_LOGON_FAILURE; + goto out; + } + /* We need to setup a auth context with each possible encoding type in turn. */ for (i=0;enctypes[i];i++) { if (!(key = (krb5_keyblock *)malloc(sizeof(*key)))) { @@ -172,8 +306,12 @@ NTSTATUS ads_verify_ticket(const char *realm, const DATA_BLOB *ticket, packet.data = (krb5_pointer)ticket->data; if (!(ret = krb5_rd_req(context, &auth_context, &packet, +#ifdef HAVE_MEMORY_KEYTAB + host_princ, +#else NULL, - NULL, NULL, &tkt))) { +#endif + keytab, NULL, &tkt))) { DEBUG(10,("ads_verify_ticket: enc type [%u] decrypted message !\n", (unsigned int)enctypes[i] )); auth_ok = True; @@ -186,7 +324,6 @@ NTSTATUS ads_verify_ticket(const char *realm, const DATA_BLOB *ticket, } release_server_mutex(); - got_replay_mutex = False; if (!auth_ok) { DEBUG(3,("ads_verify_ticket: krb5_rd_req with auth failed (%s)\n", @@ -215,11 +352,13 @@ NTSTATUS ads_verify_ticket(const char *realm, const DATA_BLOB *ticket, get_auth_data_from_tkt(auth_data, tkt); +#if 0 { TALLOC_CTX *ctx = talloc_init("pac data"); decode_pac_data(auth_data, ctx); talloc_destroy(ctx); } +#endif #if 0 if (tkt->enc_part2) { @@ -229,6 +368,10 @@ NTSTATUS ads_verify_ticket(const char *realm, const DATA_BLOB *ticket, } #endif + + /* get rid of all resources associated with the keytab */ + if (keytab) free_keytab(context, keytab); + if ((ret = krb5_unparse_name(context, get_principal_from_tkt(tkt), principal))) { DEBUG(3,("ads_verify_ticket: krb5_unparse_name failed (%s)\n", @@ -241,9 +384,6 @@ NTSTATUS ads_verify_ticket(const char *realm, const DATA_BLOB *ticket, out: - if (got_replay_mutex) - release_server_mutex(); - if (!NT_STATUS_IS_OK(sret)) data_blob_free(auth_data); diff --git a/source/libads/krb5_setpw.c b/source/libads/krb5_setpw.c index 16d3df83e93..9cf15221a8d 100644 --- a/source/libads/krb5_setpw.c +++ b/source/libads/krb5_setpw.c @@ -642,7 +642,7 @@ ADS_STATUS kerberos_set_password(const char *kpasswd_server, { int ret; - if ((ret = kerberos_kinit_password(auth_principal, auth_password, time_offset, NULL))) { + if ((ret = kerberos_kinit_password(auth_principal, auth_password, time_offset))) { DEBUG(1,("Failed kinit for principal %s (%s)\n", auth_principal, error_message(ret))); return ADS_ERROR_KRB5(ret); } diff --git a/source/libads/ldap.c b/source/libads/ldap.c index 20a36dfdf5c..8039d3d1d40 100644 --- a/source/libads/ldap.c +++ b/source/libads/ldap.c @@ -1106,14 +1106,20 @@ static void dump_binary(const char *field, struct berval **values) } } +struct uuid { + uint32 i1; + uint16 i2; + uint16 i3; + uint8 s[8]; +}; + static void dump_guid(const char *field, struct berval **values) { int i; - UUID_FLAT guid; + GUID guid; for (i=0; values[i]; i++) { memcpy(guid.info, values[i]->bv_val, sizeof(guid.info)); - printf("%s: %s\n", field, - smb_uuid_string_static(smb_uuid_unpack_static(guid))); + printf("%s: %s\n", field, smb_uuid_string_static(guid)); } } @@ -1655,7 +1661,7 @@ char **ads_pull_strings_range(ADS_STRUCT *ads, } if (!attr) { ber_free(ptr, 0); - /* nothing here - this field is just empty */ + /* nothing here - this feild is just empty */ *more_strings = False; return NULL; } @@ -1714,8 +1720,7 @@ char **ads_pull_strings_range(ADS_STRUCT *ads, if (*more_strings) { *next_attribute = talloc_asprintf(mem_ctx, - "%s;range=%d-*", - field, + "member;range=%d-*", *num_strings); if (!*next_attribute) { @@ -1765,18 +1770,16 @@ BOOL ads_pull_uint32(ADS_STRUCT *ads, * @return boolean indicating success **/ BOOL ads_pull_guid(ADS_STRUCT *ads, - void *msg, struct uuid *guid) + void *msg, GUID *guid) { char **values; - UUID_FLAT flat_guid; values = ldap_get_values(ads->ld, msg, "objectGUID"); if (!values) return False; if (values[0]) { - memcpy(&flat_guid.info, values[0], sizeof(UUID_FLAT)); - smb_uuid_unpack(flat_guid, guid); + memcpy(guid, values[0], sizeof(GUID)); ldap_value_free(values); return True; } diff --git a/source/libads/util.c b/source/libads/util.c index 9912a7ba831..f8c9a312bbc 100644 --- a/source/libads/util.c +++ b/source/libads/util.c @@ -24,37 +24,42 @@ ADS_STATUS ads_change_trust_account_password(ADS_STRUCT *ads, char *host_principal) { - char *tmp_password; - char *password; - char *new_password; - char *service_principal; - ADS_STATUS ret; - uint32 sec_channel_type; - - if ((password = secrets_fetch_machine_password(lp_workgroup(), NULL, &sec_channel_type)) == NULL) { - DEBUG(1,("Failed to retrieve password for principal %s\n", host_principal)); - return ADS_ERROR_SYSTEM(ENOENT); - } - - tmp_password = generate_random_str(DEFAULT_TRUST_ACCOUNT_PASSWORD_LENGTH); - new_password = strdup(tmp_password); - - asprintf(&service_principal, "HOST/%s", host_principal); - - ret = kerberos_set_password(ads->auth.kdc_server, service_principal, password, service_principal, new_password, ads->auth.time_offset); - - if (!ADS_ERR_OK(ret)) goto failed; - - if (!secrets_store_machine_password(new_password, lp_workgroup(), sec_channel_type)) { - DEBUG(1,("Failed to save machine password\n")); - return ADS_ERROR_SYSTEM(EACCES); - } + char *tmp_password; + char *password; + char *new_password; + char *service_principal = NULL; + ADS_STATUS ret; + uint32 sec_channel_type; + + if ((password = secrets_fetch_machine_password(lp_workgroup(), NULL, &sec_channel_type)) == NULL) { + DEBUG(1,("Failed to retrieve password for principal %s\n", host_principal)); + return ADS_ERROR_SYSTEM(ENOENT); + } + + tmp_password = generate_random_str(DEFAULT_TRUST_ACCOUNT_PASSWORD_LENGTH); + new_password = strdup(tmp_password); + + asprintf(&service_principal, "HOST/%s", host_principal); + + if (!service_principal) { + DEBUG(1,("asprintf() failed principal %s\n", host_principal)); + return ADS_ERROR_SYSTEM(ENOMEM); + } + + ret = kerberos_set_password(ads->auth.kdc_server, service_principal, password, service_principal, new_password, ads->auth.time_offset); + + if (!ADS_ERR_OK(ret)) goto failed; + + if (!secrets_store_machine_password(new_password, lp_workgroup(), sec_channel_type)) { + DEBUG(1,("Failed to save machine password\n")); + return ADS_ERROR_SYSTEM(EACCES); + } failed: - SAFE_FREE(service_principal); - SAFE_FREE(new_password); + SAFE_FREE(service_principal); + SAFE_FREE(new_password); - return ret; + return ret; } |