root/source4/libcli/smb2/util.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. smb2_util_close
  2. smb2_util_unlink
  3. smb2_util_rmdir
  4. smb2_util_mkdir
  5. smb2_util_setatr
  6. smb2_deltree

   1 /* 
   2    Unix SMB/CIFS implementation.
   3 
   4    SMB2 client utility functions
   5 
   6    Copyright (C) Andrew Tridgell 2005
   7    
   8    This program is free software; you can redistribute it and/or modify
   9    it under the terms of the GNU General Public License as published by
  10    the Free Software Foundation; either version 3 of the License, or
  11    (at your option) any later version.
  12    
  13    This program is distributed in the hope that it will be useful,
  14    but WITHOUT ANY WARRANTY; without even the implied warranty of
  15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16    GNU General Public License for more details.
  17    
  18    You should have received a copy of the GNU General Public License
  19    along with this program.  If not, see <http://www.gnu.org/licenses/>.
  20 */
  21 
  22 #include "includes.h"
  23 #include "libcli/raw/libcliraw.h"
  24 #include "libcli/raw/raw_proto.h"
  25 #include "libcli/smb2/smb2.h"
  26 #include "libcli/smb2/smb2_calls.h"
  27 #include "libcli/smb_composite/smb_composite.h"
  28 
  29 /*
  30   simple close wrapper with SMB2
  31 */
  32 NTSTATUS smb2_util_close(struct smb2_tree *tree, struct smb2_handle h)
     /* [<][>][^][v][top][bottom][index][help] */
  33 {
  34         struct smb2_close c;
  35 
  36         ZERO_STRUCT(c);
  37         c.in.file.handle = h;
  38 
  39         return smb2_close(tree, &c);
  40 }
  41 
  42 /*
  43   unlink a file with SMB2
  44 */
  45 NTSTATUS smb2_util_unlink(struct smb2_tree *tree, const char *fname)
     /* [<][>][^][v][top][bottom][index][help] */
  46 {
  47         union smb_unlink io;
  48         
  49         ZERO_STRUCT(io);
  50         io.unlink.in.pattern = fname;
  51 
  52         return smb2_composite_unlink(tree, &io);
  53 }
  54 
  55 
  56 /*
  57   rmdir with SMB2
  58 */
  59 NTSTATUS smb2_util_rmdir(struct smb2_tree *tree, const char *dname)
     /* [<][>][^][v][top][bottom][index][help] */
  60 {
  61         struct smb_rmdir io;
  62         
  63         ZERO_STRUCT(io);
  64         io.in.path = dname;
  65 
  66         return smb2_composite_rmdir(tree, &io);
  67 }
  68 
  69 
  70 /*
  71   mkdir with SMB2
  72 */
  73 NTSTATUS smb2_util_mkdir(struct smb2_tree *tree, const char *dname)
     /* [<][>][^][v][top][bottom][index][help] */
  74 {
  75         union smb_mkdir io;
  76         
  77         ZERO_STRUCT(io);
  78         io.mkdir.level = RAW_MKDIR_MKDIR;
  79         io.mkdir.in.path = dname;
  80 
  81         return smb2_composite_mkdir(tree, &io);
  82 }
  83 
  84 
  85 /*
  86   set file attribute with SMB2
  87 */
  88 NTSTATUS smb2_util_setatr(struct smb2_tree *tree, const char *name, uint32_t attrib)
     /* [<][>][^][v][top][bottom][index][help] */
  89 {
  90         union smb_setfileinfo io;
  91         
  92         ZERO_STRUCT(io);
  93         io.basic_info.level = RAW_SFILEINFO_BASIC_INFORMATION;
  94         io.basic_info.in.file.path = name;
  95         io.basic_info.in.attrib = attrib;
  96 
  97         return smb2_composite_setpathinfo(tree, &io);
  98 }
  99 
 100 
 101 
 102 
 103 /* 
 104    recursively descend a tree deleting all files
 105    returns the number of files deleted, or -1 on error
 106 */
 107 int smb2_deltree(struct smb2_tree *tree, const char *dname)
     /* [<][>][^][v][top][bottom][index][help] */
 108 {
 109         NTSTATUS status;
 110         uint32_t total_deleted = 0;
 111         uint_t count, i;
 112         union smb_search_data *list;
 113         TALLOC_CTX *tmp_ctx = talloc_new(tree);
 114         struct smb2_find f;
 115         struct smb2_create create_parm;
 116 
 117         /* it might be a file */
 118         status = smb2_util_unlink(tree, dname);
 119         if (NT_STATUS_IS_OK(status)) {
 120                 talloc_free(tmp_ctx);
 121                 return 1;
 122         }
 123         if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND) ||
 124             NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_PATH_NOT_FOUND) ||
 125             NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_FILE)) {
 126                 talloc_free(tmp_ctx);
 127                 return 0;
 128         }
 129 
 130         if (NT_STATUS_EQUAL(status, NT_STATUS_CANNOT_DELETE)) {
 131                 /* it could be read-only */
 132                 status = smb2_util_setatr(tree, dname, FILE_ATTRIBUTE_NORMAL);
 133                 status = smb2_util_unlink(tree, dname);
 134         }
 135         if (NT_STATUS_IS_OK(status)) {
 136                 talloc_free(tmp_ctx);
 137                 return 1;
 138         }
 139 
 140         ZERO_STRUCT(create_parm);
 141         create_parm.in.desired_access = SEC_FILE_READ_DATA;
 142         create_parm.in.share_access = 
 143                 NTCREATEX_SHARE_ACCESS_READ|
 144                 NTCREATEX_SHARE_ACCESS_WRITE;
 145         create_parm.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
 146         create_parm.in.create_disposition = NTCREATEX_DISP_OPEN;
 147         create_parm.in.fname = dname;
 148 
 149         status = smb2_create(tree, tmp_ctx, &create_parm);
 150         if (NT_STATUS_IS_ERR(status)) {
 151                 DEBUG(2,("Failed to open %s - %s\n", dname, nt_errstr(status)));
 152                 talloc_free(tmp_ctx);
 153                 return -1;
 154         }
 155         
 156 
 157         ZERO_STRUCT(f);
 158         f.in.file.handle       = create_parm.out.file.handle;
 159         f.in.max_response_size = 0x10000;
 160         f.in.level             = SMB2_FIND_NAME_INFO;
 161         f.in.pattern           = "*";
 162 
 163         status = smb2_find_level(tree, tmp_ctx, &f, &count, &list);
 164         if (NT_STATUS_IS_ERR(status)) {
 165                 DEBUG(2,("Failed to list %s - %s\n", 
 166                          dname, nt_errstr(status)));
 167                 smb2_util_close(tree, create_parm.out.file.handle);
 168                 talloc_free(tmp_ctx);
 169                 return -1;
 170         }
 171 
 172         for (i=0;i<count;i++) {
 173                 char *name;
 174                 if (strcmp(".", list[i].name_info.name.s) == 0 ||
 175                     strcmp("..", list[i].name_info.name.s) == 0) {
 176                         continue;
 177                 }
 178                 name = talloc_asprintf(tmp_ctx, "%s\\%s", dname, list[i].name_info.name.s);
 179                 status = smb2_util_unlink(tree, name);
 180                 if (NT_STATUS_EQUAL(status, NT_STATUS_CANNOT_DELETE)) {
 181                         /* it could be read-only */
 182                         status = smb2_util_setatr(tree, name, FILE_ATTRIBUTE_NORMAL);
 183                         status = smb2_util_unlink(tree, name);
 184                 }
 185 
 186                 if (NT_STATUS_EQUAL(status, NT_STATUS_FILE_IS_A_DIRECTORY)) {
 187                         int ret;
 188                         ret = smb2_deltree(tree, name);
 189                         if (ret > 0) total_deleted += ret;
 190                 }
 191                 talloc_free(name);
 192                 if (NT_STATUS_IS_OK(status)) {
 193                         total_deleted++;
 194                 }
 195         }
 196 
 197         smb2_util_close(tree, create_parm.out.file.handle);
 198 
 199         status = smb2_util_rmdir(tree, dname);
 200         if (NT_STATUS_EQUAL(status, NT_STATUS_CANNOT_DELETE)) {
 201                 /* it could be read-only */
 202                 status = smb2_util_setatr(tree, dname, FILE_ATTRIBUTE_NORMAL);
 203                 status = smb2_util_rmdir(tree, dname);
 204         }
 205 
 206         if (NT_STATUS_IS_ERR(status)) {
 207                 DEBUG(2,("Failed to delete %s - %s\n", 
 208                          dname, nt_errstr(status)));
 209                 talloc_free(tmp_ctx);
 210                 return -1;
 211         }
 212 
 213         talloc_free(tmp_ctx);
 214 
 215         return total_deleted;
 216 }

/* [<][>][^][v][top][bottom][index][help] */