Line data Source code
1 : /*
2 : Unix SMB/CIFS implementation.
3 : NTVFS utility code
4 : Copyright (C) Stefan Metzmacher 2004
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 : this implements common utility functions that many NTVFS backends may wish to use
21 : */
22 :
23 : #include "includes.h"
24 : #include "../lib/util/dlinklist.h"
25 : #include "ntvfs/ntvfs.h"
26 :
27 :
28 829198 : struct ntvfs_request *ntvfs_request_create(struct ntvfs_context *ctx, TALLOC_CTX *mem_ctx,
29 : struct auth_session_info *session_info,
30 : uint16_t smbpid,
31 : struct timeval request_time,
32 : void *private_data,
33 : void (*send_fn)(struct ntvfs_request *),
34 : uint32_t state)
35 : {
36 0 : struct ntvfs_request *req;
37 0 : struct ntvfs_async_state *async;
38 :
39 829198 : req = talloc(mem_ctx, struct ntvfs_request);
40 829198 : if (!req) return NULL;
41 829198 : req->ctx = ctx;
42 829198 : req->async_states = NULL;
43 829198 : req->session_info = session_info;
44 829198 : req->smbpid = smbpid;
45 829198 : req->client_caps = ctx->client_caps;
46 829198 : req->statistics.request_time = request_time;
47 :
48 829198 : async = talloc(req, struct ntvfs_async_state);
49 829198 : if (!async) goto failed;
50 :
51 829198 : async->state = state;
52 829198 : async->private_data = private_data;
53 829198 : async->send_fn = send_fn;
54 829198 : async->status = NT_STATUS_INTERNAL_ERROR;
55 829198 : async->ntvfs = NULL;
56 :
57 829198 : DLIST_ADD(req->async_states, async);
58 :
59 829198 : return req;
60 0 : failed:
61 0 : talloc_free(req);
62 0 : return NULL;
63 : }
64 :
65 424940 : NTSTATUS ntvfs_async_state_push(struct ntvfs_module_context *ntvfs,
66 : struct ntvfs_request *req,
67 : void *private_data,
68 : void (*send_fn)(struct ntvfs_request *))
69 : {
70 0 : struct ntvfs_async_state *async;
71 :
72 424940 : async = talloc(req, struct ntvfs_async_state);
73 424940 : NT_STATUS_HAVE_NO_MEMORY(async);
74 :
75 424940 : async->state = req->async_states->state;
76 424940 : async->private_data = private_data;
77 424940 : async->send_fn = send_fn;
78 424940 : async->status = NT_STATUS_INTERNAL_ERROR;
79 :
80 424940 : async->ntvfs = ntvfs;
81 :
82 424940 : DLIST_ADD(req->async_states, async);
83 :
84 424940 : return NT_STATUS_OK;
85 : }
86 :
87 424940 : void ntvfs_async_state_pop(struct ntvfs_request *req)
88 : {
89 0 : struct ntvfs_async_state *async;
90 :
91 424940 : async = req->async_states;
92 :
93 424940 : DLIST_REMOVE(req->async_states, async);
94 :
95 424940 : req->async_states->state = async->state;
96 424940 : req->async_states->status = async->status;
97 :
98 424940 : talloc_free(async);
99 424940 : }
100 :
101 220947 : NTSTATUS ntvfs_handle_new(struct ntvfs_module_context *ntvfs,
102 : struct ntvfs_request *req,
103 : struct ntvfs_handle **h)
104 : {
105 220947 : if (!ntvfs->ctx->handles.create_new) {
106 0 : return NT_STATUS_NOT_IMPLEMENTED;
107 : }
108 220947 : return ntvfs->ctx->handles.create_new(ntvfs->ctx->handles.private_data, req, h);
109 : }
110 :
111 216370 : NTSTATUS ntvfs_handle_set_backend_data(struct ntvfs_handle *h,
112 : struct ntvfs_module_context *ntvfs,
113 : TALLOC_CTX *private_data)
114 : {
115 0 : struct ntvfs_handle_data *d;
116 216370 : bool first_time = h->backend_data?false:true;
117 :
118 216370 : for (d=h->backend_data; d; d = d->next) {
119 0 : if (d->owner != ntvfs) continue;
120 0 : d->private_data = talloc_steal(d, private_data);
121 0 : return NT_STATUS_OK;
122 : }
123 :
124 216370 : d = talloc(h, struct ntvfs_handle_data);
125 216370 : NT_STATUS_HAVE_NO_MEMORY(d);
126 216370 : d->owner = ntvfs;
127 216370 : d->private_data = talloc_steal(d, private_data);
128 :
129 216370 : DLIST_ADD(h->backend_data, d);
130 :
131 216370 : if (first_time) {
132 0 : NTSTATUS status;
133 216370 : status = h->ctx->handles.make_valid(h->ctx->handles.private_data, h);
134 216370 : NT_STATUS_NOT_OK_RETURN(status);
135 : }
136 :
137 216370 : return NT_STATUS_OK;
138 : }
139 :
140 396789 : void *ntvfs_handle_get_backend_data(struct ntvfs_handle *h,
141 : struct ntvfs_module_context *ntvfs)
142 : {
143 0 : struct ntvfs_handle_data *d;
144 :
145 396789 : for (d=h->backend_data; d; d = d->next) {
146 396789 : if (d->owner != ntvfs) continue;
147 396789 : return d->private_data;
148 : }
149 :
150 0 : return NULL;
151 : }
152 :
153 207441 : void ntvfs_handle_remove_backend_data(struct ntvfs_handle *h,
154 : struct ntvfs_module_context *ntvfs)
155 : {
156 0 : struct ntvfs_handle_data *d,*n;
157 :
158 412018 : for (d=h->backend_data; d; d = n) {
159 204577 : n = d->next;
160 204577 : if (d->owner != ntvfs) continue;
161 204577 : DLIST_REMOVE(h->backend_data, d);
162 204577 : talloc_free(d);
163 204577 : d = NULL;
164 : }
165 :
166 207441 : if (h->backend_data) return;
167 :
168 : /* if there's no backend_data anymore, destroy the handle */
169 207441 : h->ctx->handles.destroy(h->ctx->handles.private_data, h);
170 : }
171 :
172 42 : struct ntvfs_handle *ntvfs_handle_search_by_wire_key(struct ntvfs_module_context *ntvfs,
173 : struct ntvfs_request *req,
174 : const DATA_BLOB *key)
175 : {
176 42 : if (!ntvfs->ctx->handles.search_by_wire_key) {
177 0 : return NULL;
178 : }
179 42 : return ntvfs->ctx->handles.search_by_wire_key(ntvfs->ctx->handles.private_data, req, key);
180 : }
181 :
182 2555 : NTSTATUS ntvfs_set_handle_callbacks(struct ntvfs_context *ntvfs,
183 : NTSTATUS (*create_new)(void *private_data, struct ntvfs_request *req, struct ntvfs_handle **h),
184 : NTSTATUS (*make_valid)(void *private_data, struct ntvfs_handle *h),
185 : void (*destroy)(void *private_data, struct ntvfs_handle *h),
186 : struct ntvfs_handle *(*search_by_wire_key)(void *private_data, struct ntvfs_request *req, const DATA_BLOB *key),
187 : DATA_BLOB (*get_wire_key)(void *private_data, struct ntvfs_handle *handle, TALLOC_CTX *mem_ctx),
188 : void *private_data)
189 : {
190 2555 : ntvfs->handles.create_new = create_new;
191 2555 : ntvfs->handles.make_valid = make_valid;
192 2555 : ntvfs->handles.destroy = destroy;
193 2555 : ntvfs->handles.search_by_wire_key = search_by_wire_key;
194 2555 : ntvfs->handles.get_wire_key = get_wire_key;
195 2555 : ntvfs->handles.private_data = private_data;
196 2555 : return NT_STATUS_OK;
197 : }
|