root/source4/libcli/smb_composite/smb2.c

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

DEFINITIONS

This source file includes following definitions.
  1. continue_close
  2. continue_unlink
  3. smb2_composite_unlink_send
  4. smb2_composite_unlink
  5. continue_mkdir
  6. smb2_composite_mkdir_send
  7. smb2_composite_mkdir
  8. continue_rmdir
  9. smb2_composite_rmdir_send
  10. smb2_composite_rmdir
  11. continue_setpathinfo_close
  12. continue_setpathinfo
  13. smb2_composite_setpathinfo_send
  14. smb2_composite_setpathinfo

   1 /* 
   2    Unix SMB/CIFS implementation.
   3 
   4    Copyright (C) Andrew Tridgell 2008
   5    
   6    This program is free software; you can redistribute it and/or modify
   7    it under the terms of the GNU General Public License as published by
   8    the Free Software Foundation; either version 3 of the License, or
   9    (at your option) any later version.
  10    
  11    This program is distributed in the hope that it will be useful,
  12    but WITHOUT ANY WARRANTY; without even the implied warranty of
  13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14    GNU General Public License for more details.
  15    
  16    You should have received a copy of the GNU General Public License
  17    along with this program.  If not, see <http://www.gnu.org/licenses/>.
  18 */
  19 /*
  20   a composite API for making SMB-like calls using SMB2. This is useful
  21   as SMB2 often requires more than one requests where a single SMB
  22   request would do. In converting code that uses SMB to use SMB2,
  23   these routines make life a lot easier
  24 */
  25 
  26 
  27 #include "includes.h"
  28 #include "libcli/raw/libcliraw.h"
  29 #include "libcli/raw/raw_proto.h"
  30 #include "libcli/composite/composite.h"
  31 #include "libcli/smb_composite/smb_composite.h"
  32 #include "libcli/smb2/smb2_calls.h"
  33 
  34 /*
  35   continue after a SMB2 close
  36  */
  37 static void continue_close(struct smb2_request *req)
     /* [<][>][^][v][top][bottom][index][help] */
  38 {
  39         struct composite_context *ctx = talloc_get_type(req->async.private_data, 
  40                                                         struct composite_context);
  41         NTSTATUS status;
  42         struct smb2_close close_parm;
  43 
  44         status = smb2_close_recv(req, &close_parm);
  45         composite_error(ctx, status);   
  46 }
  47 
  48 /*
  49   continue after the create in a composite unlink
  50  */
  51 static void continue_unlink(struct smb2_request *req)
     /* [<][>][^][v][top][bottom][index][help] */
  52 {
  53         struct composite_context *ctx = talloc_get_type(req->async.private_data, 
  54                                                         struct composite_context);
  55         struct smb2_tree *tree = req->tree;
  56         struct smb2_create create_parm;
  57         struct smb2_close close_parm;
  58         NTSTATUS status;
  59 
  60         status = smb2_create_recv(req, ctx, &create_parm);
  61         if (!NT_STATUS_IS_OK(status)) {
  62                 composite_error(ctx, status);
  63                 return;
  64         }
  65 
  66         ZERO_STRUCT(close_parm);
  67         close_parm.in.file.handle = create_parm.out.file.handle;
  68         
  69         req = smb2_close_send(tree, &close_parm);
  70         composite_continue_smb2(ctx, req, continue_close, ctx);
  71 }
  72 
  73 /*
  74   composite SMB2 unlink call
  75 */
  76 struct composite_context *smb2_composite_unlink_send(struct smb2_tree *tree, 
     /* [<][>][^][v][top][bottom][index][help] */
  77                                                      union smb_unlink *io)
  78 {
  79         struct composite_context *ctx;
  80         struct smb2_create create_parm;
  81         struct smb2_request *req;
  82 
  83         ctx = composite_create(tree, tree->session->transport->socket->event.ctx);
  84         if (ctx == NULL) return NULL;
  85 
  86         /* check for wildcards - we could support these with a
  87            search, but for now they aren't necessary */
  88         if (strpbrk(io->unlink.in.pattern, "*?<>") != NULL) {
  89                 composite_error(ctx, NT_STATUS_NOT_SUPPORTED);
  90                 return ctx;
  91         }
  92 
  93         ZERO_STRUCT(create_parm);
  94         create_parm.in.desired_access     = SEC_STD_DELETE;
  95         create_parm.in.create_disposition = NTCREATEX_DISP_OPEN;
  96         create_parm.in.share_access = 
  97                 NTCREATEX_SHARE_ACCESS_DELETE|
  98                 NTCREATEX_SHARE_ACCESS_READ|
  99                 NTCREATEX_SHARE_ACCESS_WRITE;
 100         create_parm.in.create_options = 
 101                 NTCREATEX_OPTIONS_DELETE_ON_CLOSE |
 102                 NTCREATEX_OPTIONS_NON_DIRECTORY_FILE;
 103         create_parm.in.fname = io->unlink.in.pattern;
 104         if (create_parm.in.fname[0] == '\\') {
 105                 create_parm.in.fname++;
 106         }
 107 
 108         req = smb2_create_send(tree, &create_parm);
 109 
 110         composite_continue_smb2(ctx, req, continue_unlink, ctx);
 111         return ctx;
 112 }
 113 
 114 
 115 /*
 116   composite unlink call - sync interface
 117 */
 118 NTSTATUS smb2_composite_unlink(struct smb2_tree *tree, union smb_unlink *io)
     /* [<][>][^][v][top][bottom][index][help] */
 119 {
 120         struct composite_context *c = smb2_composite_unlink_send(tree, io);
 121         return composite_wait_free(c);
 122 }
 123 
 124 
 125 
 126 
 127 /*
 128   continue after the create in a composite mkdir
 129  */
 130 static void continue_mkdir(struct smb2_request *req)
     /* [<][>][^][v][top][bottom][index][help] */
 131 {
 132         struct composite_context *ctx = talloc_get_type(req->async.private_data, 
 133                                                         struct composite_context);
 134         struct smb2_tree *tree = req->tree;
 135         struct smb2_create create_parm;
 136         struct smb2_close close_parm;
 137         NTSTATUS status;
 138 
 139         status = smb2_create_recv(req, ctx, &create_parm);
 140         if (!NT_STATUS_IS_OK(status)) {
 141                 composite_error(ctx, status);
 142                 return;
 143         }
 144 
 145         ZERO_STRUCT(close_parm);
 146         close_parm.in.file.handle = create_parm.out.file.handle;
 147         
 148         req = smb2_close_send(tree, &close_parm);
 149         composite_continue_smb2(ctx, req, continue_close, ctx);
 150 }
 151 
 152 /*
 153   composite SMB2 mkdir call
 154 */
 155 struct composite_context *smb2_composite_mkdir_send(struct smb2_tree *tree, 
     /* [<][>][^][v][top][bottom][index][help] */
 156                                                      union smb_mkdir *io)
 157 {
 158         struct composite_context *ctx;
 159         struct smb2_create create_parm;
 160         struct smb2_request *req;
 161 
 162         ctx = composite_create(tree, tree->session->transport->socket->event.ctx);
 163         if (ctx == NULL) return NULL;
 164 
 165         ZERO_STRUCT(create_parm);
 166 
 167         create_parm.in.desired_access = SEC_FLAG_MAXIMUM_ALLOWED;
 168         create_parm.in.share_access = 
 169                 NTCREATEX_SHARE_ACCESS_READ|
 170                 NTCREATEX_SHARE_ACCESS_WRITE;
 171         create_parm.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
 172         create_parm.in.file_attributes   = FILE_ATTRIBUTE_DIRECTORY;
 173         create_parm.in.create_disposition = NTCREATEX_DISP_CREATE;
 174         create_parm.in.fname = io->mkdir.in.path;
 175         if (create_parm.in.fname[0] == '\\') {
 176                 create_parm.in.fname++;
 177         }
 178 
 179         req = smb2_create_send(tree, &create_parm);
 180 
 181         composite_continue_smb2(ctx, req, continue_mkdir, ctx);
 182 
 183         return ctx;
 184 }
 185 
 186 
 187 /*
 188   composite mkdir call - sync interface
 189 */
 190 NTSTATUS smb2_composite_mkdir(struct smb2_tree *tree, union smb_mkdir *io)
     /* [<][>][^][v][top][bottom][index][help] */
 191 {
 192         struct composite_context *c = smb2_composite_mkdir_send(tree, io);
 193         return composite_wait_free(c);
 194 }
 195 
 196 
 197 
 198 /*
 199   continue after the create in a composite rmdir
 200  */
 201 static void continue_rmdir(struct smb2_request *req)
     /* [<][>][^][v][top][bottom][index][help] */
 202 {
 203         struct composite_context *ctx = talloc_get_type(req->async.private_data, 
 204                                                         struct composite_context);
 205         struct smb2_tree *tree = req->tree;
 206         struct smb2_create create_parm;
 207         struct smb2_close close_parm;
 208         NTSTATUS status;
 209 
 210         status = smb2_create_recv(req, ctx, &create_parm);
 211         if (!NT_STATUS_IS_OK(status)) {
 212                 composite_error(ctx, status);
 213                 return;
 214         }
 215 
 216         ZERO_STRUCT(close_parm);
 217         close_parm.in.file.handle = create_parm.out.file.handle;
 218         
 219         req = smb2_close_send(tree, &close_parm);
 220         composite_continue_smb2(ctx, req, continue_close, ctx);
 221 }
 222 
 223 /*
 224   composite SMB2 rmdir call
 225 */
 226 struct composite_context *smb2_composite_rmdir_send(struct smb2_tree *tree, 
     /* [<][>][^][v][top][bottom][index][help] */
 227                                                     struct smb_rmdir *io)
 228 {
 229         struct composite_context *ctx;
 230         struct smb2_create create_parm;
 231         struct smb2_request *req;
 232 
 233         ctx = composite_create(tree, tree->session->transport->socket->event.ctx);
 234         if (ctx == NULL) return NULL;
 235 
 236         ZERO_STRUCT(create_parm);
 237         create_parm.in.desired_access     = SEC_STD_DELETE;
 238         create_parm.in.create_disposition = NTCREATEX_DISP_OPEN;
 239         create_parm.in.share_access = 
 240                 NTCREATEX_SHARE_ACCESS_DELETE|
 241                 NTCREATEX_SHARE_ACCESS_READ|
 242                 NTCREATEX_SHARE_ACCESS_WRITE;
 243         create_parm.in.create_options = 
 244                 NTCREATEX_OPTIONS_DIRECTORY |
 245                 NTCREATEX_OPTIONS_DELETE_ON_CLOSE;
 246         create_parm.in.fname = io->in.path;
 247         if (create_parm.in.fname[0] == '\\') {
 248                 create_parm.in.fname++;
 249         }
 250 
 251         req = smb2_create_send(tree, &create_parm);
 252 
 253         composite_continue_smb2(ctx, req, continue_rmdir, ctx);
 254         return ctx;
 255 }
 256 
 257 
 258 /*
 259   composite rmdir call - sync interface
 260 */
 261 NTSTATUS smb2_composite_rmdir(struct smb2_tree *tree, struct smb_rmdir *io)
     /* [<][>][^][v][top][bottom][index][help] */
 262 {
 263         struct composite_context *c = smb2_composite_rmdir_send(tree, io);
 264         return composite_wait_free(c);
 265 }
 266 
 267 
 268 /*
 269   continue after the setfileinfo in a composite setpathinfo
 270  */
 271 static void continue_setpathinfo_close(struct smb2_request *req)
     /* [<][>][^][v][top][bottom][index][help] */
 272 {
 273         struct composite_context *ctx = talloc_get_type(req->async.private_data, 
 274                                                         struct composite_context);
 275         struct smb2_tree *tree = req->tree;
 276         struct smb2_close close_parm;
 277         NTSTATUS status;
 278         union smb_setfileinfo *io2 = talloc_get_type(ctx->private_data, 
 279                                                      union smb_setfileinfo);
 280 
 281         status = smb2_setinfo_recv(req);
 282         if (!NT_STATUS_IS_OK(status)) {
 283                 composite_error(ctx, status);
 284                 return;
 285         }
 286 
 287         ZERO_STRUCT(close_parm);
 288         close_parm.in.file.handle = io2->generic.in.file.handle;
 289         
 290         req = smb2_close_send(tree, &close_parm);
 291         composite_continue_smb2(ctx, req, continue_close, ctx);
 292 }
 293 
 294 
 295 /*
 296   continue after the create in a composite setpathinfo
 297  */
 298 static void continue_setpathinfo(struct smb2_request *req)
     /* [<][>][^][v][top][bottom][index][help] */
 299 {
 300         struct composite_context *ctx = talloc_get_type(req->async.private_data, 
 301                                                         struct composite_context);
 302         struct smb2_tree *tree = req->tree;
 303         struct smb2_create create_parm;
 304         NTSTATUS status;
 305         union smb_setfileinfo *io2 = talloc_get_type(ctx->private_data, 
 306                                                      union smb_setfileinfo);
 307 
 308         status = smb2_create_recv(req, ctx, &create_parm);
 309         if (!NT_STATUS_IS_OK(status)) {
 310                 composite_error(ctx, status);
 311                 return;
 312         }
 313 
 314         io2->generic.in.file.handle = create_parm.out.file.handle;
 315 
 316         req = smb2_setinfo_file_send(tree, io2);
 317         composite_continue_smb2(ctx, req, continue_setpathinfo_close, ctx);
 318 }
 319 
 320 
 321 /*
 322   composite SMB2 setpathinfo call
 323 */
 324 struct composite_context *smb2_composite_setpathinfo_send(struct smb2_tree *tree, 
     /* [<][>][^][v][top][bottom][index][help] */
 325                                                           union smb_setfileinfo *io)
 326 {
 327         struct composite_context *ctx;
 328         struct smb2_create create_parm;
 329         struct smb2_request *req;
 330         union smb_setfileinfo *io2;
 331 
 332         ctx = composite_create(tree, tree->session->transport->socket->event.ctx);
 333         if (ctx == NULL) return NULL;
 334 
 335         ZERO_STRUCT(create_parm);
 336         create_parm.in.desired_access     = SEC_FLAG_MAXIMUM_ALLOWED;
 337         create_parm.in.create_disposition = NTCREATEX_DISP_OPEN;
 338         create_parm.in.share_access = 
 339                 NTCREATEX_SHARE_ACCESS_DELETE|
 340                 NTCREATEX_SHARE_ACCESS_READ|
 341                 NTCREATEX_SHARE_ACCESS_WRITE;
 342         create_parm.in.create_options = 0;
 343         create_parm.in.fname = io->generic.in.file.path;
 344         if (create_parm.in.fname[0] == '\\') {
 345                 create_parm.in.fname++;
 346         }
 347 
 348         req = smb2_create_send(tree, &create_parm);
 349 
 350         io2 = talloc(ctx, union smb_setfileinfo);
 351         if (composite_nomem(io2, ctx)) {
 352                 return ctx;
 353         }
 354         *io2 = *io;
 355 
 356         ctx->private_data = io2;
 357 
 358         composite_continue_smb2(ctx, req, continue_setpathinfo, ctx);
 359         return ctx;
 360 }
 361 
 362 
 363 /*
 364   composite setpathinfo call
 365  */
 366 NTSTATUS smb2_composite_setpathinfo(struct smb2_tree *tree, union smb_setfileinfo *io)
     /* [<][>][^][v][top][bottom][index][help] */
 367 {
 368         struct composite_context *c = smb2_composite_setpathinfo_send(tree, io);
 369         return composite_wait_free(c);  
 370 }

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