12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244 |
- From 00c4ee62fb59a59c51d4db5efbde0d8b5e1e4a39 Mon Sep 17 00:00:00 2001
- From: Thomas Guillem <thomas@gllm.fr>
- Date: Fri, 13 Apr 2018 16:15:16 +0200
- Subject: [PATCH 26/26] access: add smb2 module
- Using libsmb2 from Ronnie Sahlberg https://github.com/sahlberg/libsmb2
- This is LGPL 2.1 fully async lib for accessing SMB2 and SMB3 shares.
- This module use the async feature of the libsmb2 lib with the vlc interrupt
- mechanism, therefore every network requests are cancellable almost immediately.
- The 2.0.0 version is required since this version drop OpenSSL dependency and
- allow to use Builtin NTLMSSP authentication instead of libkrb5.
- ---
- configure.ac | 14 +-
- ...ot-exist-on-darwin-use-posix-ENODEV-.patch | 25 +
- contrib/src/smb2/0001-master-backport.patch | 330 ++++++++
- contrib/src/smb2/SHA512SUMS | 1 +
- contrib/src/smb2/rules.mak | 29 +
- modules/MODULES_LIST | 1 +
- modules/access/Makefile.am | 11 +
- modules/access/smb2.c | 717 ++++++++++++++++++
- po/POTFILES.in | 1 +
- 9 files changed, 1128 insertions(+), 1 deletion(-)
- create mode 100644 contrib/src/smb2/0001-ENOMEDIUM-does-not-exist-on-darwin-use-posix-ENODEV-.patch
- create mode 100644 contrib/src/smb2/0001-master-backport.patch
- create mode 100644 contrib/src/smb2/SHA512SUMS
- create mode 100644 contrib/src/smb2/rules.mak
- create mode 100644 modules/access/smb2.c
- diff --git a/configure.ac b/configure.ac
- index 9891bed93e..9bbba2b3df 100644
- --- a/configure.ac
- +++ b/configure.ac
- @@ -1854,7 +1854,14 @@ AS_IF([test "${SYS}" = "mingw32" -a "${enable_winstore_app}" != "yes"], [ VLC_AD
- dnl
- dnl liBDSM access module
- dnl
- -PKG_ENABLE_MODULES_VLC([DSM], [dsm], [libdsm >= 0.2.0], [libdsm SMB/CIFS access/sd module], [auto])
- +AM_CONDITIONAL(HAVE_DSM, [test "$AS_TR_SH(with_dsm)" = "yes"])
- +PKG_WITH_MODULES([DSM], [libdsm >= 0.2.0], [
- + VLC_ADD_PLUGIN([dsm])
- + VLC_ADD_CFLAGS([dsm], [$DSM_CFLAGS])
- + VLC_ADD_LIBS([dsm], [$DSM_LIBS])
- + have_dsm="yes"
- + ],,[libdsm SMB/CIFS access/sd module], [auto])
- +AM_CONDITIONAL([HAVE_DSM], [test "${have_dsm}" = "yes"])
-
- dnl
- dnl sftp access support
- @@ -1866,6 +1873,11 @@ dnl nfs access support
- dnl
- PKG_ENABLE_MODULES_VLC([NFS], [nfs], [libnfs >= 1.10.0], (support nfs protocol via libnfs), [auto])
-
- +dnl
- +dnl smb2 access support
- +dnl
- +PKG_ENABLE_MODULES_VLC([SMB2], [smb2], [libsmb2 >= 2.0.0], (support smb2 protocol via libsmb2), [auto])
- +
- dnl
- dnl Video4Linux 2
- dnl
- diff --git a/contrib/src/smb2/0001-ENOMEDIUM-does-not-exist-on-darwin-use-posix-ENODEV-.patch b/contrib/src/smb2/0001-ENOMEDIUM-does-not-exist-on-darwin-use-posix-ENODEV-.patch
- new file mode 100644
- index 0000000000..93763dd660
- --- /dev/null
- +++ b/contrib/src/smb2/0001-ENOMEDIUM-does-not-exist-on-darwin-use-posix-ENODEV-.patch
- @@ -0,0 +1,25 @@
- +From 2256d19bc9fead528bac900d894d65e9b030f7f8 Mon Sep 17 00:00:00 2001
- +From: "S. Davilla" <davilla@4pi.com>
- +Date: Mon, 22 Oct 2018 20:53:15 -0400
- +Subject: [PATCH] ENOMEDIUM does not exist on darwin, use posix ENODEV instead
- +
- +---
- + lib/errors.c | 2 +-
- + 1 file changed, 1 insertion(+), 1 deletion(-)
- +
- +diff --git a/lib/errors.c b/lib/errors.c
- +index f2696c0..3612f9a 100644
- +--- a/lib/errors.c
- ++++ b/lib/errors.c
- +@@ -218,7 +218,7 @@ int nterror_to_errno(uint32_t status) {
- + case SMB2_STATUS_MEDIA_WRITE_PROTECTED:
- + return EROFS;
- + case SMB2_STATUS_NO_MEDIA_IN_DEVICE:
- +- return ENOMEDIUM;
- ++ return ENODEV;
- + case SMB2_STATUS_DATA_ERROR:
- + case SMB2_STATUS_CRC_ERROR:
- + case SMB2_STATUS_DEVICE_DATA_ERROR:
- +--
- +2.17.2 (Apple Git-113)
- +
- diff --git a/contrib/src/smb2/0001-master-backport.patch b/contrib/src/smb2/0001-master-backport.patch
- new file mode 100644
- index 0000000000..0f9cf7cf62
- --- /dev/null
- +++ b/contrib/src/smb2/0001-master-backport.patch
- @@ -0,0 +1,330 @@
- +From 49525025f8c91ae14e5fe3cfea0dc7948b7f5480 Mon Sep 17 00:00:00 2001
- +From: Thomas Guillem <thomas@gllm.fr>
- +Date: Tue, 12 Feb 2019 12:42:37 +0100
- +Subject: [PATCH] master-backport
- +
- +Waiting for a new release, including the following patches:
- +
- +libsmb_error patch
- +Delete libsmb2_error.latest.patch
- +Allow passing NULL to smb2_set_password
- +Add more error status
- +Map more EACCESS error status
- +---
- + include/smb2/smb2-errors.h | 50 +++++++++++
- + lib/errors.c | 178 +++++++++++++++++++++++++++++++++++--
- + lib/init.c | 4 +
- + 3 files changed, 223 insertions(+), 9 deletions(-)
- +
- +diff --git a/include/smb2/smb2-errors.h b/include/smb2/smb2-errors.h
- +index 49c5d5c..3b741e7 100644
- +--- a/include/smb2/smb2-errors.h
- ++++ b/include/smb2/smb2-errors.h
- +@@ -35,13 +35,63 @@
- + /* Error codes */
- + #define SMB2_STATUS_SUCCESS 0x00000000
- + #define SMB2_STATUS_PENDING 0x00000103
- ++#define SMB2_STATUS_SMB_BAD_FID 0x00060001
- + #define SMB2_STATUS_NO_MORE_FILES 0x80000006
- ++#define SMB2_STATUS_NOT_IMPLEMENTED 0xC0000002
- ++#define SMB2_STATUS_INVALID_HANDLE 0xC0000008
- + #define SMB2_STATUS_INVALID_PARAMETER 0xC000000d
- ++#define SMB2_STATUS_NO_SUCH_DEVICE 0xC000000E
- ++#define SMB2_STATUS_NO_SUCH_FILE 0xC000000F
- ++#define SMB2_STATUS_INVALID_DEVICE_REQUEST 0xC0000010
- + #define SMB2_STATUS_END_OF_FILE 0xC0000011
- ++#define SMB2_STATUS_NO_MEDIA_IN_DEVICE 0xC0000013
- + #define SMB2_STATUS_MORE_PROCESSING_REQUIRED 0xC0000016
- ++#define SMB2_STATUS_INVALID_LOCK_SEQUENCE 0xC000001E
- ++#define SMB2_STATUS_INVALID_VIEW_SIZE 0xC000001F
- ++#define SMB2_STATUS_ALREADY_COMMITTED 0xC0000021
- + #define SMB2_STATUS_ACCESS_DENIED 0xC0000022
- ++#define SMB2_STATUS_OBJECT_TYPE_MISMATCH 0xC0000024
- + #define SMB2_STATUS_OBJECT_NAME_NOT_FOUND 0xC0000034
- ++#define SMB2_STATUS_OBJECT_NAME_COLLISION 0xC0000035
- ++#define SMB2_STATUS_PORT_DISCONNECTED 0xC0000037
- ++#define SMB2_STATUS_OBJECT_PATH_INVALID 0xC0000039
- ++#define SMB2_STATUS_OBJECT_PATH_NOT_FOUND 0xC000003A
- ++#define SMB2_STATUS_OBJECT_PATH_SYNTAX_BAD 0xC000003B
- ++#define SMB2_STATUS_DATA_ERROR 0xC000003E
- ++#define SMB2_STATUS_CRC_ERROR 0xC000003F
- ++#define SMB2_STATUS_SECTION_TOO_BIG 0xC0000040
- ++#define SMB2_STATUS_PORT_CONNECTION_REFUSED 0xC0000041
- ++#define SMB2_STATUS_INVALID_PORT_HANDLE 0xC0000042
- ++#define SMB2_STATUS_SHARING_VIOLATION 0xC0000043
- ++#define SMB2_STATUS_THREAD_IS_TERMINATING 0xC000004B
- ++#define SMB2_STATUS_FILE_LOCK_CONFLICT 0xC0000054
- ++#define SMB2_STATUS_LOCK_NOT_GRANTED 0xC0000055
- ++#define SMB2_STATUS_DELETE_PENDING 0xC0000056
- ++#define SMB2_STATUS_PRIVILEGE_NOT_HELD 0xC0000061
- + #define SMB2_STATUS_LOGON_FAILURE 0xC000006d
- ++#define SMB2_STATUS_ACCOUNT_RESTRICTION 0xC000006E
- ++#define SMB2_STATUS_INVALID_LOGON_HOURS 0xC000006F
- ++#define SMB2_STATUS_PASSWORD_EXPIRED 0xC0000071
- ++#define SMB2_STATUS_ACCOUNT_DISABLED 0xC0000072
- ++#define SMB2_STATUS_DISK_FULL 0xC000007F
- ++#define SMB2_STATUS_TOO_MANY_PAGING_FILES 0xC0000097
- ++#define SMB2_STATUS_DFS_EXIT_PATH_FOUND 0xC000009B
- ++#define SMB2_STATUS_DEVICE_DATA_ERROR 0xC000009C
- ++#define SMB2_STATUS_MEDIA_WRITE_PROTECTED 0xC00000A2
- ++#define SMB2_STATUS_ILLEGAL_FUNCTION 0xC00000AF
- ++#define SMB2_STATUS_PIPE_DISCONNECTED 0xC00000B0
- ++#define SMB2_STATUS_FILE_IS_A_DIRECTORY 0xC00000BA
- ++#define SMB2_STATUS_NETWORK_ACCESS_DENIED 0xC00000CA
- + #define SMB2_STATUS_BAD_NETWORK_NAME 0xC00000CC
- ++#define SMB2_STATUS_NOT_SAME_DEVICE 0xC00000D4
- ++#define SMB2_STATUS_FILE_RENAMED 0xC00000D5
- ++#define SMB2_STATUS_REDIRECTOR_NOT_STARTED 0xC00000FB
- ++#define SMB2_STATUS_DIRECTORY_NOT_EMPTY 0xC0000101
- + #define SMB2_STATUS_NOT_A_DIRECTORY 0xC0000103
- ++#define SMB2_STATUS_PROCESS_IS_TERMINATING 0xC000010A
- ++#define SMB2_STATUS_TOO_MANY_OPENED_FILES 0xC000011F
- ++#define SMB2_STATUS_CANNOT_DELETE 0xC0000121
- ++#define SMB2_STATUS_FILE_DELETED 0xC0000123
- + #define SMB2_STATUS_FILE_CLOSED 0xC0000128
- ++#define SMB2_STATUS_INSUFF_SERVER_RESOURCES 0xC0000205
- ++#define SMB2_STATUS_HANDLE_NOT_CLOSABLE 0xC0000235
- +diff --git a/lib/errors.c b/lib/errors.c
- +index 68150a0..2e1648d 100644
- +--- a/lib/errors.c
- ++++ b/lib/errors.c
- +@@ -30,26 +30,124 @@ const char *nterror_to_str(uint32_t status) {
- + return "STATUS_PENDING";
- + case SMB2_STATUS_NO_MORE_FILES:
- + return "STATUS_NO_MORE_FILES";
- ++ case SMB2_STATUS_NOT_IMPLEMENTED:
- ++ return "STATUS_NOT_IMPLEMENTED";
- ++ case SMB2_STATUS_INVALID_HANDLE:
- ++ return "STATUS_INVALID_HANDLE";
- ++ case SMB2_STATUS_INVALID_PARAMETER:
- ++ return "STATUS_INVALID_PARAMETER";
- ++ case SMB2_STATUS_NO_SUCH_DEVICE:
- ++ return "STATUS_NO_SUCH_DEVICE";
- ++ case SMB2_STATUS_NO_SUCH_FILE:
- ++ return "STATUS_NO_SUCH_FILE";
- ++ case SMB2_STATUS_INVALID_DEVICE_REQUEST:
- ++ return "STATUS_INVALID_DEVICE_REQUEST";
- ++ case SMB2_STATUS_END_OF_FILE:
- ++ return "STATUS_END_OF_FILE";
- ++ case SMB2_STATUS_NO_MEDIA_IN_DEVICE:
- ++ return "STATUS_NO_MEDIA_IN_DEVICE";
- + case SMB2_STATUS_MORE_PROCESSING_REQUIRED:
- + return "STATUS_MORE_PROCESSING_REQUIRED";
- ++ case SMB2_STATUS_INVALID_LOCK_SEQUENCE:
- ++ return "STATUS_INVALID_LOCK_SEQUENCE";
- ++ case SMB2_STATUS_INVALID_VIEW_SIZE:
- ++ return "STATUS_INVALID_VIEW_SIZE";
- ++ case SMB2_STATUS_ALREADY_COMMITTED:
- ++ return "STATUS_ALREADY_COMMITTED";
- + case SMB2_STATUS_ACCESS_DENIED:
- + return "STATUS_ACCESS_DENIED";
- ++ case SMB2_STATUS_OBJECT_TYPE_MISMATCH:
- ++ return "STATUS_OBJECT_TYPE_MISMATCH";
- ++ case SMB2_STATUS_OBJECT_NAME_NOT_FOUND:
- ++ return "STATUS_OBJECT_NAME_NOT_FOUND";
- ++ case SMB2_STATUS_OBJECT_NAME_COLLISION:
- ++ return "STATUS_OBJECT_NAME_COLLISION";
- ++ case SMB2_STATUS_PORT_DISCONNECTED:
- ++ return "STATUS_PORT_DISCONNECTED";
- ++ case SMB2_STATUS_OBJECT_PATH_INVALID:
- ++ return "STATUS_OBJECT_PATH_INVALID";
- ++ case SMB2_STATUS_OBJECT_PATH_NOT_FOUND:
- ++ return "STATUS_OBJECT_PATH_NOT_FOUND";
- ++ case SMB2_STATUS_OBJECT_PATH_SYNTAX_BAD:
- ++ return "STATUS_OBJECT_PATH_SYNTAX_BAD";
- ++ case SMB2_STATUS_DATA_ERROR:
- ++ return "STATUS_DATA_ERROR";
- ++ case SMB2_STATUS_CRC_ERROR:
- ++ return "STATUS_CRC_ERROR";
- ++ case SMB2_STATUS_SECTION_TOO_BIG:
- ++ return "STATUS_SECTION_TOO_BIG";
- ++ case SMB2_STATUS_PORT_CONNECTION_REFUSED:
- ++ return "STATUS_PORT_CONNECTION_REFUSED";
- ++ case SMB2_STATUS_INVALID_PORT_HANDLE:
- ++ return "STATUS_INVALID_PORT_HANDLE";
- ++ case SMB2_STATUS_SHARING_VIOLATION:
- ++ return "STATUS_SHARING_VIOLATION";
- ++ case SMB2_STATUS_THREAD_IS_TERMINATING:
- ++ return "STATUS_THREAD_IS_TERMINATING";
- ++ case SMB2_STATUS_FILE_LOCK_CONFLICT:
- ++ return "STATUS_FILE_LOCK_CONFLICT";
- ++ case SMB2_STATUS_LOCK_NOT_GRANTED:
- ++ return "STATUS_LOCK_NOT_GRANTED";
- ++ case SMB2_STATUS_DELETE_PENDING:
- ++ return "STATUS_DELETE_PENDING";
- ++ case SMB2_STATUS_PRIVILEGE_NOT_HELD:
- ++ return "STATUS_PRIVILEGE_NOT_HELD";
- + case SMB2_STATUS_LOGON_FAILURE:
- + return "STATUS_LOGON_FAILURE";
- ++ case SMB2_STATUS_ACCOUNT_RESTRICTION:
- ++ return "STATUS_ACCOUNT_RESTRICTION";
- ++ case SMB2_STATUS_INVALID_LOGON_HOURS:
- ++ return "STATUS_INVALID_LOGON_HOURS";
- ++ case SMB2_STATUS_PASSWORD_EXPIRED:
- ++ return "STATUS_PASSWORD_EXPIRED";
- ++ case SMB2_STATUS_ACCOUNT_DISABLED:
- ++ return "STATUS_ACCOUNT_DISABLED";
- ++ case SMB2_STATUS_DISK_FULL:
- ++ return "STATUS_DISK_FULL";
- ++ case SMB2_STATUS_TOO_MANY_PAGING_FILES:
- ++ return "STATUS_TOO_MANY_PAGING_FILES";
- ++ case SMB2_STATUS_DFS_EXIT_PATH_FOUND:
- ++ return "STATUS_DFS_EXIT_PATH_FOUND";
- ++ case SMB2_STATUS_DEVICE_DATA_ERROR:
- ++ return "STATUS_DEVICE_DATA_ERROR";
- ++ case SMB2_STATUS_MEDIA_WRITE_PROTECTED:
- ++ return "STATUS_MEDIA_WRITE_PROTECTED";
- ++ case SMB2_STATUS_ILLEGAL_FUNCTION:
- ++ return "STATUS_ILLEGAL_FUNCTION";
- ++ case SMB2_STATUS_PIPE_DISCONNECTED:
- ++ return "STATUS_PIPE_DISCONNECTED";
- ++ case SMB2_STATUS_FILE_IS_A_DIRECTORY:
- ++ return "STATUS_FILE_IS_A_DIRECTORY";
- ++ case SMB2_STATUS_NETWORK_ACCESS_DENIED:
- ++ return "STATUS_NETWORK_ACCESS_DENIED";
- + case SMB2_STATUS_BAD_NETWORK_NAME:
- + return "STATUS_BAD_NETWORK_NAME";
- ++ case SMB2_STATUS_NOT_SAME_DEVICE:
- ++ return "STATUS_NOT_SAME_DEVICE";
- ++ case SMB2_STATUS_FILE_RENAMED:
- ++ return "STATUS_FILE_RENAMED";
- ++ case SMB2_STATUS_REDIRECTOR_NOT_STARTED:
- ++ return "STATUS_REDIRECTOR_NOT_STARTED";
- ++ case SMB2_STATUS_DIRECTORY_NOT_EMPTY:
- ++ return "STATUS_DIRECTORY_NOT_EMPTY";
- + case SMB2_STATUS_NOT_A_DIRECTORY:
- + return "STATUS_NOT_A_DIRECTORY";
- +- case SMB2_STATUS_INVALID_PARAMETER:
- +- return "STATUS_INVALID_PARAMETER";
- +- case SMB2_STATUS_END_OF_FILE:
- +- return "STATUS_END_OF_FILE";
- ++ case SMB2_STATUS_PROCESS_IS_TERMINATING:
- ++ return "STATUS_PROCESS_IS_TERMINATING";
- ++ case SMB2_STATUS_TOO_MANY_OPENED_FILES:
- ++ return "STATUS_TOO_MANY_OPENED_FILES";
- ++ case SMB2_STATUS_CANNOT_DELETE:
- ++ return "STATUS_CANNOT_DELETE";
- ++ case SMB2_STATUS_FILE_DELETED:
- ++ return "STATUS_FILE_DELETED";
- + case SMB2_STATUS_FILE_CLOSED:
- + return "STATUS_FILE_CLOSED";
- +- case SMB2_STATUS_OBJECT_NAME_NOT_FOUND:
- +- return "STATUS_OBJECT_NAME_NOT_FOUND";
- ++ case SMB2_STATUS_INSUFF_SERVER_RESOURCES:
- ++ return "STATUS_INSUFF_SERVER_RESOURCES";
- ++ case SMB2_STATUS_HANDLE_NOT_CLOSABLE:
- ++ return "STATUS_HANDLE_NOT_CLOSABLE";
- + default:
- +- return "Unknown";
- ++ return "Unknown";
- + }
- + }
- +
- +@@ -58,25 +156,87 @@ int nterror_to_errno(uint32_t status) {
- + case SMB2_STATUS_SUCCESS:
- + case SMB2_STATUS_END_OF_FILE:
- + return 0;
- ++ case SMB2_STATUS_PENDING:
- ++ return EAGAIN;
- ++ case SMB2_STATUS_NO_SUCH_FILE:
- ++ case SMB2_STATUS_NO_SUCH_DEVICE:
- + case SMB2_STATUS_BAD_NETWORK_NAME:
- + case SMB2_STATUS_OBJECT_NAME_NOT_FOUND:
- ++ case SMB2_STATUS_OBJECT_PATH_INVALID:
- ++ case SMB2_STATUS_OBJECT_PATH_NOT_FOUND:
- ++ case SMB2_STATUS_OBJECT_PATH_SYNTAX_BAD:
- ++ case SMB2_STATUS_DFS_EXIT_PATH_FOUND:
- ++ case SMB2_STATUS_REDIRECTOR_NOT_STARTED:
- + return ENOENT;
- + case SMB2_STATUS_FILE_CLOSED:
- ++ case SMB2_STATUS_SMB_BAD_FID:
- ++ case SMB2_STATUS_INVALID_HANDLE:
- ++ case SMB2_STATUS_OBJECT_TYPE_MISMATCH:
- ++ case SMB2_STATUS_PORT_DISCONNECTED:
- ++ case SMB2_STATUS_INVALID_PORT_HANDLE:
- ++ case SMB2_STATUS_HANDLE_NOT_CLOSABLE:
- + return EBADF;
- + case SMB2_STATUS_MORE_PROCESSING_REQUIRED:
- + return EAGAIN;
- + case SMB2_STATUS_ACCESS_DENIED:
- ++ case SMB2_STATUS_NETWORK_ACCESS_DENIED:
- ++ case SMB2_STATUS_ACCOUNT_RESTRICTION:
- ++ case SMB2_STATUS_INVALID_LOGON_HOURS:
- ++ case SMB2_STATUS_PASSWORD_EXPIRED:
- ++ case SMB2_STATUS_ACCOUNT_DISABLED:
- + return EACCES;
- +- case SMB2_STATUS_PENDING:
- +- return EAGAIN;
- ++ case SMB2_STATUS_INVALID_LOCK_SEQUENCE:
- ++ case SMB2_STATUS_INVALID_VIEW_SIZE:
- ++ case SMB2_STATUS_ALREADY_COMMITTED:
- ++ case SMB2_STATUS_PORT_CONNECTION_REFUSED:
- ++ case SMB2_STATUS_THREAD_IS_TERMINATING:
- ++ case SMB2_STATUS_DELETE_PENDING:
- ++ case SMB2_STATUS_PRIVILEGE_NOT_HELD:
- ++ case SMB2_STATUS_FILE_IS_A_DIRECTORY:
- ++ case SMB2_STATUS_FILE_RENAMED:
- ++ case SMB2_STATUS_PROCESS_IS_TERMINATING:
- ++ case SMB2_STATUS_DIRECTORY_NOT_EMPTY:
- ++ case SMB2_STATUS_CANNOT_DELETE:
- ++ case SMB2_STATUS_FILE_DELETED:
- ++ return EPERM;
- + case SMB2_STATUS_NO_MORE_FILES:
- + return ENODATA;
- + case SMB2_STATUS_LOGON_FAILURE:
- + return ECONNREFUSED;
- + case SMB2_STATUS_NOT_A_DIRECTORY:
- + return ENOTDIR;
- ++ case SMB2_STATUS_NOT_IMPLEMENTED:
- ++ case SMB2_STATUS_INVALID_DEVICE_REQUEST:
- ++ case SMB2_STATUS_ILLEGAL_FUNCTION:
- + case SMB2_STATUS_INVALID_PARAMETER:
- + return EINVAL;
- ++ case SMB2_STATUS_TOO_MANY_OPENED_FILES:
- ++ return EMFILE;
- ++ case SMB2_STATUS_SECTION_TOO_BIG:
- ++ case SMB2_STATUS_TOO_MANY_PAGING_FILES:
- ++ case SMB2_STATUS_INSUFF_SERVER_RESOURCES:
- ++ return ENOMEM;
- ++ case SMB2_STATUS_NOT_SAME_DEVICE:
- ++ return EXDEV;
- ++ case SMB2_STATUS_SHARING_VIOLATION:
- ++ return ETXTBSY;
- ++ case SMB2_STATUS_FILE_LOCK_CONFLICT:
- ++ case SMB2_STATUS_LOCK_NOT_GRANTED:
- ++ return EDEADLK;
- ++ case SMB2_STATUS_OBJECT_NAME_COLLISION:
- ++ return EEXIST;
- ++ case SMB2_STATUS_PIPE_DISCONNECTED:
- ++ return EPIPE;
- ++ case SMB2_STATUS_MEDIA_WRITE_PROTECTED:
- ++ return EROFS;
- ++ case SMB2_STATUS_NO_MEDIA_IN_DEVICE:
- ++ return ENOMEDIUM;
- ++ case SMB2_STATUS_DATA_ERROR:
- ++ case SMB2_STATUS_CRC_ERROR:
- ++ case SMB2_STATUS_DEVICE_DATA_ERROR:
- ++ return EIO;
- ++ case SMB2_STATUS_DISK_FULL:
- ++ return ENOSPC;
- + default:
- + return EIO;
- + }
- +diff --git a/lib/init.c b/lib/init.c
- +index 3720a1c..6c95cd2 100644
- +--- a/lib/init.c
- ++++ b/lib/init.c
- +@@ -412,6 +412,10 @@ void smb2_set_password(struct smb2_context *smb2, const char *password)
- + {
- + if (smb2->password) {
- + free(discard_const(smb2->password));
- ++ smb2->password = NULL;
- ++ }
- ++ if (password == NULL) {
- ++ return;
- + }
- + smb2->password = strdup(password);
- + }
- +--
- +2.20.1
- +
- diff --git a/contrib/src/smb2/SHA512SUMS b/contrib/src/smb2/SHA512SUMS
- new file mode 100644
- index 0000000000..eae3dd89c5
- --- /dev/null
- +++ b/contrib/src/smb2/SHA512SUMS
- @@ -0,0 +1 @@
- +5e7101e54a4a95eae2ed5b05dfb51a33e9d4ce19275a405fbb1e86f9e9fe197de53b41c301ca992f19a03e5117ccc90d0acb174eb9c000c71674a0dbacf57614 libsmb2-2.0.0.tar.gz
- diff --git a/contrib/src/smb2/rules.mak b/contrib/src/smb2/rules.mak
- new file mode 100644
- index 0000000000..c14f58964f
- --- /dev/null
- +++ b/contrib/src/smb2/rules.mak
- @@ -0,0 +1,29 @@
- +# SMB2
- +SMB2_VERSION := 2.0.0
- +SMB2_URL := https://github.com/sahlberg/libsmb2/archive/v$(SMB2_VERSION).tar.gz
- +
- +ifdef BUILD_NETWORK
- +ifndef HAVE_WIN32
- +PKGS += smb2
- +endif
- +endif
- +ifeq ($(call need_pkg,"smb2"),)
- +PKGS_FOUND += smb2
- +endif
- +
- +$(TARBALLS)/libsmb2-$(SMB2_VERSION).tar.gz:
- + $(call download_pkg,$(SMB2_URL),smb2)
- +
- +.sum-smb2: libsmb2-$(SMB2_VERSION).tar.gz
- +
- +smb2: libsmb2-$(SMB2_VERSION).tar.gz .sum-smb2
- + $(UNPACK)
- + $(APPLY) $(SRC)/smb2/0001-master-backport.patch
- + $(APPLY) $(SRC)/smb2/0001-ENOMEDIUM-does-not-exist-on-darwin-use-posix-ENODEV-.patch
- + $(MOVE)
- +
- +.smb2: smb2
- + cd $< && ./bootstrap
- + cd $< && $(HOSTVARS) ./configure --disable-examples --disable-werror --without-libkrb5 $(HOSTCONF)
- + cd $< && $(MAKE) install
- + touch $@
- diff --git a/modules/MODULES_LIST b/modules/MODULES_LIST
- index 051344019c..cbc2a52b69 100644
- --- a/modules/MODULES_LIST
- +++ b/modules/MODULES_LIST
- @@ -363,6 +363,7 @@ $Id$
- * skins2: Skinnable interface, new generation
- * skiptags: APE & ID3 tags-skipping stream filter
- * smb: SMB shares access module
- + * smb2: SMB2/3 access module
- * smf: Standard MIDI file demuxer
- * sndio: OpenBSD sndio audio output
- * soxr: SoX Resampler library audio filter
- diff --git a/modules/access/Makefile.am b/modules/access/Makefile.am
- index 765ceec45f..2a773029e3 100644
- --- a/modules/access/Makefile.am
- +++ b/modules/access/Makefile.am
- @@ -344,6 +344,17 @@ libdsm_plugin_la_LDFLAGS = $(AM_LDFLAGS) -rpath '$(accessdir)'
- access_LTLIBRARIES += $(LTLIBdsm)
- EXTRA_LTLIBRARIES += libdsm_plugin.la
-
- +libsmb2_plugin_la_SOURCES = access/smb2.c
- +libsmb2_plugin_la_CFLAGS = $(AM_CFLAGS) $(SMB2_CFLAGS)
- +libsmb2_plugin_la_LIBADD = $(SMB2_LIBS) $(SOCKET_LIBS)
- +libsmb2_plugin_la_LDFLAGS = $(AM_LDFLAGS) -rpath '$(accessdir)'
- +if HAVE_DSM
- +libsmb2_plugin_la_CFLAGS += $(DSM_CFLAGS) -DHAVE_DSM
- +libsmb2_plugin_la_LIBADD += $(DSM_LIBS)
- +endif
- +access_LTLIBRARIES += $(LTLIBsmb2)
- +EXTRA_LTLIBRARIES += libsmb2_plugin.la
- +
- libtcp_plugin_la_SOURCES = access/tcp.c
- libtcp_plugin_la_LIBADD = $(SOCKET_LIBS)
- access_LTLIBRARIES += libtcp_plugin.la
- diff --git a/modules/access/smb2.c b/modules/access/smb2.c
- new file mode 100644
- index 0000000000..90cd0d327f
- --- /dev/null
- +++ b/modules/access/smb2.c
- @@ -0,0 +1,717 @@
- +/*****************************************************************************
- + * smb2.c: SMB2 access plug-in
- + *****************************************************************************
- + * Copyright © 2018 VLC authors, VideoLAN and VideoLabs
- + *
- + * This program 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 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 Lesser General Public License for more details.
- + *
- + * You should have received a copy of the GNU Lesser General Public License
- + * along with this program; if not, write to the Free Software Foundation,
- + * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
- + *****************************************************************************/
- +
- +#ifdef HAVE_CONFIG_H
- +# include "config.h"
- +#endif
- +
- +#include <assert.h>
- +#include <errno.h>
- +#include <stdint.h>
- +#include <stdlib.h>
- +#include <sys/types.h>
- +#include <sys/stat.h>
- +#include <fcntl.h>
- +#ifdef HAVE_POLL
- +# include <poll.h>
- +#endif
- +
- +#include <vlc_common.h>
- +#include <vlc_access.h>
- +#include <vlc_dialog.h>
- +#include <vlc_input_item.h>
- +#include <vlc_plugin.h>
- +#include <vlc_url.h>
- +#include <vlc_keystore.h>
- +#include <vlc_interrupt.h>
- +#include <vlc_network.h>
- +
- +#include <smb2/smb2.h>
- +#include <smb2/libsmb2.h>
- +#include <smb2/libsmb2-raw.h>
- +
- +#ifdef HAVE_DSM
- +# include <bdsm/netbios_ns.h>
- +# include <bdsm/netbios_defs.h>
- +
- +# ifdef HAVE_ARPA_INET_H
- +# include <arpa/inet.h>
- +# endif
- +#endif
- +
- +#include "smb_common.h"
- +
- +#define CIFS_PORT 445
- +
- +static int Open(vlc_object_t *);
- +static void Close(vlc_object_t *);
- +
- +vlc_module_begin()
- + set_shortname("smb2")
- + set_description(N_("SMB2 / SMB3 input"))
- + set_help(N_("Samba (Windows network shares) input via libsmb2"))
- + set_capability("access", 21)
- + set_category(CAT_INPUT)
- + set_subcategory(SUBCAT_INPUT_ACCESS)
- + add_string("smb-user", NULL, SMB_USER_TEXT, SMB_USER_LONGTEXT, false)
- + add_password("smb-pwd", NULL, SMB_PASS_TEXT, SMB_PASS_LONGTEXT, false)
- + add_string("smb-domain", NULL, SMB_DOMAIN_TEXT, SMB_DOMAIN_LONGTEXT, false)
- + add_shortcut("smb", "smb2")
- + set_callbacks(Open, Close)
- +vlc_module_end()
- +
- +struct access_sys
- +{
- + struct smb2_context * smb2;
- + struct smb2fh * smb2fh;
- + struct smb2dir * smb2dir;
- + struct srvsvc_netshareenumall_rep *share_enum;
- + uint64_t smb2_size;
- + vlc_url_t encoded_url;
- + bool eof;
- + bool smb2_connected;
- + int error_status;
- +
- + bool res_done;
- + union {
- + struct
- + {
- + size_t len;
- + } read;
- + } res;
- +};
- +
- +static int
- +smb2_check_status(stream_t *access, int status, const char *psz_func)
- +{
- + struct access_sys *sys = access->p_sys;
- +
- + if (status < 0)
- + {
- + const char *psz_error = smb2_get_error(sys->smb2);
- + msg_Warn(access, "%s failed: %d, '%s'", psz_func, status, psz_error);
- + sys->error_status = status;
- + return -1;
- + }
- + else
- + {
- + sys->res_done = true;
- + return 0;
- + }
- +}
- +
- +static void
- +smb2_set_generic_error(stream_t *access, const char *psz_func)
- +{
- + struct access_sys *sys = access->p_sys;
- +
- + msg_Err(access, "%s failed: %s", psz_func, smb2_get_error(sys->smb2));
- + sys->error_status = 1;
- +}
- +
- +#define VLC_SMB2_CHECK_STATUS(access, status) \
- + smb2_check_status(access, status, __func__)
- +
- +#define VLC_SMB2_SET_GENERIC_ERROR(access, func) \
- + smb2_set_generic_error(access, func)
- +
- +#define VLC_SMB2_STATUS_DENIED(x) (x == -ECONNREFUSED || x == -EACCES)
- +
- +static int
- +vlc_smb2_mainloop(stream_t *access, bool teardown)
- +{
- + struct access_sys *sys = access->p_sys;
- +
- + int timeout = -1;
- + int (*poll_func)(struct pollfd *, unsigned, int) = vlc_poll_i11e;
- +
- + if (teardown && vlc_killed())
- + {
- + /* The thread is interrupted, so vlc_poll_i11e will return immediatly.
- + * Use poll() with a timeout instead for tear down. */
- + timeout = 500;
- + poll_func = (void *)poll;
- + }
- +
- + sys->res_done = false;
- + while (sys->error_status == 0 && !sys->res_done)
- + {
- + struct pollfd p_fds[1];
- + int ret;
- + p_fds[0].fd = smb2_get_fd(sys->smb2);
- + p_fds[0].events = smb2_which_events(sys->smb2);
- +
- + if (p_fds[0].fd == -1 || (ret = poll_func(p_fds, 1, timeout)) < 0)
- + {
- + if (errno == EINTR)
- + msg_Warn(access, "vlc_poll_i11e interrupted");
- + else
- + msg_Err(access, "vlc_poll_i11e failed");
- + sys->error_status = -errno;
- + }
- + else if (ret > 0 && p_fds[0].revents
- + && smb2_service(sys->smb2, p_fds[0].revents) < 0)
- + VLC_SMB2_SET_GENERIC_ERROR(access, "smb2_service");
- + }
- + return sys->error_status == 0 ? 0 : -1;
- +}
- +
- +#define VLC_SMB2_GENERIC_CB() \
- + VLC_UNUSED(smb2); \
- + stream_t *access = private_data; \
- + struct access_sys *sys = access->p_sys; \
- + assert(sys->smb2 == smb2); \
- + if (VLC_SMB2_CHECK_STATUS(access, status)) \
- + return
- +
- +static void
- +smb2_generic_cb(struct smb2_context *smb2, int status, void *data,
- + void *private_data)
- +{
- + VLC_UNUSED(data);
- + VLC_SMB2_GENERIC_CB();
- +}
- +
- +static void
- +smb2_read_cb(struct smb2_context *smb2, int status, void *data,
- + void *private_data)
- +{
- + VLC_UNUSED(data);
- + VLC_SMB2_GENERIC_CB();
- +
- + if (status == 0)
- + sys->eof = true;
- + else
- + sys->res.read.len = status;
- +}
- +
- +static ssize_t
- +FileRead(stream_t *access, void *buf, size_t len)
- +{
- + struct access_sys *sys = access->p_sys;
- +
- + if (sys->error_status != 0)
- + return -1;
- +
- + if (sys->eof)
- + return 0;
- +
- + sys->res.read.len = 0;
- + if (smb2_read_async(sys->smb2, sys->smb2fh, buf, len,
- + smb2_read_cb, access) < 0)
- + {
- + VLC_SMB2_SET_GENERIC_ERROR(access, "smb2_read_async");
- + return -1;
- + }
- +
- + if (vlc_smb2_mainloop(access, false) < 0)
- + return -1;
- +
- + return sys->res.read.len;
- +}
- +
- +static int
- +FileSeek(stream_t *access, uint64_t i_pos)
- +{
- + struct access_sys *sys = access->p_sys;
- +
- + if (sys->error_status != 0)
- + return VLC_EGENERIC;
- +
- + if (smb2_lseek(sys->smb2, sys->smb2fh, i_pos, SEEK_SET, NULL) < 0)
- + {
- + VLC_SMB2_SET_GENERIC_ERROR(access, "smb2_seek_async");
- + return VLC_EGENERIC;
- + }
- + sys->eof = false;
- +
- + return VLC_SUCCESS;
- +}
- +
- +static int
- +FileControl(stream_t *access, int i_query, va_list args)
- +{
- + struct access_sys *sys = access->p_sys;
- +
- + switch (i_query)
- + {
- + case STREAM_CAN_SEEK:
- + *va_arg(args, bool *) = true;
- + break;
- +
- + case STREAM_CAN_FASTSEEK:
- + *va_arg(args, bool *) = false;
- + break;
- +
- + case STREAM_CAN_PAUSE:
- + case STREAM_CAN_CONTROL_PACE:
- + *va_arg(args, bool *) = true;
- + break;
- +
- + case STREAM_GET_SIZE:
- + {
- + *va_arg(args, uint64_t *) = sys->smb2_size;
- + break;
- + }
- +
- + case STREAM_GET_PTS_DELAY:
- + *va_arg( args, int64_t * ) = INT64_C(1000)
- + * var_InheritInteger( access, "network-caching" );
- + break;
- +
- + case STREAM_SET_PAUSE_STATE:
- + break;
- +
- + default:
- + return VLC_EGENERIC;
- + }
- + return VLC_SUCCESS;
- +}
- +
- +static char *
- +vlc_smb2_get_url(vlc_url_t *url, const char *file)
- +{
- + /* smb2://<psz_host><psz_path><file>?<psz_option> */
- + char *buf;
- + if (asprintf(&buf, "smb://%s%s%s%s%s%s", url->psz_host,
- + url->psz_path != NULL ? url->psz_path : "",
- + url->psz_path != NULL && url->psz_path[0] != '\0' &&
- + url->psz_path[strlen(url->psz_path) - 1] != '/' ? "/" : "",
- + file,
- + url->psz_option != NULL ? "?" : "",
- + url->psz_option != NULL ? url->psz_option : "") == -1)
- + return NULL;
- + else
- + return buf;
- +}
- +
- +static int AddItem(stream_t *access, struct vlc_readdir_helper *rdh,
- + const char *name, int i_type)
- +{
- + struct access_sys *sys = access->p_sys;
- + char *name_encoded = vlc_uri_encode(name);
- + if (name_encoded == NULL)
- + return VLC_ENOMEM;
- +
- + char *url = vlc_smb2_get_url(&sys->encoded_url, name_encoded);
- + free(name_encoded);
- + if (url == NULL)
- + return VLC_ENOMEM;
- +
- + int ret = vlc_readdir_helper_additem(rdh, url, NULL, name, i_type,
- + ITEM_NET);
- + free(url);
- + return ret;
- +}
- +
- +static int
- +DirRead(stream_t *access, input_item_node_t *p_node)
- +{
- + struct access_sys *sys = access->p_sys;
- + struct smb2dirent *smb2dirent;
- + int ret = VLC_SUCCESS;
- + assert(sys->smb2dir);
- +
- + struct vlc_readdir_helper rdh;
- + vlc_readdir_helper_init(&rdh, access, p_node);
- +
- + while (ret == VLC_SUCCESS
- + && (smb2dirent = smb2_readdir(sys->smb2, sys->smb2dir)) != NULL)
- + {
- + int i_type;
- + switch (smb2dirent->st.smb2_type)
- + {
- + case SMB2_TYPE_FILE:
- + i_type = ITEM_TYPE_FILE;
- + break;
- + case SMB2_TYPE_DIRECTORY:
- + i_type = ITEM_TYPE_DIRECTORY;
- + break;
- + default:
- + i_type = ITEM_TYPE_UNKNOWN;
- + break;
- + }
- + ret = AddItem(access, &rdh, smb2dirent->name, i_type);
- + }
- +
- + vlc_readdir_helper_finish(&rdh, ret == VLC_SUCCESS);
- +
- + return ret;
- +}
- +
- +static int
- +ShareEnum(stream_t *access, input_item_node_t *p_node)
- +{
- + struct access_sys *sys = access->p_sys;
- + assert(sys->share_enum != NULL);
- +
- + int ret = VLC_SUCCESS;
- + struct vlc_readdir_helper rdh;
- + vlc_readdir_helper_init(&rdh, access, p_node);
- +
- + struct srvsvc_netsharectr *ctr = sys->share_enum->ctr;
- + for (uint32_t iinfo = 0;
- + iinfo < ctr->ctr1.count && ret == VLC_SUCCESS; ++iinfo)
- + {
- + struct srvsvc_netshareinfo1 *info = &ctr->ctr1.array[iinfo];
- + if (info->type & SHARE_TYPE_HIDDEN)
- + continue;
- + switch (info->type & 0x3)
- + {
- + case SHARE_TYPE_DISKTREE:
- + ret = AddItem(access, &rdh, info->name, ITEM_TYPE_DIRECTORY);
- + break;
- + }
- + }
- +
- + vlc_readdir_helper_finish(&rdh, ret == VLC_SUCCESS);
- + return 0;
- +}
- +
- +static int
- +vlc_smb2_close_fh(stream_t *access)
- +{
- + struct access_sys *sys = access->p_sys;
- +
- + assert(sys->smb2fh);
- +
- + if (smb2_close_async(sys->smb2, sys->smb2fh, smb2_generic_cb, access) < 0)
- + {
- + VLC_SMB2_SET_GENERIC_ERROR(access, "smb2_close_async");
- + return -1;
- + }
- +
- + sys->smb2fh = NULL;
- +
- + return vlc_smb2_mainloop(access, true);
- +}
- +
- +static int
- +vlc_smb2_disconnect_share(stream_t *access)
- +{
- + struct access_sys *sys = access->p_sys;
- +
- + if (!sys->smb2_connected)
- + return 0;
- +
- + if (smb2_disconnect_share_async(sys->smb2, smb2_generic_cb, access) < 0)
- + {
- + VLC_SMB2_SET_GENERIC_ERROR(access, "smb2_connect_share_async");
- + return -1;
- + }
- +
- + int ret = vlc_smb2_mainloop(access, true);
- + sys->smb2_connected = false;
- + return ret;
- +}
- +
- +static void
- +smb2_opendir_cb(struct smb2_context *smb2, int status, void *data,
- + void *private_data)
- +{
- + VLC_SMB2_GENERIC_CB();
- +
- + sys->smb2dir = data;
- +}
- +
- +static void
- +smb2_open_cb(struct smb2_context *smb2, int status, void *data,
- + void *private_data)
- +{
- + VLC_SMB2_GENERIC_CB();
- +
- + sys->smb2fh = data;
- +}
- +
- +static void
- +smb2_share_enum_cb(struct smb2_context *smb2, int status, void *data,
- + void *private_data)
- +{
- + VLC_SMB2_GENERIC_CB();
- +
- + sys->share_enum = data;
- +}
- +
- +static int
- +vlc_smb2_open_share(stream_t *access, const struct smb2_url *smb2_url,
- + const vlc_credential *credential)
- +{
- + struct access_sys *sys = access->p_sys;
- +
- + const bool do_enum = smb2_url->share[0] == '\0';
- + const char *username = credential->psz_username;
- + const char *password = credential->psz_password;
- + const char *domain = credential->psz_realm;
- + const char *share = do_enum ? "IPC$" : smb2_url->share;
- +
- + if (!username)
- + {
- + username = "Guest";
- + password = "";
- + }
- +
- + smb2_set_password(sys->smb2, password);
- + smb2_set_domain(sys->smb2, domain ? domain : "");
- +
- + if (smb2_connect_share_async(sys->smb2, smb2_url->server, share,
- + username, smb2_generic_cb, access) < 0)
- + {
- + VLC_SMB2_SET_GENERIC_ERROR(access, "smb2_connect_share_async");
- + goto error;
- + }
- + if (vlc_smb2_mainloop(access, false) != 0)
- + goto error;
- + sys->smb2_connected = true;
- +
- + int ret;
- + if (do_enum)
- + ret = smb2_share_enum_async(sys->smb2, smb2_share_enum_cb, access);
- + else
- + {
- + struct smb2_stat_64 smb2_stat;
- + if (smb2_stat_async(sys->smb2, smb2_url->path, &smb2_stat,
- + smb2_generic_cb, access) < 0)
- + VLC_SMB2_SET_GENERIC_ERROR(access, "smb2_stat_async");
- +
- + if (vlc_smb2_mainloop(access, false) != 0)
- + goto error;
- +
- + if (smb2_stat.smb2_type == SMB2_TYPE_FILE)
- + {
- + sys->smb2_size = smb2_stat.smb2_size;
- + ret = smb2_open_async(sys->smb2, smb2_url->path, O_RDONLY,
- + smb2_open_cb, access);
- + }
- + else if (smb2_stat.smb2_type == SMB2_TYPE_DIRECTORY)
- + ret = smb2_opendir_async(sys->smb2, smb2_url->path,
- + smb2_opendir_cb, access);
- + else
- + {
- + msg_Err(access, "smb2_stat_cb: file type not handled");
- + sys->error_status = 1;
- + goto error;
- + }
- + }
- +
- + if (ret < 0)
- + {
- + VLC_SMB2_SET_GENERIC_ERROR(access, "smb2_open*_async");
- + goto error;
- + }
- +
- + if (vlc_smb2_mainloop(access, false) != 0)
- + goto error;
- + return 0;
- +
- +error:
- + vlc_smb2_disconnect_share(access);
- + return -1;
- +}
- +
- +static char *
- +vlc_smb2_resolve(stream_t *access, const char *host, unsigned port)
- +{
- + (void) access;
- + if (!host)
- + return NULL;
- +
- +#ifdef HAVE_DSM
- + /* Test if the host is an IP */
- + struct in_addr addr;
- + if (inet_pton(AF_INET, host, &addr) == 1)
- + return NULL;
- +
- + /* Test if the host can be resolved */
- + struct addrinfo *info = NULL;
- + if (vlc_getaddrinfo_i11e(host, port, NULL, &info) == 0)
- + {
- + freeaddrinfo(info);
- + /* Let smb2 resolve it */
- + return NULL;
- + }
- +
- + /* Test if the host is a netbios name */
- + char *out_host = NULL;
- + netbios_ns *ns = netbios_ns_new();
- + uint32_t ip4_addr;
- + if (netbios_ns_resolve(ns, host, NETBIOS_FILESERVER, &ip4_addr) == 0)
- + {
- + char ip[] = "xxx.xxx.xxx.xxx";
- + if (inet_ntop(AF_INET, &ip4_addr, ip, sizeof(ip)))
- + out_host = strdup(ip);
- + }
- + netbios_ns_destroy(ns);
- + return out_host;
- +#else
- + (void) port;
- + return NULL;
- +#endif
- +}
- +
- +static int
- +Open(vlc_object_t *p_obj)
- +{
- + stream_t *access = (stream_t *)p_obj;
- + struct access_sys *sys = vlc_obj_calloc(p_obj, 1, sizeof (*sys));
- + struct smb2_url *smb2_url = NULL;
- + char *var_domain = NULL;
- +
- + if (unlikely(sys == NULL))
- + return VLC_ENOMEM;
- + access->p_sys = sys;
- +
- + /* Parse the encoded URL */
- + if (vlc_UrlParseFixup(&sys->encoded_url, access->psz_url) != 0)
- + return VLC_ENOMEM;
- +
- + if (sys->encoded_url.i_port != 0 && sys->encoded_url.i_port != CIFS_PORT)
- + goto error;
- + sys->encoded_url.i_port = 0;
- +
- + sys->smb2 = smb2_init_context();
- + if (sys->smb2 == NULL)
- + {
- + msg_Err(access, "smb2_init_context failed");
- + goto error;
- + }
- +
- + if (sys->encoded_url.psz_path == NULL)
- + sys->encoded_url.psz_path = (char *) "/";
- +
- + char *resolved_host = vlc_smb2_resolve(access, sys->encoded_url.psz_host,
- + CIFS_PORT);
- +
- + /* smb2_* functions need a decoded url. Re compose the url from the
- + * modified sys->encoded_url (without port and with the resolved host). */
- + char *url;
- + if (resolved_host != NULL)
- + {
- + vlc_url_t resolved_url = sys->encoded_url;
- + resolved_url.psz_host = resolved_host;
- + url = vlc_uri_compose(&resolved_url);
- + free(resolved_host);
- + }
- + else
- + url = vlc_uri_compose(&sys->encoded_url);
- + if (!vlc_uri_decode(url))
- + {
- + free(url);
- + goto error;
- + }
- + smb2_url = smb2_parse_url(sys->smb2, url);
- + free(url);
- +
- + if (!smb2_url || !smb2_url->share || !smb2_url->server)
- + {
- + msg_Err(access, "smb2_parse_url failed");
- + goto error;
- + }
- +
- + int ret = -1;
- + vlc_credential credential;
- + vlc_credential_init(&credential, &sys->encoded_url);
- + var_domain = var_InheritString(access, "smb-domain");
- + credential.psz_realm = var_domain;
- +
- + /* First, try Guest login or using "smb-" options (without
- + * keystore/user interaction) */
- + vlc_credential_get(&credential, access, "smb-user", "smb-pwd", NULL,
- + NULL);
- + ret = vlc_smb2_open_share(access, smb2_url, &credential);
- +
- + while (ret == -1
- + && (!sys->error_status || VLC_SMB2_STATUS_DENIED(sys->error_status))
- + && vlc_credential_get(&credential, access, "smb-user", "smb-pwd",
- + SMB_LOGIN_DIALOG_TITLE, SMB_LOGIN_DIALOG_TEXT,
- + smb2_url->server))
- + {
- + sys->error_status = 0;
- + ret = vlc_smb2_open_share(access, smb2_url, &credential);
- + if (ret == 0)
- + vlc_credential_store(&credential, access);
- + }
- + vlc_credential_clean(&credential);
- +
- + if (ret != 0)
- + {
- + vlc_dialog_display_error(access,
- + _("SMB2 operation failed"), "%s",
- + smb2_get_error(sys->smb2));
- + goto error;
- + }
- +
- + if (sys->smb2fh != NULL)
- + {
- + access->pf_read = FileRead;
- + access->pf_seek = FileSeek;
- + access->pf_control = FileControl;
- + }
- + else if (sys->smb2dir != NULL)
- + {
- + access->pf_readdir = DirRead;
- + access->pf_seek = NULL;
- + access->pf_control = access_vaDirectoryControlHelper;
- + }
- + else if (sys->share_enum != NULL)
- + {
- + access->pf_readdir = ShareEnum;
- + access->pf_seek = NULL;
- + access->pf_control = access_vaDirectoryControlHelper;
- + }
- + else
- + vlc_assert_unreachable();
- +
- + smb2_destroy_url(smb2_url);
- + free(var_domain);
- + return VLC_SUCCESS;
- +
- +error:
- + if (smb2_url != NULL)
- + smb2_destroy_url(smb2_url);
- + if (sys->smb2 != NULL)
- + {
- + vlc_smb2_disconnect_share(access);
- + smb2_destroy_context(sys->smb2);
- + }
- + vlc_UrlClean(&sys->encoded_url);
- + free(var_domain);
- + return VLC_EGENERIC;
- +}
- +
- +static void
- +Close(vlc_object_t *p_obj)
- +{
- + stream_t *access = (stream_t *)p_obj;
- + struct access_sys *sys = access->p_sys;
- +
- + if (sys->smb2fh != NULL)
- + vlc_smb2_close_fh(access);
- + else if (sys->smb2dir != NULL)
- + smb2_closedir(sys->smb2, sys->smb2dir);
- + else if (sys->share_enum != NULL)
- + smb2_free_data(sys->smb2, sys->share_enum);
- + else
- + vlc_assert_unreachable();
- +
- + vlc_smb2_disconnect_share(access);
- + smb2_destroy_context(sys->smb2);
- +
- + vlc_UrlClean(&sys->encoded_url);
- +}
- diff --git a/po/POTFILES.in b/po/POTFILES.in
- index cb7f3948e9..a976faa015 100644
- --- a/po/POTFILES.in
- +++ b/po/POTFILES.in
- @@ -215,6 +215,7 @@ modules/access/sftp.c
- modules/access/shm.c
- modules/access/smb.c
- modules/access/smb_common.h
- +modules/access/smb2.c
- modules/access/srt.c
- modules/access/tcp.c
- modules/access/timecode.c
- --
- 2.20.1
|