File indexing completed on 2024-04-28 04:58:02
0001 /* 0002 SPDX-License-Identifier: GPL-2.0-or-later 0003 SPDX-FileCopyrightText: 2000 Caldera Systems Inc. 0004 SPDX-FileCopyrightText: 2020 Harald Sitter <sitter@kde.org> 0005 SPDX-FileContributor: Matthew Peterson <mpeterson@caldera.com> 0006 */ 0007 0008 #include "smbcontext.h" 0009 0010 #include <KConfig> 0011 #include <KConfigGroup> 0012 0013 #include "smb-logsettings.h" 0014 #include "smbauthenticator.h" 0015 0016 SMBContext::SMBContext(SMBAuthenticator *authenticator) 0017 : m_context(smbc_new_context(), &freeContext) 0018 , m_authenticator(authenticator) 0019 { 0020 Q_ASSERT(m_context); 0021 if (!m_context) { 0022 return; 0023 } 0024 0025 qCDebug(KIO_SMB_LOG) << "auth_initialize_smbc"; 0026 0027 KConfig cfg("kioslaverc", KConfig::SimpleConfig); 0028 int debugLevel = cfg.group("SMB").readEntry("DebugLevel", 0); 0029 qCDebug(KIO_SMB_LOG) << "Setting debug level to:" << debugLevel; 0030 0031 #ifdef DEPRECATED_SMBC_INTERFACE // defined by libsmbclient.h of Samba 3.2 0032 smbc_setOptionUserData(m_context.get(), this); 0033 smbc_setFunctionAuthDataWithContext(m_context.get(), auth_cb); 0034 0035 /* New libsmbclient interface of Samba 3.2 */ 0036 smbc_setDebug(m_context.get(), debugLevel); 0037 0038 /* Enable Kerberos support */ 0039 smbc_setOptionUseKerberos(m_context.get(), 1); 0040 smbc_setOptionFallbackAfterKerberos(m_context.get(), 1); 0041 #else 0042 smbc_option_set(m_context.get(), "user_data", this); 0043 m_context->callbacks.auth_fn = NULL; 0044 smbc_option_set(m_context.get(), "auth_function", (void *)auth_cb); 0045 0046 m_context->debug = debug_level; 0047 0048 #if defined(SMB_CTX_FLAG_USE_KERBEROS) && defined(SMB_CTX_FLAG_FALLBACK_AFTER_KERBEROS) 0049 m_context->flags |= SMB_CTX_FLAG_USE_KERBEROS | SMB_CTX_FLAG_FALLBACK_AFTER_KERBEROS; 0050 #endif 0051 #endif /* DEPRECATED_SMBC_INTERFACE */ 0052 0053 if (!smbc_init_context(m_context.get())) { 0054 m_context.reset(); 0055 return; 0056 } 0057 0058 smbc_set_context(m_context.get()); 0059 0060 // TODO: refactor; checkPassword should query this on 0061 // demand to not run into situations where we may have cached 0062 // the workgroup early on and it changed since. Needs context 0063 // being held in the worker though, which opens us up to nullptr 0064 // problems should checkPassword be called without init first. 0065 authenticator->setDefaultWorkgroup(smbc_getWorkgroup(*this)); 0066 0067 return; 0068 } 0069 0070 bool SMBContext::isValid() const 0071 { 0072 return smbcctx() && authenticator(); 0073 } 0074 0075 void SMBContext::auth_cb(SMBCCTX *context, 0076 const char *server, 0077 const char *share, 0078 char *workgroup, 0079 int wgmaxlen, 0080 char *username, 0081 int unmaxlen, 0082 char *password, 0083 int pwmaxlen) 0084 { 0085 // Unfortunately because the callback API doesn't support callback specific user_data we need 0086 // to route all auths through our context object otherwise the authenticator would have 0087 // to twiddle the global context user_data and that seems much worse :| 0088 if (context != nullptr) { 0089 #ifdef DEPRECATED_SMBC_INTERFACE 0090 auto *that = static_cast<SMBContext *>(smbc_getOptionUserData(context)); 0091 #else 0092 auto *that = static_cast<SMBCContext *>(smbc_option_get(context, "user_data")); 0093 #endif 0094 that->m_authenticator->auth(context, server, share, workgroup, wgmaxlen, username, unmaxlen, password, pwmaxlen); 0095 } 0096 } 0097 0098 void SMBContext::freeContext(SMBCCTX *ptr) 0099 { 0100 smbc_free_context(ptr, 1); 0101 }