Merge branch 'v4-0-test' of ssh://git.samba.org/data/git/samba into v4-0-test
[sfrench/samba-autobuild/.git] / source4 / 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 event_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