Преглед изворни кода

add SMB files and folders delete

Sylver Bruneau пре 9 година
родитељ
комит
de95b790d3
10 измењених фајлова са 343 додато и 18 уклоњено
  1. 3 0
      Makefile.am
  2. 1 0
      include/bdsm.h
  3. 45 0
      include/bdsm/smb_defs.h
  4. 53 0
      include/bdsm/smb_dir.h
  5. 11 0
      include/bdsm/smb_file.h
  6. 10 18
      src/smb_defs.h
  7. 93 0
      src/smb_dir.c
  8. 41 0
      src/smb_dir.h
  9. 55 0
      src/smb_file.c
  10. 31 0
      src/smb_packets.h

+ 3 - 0
Makefile.am

@@ -23,6 +23,7 @@ bdsm_HEADERS = \
     include/bdsm/netbios_defs.h   \
     include/bdsm/netbios_ns.h   \
     include/bdsm/smb_defs.h   \
+    include/bdsm/smb_dir.h   \
     include/bdsm/smb_file.h   \
     include/bdsm/smb_session.h    \
     include/bdsm/smb_share.h    \
@@ -38,6 +39,7 @@ noinst_HEADERS = \
     src/netbios_utils.h  \
     src/smb_buffer.h \
     src/smb_defs.h   \
+    src/smb_dir.h    \
     src/smb_fd.h    \
     src/smb_file.h   \
     src/smb_message.h    \
@@ -69,6 +71,7 @@ libdsm_la_SOURCES = \
     src/netbios_session.c   \
     src/netbios_utils.c     \
     src/smb_buffer.c        \
+    src/smb_dir.c           \
     src/smb_fd.c            \
     src/smb_file.c          \
     src/smb_spnego.c        \

+ 1 - 0
include/bdsm.h

@@ -41,5 +41,6 @@
 #include "bdsm/smb_share.h"
 #include "bdsm/smb_file.h"
 #include "bdsm/smb_stat.h"
+#include "bdsm/smb_dir.h"
 
 #endif

+ 45 - 0
include/bdsm/smb_defs.h

@@ -138,4 +138,49 @@ enum smb_session_supports_what
 #define SMB_MOD_RO              (SMB_MOD_READ | SMB_MOD_READ_EXT \
                                 | SMB_MOD_READ_ATTR | SMB_MOD_READ_CTL )
 
