File indexing completed on 2024-04-28 04:58:00
0001 /* 0002 SPDX-License-Identifier: GPL-2.0-or-later 0003 SPDX-FileCopyrightText: 2000 Caldera Systems Inc. 0004 SPDX-FileCopyrightText: 2021-2022 Harald Sitter <sitter@kde.org> 0005 SPDX-FileContributor: Matthew Peterson <mpeterson@caldera.com> 0006 */ 0007 0008 #ifndef KIO_SMB_H_INCLUDED 0009 #define KIO_SMB_H_INCLUDED 0010 0011 #include <config-smb.h> 0012 0013 #include "smb-logsettings.h" 0014 0015 //-------------- 0016 // KF includes 0017 //-------------- 0018 #include <KIO/Global> 0019 #include <KIO/WorkerBase> 0020 0021 //----------------------------- 0022 // Standard C library includes 0023 //----------------------------- 0024 #include <arpa/inet.h> 0025 #include <errno.h> 0026 #include <net/if.h> 0027 #include <netinet/in.h> 0028 #include <stdio.h> 0029 #include <stdlib.h> 0030 #include <sys/ioctl.h> 0031 #include <sys/socket.h> 0032 #include <sys/stat.h> 0033 #include <time.h> 0034 0035 //----------------------------- 0036 // Qt includes 0037 //----------------------------- 0038 0039 #include <QDateTime> 0040 #include <QLoggingCategory> 0041 #include <QObject> 0042 #include <QUrl> 0043 0044 //------------------------------- 0045 // Samba client library includes 0046 //------------------------------- 0047 extern "C" { 0048 #include <libsmbclient.h> 0049 } 0050 0051 //--------------------------- 0052 // kio_smb internal includes 0053 //--------------------------- 0054 #include "smbauthenticator.h" 0055 #include "smbcontext.h" 0056 #include "smburl.h" 0057 0058 using namespace KIO; 0059 class SMBWorker; 0060 0061 class WorkerFrontend : public SMBAbstractFrontend 0062 { 0063 public: 0064 explicit WorkerFrontend(SMBWorker &worker); 0065 bool checkCachedAuthentication(AuthInfo &info) override; 0066 0067 private: 0068 SMBWorker &m_worker; 0069 }; 0070 0071 class SMBWorker : public QObject, public KIO::WorkerBase 0072 { 0073 Q_OBJECT 0074 friend class SMBCDiscoverer; 0075 friend class SMBResumeIO; 0076 WorkerFrontend m_frontend{*this}; 0077 SMBContext m_context{new SMBAuthenticator(m_frontend)}; 0078 Q_DISABLE_COPY(SMBWorker) 0079 0080 private: 0081 class SMBError 0082 { 0083 public: 0084 int kioErrorId; 0085 QString errorString; 0086 }; 0087 0088 /** 0089 * we store the current url, it's needed for 0090 * callback authorization method 0091 */ 0092 SMBUrl m_current_url; 0093 0094 /** 0095 * From Controlcenter, show SHARE$ or not 0096 */ 0097 // bool m_showHiddenShares; //currently unused, Alex <neundorf@kde.org> 0098 0099 /** 0100 * libsmbclient need global variables to store in, 0101 * else it crashes on exit next method after use cache_stat, 0102 * looks like gcc (C/C++) failure 0103 */ 0104 struct stat st { 0105 }; 0106 0107 protected: 0108 //--------------------------------------------- 0109 // Authentication functions (kio_smb_auth.cpp) 0110 //--------------------------------------------- 0111 // (please prefix functions with auth) 0112 0113 /** 0114 * Description : Initializes the libsmbclient 0115 * Return : true on success false with errno set on error 0116 */ 0117 bool auth_initialize_smbc(); 0118 0119 int checkPassword(SMBUrl &url); 0120 0121 //--------------------------------------------- 0122 // Cache functions (kio_smb_auth.cpp) 0123 //--------------------------------------------- 0124 0125 // Stat methods 0126 0127 //----------------------------------------- 0128 // Browsing functions (kio_smb_browse.cpp) 0129 //----------------------------------------- 0130 // (please prefix functions with browse) 0131 0132 /** 0133 * Description : Return a stat of given SMBUrl. Calls cache_stat and 0134 * pack it in UDSEntry. UDSEntry will not be cleared 0135 * Parameter : SMBUrl the url to stat 0136 * Return : cache_stat() return code 0137 */ 0138 int browse_stat_path(const SMBUrl &url, UDSEntry &udsentry); 0139 0140 /** 0141 * Description : call smbc_stat and return stats of the url 0142 * Parameter : SMBUrl the url to stat 0143 * Return : stat* of the url 0144 * Note : it has some problems with stat in method, looks like 0145 * something leave(or removed) on the stack. If your 0146 * method segfault on returning try to change the stat* 0147 * variable 0148 */ 0149 static int cache_stat(const SMBUrl &url, struct stat *st); 0150 0151 //--------------------------------------------- 0152 // Configuration functions (kio_smb_config.cpp) 0153 //--------------------------------------------- 0154 // (please prefix functions with config) 0155 0156 //--------------------------------------- 0157 // Directory functions (kio_smb_dir.cpp) 0158 //--------------------------------------- 0159 // (please prefix functions with dir) 0160 0161 //-------------------------------------- 0162 // File IO functions (kio_smb_file.cpp) 0163 //-------------------------------------- 0164 // (please prefix functions with file) 0165 0166 //---------------------------- 0167 // Misc functions (this file) 0168 //---------------------------- 0169 0170 /** 0171 * Description : correct a given URL 0172 * valid URL's are 0173 * 0174 * smb://[[domain;]user[:password]@]server[:port][/share[/path[/file]]] 0175 * smb:/[[domain;]user[:password]@][group/[server[/share[/path[/file]]]]] 0176 * domain = workgroup(domain) of the user 0177 * user = username 0178 * password = password of useraccount 0179 * group = workgroup(domain) of server 0180 * server = host to connect 0181 * share = a share of the server (host) 0182 * path = a path of the share 0183 * Parameter : QUrl the url to check 0184 * Return : new QUrl if it is corrected. else the same QUrl 0185 */ 0186 QUrl checkURL(const QUrl &kurl) const; 0187 0188 Q_REQUIRED_RESULT WorkerResult reportError(const SMBUrl &url, const int errNum); 0189 void reportWarning(const SMBUrl &url, const int errNum); 0190 0191 public: 0192 // Functions overwritten in kio_smb.cpp 0193 SMBWorker(const QByteArray &pool, const QByteArray &app); 0194 ~SMBWorker() override = default; 0195 0196 // Functions overwritten in kio_smb_browse.cpp 0197 Q_REQUIRED_RESULT WorkerResult listDir(const QUrl &url) override; 0198 Q_REQUIRED_RESULT WorkerResult stat(const QUrl &url) override; 0199 0200 // Functions overwritten in kio_smb_config.cpp 0201 void reparseConfiguration() override; 0202 0203 // Functions overwritten in kio_smb_dir.cpp 0204 Q_REQUIRED_RESULT WorkerResult copy(const QUrl &src, const QUrl &dst, int permissions, KIO::JobFlags flags) override; 0205 Q_REQUIRED_RESULT WorkerResult del(const QUrl &kurl, bool isfile) override; 0206 Q_REQUIRED_RESULT WorkerResult mkdir(const QUrl &kurl, int permissions) override; 0207 Q_REQUIRED_RESULT WorkerResult rename(const QUrl &src, const QUrl &dest, KIO::JobFlags flags) override; 0208 0209 // Functions overwritten in kio_smb_file.cpp 0210 Q_REQUIRED_RESULT WorkerResult get(const QUrl &kurl) override; 0211 Q_REQUIRED_RESULT WorkerResult put(const QUrl &kurl, int permissions, KIO::JobFlags flags) override; 0212 Q_REQUIRED_RESULT WorkerResult open(const QUrl &kurl, QIODevice::OpenMode mode) override; 0213 Q_REQUIRED_RESULT WorkerResult read(KIO::filesize_t bytesRequested) override; 0214 Q_REQUIRED_RESULT WorkerResult write(const QByteArray &fileData) override; 0215 Q_REQUIRED_RESULT WorkerResult seek(KIO::filesize_t offset) override; 0216 Q_REQUIRED_RESULT WorkerResult truncate(KIO::filesize_t size) override; 0217 Q_REQUIRED_RESULT WorkerResult close() override; 0218 Q_REQUIRED_RESULT WorkerResult fileSystemFreeSpace(const QUrl &url) override; 0219 Q_REQUIRED_RESULT WorkerResult special(const QByteArray &) override; 0220 0221 private: 0222 SMBError errnumToKioError(const SMBUrl &url, const int errNum); 0223 Q_REQUIRED_RESULT WorkerResult smbCopy(const QUrl &src, const QUrl &dst, int permissions, KIO::JobFlags flags); 0224 Q_REQUIRED_RESULT WorkerResult smbCopyGet(const QUrl &ksrc, const QUrl &kdst, int permissions, KIO::JobFlags flags); 0225 Q_REQUIRED_RESULT WorkerResult smbCopyPut(const QUrl &ksrc, const QUrl &kdst, int permissions, KIO::JobFlags flags); 0226 bool workaroundEEXIST(const int errNum) const; 0227 int statToUDSEntry(const QUrl &url, const struct stat &st, KIO::UDSEntry &udsentry); 0228 Q_REQUIRED_RESULT WorkerResult getACE(QDataStream &stream); 0229 Q_REQUIRED_RESULT WorkerResult setACE(QDataStream &stream); 0230 0231 /** 0232 * Used in open(), read(), write(), and close() 0233 * FIXME Placing these in the private section above causes m_openUrl = kurl 0234 * to fail in SMBWorker::open. Need to find out why this is. 0235 */ 0236 int m_openFd; 0237 SMBUrl m_openUrl; 0238 0239 const bool m_enableEEXISTWorkaround; /* Enables a workaround for some broken libsmbclient versions */ 0240 // Close without calling finish(). Use this to close after error. 0241 void closeWithoutFinish(); 0242 0243 // Apply mtime if modified metadata is set. This callsback with a utbuf 0244 // with modtime accordingly set. The callback should implement the actual apply. 0245 template<typename UTimeFunction> 0246 void applyMTime(UTimeFunction &&callback) 0247 { 0248 const QString mtimeStr = metaData("modified"); 0249 if (mtimeStr.isEmpty()) { 0250 return; 0251 } 0252 qCDebug(KIO_SMB_LOG) << "modified:" << mtimeStr; 0253 0254 const QDateTime dateTime = QDateTime::fromString(mtimeStr, Qt::ISODate); 0255 if (dateTime.isValid()) { 0256 struct utimbuf utbuf { 0257 }; 0258 utbuf.modtime = dateTime.toSecsSinceEpoch(); // modification time 0259 callback(utbuf); 0260 } 0261 } 0262 0263 void applyMTimeSMBC(const SMBUrl &url) 0264 { 0265 #ifdef HAVE_UTIME_H // smbc_utime is conditional inside the libsmb headers 0266 applyMTime([url](struct utimbuf utbuf) { 0267 struct stat st { 0268 }; 0269 if (cache_stat(url, &st) == 0) { 0270 utbuf.actime = st.st_atime; // access time, unchanged 0271 smbc_utime(url.toSmbcUrl(), &utbuf); 0272 } 0273 }); 0274 #endif 0275 } 0276 }; 0277 0278 //=========================================================================== 0279 // Main worker entrypoint (see kio_smb.cpp) 0280 extern "C" { 0281 int kdemain(int argc, char **argv); 0282 } 0283 0284 #endif // #endif KIO_SMB_H_INCLUDED