Merge branch 'upstream'
[jelmer/samba4-debian.git] / source / param / share_classic.c
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 loadparm_context *lp_ctx,
29                               struct share_context **ctx)
30 {
31         *ctx = talloc(mem_ctx, struct share_context);
32         if (!*ctx) {
33                 DEBUG(0, ("ERROR: Out of memory!\n"));
34                 return NT_STATUS_NO_MEMORY;
35         }
36
37         (*ctx)->ops = ops;
38         (*ctx)->priv_data = lp_ctx;
39
40         return NT_STATUS_OK;
41 }
42
43 static const char *sclassic_string_option(struct share_config *scfg, 
44                                           const char *opt_name, 
45                                           const char *defval)
46 {
47         struct loadparm_service *s = talloc_get_type(scfg->opaque, 
48                                                      struct loadparm_service);
49         struct loadparm_context *lp_ctx = talloc_get_type(scfg->ctx->priv_data, 
50                                                           struct loadparm_context);
51         char *parm, *val;
52         const char *ret;
53
54         if (strchr(opt_name, ':')) {
55                 parm = talloc_strdup(scfg, opt_name);
56                 if (!parm) {
57                         return NULL;
58                 }
59                 val = strchr(parm, ':');
60                 *val = '\0';
61                 val++;
62
63                 ret = lp_parm_string(lp_ctx, s, parm, val);
64                 if (!ret) {
65                         ret = defval;
66                 }
67                 talloc_free(parm);
68                 return ret;
69         }
70
71         if (strcmp(opt_name, SHARE_NAME) == 0) {
72                 return scfg->name;
73         }
74
75         if (strcmp(opt_name, SHARE_PATH) == 0) {
76                 return lp_pathname(s, lp_default_service(lp_ctx));
77         }
78
79         if (strcmp(opt_name, SHARE_COMMENT) == 0) {
80                 return lp_comment(s, lp_default_service(lp_ctx));
81         }
82
83         if (strcmp(opt_name, SHARE_VOLUME) == 0) {
84                 return volume_label(s, lp_default_service(lp_ctx));
85         }
86
87         if (strcmp(opt_name, SHARE_TYPE) == 0) {
88                 if (lp_print_ok(s, lp_default_service(lp_ctx))) {
89                         return "PRINTER";
90                 }
91                 if (strcmp("NTFS", lp_fstype(s, lp_default_service(lp_ctx))) == 0) {
92                         return "DISK";
93                 }
94                 return lp_fstype(s, lp_default_service(lp_ctx));
95         }
96
97         if (strcmp(opt_name, SHARE_PASSWORD) == 0) {
98                 return defval;
99         }
100
101         DEBUG(0,("request for unknown share string option '%s'\n",
102                  opt_name));
103
104         return defval;
105 }
106
107 static int sclassic_int_option(struct share_config *scfg, const char *opt_name, int defval)
108 {
109         struct loadparm_service *s = talloc_get_type(scfg->opaque, 
110                                                      struct loadparm_service);
111         struct loadparm_context *lp_ctx = talloc_get_type(scfg->ctx->priv_data, 
112                                                           struct loadparm_context);
113         char *parm, *val;
114         int ret;
115
116         if (strchr(opt_name, ':')) {
117                 parm = talloc_strdup(scfg, opt_name);
118                 if (!parm) {
119                         return -1;
120                 }
121                 val = strchr(parm, ':');
122                 *val = '\0';
123                 val++;
124
125                 ret = lp_parm_int(lp_ctx, s, parm, val, defval);
126                 if (!ret) {
127                         ret = defval;
128                 }
129                 talloc_free(parm);
130                 return ret;
131         }
132
133         if (strcmp(opt_name, SHARE_CSC_POLICY) == 0) {
134                 return lp_csc_policy(s, lp_default_service(lp_ctx));
135         }
136
137         if (strcmp(opt_name, SHARE_MAX_CONNECTIONS) == 0) {
138                 return lp_max_connections(s, lp_default_service(lp_ctx));
139         }
140
141         if (strcmp(opt_name, SHARE_CREATE_MASK) == 0) {
142                 return lp_create_mask(s, lp_default_service(lp_ctx));
143         }
144
145         if (strcmp(opt_name, SHARE_DIR_MASK) == 0) {
146                 return lp_dir_mask(s, lp_default_service(lp_ctx));
147         }
148
149         if (strcmp(opt_name, SHARE_FORCE_DIR_MODE) == 0) {
150                 return lp_force_dir_mode(s, lp_default_service(lp_ctx));
151         }
152
153         if (strcmp(opt_name, SHARE_FORCE_CREATE_MODE) == 0) {
154                 return lp_force_create_mode(s, lp_default_service(lp_ctx));
155         }
156
157
158         DEBUG(0,("request for unknown share int option '%s'\n",
159                  opt_name));
160
161         return defval;
162 }
163
164 static bool sclassic_bool_option(struct share_config *scfg, const char *opt_name, 
165                           bool defval)
166 {
167         struct loadparm_service *s = talloc_get_type(scfg->opaque, 
168                                                      struct loadparm_service);
169         struct loadparm_context *lp_ctx = talloc_get_type(scfg->ctx->priv_data, 
170                                                           struct loadparm_context);
171         char *parm, *val;
172         bool ret;
173
174         if (strchr(opt_name, ':')) {
175                 parm = talloc_strdup(scfg, opt_name);
176                 if(!parm) {
177                         return false;
178                 }
179                 val = strchr(parm, ':');
180                 *val = '\0';
181                 val++;
182
183                 ret = lp_parm_bool(lp_ctx, s, parm, val, defval);
184                 talloc_free(parm);
185                 return ret;
186         }
187
188         if (strcmp(opt_name, SHARE_AVAILABLE) == 0) {
189                 return s != NULL;
190         }
191
192         if (strcmp(opt_name, SHARE_BROWSEABLE) == 0) {
193                 return lp_browseable(s, lp_default_service(lp_ctx));
194         }
195
196         if (strcmp(opt_name, SHARE_READONLY) == 0) {
197                 return lp_readonly(s, lp_default_service(lp_ctx));
198         }
199
200         if (strcmp(opt_name, SHARE_MAP_SYSTEM) == 0) {
201                 return lp_map_system(s, lp_default_service(lp_ctx));
202         }
203
204         if (strcmp(opt_name, SHARE_MAP_HIDDEN) == 0) {
205                 return lp_map_hidden(s, lp_default_service(lp_ctx));
206         }
207
208         if (strcmp(opt_name, SHARE_MAP_ARCHIVE) == 0) {
209                 return lp_map_archive(s, lp_default_service(lp_ctx));
210         }
211
212         if (strcmp(opt_name, SHARE_STRICT_LOCKING) == 0) {
213                 return lp_strict_locking(s, lp_default_service(lp_ctx));
214         }
215
216         if (strcmp(opt_name, SHARE_OPLOCKS) == 0) {
217                 return lp_oplocks(s, lp_default_service(lp_ctx));
218         }
219
220         if (strcmp(opt_name, SHARE_STRICT_SYNC) == 0) {
221                 return lp_strict_sync(s, lp_default_service(lp_ctx));
222         }
223
224         if (strcmp(opt_name, SHARE_MSDFS_ROOT) == 0) {
225                 return lp_msdfs_root(s, lp_default_service(lp_ctx));
226         }
227
228         if (strcmp(opt_name, SHARE_CI_FILESYSTEM) == 0) {
229                 return lp_ci_filesystem(s, lp_default_service(lp_ctx));
230         }
231
232         DEBUG(0,("request for unknown share bool option '%s'\n",
233                  opt_name));
234
235         return defval;
236 }
237
238 static const char **sclassic_string_list_option(TALLOC_CTX *mem_ctx, struct share_config *scfg, const char *opt_name)
239 {
240         struct loadparm_service *s = talloc_get_type(scfg->opaque, 
241                                                      struct loadparm_service);
242         struct loadparm_context *lp_ctx = talloc_get_type(scfg->ctx->priv_data, 
243                                                           struct loadparm_context);
244         char *parm, *val;
245         const char **ret;
246
247         if (strchr(opt_name, ':')) {
248                 parm = talloc_strdup(scfg, opt_name);
249                 if (!parm) {
250                         return NULL;
251                 }
252                 val = strchr(parm, ':');
253                 *val = '\0';
254                 val++;
255
256                 ret = lp_parm_string_list(mem_ctx, lp_ctx, s, parm, val, ",;");
257                 talloc_free(parm);
258                 return ret;
259         }
260
261         if (strcmp(opt_name, SHARE_HOSTS_ALLOW) == 0) {
262                 return lp_hostsallow(s, lp_default_service(lp_ctx));
263         }
264
265         if (strcmp(opt_name, SHARE_HOSTS_DENY) == 0) {
266                 return lp_hostsdeny(s, lp_default_service(lp_ctx));
267         }
268
269         if (strcmp(opt_name, SHARE_NTVFS_HANDLER) == 0) {
270                 return lp_ntvfs_handler(s, lp_default_service(lp_ctx));
271         }
272
273         DEBUG(0,("request for unknown share list option '%s'\n",
274                  opt_name));
275
276         return NULL;
277 }
278
279 static NTSTATUS sclassic_list_all(TALLOC_CTX *mem_ctx,
280                                   struct share_context *ctx,
281                                   int *count,
282                                   const char ***names)
283 {
284         int i;
285         int num_services;
286         const char **n;
287        
288         num_services = lp_numservices((struct loadparm_context *)ctx->priv_data);
289
290         n = talloc_array(mem_ctx, const char *, num_services);
291         if (!n) {
292                 DEBUG(0,("ERROR: Out of memory!\n"));
293                 return NT_STATUS_NO_MEMORY;
294         }
295
296         for (i = 0; i < num_services; i++) {
297                 n[i] = talloc_strdup(n, lp_servicename(lp_servicebynum((struct loadparm_context *)ctx->priv_data, i)));
298                 if (!n[i]) {
299                         DEBUG(0,("ERROR: Out of memory!\n"));
300                         talloc_free(n);
301                         return NT_STATUS_NO_MEMORY;
302                 }
303         }
304
305         *names = n;
306         *count = num_services;
307
308         return NT_STATUS_OK;
309 }
310
311 static NTSTATUS sclassic_get_config(TALLOC_CTX *mem_ctx,
312                                     struct share_context *ctx,
313                                     const char *name,
314                                     struct share_config **scfg)
315 {
316         struct share_config *s;
317         struct loadparm_service *service;
318
319         service = lp_service((struct loadparm_context *)ctx->priv_data, name);
320
321         if (service == NULL) {
322                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
323         }
324
325         s = talloc(mem_ctx, struct share_config);
326         if (!s) {
327                 DEBUG(0,("ERROR: Out of memory!\n"));
328                 return NT_STATUS_NO_MEMORY;
329         }
330
331         s->name = talloc_strdup(s, lp_servicename(service));
332         if (!s->name) {
333                 DEBUG(0,("ERROR: Out of memory!\n"));
334                 talloc_free(s);
335                 return NT_STATUS_NO_MEMORY;
336         }
337
338         s->opaque = (void *)service;
339         s->ctx = ctx;
340         
341         *scfg = s;
342
343         return NT_STATUS_OK;
344 }
345
346 static const struct share_ops ops = {
347         .name = "classic",
348         .init = sclassic_init,
349         .string_option = sclassic_string_option,
350         .int_option = sclassic_int_option,
351         .bool_option = sclassic_bool_option,
352         .string_list_option = sclassic_string_list_option,
353         .list_all = sclassic_list_all,
354         .get_config = sclassic_get_config
355 };
356
357 NTSTATUS share_classic_init(void)
358 {
359         return share_register(&ops);
360 }
361