+//-----------------------------------------------------------------------------/
+// NTSTATUS & internal return codes
+//-----------------------------------------------------------------------------/
+#define NT_STATUS_SUCCESS                   0x00000000
+#define NT_STATUS_INVALID_SMB               0x00010002
+#define NT_STATUS_SMB_BAD_TID               0x00050002
+#define NT_STATUS_SMB_BAD_UID               0x005b0002
+#define NT_STATUS_NOT_IMPLEMENTED           0xc0000002
+#define NT_STATUS_INVALID_DEVICE_REQUEST    0xc0000010
+#define NT_STATUS_NO_SUCH_DEVICE            0xc000000e
+#define NT_STATUS_NO_SUCH_FILE              0xc000000f
+#define NT_STATUS_MORE_PROCESSING_REQUIRED  0xc0000016
+#define NT_STATUS_INVALID_LOCK_SEQUENCE     0xc000001e
+#define NT_STATUS_INVALID_VIEW_SIZE         0xc000001f
+#define NT_STATUS_ALREADY_COMMITTED         0xc0000021
+#define NT_STATUS_ACCESS_DENIED             0xc0000022
+#define NT_STATUS_OBJECT_NAME_NOT_FOUND     0xc0000034
+#define NT_STATUS_OBJECT_PATH_INVALID       0xc0000039
+#define NT_STATUS_OBJECT_PATH_NOT_FOUND     0xc000003a
+#define NT_STATUS_OBJECT_PATH_SYNTAX_BAD    0xc000003b
+#define NT_STATUS_PORT_CONNECTION_REFUSED   0xc0000041
+#define NT_STATUS_THREAD_IS_TERMINATING     0xc000004b
+#define NT_STATUS_DELETE_PENDING            0xc0000056
+#define NT_STATUS_PRIVILEGE_NOT_HELD        0xc0000061
+#define NT_STATUS_LOGON_FAILURE             0xc000006D
+#define NT_STATUS_DFS_EXIT_PATH_FOUND       0xc000009b
+#define NT_STATUS_MEDIA_WRITE_PROTECTED     0xc00000a2
+#define NT_STATUS_ILLEGAL_FUNCTION          0xc00000af
+#define NT_STATUS_FILE_IS_A_DIRECTORY       0xc00000ba
+#define NT_STATUS_FILE_RENAMED              0xc00000d5
+#define NT_STATUS_REDIRECTOR_NOT_STARTED    0xc00000fb
+#define NT_STATUS_DIRECTORY_NOT_EMPTY       0xc0000101
+#define NT_STATUS_PROCESS_IS_TERMINATING    0xc000010a
+#define NT_STATUS_TOO_MANY_OPENED_FILES     0xc000011f
+#define NT_STATUS_CANNOT_DELETE             0xc0000121
+#define NT_STATUS_FILE_DELETED              0xc0000123
+#define NT_STATUS_INSUFF_SERVER_RESOURCES   0xc0000205
+
+#define DSM_ERROR_INTERNAL                  0xff000001
+#define DSM_ERROR_INVALID_RCV_MESS          0xff000002
+#define DSM_ERROR_UTF16_CONV_FAILED         0xff000003
+#define DSM_ERROR_INVALID_PATH              0xff000004
+#define DSM_ERROR_INVALID_SESSION           0xff000005
+#define DSM_ERROR_INVALID_TID               0xff000006
+
 #endif

+ 53 - 0
include/bdsm/smb_dir.h

@@ -0,0 +1,53 @@
+/*****************************************************************************
+ *  __________________    _________  _____            _____  .__         ._.
+ *  \______   \______ \  /   _____/ /     \          /  _  \ |__| ____   | |
+ *   |    |  _/|    |  \ \_____  \ /  \ /  \        /  /_\  \|  _/ __ \  | |
+ *   |    |   \|    `   \/        /    Y    \      /    |    |  \  ___/   \|
+ *   |______  /_______  /_______  \____|__  / /\   \____|__  |__|\___ |   __
+ *          \/        \/        \/        \/  )/           \/        \/   \/
+ *
+ * This file is part of liBDSM. Copyright © 2014-2015 VideoLabs SAS
+ *
+ * Author: Sylver Bruneau <sylver.bruneau@gmail.com>
+ *
+ * liBDSM is released under LGPLv2.1 (or later) and is also available
+ * under a commercial license.
+ *****************************************************************************
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+/**
+ * @file smb_dir.h
+ * @brief Directory operations
+ */
+
+#ifndef __BDSM_SMB_DIR_H_
+#define __BDSM_SMB_DIR_H_
+
+#include "bdsm/smb_session.h"
+
+
+/**
+ * @brief remove a directory on a share.
+ * @details Use this function to delete an empty directory
+ *
+ * @param s The session object
+ * @param tid The tid of the share the file is in, obtained via smb_tree_connect()
+ * @param path The path of the file to delete
+ * @return 0 if delete OK or "NT" error code
+ */
+uint32_t  smb_rm_dir(smb_session *s, smb_tid tid, const char *path);
+
+#endif

+ 11 - 0
include/bdsm/smb_file.h

@@ -100,4 +100,15 @@ ssize_t   smb_fread(smb_session *s, smb_fd fd, void *buf, size_t buf_size);
  */
 ssize_t   smb_fseek(smb_session *s, smb_fd fd, ssize_t offset, int whence);
 
