summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimo Sorce <idra@samba.org>2006-07-23 18:43:07 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 14:10:18 -0500
commit9c66f601f1520a99b9236c32bc9f03a33bd4b2aa (patch)
treebba8797304b7db98aa205c3cb04344072be00030
parent2dc38416b65177aca94b4de3c9cfcb5c8edb0df2 (diff)
downloadsamba-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)
-rw-r--r--source4/ntvfs/cifs/vfs_cifs.c33
-rw-r--r--source4/ntvfs/cifs_posix_cli/vfs_simple.c9
-rw-r--r--source4/ntvfs/common/config.mk2
-rw-r--r--source4/ntvfs/common/notify.c10
-rw-r--r--source4/ntvfs/ipc/rap_server.c41
-rw-r--r--source4/ntvfs/ntvfs.h5
-rw-r--r--source4/ntvfs/ntvfs_base.c7
-rw-r--r--source4/ntvfs/posix/vfs_posix.c51
-rw-r--r--source4/ntvfs/posix/vfs_posix.h13
-rw-r--r--source4/ntvfs/print/vfs_print.c3
-rw-r--r--source4/ntvfs/simple/vfs_simple.c10
-rw-r--r--source4/ntvfs/sysdep/sys_notify.c6
-rw-r--r--source4/ntvfs/sysdep/sys_notify.h3
-rw-r--r--source4/param/config.mk23
-rw-r--r--source4/param/loadparm.c8
-rw-r--r--source4/param/share.c137
-rw-r--r--source4/param/share.h105
-rw-r--r--source4/param/share_classic.c328
-rw-r--r--source4/rpc_server/common/common.h1
-rw-r--r--source4/rpc_server/common/share_info.c64
-rw-r--r--source4/rpc_server/config.mk2
-rw-r--r--source4/rpc_server/srvsvc/dcesrv_srvsvc.c238
-rw-r--r--source4/rpc_server/srvsvc/srvsvc_ntvfs.c34
-rw-r--r--source4/scripting/libjs/provision.js7
-rw-r--r--source4/smb_server/config.mk1
-rw-r--r--source4/smb_server/smb/service.c57
-rw-r--r--source4/smb_server/smb2/tcon.c27
-rw-r--r--source4/smb_server/smb_server.c6
-rw-r--r--source4/smb_server/smb_server.h2
-rw-r--r--source4/smbd/server.c2
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