From 9c66f601f1520a99b9236c32bc9f03a33bd4b2aa Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Sun, 23 Jul 2006 18:43:07 +0000 Subject: r17206: Add a modular API for share configuration. Commit the classic backwards compatible module which is the default one (This used to be commit a89cc346b9296cb49929898d257a064a6c2bae86) --- source4/param/config.mk | 23 +++ source4/param/loadparm.c | 8 +- source4/param/share.c | 137 ++++++++++++++++++ source4/param/share.h | 105 ++++++++++++++ source4/param/share_classic.c | 328 ++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 600 insertions(+), 1 deletion(-) create mode 100644 source4/param/share.c create mode 100644 source4/param/share.h create mode 100644 source4/param/share_classic.c (limited to 'source4/param') diff --git a/source4/param/config.mk b/source4/param/config.mk index dd338a6421..4fecd399ce 100644 --- a/source4/param/config.mk +++ b/source4/param/config.mk @@ -10,3 +10,26 @@ OBJ_FILES = loadparm.o \ PUBLIC_DEPENDENCIES = LIBSAMBA-UTIL DYNCONFIG PUBLIC_PROTO_HEADER = proto.h PUBLIC_HEADERS = param.h + +################################# +# Start SUBSYSTEM share +[LIBRARY::share] +VERSION = 0.0.1 +SO_VERSION = 0 +DESCRIPTION = Services Configuration Library +PUBLIC_HEADERS = share.h +PUBLIC_PROTO_HEADER = share_proto.h +OBJ_FILES = share.o +# End SUBSYSTEM share +################################# + +################################################ +# Start MODULE share_classic +[MODULE::share_classic] +SUBSYSTEM = share +INIT_FUNCTION = share_classic_init +OBJ_FILES = share_classic.o +PUBLIC_DEPENDENCIES = LIBSAMBA-UTIL +# End MODULE share_classic +################################################ + diff --git a/source4/param/loadparm.c b/source4/param/loadparm.c index 00fffc6108..64713f74cf 100644 --- a/source4/param/loadparm.c +++ b/source4/param/loadparm.c @@ -107,6 +107,7 @@ typedef struct char *szAutoServices; char *szPasswdChat; char *szConfigFile; + char *szShareBackend; char *szSAM_URL; char *szSPOOLSS_URL; char *szWINS_CONFIG_URL; @@ -531,6 +532,7 @@ static struct parm_struct parm_table[] = { {"Miscellaneous Options", P_SEP, P_SEPARATOR}, {"config file", P_STRING, P_GLOBAL, &Globals.szConfigFile, NULL, NULL, FLAG_HIDE}, + {"share backend", P_STRING, P_GLOBAL, &Globals.szShareBackend, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, {"preload", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, {"auto services", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, {"lock dir", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, FLAG_HIDE}, @@ -591,6 +593,8 @@ static void init_globals(void) do_parameter("config file", dyn_CONFIGFILE, NULL); + do_parameter("share backend", "classic", NULL); + do_parameter("server role", "standalone", NULL); /* options that can be set on the command line must be initialised via @@ -829,6 +833,7 @@ _PUBLIC_ FN_GLOBAL_STRING(lp_tls_crlfile, &Globals.tls_crlfile) _PUBLIC_ FN_GLOBAL_STRING(lp_unix_charset, &Globals.unix_charset) _PUBLIC_ FN_GLOBAL_STRING(lp_display_charset, &Globals.display_charset) _PUBLIC_ FN_GLOBAL_STRING(lp_configfile, &Globals.szConfigFile) +_PUBLIC_ FN_GLOBAL_STRING(lp_share_backend, &Globals.szShareBackend) _PUBLIC_ FN_GLOBAL_STRING(lp_sam_url, &Globals.szSAM_URL) _PUBLIC_ FN_GLOBAL_STRING(lp_spoolss_url, &Globals.szSPOOLSS_URL) _PUBLIC_ FN_GLOBAL_STRING(lp_wins_config_url, &Globals.szWINS_CONFIG_URL) @@ -1711,6 +1716,7 @@ static void init_copymap(service * pservice) pservice->copymap[i] = True; } +#if 0 /* not used anywhere */ /*************************************************************************** Return the local pointer to a parameter given the service number and the pointer into the default structure. @@ -1720,7 +1726,7 @@ void *lp_local_ptr(int snum, void *ptr) { return (void *)(((char *)ServicePtrs[snum]) + PTR_DIFF(ptr, &sDefault)); } - +#endif /*************************************************************************** Process a parametric option diff --git a/source4/param/share.c b/source4/param/share.c new file mode 100644 index 0000000000..a87fe38f8e --- /dev/null +++ b/source4/param/share.c @@ -0,0 +1,137 @@ +/* + Unix SMB/CIFS implementation. + + Modular services configuration system + + Copyright (C) Simo Sorce 2006 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" +#include "param/share.h" +#include "build.h" + +const char *share_string_option(struct share_config *scfg, const char *opt_name, const char *defval) +{ + return scfg->ctx->ops->string_option(scfg, opt_name, defval); +} + +int share_int_option(struct share_config *scfg, const char *opt_name, int defval) +{ + return scfg->ctx->ops->int_option(scfg, opt_name, defval); +} + +BOOL share_bool_option(struct share_config *scfg, const char *opt_name, BOOL defval) +{ + return scfg->ctx->ops->bool_option(scfg, opt_name, defval); +} + +const char **share_string_list_option(TALLOC_CTX *mem_ctx, struct share_config *scfg, const char *opt_name) +{ + return scfg->ctx->ops->string_list_option(mem_ctx, scfg, opt_name); +} + +NTSTATUS share_list_all(TALLOC_CTX *mem_ctx, struct share_context *sctx, int *count, const char ***names) +{ + return sctx->ops->list_all(mem_ctx, sctx, count, names); +} + +NTSTATUS share_get_config(TALLOC_CTX *mem_ctx, struct share_context *sctx, const char *name, struct share_config **scfg) +{ + return sctx->ops->get_config(mem_ctx, sctx, name, scfg); +} + +/* List of currently available share backends */ +static struct share_ops **backends = NULL; + +static const struct share_ops *share_backend_by_name(const char *name) +{ + int i; + + for (i = 0; backends && backends[i]; i++) { + if (strcmp(backends[i]->name, name) == 0) { + return backends[i]; + } + } + + return NULL; +} + +/* + Register the share backend +*/ +NTSTATUS share_register(const struct share_ops *ops) +{ + int i; + + if (share_backend_by_name(ops->name) != NULL) { + DEBUG(0,("SHARE backend [%s] already registered\n", ops->name)); + return NT_STATUS_OBJECT_NAME_COLLISION; + } + + i = 0; + while (backends && backends[i]) { + i++; + } + + backends = realloc_p(backends, struct share_ops *, i + 2); + if (!backends) { + smb_panic("out of memory in share_register"); + } + + backends[i] = malloc(sizeof(struct share_ops)); + if (!backends[i]) { + smb_panic("out of memory in share_register"); + } + + backends[i] = smb_xmemdup(ops, sizeof(*ops)); + backends[i]->name = smb_xstrdup(ops->name); + + backends[i + 1] = NULL; + + DEBUG(3, ("SHARE backend [%s] registered.\n", ops->name)); + + return NT_STATUS_OK; +} + +NTSTATUS share_get_context(TALLOC_CTX *mem_ctx, struct share_context **ctx) +{ + const struct share_ops *ops; + + ops = share_backend_by_name(lp_share_backend()); + if (!ops) { + DEBUG(0, ("share_init_connection: share backend [%s] not found!\n", lp_share_backend())); + return NT_STATUS_INTERNAL_ERROR; + } + + return ops->init(mem_ctx, ops, ctx); +} + +/* + initialise the SHARE subsystem +*/ +NTSTATUS share_init(void) +{ + init_module_fn static_init[] = STATIC_share_MODULES; + init_module_fn *shared_init = load_samba_modules(NULL, "share"); + + run_init_functions(static_init); + run_init_functions(shared_init); + + talloc_free(shared_init); + + return NT_STATUS_OK; +} diff --git a/source4/param/share.h b/source4/param/share.h new file mode 100644 index 0000000000..af5bd0ebba --- /dev/null +++ b/source4/param/share.h @@ -0,0 +1,105 @@ +/* + Unix SMB/CIFS implementation. + + Modular services configuration + + Copyright (C) Simo Sorce 2006 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef _SHARE_H +#define _SHARE_H + +struct share_ops; + +struct share_context { + const struct share_ops *ops; + void *priv_data; +}; + +struct share_config { + const char *name; + struct share_context *ctx; + void *opaque; +}; + +struct share_ops { + const char *name; + NTSTATUS (*init)(TALLOC_CTX *, const struct share_ops*, struct share_context **); + const char *(*string_option)(struct share_config *, const char *, const char *); + int (*int_option)(struct share_config *, const char *, int); + BOOL (*bool_option)(struct share_config *, const char *, BOOL); + const char **(*string_list_option)(TALLOC_CTX *, struct share_config *, const char *); + NTSTATUS (*list_all)(TALLOC_CTX *, struct share_context *, int *, const char ***); + NTSTATUS (*get_config)(TALLOC_CTX *, struct share_context *, const char *, struct share_config **); + NTSTATUS (*create_obj)(struct share_context *, const char *); + NTSTATUS (*delete_obj)(struct share_context *, const char *); +}; + +#include "param/share_proto.h" + +/* list of shares options */ + +#define SHARE_NAME "name" +#define SHARE_PATH "path" +#define SHARE_COMMENT "comment" +#define SHARE_PASSWORD "password" +#define SHARE_HOSTS_ALLOW "hosts-allow" +#define SHARE_HOSTS_DENY "hosts-deny" +#define SHARE_NTVFS_HANDLER "ntvfs-handler" +#define SHARE_TYPE "type" +#define SHARE_VOLUME "volume" +#define SHARE_CSC_POLICY "csc-policy" +#define SHARE_AVAILABLE "available" +#define SHARE_BROWSEABLE "browseable" +#define SHARE_MAX_CONNECTIONS "max-connections" + +/* I'd like to see the following options go away + * and always use EAs and SECDESCs */ +#define SHARE_READONLY "readonly" +#define SHARE_MAP_SYSTEM "map-system" +#define SHARE_MAP_HIDDEN "map-hidden" +#define SHARE_MAP_ARCHIVE "map-archive" + +#define SHARE_STRICT_LOCKING "strict-locking" +#define SHARE_STRICT_SYNC "strict-sync" +#define SHARE_MSDFS_ROOT "msdfs-root" +#define SHARE_CI_FILESYSTEM "ci-filesystem" + +/* defaults */ + +#define SHARE_HOST_ALLOW_DEFAULT NULL +#define SHARE_HOST_DENY_DEFAULT NULL +#define SHARE_VOLUME_DEFAULT NULL +#define SHARE_TYPE_DEFAULT "DISK" +#define SHARE_CSC_POLICY_DEFAULT 0 +#define SHARE_AVAILABLE_DEFAULT True +#define SHARE_BROWSEABLE_DEFAULT True +#define SHARE_MAX_CONNECTIONS_DEFAULT 0 + +/* I'd like to see the following options go away + * and always use EAs and SECDESCs */ +#define SHARE_READONLY_DEFAULT True +#define SHARE_MAP_SYSTEM_DEFAULT False +#define SHARE_MAP_HIDDEN_DEFAULT False +#define SHARE_MAP_ARCHIVE_DEFAULT True + +#define SHARE_STRICT_LOCKING_DEFAULT True +#define SHARE_STRICT_SYNC_DEFAULT False +#define SHARE_MSDFS_ROOT_DEFAULT False +#define SHARE_CI_FILESYSTEM_DEFAULT False + +#endif /* _SHARE_H */ diff --git a/source4/param/share_classic.c b/source4/param/share_classic.c new file mode 100644 index 0000000000..9d959da787 --- /dev/null +++ b/source4/param/share_classic.c @@ -0,0 +1,328 @@ +/* + Unix SMB/CIFS implementation. + + Classic file based services configuration + + Copyright (C) Simo Sorce 2006 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" +#include "param/share.h" + +struct sclassic_snum { + int snum; +}; + +static NTSTATUS sclassic_init(TALLOC_CTX *mem_ctx, const struct share_ops *ops, struct share_context **ctx) +{ + *ctx = talloc(mem_ctx, struct share_context); + if (!*ctx) { + DEBUG(0, ("ERROR: Out of memory!\n")); + return NT_STATUS_NO_MEMORY; + } + + (*ctx)->ops = ops; + (*ctx)->priv_data = NULL; + + return NT_STATUS_OK; +} + +static const char *sclassic_string_option(struct share_config *scfg, const char *opt_name, const char *defval) +{ + struct sclassic_snum *s = talloc_get_type(scfg->opaque, struct sclassic_snum); + char *parm, *val; + const char *ret; + + if (strchr(opt_name, ':')) { + parm = talloc_strdup(scfg, opt_name); + if (!parm) { + return NULL; + } + val = strchr(parm, ':'); + *val = '\0'; + val++; + + ret = lp_parm_string(s->snum, parm, val); + if (!ret) { + ret = defval; + } + talloc_free(parm); + return ret; + } + + if (strcmp(opt_name, SHARE_NAME) == 0) { + return scfg->name; + } + + if (strcmp(opt_name, SHARE_PATH) == 0) { + return lp_pathname(s->snum); + } + + if (strcmp(opt_name, SHARE_COMMENT) == 0) { + return lp_comment(s->snum); + } + + if (strcmp(opt_name, SHARE_VOLUME) == 0) { + return volume_label(s->snum); + } + + if (strcmp(opt_name, SHARE_TYPE) == 0) { + if (lp_print_ok(s->snum)) { + return "PRINTER"; + } + return lp_fstype(s->snum); + } + + return defval; +} + +int sclassic_int_option(struct share_config *scfg, const char *opt_name, int defval) +{ + struct sclassic_snum *s = talloc_get_type(scfg->opaque, struct sclassic_snum); + char *parm, *val; + int ret; + + if (strchr(opt_name, ':')) { + parm = talloc_strdup(scfg, opt_name); + if (!parm) { + return -1; + } + val = strchr(parm, ':'); + *val = '\0'; + val++; + + ret = lp_parm_int(s->snum, parm, val, defval); + if (!ret) { + ret = defval; + } + talloc_free(parm); + return ret; + } + + if (strcmp(opt_name, SHARE_CSC_POLICY) == 0) { + ret = lp_csc_policy(s->snum); + if (ret == -1) { + return defval; + } + } + + if (strcmp(opt_name, SHARE_MAX_CONNECTIONS) == 0) { + ret = lp_max_connections(s->snum); + if (ret == -1) { + return defval; + } + } + + return defval; +} + +BOOL sclassic_bool_option(struct share_config *scfg, const char *opt_name, BOOL defval) +{ + struct sclassic_snum *s = talloc_get_type(scfg->opaque, struct sclassic_snum); + char *parm, *val; + BOOL ret; + + if (strchr(opt_name, ':')) { + parm = talloc_strdup(scfg, opt_name); + if(!parm) { + return NULL; + } + val = strchr(parm, ':'); + *val = '\0'; + val++; + + ret = lp_parm_bool(s->snum, parm, val, defval); + talloc_free(parm); + return ret; + } + + if (strcmp(opt_name, SHARE_AVAILABLE) == 0) { + return lp_snum_ok(s->snum); + } + + if (strcmp(opt_name, SHARE_BROWSEABLE) == 0) { + return lp_browseable(s->snum); + } + + if (strcmp(opt_name, SHARE_READONLY) == 0) { + return lp_readonly(s->snum); + } + + if (strcmp(opt_name, SHARE_MAP_SYSTEM) == 0) { + return lp_map_system(s->snum); + } + + if (strcmp(opt_name, SHARE_MAP_HIDDEN) == 0) { + return lp_map_hidden(s->snum); + } + + if (strcmp(opt_name, SHARE_MAP_ARCHIVE) == 0) { + return lp_map_archive(s->snum); + } + + if (strcmp(opt_name, SHARE_STRICT_LOCKING) == 0) { + return lp_strict_locking(s->snum); + } + + if (strcmp(opt_name, SHARE_STRICT_SYNC) == 0) { + return lp_strict_sync(s->snum); + } + + if (strcmp(opt_name, SHARE_MSDFS_ROOT) == 0) { + return lp_msdfs_root(s->snum); + } + + if (strcmp(opt_name, SHARE_CI_FILESYSTEM) == 0) { + return lp_ci_filesystem(s->snum); + } + + return defval; +} + +const char **sclassic_string_list_option(TALLOC_CTX *mem_ctx, struct share_config *scfg, const char *opt_name) +{ + struct sclassic_snum *s = talloc_get_type(scfg->opaque, struct sclassic_snum); + char *parm, *val; + const char **ret; + + if (strchr(opt_name, ':')) { + parm = talloc_strdup(scfg, opt_name); + if (!parm) { + return NULL; + } + val = strchr(parm, ':'); + *val = '\0'; + val++; + + ret = lp_parm_string_list(s->snum, parm, val, ",;"); + talloc_free(parm); + return ret; + } + + if (strcmp(opt_name, SHARE_HOSTS_ALLOW) == 0) { + return lp_hostsallow(s->snum); + } + + if (strcmp(opt_name, SHARE_HOSTS_DENY) == 0) { + return lp_hostsdeny(s->snum); + } + + if (strcmp(opt_name, SHARE_NTVFS_HANDLER) == 0) { + return lp_ntvfs_handler(s->snum); + } + + return NULL; +} + +NTSTATUS sclassic_list_all(TALLOC_CTX *mem_ctx, + struct share_context *ctx, + int *count, + const char ***names) +{ + int i; + int num_services; + const char **n; + + num_services = lp_numservices(); + + n = talloc_array(mem_ctx, const char *, num_services); + if (!n) { + DEBUG(0,("ERROR: Out of memory!\n")); + return NT_STATUS_NO_MEMORY; + } + + for (i = 0; i < num_services; i++) { + n[i] = talloc_strdup(n, lp_servicename(i)); + if (!n[i]) { + DEBUG(0,("ERROR: Out of memory!\n")); + talloc_free(n); + return NT_STATUS_NO_MEMORY; + } + } + + *names = n; + *count = num_services; + + return NT_STATUS_OK; +} + +NTSTATUS sclassic_get_config(TALLOC_CTX *mem_ctx, + struct share_context *ctx, + const char *name, + struct share_config **scfg) +{ + int i, snum; + struct share_config *s; + struct sclassic_snum *scnum; + + snum = -1; + for (i = 0; i < lp_numservices(); i++) { + if (strcasecmp_m(name, lp_servicename(i)) == 0) { + snum = i; + break; + } + } + + if (snum < 0) { + return NT_STATUS_OBJECT_NAME_NOT_FOUND; + } + + s = talloc(mem_ctx, struct share_config); + if (!s) { + DEBUG(0,("ERROR: Out of memory!\n")); + return NT_STATUS_NO_MEMORY; + } + + s->name = talloc_strdup(s, lp_servicename(snum)); + if (!s->name) { + DEBUG(0,("ERROR: Out of memory!\n")); + talloc_free(s); + return NT_STATUS_NO_MEMORY; + } + + scnum = talloc(s, struct sclassic_snum); + if (!scnum) { + DEBUG(0,("ERROR: Out of memory!\n")); + talloc_free(s); + return NT_STATUS_NO_MEMORY; + } + scnum->snum = snum; + + s->opaque = (void *)scnum; + s->ctx = ctx; + + *scfg = s; + + return NT_STATUS_OK; +} + +NTSTATUS share_classic_init(void) +{ + struct share_ops ops; + + ops.name = "classic"; + ops.init = sclassic_init; + ops.string_option = sclassic_string_option; + ops.int_option = sclassic_int_option; + ops.bool_option = sclassic_bool_option; + ops.string_list_option = sclassic_string_list_option; + ops.list_all = sclassic_list_all; + ops.get_config = sclassic_get_config; + + return share_register(&ops); +} + -- cgit