mirror of
https://github.com/samba-team/samba.git
synced 2025-12-03 04:23:50 +03:00
merge:
ldap and krb5 configure tests libads/*.c and libcli/raw/clikrb5.c from 3.0 metze
This commit is contained in:
@@ -12,7 +12,7 @@
|
|||||||
prefix=@prefix@
|
prefix=@prefix@
|
||||||
exec_prefix=@exec_prefix@
|
exec_prefix=@exec_prefix@
|
||||||
|
|
||||||
LIBS=@LIBS@
|
LIBS=@LIBS@ @LDAP_LIBS@ @KRB5_LIBS@
|
||||||
CC=@CC@
|
CC=@CC@
|
||||||
SHLD=@SHLD@
|
SHLD=@SHLD@
|
||||||
CFLAGS=@CFLAGS@
|
CFLAGS=@CFLAGS@
|
||||||
|
|||||||
107
source/aclocal.m4
vendored
107
source/aclocal.m4
vendored
@@ -135,6 +135,113 @@ AC_DEFUN(AC_LIBTESTFUNC,
|
|||||||
esac
|
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 Define an AC_DEFINE with ifndef guard.
|
||||||
dnl AC_N_DEFINE(VARIABLE [, VALUE])
|
dnl AC_N_DEFINE(VARIABLE [, VALUE])
|
||||||
define(AC_N_DEFINE,
|
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/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/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(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)
|
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
|
## check checking for truncated salt. Wrapped by the
|
||||||
## $with_pam_for_crypt variable as above --jerry
|
## $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,[
|
AC_CACHE_CHECK([for a crypt that needs truncated salt],samba_cv_HAVE_TRUNCATED_SALT,[
|
||||||
crypt_LIBS="$LIBS"
|
crypt_LIBS="$LIBS"
|
||||||
LIBS="$AUTHLIBS $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 {
|
typedef struct {
|
||||||
void *ld; /* the active ldap structure */
|
void *ld; /* the active ldap structure */
|
||||||
struct in_addr ldap_ip; /* the ip of the active connection, if any */
|
struct in_addr ldap_ip; /* the ip of the active connection, if any */
|
||||||
@@ -38,9 +57,9 @@ typedef struct {
|
|||||||
} config;
|
} config;
|
||||||
} ADS_STRUCT;
|
} ADS_STRUCT;
|
||||||
|
|
||||||
/* there are 4 possible types of errors the ads subsystem can produce */
|
/* there are 5 possible types of errors the ads subsystem can produce */
|
||||||
enum ads_error_type {ADS_ERROR_KRB5, ADS_ERROR_GSS,
|
enum ads_error_type {ENUM_ADS_ERROR_KRB5, ENUM_ADS_ERROR_GSS,
|
||||||
ADS_ERROR_LDAP, ADS_ERROR_SYSTEM, ADS_ERROR_NT};
|
ENUM_ADS_ERROR_LDAP, ENUM_ADS_ERROR_SYSTEM, ENUM_ADS_ERROR_NT};
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
enum ads_error_type error_type;
|
enum ads_error_type error_type;
|
||||||
@@ -48,7 +67,7 @@ typedef struct {
|
|||||||
int rc;
|
int rc;
|
||||||
NTSTATUS nt_status;
|
NTSTATUS nt_status;
|
||||||
} err;
|
} 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 */
|
/* Where rc represents major_status of GSS API error */
|
||||||
int minor_status;
|
int minor_status;
|
||||||
} ADS_STATUS;
|
} ADS_STATUS;
|
||||||
@@ -61,13 +80,13 @@ typedef void **ADS_MODLIST;
|
|||||||
|
|
||||||
/* macros to simplify error returning */
|
/* macros to simplify error returning */
|
||||||
#define ADS_ERROR(rc) ADS_ERROR_LDAP(rc)
|
#define ADS_ERROR(rc) ADS_ERROR_LDAP(rc)
|
||||||
#define ADS_ERROR_LDAP(rc) ads_build_error(ADS_ERROR_LDAP, rc, 0)
|
#define ADS_ERROR_LDAP(rc) ads_build_error(ENUM_ADS_ERROR_LDAP, rc, 0)
|
||||||
#define ADS_ERROR_SYSTEM(rc) ads_build_error(ADS_ERROR_SYSTEM, rc?rc:EINVAL, 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(ADS_ERROR_KRB5, rc, 0)
|
#define ADS_ERROR_KRB5(rc) ads_build_error(ENUM_ADS_ERROR_KRB5, rc, 0)
|
||||||
#define ADS_ERROR_GSS(rc, minor) ads_build_error(ADS_ERROR_GSS, rc, minor)
|
#define ADS_ERROR_GSS(rc, minor) ads_build_error(ENUM_ADS_ERROR_GSS, rc, minor)
|
||||||
#define ADS_ERROR_NT(rc) ads_build_nt_error(ADS_ERROR_NT,rc)
|
#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)
|
#define ADS_SUCCESS ADS_ERROR(0)
|
||||||
|
|
||||||
/* time between reconnect attempts */
|
/* time between reconnect attempts */
|
||||||
@@ -205,7 +224,11 @@ typedef void **ADS_MODLIST;
|
|||||||
#define ADS_AUTH_NO_BIND 0x02
|
#define ADS_AUTH_NO_BIND 0x02
|
||||||
#define ADS_AUTH_ANON_BIND 0x04
|
#define ADS_AUTH_ANON_BIND 0x04
|
||||||
#define ADS_AUTH_SIMPLE_BIND 0x08
|
#define ADS_AUTH_SIMPLE_BIND 0x08
|
||||||
|
#define ADS_AUTH_ALLOW_NTLMSSP 0x10
|
||||||
|
|
||||||
|
/***************************************
|
||||||
|
Some krb5 compat stuff
|
||||||
|
***************************************/
|
||||||
/* Kerberos environment variable names */
|
/* Kerberos environment variable names */
|
||||||
#define KRB5_ENV_CCNAME "KRB5CCNAME"
|
#define KRB5_ENV_CCNAME "KRB5CCNAME"
|
||||||
|
|
||||||
@@ -213,3 +236,36 @@ typedef void **ADS_MODLIST;
|
|||||||
#if defined(HAVE_ENCTYPE_ARCFOUR_HMAC_MD5)
|
#if defined(HAVE_ENCTYPE_ARCFOUR_HMAC_MD5)
|
||||||
#define ENCTYPE_ARCFOUR_HMAC ENCTYPE_ARCFOUR_HMAC_MD5
|
#define ENCTYPE_ARCFOUR_HMAC ENCTYPE_ARCFOUR_HMAC_MD5
|
||||||
#endif
|
#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>
|
#include <stropts.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_POLL_H
|
|
||||||
#include <poll.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_SYS_CAPABILITY_H
|
#ifdef HAVE_SYS_CAPABILITY_H
|
||||||
|
|
||||||
#if defined(BROKEN_REDHAT_7_SYSTEM_HEADERS) && !defined(_I386_STATFS_H)
|
#if defined(BROKEN_REDHAT_7_SYSTEM_HEADERS) && !defined(_I386_STATFS_H)
|
||||||
@@ -721,7 +717,6 @@ extern int errno;
|
|||||||
#include "../tdb/tdbutil.h"
|
#include "../tdb/tdbutil.h"
|
||||||
#include "talloc.h"
|
#include "talloc.h"
|
||||||
#include "nt_status.h"
|
#include "nt_status.h"
|
||||||
#include "ads.h"
|
|
||||||
#include "interfaces.h"
|
#include "interfaces.h"
|
||||||
#include "trans2.h"
|
#include "trans2.h"
|
||||||
#include "ioctl.h"
|
#include "ioctl.h"
|
||||||
@@ -734,6 +729,7 @@ extern int errno;
|
|||||||
|
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
#include "smb.h"
|
#include "smb.h"
|
||||||
|
#include "ads.h"
|
||||||
#include "nameserv.h"
|
#include "nameserv.h"
|
||||||
#include "secrets.h"
|
#include "secrets.h"
|
||||||
|
|
||||||
@@ -1147,30 +1143,5 @@ time_t timegm(struct tm *tm);
|
|||||||
#define VXFS_QUOTA
|
#define VXFS_QUOTA
|
||||||
#endif
|
#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 */
|
#endif /* _INCLUDES_H */
|
||||||
|
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ NTSTATUS ads_name_to_sid(ADS_STRUCT *ads,
|
|||||||
int count;
|
int count;
|
||||||
ADS_STATUS rc;
|
ADS_STATUS rc;
|
||||||
void *res = NULL;
|
void *res = NULL;
|
||||||
char *exp;
|
char *ldap_exp;
|
||||||
uint32 t;
|
uint32 t;
|
||||||
NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
|
NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
|
||||||
char *escaped_name = escape_ldap_string_alloc(name);
|
char *escaped_name = escape_ldap_string_alloc(name);
|
||||||
@@ -45,15 +45,15 @@ NTSTATUS ads_name_to_sid(ADS_STRUCT *ads,
|
|||||||
goto done;
|
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) {
|
escaped_name, escaped_name, escaped_realm) == -1) {
|
||||||
DEBUG(1,("ads_name_to_sid: asprintf failed!\n"));
|
DEBUG(1,("ads_name_to_sid: asprintf failed!\n"));
|
||||||
status = NT_STATUS_NO_MEMORY;
|
status = NT_STATUS_NO_MEMORY;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = ads_search_retry(ads, &res, exp, attrs);
|
rc = ads_search_retry(ads, &res, ldap_exp, attrs);
|
||||||
free(exp);
|
free(ldap_exp);
|
||||||
if (!ADS_ERR_OK(rc)) {
|
if (!ADS_ERR_OK(rc)) {
|
||||||
DEBUG(1,("name_to_sid ads_search: %s\n", ads_errstr(rc)));
|
DEBUG(1,("name_to_sid ads_search: %s\n", ads_errstr(rc)));
|
||||||
goto done;
|
goto done;
|
||||||
@@ -102,7 +102,7 @@ NTSTATUS ads_sid_to_name(ADS_STRUCT *ads,
|
|||||||
"sAMAccountType", NULL};
|
"sAMAccountType", NULL};
|
||||||
ADS_STATUS rc;
|
ADS_STATUS rc;
|
||||||
void *msg = NULL;
|
void *msg = NULL;
|
||||||
char *exp = NULL;
|
char *ldap_exp = NULL;
|
||||||
char *sidstr = NULL;
|
char *sidstr = NULL;
|
||||||
uint32 atype;
|
uint32 atype;
|
||||||
NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
|
NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
|
||||||
@@ -113,13 +113,13 @@ NTSTATUS ads_sid_to_name(ADS_STRUCT *ads,
|
|||||||
goto done;
|
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"));
|
DEBUG(1,("ads_sid_to_name: asprintf failed!\n"));
|
||||||
status = NT_STATUS_NO_MEMORY;
|
status = NT_STATUS_NO_MEMORY;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = ads_search_retry(ads, &msg, exp, attrs);
|
rc = ads_search_retry(ads, &msg, ldap_exp, attrs);
|
||||||
if (!ADS_ERR_OK(rc)) {
|
if (!ADS_ERR_OK(rc)) {
|
||||||
status = ads_ntstatus(rc);
|
status = ads_ntstatus(rc);
|
||||||
DEBUG(1,("ads_sid_to_name ads_search: %s\n", ads_errstr(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:
|
done:
|
||||||
if (msg) ads_msgfree(ads, msg);
|
if (msg) ads_msgfree(ads, msg);
|
||||||
|
|
||||||
SAFE_FREE(exp);
|
SAFE_FREE(ldap_exp);
|
||||||
SAFE_FREE(sidstr);
|
SAFE_FREE(sidstr);
|
||||||
|
|
||||||
return status;
|
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
|
#endif
|
||||||
|
|||||||
@@ -31,10 +31,10 @@ ADS_STATUS ads_build_error(enum ads_error_type etype,
|
|||||||
{
|
{
|
||||||
ADS_STATUS ret;
|
ADS_STATUS ret;
|
||||||
|
|
||||||
if (etype == ADS_ERROR_NT) {
|
if (etype == ENUM_ADS_ERROR_NT) {
|
||||||
DEBUG(0,("don't use ads_build_error with ADS_ERROR_NT!\n"));
|
DEBUG(0,("don't use ads_build_error with ENUM_ADS_ERROR_NT!\n"));
|
||||||
ret.err.rc = -1;
|
ret.err.rc = -1;
|
||||||
ret.error_type = ADS_ERROR_SYSTEM;
|
ret.error_type = ENUM_ADS_ERROR_SYSTEM;
|
||||||
ret.minor_status = 0;
|
ret.minor_status = 0;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -50,10 +50,10 @@ ADS_STATUS ads_build_nt_error(enum ads_error_type etype,
|
|||||||
{
|
{
|
||||||
ADS_STATUS ret;
|
ADS_STATUS ret;
|
||||||
|
|
||||||
if (etype != ADS_ERROR_NT) {
|
if (etype != ENUM_ADS_ERROR_NT) {
|
||||||
DEBUG(0,("don't use ads_build_nt_error without ADS_ERROR_NT!\n"));
|
DEBUG(0,("don't use ads_build_nt_error without ENUM_ADS_ERROR_NT!\n"));
|
||||||
ret.err.rc = -1;
|
ret.err.rc = -1;
|
||||||
ret.error_type = ADS_ERROR_SYSTEM;
|
ret.error_type = ENUM_ADS_ERROR_SYSTEM;
|
||||||
ret.minor_status = 0;
|
ret.minor_status = 0;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -69,14 +69,23 @@ ADS_STATUS ads_build_nt_error(enum ads_error_type etype,
|
|||||||
*/
|
*/
|
||||||
NTSTATUS ads_ntstatus(ADS_STATUS status)
|
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;
|
return status.err.nt_status;
|
||||||
}
|
}
|
||||||
#ifdef HAVE_LDAP
|
#ifdef HAVE_LDAP
|
||||||
if ((status.error_type == ADS_ERROR_LDAP)
|
if ((status.error_type == ENUM_ADS_ERROR_LDAP)
|
||||||
&& (status.err.rc == LDAP_NO_MEMORY)) {
|
&& (status.err.rc == LDAP_NO_MEMORY)) {
|
||||||
return NT_STATUS_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
|
#endif
|
||||||
if (ADS_ERR_OK(status)) return NT_STATUS_OK;
|
if (ADS_ERR_OK(status)) return NT_STATUS_OK;
|
||||||
return NT_STATUS_UNSUCCESSFUL;
|
return NT_STATUS_UNSUCCESSFUL;
|
||||||
@@ -87,25 +96,25 @@ NTSTATUS ads_ntstatus(ADS_STATUS status)
|
|||||||
*/
|
*/
|
||||||
const char *ads_errstr(ADS_STATUS status)
|
const char *ads_errstr(ADS_STATUS status)
|
||||||
{
|
{
|
||||||
int msg_ctx;
|
uint32 msg_ctx;
|
||||||
static char *ret;
|
static char *ret;
|
||||||
|
|
||||||
SAFE_FREE(ret);
|
SAFE_FREE(ret);
|
||||||
msg_ctx = 0;
|
msg_ctx = 0;
|
||||||
|
|
||||||
switch (status.error_type) {
|
switch (status.error_type) {
|
||||||
case ADS_ERROR_SYSTEM:
|
case ENUM_ADS_ERROR_SYSTEM:
|
||||||
return strerror(status.err.rc);
|
return strerror(status.err.rc);
|
||||||
#ifdef HAVE_LDAP
|
#ifdef HAVE_LDAP
|
||||||
case ADS_ERROR_LDAP:
|
case ENUM_ADS_ERROR_LDAP:
|
||||||
return ldap_err2string(status.err.rc);
|
return ldap_err2string(status.err.rc);
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_KRB5
|
#ifdef HAVE_KRB5
|
||||||
case ADS_ERROR_KRB5:
|
case ENUM_ADS_ERROR_KRB5:
|
||||||
return error_message(status.err.rc);
|
return error_message(status.err.rc);
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_GSSAPI
|
#ifdef HAVE_GSSAPI
|
||||||
case ADS_ERROR_GSS:
|
case ENUM_ADS_ERROR_GSS:
|
||||||
{
|
{
|
||||||
uint32 minor;
|
uint32 minor;
|
||||||
|
|
||||||
@@ -122,8 +131,8 @@ const char *ads_errstr(ADS_STATUS status)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
case ADS_ERROR_NT:
|
case ENUM_ADS_ERROR_NT:
|
||||||
return nt_errstr(ads_ntstatus(status));
|
return get_friendly_nt_error_msg(ads_ntstatus(status));
|
||||||
default:
|
default:
|
||||||
return "Unknown ADS error type!? (not compiled in?)";
|
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.workgroup = workgroup ? strdup(workgroup) : NULL;
|
||||||
ads->server.ldap_server = ldap_server? strdup(ldap_server) : 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
|
/* we need to know if this is a foreign realm */
|
||||||
use lp_ads_server() */
|
if (realm && *realm && !strequal(lp_realm(), realm)) {
|
||||||
if (realm && *realm && strcasecmp(lp_realm(), realm) != 0) {
|
|
||||||
ads->server.foreign = 1;
|
ads->server.foreign = 1;
|
||||||
}
|
}
|
||||||
if (workgroup && *workgroup && strcasecmp(lp_workgroup(), workgroup) != 0) {
|
if (workgroup && *workgroup && !strequal(lp_workgroup(), workgroup)) {
|
||||||
ads->server.foreign = 1;
|
ads->server.foreign = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -88,52 +88,6 @@ uint32 ads_uf2atype(uint32 uf)
|
|||||||
return atype;
|
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
|
get the accountType from the groupType
|
||||||
*/
|
*/
|
||||||
@@ -172,6 +126,8 @@ enum SID_NAME_USE ads_atype_map(uint32 atype)
|
|||||||
switch (atype & 0xF0000000) {
|
switch (atype & 0xF0000000) {
|
||||||
case ATYPE_GLOBAL_GROUP:
|
case ATYPE_GLOBAL_GROUP:
|
||||||
return SID_NAME_DOM_GRP;
|
return SID_NAME_DOM_GRP;
|
||||||
|
case ATYPE_SECURITY_LOCAL_GROUP:
|
||||||
|
return SID_NAME_ALIAS;
|
||||||
case ATYPE_ACCOUNT:
|
case ATYPE_ACCOUNT:
|
||||||
return SID_NAME_USER;
|
return SID_NAME_USER;
|
||||||
default:
|
default:
|
||||||
|
|||||||
@@ -1,34 +1,139 @@
|
|||||||
#################################################
|
########################################################
|
||||||
# active directory support
|
# Compile with LDAP support?
|
||||||
|
|
||||||
with_ads_support=yes
|
LDAP_LIBS=""
|
||||||
AC_MSG_CHECKING([whether to use Active Directory])
|
AC_SUBST(LDAP_LIBS)
|
||||||
|
with_ldap_support=auto
|
||||||
|
AC_MSG_CHECKING([for LDAP support])
|
||||||
|
|
||||||
AC_ARG_WITH(ads,
|
AC_ARG_WITH(ldap,
|
||||||
[ --with-ads Active Directory support (default yes)],
|
[ --with-ldap LDAP support (default yes)],
|
||||||
[ case "$withval" in
|
[ case "$withval" in
|
||||||
no)
|
yes|no)
|
||||||
with_ads_support=no
|
with_ldap_support=$withval
|
||||||
;;
|
;;
|
||||||
esac ])
|
esac ])
|
||||||
|
|
||||||
if test x"$with_ads_support" = x"yes"; then
|
AC_MSG_RESULT($with_ldap_support)
|
||||||
AC_DEFINE(WITH_ADS,1,[Whether to include Active Directory 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
|
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)
|
AC_MSG_RESULT($with_ads_support)
|
||||||
|
|
||||||
FOUND_KRB5=no
|
if test x"$with_ldap_support" != x"yes"; then
|
||||||
if test x"$with_ads_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
|
# check for krb5-config from recent MIT and Heimdal kerberos 5
|
||||||
AC_PATH_PROG(KRB5_CONFIG, krb5-config)
|
AC_PATH_PROG(KRB5_CONFIG, krb5-config)
|
||||||
AC_MSG_CHECKING(for working krb5-config)
|
AC_MSG_CHECKING(for working krb5-config)
|
||||||
if test -x "$KRB5_CONFIG"; then
|
if test -x "$KRB5_CONFIG"; then
|
||||||
LIBS="$LIBS `$KRB5_CONFIG --libs`"
|
ac_save_CFLAGS=$CFLAGS
|
||||||
CFLAGS="$CFLAGS `$KRB5_CONFIG --cflags`"
|
CFLAGS="";export CFLAGS
|
||||||
CPPFLAGS="$CPPFLAGS `$KRB5_CONFIG --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
|
FOUND_KRB5=yes
|
||||||
AC_MSG_RESULT(yes)
|
AC_MSG_RESULT(yes)
|
||||||
else
|
else
|
||||||
@@ -36,193 +141,303 @@ if test x"$with_ads_support" = x"yes"; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
if test x$FOUND_KRB5 = x"no"; then
|
if test x$FOUND_KRB5 = x"no"; then
|
||||||
#################################################
|
#################################################
|
||||||
# check for location of Kerberos 5 install
|
# check for location of Kerberos 5 install
|
||||||
AC_MSG_CHECKING(for kerberos 5 install path)
|
AC_MSG_CHECKING(for kerberos 5 install path)
|
||||||
AC_ARG_WITH(krb5,
|
AC_ARG_WITH(krb5,
|
||||||
[ --with-krb5=base-dir Locate Kerberos 5 support (default=/usr)],
|
[ --with-krb5=base-dir Locate Kerberos 5 support (default=/usr)],
|
||||||
[ case "$withval" in
|
[ case "$withval" in
|
||||||
no)
|
no)
|
||||||
AC_MSG_RESULT(no)
|
AC_MSG_RESULT(no krb5-path given)
|
||||||
;;
|
;;
|
||||||
*)
|
yes)
|
||||||
AC_MSG_RESULT(yes)
|
AC_MSG_RESULT(/usr)
|
||||||
LIBS="$LIBS -lkrb5"
|
FOUND_KRB5=yes
|
||||||
CFLAGS="$CFLAGS -I$withval/include"
|
;;
|
||||||
CPPFLAGS="$CPPFLAGS -I$withval/include"
|
*)
|
||||||
LDFLAGS="$LDFLAGS -L$withval/lib"
|
AC_MSG_RESULT($withval)
|
||||||
FOUND_KRB5=yes
|
KRB5_CFLAGS="-I$withval/include"
|
||||||
;;
|
KRB5_CPPFLAGS="-I$withval/include"
|
||||||
esac ],
|
KRB5_LDFLAGS="-L$withval/lib"
|
||||||
AC_MSG_RESULT(no)
|
FOUND_KRB5=yes
|
||||||
)
|
;;
|
||||||
|
esac ],
|
||||||
|
AC_MSG_RESULT(no krb5-path given)
|
||||||
|
)
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if test x$FOUND_KRB5 = x"no"; then
|
if test x$FOUND_KRB5 = x"no"; then
|
||||||
#################################################
|
#################################################
|
||||||
# see if this box has the SuSE location for the heimdal kerberos implementation
|
# see if this box has the SuSE location for the heimdal krb implementation
|
||||||
AC_MSG_CHECKING(for /usr/include/heimdal)
|
AC_MSG_CHECKING(for /usr/include/heimdal)
|
||||||
if test -d /usr/include/heimdal; then
|
if test -d /usr/include/heimdal; then
|
||||||
if test -f /usr/lib/heimdal/lib/libkrb5.a; then
|
if test -f /usr/lib/heimdal/lib/libkrb5.a; then
|
||||||
LIBS="$LIBS -lkrb5"
|
KRB5_CFLAGS="-I/usr/include/heimdal"
|
||||||
CFLAGS="$CFLAGS -I/usr/include/heimdal"
|
KRB5_CPPFLAGS="-I/usr/include/heimdal"
|
||||||
CPPFLAGS="$CPPFLAGS -I/usr/include/heimdal"
|
KRB5_LDFLAGS="-L/usr/lib/heimdal/lib"
|
||||||
LDFLAGS="$LDFLAGS -L/usr/lib/heimdal/lib"
|
AC_MSG_RESULT(yes)
|
||||||
AC_MSG_RESULT(yes)
|
else
|
||||||
|
KRB5_CFLAGS="-I/usr/include/heimdal"
|
||||||
|
KRB5_CPPFLAGS="-I/usr/include/heimdal"
|
||||||
|
AC_MSG_RESULT(yes)
|
||||||
|
fi
|
||||||
else
|
else
|
||||||
LIBS="$LIBS -lkrb5"
|
AC_MSG_RESULT(no)
|
||||||
CFLAGS="$CFLAGS -I/usr/include/heimdal"
|
|
||||||
CPPFLAGS="$CPPFLAGS -I/usr/include/heimdal"
|
|
||||||
AC_MSG_RESULT(yes)
|
|
||||||
|
|
||||||
fi
|
fi
|
||||||
else
|
fi
|
||||||
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
|
||||||
|
|
||||||
if test x$FOUND_KRB5 = x"no"; then
|
ac_save_CFLAGS=$CFLAGS
|
||||||
#################################################
|
ac_save_CPPFLAGS=$CPPFLAGS
|
||||||
# see if this box has the RedHat location for kerberos
|
ac_save_LDFLAGS=$LDFLAGS
|
||||||
AC_MSG_CHECKING(for /usr/kerberos)
|
|
||||||
if test -d /usr/kerberos -a -f /usr/kerberos/lib/libkrb5.a; then
|
CFLAGS="$CFLAGS $KRB5_CFLAGS"
|
||||||
LIBS="$LIBS -lkrb5"
|
CPPFLAGS="$CPPFLAGS $KRB5_CPPFLAGS"
|
||||||
LDFLAGS="$LDFLAGS -L/usr/kerberos/lib"
|
LDFLAGS="$LDFLAGS $KRB5_LDFLAGS"
|
||||||
CFLAGS="$CFLAGS -I/usr/kerberos/include"
|
|
||||||
CPPFLAGS="$CPPFLAGS -I/usr/kerberos/include"
|
KRB5_LIBS="$KRB5_LDFLAGS $KRB5_LIBS"
|
||||||
AC_MSG_RESULT(yes)
|
|
||||||
else
|
|
||||||
AC_MSG_RESULT(no)
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# now check for krb5.h. Some systems have the libraries without the headers!
|
# 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
|
# note that this check is done here to allow for different kerberos
|
||||||
# include paths
|
# include paths
|
||||||
AC_CHECK_HEADERS(krb5.h)
|
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
|
# now check for gssapi headers. This is also done here to allow for
|
||||||
# different kerberos include paths
|
# different kerberos include paths
|
||||||
AC_CHECK_HEADERS(gssapi.h gssapi/gssapi_generic.h gssapi/gssapi.h com_err.h)
|
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
|
# 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_EXT(com_err, KRB5_LIBS, _et_list)
|
||||||
AC_CHECK_LIB(k5crypto, krb5_encrypt_data, [LIBS="$LIBS -lk5crypto"])
|
AC_CHECK_LIB_EXT(k5crypto, KRB5_LIBS, krb5_encrypt_data)
|
||||||
|
|
||||||
# Heimdal checks.
|
# Heimdal checks.
|
||||||
AC_CHECK_LIB(crypto, des_set_key, [LIBS="$LIBS -lcrypto"])
|
AC_CHECK_LIB_EXT(crypto, KRB5_LIBS, des_set_key)
|
||||||
AC_CHECK_LIB(asn1, copy_Authenticator, [LIBS="$LIBS -lasn1 -lroken"])
|
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.
|
# Heimdal checks. On static Heimdal gssapi must be linked before krb5.
|
||||||
AC_CHECK_LIB(gssapi, gss_display_status, [LIBS="$LIBS -lgssapi -lkrb5 -lasn1";
|
AC_CHECK_LIB_EXT(gssapi, KRB5_LIBS, gss_display_status,[],[],
|
||||||
AC_DEFINE(HAVE_GSSAPI,1,[Whether GSSAPI is available])])
|
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
|
|
||||||
|
|
||||||
########################################################
|
########################################################
|
||||||
# now see if we can find the krb5 libs in standard paths
|
# now see if we can find the krb5 libs in standard paths
|
||||||
# or as specified above
|
# or as specified above
|
||||||
AC_CHECK_LIB(krb5, krb5_mk_req_extended, [LIBS="$LIBS -lkrb5";
|
AC_CHECK_LIB_EXT(krb5, KRB5_LIBS, krb5_mk_req_extended)
|
||||||
AC_DEFINE(HAVE_KRB5,1,[Whether KRB5 is available])])
|
|
||||||
|
|
||||||
########################################################
|
########################################################
|
||||||
# now see if we can find the gssapi libs in standard paths
|
# 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_CHECK_LIB_EXT(gssapi_krb5, KRB5_LIBS,gss_display_status,[],[],
|
||||||
AC_DEFINE(HAVE_GSSAPI,1,[Whether GSSAPI is available])])
|
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)
|
||||||
|
|
||||||
########################################################
|
LIBS="$LIBS $KRB5_LIBS"
|
||||||
# Compile with LDAP support?
|
|
||||||
|
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
|
if test x"$samba_cv_HAVE_ADDRTYPE_IN_KRB5_ADDRESS" = x"yes"; then
|
||||||
AC_MSG_CHECKING([whether to use LDAP])
|
AC_DEFINE(HAVE_ADDRTYPE_IN_KRB5_ADDRESS,1,
|
||||||
|
[Whether the krb5_address struct has a addrtype property])
|
||||||
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])
|
|
||||||
fi
|
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
|
fi
|
||||||
|
|||||||
@@ -4,6 +4,8 @@
|
|||||||
Copyright (C) Andrew Tridgell 2001
|
Copyright (C) Andrew Tridgell 2001
|
||||||
Copyright (C) Remus Koos 2001
|
Copyright (C) Remus Koos 2001
|
||||||
Copyright (C) Luke Howard 2003
|
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
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -24,38 +26,181 @@
|
|||||||
|
|
||||||
#ifdef HAVE_KRB5
|
#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
|
verify an incoming ticket and parse out the principal name and
|
||||||
authorization_data if available
|
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,
|
char **principal, DATA_BLOB *auth_data,
|
||||||
DATA_BLOB *ap_rep,
|
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_auth_context auth_context = NULL;
|
||||||
krb5_keytab keytab = NULL;
|
krb5_keytab keytab = NULL;
|
||||||
krb5_data packet;
|
krb5_data packet;
|
||||||
krb5_ticket *tkt = NULL;
|
krb5_ticket *tkt = NULL;
|
||||||
|
krb5_rcache rcache = NULL;
|
||||||
int ret, i;
|
int ret, i;
|
||||||
krb5_keyblock * key;
|
krb5_keyblock *key = NULL;
|
||||||
|
|
||||||
krb5_principal host_princ;
|
krb5_principal host_princ;
|
||||||
char *host_princ_s;
|
char *host_princ_s = NULL;
|
||||||
|
BOOL free_host_princ = False;
|
||||||
|
|
||||||
fstring myname;
|
fstring myname;
|
||||||
char *password_s;
|
char *password_s = NULL;
|
||||||
krb5_data password;
|
krb5_data password;
|
||||||
krb5_enctype *enctypes = NULL;
|
krb5_enctype *enctypes = NULL;
|
||||||
|
#if 0
|
||||||
|
krb5_address local_addr;
|
||||||
|
krb5_address remote_addr;
|
||||||
|
#endif
|
||||||
BOOL auth_ok = False;
|
BOOL auth_ok = False;
|
||||||
|
|
||||||
|
ZERO_STRUCT(packet);
|
||||||
|
ZERO_STRUCT(password);
|
||||||
|
ZERO_STRUCTP(auth_data);
|
||||||
|
ZERO_STRUCTP(ap_rep);
|
||||||
|
|
||||||
if (!secrets_init()) {
|
if (!secrets_init()) {
|
||||||
DEBUG(1,("secrets_init failed\n"));
|
DEBUG(1,("ads_verify_ticket: secrets_init failed\n"));
|
||||||
return NT_STATUS_LOGON_FAILURE;
|
return NT_STATUS_LOGON_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
password_s = secrets_fetch_machine_password();
|
password_s = secrets_fetch_machine_password(lp_workgroup(), NULL, NULL);
|
||||||
if (!password_s) {
|
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;
|
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);
|
ret = krb5_init_context(&context);
|
||||||
if (ret) {
|
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;
|
return NT_STATUS_LOGON_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = krb5_set_default_realm(context, ads->auth.realm);
|
ret = krb5_set_default_realm(context, realm);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
DEBUG(1,("krb5_set_default_realm failed (%s)\n", error_message(ret)));
|
DEBUG(1,("ads_verify_ticket: krb5_set_default_realm failed (%s)\n", error_message(ret)));
|
||||||
return NT_STATUS_LOGON_FAILURE;
|
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
|
like. We have to go through all this to allow us to store
|
||||||
the secret internally, instead of using /etc/krb5.keytab */
|
the secret internally, instead of using /etc/krb5.keytab */
|
||||||
|
|
||||||
ret = krb5_auth_con_init(context, &auth_context);
|
ret = krb5_auth_con_init(context, &auth_context);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
DEBUG(1,("krb5_auth_con_init failed (%s)\n", error_message(ret)));
|
DEBUG(1,("ads_verify_ticket: krb5_auth_con_init failed (%s)\n", error_message(ret)));
|
||||||
return NT_STATUS_LOGON_FAILURE;
|
sret = NT_STATUS_LOGON_FAILURE;
|
||||||
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
fstrcpy(myname, lp_netbios_name());
|
fstrcpy(myname, global_myname());
|
||||||
strlower(myname);
|
strlower_m(myname);
|
||||||
asprintf(&host_princ_s, "HOST/%s@%s", myname, lp_realm());
|
asprintf(&host_princ_s, "HOST/%s@%s", myname, lp_realm());
|
||||||
ret = krb5_parse_name(context, host_princ_s, &host_princ);
|
ret = krb5_parse_name(context, host_princ_s, &host_princ);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
DEBUG(1,("krb5_parse_name(%s) failed (%s)\n", host_princ_s, error_message(ret)));
|
DEBUG(1,("ads_verify_ticket: krb5_parse_name(%s) failed (%s)\n",
|
||||||
return NT_STATUS_LOGON_FAILURE;
|
host_princ_s, error_message(ret)));
|
||||||
|
sret = NT_STATUS_LOGON_FAILURE;
|
||||||
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(key = (krb5_keyblock *)malloc(sizeof(*key)))) {
|
free_host_princ = True;
|
||||||
return NT_STATUS_NO_MEMORY;
|
|
||||||
|
/*
|
||||||
|
* 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))) {
|
/* We need to setup a auth context with each possible encoding type in turn. */
|
||||||
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 */
|
|
||||||
for (i=0;enctypes[i];i++) {
|
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])) {
|
if (create_kerberos_key_from_string(context, host_princ, &password, key, enctypes[i])) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
krb5_auth_con_setuseruserkey(context, auth_context, key);
|
krb5_auth_con_setuseruserkey(context, auth_context, key);
|
||||||
|
|
||||||
|
krb5_free_keyblock(context, key);
|
||||||
|
|
||||||
packet.length = ticket->length;
|
packet.length = ticket->length;
|
||||||
packet.data = (krb5_pointer)ticket->data;
|
packet.data = (krb5_pointer)ticket->data;
|
||||||
|
|
||||||
if (!(ret = krb5_rd_req(context, &auth_context, &packet,
|
if (!(ret = krb5_rd_req(context, &auth_context, &packet,
|
||||||
NULL, keytab, NULL, &tkt))) {
|
#ifdef HAVE_MEMORY_KEYTAB
|
||||||
free_kerberos_etypes(context, enctypes);
|
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;
|
auth_ok = True;
|
||||||
break;
|
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) {
|
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)));
|
error_message(ret)));
|
||||||
return NT_STATUS_LOGON_FAILURE;
|
sret = NT_STATUS_LOGON_FAILURE;
|
||||||
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = krb5_mk_rep(context, auth_context, &packet);
|
ret = krb5_mk_rep(context, auth_context, &packet);
|
||||||
if (ret) {
|
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)));
|
error_message(ret)));
|
||||||
krb5_auth_con_free(context, auth_context);
|
sret = NT_STATUS_LOGON_FAILURE;
|
||||||
return NT_STATUS_LOGON_FAILURE;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
*ap_rep = data_blob(packet.data, packet.length);
|
*ap_rep = data_blob(packet.data, packet.length);
|
||||||
free(packet.data);
|
free(packet.data);
|
||||||
|
|
||||||
krb5_get_smb_session_key(context, auth_context, session_key);
|
get_krb5_smb_session_key(context, auth_context, session_key, True);
|
||||||
DEBUG(0,("SMB session key (from ticket) follows:\n"));
|
dump_data_pw("SMB session key (from ticket)\n", session_key->data, session_key->length);
|
||||||
dump_data(0, session_key, 16);
|
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
file_save("/tmp/ticket.dat", ticket->data, ticket->length);
|
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);
|
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 0
|
||||||
if (tkt->enc_part2) {
|
if (tkt->enc_part2) {
|
||||||
file_save("/tmp/authdata.dat",
|
file_save("/tmp/authdata.dat",
|
||||||
tkt->enc_part2->authorization_data[0]->contents,
|
tkt->enc_part2->authorization_data[0]->contents,
|
||||||
tkt->enc_part2->authorization_data[0]->length);
|
tkt->enc_part2->authorization_data[0]->length);
|
||||||
|
}
|
||||||
#endif
|
#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),
|
if ((ret = krb5_unparse_name(context, get_principal_from_tkt(tkt),
|
||||||
principal))) {
|
principal))) {
|
||||||
DEBUG(3,("krb5_unparse_name failed (%s)\n",
|
DEBUG(3,("ads_verify_ticket: krb5_unparse_name failed (%s)\n",
|
||||||
error_message(ret)));
|
error_message(ret)));
|
||||||
data_blob_free(auth_data);
|
sret = NT_STATUS_LOGON_FAILURE;
|
||||||
data_blob_free(ap_rep);
|
goto out;
|
||||||
krb5_auth_con_free(context, auth_context);
|
|
||||||
return NT_STATUS_LOGON_FAILURE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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 */
|
#endif /* HAVE_KRB5 */
|
||||||
|
|||||||
@@ -143,7 +143,7 @@ static krb5_error_code build_kpasswd_request(uint16 pversion,
|
|||||||
else
|
else
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
|
|
||||||
encoded_setpw.data = setpw.data;
|
encoded_setpw.data = (char *)setpw.data;
|
||||||
encoded_setpw.length = setpw.length;
|
encoded_setpw.length = setpw.length;
|
||||||
|
|
||||||
ret = krb5_mk_priv(context, auth_context,
|
ret = krb5_mk_priv(context, auth_context,
|
||||||
@@ -178,47 +178,39 @@ static krb5_error_code build_kpasswd_request(uint16 pversion,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static krb5_error_code krb5_setpw_result_code_string(krb5_context context,
|
static const struct kpasswd_errors {
|
||||||
int result_code,
|
int result_code;
|
||||||
char **code_string)
|
const char *error_string;
|
||||||
{
|
} kpasswd_errors[] = {
|
||||||
switch (result_code) {
|
{KRB5_KPASSWD_MALFORMED, "Malformed request error"},
|
||||||
case KRB5_KPASSWD_MALFORMED:
|
{KRB5_KPASSWD_HARDERROR, "Server error"},
|
||||||
*code_string = "Malformed request error";
|
{KRB5_KPASSWD_AUTHERROR, "Authentication error"},
|
||||||
break;
|
{KRB5_KPASSWD_SOFTERROR, "Password change rejected"},
|
||||||
case KRB5_KPASSWD_HARDERROR:
|
{KRB5_KPASSWD_ACCESSDENIED, "Client does not have proper authorization"},
|
||||||
*code_string = "Server error";
|
{KRB5_KPASSWD_BAD_VERSION, "Protocol version not supported"},
|
||||||
break;
|
{KRB5_KPASSWD_INITIAL_FLAG_NEEDED, "Authorization ticket must have initial flag set"},
|
||||||
case KRB5_KPASSWD_AUTHERROR:
|
{KRB5_KPASSWD_POLICY_REJECT, "Password rejected due to policy requirements"},
|
||||||
*code_string = "Authentication error";
|
{KRB5_KPASSWD_BAD_PRINCIPAL, "Target principal does not exist"},
|
||||||
break;
|
{KRB5_KPASSWD_ETYPE_NOSUPP, "Unsupported encryption type"},
|
||||||
case KRB5_KPASSWD_SOFTERROR:
|
{0, NULL}
|
||||||
*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;
|
|
||||||
}
|
|
||||||
|
|
||||||
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,
|
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)
|
if(res_code == KRB5_KPASSWD_SUCCESS)
|
||||||
return 0;
|
return 0;
|
||||||
else {
|
else {
|
||||||
char *errstr;
|
const char *errstr;
|
||||||
krb5_setpw_result_code_string(context, res_code, &errstr);
|
setpw_result_code_string(context, res_code, &errstr);
|
||||||
DEBUG(1, ("Error changing password: %s\n", errstr));
|
DEBUG(1, ("Error changing password: %s\n", errstr));
|
||||||
|
|
||||||
switch(res_code) {
|
switch(res_code) {
|
||||||
@@ -465,8 +457,8 @@ static ADS_STATUS do_krb5_kpasswd_request(krb5_context context,
|
|||||||
return ADS_SUCCESS;
|
return ADS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
ADS_STATUS krb5_set_password(const char *kdc_host, const char *princ, const char *newpw,
|
ADS_STATUS ads_krb5_set_password(const char *kdc_host, const char *princ,
|
||||||
int time_offset)
|
const char *newpw, int time_offset)
|
||||||
{
|
{
|
||||||
|
|
||||||
ADS_STATUS aret;
|
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_creds(context, credsp);
|
||||||
krb5_free_principal(context, creds.client);
|
krb5_free_principal(context, creds.client);
|
||||||
krb5_free_principal(context, creds.server);
|
|
||||||
krb5_free_principal(context, principal);
|
krb5_free_principal(context, principal);
|
||||||
krb5_free_context(context);
|
krb5_free_context(context);
|
||||||
|
|
||||||
@@ -579,11 +570,11 @@ kerb_prompter(krb5_context ctx, void *data,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ADS_STATUS krb5_chg_password(const char *kdc_host,
|
static ADS_STATUS ads_krb5_chg_password(const char *kdc_host,
|
||||||
const char *principal,
|
const char *principal,
|
||||||
const char *oldpw,
|
const char *oldpw,
|
||||||
const char *newpw,
|
const char *newpw,
|
||||||
int time_offset)
|
int time_offset)
|
||||||
{
|
{
|
||||||
ADS_STATUS aret;
|
ADS_STATUS aret;
|
||||||
krb5_error_code ret;
|
krb5_error_code ret;
|
||||||
@@ -657,11 +648,11 @@ ADS_STATUS kerberos_set_password(const char *kpasswd_server,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!strcmp(auth_principal, target_principal))
|
if (!strcmp(auth_principal, target_principal))
|
||||||
return krb5_chg_password(kpasswd_server, target_principal,
|
return ads_krb5_chg_password(kpasswd_server, target_principal,
|
||||||
auth_password, new_password, time_offset);
|
auth_password, new_password, time_offset);
|
||||||
else
|
else
|
||||||
return krb5_set_password(kpasswd_server, target_principal,
|
return ads_krb5_set_password(kpasswd_server, target_principal,
|
||||||
new_password, time_offset);
|
new_password, time_offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -673,24 +664,22 @@ ADS_STATUS kerberos_set_password(const char *kpasswd_server,
|
|||||||
* @return status of password change
|
* @return status of password change
|
||||||
**/
|
**/
|
||||||
ADS_STATUS ads_set_machine_password(ADS_STRUCT *ads,
|
ADS_STATUS ads_set_machine_password(ADS_STRUCT *ads,
|
||||||
const char *hostname,
|
const char *machine_account,
|
||||||
const char *password)
|
const char *password)
|
||||||
{
|
{
|
||||||
ADS_STATUS status;
|
ADS_STATUS status;
|
||||||
char *host = strdup(hostname);
|
char *principal = NULL;
|
||||||
char *principal;
|
|
||||||
|
|
||||||
strlower(host);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
we need to use the '$' form of the name here, as otherwise the
|
we need to use the '$' form of the name here (the machine account name),
|
||||||
server might end up setting the password for a user instead
|
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);
|
free(principal);
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
Unix SMB/CIFS implementation.
|
Unix SMB/CIFS implementation.
|
||||||
ads (active directory) printer utility library
|
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
|
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
|
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)
|
const char *printer, const char *servername)
|
||||||
{
|
{
|
||||||
ADS_STATUS status;
|
ADS_STATUS status;
|
||||||
char *srv_dn, **srv_cn, *exp;
|
char *srv_dn, **srv_cn, *s;
|
||||||
const char *attrs[] = {"*", "nTSecurityDescriptor", NULL};
|
const char *attrs[] = {"*", "nTSecurityDescriptor", NULL};
|
||||||
|
|
||||||
status = ads_find_machine_acct(ads, res, servername);
|
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);
|
srv_cn = ldap_explode_dn(srv_dn, 1);
|
||||||
ads_msgfree(ads, *res);
|
ads_msgfree(ads, *res);
|
||||||
|
|
||||||
asprintf(&exp, "(cn=%s-%s)", srv_cn[0], printer);
|
asprintf(&s, "(cn=%s-%s)", srv_cn[0], printer);
|
||||||
status = ads_search(ads, res, exp, attrs);
|
status = ads_search(ads, res, s, attrs);
|
||||||
|
|
||||||
ldap_memfree(srv_dn);
|
ldap_memfree(srv_dn);
|
||||||
ldap_value_free(srv_cn);
|
ldap_value_free(srv_cn);
|
||||||
free(exp);
|
free(s);
|
||||||
return status;
|
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
|
modify a printer entry in the directory
|
||||||
*/
|
*/
|
||||||
@@ -338,4 +352,3 @@ BOOL get_local_printer_publishing_data(TALLOC_CTX *mem_ctx,
|
|||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
Unix SMB/CIFS implementation.
|
Unix SMB/CIFS implementation.
|
||||||
ads (active directory) utility library
|
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
|
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
|
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 ads_find_user_acct(ADS_STRUCT *ads, void **res, const char *user)
|
||||||
{
|
{
|
||||||
ADS_STATUS status;
|
ADS_STATUS status;
|
||||||
char *exp;
|
char *ldap_exp;
|
||||||
const char *attrs[] = {"*", NULL};
|
const char *attrs[] = {"*", NULL};
|
||||||
char *escaped_user = escape_ldap_string_alloc(user);
|
char *escaped_user = escape_ldap_string_alloc(user);
|
||||||
if (!escaped_user) {
|
if (!escaped_user) {
|
||||||
return ADS_ERROR(LDAP_NO_MEMORY);
|
return ADS_ERROR(LDAP_NO_MEMORY);
|
||||||
}
|
}
|
||||||
|
|
||||||
asprintf(&exp, "(samAccountName=%s)", escaped_user);
|
asprintf(&ldap_exp, "(samAccountName=%s)", escaped_user);
|
||||||
status = ads_search(ads, res, exp, attrs);
|
status = ads_search(ads, res, ldap_exp, attrs);
|
||||||
SAFE_FREE(exp);
|
SAFE_FREE(ldap_exp);
|
||||||
SAFE_FREE(escaped_user);
|
SAFE_FREE(escaped_user);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,13 +28,15 @@
|
|||||||
this is supposed to catch dropped connections and auto-reconnect
|
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,
|
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)
|
const char **attrs, void **res)
|
||||||
{
|
{
|
||||||
ADS_STATUS status;
|
ADS_STATUS status;
|
||||||
int count = 3;
|
int count = 3;
|
||||||
char *bp;
|
char *bp;
|
||||||
|
|
||||||
|
*res = NULL;
|
||||||
|
|
||||||
if (!ads->ld &&
|
if (!ads->ld &&
|
||||||
time(NULL) - ads->last_attempt < ADS_RECONNECT_TIME) {
|
time(NULL) - ads->last_attempt < ADS_RECONNECT_TIME) {
|
||||||
return ADS_ERROR(LDAP_SERVER_DOWN);
|
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);
|
bp = strdup(bind_path);
|
||||||
|
|
||||||
if (!bp)
|
if (!bp) {
|
||||||
return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
|
return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
|
||||||
|
}
|
||||||
|
|
||||||
while (count--) {
|
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)) {
|
if (ADS_ERR_OK(status)) {
|
||||||
DEBUG(5,("Search for %s gave %d replies\n",
|
DEBUG(5,("Search for %s gave %d replies\n",
|
||||||
exp, ads_count_replies(ads, *res)));
|
expr, ads_count_replies(ads, *res)));
|
||||||
free(bp);
|
SAFE_FREE(bp);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*res) ads_msgfree(ads, *res);
|
if (*res)
|
||||||
|
ads_msgfree(ads, *res);
|
||||||
*res = NULL;
|
*res = NULL;
|
||||||
|
|
||||||
DEBUG(3,("Reopening ads connection to realm '%s' after error %s\n",
|
DEBUG(3,("Reopening ads connection to realm '%s' after error %s\n",
|
||||||
ads->config.realm, ads_errstr(status)));
|
ads->config.realm, ads_errstr(status)));
|
||||||
|
|
||||||
if (ads->ld) {
|
if (ads->ld) {
|
||||||
ldap_unbind(ads->ld);
|
ldap_unbind(ads->ld);
|
||||||
}
|
}
|
||||||
|
|
||||||
ads->ld = NULL;
|
ads->ld = NULL;
|
||||||
status = ads_connect(ads);
|
status = ads_connect(ads);
|
||||||
|
|
||||||
if (!ADS_ERR_OK(status)) {
|
if (!ADS_ERR_OK(status)) {
|
||||||
DEBUG(1,("ads_search_retry: failed to reconnect (%s)\n",
|
DEBUG(1,("ads_search_retry: failed to reconnect (%s)\n",
|
||||||
ads_errstr(status)));
|
ads_errstr(status)));
|
||||||
ads_destroy(&ads);
|
ads_destroy(&ads);
|
||||||
free(bp);
|
SAFE_FREE(bp);
|
||||||
return status;
|
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;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ADS_STATUS ads_search_retry(ADS_STRUCT *ads, void **res,
|
ADS_STATUS ads_search_retry(ADS_STRUCT *ads, void **res,
|
||||||
const char *exp,
|
const char *expr,
|
||||||
const char **attrs)
|
const char **attrs)
|
||||||
{
|
{
|
||||||
return ads_do_search_retry(ads, ads->config.bind_path, LDAP_SCOPE_SUBTREE,
|
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,
|
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);
|
msg1 = gen_negTokenTarg(mechs, blob);
|
||||||
data_blob_free(&blob);
|
data_blob_free(&blob);
|
||||||
|
|
||||||
cred.bv_val = msg1.data;
|
cred.bv_val = (char *)msg1.data;
|
||||||
cred.bv_len = msg1.length;
|
cred.bv_len = msg1.length;
|
||||||
|
|
||||||
rc = ldap_sasl_bind_s(ads->ld, NULL, "GSS-SPNEGO", &cred, NULL, NULL, &scred);
|
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,
|
nthash, 24,
|
||||||
lp_workgroup(),
|
lp_workgroup(),
|
||||||
ads->auth.user_name,
|
ads->auth.user_name,
|
||||||
lp_netbios_name(),
|
global_myname(),
|
||||||
sess_key, 16,
|
sess_key, 16,
|
||||||
neg_flags);
|
neg_flags);
|
||||||
|
|
||||||
@@ -106,7 +106,7 @@ static ADS_STATUS ads_sasl_spnego_ntlmssp_bind(ADS_STRUCT *ads)
|
|||||||
data_blob_free(&blob);
|
data_blob_free(&blob);
|
||||||
|
|
||||||
/* now send the auth packet and we should be done */
|
/* 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;
|
cred.bv_len = auth.length;
|
||||||
|
|
||||||
rc = ldap_sasl_bind_s(ads->ld, NULL, "GSS-SPNEGO", &cred, NULL, NULL, &scred);
|
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;
|
DATA_BLOB blob;
|
||||||
struct berval cred, *scred;
|
struct berval cred, *scred;
|
||||||
|
DATA_BLOB session_key;
|
||||||
int rc;
|
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) {
|
if (rc) {
|
||||||
return ADS_ERROR(LDAP_OPERATIONS_ERROR);
|
return ADS_ERROR_KRB5(rc);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* now send the auth packet and we should be done */
|
/* 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;
|
cred.bv_len = blob.length;
|
||||||
|
|
||||||
rc = ldap_sasl_bind_s(ads->ld, NULL, "GSS-SPNEGO", &cred, NULL, NULL, &scred);
|
rc = ldap_sasl_bind_s(ads->ld, NULL, "GSS-SPNEGO", &cred, NULL, NULL, &scred);
|
||||||
|
|
||||||
data_blob_free(&blob);
|
data_blob_free(&blob);
|
||||||
|
data_blob_free(&session_key);
|
||||||
|
|
||||||
return ADS_ERROR(rc);
|
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);
|
blob = data_blob(scred->bv_val, scred->bv_len);
|
||||||
|
|
||||||
|
ber_bvfree(scred);
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
file_save("sasl_spnego.dat", blob.data, blob.length);
|
file_save("sasl_spnego.dat", blob.data, blob.length);
|
||||||
#endif
|
#endif
|
||||||
@@ -195,11 +199,18 @@ static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads)
|
|||||||
status = ads_sasl_spnego_krb5_bind(ads, principal);
|
status = ads_sasl_spnego_krb5_bind(ads, principal);
|
||||||
if (ADS_ERR_OK(status))
|
if (ADS_ERR_OK(status))
|
||||||
return 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);
|
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;
|
return status;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -223,13 +234,13 @@ failed:
|
|||||||
*/
|
*/
|
||||||
static ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads)
|
static ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads)
|
||||||
{
|
{
|
||||||
int minor_status;
|
uint32 minor_status;
|
||||||
gss_name_t serv_name;
|
gss_name_t serv_name;
|
||||||
gss_buffer_desc input_name;
|
gss_buffer_desc input_name;
|
||||||
gss_ctx_id_t context_handle;
|
gss_ctx_id_t context_handle;
|
||||||
gss_OID mech_type = GSS_C_NULL_OID;
|
gss_OID mech_type = GSS_C_NULL_OID;
|
||||||
gss_buffer_desc output_token, input_token;
|
gss_buffer_desc output_token, input_token;
|
||||||
OM_uint32 ret_flags, conf_state;
|
uint32 ret_flags, conf_state;
|
||||||
struct berval cred;
|
struct berval cred;
|
||||||
struct berval *scred;
|
struct berval *scred;
|
||||||
int i=0;
|
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_release_name(&minor_status, &serv_name);
|
||||||
|
|
||||||
gss_rc = gss_unwrap(&minor_status,context_handle,&input_token,&output_token,
|
gss_rc = gss_unwrap(&minor_status,context_handle,&input_token,&output_token,
|
||||||
&conf_state,NULL);
|
(int *)&conf_state,NULL);
|
||||||
if (gss_rc) {
|
if (gss_rc) {
|
||||||
status = ADS_ERROR_GSS(gss_rc, minor_status);
|
status = ADS_ERROR_GSS(gss_rc, minor_status);
|
||||||
goto failed;
|
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>>16;
|
||||||
*p++ = max_msg_size>>8;
|
*p++ = max_msg_size>>8;
|
||||||
*p++ = max_msg_size;
|
*p++ = max_msg_size;
|
||||||
snprintf(p, strlen(ads->config.bind_path)+4, "dn:%s", ads->config.bind_path);
|
snprintf((char *)p, strlen(ads->config.bind_path)+4, "dn:%s", ads->config.bind_path);
|
||||||
p += strlen(p);
|
p += strlen((const char *)p);
|
||||||
|
|
||||||
output_token.length = PTR_DIFF(p, output_token.value);
|
output_token.length = PTR_DIFF(p, output_token.value);
|
||||||
|
|
||||||
gss_rc = gss_wrap(&minor_status, context_handle,0,GSS_C_QOP_DEFAULT,
|
gss_rc = gss_wrap(&minor_status, context_handle,0,GSS_C_QOP_DEFAULT,
|
||||||
&output_token, &conf_state,
|
&output_token, (int *)&conf_state,
|
||||||
&input_token);
|
&input_token);
|
||||||
if (gss_rc) {
|
if (gss_rc) {
|
||||||
status = ADS_ERROR_GSS(gss_rc, minor_status);
|
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)
|
ADS_STATUS ads_change_trust_account_password(ADS_STRUCT *ads, char *host_principal)
|
||||||
{
|
{
|
||||||
char *tmp_password;
|
char *tmp_password;
|
||||||
char *password;
|
char *password;
|
||||||
char *new_password;
|
char *new_password;
|
||||||
char *service_principal;
|
char *service_principal = NULL;
|
||||||
ADS_STATUS ret;
|
ADS_STATUS ret;
|
||||||
|
uint32 sec_channel_type;
|
||||||
|
|
||||||
if ((password = secrets_fetch_machine_password()) == NULL) {
|
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));
|
DEBUG(1,("Failed to retrieve password for principal %s\n", host_principal));
|
||||||
return ADS_ERROR_SYSTEM(ENOENT);
|
return ADS_ERROR_SYSTEM(ENOENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
tmp_password = generate_random_str(DEFAULT_TRUST_ACCOUNT_PASSWORD_LENGTH);
|
tmp_password = generate_random_str(DEFAULT_TRUST_ACCOUNT_PASSWORD_LENGTH);
|
||||||
new_password = strdup(tmp_password);
|
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);
|
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)) {
|
ret = kerberos_set_password(ads->auth.kdc_server, service_principal, password, service_principal, new_password, ads->auth.time_offset);
|
||||||
DEBUG(1,("Failed to save machine password\n"));
|
|
||||||
return ADS_ERROR_SYSTEM(EACCES);
|
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:
|
failed:
|
||||||
SAFE_FREE(service_principal);
|
SAFE_FREE(service_principal);
|
||||||
SAFE_FREE(new_password);
|
SAFE_FREE(new_password);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -97,7 +97,9 @@
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
krb5_use_enctype(context, &eblock, enctype);
|
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)
|
#elif defined(HAVE_KRB5_GET_PW_SALT) && defined(HAVE_KRB5_STRING_TO_KEY_SALT)
|
||||||
int create_kerberos_key_from_string(krb5_context context,
|
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
|
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,
|
static krb5_error_code ads_krb5_mk_req(krb5_context context,
|
||||||
krb5_auth_context *auth_context,
|
krb5_auth_context *auth_context,
|
||||||
const krb5_flags ap_req_options,
|
const krb5_flags ap_req_options,
|
||||||
const char *principal,
|
const char *principal,
|
||||||
krb5_ccache ccache,
|
krb5_ccache ccache,
|
||||||
krb5_data *outbuf)
|
krb5_data *outbuf)
|
||||||
{
|
{
|
||||||
krb5_error_code retval;
|
krb5_error_code retval;
|
||||||
krb5_principal server;
|
krb5_principal server;
|
||||||
@@ -255,7 +257,7 @@ static krb5_error_code krb5_mk_req2(krb5_context context,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* obtain ticket & session key */
|
/* obtain ticket & session key */
|
||||||
memset((char *)&creds, 0, sizeof(creds));
|
ZERO_STRUCT(creds);
|
||||||
if ((retval = krb5_copy_principal(context, server, &creds.server))) {
|
if ((retval = krb5_copy_principal(context, server, &creds.server))) {
|
||||||
DEBUG(1,("krb5_copy_principal failed (%s)\n",
|
DEBUG(1,("krb5_copy_principal failed (%s)\n",
|
||||||
error_message(retval)));
|
error_message(retval)));
|
||||||
@@ -305,14 +307,14 @@ cleanup_princ:
|
|||||||
/*
|
/*
|
||||||
get a kerberos5 ticket for the given service
|
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_error_code retval;
|
||||||
krb5_data packet;
|
krb5_data packet;
|
||||||
krb5_ccache ccdef;
|
krb5_ccache ccdef;
|
||||||
krb5_context context;
|
krb5_context context;
|
||||||
krb5_auth_context auth_context = NULL;
|
krb5_auth_context auth_context = NULL;
|
||||||
DATA_BLOB ret;
|
|
||||||
krb5_enctype enc_types[] = {
|
krb5_enctype enc_types[] = {
|
||||||
#ifdef ENCTYPE_ARCFOUR_HMAC
|
#ifdef ENCTYPE_ARCFOUR_HMAC
|
||||||
ENCTYPE_ARCFOUR_HMAC,
|
ENCTYPE_ARCFOUR_HMAC,
|
||||||
@@ -344,56 +346,76 @@ DATA_BLOB krb5_get_ticket(const char *principal, time_t time_offset)
|
|||||||
goto failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((retval = krb5_mk_req2(context,
|
if ((retval = ads_krb5_mk_req(context,
|
||||||
&auth_context,
|
&auth_context,
|
||||||
0,
|
AP_OPTS_USE_SUBKEY,
|
||||||
principal,
|
principal,
|
||||||
ccdef, &packet))) {
|
ccdef, &packet))) {
|
||||||
goto failed;
|
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? */
|
/* Hmm, heimdal dooesn't have this - what's the correct call? */
|
||||||
/* krb5_free_data_contents(context, &packet); */
|
#ifdef HAVE_KRB5_FREE_DATA_CONTENTS
|
||||||
krb5_free_context(context);
|
krb5_free_data_contents(context, &packet);
|
||||||
return ret;
|
#endif
|
||||||
|
|
||||||
failed:
|
failed:
|
||||||
if ( context )
|
if ( context )
|
||||||
krb5_free_context(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;
|
krb5_keyblock *skey;
|
||||||
#endif
|
krb5_error_code err;
|
||||||
BOOL ret = False;
|
BOOL ret = False;
|
||||||
|
|
||||||
memset(session_key, 0, 16);
|
memset(session_key, 0, 16);
|
||||||
|
|
||||||
#ifdef ENCTYPE_ARCFOUR_HMAC
|
if (remote)
|
||||||
if (krb5_auth_con_getremotesubkey(context, auth_context, &skey) == 0 && skey != NULL) {
|
err = krb5_auth_con_getremotesubkey(context, auth_context, &skey);
|
||||||
if (KRB5_KEY_TYPE(skey) ==
|
else
|
||||||
ENCTYPE_ARCFOUR_HMAC
|
err = krb5_auth_con_getlocalsubkey(context, auth_context, &skey);
|
||||||
&& KRB5_KEY_LENGTH(skey) == 16) {
|
if (err == 0 && skey != NULL) {
|
||||||
memcpy(session_key, KRB5_KEY_DATA(skey), KRB5_KEY_LENGTH(skey));
|
DEBUG(10, ("Got KRB5 session key of length %d\n", KRB5_KEY_LENGTH(skey)));
|
||||||
ret = True;
|
*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);
|
krb5_free_keyblock(context, skey);
|
||||||
|
} else {
|
||||||
|
DEBUG(10, ("KRB5 error getting session key %d\n", err));
|
||||||
}
|
}
|
||||||
#endif /* ENCTYPE_ARCFOUR_HMAC */
|
|
||||||
|
|
||||||
return ret;
|
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 */
|
#else /* HAVE_KRB5 */
|
||||||
/* this saves a few linking headaches */
|
/* this saves a few linking headaches */
|
||||||
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)
|
||||||
|
{
|
||||||
DEBUG(0,("NO KERBEROS SUPPORT\n"));
|
DEBUG(0,("NO KERBEROS SUPPORT\n"));
|
||||||
return data_blob(NULL, 0);
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
Unix SMB/CIFS implementation.
|
Unix SMB/CIFS implementation.
|
||||||
simple kerberos5/SPNEGO routines
|
simple kerberos5/SPNEGO routines
|
||||||
Copyright (C) Andrew Tridgell 2001
|
Copyright (C) Andrew Tridgell 2001
|
||||||
Copyright (C) Jim McDonough 2002
|
Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2002
|
||||||
Copyright (C) Luke Howard 2003
|
Copyright (C) Luke Howard 2003
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
generate a SPNEGO negTokenTarg packet, ready for a EXTENDED_SECURITY
|
||||||
kerberos session setup
|
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};
|
const char *krb_mechs[] = {OID_KERBEROS5_OLD, OID_NTLMSSP, NULL};
|
||||||
|
|
||||||
/* get a kerberos ticket for the service */
|
/* get a kerberos ticket for the service and extract the session key */
|
||||||
tkt = krb5_get_ticket(principal, time_offset);
|
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 */
|
/* wrap that up in a nice GSS-API wrapping */
|
||||||
tkt_wrapped = spnego_gen_krb5_wrap(tkt, TOK_ID_KRB_AP_REQ);
|
tkt_wrapped = spnego_gen_krb5_wrap(tkt, TOK_ID_KRB_AP_REQ);
|
||||||
|
|
||||||
/* and wrap that in a shiny SPNEGO wrapper */
|
/* 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_wrapped);
|
||||||
data_blob_free(&tkt);
|
data_blob_free(&tkt);
|
||||||
|
|
||||||
return targ;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user