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