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/ntvfs/cifs/vfs_cifs.c | 33 ++- source4/ntvfs/cifs_posix_cli/vfs_simple.c | 9 +- source4/ntvfs/common/config.mk | 2 +- source4/ntvfs/common/notify.c | 10 +- source4/ntvfs/ipc/rap_server.c | 41 +++- source4/ntvfs/ntvfs.h | 5 +- source4/ntvfs/ntvfs_base.c | 7 +- source4/ntvfs/posix/vfs_posix.c | 51 +++-- source4/ntvfs/posix/vfs_posix.h | 13 ++ source4/ntvfs/print/vfs_print.c | 3 +- source4/ntvfs/simple/vfs_simple.c | 10 +- source4/ntvfs/sysdep/sys_notify.c | 6 +- source4/ntvfs/sysdep/sys_notify.h | 3 +- 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 ++++++++++++++++++++++++++++++ source4/rpc_server/common/common.h | 1 + source4/rpc_server/common/share_info.c | 64 ++---- source4/rpc_server/config.mk | 2 +- source4/rpc_server/srvsvc/dcesrv_srvsvc.c | 238 ++++++++++++++++------ source4/rpc_server/srvsvc/srvsvc_ntvfs.c | 34 ++-- source4/scripting/libjs/provision.js | 7 + source4/smb_server/config.mk | 1 + source4/smb_server/smb/service.c | 57 +++--- source4/smb_server/smb2/tcon.c | 27 +-- source4/smb_server/smb_server.c | 6 + source4/smb_server/smb_server.h | 2 + source4/smbd/server.c | 2 + 30 files changed, 1005 insertions(+), 230 deletions(-) create mode 100644 source4/param/share.c create mode 100644 source4/param/share.h create mode 100644 source4/param/share_classic.c diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c index 1e34e953a5..edb5f7b791 100644 --- a/source4/ntvfs/cifs/vfs_cifs.c +++ b/source4/ntvfs/cifs/vfs_cifs.c @@ -74,6 +74,19 @@ struct async_info { SETUP_FILE; \ } while (0) +#define CIFS_SERVER "cifs:server" +#define CIFS_USER "cifs:user" +#define CIFS_PASSWORD "cifs:password" +#define CIFS_DOMAIN "cifs:domain" +#define CIFS_SHARE "cifs:share" +#define CIFS_USE_MACHINE_ACCT "cifs:use-machine-account" +#define CIFS_MAP_GENERIC "cifs:map-generic" +#define CIFS_MAP_TRANS2 "cifs:map-trans2" + +#define CIFS_USE_MACHINE_ACCT_DEFAULT False +#define CIFS_MAP_GENERIC_DEFAULT False +#define CIFS_MAP_TRANS2_DEFAULT True + /* a handler for oplock break events from the server - these need to be passed along to the client @@ -113,7 +126,7 @@ static NTSTATUS cvfs_connect(struct ntvfs_module_context *ntvfs, const char *host, *user, *pass, *domain, *remote_share; struct smb_composite_connect io; struct composite_context *creq; - int snum = ntvfs->ctx->config.snum; + struct share_config *scfg = ntvfs->ctx->config; struct cli_credentials *credentials; BOOL machine_account; @@ -122,16 +135,16 @@ static NTSTATUS cvfs_connect(struct ntvfs_module_context *ntvfs, * For now we use parametric options, type cifs. * Later we will use security=server and auth_server.c. */ - host = lp_parm_string(snum, "cifs", "server"); - user = lp_parm_string(snum, "cifs", "user"); - pass = lp_parm_string(snum, "cifs", "password"); - domain = lp_parm_string(snum, "cifs", "domain"); - remote_share = lp_parm_string(snum, "cifs", "share"); + host = share_string_option(scfg, CIFS_SERVER, NULL); + user = share_string_option(scfg, CIFS_USER, NULL); + pass = share_string_option(scfg, CIFS_PASSWORD, NULL); + domain = share_string_option(scfg, CIFS_DOMAIN, NULL); + remote_share = share_string_option(scfg, CIFS_SHARE, NULL); if (!remote_share) { remote_share = sharename; } - machine_account = lp_parm_bool(snum, "cifs", "use_machine_account", False); + machine_account = share_bool_option(scfg, CIFS_USE_MACHINE_ACCT, CIFS_USE_MACHINE_ACCT_DEFAULT); private = talloc_zero(ntvfs, struct cvfs_private); if (!private) { @@ -204,11 +217,9 @@ static NTSTATUS cvfs_connect(struct ntvfs_module_context *ntvfs, /* we need to receive oplock break requests from the server */ smbcli_oplock_handler(private->transport, oplock_handler, private); - private->map_generic = lp_parm_bool(ntvfs->ctx->config.snum, - "cifs", "mapgeneric", False); + private->map_generic = share_bool_option(scfg, CIFS_MAP_GENERIC, CIFS_MAP_GENERIC_DEFAULT); - private->map_trans2 = lp_parm_bool(ntvfs->ctx->config.snum, - "cifs", "maptrans2", True); + private->map_trans2 = share_bool_option(scfg, CIFS_MAP_TRANS2, CIFS_MAP_TRANS2_DEFAULT); return NT_STATUS_OK; } diff --git a/source4/ntvfs/cifs_posix_cli/vfs_simple.c b/source4/ntvfs/cifs_posix_cli/vfs_simple.c index cf28a02806..eb62336d13 100644 --- a/source4/ntvfs/cifs_posix_cli/vfs_simple.c +++ b/source4/ntvfs/cifs_posix_cli/vfs_simple.c @@ -43,7 +43,7 @@ #define O_DIRECTORY 0 #endif -#define CHECK_READ_ONLY(req) do { if (lp_readonly(ntvfs->ctx->config.snum)) return NT_STATUS_ACCESS_DENIED; } while (0) +#define CHECK_READ_ONLY(req) do { if (share_bool_option(ntvfs->ctx->config, SHARE_READONLY, True)) return NT_STATUS_ACCESS_DENIED; } while (0) /* connect to a share - used when a tree_connect operation comes @@ -56,12 +56,11 @@ static NTSTATUS svfs_connect(struct ntvfs_module_context *ntvfs, { struct stat st; struct svfs_private *private; - int snum = ntvfs->ctx->config.snum; private = talloc(ntvfs, struct svfs_private); private->next_search_handle = 0; - private->connectpath = talloc_strdup(private, lp_pathname(snum)); + private->connectpath = talloc_strdup(private, share_string_option(ntvfs->ctx->config, SHARE_PATH, "")); private->open_files = NULL; private->search = NULL; @@ -317,7 +316,7 @@ static NTSTATUS svfs_open(struct ntvfs_module_context *ntvfs, return ntvfs_map_open(ntvfs, req, io); } - readonly = lp_readonly(ntvfs->ctx->config.snum); + readonly = share_bool_option(ntvfs->ctx->config, SHARE_READONLY, True); if (readonly) { create_flags = 0; rdwr_flags = O_RDONLY; @@ -728,7 +727,7 @@ static NTSTATUS svfs_fsinfo(struct ntvfs_module_context *ntvfs, fs->generic.out.quota_soft = 0; fs->generic.out.quota_hard = 0; fs->generic.out.quota_flags = 0; - fs->generic.out.volume_name = talloc_strdup(req, lp_servicename(ntvfs->ctx->config.snum)); + fs->generic.out.volume_name = talloc_strdup(req, ntvfs->ctx->config->name); fs->generic.out.fs_type = ntvfs->ctx->fs_type; return NT_STATUS_OK; diff --git a/source4/ntvfs/common/config.mk b/source4/ntvfs/common/config.mk index feb3613f78..c16cc09dfe 100644 --- a/source4/ntvfs/common/config.mk +++ b/source4/ntvfs/common/config.mk @@ -7,6 +7,6 @@ OBJ_FILES = \ brlock.o \ opendb.o \ notify.o -PUBLIC_DEPENDENCIES = NDR_OPENDB NDR_NOTIFY sys_notify +PUBLIC_DEPENDENCIES = NDR_OPENDB NDR_NOTIFY sys_notify share # End LIBRARY ntvfs_common ################################################ diff --git a/source4/ntvfs/common/notify.c b/source4/ntvfs/common/notify.c index 222bd7a927..dbf404d9e6 100644 --- a/source4/ntvfs/common/notify.c +++ b/source4/ntvfs/common/notify.c @@ -56,6 +56,9 @@ struct notify_list { #define NOTIFY_KEY "notify array" +#define NOTIFY_ENABLE "notify:enable" +#define NOTIFY_ENABLE_DEFAULT True + static NTSTATUS notify_remove_all(struct notify_context *notify); static void notify_handler(struct messaging_context *msg_ctx, void *private, uint32_t msg_type, uint32_t server_id, DATA_BLOB *data); @@ -77,12 +80,13 @@ static int notify_destructor(struct notify_context *notify) */ struct notify_context *notify_init(TALLOC_CTX *mem_ctx, uint32_t server, struct messaging_context *messaging_ctx, - struct event_context *ev, int snum) + struct event_context *ev, + struct share_config *scfg) { char *path; struct notify_context *notify; - if (lp_parm_bool(snum, "notify", "enable", True) != True) { + if (share_bool_option(scfg, NOTIFY_ENABLE, NOTIFY_ENABLE_DEFAULT) != True) { return NULL; } @@ -114,7 +118,7 @@ struct notify_context *notify_init(TALLOC_CTX *mem_ctx, uint32_t server, messaging_register(notify->messaging_ctx, notify, MSG_PVFS_NOTIFY, notify_handler); - notify->sys_notify_ctx = sys_notify_context_create(snum, notify, ev); + notify->sys_notify_ctx = sys_notify_context_create(scfg, notify, ev); return notify; } diff --git a/source4/ntvfs/ipc/rap_server.c b/source4/ntvfs/ipc/rap_server.c index 8ec62dff8b..f92b02c20a 100644 --- a/source4/ntvfs/ipc/rap_server.c +++ b/source4/ntvfs/ipc/rap_server.c @@ -20,6 +20,7 @@ */ #include "includes.h" +#include "param/share.h" #include "libcli/rap/rap.h" #include "librpc/gen_ndr/srvsvc.h" #include "rpc_server/common/common.h" @@ -30,21 +31,45 @@ NTSTATUS rap_netshareenum(TALLOC_CTX *mem_ctx, struct rap_NetShareEnum *r) { - int i; + NTSTATUS nterr; + const char **snames; + struct share_context *sctx; + struct share_config *scfg; + int i, j, count; + r->out.status = 0; - r->out.available = dcesrv_common_get_count_of_shares(mem_ctx, NULL); + r->out.available = 0; + r->out.info = NULL; + + nterr = share_get_context(mem_ctx, &sctx); + if (!NT_STATUS_IS_OK(nterr)) { + return nterr; + } + + nterr = share_list_all(mem_ctx, sctx, &count, &snames); + if (!NT_STATUS_IS_OK(nterr)) { + return nterr; + } + + r->out.available = count; r->out.info = talloc_array(mem_ctx, union rap_shareenum_info, r->out.available); - for (i=0;iout.available;i++) { - strncpy(r->out.info[i].info1.name, - dcesrv_common_get_share_name(mem_ctx, NULL, i), + for (i = 0, j = 0; i < r->out.available; i++) { + if (!NT_STATUS_IS_OK(share_get_config(mem_ctx, sctx, snames[i], &scfg))) { + DEBUG(3, ("WARNING: Service [%s] disappeared after enumeration!\n", snames[i])); + continue; + } + strncpy(r->out.info[j].info1.name, + snames[i], sizeof(r->out.info[0].info1.name)); r->out.info[i].info1.pad = 0; - r->out.info[i].info1.type = dcesrv_common_get_share_type(mem_ctx, NULL, i); - r->out.info[i].info1.comment = talloc_strdup(mem_ctx, - dcesrv_common_get_share_comment(mem_ctx, NULL, i)); + r->out.info[i].info1.type = dcesrv_common_get_share_type(mem_ctx, NULL, scfg); + r->out.info[i].info1.comment = talloc_strdup(mem_ctx, share_string_option(scfg, SHARE_COMMENT, "")); + talloc_free(scfg); + j++; } + r->out.available = j; return NT_STATUS_OK; } diff --git a/source4/ntvfs/ntvfs.h b/source4/ntvfs/ntvfs.h index 6916ea10fc..b48a5dac00 100644 --- a/source4/ntvfs/ntvfs.h +++ b/source4/ntvfs/ntvfs.h @@ -20,6 +20,7 @@ */ #include "libcli/raw/interfaces.h" +#include "param/share.h" /* modules can use the following to determine if the interface has changed */ /* version 1 -> 0 - make module stacking easier -- metze */ @@ -181,9 +182,7 @@ struct ntvfs_context { */ struct ntvfs_module_context *modules; - struct { - int snum; - } config; + struct share_config *config; uint32_t server_id; struct event_context *event_ctx; diff --git a/source4/ntvfs/ntvfs_base.c b/source4/ntvfs/ntvfs_base.c index 316a9e9c68..e6c4089e47 100644 --- a/source4/ntvfs/ntvfs_base.c +++ b/source4/ntvfs/ntvfs_base.c @@ -148,16 +148,15 @@ _PUBLIC_ BOOL ntvfs_interface_differs(const struct ntvfs_critical_sizes *const i #undef FIELD_DIFFERS } - /* initialise a connection structure to point at a NTVFS backend */ -NTSTATUS ntvfs_init_connection(TALLOC_CTX *mem_ctx, int snum, enum ntvfs_type type, +NTSTATUS ntvfs_init_connection(TALLOC_CTX *mem_ctx, struct share_config *scfg, enum ntvfs_type type, enum protocol_types protocol, struct event_context *ev, struct messaging_context *msg, uint32_t server_id, struct ntvfs_context **_ctx) { - const char **handlers = lp_ntvfs_handler(snum); + const char **handlers = share_string_list_option(mem_ctx, scfg, SHARE_NTVFS_HANDLER); int i; struct ntvfs_context *ctx; @@ -169,7 +168,7 @@ NTSTATUS ntvfs_init_connection(TALLOC_CTX *mem_ctx, int snum, enum ntvfs_type ty NT_STATUS_HAVE_NO_MEMORY(ctx); ctx->protocol = protocol; ctx->type = type; - ctx->config.snum = snum; + ctx->config = talloc_steal(ctx, scfg); ctx->event_ctx = ev; ctx->msg_ctx = msg; ctx->server_id = server_id; diff --git a/source4/ntvfs/posix/vfs_posix.c b/source4/ntvfs/posix/vfs_posix.c index e7ef9bafd8..975649eeb5 100644 --- a/source4/ntvfs/posix/vfs_posix.c +++ b/source4/ntvfs/posix/vfs_posix.c @@ -38,35 +38,46 @@ */ static void pvfs_setup_options(struct pvfs_state *pvfs) { - int snum = pvfs->ntvfs->ctx->config.snum; + struct share_config *scfg = pvfs->ntvfs->ctx->config; const char *eadb; - if (lp_map_hidden(snum)) pvfs->flags |= PVFS_FLAG_MAP_HIDDEN; - if (lp_map_archive(snum)) pvfs->flags |= PVFS_FLAG_MAP_ARCHIVE; - if (lp_map_system(snum)) pvfs->flags |= PVFS_FLAG_MAP_SYSTEM; - if (lp_readonly(snum)) pvfs->flags |= PVFS_FLAG_READONLY; - if (lp_strict_sync(snum)) pvfs->flags |= PVFS_FLAG_STRICT_SYNC; - if (lp_strict_locking(snum)) pvfs->flags |= PVFS_FLAG_STRICT_LOCKING; - if (lp_ci_filesystem(snum)) pvfs->flags |= PVFS_FLAG_CI_FILESYSTEM; - - if (lp_parm_bool(snum, "posix", "fakeoplocks", False)) { + if (share_bool_option(scfg, SHARE_MAP_HIDDEN, SHARE_MAP_HIDDEN_DEFAULT)) + pvfs->flags |= PVFS_FLAG_MAP_HIDDEN; + if (share_bool_option(scfg, SHARE_MAP_ARCHIVE, SHARE_MAP_ARCHIVE_DEFAULT)) + pvfs->flags |= PVFS_FLAG_MAP_ARCHIVE; + if (share_bool_option(scfg, SHARE_MAP_SYSTEM, SHARE_MAP_SYSTEM_DEFAULT)) + pvfs->flags |= PVFS_FLAG_MAP_SYSTEM; + if (share_bool_option(scfg, SHARE_READONLY, SHARE_READONLY_DEFAULT)) + pvfs->flags |= PVFS_FLAG_READONLY; + if (share_bool_option(scfg, SHARE_STRICT_SYNC, SHARE_STRICT_SYNC_DEFAULT)) + pvfs->flags |= PVFS_FLAG_STRICT_SYNC; + if (share_bool_option(scfg, SHARE_STRICT_LOCKING, SHARE_STRICT_LOCKING_DEFAULT)) + pvfs->flags |= PVFS_FLAG_STRICT_LOCKING; + if (share_bool_option(scfg, SHARE_CI_FILESYSTEM, SHARE_CI_FILESYSTEM_DEFAULT)) + pvfs->flags |= PVFS_FLAG_CI_FILESYSTEM; + if (share_bool_option(scfg, PVFS_FAKE_OPLOCKS, PVFS_FAKE_OPLOCKS_DEFAULT)) { pvfs->flags |= PVFS_FLAG_FAKE_OPLOCKS; } /* this must be a power of 2 */ - pvfs->alloc_size_rounding = lp_parm_int(snum, - "posix", "allocationrounding", 512); + pvfs->alloc_size_rounding = share_int_option(scfg, + PVFS_ALLOCATION_ROUNDING, + PVFS_ALLOCATION_ROUNDING_DEFAULT); - pvfs->search.inactivity_time = lp_parm_int(snum, - "posix", "searchinactivity", 300); + pvfs->search.inactivity_time = share_int_option(scfg, + PVFS_SEARCH_INACTIVITY, + PVFS_SEARCH_INACTIVITY_DEFAULT); #if HAVE_XATTR_SUPPORT - if (lp_parm_bool(snum, "posix", "xattr", True)) pvfs->flags |= PVFS_FLAG_XATTR_ENABLE; + if (share_bool_option(scfg, PVFS_XATTR, PVFS_XATTR_DEFAULT)) + pvfs->flags |= PVFS_FLAG_XATTR_ENABLE; #endif - pvfs->sharing_violation_delay = lp_parm_int(snum, "posix", "sharedelay", 1000000); + pvfs->sharing_violation_delay = share_int_option(scfg, + PVFS_SHARE_DELAY, + PVFS_SHARE_DELAY_DEFAULT); - pvfs->share_name = talloc_strdup(pvfs, lp_servicename(snum)); + pvfs->share_name = talloc_strdup(pvfs, scfg->name); pvfs->fs_attribs = FS_ATTR_CASE_SENSITIVE_SEARCH | @@ -75,7 +86,7 @@ static void pvfs_setup_options(struct pvfs_state *pvfs) FS_ATTR_SPARSE_FILES; /* allow xattrs to be stored in a external tdb */ - eadb = lp_parm_string(snum, "posix", "eadb"); + eadb = share_string_option(scfg, PVFS_EADB, NULL); if (eadb != NULL) { pvfs->ea_db = tdb_wrap_open(pvfs, eadb, 50000, TDB_DEFAULT, O_RDWR|O_CREAT, 0600); @@ -144,7 +155,7 @@ static NTSTATUS pvfs_connect(struct ntvfs_module_context *ntvfs, NT_STATUS_HAVE_NO_MEMORY(pvfs); /* for simplicity of path construction, remove any trailing slash now */ - base_directory = talloc_strdup(pvfs, lp_pathname(ntvfs->ctx->config.snum)); + base_directory = talloc_strdup(pvfs, share_string_option(ntvfs->ctx->config, SHARE_PATH, "")); NT_STATUS_HAVE_NO_MEMORY(base_directory); if (strcmp(base_directory, "/") != 0) { trim_string(base_directory, NULL, "/"); @@ -186,7 +197,7 @@ static NTSTATUS pvfs_connect(struct ntvfs_module_context *ntvfs, pvfs->ntvfs->ctx->server_id, pvfs->ntvfs->ctx->msg_ctx, event_context_find(pvfs), - pvfs->ntvfs->ctx->config.snum); + pvfs->ntvfs->ctx->config); pvfs->sidmap = sidmap_open(pvfs); if (pvfs->sidmap == NULL) { diff --git a/source4/ntvfs/posix/vfs_posix.h b/source4/ntvfs/posix/vfs_posix.h index eb738920f4..8d3e86fff1 100644 --- a/source4/ntvfs/posix/vfs_posix.h +++ b/source4/ntvfs/posix/vfs_posix.h @@ -222,6 +222,19 @@ struct pvfs_dir; /* types of notification for pvfs wait events */ enum pvfs_wait_notice {PVFS_WAIT_EVENT, PVFS_WAIT_TIMEOUT, PVFS_WAIT_CANCEL}; +#define PVFS_EADB "posix:eadb" +#define PVFS_XATTR "posix:xattr" +#define PVFS_FAKE_OPLOCKS "posix:fakeoplocks" +#define PVFS_SHARE_DELAY "posix:sharedelay" +#define PVFS_ALLOCATION_ROUNDING "posix:allocationrounding" +#define PVFS_SEARCH_INACTIVITY "posix:searchinactivity" + +#define PVFS_XATTR_DEFAULT True +#define PVFS_FAKE_OPLOCKS_DEFAULT False +#define PVFS_SHARE_DELAY_DEFAULT 1000000 +#define PVFS_ALLOCATION_ROUNDING_DEFAULT 512 +#define PVFS_SEARCH_INACTIVITY_DEFAULT 300 + #include "ntvfs/posix/vfs_posix_proto.h" #endif /* _VFS_POSIX_H_ */ diff --git a/source4/ntvfs/print/vfs_print.c b/source4/ntvfs/print/vfs_print.c index 31cfcc9303..dfe76b846e 100644 --- a/source4/ntvfs/print/vfs_print.c +++ b/source4/ntvfs/print/vfs_print.c @@ -75,7 +75,6 @@ static NTSTATUS print_ioctl(struct ntvfs_module_context *ntvfs, } if (io->ioctl.in.request == IOCTL_QUERY_JOB_INFO) { - int snum = ntvfs->ctx->config.snum; /* a request for the print job id of an open print job */ io->ioctl.out.blob = data_blob_talloc(req, NULL, 32); @@ -85,7 +84,7 @@ static NTSTATUS print_ioctl(struct ntvfs_module_context *ntvfs, p = (char *)io->ioctl.out.blob.data; SSVAL(p,0, 1 /* REWRITE: fsp->rap_print_jobid */); push_string(p+2, lp_netbios_name(), 15, STR_TERMINATE|STR_ASCII); - push_string(p+18, lp_servicename(snum), 13, STR_TERMINATE|STR_ASCII); + push_string(p+18, ntvfs->ctx->config->name, 13, STR_TERMINATE|STR_ASCII); return NT_STATUS_OK; } diff --git a/source4/ntvfs/simple/vfs_simple.c b/source4/ntvfs/simple/vfs_simple.c index beffe2b546..ccb8b1b97c 100644 --- a/source4/ntvfs/simple/vfs_simple.c +++ b/source4/ntvfs/simple/vfs_simple.c @@ -39,7 +39,7 @@ #define O_DIRECTORY 0 #endif -#define CHECK_READ_ONLY(req) do { if (lp_readonly(ntvfs->ctx->config.snum)) return NT_STATUS_ACCESS_DENIED; } while (0) +#define CHECK_READ_ONLY(req) do { if (share_bool_option(ntvfs->ctx->config, SHARE_READONLY, True)) return NT_STATUS_ACCESS_DENIED; } while (0) /* connect to a share - used when a tree_connect operation comes @@ -52,13 +52,13 @@ static NTSTATUS svfs_connect(struct ntvfs_module_context *ntvfs, { struct stat st; struct svfs_private *private; - int snum = ntvfs->ctx->config.snum; + struct share_config *scfg = ntvfs->ctx->config; private = talloc(ntvfs, struct svfs_private); NT_STATUS_HAVE_NO_MEMORY(private); private->ntvfs = ntvfs; private->next_search_handle = 0; - private->connectpath = talloc_strdup(private, lp_pathname(snum)); + private->connectpath = talloc_strdup(private, share_string_option(scfg, SHARE_PATH, "")); private->open_files = NULL; private->search = NULL; @@ -319,7 +319,7 @@ static NTSTATUS svfs_open(struct ntvfs_module_context *ntvfs, return ntvfs_map_open(ntvfs, req, io); } - readonly = lp_readonly(ntvfs->ctx->config.snum); + readonly = share_bool_option(ntvfs->ctx->config, SHARE_READONLY, SHARE_READONLY_DEFAULT); if (readonly) { create_flags = 0; rdwr_flags = O_RDONLY; @@ -775,7 +775,7 @@ static NTSTATUS svfs_fsinfo(struct ntvfs_module_context *ntvfs, fs->generic.out.quota_soft = 0; fs->generic.out.quota_hard = 0; fs->generic.out.quota_flags = 0; - fs->generic.out.volume_name = talloc_strdup(req, lp_servicename(ntvfs->ctx->config.snum)); + fs->generic.out.volume_name = talloc_strdup(req, ntvfs->ctx->config->name); fs->generic.out.fs_type = ntvfs->ctx->fs_type; return NT_STATUS_OK; diff --git a/source4/ntvfs/sysdep/sys_notify.c b/source4/ntvfs/sysdep/sys_notify.c index c4fa4647d1..3f4f08203e 100644 --- a/source4/ntvfs/sysdep/sys_notify.c +++ b/source4/ntvfs/sysdep/sys_notify.c @@ -34,10 +34,12 @@ static struct sys_notify_backend *backends; static uint32_t num_backends; +#define NOTIFY_BACKEND "notify-backend" + /* initialise a system change notify backend */ -_PUBLIC_ struct sys_notify_context *sys_notify_context_create(int snum, +_PUBLIC_ struct sys_notify_context *sys_notify_context_create(struct share_config *scfg, TALLOC_CTX *mem_ctx, struct event_context *ev) { @@ -60,7 +62,7 @@ _PUBLIC_ struct sys_notify_context *sys_notify_context_create(int snum, ctx->ev = ev; - bname = lp_parm_string(snum, "notify", "backend"); + bname = share_string_option(scfg, NOTIFY_BACKEND, NULL); if (!bname) { if (num_backends) { bname = backends[0].name; diff --git a/source4/ntvfs/sysdep/sys_notify.h b/source4/ntvfs/sysdep/sys_notify.h index 6f8e91efec..6db10fe02c 100644 --- a/source4/ntvfs/sysdep/sys_notify.h +++ b/source4/ntvfs/sysdep/sys_notify.h @@ -19,6 +19,7 @@ */ #include "librpc/gen_ndr/notify.h" +#include "param/share.h" struct sys_notify_context; @@ -43,7 +44,7 @@ struct sys_notify_backend { }; NTSTATUS sys_notify_register(struct sys_notify_backend *backend); -struct sys_notify_context *sys_notify_context_create(int snum, +struct sys_notify_context *sys_notify_context_create(struct share_config *scfg, TALLOC_CTX *mem_ctx, struct event_context *ev); NTSTATUS sys_notify_watch(struct sys_notify_context *ctx, struct notify_entry *e, 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); +} + diff --git a/source4/rpc_server/common/common.h b/source4/rpc_server/common/common.h index 0dc3814c71..7fec95ac52 100644 --- a/source4/rpc_server/common/common.h +++ b/source4/rpc_server/common/common.h @@ -60,4 +60,5 @@ struct dcesrv_context; +#include "param/share.h" #include "rpc_server/common/proto.h" diff --git a/source4/rpc_server/common/share_info.c b/source4/rpc_server/common/share_info.c index 285218bad1..727e89e84a 100644 --- a/source4/rpc_server/common/share_info.c +++ b/source4/rpc_server/common/share_info.c @@ -21,6 +21,7 @@ */ #include "includes.h" +#include "param/share.h" #include "librpc/gen_ndr/srvsvc.h" #include "rpc_server/dcerpc_server.h" @@ -29,42 +30,19 @@ */ /* This hardcoded value should go into a ldb database! */ -uint32_t dcesrv_common_get_count_of_shares(TALLOC_CTX *mem_ctx, struct dcesrv_context *dce_ctx) -{ - /* what's about int -> uint32_t overflow */ - return lp_numservices(); -} - -_PUBLIC_ const char *dcesrv_common_get_share_name(TALLOC_CTX *mem_ctx, struct dcesrv_context *dce_ctx, int snum) -{ - return talloc_strdup(mem_ctx, lp_servicename(snum)); -} - -const char *dcesrv_common_get_share_comment(TALLOC_CTX *mem_ctx, struct dcesrv_context *dce_ctx, int snum) -{ - return talloc_strdup(mem_ctx, lp_comment(snum)); -} - -/* This hardcoded value should go into a ldb database! */ -uint32_t dcesrv_common_get_share_permissions(TALLOC_CTX *mem_ctx, struct dcesrv_context *dce_ctx, int snum) +uint32_t dcesrv_common_get_share_permissions(TALLOC_CTX *mem_ctx, struct dcesrv_context *dce_ctx, struct share_config *scfg) { return 0; } /* This hardcoded value should go into a ldb database! */ -uint32_t dcesrv_common_get_share_max_users(TALLOC_CTX *mem_ctx, struct dcesrv_context *dce_ctx, int snum) -{ - return lp_max_connections(snum); -} - -/* This hardcoded value should go into a ldb database! */ -uint32_t dcesrv_common_get_share_current_users(TALLOC_CTX *mem_ctx, struct dcesrv_context *dce_ctx, int snum) +uint32_t dcesrv_common_get_share_current_users(TALLOC_CTX *mem_ctx, struct dcesrv_context *dce_ctx, struct share_config *scfg) { return 1; } /* This hardcoded value should go into a ldb database! */ -enum srvsvc_ShareType dcesrv_common_get_share_type(TALLOC_CTX *mem_ctx, struct dcesrv_context *dce_ctx, int snum) +enum srvsvc_ShareType dcesrv_common_get_share_type(TALLOC_CTX *mem_ctx, struct dcesrv_context *dce_ctx, struct share_config *scfg) { /* for disk share 0x00000000 * for print share 0x00000001 @@ -75,17 +53,19 @@ enum srvsvc_ShareType dcesrv_common_get_share_type(TALLOC_CTX *mem_ctx, struct d * this ones are hidden in NetShareEnum, but shown in NetShareEnumAll */ enum srvsvc_ShareType share_type = 0; + const char *sharetype; - if (!lp_browseable(snum)) { + if (!share_bool_option(scfg, SHARE_BROWSEABLE, SHARE_BROWSEABLE_DEFAULT)) { share_type |= STYPE_HIDDEN; } - if (strcasecmp(lp_fstype(snum), "IPC") == 0) { + sharetype = share_string_option(scfg, SHARE_TYPE, SHARE_TYPE_DEFAULT); + if (sharetype && strcasecmp(sharetype, "IPC") == 0) { share_type |= STYPE_IPC; return share_type; } - if (lp_print_ok(snum)) { + if (sharetype && strcasecmp(sharetype, "PRINTER") == 0) { share_type |= STYPE_PRINTQ; return share_type; } @@ -96,40 +76,32 @@ enum srvsvc_ShareType dcesrv_common_get_share_type(TALLOC_CTX *mem_ctx, struct d } /* This hardcoded value should go into a ldb database! */ -const char *dcesrv_common_get_share_path(TALLOC_CTX *mem_ctx, struct dcesrv_context *dce_ctx, int snum) +const char *dcesrv_common_get_share_path(TALLOC_CTX *mem_ctx, struct dcesrv_context *dce_ctx, struct share_config *scfg) { - if (strcasecmp(lp_fstype(snum), "IPC") == 0) { + const char *sharetype; + + sharetype = share_string_option(scfg, SHARE_TYPE, SHARE_TYPE_DEFAULT); + + if (sharetype && strcasecmp(sharetype, "IPC") == 0) { return talloc_strdup(mem_ctx, ""); } return talloc_strdup(mem_ctx, "C:\\"); } /* This hardcoded value should go into a ldb database! */ -const char *dcesrv_common_get_share_password(TALLOC_CTX *mem_ctx, struct dcesrv_context *dce_ctx, int snum) -{ - return NULL; -} - -/* This hardcoded value should go into a ldb database! */ -uint32_t dcesrv_common_get_share_csc_policy(TALLOC_CTX *mem_ctx, struct dcesrv_context *dce_ctx, int snum) -{ - return 0; -} - -/* This hardcoded value should go into a ldb database! */ -uint32_t dcesrv_common_get_share_dfs_flags(TALLOC_CTX *mem_ctx, struct dcesrv_context *dce_ctx, int snum) +uint32_t dcesrv_common_get_share_dfs_flags(TALLOC_CTX *mem_ctx, struct dcesrv_context *dce_ctx, struct share_config *scfg) { return 0; } /* This hardcoded value should go into a ldb database! */ -uint32_t dcesrv_common_get_share_unknown(TALLOC_CTX *mem_ctx, struct dcesrv_context *dce_ctx, int snum) +uint32_t dcesrv_common_get_share_unknown(TALLOC_CTX *mem_ctx, struct dcesrv_context *dce_ctx, struct share_config *scfg) { return 0; } /* This hardcoded value should go into a ldb database! */ -struct security_descriptor *dcesrv_common_get_security_descriptor(TALLOC_CTX *mem_ctx, struct dcesrv_context *dce_ctx, int snum) +struct security_descriptor *dcesrv_common_get_security_descriptor(TALLOC_CTX *mem_ctx, struct dcesrv_context *dce_ctx, struct share_config *scfg) { return NULL; } diff --git a/source4/rpc_server/config.mk b/source4/rpc_server/config.mk index afe18217c1..292a86de5b 100644 --- a/source4/rpc_server/config.mk +++ b/source4/rpc_server/config.mk @@ -56,7 +56,7 @@ OBJ_FILES = \ srvsvc/dcesrv_srvsvc.o \ srvsvc/srvsvc_ntvfs.o PUBLIC_DEPENDENCIES = \ - DCERPC_COMMON NDR_SRVSVC + DCERPC_COMMON NDR_SRVSVC share # End MODULE dcerpc_srvsvc ################################################ diff --git a/source4/rpc_server/srvsvc/dcesrv_srvsvc.c b/source4/rpc_server/srvsvc/dcesrv_srvsvc.c index 44296655ac..fbff1d6cf8 100644 --- a/source4/rpc_server/srvsvc/dcesrv_srvsvc.c +++ b/source4/rpc_server/srvsvc/dcesrv_srvsvc.c @@ -21,13 +21,13 @@ */ #include "includes.h" +#include "ntvfs/ntvfs.h" #include "rpc_server/dcerpc_server.h" #include "librpc/gen_ndr/ndr_srvsvc.h" #include "rpc_server/common/common.h" #include "auth/auth.h" #include "libcli/security/security.h" #include "system/time.h" -#include "ntvfs/ntvfs.h" #include "rpc_server/srvsvc/proto.h" #define SRVSVC_CHECK_ADMIN_ACCESS do { \ @@ -465,76 +465,77 @@ static WERROR srvsvc_NetShareAdd(struct dcesrv_call_state *dce_call, TALLOC_CTX } static WERROR srvsvc_fiel_ShareInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, - int snum, uint32_t level, union srvsvc_NetShareInfo *info) + struct share_config *scfg, uint32_t level, + union srvsvc_NetShareInfo *info) { struct dcesrv_context *dce_ctx = dce_call->conn->dce_ctx; switch (level) { case 0: { - info->info0->name = dcesrv_common_get_share_name(mem_ctx, dce_ctx, snum); + info->info0->name = talloc_strdup(mem_ctx, scfg->name); W_ERROR_HAVE_NO_MEMORY(info->info0->name); return WERR_OK; } case 1: { - info->info1->name = dcesrv_common_get_share_name(mem_ctx, dce_ctx, snum); + info->info1->name = talloc_strdup(mem_ctx, scfg->name); W_ERROR_HAVE_NO_MEMORY(info->info1->name); - info->info1->type = dcesrv_common_get_share_type(mem_ctx, dce_ctx, snum); - info->info1->comment = dcesrv_common_get_share_comment(mem_ctx, dce_ctx, snum); + info->info1->type = dcesrv_common_get_share_type(mem_ctx, dce_ctx, scfg); + info->info1->comment = talloc_strdup(mem_ctx, share_string_option(scfg, SHARE_COMMENT, "")); W_ERROR_HAVE_NO_MEMORY(info->info1->comment); return WERR_OK; } case 2: { - info->info2->name = dcesrv_common_get_share_name(mem_ctx, dce_ctx, snum); + info->info2->name = talloc_strdup(mem_ctx, scfg->name); W_ERROR_HAVE_NO_MEMORY(info->info2->name); - info->info2->type = dcesrv_common_get_share_type(mem_ctx, dce_ctx, snum); - info->info2->comment = dcesrv_common_get_share_comment(mem_ctx, dce_ctx, snum); + info->info2->type = dcesrv_common_get_share_type(mem_ctx, dce_ctx, scfg); + info->info2->comment = talloc_strdup(mem_ctx, share_string_option(scfg, SHARE_COMMENT, "")); W_ERROR_HAVE_NO_MEMORY(info->info2->comment); - info->info2->permissions = dcesrv_common_get_share_permissions(mem_ctx, dce_ctx, snum); - info->info2->max_users = dcesrv_common_get_share_max_users(mem_ctx, dce_ctx, snum); - info->info2->current_users = dcesrv_common_get_share_current_users(mem_ctx, dce_ctx, snum); - info->info2->path = dcesrv_common_get_share_path(mem_ctx, dce_ctx, snum); + info->info2->permissions = dcesrv_common_get_share_permissions(mem_ctx, dce_ctx, scfg); + info->info2->max_users = share_int_option(scfg, SHARE_MAX_CONNECTIONS, SHARE_MAX_CONNECTIONS_DEFAULT); + info->info2->current_users = dcesrv_common_get_share_current_users(mem_ctx, dce_ctx, scfg); + info->info2->path = dcesrv_common_get_share_path(mem_ctx, dce_ctx, scfg); W_ERROR_HAVE_NO_MEMORY(info->info2->path); - info->info2->password = dcesrv_common_get_share_password(mem_ctx, dce_ctx, snum); + info->info2->password = talloc_strdup(mem_ctx, share_string_option(scfg, SHARE_PASSWORD, NULL)); return WERR_OK; } case 501: { - info->info501->name = dcesrv_common_get_share_name(mem_ctx, dce_ctx, snum); + info->info501->name = talloc_strdup(mem_ctx, scfg->name); W_ERROR_HAVE_NO_MEMORY(info->info501->name); - info->info501->type = dcesrv_common_get_share_type(mem_ctx, dce_ctx, snum); - info->info501->comment = dcesrv_common_get_share_comment(mem_ctx, dce_ctx, snum); + info->info501->type = dcesrv_common_get_share_type(mem_ctx, dce_ctx, scfg); + info->info501->comment = talloc_strdup(mem_ctx, share_string_option(scfg, SHARE_COMMENT, "")); W_ERROR_HAVE_NO_MEMORY(info->info501->comment); - info->info501->csc_policy = dcesrv_common_get_share_csc_policy(mem_ctx, dce_ctx, snum); + info->info501->csc_policy = share_int_option(scfg, SHARE_CSC_POLICY, SHARE_CSC_POLICY_DEFAULT); return WERR_OK; } case 502: { - info->info502->name = dcesrv_common_get_share_name(mem_ctx, dce_ctx, snum); + info->info502->name = talloc_strdup(mem_ctx, scfg->name); W_ERROR_HAVE_NO_MEMORY(info->info502->name); - info->info502->type = dcesrv_common_get_share_type(mem_ctx, dce_ctx, snum); - info->info502->comment = dcesrv_common_get_share_comment(mem_ctx, dce_ctx, snum); + info->info502->type = dcesrv_common_get_share_type(mem_ctx, dce_ctx, scfg); + info->info502->comment = talloc_strdup(mem_ctx, share_string_option(scfg, SHARE_COMMENT, "")); W_ERROR_HAVE_NO_MEMORY(info->info502->comment); - info->info502->permissions = dcesrv_common_get_share_permissions(mem_ctx, dce_ctx, snum); - info->info502->max_users = dcesrv_common_get_share_max_users(mem_ctx, dce_ctx, snum); - info->info502->current_users = dcesrv_common_get_share_current_users(mem_ctx, dce_ctx, snum); - info->info502->path = dcesrv_common_get_share_path(mem_ctx, dce_ctx, snum); + info->info502->permissions = dcesrv_common_get_share_permissions(mem_ctx, dce_ctx, scfg); + info->info502->max_users = share_int_option(scfg, SHARE_MAX_CONNECTIONS, SHARE_MAX_CONNECTIONS_DEFAULT); + info->info502->current_users = dcesrv_common_get_share_current_users(mem_ctx, dce_ctx, scfg); + info->info502->path = dcesrv_common_get_share_path(mem_ctx, dce_ctx, scfg); W_ERROR_HAVE_NO_MEMORY(info->info502->path); - info->info502->password = dcesrv_common_get_share_password(mem_ctx, dce_ctx, snum); - info->info502->unknown = dcesrv_common_get_share_unknown(mem_ctx, dce_ctx, snum); - info->info502->sd = dcesrv_common_get_security_descriptor(mem_ctx, dce_ctx, snum); + info->info502->password = talloc_strdup(mem_ctx, share_string_option(scfg, SHARE_PASSWORD, NULL)); + info->info502->unknown = dcesrv_common_get_share_unknown(mem_ctx, dce_ctx, scfg); + info->info502->sd = dcesrv_common_get_security_descriptor(mem_ctx, dce_ctx, scfg); return WERR_OK; } case 1005: { - info->info1005->dfs_flags = dcesrv_common_get_share_dfs_flags(mem_ctx, dce_ctx, snum); + info->info1005->dfs_flags = dcesrv_common_get_share_dfs_flags(mem_ctx, dce_ctx, scfg); return WERR_OK; } @@ -551,7 +552,11 @@ static WERROR srvsvc_fiel_ShareInfo(struct dcesrv_call_state *dce_call, TALLOC_C static WERROR srvsvc_NetShareEnumAll(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct srvsvc_NetShareEnumAll *r) { - struct dcesrv_context *dce_ctx = dce_call->conn->dce_ctx; + NTSTATUS nterr; + int numshares = 0; + const char **snames; + struct share_context *sctx; + struct share_config *scfg; r->out.level = r->in.level; ZERO_STRUCT(r->out.ctr); @@ -561,6 +566,16 @@ static WERROR srvsvc_NetShareEnumAll(struct dcesrv_call_state *dce_call, TALLOC_ /* TODO: - paging of results */ + nterr = share_get_context(mem_ctx, &sctx); + if (!NT_STATUS_IS_OK(nterr)) { + return ntstatus_to_werror(nterr); + } + + nterr = share_list_all(mem_ctx, sctx, &numshares, &snames); + if (!NT_STATUS_IS_OK(nterr)) { + return ntstatus_to_werror(nterr); + } + switch (r->in.level) { case 0: { @@ -570,7 +585,7 @@ static WERROR srvsvc_NetShareEnumAll(struct dcesrv_call_state *dce_call, TALLOC_ ctr0 = talloc(mem_ctx, struct srvsvc_NetShareCtr0); W_ERROR_HAVE_NO_MEMORY(ctr0); - ctr0->count = dcesrv_common_get_count_of_shares(mem_ctx, dce_ctx); + ctr0->count = numshares; ctr0->array = NULL; if (ctr0->count == 0) { @@ -581,16 +596,23 @@ static WERROR srvsvc_NetShareEnumAll(struct dcesrv_call_state *dce_call, TALLOC_ ctr0->array = talloc_array(mem_ctx, struct srvsvc_NetShareInfo0, ctr0->count); W_ERROR_HAVE_NO_MEMORY(ctr0->array); - for (i=0; i < ctr0->count; i++) { + for (i = 0; i < ctr0->count; i++) { WERROR status; union srvsvc_NetShareInfo info; + nterr = share_get_config(mem_ctx, sctx, snames[i], &scfg); + if (!NT_STATUS_IS_OK(nterr)) { + DEBUG(1, ("ERROR: Service [%s] disappeared after enumeration", snames[i])); + return WERR_GENERAL_FAILURE; + } info.info0 = &ctr0->array[i]; - status = srvsvc_fiel_ShareInfo(dce_call, mem_ctx, i, r->in.level, &info); + status = srvsvc_fiel_ShareInfo(dce_call, mem_ctx, scfg, r->in.level, &info); if (!W_ERROR_IS_OK(status)) { return status; } + talloc_free(scfg); } + talloc_free(snames); r->out.ctr.ctr0 = ctr0; r->out.totalentries = r->out.ctr.ctr0->count; @@ -604,7 +626,7 @@ static WERROR srvsvc_NetShareEnumAll(struct dcesrv_call_state *dce_call, TALLOC_ ctr1 = talloc(mem_ctx, struct srvsvc_NetShareCtr1); W_ERROR_HAVE_NO_MEMORY(ctr1); - ctr1->count = dcesrv_common_get_count_of_shares(mem_ctx, dce_ctx); + ctr1->count = numshares; ctr1->array = NULL; if (ctr1->count == 0) { @@ -619,12 +641,19 @@ static WERROR srvsvc_NetShareEnumAll(struct dcesrv_call_state *dce_call, TALLOC_ WERROR status; union srvsvc_NetShareInfo info; + nterr = share_get_config(mem_ctx, sctx, snames[i], &scfg); + if (!NT_STATUS_IS_OK(nterr)) { + DEBUG(1, ("ERROR: Service [%s] disappeared after enumeration", snames[i])); + return WERR_GENERAL_FAILURE; + } info.info1 = &ctr1->array[i]; - status = srvsvc_fiel_ShareInfo(dce_call, mem_ctx, i, r->in.level, &info); + status = srvsvc_fiel_ShareInfo(dce_call, mem_ctx, scfg, r->in.level, &info); if (!W_ERROR_IS_OK(status)) { return status; } + talloc_free(scfg); } + talloc_free(snames); r->out.ctr.ctr1 = ctr1; r->out.totalentries = r->out.ctr.ctr1->count; @@ -640,7 +669,7 @@ static WERROR srvsvc_NetShareEnumAll(struct dcesrv_call_state *dce_call, TALLOC_ ctr2 = talloc(mem_ctx, struct srvsvc_NetShareCtr2); W_ERROR_HAVE_NO_MEMORY(ctr2); - ctr2->count = dcesrv_common_get_count_of_shares(mem_ctx, dce_ctx); + ctr2->count = numshares; ctr2->array = NULL; if (ctr2->count == 0) { @@ -655,12 +684,19 @@ static WERROR srvsvc_NetShareEnumAll(struct dcesrv_call_state *dce_call, TALLOC_ WERROR status; union srvsvc_NetShareInfo info; + nterr = share_get_config(mem_ctx, sctx, snames[i], &scfg); + if (!NT_STATUS_IS_OK(nterr)) { + DEBUG(1, ("ERROR: Service [%s] disappeared after enumeration", snames[i])); + return WERR_GENERAL_FAILURE; + } info.info2 = &ctr2->array[i]; - status = srvsvc_fiel_ShareInfo(dce_call, mem_ctx, i, r->in.level, &info); + status = srvsvc_fiel_ShareInfo(dce_call, mem_ctx, scfg, r->in.level, &info); if (!W_ERROR_IS_OK(status)) { return status; } + talloc_free(scfg); } + talloc_free(snames); r->out.ctr.ctr2 = ctr2; r->out.totalentries = r->out.ctr.ctr2->count; @@ -676,7 +712,7 @@ static WERROR srvsvc_NetShareEnumAll(struct dcesrv_call_state *dce_call, TALLOC_ ctr501 = talloc(mem_ctx, struct srvsvc_NetShareCtr501); W_ERROR_HAVE_NO_MEMORY(ctr501); - ctr501->count = dcesrv_common_get_count_of_shares(mem_ctx, dce_ctx); + ctr501->count = numshares; ctr501->array = NULL; if (ctr501->count == 0) { @@ -691,12 +727,19 @@ static WERROR srvsvc_NetShareEnumAll(struct dcesrv_call_state *dce_call, TALLOC_ WERROR status; union srvsvc_NetShareInfo info; + nterr = share_get_config(mem_ctx, sctx, snames[i], &scfg); + if (!NT_STATUS_IS_OK(nterr)) { + DEBUG(1, ("ERROR: Service [%s] disappeared after enumeration", snames[i])); + return WERR_GENERAL_FAILURE; + } info.info501 = &ctr501->array[i]; - status = srvsvc_fiel_ShareInfo(dce_call, mem_ctx, i, r->in.level, &info); + status = srvsvc_fiel_ShareInfo(dce_call, mem_ctx, scfg, r->in.level, &info); if (!W_ERROR_IS_OK(status)) { return status; } + talloc_free(scfg); } + talloc_free(snames); r->out.ctr.ctr501 = ctr501; r->out.totalentries = r->out.ctr.ctr501->count; @@ -712,7 +755,7 @@ static WERROR srvsvc_NetShareEnumAll(struct dcesrv_call_state *dce_call, TALLOC_ ctr502 = talloc(mem_ctx, struct srvsvc_NetShareCtr502); W_ERROR_HAVE_NO_MEMORY(ctr502); - ctr502->count = dcesrv_common_get_count_of_shares(mem_ctx, dce_ctx); + ctr502->count = numshares; ctr502->array = NULL; if (ctr502->count == 0) { @@ -727,12 +770,19 @@ static WERROR srvsvc_NetShareEnumAll(struct dcesrv_call_state *dce_call, TALLOC_ WERROR status; union srvsvc_NetShareInfo info; + nterr = share_get_config(mem_ctx, sctx, snames[i], &scfg); + if (!NT_STATUS_IS_OK(nterr)) { + DEBUG(1, ("ERROR: Service [%s] disappeared after enumeration", snames[i])); + return WERR_GENERAL_FAILURE; + } info.info502 = &ctr502->array[i]; - status = srvsvc_fiel_ShareInfo(dce_call, mem_ctx, i, r->in.level, &info); + status = srvsvc_fiel_ShareInfo(dce_call, mem_ctx, scfg, r->in.level, &info); if (!W_ERROR_IS_OK(status)) { return status; } + talloc_free(scfg); } + talloc_free(snames); r->out.ctr.ctr502 = ctr502; r->out.totalentries = r->out.ctr.ctr502->count; @@ -752,7 +802,9 @@ static WERROR srvsvc_NetShareEnumAll(struct dcesrv_call_state *dce_call, TALLOC_ static WERROR srvsvc_NetShareGetInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct srvsvc_NetShareGetInfo *r) { - int snum; + NTSTATUS nterr; + struct share_context *sctx = NULL; + struct share_config *scfg = NULL; ZERO_STRUCT(r->out); @@ -763,9 +815,14 @@ static WERROR srvsvc_NetShareGetInfo(struct dcesrv_call_state *dce_call, TALLOC_ return WERR_INVALID_PARAM; } - snum = lp_servicenumber(r->in.share_name); - if (snum < 0) { - return WERR_NET_NAME_NOT_FOUND; + nterr = share_get_context(mem_ctx, &sctx); + if (!NT_STATUS_IS_OK(nterr)) { + return ntstatus_to_werror(nterr); + } + + nterr = share_get_config(mem_ctx, sctx, r->in.share_name, &scfg); + if (!NT_STATUS_IS_OK(nterr)) { + return ntstatus_to_werror(nterr); } switch (r->in.level) { @@ -777,7 +834,7 @@ static WERROR srvsvc_NetShareGetInfo(struct dcesrv_call_state *dce_call, TALLOC_ info.info0 = talloc(mem_ctx, struct srvsvc_NetShareInfo0); W_ERROR_HAVE_NO_MEMORY(info.info0); - status = srvsvc_fiel_ShareInfo(dce_call, mem_ctx, snum, r->in.level, &info); + status = srvsvc_fiel_ShareInfo(dce_call, mem_ctx, scfg, r->in.level, &info); if (!W_ERROR_IS_OK(status)) { return status; } @@ -793,7 +850,7 @@ static WERROR srvsvc_NetShareGetInfo(struct dcesrv_call_state *dce_call, TALLOC_ info.info1 = talloc(mem_ctx, struct srvsvc_NetShareInfo1); W_ERROR_HAVE_NO_MEMORY(info.info1); - status = srvsvc_fiel_ShareInfo(dce_call, mem_ctx, snum, r->in.level, &info); + status = srvsvc_fiel_ShareInfo(dce_call, mem_ctx, scfg, r->in.level, &info); if (!W_ERROR_IS_OK(status)) { return status; } @@ -811,7 +868,7 @@ static WERROR srvsvc_NetShareGetInfo(struct dcesrv_call_state *dce_call, TALLOC_ info.info2 = talloc(mem_ctx, struct srvsvc_NetShareInfo2); W_ERROR_HAVE_NO_MEMORY(info.info2); - status = srvsvc_fiel_ShareInfo(dce_call, mem_ctx, snum, r->in.level, &info); + status = srvsvc_fiel_ShareInfo(dce_call, mem_ctx, scfg, r->in.level, &info); if (!W_ERROR_IS_OK(status)) { return status; } @@ -827,7 +884,7 @@ static WERROR srvsvc_NetShareGetInfo(struct dcesrv_call_state *dce_call, TALLOC_ info.info501 = talloc(mem_ctx, struct srvsvc_NetShareInfo501); W_ERROR_HAVE_NO_MEMORY(info.info501); - status = srvsvc_fiel_ShareInfo(dce_call, mem_ctx, snum, r->in.level, &info); + status = srvsvc_fiel_ShareInfo(dce_call, mem_ctx, scfg, r->in.level, &info); if (!W_ERROR_IS_OK(status)) { return status; } @@ -845,7 +902,7 @@ static WERROR srvsvc_NetShareGetInfo(struct dcesrv_call_state *dce_call, TALLOC_ info.info502 = talloc(mem_ctx, struct srvsvc_NetShareInfo502); W_ERROR_HAVE_NO_MEMORY(info.info502); - status = srvsvc_fiel_ShareInfo(dce_call, mem_ctx, snum, r->in.level, &info); + status = srvsvc_fiel_ShareInfo(dce_call, mem_ctx, scfg, r->in.level, &info); if (!W_ERROR_IS_OK(status)) { return status; } @@ -861,7 +918,7 @@ static WERROR srvsvc_NetShareGetInfo(struct dcesrv_call_state *dce_call, TALLOC_ info.info1005 = talloc(mem_ctx, struct srvsvc_NetShareInfo1005); W_ERROR_HAVE_NO_MEMORY(info.info1005); - status = srvsvc_fiel_ShareInfo(dce_call, mem_ctx, snum, r->in.level, &info); + status = srvsvc_fiel_ShareInfo(dce_call, mem_ctx, scfg, r->in.level, &info); if (!W_ERROR_IS_OK(status)) { return status; } @@ -1192,6 +1249,11 @@ static WERROR srvsvc_NetPRNameCompare(struct dcesrv_call_state *dce_call, TALLOC static WERROR srvsvc_NetShareEnum(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct srvsvc_NetShareEnum *r) { + NTSTATUS nterr; + int numshares = 0; + const char **snames; + struct share_context *sctx; + struct share_config *scfg; struct dcesrv_context *dce_ctx = dce_call->conn->dce_ctx; r->out.level = r->in.level; @@ -1202,6 +1264,16 @@ static WERROR srvsvc_NetShareEnum(struct dcesrv_call_state *dce_call, TALLOC_CTX /* TODO: - paging of results */ + nterr = share_get_context(mem_ctx, &sctx); + if (!NT_STATUS_IS_OK(nterr)) { + return ntstatus_to_werror(nterr); + } + + nterr = share_list_all(mem_ctx, sctx, &numshares, &snames); + if (!NT_STATUS_IS_OK(nterr)) { + return ntstatus_to_werror(nterr); + } + switch (r->in.level) { case 0: { @@ -1212,7 +1284,7 @@ static WERROR srvsvc_NetShareEnum(struct dcesrv_call_state *dce_call, TALLOC_CTX ctr0 = talloc(mem_ctx, struct srvsvc_NetShareCtr0); W_ERROR_HAVE_NO_MEMORY(ctr0); - count = dcesrv_common_get_count_of_shares(mem_ctx, dce_ctx); + count = numshares; ctr0->count = count; ctr0->array = NULL; @@ -1227,18 +1299,28 @@ static WERROR srvsvc_NetShareEnum(struct dcesrv_call_state *dce_call, TALLOC_CTX for (i=0; i < count; i++) { WERROR status; union srvsvc_NetShareInfo info; - enum srvsvc_ShareType type = dcesrv_common_get_share_type(mem_ctx, dce_ctx, i); + enum srvsvc_ShareType type; + nterr = share_get_config(mem_ctx, sctx, snames[i], &scfg); + if (!NT_STATUS_IS_OK(nterr)) { + DEBUG(1, ("ERROR: Service [%s] disappeared after enumeration", snames[i])); + return WERR_GENERAL_FAILURE; + } + + type = dcesrv_common_get_share_type(mem_ctx, dce_ctx, scfg); if (type & STYPE_HIDDEN) { ctr0->count--; + talloc_free(scfg); continue; } info.info0 = &ctr0->array[y]; - status = srvsvc_fiel_ShareInfo(dce_call, mem_ctx, i, r->in.level, &info); + status = srvsvc_fiel_ShareInfo(dce_call, mem_ctx, scfg, r->in.level, &info); W_ERROR_NOT_OK_RETURN(status); + talloc_free(scfg); y++; } + talloc_free(snames); r->out.ctr.ctr0 = ctr0; r->out.totalentries = r->out.ctr.ctr0->count; @@ -1253,7 +1335,7 @@ static WERROR srvsvc_NetShareEnum(struct dcesrv_call_state *dce_call, TALLOC_CTX ctr1 = talloc(mem_ctx, struct srvsvc_NetShareCtr1); W_ERROR_HAVE_NO_MEMORY(ctr1); - count = dcesrv_common_get_count_of_shares(mem_ctx, dce_ctx); + count = numshares; ctr1->count = count; ctr1->array = NULL; @@ -1268,18 +1350,28 @@ static WERROR srvsvc_NetShareEnum(struct dcesrv_call_state *dce_call, TALLOC_CTX for (i=0; i < count; i++) { WERROR status; union srvsvc_NetShareInfo info; - enum srvsvc_ShareType type = dcesrv_common_get_share_type(mem_ctx, dce_ctx, i); + enum srvsvc_ShareType type; + nterr = share_get_config(mem_ctx, sctx, snames[i], &scfg); + if (!NT_STATUS_IS_OK(nterr)) { + DEBUG(1, ("ERROR: Service [%s] disappeared after enumeration", snames[i])); + return WERR_GENERAL_FAILURE; + } + + type = dcesrv_common_get_share_type(mem_ctx, dce_ctx, scfg); if (type & STYPE_HIDDEN) { ctr1->count--; + talloc_free(scfg); continue; } info.info1 = &ctr1->array[y]; - status = srvsvc_fiel_ShareInfo(dce_call, mem_ctx, i, r->in.level, &info); + status = srvsvc_fiel_ShareInfo(dce_call, mem_ctx, scfg, r->in.level, &info); W_ERROR_NOT_OK_RETURN(status); + talloc_free(scfg); y++; } + talloc_free(snames); r->out.ctr.ctr1 = ctr1; r->out.totalentries = r->out.ctr.ctr1->count; @@ -1296,7 +1388,7 @@ static WERROR srvsvc_NetShareEnum(struct dcesrv_call_state *dce_call, TALLOC_CTX ctr2 = talloc(mem_ctx, struct srvsvc_NetShareCtr2); W_ERROR_HAVE_NO_MEMORY(ctr2); - count = dcesrv_common_get_count_of_shares(mem_ctx, dce_ctx); + count = numshares; ctr2->count = count; ctr2->array = NULL; @@ -1311,18 +1403,28 @@ static WERROR srvsvc_NetShareEnum(struct dcesrv_call_state *dce_call, TALLOC_CTX for (i=0; i < count; i++) { WERROR status; union srvsvc_NetShareInfo info; - enum srvsvc_ShareType type = dcesrv_common_get_share_type(mem_ctx, dce_ctx, i); + enum srvsvc_ShareType type; + + nterr = share_get_config(mem_ctx, sctx, snames[i], &scfg); + if (!NT_STATUS_IS_OK(nterr)) { + DEBUG(1, ("ERROR: Service [%s] disappeared after enumeration", snames[i])); + return WERR_GENERAL_FAILURE; + } + type = dcesrv_common_get_share_type(mem_ctx, dce_ctx, scfg); if (type & STYPE_HIDDEN) { ctr2->count--; + talloc_free(scfg); continue; } info.info2 = &ctr2->array[y]; - status = srvsvc_fiel_ShareInfo(dce_call, mem_ctx, i, r->in.level, &info); + status = srvsvc_fiel_ShareInfo(dce_call, mem_ctx, scfg, r->in.level, &info); W_ERROR_NOT_OK_RETURN(status); + talloc_free(scfg); y++; } + talloc_free(snames); r->out.ctr.ctr2 = ctr2; r->out.totalentries = r->out.ctr.ctr2->count; @@ -1339,7 +1441,7 @@ static WERROR srvsvc_NetShareEnum(struct dcesrv_call_state *dce_call, TALLOC_CTX ctr502 = talloc(mem_ctx, struct srvsvc_NetShareCtr502); W_ERROR_HAVE_NO_MEMORY(ctr502); - count = dcesrv_common_get_count_of_shares(mem_ctx, dce_ctx); + count = numshares; ctr502->count = count; ctr502->array = NULL; @@ -1354,18 +1456,28 @@ static WERROR srvsvc_NetShareEnum(struct dcesrv_call_state *dce_call, TALLOC_CTX for (i=0; i < count; i++) { WERROR status; union srvsvc_NetShareInfo info; - enum srvsvc_ShareType type = dcesrv_common_get_share_type(mem_ctx, dce_ctx, i); + enum srvsvc_ShareType type; + + nterr = share_get_config(mem_ctx, sctx, snames[i], &scfg); + if (!NT_STATUS_IS_OK(nterr)) { + DEBUG(1, ("ERROR: Service [%s] disappeared after enumeration", snames[i])); + return WERR_GENERAL_FAILURE; + } + type = dcesrv_common_get_share_type(mem_ctx, dce_ctx, scfg); if (type & STYPE_HIDDEN) { ctr502->count--; + talloc_free(scfg); continue; } info.info502 = &ctr502->array[y]; - status = srvsvc_fiel_ShareInfo(dce_call, mem_ctx, i, r->in.level, &info); + status = srvsvc_fiel_ShareInfo(dce_call, mem_ctx, scfg, r->in.level, &info); W_ERROR_NOT_OK_RETURN(status); + talloc_free(scfg); y++; } + talloc_free(snames); r->out.ctr.ctr502 = ctr502; r->out.totalentries = r->out.ctr.ctr502->count; diff --git a/source4/rpc_server/srvsvc/srvsvc_ntvfs.c b/source4/rpc_server/srvsvc/srvsvc_ntvfs.c index 8bd88e53e9..d8d305cf9b 100644 --- a/source4/rpc_server/srvsvc/srvsvc_ntvfs.c +++ b/source4/rpc_server/srvsvc/srvsvc_ntvfs.c @@ -20,10 +20,10 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "includes.h" +#include "ntvfs/ntvfs.h" #include "rpc_server/dcerpc_server.h" #include "librpc/gen_ndr/ndr_srvsvc.h" #include "rpc_server/common/common.h" -#include "ntvfs/ntvfs.h" #include "rpc_server/srvsvc/proto.h" #include "lib/socket/socket.h" @@ -58,27 +58,35 @@ NTSTATUS srvsvc_create_ntvfs_context(struct dcesrv_call_state *dce_call, struct srvsvc_ntvfs_ctx *c; struct ntvfs_request *ntvfs_req; enum ntvfs_type type; - int snum; + struct share_context *sctx; + struct share_config *scfg; + const char *sharetype; + + status = share_get_context(mem_ctx, &sctx); + if (!NT_STATUS_IS_OK(status)) { + return status; + } - snum = lp_find_valid_service(share); - if (snum == -1) { + status = share_get_config(mem_ctx, sctx, share, &scfg); + if (!NT_STATUS_IS_OK(status)) { DEBUG(0,("srvsvc_create_ntvfs_context: couldn't find service %s\n", share)); - return NT_STATUS_BAD_NETWORK_NAME; + return status; } #if 0 /* TODO: fix access cecking */ if (!socket_check_access(dce_call->connection->socket, - lp_servicename(snum), - lp_hostsallow(snum), - lp_hostsdeny(snum))) { + scfg->name, + share_string_list_option(scfg, SHARE_HOSTS_ALLOW), + share_string_list_option(scfg, SHARE_HOSTS_DENY))) { return NT_STATUS_ACCESS_DENIED; } #endif /* work out what sort of connection this is */ - if (strcmp(lp_fstype(snum), "IPC") == 0) { + sharetype = share_string_option(scfg, SHARE_TYPE, SHARE_TYPE_DEFAULT); + if (sharetype && strcmp(sharetype, "IPC") == 0) { type = NTVFS_IPC; - } else if (lp_print_ok(snum)) { + } else if (sharetype && strcmp(sharetype, "PRINTER")) { type = NTVFS_PRINT; } else { type = NTVFS_DISK; @@ -88,7 +96,7 @@ NTSTATUS srvsvc_create_ntvfs_context(struct dcesrv_call_state *dce_call, NT_STATUS_HAVE_NO_MEMORY(c); /* init ntvfs function pointers */ - status = ntvfs_init_connection(c, snum, type, + status = ntvfs_init_connection(c, scfg, type, PROTOCOL_NT1, dce_call->event_ctx, dce_call->conn->msg_ctx, @@ -96,7 +104,7 @@ NTSTATUS srvsvc_create_ntvfs_context(struct dcesrv_call_state *dce_call, &c->ntvfs); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("srvsvc_create_ntvfs_context: ntvfs_init_connection failed for service %s\n", - lp_servicename(snum))); + scfg->name)); return status; } talloc_set_destructor(c, srvsvc_ntvfs_ctx_destructor); @@ -118,7 +126,7 @@ NTSTATUS srvsvc_create_ntvfs_context(struct dcesrv_call_state *dce_call, NT_STATUS_HAVE_NO_MEMORY(ntvfs_req); /* Invoke NTVFS connection hook */ - status = ntvfs_connect(ntvfs_req, lp_servicename(snum)); + status = ntvfs_connect(ntvfs_req, scfg->name); if (!NT_STATUS_IS_OK(status)) { DEBUG(0,("srvsvc_create_ntvfs_context: NTVFS ntvfs_connect() failed!\n")); return status; diff --git a/source4/scripting/libjs/provision.js b/source4/scripting/libjs/provision.js index 9ad2257ff3..c4ffab6a30 100644 --- a/source4/scripting/libjs/provision.js +++ b/source4/scripting/libjs/provision.js @@ -367,6 +367,7 @@ function provision_default_paths(subobj) var lp = loadparm_init(); var paths = new Object(); paths.smbconf = lp.get("config file"); + paths.shareconf = lp.get("private dir") + "/" + "share.ldb"; paths.hklm = "hklm.ldb"; paths.hkcu = "hkcu.ldb"; paths.hkcr = "hkcr.ldb"; @@ -464,6 +465,12 @@ function provision(subobj, message, blank, paths, session_info, credentials) setup_file("provision.smb.conf", info.message, paths.smbconf, subobj); lp.reload(); } + /* only install a new shares config db if there is none */ + st = sys.stat(paths.shareconf); + if (st == undefined) { + message("Setting up sconf.ldb\n"); + setup_ldb("share.ldif", info, paths.shareconf); + } message("Setting up secrets.ldb\n"); setup_ldb("secrets.ldif", info, paths.secrets); message("Setting up keytabs\n"); diff --git a/source4/smb_server/config.mk b/source4/smb_server/config.mk index 6eef711072..f21336ae69 100644 --- a/source4/smb_server/config.mk +++ b/source4/smb_server/config.mk @@ -18,6 +18,7 @@ OBJ_FILES = \ management.o PRIVATE_PROTO_HEADER = smb_server_proto.h PUBLIC_DEPENDENCIES = \ + share \ LIBPACKET \ SMB_PROTOCOL \ SMB2_PROTOCOL diff --git a/source4/smb_server/smb/service.c b/source4/smb_server/smb/service.c index 92967d858c..b396d2b605 100644 --- a/source4/smb_server/smb/service.c +++ b/source4/smb_server/smb/service.c @@ -27,22 +27,16 @@ Make a connection, given the snum to connect to, and the vuser of the connecting user if appropriate. ****************************************************************************/ -static NTSTATUS make_connection_snum(struct smbsrv_request *req, - int snum, enum ntvfs_type type, +static NTSTATUS make_connection_scfg(struct smbsrv_request *req, + struct share_config *scfg, + enum ntvfs_type type, DATA_BLOB password, const char *dev) { struct smbsrv_tcon *tcon; NTSTATUS status; - if (!socket_check_access(req->smb_conn->connection->socket, - lp_servicename(snum), - lp_hostsallow(snum), - lp_hostsdeny(snum))) { - return NT_STATUS_ACCESS_DENIED; - } - - tcon = smbsrv_smb_tcon_new(req->smb_conn, lp_servicename(snum)); + tcon = smbsrv_smb_tcon_new(req->smb_conn, scfg->name); if (!tcon) { DEBUG(0,("Couldn't find free connection.\n")); return NT_STATUS_INSUFFICIENT_RESOURCES; @@ -50,15 +44,15 @@ static NTSTATUS make_connection_snum(struct smbsrv_request *req, req->tcon = tcon; /* init ntvfs function pointers */ - status = ntvfs_init_connection(tcon, snum, type, + status = ntvfs_init_connection(tcon, scfg, type, req->smb_conn->negotiate.protocol, req->smb_conn->connection->event.ctx, req->smb_conn->connection->msg_ctx, req->smb_conn->connection->server_id, &tcon->ntvfs); if (!NT_STATUS_IS_OK(status)) { - DEBUG(0, ("ntvfs_init_connection failed for service %s\n", - lp_servicename(snum))); + DEBUG(0, ("make_connection_scfg: connection failed for service %s\n", + scfg->name)); goto failed; } @@ -97,7 +91,7 @@ static NTSTATUS make_connection_snum(struct smbsrv_request *req, } /* Invoke NTVFS connection hook */ - status = ntvfs_connect(req->ntvfs, lp_servicename(snum)); + status = ntvfs_connect(req->ntvfs, scfg->name); if (!NT_STATUS_IS_OK(status)) { DEBUG(0,("make_connection: NTVFS make connection failed!\n")); goto failed; @@ -120,11 +114,11 @@ static NTSTATUS make_connection(struct smbsrv_request *req, const char *service, DATA_BLOB password, const char *dev) { - int snum; + NTSTATUS status; enum ntvfs_type type; const char *type_str; - - /* TODO: check the password, when it's share level security! */ + struct share_config *scfg; + const char *sharetype; /* the service might be of the form \\SERVER\SHARE. Should we put the server name we get from this somewhere? */ @@ -135,17 +129,27 @@ static NTSTATUS make_connection(struct smbsrv_request *req, } } - snum = lp_find_valid_service(service); - if (snum == -1) { - DEBUG(0,("couldn't find service %s\n", service)); + status = share_get_config(req, req->smb_conn->share_context, service, &scfg); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0,("make_connection: couldn't find service %s\n", service)); return NT_STATUS_BAD_NETWORK_NAME; } + /* TODO: check the password, when it's share level security! */ + + if (!socket_check_access(req->smb_conn->connection->socket, + scfg->name, + share_string_list_option(req, scfg, SHARE_HOSTS_ALLOW), + share_string_list_option(req, scfg, SHARE_HOSTS_DENY))) { + return NT_STATUS_ACCESS_DENIED; + } + /* work out what sort of connection this is */ - if (strcmp(lp_fstype(snum), "IPC") == 0) { + sharetype = share_string_option(scfg, "type", "DISK"); + if (sharetype && strcmp(sharetype, "IPC") == 0) { type = NTVFS_IPC; type_str = "IPC"; - } else if (lp_print_ok(snum)) { + } else if (sharetype && strcmp(sharetype, "PRINTER") == 0) { type = NTVFS_PRINT; type_str = "LPT:"; } else { @@ -158,7 +162,7 @@ static NTSTATUS make_connection(struct smbsrv_request *req, return NT_STATUS_BAD_DEVICE_TYPE; } - return make_connection_snum(req, snum, type, password, dev); + return make_connection_scfg(req, scfg, type, password, dev); } /* @@ -167,7 +171,6 @@ static NTSTATUS make_connection(struct smbsrv_request *req, NTSTATUS smbsrv_tcon_backend(struct smbsrv_request *req, union smb_tcon *con) { NTSTATUS status; - int snum; if (con->generic.level == RAW_TCON_TCON) { DATA_BLOB password; @@ -191,13 +194,11 @@ NTSTATUS smbsrv_tcon_backend(struct smbsrv_request *req, union smb_tcon *con) return status; } - snum = req->tcon->ntvfs->config.snum; - con->tconx.out.tid = req->tcon->tid; con->tconx.out.dev_type = talloc_strdup(req, req->tcon->ntvfs->dev_type); con->tconx.out.fs_type = talloc_strdup(req, req->tcon->ntvfs->fs_type); - con->tconx.out.options = SMB_SUPPORT_SEARCH_BITS | (lp_csc_policy(snum) << 2); - if (lp_msdfs_root(snum) && lp_host_msdfs()) { + con->tconx.out.options = SMB_SUPPORT_SEARCH_BITS | (share_int_option(req->tcon->ntvfs->config, SHARE_CSC_POLICY, SHARE_CSC_POLICY_DEFAULT) << 2); + if (share_bool_option(req->tcon->ntvfs->config, SHARE_MSDFS_ROOT, SHARE_MSDFS_ROOT_DEFAULT) && lp_host_msdfs()) { con->tconx.out.options |= SMB_SHARE_IN_DFS; } diff --git a/source4/smb_server/smb2/tcon.c b/source4/smb_server/smb2/tcon.c index 338fb5ed22..d01b63d446 100644 --- a/source4/smb_server/smb2/tcon.c +++ b/source4/smb_server/smb2/tcon.c @@ -157,8 +157,9 @@ static NTSTATUS smb2srv_tcon_backend(struct smb2srv_request *req, union smb_tcon enum ntvfs_type type; uint16_t type_smb2; uint32_t unknown2; - int snum; const char *service = io->smb2.in.path; + struct share_config *scfg; + const char *sharetype; if (strncmp(service, "\\\\", 2) == 0) { const char *p = strchr(service+2, '\\'); @@ -167,25 +168,26 @@ static NTSTATUS smb2srv_tcon_backend(struct smb2srv_request *req, union smb_tcon } } - snum = lp_find_valid_service(service); - if (snum == -1) { + status = share_get_config(req, req->smb_conn->share_context, service, &scfg); + if (!NT_STATUS_IS_OK(status)) { DEBUG(0,("smb2srv_tcon_backend: couldn't find service %s\n", service)); return NT_STATUS_BAD_NETWORK_NAME; } if (!socket_check_access(req->smb_conn->connection->socket, - lp_servicename(snum), - lp_hostsallow(snum), - lp_hostsdeny(snum))) { + scfg->name, + share_string_list_option(req, scfg, SHARE_HOSTS_ALLOW), + share_string_list_option(req, scfg, SHARE_HOSTS_DENY))) { return NT_STATUS_ACCESS_DENIED; } /* work out what sort of connection this is */ - if (strcmp(lp_fstype(snum), "IPC") == 0) { + sharetype = share_string_option(scfg, SHARE_TYPE, "DISK"); + if (sharetype && strcmp(sharetype, "IPC") == 0) { type = NTVFS_IPC; type_smb2 = 0x0002; unknown2 = 0x00000030; - } else if (lp_print_ok(snum)) { + } else if (sharetype && strcmp(sharetype, "PRINTER") == 0) { type = NTVFS_PRINT; type_smb2 = 0x0003; unknown2 = 0x00000000; @@ -195,7 +197,7 @@ static NTSTATUS smb2srv_tcon_backend(struct smb2srv_request *req, union smb_tcon unknown2 = 0x00000800; } - tcon = smbsrv_smb2_tcon_new(req->session, lp_servicename(snum)); + tcon = smbsrv_smb2_tcon_new(req->session, scfg->name); if (!tcon) { DEBUG(0,("smb2srv_tcon_backend: Couldn't find free connection.\n")); return NT_STATUS_INSUFFICIENT_RESOURCES; @@ -203,7 +205,7 @@ static NTSTATUS smb2srv_tcon_backend(struct smb2srv_request *req, union smb_tcon req->tcon = tcon; /* init ntvfs function pointers */ - status = ntvfs_init_connection(tcon, snum, type, + status = ntvfs_init_connection(tcon, scfg, type, req->smb_conn->negotiate.protocol, req->smb_conn->connection->event.ctx, req->smb_conn->connection->msg_ctx, @@ -211,7 +213,7 @@ static NTSTATUS smb2srv_tcon_backend(struct smb2srv_request *req, union smb_tcon &tcon->ntvfs); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("smb2srv_tcon_backend: ntvfs_init_connection failed for service %s\n", - lp_servicename(snum))); + scfg->name)); goto failed; } @@ -250,7 +252,7 @@ static NTSTATUS smb2srv_tcon_backend(struct smb2srv_request *req, union smb_tcon } /* Invoke NTVFS connection hook */ - status = ntvfs_connect(req->ntvfs, lp_servicename(snum)); + status = ntvfs_connect(req->ntvfs, scfg->name); if (!NT_STATUS_IS_OK(status)) { DEBUG(0,("smb2srv_tcon_backend: NTVFS ntvfs_connect() failed!\n")); goto failed; @@ -279,7 +281,6 @@ static void smb2srv_tcon_send(struct smb2srv_request *req, union smb_tcon *io) smb2srv_send_error(req, req->status); return; } - if (io->smb2.out.unknown1 == 0x0002) { /* if it's an IPC share vista returns 0x0005 */ unknown1 = 0x0005; diff --git a/source4/smb_server/smb_server.c b/source4/smb_server/smb_server.c index 6df48f3df6..56ca686baf 100644 --- a/source4/smb_server/smb_server.c +++ b/source4/smb_server/smb_server.c @@ -31,6 +31,7 @@ #include "smb_server/smb2/smb2_server.h" #include "system/network.h" #include "netif/netif.h" +#include "param/share.h" static NTSTATUS smbsrv_recv_generic_request(void *private, DATA_BLOB blob) { @@ -155,6 +156,11 @@ static void smbsrv_accept(struct stream_connection *conn) smb_conn->statistics.connect_time = timeval_current(); smbsrv_management_init(smb_conn); + + if (!NT_STATUS_IS_OK(share_get_context(smb_conn, &(smb_conn->share_context)))) { + smbsrv_terminate_connection(smb_conn, "share_init failed!"); + return; + } } static const struct stream_server_ops smb_stream_ops = { diff --git a/source4/smb_server/smb_server.h b/source4/smb_server/smb_server.h index 9acf181c54..edd9deeafb 100644 --- a/source4/smb_server/smb_server.h +++ b/source4/smb_server/smb_server.h @@ -372,6 +372,8 @@ struct smbsrv_connection { /* the time when the last request comes in */ struct timeval last_request_time; } statistics; + + struct share_context *share_context; }; #include "smb_server/smb_server_proto.h" diff --git a/source4/smbd/server.c b/source4/smbd/server.c index c510c3cf29..62e55360fe 100644 --- a/source4/smbd/server.c +++ b/source4/smbd/server.c @@ -239,6 +239,8 @@ static int binary_smbd_main(const char *binary_name, int argc, const char *argv[ ldb_global_init(); /* FIXME: */ + share_init(); + gensec_init(); /* FIXME: */ registry_init(); /* FIXME: maybe run this in the initialization function -- cgit