Browse Source

Adds Read packet definition. Moves some code around

Julien 'Lta' BALLET 11 years ago
parent
commit
a7c4b82369
11 changed files with 363 additions and 258 deletions
  1. 1 0
      Makefile
  2. 0 5
      dsm.c
  3. 6 0
      include/bdsm.h
  4. 40 3
      include/bdsm/smb_defs.h
  5. 29 0
      include/bdsm/smb_file.h
  6. 15 0
      include/bdsm/smb_session.h
  7. 2 14
      include/bdsm/smb_share.h
  8. 134 0
      src/smb_file.c
  9. 1 1
      src/smb_message.c
  10. 134 2
      src/smb_session.c
  11. 1 233
      src/smb_share.c

+ 1 - 0
Makefile

@@ -36,6 +36,7 @@ UTIL_SRC		= dsm.c 							    \
 							src/smb_session.c				\
 							src/smb_ntlm.c					\
 							src/smb_share.c					\
+							src/smb_file.c					\
 							src/context.c
 
 UTIL_OBJS		= $(UTIL_SRC:.c=.o)

+ 0 - 5
dsm.c

@@ -33,11 +33,6 @@
 #define NBT_TCP_PORT        139
 
 #include "bdsm.h"
-#include "bdsm/netbios_utils.h"
-#include "bdsm/netbios_session.h"
-#include "bdsm/smb_session.h"
-#include "bdsm/smb_ntlm.h"
-#include "bdsm/smb_share.h"
 
 #include <openssl/md4.h>
 #include <openssl/md5.h>

+ 6 - 0
include/bdsm.h

@@ -20,5 +20,11 @@
 #define __BDSM_H_
 
 #include "bdsm/context.h"
+#include "bdsm/netbios_utils.h"
+#include "bdsm/netbios_session.h"
+#include "bdsm/smb_session.h"
+#include "bdsm/smb_ntlm.h"
+#include "bdsm/smb_share.h"
+#include "bdsm/smb_file.h"
 
 #endif

+ 40 - 3
include/bdsm/smb_defs.h

@@ -140,9 +140,9 @@
 #define NT_STATUS_ACCESS_DENIED             0xc0000022
 
 #define SMB_ANDX_MEMBERS  \
-  uint8_t         andx;         /* 0xff when no other command (recommended :)*/\
-  uint8_t         reserved;     /* 0x00 */                                     \
-  uint16_t        andx_offset;  /* 0x00 when no other command */
+  uint8_t         andx;           /* 0xff when no other command (do this :)*/  \
+  uint8_t         andx_reserved;  /* 0x00 */                                   \
+  uint16_t        andx_offset;    /* 0x00 when no other command */
 
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -277,6 +277,7 @@ typedef struct
 } __attribute__((packed))   smb_create_resp_t;
 
 
+
 //// Close File
 
 typedef struct
@@ -289,6 +290,42 @@ typedef struct
 
 
 
+//// Read File
+
+typedef struct
+{
+  uint8_t         wct;                // 12
+  SMB_ANDX_MEMBERS
+  uint16_t        fid;
+  uint32_t        offset;
+  uint16_t        max_count_low;
+  uint16_t        min_count;
+  uint32_t        max_count_high;     // Continuation of max_count_low field
+  uint16_t        remaining;
+  uint32_t        high_offset;
+  uint16_t        bct;                // 0
+} __attribute__((packed))   smb_read_req_t;
+
+typedef struct
+{
+  uint8_t         wct;                // 12
+  SMB_ANDX_MEMBERS
+  uint16_t        fid;
+  uint16_t        remaining;
+  uint16_t        compact_mode;
+  uint16_t        reserved;
+  uint16_t        data_len_low;
+  uint16_t        data_offset;
+  uint32_t        data_len_high;
+  uint32_t        reserved2;
+  uint16_t        reserved3;
+  uint16_t        bct;
+  uint8_t         file[];
+} __attribute__((packed))   smb_read_resp_t;
+
+
+
+
 ////////////////////////////////////////////////////////////////////////////////
 // Main structures for holding packet data and building packets
 

+ 29 - 0
include/bdsm/smb_file.h

