r17206: Add a modular API for share configuration.
[kai/samba.git] / source4 / param / share_classic.c
1 /* 
2    Unix SMB/CIFS implementation.
3    
4    Classic file based services 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 2 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, write to the Free Software
20    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23 #include "includes.h"
24 #include "param/share.h"
25
26 struct sclassic_snum {
27         int snum;
28 };
29
30 static NTSTATUS sclassic_init(TALLOC_CTX *mem_ctx, const struct share_ops *ops, 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 = NULL;
40
41         return NT_STATUS_OK;
42 }
43
44 static const char *sclassic_string_option(struct share_config *scfg, const char *opt_name, const char *defval)
45 {
46         struct sclassic_snum *s = talloc_get_type(scfg->opaque, struct sclassic_snum);
47         char *parm, *val;
48         const char *ret;
49
50         if (strchr(opt_name, ':')) {
51                 parm = talloc_strdup(scfg, opt_name);
52                 if (!parm) {
53                         return NULL;
54                 }
55                 val = strchr(parm, ':');
56                 *val = '\0';
57                 val++;
58
59                 ret = lp_parm_string(s->snum, parm, val);
60                 if (!ret) {
61                         ret = defval;
62                 }
63                 talloc_free(parm);
64                 return ret;
65         }
66
67         if (strcmp(opt_name, SHARE_NAME) == 0) {
68                 return scfg->name;
69         }
70
71         if (strcmp(opt_name, SHARE_PATH) == 0) {
72                 return lp_pathname(s->snum);
73         }
74
75         if (strcmp(opt_name, SHARE_COMMENT) == 0) {
76                 return lp_comment(s->snum);
77         }
78
79         if (strcmp(opt_name, SHARE_VOLUME) == 0) {
80                 return volume_label(s->snum);
81         }
82
83         if (strcmp(opt_name, SHARE_TYPE) == 0) {
84                 if (lp_print_ok(s->snum)) {
85                         return "PRINTER";
86                 }
87                 return lp_fstype(s->snum);
88         }
89
90         return defval;
91 }
92
93 int sclassic_int_option(struct share_config *scfg, const char *opt_name, int defval)
94 {
95         struct sclassic_snum *s = talloc_get_type(scfg->opaque, struct sclassic_snum);
96         char *parm, *val;
97         int ret;
98
99         if (strchr(opt_name, ':')) {
100                 parm = talloc_strdup(scfg, opt_name);
101                 if (!parm) {
102                         return -1;
103                 }
104                 val = strchr(parm, ':');
105                 *val = '\0';
106                 val++;
107
108                 ret = lp_parm_int(s->snum, parm, val, defval);
109                 if (!ret) {
110                         ret = defval;
111                 }
112                 talloc_free(parm);
113                 return ret;
114         }
115
116         if (strcmp(opt_name, SHARE_CSC_POLICY) == 0) {
117                 ret = lp_csc_policy(s->snum);
118                 if (ret == -1) {
119                         return defval;
120                 }
121         }
122
123         if (strcmp(opt_name, SHARE_MAX_CONNECTIONS) == 0) {
124                 ret = lp_max_connections(s->snum);
125                 if (ret == -1) {
126                         return defval;
127                 }
128         }
129
130         return defval;
131 }
132
133 BOOL sclassic_bool_option(struct share_config *scfg, const char *opt_name, BOOL defval)
134 {
135         struct sclassic_snum *s = talloc_get_type(scfg->opaque, struct sclassic_snum);
136         char *parm, *val;
137         BOOL ret;
138
139         if (strchr(opt_name, ':')) {
140                 parm = talloc_strdup(scfg, opt_name);
141                 if(!parm) {
142                         return NULL;
143                 }
144                 val = strchr(parm, ':');
145                 *val = '\0';
146                 val++;
147
148                 ret = lp_parm_bool(s->snum, parm, val, defval);
149                 talloc_free(parm);
150                 return ret;
151         }
152
153         if (strcmp(opt_name, SHARE_AVAILABLE) == 0) {
154                 return lp_snum_ok(s->snum);
155         }
156
157         if (strcmp(opt_name, SHARE_BROWSEABLE) == 0) {
158                 return lp_browseable(s->snum);
159         }
160
161         if (strcmp(opt_name, SHARE_READONLY) == 0) {
162                 return lp_readonly(s->snum);
163         }
164
165         if (strcmp(opt_name, SHARE_MAP_SYSTEM) == 0) {
166                 return lp_map_system(s->snum);
167         }
168
169         if (strcmp(opt_name, SHARE_MAP_HIDDEN) == 0) {
170                 return lp_map_hidden(s->snum);
171         }
172
173         if (strcmp(opt_name, SHARE_MAP_ARCHIVE) == 0) {
174                 return lp_map_archive(s->snum);
175         }
176
177         if (strcmp(opt_name, SHARE_STRICT_LOCKING) == 0) {
178                 return lp_strict_locking(s->snum);
179         }
180
181         if (strcmp(opt_name, SHARE_STRICT_SYNC) == 0) {
182                 return lp_strict_sync(s->snum);
183         }
184
185         if (strcmp(opt_name, SHARE_MSDFS_ROOT) == 0) {
186                 return lp_msdfs_root(s->snum);
187         }
188
189         if (strcmp(opt_name, SHARE_CI_FILESYSTEM) == 0) {
190                 return lp_ci_filesystem(s->snum);
191         }
192
193         return defval;
194 }
195
196 const char **sclassic_string_list_option(TALLOC_CTX *mem_ctx, struct share_config *scfg, const char *opt_name)
197 {
198         struct sclassic_snum *s = talloc_get_type(scfg->opaque, struct sclassic_snum);
199         char *parm, *val;
200         const char **ret;
201
202         if (strchr(opt_name, ':')) {
203                 parm = talloc_strdup(scfg, opt_name);
204                 if (!parm) {
205                         return NULL;
206                 }
207                 val = strchr(parm, ':');
208                 *val = '\0';
209                 val++;
210
211                 ret = lp_parm_string_list(s->snum, parm, val, ",;");
212                 talloc_free(parm);
213                 return ret;
214         }
215
216         if (strcmp(opt_name, SHARE_HOSTS_ALLOW) == 0) {
217                 return lp_hostsallow(s->snum);
218         }
219
220         if (strcmp(opt_name, SHARE_HOSTS_DENY) == 0) {
221                 return lp_hostsdeny(s->snum);
222         }
223
224         if (strcmp(opt_name, SHARE_NTVFS_HANDLER) == 0) {
225                 return lp_ntvfs_handler(s->snum);
226         }
227
228         return NULL;
229 }
230
231 NTSTATUS sclassic_list_all(TALLOC_CTX *mem_ctx,
232                                      struct share_context *ctx,
233                                      int *count,
234                                      const char ***names)
235 {
236         int i;
237         int num_services;
238         const char **n;
239        
240         num_services = lp_numservices();
241
242         n = talloc_array(mem_ctx, const char *, num_services);
243         if (!n) {
244                 DEBUG(0,("ERROR: Out of memory!\n"));
245                 return NT_STATUS_NO_MEMORY;
246         }
247
248         for (i = 0; i < num_services; i++) {
249                 n[i] = talloc_strdup(n, lp_servicename(i));
250                 if (!n[i]) {
251                         DEBUG(0,("ERROR: Out of memory!\n"));
252                         talloc_free(n);
253                         return NT_STATUS_NO_MEMORY;
254                 }
255         }
256
257         *names = n;
258         *count = num_services;
259
260         return NT_STATUS_OK;
261 }
262
263 NTSTATUS sclassic_get_config(TALLOC_CTX *mem_ctx,
264                              struct share_context *ctx,
265                              const char *name,
266                              struct share_config **scfg)
267 {
268         int i, snum;
269         struct share_config *s;
270         struct sclassic_snum *scnum;
271
272         snum = -1;
273         for (i = 0; i < lp_numservices(); i++) {
274                 if (strcasecmp_m(name, lp_servicename(i)) == 0) {
275                         snum = i;
276                         break;
277                 }
278         }
279
280         if (snum < 0) {
281                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
282         }
283
284         s = talloc(mem_ctx, struct share_config);
285         if (!s) {
286                 DEBUG(0,("ERROR: Out of memory!\n"));
287                 return NT_STATUS_NO_MEMORY;
288         }
289
290         s->name = talloc_strdup(s, lp_servicename(snum));
291         if (!s->name) {
292                 DEBUG(0,("ERROR: Out of memory!\n"));
293                 talloc_free(s);
294                 return NT_STATUS_NO_MEMORY;
295         }
296
297         scnum = talloc(s, struct sclassic_snum);
298         if (!scnum) {
299                 DEBUG(0,("ERROR: Out of memory!\n"));
300                 talloc_free(s);
301                 return NT_STATUS_NO_MEMORY;
302         }
303         scnum->snum = snum;
304
305         s->opaque = (void *)scnum;
306         s->ctx = ctx;
307         
308         *scfg = s;
309
310         return NT_STATUS_OK;
311 }
312
313 NTSTATUS share_classic_init(void)
314 {
315         struct share_ops ops;
316
317         ops.name = "classic";
318         ops.init = sclassic_init;
319         ops.string_option = sclassic_string_option;
320         ops.int_option = sclassic_int_option;
321         ops.bool_option = sclassic_bool_option;
322         ops.string_list_option = sclassic_string_list_option;
323         ops.list_all = sclassic_list_all;
324         ops.get_config = sclassic_get_config;
325
326         return share_register(&ops);
327 }
328