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 26static NTSTATUS sclassic_init(TALLOC_CTX *mem_ctx, 27 const struct share_ops *ops, 28 struct tevent_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 44static 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 108static 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 165static 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 239static 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 280static 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 312static 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 347static 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 358NTSTATUS share_classic_init(void) 359{ 360 return share_register(&ops); 361} 362 363