summaryrefslogtreecommitdiffstats
path: root/source/libads
diff options
context:
space:
mode:
Diffstat (limited to 'source/libads')
-rw-r--r--source/libads/ads_struct.c19
-rw-r--r--source/libads/authdata.c617
-rw-r--r--source/libads/config.m4442
-rw-r--r--source/libads/kerberos.c39
-rw-r--r--source/libads/kerberos_verify.c156
-rw-r--r--source/libads/krb5_setpw.c2
-rw-r--r--source/libads/ldap.c23
-rw-r--r--source/libads/util.c61
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;
}