@@ -0,0 +1,29 @@
+//---------------------------------------------------------------------------
+//  __________________    _________  _____            _____  .__         ._.
+//  \______   \______ \  /   _____/ /     \          /  _  \ |__| ____   | |
+//   |    |  _/|    |  \ \_____  \ /  \ /  \        /  /_\  \|  _/ __ \  | |
+//   |    |   \|    `   \/        /    Y    \      /    |    |  \  ___/   \|
+//   |______  /_______  /_______  \____|__  / /\   \____|__  |__|\___ |   __
+//          \/        \/        \/        \/  )/           \/        \/   \/
+//
+// This file is part of libdsm. Copyright © 2014 VideoLabs SAS
+//
+// Author: Julien 'Lta' BALLET <contact@lta.io>
+//
+// This program is free software. It comes without any warranty, to the extent
+// permitted by applicable law. You can redistribute it and/or modify it under
+// the terms of the Do What The Fuck You Want To Public License, Version 2, as
+// published by Sam Hocevar. See the COPYING file for more details.
+//----------------------------------------------------------------------------
+
+#ifndef __BDSM_SMB_FILE_H_
+#define __BDSM_SMB_FILE_H_
+
+#include "bdsm/smb_session.h"
+
+smb_fd    smb_fopen(smb_session_t *s, smb_tid tid, const char *path,
+                   uint32_t mod);
+void      smb_fclose(smb_session_t *s, smb_fd);
+ssize_t   smb_fread(smb_session_t *s, smb_fd fd, void *buf, size_t *buf_size);
+
+#endif

+ 15 - 0
include/bdsm/smb_session.h

@@ -91,11 +91,26 @@ typedef struct
 smb_session_t   *smb_session_new();
 void            smb_session_destroy(smb_session_t *s);
 
+
+
+void            smb_session_share_add(smb_session_t *s, smb_share_t *share);
+smb_share_t     *smb_session_share_get(smb_session_t *s, smb_tid tid);
+smb_share_t     *smb_session_share_remove(smb_session_t *s, smb_tid tid);
+int             smb_session_file_add(smb_session_t *s, smb_tid tid,
+                                     smb_file_t *f);
+smb_file_t      *smb_session_file_get(smb_session_t *s, smb_fd fd);
+smb_file_t      *smb_session_file_remove(smb_session_t *s, smb_fd fd);
+
+
+
 int             smb_session_send_msg(smb_session_t *s, smb_message_t *msg);
 // msg->packet will be updated to point on received data. You don't own this
 // memory. It'll be reused on next recv_msg
 size_t          smb_session_recv_msg(smb_session_t *s, smb_message_t *msg);
 int             smb_session_connect(smb_session_t *s, char *name, uint32_t ip);
+
+
+
 int             smb_negotiate(smb_session_t *s);
 int             smb_authenticate(smb_session_t *s, const char *domain,
                                  const char *user, const char *password);

+ 2 - 14
include/bdsm/smb_share.h

@@ -21,19 +21,7 @@
 
 #include "bdsm/smb_session.h"
 
-void        smb_session_share_add(smb_session_t *s, smb_share_t *share);
-smb_share_t *smb_session_share_get(smb_session_t *s, smb_tid tid);
-smb_share_t *smb_session_share_remove(smb_session_t *s, smb_tid tid);
-
-int         smb_session_file_add(smb_session_t *s, smb_tid tid, smb_file_t *f);
-smb_file_t  *smb_session_file_get(smb_session_t *s, smb_fd fd);
-smb_file_t  *smb_session_file_remove(smb_session_t *s, smb_fd fd);
-
-
-smb_tid     smb_tree_connect(smb_session_t *s, const char *path);
-int         smb_tree_disconnect(smb_session_t *s, smb_tid tid);
-smb_fd      smb_fopen(smb_session_t *s, smb_tid tid, const char *path,
-                      uint32_t mod);
-void        smb_fclose(smb_session_t *s, smb_fd);
+smb_tid         smb_tree_connect(smb_session_t *s, const char *path);
+int             smb_tree_disconnect(smb_session_t *s, smb_tid tid);
 
 #endif

+ 134 - 0
src/smb_file.c

