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 50 : static NTSTATUS fetchfile_connect(struct composite_context *c,
42 : struct smb_composite_fetchfile *io)
43 : {
44 : NTSTATUS status;
45 : struct fetchfile_state *state;
46 50 : state = talloc_get_type(c->private_data, struct fetchfile_state);
47 :
48 50 : status = smb_composite_connect_recv(state->creq, c);
49 50 : NT_STATUS_NOT_OK_RETURN(status);
50 :
51 50 : state->loadfile = talloc(state, struct smb_composite_loadfile);
52 50 : NT_STATUS_HAVE_NO_MEMORY(state->loadfile);
53 :
54 50 : state->loadfile->in.fname = io->in.filename;
55 :
56 50 : state->creq = smb_composite_loadfile_send(state->connect->out.tree,
57 : state->loadfile);
58 50 : NT_STATUS_HAVE_NO_MEMORY(state->creq);
59 :
60 50 : state->creq->async.private_data = c;
61 50 : state->creq->async.fn = fetchfile_composite_handler;
62 :
63 50 : state->stage = FETCHFILE_READ;
64 :
65 50 : return NT_STATUS_OK;
66 : }
67 :
68 50 : static NTSTATUS fetchfile_read(struct composite_context *c,
69 : struct smb_composite_fetchfile *io)
70 : {
71 : NTSTATUS status;
72 : struct fetchfile_state *state;
73 50 : state = talloc_get_type(c->private_data, struct fetchfile_state);
74 :
75 50 : status = smb_composite_loadfile_recv(state->creq, NULL);
76 50 : NT_STATUS_NOT_OK_RETURN(status);
77 :
78 50 : io->out.data = state->loadfile->out.data;
79 50 : io->out.size = state->loadfile->out.size;
80 :
81 50 : c->state = COMPOSITE_STATE_DONE;
82 50 : if (c->async.fn)
83 50 : c->async.fn(c);
84 :
85 50 : return NT_STATUS_OK;
86 : }
87 :
88 100 : static void fetchfile_state_handler(struct composite_context *c)
89 : {
90 : struct fetchfile_state *state;
91 : NTSTATUS status;
92 :
93 100 : 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 100 : switch (state->stage) {
98 50 : case FETCHFILE_CONNECT:
99 50 : status = fetchfile_connect(c, state->io);
100 50 : break;
101 50 : case FETCHFILE_READ:
102 50 : status = fetchfile_read(c, state->io);
103 50 : break;
104 0 : default:
105 0 : status = NT_STATUS_UNSUCCESSFUL;
106 0 : break;
107 : }
108 :
109 100 : 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 100 : }
117 :
118 100 : static void fetchfile_composite_handler(struct composite_context *creq)
119 : {
120 100 : struct composite_context *c = talloc_get_type(creq->async.private_data,
121 : struct composite_context);
122 100 : fetchfile_state_handler(c);
123 100 : }
124 :
125 50 : 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 50 : c = talloc_zero(NULL, struct composite_context);
132 50 : if (c == NULL) goto failed;
133 :
134 50 : state = talloc(c, struct fetchfile_state);
135 50 : if (state == NULL) goto failed;
136 :
137 50 : state->connect = talloc_zero(state, struct smb_composite_connect);
138 50 : if (state->connect == NULL) goto failed;
139 :
140 50 : state->io = io;
141 :
142 50 : state->connect->in.dest_host = io->in.dest_host;
143 50 : state->connect->in.dest_ports = io->in.ports;
144 50 : state->connect->in.socket_options = io->in.socket_options;
145 50 : state->connect->in.called_name = io->in.called_name;
146 50 : state->connect->in.service = io->in.service;
147 50 : state->connect->in.service_type = io->in.service_type;
148 50 : state->connect->in.credentials = io->in.credentials;
149 50 : state->connect->in.fallback_to_anonymous = false;
150 50 : state->connect->in.workgroup = io->in.workgroup;
151 50 : state->connect->in.gensec_settings = io->in.gensec_settings;
152 :
153 50 : state->connect->in.options = io->in.options;
154 50 : state->connect->in.session_options = io->in.session_options;
155 :
156 50 : state->creq = smb_composite_connect_send(state->connect, state,
157 : io->in.resolve_ctx, event_ctx);
158 50 : if (state->creq == NULL) goto failed;
159 :
160 50 : state->creq->async.private_data = c;
161 50 : state->creq->async.fn = fetchfile_composite_handler;
162 :
163 50 : c->state = COMPOSITE_STATE_IN_PROGRESS;
164 50 : state->stage = FETCHFILE_CONNECT;
165 50 : c->private_data = state;
166 :
167 50 : return c;
168 0 : failed:
169 0 : talloc_free(c);
170 0 : return NULL;
171 : }
172 :
173 50 : NTSTATUS smb_composite_fetchfile_recv(struct composite_context *c,
174 : TALLOC_CTX *mem_ctx)
175 : {
176 : NTSTATUS status;
177 :
178 50 : status = composite_wait(c);
179 :
180 50 : if (NT_STATUS_IS_OK(status)) {
181 50 : struct fetchfile_state *state = talloc_get_type(c->private_data, struct fetchfile_state);
182 50 : talloc_steal(mem_ctx, state->io->out.data);
183 : }
184 :
185 50 : talloc_free(c);
186 50 : 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 : }
|