1 | /*
|
---|
2 | Unix SMB/CIFS implementation.
|
---|
3 |
|
---|
4 | Classic file based shares configuration
|
---|
5 |
|
---|
6 | Copyright (C) Simo Sorce 2006
|
---|
7 |
|
---|
8 | This program is free software; you can redistribute it and/or modify
|
---|
9 | it under the terms of the GNU General Public License as published by
|
---|
10 | the Free Software Foundation; either version 3 of the License, or
|
---|
11 | (at your option) any later version.
|
---|
12 |
|
---|
13 | This program is distributed in the hope that it will be useful,
|
---|
14 | but WITHOUT ANY WARRANTY; without even the implied warranty of
|
---|
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
---|
16 | GNU General Public License for more details.
|
---|
17 |
|
---|
18 | You should have received a copy of the GNU General Public License
|
---|
19 | along with this program. If not, see <http://www.gnu.org/licenses/>.
|
---|
20 | */
|
---|
21 |
|
---|
22 | #include "includes.h"
|
---|
23 | #include "param/share.h"
|
---|
24 | #include "param/param.h"
|
---|
25 |
|
---|
26 | static NTSTATUS sclassic_init(TALLOC_CTX *mem_ctx,
|
---|
27 | const struct share_ops *ops,
|
---|
28 | struct tevent_context *event_ctx,
|
---|
29 | struct loadparm_context *lp_ctx,
|
---|
30 | struct share_context **ctx)
|
---|
31 | {
|
---|
32 | *ctx = talloc(mem_ctx, struct share_context);
|
---|
33 | if (!*ctx) {
|
---|
34 | DEBUG(0, ("ERROR: Out of memory!\n"));
|
---|
35 | return NT_STATUS_NO_MEMORY;
|
---|
36 | }
|
---|
37 |
|
---|
38 | (*ctx)->ops = ops;
|
---|
39 | (*ctx)->priv_data = lp_ctx;
|
---|
40 |
|
---|
41 | return NT_STATUS_OK;
|
---|
42 | }
|
---|
43 |
|
---|
44 | static const char *sclassic_string_option(struct share_config *scfg,
|
---|
45 | const char *opt_name,
|
---|
46 | const char *defval)
|
---|
47 | {
|
---|
48 | struct loadparm_service *s = talloc_get_type(scfg->opaque,
|
---|
49 | struct loadparm_service);
|
---|
50 | struct loadparm_context *lp_ctx = talloc_get_type(scfg->ctx->priv_data,
|
---|
51 | struct loadparm_context);
|
---|
52 | char *parm, *val;
|
---|
53 | const char *ret;
|
---|
54 |
|
---|
55 | if (strchr(opt_name, ':')) {
|
---|
56 | parm = talloc_strdup(scfg, opt_name);
|
---|
57 | if (!parm) {
|
---|
58 | return NULL;
|
---|
59 | }
|
---|
60 | val = strchr(parm, ':');
|
---|
61 | *val = '\0';
|
---|
62 | val++;
|
---|
63 |
|
---|
64 | ret = lp_parm_string(lp_ctx, s, parm, val);
|
---|
65 | if (!ret) {
|
---|
66 | ret = defval;
|
---|
67 | }
|
---|
68 | talloc_free(parm);
|
---|
69 | return ret;
|
---|
70 | }
|
---|
71 |
|
---|
72 | if (strcmp(opt_name, SHARE_NAME) == 0) {
|
---|
73 | return scfg->name;
|
---|
74 | }
|
---|
75 |
|
---|
76 | if (strcmp(opt_name, SHARE_PATH) == 0) {
|
---|
77 | return lp_pathname(s, lp_default_service(lp_ctx));
|
---|
78 | }
|
---|
79 |
|
---|
80 | if (strcmp(opt_name, SHARE_COMMENT) == 0) {
|
---|
81 | return lp_comment(s, lp_default_service(lp_ctx));
|
---|
82 | }
|
---|
83 |
|
---|
84 | if (strcmp(opt_name, SHARE_VOLUME) == 0) {
|
---|
85 | return volume_label(s, lp_default_service(lp_ctx));
|
---|
86 | }
|
---|
87 |
|
---|
88 | if (strcmp(opt_name, SHARE_TYPE) == 0) {
|
---|
89 | if (lp_print_ok(s, lp_default_service(lp_ctx))) {
|
---|
90 | return "PRINTER";
|
---|
91 | }
|
---|
92 | if (strcmp("NTFS", lp_fstype(s, lp_default_service(lp_ctx))) == 0) {
|
---|
93 | return "DISK";
|
---|
94 | }
|
---|
95 | return lp_fstype(s, lp_default_service(lp_ctx));
|
---|
96 | }
|
---|
97 |
|
---|
98 | if (strcmp(opt_name, SHARE_PASSWORD) == 0) {
|
---|
99 | return defval;
|
---|
100 | }
|
---|
101 |
|
---|
102 | DEBUG(0,("request for unknown share string option '%s'\n",
|
---|
103 | opt_name));
|
---|
104 |
|
---|
105 | return defval;
|
---|
106 | }
|
---|
107 |
|
---|
108 | static int sclassic_int_option(struct share_config *scfg, const char *opt_name, int defval)
|
---|
109 | {
|
---|
110 | struct loadparm_service *s = talloc_get_type(scfg->opaque,
|
---|
111 | struct loadparm_service);
|
---|
112 | struct loadparm_context *lp_ctx = talloc_get_type(scfg->ctx->priv_data,
|
---|
113 | struct loadparm_context);
|
---|
114 | char *parm, *val;
|
---|
115 | int ret;
|
---|
116 |
|
---|
117 | if (strchr(opt_name, ':')) {
|
---|
118 | parm = talloc_strdup(scfg, opt_name);
|
---|
119 | if (!parm) {
|
---|
120 | return -1;
|
---|
121 | }
|
---|
122 | val = strchr(parm, ':');
|
---|
123 | *val = '\0';
|
---|
124 | val++;
|
---|
125 |
|
---|
126 | ret = lp_parm_int(lp_ctx, s, parm, val, defval);
|
---|
127 | if (!ret) {
|
---|
128 | ret = defval;
|
---|
129 | }
|
---|
130 | talloc_free(parm);
|
---|
131 | return ret;
|
---|
132 | }
|
---|
133 |
|
---|
134 | if (strcmp(opt_name, SHARE_CSC_POLICY) == 0) {
|
---|
135 | return lp_csc_policy(s, lp_default_service(lp_ctx));
|
---|
136 | }
|
---|
137 |
|
---|
138 | if (strcmp(opt_name, SHARE_MAX_CONNECTIONS) == 0) {
|
---|
139 | return lp_max_connections(s, lp_default_service(lp_ctx));
|
---|
140 | }
|
---|
141 |
|
---|
142 | if (strcmp(opt_name, SHARE_CREATE_MASK) == 0) {
|
---|
143 | return lp_create_mask(s, lp_default_service(lp_ctx));
|
---|
144 | }
|
---|
145 |
|
---|
146 | if (strcmp(opt_name, SHARE_DIR_MASK) == 0) {
|
---|
147 | return lp_dir_mask(s, lp_default_service(lp_ctx));
|
---|
148 | }
|
---|
149 |
|
---|
150 | if (strcmp(opt_name, SHARE_FORCE_DIR_MODE) == 0) {
|
---|
151 | return lp_force_dir_mode(s, lp_default_service(lp_ctx));
|
---|
152 | }
|
---|
153 |
|
---|
154 | if (strcmp(opt_name, SHARE_FORCE_CREATE_MODE) == 0) {
|
---|
155 | return lp_force_create_mode(s, lp_default_service(lp_ctx));
|
---|
156 | }
|
---|
157 |
|
---|
158 |
|
---|
159 | DEBUG(0,("request for unknown share int option '%s'\n",
|
---|
160 | opt_name));
|
---|
161 |
|
---|
162 | return defval;
|
---|
163 | }
|
---|
164 |
|
---|
165 | static bool sclassic_bool_option(struct share_config *scfg, const char *opt_name,
|
---|
166 | bool defval)
|
---|
167 | {
|
---|
168 | struct loadparm_service *s = talloc_get_type(scfg->opaque,
|
---|
169 | struct loadparm_service);
|
---|
170 | struct loadparm_context *lp_ctx = talloc_get_type(scfg->ctx->priv_data,
|
---|
171 | struct loadparm_context);
|
---|
172 | char *parm, *val;
|
---|
173 | bool ret;
|
---|
174 |
|
---|
175 | if (strchr(opt_name, ':')) {
|
---|
176 | parm = talloc_strdup(scfg, opt_name);
|
---|
177 | if(!parm) {
|
---|
178 | return false;
|
---|
179 | }
|
---|
180 | val = strchr(parm, ':');
|
---|
181 | *val = '\0';
|
---|
182 | val++;
|
---|
183 |
|
---|
184 | ret = lp_parm_bool(lp_ctx, s, parm, val, defval);
|
---|
185 | talloc_free(parm);
|
---|
186 | return ret;
|
---|
187 | }
|
---|
188 |
|
---|
189 | if (strcmp(opt_name, SHARE_AVAILABLE) == 0) {
|
---|
190 | return s != NULL;
|
---|
191 | }
|
---|
192 |
|
---|
193 | if (strcmp(opt_name, SHARE_BROWSEABLE) == 0) {
|
---|
194 | return lp_browseable(s, lp_default_service(lp_ctx));
|
---|
195 | }
|
---|
196 |
|
---|
197 | if (strcmp(opt_name, SHARE_READONLY) == 0) {
|
---|
198 | return lp_readonly(s, lp_default_service(lp_ctx));
|
---|
199 | }
|
---|
200 |
|
---|
201 | if (strcmp(opt_name, SHARE_MAP_SYSTEM) == 0) {
|
---|
202 | return lp_map_system(s, lp_default_service(lp_ctx));
|
---|
203 | }
|
---|
204 |
|
---|
205 | if (strcmp(opt_name, SHARE_MAP_HIDDEN) == 0) {
|
---|
206 | return lp_map_hidden(s, lp_default_service(lp_ctx));
|
---|
207 | }
|
---|
208 |
|
---|
209 | if (strcmp(opt_name, SHARE_MAP_ARCHIVE) == 0) {
|
---|
210 | return lp_map_archive(s, lp_default_service(lp_ctx));
|
---|
211 | }
|
---|
212 |
|
---|
213 | if (strcmp(opt_name, SHARE_STRICT_LOCKING) == 0) {
|
---|
214 | return lp_strict_locking(s, lp_default_service(lp_ctx));
|
---|
215 | }
|
---|
216 |
|
---|
217 | if (strcmp(opt_name, SHARE_OPLOCKS) == 0) {
|
---|
218 | return lp_oplocks(s, lp_default_service(lp_ctx));
|
---|
219 | }
|
---|
220 |
|
---|
221 | if (strcmp(opt_name, SHARE_STRICT_SYNC) == 0) {
|
---|
222 | return lp_strict_sync(s, lp_default_service(lp_ctx));
|
---|
223 | }
|
---|
224 |
|
---|
225 | if (strcmp(opt_name, SHARE_MSDFS_ROOT) == 0) {
|
---|
226 | return lp_msdfs_root(s, lp_default_service(lp_ctx));
|
---|
227 | }
|
---|
228 |
|
---|
229 | if (strcmp(opt_name, SHARE_CI_FILESYSTEM) == 0) {
|
---|
230 | return lp_ci_filesystem(s, lp_default_service(lp_ctx));
|
---|
231 | }
|
---|
232 |
|
---|
233 | DEBUG(0,("request for unknown share bool option '%s'\n",
|
---|
234 | opt_name));
|
---|
235 |
|
---|
236 | return defval;
|
---|
237 | }
|
---|
238 |
|
---|
239 | static const char **sclassic_string_list_option(TALLOC_CTX *mem_ctx, struct share_config *scfg, const char *opt_name)
|
---|
240 | {
|
---|
241 | struct loadparm_service *s = talloc_get_type(scfg->opaque,
|
---|
242 | struct loadparm_service);
|
---|
243 | struct loadparm_context *lp_ctx = talloc_get_type(scfg->ctx->priv_data,
|
---|
244 | struct loadparm_context);
|
---|
245 | char *parm, *val;
|
---|
246 | const char **ret;
|
---|
247 |
|
---|
248 | if (strchr(opt_name, ':')) {
|
---|
249 | parm = talloc_strdup(scfg, opt_name);
|
---|
250 | if (!parm) {
|
---|
251 | return NULL;
|
---|
252 | }
|
---|
253 | val = strchr(parm, ':');
|
---|
254 | *val = '\0';
|
---|
255 | val++;
|
---|
256 |
|
---|
257 | ret = lp_parm_string_list(mem_ctx, lp_ctx, s, parm, val, ",;");
|
---|
258 | talloc_free(parm);
|
---|
259 | return ret;
|
---|
260 | }
|
---|
261 |
|
---|
262 | if (strcmp(opt_name, SHARE_HOSTS_ALLOW) == 0) {
|
---|
263 | return lp_hostsallow(s, lp_default_service(lp_ctx));
|
---|
264 | }
|
---|
265 |
|
---|
266 | if (strcmp(opt_name, SHARE_HOSTS_DENY) == 0) {
|
---|
267 | return lp_hostsdeny(s, lp_default_service(lp_ctx));
|
---|
268 | }
|
---|
269 |
|
---|
270 | if (strcmp(opt_name, SHARE_NTVFS_HANDLER) == 0) {
|
---|
271 | return lp_ntvfs_handler(s, lp_default_service(lp_ctx));
|
---|
272 | }
|
---|
273 |
|
---|
274 | DEBUG(0,("request for unknown share list option '%s'\n",
|
---|
275 | opt_name));
|
---|
276 |
|
---|
277 | return NULL;
|
---|
278 | }
|
---|
279 |
|
---|
280 | static NTSTATUS sclassic_list_all(TALLOC_CTX *mem_ctx,
|
---|
281 | struct share_context *ctx,
|
---|
282 | int *count,
|
---|
283 | const char ***names)
|
---|
284 | {
|
---|
285 | int i;
|
---|
286 | int num_services;
|
---|
287 | const char **n;
|
---|
288 |
|
---|
289 | num_services = lp_numservices((struct loadparm_context *)ctx->priv_data);
|
---|
290 |
|
---|
291 | n = talloc_array(mem_ctx, const char *, num_services);
|
---|
292 | if (!n) {
|
---|
293 | DEBUG(0,("ERROR: Out of memory!\n"));
|
---|
294 | return NT_STATUS_NO_MEMORY;
|
---|
295 | }
|
---|
296 |
|
---|
297 | for (i = 0; i < num_services; i++) {
|
---|
298 | n[i] = talloc_strdup(n, lp_servicename(lp_servicebynum((struct loadparm_context *)ctx->priv_data, i)));
|
---|
299 | if (!n[i]) {
|
---|
300 | DEBUG(0,("ERROR: Out of memory!\n"));
|
---|
301 | talloc_free(n);
|
---|
302 | return NT_STATUS_NO_MEMORY;
|
---|
303 | }
|
---|
304 | }
|
---|
305 |
|
---|
306 | *names = n;
|
---|
307 | *count = num_services;
|
---|
308 |
|
---|
309 | return NT_STATUS_OK;
|
---|
310 | }
|
---|
311 |
|
---|
312 | static NTSTATUS sclassic_get_config(TALLOC_CTX *mem_ctx,
|
---|
313 | struct share_context *ctx,
|
---|
314 | const char *name,
|
---|
315 | struct share_config **scfg)
|
---|
316 | {
|
---|
317 | struct share_config *s;
|
---|
318 | struct loadparm_service *service;
|
---|
319 |
|
---|
320 | service = lp_service((struct loadparm_context *)ctx->priv_data, name);
|
---|
321 |
|
---|
322 | if (service == NULL) {
|
---|
323 | return NT_STATUS_OBJECT_NAME_NOT_FOUND;
|
---|
324 | }
|
---|
325 |
|
---|
326 | s = talloc(mem_ctx, struct share_config);
|
---|
327 | if (!s) {
|
---|
328 | DEBUG(0,("ERROR: Out of memory!\n"));
|
---|
329 | return NT_STATUS_NO_MEMORY;
|
---|
330 | }
|
---|
331 |
|
---|
332 | s->name = talloc_strdup(s, lp_servicename(service));
|
---|
333 | if (!s->name) {
|
---|
334 | DEBUG(0,("ERROR: Out of memory!\n"));
|
---|
335 | talloc_free(s);
|
---|
336 | return NT_STATUS_NO_MEMORY;
|
---|
337 | }
|
---|
338 |
|
---|
339 | s->opaque = (void *)service;
|
---|
340 | s->ctx = ctx;
|
---|
341 |
|
---|
342 | *scfg = s;
|
---|
343 |
|
---|
344 | return NT_STATUS_OK;
|
---|
345 | }
|
---|
346 |
|
---|
347 | static const struct share_ops ops = {
|
---|
348 | .name = "classic",
|
---|
349 | .init = sclassic_init,
|
---|
350 | .string_option = sclassic_string_option,
|
---|
351 | .int_option = sclassic_int_option,
|
---|
352 | .bool_option = sclassic_bool_option,
|
---|
353 | .string_list_option = sclassic_string_list_option,
|
---|
354 | .list_all = sclassic_list_all,
|
---|
355 | .get_config = sclassic_get_config
|
---|
356 | };
|
---|
357 |
|
---|
358 | NTSTATUS share_classic_init(void)
|
---|
359 | {
|
---|
360 | return share_register(&ops);
|
---|
361 | }
|
---|
362 |
|
---|