@zerodensity/smb-cpp 0.0.0-bootstrap.0 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +54 -3
- package/darwin_arm64/libsmb2.1.dylib +0 -0
- package/darwin_arm64/libsmb2.6.1.0.dylib +0 -0
- package/darwin_arm64/libsmb2.dylib +0 -0
- package/darwin_arm64/smb_server_cpp_darwin_arm64 +0 -0
- package/darwin_arm64/third-party/libsmb2/COPYING +24 -0
- package/darwin_arm64/third-party/libsmb2/LICENCE-LGPL-2.1.txt +502 -0
- package/darwin_arm64/third-party/libsmb2/NOTICE.txt +13 -0
- package/darwin_arm64/third-party/libsmb2/README +413 -0
- package/darwin_arm64/third-party/libsmb2/source/CMakeLists.txt +205 -0
- package/darwin_arm64/third-party/libsmb2/source/COPYING +24 -0
- package/darwin_arm64/third-party/libsmb2/source/LICENCE-LGPL-2.1.txt +502 -0
- package/darwin_arm64/third-party/libsmb2/source/Makefile.am +15 -0
- package/darwin_arm64/third-party/libsmb2/source/Makefile.platform +112 -0
- package/darwin_arm64/third-party/libsmb2/source/README +413 -0
- package/darwin_arm64/third-party/libsmb2/source/Xbox/libsmb2.sln +25 -0
- package/darwin_arm64/third-party/libsmb2/source/Xbox/libsmb2.vcxproj +248 -0
- package/darwin_arm64/third-party/libsmb2/source/Xbox/libsmb2.vcxproj.filters +304 -0
- package/darwin_arm64/third-party/libsmb2/source/Xbox 360/libsmb2.sln +32 -0
- package/darwin_arm64/third-party/libsmb2/source/Xbox 360/libsmb2.vcxproj +327 -0
- package/darwin_arm64/third-party/libsmb2/source/Xbox 360/libsmb2.vcxproj.filters +268 -0
- package/darwin_arm64/third-party/libsmb2/source/bootstrap +2 -0
- package/darwin_arm64/third-party/libsmb2/source/cmake/ConfigureChecks.cmake +63 -0
- package/darwin_arm64/third-party/libsmb2/source/cmake/FindSMB2.cmake +37 -0
- package/darwin_arm64/third-party/libsmb2/source/cmake/Modules/FindGSSAPI.cmake +30 -0
- package/darwin_arm64/third-party/libsmb2/source/cmake/Modules/FindLibKrb5.cmake +44 -0
- package/darwin_arm64/third-party/libsmb2/source/cmake/config.h.cmake +126 -0
- package/darwin_arm64/third-party/libsmb2/source/cmake/libsmb2.pc.cmake +14 -0
- package/darwin_arm64/third-party/libsmb2/source/component.mk +5 -0
- package/darwin_arm64/third-party/libsmb2/source/configure.ac +184 -0
- package/darwin_arm64/third-party/libsmb2/source/dcerpc-examples/srvsvc-NetrShareAdd.yaml +9 -0
- package/darwin_arm64/third-party/libsmb2/source/dcerpc-examples/srvsvc-NetrShareCheck.yaml +4 -0
- package/darwin_arm64/third-party/libsmb2/source/dcerpc-examples/srvsvc-NetrShareDel.yaml +5 -0
- package/darwin_arm64/third-party/libsmb2/source/dcerpc-examples/srvsvc-NetrShareDelSticky.yaml +5 -0
- package/darwin_arm64/third-party/libsmb2/source/dcerpc-examples/srvsvc-NetrShareEnum.yaml +7 -0
- package/darwin_arm64/third-party/libsmb2/source/dcerpc-examples/srvsvc-NetrShareGetInfo.yaml +6 -0
- package/darwin_arm64/third-party/libsmb2/source/dcerpc-examples/srvsvc-NetrShareSetInfo.yaml +11 -0
- package/darwin_arm64/third-party/libsmb2/source/examples/CMakeLists.txt +28 -0
- package/darwin_arm64/third-party/libsmb2/source/examples/Makefile.am +54 -0
- package/darwin_arm64/third-party/libsmb2/source/examples/dcerpc.c +254 -0
- package/darwin_arm64/third-party/libsmb2/source/examples/picow/CMakeLists.txt +72 -0
- package/darwin_arm64/third-party/libsmb2/source/examples/picow/README.md +2 -0
- package/darwin_arm64/third-party/libsmb2/source/examples/picow/main.cpp +119 -0
- package/darwin_arm64/third-party/libsmb2/source/examples/picow/smb-ls-sync.c +0 -0
- package/darwin_arm64/third-party/libsmb2/source/examples/smb2-CMD-FIND.c +335 -0
- package/darwin_arm64/third-party/libsmb2/source/examples/smb2-cat-async.c +183 -0
- package/darwin_arm64/third-party/libsmb2/source/examples/smb2-cat-sync.c +105 -0
- package/darwin_arm64/third-party/libsmb2/source/examples/smb2-ftruncate-sync.c +87 -0
- package/darwin_arm64/third-party/libsmb2/source/examples/smb2-ls-async.c +185 -0
- package/darwin_arm64/third-party/libsmb2/source/examples/smb2-ls-epoll.c +234 -0
- package/darwin_arm64/third-party/libsmb2/source/examples/smb2-lsa-lookupsids.c +292 -0
- package/darwin_arm64/third-party/libsmb2/source/examples/smb2-lseek-sync.c +101 -0
- package/darwin_arm64/third-party/libsmb2/source/examples/smb2-notify.c +183 -0
- package/darwin_arm64/third-party/libsmb2/source/examples/smb2-put-async.c +175 -0
- package/darwin_arm64/third-party/libsmb2/source/examples/smb2-put-sync.c +100 -0
- package/darwin_arm64/third-party/libsmb2/source/examples/smb2-raw-fsstat-async.c +353 -0
- package/darwin_arm64/third-party/libsmb2/source/examples/smb2-raw-getsd-async.c +401 -0
- package/darwin_arm64/third-party/libsmb2/source/examples/smb2-raw-stat-async.c +448 -0
- package/darwin_arm64/third-party/libsmb2/source/examples/smb2-readlink.c +80 -0
- package/darwin_arm64/third-party/libsmb2/source/examples/smb2-rename-sync.c +80 -0
- package/darwin_arm64/third-party/libsmb2/source/examples/smb2-server-sync.c +497 -0
- package/darwin_arm64/third-party/libsmb2/source/examples/smb2-share-enum-sync.c +146 -0
- package/darwin_arm64/third-party/libsmb2/source/examples/smb2-share-enum.c +208 -0
- package/darwin_arm64/third-party/libsmb2/source/examples/smb2-share-info.c +255 -0
- package/darwin_arm64/third-party/libsmb2/source/examples/smb2-stat-sync.c +103 -0
- package/darwin_arm64/third-party/libsmb2/source/examples/smb2-statvfs-sync.c +85 -0
- package/darwin_arm64/third-party/libsmb2/source/examples/smb2-truncate-sync.c +78 -0
- package/darwin_arm64/third-party/libsmb2/source/idf_component.yml +5 -0
- package/darwin_arm64/third-party/libsmb2/source/include/Makefile.am +15 -0
- package/darwin_arm64/third-party/libsmb2/source/include/amiga_os/config.h +139 -0
- package/darwin_arm64/third-party/libsmb2/source/include/apple/config.h +139 -0
- package/darwin_arm64/third-party/libsmb2/source/include/asprintf.h +65 -0
- package/darwin_arm64/third-party/libsmb2/source/include/esp/config.h +139 -0
- package/darwin_arm64/third-party/libsmb2/source/include/libsmb2-private.h +670 -0
- package/darwin_arm64/third-party/libsmb2/source/include/module.modulemap +21 -0
- package/darwin_arm64/third-party/libsmb2/source/include/picow/FreeRTOSConfig.h +143 -0
- package/darwin_arm64/third-party/libsmb2/source/include/picow/README.md +2 -0
- package/darwin_arm64/third-party/libsmb2/source/include/picow/config.h +139 -0
- package/darwin_arm64/third-party/libsmb2/source/include/picow/lwipopts.h +27 -0
- package/darwin_arm64/third-party/libsmb2/source/include/picow/lwipopts_examples_common.h +90 -0
- package/darwin_arm64/third-party/libsmb2/source/include/portable-endian.h +377 -0
- package/darwin_arm64/third-party/libsmb2/source/include/ps3/config.h +139 -0
- package/darwin_arm64/third-party/libsmb2/source/include/slist.h +63 -0
- package/darwin_arm64/third-party/libsmb2/source/include/smb2/libsmb2-dcerpc-lsa.h +172 -0
- package/darwin_arm64/third-party/libsmb2/source/include/smb2/libsmb2-dcerpc-srvsvc.h +276 -0
- package/darwin_arm64/third-party/libsmb2/source/include/smb2/libsmb2-dcerpc.h +203 -0
- package/darwin_arm64/third-party/libsmb2/source/include/smb2/libsmb2-raw.h +497 -0
- package/darwin_arm64/third-party/libsmb2/source/include/smb2/libsmb2.h +1409 -0
- package/darwin_arm64/third-party/libsmb2/source/include/smb2/smb2-errors.h +549 -0
- package/darwin_arm64/third-party/libsmb2/source/include/smb2/smb2-ioctl.h +83 -0
- package/darwin_arm64/third-party/libsmb2/source/include/smb2/smb2.h +1251 -0
- package/darwin_arm64/third-party/libsmb2/source/include/xbox/config.h +139 -0
- package/darwin_arm64/third-party/libsmb2/source/include/xbox 360/config.h +139 -0
- package/darwin_arm64/third-party/libsmb2/source/lib/CMakeLists.txt +260 -0
- package/darwin_arm64/third-party/libsmb2/source/lib/Makefile.AMIGA +46 -0
- package/darwin_arm64/third-party/libsmb2/source/lib/Makefile.AMIGA_AROS +59 -0
- package/darwin_arm64/third-party/libsmb2/source/lib/Makefile.AMIGA_OS3 +59 -0
- package/darwin_arm64/third-party/libsmb2/source/lib/Makefile.PS3_PPU +100 -0
- package/darwin_arm64/third-party/libsmb2/source/lib/Makefile.am +85 -0
- package/darwin_arm64/third-party/libsmb2/source/lib/aes.c +33 -0
- package/darwin_arm64/third-party/libsmb2/source/lib/aes.h +29 -0
- package/darwin_arm64/third-party/libsmb2/source/lib/aes128ccm.c +185 -0
- package/darwin_arm64/third-party/libsmb2/source/lib/aes128ccm.h +28 -0
- package/darwin_arm64/third-party/libsmb2/source/lib/aes_apple.c +70 -0
- package/darwin_arm64/third-party/libsmb2/source/lib/aes_apple.h +34 -0
- package/darwin_arm64/third-party/libsmb2/source/lib/aes_reference.c +560 -0
- package/darwin_arm64/third-party/libsmb2/source/lib/aes_reference.h +49 -0
- package/darwin_arm64/third-party/libsmb2/source/lib/alloc.c +154 -0
- package/darwin_arm64/third-party/libsmb2/source/lib/asn1-ber.c +1078 -0
- package/darwin_arm64/third-party/libsmb2/source/lib/asn1-ber.h +161 -0
- package/darwin_arm64/third-party/libsmb2/source/lib/compat.c +599 -0
- package/darwin_arm64/third-party/libsmb2/source/lib/compat.h +829 -0
- package/darwin_arm64/third-party/libsmb2/source/lib/dcerpc-lsa.c +641 -0
- package/darwin_arm64/third-party/libsmb2/source/lib/dcerpc-srvsvc.c +885 -0
- package/darwin_arm64/third-party/libsmb2/source/lib/dcerpc.c +2513 -0
- package/darwin_arm64/third-party/libsmb2/source/lib/dreamcast/vfs.c +328 -0
- package/darwin_arm64/third-party/libsmb2/source/lib/dreamcast/vfs.h +15 -0
- package/darwin_arm64/third-party/libsmb2/source/lib/errors.c +1192 -0
- package/darwin_arm64/third-party/libsmb2/source/lib/hmac-md5.c +84 -0
- package/darwin_arm64/third-party/libsmb2/source/lib/hmac-md5.h +42 -0
- package/darwin_arm64/third-party/libsmb2/source/lib/hmac.c +245 -0
- package/darwin_arm64/third-party/libsmb2/source/lib/init.c +778 -0
- package/darwin_arm64/third-party/libsmb2/source/lib/krb5-wrapper.c +1072 -0
- package/darwin_arm64/third-party/libsmb2/source/lib/krb5-wrapper.h +134 -0
- package/darwin_arm64/third-party/libsmb2/source/lib/libsmb2.c +4292 -0
- package/darwin_arm64/third-party/libsmb2/source/lib/libsmb2.syms +168 -0
- package/darwin_arm64/third-party/libsmb2/source/lib/md4.h +43 -0
- package/darwin_arm64/third-party/libsmb2/source/lib/md4c.c +289 -0
- package/darwin_arm64/third-party/libsmb2/source/lib/md5.c +249 -0
- package/darwin_arm64/third-party/libsmb2/source/lib/md5.h +76 -0
- package/darwin_arm64/third-party/libsmb2/source/lib/ntlmssp.c +1380 -0
- package/darwin_arm64/third-party/libsmb2/source/lib/ntlmssp.h +84 -0
- package/darwin_arm64/third-party/libsmb2/source/lib/pdu.c +1159 -0
- package/darwin_arm64/third-party/libsmb2/source/lib/ps2/TODO +6 -0
- package/darwin_arm64/third-party/libsmb2/source/lib/ps2/imports.lst +84 -0
- package/darwin_arm64/third-party/libsmb2/source/lib/ps2/irx_imports.h +28 -0
- package/darwin_arm64/third-party/libsmb2/source/lib/ps2/ps2smb2.h +35 -0
- package/darwin_arm64/third-party/libsmb2/source/lib/ps2/smb2_fio.c +816 -0
- package/darwin_arm64/third-party/libsmb2/source/lib/ps2/smb2_fio.h +15 -0
- package/darwin_arm64/third-party/libsmb2/source/lib/ps2/smb2man.c +69 -0
- package/darwin_arm64/third-party/libsmb2/source/lib/sha-private.h +28 -0
- package/darwin_arm64/third-party/libsmb2/source/lib/sha.h +334 -0
- package/darwin_arm64/third-party/libsmb2/source/lib/sha1.c +450 -0
- package/darwin_arm64/third-party/libsmb2/source/lib/sha224-256.c +611 -0
- package/darwin_arm64/third-party/libsmb2/source/lib/sha384-512.c +1059 -0
- package/darwin_arm64/third-party/libsmb2/source/lib/smb2-cmd-close.c +240 -0
- package/darwin_arm64/third-party/libsmb2/source/lib/smb2-cmd-create.c +508 -0
- package/darwin_arm64/third-party/libsmb2/source/lib/smb2-cmd-echo.c +202 -0
- package/darwin_arm64/third-party/libsmb2/source/lib/smb2-cmd-error.c +157 -0
- package/darwin_arm64/third-party/libsmb2/source/lib/smb2-cmd-flush.c +207 -0
- package/darwin_arm64/third-party/libsmb2/source/lib/smb2-cmd-ioctl.c +445 -0
- package/darwin_arm64/third-party/libsmb2/source/lib/smb2-cmd-lock.c +312 -0
- package/darwin_arm64/third-party/libsmb2/source/lib/smb2-cmd-logoff.c +190 -0
- package/darwin_arm64/third-party/libsmb2/source/lib/smb2-cmd-negotiate.c +646 -0
- package/darwin_arm64/third-party/libsmb2/source/lib/smb2-cmd-notify-change.c +278 -0
- package/darwin_arm64/third-party/libsmb2/source/lib/smb2-cmd-oplock-break.c +543 -0
- package/darwin_arm64/third-party/libsmb2/source/lib/smb2-cmd-query-directory.c +580 -0
- package/darwin_arm64/third-party/libsmb2/source/lib/smb2-cmd-query-info.c +753 -0
- package/darwin_arm64/third-party/libsmb2/source/lib/smb2-cmd-read.c +391 -0
- package/darwin_arm64/third-party/libsmb2/source/lib/smb2-cmd-session-setup.c +331 -0
- package/darwin_arm64/third-party/libsmb2/source/lib/smb2-cmd-set-info.c +361 -0
- package/darwin_arm64/third-party/libsmb2/source/lib/smb2-cmd-tree-connect.c +278 -0
- package/darwin_arm64/third-party/libsmb2/source/lib/smb2-cmd-tree-disconnect.c +171 -0
- package/darwin_arm64/third-party/libsmb2/source/lib/smb2-cmd-write.c +319 -0
- package/darwin_arm64/third-party/libsmb2/source/lib/smb2-data-file-info.c +537 -0
- package/darwin_arm64/third-party/libsmb2/source/lib/smb2-data-filesystem-info.c +384 -0
- package/darwin_arm64/third-party/libsmb2/source/lib/smb2-data-reparse-point.c +117 -0
- package/darwin_arm64/third-party/libsmb2/source/lib/smb2-data-security-descriptor.c +361 -0
- package/darwin_arm64/third-party/libsmb2/source/lib/smb2-share-enum.c +181 -0
- package/darwin_arm64/third-party/libsmb2/source/lib/smb2-signing.c +279 -0
- package/darwin_arm64/third-party/libsmb2/source/lib/smb2-signing.h +51 -0
- package/darwin_arm64/third-party/libsmb2/source/lib/smb3-seal.c +165 -0
- package/darwin_arm64/third-party/libsmb2/source/lib/smb3-seal.h +43 -0
- package/darwin_arm64/third-party/libsmb2/source/lib/socket.c +1502 -0
- package/darwin_arm64/third-party/libsmb2/source/lib/spnego-wrapper.c +634 -0
- package/darwin_arm64/third-party/libsmb2/source/lib/spnego-wrapper.h +74 -0
- package/darwin_arm64/third-party/libsmb2/source/lib/sync.c +988 -0
- package/darwin_arm64/third-party/libsmb2/source/lib/timestamps.c +70 -0
- package/darwin_arm64/third-party/libsmb2/source/lib/unicode.c +307 -0
- package/darwin_arm64/third-party/libsmb2/source/lib/usha.c +345 -0
- package/darwin_arm64/third-party/libsmb2/source/libsmb2.pc.in +14 -0
- package/darwin_arm64/third-party/libsmb2/source/packaging/RPM/libsmb2.spec.in +135 -0
- package/darwin_arm64/third-party/libsmb2/source/packaging/RPM/makerpms.sh +114 -0
- package/darwin_arm64/third-party/libsmb2/source/tests/Makefile.am +34 -0
- package/darwin_arm64/third-party/libsmb2/source/tests/README +28 -0
- package/darwin_arm64/third-party/libsmb2/source/tests/aes128ccm-test.c +119 -0
- package/darwin_arm64/third-party/libsmb2/source/tests/functions.sh +11 -0
- package/darwin_arm64/third-party/libsmb2/source/tests/ld_sockerr.c +58 -0
- package/darwin_arm64/third-party/libsmb2/source/tests/metastat-0202-censored.c +136 -0
- package/darwin_arm64/third-party/libsmb2/source/tests/ntlmssp_generate_blob.c +123 -0
- package/darwin_arm64/third-party/libsmb2/source/tests/prog_cat.c +188 -0
- package/darwin_arm64/third-party/libsmb2/source/tests/prog_cat_cancel.c +203 -0
- package/darwin_arm64/third-party/libsmb2/source/tests/prog_ls.c +189 -0
- package/darwin_arm64/third-party/libsmb2/source/tests/prog_mkdir.c +85 -0
- package/darwin_arm64/third-party/libsmb2/source/tests/prog_rmdir.c +84 -0
- package/darwin_arm64/third-party/libsmb2/source/tests/smb2-dcerpc-coder-test.c +635 -0
- package/darwin_arm64/third-party/libsmb2/source/tests/test_0100_ls_basic.sh +22 -0
- package/darwin_arm64/third-party/libsmb2/source/tests/test_0101_ls_basic_valgrind.sh +23 -0
- package/darwin_arm64/third-party/libsmb2/source/tests/test_0102_ls_basic_socket_error.sh +16 -0
- package/darwin_arm64/third-party/libsmb2/source/tests/test_0103_ls_basic_valgrind_malloc_error.sh +25 -0
- package/darwin_arm64/third-party/libsmb2/source/tests/test_0200_mkdir.sh +15 -0
- package/darwin_arm64/third-party/libsmb2/source/tests/test_0201_mkdir_valgrind.sh +15 -0
- package/darwin_arm64/third-party/libsmb2/source/tests/test_0210_cp_basic.sh +25 -0
- package/darwin_arm64/third-party/libsmb2/source/tests/test_0211_cp_valgrind.sh +26 -0
- package/darwin_arm64/third-party/libsmb2/source/tests/test_0212_cp_valgrind_socket_error.sh +29 -0
- package/darwin_arm64/third-party/libsmb2/source/tests/test_0300_cat_basic.sh +13 -0
- package/darwin_arm64/third-party/libsmb2/source/tests/test_0301_cat_valgrind.sh +13 -0
- package/darwin_arm64/third-party/libsmb2/source/tests/test_0302_cat_valgrind_socket_error.sh +18 -0
- package/darwin_arm64/third-party/libsmb2/source/tests/test_0310_cancel_pdu.sh +13 -0
- package/darwin_arm64/third-party/libsmb2/source/tests/test_0400_overdrawn_0202.sh +25 -0
- package/darwin_arm64/third-party/libsmb2/source/tests/test_900_dcerpc.sh +10 -0
- package/darwin_arm64/third-party/libsmb2/source/utils/Makefile.am +11 -0
- package/darwin_arm64/third-party/libsmb2/source/utils/smb2-cp.c +265 -0
- package/darwin_arm64/third-party/libsmb2/source/utils/smb2-ls.c +135 -0
- package/linux_x64/libsmb2.so +0 -0
- package/linux_x64/libsmb2.so.1 +0 -0
- package/linux_x64/libsmb2.so.6.1.0 +0 -0
- package/linux_x64/smb_server_cpp_linux_x64 +0 -0
- package/linux_x64/third-party/libsmb2/COPYING +24 -0
- package/linux_x64/third-party/libsmb2/LICENCE-LGPL-2.1.txt +502 -0
- package/linux_x64/third-party/libsmb2/NOTICE.txt +13 -0
- package/linux_x64/third-party/libsmb2/README +413 -0
- package/linux_x64/third-party/libsmb2/source/CMakeLists.txt +205 -0
- package/linux_x64/third-party/libsmb2/source/COPYING +24 -0
- package/linux_x64/third-party/libsmb2/source/LICENCE-LGPL-2.1.txt +502 -0
- package/linux_x64/third-party/libsmb2/source/Makefile.am +15 -0
- package/linux_x64/third-party/libsmb2/source/Makefile.platform +112 -0
- package/linux_x64/third-party/libsmb2/source/README +413 -0
- package/linux_x64/third-party/libsmb2/source/Xbox/libsmb2.sln +25 -0
- package/linux_x64/third-party/libsmb2/source/Xbox/libsmb2.vcxproj +248 -0
- package/linux_x64/third-party/libsmb2/source/Xbox/libsmb2.vcxproj.filters +304 -0
- package/linux_x64/third-party/libsmb2/source/Xbox 360/libsmb2.sln +32 -0
- package/linux_x64/third-party/libsmb2/source/Xbox 360/libsmb2.vcxproj +327 -0
- package/linux_x64/third-party/libsmb2/source/Xbox 360/libsmb2.vcxproj.filters +268 -0
- package/linux_x64/third-party/libsmb2/source/bootstrap +2 -0
- package/linux_x64/third-party/libsmb2/source/cmake/ConfigureChecks.cmake +63 -0
- package/linux_x64/third-party/libsmb2/source/cmake/FindSMB2.cmake +37 -0
- package/linux_x64/third-party/libsmb2/source/cmake/Modules/FindGSSAPI.cmake +30 -0
- package/linux_x64/third-party/libsmb2/source/cmake/Modules/FindLibKrb5.cmake +44 -0
- package/linux_x64/third-party/libsmb2/source/cmake/config.h.cmake +126 -0
- package/linux_x64/third-party/libsmb2/source/cmake/libsmb2.pc.cmake +14 -0
- package/linux_x64/third-party/libsmb2/source/component.mk +5 -0
- package/linux_x64/third-party/libsmb2/source/configure.ac +184 -0
- package/linux_x64/third-party/libsmb2/source/dcerpc-examples/srvsvc-NetrShareAdd.yaml +9 -0
- package/linux_x64/third-party/libsmb2/source/dcerpc-examples/srvsvc-NetrShareCheck.yaml +4 -0
- package/linux_x64/third-party/libsmb2/source/dcerpc-examples/srvsvc-NetrShareDel.yaml +5 -0
- package/linux_x64/third-party/libsmb2/source/dcerpc-examples/srvsvc-NetrShareDelSticky.yaml +5 -0
- package/linux_x64/third-party/libsmb2/source/dcerpc-examples/srvsvc-NetrShareEnum.yaml +7 -0
- package/linux_x64/third-party/libsmb2/source/dcerpc-examples/srvsvc-NetrShareGetInfo.yaml +6 -0
- package/linux_x64/third-party/libsmb2/source/dcerpc-examples/srvsvc-NetrShareSetInfo.yaml +11 -0
- package/linux_x64/third-party/libsmb2/source/examples/CMakeLists.txt +28 -0
- package/linux_x64/third-party/libsmb2/source/examples/Makefile.am +54 -0
- package/linux_x64/third-party/libsmb2/source/examples/dcerpc.c +254 -0
- package/linux_x64/third-party/libsmb2/source/examples/picow/CMakeLists.txt +72 -0
- package/linux_x64/third-party/libsmb2/source/examples/picow/README.md +2 -0
- package/linux_x64/third-party/libsmb2/source/examples/picow/main.cpp +119 -0
- package/linux_x64/third-party/libsmb2/source/examples/picow/smb-ls-sync.c +0 -0
- package/linux_x64/third-party/libsmb2/source/examples/smb2-CMD-FIND.c +335 -0
- package/linux_x64/third-party/libsmb2/source/examples/smb2-cat-async.c +183 -0
- package/linux_x64/third-party/libsmb2/source/examples/smb2-cat-sync.c +105 -0
- package/linux_x64/third-party/libsmb2/source/examples/smb2-ftruncate-sync.c +87 -0
- package/linux_x64/third-party/libsmb2/source/examples/smb2-ls-async.c +185 -0
- package/linux_x64/third-party/libsmb2/source/examples/smb2-ls-epoll.c +234 -0
- package/linux_x64/third-party/libsmb2/source/examples/smb2-lsa-lookupsids.c +292 -0
- package/linux_x64/third-party/libsmb2/source/examples/smb2-lseek-sync.c +101 -0
- package/linux_x64/third-party/libsmb2/source/examples/smb2-notify.c +183 -0
- package/linux_x64/third-party/libsmb2/source/examples/smb2-put-async.c +175 -0
- package/linux_x64/third-party/libsmb2/source/examples/smb2-put-sync.c +100 -0
- package/linux_x64/third-party/libsmb2/source/examples/smb2-raw-fsstat-async.c +353 -0
- package/linux_x64/third-party/libsmb2/source/examples/smb2-raw-getsd-async.c +401 -0
- package/linux_x64/third-party/libsmb2/source/examples/smb2-raw-stat-async.c +448 -0
- package/linux_x64/third-party/libsmb2/source/examples/smb2-readlink.c +80 -0
- package/linux_x64/third-party/libsmb2/source/examples/smb2-rename-sync.c +80 -0
- package/linux_x64/third-party/libsmb2/source/examples/smb2-server-sync.c +497 -0
- package/linux_x64/third-party/libsmb2/source/examples/smb2-share-enum-sync.c +146 -0
- package/linux_x64/third-party/libsmb2/source/examples/smb2-share-enum.c +208 -0
- package/linux_x64/third-party/libsmb2/source/examples/smb2-share-info.c +255 -0
- package/linux_x64/third-party/libsmb2/source/examples/smb2-stat-sync.c +103 -0
- package/linux_x64/third-party/libsmb2/source/examples/smb2-statvfs-sync.c +85 -0
- package/linux_x64/third-party/libsmb2/source/examples/smb2-truncate-sync.c +78 -0
- package/linux_x64/third-party/libsmb2/source/idf_component.yml +5 -0
- package/linux_x64/third-party/libsmb2/source/include/Makefile.am +15 -0
- package/linux_x64/third-party/libsmb2/source/include/amiga_os/config.h +139 -0
- package/linux_x64/third-party/libsmb2/source/include/apple/config.h +139 -0
- package/linux_x64/third-party/libsmb2/source/include/asprintf.h +65 -0
- package/linux_x64/third-party/libsmb2/source/include/esp/config.h +139 -0
- package/linux_x64/third-party/libsmb2/source/include/libsmb2-private.h +670 -0
- package/linux_x64/third-party/libsmb2/source/include/module.modulemap +21 -0
- package/linux_x64/third-party/libsmb2/source/include/picow/FreeRTOSConfig.h +143 -0
- package/linux_x64/third-party/libsmb2/source/include/picow/README.md +2 -0
- package/linux_x64/third-party/libsmb2/source/include/picow/config.h +139 -0
- package/linux_x64/third-party/libsmb2/source/include/picow/lwipopts.h +27 -0
- package/linux_x64/third-party/libsmb2/source/include/picow/lwipopts_examples_common.h +90 -0
- package/linux_x64/third-party/libsmb2/source/include/portable-endian.h +377 -0
- package/linux_x64/third-party/libsmb2/source/include/ps3/config.h +139 -0
- package/linux_x64/third-party/libsmb2/source/include/slist.h +63 -0
- package/linux_x64/third-party/libsmb2/source/include/smb2/libsmb2-dcerpc-lsa.h +172 -0
- package/linux_x64/third-party/libsmb2/source/include/smb2/libsmb2-dcerpc-srvsvc.h +276 -0
- package/linux_x64/third-party/libsmb2/source/include/smb2/libsmb2-dcerpc.h +203 -0
- package/linux_x64/third-party/libsmb2/source/include/smb2/libsmb2-raw.h +497 -0
- package/linux_x64/third-party/libsmb2/source/include/smb2/libsmb2.h +1409 -0
- package/linux_x64/third-party/libsmb2/source/include/smb2/smb2-errors.h +549 -0
- package/linux_x64/third-party/libsmb2/source/include/smb2/smb2-ioctl.h +83 -0
- package/linux_x64/third-party/libsmb2/source/include/smb2/smb2.h +1251 -0
- package/linux_x64/third-party/libsmb2/source/include/xbox/config.h +139 -0
- package/linux_x64/third-party/libsmb2/source/include/xbox 360/config.h +139 -0
- package/linux_x64/third-party/libsmb2/source/lib/CMakeLists.txt +260 -0
- package/linux_x64/third-party/libsmb2/source/lib/Makefile.AMIGA +46 -0
- package/linux_x64/third-party/libsmb2/source/lib/Makefile.AMIGA_AROS +59 -0
- package/linux_x64/third-party/libsmb2/source/lib/Makefile.AMIGA_OS3 +59 -0
- package/linux_x64/third-party/libsmb2/source/lib/Makefile.PS3_PPU +100 -0
- package/linux_x64/third-party/libsmb2/source/lib/Makefile.am +85 -0
- package/linux_x64/third-party/libsmb2/source/lib/aes.c +33 -0
- package/linux_x64/third-party/libsmb2/source/lib/aes.h +29 -0
- package/linux_x64/third-party/libsmb2/source/lib/aes128ccm.c +185 -0
- package/linux_x64/third-party/libsmb2/source/lib/aes128ccm.h +28 -0
- package/linux_x64/third-party/libsmb2/source/lib/aes_apple.c +70 -0
- package/linux_x64/third-party/libsmb2/source/lib/aes_apple.h +34 -0
- package/linux_x64/third-party/libsmb2/source/lib/aes_reference.c +560 -0
- package/linux_x64/third-party/libsmb2/source/lib/aes_reference.h +49 -0
- package/linux_x64/third-party/libsmb2/source/lib/alloc.c +154 -0
- package/linux_x64/third-party/libsmb2/source/lib/asn1-ber.c +1078 -0
- package/linux_x64/third-party/libsmb2/source/lib/asn1-ber.h +161 -0
- package/linux_x64/third-party/libsmb2/source/lib/compat.c +599 -0
- package/linux_x64/third-party/libsmb2/source/lib/compat.h +829 -0
- package/linux_x64/third-party/libsmb2/source/lib/dcerpc-lsa.c +641 -0
- package/linux_x64/third-party/libsmb2/source/lib/dcerpc-srvsvc.c +885 -0
- package/linux_x64/third-party/libsmb2/source/lib/dcerpc.c +2513 -0
- package/linux_x64/third-party/libsmb2/source/lib/dreamcast/vfs.c +328 -0
- package/linux_x64/third-party/libsmb2/source/lib/dreamcast/vfs.h +15 -0
- package/linux_x64/third-party/libsmb2/source/lib/errors.c +1192 -0
- package/linux_x64/third-party/libsmb2/source/lib/hmac-md5.c +84 -0
- package/linux_x64/third-party/libsmb2/source/lib/hmac-md5.h +42 -0
- package/linux_x64/third-party/libsmb2/source/lib/hmac.c +245 -0
- package/linux_x64/third-party/libsmb2/source/lib/init.c +778 -0
- package/linux_x64/third-party/libsmb2/source/lib/krb5-wrapper.c +1072 -0
- package/linux_x64/third-party/libsmb2/source/lib/krb5-wrapper.h +134 -0
- package/linux_x64/third-party/libsmb2/source/lib/libsmb2.c +4292 -0
- package/linux_x64/third-party/libsmb2/source/lib/libsmb2.syms +168 -0
- package/linux_x64/third-party/libsmb2/source/lib/md4.h +43 -0
- package/linux_x64/third-party/libsmb2/source/lib/md4c.c +289 -0
- package/linux_x64/third-party/libsmb2/source/lib/md5.c +249 -0
- package/linux_x64/third-party/libsmb2/source/lib/md5.h +76 -0
- package/linux_x64/third-party/libsmb2/source/lib/ntlmssp.c +1380 -0
- package/linux_x64/third-party/libsmb2/source/lib/ntlmssp.h +84 -0
- package/linux_x64/third-party/libsmb2/source/lib/pdu.c +1159 -0
- package/linux_x64/third-party/libsmb2/source/lib/ps2/TODO +6 -0
- package/linux_x64/third-party/libsmb2/source/lib/ps2/imports.lst +84 -0
- package/linux_x64/third-party/libsmb2/source/lib/ps2/irx_imports.h +28 -0
- package/linux_x64/third-party/libsmb2/source/lib/ps2/ps2smb2.h +35 -0
- package/linux_x64/third-party/libsmb2/source/lib/ps2/smb2_fio.c +816 -0
- package/linux_x64/third-party/libsmb2/source/lib/ps2/smb2_fio.h +15 -0
- package/linux_x64/third-party/libsmb2/source/lib/ps2/smb2man.c +69 -0
- package/linux_x64/third-party/libsmb2/source/lib/sha-private.h +28 -0
- package/linux_x64/third-party/libsmb2/source/lib/sha.h +334 -0
- package/linux_x64/third-party/libsmb2/source/lib/sha1.c +450 -0
- package/linux_x64/third-party/libsmb2/source/lib/sha224-256.c +611 -0
- package/linux_x64/third-party/libsmb2/source/lib/sha384-512.c +1059 -0
- package/linux_x64/third-party/libsmb2/source/lib/smb2-cmd-close.c +240 -0
- package/linux_x64/third-party/libsmb2/source/lib/smb2-cmd-create.c +508 -0
- package/linux_x64/third-party/libsmb2/source/lib/smb2-cmd-echo.c +202 -0
- package/linux_x64/third-party/libsmb2/source/lib/smb2-cmd-error.c +157 -0
- package/linux_x64/third-party/libsmb2/source/lib/smb2-cmd-flush.c +207 -0
- package/linux_x64/third-party/libsmb2/source/lib/smb2-cmd-ioctl.c +445 -0
- package/linux_x64/third-party/libsmb2/source/lib/smb2-cmd-lock.c +312 -0
- package/linux_x64/third-party/libsmb2/source/lib/smb2-cmd-logoff.c +190 -0
- package/linux_x64/third-party/libsmb2/source/lib/smb2-cmd-negotiate.c +646 -0
- package/linux_x64/third-party/libsmb2/source/lib/smb2-cmd-notify-change.c +278 -0
- package/linux_x64/third-party/libsmb2/source/lib/smb2-cmd-oplock-break.c +543 -0
- package/linux_x64/third-party/libsmb2/source/lib/smb2-cmd-query-directory.c +580 -0
- package/linux_x64/third-party/libsmb2/source/lib/smb2-cmd-query-info.c +753 -0
- package/linux_x64/third-party/libsmb2/source/lib/smb2-cmd-read.c +391 -0
- package/linux_x64/third-party/libsmb2/source/lib/smb2-cmd-session-setup.c +331 -0
- package/linux_x64/third-party/libsmb2/source/lib/smb2-cmd-set-info.c +361 -0
- package/linux_x64/third-party/libsmb2/source/lib/smb2-cmd-tree-connect.c +278 -0
- package/linux_x64/third-party/libsmb2/source/lib/smb2-cmd-tree-disconnect.c +171 -0
- package/linux_x64/third-party/libsmb2/source/lib/smb2-cmd-write.c +319 -0
- package/linux_x64/third-party/libsmb2/source/lib/smb2-data-file-info.c +537 -0
- package/linux_x64/third-party/libsmb2/source/lib/smb2-data-filesystem-info.c +384 -0
- package/linux_x64/third-party/libsmb2/source/lib/smb2-data-reparse-point.c +117 -0
- package/linux_x64/third-party/libsmb2/source/lib/smb2-data-security-descriptor.c +361 -0
- package/linux_x64/third-party/libsmb2/source/lib/smb2-share-enum.c +181 -0
- package/linux_x64/third-party/libsmb2/source/lib/smb2-signing.c +279 -0
- package/linux_x64/third-party/libsmb2/source/lib/smb2-signing.h +51 -0
- package/linux_x64/third-party/libsmb2/source/lib/smb3-seal.c +165 -0
- package/linux_x64/third-party/libsmb2/source/lib/smb3-seal.h +43 -0
- package/linux_x64/third-party/libsmb2/source/lib/socket.c +1502 -0
- package/linux_x64/third-party/libsmb2/source/lib/spnego-wrapper.c +634 -0
- package/linux_x64/third-party/libsmb2/source/lib/spnego-wrapper.h +74 -0
- package/linux_x64/third-party/libsmb2/source/lib/sync.c +988 -0
- package/linux_x64/third-party/libsmb2/source/lib/timestamps.c +70 -0
- package/linux_x64/third-party/libsmb2/source/lib/unicode.c +307 -0
- package/linux_x64/third-party/libsmb2/source/lib/usha.c +345 -0
- package/linux_x64/third-party/libsmb2/source/libsmb2.pc.in +14 -0
- package/linux_x64/third-party/libsmb2/source/packaging/RPM/libsmb2.spec.in +135 -0
- package/linux_x64/third-party/libsmb2/source/packaging/RPM/makerpms.sh +114 -0
- package/linux_x64/third-party/libsmb2/source/tests/Makefile.am +34 -0
- package/linux_x64/third-party/libsmb2/source/tests/README +28 -0
- package/linux_x64/third-party/libsmb2/source/tests/aes128ccm-test.c +119 -0
- package/linux_x64/third-party/libsmb2/source/tests/functions.sh +11 -0
- package/linux_x64/third-party/libsmb2/source/tests/ld_sockerr.c +58 -0
- package/linux_x64/third-party/libsmb2/source/tests/metastat-0202-censored.c +136 -0
- package/linux_x64/third-party/libsmb2/source/tests/ntlmssp_generate_blob.c +123 -0
- package/linux_x64/third-party/libsmb2/source/tests/prog_cat.c +188 -0
- package/linux_x64/third-party/libsmb2/source/tests/prog_cat_cancel.c +203 -0
- package/linux_x64/third-party/libsmb2/source/tests/prog_ls.c +189 -0
- package/linux_x64/third-party/libsmb2/source/tests/prog_mkdir.c +85 -0
- package/linux_x64/third-party/libsmb2/source/tests/prog_rmdir.c +84 -0
- package/linux_x64/third-party/libsmb2/source/tests/smb2-dcerpc-coder-test.c +635 -0
- package/linux_x64/third-party/libsmb2/source/tests/test_0100_ls_basic.sh +22 -0
- package/linux_x64/third-party/libsmb2/source/tests/test_0101_ls_basic_valgrind.sh +23 -0
- package/linux_x64/third-party/libsmb2/source/tests/test_0102_ls_basic_socket_error.sh +16 -0
- package/linux_x64/third-party/libsmb2/source/tests/test_0103_ls_basic_valgrind_malloc_error.sh +25 -0
- package/linux_x64/third-party/libsmb2/source/tests/test_0200_mkdir.sh +15 -0
- package/linux_x64/third-party/libsmb2/source/tests/test_0201_mkdir_valgrind.sh +15 -0
- package/linux_x64/third-party/libsmb2/source/tests/test_0210_cp_basic.sh +25 -0
- package/linux_x64/third-party/libsmb2/source/tests/test_0211_cp_valgrind.sh +26 -0
- package/linux_x64/third-party/libsmb2/source/tests/test_0212_cp_valgrind_socket_error.sh +29 -0
- package/linux_x64/third-party/libsmb2/source/tests/test_0300_cat_basic.sh +13 -0
- package/linux_x64/third-party/libsmb2/source/tests/test_0301_cat_valgrind.sh +13 -0
- package/linux_x64/third-party/libsmb2/source/tests/test_0302_cat_valgrind_socket_error.sh +18 -0
- package/linux_x64/third-party/libsmb2/source/tests/test_0310_cancel_pdu.sh +13 -0
- package/linux_x64/third-party/libsmb2/source/tests/test_0400_overdrawn_0202.sh +25 -0
- package/linux_x64/third-party/libsmb2/source/tests/test_900_dcerpc.sh +10 -0
- package/linux_x64/third-party/libsmb2/source/utils/Makefile.am +11 -0
- package/linux_x64/third-party/libsmb2/source/utils/smb2-cp.c +265 -0
- package/linux_x64/third-party/libsmb2/source/utils/smb2-ls.c +135 -0
- package/package.json +10 -4
- package/smb2.proto +164 -0
- package/win32_x64/smb2.dll +0 -0
- package/win32_x64/smb_server_cpp_win32_x64.exe +0 -0
- package/win32_x64/third-party/libsmb2/COPYING +24 -0
- package/win32_x64/third-party/libsmb2/LICENCE-LGPL-2.1.txt +502 -0
- package/win32_x64/third-party/libsmb2/NOTICE.txt +13 -0
- package/win32_x64/third-party/libsmb2/README +413 -0
- package/win32_x64/third-party/libsmb2/source/CMakeLists.txt +205 -0
- package/win32_x64/third-party/libsmb2/source/COPYING +24 -0
- package/win32_x64/third-party/libsmb2/source/LICENCE-LGPL-2.1.txt +502 -0
- package/win32_x64/third-party/libsmb2/source/Makefile.am +15 -0
- package/win32_x64/third-party/libsmb2/source/Makefile.platform +112 -0
- package/win32_x64/third-party/libsmb2/source/README +413 -0
- package/win32_x64/third-party/libsmb2/source/Xbox/libsmb2.sln +25 -0
- package/win32_x64/third-party/libsmb2/source/Xbox/libsmb2.vcxproj +248 -0
- package/win32_x64/third-party/libsmb2/source/Xbox/libsmb2.vcxproj.filters +304 -0
- package/win32_x64/third-party/libsmb2/source/Xbox 360/libsmb2.sln +32 -0
- package/win32_x64/third-party/libsmb2/source/Xbox 360/libsmb2.vcxproj +327 -0
- package/win32_x64/third-party/libsmb2/source/Xbox 360/libsmb2.vcxproj.filters +268 -0
- package/win32_x64/third-party/libsmb2/source/bootstrap +2 -0
- package/win32_x64/third-party/libsmb2/source/cmake/ConfigureChecks.cmake +63 -0
- package/win32_x64/third-party/libsmb2/source/cmake/FindSMB2.cmake +37 -0
- package/win32_x64/third-party/libsmb2/source/cmake/Modules/FindGSSAPI.cmake +30 -0
- package/win32_x64/third-party/libsmb2/source/cmake/Modules/FindLibKrb5.cmake +44 -0
- package/win32_x64/third-party/libsmb2/source/cmake/config.h.cmake +126 -0
- package/win32_x64/third-party/libsmb2/source/cmake/libsmb2.pc.cmake +14 -0
- package/win32_x64/third-party/libsmb2/source/component.mk +5 -0
- package/win32_x64/third-party/libsmb2/source/configure.ac +184 -0
- package/win32_x64/third-party/libsmb2/source/dcerpc-examples/srvsvc-NetrShareAdd.yaml +9 -0
- package/win32_x64/third-party/libsmb2/source/dcerpc-examples/srvsvc-NetrShareCheck.yaml +4 -0
- package/win32_x64/third-party/libsmb2/source/dcerpc-examples/srvsvc-NetrShareDel.yaml +5 -0
- package/win32_x64/third-party/libsmb2/source/dcerpc-examples/srvsvc-NetrShareDelSticky.yaml +5 -0
- package/win32_x64/third-party/libsmb2/source/dcerpc-examples/srvsvc-NetrShareEnum.yaml +7 -0
- package/win32_x64/third-party/libsmb2/source/dcerpc-examples/srvsvc-NetrShareGetInfo.yaml +6 -0
- package/win32_x64/third-party/libsmb2/source/dcerpc-examples/srvsvc-NetrShareSetInfo.yaml +11 -0
- package/win32_x64/third-party/libsmb2/source/examples/CMakeLists.txt +28 -0
- package/win32_x64/third-party/libsmb2/source/examples/Makefile.am +54 -0
- package/win32_x64/third-party/libsmb2/source/examples/dcerpc.c +254 -0
- package/win32_x64/third-party/libsmb2/source/examples/picow/CMakeLists.txt +72 -0
- package/win32_x64/third-party/libsmb2/source/examples/picow/README.md +2 -0
- package/win32_x64/third-party/libsmb2/source/examples/picow/main.cpp +119 -0
- package/win32_x64/third-party/libsmb2/source/examples/picow/smb-ls-sync.c +0 -0
- package/win32_x64/third-party/libsmb2/source/examples/smb2-CMD-FIND.c +335 -0
- package/win32_x64/third-party/libsmb2/source/examples/smb2-cat-async.c +183 -0
- package/win32_x64/third-party/libsmb2/source/examples/smb2-cat-sync.c +105 -0
- package/win32_x64/third-party/libsmb2/source/examples/smb2-ftruncate-sync.c +87 -0
- package/win32_x64/third-party/libsmb2/source/examples/smb2-ls-async.c +185 -0
- package/win32_x64/third-party/libsmb2/source/examples/smb2-ls-epoll.c +234 -0
- package/win32_x64/third-party/libsmb2/source/examples/smb2-lsa-lookupsids.c +292 -0
- package/win32_x64/third-party/libsmb2/source/examples/smb2-lseek-sync.c +101 -0
- package/win32_x64/third-party/libsmb2/source/examples/smb2-notify.c +183 -0
- package/win32_x64/third-party/libsmb2/source/examples/smb2-put-async.c +175 -0
- package/win32_x64/third-party/libsmb2/source/examples/smb2-put-sync.c +100 -0
- package/win32_x64/third-party/libsmb2/source/examples/smb2-raw-fsstat-async.c +353 -0
- package/win32_x64/third-party/libsmb2/source/examples/smb2-raw-getsd-async.c +401 -0
- package/win32_x64/third-party/libsmb2/source/examples/smb2-raw-stat-async.c +448 -0
- package/win32_x64/third-party/libsmb2/source/examples/smb2-readlink.c +80 -0
- package/win32_x64/third-party/libsmb2/source/examples/smb2-rename-sync.c +80 -0
- package/win32_x64/third-party/libsmb2/source/examples/smb2-server-sync.c +497 -0
- package/win32_x64/third-party/libsmb2/source/examples/smb2-share-enum-sync.c +146 -0
- package/win32_x64/third-party/libsmb2/source/examples/smb2-share-enum.c +208 -0
- package/win32_x64/third-party/libsmb2/source/examples/smb2-share-info.c +255 -0
- package/win32_x64/third-party/libsmb2/source/examples/smb2-stat-sync.c +103 -0
- package/win32_x64/third-party/libsmb2/source/examples/smb2-statvfs-sync.c +85 -0
- package/win32_x64/third-party/libsmb2/source/examples/smb2-truncate-sync.c +78 -0
- package/win32_x64/third-party/libsmb2/source/idf_component.yml +5 -0
- package/win32_x64/third-party/libsmb2/source/include/Makefile.am +15 -0
- package/win32_x64/third-party/libsmb2/source/include/amiga_os/config.h +139 -0
- package/win32_x64/third-party/libsmb2/source/include/apple/config.h +139 -0
- package/win32_x64/third-party/libsmb2/source/include/asprintf.h +65 -0
- package/win32_x64/third-party/libsmb2/source/include/esp/config.h +139 -0
- package/win32_x64/third-party/libsmb2/source/include/libsmb2-private.h +670 -0
- package/win32_x64/third-party/libsmb2/source/include/module.modulemap +21 -0
- package/win32_x64/third-party/libsmb2/source/include/picow/FreeRTOSConfig.h +143 -0
- package/win32_x64/third-party/libsmb2/source/include/picow/README.md +2 -0
- package/win32_x64/third-party/libsmb2/source/include/picow/config.h +139 -0
- package/win32_x64/third-party/libsmb2/source/include/picow/lwipopts.h +27 -0
- package/win32_x64/third-party/libsmb2/source/include/picow/lwipopts_examples_common.h +90 -0
- package/win32_x64/third-party/libsmb2/source/include/portable-endian.h +377 -0
- package/win32_x64/third-party/libsmb2/source/include/ps3/config.h +139 -0
- package/win32_x64/third-party/libsmb2/source/include/slist.h +63 -0
- package/win32_x64/third-party/libsmb2/source/include/smb2/libsmb2-dcerpc-lsa.h +172 -0
- package/win32_x64/third-party/libsmb2/source/include/smb2/libsmb2-dcerpc-srvsvc.h +276 -0
- package/win32_x64/third-party/libsmb2/source/include/smb2/libsmb2-dcerpc.h +203 -0
- package/win32_x64/third-party/libsmb2/source/include/smb2/libsmb2-raw.h +497 -0
- package/win32_x64/third-party/libsmb2/source/include/smb2/libsmb2.h +1409 -0
- package/win32_x64/third-party/libsmb2/source/include/smb2/smb2-errors.h +549 -0
- package/win32_x64/third-party/libsmb2/source/include/smb2/smb2-ioctl.h +83 -0
- package/win32_x64/third-party/libsmb2/source/include/smb2/smb2.h +1251 -0
- package/win32_x64/third-party/libsmb2/source/include/xbox/config.h +139 -0
- package/win32_x64/third-party/libsmb2/source/include/xbox 360/config.h +139 -0
- package/win32_x64/third-party/libsmb2/source/lib/CMakeLists.txt +260 -0
- package/win32_x64/third-party/libsmb2/source/lib/Makefile.AMIGA +46 -0
- package/win32_x64/third-party/libsmb2/source/lib/Makefile.AMIGA_AROS +59 -0
- package/win32_x64/third-party/libsmb2/source/lib/Makefile.AMIGA_OS3 +59 -0
- package/win32_x64/third-party/libsmb2/source/lib/Makefile.PS3_PPU +100 -0
- package/win32_x64/third-party/libsmb2/source/lib/Makefile.am +85 -0
- package/win32_x64/third-party/libsmb2/source/lib/aes.c +33 -0
- package/win32_x64/third-party/libsmb2/source/lib/aes.h +29 -0
- package/win32_x64/third-party/libsmb2/source/lib/aes128ccm.c +185 -0
- package/win32_x64/third-party/libsmb2/source/lib/aes128ccm.h +28 -0
- package/win32_x64/third-party/libsmb2/source/lib/aes_apple.c +70 -0
- package/win32_x64/third-party/libsmb2/source/lib/aes_apple.h +34 -0
- package/win32_x64/third-party/libsmb2/source/lib/aes_reference.c +560 -0
- package/win32_x64/third-party/libsmb2/source/lib/aes_reference.h +49 -0
- package/win32_x64/third-party/libsmb2/source/lib/alloc.c +154 -0
- package/win32_x64/third-party/libsmb2/source/lib/asn1-ber.c +1078 -0
- package/win32_x64/third-party/libsmb2/source/lib/asn1-ber.h +161 -0
- package/win32_x64/third-party/libsmb2/source/lib/compat.c +599 -0
- package/win32_x64/third-party/libsmb2/source/lib/compat.h +829 -0
- package/win32_x64/third-party/libsmb2/source/lib/dcerpc-lsa.c +641 -0
- package/win32_x64/third-party/libsmb2/source/lib/dcerpc-srvsvc.c +885 -0
- package/win32_x64/third-party/libsmb2/source/lib/dcerpc.c +2513 -0
- package/win32_x64/third-party/libsmb2/source/lib/dreamcast/vfs.c +328 -0
- package/win32_x64/third-party/libsmb2/source/lib/dreamcast/vfs.h +15 -0
- package/win32_x64/third-party/libsmb2/source/lib/errors.c +1192 -0
- package/win32_x64/third-party/libsmb2/source/lib/hmac-md5.c +84 -0
- package/win32_x64/third-party/libsmb2/source/lib/hmac-md5.h +42 -0
- package/win32_x64/third-party/libsmb2/source/lib/hmac.c +245 -0
- package/win32_x64/third-party/libsmb2/source/lib/init.c +778 -0
- package/win32_x64/third-party/libsmb2/source/lib/krb5-wrapper.c +1072 -0
- package/win32_x64/third-party/libsmb2/source/lib/krb5-wrapper.h +134 -0
- package/win32_x64/third-party/libsmb2/source/lib/libsmb2.c +4292 -0
- package/win32_x64/third-party/libsmb2/source/lib/libsmb2.syms +168 -0
- package/win32_x64/third-party/libsmb2/source/lib/md4.h +43 -0
- package/win32_x64/third-party/libsmb2/source/lib/md4c.c +289 -0
- package/win32_x64/third-party/libsmb2/source/lib/md5.c +249 -0
- package/win32_x64/third-party/libsmb2/source/lib/md5.h +76 -0
- package/win32_x64/third-party/libsmb2/source/lib/ntlmssp.c +1380 -0
- package/win32_x64/third-party/libsmb2/source/lib/ntlmssp.h +84 -0
- package/win32_x64/third-party/libsmb2/source/lib/pdu.c +1159 -0
- package/win32_x64/third-party/libsmb2/source/lib/ps2/TODO +6 -0
- package/win32_x64/third-party/libsmb2/source/lib/ps2/imports.lst +84 -0
- package/win32_x64/third-party/libsmb2/source/lib/ps2/irx_imports.h +28 -0
- package/win32_x64/third-party/libsmb2/source/lib/ps2/ps2smb2.h +35 -0
- package/win32_x64/third-party/libsmb2/source/lib/ps2/smb2_fio.c +816 -0
- package/win32_x64/third-party/libsmb2/source/lib/ps2/smb2_fio.h +15 -0
- package/win32_x64/third-party/libsmb2/source/lib/ps2/smb2man.c +69 -0
- package/win32_x64/third-party/libsmb2/source/lib/sha-private.h +28 -0
- package/win32_x64/third-party/libsmb2/source/lib/sha.h +334 -0
- package/win32_x64/third-party/libsmb2/source/lib/sha1.c +450 -0
- package/win32_x64/third-party/libsmb2/source/lib/sha224-256.c +611 -0
- package/win32_x64/third-party/libsmb2/source/lib/sha384-512.c +1059 -0
- package/win32_x64/third-party/libsmb2/source/lib/smb2-cmd-close.c +240 -0
- package/win32_x64/third-party/libsmb2/source/lib/smb2-cmd-create.c +508 -0
- package/win32_x64/third-party/libsmb2/source/lib/smb2-cmd-echo.c +202 -0
- package/win32_x64/third-party/libsmb2/source/lib/smb2-cmd-error.c +157 -0
- package/win32_x64/third-party/libsmb2/source/lib/smb2-cmd-flush.c +207 -0
- package/win32_x64/third-party/libsmb2/source/lib/smb2-cmd-ioctl.c +445 -0
- package/win32_x64/third-party/libsmb2/source/lib/smb2-cmd-lock.c +312 -0
- package/win32_x64/third-party/libsmb2/source/lib/smb2-cmd-logoff.c +190 -0
- package/win32_x64/third-party/libsmb2/source/lib/smb2-cmd-negotiate.c +646 -0
- package/win32_x64/third-party/libsmb2/source/lib/smb2-cmd-notify-change.c +278 -0
- package/win32_x64/third-party/libsmb2/source/lib/smb2-cmd-oplock-break.c +543 -0
- package/win32_x64/third-party/libsmb2/source/lib/smb2-cmd-query-directory.c +580 -0
- package/win32_x64/third-party/libsmb2/source/lib/smb2-cmd-query-info.c +753 -0
- package/win32_x64/third-party/libsmb2/source/lib/smb2-cmd-read.c +391 -0
- package/win32_x64/third-party/libsmb2/source/lib/smb2-cmd-session-setup.c +331 -0
- package/win32_x64/third-party/libsmb2/source/lib/smb2-cmd-set-info.c +361 -0
- package/win32_x64/third-party/libsmb2/source/lib/smb2-cmd-tree-connect.c +278 -0
- package/win32_x64/third-party/libsmb2/source/lib/smb2-cmd-tree-disconnect.c +171 -0
- package/win32_x64/third-party/libsmb2/source/lib/smb2-cmd-write.c +319 -0
- package/win32_x64/third-party/libsmb2/source/lib/smb2-data-file-info.c +537 -0
- package/win32_x64/third-party/libsmb2/source/lib/smb2-data-filesystem-info.c +384 -0
- package/win32_x64/third-party/libsmb2/source/lib/smb2-data-reparse-point.c +117 -0
- package/win32_x64/third-party/libsmb2/source/lib/smb2-data-security-descriptor.c +361 -0
- package/win32_x64/third-party/libsmb2/source/lib/smb2-share-enum.c +181 -0
- package/win32_x64/third-party/libsmb2/source/lib/smb2-signing.c +279 -0
- package/win32_x64/third-party/libsmb2/source/lib/smb2-signing.h +51 -0
- package/win32_x64/third-party/libsmb2/source/lib/smb3-seal.c +165 -0
- package/win32_x64/third-party/libsmb2/source/lib/smb3-seal.h +43 -0
- package/win32_x64/third-party/libsmb2/source/lib/socket.c +1502 -0
- package/win32_x64/third-party/libsmb2/source/lib/spnego-wrapper.c +634 -0
- package/win32_x64/third-party/libsmb2/source/lib/spnego-wrapper.h +74 -0
- package/win32_x64/third-party/libsmb2/source/lib/sync.c +988 -0
- package/win32_x64/third-party/libsmb2/source/lib/timestamps.c +70 -0
- package/win32_x64/third-party/libsmb2/source/lib/unicode.c +307 -0
- package/win32_x64/third-party/libsmb2/source/lib/usha.c +345 -0
- package/win32_x64/third-party/libsmb2/source/libsmb2.pc.in +14 -0
- package/win32_x64/third-party/libsmb2/source/packaging/RPM/libsmb2.spec.in +135 -0
- package/win32_x64/third-party/libsmb2/source/packaging/RPM/makerpms.sh +114 -0
- package/win32_x64/third-party/libsmb2/source/tests/Makefile.am +34 -0
- package/win32_x64/third-party/libsmb2/source/tests/README +28 -0
- package/win32_x64/third-party/libsmb2/source/tests/aes128ccm-test.c +119 -0
- package/win32_x64/third-party/libsmb2/source/tests/functions.sh +11 -0
- package/win32_x64/third-party/libsmb2/source/tests/ld_sockerr.c +58 -0
- package/win32_x64/third-party/libsmb2/source/tests/metastat-0202-censored.c +136 -0
- package/win32_x64/third-party/libsmb2/source/tests/ntlmssp_generate_blob.c +123 -0
- package/win32_x64/third-party/libsmb2/source/tests/prog_cat.c +188 -0
- package/win32_x64/third-party/libsmb2/source/tests/prog_cat_cancel.c +203 -0
- package/win32_x64/third-party/libsmb2/source/tests/prog_ls.c +189 -0
- package/win32_x64/third-party/libsmb2/source/tests/prog_mkdir.c +85 -0
- package/win32_x64/third-party/libsmb2/source/tests/prog_rmdir.c +84 -0
- package/win32_x64/third-party/libsmb2/source/tests/smb2-dcerpc-coder-test.c +635 -0
- package/win32_x64/third-party/libsmb2/source/tests/test_0100_ls_basic.sh +22 -0
- package/win32_x64/third-party/libsmb2/source/tests/test_0101_ls_basic_valgrind.sh +23 -0
- package/win32_x64/third-party/libsmb2/source/tests/test_0102_ls_basic_socket_error.sh +16 -0
- package/win32_x64/third-party/libsmb2/source/tests/test_0103_ls_basic_valgrind_malloc_error.sh +25 -0
- package/win32_x64/third-party/libsmb2/source/tests/test_0200_mkdir.sh +15 -0
- package/win32_x64/third-party/libsmb2/source/tests/test_0201_mkdir_valgrind.sh +15 -0
- package/win32_x64/third-party/libsmb2/source/tests/test_0210_cp_basic.sh +25 -0
- package/win32_x64/third-party/libsmb2/source/tests/test_0211_cp_valgrind.sh +26 -0
- package/win32_x64/third-party/libsmb2/source/tests/test_0212_cp_valgrind_socket_error.sh +29 -0
- package/win32_x64/third-party/libsmb2/source/tests/test_0300_cat_basic.sh +13 -0
- package/win32_x64/third-party/libsmb2/source/tests/test_0301_cat_valgrind.sh +13 -0
- package/win32_x64/third-party/libsmb2/source/tests/test_0302_cat_valgrind_socket_error.sh +18 -0
- package/win32_x64/third-party/libsmb2/source/tests/test_0310_cancel_pdu.sh +13 -0
- package/win32_x64/third-party/libsmb2/source/tests/test_0400_overdrawn_0202.sh +25 -0
- package/win32_x64/third-party/libsmb2/source/tests/test_900_dcerpc.sh +10 -0
- package/win32_x64/third-party/libsmb2/source/utils/Makefile.am +11 -0
- package/win32_x64/third-party/libsmb2/source/utils/smb2-cp.c +265 -0
- package/win32_x64/third-party/libsmb2/source/utils/smb2-ls.c +135 -0
|
@@ -0,0 +1,4292 @@
|
|
|
1
|
+
/* -*- mode:c; tab-width:8; c-basic-offset:8; indent-tabs-mode:nil; -*- */
|
|
2
|
+
/*
|
|
3
|
+
Copyright (C) 2016 by Ronnie Sahlberg <ronniesahlberg@gmail.com>
|
|
4
|
+
|
|
5
|
+
Portions of this code are copyright 2017 to Primary Data Inc.
|
|
6
|
+
|
|
7
|
+
This program is free software; you can redistribute it and/or modify
|
|
8
|
+
it under the terms of the GNU Lesser General Public License as published by
|
|
9
|
+
the Free Software Foundation; either version 2.1 of the License, or
|
|
10
|
+
(at your option) any later version.
|
|
11
|
+
|
|
12
|
+
This program is distributed in the hope that it will be useful,
|
|
13
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
14
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
15
|
+
GNU Lesser General Public License for more details.
|
|
16
|
+
|
|
17
|
+
You should have received a copy of the GNU Lesser General Public License
|
|
18
|
+
along with this program; if not, see <http://www.gnu.org/licenses/>.
|
|
19
|
+
*/
|
|
20
|
+
#ifdef HAVE_CONFIG_H
|
|
21
|
+
#include "config.h"
|
|
22
|
+
#endif
|
|
23
|
+
|
|
24
|
+
#ifndef _GNU_SOURCE
|
|
25
|
+
#define _GNU_SOURCE
|
|
26
|
+
#endif
|
|
27
|
+
|
|
28
|
+
#ifdef HAVE_STDINT_H
|
|
29
|
+
#include <stdint.h>
|
|
30
|
+
#endif
|
|
31
|
+
|
|
32
|
+
#ifdef HAVE_STDLIB_H
|
|
33
|
+
#include <stdlib.h>
|
|
34
|
+
#endif
|
|
35
|
+
|
|
36
|
+
#ifdef HAVE_STRING_H
|
|
37
|
+
#include <string.h>
|
|
38
|
+
#endif
|
|
39
|
+
|
|
40
|
+
#ifdef STDC_HEADERS
|
|
41
|
+
#include <stddef.h>
|
|
42
|
+
#endif
|
|
43
|
+
|
|
44
|
+
#ifdef HAVE_SYS_TYPES_H
|
|
45
|
+
#include <sys/types.h>
|
|
46
|
+
#endif
|
|
47
|
+
|
|
48
|
+
#ifdef HAVE_SYS_STAT_H
|
|
49
|
+
#include <sys/stat.h>
|
|
50
|
+
#endif
|
|
51
|
+
|
|
52
|
+
#ifdef HAVE_UNISTD_H
|
|
53
|
+
#include <unistd.h>
|
|
54
|
+
#endif
|
|
55
|
+
|
|
56
|
+
#ifdef HAVE_SYS_UNISTD_H
|
|
57
|
+
#include <sys/unistd.h>
|
|
58
|
+
#endif
|
|
59
|
+
|
|
60
|
+
#include <errno.h>
|
|
61
|
+
#include <stdio.h>
|
|
62
|
+
|
|
63
|
+
#ifdef HAVE_SYS_POLL_H
|
|
64
|
+
#include <sys/poll.h>
|
|
65
|
+
#endif
|
|
66
|
+
|
|
67
|
+
#ifdef HAVE_POLL_H
|
|
68
|
+
#include <poll.h>
|
|
69
|
+
#endif
|
|
70
|
+
|
|
71
|
+
#ifdef HAVE_TIME_H
|
|
72
|
+
#include <time.h>
|
|
73
|
+
#endif
|
|
74
|
+
|
|
75
|
+
#ifdef HAVE_SYS_TIME_H
|
|
76
|
+
#include <sys/time.h>
|
|
77
|
+
#endif
|
|
78
|
+
|
|
79
|
+
#ifdef HAVE_FCNTL_H
|
|
80
|
+
#include <fcntl.h>
|
|
81
|
+
#endif
|
|
82
|
+
|
|
83
|
+
#ifdef HAVE_SYS_FCNTL_H
|
|
84
|
+
#include <sys/fcntl.h>
|
|
85
|
+
#endif
|
|
86
|
+
|
|
87
|
+
#ifdef HAVE_SYS_SOCKET_H
|
|
88
|
+
#include <sys/socket.h>
|
|
89
|
+
#endif
|
|
90
|
+
|
|
91
|
+
#if defined(_WIN32) || defined(_XBOX) || defined(__AROS__)
|
|
92
|
+
#include "asprintf.h"
|
|
93
|
+
#endif
|
|
94
|
+
|
|
95
|
+
#include "compat.h"
|
|
96
|
+
|
|
97
|
+
#include "sha.h"
|
|
98
|
+
#include "sha-private.h"
|
|
99
|
+
|
|
100
|
+
#include "slist.h"
|
|
101
|
+
#include "smb2.h"
|
|
102
|
+
#include "libsmb2.h"
|
|
103
|
+
#include "libsmb2-raw.h"
|
|
104
|
+
#include "libsmb2-private.h"
|
|
105
|
+
#include "smb2-signing.h"
|
|
106
|
+
#include "portable-endian.h"
|
|
107
|
+
#include "ntlmssp.h"
|
|
108
|
+
|
|
109
|
+
#ifdef HAVE_LIBKRB5
|
|
110
|
+
#include "krb5-wrapper.h"
|
|
111
|
+
#endif
|
|
112
|
+
#include "spnego-wrapper.h"
|
|
113
|
+
|
|
114
|
+
#if defined(ESP_PLATFORM)
|
|
115
|
+
#define DEFAULT_OUTPUT_BUFFER_LENGTH 512
|
|
116
|
+
#elif defined(__PS2__)
|
|
117
|
+
#define DEFAULT_OUTPUT_BUFFER_LENGTH 4096
|
|
118
|
+
#else
|
|
119
|
+
#define DEFAULT_OUTPUT_BUFFER_LENGTH 0xffff
|
|
120
|
+
#endif
|
|
121
|
+
|
|
122
|
+
/* strings used to derive SMB signing and encryption keys */
|
|
123
|
+
static const char SMBSigningKey[] = "SMBSigningKey";
|
|
124
|
+
static const char SMBC2SCipherKey[] = "SMBC2SCipherKey";
|
|
125
|
+
static const char SMBS2CCipherKey[] = "SMBS2CCipherKey";
|
|
126
|
+
static const char SMB2AESCMAC[] = "SMB2AESCMAC";
|
|
127
|
+
static const char SmbSign[] = "SmbSign";
|
|
128
|
+
static const char SMB2AESCCM[] = "SMB2AESCCM";
|
|
129
|
+
static const char ServerOut[] = "ServerOut";
|
|
130
|
+
static const char ServerIn[] = "ServerIn ";
|
|
131
|
+
/* The following strings will be used for deriving other keys */
|
|
132
|
+
#if 0
|
|
133
|
+
static const char SMB2APP[] = "SMB2APP";
|
|
134
|
+
static const char SmbRpc[] = "SmbRpc";
|
|
135
|
+
static const char SMBAppKey[] = "SMBAppKey";
|
|
136
|
+
#endif
|
|
137
|
+
|
|
138
|
+
const smb2_file_id compound_file_id = {
|
|
139
|
+
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
140
|
+
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
struct connect_data {
|
|
144
|
+
smb2_command_cb cb;
|
|
145
|
+
void *cb_data;
|
|
146
|
+
|
|
147
|
+
const char *server;
|
|
148
|
+
const char *share;
|
|
149
|
+
const char *user;
|
|
150
|
+
|
|
151
|
+
/* UNC for the share in utf8 as well as utf16 formats */
|
|
152
|
+
char *utf8_unc;
|
|
153
|
+
struct smb2_utf16 *utf16_unc;
|
|
154
|
+
|
|
155
|
+
void *auth_data;
|
|
156
|
+
|
|
157
|
+
/* if context is being served by our server */
|
|
158
|
+
struct smb2_server *server_context;
|
|
159
|
+
};
|
|
160
|
+
|
|
161
|
+
struct smb2fh {
|
|
162
|
+
smb2_command_cb cb;
|
|
163
|
+
void *cb_data;
|
|
164
|
+
|
|
165
|
+
smb2_file_id file_id;
|
|
166
|
+
int64_t offset;
|
|
167
|
+
int64_t end_of_file;
|
|
168
|
+
};
|
|
169
|
+
|
|
170
|
+
void
|
|
171
|
+
smb2_close_context(struct smb2_context *smb2)
|
|
172
|
+
{
|
|
173
|
+
if (smb2 == NULL) {
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
if (SMB2_VALID_SOCKET(smb2->fd)) {
|
|
178
|
+
if (smb2->change_fd) {
|
|
179
|
+
smb2->change_fd(smb2, smb2->fd, SMB2_DEL_FD);
|
|
180
|
+
}
|
|
181
|
+
close(smb2->fd);
|
|
182
|
+
smb2->fd = SMB2_INVALID_SOCKET;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
smb2->message_id = 0;
|
|
186
|
+
smb2->session_id = 0;
|
|
187
|
+
smb2->tree_id_top = 0;
|
|
188
|
+
smb2->tree_id_cur = 0;
|
|
189
|
+
smb2->tree_id[0] = 0xdeadbeef;
|
|
190
|
+
memset(smb2->signing_key, 0, SMB2_KEY_SIZE);
|
|
191
|
+
if (smb2->session_key) {
|
|
192
|
+
free(smb2->session_key);
|
|
193
|
+
smb2->session_key = NULL;
|
|
194
|
+
}
|
|
195
|
+
smb2->session_key_size = 0;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
static int
|
|
199
|
+
send_session_setup_request(struct smb2_context *smb2,
|
|
200
|
+
struct connect_data *c_data,
|
|
201
|
+
unsigned char *buf, int len);
|
|
202
|
+
|
|
203
|
+
static void
|
|
204
|
+
free_smb2dir(struct smb2_context *smb2, struct smb2dir *dir)
|
|
205
|
+
{
|
|
206
|
+
while (dir->entries) {
|
|
207
|
+
struct smb2_dirent_internal *e = dir->entries->next;
|
|
208
|
+
|
|
209
|
+
free(discard_const(dir->entries->dirent.name));
|
|
210
|
+
free(dir->entries);
|
|
211
|
+
dir->entries = e;
|
|
212
|
+
}
|
|
213
|
+
if (dir->free_cb_data) {
|
|
214
|
+
dir->free_cb_data(dir->cb_data);
|
|
215
|
+
}
|
|
216
|
+
free(dir);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
void
|
|
220
|
+
smb2_seekdir(struct smb2_context *smb2, struct smb2dir *dir,
|
|
221
|
+
long loc)
|
|
222
|
+
{
|
|
223
|
+
if (dir == NULL){
|
|
224
|
+
return;
|
|
225
|
+
}
|
|
226
|
+
dir->current_entry = dir->entries;
|
|
227
|
+
dir->index = 0;
|
|
228
|
+
|
|
229
|
+
while (dir->current_entry && loc--) {
|
|
230
|
+
dir->current_entry = dir->current_entry->next;
|
|
231
|
+
dir->index++;
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
long
|
|
236
|
+
smb2_telldir(struct smb2_context *smb2, struct smb2dir *dir)
|
|
237
|
+
{
|
|
238
|
+
if (dir == NULL) {
|
|
239
|
+
return -EINVAL;
|
|
240
|
+
}
|
|
241
|
+
return dir->index;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
void
|
|
245
|
+
smb2_rewinddir(struct smb2_context *smb2,
|
|
246
|
+
struct smb2dir *dir)
|
|
247
|
+
{
|
|
248
|
+
if (dir == NULL) {
|
|
249
|
+
return;
|
|
250
|
+
}
|
|
251
|
+
dir->current_entry = dir->entries;
|
|
252
|
+
dir->index = 0;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
struct smb2dirent *
|
|
256
|
+
smb2_readdir(struct smb2_context *smb2,
|
|
257
|
+
struct smb2dir *dir)
|
|
258
|
+
{
|
|
259
|
+
struct smb2dirent *ent;
|
|
260
|
+
if ((dir == NULL) || (dir->current_entry == NULL)) {
|
|
261
|
+
return NULL;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
ent = &dir->current_entry->dirent;
|
|
265
|
+
dir->current_entry = dir->current_entry->next;
|
|
266
|
+
dir->index++;
|
|
267
|
+
|
|
268
|
+
return ent;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
void
|
|
272
|
+
smb2_closedir(struct smb2_context *smb2, struct smb2dir *dir)
|
|
273
|
+
{
|
|
274
|
+
if ((smb2 == NULL) || (dir == NULL)) {
|
|
275
|
+
return;
|
|
276
|
+
}
|
|
277
|
+
free_smb2dir(smb2, dir);
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
static int
|
|
281
|
+
decode_dirents(struct smb2_context *smb2, struct smb2dir *dir,
|
|
282
|
+
struct smb2_iovec *vec)
|
|
283
|
+
{
|
|
284
|
+
struct smb2_dirent_internal *ent;
|
|
285
|
+
struct smb2_fileidfulldirectoryinformation fs;
|
|
286
|
+
uint32_t offset = 0;
|
|
287
|
+
|
|
288
|
+
do {
|
|
289
|
+
struct smb2_iovec tmp_vec _U_;
|
|
290
|
+
|
|
291
|
+
/* Make sure we do not go beyond end of vector */
|
|
292
|
+
if (offset >= vec->len) {
|
|
293
|
+
smb2_set_error(smb2, "Malformed query reply.");
|
|
294
|
+
return -1;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
ent = calloc(1, sizeof(struct smb2_dirent_internal));
|
|
298
|
+
if (ent == NULL) {
|
|
299
|
+
smb2_set_error(smb2, "Failed to allocate "
|
|
300
|
+
"dirent_internal");
|
|
301
|
+
return -1;
|
|
302
|
+
}
|
|
303
|
+
SMB2_LIST_ADD(&dir->entries, ent);
|
|
304
|
+
|
|
305
|
+
|
|
306
|
+
tmp_vec.buf = &vec->buf[offset];
|
|
307
|
+
tmp_vec.len = vec->len - offset;
|
|
308
|
+
|
|
309
|
+
smb2_decode_fileidfulldirectoryinformation(smb2, &fs,
|
|
310
|
+
&tmp_vec);
|
|
311
|
+
/* steal the name */
|
|
312
|
+
ent->dirent.name = fs.name;
|
|
313
|
+
ent->dirent.st.smb2_type = SMB2_TYPE_FILE;
|
|
314
|
+
if (fs.file_attributes & SMB2_FILE_ATTRIBUTE_DIRECTORY) {
|
|
315
|
+
ent->dirent.st.smb2_type = SMB2_TYPE_DIRECTORY;
|
|
316
|
+
}
|
|
317
|
+
if (fs.file_attributes & SMB2_FILE_ATTRIBUTE_REPARSE_POINT) {
|
|
318
|
+
ent->dirent.st.smb2_type = SMB2_TYPE_LINK;
|
|
319
|
+
}
|
|
320
|
+
ent->dirent.st.smb2_nlink = 0;
|
|
321
|
+
ent->dirent.st.smb2_ino = fs.file_id;
|
|
322
|
+
ent->dirent.st.smb2_size = fs.end_of_file;
|
|
323
|
+
ent->dirent.st.smb2_atime = fs.last_access_time.tv_sec;
|
|
324
|
+
ent->dirent.st.smb2_atime_nsec = fs.last_access_time.tv_usec * 1000;
|
|
325
|
+
ent->dirent.st.smb2_mtime = fs.last_write_time.tv_sec;
|
|
326
|
+
ent->dirent.st.smb2_mtime_nsec = fs.last_write_time.tv_usec * 1000;
|
|
327
|
+
ent->dirent.st.smb2_ctime = fs.change_time.tv_sec;
|
|
328
|
+
ent->dirent.st.smb2_ctime_nsec = fs.change_time.tv_usec * 1000;
|
|
329
|
+
ent->dirent.st.smb2_btime = fs.creation_time.tv_sec;
|
|
330
|
+
ent->dirent.st.smb2_btime_nsec = fs.creation_time.tv_usec * 1000;
|
|
331
|
+
|
|
332
|
+
offset += fs.next_entry_offset;
|
|
333
|
+
} while (fs.next_entry_offset);
|
|
334
|
+
|
|
335
|
+
return 0;
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
static void
|
|
339
|
+
od_close_cb(struct smb2_context *smb2, int status,
|
|
340
|
+
void *command_data, void *private_data)
|
|
341
|
+
{
|
|
342
|
+
struct smb2dir *dir = private_data;
|
|
343
|
+
|
|
344
|
+
if (status != SMB2_STATUS_SUCCESS) {
|
|
345
|
+
dir->cb(smb2, -nterror_to_errno(status),
|
|
346
|
+
NULL, dir->cb_data);
|
|
347
|
+
free_smb2dir(smb2, dir);
|
|
348
|
+
return;
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
dir->current_entry = dir->entries;
|
|
352
|
+
dir->index = 0;
|
|
353
|
+
|
|
354
|
+
/* dir will be freed in smb2_closedir() */
|
|
355
|
+
dir->cb(smb2, 0, dir, dir->cb_data);
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
static void
|
|
359
|
+
query_cb(struct smb2_context *smb2, int status,
|
|
360
|
+
void *command_data, void *private_data)
|
|
361
|
+
{
|
|
362
|
+
struct smb2dir *dir = private_data;
|
|
363
|
+
struct smb2_query_directory_reply *rep = command_data;
|
|
364
|
+
|
|
365
|
+
if (status == SMB2_STATUS_SUCCESS) {
|
|
366
|
+
struct smb2_iovec vec _U_;
|
|
367
|
+
struct smb2_query_directory_request req;
|
|
368
|
+
struct smb2_pdu *pdu;
|
|
369
|
+
|
|
370
|
+
vec.buf = rep->output_buffer;
|
|
371
|
+
vec.len = rep->output_buffer_length;
|
|
372
|
+
|
|
373
|
+
if (decode_dirents(smb2, dir, &vec) < 0) {
|
|
374
|
+
dir->cb(smb2, -ENOMEM, NULL, dir->cb_data);
|
|
375
|
+
free_smb2dir(smb2, dir);
|
|
376
|
+
return;
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
/* We need to get more data */
|
|
380
|
+
memset(&req, 0, sizeof(struct smb2_query_directory_request));
|
|
381
|
+
req.file_information_class = SMB2_FILE_ID_FULL_DIRECTORY_INFORMATION;
|
|
382
|
+
req.flags = 0;
|
|
383
|
+
memcpy(req.file_id, dir->file_id, SMB2_FD_SIZE);
|
|
384
|
+
req.output_buffer_length = DEFAULT_OUTPUT_BUFFER_LENGTH;
|
|
385
|
+
req.name = "*";
|
|
386
|
+
|
|
387
|
+
pdu = smb2_cmd_query_directory_async(smb2, &req, query_cb, dir);
|
|
388
|
+
if (pdu == NULL) {
|
|
389
|
+
dir->cb(smb2, -ENOMEM, NULL, dir->cb_data);
|
|
390
|
+
free_smb2dir(smb2, dir);
|
|
391
|
+
return;
|
|
392
|
+
}
|
|
393
|
+
smb2_queue_pdu(smb2, pdu);
|
|
394
|
+
|
|
395
|
+
return;
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
if (status == SMB2_STATUS_NO_MORE_FILES) {
|
|
399
|
+
struct smb2_close_request req;
|
|
400
|
+
struct smb2_pdu *pdu;
|
|
401
|
+
|
|
402
|
+
/* We have all the data */
|
|
403
|
+
memset(&req, 0, sizeof(struct smb2_close_request));
|
|
404
|
+
req.flags = SMB2_CLOSE_FLAG_POSTQUERY_ATTRIB;
|
|
405
|
+
memcpy(req.file_id, dir->file_id, SMB2_FD_SIZE);
|
|
406
|
+
|
|
407
|
+
pdu = smb2_cmd_close_async(smb2, &req, od_close_cb, dir);
|
|
408
|
+
if (pdu == NULL) {
|
|
409
|
+
dir->cb(smb2, -ENOMEM, NULL, dir->cb_data);
|
|
410
|
+
free_smb2dir(smb2, dir);
|
|
411
|
+
return;
|
|
412
|
+
}
|
|
413
|
+
smb2_queue_pdu(smb2, pdu);
|
|
414
|
+
|
|
415
|
+
return;
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
smb2_set_nterror(smb2, status, "Query directory failed with (0x%08x) %s. %s",
|
|
419
|
+
status, nterror_to_str(status),
|
|
420
|
+
smb2_get_error(smb2));
|
|
421
|
+
dir->cb(smb2, -nterror_to_errno(status), NULL, dir->cb_data);
|
|
422
|
+
free_smb2dir(smb2, dir);
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
static void
|
|
426
|
+
opendir_cb(struct smb2_context *smb2, int status,
|
|
427
|
+
void *command_data, void *private_data)
|
|
428
|
+
{
|
|
429
|
+
struct smb2dir *dir = private_data;
|
|
430
|
+
struct smb2_create_reply *rep = command_data;
|
|
431
|
+
struct smb2_query_directory_request req;
|
|
432
|
+
struct smb2_pdu *pdu;
|
|
433
|
+
|
|
434
|
+
if (status != SMB2_STATUS_SUCCESS) {
|
|
435
|
+
smb2_set_nterror(smb2, status, "Opendir failed with (0x%08x) %s.",
|
|
436
|
+
status, nterror_to_str(status));
|
|
437
|
+
dir->cb(smb2, -nterror_to_errno(status), NULL, dir->cb_data);
|
|
438
|
+
free_smb2dir(smb2, dir);
|
|
439
|
+
return;
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
memcpy(dir->file_id, rep->file_id, SMB2_FD_SIZE);
|
|
443
|
+
|
|
444
|
+
memset(&req, 0, sizeof(struct smb2_query_directory_request));
|
|
445
|
+
req.file_information_class = SMB2_FILE_ID_FULL_DIRECTORY_INFORMATION;
|
|
446
|
+
req.flags = 0;
|
|
447
|
+
memcpy(req.file_id, dir->file_id, SMB2_FD_SIZE);
|
|
448
|
+
req.output_buffer_length = DEFAULT_OUTPUT_BUFFER_LENGTH;
|
|
449
|
+
req.name = "*";
|
|
450
|
+
|
|
451
|
+
pdu = smb2_cmd_query_directory_async(smb2, &req, query_cb, dir);
|
|
452
|
+
if (pdu == NULL) {
|
|
453
|
+
smb2_set_error(smb2, "Failed to create query command.");
|
|
454
|
+
dir->cb(smb2, -ENOMEM, NULL, dir->cb_data);
|
|
455
|
+
free_smb2dir(smb2, dir);
|
|
456
|
+
return;
|
|
457
|
+
}
|
|
458
|
+
smb2_queue_pdu(smb2, pdu);
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
static struct smb2_pdu *
|
|
462
|
+
_smb2_opendir_async(struct smb2_context *smb2, const char *path,
|
|
463
|
+
smb2_command_cb cb, void *cb_data, void (*free_cb)(void *),
|
|
464
|
+
int caller_frees_pdu)
|
|
465
|
+
{
|
|
466
|
+
struct smb2_create_request req;
|
|
467
|
+
struct smb2dir *dir;
|
|
468
|
+
struct smb2_pdu *pdu;
|
|
469
|
+
|
|
470
|
+
if (smb2 == NULL) {
|
|
471
|
+
return NULL;
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
if (path == NULL) {
|
|
475
|
+
path = "";
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
dir = calloc(1, sizeof(struct smb2dir));
|
|
479
|
+
if (dir == NULL) {
|
|
480
|
+
smb2_set_error(smb2, "Failed to allocate smb2dir.");
|
|
481
|
+
return NULL;
|
|
482
|
+
}
|
|
483
|
+
dir->cb = cb;
|
|
484
|
+
dir->cb_data = cb_data;
|
|
485
|
+
|
|
486
|
+
memset(&req, 0, sizeof(struct smb2_create_request));
|
|
487
|
+
req.requested_oplock_level = SMB2_OPLOCK_LEVEL_NONE;
|
|
488
|
+
req.impersonation_level = SMB2_IMPERSONATION_IMPERSONATION;
|
|
489
|
+
req.desired_access = SMB2_FILE_LIST_DIRECTORY | SMB2_FILE_READ_ATTRIBUTES;
|
|
490
|
+
req.file_attributes = SMB2_FILE_ATTRIBUTE_DIRECTORY;
|
|
491
|
+
req.share_access = SMB2_FILE_SHARE_READ | SMB2_FILE_SHARE_WRITE;
|
|
492
|
+
req.create_disposition = SMB2_FILE_OPEN;
|
|
493
|
+
req.create_options = SMB2_FILE_DIRECTORY_FILE;
|
|
494
|
+
req.name = path;
|
|
495
|
+
|
|
496
|
+
pdu = smb2_cmd_create_async(smb2, &req, opendir_cb, dir);
|
|
497
|
+
if (pdu == NULL) {
|
|
498
|
+
free_smb2dir(smb2, dir);
|
|
499
|
+
smb2_set_error(smb2, "Failed to create opendir command.");
|
|
500
|
+
return NULL;
|
|
501
|
+
}
|
|
502
|
+
pdu->free_cb = free_cb;
|
|
503
|
+
pdu->caller_frees_pdu = caller_frees_pdu;
|
|
504
|
+
smb2_queue_pdu(smb2, pdu);
|
|
505
|
+
|
|
506
|
+
return pdu;
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
struct smb2_pdu *
|
|
510
|
+
smb2_opendir_async_pdu(struct smb2_context *smb2, const char *path,
|
|
511
|
+
smb2_command_cb cb, void *cb_data, void (*free_cb)(void *))
|
|
512
|
+
{
|
|
513
|
+
struct smb2_pdu *pdu;
|
|
514
|
+
|
|
515
|
+
pdu = _smb2_opendir_async(smb2, path, cb, cb_data, free_cb, 1);
|
|
516
|
+
return pdu;
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
int
|
|
520
|
+
smb2_opendir_async(struct smb2_context *smb2, const char *path,
|
|
521
|
+
smb2_command_cb cb, void *cb_data)
|
|
522
|
+
{
|
|
523
|
+
struct smb2_pdu *pdu;
|
|
524
|
+
|
|
525
|
+
pdu = _smb2_opendir_async(smb2, path, cb, cb_data, NULL, 0);
|
|
526
|
+
return pdu ? 0 : -1;
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
extern void
|
|
530
|
+
free_c_data(struct smb2_context *smb2, struct connect_data *c_data)
|
|
531
|
+
{
|
|
532
|
+
if (c_data->auth_data) {
|
|
533
|
+
if (smb2->sec == SMB2_SEC_NTLMSSP) {
|
|
534
|
+
ntlmssp_destroy_context(c_data->auth_data);
|
|
535
|
+
}
|
|
536
|
+
#ifdef HAVE_LIBKRB5
|
|
537
|
+
else {
|
|
538
|
+
krb5_free_auth_data(c_data->auth_data);
|
|
539
|
+
}
|
|
540
|
+
#endif
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
if (smb2->connect_data == c_data) {
|
|
544
|
+
smb2->connect_data = NULL; /* to prevent double-free in smb2_destroy_context */
|
|
545
|
+
}
|
|
546
|
+
free(c_data->utf8_unc);
|
|
547
|
+
free(c_data->utf16_unc);
|
|
548
|
+
free(discard_const(c_data->server));
|
|
549
|
+
free(discard_const(c_data->share));
|
|
550
|
+
free(discard_const(c_data->user));
|
|
551
|
+
free(c_data);
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
static void
|
|
555
|
+
tree_connect_cb(struct smb2_context *smb2, int status,
|
|
556
|
+
void *command_data, void *private_data)
|
|
557
|
+
{
|
|
558
|
+
struct connect_data *c_data = private_data;
|
|
559
|
+
|
|
560
|
+
if (status != SMB2_STATUS_SUCCESS) {
|
|
561
|
+
smb2_close_context(smb2);
|
|
562
|
+
smb2_set_nterror(smb2, status, "Tree Connect failed with (0x%08x) %s. %s",
|
|
563
|
+
status, nterror_to_str(status),
|
|
564
|
+
smb2_get_error(smb2));
|
|
565
|
+
c_data->cb(smb2, -nterror_to_errno(status), NULL, c_data->cb_data);
|
|
566
|
+
free_c_data(smb2, c_data);
|
|
567
|
+
return;
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
c_data->cb(smb2, 0, NULL, c_data->cb_data);
|
|
571
|
+
free_c_data(smb2, c_data);
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
void smb2_derive_key(
|
|
575
|
+
uint8_t *derivation_key,
|
|
576
|
+
uint32_t derivation_key_len,
|
|
577
|
+
const char *label,
|
|
578
|
+
uint32_t label_len,
|
|
579
|
+
const char *context,
|
|
580
|
+
uint32_t context_len,
|
|
581
|
+
uint8_t derived_key[SMB2_KEY_SIZE]
|
|
582
|
+
)
|
|
583
|
+
{
|
|
584
|
+
unsigned char nul = 0;
|
|
585
|
+
const uint32_t counter = htobe32(1);
|
|
586
|
+
const uint32_t keylen = htobe32(SMB2_KEY_SIZE * 8);
|
|
587
|
+
uint8_t input_key[SMB2_KEY_SIZE] = {0};
|
|
588
|
+
HMACContext ctx;
|
|
589
|
+
uint8_t digest[USHAMaxHashSize];
|
|
590
|
+
|
|
591
|
+
memcpy(input_key, derivation_key, MIN(sizeof(input_key),
|
|
592
|
+
derivation_key_len));
|
|
593
|
+
hmacReset(&ctx, SHA256, input_key, sizeof(input_key));
|
|
594
|
+
hmacInput(&ctx, (unsigned char *)&counter, sizeof(counter));
|
|
595
|
+
hmacInput(&ctx, (unsigned char *)label, label_len);
|
|
596
|
+
hmacInput(&ctx, &nul, 1);
|
|
597
|
+
hmacInput(&ctx, (unsigned char *)context, context_len);
|
|
598
|
+
hmacInput(&ctx, (unsigned char *)&keylen, sizeof(keylen));
|
|
599
|
+
hmacResult(&ctx, digest);
|
|
600
|
+
memcpy(derived_key, digest, SMB2_KEY_SIZE);
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
/* MS-SMB2 3.2.5.2 */
|
|
604
|
+
static void
|
|
605
|
+
smb3_init_preauth_hash(struct smb2_context *smb2)
|
|
606
|
+
{
|
|
607
|
+
memset(&smb2->preauthhash[0], 0, SMB2_PREAUTH_HASH_SIZE);
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
/* MS-SMB2 3.2.5.2 */
|
|
611
|
+
static int
|
|
612
|
+
smb3_update_preauth_hash(struct smb2_context *smb2, int niov,
|
|
613
|
+
struct smb2_iovec *iov)
|
|
614
|
+
{
|
|
615
|
+
int i;
|
|
616
|
+
USHAContext tctx;
|
|
617
|
+
|
|
618
|
+
USHAReset(&tctx, SHA512);
|
|
619
|
+
USHAInput(&tctx, smb2->preauthhash, SMB2_PREAUTH_HASH_SIZE);
|
|
620
|
+
for (i = 0; i < niov; i++) {
|
|
621
|
+
USHAInput(&tctx, iov[i].buf, iov[i].len);
|
|
622
|
+
}
|
|
623
|
+
USHAResult(&tctx, smb2->preauthhash);
|
|
624
|
+
|
|
625
|
+
return 0;
|
|
626
|
+
}
|
|
627
|
+
|
|
628
|
+
static void smb2_create_signing_key(struct smb2_context *smb2)
|
|
629
|
+
{
|
|
630
|
+
/* Derive the signing key from session key
|
|
631
|
+
* This is based on negotiated protocol
|
|
632
|
+
*/
|
|
633
|
+
if (smb2->dialect == SMB2_VERSION_0202 ||
|
|
634
|
+
smb2->dialect == SMB2_VERSION_0210) {
|
|
635
|
+
/* For SMB2 session key is the signing key */
|
|
636
|
+
memcpy(smb2->signing_key,
|
|
637
|
+
smb2->session_key,
|
|
638
|
+
MIN(smb2->session_key_size, SMB2_KEY_SIZE));
|
|
639
|
+
} else if (smb2->dialect <= SMB2_VERSION_0302) {
|
|
640
|
+
smb2_derive_key(smb2->session_key,
|
|
641
|
+
smb2->session_key_size,
|
|
642
|
+
SMB2AESCMAC,
|
|
643
|
+
sizeof(SMB2AESCMAC),
|
|
644
|
+
SmbSign,
|
|
645
|
+
sizeof(SmbSign),
|
|
646
|
+
smb2->signing_key);
|
|
647
|
+
smb2_derive_key(smb2->session_key,
|
|
648
|
+
smb2->session_key_size,
|
|
649
|
+
SMB2AESCCM,
|
|
650
|
+
sizeof(SMB2AESCCM),
|
|
651
|
+
ServerIn,
|
|
652
|
+
sizeof(ServerIn),
|
|
653
|
+
smb2->serverin_key);
|
|
654
|
+
smb2_derive_key(smb2->session_key,
|
|
655
|
+
smb2->session_key_size,
|
|
656
|
+
SMB2AESCCM,
|
|
657
|
+
sizeof(SMB2AESCCM),
|
|
658
|
+
ServerOut,
|
|
659
|
+
sizeof(ServerOut),
|
|
660
|
+
smb2->serverout_key);
|
|
661
|
+
} else if (smb2->dialect > SMB2_VERSION_0302) {
|
|
662
|
+
smb2_derive_key(smb2->session_key,
|
|
663
|
+
smb2->session_key_size,
|
|
664
|
+
SMBSigningKey,
|
|
665
|
+
sizeof(SMBSigningKey),
|
|
666
|
+
(char *)smb2->preauthhash,
|
|
667
|
+
SMB2_PREAUTH_HASH_SIZE,
|
|
668
|
+
smb2->signing_key);
|
|
669
|
+
smb2_derive_key(smb2->session_key,
|
|
670
|
+
smb2->session_key_size,
|
|
671
|
+
SMBC2SCipherKey,
|
|
672
|
+
sizeof(SMBC2SCipherKey),
|
|
673
|
+
(char *)smb2->preauthhash,
|
|
674
|
+
SMB2_PREAUTH_HASH_SIZE,
|
|
675
|
+
smb2->serverin_key);
|
|
676
|
+
smb2_derive_key(smb2->session_key,
|
|
677
|
+
smb2->session_key_size,
|
|
678
|
+
SMBS2CCipherKey,
|
|
679
|
+
sizeof(SMBS2CCipherKey),
|
|
680
|
+
(char *)smb2->preauthhash,
|
|
681
|
+
SMB2_PREAUTH_HASH_SIZE,
|
|
682
|
+
smb2->serverout_key);
|
|
683
|
+
}
|
|
684
|
+
}
|
|
685
|
+
|
|
686
|
+
static void
|
|
687
|
+
session_setup_cb(struct smb2_context *smb2, int status,
|
|
688
|
+
void *command_data, void *private_data)
|
|
689
|
+
{
|
|
690
|
+
struct connect_data *c_data = private_data;
|
|
691
|
+
struct smb2_session_setup_reply *rep = command_data;
|
|
692
|
+
struct smb2_tree_connect_request req;
|
|
693
|
+
struct smb2_pdu *pdu;
|
|
694
|
+
int ret;
|
|
695
|
+
|
|
696
|
+
if (status == SMB2_STATUS_MORE_PROCESSING_REQUIRED &&
|
|
697
|
+
rep->security_buffer) {
|
|
698
|
+
smb3_update_preauth_hash(smb2, smb2->in.niov - 1, &smb2->in.iov[1]);
|
|
699
|
+
if ((ret = send_session_setup_request(
|
|
700
|
+
smb2, c_data, rep->security_buffer,
|
|
701
|
+
rep->security_buffer_length)) < 0) {
|
|
702
|
+
smb2_close_context(smb2);
|
|
703
|
+
c_data->cb(smb2, ret, NULL, c_data->cb_data);
|
|
704
|
+
free_c_data(smb2, c_data);
|
|
705
|
+
return;
|
|
706
|
+
}
|
|
707
|
+
return;
|
|
708
|
+
} else if (status != SMB2_STATUS_SUCCESS) {
|
|
709
|
+
smb2_close_context(smb2);
|
|
710
|
+
smb2_set_nterror(smb2, status, "Session setup failed with (0x%08x) %s",
|
|
711
|
+
status, nterror_to_str(status));
|
|
712
|
+
c_data->cb(smb2, -nterror_to_errno(status), NULL,
|
|
713
|
+
c_data->cb_data);
|
|
714
|
+
free_c_data(smb2, c_data);
|
|
715
|
+
return;
|
|
716
|
+
}
|
|
717
|
+
|
|
718
|
+
if (rep->session_flags & SMB2_SESSION_FLAG_IS_ENCRYPT_DATA) {
|
|
719
|
+
smb2->seal = 1;
|
|
720
|
+
smb2->sign = 0;
|
|
721
|
+
}
|
|
722
|
+
|
|
723
|
+
#ifdef HAVE_LIBKRB5
|
|
724
|
+
if (smb2->sec == SMB2_SEC_KRB5) {
|
|
725
|
+
/* For NTLM the status will be
|
|
726
|
+
* SMB2_STATUS_MORE_PROCESSING_REQUIRED and a second call to
|
|
727
|
+
* gss_init_sec_context will complete the gss session.
|
|
728
|
+
* But for krb5 a second call to gss_init_sec_context is
|
|
729
|
+
* required if GSS_C_MUTUAL_FLAG is set.
|
|
730
|
+
*
|
|
731
|
+
* At this point SMB2 layer reported success already, so we
|
|
732
|
+
* ignore krb5 errors.
|
|
733
|
+
*/
|
|
734
|
+
krb5_session_request(smb2, c_data->auth_data,
|
|
735
|
+
rep->security_buffer,
|
|
736
|
+
rep->security_buffer_length);
|
|
737
|
+
}
|
|
738
|
+
#endif
|
|
739
|
+
|
|
740
|
+
|
|
741
|
+
if (smb2->sign || smb2->seal || smb2->dialect == SMB2_VERSION_0311) {
|
|
742
|
+
uint8_t zero_key[SMB2_KEY_SIZE] = {0};
|
|
743
|
+
int have_valid_session_key = 1;
|
|
744
|
+
|
|
745
|
+
if (smb2->sec == SMB2_SEC_NTLMSSP) {
|
|
746
|
+
if (ntlmssp_get_session_key(c_data->auth_data,
|
|
747
|
+
&smb2->session_key,
|
|
748
|
+
&smb2->session_key_size) < 0) {
|
|
749
|
+
have_valid_session_key = 0;
|
|
750
|
+
}
|
|
751
|
+
}
|
|
752
|
+
#ifdef HAVE_LIBKRB5
|
|
753
|
+
else {
|
|
754
|
+
if (krb5_session_get_session_key(smb2, c_data->auth_data) < 0) {
|
|
755
|
+
have_valid_session_key = 0;
|
|
756
|
+
}
|
|
757
|
+
}
|
|
758
|
+
#endif
|
|
759
|
+
/* check if the session key is proper */
|
|
760
|
+
if (smb2->session_key == NULL || memcmp(smb2->session_key, zero_key, SMB2_KEY_SIZE) == 0) {
|
|
761
|
+
have_valid_session_key = 0;
|
|
762
|
+
}
|
|
763
|
+
if (smb2->sign && have_valid_session_key == 0) {
|
|
764
|
+
smb2_close_context(smb2);
|
|
765
|
+
smb2_set_error(smb2, "Signing required by server. Session "
|
|
766
|
+
"Key is not available %s",
|
|
767
|
+
smb2_get_error(smb2));
|
|
768
|
+
c_data->cb(smb2, -EACCES, NULL, c_data->cb_data);
|
|
769
|
+
free_c_data(smb2, c_data);
|
|
770
|
+
return;
|
|
771
|
+
}
|
|
772
|
+
|
|
773
|
+
smb2_create_signing_key(smb2);
|
|
774
|
+
|
|
775
|
+
if (smb2->hdr.flags & SMB2_FLAGS_SIGNED) {
|
|
776
|
+
uint8_t signature[16] _U_;
|
|
777
|
+
|
|
778
|
+
memcpy(&signature[0], &smb2->in.iov[1].buf[48], 16);
|
|
779
|
+
if (smb2_calc_signature(smb2, &smb2->in.iov[1].buf[48],
|
|
780
|
+
&smb2->in.iov[1],
|
|
781
|
+
smb2->in.niov - 1) < 0) {
|
|
782
|
+
c_data->cb(smb2, -EINVAL, NULL, c_data->cb_data);
|
|
783
|
+
free_c_data(smb2, c_data);
|
|
784
|
+
return;
|
|
785
|
+
}
|
|
786
|
+
if (memcmp(&signature[0], &smb2->in.iov[1].buf[48], 16)) {
|
|
787
|
+
smb2_set_error(smb2, "Wrong signature in received "
|
|
788
|
+
"PDU");
|
|
789
|
+
c_data->cb(smb2, -EINVAL, NULL, c_data->cb_data);
|
|
790
|
+
free_c_data(smb2, c_data);
|
|
791
|
+
return;
|
|
792
|
+
}
|
|
793
|
+
}
|
|
794
|
+
}
|
|
795
|
+
|
|
796
|
+
memset(&req, 0, sizeof(struct smb2_tree_connect_request));
|
|
797
|
+
req.flags = 0;
|
|
798
|
+
req.path_length = 2 * c_data->utf16_unc->len;
|
|
799
|
+
req.path = c_data->utf16_unc->val;
|
|
800
|
+
|
|
801
|
+
if (!smb2->passthrough) {
|
|
802
|
+
pdu = smb2_cmd_tree_connect_async(smb2, &req, tree_connect_cb, c_data);
|
|
803
|
+
if (pdu == NULL) {
|
|
804
|
+
smb2_close_context(smb2);
|
|
805
|
+
c_data->cb(smb2, -ENOMEM, NULL, c_data->cb_data);
|
|
806
|
+
free_c_data(smb2, c_data);
|
|
807
|
+
return;
|
|
808
|
+
}
|
|
809
|
+
smb2_queue_pdu(smb2, pdu);
|
|
810
|
+
}
|
|
811
|
+
else {
|
|
812
|
+
/* if user wants raw data she probably doesnt want us to
|
|
813
|
+
* do an implicit tree-connect, so just end here
|
|
814
|
+
*/
|
|
815
|
+
c_data->cb(smb2, 0, NULL, c_data->cb_data);
|
|
816
|
+
free_c_data(smb2, c_data);
|
|
817
|
+
}
|
|
818
|
+
}
|
|
819
|
+
|
|
820
|
+
/* Returns 0 for success and -errno for failure */
|
|
821
|
+
static int
|
|
822
|
+
send_session_setup_request(struct smb2_context *smb2,
|
|
823
|
+
struct connect_data *c_data,
|
|
824
|
+
unsigned char *buf, int len)
|
|
825
|
+
{
|
|
826
|
+
struct smb2_pdu *pdu;
|
|
827
|
+
struct smb2_session_setup_request req;
|
|
828
|
+
|
|
829
|
+
/* Session setup request. */
|
|
830
|
+
memset(&req, 0, sizeof(struct smb2_session_setup_request));
|
|
831
|
+
req.security_mode = (uint8_t)smb2->security_mode;
|
|
832
|
+
|
|
833
|
+
if (smb2->sec == SMB2_SEC_NTLMSSP) {
|
|
834
|
+
if (ntlmssp_generate_blob(NULL, smb2, time(NULL), c_data->auth_data,
|
|
835
|
+
buf, len,
|
|
836
|
+
&req.security_buffer,
|
|
837
|
+
&req.security_buffer_length) < 0) {
|
|
838
|
+
smb2_close_context(smb2);
|
|
839
|
+
return -1;
|
|
840
|
+
}
|
|
841
|
+
}
|
|
842
|
+
#ifdef HAVE_LIBKRB5
|
|
843
|
+
else {
|
|
844
|
+
if (krb5_session_request(smb2, c_data->auth_data,
|
|
845
|
+
buf, len) < 0) {
|
|
846
|
+
smb2_close_context(smb2);
|
|
847
|
+
return -1;
|
|
848
|
+
}
|
|
849
|
+
req.security_buffer_length =
|
|
850
|
+
krb5_get_output_token_length(c_data->auth_data);
|
|
851
|
+
req.security_buffer =
|
|
852
|
+
krb5_get_output_token_buffer(c_data->auth_data);
|
|
853
|
+
}
|
|
854
|
+
#endif
|
|
855
|
+
|
|
856
|
+
pdu = smb2_cmd_session_setup_async(smb2, &req,
|
|
857
|
+
session_setup_cb, c_data);
|
|
858
|
+
if (pdu == NULL) {
|
|
859
|
+
smb2_close_context(smb2);
|
|
860
|
+
return -ENOMEM;
|
|
861
|
+
}
|
|
862
|
+
smb2_queue_pdu(smb2, pdu);
|
|
863
|
+
smb3_update_preauth_hash(smb2, pdu->out.niov, &pdu->out.iov[0]);
|
|
864
|
+
|
|
865
|
+
return 0;
|
|
866
|
+
}
|
|
867
|
+
|
|
868
|
+
static void
|
|
869
|
+
negotiate_cb(struct smb2_context *smb2, int status,
|
|
870
|
+
void *command_data, void *private_data)
|
|
871
|
+
{
|
|
872
|
+
struct connect_data *c_data = private_data;
|
|
873
|
+
struct smb2_negotiate_reply *rep = command_data;
|
|
874
|
+
uint32_t spnego_mechs;
|
|
875
|
+
int ret;
|
|
876
|
+
|
|
877
|
+
smb3_update_preauth_hash(smb2, smb2->in.niov - 1, &smb2->in.iov[1]);
|
|
878
|
+
|
|
879
|
+
if (status != SMB2_STATUS_SUCCESS) {
|
|
880
|
+
smb2_close_context(smb2);
|
|
881
|
+
smb2_set_nterror(smb2, status, "Negotiate failed with (0x%08x) %s. %s",
|
|
882
|
+
status, nterror_to_str(status),
|
|
883
|
+
smb2_get_error(smb2));
|
|
884
|
+
/* calls connect_cb */
|
|
885
|
+
c_data->cb(smb2, -nterror_to_errno(status), NULL,
|
|
886
|
+
c_data->cb_data);
|
|
887
|
+
free_c_data(smb2, c_data);
|
|
888
|
+
return;
|
|
889
|
+
}
|
|
890
|
+
|
|
891
|
+
/* update the context with the server capabilities */
|
|
892
|
+
if (rep->dialect_revision > SMB2_VERSION_0202) {
|
|
893
|
+
if (rep->capabilities & SMB2_GLOBAL_CAP_LARGE_MTU) {
|
|
894
|
+
smb2->supports_multi_credit = 1;
|
|
895
|
+
}
|
|
896
|
+
}
|
|
897
|
+
|
|
898
|
+
smb2->max_transact_size = rep->max_transact_size;
|
|
899
|
+
smb2->max_read_size = rep->max_read_size;
|
|
900
|
+
smb2->max_write_size = rep->max_write_size;
|
|
901
|
+
smb2->dialect = rep->dialect_revision;
|
|
902
|
+
smb2->cypher = rep->cypher;
|
|
903
|
+
|
|
904
|
+
if (smb2->seal && (smb2->dialect == SMB2_VERSION_0300 ||
|
|
905
|
+
smb2->dialect == SMB2_VERSION_0302)) {
|
|
906
|
+
if(!(rep->capabilities & SMB2_GLOBAL_CAP_ENCRYPTION)) {
|
|
907
|
+
smb2_set_error(smb2, "Encryption requested but server "
|
|
908
|
+
"does not support encryption.");
|
|
909
|
+
smb2_close_context(smb2);
|
|
910
|
+
c_data->cb(smb2, -ENOMEM, NULL, c_data->cb_data);
|
|
911
|
+
free_c_data(smb2, c_data);
|
|
912
|
+
return;
|
|
913
|
+
}
|
|
914
|
+
}
|
|
915
|
+
|
|
916
|
+
if (smb2->sign &&
|
|
917
|
+
!(rep->security_mode & SMB2_NEGOTIATE_SIGNING_ENABLED)) {
|
|
918
|
+
smb2_set_error(smb2, "Signing requested but server "
|
|
919
|
+
"does not support signing.");
|
|
920
|
+
smb2_close_context(smb2);
|
|
921
|
+
c_data->cb(smb2, -ENOMEM, NULL, c_data->cb_data);
|
|
922
|
+
free_c_data(smb2, c_data);
|
|
923
|
+
return;
|
|
924
|
+
}
|
|
925
|
+
|
|
926
|
+
if (rep->security_mode & SMB2_NEGOTIATE_SIGNING_REQUIRED) {
|
|
927
|
+
smb2->sign = 1;
|
|
928
|
+
}
|
|
929
|
+
|
|
930
|
+
if (smb2->seal) {
|
|
931
|
+
smb2->sign = 0;
|
|
932
|
+
}
|
|
933
|
+
|
|
934
|
+
/* if there is a gssapi blob in the reply, parse it to determine which
|
|
935
|
+
* mechanisms are supported if caller hasn't explicitly set security
|
|
936
|
+
*/
|
|
937
|
+
if (smb2->sec == SMB2_SEC_UNDEFINED &&
|
|
938
|
+
rep->security_buffer && rep->security_buffer_length) {
|
|
939
|
+
spnego_mechs = 0;
|
|
940
|
+
smb2_spnego_unwrap_gssapi(smb2, rep->security_buffer,
|
|
941
|
+
rep->security_buffer_length, 1,
|
|
942
|
+
NULL, &spnego_mechs);
|
|
943
|
+
#ifdef HAVE_LIBKRB5
|
|
944
|
+
if (spnego_mechs & SPNEGO_MECHANISM_KRB5) {
|
|
945
|
+
smb2->sec = SMB2_SEC_KRB5;
|
|
946
|
+
}
|
|
947
|
+
#endif
|
|
948
|
+
if (smb2->sec == SMB2_SEC_UNDEFINED &&
|
|
949
|
+
(spnego_mechs & SPNEGO_MECHANISM_NTLMSSP)) {
|
|
950
|
+
smb2->sec = SMB2_SEC_NTLMSSP;
|
|
951
|
+
}
|
|
952
|
+
}
|
|
953
|
+
if (smb2->sec == SMB2_SEC_UNDEFINED) {
|
|
954
|
+
#ifdef HAVE_LIBKRB5
|
|
955
|
+
smb2->sec = SMB2_SEC_KRB5;
|
|
956
|
+
#else
|
|
957
|
+
smb2->sec = SMB2_SEC_NTLMSSP;
|
|
958
|
+
#endif
|
|
959
|
+
}
|
|
960
|
+
|
|
961
|
+
if (smb2->sec == SMB2_SEC_NTLMSSP) {
|
|
962
|
+
c_data->auth_data = ntlmssp_init_context(smb2->user,
|
|
963
|
+
smb2->password,
|
|
964
|
+
smb2->domain,
|
|
965
|
+
smb2->workstation,
|
|
966
|
+
smb2->client_challenge);
|
|
967
|
+
}
|
|
968
|
+
#ifdef HAVE_LIBKRB5
|
|
969
|
+
else {
|
|
970
|
+
c_data->auth_data = krb5_negotiate_reply(smb2,
|
|
971
|
+
c_data->server,
|
|
972
|
+
smb2->domain,
|
|
973
|
+
c_data->user,
|
|
974
|
+
smb2->password);
|
|
975
|
+
}
|
|
976
|
+
#endif
|
|
977
|
+
if (c_data->auth_data == NULL) {
|
|
978
|
+
smb2_close_context(smb2);
|
|
979
|
+
c_data->cb(smb2, -ENOMEM, NULL, c_data->cb_data);
|
|
980
|
+
free_c_data(smb2, c_data);
|
|
981
|
+
return;
|
|
982
|
+
}
|
|
983
|
+
|
|
984
|
+
if ((ret = send_session_setup_request(smb2, c_data, NULL, 0)) < 0) {
|
|
985
|
+
smb2_close_context(smb2);
|
|
986
|
+
c_data->cb(smb2, ret, NULL, c_data->cb_data);
|
|
987
|
+
free_c_data(smb2, c_data);
|
|
988
|
+
return;
|
|
989
|
+
}
|
|
990
|
+
}
|
|
991
|
+
|
|
992
|
+
static void
|
|
993
|
+
connect_cb(struct smb2_context *smb2, int status,
|
|
994
|
+
void *command_data _U_, void *private_data)
|
|
995
|
+
{
|
|
996
|
+
struct connect_data *c_data = private_data;
|
|
997
|
+
struct smb2_negotiate_request req;
|
|
998
|
+
struct smb2_pdu *pdu;
|
|
999
|
+
|
|
1000
|
+
if (status != 0) {
|
|
1001
|
+
smb2_set_error(smb2, "Socket connect failed with %d",
|
|
1002
|
+
status);
|
|
1003
|
+
c_data->cb(smb2, -status, NULL, c_data->cb_data);
|
|
1004
|
+
free_c_data(smb2, c_data);
|
|
1005
|
+
return;
|
|
1006
|
+
}
|
|
1007
|
+
|
|
1008
|
+
memset(&req, 0, sizeof(struct smb2_negotiate_request));
|
|
1009
|
+
req.capabilities = SMB2_GLOBAL_CAP_LARGE_MTU;
|
|
1010
|
+
if (smb2->version == SMB2_VERSION_ANY ||
|
|
1011
|
+
smb2->version == SMB2_VERSION_ANY3 ||
|
|
1012
|
+
smb2->version == SMB2_VERSION_0300 ||
|
|
1013
|
+
smb2->version == SMB2_VERSION_0302 ||
|
|
1014
|
+
smb2->version == SMB2_VERSION_0311) {
|
|
1015
|
+
req.capabilities |= SMB2_GLOBAL_CAP_ENCRYPTION;
|
|
1016
|
+
}
|
|
1017
|
+
req.security_mode = smb2->security_mode;
|
|
1018
|
+
switch (smb2->version) {
|
|
1019
|
+
case SMB2_VERSION_ANY:
|
|
1020
|
+
req.dialect_count = 5;
|
|
1021
|
+
req.dialects[0] = SMB2_VERSION_0202;
|
|
1022
|
+
req.dialects[1] = SMB2_VERSION_0210;
|
|
1023
|
+
req.dialects[2] = SMB2_VERSION_0300;
|
|
1024
|
+
req.dialects[3] = SMB2_VERSION_0302;
|
|
1025
|
+
req.dialects[4] = SMB2_VERSION_0311;
|
|
1026
|
+
break;
|
|
1027
|
+
case SMB2_VERSION_ANY2:
|
|
1028
|
+
req.dialect_count = 2;
|
|
1029
|
+
req.dialects[0] = SMB2_VERSION_0202;
|
|
1030
|
+
req.dialects[1] = SMB2_VERSION_0210;
|
|
1031
|
+
break;
|
|
1032
|
+
case SMB2_VERSION_ANY3:
|
|
1033
|
+
req.dialect_count = 3;
|
|
1034
|
+
req.dialects[0] = SMB2_VERSION_0300;
|
|
1035
|
+
req.dialects[1] = SMB2_VERSION_0302;
|
|
1036
|
+
req.dialects[2] = SMB2_VERSION_0311;
|
|
1037
|
+
break;
|
|
1038
|
+
case SMB2_VERSION_0202:
|
|
1039
|
+
case SMB2_VERSION_0210:
|
|
1040
|
+
case SMB2_VERSION_0300:
|
|
1041
|
+
case SMB2_VERSION_0302:
|
|
1042
|
+
case SMB2_VERSION_0311:
|
|
1043
|
+
req.dialect_count = 1;
|
|
1044
|
+
req.dialects[0] = smb2->version;
|
|
1045
|
+
break;
|
|
1046
|
+
}
|
|
1047
|
+
|
|
1048
|
+
memcpy(req.client_guid, smb2_get_client_guid(smb2), SMB2_GUID_SIZE);
|
|
1049
|
+
|
|
1050
|
+
smb3_init_preauth_hash(smb2);
|
|
1051
|
+
pdu = smb2_cmd_negotiate_async(smb2, &req, negotiate_cb, c_data);
|
|
1052
|
+
if (pdu == NULL) {
|
|
1053
|
+
c_data->cb(smb2, -ENOMEM, NULL, c_data->cb_data);
|
|
1054
|
+
free_c_data(smb2, c_data);
|
|
1055
|
+
return;
|
|
1056
|
+
}
|
|
1057
|
+
smb2_queue_pdu(smb2, pdu);
|
|
1058
|
+
smb3_update_preauth_hash(smb2, pdu->out.niov, &pdu->out.iov[0]);
|
|
1059
|
+
}
|
|
1060
|
+
|
|
1061
|
+
int
|
|
1062
|
+
smb2_connect_share_async(struct smb2_context *smb2,
|
|
1063
|
+
const char *server,
|
|
1064
|
+
const char *share, const char *user,
|
|
1065
|
+
smb2_command_cb cb, void *cb_data)
|
|
1066
|
+
{
|
|
1067
|
+
struct connect_data *c_data;
|
|
1068
|
+
int err;
|
|
1069
|
+
|
|
1070
|
+
if (smb2 == NULL) {
|
|
1071
|
+
return -EINVAL;
|
|
1072
|
+
}
|
|
1073
|
+
|
|
1074
|
+
if (smb2->server != NULL) {
|
|
1075
|
+
free(discard_const(smb2->server));
|
|
1076
|
+
smb2->server = NULL;
|
|
1077
|
+
}
|
|
1078
|
+
if (server == NULL) {
|
|
1079
|
+
smb2_set_error(smb2, "No server name provided");
|
|
1080
|
+
return -EINVAL;
|
|
1081
|
+
}
|
|
1082
|
+
if (share == NULL) {
|
|
1083
|
+
smb2_set_error(smb2, "No share name provided");
|
|
1084
|
+
return -EINVAL;
|
|
1085
|
+
}
|
|
1086
|
+
smb2->server = strdup(server);
|
|
1087
|
+
if (smb2->server == NULL) {
|
|
1088
|
+
return -ENOMEM;
|
|
1089
|
+
}
|
|
1090
|
+
|
|
1091
|
+
if (smb2->share) {
|
|
1092
|
+
free(discard_const(smb2->share));
|
|
1093
|
+
}
|
|
1094
|
+
smb2->share = strdup(share);
|
|
1095
|
+
if (smb2->share == NULL) {
|
|
1096
|
+
return -ENOMEM;
|
|
1097
|
+
}
|
|
1098
|
+
|
|
1099
|
+
if (user) {
|
|
1100
|
+
smb2_set_user(smb2, user);
|
|
1101
|
+
}
|
|
1102
|
+
c_data = calloc(1, sizeof(struct connect_data));
|
|
1103
|
+
if (c_data == NULL) {
|
|
1104
|
+
smb2_set_error(smb2, "Failed to allocate connect_data");
|
|
1105
|
+
return -ENOMEM;
|
|
1106
|
+
}
|
|
1107
|
+
c_data->server = strdup(smb2->server);
|
|
1108
|
+
if (c_data->server == NULL) {
|
|
1109
|
+
free_c_data(smb2, c_data);
|
|
1110
|
+
smb2_set_error(smb2, "Failed to strdup(server)");
|
|
1111
|
+
return -ENOMEM;
|
|
1112
|
+
}
|
|
1113
|
+
c_data->share = strdup(smb2->share);
|
|
1114
|
+
if (c_data->share == NULL) {
|
|
1115
|
+
free_c_data(smb2, c_data);
|
|
1116
|
+
smb2_set_error(smb2, "Failed to strdup(share)");
|
|
1117
|
+
return -ENOMEM;
|
|
1118
|
+
}
|
|
1119
|
+
if (smb2->user == NULL) {
|
|
1120
|
+
smb2_set_error(smb2, "smb2->user is NULL");
|
|
1121
|
+
return -ENOMEM;
|
|
1122
|
+
}
|
|
1123
|
+
c_data->user = strdup(smb2->user);
|
|
1124
|
+
if (c_data->user == NULL) {
|
|
1125
|
+
free_c_data(smb2, c_data);
|
|
1126
|
+
smb2_set_error(smb2, "Failed to strdup(user)");
|
|
1127
|
+
return -ENOMEM;
|
|
1128
|
+
}
|
|
1129
|
+
if (asprintf(&c_data->utf8_unc, "\\\\%s\\%s", c_data->server,
|
|
1130
|
+
c_data->share) < 0) {
|
|
1131
|
+
free_c_data(smb2, c_data);
|
|
1132
|
+
smb2_set_error(smb2, "Failed to allocate unc string.");
|
|
1133
|
+
return -ENOMEM;
|
|
1134
|
+
}
|
|
1135
|
+
|
|
1136
|
+
c_data->utf16_unc = smb2_utf8_to_utf16(c_data->utf8_unc);
|
|
1137
|
+
if (c_data->utf16_unc == NULL) {
|
|
1138
|
+
smb2_set_error(smb2, "Count not convert UNC:[%s] into UTF-16",
|
|
1139
|
+
c_data->utf8_unc);
|
|
1140
|
+
free_c_data(smb2, c_data);
|
|
1141
|
+
return -ENOMEM;
|
|
1142
|
+
}
|
|
1143
|
+
|
|
1144
|
+
c_data->cb = cb;
|
|
1145
|
+
c_data->cb_data = cb_data;
|
|
1146
|
+
|
|
1147
|
+
err = smb2_connect_async(smb2, server, connect_cb, c_data);
|
|
1148
|
+
if (err != 0) {
|
|
1149
|
+
free_c_data(smb2, c_data);
|
|
1150
|
+
return err;
|
|
1151
|
+
}
|
|
1152
|
+
|
|
1153
|
+
return 0;
|
|
1154
|
+
}
|
|
1155
|
+
|
|
1156
|
+
static void
|
|
1157
|
+
free_smb2fh(struct smb2_context *smb2, struct smb2fh *fh)
|
|
1158
|
+
{
|
|
1159
|
+
free(fh);
|
|
1160
|
+
}
|
|
1161
|
+
|
|
1162
|
+
static void
|
|
1163
|
+
open_cb(struct smb2_context *smb2, int status,
|
|
1164
|
+
void *command_data, void *private_data)
|
|
1165
|
+
{
|
|
1166
|
+
struct smb2fh *fh = private_data;
|
|
1167
|
+
struct smb2_create_reply *rep = command_data;
|
|
1168
|
+
|
|
1169
|
+
if (status != SMB2_STATUS_SUCCESS) {
|
|
1170
|
+
smb2_set_nterror(smb2, status, "Open failed with (0x%08x) %s.",
|
|
1171
|
+
status, nterror_to_str(status));
|
|
1172
|
+
fh->cb(smb2, -nterror_to_errno(status), NULL, fh->cb_data);
|
|
1173
|
+
free_smb2fh(smb2, fh);
|
|
1174
|
+
return;
|
|
1175
|
+
}
|
|
1176
|
+
|
|
1177
|
+
memcpy(fh->file_id, rep->file_id, SMB2_FD_SIZE);
|
|
1178
|
+
fh->end_of_file = rep->end_of_file;
|
|
1179
|
+
fh->cb(smb2, 0, fh, fh->cb_data);
|
|
1180
|
+
}
|
|
1181
|
+
|
|
1182
|
+
static struct smb2_pdu *
|
|
1183
|
+
_smb2_open_async_with_oplock_or_lease(struct smb2_context *smb2, const char *path, int flags,
|
|
1184
|
+
uint8_t oplock_level, uint32_t lease_state, smb2_lease_key lease_key,
|
|
1185
|
+
smb2_command_cb cb, void *cb_data, void (*free_cb)(void *),
|
|
1186
|
+
int caller_frees_pdu)
|
|
1187
|
+
{
|
|
1188
|
+
struct smb2fh *fh;
|
|
1189
|
+
struct smb2_create_request req;
|
|
1190
|
+
struct smb2_pdu *pdu;
|
|
1191
|
+
struct smb2_iovec iov;
|
|
1192
|
+
uint32_t desired_access = 0;
|
|
1193
|
+
uint32_t create_disposition = 0;
|
|
1194
|
+
uint32_t create_options = 0;
|
|
1195
|
+
uint32_t file_attributes = 0;
|
|
1196
|
+
|
|
1197
|
+
if (smb2 == NULL) {
|
|
1198
|
+
return NULL;
|
|
1199
|
+
}
|
|
1200
|
+
|
|
1201
|
+
fh = calloc(1, sizeof(struct smb2fh));
|
|
1202
|
+
if (fh == NULL) {
|
|
1203
|
+
smb2_set_error(smb2, "Failed to allocate smbfh");
|
|
1204
|
+
return NULL;
|
|
1205
|
+
}
|
|
1206
|
+
|
|
1207
|
+
fh->cb = cb;
|
|
1208
|
+
fh->cb_data = cb_data;
|
|
1209
|
+
|
|
1210
|
+
/* Create disposition */
|
|
1211
|
+
if (flags & O_CREAT) {
|
|
1212
|
+
if (flags & O_EXCL) {
|
|
1213
|
+
create_disposition = SMB2_FILE_CREATE;
|
|
1214
|
+
} else if(flags & O_TRUNC) {
|
|
1215
|
+
create_disposition = SMB2_FILE_OVERWRITE_IF;
|
|
1216
|
+
} else {
|
|
1217
|
+
create_disposition = SMB2_FILE_OPEN_IF;
|
|
1218
|
+
}
|
|
1219
|
+
} else {
|
|
1220
|
+
if (flags & O_TRUNC) {
|
|
1221
|
+
create_disposition = SMB2_FILE_OVERWRITE;
|
|
1222
|
+
} else {
|
|
1223
|
+
create_disposition = SMB2_FILE_OPEN;
|
|
1224
|
+
}
|
|
1225
|
+
}
|
|
1226
|
+
|
|
1227
|
+
/* desired access */
|
|
1228
|
+
switch (flags & O_ACCMODE) {
|
|
1229
|
+
case O_RDWR:
|
|
1230
|
+
case O_WRONLY:
|
|
1231
|
+
desired_access |= SMB2_FILE_WRITE_DATA |
|
|
1232
|
+
SMB2_FILE_WRITE_EA |
|
|
1233
|
+
SMB2_FILE_WRITE_ATTRIBUTES;
|
|
1234
|
+
if ((flags & O_ACCMODE) == O_WRONLY)
|
|
1235
|
+
break;
|
|
1236
|
+
case O_RDONLY:
|
|
1237
|
+
desired_access |= SMB2_FILE_READ_DATA |
|
|
1238
|
+
SMB2_FILE_READ_EA |
|
|
1239
|
+
SMB2_FILE_READ_ATTRIBUTES;
|
|
1240
|
+
break;
|
|
1241
|
+
}
|
|
1242
|
+
|
|
1243
|
+
#ifdef O_DIRECTORY
|
|
1244
|
+
if (flags & O_DIRECTORY) {
|
|
1245
|
+
/* must be directory */
|
|
1246
|
+
create_options |= SMB2_FILE_DIRECTORY_FILE;
|
|
1247
|
+
} else {
|
|
1248
|
+
/* must not be directory */
|
|
1249
|
+
create_options |= SMB2_FILE_NON_DIRECTORY_FILE;
|
|
1250
|
+
}
|
|
1251
|
+
#else
|
|
1252
|
+
create_options |= SMB2_FILE_NON_DIRECTORY_FILE;
|
|
1253
|
+
#endif
|
|
1254
|
+
|
|
1255
|
+
if (flags & O_SYNC) {
|
|
1256
|
+
desired_access |= SMB2_SYNCHRONIZE;
|
|
1257
|
+
create_options |= SMB2_FILE_NO_INTERMEDIATE_BUFFERING;
|
|
1258
|
+
}
|
|
1259
|
+
|
|
1260
|
+
memset(&req, 0, sizeof(struct smb2_create_request));
|
|
1261
|
+
req.requested_oplock_level = oplock_level;
|
|
1262
|
+
req.impersonation_level = SMB2_IMPERSONATION_IMPERSONATION;
|
|
1263
|
+
req.desired_access = desired_access;
|
|
1264
|
+
req.file_attributes = file_attributes;
|
|
1265
|
+
req.share_access = SMB2_FILE_SHARE_READ | SMB2_FILE_SHARE_WRITE;
|
|
1266
|
+
req.create_disposition = create_disposition;
|
|
1267
|
+
req.create_options = create_options;
|
|
1268
|
+
req.name = path;
|
|
1269
|
+
|
|
1270
|
+
if (lease_state && lease_key) {
|
|
1271
|
+
req.create_context_length = SMB2_CREATE_REQUEST_LEASE_SIZE + 24;
|
|
1272
|
+
req.create_context = calloc(1, SMB2_CREATE_REQUEST_LEASE_SIZE + 24);
|
|
1273
|
+
iov.buf = req.create_context;
|
|
1274
|
+
iov.len = req.create_context_length;
|
|
1275
|
+
smb2_set_uint32(&iov, 0, 0); /* chain offset */
|
|
1276
|
+
smb2_set_uint16(&iov, 4, 16); /* tag offset */
|
|
1277
|
+
smb2_set_uint16(&iov, 6, 4); /* tag length lo */
|
|
1278
|
+
smb2_set_uint16(&iov, 8, 0); /* tag length up */
|
|
1279
|
+
smb2_set_uint16(&iov, 10, 24); /* data offset */
|
|
1280
|
+
smb2_set_uint16(&iov, 12, SMB2_CREATE_REQUEST_LEASE_SIZE);
|
|
1281
|
+
smb2_set_uint32(&iov, 16, htobe32(0x52714c73));
|
|
1282
|
+
memcpy(iov.buf + 24, lease_key, SMB2_LEASE_KEY_SIZE);
|
|
1283
|
+
smb2_set_uint32(&iov, 40, lease_state);
|
|
1284
|
+
}
|
|
1285
|
+
|
|
1286
|
+
pdu = smb2_cmd_create_async(smb2, &req, open_cb, fh);
|
|
1287
|
+
if (pdu == NULL) {
|
|
1288
|
+
smb2_set_error(smb2, "Failed to create create command");
|
|
1289
|
+
free_smb2fh(smb2, fh);
|
|
1290
|
+
return NULL;
|
|
1291
|
+
}
|
|
1292
|
+
if (req.create_context && req.create_context_length) {
|
|
1293
|
+
free(req.create_context);
|
|
1294
|
+
}
|
|
1295
|
+
|
|
1296
|
+
pdu->caller_frees_pdu = caller_frees_pdu;
|
|
1297
|
+
smb2_queue_pdu(smb2, pdu);
|
|
1298
|
+
|
|
1299
|
+
return pdu;
|
|
1300
|
+
}
|
|
1301
|
+
|
|
1302
|
+
struct smb2_pdu *
|
|
1303
|
+
smb2_open_async_pdu(struct smb2_context *smb2, const char *path, int flags,
|
|
1304
|
+
smb2_command_cb cb, void *cb_data, void (*free_cb)(void *))
|
|
1305
|
+
{
|
|
1306
|
+
return _smb2_open_async_with_oplock_or_lease(smb2, path, flags,
|
|
1307
|
+
SMB2_OPLOCK_LEVEL_NONE, 0, NULL,
|
|
1308
|
+
cb, cb_data, free_cb, 1);
|
|
1309
|
+
}
|
|
1310
|
+
|
|
1311
|
+
int
|
|
1312
|
+
smb2_open_async_with_oplock_or_lease(struct smb2_context *smb2, const char *path, int flags,
|
|
1313
|
+
uint8_t oplock_level, uint32_t lease_state, smb2_lease_key lease_key,
|
|
1314
|
+
smb2_command_cb cb, void *cb_data)
|
|
1315
|
+
|
|
1316
|
+
{
|
|
1317
|
+
struct smb2_pdu *pdu;
|
|
1318
|
+
|
|
1319
|
+
pdu = _smb2_open_async_with_oplock_or_lease(smb2, path, flags,
|
|
1320
|
+
oplock_level, lease_state, lease_key,
|
|
1321
|
+
cb, cb_data, NULL, 0);
|
|
1322
|
+
return pdu ? 0 : -1;
|
|
1323
|
+
}
|
|
1324
|
+
|
|
1325
|
+
int
|
|
1326
|
+
smb2_open_async(struct smb2_context *smb2, const char *path, int flags,
|
|
1327
|
+
smb2_command_cb cb, void *cb_data)
|
|
1328
|
+
{
|
|
1329
|
+
struct smb2_pdu *pdu;
|
|
1330
|
+
|
|
1331
|
+
pdu = _smb2_open_async_with_oplock_or_lease(smb2, path, flags,
|
|
1332
|
+
SMB2_OPLOCK_LEVEL_NONE, 0, NULL,
|
|
1333
|
+
cb, cb_data, NULL, 0);
|
|
1334
|
+
return pdu ? 0 : -1;
|
|
1335
|
+
}
|
|
1336
|
+
|
|
1337
|
+
static void
|
|
1338
|
+
close_cb(struct smb2_context *smb2, int status,
|
|
1339
|
+
void *command_data, void *private_data)
|
|
1340
|
+
{
|
|
1341
|
+
struct smb2fh *fh = private_data;
|
|
1342
|
+
|
|
1343
|
+
if (status != SMB2_STATUS_SUCCESS) {
|
|
1344
|
+
smb2_set_nterror(smb2, status, "Close failed with (0x%08x) %s",
|
|
1345
|
+
status, nterror_to_str(status));
|
|
1346
|
+
fh->cb(smb2, -nterror_to_errno(status), NULL, fh->cb_data);
|
|
1347
|
+
free_smb2fh(smb2, fh);
|
|
1348
|
+
return;
|
|
1349
|
+
}
|
|
1350
|
+
|
|
1351
|
+
fh->cb(smb2, 0, NULL, fh->cb_data);
|
|
1352
|
+
free_smb2fh(smb2, fh);
|
|
1353
|
+
}
|
|
1354
|
+
|
|
1355
|
+
int
|
|
1356
|
+
smb2_close_async(struct smb2_context *smb2, struct smb2fh *fh,
|
|
1357
|
+
smb2_command_cb cb, void *cb_data)
|
|
1358
|
+
{
|
|
1359
|
+
struct smb2_close_request req;
|
|
1360
|
+
struct smb2_pdu *pdu;
|
|
1361
|
+
|
|
1362
|
+
if (smb2 == NULL) {
|
|
1363
|
+
return -EINVAL;
|
|
1364
|
+
}
|
|
1365
|
+
if (fh == NULL) {
|
|
1366
|
+
smb2_set_error(smb2, "File handle was NULL");
|
|
1367
|
+
return -EINVAL;
|
|
1368
|
+
}
|
|
1369
|
+
|
|
1370
|
+
fh->cb = cb;
|
|
1371
|
+
fh->cb_data = cb_data;
|
|
1372
|
+
|
|
1373
|
+
memset(&req, 0, sizeof(struct smb2_close_request));
|
|
1374
|
+
req.flags = SMB2_CLOSE_FLAG_POSTQUERY_ATTRIB;
|
|
1375
|
+
memcpy(req.file_id, fh->file_id, SMB2_FD_SIZE);
|
|
1376
|
+
|
|
1377
|
+
pdu = smb2_cmd_close_async(smb2, &req, close_cb, fh);
|
|
1378
|
+
if (pdu == NULL) {
|
|
1379
|
+
smb2_set_error(smb2, "Failed to create close command");
|
|
1380
|
+
return -ENOMEM;
|
|
1381
|
+
}
|
|
1382
|
+
smb2_queue_pdu(smb2, pdu);
|
|
1383
|
+
|
|
1384
|
+
return 0;
|
|
1385
|
+
}
|
|
1386
|
+
|
|
1387
|
+
static void
|
|
1388
|
+
fsync_cb(struct smb2_context *smb2, int status,
|
|
1389
|
+
void *command_data, void *private_data)
|
|
1390
|
+
{
|
|
1391
|
+
struct smb2fh *fh = private_data;
|
|
1392
|
+
|
|
1393
|
+
if (status != SMB2_STATUS_SUCCESS) {
|
|
1394
|
+
smb2_set_nterror(smb2, status, "Flush failed with (0x%08x) %s",
|
|
1395
|
+
status, nterror_to_str(status));
|
|
1396
|
+
fh->cb(smb2, -nterror_to_errno(status), NULL, fh->cb_data);
|
|
1397
|
+
return;
|
|
1398
|
+
}
|
|
1399
|
+
|
|
1400
|
+
fh->cb(smb2, 0, NULL, fh->cb_data);
|
|
1401
|
+
}
|
|
1402
|
+
|
|
1403
|
+
int
|
|
1404
|
+
smb2_fsync_async(struct smb2_context *smb2, struct smb2fh *fh,
|
|
1405
|
+
smb2_command_cb cb, void *cb_data)
|
|
1406
|
+
{
|
|
1407
|
+
struct smb2_flush_request req;
|
|
1408
|
+
struct smb2_pdu *pdu;
|
|
1409
|
+
|
|
1410
|
+
if (smb2 == NULL) {
|
|
1411
|
+
return -EINVAL;
|
|
1412
|
+
}
|
|
1413
|
+
if (fh == NULL) {
|
|
1414
|
+
smb2_set_error(smb2, "File handle was NULL");
|
|
1415
|
+
return -EINVAL;
|
|
1416
|
+
}
|
|
1417
|
+
|
|
1418
|
+
fh->cb = cb;
|
|
1419
|
+
fh->cb_data = cb_data;
|
|
1420
|
+
|
|
1421
|
+
memset(&req, 0, sizeof(struct smb2_flush_request));
|
|
1422
|
+
memcpy(req.file_id, fh->file_id, SMB2_FD_SIZE);
|
|
1423
|
+
|
|
1424
|
+
pdu = smb2_cmd_flush_async(smb2, &req, fsync_cb, fh);
|
|
1425
|
+
if (pdu == NULL) {
|
|
1426
|
+
smb2_set_error(smb2, "Failed to create flush command");
|
|
1427
|
+
return -ENOMEM;
|
|
1428
|
+
}
|
|
1429
|
+
smb2_queue_pdu(smb2, pdu);
|
|
1430
|
+
|
|
1431
|
+
return 0;
|
|
1432
|
+
}
|
|
1433
|
+
|
|
1434
|
+
struct read_data {
|
|
1435
|
+
smb2_command_cb cb;
|
|
1436
|
+
void *cb_data;
|
|
1437
|
+
|
|
1438
|
+
struct smb2_read_cb_data read_cb_data;
|
|
1439
|
+
};
|
|
1440
|
+
|
|
1441
|
+
static void
|
|
1442
|
+
read_cb(struct smb2_context *smb2, int status,
|
|
1443
|
+
void *command_data, void *private_data)
|
|
1444
|
+
{
|
|
1445
|
+
struct read_data *rd = private_data;
|
|
1446
|
+
struct smb2_read_reply *rep = command_data;
|
|
1447
|
+
|
|
1448
|
+
if (status && status != SMB2_STATUS_END_OF_FILE) {
|
|
1449
|
+
smb2_set_nterror(smb2, status, "Read/Write failed with (0x%08x) %s",
|
|
1450
|
+
status, nterror_to_str(status));
|
|
1451
|
+
rd->cb(smb2, -nterror_to_errno(status), &rd->read_cb_data, rd->cb_data);
|
|
1452
|
+
free(rd);
|
|
1453
|
+
return;
|
|
1454
|
+
}
|
|
1455
|
+
|
|
1456
|
+
if (status == SMB2_STATUS_SUCCESS) {
|
|
1457
|
+
rd->read_cb_data.fh->offset = rd->read_cb_data.offset + rep->data_length;
|
|
1458
|
+
}
|
|
1459
|
+
|
|
1460
|
+
rd->cb(smb2, rep->data_length, &rd->read_cb_data, rd->cb_data);
|
|
1461
|
+
free(rd);
|
|
1462
|
+
}
|
|
1463
|
+
|
|
1464
|
+
int
|
|
1465
|
+
smb2_pread_async(struct smb2_context *smb2, struct smb2fh *fh,
|
|
1466
|
+
uint8_t *buf, uint32_t count, uint64_t offset,
|
|
1467
|
+
smb2_command_cb cb, void *cb_data)
|
|
1468
|
+
{
|
|
1469
|
+
struct smb2_read_request req;
|
|
1470
|
+
struct read_data *rd;
|
|
1471
|
+
struct smb2_pdu *pdu;
|
|
1472
|
+
int needed_credits;
|
|
1473
|
+
|
|
1474
|
+
if (smb2 == NULL) {
|
|
1475
|
+
return -EINVAL;
|
|
1476
|
+
}
|
|
1477
|
+
if (fh == NULL) {
|
|
1478
|
+
smb2_set_error(smb2, "File handle was NULL");
|
|
1479
|
+
return -EINVAL;
|
|
1480
|
+
}
|
|
1481
|
+
|
|
1482
|
+
rd = calloc(1, sizeof(struct read_data));
|
|
1483
|
+
if (rd == NULL) {
|
|
1484
|
+
smb2_set_error(smb2, "Failed to allocate read_data");
|
|
1485
|
+
return -ENOMEM;
|
|
1486
|
+
}
|
|
1487
|
+
|
|
1488
|
+
rd->cb = cb;
|
|
1489
|
+
rd->cb_data = cb_data;
|
|
1490
|
+
rd->read_cb_data.fh = fh;
|
|
1491
|
+
rd->read_cb_data.buf = buf;
|
|
1492
|
+
rd->read_cb_data.count = count;
|
|
1493
|
+
rd->read_cb_data.offset = offset;
|
|
1494
|
+
|
|
1495
|
+
if (count > smb2->max_read_size) {
|
|
1496
|
+
count = smb2->max_read_size;
|
|
1497
|
+
}
|
|
1498
|
+
needed_credits = (count - 1) / 65536 + 1;
|
|
1499
|
+
|
|
1500
|
+
if (smb2->dialect > SMB2_VERSION_0202) {
|
|
1501
|
+
if (needed_credits > MAX_CREDITS - 16) {
|
|
1502
|
+
count = (MAX_CREDITS - 16) * 65536;
|
|
1503
|
+
}
|
|
1504
|
+
needed_credits = (count - 1) / 65536 + 1;
|
|
1505
|
+
if (needed_credits > smb2->credits) {
|
|
1506
|
+
count = smb2->credits * 65536;
|
|
1507
|
+
}
|
|
1508
|
+
} else {
|
|
1509
|
+
if (count > 65536) {
|
|
1510
|
+
count = 65536;
|
|
1511
|
+
}
|
|
1512
|
+
}
|
|
1513
|
+
needed_credits = (count - 1) / 65536 + 1;
|
|
1514
|
+
|
|
1515
|
+
memset(&req, 0, sizeof(struct smb2_read_request));
|
|
1516
|
+
req.flags = 0;
|
|
1517
|
+
req.length = count;
|
|
1518
|
+
req.offset = offset;
|
|
1519
|
+
req.buf = buf;
|
|
1520
|
+
memcpy(req.file_id, fh->file_id, SMB2_FD_SIZE);
|
|
1521
|
+
req.minimum_count = 0;
|
|
1522
|
+
req.channel = SMB2_CHANNEL_NONE;
|
|
1523
|
+
req.remaining_bytes = 0;
|
|
1524
|
+
|
|
1525
|
+
pdu = smb2_cmd_read_async(smb2, &req, read_cb, rd);
|
|
1526
|
+
if (pdu == NULL) {
|
|
1527
|
+
smb2_set_error(smb2, "Failed to create read command");
|
|
1528
|
+
return -EINVAL;
|
|
1529
|
+
}
|
|
1530
|
+
|
|
1531
|
+
smb2_queue_pdu(smb2, pdu);
|
|
1532
|
+
|
|
1533
|
+
return 0;
|
|
1534
|
+
}
|
|
1535
|
+
|
|
1536
|
+
int
|
|
1537
|
+
smb2_read_async(struct smb2_context *smb2, struct smb2fh *fh,
|
|
1538
|
+
uint8_t *buf, uint32_t count,
|
|
1539
|
+
smb2_command_cb cb, void *cb_data)
|
|
1540
|
+
{
|
|
1541
|
+
if (smb2 == NULL) {
|
|
1542
|
+
return -EINVAL;
|
|
1543
|
+
}
|
|
1544
|
+
if (fh == NULL) {
|
|
1545
|
+
smb2_set_error(smb2, "File handle was NULL");
|
|
1546
|
+
return -EINVAL;
|
|
1547
|
+
}
|
|
1548
|
+
|
|
1549
|
+
return smb2_pread_async(smb2, fh, buf, count, fh->offset,
|
|
1550
|
+
cb, cb_data);
|
|
1551
|
+
}
|
|
1552
|
+
|
|
1553
|
+
struct write_data {
|
|
1554
|
+
smb2_command_cb cb;
|
|
1555
|
+
void *cb_data;
|
|
1556
|
+
|
|
1557
|
+
struct smb2_write_cb_data write_cb_data;
|
|
1558
|
+
};
|
|
1559
|
+
|
|
1560
|
+
static void
|
|
1561
|
+
write_cb(struct smb2_context *smb2, int status,
|
|
1562
|
+
void *command_data, void *private_data)
|
|
1563
|
+
{
|
|
1564
|
+
struct write_data *wd = private_data;
|
|
1565
|
+
struct smb2_write_reply *rep = command_data;
|
|
1566
|
+
|
|
1567
|
+
if (status && status != SMB2_STATUS_END_OF_FILE) {
|
|
1568
|
+
smb2_set_nterror(smb2, status, "Read/Write failed with (0x%08x) %s",
|
|
1569
|
+
status, nterror_to_str(status));
|
|
1570
|
+
wd->cb(smb2, -nterror_to_errno(status), &wd->write_cb_data, wd->cb_data);
|
|
1571
|
+
free(wd);
|
|
1572
|
+
return;
|
|
1573
|
+
}
|
|
1574
|
+
|
|
1575
|
+
if (status == SMB2_STATUS_SUCCESS) {
|
|
1576
|
+
wd->write_cb_data.fh->offset = wd->write_cb_data.offset + rep->count;
|
|
1577
|
+
}
|
|
1578
|
+
|
|
1579
|
+
wd->cb(smb2, rep->count, &wd->write_cb_data, wd->cb_data);
|
|
1580
|
+
free(wd);
|
|
1581
|
+
}
|
|
1582
|
+
|
|
1583
|
+
int
|
|
1584
|
+
smb2_pwrite_async(struct smb2_context *smb2, struct smb2fh *fh,
|
|
1585
|
+
const uint8_t *buf, uint32_t count, uint64_t offset,
|
|
1586
|
+
smb2_command_cb cb, void *cb_data)
|
|
1587
|
+
{
|
|
1588
|
+
struct smb2_write_request req;
|
|
1589
|
+
struct write_data *wr;
|
|
1590
|
+
struct smb2_pdu *pdu;
|
|
1591
|
+
int needed_credits;
|
|
1592
|
+
|
|
1593
|
+
if (smb2 == NULL) {
|
|
1594
|
+
return -EINVAL;
|
|
1595
|
+
}
|
|
1596
|
+
if (fh == NULL) {
|
|
1597
|
+
smb2_set_error(smb2, "File handle was NULL");
|
|
1598
|
+
return -EINVAL;
|
|
1599
|
+
}
|
|
1600
|
+
|
|
1601
|
+
wr = calloc(1, sizeof(struct write_data));
|
|
1602
|
+
if (wr == NULL) {
|
|
1603
|
+
smb2_set_error(smb2, "Failed to allocate write_data");
|
|
1604
|
+
return -ENOMEM;
|
|
1605
|
+
}
|
|
1606
|
+
|
|
1607
|
+
wr->cb = cb;
|
|
1608
|
+
wr->cb_data = cb_data;
|
|
1609
|
+
wr->write_cb_data.fh = fh;
|
|
1610
|
+
wr->write_cb_data.buf = buf;
|
|
1611
|
+
wr->write_cb_data.count = count;
|
|
1612
|
+
wr->write_cb_data.offset = offset;
|
|
1613
|
+
|
|
1614
|
+
if (count > smb2->max_write_size) {
|
|
1615
|
+
count = smb2->max_write_size;
|
|
1616
|
+
}
|
|
1617
|
+
needed_credits = (count - 1) / 65536 + 1;
|
|
1618
|
+
|
|
1619
|
+
if (smb2->dialect > SMB2_VERSION_0202) {
|
|
1620
|
+
if (needed_credits > MAX_CREDITS - 16) {
|
|
1621
|
+
count = (MAX_CREDITS - 16) * 65536;
|
|
1622
|
+
}
|
|
1623
|
+
needed_credits = (count - 1) / 65536 + 1;
|
|
1624
|
+
if (needed_credits > smb2->credits) {
|
|
1625
|
+
count = smb2->credits * 65536;
|
|
1626
|
+
}
|
|
1627
|
+
} else {
|
|
1628
|
+
if (count > 65536) {
|
|
1629
|
+
count = 65536;
|
|
1630
|
+
}
|
|
1631
|
+
}
|
|
1632
|
+
needed_credits = (count - 1) / 65536 + 1;
|
|
1633
|
+
|
|
1634
|
+
memset(&req, 0, sizeof(struct smb2_write_request));
|
|
1635
|
+
req.length = count;
|
|
1636
|
+
req.offset = offset;
|
|
1637
|
+
req.buf = buf;
|
|
1638
|
+
memcpy(req.file_id, fh->file_id, SMB2_FD_SIZE);
|
|
1639
|
+
req.channel = SMB2_CHANNEL_NONE;
|
|
1640
|
+
req.remaining_bytes = 0;
|
|
1641
|
+
req.flags = 0;
|
|
1642
|
+
|
|
1643
|
+
pdu = smb2_cmd_write_async(smb2, &req, 0, write_cb, wr);
|
|
1644
|
+
if (pdu == NULL) {
|
|
1645
|
+
smb2_set_error(smb2, "Failed to create write command");
|
|
1646
|
+
return -EINVAL;
|
|
1647
|
+
}
|
|
1648
|
+
smb2_queue_pdu(smb2, pdu);
|
|
1649
|
+
|
|
1650
|
+
return 0;
|
|
1651
|
+
}
|
|
1652
|
+
|
|
1653
|
+
int
|
|
1654
|
+
smb2_write_async(struct smb2_context *smb2, struct smb2fh *fh,
|
|
1655
|
+
const uint8_t *buf, uint32_t count,
|
|
1656
|
+
smb2_command_cb cb, void *cb_data)
|
|
1657
|
+
{
|
|
1658
|
+
if (smb2 == NULL) {
|
|
1659
|
+
return -EINVAL;
|
|
1660
|
+
}
|
|
1661
|
+
if (fh == NULL) {
|
|
1662
|
+
smb2_set_error(smb2, "File handle was NULL");
|
|
1663
|
+
return -EINVAL;
|
|
1664
|
+
}
|
|
1665
|
+
return smb2_pwrite_async(smb2, fh, buf, count, fh->offset,
|
|
1666
|
+
cb, cb_data);
|
|
1667
|
+
}
|
|
1668
|
+
|
|
1669
|
+
int64_t
|
|
1670
|
+
smb2_lseek(struct smb2_context *smb2, struct smb2fh *fh,
|
|
1671
|
+
int64_t offset, int whence, uint64_t *current_offset)
|
|
1672
|
+
{
|
|
1673
|
+
if (smb2 == NULL) {
|
|
1674
|
+
return -EINVAL;
|
|
1675
|
+
}
|
|
1676
|
+
if (fh == NULL) {
|
|
1677
|
+
smb2_set_error(smb2, "File handle was NULL");
|
|
1678
|
+
return -EINVAL;
|
|
1679
|
+
}
|
|
1680
|
+
|
|
1681
|
+
switch(whence) {
|
|
1682
|
+
case SEEK_SET:
|
|
1683
|
+
if (offset < 0) {
|
|
1684
|
+
smb2_set_error(smb2, "Lseek() offset would become"
|
|
1685
|
+
"negative");
|
|
1686
|
+
return -EINVAL;
|
|
1687
|
+
}
|
|
1688
|
+
fh->offset = offset;
|
|
1689
|
+
if (current_offset) {
|
|
1690
|
+
*current_offset = fh->offset;
|
|
1691
|
+
}
|
|
1692
|
+
return fh->offset;
|
|
1693
|
+
case SEEK_CUR:
|
|
1694
|
+
if (fh->offset + offset < 0) {
|
|
1695
|
+
smb2_set_error(smb2, "Lseek() offset would become"
|
|
1696
|
+
"negative");
|
|
1697
|
+
return -EINVAL;
|
|
1698
|
+
}
|
|
1699
|
+
fh->offset += offset;
|
|
1700
|
+
if (current_offset) {
|
|
1701
|
+
*current_offset = fh->offset;
|
|
1702
|
+
}
|
|
1703
|
+
return fh->offset;
|
|
1704
|
+
case SEEK_END:
|
|
1705
|
+
fh->offset = fh->end_of_file;
|
|
1706
|
+
if (fh->offset + offset < 0) {
|
|
1707
|
+
smb2_set_error(smb2, "Lseek() offset would become"
|
|
1708
|
+
"negative");
|
|
1709
|
+
return -EINVAL;
|
|
1710
|
+
}
|
|
1711
|
+
fh->offset += offset;
|
|
1712
|
+
if (current_offset) {
|
|
1713
|
+
*current_offset = fh->offset;
|
|
1714
|
+
}
|
|
1715
|
+
return fh->offset;
|
|
1716
|
+
default:
|
|
1717
|
+
smb2_set_error(smb2, "Invalid whence(%d) for lseek",
|
|
1718
|
+
whence);
|
|
1719
|
+
return -EINVAL;
|
|
1720
|
+
}
|
|
1721
|
+
}
|
|
1722
|
+
|
|
1723
|
+
struct create_cb_data {
|
|
1724
|
+
smb2_command_cb cb;
|
|
1725
|
+
void *cb_data;
|
|
1726
|
+
};
|
|
1727
|
+
|
|
1728
|
+
static void
|
|
1729
|
+
create_cb_2(struct smb2_context *smb2, int status,
|
|
1730
|
+
void *command_data, void *private_data)
|
|
1731
|
+
{
|
|
1732
|
+
struct create_cb_data *create_data = private_data;
|
|
1733
|
+
|
|
1734
|
+
if (status != SMB2_STATUS_SUCCESS) {
|
|
1735
|
+
status = -nterror_to_errno(status);
|
|
1736
|
+
}
|
|
1737
|
+
|
|
1738
|
+
create_data->cb(smb2, status, NULL, create_data->cb_data);
|
|
1739
|
+
free(create_data);
|
|
1740
|
+
}
|
|
1741
|
+
|
|
1742
|
+
static void
|
|
1743
|
+
create_cb_1(struct smb2_context *smb2, int status,
|
|
1744
|
+
void *command_data, void *private_data)
|
|
1745
|
+
{
|
|
1746
|
+
if (status != SMB2_STATUS_SUCCESS) {
|
|
1747
|
+
smb2_set_error(smb2, "Create failed with status %s.", nterror_to_str(status));
|
|
1748
|
+
return;
|
|
1749
|
+
}
|
|
1750
|
+
}
|
|
1751
|
+
|
|
1752
|
+
static int
|
|
1753
|
+
smb2_unlink_internal(struct smb2_context *smb2, const char *path,
|
|
1754
|
+
int is_dir,
|
|
1755
|
+
smb2_command_cb cb, void *cb_data)
|
|
1756
|
+
{
|
|
1757
|
+
struct create_cb_data *create_data;
|
|
1758
|
+
struct smb2_create_request cr_req;
|
|
1759
|
+
struct smb2_close_request cl_req;
|
|
1760
|
+
struct smb2_pdu *pdu, *next_pdu;
|
|
1761
|
+
|
|
1762
|
+
if (smb2 == NULL) {
|
|
1763
|
+
return -EINVAL;
|
|
1764
|
+
}
|
|
1765
|
+
|
|
1766
|
+
create_data = calloc(1, sizeof(struct create_cb_data));
|
|
1767
|
+
if (create_data == NULL) {
|
|
1768
|
+
smb2_set_error(smb2, "Failed to allocate create_data");
|
|
1769
|
+
return -ENOMEM;
|
|
1770
|
+
}
|
|
1771
|
+
|
|
1772
|
+
create_data->cb = cb;
|
|
1773
|
+
create_data->cb_data = cb_data;
|
|
1774
|
+
|
|
1775
|
+
|
|
1776
|
+
memset(&cr_req, 0, sizeof(struct smb2_create_request));
|
|
1777
|
+
cr_req.requested_oplock_level = SMB2_OPLOCK_LEVEL_NONE;
|
|
1778
|
+
cr_req.impersonation_level = SMB2_IMPERSONATION_IMPERSONATION;
|
|
1779
|
+
cr_req.desired_access = SMB2_DELETE;
|
|
1780
|
+
if (is_dir) {
|
|
1781
|
+
cr_req.file_attributes = SMB2_FILE_ATTRIBUTE_DIRECTORY;
|
|
1782
|
+
} else {
|
|
1783
|
+
cr_req.file_attributes = SMB2_FILE_ATTRIBUTE_NORMAL;
|
|
1784
|
+
}
|
|
1785
|
+
cr_req.share_access = SMB2_FILE_SHARE_READ | SMB2_FILE_SHARE_WRITE |
|
|
1786
|
+
SMB2_FILE_SHARE_DELETE;
|
|
1787
|
+
cr_req.create_disposition = SMB2_FILE_OPEN;
|
|
1788
|
+
cr_req.create_options = SMB2_FILE_DELETE_ON_CLOSE;
|
|
1789
|
+
cr_req.name = path;
|
|
1790
|
+
|
|
1791
|
+
pdu = smb2_cmd_create_async(smb2, &cr_req, create_cb_1, create_data);
|
|
1792
|
+
if (pdu == NULL) {
|
|
1793
|
+
smb2_set_error(smb2, "Failed to create create command");
|
|
1794
|
+
return -ENOMEM;
|
|
1795
|
+
}
|
|
1796
|
+
|
|
1797
|
+
memset(&cl_req, 0, sizeof(struct smb2_close_request));
|
|
1798
|
+
cl_req.flags = SMB2_CLOSE_FLAG_POSTQUERY_ATTRIB;
|
|
1799
|
+
memcpy(cl_req.file_id, compound_file_id, SMB2_FD_SIZE);
|
|
1800
|
+
|
|
1801
|
+
next_pdu = smb2_cmd_close_async(smb2, &cl_req, create_cb_2, create_data);
|
|
1802
|
+
if (next_pdu == NULL) {
|
|
1803
|
+
smb2_set_error(smb2, "Failed to create close command");
|
|
1804
|
+
smb2_free_pdu(smb2, pdu);
|
|
1805
|
+
free(create_data);
|
|
1806
|
+
return -ENOMEM;
|
|
1807
|
+
}
|
|
1808
|
+
smb2_add_compound_pdu(smb2, pdu, next_pdu);
|
|
1809
|
+
|
|
1810
|
+
smb2_queue_pdu(smb2, pdu);
|
|
1811
|
+
|
|
1812
|
+
return 0;
|
|
1813
|
+
}
|
|
1814
|
+
|
|
1815
|
+
int
|
|
1816
|
+
smb2_unlink_async(struct smb2_context *smb2, const char *path,
|
|
1817
|
+
smb2_command_cb cb, void *cb_data)
|
|
1818
|
+
{
|
|
1819
|
+
return smb2_unlink_internal(smb2, path, 0, cb, cb_data);
|
|
1820
|
+
}
|
|
1821
|
+
|
|
1822
|
+
int
|
|
1823
|
+
smb2_rmdir_async(struct smb2_context *smb2, const char *path,
|
|
1824
|
+
smb2_command_cb cb, void *cb_data)
|
|
1825
|
+
{
|
|
1826
|
+
return smb2_unlink_internal(smb2, path, 1, cb, cb_data);
|
|
1827
|
+
}
|
|
1828
|
+
|
|
1829
|
+
int
|
|
1830
|
+
smb2_mkdir_async(struct smb2_context *smb2, const char *path,
|
|
1831
|
+
smb2_command_cb cb, void *cb_data)
|
|
1832
|
+
{
|
|
1833
|
+
struct create_cb_data *create_data;
|
|
1834
|
+
struct smb2_create_request cr_req;
|
|
1835
|
+
struct smb2_close_request cl_req;
|
|
1836
|
+
struct smb2_pdu *pdu, *next_pdu;
|
|
1837
|
+
|
|
1838
|
+
if (smb2 == NULL) {
|
|
1839
|
+
return -EINVAL;
|
|
1840
|
+
}
|
|
1841
|
+
|
|
1842
|
+
create_data = calloc(1, sizeof(struct create_cb_data));
|
|
1843
|
+
if (create_data == NULL) {
|
|
1844
|
+
smb2_set_error(smb2, "Failed to allocate create_data");
|
|
1845
|
+
return -ENOMEM;
|
|
1846
|
+
}
|
|
1847
|
+
|
|
1848
|
+
create_data->cb = cb;
|
|
1849
|
+
create_data->cb_data = cb_data;
|
|
1850
|
+
|
|
1851
|
+
memset(&cr_req, 0, sizeof(struct smb2_create_request));
|
|
1852
|
+
cr_req.requested_oplock_level = SMB2_OPLOCK_LEVEL_NONE;
|
|
1853
|
+
cr_req.impersonation_level = SMB2_IMPERSONATION_IMPERSONATION;
|
|
1854
|
+
cr_req.desired_access = SMB2_FILE_READ_ATTRIBUTES;
|
|
1855
|
+
cr_req.file_attributes = SMB2_FILE_ATTRIBUTE_DIRECTORY;
|
|
1856
|
+
cr_req.share_access = SMB2_FILE_SHARE_READ | SMB2_FILE_SHARE_WRITE;
|
|
1857
|
+
cr_req.create_disposition = SMB2_FILE_CREATE;
|
|
1858
|
+
cr_req.create_options = SMB2_FILE_DIRECTORY_FILE;
|
|
1859
|
+
cr_req.name = path;
|
|
1860
|
+
|
|
1861
|
+
pdu = smb2_cmd_create_async(smb2, &cr_req, create_cb_1, create_data);
|
|
1862
|
+
if (pdu == NULL) {
|
|
1863
|
+
smb2_set_error(smb2, "Failed to create create command");
|
|
1864
|
+
return -ENOMEM;
|
|
1865
|
+
}
|
|
1866
|
+
|
|
1867
|
+
memset(&cl_req, 0, sizeof(struct smb2_close_request));
|
|
1868
|
+
cl_req.flags = SMB2_CLOSE_FLAG_POSTQUERY_ATTRIB;
|
|
1869
|
+
memcpy(cl_req.file_id, compound_file_id, SMB2_FD_SIZE);
|
|
1870
|
+
|
|
1871
|
+
next_pdu = smb2_cmd_close_async(smb2, &cl_req, create_cb_2, create_data);
|
|
1872
|
+
if (next_pdu == NULL) {
|
|
1873
|
+
smb2_set_error(smb2, "Failed to create close command");
|
|
1874
|
+
smb2_free_pdu(smb2, pdu);
|
|
1875
|
+
free(create_data);
|
|
1876
|
+
return -ENOMEM;
|
|
1877
|
+
}
|
|
1878
|
+
smb2_add_compound_pdu(smb2, pdu, next_pdu);
|
|
1879
|
+
|
|
1880
|
+
smb2_queue_pdu(smb2, pdu);
|
|
1881
|
+
|
|
1882
|
+
return 0;
|
|
1883
|
+
}
|
|
1884
|
+
|
|
1885
|
+
struct stat_cb_data {
|
|
1886
|
+
smb2_command_cb cb;
|
|
1887
|
+
void *cb_data;
|
|
1888
|
+
|
|
1889
|
+
uint32_t status;
|
|
1890
|
+
uint8_t info_type;
|
|
1891
|
+
uint8_t file_info_class;
|
|
1892
|
+
void *st;
|
|
1893
|
+
};
|
|
1894
|
+
|
|
1895
|
+
static void
|
|
1896
|
+
fstat_cb_1(struct smb2_context *smb2, int status,
|
|
1897
|
+
void *command_data, void *private_data)
|
|
1898
|
+
{
|
|
1899
|
+
struct stat_cb_data *stat_data = private_data;
|
|
1900
|
+
struct smb2_query_info_reply *rep = command_data;
|
|
1901
|
+
struct smb2_file_all_info *fs = rep->output_buffer;
|
|
1902
|
+
struct smb2_stat_64 *st = stat_data->st;
|
|
1903
|
+
|
|
1904
|
+
if (status != SMB2_STATUS_SUCCESS) {
|
|
1905
|
+
stat_data->cb(smb2, -nterror_to_errno(status),
|
|
1906
|
+
NULL, stat_data->cb_data);
|
|
1907
|
+
free(stat_data);
|
|
1908
|
+
return;
|
|
1909
|
+
}
|
|
1910
|
+
|
|
1911
|
+
st->smb2_type = SMB2_TYPE_FILE;
|
|
1912
|
+
if (fs->basic.file_attributes & SMB2_FILE_ATTRIBUTE_DIRECTORY) {
|
|
1913
|
+
st->smb2_type = SMB2_TYPE_DIRECTORY;
|
|
1914
|
+
}
|
|
1915
|
+
if (fs->basic.file_attributes & SMB2_FILE_ATTRIBUTE_REPARSE_POINT) {
|
|
1916
|
+
st->smb2_type = SMB2_TYPE_LINK;
|
|
1917
|
+
}
|
|
1918
|
+
st->smb2_nlink = fs->standard.number_of_links;
|
|
1919
|
+
st->smb2_ino = fs->index_number;
|
|
1920
|
+
st->smb2_size = fs->standard.end_of_file;
|
|
1921
|
+
st->smb2_atime = fs->basic.last_access_time.tv_sec;
|
|
1922
|
+
st->smb2_atime_nsec = fs->basic.last_access_time.tv_usec *
|
|
1923
|
+
1000;
|
|
1924
|
+
st->smb2_mtime = fs->basic.last_write_time.tv_sec;
|
|
1925
|
+
st->smb2_mtime_nsec = fs->basic.last_write_time.tv_usec *
|
|
1926
|
+
1000;
|
|
1927
|
+
st->smb2_ctime = fs->basic.change_time.tv_sec;
|
|
1928
|
+
st->smb2_ctime_nsec = fs->basic.change_time.tv_usec *
|
|
1929
|
+
1000;
|
|
1930
|
+
st->smb2_btime = fs->basic.creation_time.tv_sec;
|
|
1931
|
+
st->smb2_btime_nsec = fs->basic.creation_time.tv_usec *
|
|
1932
|
+
1000;
|
|
1933
|
+
|
|
1934
|
+
smb2_free_data(smb2, fs);
|
|
1935
|
+
|
|
1936
|
+
stat_data->cb(smb2, 0, st, stat_data->cb_data);
|
|
1937
|
+
free(stat_data);
|
|
1938
|
+
}
|
|
1939
|
+
|
|
1940
|
+
int
|
|
1941
|
+
smb2_fstat_async(struct smb2_context *smb2, struct smb2fh *fh,
|
|
1942
|
+
struct smb2_stat_64 *st,
|
|
1943
|
+
smb2_command_cb cb, void *cb_data)
|
|
1944
|
+
{
|
|
1945
|
+
struct stat_cb_data *stat_data;
|
|
1946
|
+
struct smb2_query_info_request req;
|
|
1947
|
+
struct smb2_pdu *pdu;
|
|
1948
|
+
|
|
1949
|
+
if (smb2 == NULL) {
|
|
1950
|
+
return -EINVAL;
|
|
1951
|
+
}
|
|
1952
|
+
if (fh == NULL) {
|
|
1953
|
+
smb2_set_error(smb2, "File handle was NULL");
|
|
1954
|
+
return -EINVAL;
|
|
1955
|
+
}
|
|
1956
|
+
|
|
1957
|
+
stat_data = calloc(1, sizeof(struct stat_cb_data));
|
|
1958
|
+
if (stat_data == NULL) {
|
|
1959
|
+
smb2_set_error(smb2, "Failed to allocate stat_data");
|
|
1960
|
+
return -ENOMEM;
|
|
1961
|
+
}
|
|
1962
|
+
|
|
1963
|
+
stat_data->cb = cb;
|
|
1964
|
+
stat_data->cb_data = cb_data;
|
|
1965
|
+
stat_data->st = st;
|
|
1966
|
+
|
|
1967
|
+
memset(&req, 0, sizeof(struct smb2_query_info_request));
|
|
1968
|
+
req.info_type = SMB2_0_INFO_FILE;
|
|
1969
|
+
req.file_info_class = SMB2_FILE_ALL_INFORMATION;
|
|
1970
|
+
req.output_buffer_length = DEFAULT_OUTPUT_BUFFER_LENGTH;
|
|
1971
|
+
req.additional_information = 0;
|
|
1972
|
+
req.flags = 0;
|
|
1973
|
+
memcpy(req.file_id, fh->file_id, SMB2_FD_SIZE);
|
|
1974
|
+
|
|
1975
|
+
pdu = smb2_cmd_query_info_async(smb2, &req, fstat_cb_1, stat_data);
|
|
1976
|
+
if (pdu == NULL) {
|
|
1977
|
+
smb2_set_error(smb2, "Failed to create query command");
|
|
1978
|
+
free(stat_data);
|
|
1979
|
+
return -ENOMEM;
|
|
1980
|
+
}
|
|
1981
|
+
smb2_queue_pdu(smb2, pdu);
|
|
1982
|
+
|
|
1983
|
+
return 0;
|
|
1984
|
+
}
|
|
1985
|
+
|
|
1986
|
+
static void
|
|
1987
|
+
getinfo_cb_3(struct smb2_context *smb2, int status,
|
|
1988
|
+
void *command_data _U_, void *private_data)
|
|
1989
|
+
{
|
|
1990
|
+
struct stat_cb_data *stat_data = private_data;
|
|
1991
|
+
|
|
1992
|
+
if (stat_data->status == SMB2_STATUS_SUCCESS) {
|
|
1993
|
+
stat_data->status = status;
|
|
1994
|
+
}
|
|
1995
|
+
|
|
1996
|
+
stat_data->cb(smb2, -nterror_to_errno(stat_data->status),
|
|
1997
|
+
stat_data->st, stat_data->cb_data);
|
|
1998
|
+
free(stat_data);
|
|
1999
|
+
}
|
|
2000
|
+
|
|
2001
|
+
static void
|
|
2002
|
+
getinfo_cb_2(struct smb2_context *smb2, int status,
|
|
2003
|
+
void *command_data, void *private_data)
|
|
2004
|
+
{
|
|
2005
|
+
struct stat_cb_data *stat_data = private_data;
|
|
2006
|
+
struct smb2_query_info_reply *rep = command_data;
|
|
2007
|
+
|
|
2008
|
+
if (stat_data->status == SMB2_STATUS_SUCCESS) {
|
|
2009
|
+
stat_data->status = status;
|
|
2010
|
+
}
|
|
2011
|
+
if (stat_data->status != SMB2_STATUS_SUCCESS) {
|
|
2012
|
+
return;
|
|
2013
|
+
}
|
|
2014
|
+
|
|
2015
|
+
if (stat_data->info_type == SMB2_0_INFO_FILE &&
|
|
2016
|
+
stat_data->file_info_class == SMB2_FILE_ALL_INFORMATION) {
|
|
2017
|
+
struct smb2_stat_64 *st = stat_data->st;
|
|
2018
|
+
struct smb2_file_all_info *fs = rep->output_buffer;
|
|
2019
|
+
|
|
2020
|
+
st->smb2_type = SMB2_TYPE_FILE;
|
|
2021
|
+
if (fs->basic.file_attributes & SMB2_FILE_ATTRIBUTE_DIRECTORY) {
|
|
2022
|
+
st->smb2_type = SMB2_TYPE_DIRECTORY;
|
|
2023
|
+
}
|
|
2024
|
+
if (fs->basic.file_attributes & SMB2_FILE_ATTRIBUTE_REPARSE_POINT) {
|
|
2025
|
+
st->smb2_type = SMB2_TYPE_LINK;
|
|
2026
|
+
}
|
|
2027
|
+
st->smb2_nlink = fs->standard.number_of_links;
|
|
2028
|
+
st->smb2_ino = fs->index_number;
|
|
2029
|
+
st->smb2_size = fs->standard.end_of_file;
|
|
2030
|
+
st->smb2_atime = fs->basic.last_access_time.tv_sec;
|
|
2031
|
+
st->smb2_atime_nsec = fs->basic.last_access_time.tv_usec *
|
|
2032
|
+
1000;
|
|
2033
|
+
st->smb2_mtime = fs->basic.last_write_time.tv_sec;
|
|
2034
|
+
st->smb2_mtime_nsec = fs->basic.last_write_time.tv_usec *
|
|
2035
|
+
1000;
|
|
2036
|
+
st->smb2_ctime = fs->basic.change_time.tv_sec;
|
|
2037
|
+
st->smb2_ctime_nsec = fs->basic.change_time.tv_usec *
|
|
2038
|
+
1000;
|
|
2039
|
+
st->smb2_btime = fs->basic.creation_time.tv_sec;
|
|
2040
|
+
st->smb2_btime_nsec = fs->basic.creation_time.tv_usec *
|
|
2041
|
+
1000;
|
|
2042
|
+
} else if (stat_data->info_type == SMB2_0_INFO_FILESYSTEM &&
|
|
2043
|
+
stat_data->file_info_class == SMB2_FILE_FS_FULL_SIZE_INFORMATION) {
|
|
2044
|
+
struct smb2_statvfs *statvfs = stat_data->st;
|
|
2045
|
+
struct smb2_file_fs_full_size_info *vfs = rep->output_buffer;
|
|
2046
|
+
|
|
2047
|
+
memset(statvfs, 0, sizeof(struct smb2_statvfs));
|
|
2048
|
+
statvfs->f_bsize = statvfs->f_frsize =
|
|
2049
|
+
vfs->bytes_per_sector *
|
|
2050
|
+
vfs->sectors_per_allocation_unit;
|
|
2051
|
+
statvfs->f_blocks = vfs->total_allocation_units;
|
|
2052
|
+
statvfs->f_bfree = statvfs->f_bavail =
|
|
2053
|
+
vfs->caller_available_allocation_units;
|
|
2054
|
+
}
|
|
2055
|
+
smb2_free_data(smb2, rep->output_buffer);
|
|
2056
|
+
}
|
|
2057
|
+
|
|
2058
|
+
static void
|
|
2059
|
+
getinfo_cb_1(struct smb2_context *smb2, int status,
|
|
2060
|
+
void *command_data _U_, void *private_data)
|
|
2061
|
+
{
|
|
2062
|
+
struct stat_cb_data *stat_data = private_data;
|
|
2063
|
+
|
|
2064
|
+
if (stat_data->status == SMB2_STATUS_SUCCESS) {
|
|
2065
|
+
stat_data->status = status;
|
|
2066
|
+
}
|
|
2067
|
+
}
|
|
2068
|
+
|
|
2069
|
+
static int
|
|
2070
|
+
smb2_getinfo_async(struct smb2_context *smb2, const char *path,
|
|
2071
|
+
uint8_t info_type, uint8_t file_info_class,
|
|
2072
|
+
void *st,
|
|
2073
|
+
smb2_command_cb cb, void *cb_data)
|
|
2074
|
+
{
|
|
2075
|
+
struct stat_cb_data *stat_data;
|
|
2076
|
+
struct smb2_create_request cr_req;
|
|
2077
|
+
struct smb2_query_info_request qi_req;
|
|
2078
|
+
struct smb2_close_request cl_req;
|
|
2079
|
+
struct smb2_pdu *pdu, *next_pdu;
|
|
2080
|
+
|
|
2081
|
+
if (smb2 == NULL) {
|
|
2082
|
+
return -EINVAL;
|
|
2083
|
+
}
|
|
2084
|
+
|
|
2085
|
+
stat_data = calloc(1, sizeof(struct stat_cb_data));
|
|
2086
|
+
if (stat_data == NULL) {
|
|
2087
|
+
smb2_set_error(smb2, "Failed to allocate create_data");
|
|
2088
|
+
return -1;
|
|
2089
|
+
}
|
|
2090
|
+
|
|
2091
|
+
stat_data->cb = cb;
|
|
2092
|
+
stat_data->cb_data = cb_data;
|
|
2093
|
+
stat_data->info_type = info_type;
|
|
2094
|
+
stat_data->file_info_class = file_info_class;
|
|
2095
|
+
stat_data->st = st;
|
|
2096
|
+
|
|
2097
|
+
/* CREATE command */
|
|
2098
|
+
memset(&cr_req, 0, sizeof(struct smb2_create_request));
|
|
2099
|
+
cr_req.requested_oplock_level = SMB2_OPLOCK_LEVEL_NONE;
|
|
2100
|
+
cr_req.impersonation_level = SMB2_IMPERSONATION_IMPERSONATION;
|
|
2101
|
+
cr_req.desired_access = SMB2_FILE_READ_ATTRIBUTES | SMB2_FILE_READ_EA;
|
|
2102
|
+
cr_req.file_attributes = 0;
|
|
2103
|
+
cr_req.share_access = SMB2_FILE_SHARE_READ | SMB2_FILE_SHARE_WRITE;
|
|
2104
|
+
cr_req.create_disposition = SMB2_FILE_OPEN;
|
|
2105
|
+
cr_req.create_options = 0;
|
|
2106
|
+
cr_req.name = path;
|
|
2107
|
+
|
|
2108
|
+
pdu = smb2_cmd_create_async(smb2, &cr_req, getinfo_cb_1, stat_data);
|
|
2109
|
+
if (pdu == NULL) {
|
|
2110
|
+
smb2_set_error(smb2, "Failed to create create command");
|
|
2111
|
+
free(stat_data);
|
|
2112
|
+
return -1;
|
|
2113
|
+
}
|
|
2114
|
+
|
|
2115
|
+
/* QUERY INFO command */
|
|
2116
|
+
memset(&qi_req, 0, sizeof(struct smb2_query_info_request));
|
|
2117
|
+
qi_req.info_type = info_type;
|
|
2118
|
+
qi_req.file_info_class = file_info_class;
|
|
2119
|
+
qi_req.output_buffer_length = DEFAULT_OUTPUT_BUFFER_LENGTH;
|
|
2120
|
+
qi_req.additional_information = 0;
|
|
2121
|
+
qi_req.flags = 0;
|
|
2122
|
+
memcpy(qi_req.file_id, compound_file_id, SMB2_FD_SIZE);
|
|
2123
|
+
|
|
2124
|
+
next_pdu = smb2_cmd_query_info_async(smb2, &qi_req,
|
|
2125
|
+
getinfo_cb_2, stat_data);
|
|
2126
|
+
if (next_pdu == NULL) {
|
|
2127
|
+
smb2_set_error(smb2, "Failed to create query command");
|
|
2128
|
+
free(stat_data);
|
|
2129
|
+
smb2_free_pdu(smb2, pdu);
|
|
2130
|
+
return -1;
|
|
2131
|
+
}
|
|
2132
|
+
smb2_add_compound_pdu(smb2, pdu, next_pdu);
|
|
2133
|
+
|
|
2134
|
+
/* CLOSE command */
|
|
2135
|
+
memset(&cl_req, 0, sizeof(struct smb2_close_request));
|
|
2136
|
+
cl_req.flags = SMB2_CLOSE_FLAG_POSTQUERY_ATTRIB;
|
|
2137
|
+
memcpy(cl_req.file_id, compound_file_id, SMB2_FD_SIZE);
|
|
2138
|
+
|
|
2139
|
+
next_pdu = smb2_cmd_close_async(smb2, &cl_req, getinfo_cb_3, stat_data);
|
|
2140
|
+
if (next_pdu == NULL) {
|
|
2141
|
+
stat_data->cb(smb2, -ENOMEM, NULL, stat_data->cb_data);
|
|
2142
|
+
free(stat_data);
|
|
2143
|
+
smb2_free_pdu(smb2, pdu);
|
|
2144
|
+
return -1;
|
|
2145
|
+
}
|
|
2146
|
+
smb2_add_compound_pdu(smb2, pdu, next_pdu);
|
|
2147
|
+
|
|
2148
|
+
smb2_queue_pdu(smb2, pdu);
|
|
2149
|
+
|
|
2150
|
+
return 0;
|
|
2151
|
+
}
|
|
2152
|
+
|
|
2153
|
+
int
|
|
2154
|
+
smb2_stat_async(struct smb2_context *smb2, const char *path,
|
|
2155
|
+
struct smb2_stat_64 *st,
|
|
2156
|
+
smb2_command_cb cb, void *cb_data)
|
|
2157
|
+
{
|
|
2158
|
+
return smb2_getinfo_async(smb2, path,
|
|
2159
|
+
SMB2_0_INFO_FILE,
|
|
2160
|
+
SMB2_FILE_ALL_INFORMATION,
|
|
2161
|
+
st, cb, cb_data);
|
|
2162
|
+
}
|
|
2163
|
+
|
|
2164
|
+
int
|
|
2165
|
+
smb2_statvfs_async(struct smb2_context *smb2, const char *path,
|
|
2166
|
+
struct smb2_statvfs *statvfs,
|
|
2167
|
+
smb2_command_cb cb, void *cb_data)
|
|
2168
|
+
{
|
|
2169
|
+
return smb2_getinfo_async(smb2, path,
|
|
2170
|
+
SMB2_0_INFO_FILESYSTEM,
|
|
2171
|
+
SMB2_FILE_FS_FULL_SIZE_INFORMATION,
|
|
2172
|
+
statvfs, cb, cb_data);
|
|
2173
|
+
}
|
|
2174
|
+
|
|
2175
|
+
struct trunc_cb_data {
|
|
2176
|
+
smb2_command_cb cb;
|
|
2177
|
+
void *cb_data;
|
|
2178
|
+
|
|
2179
|
+
uint32_t status;
|
|
2180
|
+
uint64_t length;
|
|
2181
|
+
};
|
|
2182
|
+
|
|
2183
|
+
static void
|
|
2184
|
+
trunc_cb_3(struct smb2_context *smb2, int status,
|
|
2185
|
+
void *command_data _U_, void *private_data)
|
|
2186
|
+
{
|
|
2187
|
+
struct trunc_cb_data *trunc_data = private_data;
|
|
2188
|
+
|
|
2189
|
+
if (trunc_data->status == SMB2_STATUS_SUCCESS) {
|
|
2190
|
+
trunc_data->status = status;
|
|
2191
|
+
}
|
|
2192
|
+
|
|
2193
|
+
trunc_data->cb(smb2, -nterror_to_errno(trunc_data->status),
|
|
2194
|
+
NULL, trunc_data->cb_data);
|
|
2195
|
+
free(trunc_data);
|
|
2196
|
+
}
|
|
2197
|
+
|
|
2198
|
+
static void
|
|
2199
|
+
trunc_cb_2(struct smb2_context *smb2, int status,
|
|
2200
|
+
void *command_data, void *private_data)
|
|
2201
|
+
{
|
|
2202
|
+
struct trunc_cb_data *trunc_data = private_data;
|
|
2203
|
+
|
|
2204
|
+
if (trunc_data->status == SMB2_STATUS_SUCCESS) {
|
|
2205
|
+
trunc_data->status = status;
|
|
2206
|
+
}
|
|
2207
|
+
}
|
|
2208
|
+
|
|
2209
|
+
static void
|
|
2210
|
+
trunc_cb_1(struct smb2_context *smb2, int status,
|
|
2211
|
+
void *command_data _U_, void *private_data)
|
|
2212
|
+
{
|
|
2213
|
+
struct trunc_cb_data *trunc_data = private_data;
|
|
2214
|
+
|
|
2215
|
+
if (trunc_data->status == SMB2_STATUS_SUCCESS) {
|
|
2216
|
+
trunc_data->status = status;
|
|
2217
|
+
}
|
|
2218
|
+
}
|
|
2219
|
+
|
|
2220
|
+
int
|
|
2221
|
+
smb2_truncate_async(struct smb2_context *smb2, const char *path,
|
|
2222
|
+
uint64_t length, smb2_command_cb cb, void *cb_data)
|
|
2223
|
+
{
|
|
2224
|
+
struct trunc_cb_data *trunc_data;
|
|
2225
|
+
struct smb2_create_request cr_req;
|
|
2226
|
+
struct smb2_set_info_request si_req;
|
|
2227
|
+
struct smb2_close_request cl_req;
|
|
2228
|
+
struct smb2_pdu *pdu, *next_pdu;
|
|
2229
|
+
struct smb2_file_end_of_file_info eofi _U_;
|
|
2230
|
+
|
|
2231
|
+
if (smb2 == NULL) {
|
|
2232
|
+
return -EINVAL;
|
|
2233
|
+
}
|
|
2234
|
+
|
|
2235
|
+
trunc_data = calloc(1, sizeof(struct trunc_cb_data));
|
|
2236
|
+
if (trunc_data == NULL) {
|
|
2237
|
+
smb2_set_error(smb2, "Failed to allocate trunc_data");
|
|
2238
|
+
return -ENOMEM;
|
|
2239
|
+
}
|
|
2240
|
+
|
|
2241
|
+
trunc_data->cb = cb;
|
|
2242
|
+
trunc_data->cb_data = cb_data;
|
|
2243
|
+
trunc_data->length = length;
|
|
2244
|
+
|
|
2245
|
+
/* CREATE command */
|
|
2246
|
+
memset(&cr_req, 0, sizeof(struct smb2_create_request));
|
|
2247
|
+
cr_req.requested_oplock_level = SMB2_OPLOCK_LEVEL_NONE;
|
|
2248
|
+
cr_req.impersonation_level = SMB2_IMPERSONATION_IMPERSONATION;
|
|
2249
|
+
cr_req.desired_access = SMB2_GENERIC_WRITE;
|
|
2250
|
+
cr_req.file_attributes = 0;
|
|
2251
|
+
cr_req.share_access = SMB2_FILE_SHARE_READ | SMB2_FILE_SHARE_WRITE;
|
|
2252
|
+
cr_req.create_disposition = SMB2_FILE_OPEN;
|
|
2253
|
+
cr_req.create_options = 0;
|
|
2254
|
+
cr_req.name = path;
|
|
2255
|
+
|
|
2256
|
+
pdu = smb2_cmd_create_async(smb2, &cr_req, trunc_cb_1, trunc_data);
|
|
2257
|
+
if (pdu == NULL) {
|
|
2258
|
+
smb2_set_error(smb2, "Failed to create create command");
|
|
2259
|
+
free(trunc_data);
|
|
2260
|
+
return -EINVAL;
|
|
2261
|
+
}
|
|
2262
|
+
|
|
2263
|
+
/* SET INFO command */
|
|
2264
|
+
eofi.end_of_file = length;
|
|
2265
|
+
|
|
2266
|
+
memset(&si_req, 0, sizeof(struct smb2_set_info_request));
|
|
2267
|
+
si_req.info_type = SMB2_0_INFO_FILE;
|
|
2268
|
+
si_req.file_info_class = SMB2_FILE_END_OF_FILE_INFORMATION;
|
|
2269
|
+
si_req.additional_information = 0;
|
|
2270
|
+
memcpy(si_req.file_id, compound_file_id, SMB2_FD_SIZE);
|
|
2271
|
+
si_req.input_data = &eofi;
|
|
2272
|
+
|
|
2273
|
+
next_pdu = smb2_cmd_set_info_async(smb2, &si_req,
|
|
2274
|
+
trunc_cb_2, trunc_data);
|
|
2275
|
+
if (next_pdu == NULL) {
|
|
2276
|
+
smb2_set_error(smb2, "Failed to create set command. %s",
|
|
2277
|
+
smb2_get_error(smb2));
|
|
2278
|
+
free(trunc_data);
|
|
2279
|
+
smb2_free_pdu(smb2, pdu);
|
|
2280
|
+
return -EINVAL;
|
|
2281
|
+
}
|
|
2282
|
+
smb2_add_compound_pdu(smb2, pdu, next_pdu);
|
|
2283
|
+
|
|
2284
|
+
/* CLOSE command */
|
|
2285
|
+
memset(&cl_req, 0, sizeof(struct smb2_close_request));
|
|
2286
|
+
cl_req.flags = SMB2_CLOSE_FLAG_POSTQUERY_ATTRIB;
|
|
2287
|
+
memcpy(cl_req.file_id, compound_file_id, SMB2_FD_SIZE);
|
|
2288
|
+
|
|
2289
|
+
next_pdu = smb2_cmd_close_async(smb2, &cl_req, trunc_cb_3, trunc_data);
|
|
2290
|
+
if (next_pdu == NULL) {
|
|
2291
|
+
trunc_data->cb(smb2, -ENOMEM, NULL, trunc_data->cb_data);
|
|
2292
|
+
free(trunc_data);
|
|
2293
|
+
smb2_free_pdu(smb2, pdu);
|
|
2294
|
+
return -EINVAL;
|
|
2295
|
+
}
|
|
2296
|
+
smb2_add_compound_pdu(smb2, pdu, next_pdu);
|
|
2297
|
+
|
|
2298
|
+
smb2_queue_pdu(smb2, pdu);
|
|
2299
|
+
|
|
2300
|
+
return 0;
|
|
2301
|
+
}
|
|
2302
|
+
|
|
2303
|
+
struct rename_cb_data {
|
|
2304
|
+
uint8_t *newpath;
|
|
2305
|
+
smb2_command_cb cb;
|
|
2306
|
+
void *cb_data;
|
|
2307
|
+
uint32_t status;
|
|
2308
|
+
};
|
|
2309
|
+
|
|
2310
|
+
static void free_rename_data(struct rename_cb_data *rename_data)
|
|
2311
|
+
{
|
|
2312
|
+
free(rename_data->newpath);
|
|
2313
|
+
free(rename_data);
|
|
2314
|
+
}
|
|
2315
|
+
|
|
2316
|
+
static void
|
|
2317
|
+
rename_cb_3(struct smb2_context *smb2, int status,
|
|
2318
|
+
void *command_data _U_, void *private_data)
|
|
2319
|
+
{
|
|
2320
|
+
struct rename_cb_data *rename_data = private_data;
|
|
2321
|
+
|
|
2322
|
+
if (rename_data->status == SMB2_STATUS_SUCCESS) {
|
|
2323
|
+
rename_data->status = status;
|
|
2324
|
+
}
|
|
2325
|
+
|
|
2326
|
+
rename_data->cb(smb2, -nterror_to_errno(rename_data->status),
|
|
2327
|
+
NULL, rename_data->cb_data);
|
|
2328
|
+
free_rename_data(rename_data);
|
|
2329
|
+
}
|
|
2330
|
+
|
|
2331
|
+
static void
|
|
2332
|
+
rename_cb_2(struct smb2_context *smb2, int status,
|
|
2333
|
+
void *command_data _U_, void *private_data)
|
|
2334
|
+
{
|
|
2335
|
+
struct rename_cb_data *rename_data = private_data;
|
|
2336
|
+
|
|
2337
|
+
if (rename_data->status == SMB2_STATUS_SUCCESS) {
|
|
2338
|
+
rename_data->status = status;
|
|
2339
|
+
}
|
|
2340
|
+
}
|
|
2341
|
+
|
|
2342
|
+
static void
|
|
2343
|
+
rename_cb_1(struct smb2_context *smb2, int status,
|
|
2344
|
+
void *command_data _U_, void *private_data)
|
|
2345
|
+
{
|
|
2346
|
+
struct rename_cb_data *rename_data = private_data;
|
|
2347
|
+
|
|
2348
|
+
if (rename_data->status == SMB2_STATUS_SUCCESS) {
|
|
2349
|
+
rename_data->status = status;
|
|
2350
|
+
}
|
|
2351
|
+
}
|
|
2352
|
+
|
|
2353
|
+
int
|
|
2354
|
+
smb2_rename_async(struct smb2_context *smb2, const char *oldpath,
|
|
2355
|
+
const char *newpath, smb2_command_cb cb, void *cb_data)
|
|
2356
|
+
{
|
|
2357
|
+
struct rename_cb_data *rename_data;
|
|
2358
|
+
struct smb2_create_request cr_req;
|
|
2359
|
+
struct smb2_set_info_request si_req;
|
|
2360
|
+
struct smb2_close_request cl_req;
|
|
2361
|
+
struct smb2_pdu *pdu, *next_pdu;
|
|
2362
|
+
struct smb2_file_rename_info rn_info _U_;
|
|
2363
|
+
uint8_t *ptr;
|
|
2364
|
+
|
|
2365
|
+
if (smb2 == NULL) {
|
|
2366
|
+
return -EINVAL;
|
|
2367
|
+
}
|
|
2368
|
+
|
|
2369
|
+
rename_data = calloc(1, sizeof(struct rename_cb_data));
|
|
2370
|
+
if (rename_data == NULL) {
|
|
2371
|
+
smb2_set_error(smb2, "Failed to allocate rename_data");
|
|
2372
|
+
return -ENOMEM;
|
|
2373
|
+
}
|
|
2374
|
+
|
|
2375
|
+
rename_data->cb = cb;
|
|
2376
|
+
rename_data->cb_data = cb_data;
|
|
2377
|
+
rename_data->newpath = (uint8_t *)strdup(newpath);
|
|
2378
|
+
if (rename_data->newpath == NULL) {
|
|
2379
|
+
free_rename_data(rename_data);
|
|
2380
|
+
smb2_set_error(smb2, "Failed to allocate rename_data->newpath");
|
|
2381
|
+
return -ENOMEM;
|
|
2382
|
+
}
|
|
2383
|
+
for (ptr = rename_data->newpath; *ptr; ptr++) {
|
|
2384
|
+
if (*ptr == '/') {
|
|
2385
|
+
*ptr = '\\';
|
|
2386
|
+
}
|
|
2387
|
+
}
|
|
2388
|
+
|
|
2389
|
+
/* CREATE command */
|
|
2390
|
+
memset(&cr_req, 0, sizeof(struct smb2_create_request));
|
|
2391
|
+
cr_req.requested_oplock_level = SMB2_OPLOCK_LEVEL_NONE;
|
|
2392
|
+
cr_req.impersonation_level = SMB2_IMPERSONATION_IMPERSONATION;
|
|
2393
|
+
cr_req.desired_access = SMB2_GENERIC_READ | SMB2_FILE_READ_ATTRIBUTES | SMB2_DELETE;
|
|
2394
|
+
cr_req.file_attributes = 0;
|
|
2395
|
+
cr_req.share_access = SMB2_FILE_SHARE_READ | SMB2_FILE_SHARE_WRITE | SMB2_FILE_SHARE_DELETE;
|
|
2396
|
+
cr_req.create_disposition = SMB2_FILE_OPEN;
|
|
2397
|
+
cr_req.create_options = 0;
|
|
2398
|
+
cr_req.name = oldpath;
|
|
2399
|
+
|
|
2400
|
+
pdu = smb2_cmd_create_async(smb2, &cr_req, rename_cb_1, rename_data);
|
|
2401
|
+
if (pdu == NULL) {
|
|
2402
|
+
smb2_set_error(smb2, "Failed to create create command");
|
|
2403
|
+
free_rename_data(rename_data);
|
|
2404
|
+
return -EINVAL;
|
|
2405
|
+
}
|
|
2406
|
+
|
|
2407
|
+
/* SET INFO command */
|
|
2408
|
+
rn_info.replace_if_exist = 0;
|
|
2409
|
+
rn_info.file_name = rename_data->newpath;
|
|
2410
|
+
|
|
2411
|
+
memset(&si_req, 0, sizeof(struct smb2_set_info_request));
|
|
2412
|
+
si_req.info_type = SMB2_0_INFO_FILE;
|
|
2413
|
+
si_req.file_info_class = SMB2_FILE_RENAME_INFORMATION;
|
|
2414
|
+
si_req.additional_information = 0;
|
|
2415
|
+
memcpy(si_req.file_id, compound_file_id, SMB2_FD_SIZE);
|
|
2416
|
+
si_req.input_data = &rn_info;
|
|
2417
|
+
|
|
2418
|
+
next_pdu = smb2_cmd_set_info_async(smb2, &si_req,
|
|
2419
|
+
rename_cb_2, rename_data);
|
|
2420
|
+
if (next_pdu == NULL) {
|
|
2421
|
+
smb2_set_error(smb2, "Failed to create set command. %s",
|
|
2422
|
+
smb2_get_error(smb2));
|
|
2423
|
+
free_rename_data(rename_data);
|
|
2424
|
+
smb2_free_pdu(smb2, pdu);
|
|
2425
|
+
return -EINVAL;
|
|
2426
|
+
}
|
|
2427
|
+
smb2_add_compound_pdu(smb2, pdu, next_pdu);
|
|
2428
|
+
|
|
2429
|
+
/* CLOSE command */
|
|
2430
|
+
memset(&cl_req, 0, sizeof(struct smb2_close_request));
|
|
2431
|
+
cl_req.flags = SMB2_CLOSE_FLAG_POSTQUERY_ATTRIB;
|
|
2432
|
+
memcpy(cl_req.file_id, compound_file_id, SMB2_FD_SIZE);
|
|
2433
|
+
|
|
2434
|
+
next_pdu = smb2_cmd_close_async(smb2, &cl_req, rename_cb_3, rename_data);
|
|
2435
|
+
if (next_pdu == NULL) {
|
|
2436
|
+
rename_data->cb(smb2, -ENOMEM, NULL, rename_data->cb_data);
|
|
2437
|
+
free_rename_data(rename_data);
|
|
2438
|
+
smb2_free_pdu(smb2, pdu);
|
|
2439
|
+
return -EINVAL;
|
|
2440
|
+
}
|
|
2441
|
+
smb2_add_compound_pdu(smb2, pdu, next_pdu);
|
|
2442
|
+
|
|
2443
|
+
smb2_queue_pdu(smb2, pdu);
|
|
2444
|
+
|
|
2445
|
+
return 0;
|
|
2446
|
+
}
|
|
2447
|
+
|
|
2448
|
+
static void
|
|
2449
|
+
ftrunc_cb_1(struct smb2_context *smb2, int status,
|
|
2450
|
+
void *command_data _U_, void *private_data)
|
|
2451
|
+
{
|
|
2452
|
+
struct create_cb_data *cb_data = private_data;
|
|
2453
|
+
|
|
2454
|
+
cb_data->cb(smb2, -nterror_to_errno(status),
|
|
2455
|
+
NULL, cb_data->cb_data);
|
|
2456
|
+
free(cb_data);
|
|
2457
|
+
}
|
|
2458
|
+
|
|
2459
|
+
int
|
|
2460
|
+
smb2_ftruncate_async(struct smb2_context *smb2, struct smb2fh *fh,
|
|
2461
|
+
uint64_t length, smb2_command_cb cb, void *cb_data)
|
|
2462
|
+
{
|
|
2463
|
+
struct create_cb_data *create_data;
|
|
2464
|
+
struct smb2_set_info_request req;
|
|
2465
|
+
struct smb2_file_end_of_file_info eofi _U_;
|
|
2466
|
+
struct smb2_pdu *pdu;
|
|
2467
|
+
|
|
2468
|
+
if (smb2 == NULL) {
|
|
2469
|
+
return -EINVAL;
|
|
2470
|
+
}
|
|
2471
|
+
if (fh == NULL) {
|
|
2472
|
+
smb2_set_error(smb2, "File handle was NULL");
|
|
2473
|
+
return -EINVAL;
|
|
2474
|
+
}
|
|
2475
|
+
|
|
2476
|
+
create_data = calloc(1, sizeof(struct create_cb_data));
|
|
2477
|
+
if (create_data == NULL) {
|
|
2478
|
+
smb2_set_error(smb2, "Failed to allocate create_data");
|
|
2479
|
+
return -ENOMEM;
|
|
2480
|
+
}
|
|
2481
|
+
|
|
2482
|
+
create_data->cb = cb;
|
|
2483
|
+
create_data->cb_data = cb_data;
|
|
2484
|
+
|
|
2485
|
+
eofi.end_of_file = length;
|
|
2486
|
+
|
|
2487
|
+
memset(&req, 0, sizeof(struct smb2_set_info_request));
|
|
2488
|
+
req.info_type = SMB2_0_INFO_FILE;
|
|
2489
|
+
req.file_info_class = SMB2_FILE_END_OF_FILE_INFORMATION;
|
|
2490
|
+
req.additional_information = 0;
|
|
2491
|
+
memcpy(req.file_id, fh->file_id, SMB2_FD_SIZE);
|
|
2492
|
+
req.input_data = &eofi;
|
|
2493
|
+
|
|
2494
|
+
pdu = smb2_cmd_set_info_async(smb2, &req, ftrunc_cb_1, create_data);
|
|
2495
|
+
if (pdu == NULL) {
|
|
2496
|
+
smb2_set_error(smb2, "Failed to create set info command");
|
|
2497
|
+
return -ENOMEM;
|
|
2498
|
+
}
|
|
2499
|
+
smb2_queue_pdu(smb2, pdu);
|
|
2500
|
+
|
|
2501
|
+
return 0;
|
|
2502
|
+
}
|
|
2503
|
+
|
|
2504
|
+
struct readlink_cb_data {
|
|
2505
|
+
smb2_command_cb cb;
|
|
2506
|
+
void *cb_data;
|
|
2507
|
+
|
|
2508
|
+
uint32_t status;
|
|
2509
|
+
struct smb2_reparse_data_buffer *reparse;
|
|
2510
|
+
};
|
|
2511
|
+
|
|
2512
|
+
static void
|
|
2513
|
+
readlink_cb_3(struct smb2_context *smb2, int status,
|
|
2514
|
+
void *command_data _U_, void *private_data)
|
|
2515
|
+
{
|
|
2516
|
+
struct readlink_cb_data *cb_data = private_data;
|
|
2517
|
+
struct smb2_reparse_data_buffer *rp = cb_data->reparse;
|
|
2518
|
+
char *target = (char*)"<unknown reparse point type>";
|
|
2519
|
+
|
|
2520
|
+
if (rp) {
|
|
2521
|
+
switch (rp->reparse_tag) {
|
|
2522
|
+
case SMB2_REPARSE_TAG_SYMLINK:
|
|
2523
|
+
target = rp->symlink.subname;
|
|
2524
|
+
}
|
|
2525
|
+
}
|
|
2526
|
+
cb_data->cb(smb2, -nterror_to_errno(cb_data->status),
|
|
2527
|
+
target, cb_data->cb_data);
|
|
2528
|
+
smb2_free_data(smb2, rp);
|
|
2529
|
+
free(cb_data);
|
|
2530
|
+
}
|
|
2531
|
+
|
|
2532
|
+
static void
|
|
2533
|
+
readlink_cb_2(struct smb2_context *smb2, int status,
|
|
2534
|
+
void *command_data, void *private_data)
|
|
2535
|
+
{
|
|
2536
|
+
struct readlink_cb_data *cb_data = private_data;
|
|
2537
|
+
struct smb2_ioctl_reply *rep = command_data;
|
|
2538
|
+
|
|
2539
|
+
if (cb_data->status == SMB2_STATUS_SUCCESS) {
|
|
2540
|
+
cb_data->status = status;
|
|
2541
|
+
}
|
|
2542
|
+
if (status == SMB2_STATUS_NOT_A_REPARSE_POINT) {
|
|
2543
|
+
smb2_set_error(smb2, "Not a reparse point");
|
|
2544
|
+
}
|
|
2545
|
+
if (status == SMB2_STATUS_SUCCESS) {
|
|
2546
|
+
cb_data->reparse = rep->output;
|
|
2547
|
+
}
|
|
2548
|
+
}
|
|
2549
|
+
|
|
2550
|
+
static void
|
|
2551
|
+
readlink_cb_1(struct smb2_context *smb2, int status,
|
|
2552
|
+
void *command_data _U_, void *private_data)
|
|
2553
|
+
{
|
|
2554
|
+
struct readlink_cb_data *cb_data = private_data;
|
|
2555
|
+
|
|
2556
|
+
if (status != SMB2_STATUS_SUCCESS) {
|
|
2557
|
+
smb2_set_nterror(smb2, status, "%s", nterror_to_str(status));
|
|
2558
|
+
}
|
|
2559
|
+
cb_data->status = status;
|
|
2560
|
+
}
|
|
2561
|
+
|
|
2562
|
+
int
|
|
2563
|
+
smb2_readlink_async(struct smb2_context *smb2, const char *path,
|
|
2564
|
+
smb2_command_cb cb, void *cb_data)
|
|
2565
|
+
{
|
|
2566
|
+
struct readlink_cb_data *readlink_data;
|
|
2567
|
+
struct smb2_create_request cr_req;
|
|
2568
|
+
struct smb2_ioctl_request io_req;
|
|
2569
|
+
struct smb2_close_request cl_req;
|
|
2570
|
+
struct smb2_pdu *pdu, *next_pdu;
|
|
2571
|
+
|
|
2572
|
+
if (smb2 == NULL) {
|
|
2573
|
+
return -EINVAL;
|
|
2574
|
+
}
|
|
2575
|
+
|
|
2576
|
+
readlink_data = calloc(1, sizeof(struct readlink_cb_data));
|
|
2577
|
+
if (readlink_data == NULL) {
|
|
2578
|
+
smb2_set_error(smb2, "Failed to allocate readlink_data");
|
|
2579
|
+
return -ENOMEM;
|
|
2580
|
+
}
|
|
2581
|
+
|
|
2582
|
+
readlink_data->cb = cb;
|
|
2583
|
+
readlink_data->cb_data = cb_data;
|
|
2584
|
+
|
|
2585
|
+
/* CREATE command */
|
|
2586
|
+
memset(&cr_req, 0, sizeof(struct smb2_create_request));
|
|
2587
|
+
cr_req.requested_oplock_level = SMB2_OPLOCK_LEVEL_NONE;
|
|
2588
|
+
cr_req.impersonation_level = SMB2_IMPERSONATION_IMPERSONATION;
|
|
2589
|
+
cr_req.desired_access = SMB2_FILE_READ_ATTRIBUTES;
|
|
2590
|
+
cr_req.file_attributes = 0;
|
|
2591
|
+
cr_req.share_access = SMB2_FILE_SHARE_READ | SMB2_FILE_SHARE_WRITE |
|
|
2592
|
+
SMB2_FILE_SHARE_DELETE;
|
|
2593
|
+
cr_req.create_disposition = SMB2_FILE_OPEN;
|
|
2594
|
+
cr_req.create_options = SMB2_FILE_OPEN_REPARSE_POINT;
|
|
2595
|
+
cr_req.name = path;
|
|
2596
|
+
|
|
2597
|
+
pdu = smb2_cmd_create_async(smb2, &cr_req, readlink_cb_1, readlink_data);
|
|
2598
|
+
if (pdu == NULL) {
|
|
2599
|
+
smb2_set_error(smb2, "Failed to create create command");
|
|
2600
|
+
free(readlink_data);
|
|
2601
|
+
return -EINVAL;
|
|
2602
|
+
}
|
|
2603
|
+
|
|
2604
|
+
/* IOCTL command */
|
|
2605
|
+
memset(&io_req, 0, sizeof(struct smb2_ioctl_request));
|
|
2606
|
+
io_req.ctl_code = SMB2_FSCTL_GET_REPARSE_POINT;
|
|
2607
|
+
memcpy(io_req.file_id, compound_file_id, SMB2_FD_SIZE);
|
|
2608
|
+
io_req.input_count = 0;
|
|
2609
|
+
io_req.input = NULL;
|
|
2610
|
+
io_req.flags = SMB2_0_IOCTL_IS_FSCTL;
|
|
2611
|
+
|
|
2612
|
+
next_pdu = smb2_cmd_ioctl_async(smb2, &io_req, readlink_cb_2,
|
|
2613
|
+
readlink_data);
|
|
2614
|
+
if (next_pdu == NULL) {
|
|
2615
|
+
free(readlink_data);
|
|
2616
|
+
smb2_free_pdu(smb2, pdu);
|
|
2617
|
+
return -EINVAL;
|
|
2618
|
+
}
|
|
2619
|
+
smb2_add_compound_pdu(smb2, pdu, next_pdu);
|
|
2620
|
+
|
|
2621
|
+
/* CLOSE command */
|
|
2622
|
+
memset(&cl_req, 0, sizeof(struct smb2_close_request));
|
|
2623
|
+
cl_req.flags = SMB2_CLOSE_FLAG_POSTQUERY_ATTRIB;
|
|
2624
|
+
memcpy(cl_req.file_id, compound_file_id, SMB2_FD_SIZE);
|
|
2625
|
+
|
|
2626
|
+
next_pdu = smb2_cmd_close_async(smb2, &cl_req, readlink_cb_3,
|
|
2627
|
+
readlink_data);
|
|
2628
|
+
if (next_pdu == NULL) {
|
|
2629
|
+
free(readlink_data);
|
|
2630
|
+
smb2_free_pdu(smb2, pdu);
|
|
2631
|
+
return -EINVAL;
|
|
2632
|
+
}
|
|
2633
|
+
smb2_add_compound_pdu(smb2, pdu, next_pdu);
|
|
2634
|
+
|
|
2635
|
+
smb2_queue_pdu(smb2, pdu);
|
|
2636
|
+
|
|
2637
|
+
return 0;
|
|
2638
|
+
}
|
|
2639
|
+
|
|
2640
|
+
struct disconnect_data {
|
|
2641
|
+
smb2_command_cb cb;
|
|
2642
|
+
void *cb_data;
|
|
2643
|
+
};
|
|
2644
|
+
|
|
2645
|
+
static void
|
|
2646
|
+
disconnect_cb_2(struct smb2_context *smb2, int status,
|
|
2647
|
+
void *command_data _U_, void *private_data)
|
|
2648
|
+
{
|
|
2649
|
+
struct disconnect_data *dc_data = private_data;
|
|
2650
|
+
|
|
2651
|
+
dc_data->cb(smb2, 0, NULL, dc_data->cb_data);
|
|
2652
|
+
free(dc_data);
|
|
2653
|
+
if (smb2->change_fd) {
|
|
2654
|
+
smb2->change_fd(smb2, smb2->fd, SMB2_DEL_FD);
|
|
2655
|
+
}
|
|
2656
|
+
close(smb2->fd);
|
|
2657
|
+
smb2->fd = SMB2_INVALID_SOCKET;
|
|
2658
|
+
}
|
|
2659
|
+
|
|
2660
|
+
static void
|
|
2661
|
+
disconnect_cb_1(struct smb2_context *smb2, int status,
|
|
2662
|
+
void *command_data _U_, void *private_data)
|
|
2663
|
+
{
|
|
2664
|
+
struct disconnect_data *dc_data = private_data;
|
|
2665
|
+
struct smb2_pdu *pdu;
|
|
2666
|
+
|
|
2667
|
+
if (status != SMB2_STATUS_SUCCESS) {
|
|
2668
|
+
smb2_set_nterror(smb2, status, "%s", nterror_to_str(status));
|
|
2669
|
+
dc_data->cb(smb2, -ENOMEM, NULL, dc_data->cb_data);
|
|
2670
|
+
free(dc_data);
|
|
2671
|
+
return;
|
|
2672
|
+
}
|
|
2673
|
+
pdu = smb2_cmd_logoff_async(smb2, disconnect_cb_2, dc_data);
|
|
2674
|
+
if (pdu == NULL) {
|
|
2675
|
+
dc_data->cb(smb2, -ENOMEM, NULL, dc_data->cb_data);
|
|
2676
|
+
free(dc_data);
|
|
2677
|
+
return;
|
|
2678
|
+
}
|
|
2679
|
+
smb2_queue_pdu(smb2, pdu);
|
|
2680
|
+
}
|
|
2681
|
+
|
|
2682
|
+
int
|
|
2683
|
+
smb2_disconnect_share_async(struct smb2_context *smb2,
|
|
2684
|
+
smb2_command_cb cb, void *cb_data)
|
|
2685
|
+
{
|
|
2686
|
+
struct disconnect_data *dc_data;
|
|
2687
|
+
struct smb2_pdu *pdu;
|
|
2688
|
+
|
|
2689
|
+
if (smb2 == NULL) {
|
|
2690
|
+
return -EINVAL;
|
|
2691
|
+
}
|
|
2692
|
+
|
|
2693
|
+
if (!SMB2_VALID_SOCKET(smb2->fd)) {
|
|
2694
|
+
smb2_set_error(smb2, "connection is alreeady disconnected or was never connected");
|
|
2695
|
+
return -EINVAL;
|
|
2696
|
+
}
|
|
2697
|
+
|
|
2698
|
+
dc_data = calloc(1, sizeof(struct disconnect_data));
|
|
2699
|
+
if (dc_data == NULL) {
|
|
2700
|
+
smb2_set_error(smb2, "Failed to allocate disconnect_data");
|
|
2701
|
+
return -ENOMEM;
|
|
2702
|
+
}
|
|
2703
|
+
|
|
2704
|
+
dc_data->cb = cb;
|
|
2705
|
+
dc_data->cb_data = cb_data;
|
|
2706
|
+
|
|
2707
|
+
pdu = smb2_cmd_tree_disconnect_async(smb2, disconnect_cb_1, dc_data);
|
|
2708
|
+
if (pdu == NULL) {
|
|
2709
|
+
free(dc_data);
|
|
2710
|
+
return -ENOMEM;
|
|
2711
|
+
}
|
|
2712
|
+
smb2_queue_pdu(smb2, pdu);
|
|
2713
|
+
|
|
2714
|
+
return 0;
|
|
2715
|
+
}
|
|
2716
|
+
|
|
2717
|
+
struct smb2_echo_data {
|
|
2718
|
+
smb2_command_cb cb;
|
|
2719
|
+
void *cb_data;
|
|
2720
|
+
};
|
|
2721
|
+
|
|
2722
|
+
static void
|
|
2723
|
+
echo_cb(struct smb2_context *smb2, int status,
|
|
2724
|
+
void *command_data _U_, void *private_data)
|
|
2725
|
+
{
|
|
2726
|
+
struct smb2_echo_data *cb_data = private_data;
|
|
2727
|
+
|
|
2728
|
+
cb_data->cb(smb2, -nterror_to_errno(status),
|
|
2729
|
+
NULL, cb_data->cb_data);
|
|
2730
|
+
free(cb_data);
|
|
2731
|
+
}
|
|
2732
|
+
|
|
2733
|
+
int
|
|
2734
|
+
smb2_echo_async(struct smb2_context *smb2,
|
|
2735
|
+
smb2_command_cb cb, void *cb_data)
|
|
2736
|
+
{
|
|
2737
|
+
struct smb2_echo_data *echo_data;
|
|
2738
|
+
struct smb2_pdu *pdu;
|
|
2739
|
+
|
|
2740
|
+
if (smb2 == NULL) {
|
|
2741
|
+
return -EINVAL;
|
|
2742
|
+
}
|
|
2743
|
+
|
|
2744
|
+
echo_data = calloc(1, sizeof(struct smb2_echo_data));
|
|
2745
|
+
if (echo_data == NULL) {
|
|
2746
|
+
smb2_set_error(smb2, "Failed to allocate echo_data");
|
|
2747
|
+
return -ENOMEM;
|
|
2748
|
+
}
|
|
2749
|
+
|
|
2750
|
+
echo_data->cb = cb;
|
|
2751
|
+
echo_data->cb_data = cb_data;
|
|
2752
|
+
|
|
2753
|
+
pdu = smb2_cmd_echo_async(smb2, echo_cb, echo_data);
|
|
2754
|
+
if (pdu == NULL) {
|
|
2755
|
+
free(echo_data);
|
|
2756
|
+
return -ENOMEM;
|
|
2757
|
+
}
|
|
2758
|
+
smb2_queue_pdu(smb2, pdu);
|
|
2759
|
+
|
|
2760
|
+
return 0;
|
|
2761
|
+
}
|
|
2762
|
+
|
|
2763
|
+
uint32_t
|
|
2764
|
+
smb2_get_max_read_size(struct smb2_context *smb2)
|
|
2765
|
+
{
|
|
2766
|
+
return smb2->max_read_size;
|
|
2767
|
+
}
|
|
2768
|
+
|
|
2769
|
+
uint32_t
|
|
2770
|
+
smb2_get_max_write_size(struct smb2_context *smb2)
|
|
2771
|
+
{
|
|
2772
|
+
return smb2->max_write_size;
|
|
2773
|
+
}
|
|
2774
|
+
|
|
2775
|
+
smb2_file_id *
|
|
2776
|
+
smb2_get_file_id(struct smb2fh *fh)
|
|
2777
|
+
{
|
|
2778
|
+
return &fh->file_id;
|
|
2779
|
+
}
|
|
2780
|
+
|
|
2781
|
+
struct smb2fh *
|
|
2782
|
+
smb2_fh_from_file_id(struct smb2_context *smb2, smb2_file_id *fileid)
|
|
2783
|
+
{
|
|
2784
|
+
struct smb2fh *fh;
|
|
2785
|
+
|
|
2786
|
+
fh = calloc(1, sizeof(struct smb2fh));
|
|
2787
|
+
if (fh == NULL) {
|
|
2788
|
+
return NULL;
|
|
2789
|
+
}
|
|
2790
|
+
memcpy(fh->file_id, fileid, SMB2_FD_SIZE);
|
|
2791
|
+
|
|
2792
|
+
return fh;
|
|
2793
|
+
}
|
|
2794
|
+
|
|
2795
|
+
void
|
|
2796
|
+
smb2_fd_event_callbacks(struct smb2_context *smb2,
|
|
2797
|
+
smb2_change_fd_cb change_fd,
|
|
2798
|
+
smb2_change_events_cb change_events)
|
|
2799
|
+
{
|
|
2800
|
+
smb2->change_fd = change_fd;
|
|
2801
|
+
smb2->change_events = change_events;
|
|
2802
|
+
}
|
|
2803
|
+
|
|
2804
|
+
void
|
|
2805
|
+
smb2_oplock_break_notify(struct smb2_context *smb2, int status, void *command_data, void *cb_data)
|
|
2806
|
+
{
|
|
2807
|
+
struct smb2_oplock_or_lease_break_reply *rep;
|
|
2808
|
+
struct smb2_oplock_break_reply rep_oplock;
|
|
2809
|
+
struct smb2_lease_break_reply rep_lease;
|
|
2810
|
+
struct smb2_pdu *pdu = NULL;
|
|
2811
|
+
uint8_t new_oplock_level;
|
|
2812
|
+
uint32_t new_lease_state;
|
|
2813
|
+
|
|
2814
|
+
rep= command_data;
|
|
2815
|
+
|
|
2816
|
+
|
|
2817
|
+
if (smb2->oplock_or_lease_break_cb) {
|
|
2818
|
+
smb2->oplock_or_lease_break_cb(smb2,
|
|
2819
|
+
status, rep, &new_oplock_level, &new_lease_state);
|
|
2820
|
+
}
|
|
2821
|
+
/* for passthrough case assume the app callback will do everything needed
|
|
2822
|
+
*/
|
|
2823
|
+
if (!smb2->passthrough) {
|
|
2824
|
+
if (status) {
|
|
2825
|
+
return;
|
|
2826
|
+
} else switch (rep->break_type) {
|
|
2827
|
+
case SMB2_BREAK_TYPE_OPLOCK_NOTIFICATION:
|
|
2828
|
+
memset(&rep_oplock, 0, sizeof(rep_oplock));
|
|
2829
|
+
rep_oplock.oplock_level = new_oplock_level;
|
|
2830
|
+
memcpy(rep_oplock.file_id, rep->lock.oplock.file_id, SMB2_FD_SIZE);
|
|
2831
|
+
pdu = smb2_cmd_oplock_break_reply_async(smb2, &rep_oplock, NULL, cb_data);
|
|
2832
|
+
break;
|
|
2833
|
+
case SMB2_BREAK_TYPE_OPLOCK_RESPONSE:
|
|
2834
|
+
break;
|
|
2835
|
+
case SMB2_BREAK_TYPE_LEASE_NOTIFICATION:
|
|
2836
|
+
memset(&rep_lease, 0, sizeof(rep_oplock));
|
|
2837
|
+
rep_lease.flags = rep->lock.lease.flags;
|
|
2838
|
+
rep_lease.lease_state = new_lease_state;
|
|
2839
|
+
memcpy(rep_lease.lease_key, rep->lock.lease.lease_key, SMB2_LEASE_KEY_SIZE);
|
|
2840
|
+
pdu = smb2_cmd_lease_break_reply_async(smb2, &rep_lease, NULL, cb_data);
|
|
2841
|
+
break;
|
|
2842
|
+
case SMB2_BREAK_TYPE_LEASE_RESPONSE:
|
|
2843
|
+
break;
|
|
2844
|
+
default:
|
|
2845
|
+
smb2_set_error(smb2, "Bad oplock/lease break request %s",
|
|
2846
|
+
smb2_get_error(smb2));
|
|
2847
|
+
return;
|
|
2848
|
+
}
|
|
2849
|
+
if (pdu != NULL) {
|
|
2850
|
+
smb2_queue_pdu(smb2, pdu);
|
|
2851
|
+
}
|
|
2852
|
+
}
|
|
2853
|
+
}
|
|
2854
|
+
|
|
2855
|
+
int
|
|
2856
|
+
smb2_decode_filenotifychangeinformation(
|
|
2857
|
+
struct smb2_context *smb2,
|
|
2858
|
+
struct smb2_file_notify_change_information *fnc,
|
|
2859
|
+
struct smb2_iovec *vec,
|
|
2860
|
+
uint32_t next_entry_offset)
|
|
2861
|
+
{
|
|
2862
|
+
uint32_t name_len, tmp;
|
|
2863
|
+
|
|
2864
|
+
if (next_entry_offset + 12 > vec->len) {
|
|
2865
|
+
return 0;
|
|
2866
|
+
}
|
|
2867
|
+
smb2_get_uint32(vec, next_entry_offset+4, &fnc->action);
|
|
2868
|
+
smb2_get_uint32(vec, next_entry_offset+8, &name_len);
|
|
2869
|
+
fnc->name = smb2_utf16_to_utf8((uint16_t *)(void *)&vec->buf[next_entry_offset+12], name_len / 2);
|
|
2870
|
+
|
|
2871
|
+
smb2_get_uint32(vec, next_entry_offset, &tmp);
|
|
2872
|
+
next_entry_offset += tmp;
|
|
2873
|
+
if (tmp != 0) {
|
|
2874
|
+
struct smb2_file_notify_change_information *next_fnc = calloc(1, sizeof(struct smb2_file_notify_change_information));
|
|
2875
|
+
fnc->next = next_fnc;
|
|
2876
|
+
smb2_decode_filenotifychangeinformation(smb2, next_fnc, vec, next_entry_offset);
|
|
2877
|
+
}
|
|
2878
|
+
return 0;
|
|
2879
|
+
}
|
|
2880
|
+
|
|
2881
|
+
void
|
|
2882
|
+
free_smb2_file_notify_change_information(struct smb2_context *smb2, struct smb2_file_notify_change_information *fnc)
|
|
2883
|
+
{
|
|
2884
|
+
if (fnc->next) {
|
|
2885
|
+
free_smb2_file_notify_change_information(smb2, fnc->next);
|
|
2886
|
+
}
|
|
2887
|
+
free(discard_const(fnc->name));
|
|
2888
|
+
free(fnc);
|
|
2889
|
+
}
|
|
2890
|
+
|
|
2891
|
+
struct notify_change_cb_data {
|
|
2892
|
+
smb2_command_cb cb;
|
|
2893
|
+
void *cb_data;
|
|
2894
|
+
// smb2fh file handle of the directory to get notified
|
|
2895
|
+
struct smb2fh *fh;
|
|
2896
|
+
// filter of SMB2_CHANGE_NOTIFY_FILE_NOTIFY_CHANGE_* flags
|
|
2897
|
+
uint16_t filter;
|
|
2898
|
+
// flags such as SMB2_CHANGE_NOTIFY_WATCH_TREE
|
|
2899
|
+
uint32_t flags;
|
|
2900
|
+
// do a new notify_change request after each response if 1
|
|
2901
|
+
uint32_t loop;
|
|
2902
|
+
uint32_t status;
|
|
2903
|
+
};
|
|
2904
|
+
|
|
2905
|
+
static void
|
|
2906
|
+
notify_change_cb(struct smb2_context *smb2, int status,
|
|
2907
|
+
void *command_data _U_, void *private_data)
|
|
2908
|
+
{
|
|
2909
|
+
struct notify_change_cb_data *notify_change_data = private_data;
|
|
2910
|
+
|
|
2911
|
+
struct smb2_change_notify_reply *rep = command_data;
|
|
2912
|
+
struct smb2_iovec vec;
|
|
2913
|
+
struct smb2_file_notify_change_information *fnc = calloc(1, sizeof(struct smb2_file_notify_change_information));
|
|
2914
|
+
|
|
2915
|
+
if (status) {
|
|
2916
|
+
smb2_set_error(smb2, "notify_change_cb failed (%s) %s\n",
|
|
2917
|
+
strerror(-status), smb2_get_error(smb2));
|
|
2918
|
+
}
|
|
2919
|
+
|
|
2920
|
+
if (status || rep == NULL) {
|
|
2921
|
+
/* Error or cancellation -- e.g. smb2_destroy_context() flushing the pending
|
|
2922
|
+
* watch request with command_data == NULL. There is no reply to decode, so
|
|
2923
|
+
* signal the failure to the callback, do not re-arm, and free. Without this
|
|
2924
|
+
* the unconditional rep->output dereference below SEGVs whenever a watcher
|
|
2925
|
+
* is torn down with a notify request still outstanding. */
|
|
2926
|
+
if (notify_change_data->cb) {
|
|
2927
|
+
notify_change_data->cb(smb2, status ? status : -EIO,
|
|
2928
|
+
NULL, notify_change_data->cb_data);
|
|
2929
|
+
}
|
|
2930
|
+
free(fnc);
|
|
2931
|
+
free(notify_change_data);
|
|
2932
|
+
return;
|
|
2933
|
+
}
|
|
2934
|
+
|
|
2935
|
+
vec.buf = rep->output;
|
|
2936
|
+
vec.len = rep->output_buffer_length;
|
|
2937
|
+
|
|
2938
|
+
if (smb2_decode_filenotifychangeinformation(smb2, fnc, &vec, 0)) {
|
|
2939
|
+
smb2_set_error(smb2, "Failed to decode file notify change information\n");
|
|
2940
|
+
}
|
|
2941
|
+
|
|
2942
|
+
if (notify_change_data->cb) {
|
|
2943
|
+
notify_change_data->cb(
|
|
2944
|
+
smb2,
|
|
2945
|
+
-nterror_to_errno(notify_change_data->status),
|
|
2946
|
+
fnc,
|
|
2947
|
+
notify_change_data->cb_data
|
|
2948
|
+
);
|
|
2949
|
+
}
|
|
2950
|
+
if (notify_change_data->loop) {
|
|
2951
|
+
smb2_notify_change_filehandle_async(smb2, notify_change_data->fh, notify_change_data->flags, notify_change_data->filter,
|
|
2952
|
+
notify_change_data->loop, notify_change_data->cb, notify_change_data->cb_data);
|
|
2953
|
+
} else {
|
|
2954
|
+
smb2_close(smb2, notify_change_data->fh);
|
|
2955
|
+
}
|
|
2956
|
+
free(notify_change_data);
|
|
2957
|
+
}
|
|
2958
|
+
|
|
2959
|
+
int smb2_notify_change_filehandle_async(struct smb2_context *smb2, struct smb2fh *smb2_dir_fh, uint16_t flags, uint32_t filter, int loop,
|
|
2960
|
+
smb2_command_cb cb, void *cb_data)
|
|
2961
|
+
{
|
|
2962
|
+
struct notify_change_cb_data *notify_change_cb_data;
|
|
2963
|
+
struct smb2_change_notify_request ch_req;
|
|
2964
|
+
struct smb2_pdu *pdu;
|
|
2965
|
+
|
|
2966
|
+
notify_change_cb_data = calloc(1, sizeof(struct notify_change_cb_data));
|
|
2967
|
+
if (notify_change_cb_data == NULL) {
|
|
2968
|
+
smb2_set_error(smb2, "Failed to allocate notify_change_data");
|
|
2969
|
+
return -1;
|
|
2970
|
+
}
|
|
2971
|
+
memset(notify_change_cb_data, 0, sizeof(struct notify_change_cb_data));
|
|
2972
|
+
notify_change_cb_data->cb = cb;
|
|
2973
|
+
notify_change_cb_data->cb_data = cb_data;
|
|
2974
|
+
notify_change_cb_data->fh = smb2_dir_fh;
|
|
2975
|
+
|
|
2976
|
+
notify_change_cb_data->flags = flags;
|
|
2977
|
+
notify_change_cb_data->filter = filter;
|
|
2978
|
+
notify_change_cb_data->loop = loop;
|
|
2979
|
+
|
|
2980
|
+
/* CHANGE NOTIFY command */
|
|
2981
|
+
memset(&ch_req, 0, sizeof(struct smb2_change_notify_request));
|
|
2982
|
+
ch_req.flags = flags;
|
|
2983
|
+
ch_req.output_buffer_length = DEFAULT_OUTPUT_BUFFER_LENGTH;
|
|
2984
|
+
const smb2_file_id *file_id = smb2_get_file_id(smb2_dir_fh);
|
|
2985
|
+
memcpy(ch_req.file_id, file_id, SMB2_FD_SIZE);
|
|
2986
|
+
ch_req.completion_filter = filter;
|
|
2987
|
+
|
|
2988
|
+
pdu = smb2_cmd_change_notify_async(smb2, &ch_req,
|
|
2989
|
+
notify_change_cb, notify_change_cb_data);
|
|
2990
|
+
if (pdu == NULL) {
|
|
2991
|
+
smb2_set_error(smb2, "Failed to create change_notify command\n");
|
|
2992
|
+
free(notify_change_cb_data);
|
|
2993
|
+
return -1;
|
|
2994
|
+
}
|
|
2995
|
+
smb2_queue_pdu(smb2, pdu);
|
|
2996
|
+
|
|
2997
|
+
return 0;
|
|
2998
|
+
}
|
|
2999
|
+
|
|
3000
|
+
int smb2_notify_change_async(struct smb2_context *smb2, const char *path, uint16_t flags, uint32_t filter, int loop,
|
|
3001
|
+
smb2_command_cb cb, void *cb_data)
|
|
3002
|
+
{
|
|
3003
|
+
struct smb2fh *fh;
|
|
3004
|
+
#ifdef O_DIRECTORY
|
|
3005
|
+
fh = smb2_open(smb2, path, O_DIRECTORY);
|
|
3006
|
+
#else
|
|
3007
|
+
fh = smb2_open(smb2, path, 0);
|
|
3008
|
+
#endif
|
|
3009
|
+
if (fh == NULL) {
|
|
3010
|
+
smb2_set_error(smb2, "smb2_open failed. %s\n", smb2_get_error(smb2));
|
|
3011
|
+
return -1;
|
|
3012
|
+
}
|
|
3013
|
+
return smb2_notify_change_filehandle_async(smb2, fh, flags, filter, loop, cb, cb_data);
|
|
3014
|
+
|
|
3015
|
+
}
|
|
3016
|
+
|
|
3017
|
+
/*************************** server handlers *************************************************************/
|
|
3018
|
+
static void
|
|
3019
|
+
smb2_logoff_request_cb(struct smb2_server *server, struct smb2_context *smb2, void *command_data, void *cb_data)
|
|
3020
|
+
{
|
|
3021
|
+
struct smb2_pdu *pdu = NULL;
|
|
3022
|
+
struct smb2_error_reply err;
|
|
3023
|
+
int ret = -EINVAL;
|
|
3024
|
+
|
|
3025
|
+
if (server->handlers && server->handlers->logoff_cmd) {
|
|
3026
|
+
ret = server->handlers->logoff_cmd(server, smb2);
|
|
3027
|
+
}
|
|
3028
|
+
if (!ret) {
|
|
3029
|
+
pdu = smb2_cmd_logoff_reply_async(smb2, NULL, cb_data);
|
|
3030
|
+
}
|
|
3031
|
+
else if (ret < 0) {
|
|
3032
|
+
memset(&err, 0, sizeof(err));
|
|
3033
|
+
pdu = smb2_cmd_error_reply_async(smb2,
|
|
3034
|
+
&err, SMB2_LOGOFF, SMB2_STATUS_NOT_IMPLEMENTED, NULL, cb_data);
|
|
3035
|
+
}
|
|
3036
|
+
if (pdu != NULL) {
|
|
3037
|
+
smb2_set_pdu_message_id(smb2, pdu, smb2->message_id);
|
|
3038
|
+
smb2_queue_pdu(smb2, pdu);
|
|
3039
|
+
}
|
|
3040
|
+
}
|
|
3041
|
+
|
|
3042
|
+
static void
|
|
3043
|
+
smb2_tree_connect_request_cb(struct smb2_server *server, struct smb2_context *smb2, void *command_data, void *cb_data)
|
|
3044
|
+
{
|
|
3045
|
+
struct smb2_tree_connect_request *req = command_data;
|
|
3046
|
+
struct smb2_tree_connect_reply rep;
|
|
3047
|
+
struct smb2_error_reply err;
|
|
3048
|
+
struct smb2_pdu *pdu = NULL;
|
|
3049
|
+
int ret = -1;
|
|
3050
|
+
|
|
3051
|
+
memset(&rep, 0, sizeof(rep));
|
|
3052
|
+
if (server->handlers && server->handlers->tree_connect_cmd) {
|
|
3053
|
+
ret = server->handlers->tree_connect_cmd(server, smb2, req, &rep);
|
|
3054
|
+
}
|
|
3055
|
+
if (!ret) {
|
|
3056
|
+
pdu = smb2_cmd_tree_connect_reply_async(smb2, &rep, 0, NULL, cb_data);
|
|
3057
|
+
}
|
|
3058
|
+
else if (ret < 0) {
|
|
3059
|
+
memset(&err, 0, sizeof(err));
|
|
3060
|
+
pdu = smb2_cmd_error_reply_async(smb2,
|
|
3061
|
+
&err, SMB2_TREE_CONNECT, SMB2_STATUS_NOT_IMPLEMENTED, NULL, cb_data);
|
|
3062
|
+
}
|
|
3063
|
+
if (pdu != NULL) {
|
|
3064
|
+
smb2_set_pdu_message_id(smb2, pdu, smb2->message_id);
|
|
3065
|
+
smb2_queue_pdu(smb2, pdu);
|
|
3066
|
+
}
|
|
3067
|
+
}
|
|
3068
|
+
|
|
3069
|
+
static void
|
|
3070
|
+
smb2_tree_disconnect_request_cb(struct smb2_server *server, struct smb2_context *smb2, void *command_data, void *cb_data)
|
|
3071
|
+
{
|
|
3072
|
+
struct smb2_pdu *pdu = NULL;
|
|
3073
|
+
struct smb2_error_reply err;
|
|
3074
|
+
uint32_t tree_id = smb2->hdr.sync.tree_id;
|
|
3075
|
+
int ret = -1;
|
|
3076
|
+
|
|
3077
|
+
if (server->handlers && server->handlers->tree_disconnect_cmd) {
|
|
3078
|
+
ret = server->handlers->tree_disconnect_cmd(server, smb2, smb2_tree_id(smb2));
|
|
3079
|
+
}
|
|
3080
|
+
if (!ret) {
|
|
3081
|
+
pdu = smb2_cmd_tree_disconnect_reply_async(smb2, NULL, cb_data);
|
|
3082
|
+
}
|
|
3083
|
+
else if (ret < 0) {
|
|
3084
|
+
memset(&err, 0, sizeof(err));
|
|
3085
|
+
pdu = smb2_cmd_error_reply_async(smb2,
|
|
3086
|
+
&err, SMB2_TREE_DISCONNECT, SMB2_STATUS_NOT_IMPLEMENTED, NULL, cb_data);
|
|
3087
|
+
}
|
|
3088
|
+
if (pdu != NULL) {
|
|
3089
|
+
smb2_set_pdu_message_id(smb2, pdu, smb2->message_id);
|
|
3090
|
+
smb2_queue_pdu(smb2, pdu);
|
|
3091
|
+
}
|
|
3092
|
+
|
|
3093
|
+
smb2_disconnect_tree_id(smb2, tree_id);
|
|
3094
|
+
}
|
|
3095
|
+
|
|
3096
|
+
static void
|
|
3097
|
+
smb2_create_request_cb(struct smb2_server *server, struct smb2_context *smb2, void *command_data, void *cb_data)
|
|
3098
|
+
{
|
|
3099
|
+
struct smb2_create_request *req = command_data;
|
|
3100
|
+
struct smb2_create_reply rep;
|
|
3101
|
+
struct smb2_error_reply err;
|
|
3102
|
+
struct smb2_pdu *pdu = NULL;
|
|
3103
|
+
int ret = -1;
|
|
3104
|
+
|
|
3105
|
+
memset(&rep, 0, sizeof(rep));
|
|
3106
|
+
if (server->handlers && server->handlers->create_cmd) {
|
|
3107
|
+
ret = server->handlers->create_cmd(server, smb2, req, &rep);
|
|
3108
|
+
}
|
|
3109
|
+
if (!ret) {
|
|
3110
|
+
pdu = smb2_cmd_create_reply_async(smb2, &rep, NULL, cb_data);
|
|
3111
|
+
}
|
|
3112
|
+
else if (ret < 0) {
|
|
3113
|
+
memset(&err, 0, sizeof(err));
|
|
3114
|
+
pdu = smb2_cmd_error_reply_async(smb2,
|
|
3115
|
+
&err, SMB2_CREATE, SMB2_STATUS_NOT_IMPLEMENTED, NULL, cb_data);
|
|
3116
|
+
}
|
|
3117
|
+
if (pdu) {
|
|
3118
|
+
if (req->name) {
|
|
3119
|
+
smb2_free_data(smb2, discard_const(req->name));
|
|
3120
|
+
}
|
|
3121
|
+
smb2_set_pdu_message_id(smb2, pdu, smb2->message_id);
|
|
3122
|
+
smb2_queue_pdu(smb2, pdu);
|
|
3123
|
+
}
|
|
3124
|
+
}
|
|
3125
|
+
|
|
3126
|
+
static void
|
|
3127
|
+
smb2_close_request_cb(struct smb2_server *server, struct smb2_context *smb2, void *command_data, void *cb_data)
|
|
3128
|
+
{
|
|
3129
|
+
struct smb2_close_request *req = command_data;
|
|
3130
|
+
struct smb2_close_reply rep;
|
|
3131
|
+
struct smb2_error_reply err;
|
|
3132
|
+
struct smb2_pdu *pdu = NULL;
|
|
3133
|
+
int ret = -1;
|
|
3134
|
+
|
|
3135
|
+
memset(&rep, 0, sizeof(rep));
|
|
3136
|
+
if (server->handlers && server->handlers->close_cmd) {
|
|
3137
|
+
ret = server->handlers->close_cmd(server, smb2, req, &rep);
|
|
3138
|
+
}
|
|
3139
|
+
if (!ret) {
|
|
3140
|
+
pdu = smb2_cmd_close_reply_async(smb2, &rep, NULL, cb_data);
|
|
3141
|
+
}
|
|
3142
|
+
else if (ret < 0) {
|
|
3143
|
+
memset(&err, 0, sizeof(err));
|
|
3144
|
+
pdu = smb2_cmd_error_reply_async(smb2,
|
|
3145
|
+
&err, SMB2_CLOSE, SMB2_STATUS_NOT_IMPLEMENTED, NULL, cb_data);
|
|
3146
|
+
}
|
|
3147
|
+
if (pdu != NULL) {
|
|
3148
|
+
smb2_set_pdu_message_id(smb2, pdu, smb2->message_id);
|
|
3149
|
+
smb2_queue_pdu(smb2, pdu);
|
|
3150
|
+
}
|
|
3151
|
+
}
|
|
3152
|
+
|
|
3153
|
+
static void
|
|
3154
|
+
smb2_flush_request_cb(struct smb2_server *server, struct smb2_context *smb2, void *command_data, void *cb_data)
|
|
3155
|
+
{
|
|
3156
|
+
struct smb2_flush_request *req = command_data;
|
|
3157
|
+
struct smb2_error_reply err;
|
|
3158
|
+
struct smb2_pdu *pdu = NULL;
|
|
3159
|
+
int ret = -1;
|
|
3160
|
+
|
|
3161
|
+
if (server->handlers && server->handlers->flush_cmd) {
|
|
3162
|
+
ret = server->handlers->flush_cmd(server, smb2, req);
|
|
3163
|
+
}
|
|
3164
|
+
if (!ret) {
|
|
3165
|
+
pdu = smb2_cmd_flush_reply_async(smb2, NULL, cb_data);
|
|
3166
|
+
}
|
|
3167
|
+
else if (ret < 0) {
|
|
3168
|
+
memset(&err, 0, sizeof(err));
|
|
3169
|
+
pdu = smb2_cmd_error_reply_async(smb2,
|
|
3170
|
+
&err, SMB2_FLUSH, SMB2_STATUS_NOT_IMPLEMENTED, NULL, cb_data);
|
|
3171
|
+
}
|
|
3172
|
+
if (pdu != NULL) {
|
|
3173
|
+
smb2_set_pdu_message_id(smb2, pdu, smb2->message_id);
|
|
3174
|
+
smb2_queue_pdu(smb2, pdu);
|
|
3175
|
+
}
|
|
3176
|
+
}
|
|
3177
|
+
|
|
3178
|
+
static void
|
|
3179
|
+
smb2_read_request_cb(struct smb2_server *server, struct smb2_context *smb2, void *command_data, void *cb_data)
|
|
3180
|
+
{
|
|
3181
|
+
struct smb2_read_request *req = command_data;
|
|
3182
|
+
struct smb2_read_reply rep;
|
|
3183
|
+
struct smb2_error_reply err;
|
|
3184
|
+
struct smb2_pdu *pdu = NULL;
|
|
3185
|
+
int ret = -1;
|
|
3186
|
+
|
|
3187
|
+
memset(&rep, 0, sizeof(rep));
|
|
3188
|
+
if (server->handlers && server->handlers->read_cmd) {
|
|
3189
|
+
ret = server->handlers->read_cmd(server, smb2, req, &rep);
|
|
3190
|
+
}
|
|
3191
|
+
if (!ret) {
|
|
3192
|
+
pdu = smb2_cmd_read_reply_async(smb2, &rep, NULL, cb_data);
|
|
3193
|
+
}
|
|
3194
|
+
else if (ret < 0) {
|
|
3195
|
+
memset(&err, 0, sizeof(err));
|
|
3196
|
+
pdu = smb2_cmd_error_reply_async(smb2,
|
|
3197
|
+
&err, SMB2_READ, SMB2_STATUS_NOT_IMPLEMENTED, NULL, cb_data);
|
|
3198
|
+
}
|
|
3199
|
+
if (pdu != NULL) {
|
|
3200
|
+
smb2_set_pdu_message_id(smb2, pdu, smb2->message_id);
|
|
3201
|
+
smb2_queue_pdu(smb2, pdu);
|
|
3202
|
+
}
|
|
3203
|
+
}
|
|
3204
|
+
|
|
3205
|
+
static void
|
|
3206
|
+
smb2_write_request_cb(struct smb2_server *server, struct smb2_context *smb2, void *command_data, void *cb_data)
|
|
3207
|
+
{
|
|
3208
|
+
struct smb2_write_request *req = command_data;
|
|
3209
|
+
struct smb2_write_reply rep;
|
|
3210
|
+
struct smb2_error_reply err;
|
|
3211
|
+
struct smb2_pdu *pdu = NULL;
|
|
3212
|
+
int ret = -1;
|
|
3213
|
+
|
|
3214
|
+
memset(&rep, 0, sizeof(rep));
|
|
3215
|
+
if (server->handlers && server->handlers->write_cmd) {
|
|
3216
|
+
ret = server->handlers->write_cmd(server, smb2, req, &rep);
|
|
3217
|
+
}
|
|
3218
|
+
if (!ret) {
|
|
3219
|
+
pdu = smb2_cmd_write_reply_async(smb2, &rep, NULL, cb_data);
|
|
3220
|
+
}
|
|
3221
|
+
else if (ret < 0) {
|
|
3222
|
+
memset(&err, 0, sizeof(err));
|
|
3223
|
+
pdu = smb2_cmd_error_reply_async(smb2,
|
|
3224
|
+
&err, SMB2_WRITE, SMB2_STATUS_NOT_IMPLEMENTED, NULL, cb_data);
|
|
3225
|
+
}
|
|
3226
|
+
if (pdu != NULL) {
|
|
3227
|
+
smb2_set_pdu_message_id(smb2, pdu, smb2->message_id);
|
|
3228
|
+
smb2_queue_pdu(smb2, pdu);
|
|
3229
|
+
}
|
|
3230
|
+
}
|
|
3231
|
+
|
|
3232
|
+
static void
|
|
3233
|
+
smb2_oplock_break_request_cb(struct smb2_server *server, struct smb2_context *smb2, void *command_data, void *cb_data)
|
|
3234
|
+
{
|
|
3235
|
+
struct smb2_oplock_or_lease_break_request *req = command_data;
|
|
3236
|
+
struct smb2_oplock_break_reply rep_oplock;
|
|
3237
|
+
struct smb2_lease_break_reply rep_lease;
|
|
3238
|
+
struct smb2_error_reply err;
|
|
3239
|
+
struct smb2_pdu *pdu = NULL;
|
|
3240
|
+
int ret = -1;
|
|
3241
|
+
|
|
3242
|
+
if (req->struct_size == SMB2_OPLOCK_BREAK_NOTIFICATION_SIZE) {
|
|
3243
|
+
if (server->handlers && server->handlers->oplock_break_cmd) {
|
|
3244
|
+
ret = server->handlers->oplock_break_cmd(server, smb2,
|
|
3245
|
+
&req->lock.oplock);
|
|
3246
|
+
if (!ret) {
|
|
3247
|
+
memset(&rep_oplock, 0, sizeof(rep_oplock));
|
|
3248
|
+
pdu = smb2_cmd_oplock_break_reply_async(smb2,
|
|
3249
|
+
&rep_oplock, NULL, cb_data);
|
|
3250
|
+
}
|
|
3251
|
+
}
|
|
3252
|
+
}
|
|
3253
|
+
else if ((req->struct_size == SMB2_LEASE_BREAK_NOTIFICATION_SIZE) |
|
|
3254
|
+
(req->struct_size == SMB2_LEASE_BREAK_REPLY_SIZE)) {
|
|
3255
|
+
if (server->handlers && server->handlers->lease_break_cmd) {
|
|
3256
|
+
ret = server->handlers->lease_break_cmd(server, smb2,
|
|
3257
|
+
&req->lock.lease);
|
|
3258
|
+
if (!ret) {
|
|
3259
|
+
memset(&rep_lease, 0, sizeof(rep_lease));
|
|
3260
|
+
pdu = smb2_cmd_lease_break_reply_async(smb2,
|
|
3261
|
+
&rep_lease, NULL, cb_data);
|
|
3262
|
+
}
|
|
3263
|
+
}
|
|
3264
|
+
}
|
|
3265
|
+
if(ret < 0) {
|
|
3266
|
+
memset(&err, 0, sizeof(err));
|
|
3267
|
+
pdu = smb2_cmd_error_reply_async(smb2,
|
|
3268
|
+
&err, SMB2_LOCK, SMB2_STATUS_NOT_IMPLEMENTED, NULL, cb_data);
|
|
3269
|
+
}
|
|
3270
|
+
if (pdu != NULL) {
|
|
3271
|
+
smb2_set_pdu_message_id(smb2, pdu, smb2->message_id);
|
|
3272
|
+
smb2_queue_pdu(smb2, pdu);
|
|
3273
|
+
}
|
|
3274
|
+
}
|
|
3275
|
+
|
|
3276
|
+
static void
|
|
3277
|
+
smb2_lock_request_cb(struct smb2_server *server, struct smb2_context *smb2, void *command_data, void *cb_data)
|
|
3278
|
+
{
|
|
3279
|
+
struct smb2_lock_request *req = command_data;
|
|
3280
|
+
struct smb2_error_reply err;
|
|
3281
|
+
struct smb2_pdu *pdu = NULL;
|
|
3282
|
+
int ret = -1;
|
|
3283
|
+
|
|
3284
|
+
if (server->handlers && server->handlers->lock_cmd) {
|
|
3285
|
+
ret = server->handlers->lock_cmd(server, smb2, req);
|
|
3286
|
+
}
|
|
3287
|
+
if (!ret) {
|
|
3288
|
+
pdu = smb2_cmd_lock_reply_async(smb2, NULL, cb_data);
|
|
3289
|
+
}
|
|
3290
|
+
else if(ret < 0) {
|
|
3291
|
+
memset(&err, 0, sizeof(err));
|
|
3292
|
+
pdu = smb2_cmd_error_reply_async(smb2,
|
|
3293
|
+
&err, SMB2_LOCK, SMB2_STATUS_NOT_IMPLEMENTED, NULL, cb_data);
|
|
3294
|
+
}
|
|
3295
|
+
if (pdu != NULL) {
|
|
3296
|
+
smb2_set_pdu_message_id(smb2, pdu, smb2->message_id);
|
|
3297
|
+
smb2_queue_pdu(smb2, pdu);
|
|
3298
|
+
}
|
|
3299
|
+
}
|
|
3300
|
+
|
|
3301
|
+
static void
|
|
3302
|
+
smb2_ioctl_request_cb(struct smb2_server *server, struct smb2_context *smb2, void *command_data, void *cb_data)
|
|
3303
|
+
{
|
|
3304
|
+
struct smb2_ioctl_request *req = command_data;
|
|
3305
|
+
struct smb2_ioctl_reply rep;
|
|
3306
|
+
struct smb2_error_reply err;
|
|
3307
|
+
struct smb2_pdu *pdu = NULL;
|
|
3308
|
+
struct smb2_ioctl_validate_negotiate_info out_info;
|
|
3309
|
+
int ret = -1;
|
|
3310
|
+
|
|
3311
|
+
memset(&rep, 0, sizeof(rep));
|
|
3312
|
+
rep.ctl_code = req->ctl_code;
|
|
3313
|
+
memcpy(rep.file_id, req->file_id, SMB2_FD_SIZE);
|
|
3314
|
+
|
|
3315
|
+
if (req->ctl_code == SMB2_FSCTL_VALIDATE_NEGOTIATE_INFO) {
|
|
3316
|
+
/* this one only needs local handling ever */
|
|
3317
|
+
/* in_info = (struct smb2_ioctl_validate_negotiate_info *)req->input; */
|
|
3318
|
+
out_info.capabilities = smb2->capabilities;
|
|
3319
|
+
out_info.security_mode = smb2->security_mode;
|
|
3320
|
+
memcpy(out_info.guid, server->guid, 16);
|
|
3321
|
+
out_info.dialect = smb2->dialect;
|
|
3322
|
+
rep.output = (uint8_t*)&out_info;
|
|
3323
|
+
rep.output_count = sizeof(out_info);
|
|
3324
|
+
pdu = smb2_cmd_ioctl_reply_async(smb2, &rep, NULL, cb_data);
|
|
3325
|
+
if (req->input) {
|
|
3326
|
+
smb2_free_data(smb2, discard_const(req->input));
|
|
3327
|
+
}
|
|
3328
|
+
}
|
|
3329
|
+
else {
|
|
3330
|
+
if (server->handlers && server->handlers->ioctl_cmd) {
|
|
3331
|
+
ret = server->handlers->ioctl_cmd(server, smb2, req, &rep);
|
|
3332
|
+
}
|
|
3333
|
+
if (!ret) {
|
|
3334
|
+
pdu = smb2_cmd_ioctl_reply_async(smb2, &rep, NULL, cb_data);
|
|
3335
|
+
}
|
|
3336
|
+
else if (ret < 0) {
|
|
3337
|
+
memset(&err, 0, sizeof(err));
|
|
3338
|
+
pdu = smb2_cmd_error_reply_async(smb2,
|
|
3339
|
+
&err, SMB2_IOCTL, SMB2_STATUS_NOT_IMPLEMENTED, NULL, cb_data);
|
|
3340
|
+
}
|
|
3341
|
+
}
|
|
3342
|
+
if (pdu != NULL) {
|
|
3343
|
+
smb2_set_pdu_message_id(smb2, pdu, smb2->message_id);
|
|
3344
|
+
smb2_queue_pdu(smb2, pdu);
|
|
3345
|
+
}
|
|
3346
|
+
}
|
|
3347
|
+
|
|
3348
|
+
static void
|
|
3349
|
+
smb2_cancel_request_cb(struct smb2_server *server, struct smb2_context *smb2, void *command_data, void *cb_data)
|
|
3350
|
+
{
|
|
3351
|
+
struct smb2_error_reply err;
|
|
3352
|
+
struct smb2_pdu *pdu = NULL;
|
|
3353
|
+
int ret = -1;
|
|
3354
|
+
|
|
3355
|
+
if (server->handlers && server->handlers->cancel_cmd) {
|
|
3356
|
+
ret = server->handlers->cancel_cmd(server, smb2);
|
|
3357
|
+
}
|
|
3358
|
+
if (ret < 0) {
|
|
3359
|
+
memset(&err, 0, sizeof(err));
|
|
3360
|
+
pdu = smb2_cmd_error_reply_async(smb2,
|
|
3361
|
+
&err, SMB2_CANCEL, SMB2_STATUS_NOT_IMPLEMENTED, NULL, cb_data);
|
|
3362
|
+
}
|
|
3363
|
+
if (pdu != NULL) {
|
|
3364
|
+
smb2_set_pdu_message_id(smb2, pdu, smb2->message_id);
|
|
3365
|
+
smb2_queue_pdu(smb2, pdu);
|
|
3366
|
+
}
|
|
3367
|
+
}
|
|
3368
|
+
|
|
3369
|
+
static void
|
|
3370
|
+
smb2_echo_request_cb(struct smb2_server *server, struct smb2_context *smb2, void *command_data, void *cb_data)
|
|
3371
|
+
{
|
|
3372
|
+
struct smb2_error_reply err;
|
|
3373
|
+
struct smb2_pdu *pdu = NULL;
|
|
3374
|
+
int ret = -1;
|
|
3375
|
+
|
|
3376
|
+
if (server->handlers && server->handlers->echo_cmd) {
|
|
3377
|
+
ret = server->handlers->echo_cmd(server, smb2);
|
|
3378
|
+
}
|
|
3379
|
+
if (!ret) {
|
|
3380
|
+
pdu = smb2_cmd_echo_reply_async(smb2, NULL, cb_data);
|
|
3381
|
+
}
|
|
3382
|
+
else if (ret < 0) {
|
|
3383
|
+
memset(&err, 0, sizeof(err));
|
|
3384
|
+
pdu = smb2_cmd_error_reply_async(smb2,
|
|
3385
|
+
&err, SMB2_ECHO, SMB2_STATUS_NOT_IMPLEMENTED, NULL, cb_data);
|
|
3386
|
+
}
|
|
3387
|
+
if (pdu != NULL) {
|
|
3388
|
+
smb2_set_pdu_message_id(smb2, pdu, smb2->message_id);
|
|
3389
|
+
smb2_queue_pdu(smb2, pdu);
|
|
3390
|
+
}
|
|
3391
|
+
}
|
|
3392
|
+
|
|
3393
|
+
static void
|
|
3394
|
+
smb2_query_directory_request_cb(struct smb2_server *server, struct smb2_context *smb2, void *command_data, void *cb_data)
|
|
3395
|
+
{
|
|
3396
|
+
struct smb2_query_directory_request *req = command_data;
|
|
3397
|
+
struct smb2_query_directory_reply rep;
|
|
3398
|
+
struct smb2_error_reply err;
|
|
3399
|
+
struct smb2_pdu *pdu = NULL;
|
|
3400
|
+
int ret = -1;
|
|
3401
|
+
|
|
3402
|
+
memset(&rep, 0, sizeof(rep));
|
|
3403
|
+
memset(&err, 0, sizeof(err));
|
|
3404
|
+
|
|
3405
|
+
if (server->handlers && server->handlers->query_directory_cmd) {
|
|
3406
|
+
ret = server->handlers->query_directory_cmd(server, smb2, req, &rep);
|
|
3407
|
+
}
|
|
3408
|
+
if (ret < 0) {
|
|
3409
|
+
pdu = smb2_cmd_error_reply_async(smb2,
|
|
3410
|
+
&err, SMB2_QUERY_DIRECTORY, SMB2_STATUS_NOT_IMPLEMENTED, NULL, cb_data);
|
|
3411
|
+
}
|
|
3412
|
+
else if (!ret) {
|
|
3413
|
+
if (rep.output_buffer_length == 0) {
|
|
3414
|
+
pdu = smb2_cmd_error_reply_async(smb2,
|
|
3415
|
+
&err, SMB2_QUERY_DIRECTORY, SMB2_STATUS_NO_MORE_FILES, NULL, cb_data);
|
|
3416
|
+
}
|
|
3417
|
+
else if (rep.output_buffer_length < 0) {
|
|
3418
|
+
pdu = smb2_cmd_error_reply_async(smb2,
|
|
3419
|
+
&err, SMB2_QUERY_DIRECTORY, SMB2_STATUS_NOT_SUPPORTED, NULL, cb_data);
|
|
3420
|
+
}
|
|
3421
|
+
else {
|
|
3422
|
+
pdu = smb2_cmd_query_directory_reply_async(smb2, req, &rep, NULL, cb_data);
|
|
3423
|
+
}
|
|
3424
|
+
}
|
|
3425
|
+
if (req->name) {
|
|
3426
|
+
smb2_free_data(smb2, discard_const(req->name));
|
|
3427
|
+
}
|
|
3428
|
+
if (pdu != NULL) {
|
|
3429
|
+
smb2_set_pdu_message_id(smb2, pdu, smb2->message_id);
|
|
3430
|
+
smb2_queue_pdu(smb2, pdu);
|
|
3431
|
+
}
|
|
3432
|
+
}
|
|
3433
|
+
|
|
3434
|
+
static void
|
|
3435
|
+
smb2_change_notify_request_cb(struct smb2_server *server, struct smb2_context *smb2, void *command_data, void *cb_data)
|
|
3436
|
+
{
|
|
3437
|
+
struct smb2_change_notify_request *req = command_data;
|
|
3438
|
+
struct smb2_change_notify_reply rep;
|
|
3439
|
+
struct smb2_error_reply err;
|
|
3440
|
+
struct smb2_pdu *pdu = NULL;
|
|
3441
|
+
int ret = -1;
|
|
3442
|
+
|
|
3443
|
+
memset(&rep, 0, sizeof(rep));
|
|
3444
|
+
memset(&err, 0, sizeof(err));
|
|
3445
|
+
|
|
3446
|
+
if (server->handlers && server->handlers->change_notify_cmd) {
|
|
3447
|
+
ret = server->handlers->change_notify_cmd(server, smb2, req, &rep);
|
|
3448
|
+
}
|
|
3449
|
+
if (ret < 0) {
|
|
3450
|
+
pdu = smb2_cmd_error_reply_async(smb2,
|
|
3451
|
+
&err, SMB2_CHANGE_NOTIFY, SMB2_STATUS_NOT_IMPLEMENTED, NULL, cb_data);
|
|
3452
|
+
}
|
|
3453
|
+
else if (!ret) {
|
|
3454
|
+
pdu = smb2_cmd_change_notify_reply_async(smb2, &rep, NULL, cb_data);
|
|
3455
|
+
}
|
|
3456
|
+
if (pdu != NULL) {
|
|
3457
|
+
smb2_set_pdu_message_id(smb2, pdu, smb2->message_id);
|
|
3458
|
+
smb2_queue_pdu(smb2, pdu);
|
|
3459
|
+
}
|
|
3460
|
+
}
|
|
3461
|
+
|
|
3462
|
+
static void
|
|
3463
|
+
smb2_query_info_request_cb(struct smb2_server *server, struct smb2_context *smb2, void *command_data, void *cb_data)
|
|
3464
|
+
{
|
|
3465
|
+
struct smb2_query_info_request *req = command_data;
|
|
3466
|
+
struct smb2_query_info_reply rep;
|
|
3467
|
+
struct smb2_error_reply err;
|
|
3468
|
+
struct smb2_pdu *pdu = NULL;
|
|
3469
|
+
int ret = -1;
|
|
3470
|
+
|
|
3471
|
+
memset(&rep, 0, sizeof(rep));
|
|
3472
|
+
memset(&err, 0, sizeof(err));
|
|
3473
|
+
|
|
3474
|
+
if (server->handlers && server->handlers->query_info_cmd) {
|
|
3475
|
+
ret = server->handlers->query_info_cmd(server, smb2, req, &rep);
|
|
3476
|
+
}
|
|
3477
|
+
if (ret < 0) {
|
|
3478
|
+
pdu = smb2_cmd_error_reply_async(smb2,
|
|
3479
|
+
&err, SMB2_QUERY_INFO, SMB2_STATUS_NOT_IMPLEMENTED, NULL, cb_data);
|
|
3480
|
+
}
|
|
3481
|
+
else if (!ret) {
|
|
3482
|
+
if (rep.output_buffer_length == 0) {
|
|
3483
|
+
pdu = smb2_cmd_error_reply_async(smb2,
|
|
3484
|
+
&err, SMB2_QUERY_INFO, SMB2_STATUS_NOT_SUPPORTED, NULL, cb_data);
|
|
3485
|
+
}
|
|
3486
|
+
else if (rep.output_buffer_length < 0) {
|
|
3487
|
+
pdu = smb2_cmd_error_reply_async(smb2,
|
|
3488
|
+
&err, SMB2_QUERY_INFO, SMB2_STATUS_INVALID_INFO_CLASS, NULL, cb_data);
|
|
3489
|
+
}
|
|
3490
|
+
else {
|
|
3491
|
+
pdu = smb2_cmd_query_info_reply_async(smb2, req, &rep, NULL, cb_data);
|
|
3492
|
+
}
|
|
3493
|
+
}
|
|
3494
|
+
if (pdu != NULL) {
|
|
3495
|
+
smb2_set_pdu_message_id(smb2, pdu, smb2->message_id);
|
|
3496
|
+
smb2_queue_pdu(smb2, pdu);
|
|
3497
|
+
}
|
|
3498
|
+
}
|
|
3499
|
+
|
|
3500
|
+
static void
|
|
3501
|
+
smb2_set_info_request_cb(struct smb2_server *server, struct smb2_context *smb2, void *command_data, void *cb_data)
|
|
3502
|
+
{
|
|
3503
|
+
struct smb2_set_info_request *req = command_data;
|
|
3504
|
+
struct smb2_error_reply err;
|
|
3505
|
+
struct smb2_pdu *pdu = NULL;
|
|
3506
|
+
int ret = -1;
|
|
3507
|
+
|
|
3508
|
+
memset(&err, 0, sizeof(err));
|
|
3509
|
+
|
|
3510
|
+
if (server->handlers && server->handlers->set_info_cmd) {
|
|
3511
|
+
ret = server->handlers->set_info_cmd(server, smb2, req);
|
|
3512
|
+
}
|
|
3513
|
+
if (ret < 0) {
|
|
3514
|
+
pdu = smb2_cmd_error_reply_async(smb2,
|
|
3515
|
+
&err, SMB2_SET_INFO, SMB2_STATUS_NOT_IMPLEMENTED, NULL, cb_data);
|
|
3516
|
+
}
|
|
3517
|
+
else if (!ret) {
|
|
3518
|
+
pdu = smb2_cmd_set_info_reply_async(smb2, req, NULL, cb_data);
|
|
3519
|
+
}
|
|
3520
|
+
if (pdu != NULL) {
|
|
3521
|
+
smb2_set_pdu_message_id(smb2, pdu, smb2->message_id);
|
|
3522
|
+
smb2_queue_pdu(smb2, pdu);
|
|
3523
|
+
}
|
|
3524
|
+
}
|
|
3525
|
+
|
|
3526
|
+
static void
|
|
3527
|
+
smb2_session_setup_request_cb(struct smb2_context *smb2, int status, void *command_data, void *cb_data);
|
|
3528
|
+
|
|
3529
|
+
static void
|
|
3530
|
+
smb2_general_client_request_cb(struct smb2_context *smb2, int status, void *command_data, void *cb_data)
|
|
3531
|
+
{
|
|
3532
|
+
struct connect_data *c_data = cb_data;
|
|
3533
|
+
struct smb2_server *server = c_data->server_context;
|
|
3534
|
+
enum smb2_command next_cmd = SMB2_TREE_CONNECT;
|
|
3535
|
+
smb2_command_cb next_cb = smb2_general_client_request_cb;
|
|
3536
|
+
|
|
3537
|
+
if (!smb2->pdu) {
|
|
3538
|
+
smb2_set_error(smb2, "No pdu for general client request");
|
|
3539
|
+
smb2_close_context(smb2);
|
|
3540
|
+
return;
|
|
3541
|
+
}
|
|
3542
|
+
if (status == SMB2_STATUS_CANCELLED || status == SMB2_STATUS_SHUTDOWN) {
|
|
3543
|
+
return;
|
|
3544
|
+
}
|
|
3545
|
+
|
|
3546
|
+
switch (smb2->pdu->header.command) {
|
|
3547
|
+
case SMB2_SESSION_SETUP:
|
|
3548
|
+
smb2_session_setup_request_cb(smb2, status, command_data, cb_data);
|
|
3549
|
+
/* session setup cb allocs next_pdu itself */
|
|
3550
|
+
next_cb = NULL;
|
|
3551
|
+
break;
|
|
3552
|
+
case SMB2_LOGOFF:
|
|
3553
|
+
smb2_logoff_request_cb(server, smb2, command_data, cb_data);
|
|
3554
|
+
/* prep for a new session setup req */
|
|
3555
|
+
next_cmd = SMB2_SESSION_SETUP;
|
|
3556
|
+
next_cb = smb2_session_setup_request_cb;
|
|
3557
|
+
break;
|
|
3558
|
+
case SMB2_TREE_CONNECT:
|
|
3559
|
+
smb2_tree_connect_request_cb(server, smb2, command_data, cb_data);
|
|
3560
|
+
break;
|
|
3561
|
+
case SMB2_TREE_DISCONNECT:
|
|
3562
|
+
smb2_tree_disconnect_request_cb(server, smb2, command_data, cb_data);
|
|
3563
|
+
break;
|
|
3564
|
+
case SMB2_CREATE:
|
|
3565
|
+
smb2_create_request_cb(server, smb2, command_data, cb_data);
|
|
3566
|
+
break;
|
|
3567
|
+
case SMB2_CLOSE:
|
|
3568
|
+
smb2_close_request_cb(server, smb2, command_data, cb_data);
|
|
3569
|
+
break;
|
|
3570
|
+
case SMB2_FLUSH:
|
|
3571
|
+
smb2_flush_request_cb(server, smb2, command_data, cb_data);
|
|
3572
|
+
break;
|
|
3573
|
+
case SMB2_READ:
|
|
3574
|
+
smb2_read_request_cb(server, smb2, command_data, cb_data);
|
|
3575
|
+
break;
|
|
3576
|
+
case SMB2_WRITE:
|
|
3577
|
+
smb2_write_request_cb(server, smb2, command_data, cb_data);
|
|
3578
|
+
break;
|
|
3579
|
+
case SMB2_OPLOCK_BREAK:
|
|
3580
|
+
smb2_oplock_break_request_cb(server, smb2, command_data, cb_data);
|
|
3581
|
+
break;
|
|
3582
|
+
case SMB2_LOCK:
|
|
3583
|
+
smb2_lock_request_cb(server, smb2, command_data, cb_data);
|
|
3584
|
+
break;
|
|
3585
|
+
case SMB2_IOCTL:
|
|
3586
|
+
smb2_ioctl_request_cb(server, smb2, command_data, cb_data);
|
|
3587
|
+
break;
|
|
3588
|
+
case SMB2_CANCEL:
|
|
3589
|
+
smb2_cancel_request_cb(server, smb2, command_data, cb_data);
|
|
3590
|
+
break;
|
|
3591
|
+
case SMB2_ECHO:
|
|
3592
|
+
smb2_echo_request_cb(server, smb2, command_data, cb_data);
|
|
3593
|
+
break;
|
|
3594
|
+
case SMB2_QUERY_DIRECTORY:
|
|
3595
|
+
smb2_query_directory_request_cb(server, smb2, command_data, cb_data);
|
|
3596
|
+
break;
|
|
3597
|
+
case SMB2_CHANGE_NOTIFY:
|
|
3598
|
+
smb2_change_notify_request_cb(server, smb2, command_data, cb_data);
|
|
3599
|
+
break;
|
|
3600
|
+
case SMB2_QUERY_INFO:
|
|
3601
|
+
smb2_query_info_request_cb(server, smb2, command_data, cb_data);
|
|
3602
|
+
break;
|
|
3603
|
+
case SMB2_SET_INFO:
|
|
3604
|
+
smb2_set_info_request_cb(server, smb2, command_data, cb_data);
|
|
3605
|
+
break;
|
|
3606
|
+
default:
|
|
3607
|
+
smb2_set_error(smb2, "Client request %d not implemented %s",
|
|
3608
|
+
smb2->pdu->header.command, smb2_get_error(smb2));
|
|
3609
|
+
break;
|
|
3610
|
+
}
|
|
3611
|
+
|
|
3612
|
+
if (next_cb) {
|
|
3613
|
+
/* alloc a pdu for next request. note that we dont really expect a tree connect, its just to
|
|
3614
|
+
* allow pdu reading to know to allow for any command above negotiate and session-setup
|
|
3615
|
+
*/
|
|
3616
|
+
smb2->next_pdu = smb2_allocate_pdu(smb2, next_cmd, next_cb, cb_data);
|
|
3617
|
+
if (!smb2->next_pdu) {
|
|
3618
|
+
smb2_set_error(smb2, "can not alloc pdu for authorization session setup request");
|
|
3619
|
+
smb2_close_context(smb2);
|
|
3620
|
+
}
|
|
3621
|
+
}
|
|
3622
|
+
}
|
|
3623
|
+
|
|
3624
|
+
static void
|
|
3625
|
+
smb2_session_setup_request_cb(struct smb2_context *smb2, int status, void *command_data, void *cb_data)
|
|
3626
|
+
{
|
|
3627
|
+
struct connect_data *c_data = cb_data;
|
|
3628
|
+
struct smb2_server *server = c_data->server_context;
|
|
3629
|
+
struct smb2_session_setup_request *req = command_data;
|
|
3630
|
+
struct smb2_session_setup_reply rep;
|
|
3631
|
+
struct smb2_pdu *pdu;
|
|
3632
|
+
struct smb2_error_reply err;
|
|
3633
|
+
uint32_t message_type;
|
|
3634
|
+
int more_processing_needed = 0;
|
|
3635
|
+
uint8_t *response_token;
|
|
3636
|
+
int response_length;
|
|
3637
|
+
int is_spnego_wrapped;
|
|
3638
|
+
int have_valid_session_key = 1;
|
|
3639
|
+
int ret;
|
|
3640
|
+
|
|
3641
|
+
if (status) {
|
|
3642
|
+
return;
|
|
3643
|
+
}
|
|
3644
|
+
|
|
3645
|
+
rep.security_buffer_length = 0;
|
|
3646
|
+
rep.security_buffer_offset = 0;
|
|
3647
|
+
|
|
3648
|
+
rep.session_flags = 0; /* req->flags; */
|
|
3649
|
+
|
|
3650
|
+
smb3_update_preauth_hash(smb2, smb2->in.niov - 1, &smb2->in.iov[1]);
|
|
3651
|
+
memset(&err, 0, sizeof(err));
|
|
3652
|
+
|
|
3653
|
+
pdu = NULL;
|
|
3654
|
+
|
|
3655
|
+
if (smb2->sec == SMB2_SEC_UNDEFINED || smb2->sec == SMB2_SEC_NTLMSSP) {
|
|
3656
|
+
/* if we haven't set sec type yet, and the blob contains
|
|
3657
|
+
* valid ntlmssp, use our ntlmssp implementation, but supress
|
|
3658
|
+
* error-setting while sniffing. if we are expecting ntlmssp
|
|
3659
|
+
* insist on a valid message
|
|
3660
|
+
* TODO - perhaps use krb5+ntlmssp if configured?
|
|
3661
|
+
*/
|
|
3662
|
+
if (ntlmssp_get_message_type(smb2,
|
|
3663
|
+
req->security_buffer, req->security_buffer_length,
|
|
3664
|
+
smb2->sec == SMB2_SEC_UNDEFINED,
|
|
3665
|
+
&message_type,
|
|
3666
|
+
&response_token, &response_length,
|
|
3667
|
+
&is_spnego_wrapped) >= 0) {
|
|
3668
|
+
smb2->sec = SMB2_SEC_NTLMSSP;
|
|
3669
|
+
} else {
|
|
3670
|
+
|
|
3671
|
+
#ifdef HAVE_LIBKRB5
|
|
3672
|
+
smb2->sec = SMB2_SEC_KRB5;
|
|
3673
|
+
#else
|
|
3674
|
+
smb2_set_error(smb2, "No message type in NTLMSSP %s",
|
|
3675
|
+
smb2_get_error(smb2));
|
|
3676
|
+
smb2_close_context(smb2);
|
|
3677
|
+
return;
|
|
3678
|
+
#endif
|
|
3679
|
+
}
|
|
3680
|
+
}
|
|
3681
|
+
|
|
3682
|
+
if (smb2->sec == SMB2_SEC_NTLMSSP) {
|
|
3683
|
+
/* set error code in header - more processing required if negotiate req not auth req */
|
|
3684
|
+
if (message_type == NEGOTIATE_MESSAGE) {
|
|
3685
|
+
if (c_data->auth_data) {
|
|
3686
|
+
ntlmssp_destroy_context(c_data->auth_data);
|
|
3687
|
+
}
|
|
3688
|
+
c_data->auth_data = ntlmssp_init_context(
|
|
3689
|
+
"",
|
|
3690
|
+
"",
|
|
3691
|
+
"",
|
|
3692
|
+
server->hostname,
|
|
3693
|
+
smb2->client_challenge
|
|
3694
|
+
);
|
|
3695
|
+
if (!c_data->auth_data) {
|
|
3696
|
+
smb2_set_error(smb2, "can not init auth data %s", smb2_get_error(smb2));
|
|
3697
|
+
smb2_close_context(smb2);
|
|
3698
|
+
return;
|
|
3699
|
+
}
|
|
3700
|
+
smb2->connect_data = c_data;
|
|
3701
|
+
|
|
3702
|
+
/* alloc a pdu for next request */
|
|
3703
|
+
smb2->next_pdu = smb2_allocate_pdu(smb2, SMB2_SESSION_SETUP,
|
|
3704
|
+
smb2_session_setup_request_cb, cb_data);
|
|
3705
|
+
more_processing_needed = 1;
|
|
3706
|
+
smb2->session_id = server->session_counter++;
|
|
3707
|
+
}
|
|
3708
|
+
else if (message_type == AUTHENTICATION_MESSAGE) {
|
|
3709
|
+
/* alloc a pdu for next request (not really required to get tree connect) */
|
|
3710
|
+
smb2->next_pdu = smb2_allocate_pdu(smb2, SMB2_TREE_CONNECT,
|
|
3711
|
+
smb2_general_client_request_cb, cb_data);
|
|
3712
|
+
}
|
|
3713
|
+
else {
|
|
3714
|
+
smb2_set_error(smb2, "Unexpected ntlmssp msg code %08X", message_type);
|
|
3715
|
+
smb2_close_context(smb2);
|
|
3716
|
+
return;
|
|
3717
|
+
}
|
|
3718
|
+
if (ntlmssp_generate_blob(server, smb2, 0, c_data->auth_data,
|
|
3719
|
+
req->security_buffer, req->security_buffer_length,
|
|
3720
|
+
&rep.security_buffer,
|
|
3721
|
+
&rep.security_buffer_length) < 0) {
|
|
3722
|
+
smb2_close_context(smb2);
|
|
3723
|
+
return;
|
|
3724
|
+
}
|
|
3725
|
+
if (message_type == AUTHENTICATION_MESSAGE) {
|
|
3726
|
+
if (!ntlmssp_get_authenticated(c_data->auth_data)) {
|
|
3727
|
+
smb2_set_error(smb2, "Authentication failed: %s", smb2_get_error(smb2));
|
|
3728
|
+
#if 0
|
|
3729
|
+
smb2_close_context(smb2);
|
|
3730
|
+
return;
|
|
3731
|
+
#else
|
|
3732
|
+
pdu = smb2_cmd_error_reply_async(smb2,
|
|
3733
|
+
&err, SMB2_SESSION_SETUP,
|
|
3734
|
+
SMB2_STATUS_LOGON_FAILURE, NULL, cb_data);
|
|
3735
|
+
smb2_free_pdu(smb2, smb2->next_pdu);
|
|
3736
|
+
smb2->next_pdu = smb2_allocate_pdu(smb2, SMB2_SESSION_SETUP,
|
|
3737
|
+
smb2_session_setup_request_cb, cb_data);
|
|
3738
|
+
more_processing_needed = 0;
|
|
3739
|
+
#endif
|
|
3740
|
+
}
|
|
3741
|
+
if (ntlmssp_get_session_key(c_data->auth_data,
|
|
3742
|
+
&smb2->session_key,
|
|
3743
|
+
&smb2->session_key_size) < 0) {
|
|
3744
|
+
have_valid_session_key = 0;
|
|
3745
|
+
}
|
|
3746
|
+
}
|
|
3747
|
+
}
|
|
3748
|
+
#ifdef HAVE_LIBKRB5
|
|
3749
|
+
else {
|
|
3750
|
+
if (!c_data->auth_data) {
|
|
3751
|
+
c_data->auth_data = krb5_init_server_client_cred(server, smb2, NULL);
|
|
3752
|
+
if (!c_data->auth_data) {
|
|
3753
|
+
smb2_set_error(smb2, "can not init auth data %s", smb2_get_error(smb2));
|
|
3754
|
+
smb2_close_context(smb2);
|
|
3755
|
+
return;
|
|
3756
|
+
}
|
|
3757
|
+
smb2->connect_data = c_data;
|
|
3758
|
+
if (!smb2->session_id) {
|
|
3759
|
+
smb2->session_id = server->session_counter++;
|
|
3760
|
+
}
|
|
3761
|
+
}
|
|
3762
|
+
|
|
3763
|
+
if (krb5_session_reply(smb2, c_data->auth_data,
|
|
3764
|
+
req->security_buffer,
|
|
3765
|
+
req->security_buffer_length,
|
|
3766
|
+
&more_processing_needed)) {
|
|
3767
|
+
smb2_close_context(smb2);
|
|
3768
|
+
return;
|
|
3769
|
+
}
|
|
3770
|
+
|
|
3771
|
+
/* alloc a pdu for next request */
|
|
3772
|
+
if (more_processing_needed) {
|
|
3773
|
+
smb2->next_pdu = smb2_allocate_pdu(smb2, SMB2_SESSION_SETUP,
|
|
3774
|
+
smb2_session_setup_request_cb, cb_data);
|
|
3775
|
+
smb2->session_id = server->session_counter++;
|
|
3776
|
+
} else {
|
|
3777
|
+
smb2->next_pdu = smb2_allocate_pdu(smb2, SMB2_TREE_CONNECT,
|
|
3778
|
+
smb2_general_client_request_cb, cb_data);
|
|
3779
|
+
}
|
|
3780
|
+
rep.security_buffer_length =
|
|
3781
|
+
krb5_get_output_token_length(c_data->auth_data);
|
|
3782
|
+
rep.security_buffer =
|
|
3783
|
+
krb5_get_output_token_buffer(c_data->auth_data);
|
|
3784
|
+
|
|
3785
|
+
if (!krb5_session_get_session_key(smb2, c_data->auth_data)) {
|
|
3786
|
+
have_valid_session_key = 1;
|
|
3787
|
+
}
|
|
3788
|
+
}
|
|
3789
|
+
#endif
|
|
3790
|
+
if (smb2->sign && have_valid_session_key == 0) {
|
|
3791
|
+
smb2_close_context(smb2);
|
|
3792
|
+
smb2_set_error(smb2, "Signing required by server. Session "
|
|
3793
|
+
"Key is not available %s",
|
|
3794
|
+
smb2_get_error(smb2));
|
|
3795
|
+
smb2_close_context(smb2);
|
|
3796
|
+
return;
|
|
3797
|
+
}
|
|
3798
|
+
|
|
3799
|
+
if (smb2->sign) {
|
|
3800
|
+
/* Derive the signing key from session key
|
|
3801
|
+
* This is based on negotiated protocol
|
|
3802
|
+
*/
|
|
3803
|
+
smb2_create_signing_key(smb2);
|
|
3804
|
+
}
|
|
3805
|
+
|
|
3806
|
+
if (server->allow_anonymous &&
|
|
3807
|
+
((smb2->user == NULL || smb2->user[0] == '\0')||
|
|
3808
|
+
(smb2->password == NULL || smb2->password[0] == '\0'))) {
|
|
3809
|
+
rep.session_flags |= SMB2_SESSION_FLAG_IS_GUEST;
|
|
3810
|
+
}
|
|
3811
|
+
|
|
3812
|
+
if (!pdu) {
|
|
3813
|
+
pdu = smb2_cmd_session_setup_reply_async(smb2, &rep, NULL, cb_data);
|
|
3814
|
+
if (pdu == NULL) {
|
|
3815
|
+
smb2_set_error(smb2, "can not alloc pdu for session setup reply");
|
|
3816
|
+
smb2_close_context(smb2);
|
|
3817
|
+
return;
|
|
3818
|
+
}
|
|
3819
|
+
if (more_processing_needed) {
|
|
3820
|
+
pdu->header.status = SMB2_STATUS_MORE_PROCESSING_REQUIRED;
|
|
3821
|
+
}
|
|
3822
|
+
else {
|
|
3823
|
+
if (server->handlers && server->handlers->session_established) {
|
|
3824
|
+
ret = server->handlers->session_established(server, smb2);
|
|
3825
|
+
if (ret) {
|
|
3826
|
+
smb2_set_error(smb2, "server session start handler failed");
|
|
3827
|
+
smb2_close_context(smb2);
|
|
3828
|
+
return;
|
|
3829
|
+
}
|
|
3830
|
+
}
|
|
3831
|
+
else {
|
|
3832
|
+
pdu = smb2_cmd_error_reply_async(smb2,
|
|
3833
|
+
&err, SMB2_SESSION_SETUP,
|
|
3834
|
+
SMB2_STATUS_NOT_IMPLEMENTED, NULL, cb_data);
|
|
3835
|
+
}
|
|
3836
|
+
}
|
|
3837
|
+
}
|
|
3838
|
+
if (!smb2->next_pdu) {
|
|
3839
|
+
smb2_set_error(smb2, "can not alloc pdu for authorization session setup request");
|
|
3840
|
+
smb2_close_context(smb2);
|
|
3841
|
+
return;
|
|
3842
|
+
}
|
|
3843
|
+
|
|
3844
|
+
smb2_set_pdu_message_id(smb2, pdu, smb2->message_id);
|
|
3845
|
+
smb2_queue_pdu(smb2, pdu);
|
|
3846
|
+
smb3_update_preauth_hash(smb2, pdu->out.niov, &pdu->out.iov[0]);
|
|
3847
|
+
}
|
|
3848
|
+
|
|
3849
|
+
static void
|
|
3850
|
+
smb2_negotiate_request_cb(struct smb2_context *smb2, int status, void *command_data, void *cb_data)
|
|
3851
|
+
{
|
|
3852
|
+
struct connect_data *c_data = cb_data;
|
|
3853
|
+
struct smb2_server *server = c_data->server_context;
|
|
3854
|
+
struct smb2_negotiate_request *req = command_data;
|
|
3855
|
+
struct smb2_negotiate_reply rep;
|
|
3856
|
+
struct smb2_error_reply err;
|
|
3857
|
+
struct smb2_pdu *pdu;
|
|
3858
|
+
uint16_t dialects[SMB2_NEGOTIATE_MAX_DIALECTS];
|
|
3859
|
+
int dialect_count;
|
|
3860
|
+
int d;
|
|
3861
|
+
int dialect_index;
|
|
3862
|
+
struct smb2_timeval now;
|
|
3863
|
+
int will_sign = 0;
|
|
3864
|
+
|
|
3865
|
+
memset(&rep, 0, sizeof(rep));
|
|
3866
|
+
memset(&err, 0, sizeof(err));
|
|
3867
|
+
smb2_set_error(smb2, "");
|
|
3868
|
+
|
|
3869
|
+
if (status != SMB2_STATUS_SUCCESS) {
|
|
3870
|
+
/* context is being destroyed */
|
|
3871
|
+
return;
|
|
3872
|
+
}
|
|
3873
|
+
|
|
3874
|
+
/* assume we can always reply */
|
|
3875
|
+
smb2->credits = 128;
|
|
3876
|
+
|
|
3877
|
+
/* negotiate highest version in request dialects */
|
|
3878
|
+
switch (smb2->version) {
|
|
3879
|
+
case SMB2_VERSION_ANY:
|
|
3880
|
+
dialect_count = 5;
|
|
3881
|
+
dialects[0] = SMB2_VERSION_0202;
|
|
3882
|
+
dialects[1] = SMB2_VERSION_0210;
|
|
3883
|
+
dialects[2] = SMB2_VERSION_0300;
|
|
3884
|
+
dialects[3] = SMB2_VERSION_0302;
|
|
3885
|
+
dialects[4] = SMB2_VERSION_0311;
|
|
3886
|
+
break;
|
|
3887
|
+
case SMB2_VERSION_ANY2:
|
|
3888
|
+
dialect_count = 2;
|
|
3889
|
+
dialects[0] = SMB2_VERSION_0202;
|
|
3890
|
+
dialects[1] = SMB2_VERSION_0210;
|
|
3891
|
+
break;
|
|
3892
|
+
case SMB2_VERSION_ANY3:
|
|
3893
|
+
dialect_count = 3;
|
|
3894
|
+
dialects[0] = SMB2_VERSION_0300;
|
|
3895
|
+
dialects[1] = SMB2_VERSION_0302;
|
|
3896
|
+
dialects[2] = SMB2_VERSION_0311;
|
|
3897
|
+
break;
|
|
3898
|
+
case SMB2_VERSION_0202:
|
|
3899
|
+
case SMB2_VERSION_0210:
|
|
3900
|
+
case SMB2_VERSION_0300:
|
|
3901
|
+
case SMB2_VERSION_0302:
|
|
3902
|
+
case SMB2_VERSION_0311:
|
|
3903
|
+
default:
|
|
3904
|
+
dialect_count = 1;
|
|
3905
|
+
dialects[0] = smb2->version;
|
|
3906
|
+
break;
|
|
3907
|
+
}
|
|
3908
|
+
|
|
3909
|
+
if (req && smb2->pdu->header.command != SMB1_NEGOTIATE) {
|
|
3910
|
+
if (req->dialect_count == 0) {
|
|
3911
|
+
/* windows does this crap */
|
|
3912
|
+
/* alloc a pdu for another negotiate request */
|
|
3913
|
+
smb2->next_pdu = smb2_allocate_pdu(smb2, SMB2_NEGOTIATE, smb2_negotiate_request_cb, cb_data);
|
|
3914
|
+
if (!smb2->next_pdu) {
|
|
3915
|
+
smb2_set_error(smb2, "can not alloc pdu for second negotiate request");
|
|
3916
|
+
smb2_close_context(smb2);
|
|
3917
|
+
}
|
|
3918
|
+
pdu = smb2_cmd_error_reply_async(smb2,
|
|
3919
|
+
&err, SMB2_NEGOTIATE, SMB2_STATUS_INVALID_PARAMETER, NULL, cb_data);
|
|
3920
|
+
if (pdu == NULL) {
|
|
3921
|
+
return;
|
|
3922
|
+
}
|
|
3923
|
+
smb2_set_pdu_message_id(smb2, pdu, smb2->message_id);
|
|
3924
|
+
smb2_queue_pdu(smb2, pdu);
|
|
3925
|
+
return;
|
|
3926
|
+
}
|
|
3927
|
+
smb2->dialect = 0;
|
|
3928
|
+
for (dialect_index = req->dialect_count - 1;
|
|
3929
|
+
dialect_index >= 0; dialect_index--) {
|
|
3930
|
+
for (d = dialect_count - 1; d >= 0; d--) {
|
|
3931
|
+
if (dialects[d] == req->dialects[dialect_index]) {
|
|
3932
|
+
smb2->dialect = dialects[d];
|
|
3933
|
+
break;
|
|
3934
|
+
}
|
|
3935
|
+
}
|
|
3936
|
+
if (smb2->dialect != 0) {
|
|
3937
|
+
break;
|
|
3938
|
+
}
|
|
3939
|
+
}
|
|
3940
|
+
|
|
3941
|
+
if (dialect_index < 0) {
|
|
3942
|
+
smb2_set_error(smb2, "No common dialects for protocol");
|
|
3943
|
+
smb2_close_context(smb2);
|
|
3944
|
+
return;
|
|
3945
|
+
}
|
|
3946
|
+
|
|
3947
|
+
smb2_set_client_guid(smb2, req->client_guid);
|
|
3948
|
+
}
|
|
3949
|
+
else {
|
|
3950
|
+
/* an smb1-negotiate, list all dialects */
|
|
3951
|
+
smb2->dialect = SMB2_VERSION_WILDCARD;
|
|
3952
|
+
}
|
|
3953
|
+
|
|
3954
|
+
smb3_init_preauth_hash(smb2);
|
|
3955
|
+
smb3_update_preauth_hash(smb2, smb2->in.niov - 1, &smb2->in.iov[1]);
|
|
3956
|
+
|
|
3957
|
+
if (req) {
|
|
3958
|
+
rep.capabilities = SMB2_GLOBAL_CAP_LARGE_MTU;
|
|
3959
|
+
if (smb2->version == SMB2_VERSION_ANY ||
|
|
3960
|
+
smb2->version == SMB2_VERSION_ANY3 ||
|
|
3961
|
+
smb2->version == SMB2_VERSION_0300 ||
|
|
3962
|
+
smb2->version == SMB2_VERSION_0302 ||
|
|
3963
|
+
smb2->version == SMB2_VERSION_0311) {
|
|
3964
|
+
rep.capabilities |= SMB2_GLOBAL_CAP_ENCRYPTION;
|
|
3965
|
+
}
|
|
3966
|
+
|
|
3967
|
+
/* update the context with the client capabilities */
|
|
3968
|
+
if (smb2->dialect > SMB2_VERSION_0202) {
|
|
3969
|
+
if (req->capabilities & SMB2_GLOBAL_CAP_LARGE_MTU) {
|
|
3970
|
+
smb2->supports_multi_credit = 1;
|
|
3971
|
+
}
|
|
3972
|
+
}
|
|
3973
|
+
|
|
3974
|
+
if (smb2->seal && (smb2->dialect == SMB2_VERSION_0300 ||
|
|
3975
|
+
smb2->dialect == SMB2_VERSION_0302)) {
|
|
3976
|
+
if(!(req->capabilities & SMB2_GLOBAL_CAP_ENCRYPTION)) {
|
|
3977
|
+
smb2_set_error(smb2, "Encryption requested but client "
|
|
3978
|
+
"does not support encryption.");
|
|
3979
|
+
smb2_close_context(smb2);
|
|
3980
|
+
return;
|
|
3981
|
+
}
|
|
3982
|
+
}
|
|
3983
|
+
|
|
3984
|
+
if (req->security_mode & SMB2_NEGOTIATE_SIGNING_REQUIRED) {
|
|
3985
|
+
will_sign = 1;
|
|
3986
|
+
}
|
|
3987
|
+
|
|
3988
|
+
if (!server->allow_anonymous ||
|
|
3989
|
+
(smb2->password && smb2->password[0])) {
|
|
3990
|
+
if (smb2->dialect == SMB2_VERSION_0210) {
|
|
3991
|
+
/* smb2.1 requires signing if enabled on both sides
|
|
3992
|
+
* regardless of what the flags say */
|
|
3993
|
+
will_sign = 1;
|
|
3994
|
+
}
|
|
3995
|
+
if (smb2->dialect >= SMB2_VERSION_0311) {
|
|
3996
|
+
/* smb3.1.1 requires signing if enabled on both sides
|
|
3997
|
+
* regardless of what the flags say */
|
|
3998
|
+
will_sign = 1;
|
|
3999
|
+
}
|
|
4000
|
+
}
|
|
4001
|
+
|
|
4002
|
+
if (smb2->seal) {
|
|
4003
|
+
smb2->sign = 0;
|
|
4004
|
+
} else if (will_sign) {
|
|
4005
|
+
if (server->signing_enabled) {
|
|
4006
|
+
smb2->sign = 1;
|
|
4007
|
+
} else {
|
|
4008
|
+
smb2_set_error(smb2, "Signing required but server "
|
|
4009
|
+
"does not have signing enabled.");
|
|
4010
|
+
smb2_close_context(smb2);
|
|
4011
|
+
return;
|
|
4012
|
+
}
|
|
4013
|
+
}
|
|
4014
|
+
}
|
|
4015
|
+
|
|
4016
|
+
rep.security_mode = (server->signing_enabled ? SMB2_NEGOTIATE_SIGNING_ENABLED : 0)|
|
|
4017
|
+
(smb2->sign ? SMB2_NEGOTIATE_SIGNING_REQUIRED : 0);
|
|
4018
|
+
memcpy(rep.server_guid, server->guid, 16); /* TODO */
|
|
4019
|
+
rep.max_transact_size = smb2->max_transact_size;;
|
|
4020
|
+
rep.max_read_size = smb2->max_read_size;
|
|
4021
|
+
rep.max_write_size = smb2->max_write_size;
|
|
4022
|
+
rep.dialect_revision = smb2->dialect;
|
|
4023
|
+
rep.cypher = smb2->cypher;
|
|
4024
|
+
|
|
4025
|
+
/* remember negotiated capabilites and security mode */
|
|
4026
|
+
smb2->capabilities = rep.capabilities;
|
|
4027
|
+
smb2->security_mode = rep.security_mode;
|
|
4028
|
+
|
|
4029
|
+
now.tv_sec = time(NULL);
|
|
4030
|
+
now.tv_usec = 0;
|
|
4031
|
+
|
|
4032
|
+
rep.system_time = smb2_timeval_to_win(&now);
|
|
4033
|
+
now.tv_sec = 0;
|
|
4034
|
+
rep.server_start_time = smb2_timeval_to_win(&now);
|
|
4035
|
+
|
|
4036
|
+
rep.security_buffer_length = smb2_spnego_create_negotiate_reply_blob(
|
|
4037
|
+
smb2,
|
|
4038
|
+
(smb2->sec == SMB2_SEC_UNDEFINED || smb2->sec == SMB2_SEC_NTLMSSP),
|
|
4039
|
+
(void*)&rep.security_buffer);
|
|
4040
|
+
|
|
4041
|
+
pdu = smb2_cmd_negotiate_reply_async(smb2, &rep, NULL, cb_data);
|
|
4042
|
+
if (rep.security_buffer) {
|
|
4043
|
+
free(rep.security_buffer);
|
|
4044
|
+
}
|
|
4045
|
+
if (pdu == NULL) {
|
|
4046
|
+
return;
|
|
4047
|
+
}
|
|
4048
|
+
|
|
4049
|
+
smb2_set_pdu_message_id(smb2, pdu, smb2->message_id);
|
|
4050
|
+
smb2_queue_pdu(smb2, pdu);
|
|
4051
|
+
smb3_update_preauth_hash(smb2, pdu->out.niov, &pdu->out.iov[0]);
|
|
4052
|
+
|
|
4053
|
+
if (req) {
|
|
4054
|
+
/* alloc a pdu for session request */
|
|
4055
|
+
smb2->next_pdu = smb2_allocate_pdu(smb2, SMB2_SESSION_SETUP, smb2_session_setup_request_cb, cb_data);
|
|
4056
|
+
if (!smb2->next_pdu) {
|
|
4057
|
+
smb2_set_error(smb2, "can not alloc pdu for session setup request");
|
|
4058
|
+
smb2_close_context(smb2);
|
|
4059
|
+
}
|
|
4060
|
+
}
|
|
4061
|
+
else {
|
|
4062
|
+
/* alloc a pdu for another negotiate request */
|
|
4063
|
+
smb2->next_pdu = smb2_allocate_pdu(smb2, SMB2_NEGOTIATE, smb2_negotiate_request_cb, cb_data);
|
|
4064
|
+
if (!smb2->next_pdu) {
|
|
4065
|
+
smb2_set_error(smb2, "can not alloc pdu for second negotiate request");
|
|
4066
|
+
smb2_close_context(smb2);
|
|
4067
|
+
}
|
|
4068
|
+
}
|
|
4069
|
+
}
|
|
4070
|
+
|
|
4071
|
+
static int
|
|
4072
|
+
accept_cb(const int fd, void *cb_data)
|
|
4073
|
+
{
|
|
4074
|
+
int err = -1;
|
|
4075
|
+
struct smb2_context **psmb2 = (struct smb2_context**)cb_data;
|
|
4076
|
+
struct smb2_context *smb2;
|
|
4077
|
+
|
|
4078
|
+
if (!psmb2) {
|
|
4079
|
+
return -EINVAL;
|
|
4080
|
+
}
|
|
4081
|
+
|
|
4082
|
+
*psmb2 = NULL;
|
|
4083
|
+
|
|
4084
|
+
smb2 = smb2_init_context();
|
|
4085
|
+
if (smb2 == NULL) {
|
|
4086
|
+
err = -ENOMEM;
|
|
4087
|
+
}
|
|
4088
|
+
else {
|
|
4089
|
+
*psmb2 = smb2;
|
|
4090
|
+
/* put client fd into connecting fd array (todo? for now just set fd) */
|
|
4091
|
+
smb2->fd = fd;
|
|
4092
|
+
err = 0;
|
|
4093
|
+
}
|
|
4094
|
+
|
|
4095
|
+
return err;
|
|
4096
|
+
}
|
|
4097
|
+
|
|
4098
|
+
int smb2_serve_port_async(const int fd, const int to_msecs, struct smb2_context **smb2)
|
|
4099
|
+
{
|
|
4100
|
+
int err = -1;
|
|
4101
|
+
|
|
4102
|
+
err = smb2_accept_connection_async(fd, to_msecs, accept_cb, smb2);
|
|
4103
|
+
return err;
|
|
4104
|
+
}
|
|
4105
|
+
|
|
4106
|
+
int smb2_serve_port(struct smb2_server *server, const int max_connections, smb2_client_connection cb, void *cb_data)
|
|
4107
|
+
{
|
|
4108
|
+
struct smb2_context *smb2;
|
|
4109
|
+
struct connect_data *c_data = cb_data;
|
|
4110
|
+
fd_set rfds, wfds;
|
|
4111
|
+
int maxfd;
|
|
4112
|
+
int ready;
|
|
4113
|
+
short events;
|
|
4114
|
+
struct timeval timeout;
|
|
4115
|
+
int err = -1;
|
|
4116
|
+
static const char *default_domain = "WORKGROUP";
|
|
4117
|
+
time_t now;
|
|
4118
|
+
#ifdef HAVE_LIBKRB5
|
|
4119
|
+
static time_t credential_renewal_time = 0;
|
|
4120
|
+
#endif
|
|
4121
|
+
|
|
4122
|
+
if (!server->max_transact_size) {
|
|
4123
|
+
server->max_transact_size = 0x100000;
|
|
4124
|
+
server->max_read_size = 0x100000;
|
|
4125
|
+
server->max_write_size = 0x100000;
|
|
4126
|
+
}
|
|
4127
|
+
if (!server->guid[0]) {
|
|
4128
|
+
memcpy(server->guid, "libsmb2-srvrguid", 16);
|
|
4129
|
+
}
|
|
4130
|
+
if (!server->hostname[0]) {
|
|
4131
|
+
gethostname(server->hostname, sizeof(server->hostname));
|
|
4132
|
+
}
|
|
4133
|
+
if (!server->domain[0]) {
|
|
4134
|
+
strncpy(server->domain, default_domain,
|
|
4135
|
+
MIN(sizeof(server->domain),strlen(default_domain) + 1));
|
|
4136
|
+
}
|
|
4137
|
+
|
|
4138
|
+
#ifdef HAVE_LIBKRB5
|
|
4139
|
+
err = krb5_init_server_credentials(server, server->keytab_path);
|
|
4140
|
+
if (err) {
|
|
4141
|
+
return err;
|
|
4142
|
+
}
|
|
4143
|
+
#endif
|
|
4144
|
+
err = smb2_bind_and_listen(server->port, max_connections, &server->fd);
|
|
4145
|
+
if (err != 0) {
|
|
4146
|
+
return err;
|
|
4147
|
+
}
|
|
4148
|
+
server->session_counter = 0x1234;
|
|
4149
|
+
|
|
4150
|
+
do {
|
|
4151
|
+
/* select on the file descriptors of all active client connections and our server socket
|
|
4152
|
+
for the first readable event
|
|
4153
|
+
*/
|
|
4154
|
+
FD_ZERO(&rfds);
|
|
4155
|
+
FD_ZERO(&wfds);
|
|
4156
|
+
FD_SET(server->fd, &rfds);
|
|
4157
|
+
maxfd = server->fd;
|
|
4158
|
+
|
|
4159
|
+
for (smb2 = smb2_active_contexts(); smb2; smb2 = smb2->next) {
|
|
4160
|
+
if (SMB2_VALID_SOCKET(smb2_get_fd(smb2))) {
|
|
4161
|
+
events = smb2_which_events(smb2);
|
|
4162
|
+
if (events) {
|
|
4163
|
+
if (events & POLLIN) {
|
|
4164
|
+
FD_SET(smb2_get_fd(smb2), &rfds);
|
|
4165
|
+
}
|
|
4166
|
+
if (events & POLLOUT) {
|
|
4167
|
+
FD_SET(smb2_get_fd(smb2), &wfds);
|
|
4168
|
+
}
|
|
4169
|
+
if (smb2_get_fd(smb2) > (t_socket)maxfd) {
|
|
4170
|
+
maxfd = smb2_get_fd(smb2);
|
|
4171
|
+
}
|
|
4172
|
+
}
|
|
4173
|
+
}
|
|
4174
|
+
}
|
|
4175
|
+
|
|
4176
|
+
/* 100ms select timeout to allow periodic pdu timeouts */
|
|
4177
|
+
timeout.tv_sec = 0;
|
|
4178
|
+
timeout.tv_usec = 100000;
|
|
4179
|
+
|
|
4180
|
+
ready = select(
|
|
4181
|
+
maxfd + 1,
|
|
4182
|
+
&rfds,
|
|
4183
|
+
&wfds,
|
|
4184
|
+
NULL,
|
|
4185
|
+
(timeout.tv_sec > 0 || timeout.tv_usec >= 0) ? &timeout : NULL
|
|
4186
|
+
);
|
|
4187
|
+
|
|
4188
|
+
if (ready > 0) {
|
|
4189
|
+
now = time(NULL);
|
|
4190
|
+
|
|
4191
|
+
/* for each client context ready to read, process that context */
|
|
4192
|
+
for (smb2 = smb2_active_contexts(); smb2; smb2 = smb2->next) {
|
|
4193
|
+
if (SMB2_VALID_SOCKET(smb2_get_fd(smb2)) && FD_ISSET(smb2_get_fd(smb2), &rfds)) {
|
|
4194
|
+
if (smb2_service(smb2, POLLIN) < 0) {
|
|
4195
|
+
smb2_set_error(smb2, "smb2_service (in) failed with : "
|
|
4196
|
+
"%s", smb2_get_error(smb2));
|
|
4197
|
+
smb2_close_context(smb2);
|
|
4198
|
+
}
|
|
4199
|
+
err = 0;
|
|
4200
|
+
}
|
|
4201
|
+
if (SMB2_VALID_SOCKET(smb2_get_fd(smb2)) && FD_ISSET(smb2_get_fd(smb2), &wfds)) {
|
|
4202
|
+
if (smb2_service(smb2, POLLOUT) < 0) {
|
|
4203
|
+
smb2_set_error(smb2, "smb2_service (out) failed with : "
|
|
4204
|
+
"%s", smb2_get_error(smb2));
|
|
4205
|
+
smb2_close_context(smb2);
|
|
4206
|
+
}
|
|
4207
|
+
}
|
|
4208
|
+
if (!SMB2_VALID_SOCKET(smb2->fd) && ((time(NULL) - now) > (smb2->timeout)))
|
|
4209
|
+
{
|
|
4210
|
+
smb2_set_error(smb2, "Timeout expired and no connection exists");
|
|
4211
|
+
smb2_close_context(smb2);
|
|
4212
|
+
}
|
|
4213
|
+
if (smb2->timeout) {
|
|
4214
|
+
smb2_timeout_pdus(smb2);
|
|
4215
|
+
}
|
|
4216
|
+
}
|
|
4217
|
+
|
|
4218
|
+
if (FD_ISSET(server->fd, &rfds)) {
|
|
4219
|
+
smb2 = NULL;
|
|
4220
|
+
err = smb2_serve_port_async(server->fd, 10, &smb2);
|
|
4221
|
+
if (!err && smb2) {
|
|
4222
|
+
c_data = calloc(1, sizeof(struct connect_data));
|
|
4223
|
+
if (c_data == NULL) {
|
|
4224
|
+
smb2_set_error(smb2, "Failed to allocate connect_data");
|
|
4225
|
+
smb2_close_context(smb2);
|
|
4226
|
+
}
|
|
4227
|
+
c_data->server_context = server;
|
|
4228
|
+
smb2->connect_data = c_data;
|
|
4229
|
+
|
|
4230
|
+
/* alloc a pdu for first server request */
|
|
4231
|
+
smb2->pdu = smb2_allocate_pdu(smb2, SMB2_NEGOTIATE, smb2_negotiate_request_cb, c_data);
|
|
4232
|
+
if (!smb2->pdu) {
|
|
4233
|
+
smb2_set_error(smb2, "can not alloc pdu for request");
|
|
4234
|
+
smb2_close_context(smb2);
|
|
4235
|
+
}
|
|
4236
|
+
/* got a new smb2 context with a connection, enlist it and tell user */
|
|
4237
|
+
smb2->owning_server = server;
|
|
4238
|
+
smb2->max_transact_size = server->max_transact_size;
|
|
4239
|
+
smb2->max_read_size = server->max_read_size;
|
|
4240
|
+
smb2->max_write_size = server->max_write_size;
|
|
4241
|
+
|
|
4242
|
+
if (cb) {
|
|
4243
|
+
cb(smb2, cb_data);
|
|
4244
|
+
}
|
|
4245
|
+
}
|
|
4246
|
+
else if (err) {
|
|
4247
|
+
break;
|
|
4248
|
+
}
|
|
4249
|
+
}
|
|
4250
|
+
|
|
4251
|
+
/* cull connection-less servers here (servers who's client has disconnected)
|
|
4252
|
+
* do only one per iteration since active list changes on destroy
|
|
4253
|
+
*/
|
|
4254
|
+
for (smb2 = smb2_active_contexts(); smb2; smb2 = smb2->next) {
|
|
4255
|
+
if (smb2_is_server(smb2)) {
|
|
4256
|
+
if (!SMB2_VALID_SOCKET(smb2_get_fd(smb2))) {
|
|
4257
|
+
if (server->handlers && server->handlers->destruction_event) {
|
|
4258
|
+
server->handlers->destruction_event(server, smb2);
|
|
4259
|
+
}
|
|
4260
|
+
smb2_destroy_context(smb2);
|
|
4261
|
+
break;
|
|
4262
|
+
}
|
|
4263
|
+
}
|
|
4264
|
+
/* client connections are destroyed when they timeout or get disconnected */
|
|
4265
|
+
}
|
|
4266
|
+
}
|
|
4267
|
+
#ifdef HAVE_LIBKRB5
|
|
4268
|
+
/* renew kerberos credentials daily */
|
|
4269
|
+
time(&now);
|
|
4270
|
+
|
|
4271
|
+
if (credential_renewal_time < now) {
|
|
4272
|
+
credential_renewal_time = now + 60*60*24;
|
|
4273
|
+
|
|
4274
|
+
err = krb5_renew_server_credentials(server);
|
|
4275
|
+
}
|
|
4276
|
+
#endif
|
|
4277
|
+
}
|
|
4278
|
+
while (err == 0);
|
|
4279
|
+
|
|
4280
|
+
close(server->fd);
|
|
4281
|
+
server->fd = -1;
|
|
4282
|
+
|
|
4283
|
+
while (smb2_active_contexts()) {
|
|
4284
|
+
smb2 = smb2_active_contexts();
|
|
4285
|
+
smb2_destroy_context(smb2);
|
|
4286
|
+
}
|
|
4287
|
+
#ifdef HAVE_LIBKRB5
|
|
4288
|
+
krb5_free_server_credentials(server);
|
|
4289
|
+
#endif
|
|
4290
|
+
return err;
|
|
4291
|
+
}
|
|
4292
|
+
|