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 2949 : 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 2949 : *ctx = talloc(mem_ctx, struct share_context);
34 2949 : if (!*ctx) {
35 0 : DEBUG(0, ("ERROR: Out of memory!\n"));
36 0 : return NT_STATUS_NO_MEMORY;
37 : }
38 :
39 2949 : (*ctx)->ops = ops;
40 2949 : (*ctx)->priv_data = lp_ctx;
41 :
42 2949 : return NT_STATUS_OK;
43 : }
44 :
45 12147 : 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 12147 : struct loadparm_service *s = talloc_get_type(scfg->opaque,
51 : struct loadparm_service);
52 12147 : struct loadparm_context *lp_ctx = talloc_get_type(scfg->ctx->priv_data,
53 : struct loadparm_context);
54 0 : char *parm, *val;
55 0 : const char *ret;
56 :
57 12147 : if (strchr(opt_name, ':')) {
58 6092 : parm = talloc_strdup(scfg, opt_name);
59 6092 : if (!parm) {
60 0 : return NULL;
61 : }
62 6092 : val = strchr(parm, ':');
63 6092 : *val = '\0';
64 6092 : val++;
65 :
66 6092 : ret = lpcfg_parm_string(lp_ctx, s, parm, val);
67 6092 : if (!ret) {
68 4452 : ret = defval;
69 : }
70 6092 : talloc_free(parm);
71 6092 : return talloc_strdup(mem_ctx, ret);
72 : }
73 :
74 6055 : if (strcmp(opt_name, SHARE_NAME) == 0) {
75 0 : return talloc_strdup(mem_ctx, scfg->name);
76 : }
77 :
78 6055 : if (strcmp(opt_name, SHARE_PATH) == 0) {
79 1663 : return lpcfg_path(s, lpcfg_default_service(lp_ctx), mem_ctx);
80 : }
81 :
82 4392 : if (strcmp(opt_name, SHARE_COMMENT) == 0) {
83 540 : return lpcfg_comment(s, lpcfg_default_service(lp_ctx), mem_ctx);
84 : }
85 :
86 3852 : if (strcmp(opt_name, SHARE_TYPE) == 0) {
87 3618 : if (lpcfg_printable(s, lpcfg_default_service(lp_ctx))) {
88 0 : return talloc_strdup(mem_ctx, "PRINTER");
89 : }
90 3618 : if (strcmp("NTFS", lpcfg_fstype(s, lpcfg_default_service(lp_ctx))) == 0) {
91 2456 : return talloc_strdup(mem_ctx, "DISK");
92 : }
93 1162 : 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 13223 : static int sclassic_int_option(struct share_config *scfg, const char *opt_name, int defval)
107 : {
108 13223 : struct loadparm_service *s = talloc_get_type(scfg->opaque,
109 : struct loadparm_service);
110 13223 : struct loadparm_context *lp_ctx = talloc_get_type(scfg->ctx->priv_data,
111 : struct loadparm_context);
112 0 : char *parm, *val;
113 0 : int ret;
114 :
115 13223 : if (strchr(opt_name, ':')) {
116 6640 : parm = talloc_strdup(scfg, opt_name);
117 6640 : if (!parm) {
118 0 : return -1;
119 : }
120 6640 : val = strchr(parm, ':');
121 6640 : *val = '\0';
122 6640 : val++;
123 :
124 6640 : ret = lpcfg_parm_int(lp_ctx, s, parm, val, defval);
125 6640 : if (!ret) {
126 0 : ret = defval;
127 : }
128 6640 : talloc_free(parm);
129 6640 : return ret;
130 : }
131 :
132 6583 : if (strcmp(opt_name, SHARE_CSC_POLICY) == 0) {
133 1037 : return lpcfg_csc_policy(s, lpcfg_default_service(lp_ctx));
134 : }
135 :
136 5546 : if (strcmp(opt_name, SHARE_MAX_CONNECTIONS) == 0) {
137 234 : return lpcfg_max_connections(s, lpcfg_default_service(lp_ctx));
138 : }
139 :
140 5312 : if (strcmp(opt_name, SHARE_CREATE_MASK) == 0) {
141 1328 : return lpcfg_create_mask(s, lpcfg_default_service(lp_ctx));
142 : }
143 :
144 3984 : if (strcmp(opt_name, SHARE_DIR_MASK) == 0) {
145 1328 : return lpcfg_directory_mask(s, lpcfg_default_service(lp_ctx));
146 : }
147 :
148 2656 : if (strcmp(opt_name, SHARE_FORCE_DIR_MODE) == 0) {
149 1328 : return lpcfg_force_directory_mode(s, lpcfg_default_service(lp_ctx));
150 : }
151 :
152 1328 : if (strcmp(opt_name, SHARE_FORCE_CREATE_MODE) == 0) {
153 1328 : 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 19672 : static bool sclassic_bool_option(struct share_config *scfg, const char *opt_name,
164 : bool defval)
165 : {
166 19672 : struct loadparm_service *s = talloc_get_type(scfg->opaque,
167 : struct loadparm_service);
168 19672 : struct loadparm_context *lp_ctx = talloc_get_type(scfg->ctx->priv_data,
169 : struct loadparm_context);
170 0 : char *parm, *val;
171 0 : bool ret;
172 :
173 19672 : if (strchr(opt_name, ':')) {
174 7264 : parm = talloc_strdup(scfg, opt_name);
175 7264 : if(!parm) {
176 0 : return false;
177 : }
178 7264 : val = strchr(parm, ':');
179 7264 : *val = '\0';
180 7264 : val++;
181 :
182 7264 : ret = lpcfg_parm_bool(lp_ctx, s, parm, val, defval);
183 7264 : talloc_free(parm);
184 7264 : return ret;
185 : }
186 :
187 12408 : if (strcmp(opt_name, SHARE_AVAILABLE) == 0) {
188 0 : return s != NULL;
189 : }
190 :
191 12408 : if (strcmp(opt_name, SHARE_BROWSEABLE) == 0) {
192 774 : return lpcfg_browseable(s, lpcfg_default_service(lp_ctx));
193 : }
194 :
195 11634 : if (strcmp(opt_name, SHARE_READONLY) == 0) {
196 1385 : return lpcfg_read_only(s, lpcfg_default_service(lp_ctx));
197 : }
198 :
199 10249 : if (strcmp(opt_name, SHARE_MAP_SYSTEM) == 0) {
200 1328 : return lpcfg_map_system(s, lpcfg_default_service(lp_ctx));
201 : }
202 :
203 8921 : if (strcmp(opt_name, SHARE_MAP_HIDDEN) == 0) {
204 1328 : return lpcfg_map_hidden(s, lpcfg_default_service(lp_ctx));
205 : }
206 :
207 7593 : if (strcmp(opt_name, SHARE_MAP_ARCHIVE) == 0) {
208 1328 : return lpcfg_map_archive(s, lpcfg_default_service(lp_ctx));
209 : }
210 :
211 6265 : if (strcmp(opt_name, SHARE_STRICT_LOCKING) == 0) {
212 1328 : return lpcfg_strict_locking(s, lpcfg_default_service(lp_ctx));
213 : }
214 :
215 4937 : if (strcmp(opt_name, SHARE_OPLOCKS) == 0) {
216 1328 : return lpcfg_oplocks(s, lpcfg_default_service(lp_ctx));
217 : }
218 :
219 3609 : if (strcmp(opt_name, SHARE_STRICT_SYNC) == 0) {
220 1328 : return lpcfg_strict_sync(s, lpcfg_default_service(lp_ctx));
221 : }
222 :
223 2281 : if (strcmp(opt_name, SHARE_MSDFS_ROOT) == 0) {
224 953 : return lpcfg_msdfs_root(s, lpcfg_default_service(lp_ctx));
225 : }
226 :
227 1328 : if (strcmp(opt_name, SHARE_CI_FILESYSTEM) == 0) {
228 1328 : 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 1328 : 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 1328 : 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 7703 : static const char **sclassic_string_list_option(TALLOC_CTX *mem_ctx, struct share_config *scfg, const char *opt_name)
263 : {
264 7703 : struct loadparm_service *s = talloc_get_type(scfg->opaque,
265 : struct loadparm_service);
266 7703 : struct loadparm_context *lp_ctx = talloc_get_type(scfg->ctx->priv_data,
267 : struct loadparm_context);
268 0 : char *parm, *val;
269 0 : const char **ret;
270 :
271 7703 : 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 7703 : if (strcmp(opt_name, SHARE_HOSTS_ALLOW) == 0) {
286 2574 : return lpcfg_hosts_allow(s, lpcfg_default_service(lp_ctx));
287 : }
288 :
289 5129 : if (strcmp(opt_name, SHARE_HOSTS_DENY) == 0) {
290 2574 : return lpcfg_hosts_deny(s, lpcfg_default_service(lp_ctx));
291 : }
292 :
293 2555 : if (strcmp(opt_name, SHARE_NTVFS_HANDLER) == 0) {
294 2555 : 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 99 : static NTSTATUS sclassic_list_all(TALLOC_CTX *mem_ctx,
304 : struct share_context *ctx,
305 : int *count,
306 : const char ***names)
307 : {
308 1 : int i;
309 1 : int num_services;
310 1 : const char **n;
311 :
312 99 : num_services = lpcfg_numservices((struct loadparm_context *)ctx->priv_data);
313 :
314 99 : n = talloc_array(mem_ctx, const char *, num_services);
315 99 : if (!n) {
316 0 : DEBUG(0,("ERROR: Out of memory!\n"));
317 0 : return NT_STATUS_NO_MEMORY;
318 : }
319 :
320 1373 : 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 99 : *names = n;
330 99 : *count = num_services;
331 :
332 99 : return NT_STATUS_OK;
333 : }
334 :
335 3499 : 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 0 : struct share_config *s;
341 0 : struct loadparm_service *service;
342 :
343 3499 : service = lpcfg_service((struct loadparm_context *)ctx->priv_data, name);
344 :
345 3499 : if (service == NULL) {
346 4 : return NT_STATUS_OBJECT_NAME_NOT_FOUND;
347 : }
348 :
349 3495 : s = talloc(mem_ctx, struct share_config);
350 3495 : if (!s) {
351 0 : DEBUG(0,("ERROR: Out of memory!\n"));
352 0 : return NT_STATUS_NO_MEMORY;
353 : }
354 :
355 3495 : s->name = talloc_strdup(s, lpcfg_servicename(service));
356 3495 : 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 3495 : s->opaque = (void *)service;
363 3495 : s->ctx = ctx;
364 :
365 3495 : *scfg = s;
366 :
367 3495 : 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 2420 : NTSTATUS share_classic_init(TALLOC_CTX *ctx)
382 : {
383 2420 : return share_register(&ops);
384 : }
385 :
|