+/**
+ * @brief remove a file on a share.
+ * @details Use this function to delete a file
+ *
+ * @param s The session object
+ * @param tid The tid of the share the file is in, obtained via smb_tree_connect()
+ * @param path The path of the file to delete
+ * @return 0 if delete OK or "NT" error code
+ */
+uint32_t  smb_rm_file(smb_session *s, smb_tid tid, const char *path);
+
 #endif

+ 10 - 18
src/smb_defs.h

@@ -72,7 +72,16 @@
 #define SMB_CMD_ECHO            0x2b
 #define SMB_CMD_READ            0x2e // Read AndX
 #define SMB_CMD_CREATE          0xa2 // NT Create AndX
+#define SMB_CMD_MKDIR           0x00
+#define SMB_CMD_RMDIR           0x01
+#define SMB_CMD_RMFILE          0x06
+#define SMB_CMD_MOVE            0x07 // Move or rename
 
+//-----------------------------------------------------------------------------/
+// SMB FLAGS2 values
+//-----------------------------------------------------------------------------/
+#define SMB_FLAGS2_SHORT_NAMES  0x0000
+#define SMB_FLAGS2_LONG_NAMES   0x0001
 
 //-----------------------------------------------------------------------------/
 // SMB TRANS2 SubCommands
@@ -104,14 +113,6 @@
 #define SMB_FIND2_QUERY_FILE_COMPRESSION_INFO 0x010B
 
 
-//-----------------------------------------------------------------------------/
-// NTSTATUS Codes
-//-----------------------------------------------------------------------------/
-#define NT_STATUS_SUCCESS                   0x00000000
-#define NT_STATUS_MORE_PROCESSING_REQUIRED  0xc0000016
-#define NT_STATUS_ACCESS_DENIED             0xc0000022
-
-
 ///////////////////////////////////////////////////////////////////////////////
 //// Flags definitions
 //// Many aren't use in libdsm but are here for possible later use
@@ -155,23 +156,14 @@
 #define SMB_CREATE_EXT_RESP     (1 << 4)
 #define SMB_CREATE_DEFAULTS     (0)
 
-
 // File attributes
+#define SMB_ATTR_NORMAL         0
 #define SMB_ATTR_RO             (1 << 0)
 #define SMB_ATTR_HIDDEN         (1 << 1)
 #define SMB_ATTR_SYS            (1 << 2)
 #define SMB_ATTR_VOLID          (1 << 3)  // Volume ID
 #define SMB_ATTR_DIR            (1 << 4)
 #define SMB_ATTR_ARCHIVE        (1 << 5)  // Modified since last archive (!?)
-#define SMB_ATTR_DEVICE         (1 << 6)
-#define SMB_ATTR_NORMAL         (1 << 7)
-#define SMB_ATTR_TEMP           (1 << 8)
-#define SMB_ATTR_SPARSE         (1 << 9)
-#define SMB_ATTR_REPARSE_PT     (1 << 10)
-#define SMB_ATTR_COMPRESSED     (1 << 11)
-#define SMB_ATTR_OFFLINE        (1 << 12)
-#define SMB_ATTR_INDEXED        (1 << 13) // Not set = May be indexed
-#define SMB_ATTR_ENCRYPTED      (1 << 14)
 // Share access flags
 #define SMB_SHARE_READ          (1 << 0)
 #define SMB_SHARE_WRITE         (1 << 1)

+ 93 - 0
src/smb_dir.c

