Line data Source code
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 : NTSTATUS share_classic_init(TALLOC_CTX *);
27 :
28 3013 : static NTSTATUS sclassic_init(TALLOC_CTX *mem_ctx,
29 : const struct share_ops *ops,
30 : struct loadparm_context *lp_ctx,
31 : struct share_context **ctx)
32 : {
33 3013 : *ctx = talloc(mem_ctx, struct share_context);
34 3013 : if (!*ctx) {
35 0 : DEBUG(0, ("ERROR: Out of memory!\n"));
36 0 : return NT_STATUS_NO_MEMORY;
37 : }
38 :
39 3013 : (*ctx)->ops = ops;
40 3013 : (*ctx)->priv_data = lp_ctx;
41 :
42 3013 : return NT_STATUS_OK;
43 : }
44 :
45 12179 : static char *sclassic_string_option(TALLOC_CTX *mem_ctx,
46 : struct share_config *scfg,
47 : const char *opt_name,
48 : const char *defval)
49 : {
50 12179 : struct loadparm_service *s = talloc_get_type(scfg->opaque,
51 : struct loadparm_service);
52 12179 : struct loadparm_context *lp_ctx = talloc_get_type(scfg->ctx->priv_data,
53 : struct loadparm_context);
54 : char *parm, *val;
55 : const char *ret;
56 :
57 12179 : if (strchr(opt_name, ':')) {
58 6064 : parm = talloc_strdup(scfg, opt_name);
59 6064 : if (!parm) {
60 0 : return NULL;
61 : }
62 6064 : val = strchr(parm, ':');
63 6064 : *val = '\0';
64 6064 : val++;
65 :
66 6064 : ret = lpcfg_parm_string(lp_ctx, s, parm, val);
67 6064 : if (!ret) {
68 4431 : ret = defval;
69 : }
70 6064 : talloc_free(parm);
71 6064 : return talloc_strdup(mem_ctx, ret);
72 : }
73 :
74 6115 : if (strcmp(opt_name, SHARE_NAME) == 0) {
75 0 : return talloc_strdup(mem_ctx, scfg->name);
76 : }
77 :
78 6115 : if (strcmp(opt_name, SHARE_PATH) == 0) {
79 1656 : return lpcfg_path(s, lpcfg_default_service(lp_ctx), mem_ctx);
80 : }
81 :
82 4459 : if (strcmp(opt_name, SHARE_COMMENT) == 0) {
83 540 : return lpcfg_comment(s, lpcfg_default_service(lp_ctx), mem_ctx);
84 : }
85 :
86 3919 : if (strcmp(opt_name, SHARE_TYPE) == 0) {
87 3685 : if (lpcfg_printable(s, lpcfg_default_service(lp_ctx))) {
88 0 : return talloc_strdup(mem_ctx, "PRINTER");
89 : }
90 3685 : if (strcmp("NTFS", lpcfg_fstype(s, lpcfg_default_service(lp_ctx))) == 0) {
91 2449 : return talloc_strdup(mem_ctx, "DISK");
92 : }
93 1236 : return talloc_strdup(mem_ctx, lpcfg_fstype(s, lpcfg_default_service(lp_ctx)));
94 : }
95 :
96 234 : if (strcmp(opt_name, SHARE_PASSWORD) == 0) {
97 234 : return talloc_strdup(mem_ctx, defval);
98 : }
99 :
100 0 : DEBUG(0,("request for unknown share string option '%s'\n",
101 : opt_name));
102 :
103 0 : return talloc_strdup(mem_ctx, defval);
104 : }
105 :
106 13184 : static int sclassic_int_option(struct share_config *scfg, const char *opt_name, int defval)
107 : {
108 13184 : struct loadparm_service *s = talloc_get_type(scfg->opaque,
109 : struct loadparm_service);
110 13184 : struct loadparm_context *lp_ctx = talloc_get_type(scfg->ctx->priv_data,
111 : struct loadparm_context);
112 : char *parm, *val;
113 : int ret;
114 :
115 13184 : if (strchr(opt_name, ':')) {
116 6605 : parm = talloc_strdup(scfg, opt_name);
117 6605 : if (!parm) {
118 0 : return -1;
119 : }
120 6605 : val = strchr(parm, ':');
121 6605 : *val = '\0';
122 6605 : val++;
123 :
124 6605 : ret = lpcfg_parm_int(lp_ctx, s, parm, val, defval);
125 6605 : if (!ret) {
126 0 : ret = defval;
127 : }
128 6605 : talloc_free(parm);
129 6605 : return ret;
130 : }
131 :
132 6579 : if (strcmp(opt_name, SHARE_CSC_POLICY) == 0) {
133 1061 : return lpcfg_csc_policy(s, lpcfg_default_service(lp_ctx));
134 : }
135 :
136 5518 : if (strcmp(opt_name, SHARE_MAX_CONNECTIONS) == 0) {
137 234 : return lpcfg_max_connections(s, lpcfg_default_service(lp_ctx));
138 : }
139 :
140 5284 : if (strcmp(opt_name, SHARE_CREATE_MASK) == 0) {
141 1321 : return lpcfg_create_mask(s, lpcfg_default_service(lp_ctx));
142 : }
143 :
144 3963 : if (strcmp(opt_name, SHARE_DIR_MASK) == 0) {
145 1321 : return lpcfg_directory_mask(s, lpcfg_default_service(lp_ctx));
146 : }
147 :
148 2642 : if (strcmp(opt_name, SHARE_FORCE_DIR_MODE) == 0) {
149 1321 : return lpcfg_force_directory_mode(s, lpcfg_default_service(lp_ctx));
150 : }
151 :
152 1321 : if (strcmp(opt_name, SHARE_FORCE_CREATE_MODE) == 0) {
153 1321 : return lpcfg_force_create_mode(s, lpcfg_default_service(lp_ctx));
154 : }
155 :
156 :
157 0 : DEBUG(0,("request for unknown share int option '%s'\n",
158 : opt_name));
159 :
160 0 : return defval;
161 : }
162 :
163 19603 : static bool sclassic_bool_option(struct share_config *scfg, const char *opt_name,
164 : bool defval)
165 : {
166 19603 : struct loadparm_service *s = talloc_get_type(scfg->opaque,
167 : struct loadparm_service);
168 19603 : struct loadparm_context *lp_ctx = talloc_get_type(scfg->ctx->priv_data,
169 : struct loadparm_context);
170 : char *parm, *val;
171 : bool ret;
172 :
173 19603 : if (strchr(opt_name, ':')) {
174 7229 : parm = talloc_strdup(scfg, opt_name);
175 7229 : if(!parm) {
176 0 : return false;
177 : }
178 7229 : val = strchr(parm, ':');
179 7229 : *val = '\0';
180 7229 : val++;
181 :
182 7229 : ret = lpcfg_parm_bool(lp_ctx, s, parm, val, defval);
183 7229 : talloc_free(parm);
184 7229 : return ret;
185 : }
186 :
187 12374 : if (strcmp(opt_name, SHARE_AVAILABLE) == 0) {
188 0 : return s != NULL;
189 : }
190 :
191 12374 : if (strcmp(opt_name, SHARE_BROWSEABLE) == 0) {
192 774 : return lpcfg_browseable(s, lpcfg_default_service(lp_ctx));
193 : }
194 :
195 11600 : if (strcmp(opt_name, SHARE_READONLY) == 0) {
196 1376 : return lpcfg_read_only(s, lpcfg_default_service(lp_ctx));
197 : }
198 :
199 10224 : if (strcmp(opt_name, SHARE_MAP_SYSTEM) == 0) {
200 1321 : return lpcfg_map_system(s, lpcfg_default_service(lp_ctx));
201 : }
202 :
203 8903 : if (strcmp(opt_name, SHARE_MAP_HIDDEN) == 0) {
204 1321 : return lpcfg_map_hidden(s, lpcfg_default_service(lp_ctx));
205 : }
206 :
207 7582 : if (strcmp(opt_name, SHARE_MAP_ARCHIVE) == 0) {
208 1321 : return lpcfg_map_archive(s, lpcfg_default_service(lp_ctx));
209 : }
210 :
211 6261 : if (strcmp(opt_name, SHARE_STRICT_LOCKING) == 0) {
212 1321 : return lpcfg_strict_locking(s, lpcfg_default_service(lp_ctx));
213 : }
214 :
215 4940 : if (strcmp(opt_name, SHARE_OPLOCKS) == 0) {
216 1321 : return lpcfg_oplocks(s, lpcfg_default_service(lp_ctx));
217 : }
218 :
219 3619 : if (strcmp(opt_name, SHARE_STRICT_SYNC) == 0) {
220 1321 : return lpcfg_strict_sync(s, lpcfg_default_service(lp_ctx));
221 : }
222 :
223 2298 : if (strcmp(opt_name, SHARE_MSDFS_ROOT) == 0) {
224 977 : return lpcfg_msdfs_root(s, lpcfg_default_service(lp_ctx));
225 : }
226 :
227 1321 : if (strcmp(opt_name, SHARE_CI_FILESYSTEM) == 0) {
228 1321 : int case_sensitive = lpcfg_case_sensitive(s, lpcfg_default_service(lp_ctx));
229 : /*
230 : * Yes, this confusingly named option means Samba acts
231 : * case sensitive, so that the filesystem can act case
232 : * insensitive.
233 : *
234 : */
235 1321 : if (case_sensitive == Auto) {
236 : /* Auto is for unix extensions and unix
237 : * clients, which we don't support here.
238 : * Samba needs to do the case changing,
239 : * because the filesystem is case
240 : * sensitive */
241 1321 : return false;
242 0 : } else if (case_sensitive) {
243 : /* True means that Samba won't do anything to
244 : * change the case of incoming requests.
245 : * Essentially this means we trust the file
246 : * system to be case insensitive */
247 0 : return true;
248 : } else {
249 : /* False means that Smaba needs to do the case
250 : * changing, because the filesystem is case
251 : * sensitive */
252 0 : return false;
253 : }
254 : }
255 :
256 0 : DEBUG(0,("request for unknown share bool option '%s'\n",
257 : opt_name));
258 :
259 0 : return defval;
260 : }
261 :
262 7904 : static const char **sclassic_string_list_option(TALLOC_CTX *mem_ctx, struct share_config *scfg, const char *opt_name)
263 : {
264 7904 : struct loadparm_service *s = talloc_get_type(scfg->opaque,
265 : struct loadparm_service);
266 7904 : struct loadparm_context *lp_ctx = talloc_get_type(scfg->ctx->priv_data,
267 : struct loadparm_context);
268 : char *parm, *val;
269 : const char **ret;
270 :
271 7904 : if (strchr(opt_name, ':')) {
272 0 : parm = talloc_strdup(scfg, opt_name);
273 0 : if (!parm) {
274 0 : return NULL;
275 : }
276 0 : val = strchr(parm, ':');
277 0 : *val = '\0';
278 0 : val++;
279 :
280 0 : ret = lpcfg_parm_string_list(mem_ctx, lp_ctx, s, parm, val, ",;");
281 0 : talloc_free(parm);
282 0 : return ret;
283 : }
284 :
285 7904 : if (strcmp(opt_name, SHARE_HOSTS_ALLOW) == 0) {
286 2641 : return lpcfg_hosts_allow(s, lpcfg_default_service(lp_ctx));
287 : }
288 :
289 5263 : if (strcmp(opt_name, SHARE_HOSTS_DENY) == 0) {
290 2641 : return lpcfg_hosts_deny(s, lpcfg_default_service(lp_ctx));
291 : }
292 :
293 2622 : if (strcmp(opt_name, SHARE_NTVFS_HANDLER) == 0) {
294 2622 : return lpcfg_ntvfs_handler(s, lpcfg_default_service(lp_ctx));
295 : }
296 :
297 0 : DEBUG(0,("request for unknown share list option '%s'\n",
298 : opt_name));
299 :
300 0 : return NULL;
301 : }
302 :
303 98 : static NTSTATUS sclassic_list_all(TALLOC_CTX *mem_ctx,
304 : struct share_context *ctx,
305 : int *count,
306 : const char ***names)
307 : {
308 : int i;
309 : int num_services;
310 : const char **n;
311 :
312 98 : num_services = lpcfg_numservices((struct loadparm_context *)ctx->priv_data);
313 :
314 98 : n = talloc_array(mem_ctx, const char *, num_services);
315 98 : if (!n) {
316 0 : DEBUG(0,("ERROR: Out of memory!\n"));
317 0 : return NT_STATUS_NO_MEMORY;
318 : }
319 :
320 1372 : for (i = 0; i < num_services; i++) {
321 1274 : n[i] = talloc_strdup(n, lpcfg_servicename(lpcfg_servicebynum((struct loadparm_context *)ctx->priv_data, i)));
322 1274 : if (!n[i]) {
323 0 : DEBUG(0,("ERROR: Out of memory!\n"));
324 0 : talloc_free(n);
325 0 : return NT_STATUS_NO_MEMORY;
326 : }
327 : }
328 :
329 98 : *names = n;
330 98 : *count = num_services;
331 :
332 98 : return NT_STATUS_OK;
333 : }
334 :
335 3562 : static NTSTATUS sclassic_get_config(TALLOC_CTX *mem_ctx,
336 : struct share_context *ctx,
337 : const char *name,
338 : struct share_config **scfg)
339 : {
340 : struct share_config *s;
341 : struct loadparm_service *service;
342 :
343 3562 : service = lpcfg_service((struct loadparm_context *)ctx->priv_data, name);
344 :
345 3562 : if (service == NULL) {
346 0 : return NT_STATUS_OBJECT_NAME_NOT_FOUND;
347 : }
348 :
349 3562 : s = talloc(mem_ctx, struct share_config);
350 3562 : if (!s) {
351 0 : DEBUG(0,("ERROR: Out of memory!\n"));
352 0 : return NT_STATUS_NO_MEMORY;
353 : }
354 :
355 3562 : s->name = talloc_strdup(s, lpcfg_servicename(service));
356 3562 : if (!s->name) {
357 0 : DEBUG(0,("ERROR: Out of memory!\n"));
358 0 : talloc_free(s);
359 0 : return NT_STATUS_NO_MEMORY;
360 : }
361 :
362 3562 : s->opaque = (void *)service;
363 3562 : s->ctx = ctx;
364 :
365 3562 : *scfg = s;
366 :
367 3562 : return NT_STATUS_OK;
368 : }
369 :
370 : static const struct share_ops ops = {
371 : .name = "classic",
372 : .init = sclassic_init,
373 : .string_option = sclassic_string_option,
374 : .int_option = sclassic_int_option,
375 : .bool_option = sclassic_bool_option,
376 : .string_list_option = sclassic_string_list_option,
377 : .list_all = sclassic_list_all,
378 : .get_config = sclassic_get_config
379 : };
380 :
381 1017 : NTSTATUS share_classic_init(TALLOC_CTX *ctx)
382 : {
383 1017 : return share_register(&ops);
384 : }
385 :
|