Line data Source code
1 : /*
2 : Unix SMB/CIFS implementation.
3 :
4 : Copyright (C) Volker Lendecke 2005
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 loading a whole file into memory
21 : */
22 :
23 : #include "includes.h"
24 : #include "libcli/composite/composite.h"
25 : #include "libcli/smb_composite/smb_composite.h"
26 : #include "libcli/resolve/resolve.h"
27 :
28 : enum fetchfile_stage {FETCHFILE_CONNECT,
29 : FETCHFILE_READ};
30 :
31 : struct fetchfile_state {
32 : enum fetchfile_stage stage;
33 : struct smb_composite_fetchfile *io;
34 : struct composite_context *creq;
35 : struct smb_composite_connect *connect;
36 : struct smb_composite_loadfile *loadfile;
37 : };
38 :
39 : static void fetchfile_composite_handler(struct composite_context *req);
40 :
41 10 : static NTSTATUS fetchfile_connect(struct composite_context *c,
42 : struct smb_composite_fetchfile *io)
43 : {
44 : NTSTATUS status;
45 : struct fetchfile_state *state;
46 10 : state = talloc_get_type(c->private_data, struct fetchfile_state);
47 :
48 10 : status = smb_composite_connect_recv(state->creq, c);
49 10 : NT_STATUS_NOT_OK_RETURN(status);
50 :
51 10 : state->loadfile = talloc(state, struct smb_composite_loadfile);
52 10 : NT_STATUS_HAVE_NO_MEMORY(state->loadfile);
53 :
54 10 : state->loadfile->in.fname = io->in.filename;
55 :
56 10 : state->creq = smb_composite_loadfile_send(state->connect->out.tree,
57 : state->loadfile);
58 10 : NT_STATUS_HAVE_NO_MEMORY(state->creq);
59 :
60 10 : state->creq->async.private_data = c;
61 10 : state->creq->async.fn = fetchfile_composite_handler;
62 :
63 10 : state->stage = FETCHFILE_READ;
64 :
65 10 : return NT_STATUS_OK;
66 : }
67 :
68 10 : static NTSTATUS fetchfile_read(struct composite_context *c,
69 : struct smb_composite_fetchfile *io)
70 : {
71 : NTSTATUS status;
72 : struct fetchfile_state *state;
73 10 : state = talloc_get_type(c->private_data, struct fetchfile_state);
74 :
75 10 : status = smb_composite_loadfile_recv(state->creq, NULL);
76 10 : NT_STATUS_NOT_OK_RETURN(status);
77 :
78 10 : io->out.data = state->loadfile->out.data;
79 10 : io->out.size = state->loadfile->out.size;
80 :
81 10 : c->state = COMPOSITE_STATE_DONE;
82 10 : if (c->async.fn)
83 10 : c->async.fn(c);
84 :
85 10 : return NT_STATUS_OK;
86 : }
87 :
88 20 : static void fetchfile_state_handler(struct composite_context *c)
89 : {
90 : struct fetchfile_state *state;
91 : NTSTATUS status;
92 :
93 20 : state = talloc_get_type(c->private_data, struct fetchfile_state);
94 :
95 : /* when this handler is called, the stage indicates what
96 : call has just finished */
97 20 : switch (state->stage) {
98 10 : case FETCHFILE_CONNECT:
99 10 : status = fetchfile_connect(c, state->io);
100 10 : break;
101 10 : case FETCHFILE_READ:
102 10 : status = fetchfile_read(c, state->io);
103 10 : break;
104 0 : default:
105 0 : status = NT_STATUS_UNSUCCESSFUL;
106 0 : break;
107 : }
108 :
109 20 : if (!NT_STATUS_IS_OK(status)) {
110 0 : c->status = status;
111 0 : c->state = COMPOSITE_STATE_ERROR;
112 0 : if (c->async.fn) {
113 0 : c->async.fn(c);
114 : }
115 : }
116 20 : }
117 :
118 20 : static void fetchfile_composite_handler(struct composite_context *creq)
119 : {
120 20 : struct composite_context *c = talloc_get_type(creq->async.private_data,
121 : struct composite_context);
122 20 : fetchfile_state_handler(c);
123 20 : }
124 :
125 10 : struct composite_context *smb_composite_fetchfile_send(struct smb_composite_fetchfile *io,
126 : struct tevent_context *event_ctx)
127 : {
128 : struct composite_context *c;
129 : struct fetchfile_state *state;
130 :
131 10 : c = talloc_zero(NULL, struct composite_context);
132 10 : if (c == NULL) goto failed;
133 :
134 10 : state = talloc(c, struct fetchfile_state);
135 10 : if (state == NULL) goto failed;
136 :
137 10 : state->connect = talloc_zero(state, struct smb_composite_connect);
138 10 : if (state->connect == NULL) goto failed;
139 :
140 10 : state->io = io;
141 :
142 10 : state->connect->in.dest_host = io->in.dest_host;
143 10 : state->connect->in.dest_ports = io->in.ports;
144 10 : state->connect->in.socket_options = io->in.socket_options;
145 10 : state->connect->in.called_name = io->in.called_name;
146 10 : state->connect->in.service = io->in.service;
147 10 : state->connect->in.service_type = io->in.service_type;
148 10 : state->connect->in.credentials = io->in.credentials;
149 10 : state->connect->in.fallback_to_anonymous = false;
150 10 : state->connect->in.workgroup = io->in.workgroup;
151 10 : state->connect->in.gensec_settings = io->in.gensec_settings;
152 :
153 10 : state->connect->in.options = io->in.options;
154 10 : state->connect->in.session_options = io->in.session_options;
155 :
156 10 : state->creq = smb_composite_connect_send(state->connect, state,
157 : io->in.resolve_ctx, event_ctx);
158 10 : if (state->creq == NULL) goto failed;
159 :
160 10 : state->creq->async.private_data = c;
161 10 : state->creq->async.fn = fetchfile_composite_handler;
162 :
163 10 : c->state = COMPOSITE_STATE_IN_PROGRESS;
164 10 : state->stage = FETCHFILE_CONNECT;
165 10 : c->private_data = state;
166 :
167 10 : return c;
168 0 : failed:
169 0 : talloc_free(c);
170 0 : return NULL;
171 : }
172 :
173 10 : NTSTATUS smb_composite_fetchfile_recv(struct composite_context *c,
174 : TALLOC_CTX *mem_ctx)
175 : {
176 : NTSTATUS status;
177 :
178 10 : status = composite_wait(c);
179 :
180 10 : if (NT_STATUS_IS_OK(status)) {
181 10 : struct fetchfile_state *state = talloc_get_type(c->private_data, struct fetchfile_state);
182 10 : talloc_steal(mem_ctx, state->io->out.data);
183 : }
184 :
185 10 : talloc_free(c);
186 10 : return status;
187 : }
188 :
189 0 : NTSTATUS smb_composite_fetchfile(struct smb_composite_fetchfile *io,
190 : TALLOC_CTX *mem_ctx)
191 : {
192 0 : struct composite_context *c = smb_composite_fetchfile_send(io, NULL);
193 0 : return smb_composite_fetchfile_recv(c, mem_ctx);
194 : }
|