@@ -0,0 +1,93 @@
+/*****************************************************************************
+ *  __________________    _________  _____            _____  .__         ._.
+ *  \______   \______ \  /   _____/ /     \          /  _  \ |__| ____   | |
+ *   |    |  _/|    |  \ \_____  \ /  \ /  \        /  /_\  \|  _/ __ \  | |
+ *   |    |   \|    `   \/        /    Y    \      /    |    |  \  ___/   \|
+ *   |______  /_______  /_______  \____|__  / /\   \____|__  |__|\___ |   __
+ *          \/        \/        \/        \/  )/           \/        \/   \/
+ *
+ * This file is part of liBDSM. Copyright © 2014-2015 VideoLabs SAS
+ *
+ * Author: Sylver Bruneau <sylver.bruneau@gmail.com>
+ *
+ * liBDSM is released under LGPLv2.1 (or later) and is also available
+ * under a commercial license.
+ *****************************************************************************
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+#include <assert.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdio.h>
+
+#include "smb_session_msg.h"
+#include "smb_fd.h"
+#include "smb_utils.h"
+#include "smb_dir.h"
+
+uint32_t  smb_rm_dir(smb_session *s, smb_tid tid, const char *path)
+{
+    smb_message           *req_msg, resp_msg;
+    smb_rm_dir_req       req;
+    smb_rm_dir_resp      *resp;
+    size_t                utf_pattern_len;
+    char                  *utf_pattern;
+
+    if (s == NULL)
+        return DSM_ERROR_INVALID_SESSION;
+    if (tid == -1)
+        return DSM_ERROR_INVALID_TID;
+    if (path == NULL)
+        return DSM_ERROR_INVALID_PATH;
+
+    utf_pattern_len = smb_to_utf16(path, strlen(path) + 1, &utf_pattern);
+    if (utf_pattern_len == 0)
+        return DSM_ERROR_UTF16_CONV_FAILED;
+
+    req_msg = smb_message_new(SMB_CMD_RMDIR);
+    if (!req_msg)
+    {
+        free(utf_pattern);
+        return DSM_ERROR_INTERNAL;
+    }
+
+    req_msg->packet->header.tid = (uint16_t)tid;
+
+    SMB_MSG_INIT_PKT(req);
+    req.wct              = 0x00; // Must be 0
+    req.bct              = (uint16_t)(utf_pattern_len + 1);
+    req.buffer_format    = 0x04; // Must be 4
+    SMB_MSG_PUT_PKT(req_msg, req);
+    smb_message_append(req_msg, utf_pattern, utf_pattern_len);
+
+    smb_session_send_msg(s, req_msg);
+    smb_message_destroy(req_msg);
+
+    free(utf_pattern);
+
+    if (!smb_session_recv_msg(s, &resp_msg))
+        return DSM_ERROR_INVALID_RCV_MESS;
+
+    if (resp_msg.packet->header.status != NT_STATUS_SUCCESS)
+        return (resp_msg.packet->header.status);
+
+    resp = (smb_rm_dir_resp *)resp_msg.packet->payload;
+    if ((resp->wct != 0) || (resp->bct != 0))
+        return DSM_ERROR_INVALID_RCV_MESS;
+
+    return NT_STATUS_SUCCESS;
+}

+ 41 - 0
src/smb_dir.h

@@ -0,0 +1,41 @@
+/*****************************************************************************
+ *  __________________    _________  _____            _____  .__         ._.
+ *  \______   \______ \  /   _____/ /     \          /  _  \ |__| ____   | |
+ *   |    |  _/|    |  \ \_____  \ /  \ /  \        /  /_\  \|  _/ __ \  | |
+ *   |    |   \|    `   \/        /    Y    \      /    |    |  \  ___/   \|
+ *   |______  /_______  /_______  \____|__  / /\   \____|__  |__|\___ |   __
+ *          \/        \/        \/        \/  )/           \/        \/   \/
+ *
+ * This file is part of liBDSM. Copyright © 2014-2015 VideoLabs SAS
+ *
+ * Author: Sylver Bruneau <sylver.bruneau@gmail.com>
+ *
+ * liBDSM is released under LGPLv2.1 (or later) and is also available
+ * under a commercial license.
+ *****************************************************************************
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+/**
+ * @file smb_dir.h
+ * @brief Directory operations
+ */
+
+#ifndef _SMB_DIR_H_
+#define _SMB_DIR_H_
+
+#include "bdsm/smb_dir.h"
+
+#endif

