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