mirror of
https://github.com/samba-team/samba.git
synced 2024-12-23 17:34:34 +03:00
r18542: Some late nite work.
Now we can add and remove a share from the "Computer Management" console (not yet modify!) usinf share backend = ldb
This commit is contained in:
parent
ce5d5a1872
commit
ae2f6d4a5a
@ -54,6 +54,22 @@ NTSTATUS share_get_config(TALLOC_CTX *mem_ctx, struct share_context *sctx, const
|
||||
return sctx->ops->get_config(mem_ctx, sctx, name, scfg);
|
||||
}
|
||||
|
||||
NTSTATUS share_create(struct share_context *sctx, struct share_info *info)
|
||||
{
|
||||
if (sctx->ops->create) {
|
||||
return sctx->ops->create(sctx, info);
|
||||
}
|
||||
return NT_STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NTSTATUS share_remove(struct share_context *sctx, const char *name)
|
||||
{
|
||||
if (sctx->ops->remove) {
|
||||
return sctx->ops->remove(sctx, name);
|
||||
}
|
||||
return NT_STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
/* List of currently available share backends */
|
||||
static struct share_ops **backends = NULL;
|
||||
|
||||
|
@ -36,6 +36,16 @@ struct share_config {
|
||||
void *opaque;
|
||||
};
|
||||
|
||||
struct share_info {
|
||||
const char *name;
|
||||
const char *type;
|
||||
const char *path;
|
||||
const char *comment;
|
||||
const char *password;
|
||||
int32_t max_users;
|
||||
struct security_descriptor *sd;
|
||||
};
|
||||
|
||||
struct share_ops {
|
||||
const char *name;
|
||||
NTSTATUS (*init)(TALLOC_CTX *, const struct share_ops*, struct share_context **);
|
||||
@ -45,8 +55,8 @@ struct share_ops {
|
||||
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 *);
|
||||
NTSTATUS (*create)(struct share_context *, struct share_info *);
|
||||
NTSTATUS (*remove)(struct share_context *, const char *);
|
||||
};
|
||||
|
||||
#include "param/share_proto.h"
|
||||
@ -56,14 +66,14 @@ struct share_ops {
|
||||
#define SHARE_NAME "name"
|
||||
#define SHARE_PATH "path"
|
||||
#define SHARE_COMMENT "comment"
|
||||
#define SHARE_PASSWORD "password"
|
||||
#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_AVAILABLE "available"
|
||||
#define SHARE_BROWSEABLE "browseable"
|
||||
#define SHARE_MAX_CONNECTIONS "max-connections"
|
||||
|
||||
|
@ -312,16 +312,16 @@ NTSTATUS sclassic_get_config(TALLOC_CTX *mem_ctx,
|
||||
|
||||
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;
|
||||
static struct share_ops ops = {
|
||||
.name = "classic",
|
||||
.init = sclassic_init,
|
||||
.string_option = sclassic_string_option,
|
||||
.int_option = sclassic_int_option,
|
||||
.bool_option = sclassic_bool_option,
|
||||
.string_list_option = sclassic_string_list_option,
|
||||
.list_all = sclassic_list_all,
|
||||
.get_config = sclassic_get_config
|
||||
};
|
||||
|
||||
return share_register(&ops);
|
||||
}
|
||||
|
@ -263,18 +263,141 @@ static NTSTATUS sldb_get_config(TALLOC_CTX *mem_ctx,
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
#define SHARE_ADD_STRING(type, data) do { \
|
||||
err = ldb_msg_add_string(msg, type, data); \
|
||||
if (err != LDB_SUCCESS) { \
|
||||
DEBUG(2,("ERROR: unable to add share %s to ldb msg\n", type)); \
|
||||
ret = NT_STATUS_UNSUCCESSFUL; \
|
||||
goto done; \
|
||||
} } while(0)
|
||||
|
||||
NTSTATUS sldb_create(struct share_context *ctx, struct share_info *info)
|
||||
{
|
||||
struct ldb_context *ldb;
|
||||
struct ldb_message *msg;
|
||||
TALLOC_CTX *tmp_ctx;
|
||||
NTSTATUS ret;
|
||||
char *conns;
|
||||
int err;
|
||||
|
||||
if (!info->name || !info->type || !info->path) {
|
||||
return NT_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
tmp_ctx = talloc_new(NULL);
|
||||
if (!tmp_ctx) {
|
||||
DEBUG(0,("ERROR: Out of memory!\n"));
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
ldb = talloc_get_type(ctx->priv_data, struct ldb_context);
|
||||
|
||||
msg = ldb_msg_new(tmp_ctx);
|
||||
if (!msg) {
|
||||
DEBUG(0,("ERROR: Out of memory!\n"));
|
||||
ret = NT_STATUS_NO_MEMORY;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* TODO: escape info->name */
|
||||
msg->dn = ldb_dn_string_compose(tmp_ctx, ldb_dn_new(tmp_ctx), "CN=%s,CN=SHARES", info->name);
|
||||
if (!msg->dn) {
|
||||
DEBUG(0,("ERROR: Out of memory!\n"));
|
||||
ret = NT_STATUS_NO_MEMORY;
|
||||
goto done;
|
||||
}
|
||||
|
||||
SHARE_ADD_STRING("cn", info->name);
|
||||
SHARE_ADD_STRING("objectClass", "top");
|
||||
SHARE_ADD_STRING("objectClass", "share");
|
||||
|
||||
SHARE_ADD_STRING(SHARE_NAME, info->name);
|
||||
SHARE_ADD_STRING(SHARE_TYPE, info->type);
|
||||
SHARE_ADD_STRING(SHARE_PATH, info->path);
|
||||
if (strcmp(info->type, "DISK") == 0) {
|
||||
SHARE_ADD_STRING(SHARE_NTVFS_HANDLER, "default");
|
||||
}
|
||||
if (info->comment) {
|
||||
SHARE_ADD_STRING(SHARE_COMMENT, info->comment);
|
||||
}
|
||||
|
||||
if (info->password) {
|
||||
SHARE_ADD_STRING(SHARE_PASSWORD, info->password);
|
||||
}
|
||||
|
||||
/* TODO: Security Descriptor */
|
||||
|
||||
SHARE_ADD_STRING(SHARE_AVAILABLE, "True");
|
||||
SHARE_ADD_STRING(SHARE_BROWSEABLE, "True");
|
||||
SHARE_ADD_STRING(SHARE_READONLY, "False");
|
||||
conns = talloc_asprintf(tmp_ctx, "%d", info->max_users);
|
||||
SHARE_ADD_STRING(SHARE_MAX_CONNECTIONS, conns);
|
||||
|
||||
err = ldb_add(ldb, msg);
|
||||
if (err != LDB_SUCCESS) {
|
||||
DEBUG(2,("ERROR: unable to add share %s to share.ldb\n"
|
||||
" err=%d [%s]\n", info->name, err, ldb_errstring(ldb)));
|
||||
ret = NT_STATUS_UNSUCCESSFUL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
ret = NT_STATUS_OK;
|
||||
done:
|
||||
talloc_free(tmp_ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
NTSTATUS sldb_remove(struct share_context *ctx, const char *name)
|
||||
{
|
||||
struct ldb_context *ldb;
|
||||
struct ldb_dn *dn;
|
||||
TALLOC_CTX *tmp_ctx;
|
||||
NTSTATUS ret;
|
||||
int err;
|
||||
|
||||
tmp_ctx = talloc_new(NULL);
|
||||
if (!tmp_ctx) {
|
||||
DEBUG(0,("ERROR: Out of memory!\n"));
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
ldb = talloc_get_type(ctx->priv_data, struct ldb_context);
|
||||
|
||||
dn = ldb_dn_string_compose(tmp_ctx, ldb_dn_new(tmp_ctx), "CN=%s,CN=SHARES", name);
|
||||
if (!dn) {
|
||||
DEBUG(0,("ERROR: Out of memory!\n"));
|
||||
ret = NT_STATUS_NO_MEMORY;
|
||||
goto done;
|
||||
}
|
||||
|
||||
err = ldb_delete(ldb, dn);
|
||||
if (err != LDB_SUCCESS) {
|
||||
DEBUG(2,("ERROR: unable to remove share %s from share.ldb\n"
|
||||
" err=%d [%s]\n", name, err, ldb_errstring(ldb)));
|
||||
ret = NT_STATUS_UNSUCCESSFUL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
ret = NT_STATUS_OK;
|
||||
done:
|
||||
talloc_free(tmp_ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
NTSTATUS share_ldb_init(void)
|
||||
{
|
||||
struct share_ops ops;
|
||||
|
||||
ops.name = "ldb";
|
||||
ops.init = sldb_init;
|
||||
ops.string_option = sldb_string_option;
|
||||
ops.int_option = sldb_int_option;
|
||||
ops.bool_option = sldb_bool_option;
|
||||
ops.string_list_option = sldb_string_list_option;
|
||||
ops.list_all = sldb_list_all;
|
||||
ops.get_config = sldb_get_config;
|
||||
static struct share_ops ops = {
|
||||
.name = "ldb",
|
||||
.init = sldb_init,
|
||||
.string_option = sldb_string_option,
|
||||
.int_option = sldb_int_option,
|
||||
.bool_option = sldb_bool_option,
|
||||
.string_list_option = sldb_string_list_option,
|
||||
.list_all = sldb_list_all,
|
||||
.get_config = sldb_get_config,
|
||||
.create = sldb_create,
|
||||
.remove = sldb_remove
|
||||
};
|
||||
|
||||
return share_register(&ops);
|
||||
}
|
||||
|
@ -452,10 +452,68 @@ static WERROR srvsvc_NetShareAdd(struct dcesrv_call_state *dce_call, TALLOC_CTX
|
||||
}
|
||||
case 502:
|
||||
{
|
||||
NTSTATUS nterr;
|
||||
struct share_info *info;
|
||||
struct share_context *sctx;
|
||||
|
||||
nterr = share_get_context(mem_ctx, &sctx);
|
||||
if (!NT_STATUS_IS_OK(nterr)) {
|
||||
return ntstatus_to_werror(nterr);
|
||||
}
|
||||
|
||||
info = talloc_zero(mem_ctx, struct share_info);
|
||||
W_ERROR_HAVE_NO_MEMORY(info);
|
||||
|
||||
info->name = talloc_strdup(info, r->in.info.info502->name);
|
||||
W_ERROR_HAVE_NO_MEMORY(info->name);
|
||||
switch (r->in.info.info502->type) {
|
||||
case 0x00:
|
||||
info->type = talloc_strdup(mem_ctx, "DISK");
|
||||
break;
|
||||
case 0x01:
|
||||
info->type = talloc_strdup(mem_ctx, "PRINTER");
|
||||
break;
|
||||
case 0x03:
|
||||
info->type = talloc_strdup(mem_ctx, "IPC");
|
||||
break;
|
||||
default:
|
||||
return WERR_INVALID_PARAM;
|
||||
}
|
||||
W_ERROR_HAVE_NO_MEMORY(info->type);
|
||||
|
||||
/* Windows will send a path in a form of C:\example\path */
|
||||
if (r->in.info.info502->path[1] == ':') {
|
||||
info->path = talloc_strdup(info, &r->in.info.info502->path[2]);
|
||||
} else {
|
||||
info->path = talloc_strdup(info, r->in.info.info502->path);
|
||||
}
|
||||
W_ERROR_HAVE_NO_MEMORY(info->path);
|
||||
all_string_sub(info->path, "\\", "/", 0);
|
||||
|
||||
if (r->in.info.info502->comment && r->in.info.info502->comment[0]) {
|
||||
info->comment = talloc_strdup(info, r->in.info.info502->comment);
|
||||
W_ERROR_HAVE_NO_MEMORY(info->comment);
|
||||
}
|
||||
|
||||
if (r->in.info.info502->password && r->in.info.info502->password[0]) {
|
||||
info->password = talloc_strdup(info, r->in.info.info502->password);
|
||||
W_ERROR_HAVE_NO_MEMORY(info->password);
|
||||
}
|
||||
|
||||
info->max_users = r->in.info.info502->max_users;
|
||||
/* TODO: security descriptor */
|
||||
|
||||
|
||||
nterr = share_create(sctx, info);
|
||||
if (!NT_STATUS_IS_OK(nterr)) {
|
||||
return ntstatus_to_werror(nterr);
|
||||
}
|
||||
|
||||
if (r->in.parm_error) {
|
||||
r->out.parm_error = r->in.parm_error;
|
||||
}
|
||||
return WERR_NOT_SUPPORTED;
|
||||
|
||||
return WERR_OK;
|
||||
}
|
||||
default:
|
||||
return WERR_UNKNOWN_LEVEL;
|
||||
@ -1808,7 +1866,20 @@ static WERROR srvsvc_NETRSERVERTRANSPORTDELEX(struct dcesrv_call_state *dce_call
|
||||
static WERROR srvsvc_NetShareDel(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
|
||||
struct srvsvc_NetShareDel *r)
|
||||
{
|
||||
DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
|
||||
NTSTATUS nterr;
|
||||
struct share_context *sctx;
|
||||
|
||||
nterr = share_get_context(mem_ctx, &sctx);
|
||||
if (!NT_STATUS_IS_OK(nterr)) {
|
||||
return ntstatus_to_werror(nterr);
|
||||
}
|
||||
|
||||
nterr = share_remove(sctx, r->in.share_name);
|
||||
if (!NT_STATUS_IS_OK(nterr)) {
|
||||
return ntstatus_to_werror(nterr);
|
||||
}
|
||||
|
||||
return WERR_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user