1
0
mirror of https://github.com/samba-team/samba.git synced 2025-03-25 14:50:24 +03:00

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)
This commit is contained in:
Simo Sorce 2006-07-23 18:43:07 +00:00 committed by Gerald (Jerry) Carter
parent 2dc38416b6
commit 9c66f601f1
30 changed files with 1015 additions and 240 deletions

@ -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;
}

@ -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;

@ -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
################################################

@ -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;
}

@ -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;
}

@ -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;

@ -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;

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

@ -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_ */

@ -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;
}

@ -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;

@ -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;

@ -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,

@ -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
################################################

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

137
source4/param/share.c Normal file

@ -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;
}

105
source4/param/share.h Normal file

@ -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 */

@ -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);
}

@ -60,4 +60,5 @@
struct dcesrv_context;
#include "param/share.h"
#include "rpc_server/common/proto.h"

@ -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)
{
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)
{
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)
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, 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, struct share_config *scfg)
{
return NULL;
}

@ -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
################################################

@ -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;

@ -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;
snum = lp_find_valid_service(share);
if (snum == -1) {
status = share_get_context(mem_ctx, &sctx);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
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;

@ -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");

@ -18,6 +18,7 @@ OBJ_FILES = \
management.o
PRIVATE_PROTO_HEADER = smb_server_proto.h
PUBLIC_DEPENDENCIES = \
share \
LIBPACKET \
SMB_PROTOCOL \
SMB2_PROTOCOL

@ -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;
}

@ -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;

@ -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 = {

@ -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"

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