0026-access-add-smb2-module.patch 41 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244
  1. From 00c4ee62fb59a59c51d4db5efbde0d8b5e1e4a39 Mon Sep 17 00:00:00 2001
  2. From: Thomas Guillem <thomas@gllm.fr>
  3. Date: Fri, 13 Apr 2018 16:15:16 +0200
  4. Subject: [PATCH 26/26] access: add smb2 module
  5. Using libsmb2 from Ronnie Sahlberg https://github.com/sahlberg/libsmb2
  6. This is LGPL 2.1 fully async lib for accessing SMB2 and SMB3 shares.
  7. This module use the async feature of the libsmb2 lib with the vlc interrupt
  8. mechanism, therefore every network requests are cancellable almost immediately.
  9. The 2.0.0 version is required since this version drop OpenSSL dependency and
  10. allow to use Builtin NTLMSSP authentication instead of libkrb5.
  11. ---
  12. configure.ac | 14 +-
  13. ...ot-exist-on-darwin-use-posix-ENODEV-.patch | 25 +
  14. contrib/src/smb2/0001-master-backport.patch | 330 ++++++++
  15. contrib/src/smb2/SHA512SUMS | 1 +
  16. contrib/src/smb2/rules.mak | 29 +
  17. modules/MODULES_LIST | 1 +
  18. modules/access/Makefile.am | 11 +
  19. modules/access/smb2.c | 717 ++++++++++++++++++
  20. po/POTFILES.in | 1 +
  21. 9 files changed, 1128 insertions(+), 1 deletion(-)
  22. create mode 100644 contrib/src/smb2/0001-ENOMEDIUM-does-not-exist-on-darwin-use-posix-ENODEV-.patch
  23. create mode 100644 contrib/src/smb2/0001-master-backport.patch
  24. create mode 100644 contrib/src/smb2/SHA512SUMS
  25. create mode 100644 contrib/src/smb2/rules.mak
  26. create mode 100644 modules/access/smb2.c
  27. diff --git a/configure.ac b/configure.ac
  28. index 9891bed93e..9bbba2b3df 100644
  29. --- a/configure.ac
  30. +++ b/configure.ac
  31. @@ -1854,7 +1854,14 @@ AS_IF([test "${SYS}" = "mingw32" -a "${enable_winstore_app}" != "yes"], [ VLC_AD
  32. dnl
  33. dnl liBDSM access module
  34. dnl
  35. -PKG_ENABLE_MODULES_VLC([DSM], [dsm], [libdsm >= 0.2.0], [libdsm SMB/CIFS access/sd module], [auto])
  36. +AM_CONDITIONAL(HAVE_DSM, [test "$AS_TR_SH(with_dsm)" = "yes"])
  37. +PKG_WITH_MODULES([DSM], [libdsm >= 0.2.0], [
  38. + VLC_ADD_PLUGIN([dsm])
  39. + VLC_ADD_CFLAGS([dsm], [$DSM_CFLAGS])
  40. + VLC_ADD_LIBS([dsm], [$DSM_LIBS])
  41. + have_dsm="yes"
  42. + ],,[libdsm SMB/CIFS access/sd module], [auto])
  43. +AM_CONDITIONAL([HAVE_DSM], [test "${have_dsm}" = "yes"])
  44. dnl
  45. dnl sftp access support
  46. @@ -1866,6 +1873,11 @@ dnl nfs access support
  47. dnl
  48. PKG_ENABLE_MODULES_VLC([NFS], [nfs], [libnfs >= 1.10.0], (support nfs protocol via libnfs), [auto])
  49. +dnl
  50. +dnl smb2 access support
  51. +dnl
  52. +PKG_ENABLE_MODULES_VLC([SMB2], [smb2], [libsmb2 >= 2.0.0], (support smb2 protocol via libsmb2), [auto])
  53. +
  54. dnl
  55. dnl Video4Linux 2
  56. dnl
  57. 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
  58. new file mode 100644
  59. index 0000000000..93763dd660
  60. --- /dev/null
  61. +++ b/contrib/src/smb2/0001-ENOMEDIUM-does-not-exist-on-darwin-use-posix-ENODEV-.patch
  62. @@ -0,0 +1,25 @@
  63. +From 2256d19bc9fead528bac900d894d65e9b030f7f8 Mon Sep 17 00:00:00 2001
  64. +From: "S. Davilla" <davilla@4pi.com>
  65. +Date: Mon, 22 Oct 2018 20:53:15 -0400
  66. +Subject: [PATCH] ENOMEDIUM does not exist on darwin, use posix ENODEV instead
  67. +
  68. +---
  69. + lib/errors.c | 2 +-
  70. + 1 file changed, 1 insertion(+), 1 deletion(-)
  71. +
  72. +diff --git a/lib/errors.c b/lib/errors.c
  73. +index f2696c0..3612f9a 100644
  74. +--- a/lib/errors.c
  75. ++++ b/lib/errors.c
  76. +@@ -218,7 +218,7 @@ int nterror_to_errno(uint32_t status) {
  77. + case SMB2_STATUS_MEDIA_WRITE_PROTECTED:
  78. + return EROFS;
  79. + case SMB2_STATUS_NO_MEDIA_IN_DEVICE:
  80. +- return ENOMEDIUM;
  81. ++ return ENODEV;
  82. + case SMB2_STATUS_DATA_ERROR:
  83. + case SMB2_STATUS_CRC_ERROR:
  84. + case SMB2_STATUS_DEVICE_DATA_ERROR:
  85. +--
  86. +2.17.2 (Apple Git-113)
  87. +
  88. diff --git a/contrib/src/smb2/0001-master-backport.patch b/contrib/src/smb2/0001-master-backport.patch
  89. new file mode 100644
  90. index 0000000000..0f9cf7cf62
  91. --- /dev/null
  92. +++ b/contrib/src/smb2/0001-master-backport.patch
  93. @@ -0,0 +1,330 @@
  94. +From 49525025f8c91ae14e5fe3cfea0dc7948b7f5480 Mon Sep 17 00:00:00 2001
  95. +From: Thomas Guillem <thomas@gllm.fr>
  96. +Date: Tue, 12 Feb 2019 12:42:37 +0100
  97. +Subject: [PATCH] master-backport
  98. +
  99. +Waiting for a new release, including the following patches:
  100. +
  101. +libsmb_error patch
  102. +Delete libsmb2_error.latest.patch
  103. +Allow passing NULL to smb2_set_password
  104. +Add more error status
  105. +Map more EACCESS error status
  106. +---
  107. + include/smb2/smb2-errors.h | 50 +++++++++++
  108. + lib/errors.c | 178 +++++++++++++++++++++++++++++++++++--
  109. + lib/init.c | 4 +
  110. + 3 files changed, 223 insertions(+), 9 deletions(-)
  111. +
  112. +diff --git a/include/smb2/smb2-errors.h b/include/smb2/smb2-errors.h
  113. +index 49c5d5c..3b741e7 100644
  114. +--- a/include/smb2/smb2-errors.h
  115. ++++ b/include/smb2/smb2-errors.h
  116. +@@ -35,13 +35,63 @@
  117. + /* Error codes */
  118. + #define SMB2_STATUS_SUCCESS 0x00000000
  119. + #define SMB2_STATUS_PENDING 0x00000103
  120. ++#define SMB2_STATUS_SMB_BAD_FID 0x00060001
  121. + #define SMB2_STATUS_NO_MORE_FILES 0x80000006
  122. ++#define SMB2_STATUS_NOT_IMPLEMENTED 0xC0000002
  123. ++#define SMB2_STATUS_INVALID_HANDLE 0xC0000008
  124. + #define SMB2_STATUS_INVALID_PARAMETER 0xC000000d
  125. ++#define SMB2_STATUS_NO_SUCH_DEVICE 0xC000000E
  126. ++#define SMB2_STATUS_NO_SUCH_FILE 0xC000000F
  127. ++#define SMB2_STATUS_INVALID_DEVICE_REQUEST 0xC0000010
  128. + #define SMB2_STATUS_END_OF_FILE 0xC0000011
  129. ++#define SMB2_STATUS_NO_MEDIA_IN_DEVICE 0xC0000013
  130. + #define SMB2_STATUS_MORE_PROCESSING_REQUIRED 0xC0000016
  131. ++#define SMB2_STATUS_INVALID_LOCK_SEQUENCE 0xC000001E
  132. ++#define SMB2_STATUS_INVALID_VIEW_SIZE 0xC000001F
  133. ++#define SMB2_STATUS_ALREADY_COMMITTED 0xC0000021
  134. + #define SMB2_STATUS_ACCESS_DENIED 0xC0000022
  135. ++#define SMB2_STATUS_OBJECT_TYPE_MISMATCH 0xC0000024
  136. + #define SMB2_STATUS_OBJECT_NAME_NOT_FOUND 0xC0000034
  137. ++#define SMB2_STATUS_OBJECT_NAME_COLLISION 0xC0000035
  138. ++#define SMB2_STATUS_PORT_DISCONNECTED 0xC0000037
  139. ++#define SMB2_STATUS_OBJECT_PATH_INVALID 0xC0000039
  140. ++#define SMB2_STATUS_OBJECT_PATH_NOT_FOUND 0xC000003A
  141. ++#define SMB2_STATUS_OBJECT_PATH_SYNTAX_BAD 0xC000003B
  142. ++#define SMB2_STATUS_DATA_ERROR 0xC000003E
  143. ++#define SMB2_STATUS_CRC_ERROR 0xC000003F
  144. ++#define SMB2_STATUS_SECTION_TOO_BIG 0xC0000040
  145. ++#define SMB2_STATUS_PORT_CONNECTION_REFUSED 0xC0000041
  146. ++#define SMB2_STATUS_INVALID_PORT_HANDLE 0xC0000042
  147. ++#define SMB2_STATUS_SHARING_VIOLATION 0xC0000043
  148. ++#define SMB2_STATUS_THREAD_IS_TERMINATING 0xC000004B
  149. ++#define SMB2_STATUS_FILE_LOCK_CONFLICT 0xC0000054
  150. ++#define SMB2_STATUS_LOCK_NOT_GRANTED 0xC0000055
  151. ++#define SMB2_STATUS_DELETE_PENDING 0xC0000056
  152. ++#define SMB2_STATUS_PRIVILEGE_NOT_HELD 0xC0000061
  153. + #define SMB2_STATUS_LOGON_FAILURE 0xC000006d
  154. ++#define SMB2_STATUS_ACCOUNT_RESTRICTION 0xC000006E
  155. ++#define SMB2_STATUS_INVALID_LOGON_HOURS 0xC000006F
  156. ++#define SMB2_STATUS_PASSWORD_EXPIRED 0xC0000071
  157. ++#define SMB2_STATUS_ACCOUNT_DISABLED 0xC0000072
  158. ++#define SMB2_STATUS_DISK_FULL 0xC000007F
  159. ++#define SMB2_STATUS_TOO_MANY_PAGING_FILES 0xC0000097
  160. ++#define SMB2_STATUS_DFS_EXIT_PATH_FOUND 0xC000009B
  161. ++#define SMB2_STATUS_DEVICE_DATA_ERROR 0xC000009C
  162. ++#define SMB2_STATUS_MEDIA_WRITE_PROTECTED 0xC00000A2
  163. ++#define SMB2_STATUS_ILLEGAL_FUNCTION 0xC00000AF
  164. ++#define SMB2_STATUS_PIPE_DISCONNECTED 0xC00000B0
  165. ++#define SMB2_STATUS_FILE_IS_A_DIRECTORY 0xC00000BA
  166. ++#define SMB2_STATUS_NETWORK_ACCESS_DENIED 0xC00000CA
  167. + #define SMB2_STATUS_BAD_NETWORK_NAME 0xC00000CC
  168. ++#define SMB2_STATUS_NOT_SAME_DEVICE 0xC00000D4
  169. ++#define SMB2_STATUS_FILE_RENAMED 0xC00000D5
  170. ++#define SMB2_STATUS_REDIRECTOR_NOT_STARTED 0xC00000FB
  171. ++#define SMB2_STATUS_DIRECTORY_NOT_EMPTY 0xC0000101
  172. + #define SMB2_STATUS_NOT_A_DIRECTORY 0xC0000103
  173. ++#define SMB2_STATUS_PROCESS_IS_TERMINATING 0xC000010A
  174. ++#define SMB2_STATUS_TOO_MANY_OPENED_FILES 0xC000011F
  175. ++#define SMB2_STATUS_CANNOT_DELETE 0xC0000121
  176. ++#define SMB2_STATUS_FILE_DELETED 0xC0000123
  177. + #define SMB2_STATUS_FILE_CLOSED 0xC0000128
  178. ++#define SMB2_STATUS_INSUFF_SERVER_RESOURCES 0xC0000205
  179. ++#define SMB2_STATUS_HANDLE_NOT_CLOSABLE 0xC0000235
  180. +diff --git a/lib/errors.c b/lib/errors.c
  181. +index 68150a0..2e1648d 100644
  182. +--- a/lib/errors.c
  183. ++++ b/lib/errors.c
  184. +@@ -30,26 +30,124 @@ const char *nterror_to_str(uint32_t status) {
  185. + return "STATUS_PENDING";
  186. + case SMB2_STATUS_NO_MORE_FILES:
  187. + return "STATUS_NO_MORE_FILES";
  188. ++ case SMB2_STATUS_NOT_IMPLEMENTED:
  189. ++ return "STATUS_NOT_IMPLEMENTED";
  190. ++ case SMB2_STATUS_INVALID_HANDLE:
  191. ++ return "STATUS_INVALID_HANDLE";
  192. ++ case SMB2_STATUS_INVALID_PARAMETER:
  193. ++ return "STATUS_INVALID_PARAMETER";
  194. ++ case SMB2_STATUS_NO_SUCH_DEVICE:
  195. ++ return "STATUS_NO_SUCH_DEVICE";
  196. ++ case SMB2_STATUS_NO_SUCH_FILE:
  197. ++ return "STATUS_NO_SUCH_FILE";
  198. ++ case SMB2_STATUS_INVALID_DEVICE_REQUEST:
  199. ++ return "STATUS_INVALID_DEVICE_REQUEST";
  200. ++ case SMB2_STATUS_END_OF_FILE:
  201. ++ return "STATUS_END_OF_FILE";
  202. ++ case SMB2_STATUS_NO_MEDIA_IN_DEVICE:
  203. ++ return "STATUS_NO_MEDIA_IN_DEVICE";
  204. + case SMB2_STATUS_MORE_PROCESSING_REQUIRED:
  205. + return "STATUS_MORE_PROCESSING_REQUIRED";
  206. ++ case SMB2_STATUS_INVALID_LOCK_SEQUENCE:
  207. ++ return "STATUS_INVALID_LOCK_SEQUENCE";
  208. ++ case SMB2_STATUS_INVALID_VIEW_SIZE:
  209. ++ return "STATUS_INVALID_VIEW_SIZE";
  210. ++ case SMB2_STATUS_ALREADY_COMMITTED:
  211. ++ return "STATUS_ALREADY_COMMITTED";
  212. + case SMB2_STATUS_ACCESS_DENIED:
  213. + return "STATUS_ACCESS_DENIED";
  214. ++ case SMB2_STATUS_OBJECT_TYPE_MISMATCH:
  215. ++ return "STATUS_OBJECT_TYPE_MISMATCH";
  216. ++ case SMB2_STATUS_OBJECT_NAME_NOT_FOUND:
  217. ++ return "STATUS_OBJECT_NAME_NOT_FOUND";
  218. ++ case SMB2_STATUS_OBJECT_NAME_COLLISION:
  219. ++ return "STATUS_OBJECT_NAME_COLLISION";
  220. ++ case SMB2_STATUS_PORT_DISCONNECTED:
  221. ++ return "STATUS_PORT_DISCONNECTED";
  222. ++ case SMB2_STATUS_OBJECT_PATH_INVALID:
  223. ++ return "STATUS_OBJECT_PATH_INVALID";
  224. ++ case SMB2_STATUS_OBJECT_PATH_NOT_FOUND:
  225. ++ return "STATUS_OBJECT_PATH_NOT_FOUND";
  226. ++ case SMB2_STATUS_OBJECT_PATH_SYNTAX_BAD:
  227. ++ return "STATUS_OBJECT_PATH_SYNTAX_BAD";
  228. ++ case SMB2_STATUS_DATA_ERROR:
  229. ++ return "STATUS_DATA_ERROR";
  230. ++ case SMB2_STATUS_CRC_ERROR:
  231. ++ return "STATUS_CRC_ERROR";
  232. ++ case SMB2_STATUS_SECTION_TOO_BIG:
  233. ++ return "STATUS_SECTION_TOO_BIG";
  234. ++ case SMB2_STATUS_PORT_CONNECTION_REFUSED:
  235. ++ return "STATUS_PORT_CONNECTION_REFUSED";
  236. ++ case SMB2_STATUS_INVALID_PORT_HANDLE:
  237. ++ return "STATUS_INVALID_PORT_HANDLE";
  238. ++ case SMB2_STATUS_SHARING_VIOLATION:
  239. ++ return "STATUS_SHARING_VIOLATION";
  240. ++ case SMB2_STATUS_THREAD_IS_TERMINATING:
  241. ++ return "STATUS_THREAD_IS_TERMINATING";
  242. ++ case SMB2_STATUS_FILE_LOCK_CONFLICT:
  243. ++ return "STATUS_FILE_LOCK_CONFLICT";
  244. ++ case SMB2_STATUS_LOCK_NOT_GRANTED:
  245. ++ return "STATUS_LOCK_NOT_GRANTED";
  246. ++ case SMB2_STATUS_DELETE_PENDING:
  247. ++ return "STATUS_DELETE_PENDING";
  248. ++ case SMB2_STATUS_PRIVILEGE_NOT_HELD:
  249. ++ return "STATUS_PRIVILEGE_NOT_HELD";
  250. + case SMB2_STATUS_LOGON_FAILURE:
  251. + return "STATUS_LOGON_FAILURE";
  252. ++ case SMB2_STATUS_ACCOUNT_RESTRICTION:
  253. ++ return "STATUS_ACCOUNT_RESTRICTION";
  254. ++ case SMB2_STATUS_INVALID_LOGON_HOURS:
  255. ++ return "STATUS_INVALID_LOGON_HOURS";
  256. ++ case SMB2_STATUS_PASSWORD_EXPIRED:
  257. ++ return "STATUS_PASSWORD_EXPIRED";
  258. ++ case SMB2_STATUS_ACCOUNT_DISABLED:
  259. ++ return "STATUS_ACCOUNT_DISABLED";
  260. ++ case SMB2_STATUS_DISK_FULL:
  261. ++ return "STATUS_DISK_FULL";
  262. ++ case SMB2_STATUS_TOO_MANY_PAGING_FILES:
  263. ++ return "STATUS_TOO_MANY_PAGING_FILES";
  264. ++ case SMB2_STATUS_DFS_EXIT_PATH_FOUND:
  265. ++ return "STATUS_DFS_EXIT_PATH_FOUND";
  266. ++ case SMB2_STATUS_DEVICE_DATA_ERROR:
  267. ++ return "STATUS_DEVICE_DATA_ERROR";
  268. ++ case SMB2_STATUS_MEDIA_WRITE_PROTECTED:
  269. ++ return "STATUS_MEDIA_WRITE_PROTECTED";
  270. ++ case SMB2_STATUS_ILLEGAL_FUNCTION:
  271. ++ return "STATUS_ILLEGAL_FUNCTION";
  272. ++ case SMB2_STATUS_PIPE_DISCONNECTED:
  273. ++ return "STATUS_PIPE_DISCONNECTED";
  274. ++ case SMB2_STATUS_FILE_IS_A_DIRECTORY:
  275. ++ return "STATUS_FILE_IS_A_DIRECTORY";
  276. ++ case SMB2_STATUS_NETWORK_ACCESS_DENIED:
  277. ++ return "STATUS_NETWORK_ACCESS_DENIED";
  278. + case SMB2_STATUS_BAD_NETWORK_NAME:
  279. + return "STATUS_BAD_NETWORK_NAME";
  280. ++ case SMB2_STATUS_NOT_SAME_DEVICE:
  281. ++ return "STATUS_NOT_SAME_DEVICE";
  282. ++ case SMB2_STATUS_FILE_RENAMED:
  283. ++ return "STATUS_FILE_RENAMED";
  284. ++ case SMB2_STATUS_REDIRECTOR_NOT_STARTED:
  285. ++ return "STATUS_REDIRECTOR_NOT_STARTED";
  286. ++ case SMB2_STATUS_DIRECTORY_NOT_EMPTY:
  287. ++ return "STATUS_DIRECTORY_NOT_EMPTY";
  288. + case SMB2_STATUS_NOT_A_DIRECTORY:
  289. + return "STATUS_NOT_A_DIRECTORY";
  290. +- case SMB2_STATUS_INVALID_PARAMETER:
  291. +- return "STATUS_INVALID_PARAMETER";
  292. +- case SMB2_STATUS_END_OF_FILE:
  293. +- return "STATUS_END_OF_FILE";
  294. ++ case SMB2_STATUS_PROCESS_IS_TERMINATING:
  295. ++ return "STATUS_PROCESS_IS_TERMINATING";
  296. ++ case SMB2_STATUS_TOO_MANY_OPENED_FILES:
  297. ++ return "STATUS_TOO_MANY_OPENED_FILES";
  298. ++ case SMB2_STATUS_CANNOT_DELETE:
  299. ++ return "STATUS_CANNOT_DELETE";
  300. ++ case SMB2_STATUS_FILE_DELETED:
  301. ++ return "STATUS_FILE_DELETED";
  302. + case SMB2_STATUS_FILE_CLOSED:
  303. + return "STATUS_FILE_CLOSED";
  304. +- case SMB2_STATUS_OBJECT_NAME_NOT_FOUND:
  305. +- return "STATUS_OBJECT_NAME_NOT_FOUND";
  306. ++ case SMB2_STATUS_INSUFF_SERVER_RESOURCES:
  307. ++ return "STATUS_INSUFF_SERVER_RESOURCES";
  308. ++ case SMB2_STATUS_HANDLE_NOT_CLOSABLE:
  309. ++ return "STATUS_HANDLE_NOT_CLOSABLE";
  310. + default:
  311. +- return "Unknown";
  312. ++ return "Unknown";
  313. + }
  314. + }
  315. +
  316. +@@ -58,25 +156,87 @@ int nterror_to_errno(uint32_t status) {
  317. + case SMB2_STATUS_SUCCESS:
  318. + case SMB2_STATUS_END_OF_FILE:
  319. + return 0;
  320. ++ case SMB2_STATUS_PENDING:
  321. ++ return EAGAIN;
  322. ++ case SMB2_STATUS_NO_SUCH_FILE:
  323. ++ case SMB2_STATUS_NO_SUCH_DEVICE:
  324. + case SMB2_STATUS_BAD_NETWORK_NAME:
  325. + case SMB2_STATUS_OBJECT_NAME_NOT_FOUND:
  326. ++ case SMB2_STATUS_OBJECT_PATH_INVALID:
  327. ++ case SMB2_STATUS_OBJECT_PATH_NOT_FOUND:
  328. ++ case SMB2_STATUS_OBJECT_PATH_SYNTAX_BAD:
  329. ++ case SMB2_STATUS_DFS_EXIT_PATH_FOUND:
  330. ++ case SMB2_STATUS_REDIRECTOR_NOT_STARTED:
  331. + return ENOENT;
  332. + case SMB2_STATUS_FILE_CLOSED:
  333. ++ case SMB2_STATUS_SMB_BAD_FID:
  334. ++ case SMB2_STATUS_INVALID_HANDLE:
  335. ++ case SMB2_STATUS_OBJECT_TYPE_MISMATCH:
  336. ++ case SMB2_STATUS_PORT_DISCONNECTED:
  337. ++ case SMB2_STATUS_INVALID_PORT_HANDLE:
  338. ++ case SMB2_STATUS_HANDLE_NOT_CLOSABLE:
  339. + return EBADF;
  340. + case SMB2_STATUS_MORE_PROCESSING_REQUIRED:
  341. + return EAGAIN;
  342. + case SMB2_STATUS_ACCESS_DENIED:
  343. ++ case SMB2_STATUS_NETWORK_ACCESS_DENIED:
  344. ++ case SMB2_STATUS_ACCOUNT_RESTRICTION:
  345. ++ case SMB2_STATUS_INVALID_LOGON_HOURS:
  346. ++ case SMB2_STATUS_PASSWORD_EXPIRED:
  347. ++ case SMB2_STATUS_ACCOUNT_DISABLED:
  348. + return EACCES;
  349. +- case SMB2_STATUS_PENDING:
  350. +- return EAGAIN;
  351. ++ case SMB2_STATUS_INVALID_LOCK_SEQUENCE:
  352. ++ case SMB2_STATUS_INVALID_VIEW_SIZE:
  353. ++ case SMB2_STATUS_ALREADY_COMMITTED:
  354. ++ case SMB2_STATUS_PORT_CONNECTION_REFUSED:
  355. ++ case SMB2_STATUS_THREAD_IS_TERMINATING:
  356. ++ case SMB2_STATUS_DELETE_PENDING:
  357. ++ case SMB2_STATUS_PRIVILEGE_NOT_HELD:
  358. ++ case SMB2_STATUS_FILE_IS_A_DIRECTORY:
  359. ++ case SMB2_STATUS_FILE_RENAMED:
  360. ++ case SMB2_STATUS_PROCESS_IS_TERMINATING:
  361. ++ case SMB2_STATUS_DIRECTORY_NOT_EMPTY:
  362. ++ case SMB2_STATUS_CANNOT_DELETE:
  363. ++ case SMB2_STATUS_FILE_DELETED:
  364. ++ return EPERM;
  365. + case SMB2_STATUS_NO_MORE_FILES:
  366. + return ENODATA;
  367. + case SMB2_STATUS_LOGON_FAILURE:
  368. + return ECONNREFUSED;
  369. + case SMB2_STATUS_NOT_A_DIRECTORY:
  370. + return ENOTDIR;
  371. ++ case SMB2_STATUS_NOT_IMPLEMENTED:
  372. ++ case SMB2_STATUS_INVALID_DEVICE_REQUEST:
  373. ++ case SMB2_STATUS_ILLEGAL_FUNCTION:
  374. + case SMB2_STATUS_INVALID_PARAMETER:
  375. + return EINVAL;
  376. ++ case SMB2_STATUS_TOO_MANY_OPENED_FILES:
  377. ++ return EMFILE;
  378. ++ case SMB2_STATUS_SECTION_TOO_BIG:
  379. ++ case SMB2_STATUS_TOO_MANY_PAGING_FILES:
  380. ++ case SMB2_STATUS_INSUFF_SERVER_RESOURCES:
  381. ++ return ENOMEM;
  382. ++ case SMB2_STATUS_NOT_SAME_DEVICE:
  383. ++ return EXDEV;
  384. ++ case SMB2_STATUS_SHARING_VIOLATION:
  385. ++ return ETXTBSY;
  386. ++ case SMB2_STATUS_FILE_LOCK_CONFLICT:
  387. ++ case SMB2_STATUS_LOCK_NOT_GRANTED:
  388. ++ return EDEADLK;
  389. ++ case SMB2_STATUS_OBJECT_NAME_COLLISION:
  390. ++ return EEXIST;
  391. ++ case SMB2_STATUS_PIPE_DISCONNECTED:
  392. ++ return EPIPE;
  393. ++ case SMB2_STATUS_MEDIA_WRITE_PROTECTED:
  394. ++ return EROFS;
  395. ++ case SMB2_STATUS_NO_MEDIA_IN_DEVICE:
  396. ++ return ENOMEDIUM;
  397. ++ case SMB2_STATUS_DATA_ERROR:
  398. ++ case SMB2_STATUS_CRC_ERROR:
  399. ++ case SMB2_STATUS_DEVICE_DATA_ERROR:
  400. ++ return EIO;
  401. ++ case SMB2_STATUS_DISK_FULL:
  402. ++ return ENOSPC;
  403. + default:
  404. + return EIO;
  405. + }
  406. +diff --git a/lib/init.c b/lib/init.c
  407. +index 3720a1c..6c95cd2 100644
  408. +--- a/lib/init.c
  409. ++++ b/lib/init.c
  410. +@@ -412,6 +412,10 @@ void smb2_set_password(struct smb2_context *smb2, const char *password)
  411. + {
  412. + if (smb2->password) {
  413. + free(discard_const(smb2->password));
  414. ++ smb2->password = NULL;
  415. ++ }
  416. ++ if (password == NULL) {
  417. ++ return;
  418. + }
  419. + smb2->password = strdup(password);
  420. + }
  421. +--
  422. +2.20.1
  423. +
  424. diff --git a/contrib/src/smb2/SHA512SUMS b/contrib/src/smb2/SHA512SUMS
  425. new file mode 100644
  426. index 0000000000..eae3dd89c5
  427. --- /dev/null
  428. +++ b/contrib/src/smb2/SHA512SUMS
  429. @@ -0,0 +1 @@
  430. +5e7101e54a4a95eae2ed5b05dfb51a33e9d4ce19275a405fbb1e86f9e9fe197de53b41c301ca992f19a03e5117ccc90d0acb174eb9c000c71674a0dbacf57614 libsmb2-2.0.0.tar.gz
  431. diff --git a/contrib/src/smb2/rules.mak b/contrib/src/smb2/rules.mak
  432. new file mode 100644
  433. index 0000000000..c14f58964f
  434. --- /dev/null
  435. +++ b/contrib/src/smb2/rules.mak
  436. @@ -0,0 +1,29 @@
  437. +# SMB2
  438. +SMB2_VERSION := 2.0.0
  439. +SMB2_URL := https://github.com/sahlberg/libsmb2/archive/v$(SMB2_VERSION).tar.gz
  440. +
  441. +ifdef BUILD_NETWORK
  442. +ifndef HAVE_WIN32
  443. +PKGS += smb2
  444. +endif
  445. +endif
  446. +ifeq ($(call need_pkg,"smb2"),)
  447. +PKGS_FOUND += smb2
  448. +endif
  449. +
  450. +$(TARBALLS)/libsmb2-$(SMB2_VERSION).tar.gz:
  451. + $(call download_pkg,$(SMB2_URL),smb2)
  452. +
  453. +.sum-smb2: libsmb2-$(SMB2_VERSION).tar.gz
  454. +
  455. +smb2: libsmb2-$(SMB2_VERSION).tar.gz .sum-smb2
  456. + $(UNPACK)
  457. + $(APPLY) $(SRC)/smb2/0001-master-backport.patch
  458. + $(APPLY) $(SRC)/smb2/0001-ENOMEDIUM-does-not-exist-on-darwin-use-posix-ENODEV-.patch
  459. + $(MOVE)
  460. +
  461. +.smb2: smb2
  462. + cd $< && ./bootstrap
  463. + cd $< && $(HOSTVARS) ./configure --disable-examples --disable-werror --without-libkrb5 $(HOSTCONF)
  464. + cd $< && $(MAKE) install
  465. + touch $@
  466. diff --git a/modules/MODULES_LIST b/modules/MODULES_LIST
  467. index 051344019c..cbc2a52b69 100644
  468. --- a/modules/MODULES_LIST
  469. +++ b/modules/MODULES_LIST
  470. @@ -363,6 +363,7 @@ $Id$
  471. * skins2: Skinnable interface, new generation
  472. * skiptags: APE & ID3 tags-skipping stream filter
  473. * smb: SMB shares access module
  474. + * smb2: SMB2/3 access module
  475. * smf: Standard MIDI file demuxer
  476. * sndio: OpenBSD sndio audio output
  477. * soxr: SoX Resampler library audio filter
  478. diff --git a/modules/access/Makefile.am b/modules/access/Makefile.am
  479. index 765ceec45f..2a773029e3 100644
  480. --- a/modules/access/Makefile.am
  481. +++ b/modules/access/Makefile.am
  482. @@ -344,6 +344,17 @@ libdsm_plugin_la_LDFLAGS = $(AM_LDFLAGS) -rpath '$(accessdir)'
  483. access_LTLIBRARIES += $(LTLIBdsm)
  484. EXTRA_LTLIBRARIES += libdsm_plugin.la
  485. +libsmb2_plugin_la_SOURCES = access/smb2.c
  486. +libsmb2_plugin_la_CFLAGS = $(AM_CFLAGS) $(SMB2_CFLAGS)
  487. +libsmb2_plugin_la_LIBADD = $(SMB2_LIBS) $(SOCKET_LIBS)
  488. +libsmb2_plugin_la_LDFLAGS = $(AM_LDFLAGS) -rpath '$(accessdir)'
  489. +if HAVE_DSM
  490. +libsmb2_plugin_la_CFLAGS += $(DSM_CFLAGS) -DHAVE_DSM
  491. +libsmb2_plugin_la_LIBADD += $(DSM_LIBS)
  492. +endif
  493. +access_LTLIBRARIES += $(LTLIBsmb2)
  494. +EXTRA_LTLIBRARIES += libsmb2_plugin.la
  495. +
  496. libtcp_plugin_la_SOURCES = access/tcp.c
  497. libtcp_plugin_la_LIBADD = $(SOCKET_LIBS)
  498. access_LTLIBRARIES += libtcp_plugin.la
  499. diff --git a/modules/access/smb2.c b/modules/access/smb2.c
  500. new file mode 100644
  501. index 0000000000..90cd0d327f
  502. --- /dev/null
  503. +++ b/modules/access/smb2.c
  504. @@ -0,0 +1,717 @@
  505. +/*****************************************************************************
  506. + * smb2.c: SMB2 access plug-in
  507. + *****************************************************************************
  508. + * Copyright © 2018 VLC authors, VideoLAN and VideoLabs
  509. + *
  510. + * This program is free software; you can redistribute it and/or modify it
  511. + * under the terms of the GNU Lesser General Public License as published by
  512. + * the Free Software Foundation; either version 2.1 of the License, or
  513. + * (at your option) any later version.
  514. + *
  515. + * This program is distributed in the hope that it will be useful,
  516. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  517. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  518. + * GNU Lesser General Public License for more details.
  519. + *
  520. + * You should have received a copy of the GNU Lesser General Public License
  521. + * along with this program; if not, write to the Free Software Foundation,
  522. + * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
  523. + *****************************************************************************/
  524. +
  525. +#ifdef HAVE_CONFIG_H
  526. +# include "config.h"
  527. +#endif
  528. +
  529. +#include <assert.h>
  530. +#include <errno.h>
  531. +#include <stdint.h>
  532. +#include <stdlib.h>
  533. +#include <sys/types.h>
  534. +#include <sys/stat.h>
  535. +#include <fcntl.h>
  536. +#ifdef HAVE_POLL
  537. +# include <poll.h>
  538. +#endif
  539. +
  540. +#include <vlc_common.h>
  541. +#include <vlc_access.h>
  542. +#include <vlc_dialog.h>
  543. +#include <vlc_input_item.h>
  544. +#include <vlc_plugin.h>
  545. +#include <vlc_url.h>
  546. +#include <vlc_keystore.h>
  547. +#include <vlc_interrupt.h>
  548. +#include <vlc_network.h>
  549. +
  550. +#include <smb2/smb2.h>
  551. +#include <smb2/libsmb2.h>
  552. +#include <smb2/libsmb2-raw.h>
  553. +
  554. +#ifdef HAVE_DSM
  555. +# include <bdsm/netbios_ns.h>
  556. +# include <bdsm/netbios_defs.h>
  557. +
  558. +# ifdef HAVE_ARPA_INET_H
  559. +# include <arpa/inet.h>
  560. +# endif
  561. +#endif
  562. +
  563. +#include "smb_common.h"
  564. +
  565. +#define CIFS_PORT 445
  566. +
  567. +static int Open(vlc_object_t *);
  568. +static void Close(vlc_object_t *);
  569. +
  570. +vlc_module_begin()
  571. + set_shortname("smb2")
  572. + set_description(N_("SMB2 / SMB3 input"))
  573. + set_help(N_("Samba (Windows network shares) input via libsmb2"))
  574. + set_capability("access", 21)
  575. + set_category(CAT_INPUT)
  576. + set_subcategory(SUBCAT_INPUT_ACCESS)
  577. + add_string("smb-user", NULL, SMB_USER_TEXT, SMB_USER_LONGTEXT, false)
  578. + add_password("smb-pwd", NULL, SMB_PASS_TEXT, SMB_PASS_LONGTEXT, false)
  579. + add_string("smb-domain", NULL, SMB_DOMAIN_TEXT, SMB_DOMAIN_LONGTEXT, false)
  580. + add_shortcut("smb", "smb2")
  581. + set_callbacks(Open, Close)
  582. +vlc_module_end()
  583. +
  584. +struct access_sys
  585. +{
  586. + struct smb2_context * smb2;
  587. + struct smb2fh * smb2fh;
  588. + struct smb2dir * smb2dir;
  589. + struct srvsvc_netshareenumall_rep *share_enum;
  590. + uint64_t smb2_size;
  591. + vlc_url_t encoded_url;
  592. + bool eof;
  593. + bool smb2_connected;
  594. + int error_status;
  595. +
  596. + bool res_done;
  597. + union {
  598. + struct
  599. + {
  600. + size_t len;
  601. + } read;
  602. + } res;
  603. +};
  604. +
  605. +static int
  606. +smb2_check_status(stream_t *access, int status, const char *psz_func)
  607. +{
  608. + struct access_sys *sys = access->p_sys;
  609. +
  610. + if (status < 0)
  611. + {
  612. + const char *psz_error = smb2_get_error(sys->smb2);
  613. + msg_Warn(access, "%s failed: %d, '%s'", psz_func, status, psz_error);
  614. + sys->error_status = status;
  615. + return -1;
  616. + }
  617. + else
  618. + {
  619. + sys->res_done = true;
  620. + return 0;
  621. + }
  622. +}
  623. +
  624. +static void
  625. +smb2_set_generic_error(stream_t *access, const char *psz_func)
  626. +{
  627. + struct access_sys *sys = access->p_sys;
  628. +
  629. + msg_Err(access, "%s failed: %s", psz_func, smb2_get_error(sys->smb2));
  630. + sys->error_status = 1;
  631. +}
  632. +
  633. +#define VLC_SMB2_CHECK_STATUS(access, status) \
  634. + smb2_check_status(access, status, __func__)
  635. +
  636. +#define VLC_SMB2_SET_GENERIC_ERROR(access, func) \
  637. + smb2_set_generic_error(access, func)
  638. +
  639. +#define VLC_SMB2_STATUS_DENIED(x) (x == -ECONNREFUSED || x == -EACCES)
  640. +
  641. +static int
  642. +vlc_smb2_mainloop(stream_t *access, bool teardown)
  643. +{
  644. + struct access_sys *sys = access->p_sys;
  645. +
  646. + int timeout = -1;
  647. + int (*poll_func)(struct pollfd *, unsigned, int) = vlc_poll_i11e;
  648. +
  649. + if (teardown && vlc_killed())
  650. + {
  651. + /* The thread is interrupted, so vlc_poll_i11e will return immediatly.
  652. + * Use poll() with a timeout instead for tear down. */
  653. + timeout = 500;
  654. + poll_func = (void *)poll;
  655. + }
  656. +
  657. + sys->res_done = false;
  658. + while (sys->error_status == 0 && !sys->res_done)
  659. + {
  660. + struct pollfd p_fds[1];
  661. + int ret;
  662. + p_fds[0].fd = smb2_get_fd(sys->smb2);
  663. + p_fds[0].events = smb2_which_events(sys->smb2);
  664. +
  665. + if (p_fds[0].fd == -1 || (ret = poll_func(p_fds, 1, timeout)) < 0)
  666. + {
  667. + if (errno == EINTR)
  668. + msg_Warn(access, "vlc_poll_i11e interrupted");
  669. + else
  670. + msg_Err(access, "vlc_poll_i11e failed");
  671. + sys->error_status = -errno;
  672. + }
  673. + else if (ret > 0 && p_fds[0].revents
  674. + && smb2_service(sys->smb2, p_fds[0].revents) < 0)
  675. + VLC_SMB2_SET_GENERIC_ERROR(access, "smb2_service");
  676. + }
  677. + return sys->error_status == 0 ? 0 : -1;
  678. +}
  679. +
  680. +#define VLC_SMB2_GENERIC_CB() \
  681. + VLC_UNUSED(smb2); \
  682. + stream_t *access = private_data; \
  683. + struct access_sys *sys = access->p_sys; \
  684. + assert(sys->smb2 == smb2); \
  685. + if (VLC_SMB2_CHECK_STATUS(access, status)) \
  686. + return
  687. +
  688. +static void
  689. +smb2_generic_cb(struct smb2_context *smb2, int status, void *data,
  690. + void *private_data)
  691. +{
  692. + VLC_UNUSED(data);
  693. + VLC_SMB2_GENERIC_CB();
  694. +}
  695. +
  696. +static void
  697. +smb2_read_cb(struct smb2_context *smb2, int status, void *data,
  698. + void *private_data)
  699. +{
  700. + VLC_UNUSED(data);
  701. + VLC_SMB2_GENERIC_CB();
  702. +
  703. + if (status == 0)
  704. + sys->eof = true;
  705. + else
  706. + sys->res.read.len = status;
  707. +}
  708. +
  709. +static ssize_t
  710. +FileRead(stream_t *access, void *buf, size_t len)
  711. +{
  712. + struct access_sys *sys = access->p_sys;
  713. +
  714. + if (sys->error_status != 0)
  715. + return -1;
  716. +
  717. + if (sys->eof)
  718. + return 0;
  719. +
  720. + sys->res.read.len = 0;
  721. + if (smb2_read_async(sys->smb2, sys->smb2fh, buf, len,
  722. + smb2_read_cb, access) < 0)
  723. + {
  724. + VLC_SMB2_SET_GENERIC_ERROR(access, "smb2_read_async");
  725. + return -1;
  726. + }
  727. +
  728. + if (vlc_smb2_mainloop(access, false) < 0)
  729. + return -1;
  730. +
  731. + return sys->res.read.len;
  732. +}
  733. +
  734. +static int
  735. +FileSeek(stream_t *access, uint64_t i_pos)
  736. +{
  737. + struct access_sys *sys = access->p_sys;
  738. +
  739. + if (sys->error_status != 0)
  740. + return VLC_EGENERIC;
  741. +
  742. + if (smb2_lseek(sys->smb2, sys->smb2fh, i_pos, SEEK_SET, NULL) < 0)
  743. + {
  744. + VLC_SMB2_SET_GENERIC_ERROR(access, "smb2_seek_async");
  745. + return VLC_EGENERIC;
  746. + }
  747. + sys->eof = false;
  748. +
  749. + return VLC_SUCCESS;
  750. +}
  751. +
  752. +static int
  753. +FileControl(stream_t *access, int i_query, va_list args)
  754. +{
  755. + struct access_sys *sys = access->p_sys;
  756. +
  757. + switch (i_query)
  758. + {
  759. + case STREAM_CAN_SEEK:
  760. + *va_arg(args, bool *) = true;
  761. + break;
  762. +
  763. + case STREAM_CAN_FASTSEEK:
  764. + *va_arg(args, bool *) = false;
  765. + break;
  766. +
  767. + case STREAM_CAN_PAUSE:
  768. + case STREAM_CAN_CONTROL_PACE:
  769. + *va_arg(args, bool *) = true;
  770. + break;
  771. +
  772. + case STREAM_GET_SIZE:
  773. + {
  774. + *va_arg(args, uint64_t *) = sys->smb2_size;
  775. + break;
  776. + }
  777. +
  778. + case STREAM_GET_PTS_DELAY:
  779. + *va_arg( args, int64_t * ) = INT64_C(1000)
  780. + * var_InheritInteger( access, "network-caching" );
  781. + break;
  782. +
  783. + case STREAM_SET_PAUSE_STATE:
  784. + break;
  785. +
  786. + default:
  787. + return VLC_EGENERIC;
  788. + }
  789. + return VLC_SUCCESS;
  790. +}
  791. +
  792. +static char *
  793. +vlc_smb2_get_url(vlc_url_t *url, const char *file)
  794. +{
  795. + /* smb2://<psz_host><psz_path><file>?<psz_option> */
  796. + char *buf;
  797. + if (asprintf(&buf, "smb://%s%s%s%s%s%s", url->psz_host,
  798. + url->psz_path != NULL ? url->psz_path : "",
  799. + url->psz_path != NULL && url->psz_path[0] != '\0' &&
  800. + url->psz_path[strlen(url->psz_path) - 1] != '/' ? "/" : "",
  801. + file,
  802. + url->psz_option != NULL ? "?" : "",
  803. + url->psz_option != NULL ? url->psz_option : "") == -1)
  804. + return NULL;
  805. + else
  806. + return buf;
  807. +}
  808. +
  809. +static int AddItem(stream_t *access, struct vlc_readdir_helper *rdh,
  810. + const char *name, int i_type)
  811. +{
  812. + struct access_sys *sys = access->p_sys;
  813. + char *name_encoded = vlc_uri_encode(name);
  814. + if (name_encoded == NULL)
  815. + return VLC_ENOMEM;
  816. +
  817. + char *url = vlc_smb2_get_url(&sys->encoded_url, name_encoded);
  818. + free(name_encoded);
  819. + if (url == NULL)
  820. + return VLC_ENOMEM;
  821. +
  822. + int ret = vlc_readdir_helper_additem(rdh, url, NULL, name, i_type,
  823. + ITEM_NET);
  824. + free(url);
  825. + return ret;
  826. +}
  827. +
  828. +static int
  829. +DirRead(stream_t *access, input_item_node_t *p_node)
  830. +{
  831. + struct access_sys *sys = access->p_sys;
  832. + struct smb2dirent *smb2dirent;
  833. + int ret = VLC_SUCCESS;
  834. + assert(sys->smb2dir);
  835. +
  836. + struct vlc_readdir_helper rdh;
  837. + vlc_readdir_helper_init(&rdh, access, p_node);
  838. +
  839. + while (ret == VLC_SUCCESS
  840. + && (smb2dirent = smb2_readdir(sys->smb2, sys->smb2dir)) != NULL)
  841. + {
  842. + int i_type;
  843. + switch (smb2dirent->st.smb2_type)
  844. + {
  845. + case SMB2_TYPE_FILE:
  846. + i_type = ITEM_TYPE_FILE;
  847. + break;
  848. + case SMB2_TYPE_DIRECTORY:
  849. + i_type = ITEM_TYPE_DIRECTORY;
  850. + break;
  851. + default:
  852. + i_type = ITEM_TYPE_UNKNOWN;
  853. + break;
  854. + }
  855. + ret = AddItem(access, &rdh, smb2dirent->name, i_type);
  856. + }
  857. +
  858. + vlc_readdir_helper_finish(&rdh, ret == VLC_SUCCESS);
  859. +
  860. + return ret;
  861. +}
  862. +
  863. +static int
  864. +ShareEnum(stream_t *access, input_item_node_t *p_node)
  865. +{
  866. + struct access_sys *sys = access->p_sys;
  867. + assert(sys->share_enum != NULL);
  868. +
  869. + int ret = VLC_SUCCESS;
  870. + struct vlc_readdir_helper rdh;
  871. + vlc_readdir_helper_init(&rdh, access, p_node);
  872. +
  873. + struct srvsvc_netsharectr *ctr = sys->share_enum->ctr;
  874. + for (uint32_t iinfo = 0;
  875. + iinfo < ctr->ctr1.count && ret == VLC_SUCCESS; ++iinfo)
  876. + {
  877. + struct srvsvc_netshareinfo1 *info = &ctr->ctr1.array[iinfo];
  878. + if (info->type & SHARE_TYPE_HIDDEN)
  879. + continue;
  880. + switch (info->type & 0x3)
  881. + {
  882. + case SHARE_TYPE_DISKTREE:
  883. + ret = AddItem(access, &rdh, info->name, ITEM_TYPE_DIRECTORY);
  884. + break;
  885. + }
  886. + }
  887. +
  888. + vlc_readdir_helper_finish(&rdh, ret == VLC_SUCCESS);
  889. + return 0;
  890. +}
  891. +
  892. +static int
  893. +vlc_smb2_close_fh(stream_t *access)
  894. +{
  895. + struct access_sys *sys = access->p_sys;
  896. +
  897. + assert(sys->smb2fh);
  898. +
  899. + if (smb2_close_async(sys->smb2, sys->smb2fh, smb2_generic_cb, access) < 0)
  900. + {
  901. + VLC_SMB2_SET_GENERIC_ERROR(access, "smb2_close_async");
  902. + return -1;
  903. + }
  904. +
  905. + sys->smb2fh = NULL;
  906. +
  907. + return vlc_smb2_mainloop(access, true);
  908. +}
  909. +
  910. +static int
  911. +vlc_smb2_disconnect_share(stream_t *access)
  912. +{
  913. + struct access_sys *sys = access->p_sys;
  914. +
  915. + if (!sys->smb2_connected)
  916. + return 0;
  917. +
  918. + if (smb2_disconnect_share_async(sys->smb2, smb2_generic_cb, access) < 0)
  919. + {
  920. + VLC_SMB2_SET_GENERIC_ERROR(access, "smb2_connect_share_async");
  921. + return -1;
  922. + }
  923. +
  924. + int ret = vlc_smb2_mainloop(access, true);
  925. + sys->smb2_connected = false;
  926. + return ret;
  927. +}
  928. +
  929. +static void
  930. +smb2_opendir_cb(struct smb2_context *smb2, int status, void *data,
  931. + void *private_data)
  932. +{
  933. + VLC_SMB2_GENERIC_CB();
  934. +
  935. + sys->smb2dir = data;
  936. +}
  937. +
  938. +static void
  939. +smb2_open_cb(struct smb2_context *smb2, int status, void *data,
  940. + void *private_data)
  941. +{
  942. + VLC_SMB2_GENERIC_CB();
  943. +
  944. + sys->smb2fh = data;
  945. +}
  946. +
  947. +static void
  948. +smb2_share_enum_cb(struct smb2_context *smb2, int status, void *data,
  949. + void *private_data)
  950. +{
  951. + VLC_SMB2_GENERIC_CB();
  952. +
  953. + sys->share_enum = data;
  954. +}
  955. +
  956. +static int
  957. +vlc_smb2_open_share(stream_t *access, const struct smb2_url *smb2_url,
  958. + const vlc_credential *credential)
  959. +{
  960. + struct access_sys *sys = access->p_sys;
  961. +
  962. + const bool do_enum = smb2_url->share[0] == '\0';
  963. + const char *username = credential->psz_username;
  964. + const char *password = credential->psz_password;
  965. + const char *domain = credential->psz_realm;
  966. + const char *share = do_enum ? "IPC$" : smb2_url->share;
  967. +
  968. + if (!username)
  969. + {
  970. + username = "Guest";
  971. + password = "";
  972. + }
  973. +
  974. + smb2_set_password(sys->smb2, password);
  975. + smb2_set_domain(sys->smb2, domain ? domain : "");
  976. +
  977. + if (smb2_connect_share_async(sys->smb2, smb2_url->server, share,
  978. + username, smb2_generic_cb, access) < 0)
  979. + {
  980. + VLC_SMB2_SET_GENERIC_ERROR(access, "smb2_connect_share_async");
  981. + goto error;
  982. + }
  983. + if (vlc_smb2_mainloop(access, false) != 0)
  984. + goto error;
  985. + sys->smb2_connected = true;
  986. +
  987. + int ret;
  988. + if (do_enum)
  989. + ret = smb2_share_enum_async(sys->smb2, smb2_share_enum_cb, access);
  990. + else
  991. + {
  992. + struct smb2_stat_64 smb2_stat;
  993. + if (smb2_stat_async(sys->smb2, smb2_url->path, &smb2_stat,
  994. + smb2_generic_cb, access) < 0)
  995. + VLC_SMB2_SET_GENERIC_ERROR(access, "smb2_stat_async");
  996. +
  997. + if (vlc_smb2_mainloop(access, false) != 0)
  998. + goto error;
  999. +
  1000. + if (smb2_stat.smb2_type == SMB2_TYPE_FILE)
  1001. + {
  1002. + sys->smb2_size = smb2_stat.smb2_size;
  1003. + ret = smb2_open_async(sys->smb2, smb2_url->path, O_RDONLY,
  1004. + smb2_open_cb, access);
  1005. + }
  1006. + else if (smb2_stat.smb2_type == SMB2_TYPE_DIRECTORY)
  1007. + ret = smb2_opendir_async(sys->smb2, smb2_url->path,
  1008. + smb2_opendir_cb, access);
  1009. + else
  1010. + {
  1011. + msg_Err(access, "smb2_stat_cb: file type not handled");
  1012. + sys->error_status = 1;
  1013. + goto error;
  1014. + }
  1015. + }
  1016. +
  1017. + if (ret < 0)
  1018. + {
  1019. + VLC_SMB2_SET_GENERIC_ERROR(access, "smb2_open*_async");
  1020. + goto error;
  1021. + }
  1022. +
  1023. + if (vlc_smb2_mainloop(access, false) != 0)
  1024. + goto error;
  1025. + return 0;
  1026. +
  1027. +error:
  1028. + vlc_smb2_disconnect_share(access);
  1029. + return -1;
  1030. +}
  1031. +
  1032. +static char *
  1033. +vlc_smb2_resolve(stream_t *access, const char *host, unsigned port)
  1034. +{
  1035. + (void) access;
  1036. + if (!host)
  1037. + return NULL;
  1038. +
  1039. +#ifdef HAVE_DSM
  1040. + /* Test if the host is an IP */
  1041. + struct in_addr addr;
  1042. + if (inet_pton(AF_INET, host, &addr) == 1)
  1043. + return NULL;
  1044. +
  1045. + /* Test if the host can be resolved */
  1046. + struct addrinfo *info = NULL;
  1047. + if (vlc_getaddrinfo_i11e(host, port, NULL, &info) == 0)
  1048. + {
  1049. + freeaddrinfo(info);
  1050. + /* Let smb2 resolve it */
  1051. + return NULL;
  1052. + }
  1053. +
  1054. + /* Test if the host is a netbios name */
  1055. + char *out_host = NULL;
  1056. + netbios_ns *ns = netbios_ns_new();
  1057. + uint32_t ip4_addr;
  1058. + if (netbios_ns_resolve(ns, host, NETBIOS_FILESERVER, &ip4_addr) == 0)
  1059. + {
  1060. + char ip[] = "xxx.xxx.xxx.xxx";
  1061. + if (inet_ntop(AF_INET, &ip4_addr, ip, sizeof(ip)))
  1062. + out_host = strdup(ip);
  1063. + }
  1064. + netbios_ns_destroy(ns);
  1065. + return out_host;
  1066. +#else
  1067. + (void) port;
  1068. + return NULL;
  1069. +#endif
  1070. +}
  1071. +
  1072. +static int
  1073. +Open(vlc_object_t *p_obj)
  1074. +{
  1075. + stream_t *access = (stream_t *)p_obj;
  1076. + struct access_sys *sys = vlc_obj_calloc(p_obj, 1, sizeof (*sys));
  1077. + struct smb2_url *smb2_url = NULL;
  1078. + char *var_domain = NULL;
  1079. +
  1080. + if (unlikely(sys == NULL))
  1081. + return VLC_ENOMEM;
  1082. + access->p_sys = sys;
  1083. +
  1084. + /* Parse the encoded URL */
  1085. + if (vlc_UrlParseFixup(&sys->encoded_url, access->psz_url) != 0)
  1086. + return VLC_ENOMEM;
  1087. +
  1088. + if (sys->encoded_url.i_port != 0 && sys->encoded_url.i_port != CIFS_PORT)
  1089. + goto error;
  1090. + sys->encoded_url.i_port = 0;
  1091. +
  1092. + sys->smb2 = smb2_init_context();
  1093. + if (sys->smb2 == NULL)
  1094. + {
  1095. + msg_Err(access, "smb2_init_context failed");
  1096. + goto error;
  1097. + }
  1098. +
  1099. + if (sys->encoded_url.psz_path == NULL)
  1100. + sys->encoded_url.psz_path = (char *) "/";
  1101. +
  1102. + char *resolved_host = vlc_smb2_resolve(access, sys->encoded_url.psz_host,
  1103. + CIFS_PORT);
  1104. +
  1105. + /* smb2_* functions need a decoded url. Re compose the url from the
  1106. + * modified sys->encoded_url (without port and with the resolved host). */
  1107. + char *url;
  1108. + if (resolved_host != NULL)
  1109. + {
  1110. + vlc_url_t resolved_url = sys->encoded_url;
  1111. + resolved_url.psz_host = resolved_host;
  1112. + url = vlc_uri_compose(&resolved_url);
  1113. + free(resolved_host);
  1114. + }
  1115. + else
  1116. + url = vlc_uri_compose(&sys->encoded_url);
  1117. + if (!vlc_uri_decode(url))
  1118. + {
  1119. + free(url);
  1120. + goto error;
  1121. + }
  1122. + smb2_url = smb2_parse_url(sys->smb2, url);
  1123. + free(url);
  1124. +
  1125. + if (!smb2_url || !smb2_url->share || !smb2_url->server)
  1126. + {
  1127. + msg_Err(access, "smb2_parse_url failed");
  1128. + goto error;
  1129. + }
  1130. +
  1131. + int ret = -1;
  1132. + vlc_credential credential;
  1133. + vlc_credential_init(&credential, &sys->encoded_url);
  1134. + var_domain = var_InheritString(access, "smb-domain");
  1135. + credential.psz_realm = var_domain;
  1136. +
  1137. + /* First, try Guest login or using "smb-" options (without
  1138. + * keystore/user interaction) */
  1139. + vlc_credential_get(&credential, access, "smb-user", "smb-pwd", NULL,
  1140. + NULL);
  1141. + ret = vlc_smb2_open_share(access, smb2_url, &credential);
  1142. +
  1143. + while (ret == -1
  1144. + && (!sys->error_status || VLC_SMB2_STATUS_DENIED(sys->error_status))
  1145. + && vlc_credential_get(&credential, access, "smb-user", "smb-pwd",
  1146. + SMB_LOGIN_DIALOG_TITLE, SMB_LOGIN_DIALOG_TEXT,
  1147. + smb2_url->server))
  1148. + {
  1149. + sys->error_status = 0;
  1150. + ret = vlc_smb2_open_share(access, smb2_url, &credential);
  1151. + if (ret == 0)
  1152. + vlc_credential_store(&credential, access);
  1153. + }
  1154. + vlc_credential_clean(&credential);
  1155. +
  1156. + if (ret != 0)
  1157. + {
  1158. + vlc_dialog_display_error(access,
  1159. + _("SMB2 operation failed"), "%s",
  1160. + smb2_get_error(sys->smb2));
  1161. + goto error;
  1162. + }
  1163. +
  1164. + if (sys->smb2fh != NULL)
  1165. + {
  1166. + access->pf_read = FileRead;
  1167. + access->pf_seek = FileSeek;
  1168. + access->pf_control = FileControl;
  1169. + }
  1170. + else if (sys->smb2dir != NULL)
  1171. + {
  1172. + access->pf_readdir = DirRead;
  1173. + access->pf_seek = NULL;
  1174. + access->pf_control = access_vaDirectoryControlHelper;
  1175. + }
  1176. + else if (sys->share_enum != NULL)
  1177. + {
  1178. + access->pf_readdir = ShareEnum;
  1179. + access->pf_seek = NULL;
  1180. + access->pf_control = access_vaDirectoryControlHelper;
  1181. + }
  1182. + else
  1183. + vlc_assert_unreachable();
  1184. +
  1185. + smb2_destroy_url(smb2_url);
  1186. + free(var_domain);
  1187. + return VLC_SUCCESS;
  1188. +
  1189. +error:
  1190. + if (smb2_url != NULL)
  1191. + smb2_destroy_url(smb2_url);
  1192. + if (sys->smb2 != NULL)
  1193. + {
  1194. + vlc_smb2_disconnect_share(access);
  1195. + smb2_destroy_context(sys->smb2);
  1196. + }
  1197. + vlc_UrlClean(&sys->encoded_url);
  1198. + free(var_domain);
  1199. + return VLC_EGENERIC;
  1200. +}
  1201. +
  1202. +static void
  1203. +Close(vlc_object_t *p_obj)
  1204. +{
  1205. + stream_t *access = (stream_t *)p_obj;
  1206. + struct access_sys *sys = access->p_sys;
  1207. +
  1208. + if (sys->smb2fh != NULL)
  1209. + vlc_smb2_close_fh(access);
  1210. + else if (sys->smb2dir != NULL)
  1211. + smb2_closedir(sys->smb2, sys->smb2dir);
  1212. + else if (sys->share_enum != NULL)
  1213. + smb2_free_data(sys->smb2, sys->share_enum);
  1214. + else
  1215. + vlc_assert_unreachable();
  1216. +
  1217. + vlc_smb2_disconnect_share(access);
  1218. + smb2_destroy_context(sys->smb2);
  1219. +
  1220. + vlc_UrlClean(&sys->encoded_url);
  1221. +}
  1222. diff --git a/po/POTFILES.in b/po/POTFILES.in
  1223. index cb7f3948e9..a976faa015 100644
  1224. --- a/po/POTFILES.in
  1225. +++ b/po/POTFILES.in
  1226. @@ -215,6 +215,7 @@ modules/access/sftp.c
  1227. modules/access/shm.c
  1228. modules/access/smb.c
  1229. modules/access/smb_common.h
  1230. +modules/access/smb2.c
  1231. modules/access/srt.c
  1232. modules/access/tcp.c
  1233. modules/access/timecode.c
  1234. --
  1235. 2.20.1