r18542: Some late nite work.
authorSimo Sorce <idra@samba.org>
Fri, 15 Sep 2006 05:18:53 +0000 (05:18 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 19:18:44 +0000 (14:18 -0500)
Now we can add and remove a share from the "Computer Management"
console (not yet modify!) usinf share backend = ldb
(This used to be commit ae2f6d4a5a372a37b9783a02bb8e7f16588b21f0)

source4/param/share.c
source4/param/share.h
source4/param/share_classic.c
source4/param/share_ldb.c
source4/rpc_server/srvsvc/dcesrv_srvsvc.c

index a87fe38f8e165aea4835ec1154e1b6292daaab64..c27619b11b2c623deaaadae45bd2eacdb907acdf 100644 (file)
@@ -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;
 
index af5bd0ebbaa34061017c7e7924fce7050f0ce908..ca3accd4ef68ed6253e207fee4ff36b56a2eea52 100644 (file)
@@ -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"
 
index 59c58e4d54131393d57bb2ab8a368976a2bd65b8..75f66b1fd43a12dbcc9908dcadbc4f4c75a98a04 100644 (file)
@@ -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);
 }
index 8349ad7fe55f176fc7ecf6f454ae90d29c85a394..2fd43c04a7fd6c1f55006cdf035d86dee5ce2613 100644 (file)
@@ -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);
 }
index 2464da447afb92349daaaec0ebeecc5b910c52da..68ab1498c2d2fe55a0c9bab9f1cd08b8a9c59a3e 100644 (file)
@@ -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;
 }
 
 /*