2 a composite API for quering file system information
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"
12 /* the stages of this call */
13 enum fsinfo_stage
{FSINFO_CONNECT
, FSINFO_QUERY
};
16 static void fsinfo_raw_handler(struct smbcli_request
*req
);
17 static void fsinfo_composite_handler(struct composite_context
*c
);
18 static void fsinfo_state_handler(struct composite_context
*c
);
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
;
30 static NTSTATUS
fsinfo_connect(struct composite_context
*c
,
31 struct smb_composite_fsinfo
*io
)
34 struct fsinfo_state
*state
;
35 state
= talloc_get_type(c
->private_data
, struct fsinfo_state
);
37 status
= smb_composite_connect_recv(state
->creq
, c
);
38 NT_STATUS_NOT_OK_RETURN(status
);
40 state
->fsinfo
= talloc(state
, union smb_fsinfo
);
41 NT_STATUS_HAVE_NO_MEMORY(state
->fsinfo
);
43 state
->fsinfo
->generic
.level
= io
->in
.level
;
45 state
->req
= smb_raw_fsinfo_send(state
->connect
->out
.tree
,
48 NT_STATUS_HAVE_NO_MEMORY(state
->req
);
50 state
->req
->async
.private_data
= c
;
51 state
->req
->async
.fn
= fsinfo_raw_handler
;
53 state
->stage
= FSINFO_QUERY
;
58 static NTSTATUS
fsinfo_query(struct composite_context
*c
,
59 struct smb_composite_fsinfo
*io
)
62 struct fsinfo_state
*state
;
63 state
= talloc_get_type(c
->private_data
, struct fsinfo_state
);
65 status
= smb_raw_fsinfo_recv(state
->req
, state
, state
->fsinfo
);
66 NT_STATUS_NOT_OK_RETURN(status
);
68 state
->io
->out
.fsinfo
= state
->fsinfo
;
70 c
->state
= COMPOSITE_STATE_DONE
;
80 handler for completion of a sub-request in fsinfo
82 static void fsinfo_state_handler(struct composite_context
*creq
)
84 struct fsinfo_state
*state
= talloc_get_type(creq
->private_data
, struct fsinfo_state
);
86 /* when this handler is called, the stage indicates what
87 call has just finished */
88 switch (state
->stage
) {
90 creq
->status
= fsinfo_connect(creq
, state
->io
);
94 creq
->status
= fsinfo_query(creq
, state
->io
);
98 if (!NT_STATUS_IS_OK(creq
->status
)) {
99 creq
->state
= COMPOSITE_STATE_ERROR
;
102 if (creq
->state
>= COMPOSITE_STATE_DONE
&& creq
->async
.fn
) {
103 creq
->async
.fn(creq
);
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()
111 static void fsinfo_raw_handler(struct smbcli_request
*req
)
113 struct composite_context
*c
= talloc_get_type(req
->async
.private_data
,
114 struct composite_context
);
115 fsinfo_state_handler(c
);
118 static void fsinfo_composite_handler(struct composite_context
*creq
)
120 struct composite_context
*c
= talloc_get_type(creq
->async
.private_data
,
121 struct composite_context
);
122 fsinfo_state_handler(c
);
126 composite fsinfo call - connects to a tree and queries a file system information
128 struct composite_context
*smb_composite_fsinfo_send(struct smbcli_tree
*tree
,
129 struct smb_composite_fsinfo
*io
,
130 struct resolve_context
*resolve_ctx
)
132 struct composite_context
*c
;
133 struct fsinfo_state
*state
;
135 c
= talloc_zero(tree
, struct composite_context
);
136 if (c
== NULL
) goto failed
;
138 state
= talloc(c
, struct fsinfo_state
);
139 if (state
== NULL
) goto failed
;
143 state
->connect
= talloc(state
, struct smb_composite_connect
);
145 if (state
->connect
== NULL
) goto failed
;
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
;
159 state
->connect
->in
.options
= tree
->session
->transport
->options
;
160 state
->connect
->in
.session_options
= tree
->session
->options
;
162 c
->state
= COMPOSITE_STATE_IN_PROGRESS
;
163 state
->stage
= FSINFO_CONNECT
;
164 c
->private_data
= state
;
166 state
->creq
= smb_composite_connect_send(state
->connect
, state
,
167 resolve_ctx
, c
->event_ctx
);
169 if (state
->creq
== NULL
) goto failed
;
171 state
->creq
->async
.private_data
= c
;
172 state
->creq
->async
.fn
= fsinfo_composite_handler
;
181 composite fsinfo call - recv side
183 NTSTATUS
smb_composite_fsinfo_recv(struct composite_context
*c
, TALLOC_CTX
*mem_ctx
)
187 status
= composite_wait(c
);
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
);
200 composite fsinfo call - sync interface
202 NTSTATUS
smb_composite_fsinfo(struct smbcli_tree
*tree
,
204 struct smb_composite_fsinfo
*io
,
205 struct resolve_context
*resolve_ctx
)
207 struct composite_context
*c
= smb_composite_fsinfo_send(tree
, io
, resolve_ctx
);
208 return smb_composite_fsinfo_recv(c
, mem_ctx
);