~zulcss/samba/server-dailies-3.4

« back to all changes in this revision

Viewing changes to source4/libcli/smb_composite/appendacl.c

  • Committer: Chuck Short
  • Date: 2010-09-28 20:38:39 UTC
  • Revision ID: zulcss@ubuntu.com-20100928203839-pgjulytsi9ue63x1
Initial version

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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, 
 
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, 
 
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, 
 
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, 
 
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, 
 
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)
 
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, 
 
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)
 
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, 
 
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