From e9063e1243f023e6f2e1ac93d5809b66acd3f23c Mon Sep 17 00:00:00 2001 From: Dmitry Timoshkov Date: Wed, 18 Oct 2017 10:42:13 +0800 Subject: [PATCH] kerberos: Add a stub for Kerberos5 Authentication Package. Signed-off-by: Dmitry Timoshkov Signed-off-by: Hans Leidekker Signed-off-by: Alexandre Julliard --- configure | 122 +++++++++++++++++++++++++ configure.ac | 17 ++++ dlls/kerberos/Makefile.in | 5 ++ dlls/kerberos/kerberos.spec | 12 +++ dlls/kerberos/krb5_ap.c | 175 ++++++++++++++++++++++++++++++++++++ include/config.h.in | 6 ++ include/ntsecapi.h | 12 +++ 7 files changed, 349 insertions(+) create mode 100644 dlls/kerberos/Makefile.in create mode 100644 dlls/kerberos/kerberos.spec create mode 100644 dlls/kerberos/krb5_ap.c diff --git a/configure b/configure index e2c35a9a9bc..014dd46e01e 100755 --- a/configure +++ b/configure @@ -648,6 +648,8 @@ PNG_LIBS PNG_CFLAGS JPEG_LIBS JPEG_CFLAGS +KRB5_LIBS +KRB5_CFLAGS FONTCONFIG_LIBS FONTCONFIG_CFLAGS CUPS_LIBS @@ -838,6 +840,7 @@ with_gsm with_gstreamer with_hal with_jpeg +with_krb5 with_ldap with_mpg123 with_netapi @@ -1276,6 +1279,7 @@ enable_itss enable_joy_cpl enable_jscript enable_jsproxy +enable_kerberos enable_kernel32 enable_kernelbase enable_ksuser @@ -1722,6 +1726,8 @@ CUPS_CFLAGS CUPS_LIBS FONTCONFIG_CFLAGS FONTCONFIG_LIBS +KRB5_CFLAGS +KRB5_LIBS JPEG_CFLAGS JPEG_LIBS PNG_CFLAGS @@ -2391,6 +2397,7 @@ Optional Packages: --without-gstreamer do not use GStreamer (codecs support) --without-hal do not use HAL (dynamic device support) --without-jpeg do not use JPEG + --without-krb5 do not use krb5 (Kerberos) --without-ldap do not use LDAP --without-mpg123 do not use the mpg123 library --without-netapi do not use the Samba NetAPI library @@ -2485,6 +2492,8 @@ Some influential environment variables: C compiler flags for fontconfig, overriding pkg-config FONTCONFIG_LIBS Linker flags for fontconfig, overriding pkg-config + KRB5_CFLAGS C compiler flags for krb5, overriding pkg-config + KRB5_LIBS Linker flags for krb5, overriding pkg-config JPEG_CFLAGS C compiler flags for libjpeg, overriding pkg-config JPEG_LIBS Linker flags for libjpeg, overriding pkg-config PNG_CFLAGS C compiler flags for libpng, overriding pkg-config @@ -3600,6 +3609,12 @@ if test "${with_jpeg+set}" = set; then : fi +# Check whether --with-krb5 was given. +if test "${with_krb5+set}" = set; then : + withval=$with_krb5; +fi + + # Check whether --with-ldap was given. if test "${with_ldap+set}" = set; then : withval=$with_ldap; if test "x$withval" = "xno"; then ac_cv_header_ldap_h=no; ac_cv_header_lber_h=no; fi @@ -13730,6 +13745,110 @@ esac fi +if test "x$with_krb5" != "xno" +then + if ${KRB5_CFLAGS:+false} :; then : + if ${PKG_CONFIG+:} false; then : + KRB5_CFLAGS=`$PKG_CONFIG --cflags krb5 2>/dev/null` +fi +fi +test "$cross_compiling" = yes || KRB5_CFLAGS=${KRB5_CFLAGS:-`krb5-config --cflags`} +if ${KRB5_LIBS:+false} :; then : + if ${PKG_CONFIG+:} false; then : + KRB5_LIBS=`$PKG_CONFIG --libs krb5 2>/dev/null` +fi +fi +test "$cross_compiling" = yes || KRB5_LIBS=${KRB5_LIBS:-`krb5-config --libs`} + +$as_echo "$as_me:${as_lineno-$LINENO}: krb5 cflags: $KRB5_CFLAGS" >&5 +$as_echo "$as_me:${as_lineno-$LINENO}: krb5 libs: $KRB5_LIBS" >&5 +ac_save_CPPFLAGS=$CPPFLAGS +CPPFLAGS="$CPPFLAGS $KRB5_CFLAGS" +for ac_header in krb5/krb5.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "krb5/krb5.h" "ac_cv_header_krb5_krb5_h" "$ac_includes_default" +if test "x$ac_cv_header_krb5_krb5_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_KRB5_KRB5_H 1 +_ACEOF + +fi + +done + + if test "$ac_cv_header_krb5_krb5_h" = "yes" + then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -lkrb5" >&5 +$as_echo_n "checking for -lkrb5... " >&6; } +if ${ac_cv_lib_soname_krb5+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_soname_save_LIBS=$LIBS +LIBS="-lkrb5 $KRB5_LIBS $LIBS" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char krb5_init_context (); +int +main () +{ +return krb5_init_context (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + case "$LIBEXT" in + dll) ac_cv_lib_soname_krb5=`$ac_cv_path_LDD conftest.exe | grep "krb5" | sed -e "s/dll.*/dll/"';2,$d'` ;; + dylib) ac_cv_lib_soname_krb5=`$OTOOL -L conftest$ac_exeext | grep "libkrb5\\.[0-9A-Za-z.]*dylib" | sed -e "s/^.*\/\(libkrb5\.[0-9A-Za-z.]*dylib\).*$/\1/"';2,$d'` ;; + *) ac_cv_lib_soname_krb5=`$READELF -d conftest$ac_exeext | grep "NEEDED.*libkrb5\\.$LIBEXT" | sed -e "s/^.*\\[\\(libkrb5\\.$LIBEXT[^ ]*\\)\\].*$/\1/"';2,$d'` + if ${ac_cv_lib_soname_krb5:+false} :; then : + ac_cv_lib_soname_krb5=`$LDD conftest$ac_exeext | grep "libkrb5\\.$LIBEXT" | sed -e "s/^.*\(libkrb5\.$LIBEXT[^ ]*\).*$/\1/"';2,$d'` +fi ;; + esac +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LIBS=$ac_check_soname_save_LIBS +fi +if ${ac_cv_lib_soname_krb5:+false} :; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5 +$as_echo "not found" >&6; } + KRB5_CFLAGS="" +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_soname_krb5" >&5 +$as_echo "$ac_cv_lib_soname_krb5" >&6; } + +cat >>confdefs.h <<_ACEOF +#define SONAME_LIBKRB5 "$ac_cv_lib_soname_krb5" +_ACEOF + + +fi + else + KRB5_CFLAGS="" + fi +CPPFLAGS=$ac_save_CPPFLAGS +test -z "$KRB5_CFLAGS" || KRB5_CFLAGS=`echo " $KRB5_CFLAGS" | sed 's/ -I\([^/]\)/ -I\$(top_builddir)\/\1/g'` +test -z "$KRB5_LIBS" || KRB5_LIBS=`echo " $KRB5_LIBS" | sed 's/ -L\([^/]\)/ -L\$(top_builddir)\/\1/g'` + +fi +if test "x$ac_cv_lib_soname_krb5" = "x"; then : + case "x$with_krb5" in + x) as_fn_append wine_notices "|libkrb5 ${notice_platform}development files not found, Kerberos won't be supported." ;; + xno) ;; + *) as_fn_error $? "libkrb5 ${notice_platform}development files not found, Kerberos won't be supported. +This is an error since --with-krb5 was requested." "$LINENO" 5 ;; +esac + +fi + if test "x$with_jpeg" != "xno" then if ${JPEG_CFLAGS:+false} :; then : @@ -17904,6 +18023,8 @@ CUPS_CFLAGS = $CUPS_CFLAGS CUPS_LIBS = $CUPS_LIBS FONTCONFIG_CFLAGS = $FONTCONFIG_CFLAGS FONTCONFIG_LIBS = $FONTCONFIG_LIBS +KRB5_CFLAGS = $KRB5_CFLAGS +KRB5_LIBS = $KRB5_LIBS JPEG_CFLAGS = $JPEG_CFLAGS JPEG_LIBS = $JPEG_LIBS PNG_CFLAGS = $PNG_CFLAGS @@ -18455,6 +18576,7 @@ wine_fn_config_dll jscript enable_jscript clean wine_fn_config_test dlls/jscript/tests jscript_test wine_fn_config_dll jsproxy enable_jsproxy implib wine_fn_config_test dlls/jsproxy/tests jsproxy_test +wine_fn_config_dll kerberos enable_kerberos wine_fn_config_dll kernel32 enable_kernel32 clean,implib wine_fn_config_test dlls/kernel32/tests kernel32_test wine_fn_config_dll kernelbase enable_kernelbase diff --git a/configure.ac b/configure.ac index 58737162a8c..04091fc0ec9 100644 --- a/configure.ac +++ b/configure.ac @@ -56,6 +56,7 @@ AC_ARG_WITH(gsm, AS_HELP_STRING([--without-gsm],[do not use libgsm (GSM 06 AC_ARG_WITH(gstreamer, AS_HELP_STRING([--without-gstreamer],[do not use GStreamer (codecs support)])) AC_ARG_WITH(hal, AS_HELP_STRING([--without-hal],[do not use HAL (dynamic device support)])) AC_ARG_WITH(jpeg, AS_HELP_STRING([--without-jpeg],[do not use JPEG])) +AC_ARG_WITH(krb5, AS_HELP_STRING([--without-krb5],[do not use krb5 (Kerberos)])) AC_ARG_WITH(ldap, AS_HELP_STRING([--without-ldap],[do not use LDAP]), [if test "x$withval" = "xno"; then ac_cv_header_ldap_h=no; ac_cv_header_lber_h=no; fi]) AC_ARG_WITH(mpg123, AS_HELP_STRING([--without-mpg123],[do not use the mpg123 library])) @@ -1625,6 +1626,21 @@ fi WINE_NOTICE_WITH(gsm,[test "x$ac_cv_lib_soname_gsm" = "x"], [libgsm ${notice_platform}development files not found, gsm 06.10 codec won't be supported.]) +dnl **** Check for krb5 **** +if test "x$with_krb5" != "xno" +then + WINE_PACKAGE_FLAGS(KRB5,[krb5],,[`krb5-config --cflags`],[`krb5-config --libs`], + [AC_CHECK_HEADERS([krb5/krb5.h]) + if test "$ac_cv_header_krb5_krb5_h" = "yes" + then + WINE_CHECK_SONAME(krb5,krb5_init_context,,[KRB5_CFLAGS=""],[$KRB5_LIBS]) + else + KRB5_CFLAGS="" + fi]) +fi +WINE_NOTICE_WITH(krb5,[test "x$ac_cv_lib_soname_krb5" = "x"], + [libkrb5 ${notice_platform}development files not found, Kerberos won't be supported.]) + dnl **** Check for libjpeg **** if test "x$with_jpeg" != "xno" then @@ -3216,6 +3232,7 @@ WINE_CONFIG_DLL(jscript,,[clean]) WINE_CONFIG_TEST(dlls/jscript/tests) WINE_CONFIG_DLL(jsproxy,,[implib]) WINE_CONFIG_TEST(dlls/jsproxy/tests) +WINE_CONFIG_DLL(kerberos) WINE_CONFIG_DLL(kernel32,,[clean,implib]) WINE_CONFIG_TEST(dlls/kernel32/tests) WINE_CONFIG_DLL(kernelbase) diff --git a/dlls/kerberos/Makefile.in b/dlls/kerberos/Makefile.in new file mode 100644 index 00000000000..253e9447164 --- /dev/null +++ b/dlls/kerberos/Makefile.in @@ -0,0 +1,5 @@ +MODULE = kerberos.dll +EXTRAINCL = $(KRB5_CFLAGS) + +C_SRCS = \ + krb5_ap.c diff --git a/dlls/kerberos/kerberos.spec b/dlls/kerberos/kerberos.spec new file mode 100644 index 00000000000..c41b830e46f --- /dev/null +++ b/dlls/kerberos/kerberos.spec @@ -0,0 +1,12 @@ +1 stub SpInitialize +2 stub KerbDomainChangeCallback +3 stdcall SpLsaModeInitialize(long ptr ptr ptr) +4 stub SpUserModeInitialize +32 stub SpInstanceInit + +@ stdcall -private DllMain(long long ptr) +@ stub KerbCreateTokenFromTicket +@ stub KerbIsInitialized +@ stub KerbKdcCallBack +@ stub KerbMakeKdcCall +@ stub Kerberos diff --git a/dlls/kerberos/krb5_ap.c b/dlls/kerberos/krb5_ap.c new file mode 100644 index 00000000000..0134b94f6d0 --- /dev/null +++ b/dlls/kerberos/krb5_ap.c @@ -0,0 +1,175 @@ +/* + * Copyright 2017 Dmitry Timoshkov + * + * Kerberos5 Authentication Package + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "config.h" +#include "wine/port.h" + +#include +#ifdef HAVE_KRB5_KRB5_H +#include +#endif + +#include "ntstatus.h" +#define WIN32_NO_STATUS +#include "windef.h" +#include "winbase.h" +#include "sspi.h" +#include "ntsecapi.h" +#include "ntsecpkg.h" +#include "winternl.h" +#include "wine/library.h" +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(krb5); + +static ULONG krb5_package_id; +static LSA_DISPATCH_TABLE lsa_dispatch; + +#ifdef SONAME_LIBKRB5 + +static void *libkrb5_handle; + +#define MAKE_FUNCPTR(f) static typeof(f) * p_##f +MAKE_FUNCPTR(krb5_init_context); +#undef MAKE_FUNCPTR + +static void load_krb5(void) +{ + if (!(libkrb5_handle = wine_dlopen(SONAME_LIBKRB5, RTLD_NOW, NULL, 0))) + { + WARN("Failed to load %s, Kerberos support will be disabled\n", SONAME_LIBKRB5); + return; + } + +#define LOAD_FUNCPTR(f) \ + if (!(p_##f = wine_dlsym(libkrb5_handle, #f, NULL, 0))) \ + { \ + ERR("Failed to load %s\n", #f); \ + goto fail; \ + } + + LOAD_FUNCPTR(krb5_init_context) +#undef LOAD_FUNCPTR + + return; + +fail: + wine_dlclose(libkrb5_handle, NULL, 0); + libkrb5_handle = NULL; +} + +#else /* SONAME_LIBKRB5 */ + +static void load_krb5(void) +{ + WARN("Kerberos support was not provided at compile time\n"); +} + +#endif /* SONAME_LIBKRB5 */ + +static NTSTATUS NTAPI krb5_LsaApInitializePackage(ULONG package_id, PLSA_DISPATCH_TABLE dispatch, + PLSA_STRING database, PLSA_STRING confidentiality, PLSA_STRING *package_name) +{ + char *krb5_name; + + load_krb5(); + + krb5_package_id = package_id; + lsa_dispatch = *dispatch; + + krb5_name = lsa_dispatch.AllocateLsaHeap(sizeof(MICROSOFT_KERBEROS_NAME_A)); + if (!krb5_name) return STATUS_NO_MEMORY; + + memcpy(krb5_name, MICROSOFT_KERBEROS_NAME_A, sizeof(MICROSOFT_KERBEROS_NAME_A)); + + *package_name = lsa_dispatch.AllocateLsaHeap(sizeof(**package_name)); + if (!*package_name) + { + lsa_dispatch.FreeLsaHeap(krb5_name); + return STATUS_NO_MEMORY; + } + + RtlInitString(*package_name, krb5_name); + + return STATUS_SUCCESS; +} + +static NTSTATUS NTAPI krb5_LsaApCallPackageUntrusted(PLSA_CLIENT_REQUEST request, + PVOID in_buffer, PVOID client_buffer_base, ULONG in_buffer_length, + PVOID *out_buffer, PULONG out_buffer_length, PNTSTATUS status) +{ + FIXME("%p,%p,%p,%u,%p,%p,%p: stub\n", request, in_buffer, client_buffer_base, + in_buffer_length, out_buffer, out_buffer_length, status); + + *status = STATUS_NOT_IMPLEMENTED; + return STATUS_NOT_IMPLEMENTED; +} + +static SECPKG_FUNCTION_TABLE krb5_table = +{ + krb5_LsaApInitializePackage, /* InitializePackage */ + NULL, /* LsaLogonUser */ + NULL, /* CallPackage */ + NULL, /* LogonTerminated */ + krb5_LsaApCallPackageUntrusted, /* CallPackageUntrusted */ + NULL, /* CallPackagePassthrough */ + NULL, /* LogonUserEx */ + NULL, /* LogonUserEx2 */ + NULL, /* Initialize */ + NULL, /* Shutdown */ + NULL, /* SpGetInfoUnified */ + NULL, /* AcceptCredentials */ + NULL, /* SpAcquireCredentialsHandle */ + NULL, /* SpQueryCredentialsAttributes */ + NULL, /* FreeCredentialsHandle */ + NULL, /* SaveCredentials */ + NULL, /* GetCredentials */ + NULL, /* DeleteCredentials */ + NULL, /* InitLsaModeContext */ + NULL, /* AcceptLsaModeContext */ + NULL, /* DeleteContext */ + NULL, /* ApplyControlToken */ + NULL, /* GetUserInfo */ + NULL, /* GetExtendedInformation */ + NULL, /* SpQueryContextAttributes */ + NULL, /* SpAddCredentials */ + NULL, /* SetExtendedInformation */ + NULL, /* SetContextAttributes */ + NULL, /* SetCredentialsAttributes */ + NULL, /* ChangeAccountPassword */ + NULL, /* QueryMetaData */ + NULL, /* ExchangeMetaData */ + NULL, /* GetCredUIContext */ + NULL, /* UpdateCredentials */ + NULL, /* ValidateTargetInfo */ + NULL, /* PostLogonUser */ +}; + +NTSTATUS NTAPI SpLsaModeInitialize(ULONG lsa_version, PULONG package_version, + PSECPKG_FUNCTION_TABLE *table, PULONG table_count) +{ + TRACE("%#x,%p,%p,%p\n", lsa_version, package_version, table, table_count); + + *package_version = SECPKG_INTERFACE_VERSION; + *table = &krb5_table; + *table_count = 1; + + return STATUS_SUCCESS; +} diff --git a/include/config.h.in b/include/config.h.in index dd7a3a2ef67..a6ec41b5fa9 100644 --- a/include/config.h.in +++ b/include/config.h.in @@ -342,6 +342,9 @@ /* Define to 1 if you have the `kqueue' function. */ #undef HAVE_KQUEUE +/* Define to 1 if you have the header file. */ +#undef HAVE_KRB5_KRB5_H + /* Define to 1 if you have the header file. */ #undef HAVE_KSTAT_H @@ -1475,6 +1478,9 @@ /* Define to the soname of the libjpeg library. */ #undef SONAME_LIBJPEG +/* Define to the soname of the libkrb5 library. */ +#undef SONAME_LIBKRB5 + /* Define to the soname of the libncurses library. */ #undef SONAME_LIBNCURSES diff --git a/include/ntsecapi.h b/include/ntsecapi.h index 2bb3d312e43..36357c61b46 100644 --- a/include/ntsecapi.h +++ b/include/ntsecapi.h @@ -340,6 +340,18 @@ typedef enum _POLICY_NOTIFICATION_INFORMATION_CLASS PolicyNotifyMachineAccountPasswordInformation } POLICY_NOTIFICATION_INFORMATION_CLASS, *PPOLICY_NOTIFICATION_INFORMATION_CLASS; +#ifdef UNICODE +#if defined(_MSC_VER) +#define MICROSOFT_KERBEROS_NAME_W L"Kerberos" +#elif defined(__GNUC__) +#define MICROSOFT_KERBEROS_NAME_W (const WCHAR []){ 'K','e','r','b','e','r','o','s',0 } +#else /* _MSC_VER/__GNUC__ */ +static const WCHAR MICROSOFT_KERBEROS_NAME_W[] = { 'K','e','r','b','e','r','o','s',0 }; +#endif +#else /* UNICODE */ +#define MICROSOFT_KERBEROS_NAME_A "Kerberos" +#endif + #define RtlGenRandom SystemFunction036 #define RtlEncryptMemory SystemFunction040 #define RtlDecryptMemory SystemFunction041