mirror of
https://github.com/samba-team/samba.git
synced 2025-01-11 05:18:09 +03:00
merge:
ldap and krb5 configure tests
libads/*.c and libcli/raw/clikrb5.c from 3.0
metze
(This used to be commit 64b5bfcd73
)
This commit is contained in:
parent
0d90f4b47b
commit
670ccc7d64
@ -12,7 +12,7 @@
|
||||
prefix=@prefix@
|
||||
exec_prefix=@exec_prefix@
|
||||
|
||||
LIBS=@LIBS@
|
||||
LIBS=@LIBS@ @LDAP_LIBS@ @KRB5_LIBS@
|
||||
CC=@CC@
|
||||
SHLD=@SHLD@
|
||||
CFLAGS=@CFLAGS@
|
||||
|
107
source4/aclocal.m4
vendored
107
source4/aclocal.m4
vendored
@ -135,6 +135,113 @@ AC_DEFUN(AC_LIBTESTFUNC,
|
||||
esac
|
||||
])
|
||||
|
||||
# AC_CHECK_LIB_EXT(LIBRARY, [EXT_LIBS], [FUNCTION],
|
||||
# [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND],
|
||||
# [ADD-ACTION-IF-FOUND],[OTHER-LIBRARIES])
|
||||
# ------------------------------------------------------
|
||||
#
|
||||
# Use a cache variable name containing both the library and function name,
|
||||
# because the test really is for library $1 defining function $3, not
|
||||
# just for library $1. Separate tests with the same $1 and different $3s
|
||||
# may have different results.
|
||||
#
|
||||
# Note that using directly AS_VAR_PUSHDEF([ac_Lib], [ac_cv_lib_$1_$3])
|
||||
# is asking for trouble, since AC_CHECK_LIB($lib, fun) would give
|
||||
# ac_cv_lib_$lib_fun, which is definitely not what was meant. Hence
|
||||
# the AS_LITERAL_IF indirection.
|
||||
#
|
||||
# FIXME: This macro is extremely suspicious. It DEFINEs unconditionally,
|
||||
# whatever the FUNCTION, in addition to not being a *S macro. Note
|
||||
# that the cache does depend upon the function we are looking for.
|
||||
#
|
||||
# It is on purpose we used `ac_check_lib_ext_save_LIBS' and not just
|
||||
# `ac_save_LIBS': there are many macros which don't want to see `LIBS'
|
||||
# changed but still want to use AC_CHECK_LIB_EXT, so they save `LIBS'.
|
||||
# And ``ac_save_LIBS' is too tempting a name, so let's leave them some
|
||||
# freedom.
|
||||
AC_DEFUN([AC_CHECK_LIB_EXT],
|
||||
[
|
||||
AH_CHECK_LIB_EXT([$1])
|
||||
ac_check_lib_ext_save_LIBS=$LIBS
|
||||
LIBS="-l$1 $$2 $7 $LIBS"
|
||||
AS_LITERAL_IF([$1],
|
||||
[AS_VAR_PUSHDEF([ac_Lib_ext], [ac_cv_lib_ext_$1])],
|
||||
[AS_VAR_PUSHDEF([ac_Lib_ext], [ac_cv_lib_ext_$1''])])dnl
|
||||
|
||||
m4_ifval([$3],
|
||||
[
|
||||
AH_CHECK_FUNC_EXT([$3])
|
||||
AS_LITERAL_IF([$1],
|
||||
[AS_VAR_PUSHDEF([ac_Lib_func], [ac_cv_lib_ext_$1_$3])],
|
||||
[AS_VAR_PUSHDEF([ac_Lib_func], [ac_cv_lib_ext_$1''_$3])])dnl
|
||||
AC_CACHE_CHECK([for $3 in -l$1], ac_Lib_func,
|
||||
[AC_TRY_LINK_FUNC($3,
|
||||
[AS_VAR_SET(ac_Lib_func, yes);
|
||||
AS_VAR_SET(ac_Lib_ext, yes)],
|
||||
[AS_VAR_SET(ac_Lib_func, no);
|
||||
AS_VAR_SET(ac_Lib_ext, no)])
|
||||
])
|
||||
AS_IF([test AS_VAR_GET(ac_Lib_func) = yes],
|
||||
[AC_DEFINE_UNQUOTED(AS_TR_CPP(HAVE_$3))])dnl
|
||||
AS_VAR_POPDEF([ac_Lib_func])dnl
|
||||
],[
|
||||
AC_CACHE_CHECK([for -l$1], ac_Lib_ext,
|
||||
[AC_TRY_LINK_FUNC([main],
|
||||
[AS_VAR_SET(ac_Lib_ext, yes)],
|
||||
[AS_VAR_SET(ac_Lib_ext, no)])
|
||||
])
|
||||
])
|
||||
LIBS=$ac_check_lib_ext_save_LIBS
|
||||
|
||||
AS_IF([test AS_VAR_GET(ac_Lib_ext) = yes],
|
||||
[m4_default([$4],
|
||||
[AC_DEFINE_UNQUOTED(AS_TR_CPP(HAVE_LIB$1))
|
||||
case "$$2" in
|
||||
*-l$1*)
|
||||
;;
|
||||
*)
|
||||
$2="-l$1 $$2"
|
||||
;;
|
||||
esac])
|
||||
[$6]
|
||||
],
|
||||
[$5])dnl
|
||||
AS_VAR_POPDEF([ac_Lib_ext])dnl
|
||||
])# AC_CHECK_LIB_EXT
|
||||
|
||||
# AH_CHECK_LIB_EXT(LIBNAME)
|
||||
# ---------------------
|
||||
m4_define([AH_CHECK_LIB_EXT],
|
||||
[AH_TEMPLATE(AS_TR_CPP(HAVE_LIB$1),
|
||||
[Define to 1 if you have the `]$1[' library (-l]$1[).])])
|
||||
|
||||
# AC_CHECK_FUNCS_EXT(FUNCTION, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
|
||||
# -----------------------------------------------------------------
|
||||
dnl check for a function in a $LIBS and $OTHER_LIBS libraries variable.
|
||||
dnl AC_CHECK_FUNC_EXT(func,OTHER_LIBS,IF-TRUE,IF-FALSE)
|
||||
AC_DEFUN([AC_CHECK_FUNC_EXT],
|
||||
[
|
||||
AH_CHECK_FUNC_EXT($1)
|
||||
ac_check_func_ext_save_LIBS=$LIBS
|
||||
LIBS="$2 $LIBS"
|
||||
AS_VAR_PUSHDEF([ac_var], [ac_cv_func_ext_$1])dnl
|
||||
AC_CACHE_CHECK([for $1], ac_var,
|
||||
[AC_LINK_IFELSE([AC_LANG_FUNC_LINK_TRY([$1])],
|
||||
[AS_VAR_SET(ac_var, yes)],
|
||||
[AS_VAR_SET(ac_var, no)])])
|
||||
LIBS=$ac_check_func_ext_save_LIBS
|
||||
AS_IF([test AS_VAR_GET(ac_var) = yes],
|
||||
[AC_DEFINE_UNQUOTED(AS_TR_CPP([HAVE_$1])) $3],
|
||||
[$4])dnl
|
||||
AS_VAR_POPDEF([ac_var])dnl
|
||||
])# AC_CHECK_FUNC
|
||||
|
||||
# AH_CHECK_FUNC_EXT(FUNCNAME)
|
||||
# ---------------------
|
||||
m4_define([AH_CHECK_FUNC_EXT],
|
||||
[AH_TEMPLATE(AS_TR_CPP(HAVE_$1),
|
||||
[Define to 1 if you have the `]$1[' function.])])
|
||||
|
||||
dnl Define an AC_DEFINE with ifndef guard.
|
||||
dnl AC_N_DEFINE(VARIABLE [, VALUE])
|
||||
define(AC_N_DEFINE,
|
||||
|
@ -462,7 +462,7 @@ AC_CHECK_HEADERS(sys/param.h ctype.h sys/wait.h sys/resource.h sys/ioctl.h sys/i
|
||||
AC_CHECK_HEADERS(sys/mman.h sys/filio.h sys/priv.h sys/shm.h string.h strings.h stdlib.h sys/socket.h)
|
||||
AC_CHECK_HEADERS(sys/mount.h sys/vfs.h sys/fs/s5param.h sys/filsys.h termios.h termio.h)
|
||||
AC_CHECK_HEADERS(sys/termio.h sys/statfs.h sys/dustat.h sys/statvfs.h stdarg.h sys/sockio.h)
|
||||
AC_CHECK_HEADERS(security/pam_modules.h security/_pam_macros.h ldap.h lber.h dlfcn.h)
|
||||
AC_CHECK_HEADERS(security/pam_modules.h security/_pam_macros.h dlfcn.h)
|
||||
AC_CHECK_HEADERS(sys/syslog.h syslog.h)
|
||||
|
||||
#
|
||||
@ -1815,7 +1815,7 @@ AC_SEARCH_LIBS(crypt, [crypt],
|
||||
## check checking for truncated salt. Wrapped by the
|
||||
## $with_pam_for_crypt variable as above --jerry
|
||||
##
|
||||
if test $with_pam_for_crypt = no; then
|
||||
if test x"$with_pam_for_crypt" != x"yes"; then
|
||||
AC_CACHE_CHECK([for a crypt that needs truncated salt],samba_cv_HAVE_TRUNCATED_SALT,[
|
||||
crypt_LIBS="$LIBS"
|
||||
LIBS="$AUTHLIBS $LIBS"
|
||||
|
@ -1,9 +1,28 @@
|
||||
/*
|
||||
header for ads (active directory) library routines
|
||||
/*
|
||||
Unix SMB/CIFS implementation.
|
||||
header for ads (active directory) library routines
|
||||
basically this is a wrapper around ldap
|
||||
|
||||
basically this is a wrapper around ldap
|
||||
Copyright (C) Andrew Tridgell 2001-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.
|
||||
*/
|
||||
|
||||
#ifndef _ADS_H
|
||||
#define _ADS_H
|
||||
|
||||
typedef struct {
|
||||
void *ld; /* the active ldap structure */
|
||||
struct in_addr ldap_ip; /* the ip of the active connection, if any */
|
||||
@ -38,9 +57,9 @@ typedef struct {
|
||||
} config;
|
||||
} ADS_STRUCT;
|
||||
|
||||
/* there are 4 possible types of errors the ads subsystem can produce */
|
||||
enum ads_error_type {ADS_ERROR_KRB5, ADS_ERROR_GSS,
|
||||
ADS_ERROR_LDAP, ADS_ERROR_SYSTEM, ADS_ERROR_NT};
|
||||
/* there are 5 possible types of errors the ads subsystem can produce */
|
||||
enum ads_error_type {ENUM_ADS_ERROR_KRB5, ENUM_ADS_ERROR_GSS,
|
||||
ENUM_ADS_ERROR_LDAP, ENUM_ADS_ERROR_SYSTEM, ENUM_ADS_ERROR_NT};
|
||||
|
||||
typedef struct {
|
||||
enum ads_error_type error_type;
|
||||
@ -48,7 +67,7 @@ typedef struct {
|
||||
int rc;
|
||||
NTSTATUS nt_status;
|
||||
} err;
|
||||
/* For error_type = ADS_ERROR_GSS minor_status describe GSS API error */
|
||||
/* For error_type = ENUM_ADS_ERROR_GSS minor_status describe GSS API error */
|
||||
/* Where rc represents major_status of GSS API error */
|
||||
int minor_status;
|
||||
} ADS_STATUS;
|
||||
@ -61,13 +80,13 @@ typedef void **ADS_MODLIST;
|
||||
|
||||
/* macros to simplify error returning */
|
||||
#define ADS_ERROR(rc) ADS_ERROR_LDAP(rc)
|
||||
#define ADS_ERROR_LDAP(rc) ads_build_error(ADS_ERROR_LDAP, rc, 0)
|
||||
#define ADS_ERROR_SYSTEM(rc) ads_build_error(ADS_ERROR_SYSTEM, rc?rc:EINVAL, 0)
|
||||
#define ADS_ERROR_KRB5(rc) ads_build_error(ADS_ERROR_KRB5, rc, 0)
|
||||
#define ADS_ERROR_GSS(rc, minor) ads_build_error(ADS_ERROR_GSS, rc, minor)
|
||||
#define ADS_ERROR_NT(rc) ads_build_nt_error(ADS_ERROR_NT,rc)
|
||||
#define ADS_ERROR_LDAP(rc) ads_build_error(ENUM_ADS_ERROR_LDAP, rc, 0)
|
||||
#define ADS_ERROR_SYSTEM(rc) ads_build_error(ENUM_ADS_ERROR_SYSTEM, rc?rc:EINVAL, 0)
|
||||
#define ADS_ERROR_KRB5(rc) ads_build_error(ENUM_ADS_ERROR_KRB5, rc, 0)
|
||||
#define ADS_ERROR_GSS(rc, minor) ads_build_error(ENUM_ADS_ERROR_GSS, rc, minor)
|
||||
#define ADS_ERROR_NT(rc) ads_build_nt_error(ENUM_ADS_ERROR_NT,rc)
|
||||
|
||||
#define ADS_ERR_OK(status) ((status.error_type == ADS_ERROR_NT) ? NT_STATUS_IS_OK(status.err.nt_status):(status.err.rc == 0))
|
||||
#define ADS_ERR_OK(status) ((status.error_type == ENUM_ADS_ERROR_NT) ? NT_STATUS_IS_OK(status.err.nt_status):(status.err.rc == 0))
|
||||
#define ADS_SUCCESS ADS_ERROR(0)
|
||||
|
||||
/* time between reconnect attempts */
|
||||
@ -205,7 +224,11 @@ typedef void **ADS_MODLIST;
|
||||
#define ADS_AUTH_NO_BIND 0x02
|
||||
#define ADS_AUTH_ANON_BIND 0x04
|
||||
#define ADS_AUTH_SIMPLE_BIND 0x08
|
||||
#define ADS_AUTH_ALLOW_NTLMSSP 0x10
|
||||
|
||||
/***************************************
|
||||
Some krb5 compat stuff
|
||||
***************************************/
|
||||
/* Kerberos environment variable names */
|
||||
#define KRB5_ENV_CCNAME "KRB5CCNAME"
|
||||
|
||||
@ -213,3 +236,36 @@ typedef void **ADS_MODLIST;
|
||||
#if defined(HAVE_ENCTYPE_ARCFOUR_HMAC_MD5)
|
||||
#define ENCTYPE_ARCFOUR_HMAC ENCTYPE_ARCFOUR_HMAC_MD5
|
||||
#endif
|
||||
|
||||
/* The older versions of heimdal that don't have this
|
||||
define don't seem to use it anyway. I'm told they
|
||||
always use a subkey */
|
||||
#ifndef HAVE_AP_OPTS_USE_SUBKEY
|
||||
#define AP_OPTS_USE_SUBKEY 0
|
||||
#endif
|
||||
#if defined(HAVE_KRB5)
|
||||
|
||||
#ifndef HAVE_KRB5_SET_REAL_TIME
|
||||
krb5_error_code krb5_set_real_time(krb5_context context, int32_t seconds, int32_t microseconds);
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_KRB5_SET_DEFAULT_TGS_KTYPES
|
||||
krb5_error_code krb5_set_default_tgs_ktypes(krb5_context ctx, const krb5_enctype *enc);
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_KRB5_AUTH_CON_SETKEY) && !defined(HAVE_KRB5_AUTH_CON_SETUSERUSERKEY)
|
||||
krb5_error_code krb5_auth_con_setuseruserkey(krb5_context context, krb5_auth_context auth_context, krb5_keyblock *keyblock);
|
||||
#endif
|
||||
|
||||
/* Samba wrapper function for krb5 functionality. */
|
||||
void setup_kaddr( krb5_address *pkaddr, struct sockaddr *paddr);
|
||||
int create_kerberos_key_from_string(krb5_context context, krb5_principal host_princ, krb5_data *password, krb5_keyblock *key, krb5_enctype enctype);
|
||||
void get_auth_data_from_tkt(DATA_BLOB *auth_data, krb5_ticket *tkt);
|
||||
krb5_const_principal get_principal_from_tkt(krb5_ticket *tkt);
|
||||
krb5_error_code krb5_locate_kdc(krb5_context ctx, const krb5_data *realm, struct sockaddr **addr_pp, int *naddrs, int get_masters);
|
||||
krb5_error_code get_kerberos_allowed_etypes(krb5_context context, krb5_enctype **enctypes);
|
||||
void free_kerberos_etypes(krb5_context context, krb5_enctype *enctypes);
|
||||
BOOL get_krb5_smb_session_key(krb5_context context, krb5_auth_context auth_context, DATA_BLOB *session_key, BOOL remote);
|
||||
#endif /* HAVE_KRB5 */
|
||||
|
||||
#endif /* _ADS_H */
|
||||
|
@ -339,10 +339,6 @@
|
||||
#include <stropts.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_POLL_H
|
||||
#include <poll.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_CAPABILITY_H
|
||||
|
||||
#if defined(BROKEN_REDHAT_7_SYSTEM_HEADERS) && !defined(_I386_STATFS_H)
|
||||
@ -721,7 +717,6 @@ extern int errno;
|
||||
#include "../tdb/tdbutil.h"
|
||||
#include "talloc.h"
|
||||
#include "nt_status.h"
|
||||
#include "ads.h"
|
||||
#include "interfaces.h"
|
||||
#include "trans2.h"
|
||||
#include "ioctl.h"
|
||||
@ -734,6 +729,7 @@ extern int errno;
|
||||
|
||||
#include "version.h"
|
||||
#include "smb.h"
|
||||
#include "ads.h"
|
||||
#include "nameserv.h"
|
||||
#include "secrets.h"
|
||||
|
||||
@ -1147,30 +1143,5 @@ time_t timegm(struct tm *tm);
|
||||
#define VXFS_QUOTA
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_KRB5)
|
||||
|
||||
#ifndef KRB5_SET_REAL_TIME
|
||||
krb5_error_code krb5_set_real_time(krb5_context context, int32_t seconds, int32_t microseconds);
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_KRB5_SET_DEFAULT_TGS_KTYPES
|
||||
krb5_error_code krb5_set_default_tgs_ktypes(krb5_context ctx, const krb5_enctype *enc);
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_KRB5_AUTH_CON_SETKEY) && !defined(HAVE_KRB5_AUTH_CON_SETUSERUSERKEY)
|
||||
krb5_error_code krb5_auth_con_setuseruserkey(krb5_context context, krb5_auth_context auth_context, krb5_keyblock *keyblock);
|
||||
#endif
|
||||
|
||||
/* Samba wrapper function for krb5 functionality. */
|
||||
void setup_kaddr( krb5_address *pkaddr, struct sockaddr *paddr);
|
||||
int create_kerberos_key_from_string(krb5_context context, krb5_principal host_princ, krb5_data *password, krb5_keyblock *key, krb5_enctype enctype);
|
||||
void get_auth_data_from_tkt(DATA_BLOB *auth_data, krb5_ticket *tkt);
|
||||
krb5_const_principal get_principal_from_tkt(krb5_ticket *tkt);
|
||||
krb5_error_code krb5_locate_kdc(krb5_context ctx, const krb5_data *realm, struct sockaddr **addr_pp, int *naddrs, int get_masters);
|
||||
krb5_error_code get_kerberos_allowed_etypes(krb5_context context, krb5_enctype **enctypes);
|
||||
void free_kerberos_etypes(krb5_context context, krb5_enctype *enctypes);
|
||||
BOOL krb5_get_smb_session_key(krb5_context context, krb5_auth_context auth_context, uint8 session_key[16]);
|
||||
#endif /* HAVE_KRB5 */
|
||||
|
||||
#endif /* _INCLUDES_H */
|
||||
|
||||
|
@ -34,7 +34,7 @@ NTSTATUS ads_name_to_sid(ADS_STRUCT *ads,
|
||||
int count;
|
||||
ADS_STATUS rc;
|
||||
void *res = NULL;
|
||||
char *exp;
|
||||
char *ldap_exp;
|
||||
uint32 t;
|
||||
NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
|
||||
char *escaped_name = escape_ldap_string_alloc(name);
|
||||
@ -45,15 +45,15 @@ NTSTATUS ads_name_to_sid(ADS_STRUCT *ads,
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (asprintf(&exp, "(|(sAMAccountName=%s)(userPrincipalName=%s@%s))",
|
||||
if (asprintf(&ldap_exp, "(|(sAMAccountName=%s)(userPrincipalName=%s@%s))",
|
||||
escaped_name, escaped_name, escaped_realm) == -1) {
|
||||
DEBUG(1,("ads_name_to_sid: asprintf failed!\n"));
|
||||
status = NT_STATUS_NO_MEMORY;
|
||||
goto done;
|
||||
}
|
||||
|
||||
rc = ads_search_retry(ads, &res, exp, attrs);
|
||||
free(exp);
|
||||
rc = ads_search_retry(ads, &res, ldap_exp, attrs);
|
||||
free(ldap_exp);
|
||||
if (!ADS_ERR_OK(rc)) {
|
||||
DEBUG(1,("name_to_sid ads_search: %s\n", ads_errstr(rc)));
|
||||
goto done;
|
||||
@ -102,7 +102,7 @@ NTSTATUS ads_sid_to_name(ADS_STRUCT *ads,
|
||||
"sAMAccountType", NULL};
|
||||
ADS_STATUS rc;
|
||||
void *msg = NULL;
|
||||
char *exp = NULL;
|
||||
char *ldap_exp = NULL;
|
||||
char *sidstr = NULL;
|
||||
uint32 atype;
|
||||
NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
|
||||
@ -113,13 +113,13 @@ NTSTATUS ads_sid_to_name(ADS_STRUCT *ads,
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (asprintf(&exp, "(objectSid=%s)", sidstr) == -1) {
|
||||
if (asprintf(&ldap_exp, "(objectSid=%s)", sidstr) == -1) {
|
||||
DEBUG(1,("ads_sid_to_name: asprintf failed!\n"));
|
||||
status = NT_STATUS_NO_MEMORY;
|
||||
goto done;
|
||||
}
|
||||
|
||||
rc = ads_search_retry(ads, &msg, exp, attrs);
|
||||
rc = ads_search_retry(ads, &msg, ldap_exp, attrs);
|
||||
if (!ADS_ERR_OK(rc)) {
|
||||
status = ads_ntstatus(rc);
|
||||
DEBUG(1,("ads_sid_to_name ads_search: %s\n", ads_errstr(rc)));
|
||||
@ -146,10 +146,89 @@ NTSTATUS ads_sid_to_name(ADS_STRUCT *ads,
|
||||
done:
|
||||
if (msg) ads_msgfree(ads, msg);
|
||||
|
||||
SAFE_FREE(exp);
|
||||
SAFE_FREE(ldap_exp);
|
||||
SAFE_FREE(sidstr);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/* convert a sid to a DN */
|
||||
|
||||
ADS_STATUS ads_sid_to_dn(ADS_STRUCT *ads,
|
||||
TALLOC_CTX *mem_ctx,
|
||||
const DOM_SID *sid,
|
||||
char **dn)
|
||||
{
|
||||
ADS_STATUS rc;
|
||||
LDAPMessage *msg = NULL;
|
||||
LDAPMessage *entry = NULL;
|
||||
char *ldap_exp;
|
||||
char *sidstr = NULL;
|
||||
int count;
|
||||
char *dn2 = NULL;
|
||||
|
||||
const char *attr[] = {
|
||||
"dn",
|
||||
NULL
|
||||
};
|
||||
|
||||
if (!(sidstr = sid_binstring(sid))) {
|
||||
DEBUG(1,("ads_sid_to_dn: sid_binstring failed!\n"));
|
||||
rc = ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
|
||||
goto done;
|
||||
}
|
||||
|
||||
if(!(ldap_exp = talloc_asprintf(mem_ctx, "(objectSid=%s)", sidstr))) {
|
||||
DEBUG(1,("ads_sid_to_dn: talloc_asprintf failed!\n"));
|
||||
rc = ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
|
||||
goto done;
|
||||
}
|
||||
|
||||
rc = ads_search_retry(ads, (void **)&msg, ldap_exp, attr);
|
||||
|
||||
if (!ADS_ERR_OK(rc)) {
|
||||
DEBUG(1,("ads_sid_to_dn ads_search: %s\n", ads_errstr(rc)));
|
||||
goto done;
|
||||
}
|
||||
|
||||
if ((count = ads_count_replies(ads, msg)) != 1) {
|
||||
fstring sid_string;
|
||||
DEBUG(1,("ads_sid_to_dn (sid=%s): Not found (count=%d)\n",
|
||||
sid_to_string(sid_string, sid), count));
|
||||
rc = ADS_ERROR_NT(NT_STATUS_UNSUCCESSFUL);
|
||||
goto done;
|
||||
}
|
||||
|
||||
entry = ads_first_entry(ads, msg);
|
||||
|
||||
dn2 = ads_get_dn(ads, entry);
|
||||
|
||||
if (!dn2) {
|
||||
rc = ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
|
||||
goto done;
|
||||
}
|
||||
|
||||
*dn = talloc_strdup(mem_ctx, dn2);
|
||||
|
||||
if (!*dn) {
|
||||
ads_memfree(ads, dn2);
|
||||
rc = ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
|
||||
goto done;
|
||||
}
|
||||
|
||||
rc = ADS_ERROR_NT(NT_STATUS_OK);
|
||||
|
||||
DEBUG(3,("ads sid_to_dn mapped %s\n", dn2));
|
||||
|
||||
SAFE_FREE(dn2);
|
||||
done:
|
||||
if (msg) ads_msgfree(ads, msg);
|
||||
if (dn2) ads_memfree(ads, dn2);
|
||||
|
||||
SAFE_FREE(sidstr);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -31,10 +31,10 @@ ADS_STATUS ads_build_error(enum ads_error_type etype,
|
||||
{
|
||||
ADS_STATUS ret;
|
||||
|
||||
if (etype == ADS_ERROR_NT) {
|
||||
DEBUG(0,("don't use ads_build_error with ADS_ERROR_NT!\n"));
|
||||
if (etype == ENUM_ADS_ERROR_NT) {
|
||||
DEBUG(0,("don't use ads_build_error with ENUM_ADS_ERROR_NT!\n"));
|
||||
ret.err.rc = -1;
|
||||
ret.error_type = ADS_ERROR_SYSTEM;
|
||||
ret.error_type = ENUM_ADS_ERROR_SYSTEM;
|
||||
ret.minor_status = 0;
|
||||
return ret;
|
||||
}
|
||||
@ -50,10 +50,10 @@ ADS_STATUS ads_build_nt_error(enum ads_error_type etype,
|
||||
{
|
||||
ADS_STATUS ret;
|
||||
|
||||
if (etype != ADS_ERROR_NT) {
|
||||
DEBUG(0,("don't use ads_build_nt_error without ADS_ERROR_NT!\n"));
|
||||
if (etype != ENUM_ADS_ERROR_NT) {
|
||||
DEBUG(0,("don't use ads_build_nt_error without ENUM_ADS_ERROR_NT!\n"));
|
||||
ret.err.rc = -1;
|
||||
ret.error_type = ADS_ERROR_SYSTEM;
|
||||
ret.error_type = ENUM_ADS_ERROR_SYSTEM;
|
||||
ret.minor_status = 0;
|
||||
return ret;
|
||||
}
|
||||
@ -69,14 +69,23 @@ ADS_STATUS ads_build_nt_error(enum ads_error_type etype,
|
||||
*/
|
||||
NTSTATUS ads_ntstatus(ADS_STATUS status)
|
||||
{
|
||||
if (status.error_type == ADS_ERROR_NT){
|
||||
if (status.error_type == ENUM_ADS_ERROR_NT){
|
||||
return status.err.nt_status;
|
||||
}
|
||||
#ifdef HAVE_LDAP
|
||||
if ((status.error_type == ADS_ERROR_LDAP)
|
||||
if ((status.error_type == ENUM_ADS_ERROR_LDAP)
|
||||
&& (status.err.rc == LDAP_NO_MEMORY)) {
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_KRB5
|
||||
if (status.error_type == ENUM_ADS_ERROR_KRB5) {
|
||||
if (status.err.rc == KRB5KDC_ERR_PREAUTH_FAILED) {
|
||||
return NT_STATUS_LOGON_FAILURE;
|
||||
} else if (status.err.rc == KRB5_KDC_UNREACH) {
|
||||
return NT_STATUS_NO_LOGON_SERVERS;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (ADS_ERR_OK(status)) return NT_STATUS_OK;
|
||||
return NT_STATUS_UNSUCCESSFUL;
|
||||
@ -87,25 +96,25 @@ NTSTATUS ads_ntstatus(ADS_STATUS status)
|
||||
*/
|
||||
const char *ads_errstr(ADS_STATUS status)
|
||||
{
|
||||
int msg_ctx;
|
||||
uint32 msg_ctx;
|
||||
static char *ret;
|
||||
|
||||
SAFE_FREE(ret);
|
||||
msg_ctx = 0;
|
||||
|
||||
switch (status.error_type) {
|
||||
case ADS_ERROR_SYSTEM:
|
||||
case ENUM_ADS_ERROR_SYSTEM:
|
||||
return strerror(status.err.rc);
|
||||
#ifdef HAVE_LDAP
|
||||
case ADS_ERROR_LDAP:
|
||||
case ENUM_ADS_ERROR_LDAP:
|
||||
return ldap_err2string(status.err.rc);
|
||||
#endif
|
||||
#ifdef HAVE_KRB5
|
||||
case ADS_ERROR_KRB5:
|
||||
case ENUM_ADS_ERROR_KRB5:
|
||||
return error_message(status.err.rc);
|
||||
#endif
|
||||
#ifdef HAVE_GSSAPI
|
||||
case ADS_ERROR_GSS:
|
||||
case ENUM_ADS_ERROR_GSS:
|
||||
{
|
||||
uint32 minor;
|
||||
|
||||
@ -122,8 +131,8 @@ const char *ads_errstr(ADS_STATUS status)
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
case ADS_ERROR_NT:
|
||||
return nt_errstr(ads_ntstatus(status));
|
||||
case ENUM_ADS_ERROR_NT:
|
||||
return get_friendly_nt_error_msg(ads_ntstatus(status));
|
||||
default:
|
||||
return "Unknown ADS error type!? (not compiled in?)";
|
||||
}
|
||||
|
@ -94,12 +94,11 @@ ADS_STRUCT *ads_init(const char *realm,
|
||||
ads->server.workgroup = workgroup ? strdup(workgroup) : NULL;
|
||||
ads->server.ldap_server = ldap_server? strdup(ldap_server) : NULL;
|
||||
|
||||
/* we need to know if this is a foreign realm to know if we can
|
||||
use lp_ads_server() */
|
||||
if (realm && *realm && strcasecmp(lp_realm(), realm) != 0) {
|
||||
/* we need to know if this is a foreign realm */
|
||||
if (realm && *realm && !strequal(lp_realm(), realm)) {
|
||||
ads->server.foreign = 1;
|
||||
}
|
||||
if (workgroup && *workgroup && strcasecmp(lp_workgroup(), workgroup) != 0) {
|
||||
if (workgroup && *workgroup && !strequal(lp_workgroup(), workgroup)) {
|
||||
ads->server.foreign = 1;
|
||||
}
|
||||
|
||||
|
@ -88,52 +88,6 @@ uint32 ads_uf2atype(uint32 uf)
|
||||
return atype;
|
||||
}
|
||||
|
||||
/*
|
||||
translated the GROUP_CTRL Flags to GroupType (groupType)
|
||||
*/
|
||||
uint32 ads_gcb2gtype(uint16 gcb)
|
||||
{
|
||||
uint32 gtype = 0x00000000;
|
||||
|
||||
if (gcb & GCB_ALIAS_GROUP) gtype |= GTYPE_SECURITY_BUILTIN_LOCAL_GROUP;
|
||||
else if(gcb & GCB_LOCAL_GROUP) gtype |= GTYPE_SECURITY_DOMAIN_LOCAL_GROUP;
|
||||
if (gcb & GCB_GLOBAL_GROUP) gtype |= GTYPE_SECURITY_GLOBAL_GROUP;
|
||||
|
||||
return gtype;
|
||||
}
|
||||
|
||||
/*
|
||||
translated the GroupType (groupType) to GROUP_CTRL Flags
|
||||
*/
|
||||
uint16 ads_gtype2gcb(uint32 gtype)
|
||||
{
|
||||
uint16 gcb = 0x0000;
|
||||
|
||||
switch(gtype) {
|
||||
case GTYPE_SECURITY_BUILTIN_LOCAL_GROUP:
|
||||
gcb = GCB_ALIAS_GROUP;
|
||||
break;
|
||||
case GTYPE_SECURITY_DOMAIN_LOCAL_GROUP:
|
||||
gcb = GCB_LOCAL_GROUP;
|
||||
break;
|
||||
case GTYPE_SECURITY_GLOBAL_GROUP:
|
||||
gcb = GCB_GLOBAL_GROUP;
|
||||
break;
|
||||
|
||||
case GTYPE_DISTRIBUTION_GLOBAL_GROUP:
|
||||
gcb = GCB_GLOBAL_GROUP;
|
||||
break;
|
||||
case GTYPE_DISTRIBUTION_DOMAIN_LOCAL_GROUP:
|
||||
gcb = GCB_LOCAL_GROUP;
|
||||
break;
|
||||
case GTYPE_DISTRIBUTION_UNIVERSAL_GROUP:
|
||||
gcb = GCB_GLOBAL_GROUP;
|
||||
break;
|
||||
}
|
||||
|
||||
return gcb;
|
||||
}
|
||||
|
||||
/*
|
||||
get the accountType from the groupType
|
||||
*/
|
||||
@ -172,6 +126,8 @@ enum SID_NAME_USE ads_atype_map(uint32 atype)
|
||||
switch (atype & 0xF0000000) {
|
||||
case ATYPE_GLOBAL_GROUP:
|
||||
return SID_NAME_DOM_GRP;
|
||||
case ATYPE_SECURITY_LOCAL_GROUP:
|
||||
return SID_NAME_ALIAS;
|
||||
case ATYPE_ACCOUNT:
|
||||
return SID_NAME_USER;
|
||||
default:
|
||||
|
@ -1,34 +1,139 @@
|
||||
#################################################
|
||||
# active directory support
|
||||
########################################################
|
||||
# Compile with LDAP support?
|
||||
|
||||
with_ads_support=yes
|
||||
AC_MSG_CHECKING([whether to use Active Directory])
|
||||
LDAP_LIBS=""
|
||||
AC_SUBST(LDAP_LIBS)
|
||||
with_ldap_support=auto
|
||||
AC_MSG_CHECKING([for LDAP support])
|
||||
|
||||
AC_ARG_WITH(ads,
|
||||
[ --with-ads Active Directory support (default yes)],
|
||||
AC_ARG_WITH(ldap,
|
||||
[ --with-ldap LDAP support (default yes)],
|
||||
[ case "$withval" in
|
||||
no)
|
||||
with_ads_support=no
|
||||
yes|no)
|
||||
with_ldap_support=$withval
|
||||
;;
|
||||
esac ])
|
||||
|
||||
if test x"$with_ads_support" = x"yes"; then
|
||||
AC_DEFINE(WITH_ADS,1,[Whether to include Active Directory support])
|
||||
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])
|
||||
SMB_MODULE_DEFAULT(STATIC,pdb_ldap)
|
||||
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)
|
||||
|
||||
FOUND_KRB5=no
|
||||
if test x"$with_ads_support" = x"yes"; then
|
||||
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
|
||||
LIBS="$LIBS `$KRB5_CONFIG --libs`"
|
||||
CFLAGS="$CFLAGS `$KRB5_CONFIG --cflags`"
|
||||
CPPFLAGS="$CPPFLAGS `$KRB5_CONFIG --cflags`"
|
||||
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
|
||||
@ -36,193 +141,303 @@ if test x"$with_ads_support" = x"yes"; then
|
||||
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)
|
||||
;;
|
||||
*)
|
||||
AC_MSG_RESULT(yes)
|
||||
LIBS="$LIBS -lkrb5"
|
||||
CFLAGS="$CFLAGS -I$withval/include"
|
||||
CPPFLAGS="$CPPFLAGS -I$withval/include"
|
||||
LDFLAGS="$LDFLAGS -L$withval/lib"
|
||||
FOUND_KRB5=yes
|
||||
;;
|
||||
esac ],
|
||||
AC_MSG_RESULT(no)
|
||||
)
|
||||
#################################################
|
||||
# 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 kerberos 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
|
||||
LIBS="$LIBS -lkrb5"
|
||||
CFLAGS="$CFLAGS -I/usr/include/heimdal"
|
||||
CPPFLAGS="$CPPFLAGS -I/usr/include/heimdal"
|
||||
LDFLAGS="$LDFLAGS -L/usr/lib/heimdal/lib"
|
||||
AC_MSG_RESULT(yes)
|
||||
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
|
||||
LIBS="$LIBS -lkrb5"
|
||||
CFLAGS="$CFLAGS -I/usr/include/heimdal"
|
||||
CPPFLAGS="$CPPFLAGS -I/usr/include/heimdal"
|
||||
AC_MSG_RESULT(yes)
|
||||
|
||||
AC_MSG_RESULT(no)
|
||||
fi
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
fi
|
||||
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
|
||||
|
||||
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
|
||||
LIBS="$LIBS -lkrb5"
|
||||
LDFLAGS="$LDFLAGS -L/usr/kerberos/lib"
|
||||
CFLAGS="$CFLAGS -I/usr/kerberos/include"
|
||||
CPPFLAGS="$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(com_err, _et_list, [LIBS="$LIBS -lcom_err"])
|
||||
AC_CHECK_LIB(k5crypto, krb5_encrypt_data, [LIBS="$LIBS -lk5crypto"])
|
||||
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(crypto, des_set_key, [LIBS="$LIBS -lcrypto"])
|
||||
AC_CHECK_LIB(asn1, copy_Authenticator, [LIBS="$LIBS -lasn1 -lroken"])
|
||||
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(gssapi, gss_display_status, [LIBS="$LIBS -lgssapi -lkrb5 -lasn1";
|
||||
AC_DEFINE(HAVE_GSSAPI,1,[Whether GSSAPI is available])])
|
||||
|
||||
AC_CHECK_LIB(krb5, krb5_set_real_time, [AC_DEFINE(HAVE_KRB5_SET_REAL_TIME,1,[Whether krb5_set_real_time is available])])
|
||||
AC_CHECK_LIB(krb5, krb5_set_default_in_tkt_etypes, [AC_DEFINE(HAVE_KRB5_SET_DEFAULT_IN_TKT_ETYPES,1,[Whether krb5_set_default_in_tkt_etypes, is available])])
|
||||
AC_CHECK_LIB(krb5, krb5_set_default_tgs_ktypes, [AC_DEFINE(HAVE_KRB5_SET_DEFAULT_TGS_KTYPES,1,[Whether krb5_set_default_tgs_ktypes is available])])
|
||||
|
||||
AC_CHECK_LIB(krb5, krb5_principal2salt, [AC_DEFINE(HAVE_KRB5_PRINCIPAL2SALT,1,[Whether krb5_principal2salt is available])])
|
||||
AC_CHECK_LIB(krb5, krb5_use_enctype, [AC_DEFINE(HAVE_KRB5_USE_ENCTYPE,1,[Whether krb5_use_enctype is available])])
|
||||
AC_CHECK_LIB(krb5, krb5_string_to_key, [AC_DEFINE(HAVE_KRB5_STRING_TO_KEY,1,[Whether krb5_string_to_key is available])])
|
||||
AC_CHECK_LIB(krb5, krb5_get_pw_salt, [AC_DEFINE(HAVE_KRB5_GET_PW_SALT,1,[Whether krb5_get_pw_salt is available])])
|
||||
AC_CHECK_LIB(krb5, krb5_string_to_key_salt, [AC_DEFINE(HAVE_KRB5_STRING_TO_KEY_SALT,1,[Whether krb5_string_to_key_salt is available])])
|
||||
AC_CHECK_LIB(krb5, krb5_auth_con_setkey, [AC_DEFINE(HAVE_KRB5_AUTH_CON_SETKEY,1,[Whether krb5_auth_con_setkey is available])])
|
||||
AC_CHECK_LIB(krb5, krb5_auth_con_setuseruserkey, [AC_DEFINE(HAVE_KRB5_AUTH_CON_SETUSERUSERKEY,1,[Whether krb5_auth_con_setuseruserkey is available])])
|
||||
AC_CHECK_LIB(krb5, krb5_locate_kdc, [AC_DEFINE(HAVE_KRB5_LOCATE_KDC,1,[Whether krb5_locate_kdc is available])])
|
||||
AC_CHECK_LIB(krb5, krb5_get_permitted_enctypes, [AC_DEFINE(HAVE_KRB5_GET_PERMITTED_ENCTYPES,1,[Whether krb5_get_permitted_enctypes is available])])
|
||||
AC_CHECK_LIB(krb5, krb5_get_default_in_tkt_etypes, [AC_DEFINE(HAVE_KRB5_GET_DEFAULT_IN_TKT_ETYPES,1,[Whether krb5_get_default_in_tkt_etypes is available])])
|
||||
AC_CHECK_LIB(krb5, krb5_free_ktypes, [AC_DEFINE(HAVE_KRB5_FREE_KTYPES,1,[Whether krb5_free_ktypes is available])])
|
||||
|
||||
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)])
|
||||
if test x"$samba_cv_HAVE_ENCTYPE_ARCFOUR_HMAC_MD5" = x"yes"; then
|
||||
AC_DEFINE(HAVE_ENCTYPE_ARCFOUR_HMAC_MD5,1,[Whether the ENCTYPE_ARCFOUR_HMAC_MD5 key type is available])
|
||||
fi
|
||||
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(krb5, krb5_mk_req_extended, [LIBS="$LIBS -lkrb5";
|
||||
AC_DEFINE(HAVE_KRB5,1,[Whether KRB5 is available])])
|
||||
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(gssapi_krb5, gss_display_status, [LIBS="$LIBS -lgssapi_krb5";
|
||||
AC_DEFINE(HAVE_GSSAPI,1,[Whether GSSAPI is available])])
|
||||
AC_CHECK_LIB_EXT(gssapi_krb5, KRB5_LIBS,gss_display_status,[],[],
|
||||
AC_DEFINE(HAVE_GSSAPI,1,[Whether GSSAPI is available]))
|
||||
|
||||
fi
|
||||
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)
|
||||
|
||||
########################################################
|
||||
# Compile with LDAP support?
|
||||
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)])
|
||||
|
||||
with_ldap_support=yes
|
||||
AC_MSG_CHECKING([whether to use LDAP])
|
||||
|
||||
AC_ARG_WITH(ldap,
|
||||
[ --with-ldap LDAP support (default yes)],
|
||||
[ case "$withval" in
|
||||
no)
|
||||
with_ldap_support=no
|
||||
;;
|
||||
esac ])
|
||||
|
||||
AC_MSG_RESULT($with_ldap_support)
|
||||
|
||||
if test x"$with_ldap_support" = x"yes"; then
|
||||
|
||||
##################################################################
|
||||
# we might need the lber lib on some systems. To avoid link errors
|
||||
# this test must be before the libldap test
|
||||
AC_CHECK_LIB(lber, ber_scanf, [LIBS="$LIBS -llber"])
|
||||
|
||||
########################################################
|
||||
# now see if we can find the ldap libs in standard paths
|
||||
if test x$have_ldap != xyes; then
|
||||
AC_CHECK_LIB(ldap, ldap_domain2hostlist, [LIBS="$LIBS -lldap";
|
||||
AC_DEFINE(HAVE_LDAP,1,[Whether ldap is available])])
|
||||
|
||||
########################################################
|
||||
# If we have LDAP, does it's rebind procedure take 2 or 3 arguments?
|
||||
# Check found in pam_ldap 145.
|
||||
AC_CHECK_FUNCS(ldap_set_rebind_proc)
|
||||
AC_CACHE_CHECK(whether ldap_set_rebind_proc takes 3 arguments, pam_ldap_cv_ldap_set_rebind_proc, [
|
||||
AC_TRY_COMPILE([
|
||||
#include <lber.h>
|
||||
#include <ldap.h>], [ldap_set_rebind_proc(0, 0, 0);], [pam_ldap_cv_ldap_set_rebind_proc=3], [pam_ldap_cv_ldap_set_rebind_proc=2]) ])
|
||||
AC_DEFINE_UNQUOTED(LDAP_SET_REBIND_PROC_ARGS, $pam_ldap_cv_ldap_set_rebind_proc, [Number of arguments to ldap_set_rebind_proc])
|
||||
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
|
||||
|
@ -4,6 +4,8 @@
|
||||
Copyright (C) Andrew Tridgell 2001
|
||||
Copyright (C) Remus Koos 2001
|
||||
Copyright (C) Luke Howard 2003
|
||||
Copyright (C) Guenther Deschner 2003
|
||||
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
|
||||
@ -24,38 +26,181 @@
|
||||
|
||||
#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
|
||||
*/
|
||||
NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket,
|
||||
NTSTATUS ads_verify_ticket(const char *realm, const DATA_BLOB *ticket,
|
||||
char **principal, DATA_BLOB *auth_data,
|
||||
DATA_BLOB *ap_rep,
|
||||
uint8 session_key[16])
|
||||
DATA_BLOB *session_key)
|
||||
{
|
||||
krb5_context context;
|
||||
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;
|
||||
int ret, i;
|
||||
krb5_keyblock * key;
|
||||
krb5_keyblock *key = NULL;
|
||||
|
||||
krb5_principal host_princ;
|
||||
char *host_princ_s;
|
||||
char *host_princ_s = NULL;
|
||||
BOOL free_host_princ = False;
|
||||
|
||||
fstring myname;
|
||||
char *password_s;
|
||||
char *password_s = NULL;
|
||||
krb5_data password;
|
||||
krb5_enctype *enctypes = NULL;
|
||||
#if 0
|
||||
krb5_address local_addr;
|
||||
krb5_address remote_addr;
|
||||
#endif
|
||||
BOOL auth_ok = False;
|
||||
|
||||
ZERO_STRUCT(packet);
|
||||
ZERO_STRUCT(password);
|
||||
ZERO_STRUCTP(auth_data);
|
||||
ZERO_STRUCTP(ap_rep);
|
||||
|
||||
if (!secrets_init()) {
|
||||
DEBUG(1,("secrets_init failed\n"));
|
||||
DEBUG(1,("ads_verify_ticket: secrets_init failed\n"));
|
||||
return NT_STATUS_LOGON_FAILURE;
|
||||
}
|
||||
|
||||
password_s = secrets_fetch_machine_password();
|
||||
password_s = secrets_fetch_machine_password(lp_workgroup(), NULL, NULL);
|
||||
if (!password_s) {
|
||||
DEBUG(1,("failed to fetch machine password\n"));
|
||||
DEBUG(1,("ads_verify_ticket: failed to fetch machine password\n"));
|
||||
return NT_STATUS_LOGON_FAILURE;
|
||||
}
|
||||
|
||||
@ -64,83 +209,142 @@ NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket,
|
||||
|
||||
ret = krb5_init_context(&context);
|
||||
if (ret) {
|
||||
DEBUG(1,("krb5_init_context failed (%s)\n", error_message(ret)));
|
||||
DEBUG(1,("ads_verify_ticket: krb5_init_context failed (%s)\n", error_message(ret)));
|
||||
return NT_STATUS_LOGON_FAILURE;
|
||||
}
|
||||
|
||||
ret = krb5_set_default_realm(context, ads->auth.realm);
|
||||
ret = krb5_set_default_realm(context, realm);
|
||||
if (ret) {
|
||||
DEBUG(1,("krb5_set_default_realm failed (%s)\n", error_message(ret)));
|
||||
return NT_STATUS_LOGON_FAILURE;
|
||||
DEBUG(1,("ads_verify_ticket: krb5_set_default_realm failed (%s)\n", error_message(ret)));
|
||||
sret = NT_STATUS_LOGON_FAILURE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* this whole process is far more complex than I would
|
||||
/* This whole process is far more complex than I would
|
||||
like. We have to go through all this to allow us to store
|
||||
the secret internally, instead of using /etc/krb5.keytab */
|
||||
|
||||
ret = krb5_auth_con_init(context, &auth_context);
|
||||
if (ret) {
|
||||
DEBUG(1,("krb5_auth_con_init failed (%s)\n", error_message(ret)));
|
||||
return NT_STATUS_LOGON_FAILURE;
|
||||
DEBUG(1,("ads_verify_ticket: krb5_auth_con_init failed (%s)\n", error_message(ret)));
|
||||
sret = NT_STATUS_LOGON_FAILURE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
fstrcpy(myname, lp_netbios_name());
|
||||
strlower(myname);
|
||||
fstrcpy(myname, global_myname());
|
||||
strlower_m(myname);
|
||||
asprintf(&host_princ_s, "HOST/%s@%s", myname, lp_realm());
|
||||
ret = krb5_parse_name(context, host_princ_s, &host_princ);
|
||||
if (ret) {
|
||||
DEBUG(1,("krb5_parse_name(%s) failed (%s)\n", host_princ_s, error_message(ret)));
|
||||
return NT_STATUS_LOGON_FAILURE;
|
||||
DEBUG(1,("ads_verify_ticket: krb5_parse_name(%s) failed (%s)\n",
|
||||
host_princ_s, error_message(ret)));
|
||||
sret = NT_STATUS_LOGON_FAILURE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!(key = (krb5_keyblock *)malloc(sizeof(*key)))) {
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
free_host_princ = True;
|
||||
|
||||
/*
|
||||
* JRA. We must set the rcache here. This will prevent replay attacks.
|
||||
*/
|
||||
|
||||
ret = krb5_get_server_rcache(context, krb5_princ_component(context, host_princ, 0), &rcache);
|
||||
if (ret) {
|
||||
DEBUG(1,("ads_verify_ticket: krb5_get_server_rcache failed (%s)\n", error_message(ret)));
|
||||
sret = NT_STATUS_LOGON_FAILURE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = krb5_auth_con_setrcache(context, auth_context, rcache);
|
||||
if (ret) {
|
||||
DEBUG(1,("ads_verify_ticket: krb5_auth_con_setrcache failed (%s)\n", error_message(ret)));
|
||||
sret = NT_STATUS_LOGON_FAILURE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* CIFS doesn't use addresses in tickets. This would breat NAT. JRA */
|
||||
|
||||
if ((ret = get_kerberos_allowed_etypes(context, &enctypes))) {
|
||||
DEBUG(1,("ads_verify_ticket: krb5_get_permitted_enctypes failed (%s)\n",
|
||||
error_message(ret)));
|
||||
sret = NT_STATUS_LOGON_FAILURE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Lock a mutex surrounding the replay as there is no locking in the MIT krb5
|
||||
* code surrounding the replay cache... */
|
||||
|
||||
if (!grab_server_mutex("replay cache mutex")) {
|
||||
DEBUG(1,("ads_verify_ticket: unable to protect replay cache with mutex.\n"));
|
||||
sret = NT_STATUS_LOGON_FAILURE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
if ((ret = get_kerberos_allowed_etypes(context, &enctypes))) {
|
||||
DEBUG(1,("krb5_get_permitted_enctypes failed (%s)\n",
|
||||
error_message(ret)));
|
||||
return NT_STATUS_LOGON_FAILURE;
|
||||
}
|
||||
|
||||
/* we need to setup a auth context with each possible encoding type in turn */
|
||||
/* 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)))) {
|
||||
sret = NT_STATUS_NO_MEMORY;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (create_kerberos_key_from_string(context, host_princ, &password, key, enctypes[i])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
krb5_auth_con_setuseruserkey(context, auth_context, key);
|
||||
|
||||
krb5_free_keyblock(context, key);
|
||||
|
||||
packet.length = ticket->length;
|
||||
packet.data = (krb5_pointer)ticket->data;
|
||||
|
||||
if (!(ret = krb5_rd_req(context, &auth_context, &packet,
|
||||
NULL, keytab, NULL, &tkt))) {
|
||||
free_kerberos_etypes(context, enctypes);
|
||||
#ifdef HAVE_MEMORY_KEYTAB
|
||||
host_princ,
|
||||
#else
|
||||
NULL,
|
||||
#endif
|
||||
keytab, NULL, &tkt))) {
|
||||
DEBUG(10,("ads_verify_ticket: enc type [%u] decrypted message !\n",
|
||||
(unsigned int)enctypes[i] ));
|
||||
auth_ok = True;
|
||||
break;
|
||||
}
|
||||
|
||||
DEBUG((ret != KRB5_BAD_ENCTYPE) ? 3 : 10,
|
||||
("ads_verify_ticket: enc type [%u] failed to decrypt with error %s\n",
|
||||
(unsigned int)enctypes[i], error_message(ret)));
|
||||
}
|
||||
|
||||
release_server_mutex();
|
||||
|
||||
if (!auth_ok) {
|
||||
DEBUG(3,("krb5_rd_req with auth failed (%s)\n",
|
||||
DEBUG(3,("ads_verify_ticket: krb5_rd_req with auth failed (%s)\n",
|
||||
error_message(ret)));
|
||||
return NT_STATUS_LOGON_FAILURE;
|
||||
sret = NT_STATUS_LOGON_FAILURE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = krb5_mk_rep(context, auth_context, &packet);
|
||||
if (ret) {
|
||||
DEBUG(3,("Failed to generate mutual authentication reply (%s)\n",
|
||||
DEBUG(3,("ads_verify_ticket: Failed to generate mutual authentication reply (%s)\n",
|
||||
error_message(ret)));
|
||||
krb5_auth_con_free(context, auth_context);
|
||||
return NT_STATUS_LOGON_FAILURE;
|
||||
sret = NT_STATUS_LOGON_FAILURE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
*ap_rep = data_blob(packet.data, packet.length);
|
||||
free(packet.data);
|
||||
|
||||
krb5_get_smb_session_key(context, auth_context, session_key);
|
||||
DEBUG(0,("SMB session key (from ticket) follows:\n"));
|
||||
dump_data(0, session_key, 16);
|
||||
get_krb5_smb_session_key(context, auth_context, session_key, True);
|
||||
dump_data_pw("SMB session key (from ticket)\n", session_key->data, session_key->length);
|
||||
|
||||
#if 0
|
||||
file_save("/tmp/ticket.dat", ticket->data, ticket->length);
|
||||
@ -148,26 +352,60 @@ NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, 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) {
|
||||
file_save("/tmp/authdata.dat",
|
||||
tkt->enc_part2->authorization_data[0]->contents,
|
||||
tkt->enc_part2->authorization_data[0]->length);
|
||||
}
|
||||
#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,("krb5_unparse_name failed (%s)\n",
|
||||
DEBUG(3,("ads_verify_ticket: krb5_unparse_name failed (%s)\n",
|
||||
error_message(ret)));
|
||||
data_blob_free(auth_data);
|
||||
data_blob_free(ap_rep);
|
||||
krb5_auth_con_free(context, auth_context);
|
||||
return NT_STATUS_LOGON_FAILURE;
|
||||
sret = NT_STATUS_LOGON_FAILURE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
krb5_auth_con_free(context, auth_context);
|
||||
sret = NT_STATUS_OK;
|
||||
|
||||
return NT_STATUS_OK;
|
||||
out:
|
||||
|
||||
if (!NT_STATUS_IS_OK(sret))
|
||||
data_blob_free(auth_data);
|
||||
|
||||
if (!NT_STATUS_IS_OK(sret))
|
||||
data_blob_free(ap_rep);
|
||||
|
||||
if (free_host_princ)
|
||||
krb5_free_principal(context, host_princ);
|
||||
|
||||
if (tkt != NULL)
|
||||
krb5_free_ticket(context, tkt);
|
||||
free_kerberos_etypes(context, enctypes);
|
||||
SAFE_FREE(password_s);
|
||||
SAFE_FREE(host_princ_s);
|
||||
|
||||
if (auth_context)
|
||||
krb5_auth_con_free(context, auth_context);
|
||||
|
||||
if (context)
|
||||
krb5_free_context(context);
|
||||
|
||||
return sret;
|
||||
}
|
||||
|
||||
#endif /* HAVE_KRB5 */
|
||||
|
@ -143,7 +143,7 @@ static krb5_error_code build_kpasswd_request(uint16 pversion,
|
||||
else
|
||||
return EINVAL;
|
||||
|
||||
encoded_setpw.data = setpw.data;
|
||||
encoded_setpw.data = (char *)setpw.data;
|
||||
encoded_setpw.length = setpw.length;
|
||||
|
||||
ret = krb5_mk_priv(context, auth_context,
|
||||
@ -178,47 +178,39 @@ static krb5_error_code build_kpasswd_request(uint16 pversion,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static krb5_error_code krb5_setpw_result_code_string(krb5_context context,
|
||||
int result_code,
|
||||
char **code_string)
|
||||
{
|
||||
switch (result_code) {
|
||||
case KRB5_KPASSWD_MALFORMED:
|
||||
*code_string = "Malformed request error";
|
||||
break;
|
||||
case KRB5_KPASSWD_HARDERROR:
|
||||
*code_string = "Server error";
|
||||
break;
|
||||
case KRB5_KPASSWD_AUTHERROR:
|
||||
*code_string = "Authentication error";
|
||||
break;
|
||||
case KRB5_KPASSWD_SOFTERROR:
|
||||
*code_string = "Password change rejected";
|
||||
break;
|
||||
case KRB5_KPASSWD_ACCESSDENIED:
|
||||
*code_string = "Client does not have proper authorization";
|
||||
break;
|
||||
case KRB5_KPASSWD_BAD_VERSION:
|
||||
*code_string = "Protocol version not supported";
|
||||
break;
|
||||
case KRB5_KPASSWD_INITIAL_FLAG_NEEDED:
|
||||
*code_string = "Authorization ticket must have initial flag set";
|
||||
break;
|
||||
case KRB5_KPASSWD_POLICY_REJECT:
|
||||
*code_string = "Password rejected due to policy requirements";
|
||||
break;
|
||||
case KRB5_KPASSWD_BAD_PRINCIPAL:
|
||||
*code_string = "Target principal does not exist";
|
||||
break;
|
||||
case KRB5_KPASSWD_ETYPE_NOSUPP:
|
||||
*code_string = "Unsupported encryption type";
|
||||
break;
|
||||
default:
|
||||
*code_string = "Password change failed";
|
||||
break;
|
||||
}
|
||||
static const struct kpasswd_errors {
|
||||
int result_code;
|
||||
const char *error_string;
|
||||
} kpasswd_errors[] = {
|
||||
{KRB5_KPASSWD_MALFORMED, "Malformed request error"},
|
||||
{KRB5_KPASSWD_HARDERROR, "Server error"},
|
||||
{KRB5_KPASSWD_AUTHERROR, "Authentication error"},
|
||||
{KRB5_KPASSWD_SOFTERROR, "Password change rejected"},
|
||||
{KRB5_KPASSWD_ACCESSDENIED, "Client does not have proper authorization"},
|
||||
{KRB5_KPASSWD_BAD_VERSION, "Protocol version not supported"},
|
||||
{KRB5_KPASSWD_INITIAL_FLAG_NEEDED, "Authorization ticket must have initial flag set"},
|
||||
{KRB5_KPASSWD_POLICY_REJECT, "Password rejected due to policy requirements"},
|
||||
{KRB5_KPASSWD_BAD_PRINCIPAL, "Target principal does not exist"},
|
||||
{KRB5_KPASSWD_ETYPE_NOSUPP, "Unsupported encryption type"},
|
||||
{0, NULL}
|
||||
};
|
||||
|
||||
return(0);
|
||||
static krb5_error_code setpw_result_code_string(krb5_context context,
|
||||
int result_code,
|
||||
const char **code_string)
|
||||
{
|
||||
unsigned int idx = 0;
|
||||
|
||||
while (kpasswd_errors[idx].error_string != NULL) {
|
||||
if (kpasswd_errors[idx].result_code ==
|
||||
result_code) {
|
||||
*code_string = kpasswd_errors[idx].error_string;
|
||||
return 0;
|
||||
}
|
||||
idx++;
|
||||
}
|
||||
*code_string = "Password change failed";
|
||||
return (0);
|
||||
}
|
||||
|
||||
static krb5_error_code parse_setpw_reply(krb5_context context,
|
||||
@ -318,8 +310,8 @@ static krb5_error_code parse_setpw_reply(krb5_context context,
|
||||
if(res_code == KRB5_KPASSWD_SUCCESS)
|
||||
return 0;
|
||||
else {
|
||||
char *errstr;
|
||||
krb5_setpw_result_code_string(context, res_code, &errstr);
|
||||
const char *errstr;
|
||||
setpw_result_code_string(context, res_code, &errstr);
|
||||
DEBUG(1, ("Error changing password: %s\n", errstr));
|
||||
|
||||
switch(res_code) {
|
||||
@ -465,8 +457,8 @@ static ADS_STATUS do_krb5_kpasswd_request(krb5_context context,
|
||||
return ADS_SUCCESS;
|
||||
}
|
||||
|
||||
ADS_STATUS krb5_set_password(const char *kdc_host, const char *princ, const char *newpw,
|
||||
int time_offset)
|
||||
ADS_STATUS ads_krb5_set_password(const char *kdc_host, const char *princ,
|
||||
const char *newpw, int time_offset)
|
||||
{
|
||||
|
||||
ADS_STATUS aret;
|
||||
@ -546,7 +538,6 @@ ADS_STATUS krb5_set_password(const char *kdc_host, const char *princ, const char
|
||||
|
||||
krb5_free_creds(context, credsp);
|
||||
krb5_free_principal(context, creds.client);
|
||||
krb5_free_principal(context, creds.server);
|
||||
krb5_free_principal(context, principal);
|
||||
krb5_free_context(context);
|
||||
|
||||
@ -579,11 +570,11 @@ kerb_prompter(krb5_context ctx, void *data,
|
||||
return 0;
|
||||
}
|
||||
|
||||
ADS_STATUS krb5_chg_password(const char *kdc_host,
|
||||
const char *principal,
|
||||
const char *oldpw,
|
||||
const char *newpw,
|
||||
int time_offset)
|
||||
static ADS_STATUS ads_krb5_chg_password(const char *kdc_host,
|
||||
const char *principal,
|
||||
const char *oldpw,
|
||||
const char *newpw,
|
||||
int time_offset)
|
||||
{
|
||||
ADS_STATUS aret;
|
||||
krb5_error_code ret;
|
||||
@ -657,11 +648,11 @@ ADS_STATUS kerberos_set_password(const char *kpasswd_server,
|
||||
}
|
||||
|
||||
if (!strcmp(auth_principal, target_principal))
|
||||
return krb5_chg_password(kpasswd_server, target_principal,
|
||||
auth_password, new_password, time_offset);
|
||||
return ads_krb5_chg_password(kpasswd_server, target_principal,
|
||||
auth_password, new_password, time_offset);
|
||||
else
|
||||
return krb5_set_password(kpasswd_server, target_principal,
|
||||
new_password, time_offset);
|
||||
return ads_krb5_set_password(kpasswd_server, target_principal,
|
||||
new_password, time_offset);
|
||||
}
|
||||
|
||||
|
||||
@ -673,24 +664,22 @@ ADS_STATUS kerberos_set_password(const char *kpasswd_server,
|
||||
* @return status of password change
|
||||
**/
|
||||
ADS_STATUS ads_set_machine_password(ADS_STRUCT *ads,
|
||||
const char *hostname,
|
||||
const char *machine_account,
|
||||
const char *password)
|
||||
{
|
||||
ADS_STATUS status;
|
||||
char *host = strdup(hostname);
|
||||
char *principal;
|
||||
|
||||
strlower(host);
|
||||
char *principal = NULL;
|
||||
|
||||
/*
|
||||
we need to use the '$' form of the name here, as otherwise the
|
||||
server might end up setting the password for a user instead
|
||||
we need to use the '$' form of the name here (the machine account name),
|
||||
as otherwise the server might end up setting the password for a user
|
||||
instead
|
||||
*/
|
||||
asprintf(&principal, "%s$@%s", host, ads->auth.realm);
|
||||
asprintf(&principal, "%s@%s", machine_account, ads->config.realm);
|
||||
|
||||
status = krb5_set_password(ads->auth.kdc_server, principal, password, ads->auth.time_offset);
|
||||
status = ads_krb5_set_password(ads->auth.kdc_server, principal,
|
||||
password, ads->auth.time_offset);
|
||||
|
||||
free(host);
|
||||
free(principal);
|
||||
|
||||
return status;
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,7 +1,7 @@
|
||||
/*
|
||||
Unix SMB/CIFS implementation.
|
||||
ads (active directory) printer utility library
|
||||
Copyright (C) Jim McDonough 2002
|
||||
Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2002
|
||||
|
||||
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
|
||||
@ -31,7 +31,7 @@ ADS_STATUS ads_find_printer_on_server(ADS_STRUCT *ads, void **res,
|
||||
const char *printer, const char *servername)
|
||||
{
|
||||
ADS_STATUS status;
|
||||
char *srv_dn, **srv_cn, *exp;
|
||||
char *srv_dn, **srv_cn, *s;
|
||||
const char *attrs[] = {"*", "nTSecurityDescriptor", NULL};
|
||||
|
||||
status = ads_find_machine_acct(ads, res, servername);
|
||||
@ -44,15 +44,29 @@ ADS_STATUS ads_find_printer_on_server(ADS_STRUCT *ads, void **res,
|
||||
srv_cn = ldap_explode_dn(srv_dn, 1);
|
||||
ads_msgfree(ads, *res);
|
||||
|
||||
asprintf(&exp, "(cn=%s-%s)", srv_cn[0], printer);
|
||||
status = ads_search(ads, res, exp, attrs);
|
||||
asprintf(&s, "(cn=%s-%s)", srv_cn[0], printer);
|
||||
status = ads_search(ads, res, s, attrs);
|
||||
|
||||
ldap_memfree(srv_dn);
|
||||
ldap_value_free(srv_cn);
|
||||
free(exp);
|
||||
free(s);
|
||||
return status;
|
||||
}
|
||||
|
||||
ADS_STATUS ads_find_printers(ADS_STRUCT *ads, void **res)
|
||||
{
|
||||
char *ldap_expr;
|
||||
const char *attrs[] = { "objectClass", "printerName", "location", "driverName",
|
||||
"serverName", "description", NULL };
|
||||
|
||||
/* For the moment only display all printers */
|
||||
|
||||
ldap_expr = "(&(!(showInAdvancedViewOnly=TRUE))(uncName=*)"
|
||||
"(objectCategory=printQueue))";
|
||||
|
||||
return ads_search(ads, res, ldap_expr, attrs);
|
||||
}
|
||||
|
||||
/*
|
||||
modify a printer entry in the directory
|
||||
*/
|
||||
@ -338,4 +352,3 @@ BOOL get_local_printer_publishing_data(TALLOC_CTX *mem_ctx,
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
Unix SMB/CIFS implementation.
|
||||
ads (active directory) utility library
|
||||
Copyright (C) Jim McDonough 2002
|
||||
Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2002
|
||||
|
||||
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
|
||||
@ -28,16 +28,16 @@
|
||||
ADS_STATUS ads_find_user_acct(ADS_STRUCT *ads, void **res, const char *user)
|
||||
{
|
||||
ADS_STATUS status;
|
||||
char *exp;
|
||||
char *ldap_exp;
|
||||
const char *attrs[] = {"*", NULL};
|
||||
char *escaped_user = escape_ldap_string_alloc(user);
|
||||
if (!escaped_user) {
|
||||
return ADS_ERROR(LDAP_NO_MEMORY);
|
||||
}
|
||||
|
||||
asprintf(&exp, "(samAccountName=%s)", escaped_user);
|
||||
status = ads_search(ads, res, exp, attrs);
|
||||
SAFE_FREE(exp);
|
||||
asprintf(&ldap_exp, "(samAccountName=%s)", escaped_user);
|
||||
status = ads_search(ads, res, ldap_exp, attrs);
|
||||
SAFE_FREE(ldap_exp);
|
||||
SAFE_FREE(escaped_user);
|
||||
return status;
|
||||
}
|
||||
|
@ -28,13 +28,15 @@
|
||||
this is supposed to catch dropped connections and auto-reconnect
|
||||
*/
|
||||
ADS_STATUS ads_do_search_retry(ADS_STRUCT *ads, const char *bind_path, int scope,
|
||||
const char *exp,
|
||||
const char *expr,
|
||||
const char **attrs, void **res)
|
||||
{
|
||||
ADS_STATUS status;
|
||||
int count = 3;
|
||||
char *bp;
|
||||
|
||||
*res = NULL;
|
||||
|
||||
if (!ads->ld &&
|
||||
time(NULL) - ads->last_attempt < ADS_RECONNECT_TIME) {
|
||||
return ADS_ERROR(LDAP_SERVER_DOWN);
|
||||
@ -42,48 +44,58 @@ ADS_STATUS ads_do_search_retry(ADS_STRUCT *ads, const char *bind_path, int scope
|
||||
|
||||
bp = strdup(bind_path);
|
||||
|
||||
if (!bp)
|
||||
if (!bp) {
|
||||
return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
|
||||
}
|
||||
|
||||
while (count--) {
|
||||
status = ads_do_search_all(ads, bp, scope, exp, attrs, res);
|
||||
*res = NULL;
|
||||
status = ads_do_search_all(ads, bp, scope, expr, attrs, res);
|
||||
if (ADS_ERR_OK(status)) {
|
||||
DEBUG(5,("Search for %s gave %d replies\n",
|
||||
exp, ads_count_replies(ads, *res)));
|
||||
free(bp);
|
||||
expr, ads_count_replies(ads, *res)));
|
||||
SAFE_FREE(bp);
|
||||
return status;
|
||||
}
|
||||
|
||||
if (*res) ads_msgfree(ads, *res);
|
||||
if (*res)
|
||||
ads_msgfree(ads, *res);
|
||||
*res = NULL;
|
||||
|
||||
DEBUG(3,("Reopening ads connection to realm '%s' after error %s\n",
|
||||
ads->config.realm, ads_errstr(status)));
|
||||
|
||||
if (ads->ld) {
|
||||
ldap_unbind(ads->ld);
|
||||
}
|
||||
|
||||
ads->ld = NULL;
|
||||
status = ads_connect(ads);
|
||||
|
||||
if (!ADS_ERR_OK(status)) {
|
||||
DEBUG(1,("ads_search_retry: failed to reconnect (%s)\n",
|
||||
ads_errstr(status)));
|
||||
ads_destroy(&ads);
|
||||
free(bp);
|
||||
SAFE_FREE(bp);
|
||||
return status;
|
||||
}
|
||||
}
|
||||
free(bp);
|
||||
SAFE_FREE(bp);
|
||||
|
||||
if (!ADS_ERR_OK(status))
|
||||
DEBUG(1,("ads reopen failed after error %s\n",
|
||||
ads_errstr(status)));
|
||||
|
||||
DEBUG(1,("ads reopen failed after error %s\n", ads_errstr(status)));
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
ADS_STATUS ads_search_retry(ADS_STRUCT *ads, void **res,
|
||||
const char *exp,
|
||||
const char *expr,
|
||||
const char **attrs)
|
||||
{
|
||||
return ads_do_search_retry(ads, ads->config.bind_path, LDAP_SCOPE_SUBTREE,
|
||||
exp, attrs, res);
|
||||
expr, attrs, res);
|
||||
}
|
||||
|
||||
ADS_STATUS ads_search_retry_dn(ADS_STRUCT *ads, void **res,
|
||||
|
@ -60,7 +60,7 @@ static ADS_STATUS ads_sasl_spnego_ntlmssp_bind(ADS_STRUCT *ads)
|
||||
msg1 = gen_negTokenTarg(mechs, blob);
|
||||
data_blob_free(&blob);
|
||||
|
||||
cred.bv_val = msg1.data;
|
||||
cred.bv_val = (char *)msg1.data;
|
||||
cred.bv_len = msg1.length;
|
||||
|
||||
rc = ldap_sasl_bind_s(ads->ld, NULL, "GSS-SPNEGO", &cred, NULL, NULL, &scred);
|
||||
@ -96,7 +96,7 @@ static ADS_STATUS ads_sasl_spnego_ntlmssp_bind(ADS_STRUCT *ads)
|
||||
nthash, 24,
|
||||
lp_workgroup(),
|
||||
ads->auth.user_name,
|
||||
lp_netbios_name(),
|
||||
global_myname(),
|
||||
sess_key, 16,
|
||||
neg_flags);
|
||||
|
||||
@ -106,7 +106,7 @@ static ADS_STATUS ads_sasl_spnego_ntlmssp_bind(ADS_STRUCT *ads)
|
||||
data_blob_free(&blob);
|
||||
|
||||
/* now send the auth packet and we should be done */
|
||||
cred.bv_val = auth.data;
|
||||
cred.bv_val = (char *)auth.data;
|
||||
cred.bv_len = auth.length;
|
||||
|
||||
rc = ldap_sasl_bind_s(ads->ld, NULL, "GSS-SPNEGO", &cred, NULL, NULL, &scred);
|
||||
@ -124,21 +124,23 @@ static ADS_STATUS ads_sasl_spnego_krb5_bind(ADS_STRUCT *ads, const char *princip
|
||||
{
|
||||
DATA_BLOB blob;
|
||||
struct berval cred, *scred;
|
||||
DATA_BLOB session_key;
|
||||
int rc;
|
||||
|
||||
blob = spnego_gen_negTokenTarg(principal, ads->auth.time_offset);
|
||||
rc = spnego_gen_negTokenTarg(principal, ads->auth.time_offset, &blob, &session_key);
|
||||
|
||||
if (!blob.data) {
|
||||
return ADS_ERROR(LDAP_OPERATIONS_ERROR);
|
||||
if (rc) {
|
||||
return ADS_ERROR_KRB5(rc);
|
||||
}
|
||||
|
||||
/* now send the auth packet and we should be done */
|
||||
cred.bv_val = blob.data;
|
||||
cred.bv_val = (char *)blob.data;
|
||||
cred.bv_len = blob.length;
|
||||
|
||||
rc = ldap_sasl_bind_s(ads->ld, NULL, "GSS-SPNEGO", &cred, NULL, NULL, &scred);
|
||||
|
||||
data_blob_free(&blob);
|
||||
data_blob_free(&session_key);
|
||||
|
||||
return ADS_ERROR(rc);
|
||||
}
|
||||
@ -165,6 +167,8 @@ static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads)
|
||||
|
||||
blob = data_blob(scred->bv_val, scred->bv_len);
|
||||
|
||||
ber_bvfree(scred);
|
||||
|
||||
#if 0
|
||||
file_save("sasl_spnego.dat", blob.data, blob.length);
|
||||
#endif
|
||||
@ -195,11 +199,18 @@ static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads)
|
||||
status = ads_sasl_spnego_krb5_bind(ads, principal);
|
||||
if (ADS_ERR_OK(status))
|
||||
return status;
|
||||
if (ads_kinit_password(ads) == 0) {
|
||||
|
||||
status = ADS_ERROR_KRB5(ads_kinit_password(ads));
|
||||
|
||||
if (ADS_ERR_OK(status)) {
|
||||
status = ads_sasl_spnego_krb5_bind(ads, principal);
|
||||
}
|
||||
if (ADS_ERR_OK(status))
|
||||
|
||||
/* only fallback to NTLMSSP if allowed */
|
||||
if (ADS_ERR_OK(status) ||
|
||||
!(ads->auth.flags & ADS_AUTH_ALLOW_NTLMSSP)) {
|
||||
return status;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -223,13 +234,13 @@ failed:
|
||||
*/
|
||||
static ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads)
|
||||
{
|
||||
int minor_status;
|
||||
uint32 minor_status;
|
||||
gss_name_t serv_name;
|
||||
gss_buffer_desc input_name;
|
||||
gss_ctx_id_t context_handle;
|
||||
gss_OID mech_type = GSS_C_NULL_OID;
|
||||
gss_buffer_desc output_token, input_token;
|
||||
OM_uint32 ret_flags, conf_state;
|
||||
uint32 ret_flags, conf_state;
|
||||
struct berval cred;
|
||||
struct berval *scred;
|
||||
int i=0;
|
||||
@ -324,7 +335,7 @@ static ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads)
|
||||
gss_release_name(&minor_status, &serv_name);
|
||||
|
||||
gss_rc = gss_unwrap(&minor_status,context_handle,&input_token,&output_token,
|
||||
&conf_state,NULL);
|
||||
(int *)&conf_state,NULL);
|
||||
if (gss_rc) {
|
||||
status = ADS_ERROR_GSS(gss_rc, minor_status);
|
||||
goto failed;
|
||||
@ -349,13 +360,13 @@ static ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads)
|
||||
*p++ = max_msg_size>>16;
|
||||
*p++ = max_msg_size>>8;
|
||||
*p++ = max_msg_size;
|
||||
snprintf(p, strlen(ads->config.bind_path)+4, "dn:%s", ads->config.bind_path);
|
||||
p += strlen(p);
|
||||
snprintf((char *)p, strlen(ads->config.bind_path)+4, "dn:%s", ads->config.bind_path);
|
||||
p += strlen((const char *)p);
|
||||
|
||||
output_token.length = PTR_DIFF(p, output_token.value);
|
||||
|
||||
gss_rc = gss_wrap(&minor_status, context_handle,0,GSS_C_QOP_DEFAULT,
|
||||
&output_token, &conf_state,
|
||||
&output_token, (int *)&conf_state,
|
||||
&input_token);
|
||||
if (gss_rc) {
|
||||
status = ADS_ERROR_GSS(gss_rc, minor_status);
|
||||
|
@ -24,35 +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;
|
||||
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()) == NULL) {
|
||||
DEBUG(1,("Failed to retrieve password for principal %s\n", host_principal));
|
||||
return ADS_ERROR_SYSTEM(ENOENT);
|
||||
}
|
||||
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);
|
||||
tmp_password = generate_random_str(DEFAULT_TRUST_ACCOUNT_PASSWORD_LENGTH);
|
||||
new_password = strdup(tmp_password);
|
||||
|
||||
ret = kerberos_set_password(ads->auth.kdc_server, service_principal, password, service_principal, new_password, ads->auth.time_offset);
|
||||
asprintf(&service_principal, "HOST/%s", host_principal);
|
||||
|
||||
if (!ADS_ERR_OK(ret)) goto failed;
|
||||
if (!service_principal) {
|
||||
DEBUG(1,("asprintf() failed principal %s\n", host_principal));
|
||||
return ADS_ERROR_SYSTEM(ENOMEM);
|
||||
}
|
||||
|
||||
if (!secrets_store_machine_password(new_password)) {
|
||||
DEBUG(1,("Failed to save machine password\n"));
|
||||
return ADS_ERROR_SYSTEM(EACCES);
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -97,7 +97,9 @@
|
||||
return ret;
|
||||
}
|
||||
krb5_use_enctype(context, &eblock, enctype);
|
||||
return krb5_string_to_key(context, &eblock, key, password, &salt);
|
||||
ret = krb5_string_to_key(context, &eblock, key, password, &salt);
|
||||
SAFE_FREE(salt.data);
|
||||
return ret;
|
||||
}
|
||||
#elif defined(HAVE_KRB5_GET_PW_SALT) && defined(HAVE_KRB5_STRING_TO_KEY_SALT)
|
||||
int create_kerberos_key_from_string(krb5_context context,
|
||||
@ -235,12 +237,12 @@ krb5_error_code get_kerberos_allowed_etypes(krb5_context context,
|
||||
/*
|
||||
we can't use krb5_mk_req because w2k wants the service to be in a particular format
|
||||
*/
|
||||
static krb5_error_code krb5_mk_req2(krb5_context context,
|
||||
krb5_auth_context *auth_context,
|
||||
const krb5_flags ap_req_options,
|
||||
const char *principal,
|
||||
krb5_ccache ccache,
|
||||
krb5_data *outbuf)
|
||||
static krb5_error_code ads_krb5_mk_req(krb5_context context,
|
||||
krb5_auth_context *auth_context,
|
||||
const krb5_flags ap_req_options,
|
||||
const char *principal,
|
||||
krb5_ccache ccache,
|
||||
krb5_data *outbuf)
|
||||
{
|
||||
krb5_error_code retval;
|
||||
krb5_principal server;
|
||||
@ -255,7 +257,7 @@ static krb5_error_code krb5_mk_req2(krb5_context context,
|
||||
}
|
||||
|
||||
/* obtain ticket & session key */
|
||||
memset((char *)&creds, 0, sizeof(creds));
|
||||
ZERO_STRUCT(creds);
|
||||
if ((retval = krb5_copy_principal(context, server, &creds.server))) {
|
||||
DEBUG(1,("krb5_copy_principal failed (%s)\n",
|
||||
error_message(retval)));
|
||||
@ -305,14 +307,14 @@ cleanup_princ:
|
||||
/*
|
||||
get a kerberos5 ticket for the given service
|
||||
*/
|
||||
DATA_BLOB krb5_get_ticket(const char *principal, time_t time_offset)
|
||||
int cli_krb5_get_ticket(const char *principal, time_t time_offset,
|
||||
DATA_BLOB *ticket, DATA_BLOB *session_key_krb5)
|
||||
{
|
||||
krb5_error_code retval;
|
||||
krb5_data packet;
|
||||
krb5_ccache ccdef;
|
||||
krb5_context context;
|
||||
krb5_auth_context auth_context = NULL;
|
||||
DATA_BLOB ret;
|
||||
krb5_enctype enc_types[] = {
|
||||
#ifdef ENCTYPE_ARCFOUR_HMAC
|
||||
ENCTYPE_ARCFOUR_HMAC,
|
||||
@ -344,56 +346,76 @@ DATA_BLOB krb5_get_ticket(const char *principal, time_t time_offset)
|
||||
goto failed;
|
||||
}
|
||||
|
||||
if ((retval = krb5_mk_req2(context,
|
||||
&auth_context,
|
||||
0,
|
||||
principal,
|
||||
ccdef, &packet))) {
|
||||
if ((retval = ads_krb5_mk_req(context,
|
||||
&auth_context,
|
||||
AP_OPTS_USE_SUBKEY,
|
||||
principal,
|
||||
ccdef, &packet))) {
|
||||
goto failed;
|
||||
}
|
||||
|
||||
ret = data_blob(packet.data, packet.length);
|
||||
get_krb5_smb_session_key(context, auth_context, session_key_krb5, False);
|
||||
|
||||
*ticket = data_blob(packet.data, packet.length);
|
||||
|
||||
/* Hmm, heimdal dooesn't have this - what's the correct call? */
|
||||
/* krb5_free_data_contents(context, &packet); */
|
||||
krb5_free_context(context);
|
||||
return ret;
|
||||
#ifdef HAVE_KRB5_FREE_DATA_CONTENTS
|
||||
krb5_free_data_contents(context, &packet);
|
||||
#endif
|
||||
|
||||
failed:
|
||||
if ( context )
|
||||
krb5_free_context(context);
|
||||
|
||||
return data_blob(NULL, 0);
|
||||
return retval;
|
||||
}
|
||||
|
||||
BOOL krb5_get_smb_session_key(krb5_context context, krb5_auth_context auth_context, uint8 session_key[16])
|
||||
BOOL get_krb5_smb_session_key(krb5_context context, krb5_auth_context auth_context, DATA_BLOB *session_key, BOOL remote)
|
||||
{
|
||||
#ifdef ENCTYPE_ARCFOUR_HMAC
|
||||
krb5_keyblock *skey;
|
||||
#endif
|
||||
krb5_error_code err;
|
||||
BOOL ret = False;
|
||||
|
||||
memset(session_key, 0, 16);
|
||||
|
||||
#ifdef ENCTYPE_ARCFOUR_HMAC
|
||||
if (krb5_auth_con_getremotesubkey(context, auth_context, &skey) == 0 && skey != NULL) {
|
||||
if (KRB5_KEY_TYPE(skey) ==
|
||||
ENCTYPE_ARCFOUR_HMAC
|
||||
&& KRB5_KEY_LENGTH(skey) == 16) {
|
||||
memcpy(session_key, KRB5_KEY_DATA(skey), KRB5_KEY_LENGTH(skey));
|
||||
ret = True;
|
||||
}
|
||||
if (remote)
|
||||
err = krb5_auth_con_getremotesubkey(context, auth_context, &skey);
|
||||
else
|
||||
err = krb5_auth_con_getlocalsubkey(context, auth_context, &skey);
|
||||
if (err == 0 && skey != NULL) {
|
||||
DEBUG(10, ("Got KRB5 session key of length %d\n", KRB5_KEY_LENGTH(skey)));
|
||||
*session_key = data_blob(KRB5_KEY_DATA(skey), KRB5_KEY_LENGTH(skey));
|
||||
dump_data_pw("KRB5 Session Key:\n", session_key->data, session_key->length);
|
||||
|
||||
ret = True;
|
||||
|
||||
krb5_free_keyblock(context, skey);
|
||||
} else {
|
||||
DEBUG(10, ("KRB5 error getting session key %d\n", err));
|
||||
}
|
||||
#endif /* ENCTYPE_ARCFOUR_HMAC */
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
#if defined(HAVE_KRB5_PRINCIPAL_GET_COMP_STRING) && !defined(HAVE_KRB5_PRINC_COMPONENT)
|
||||
const krb5_data *krb5_princ_component(krb5_context context, krb5_principal principal, int i )
|
||||
{
|
||||
static krb5_data kdata;
|
||||
|
||||
kdata.data = krb5_principal_get_comp_string(context, principal, i);
|
||||
kdata.length = strlen(kdata.data);
|
||||
return &kdata;
|
||||
}
|
||||
#endif
|
||||
|
||||
#else /* HAVE_KRB5 */
|
||||
/* this saves a few linking headaches */
|
||||
DATA_BLOB krb5_get_ticket(const char *principal, time_t time_offset)
|
||||
{
|
||||
/* this saves a few linking headaches */
|
||||
int cli_krb5_get_ticket(const char *principal, time_t time_offset,
|
||||
DATA_BLOB *ticket, DATA_BLOB *session_key_krb5)
|
||||
{
|
||||
DEBUG(0,("NO KERBEROS SUPPORT\n"));
|
||||
return data_blob(NULL, 0);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -2,7 +2,7 @@
|
||||
Unix SMB/CIFS implementation.
|
||||
simple kerberos5/SPNEGO routines
|
||||
Copyright (C) Andrew Tridgell 2001
|
||||
Copyright (C) Jim McDonough 2002
|
||||
Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2002
|
||||
Copyright (C) Luke Howard 2003
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
@ -323,24 +323,30 @@ BOOL spnego_parse_krb5_wrap(DATA_BLOB blob, DATA_BLOB *ticket, uint8 tok_id[2])
|
||||
generate a SPNEGO negTokenTarg packet, ready for a EXTENDED_SECURITY
|
||||
kerberos session setup
|
||||
*/
|
||||
DATA_BLOB spnego_gen_negTokenTarg(const char *principal, int time_offset)
|
||||
int spnego_gen_negTokenTarg(const char *principal, int time_offset,
|
||||
DATA_BLOB *targ,
|
||||
DATA_BLOB *session_key_krb5)
|
||||
{
|
||||
DATA_BLOB tkt, tkt_wrapped, targ;
|
||||
int retval;
|
||||
DATA_BLOB tkt, tkt_wrapped;
|
||||
const char *krb_mechs[] = {OID_KERBEROS5_OLD, OID_NTLMSSP, NULL};
|
||||
|
||||
/* get a kerberos ticket for the service */
|
||||
tkt = krb5_get_ticket(principal, time_offset);
|
||||
/* get a kerberos ticket for the service and extract the session key */
|
||||
retval = cli_krb5_get_ticket(principal, time_offset, &tkt, session_key_krb5);
|
||||
|
||||
if (retval)
|
||||
return retval;
|
||||
|
||||
/* wrap that up in a nice GSS-API wrapping */
|
||||
tkt_wrapped = spnego_gen_krb5_wrap(tkt, TOK_ID_KRB_AP_REQ);
|
||||
|
||||
/* and wrap that in a shiny SPNEGO wrapper */
|
||||
targ = gen_negTokenTarg(krb_mechs, tkt_wrapped);
|
||||
*targ = gen_negTokenTarg(krb_mechs, tkt_wrapped);
|
||||
|
||||
data_blob_free(&tkt_wrapped);
|
||||
data_blob_free(&tkt);
|
||||
|
||||
return targ;
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user