• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src/router/samba-3.5.8/source4/libcli/smb_composite/
1/*
2  a composite API for quering file system information
3*/
4
5#include "includes.h"
6#include "libcli/raw/libcliraw.h"
7#include "libcli/raw/raw_proto.h"
8#include "libcli/composite/composite.h"
9#include "libcli/smb_composite/smb_composite.h"
10#include "libcli/resolve/resolve.h"
11
12/* the stages of this call */
13enum fsinfo_stage {FSINFO_CONNECT, FSINFO_QUERY};
14
15
16static void fsinfo_raw_handler(struct smbcli_request *req);
17static void fsinfo_composite_handler(struct composite_context *c);
18static void fsinfo_state_handler(struct composite_context *c);
19
20struct fsinfo_state {
21	enum fsinfo_stage stage;
22	struct composite_context *creq;
23	struct smb_composite_fsinfo *io;
24	struct smb_composite_connect *connect;
25	union smb_fsinfo *fsinfo;
26	struct smbcli_tree *tree;
27	struct smbcli_request *req;
28};
29
30static NTSTATUS fsinfo_connect(struct composite_context *c,
31			       struct smb_composite_fsinfo *io)
32{
33	NTSTATUS status;
34	struct fsinfo_state *state;
35	state = talloc_get_type(c->private_data, struct fsinfo_state);
36
37	status = smb_composite_connect_recv(state->creq, c);
38	NT_STATUS_NOT_OK_RETURN(status);
39
40	state->fsinfo = talloc(state, union smb_fsinfo);
41	NT_STATUS_HAVE_NO_MEMORY(state->fsinfo);
42
43	state->fsinfo->generic.level = io->in.level;
44
45	state->req = smb_raw_fsinfo_send(state->connect->out.tree,
46					 state,
47					 state->fsinfo);
48	NT_STATUS_HAVE_NO_MEMORY(state->req);
49
50	state->req->async.private_data = c;
51	state->req->async.fn = fsinfo_raw_handler;
52
53	state->stage = FSINFO_QUERY;
54
55	return NT_STATUS_OK;
56}
57
58static NTSTATUS fsinfo_query(struct composite_context *c,
59			       struct smb_composite_fsinfo *io)
60{
61	NTSTATUS status;
62	struct fsinfo_state *state;
63	state = talloc_get_type(c->private_data, struct fsinfo_state);
64
65	status = smb_raw_fsinfo_recv(state->req, state, state->fsinfo);
66	NT_STATUS_NOT_OK_RETURN(status);
67
68	state->io->out.fsinfo = state->fsinfo;
69
70	c->state = COMPOSITE_STATE_DONE;
71
72	if (c->async.fn)
73		c->async.fn(c);
74
75	return NT_STATUS_OK;
76
77}
78
79/*
80  handler for completion of a sub-request in fsinfo
81*/
82static void fsinfo_state_handler(struct composite_context *creq)
83{
84	struct fsinfo_state *state = talloc_get_type(creq->private_data, struct fsinfo_state);
85
86	/* when this handler is called, the stage indicates what
87	   call has just finished */
88	switch (state->stage) {
89	case FSINFO_CONNECT:
90		creq->status = fsinfo_connect(creq, state->io);
91		break;
92
93	case FSINFO_QUERY:
94		creq->status = fsinfo_query(creq, state->io);
95		break;
96	}
97
98	if (!NT_STATUS_IS_OK(creq->status)) {
99		creq->state = COMPOSITE_STATE_ERROR;
100	}
101
102	if (creq->state >= COMPOSITE_STATE_DONE && creq->async.fn) {
103		creq->async.fn(creq);
104	}
105}
106
107/*
108   As raw and composite handlers take different requests, we need to handlers
109   to adapt both for the same state machine in fsinfo_state_handler()
110*/
111static void fsinfo_raw_handler(struct smbcli_request *req)
112{
113	struct composite_context *c = talloc_get_type(req->async.private_data,
114						      struct composite_context);
115	fsinfo_state_handler(c);
116}
117
118static void fsinfo_composite_handler(struct composite_context *creq)
119{
120	struct composite_context *c = talloc_get_type(creq->async.private_data,
121						      struct composite_context);
122	fsinfo_state_handler(c);
123}
124
125/*
126  composite fsinfo call - connects to a tree and queries a file system information
127*/
128struct composite_context *smb_composite_fsinfo_send(struct smbcli_tree *tree,
129						    struct smb_composite_fsinfo *io,
130						    struct resolve_context *resolve_ctx)
131{
132	struct composite_context *c;
133	struct fsinfo_state *state;
134
135	c = talloc_zero(tree, struct composite_context);
136	if (c == NULL) goto failed;
137
138	state = talloc(c, struct fsinfo_state);
139	if (state == NULL) goto failed;
140
141	state->io = io;
142
143	state->connect = talloc(state, struct smb_composite_connect);
144
145	if (state->connect == NULL) goto failed;
146
147	state->connect->in.dest_host    = io->in.dest_host;
148	state->connect->in.dest_ports   = io->in.dest_ports;
149	state->connect->in.socket_options = io->in.socket_options;
150	state->connect->in.called_name  = io->in.called_name;
151	state->connect->in.service      = io->in.service;
152	state->connect->in.service_type = io->in.service_type;
153	state->connect->in.credentials  = io->in.credentials;
154	state->connect->in.fallback_to_anonymous = false;
155	state->connect->in.workgroup    = io->in.workgroup;
156	state->connect->in.iconv_convenience = io->in.iconv_convenience;
157	state->connect->in.gensec_settings = io->in.gensec_settings;
158
159	state->connect->in.options = tree->session->transport->options;
160	state->connect->in.session_options = tree->session->options;
161
162	c->state = COMPOSITE_STATE_IN_PROGRESS;
163	state->stage = FSINFO_CONNECT;
164	c->private_data = state;
165
166	state->creq = smb_composite_connect_send(state->connect, state,
167			 resolve_ctx, c->event_ctx);
168
169	if (state->creq == NULL) goto failed;
170
171	state->creq->async.private_data = c;
172	state->creq->async.fn = fsinfo_composite_handler;
173
174	return c;
175failed:
176	talloc_free(c);
177	return NULL;
178}
179
180/*
181  composite fsinfo call - recv side
182*/
183NTSTATUS smb_composite_fsinfo_recv(struct composite_context *c, TALLOC_CTX *mem_ctx)
184{
185	NTSTATUS status;
186
187	status = composite_wait(c);
188
189	if (NT_STATUS_IS_OK(status)) {
190		struct fsinfo_state *state = talloc_get_type(c->private_data, struct fsinfo_state);
191		talloc_steal(mem_ctx, state->io->out.fsinfo);
192	}
193
194	talloc_free(c);
195	return status;
196}
197
198
199/*
200  composite fsinfo call - sync interface
201*/
202NTSTATUS smb_composite_fsinfo(struct smbcli_tree *tree,
203			      TALLOC_CTX *mem_ctx,
204			      struct smb_composite_fsinfo *io,
205			      struct resolve_context *resolve_ctx)
206{
207	struct composite_context *c = smb_composite_fsinfo_send(tree, io, resolve_ctx);
208	return smb_composite_fsinfo_recv(c, mem_ctx);
209}
210
211