0a6e23287cfc822497c2b38422451baedff8148c
[tprouty/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                 if (strcmp("NTFS", lp_fstype(s->snum)) == 0) {
88                         return "DISK";
89                 }
90                 return lp_fstype(s->snum);
91         }
92
93         DEBUG(0,("request for unknown share string option '%s'\n",
94                  opt_name));
95
96         return defval;
97 }
98
99 int sclassic_int_option(struct share_config *scfg, const char *opt_name, int defval)
100 {
101         struct sclassic_snum *s = talloc_get_type(scfg->opaque, struct sclassic_snum);
102         char *parm, *val;
103         int ret;
104
105         if (strchr(opt_name, ':')) {
106                 parm = talloc_strdup(scfg, opt_name);
107                 if (!parm) {
108                         return -1;
109                 }
110                 val = strchr(parm, ':');
111                 *val = '\0';
112                 val++;
113
114                 ret = lp_parm_int(s->snum, parm, val, defval);
115                 if (!ret) {
116                         ret = defval;
117                 }
118                 talloc_free(parm);
119                 return ret;
120         }
121
122         if (strcmp(opt_name, SHARE_CSC_POLICY) == 0) {
123                 return lp_csc_policy(s->snum);
124         }
125
126         if (strcmp(opt_name, SHARE_MAX_CONNECTIONS) == 0) {
127                 return lp_max_connections(s->snum);
128         }
129
130         if (strcmp(opt_name, SHARE_CREATE_MASK) == 0) {
131                 return lp_create_mask(s->snum);
132         }
133
134         if (strcmp(opt_name, SHARE_DIR_MASK) == 0) {
135                 return lp_dir_mask(s->snum);
136         }
137
138         if (strcmp(opt_name, SHARE_FORCE_DIR_MODE) == 0) {
139                 return lp_force_dir_mode(s->snum);
140         }
141
142         if (strcmp(opt_name, SHARE_FORCE_CREATE_MODE) == 0) {
143                 return lp_force_create_mode(s->snum);
144         }
145
146
147         DEBUG(0,("request for unknown share int option '%s'\n",
148                  opt_name));
149
150         return defval;
151 }
152
153 BOOL sclassic_bool_option(struct share_config *scfg, const char *opt_name, BOOL defval)
154 {
155         struct sclassic_snum *s = talloc_get_type(scfg->opaque, struct sclassic_snum);
156         char *parm, *val;
157         BOOL ret;
158
159         if (strchr(opt_name, ':')) {
160                 parm = talloc_strdup(scfg, opt_name);
161                 if(!parm) {
162                         return False;
163                 }
164                 val = strchr(parm, ':');
165                 *val = '\0';
166                 val++;
167
168                 ret = lp_parm_bool(s->snum, parm, val, defval);
169                 talloc_free(parm);
170                 return ret;
171         }
172
173         if (strcmp(opt_name, SHARE_AVAILABLE) == 0) {
174                 return lp_snum_ok(s->snum);
175         }
176
177         if (strcmp(opt_name, SHARE_BROWSEABLE) == 0) {
178                 return lp_browseable(s->snum);
179         }
180
181         if (strcmp(opt_name, SHARE_READONLY) == 0) {
182                 return lp_readonly(s->snum);
183         }
184
185         if (strcmp(opt_name, SHARE_MAP_SYSTEM) == 0) {
186                 return lp_map_system(s->snum);
187         }
188
189         if (strcmp(opt_name, SHARE_MAP_HIDDEN) == 0) {
190                 return lp_map_hidden(s->snum);
191         }
192
193         if (strcmp(opt_name, SHARE_MAP_ARCHIVE) == 0) {
194                 return lp_map_archive(s->snum);
195         }
196
197         if (strcmp(opt_name, SHARE_STRICT_LOCKING) == 0) {
198                 return lp_strict_locking(s->snum);
199         }
200
201         if (strcmp(opt_name, SHARE_STRICT_SYNC) == 0) {
202                 return lp_strict_sync(s->snum);
203         }
204
205         if (strcmp(opt_name, SHARE_MSDFS_ROOT) == 0) {
206                 return lp_msdfs_root(s->snum);
207         }
208
209         if (strcmp(opt_name, SHARE_CI_FILESYSTEM) == 0) {
210                 return lp_ci_filesystem(s->snum);
211         }
212
213         DEBUG(0,("request for unknown share bool option '%s'\n",
214                  opt_name));
215
216         return defval;
217 }
218
219 const char **sclassic_string_list_option(TALLOC_CTX *mem_ctx, struct share_config *scfg, const char *opt_name)
220 {
221         struct sclassic_snum *s = talloc_get_type(scfg->opaque, struct sclassic_snum);
222         char *parm, *val;
223         const char **ret;
224
225         if (strchr(opt_name, ':')) {
226                 parm = talloc_strdup(scfg, opt_name);
227                 if (!parm) {
228                         return NULL;
229                 }
230                 val = strchr(parm, ':');
231                 *val = '\0';
232                 val++;
233
234                 ret = lp_parm_string_list(s->snum, parm, val, ",;");
235                 talloc_free(parm);
236                 return ret;
237         }
238
239         if (strcmp(opt_name, SHARE_HOSTS_ALLOW) == 0) {
240                 return lp_hostsallow(s->snum);
241         }
242
243         if (strcmp(opt_name, SHARE_HOSTS_DENY) == 0) {
244                 return lp_hostsdeny(s->snum);
245         }
246
247         if (strcmp(opt_name, SHARE_NTVFS_HANDLER) == 0) {
248                 return lp_ntvfs_handler(s->snum);
249         }
250
251         DEBUG(0,("request for unknown share list option '%s'\n",
252                  opt_name));
253
254         return NULL;
255 }
256
257 NTSTATUS sclassic_list_all(TALLOC_CTX *mem_ctx,
258                                      struct share_context *ctx,
259                                      int *count,
260                                      const char ***names)
261 {
262         int i;
263         int num_services;
264         const char **n;
265        
266         num_services = lp_numservices();
267
268         n = talloc_array(mem_ctx, const char *, num_services);
269         if (!n) {
270                 DEBUG(0,("ERROR: Out of memory!\n"));
271                 return NT_STATUS_NO_MEMORY;
272         }
273
274         for (i = 0; i < num_services; i++) {
275                 n[i] = talloc_strdup(n, lp_servicename(i));
276                 if (!n[i]) {
277                         DEBUG(0,("ERROR: Out of memory!\n"));
278                         talloc_free(n);
279                         return NT_STATUS_NO_MEMORY;
280                 }
281         }
282
283         *names = n;
284         *count = num_services;
285
286         return NT_STATUS_OK;
287 }
288
289 NTSTATUS sclassic_get_config(TALLOC_CTX *mem_ctx,
290                              struct share_context *ctx,
291                              const char *name,
292                              struct share_config **scfg)
293 {
294         int i, snum;
295         struct share_config *s;
296         struct sclassic_snum *scnum;
297
298         snum = -1;
299         for (i = 0; i < lp_numservices(); i++) {
300                 if (strcasecmp_m(name, lp_servicename(i)) == 0) {
301                         snum = i;
302                         break;
303                 }
304         }
305
306         if (snum < 0) {
307                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
308         }
309
310         s = talloc(mem_ctx, struct share_config);
311         if (!s) {
312                 DEBUG(0,("ERROR: Out of memory!\n"));
313                 return NT_STATUS_NO_MEMORY;
314         }
315
316         s->name = talloc_strdup(s, lp_servicename(snum));
317         if (!s->name) {
318                 DEBUG(0,("ERROR: Out of memory!\n"));
319                 talloc_free(s);
320                 return NT_STATUS_NO_MEMORY;
321         }
322
323         scnum = talloc(s, struct sclassic_snum);
324         if (!scnum) {
325                 DEBUG(0,("ERROR: Out of memory!\n"));
326                 talloc_free(s);
327                 return NT_STATUS_NO_MEMORY;
328         }
329         scnum->snum = snum;
330
331         s->opaque = (void *)scnum;
332         s->ctx = ctx;
333         
334         *scfg = s;
335
336         return NT_STATUS_OK;
337 }
338
339 NTSTATUS share_classic_init(void)
340 {
341         static struct share_ops ops = {
342                 .name = "classic",
343                 .init = sclassic_init,
344                 .string_option = sclassic_string_option,
345                 .int_option = sclassic_int_option,
346                 .bool_option = sclassic_bool_option,
347                 .string_list_option = sclassic_string_list_option,
348                 .list_all = sclassic_list_all,
349                 .get_config = sclassic_get_config
350         };
351
352         return share_register(&ops);
353 }
354