@@ -0,0 +1,134 @@
+//---------------------------------------------------------------------------
+//  __________________    _________  _____            _____  .__         ._.
+//  \______   \______ \  /   _____/ /     \          /  _  \ |__| ____   | |
+//   |    |  _/|    |  \ \_____  \ /  \ /  \        /  /_\  \|  _/ __ \  | |
+//   |    |   \|    `   \/        /    Y    \      /    |    |  \  ___/   \|
+//   |______  /_______  /_______  \____|__  / /\   \____|__  |__|\___ |   __
+//          \/        \/        \/        \/  )/           \/        \/   \/
+//
+// This file is part of libdsm. Copyright © 2014 VideoLabs SAS
+//
+// Author: Julien 'Lta' BALLET <contact@lta.io>
+//
+// This program is free software. It comes without any warranty, to the extent
+// permitted by applicable law. You can redistribute it and/or modify it under
+// the terms of the Do What The Fuck You Want To Public License, Version 2, as
+// published by Sam Hocevar. See the COPYING file for more details.
+//----------------------------------------------------------------------------
+
+#include <assert.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdio.h>
+
+#include "bdsm/smb_utils.h"
+#include "bdsm/smb_file.h"
+
+smb_fd      smb_fopen(smb_session_t *s, smb_tid tid, const char *path,
+                      uint32_t o_flags)
+{
+  smb_share_t       *share;
+  smb_file_t        *file;
+  smb_message_t     *req_msg, resp_msg;
+  smb_create_req_t  *req;
+  smb_create_resp_t *resp;
+  size_t            path_len;
+  int               res;
+
+  assert(s != NULL && path != NULL);
+  if ((share = smb_session_share_get(s, tid)) == NULL)
+    return (0);
+
+  req_msg = smb_message_new(SMB_CMD_CREATE, 128);
+
+  // Set SMB Headers
+  smb_message_set_default_flags(req_msg);
+  smb_message_set_andx_members(req_msg);
+  req_msg->packet->header.tid = tid;
+
+  // Create AndX Params
+  req = (smb_create_req_t *)req_msg->packet->payload;
+  req->wct            = 24;
+  req->flags          = 0;
+  req->root_fid       = 0;
+  req->access_mask    = o_flags;
+  req->alloc_size     = 0;
+  req->file_attr      = 0;
+  req->share_access   = SMB_SHARE_READ | SMB_SHARE_WRITE;
+  req->disposition    = 1;  // 1 = Open and file if doesn't exist
+  req->create_opts    = 0;  // We dont't support create
+  req->impersonation  = 2;  // ?????
+  req->security_flags = 0;  // ???
+
+  // Create AndX 'Body'
+  smb_message_advance(req_msg, sizeof(smb_create_req_t));
+  smb_message_put8(req_msg, 0);   // Align beginning of path
+  path_len = smb_message_put_utf16(req_msg, "", path, strlen(path) + 1);
+  // smb_message_put16(req_msg, 0);  // ??
+  req->path_length  = path_len;
+  req->bct          = path_len + 1;
+
+  res = smb_session_send_msg(s, req_msg);
+  smb_message_destroy(req_msg);
+  if (!res)
+    return (0);
+
+  if (!smb_session_recv_msg(s, &resp_msg))
+    return (0);
+  if (resp_msg.packet->header.status != NT_STATUS_SUCCESS)
+    return (0);
+
+  resp = (smb_create_resp_t *)resp_msg.packet->payload;
+  file = calloc(1, sizeof(smb_file_t));
+  assert(file != NULL);
+
+  file->fid           = resp->fid;
+  file->tid           = tid;
+  file->created       = resp->created;
+  file->accessed      = resp->accessed;
+  file->written       = resp->written;
+  file->changed       = resp->changed;
+  file->alloc_size    = resp->alloc_size;
+  file->size          = resp->size;
+  file->attr          = resp->attr;
+
+  smb_session_file_add(s, tid, file); // XXX Check return
+
+  return (SMB_FD(tid, file->fid));
+}
+
+void        smb_fclose(smb_session_t *s, smb_fd fd)
+{
+  smb_file_t        *file;
+  smb_message_t     *msg;
+  smb_close_req_t   *req;
+
+  assert(s != NULL && fd);
+
+  if ((file = smb_session_file_remove(s, fd)) == NULL)
+    return;
+
+  msg = smb_message_new(SMB_CMD_CLOSE, 64);
+  req = (smb_close_req_t *)msg->packet->payload;
+
+  msg->packet->header.tid = SMB_FD_TID(fd);
+
+  smb_message_advance(msg, sizeof(smb_close_req_t));
+  req->wct        = 3;
+  req->fid        = SMB_FD_FID(fd);
+  req->last_write = ~0;
+  req->bct        = 0;
+
+  // We don't check for succes or failure, since we actually don't really
+  // care about creating a potentiel leak server side.
+  smb_session_send_msg(s, msg);
+  smb_session_recv_msg(s, 0);
+}
+
+ssize_t   smb_fread(smb_session_t *s, smb_fd fd, void *buf, size_t *buf_size)
+{
+  smb_message_t     *req_msg, resp_msg;
+  smb_read_req_t    *req;
+  smb_read_resp_t   *resp;
+}

