root/source4/libcli/smb_composite/appendacl.c

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

DEFINITIONS

This source file includes following definitions.
  1. appendacl_open
  2. appendacl_get
  3. appendacl_set
  4. appendacl_getagain
  5. appendacl_close
  6. appendacl_handler
  7. smb_composite_appendacl_send
  8. smb_composite_appendacl_recv
  9. smb_composite_appendacl

   1 #include "includes.h"
   2 #include "libcli/raw/libcliraw.h"
   3 #include "libcli/raw/raw_proto.h"
   4 #include "libcli/composite/composite.h"
   5 #include "libcli/security/security.h"
   6 #include "libcli/smb_composite/smb_composite.h"
   7 
   8 /* the stages of this call */
   9 enum appendacl_stage {APPENDACL_OPENPATH, APPENDACL_GET, 
  10                        APPENDACL_SET, APPENDACL_GETAGAIN, APPENDACL_CLOSEPATH};
  11 
  12 static void appendacl_handler(struct smbcli_request *req);
  13 
  14 struct appendacl_state {
  15         enum appendacl_stage stage;
  16         struct smb_composite_appendacl *io;
  17 
  18         union smb_open *io_open;
  19         union smb_setfileinfo *io_setfileinfo;
  20         union smb_fileinfo *io_fileinfo;
  21 
  22         struct smbcli_request *req;
  23 };
  24 
  25 
  26 static NTSTATUS appendacl_open(struct composite_context *c, 
     /* [<][>][^][v][top][bottom][index][help] */
  27                               struct smb_composite_appendacl *io)
  28 {
  29         struct appendacl_state *state = talloc_get_type(c->private_data, struct appendacl_state);
  30         struct smbcli_tree *tree = state->req->tree;
  31         NTSTATUS status;
  32 
  33         status = smb_raw_open_recv(state->req, c, state->io_open);
  34         NT_STATUS_NOT_OK_RETURN(status);
  35 
  36         /* setup structures for getting fileinfo */
  37         state->io_fileinfo = talloc(c, union smb_fileinfo);
  38         NT_STATUS_HAVE_NO_MEMORY(state->io_fileinfo);
  39         
  40         state->io_fileinfo->query_secdesc.level = RAW_FILEINFO_SEC_DESC;
  41         state->io_fileinfo->query_secdesc.in.file.fnum = state->io_open->ntcreatex.out.file.fnum;
  42         state->io_fileinfo->query_secdesc.in.secinfo_flags = SECINFO_DACL;
  43 
  44         state->req = smb_raw_fileinfo_send(tree, state->io_fileinfo);
  45         NT_STATUS_HAVE_NO_MEMORY(state->req);
  46 
  47         /* set the handler */
  48         state->req->async.fn = appendacl_handler;
  49         state->req->async.private_data = c;
  50         state->stage = APPENDACL_GET;
  51         
  52         talloc_free (state->io_open);
  53 
  54         return NT_STATUS_OK;
  55 }
  56 
  57 static NTSTATUS appendacl_get(struct composite_context *c, 
     /* [<][>][^][v][top][bottom][index][help] */
  58                                struct smb_composite_appendacl *io)
  59 {
  60         struct appendacl_state *state = talloc_get_type(c->private_data, struct appendacl_state);
  61         struct smbcli_tree *tree = state->req->tree;
  62         int i;
  63         NTSTATUS status;
  64         
  65         status = smb_raw_fileinfo_recv(state->req, state->io_fileinfo, state->io_fileinfo);
  66         NT_STATUS_NOT_OK_RETURN(status);
  67         
  68         /* setup structures for setting fileinfo */
  69         state->io_setfileinfo = talloc(c, union smb_setfileinfo);
  70         NT_STATUS_HAVE_NO_MEMORY(state->io_setfileinfo);
  71         
  72         state->io_setfileinfo->set_secdesc.level            = RAW_SFILEINFO_SEC_DESC;
  73         state->io_setfileinfo->set_secdesc.in.file.fnum     = state->io_fileinfo->query_secdesc.in.file.fnum;
  74         
  75         state->io_setfileinfo->set_secdesc.in.secinfo_flags = SECINFO_DACL;
  76         state->io_setfileinfo->set_secdesc.in.sd            = state->io_fileinfo->query_secdesc.out.sd;
  77         talloc_steal(state->io_setfileinfo, state->io_setfileinfo->set_secdesc.in.sd);
  78 
  79         /* append all aces from io->in.sd->dacl to new security descriptor */
  80         if (io->in.sd->dacl != NULL) {
  81                 for (i = 0; i < io->in.sd->dacl->num_aces; i++) {
  82                         security_descriptor_dacl_add(state->io_setfileinfo->set_secdesc.in.sd,
  83                                                      &(io->in.sd->dacl->aces[i]));
  84                 }
  85         }
  86 
  87         status = smb_raw_setfileinfo(tree, state->io_setfileinfo);
  88         NT_STATUS_NOT_OK_RETURN(status);
  89 
  90         state->req = smb_raw_setfileinfo_send(tree, state->io_setfileinfo);
  91         NT_STATUS_HAVE_NO_MEMORY(state->req);
  92 
  93         /* call handler when done setting new security descriptor on file */
  94         state->req->async.fn = appendacl_handler;
  95         state->req->async.private_data = c;
  96         state->stage = APPENDACL_SET;
  97 
  98         talloc_free (state->io_fileinfo);
  99 
 100         return NT_STATUS_OK;
 101 }
 102 
 103 static NTSTATUS appendacl_set(struct composite_context *c, 
     /* [<][>][^][v][top][bottom][index][help] */
 104                               struct smb_composite_appendacl *io)
 105 {
 106         struct appendacl_state *state = talloc_get_type(c->private_data, struct appendacl_state);
 107         struct smbcli_tree *tree = state->req->tree;
 108         NTSTATUS status;
 109 
 110         status = smbcli_request_simple_recv(state->req);
 111         NT_STATUS_NOT_OK_RETURN(status);
 112 
 113         /* setup structures for getting fileinfo */
 114         state->io_fileinfo = talloc(c, union smb_fileinfo);
 115         NT_STATUS_HAVE_NO_MEMORY(state->io_fileinfo);
 116         
 117 
 118         state->io_fileinfo->query_secdesc.level = RAW_FILEINFO_SEC_DESC;
 119         state->io_fileinfo->query_secdesc.in.file.fnum = state->io_setfileinfo->set_secdesc.in.file.fnum;
 120         state->io_fileinfo->query_secdesc.in.secinfo_flags = SECINFO_DACL;
 121 
 122         state->req = smb_raw_fileinfo_send(tree, state->io_fileinfo);
 123         NT_STATUS_HAVE_NO_MEMORY(state->req);
 124 
 125         /* set the handler */
 126         state->req->async.fn = appendacl_handler;
 127         state->req->async.private_data = c;
 128         state->stage = APPENDACL_GETAGAIN;
 129         
 130         talloc_free (state->io_setfileinfo);
 131 
 132         return NT_STATUS_OK;
 133 }
 134 
 135 
 136 static NTSTATUS appendacl_getagain(struct composite_context *c, 
     /* [<][>][^][v][top][bottom][index][help] */
 137                                    struct smb_composite_appendacl *io)
 138 {
 139         struct appendacl_state *state = talloc_get_type(c->private_data, struct appendacl_state);
 140         struct smbcli_tree *tree = state->req->tree;
 141         union smb_close *io_close;
 142         NTSTATUS status;
 143         
 144         status = smb_raw_fileinfo_recv(state->req, c, state->io_fileinfo);
 145         NT_STATUS_NOT_OK_RETURN(status);
 146 
 147         io->out.sd = state->io_fileinfo->query_secdesc.out.sd;
 148 
 149         /* setup structures for close */
 150         io_close = talloc(c, union smb_close);
 151         NT_STATUS_HAVE_NO_MEMORY(io_close);
 152         
 153         io_close->close.level = RAW_CLOSE_CLOSE;
 154         io_close->close.in.file.fnum = state->io_fileinfo->query_secdesc.in.file.fnum;
 155         io_close->close.in.write_time = 0;
 156 
 157         state->req = smb_raw_close_send(tree, io_close);
 158         NT_STATUS_HAVE_NO_MEMORY(state->req);
 159 
 160         /* call the handler */
 161         state->req->async.fn = appendacl_handler;
 162         state->req->async.private_data = c;
 163         state->stage = APPENDACL_CLOSEPATH;
 164 
 165         talloc_free (state->io_fileinfo);
 166 
 167         return NT_STATUS_OK;
 168 }
 169 
 170 
 171 
 172 static NTSTATUS appendacl_close(struct composite_context *c, 
     /* [<][>][^][v][top][bottom][index][help] */
 173                                 struct smb_composite_appendacl *io)
 174 {
 175         struct appendacl_state *state = talloc_get_type(c->private_data, struct appendacl_state);
 176         NTSTATUS status;
 177 
 178         status = smbcli_request_simple_recv(state->req);
 179         NT_STATUS_NOT_OK_RETURN(status);
 180         
 181         c->state = COMPOSITE_STATE_DONE;
 182 
 183         return NT_STATUS_OK;
 184 }
 185 
 186 /*
 187   handler for completion of a sub-request in appendacl
 188 */
 189 static void appendacl_handler(struct smbcli_request *req)
     /* [<][>][^][v][top][bottom][index][help] */
 190 {
 191         struct composite_context *c = (struct composite_context *)req->async.private_data;
 192         struct appendacl_state *state = talloc_get_type(c->private_data, struct appendacl_state);
 193 
 194         /* when this handler is called, the stage indicates what
 195            call has just finished */
 196         switch (state->stage) {
 197         case APPENDACL_OPENPATH:
 198                 c->status = appendacl_open(c, state->io);
 199                 break;
 200 
 201         case APPENDACL_GET:
 202                 c->status = appendacl_get(c, state->io);
 203                 break;
 204 
 205         case APPENDACL_SET:
 206                 c->status = appendacl_set(c, state->io);
 207                 break;
 208 
 209         case APPENDACL_GETAGAIN:
 210                 c->status = appendacl_getagain(c, state->io);
 211                 break;
 212 
 213         case APPENDACL_CLOSEPATH:
 214                 c->status = appendacl_close(c, state->io);
 215                 break;
 216         }
 217 
 218         /* We should get here if c->state >= SMBCLI_REQUEST_DONE */
 219         if (!NT_STATUS_IS_OK(c->status)) {
 220                 c->state = COMPOSITE_STATE_ERROR;
 221         }
 222 
 223         if (c->state >= COMPOSITE_STATE_DONE &&
 224             c->async.fn) {
 225                 c->async.fn(c);
 226         }
 227 }
 228 
 229 
 230 /*
 231   composite appendacl call - does an open followed by a number setfileinfo,
 232   after that new acls are read with fileinfo, followed by a close
 233 */
 234 struct composite_context *smb_composite_appendacl_send(struct smbcli_tree *tree, 
     /* [<][>][^][v][top][bottom][index][help] */
 235                                                         struct smb_composite_appendacl *io)
 236 {
 237         struct composite_context *c;
 238         struct appendacl_state *state;
 239 
 240         c = talloc_zero(tree, struct composite_context);
 241         if (c == NULL) goto failed;
 242 
 243         state = talloc(c, struct appendacl_state);
 244         if (state == NULL) goto failed;
 245 
 246         state->io = io;
 247 
 248         c->private_data = state;
 249         c->state = COMPOSITE_STATE_IN_PROGRESS;
 250         c->event_ctx = tree->session->transport->socket->event.ctx;
 251 
 252         /* setup structures for opening file */
 253         state->io_open = talloc_zero(c, union smb_open);
 254         if (state->io_open == NULL) goto failed;
 255         
 256         state->io_open->ntcreatex.level               = RAW_OPEN_NTCREATEX;
 257         state->io_open->ntcreatex.in.root_fid = 0;
 258         state->io_open->ntcreatex.in.flags            = 0;
 259         state->io_open->ntcreatex.in.access_mask      = SEC_FLAG_MAXIMUM_ALLOWED;
 260         state->io_open->ntcreatex.in.file_attr        = FILE_ATTRIBUTE_NORMAL;
 261         state->io_open->ntcreatex.in.share_access     = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
 262         state->io_open->ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
 263         state->io_open->ntcreatex.in.impersonation    = NTCREATEX_IMPERSONATION_ANONYMOUS;
 264         state->io_open->ntcreatex.in.security_flags   = 0;
 265         state->io_open->ntcreatex.in.fname            = io->in.fname;
 266 
 267         /* send the open on its way */
 268         state->req = smb_raw_open_send(tree, state->io_open);
 269         if (state->req == NULL) goto failed;
 270 
 271         /* setup the callback handler */
 272         state->req->async.fn = appendacl_handler;
 273         state->req->async.private_data = c;
 274         state->stage = APPENDACL_OPENPATH;
 275 
 276         return c;
 277 
 278 failed:
 279         talloc_free(c);
 280         return NULL;
 281 }
 282 
 283 
 284 /*
 285   composite appendacl call - recv side
 286 */
 287 NTSTATUS smb_composite_appendacl_recv(struct composite_context *c, TALLOC_CTX *mem_ctx)
     /* [<][>][^][v][top][bottom][index][help] */
 288 {
 289         NTSTATUS status;
 290 
 291         status = composite_wait(c);
 292 
 293         if (NT_STATUS_IS_OK(status)) {
 294                 struct appendacl_state *state = talloc_get_type(c->private_data, struct appendacl_state);
 295                 state->io->out.sd = security_descriptor_copy (mem_ctx, state->io->out.sd);
 296         }
 297 
 298         talloc_free(c);
 299         return status;
 300 }
 301 
 302 
 303 /*
 304   composite appendacl call - sync interface
 305 */
 306 NTSTATUS smb_composite_appendacl(struct smbcli_tree *tree, 
     /* [<][>][^][v][top][bottom][index][help] */
 307                                 TALLOC_CTX *mem_ctx,
 308                                 struct smb_composite_appendacl *io)
 309 {
 310         struct composite_context *c = smb_composite_appendacl_send(tree, io);
 311         return smb_composite_appendacl_recv(c, mem_ctx);
 312 }
 313 

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