r23792: convert Samba4 to GPLv3
[ira/wip.git] / source4 / lib / registry / reg_backend_rpc.c
index 16516d25b70feac7c1c3aeaa7d26a7c07cfd1149..dc6a2d86f160c2df9f606bcff5fd5e4e37f3b524 100644 (file)
@@ -5,7 +5,7 @@
 
    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
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
    
    This program is distributed in the hope that it will be useful,
    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.  */
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
  
 #include "includes.h"
 #include "registry.h"
-#include "librpc/gen_ndr/ndr_winreg.h"
+#include "librpc/gen_ndr/ndr_winreg_c.h"
 
 static struct hive_operations reg_backend_rpc;
 
@@ -29,27 +28,17 @@ static struct hive_operations reg_backend_rpc;
 
 static void init_winreg_String(struct winreg_String *name, const char *s)
 {
-    name->name = s;
-    if (s) {
-        name->name_len = 2 * (strlen_m(s) + 1);
-        name->name_size = name->name_len;
-    } else {
-        name->name_len = 0;
-        name->name_size = 0;
-    }
+       name->name = s;
 }
 
 
 #define openhive(u) static WERROR open_ ## u(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, struct policy_handle *hnd) \
 { \
        struct winreg_Open ## u r; \
-       struct winreg_OpenUnknown unknown; \
        NTSTATUS status; \
        \
-       unknown.unknown0 = 0x84e0; \
-       unknown.unknown1 = 0x0000; \
-       r.in.unknown = &unknown; \
-       r.in.access_required = SEC_FLAG_MAXIMUM_ALLOWED; \
+       r.in.system_name = NULL; \
+       r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; \
        r.out.handle = hnd;\
        \
        status = dcerpc_winreg_Open ## u(p, mem_ctx, &r); \
@@ -77,8 +66,8 @@ struct rpc_key_data {
        int max_valdatalen;
 };
 
-struct {
-       uint32 hkey;
+static struct {
+       uint32_t hkey;
        WERROR (*open) (struct dcerpc_pipe *p, TALLOC_CTX *, struct policy_handle *h);
 } known_hives[] = {
 { HKEY_LOCAL_MACHINE, open_HKLM },
@@ -91,9 +80,9 @@ struct {
 { 0, NULL }
 };
 
-static WERROR rpc_query_key(struct registry_key *k);
+static WERROR rpc_query_key(const struct registry_key *k);
 
-static WERROR rpc_get_predefined_key (struct registry_context *ctx, uint32 hkey_type, struct registry_key **k)
+static WERROR rpc_get_predefined_key (struct registry_context *ctx, uint32_t hkey_type, struct registry_key **k)
 {
        int n;
        struct registry_hive *h;
@@ -109,33 +98,26 @@ static WERROR rpc_get_predefined_key (struct registry_context *ctx, uint32 hkey_
                return WERR_NO_MORE_ITEMS;
        }
 
-       h = talloc_p(ctx, struct registry_hive);
+       h = talloc(ctx, struct registry_hive);
        h->functions = &reg_backend_rpc;
        h->location = NULL;
        h->backend_data = ctx->backend_data;
        
-       (*k) = h->root = talloc_p(h, struct registry_key);
+       (*k) = h->root = talloc(h, struct registry_key);
        (*k)->hive = h;
-       (*k)->backend_data = mykeydata = talloc_p(*k, struct rpc_key_data);
+       (*k)->backend_data = mykeydata = talloc(*k, struct rpc_key_data);
        mykeydata->num_values = -1;
        mykeydata->num_subkeys = -1;
        return known_hives[n].open((struct dcerpc_pipe *)ctx->backend_data, *k, &(mykeydata->pol));
 }
 
-static int rpc_close (void *_h)
-{
-       struct registry_context *h = _h;
-       dcerpc_pipe_close(h->backend_data);
-       return 0;
-}
-
 #if 0
 static WERROR rpc_key_put_rpc_data(TALLOC_CTX *mem_ctx, struct registry_key *k)
 {
     struct winreg_OpenKey r;
        struct rpc_key_data *mykeydata;
 
-       k->backend_data = mykeydata = talloc_p(mem_ctx, struct rpc_key_data);
+       k->backend_data = mykeydata = talloc(mem_ctx, struct rpc_key_data);
        mykeydata->num_values = -1;
        mykeydata->num_subkeys = -1;
 
@@ -154,22 +136,22 @@ static WERROR rpc_key_put_rpc_data(TALLOC_CTX *mem_ctx, struct registry_key *k)
 }
 #endif
 
-static WERROR rpc_open_key(TALLOC_CTX *mem_ctx, struct registry_key *h, const char *name, struct registry_key **key)
+static WERROR rpc_open_key(TALLOC_CTX *mem_ctx, const struct registry_key *h, const char *name, struct registry_key **key)
 {
        struct rpc_key_data *mykeydata;
     struct winreg_OpenKey r;
 
-       *key = talloc_p(mem_ctx, struct registry_key);
+       *key = talloc(mem_ctx, struct registry_key);
        (*key)->name = talloc_strdup(mem_ctx, name);
 
-       (*key)->backend_data = mykeydata = talloc_p(mem_ctx, struct rpc_key_data);
+       (*key)->backend_data = mykeydata = talloc(mem_ctx, struct rpc_key_data);
        mykeydata->num_values = -1;
        mykeydata->num_subkeys = -1;
 
        /* Then, open the handle using the hive */
 
        memset(&r, 0, sizeof(struct winreg_OpenKey));
-    r.in.handle = &(((struct rpc_key_data *)h->backend_data)->pol);
+    r.in.parent_handle = &(((struct rpc_key_data *)h->backend_data)->pol);
     init_winreg_String(&r.in.keyname, name);
     r.in.unknown = 0x00000000;
     r.in.access_mask = 0x02000000;
@@ -180,15 +162,16 @@ static WERROR rpc_open_key(TALLOC_CTX *mem_ctx, struct registry_key *h, const ch
        return r.out.result;
 }
 
-static WERROR rpc_get_value_by_index(TALLOC_CTX *mem_ctx, struct registry_key *parent, int n, struct registry_value **value)  
+static WERROR rpc_get_value_by_index(TALLOC_CTX *mem_ctx, const struct registry_key *parent, int n, struct registry_value **value)  
 {
        struct rpc_key_data *mykeydata = parent->backend_data;
        WERROR error;
        struct winreg_EnumValue r;
-       uint32 type, len1, zero = 0;
+       uint32_t len1, zero = 0;
+       enum winreg_Type type;
        NTSTATUS status;
-       uint8_t buf8;
-       uint16_t buf16;
+       struct winreg_StringBuf name;
+       uint8_t u8;
        
        if(mykeydata->num_values == -1) {
                error = rpc_query_key(parent);
@@ -197,17 +180,18 @@ static WERROR rpc_get_value_by_index(TALLOC_CTX *mem_ctx, struct registry_key *p
 
        len1 = mykeydata->max_valdatalen;
        
+       name.length = 0;
+       name.size   = mykeydata->max_valnamelen * 2;
+       name.name   = "";
+
        r.in.handle = &mykeydata->pol;
        r.in.enum_index = n;
-       r.in.name_in.length = 0;
-       r.in.name_in.size = mykeydata->max_valnamelen * 2;
-       r.in.name_in.name = &buf16;
+       r.in.name = &name;
        r.in.type = &type;
-       r.in.value = &buf8;
+       r.in.value = &u8;
        r.in.length = &zero;
        r.in.size = &len1;
-       r.out.type = &type;
-
+       r.out.name = &name;
        
        status = dcerpc_winreg_EnumValue((struct dcerpc_pipe *)parent->hive->backend_data, mem_ctx, &r);
        if(NT_STATUS_IS_ERR(status)) {
@@ -217,63 +201,90 @@ static WERROR rpc_get_value_by_index(TALLOC_CTX *mem_ctx, struct registry_key *p
        
        if(NT_STATUS_IS_OK(status) && 
           W_ERROR_IS_OK(r.out.result) && r.out.length) {
-               *value = talloc_p(mem_ctx, struct registry_value);
-               (*value)->name = talloc_strdup(mem_ctx, r.out.name_out.name);
+               *value = talloc(mem_ctx, struct registry_value);
+               (*value)->name = talloc_strdup(mem_ctx, r.out.name->name);
                (*value)->data_type = type;
-               (*value)->data_len = *r.out.length;
-               (*value)->data_blk = talloc_memdup(mem_ctx, r.out.value, *r.out.length);
+               (*value)->data = data_blob_talloc(mem_ctx, r.out.value, *r.out.length);
                return WERR_OK;
        }
        
        return r.out.result;
 }
 
-static WERROR rpc_get_subkey_by_index(TALLOC_CTX *mem_ctx, struct registry_key *parent, int n, struct registry_key **subkey) 
+static WERROR rpc_get_subkey_by_index(TALLOC_CTX *mem_ctx, const struct registry_key *parent, int n, struct registry_key **subkey) 
 {
        struct winreg_EnumKey r;
-       struct winreg_EnumKeyNameRequest keyname;
-       struct winreg_String classname;
-       struct winreg_Time tm;
        struct rpc_key_data *mykeydata = parent->backend_data;
        NTSTATUS status;
+       struct winreg_StringBuf namebuf, classbuf;
+       NTTIME change_time = 0;
 
-       r.in.handle = &mykeydata->pol;
-       keyname.unknown = 0x0000020a;
-       init_winreg_String(&keyname.key_name, NULL);
-       init_winreg_String(&classname, NULL);
-       r.in.in_name = &keyname;
-       r.in.class = &classname;
-       tm.low = tm.high = 0x7fffffff;
-       r.in.last_changed_time = &tm;
+       namebuf.length = 0;
+       namebuf.size   = 1024;
+       namebuf.name   = NULL;
+       classbuf.length = 0;
+       classbuf.size   = 0;
+       classbuf.name   = NULL;
 
+       r.in.handle = &mykeydata->pol;
        r.in.enum_index = n;
-       r.in.unknown = r.out.unknown = 0x0414;
-       r.in.key_name_len = r.out.key_name_len = 0;
+       r.in.name = &namebuf;
+       r.in.keyclass = &classbuf;
+       r.in.last_changed_time = &change_time;
+       r.out.name = &namebuf;
+
        status = dcerpc_winreg_EnumKey((struct dcerpc_pipe *)parent->hive->backend_data, mem_ctx, &r);
        if(NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(r.out.result)) {
-                       return rpc_open_key(mem_ctx, parent, talloc_strdup(mem_ctx, r.out.out_name->name), subkey);
+               char *name = talloc_strdup(mem_ctx, r.out.name->name);
+               return rpc_open_key(mem_ctx, parent, name, subkey);
        }
 
        return r.out.result;
 }
 
-static WERROR rpc_add_key(TALLOC_CTX *mem_ctx, struct registry_key *parent, const char *name, uint32_t access_mask, SEC_DESC *sec, struct registry_key **key)
+static WERROR rpc_add_key(TALLOC_CTX *mem_ctx, const struct registry_key *parent, const char *name, uint32_t access_mask, struct security_descriptor *sec, struct registry_key **key)
 {
-       return WERR_NOT_SUPPORTED;
+       NTSTATUS status;
+       struct winreg_CreateKey r;
+
+       init_winreg_String(&r.in.name, name);
+       init_winreg_String(&r.in.keyclass, NULL);
+
+       r.in.handle = parent->backend_data;
+       r.out.new_handle = talloc(mem_ctx, struct policy_handle);       
+       r.in.options = 0;
+       r.in.access_mask = access_mask;
+       r.in.secdesc = NULL;
+
+       status = dcerpc_winreg_CreateKey((struct dcerpc_pipe *)(parent->hive->backend_data), mem_ctx, &r);
+
+    if (!NT_STATUS_IS_OK(status)) {
+        DEBUG(1, ("CreateKey failed - %s\n", nt_errstr(status)));
+        return ntstatus_to_werror(status);
+    }
+
+       if (W_ERROR_IS_OK(r.out.result)) {
+               *key = talloc(mem_ctx, struct registry_key);
+               (*key)->name = talloc_strdup(*key, name);
+               (*key)->backend_data = r.out.new_handle;
+       }
+
+       return r.out.result;
 }
 
-static WERROR rpc_query_key(struct registry_key *k)
+static WERROR rpc_query_key(const struct registry_key *k)
 {
     NTSTATUS status;
     struct winreg_QueryInfoKey r;
     struct rpc_key_data *mykeydata = k->backend_data;
        TALLOC_CTX *mem_ctx = talloc_init("query_key");
 
-    init_winreg_String(&r.in.class, NULL);
+       r.in.classname = talloc(mem_ctx, struct winreg_String);
+    init_winreg_String(r.in.classname, NULL);
     r.in.handle = &mykeydata->pol;
        
     status = dcerpc_winreg_QueryInfoKey((struct dcerpc_pipe *)(k->hive->backend_data), mem_ctx, &r);
-       talloc_destroy(mem_ctx);
+       talloc_free(mem_ctx);
 
     if (!NT_STATUS_IS_OK(status)) {
         DEBUG(1, ("QueryInfoKey failed - %s\n", nt_errstr(status)));
@@ -281,43 +292,34 @@ static WERROR rpc_query_key(struct registry_key *k)
     }
                                                                                                        
     if (W_ERROR_IS_OK(r.out.result)) {
-               mykeydata->num_subkeys = r.out.num_subkeys;
-               mykeydata->num_values = r.out.num_values;
-               mykeydata->max_valnamelen = r.out.max_valnamelen;
-               mykeydata->max_valdatalen = r.out.max_valbufsize;
+               mykeydata->num_subkeys = *r.out.num_subkeys;
+               mykeydata->num_values = *r.out.num_values;
+               mykeydata->max_valnamelen = *r.out.max_valnamelen;
+               mykeydata->max_valdatalen = *r.out.max_valbufsize;
        } 
 
        return r.out.result;
 }
 
-static WERROR rpc_del_key(struct registry_key *k)
+static WERROR rpc_del_key(const struct registry_key *parent, const char *name)
 {
        NTSTATUS status;
-       struct rpc_key_data *mykeydata = k->backend_data;
+       struct rpc_key_data *mykeydata = parent->backend_data;
        struct winreg_DeleteKey r;
-       struct registry_key *parent;
-       WERROR error;
        TALLOC_CTX *mem_ctx = talloc_init("del_key");
        
-       error = reg_key_get_parent(mem_ctx, k, &parent);
-       if(!W_ERROR_IS_OK(error)) { 
-               talloc_destroy(mem_ctx); 
-               return error; 
-       }
-
-       mykeydata = parent->backend_data;
-
     r.in.handle = &mykeydata->pol;
-    init_winreg_String(&r.in.key, k->name);
+    init_winreg_String(&r.in.key, name);
  
-    status = dcerpc_winreg_DeleteKey((struct dcerpc_pipe *)k->hive->backend_data, mem_ctx, &r);
+    status = dcerpc_winreg_DeleteKey((struct dcerpc_pipe *)parent->hive->backend_data, mem_ctx, &r);
 
-       talloc_destroy(mem_ctx);
+       talloc_free(mem_ctx);
 
        return r.out.result;
 }
 
-static WERROR rpc_num_values(struct registry_key *key, int *count) {
+static WERROR rpc_num_values(const struct registry_key *key, uint32_t *count) 
+{
        struct rpc_key_data *mykeydata = key->backend_data;
        WERROR error;
                
@@ -330,7 +332,8 @@ static WERROR rpc_num_values(struct registry_key *key, int *count) {
        return WERR_OK;
 }
 
-static WERROR rpc_num_subkeys(struct registry_key *key, int *count) {
+static WERROR rpc_num_subkeys(const struct registry_key *key, uint32_t *count) 
+{
        struct rpc_key_data *mykeydata = key->backend_data;
        WERROR error;
 
@@ -354,38 +357,39 @@ static struct hive_operations reg_backend_rpc = {
        .num_values = rpc_num_values,
 };
 
-WERROR reg_open_remote (struct registry_context **ctx, const char *user, const char *pass, const char *location)
+_PUBLIC_ WERROR reg_open_remote(struct registry_context **ctx, struct auth_session_info *session_info, struct cli_credentials *credentials, 
+                      const char *location, struct event_context *ev)
 {
        NTSTATUS status;
        struct dcerpc_pipe *p;
 
-       *ctx = talloc_p(NULL, struct registry_context);
+       *ctx = talloc(NULL, struct registry_context);
 
        /* Default to local smbd if no connection is specified */
        if (!location) {
                location = talloc_strdup(ctx, "ncalrpc:");
        }
 
-       status = dcerpc_pipe_connect(&p, location, 
-                                    DCERPC_WINREG_UUID,
-                                    DCERPC_WINREG_VERSION,
-                                    lp_workgroup(),
-                                    user, pass);
+       status = dcerpc_pipe_connect(*ctx /* TALLOC_CTX */, 
+                                    &p, location, 
+                                        &dcerpc_table_winreg,
+                                    credentials, ev);
        (*ctx)->backend_data = p;
 
        if(NT_STATUS_IS_ERR(status)) {
                DEBUG(1, ("Unable to open '%s': %s\n", location, nt_errstr(status)));
+               talloc_free(*ctx);
+               *ctx = NULL;
                return ntstatus_to_werror(status);
        }
 
        (*ctx)->get_predefined_key = rpc_get_predefined_key;
 
-       talloc_set_destructor(*ctx, rpc_close);
-
        return WERR_OK;
 }
 
 NTSTATUS registry_rpc_init(void)
 {
+       dcerpc_init();
        return registry_register(&reg_backend_rpc);
 }