+ 1 - 1
src/smb_message.c

@@ -155,6 +155,6 @@ void            smb_message_set_andx_members(smb_message_t *msg)
 
   req = (smb_session_req_t *)msg->packet->payload;
   req->andx           = 0xff;
-  req->reserved       = 0;
+  req->andx_reserved  = 0;
   req->andx_offset    = 0;
 }

+ 134 - 2
src/smb_session.c

@@ -117,6 +117,139 @@ size_t          smb_session_recv_msg(smb_session_t *s, smb_message_t *msg)
   return (payload_size - sizeof(smb_header_t));
 }
 
+
+void        smb_session_share_add(smb_session_t *s, smb_share_t *share)
+{
+  smb_share_t *iter;
+
+  assert(s != NULL && share != NULL);
+
+  if (s->shares == NULL)
+  {
+    s->shares = share;
+    return;
+  }
+
+  iter = s->shares;
+  while(iter->next != NULL)
+    iter = iter->next;
+  iter->next = share;
+}
+
+smb_share_t *smb_session_share_get(smb_session_t *s, smb_tid tid)
+{
+  smb_share_t *iter;
+
+  assert(s != NULL && tid);
+
+  iter = s->shares;
+  while(iter != NULL && iter->tid != tid)
+    iter = iter->next;
+
+  return (iter);
+}
+
+smb_share_t *smb_session_share_remove(smb_session_t *s, smb_tid tid)
+{
+  smb_share_t *iter, *keep;
+
+  assert(s != NULL && tid);
+  iter = s->shares;
+
+  if (iter == NULL)
+    return (NULL);
+  if (iter->tid == tid)
+  {
+    s->shares = s->shares->next;
+    return (iter);
+  }
+
+  while(iter->next != NULL && iter->next->tid != tid)
+    iter = iter->next;
+
+  if (iter->next != NULL) // We found it
+  {
+    keep = iter->next;
+    iter->next = iter->next->next;
+    return (keep);
+  }
+  return (NULL);
+}
+
+int         smb_session_file_add(smb_session_t *s, smb_tid tid, smb_file_t *f)
+{
+  smb_share_t *share;
+  smb_file_t  *iter;
+
+  assert(s != NULL && tid && f != NULL);
+
+  if ((share = smb_session_share_get(s, tid)) == NULL)
+    return (0);
+
+  if (share->files == NULL)
+    share->files = f;
+  else
+  {
+    iter = share->files;
+    while (iter->next != NULL)
+      iter = iter->next;
+    iter->next = f;
+  }
+
+  return (1);
+}
+
+smb_file_t  *smb_session_file_get(smb_session_t *s, smb_fd fd)
+{
+  smb_share_t *share;
+  smb_file_t  *iter;
+
+  assert(s != NULL && fd);
+
+  if ((share = smb_session_share_get(s, SMB_FD_TID(fd))) == NULL)
+    return (NULL);
+
+  iter = share->files;
+  while(iter != NULL && iter->fid != SMB_FD_FID(fd))
+    iter = iter->next;
+
+  return (iter);
+}
+
+smb_file_t  *smb_session_file_remove(smb_session_t *s, smb_fd fd)
+{
+  smb_share_t *share;
+  smb_file_t  *iter, *keep;
+
+  assert(s != NULL && fd);
+
+  if ((share = smb_session_share_get(s, SMB_FD_TID(fd))) == NULL)
+    return (NULL);
+
+  iter = share->files;
+
+  if (iter == NULL)
+    return (NULL);
+  if (iter->fid == SMB_FD_FID(fd))
+  {
+    share->files = iter->next;
+    return (iter);
+  }
+
+  while(iter->next != NULL && iter->next->fid != SMB_FD_TID(fd))
+    iter = iter->next;
+  if (iter->next != NULL)
+  {
+    keep = iter->next;
+    iter->next = iter->next->next;
+    return (keep);
+  }
+  else
+    return (NULL);
+}
+
+
+
 int             smb_negotiate(smb_session_t *s)
 {
   const char            *dialects[] = SMB_DIALECTS;
@@ -183,11 +316,10 @@ int             smb_authenticate(smb_session_t *s, const char *domain,
 
   msg = smb_message_new(SMB_CMD_SETUP, 512);
   smb_message_set_default_flags(msg);
+  smb_message_set_andx_members(msg);
   req = (smb_session_req_t *)msg->packet->payload;
 
   req->wct              = (sizeof(smb_session_req_t) - 3) / 2;
-  req->andx             = 0xFF;
-  req->reserved         = 0;
   req->max_buffer       = NETBIOS_SESSION_PAYLOAD;
   req->max_buffer      -= sizeof(netbios_session_packet_t);
   req->max_buffer      -= sizeof(smb_packet_t);

+ 1 - 233
src/smb_share.c

@@ -25,135 +25,6 @@
 #include "bdsm/smb_utils.h"
 #include "bdsm/smb_share.h"
 
-void        smb_session_share_add(smb_session_t *s, smb_share_t *share)
-{
-  smb_share_t *iter;
-
-  assert(s != NULL && share != NULL);
-
-  if (s->shares == NULL)
-  {
-    s->shares = share;
-    return;
-  }
-
-  iter = s->shares;
-  while(iter->next != NULL)
-    iter = iter->next;
-  iter->next = share;
-}
-
-smb_share_t *smb_session_share_get(smb_session_t *s, smb_tid tid)
-{
-  smb_share_t *iter;
-
-  assert(s != NULL && tid);
-
-  iter = s->shares;
-  while(iter != NULL && iter->tid != tid)
-    iter = iter->next;
-
-  return (iter);
-}
-
-smb_share_t *smb_session_share_remove(smb_session_t *s, smb_tid tid)
-{
-  smb_share_t *iter, *keep;
-
-  assert(s != NULL && tid);
-  iter = s->shares;
-
-  if (iter == NULL)
-    return (NULL);
-  if (iter->tid == tid)
-  {
-    s->shares = s->shares->next;
-    return (iter);
-  }
-
-  while(iter->next != NULL && iter->next->tid != tid)
-    iter = iter->next;
-
-  if (iter->next != NULL) // We found it
-  {
-    keep = iter->next;
-    iter->next = iter->next->next;
-    return (keep);
-  }
-  return (NULL);
-}
-
-int         smb_session_file_add(smb_session_t *s, smb_tid tid, smb_file_t *f)
-{
-  smb_share_t *share;
-  smb_file_t  *iter;
-
-  assert(s != NULL && tid && f != NULL);
-
-  if ((share = smb_session_share_get(s, tid)) == NULL)
-    return (0);
-
-  if (share->files == NULL)
-    share->files = f;
-  else
-  {
-    iter = share->files;
-    while (iter->next != NULL)
-      iter = iter->next;
-    iter->next = f;
-  }
-
-  return (1);
-}
-
-smb_file_t  *smb_session_file_get(smb_session_t *s, smb_fd fd)
-{
-  smb_share_t *share;
-  smb_file_t  *iter;
-
-  assert(s != NULL && fd);
-
-  if ((share = smb_session_share_get(s, SMB_FD_TID(fd))) == NULL)
-    return (NULL);
-
-  iter = share->files;
-  while(iter != NULL && iter->fid != SMB_FD_FID(fd))
-    iter = iter->next;
-
-  return (iter);
-}
-
-smb_file_t  *smb_session_file_remove(smb_session_t *s, smb_fd fd)
-{
-  smb_share_t *share;
-  smb_file_t  *iter, *keep;
-
-  assert(s != NULL && fd);
-
-  if ((share = smb_session_share_get(s, SMB_FD_TID(fd))) == NULL)
-    return (NULL);
-
-  iter = share->files;
-
-  if (iter == NULL)
-    return (NULL);
-  if (iter->fid == SMB_FD_FID(fd))
-  {
-    share->files = iter->next;
-    return (iter);
-  }
-
-  while(iter->next != NULL && iter->next->fid != SMB_FD_TID(fd))
-    iter = iter->next;
-  if (iter->next != NULL)
-  {
-    keep = iter->next;
-    iter->next = iter->next->next;
-    return (keep);
-  }
-  else
-    return (NULL);
-}
 
 smb_tid         smb_tree_connect(smb_session_t *s, const char *path)
 {
@@ -169,15 +40,13 @@ smb_tid         smb_tree_connect(smb_session_t *s, const char *path)
 
   // Packet headers
   smb_message_set_default_flags(req_msg);
+  smb_message_set_andx_members(req_msg);
   req_msg->packet->header.tid   = 0xffff; // Behavior of libsmbclient
 
   // Packet payload
   req = (smb_tree_connect_req_t *)req_msg->packet->payload;
   smb_message_advance(req_msg, sizeof(smb_tree_connect_req_t));
   req->wct          = 4;
-  req->andx         = 0xff;
-  req->reserved     = 0;
-  req->andx_offset  = 0;
   req->flags        = 0x0c; // (??)
   req->passwd_len   = 1;    // Null byte
 
@@ -219,104 +88,3 @@ int           smb_tree_disconnect(smb_session_t *s, smb_tid tid)
   return (0);
 }
 
-smb_fd      smb_fopen(smb_session_t *s, smb_tid tid, const char *path,
-                      uint32_t o_flags)
-{
-  smb_share_t       *share;
-  smb_file_t        *file;
-  smb_message_t     *req_msg, resp_msg;
-  smb_create_req_t  *req;
-  smb_create_resp_t *resp;
-  size_t            path_len;
-  int               res;
-
-  assert(s != NULL && path != NULL);
-  if ((share = smb_session_share_get(s, tid)) == NULL)
-    return (0);
-
-  req_msg = smb_message_new(SMB_CMD_CREATE, 128);
-
-  // Set SMB Headers
-  smb_message_set_default_flags(req_msg);
-  smb_message_set_andx_members(req_msg);
-  req_msg->packet->header.tid = tid;
-
-  // Create AndX Params
-  req = (smb_create_req_t *)req_msg->packet->payload;
-  req->wct            = 24;
-  req->flags          = 0;
-  req->root_fid       = 0;
-  req->access_mask    = o_flags;
-  req->alloc_size     = 0;
-  req->file_attr      = 0;
-  req->share_access   = SMB_SHARE_READ | SMB_SHARE_WRITE;
-  req->disposition    = 1;  // 1 = Open and file if doesn't exist
-  req->create_opts    = 0;  // We dont't support create
-  req->impersonation  = 2;  // ?????
-  req->security_flags = 0;  // ???
-
-  // Create AndX 'Body'
-  smb_message_advance(req_msg, sizeof(smb_create_req_t));
-  smb_message_put8(req_msg, 0);   // Align beginning of path
-  path_len = smb_message_put_utf16(req_msg, "", path, strlen(path) + 1);
-  // smb_message_put16(req_msg, 0);  // ??
-  req->path_length  = path_len;
-  req->bct          = path_len + 1;
-
-  res = smb_session_send_msg(s, req_msg);
-  smb_message_destroy(req_msg);
-  if (!res)
-    return (0);
-
-  if (!smb_session_recv_msg(s, &resp_msg))
-    return (0);
-  if (resp_msg.packet->header.status != NT_STATUS_SUCCESS)
-    return (0);
-
-  resp = (smb_create_resp_t *)resp_msg.packet->payload;
-  file = calloc(1, sizeof(smb_file_t));
-  assert(file != NULL);
-
-  file->fid           = resp->fid;
-  file->tid           = tid;
-  file->created       = resp->created;
-  file->accessed      = resp->accessed;
-  file->written       = resp->written;
-  file->changed       = resp->changed;
-  file->alloc_size    = resp->alloc_size;
-  file->size          = resp->size;
-  file->attr          = resp->attr;
-
-  smb_session_file_add(s, tid, file); // XXX Check return
-
-  return (SMB_FD(tid, file->fid));
-}
-
-void        smb_fclose(smb_session_t *s, smb_fd fd)
-{
-  smb_file_t        *file;
-  smb_message_t     *msg;
-  smb_close_req_t   *req;
-
-  assert(s != NULL && fd);
-
-  if ((file = smb_session_file_remove(s, fd)) == NULL)
-    return;
-
-  msg = smb_message_new(SMB_CMD_CLOSE, 64);
-  req = (smb_close_req_t *)msg->packet->payload;
-
-  msg->packet->header.tid = SMB_FD_TID(fd);
-
-  smb_message_advance(msg, sizeof(smb_close_req_t));
-  req->wct        = 3;
-  req->fid        = SMB_FD_FID(fd);
-  req->last_write = ~0;
-  req->bct        = 0;
-
-  // We don't check for succes or failure, since we actually don't really
-  // care about creating a potentiel leak server side.
-  smb_session_send_msg(s, msg);
-  smb_session_recv_msg(s, 0);
-}
-