+ 55 - 0
src/smb_file.c

@@ -231,3 +231,58 @@ ssize_t   smb_fseek(smb_session *s, smb_fd fd, ssize_t offset, int whence)
 
     return (file->readp);
 }
+
+uint32_t  smb_rm_file(smb_session *s, smb_tid tid, const char *path)
+{
+    smb_message           *req_msg, resp_msg;
+    smb_rm_file_req       req;
+    smb_rm_file_resp      *resp;
+    size_t                utf_pattern_len;
+    char                  *utf_pattern;
+
+    if (s == NULL)
+        return DSM_ERROR_INVALID_SESSION;
+    if (tid == -1)
+        return DSM_ERROR_INVALID_TID;
+    if (path == NULL)
+        return DSM_ERROR_INVALID_PATH;
+
+    utf_pattern_len = smb_to_utf16(path, strlen(path) + 1, &utf_pattern);
+    if (utf_pattern_len == 0)
+        return DSM_ERROR_UTF16_CONV_FAILED;
+
+    req_msg = smb_message_new(SMB_CMD_RMFILE);
+    if (!req_msg)
+    {
+        free(utf_pattern);
+        return (DSM_ERROR_INTERNAL);
+    }
+
+    req_msg->packet->header.tid = (uint16_t)tid;
+    req_msg->packet->header.flags2 = SMB_FLAGS2_LONG_NAMES;
+
+    SMB_MSG_INIT_PKT(req);
+    req.wct               = 0x01; // Must be 1
+    req.search_attributes = SMB_ATTR_NORMAL;
+    req.bct               = (uint16_t)(utf_pattern_len + 1);
+    req.buffer_format     = 0x04; // Must be 4
+    SMB_MSG_PUT_PKT(req_msg, req);
+    smb_message_append(req_msg, utf_pattern, utf_pattern_len);
+
+    smb_session_send_msg(s, req_msg);
+    smb_message_destroy(req_msg);
+
+    free(utf_pattern);
+
+    if (!smb_session_recv_msg(s, &resp_msg))
+        return DSM_ERROR_INVALID_RCV_MESS;
+
+    if (resp_msg.packet->header.status != NT_STATUS_SUCCESS)
+        return (resp_msg.packet->header.status);
+
+    resp = (smb_rm_file_resp *)resp_msg.packet->payload;
+    if ((resp->wct != 0) || (resp->bct != 0))
+        return DSM_ERROR_INVALID_RCV_MESS;
+
+    return NT_STATUS_SUCCESS;
+}

+ 31 - 0
src/smb_packets.h

@@ -274,6 +274,37 @@ typedef struct
     uint16_t        bct;
 } __attribute__((packed))   smb_read_resp;
 
+//-> Remove File
+typedef struct
+{
+    uint8_t         wct;                // 0x01
+    uint16_t        search_attributes;  // 0x0000 for "normal" (not hidden/ystem) files
+    uint16_t        bct;                // >= 2
+    uint8_t         buffer_format;      // 0x04
+} __attribute__((packed))   smb_rm_file_req;
+
+//<- Remove File
+typedef struct
+{
+    uint8_t         wct;                // 0x00
+    uint16_t        bct;                // 0x0000
+} __attribute__((packed))   smb_rm_file_resp;
+
+//-> Remove Directory
+typedef struct
+{
+    uint8_t         wct;                // 0x01
+    uint16_t        bct;                // >= 2
+    uint8_t         buffer_format;      // 0x04
+} __attribute__((packed))   smb_rm_dir_req;
+
+//<- Remove Directory
+typedef struct
+{
+    uint8_t         wct;                // 0x00
+    uint16_t        bct;                // 0x0000
+} __attribute__((packed))   smb_rm_dir_resp;
+
 //-> Trans
 typedef struct
 {