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 | |
| 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)
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  | 
