diff options
author | Simo Sorce <idra@samba.org> | 2006-07-23 18:43:07 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 14:10:18 -0500 |
commit | 9c66f601f1520a99b9236c32bc9f03a33bd4b2aa (patch) | |
tree | bba8797304b7db98aa205c3cb04344072be00030 /source4 | |
parent | 2dc38416b65177aca94b4de3c9cfcb5c8edb0df2 (diff) | |
download | samba-9c66f601f1520a99b9236c32bc9f03a33bd4b2aa.tar.gz samba-9c66f601f1520a99b9236c32bc9f03a33bd4b2aa.tar.bz2 samba-9c66f601f1520a99b9236c32bc9f03a33bd4b2aa.zip |
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)
Diffstat (limited to 'source4')
30 files changed, 1005 insertions, 230 deletions
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;i<r->out.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 |