root/source4/lib/registry/rpc.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. openhive
  2. rpc_get_predefined_key
  3. rpc_key_put_rpc_data
  4. rpc_open_key
  5. rpc_get_value_by_index
  6. rpc_get_value_by_name
  7. rpc_get_subkey_by_index
  8. rpc_add_key
  9. rpc_query_key
  10. rpc_del_key
  11. rpc_get_info
  12. reg_open_remote

   1 /*
   2    Samba Unix/Linux SMB implementation
   3    RPC backend for the registry library
   4    Copyright (C) 2003-2007 Jelmer Vernooij, jelmer@samba.org
   5    Copyright (C) 2008 Matthias Dieter Wallnöfer, mwallnoefer@yahoo.de
   6 
   7    This program is free software; you can redistribute it and/or modify
   8    it under the terms of the GNU General Public License as published by
   9    the Free Software Foundation; either version 3 of the License, or
  10    (at your option) any later version.
  11 
  12    This program is distributed in the hope that it will be useful,
  13    but WITHOUT ANY WARRANTY; without even the implied warranty of
  14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15    GNU General Public License for more details.
  16 
  17    You should have received a copy of the GNU General Public License
  18    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
  19 
  20 #include "includes.h"
  21 #include "registry.h"
  22 #include "librpc/gen_ndr/ndr_winreg_c.h"
  23 
  24 #define MAX_NAMESIZE 512
  25 #define MAX_VALSIZE 32768
  26 
  27 struct rpc_key {
  28         struct registry_key key;
  29         struct policy_handle pol;
  30         struct dcerpc_pipe *pipe;
  31 
  32         const char* classname;  
  33         uint32_t num_subkeys;
  34         uint32_t max_subkeylen;
  35         uint32_t max_classlen;
  36         uint32_t num_values;
  37         uint32_t max_valnamelen;
  38         uint32_t max_valbufsize;
  39         uint32_t secdescsize;
  40         NTTIME last_changed_time;
  41 };
  42 
  43 struct rpc_registry_context {
  44         struct registry_context context;
  45         struct dcerpc_pipe *pipe;
  46 };
  47 
  48 static struct registry_operations reg_backend_rpc;
  49 
  50 /**
  51  * This is the RPC backend for the registry library.
  52  */
  53 
  54 #define openhive(u) static WERROR open_ ## u(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, struct policy_handle *hnd) \
  55 { \
  56         struct winreg_Open ## u r; \
  57         NTSTATUS status; \
  58 \
  59         ZERO_STRUCT(r); \
  60         r.in.system_name = NULL; \
  61         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; \
  62         r.out.handle = hnd;\
  63 \
  64         status = dcerpc_winreg_Open ## u(p, mem_ctx, &r); \
  65 \
  66         if (!NT_STATUS_IS_OK(status)) { \
  67                 DEBUG(1, ("OpenHive failed - %s\n", nt_errstr(status))); \
  68                 return ntstatus_to_werror(status); \
  69         } \
  70 \
  71         return r.out.result;\
  72 }
  73 
  74 openhive(HKLM)
     /* [<][>][^][v][top][bottom][index][help] */
  75 openhive(HKCU)
  76 openhive(HKPD)
  77 openhive(HKU)
  78 openhive(HKCR)
  79 openhive(HKDD)
  80 openhive(HKCC)
  81 
  82 static struct {
  83         uint32_t hkey;
  84         WERROR (*open) (struct dcerpc_pipe *p, TALLOC_CTX *,
  85                         struct policy_handle *h);
  86 } known_hives[] = {
  87         { HKEY_LOCAL_MACHINE, open_HKLM },
  88         { HKEY_CURRENT_USER, open_HKCU },
  89         { HKEY_CLASSES_ROOT, open_HKCR },
  90         { HKEY_PERFORMANCE_DATA, open_HKPD },
  91         { HKEY_USERS, open_HKU },
  92         { HKEY_DYN_DATA, open_HKDD },
  93         { HKEY_CURRENT_CONFIG, open_HKCC },
  94         { 0, NULL }
  95 };
  96 
  97 static WERROR rpc_query_key(TALLOC_CTX *mem_ctx, const struct registry_key *k);
  98 
  99 static WERROR rpc_get_predefined_key(struct registry_context *ctx,
     /* [<][>][^][v][top][bottom][index][help] */
 100                                      uint32_t hkey_type,
 101                                      struct registry_key **k)
 102 {
 103         int n;
 104         struct rpc_key *mykeydata;
 105         struct rpc_registry_context *rctx = talloc_get_type(ctx, struct rpc_registry_context);
 106 
 107         *k = NULL;
 108 
 109         for(n = 0; known_hives[n].hkey; n++) {
 110                 if(known_hives[n].hkey == hkey_type)
 111                         break;
 112         }
 113 
 114         if (known_hives[n].open == NULL)  {
 115                 DEBUG(1, ("No such hive %d\n", hkey_type));
 116                 return WERR_NO_MORE_ITEMS;
 117         }
 118 
 119         mykeydata = talloc_zero(ctx, struct rpc_key);
 120         mykeydata->key.context = ctx;
 121         mykeydata->pipe = talloc_reference(mykeydata, rctx->pipe);
 122         mykeydata->num_values = -1;
 123         mykeydata->num_subkeys = -1;
 124         *k = (struct registry_key *)mykeydata;
 125         return known_hives[n].open(mykeydata->pipe, mykeydata, &(mykeydata->pol));
 126 }
 127 
 128 #if 0
 129 static WERROR rpc_key_put_rpc_data(TALLOC_CTX *mem_ctx, struct registry_key *k)
     /* [<][>][^][v][top][bottom][index][help] */
 130 {
 131         struct winreg_OpenKey r;
 132         struct rpc_key_data *mykeydata;
 133 
 134         k->backend_data = mykeydata = talloc_zero(mem_ctx, struct rpc_key_data);
 135         mykeydata->num_values = -1;
 136         mykeydata->num_subkeys = -1;
 137 
 138         /* Then, open the handle using the hive */
 139 
 140         ZERO_STRUCT(r);
 141         r.in.handle = &(((struct rpc_key_data *)k->hive->root->backend_data)->pol);
 142         r.in.keyname.name = k->path;
 143         r.in.unknown = 0x00000000;
 144         r.in.access_mask = 0x02000000;
 145         r.out.handle = &mykeydata->pol;
 146 
 147         dcerpc_winreg_OpenKey((struct dcerpc_pipe *)k->hive->backend_data,
 148                               mem_ctx, &r);
 149 
 150         return r.out.result;
 151 }
 152 #endif
 153 
 154 static WERROR rpc_open_key(TALLOC_CTX *mem_ctx, struct registry_key *h,
     /* [<][>][^][v][top][bottom][index][help] */
 155                            const char *name, struct registry_key **key)
 156 {
 157         struct rpc_key *parentkeydata = talloc_get_type(h, struct rpc_key),
 158                                                     *mykeydata;
 159         struct winreg_OpenKey r;
 160         NTSTATUS status;
 161 
 162         mykeydata = talloc_zero(mem_ctx, struct rpc_key);
 163         mykeydata->key.context = parentkeydata->key.context;
 164         mykeydata->pipe = talloc_reference(mykeydata, parentkeydata->pipe);
 165         mykeydata->num_values = -1;
 166         mykeydata->num_subkeys = -1;
 167         *key = (struct registry_key *)mykeydata;
 168 
 169         /* Then, open the handle using the hive */
 170         ZERO_STRUCT(r);
 171         r.in.parent_handle = &parentkeydata->pol;
 172         r.in.keyname.name = name;
 173         r.in.unknown = 0x00000000;
 174         r.in.access_mask = 0x02000000;
 175         r.out.handle = &mykeydata->pol;
 176 
 177         status = dcerpc_winreg_OpenKey(mykeydata->pipe, mem_ctx, &r);
 178 
 179         if (!NT_STATUS_IS_OK(status)) {
 180                 DEBUG(1, ("OpenKey failed - %s\n", nt_errstr(status)));
 181                 return ntstatus_to_werror(status);
 182         }
 183 
 184         return r.out.result;
 185 }
 186 
 187 static WERROR rpc_get_value_by_index(TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
 188                                      const struct registry_key *parent,
 189                                      uint32_t n,
 190                                      const char **value_name,
 191                                      uint32_t *type,
 192                                      DATA_BLOB *data)
 193 {
 194         struct rpc_key *mykeydata = talloc_get_type(parent, struct rpc_key);
 195         struct winreg_EnumValue r;
 196         struct winreg_ValNameBuf name;
 197         uint8_t value;
 198         uint32_t val_size = MAX_VALSIZE;
 199         uint32_t zero = 0;
 200         WERROR error;
 201         NTSTATUS status;
 202 
 203         if (mykeydata->num_values == -1) {
 204                 error = rpc_query_key(mem_ctx, parent);
 205                 if(!W_ERROR_IS_OK(error)) return error;
 206         }
 207 
 208         name.name = "";
 209         name.size = MAX_NAMESIZE;
 210 
 211         ZERO_STRUCT(r);
 212         r.in.handle = &mykeydata->pol;
 213         r.in.enum_index = n;
 214         r.in.name = &name;
 215         r.in.type = type;
 216         r.in.value = &value;
 217         r.in.size = &val_size;
 218         r.in.length = &zero;
 219         r.out.name = &name;
 220         r.out.type = type;
 221         r.out.value = &value;
 222         r.out.size = &val_size;
 223         r.out.length = &zero;
 224 
 225         status = dcerpc_winreg_EnumValue(mykeydata->pipe, mem_ctx, &r);
 226 
 227         if (!NT_STATUS_IS_OK(status)) {
 228                 DEBUG(1, ("EnumValue failed - %s\n", nt_errstr(status)));
 229                 return ntstatus_to_werror(status);
 230         }
 231 
 232         *value_name = talloc_reference(mem_ctx, r.out.name->name);
 233         *type = *(r.out.type);
 234         *data = data_blob_talloc(mem_ctx, r.out.value, *r.out.length);
 235 
 236         return r.out.result;
 237 }
 238 
 239 static WERROR rpc_get_value_by_name(TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
 240                                      const struct registry_key *parent,
 241                                      const char *value_name,
 242                                      uint32_t *type,
 243                                      DATA_BLOB *data)
 244 {
 245         struct rpc_key *mykeydata = talloc_get_type(parent, struct rpc_key);
 246         struct winreg_QueryValue r;
 247         struct winreg_String name;
 248         uint8_t value;
 249         uint32_t val_size = MAX_VALSIZE;
 250         uint32_t zero = 0;
 251         WERROR error;
 252         NTSTATUS status;
 253 
 254         if (mykeydata->num_values == -1) {
 255                 error = rpc_query_key(mem_ctx, parent);
 256                 if(!W_ERROR_IS_OK(error)) return error;
 257         }
 258 
 259         name.name = value_name;
 260 
 261         ZERO_STRUCT(r);
 262         r.in.handle = &mykeydata->pol;
 263         r.in.value_name = &name;
 264         r.in.type = type;
 265         r.in.data = &value;
 266         r.in.data_size = &val_size;
 267         r.in.data_length = &zero;
 268         r.out.type = type;
 269         r.out.data = &value;
 270         r.out.data_size = &val_size;
 271         r.out.data_length = &zero;
 272 
 273         status = dcerpc_winreg_QueryValue(mykeydata->pipe, mem_ctx, &r);
 274 
 275         if (!NT_STATUS_IS_OK(status)) {
 276                 DEBUG(1, ("QueryValue failed - %s\n", nt_errstr(status)));
 277                 return ntstatus_to_werror(status);
 278         }
 279 
 280         *type = *(r.out.type);
 281         *data = data_blob_talloc(mem_ctx, r.out.data, *r.out.data_length);
 282 
 283         return r.out.result;
 284 }
 285 
 286 static WERROR rpc_get_subkey_by_index(TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
 287                                       const struct registry_key *parent,
 288                                       uint32_t n,
 289                                       const char **name,
 290                                       const char **keyclass,
 291                                       NTTIME *last_changed_time)
 292 {
 293         struct winreg_EnumKey r;
 294         struct rpc_key *mykeydata = talloc_get_type(parent, struct rpc_key);
 295         struct winreg_StringBuf namebuf, classbuf;
 296         NTTIME change_time = 0;
 297         NTSTATUS status;
 298 
 299         namebuf.name = "";
 300         namebuf.size = MAX_NAMESIZE;
 301         classbuf.name = NULL;
 302         classbuf.size = 0;
 303 
 304         ZERO_STRUCT(r);
 305         r.in.handle = &mykeydata->pol;
 306         r.in.enum_index = n;
 307         r.in.name = &namebuf;
 308         r.in.keyclass = &classbuf;
 309         r.in.last_changed_time = &change_time;
 310         r.out.name = &namebuf;
 311         r.out.keyclass = &classbuf;
 312         r.out.last_changed_time = &change_time;
 313 
 314         status = dcerpc_winreg_EnumKey(mykeydata->pipe, mem_ctx, &r);
 315 
 316         if (!NT_STATUS_IS_OK(status)) {
 317                 DEBUG(1, ("EnumKey failed - %s\n", nt_errstr(status)));
 318                 return ntstatus_to_werror(status);
 319         }
 320 
 321         if (name != NULL)
 322                 *name = talloc_reference(mem_ctx, r.out.name->name);
 323         if (keyclass != NULL)
 324                 *keyclass = talloc_reference(mem_ctx, r.out.keyclass->name);
 325         if (last_changed_time != NULL)
 326                 *last_changed_time = *(r.out.last_changed_time);
 327 
 328         return r.out.result;
 329 }
 330 
 331 static WERROR rpc_add_key(TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
 332                           struct registry_key *parent, const char *name,
 333                           const char *key_class,
 334                           struct security_descriptor *sec,
 335                           struct registry_key **key)
 336 {
 337         struct winreg_CreateKey r;
 338         struct rpc_key *parentkd = talloc_get_type(parent, struct rpc_key);
 339         struct rpc_key *rpck = talloc(mem_ctx, struct rpc_key);
 340         
 341         NTSTATUS status;
 342 
 343         ZERO_STRUCT(r);
 344         r.in.handle = &parentkd->pol;
 345         r.in.name.name = name;
 346         r.in.keyclass.name = NULL;
 347         r.in.options = 0;
 348         r.in.access_mask = 0x02000000;
 349         r.in.secdesc = NULL;
 350         r.in.action_taken = NULL;
 351         r.out.new_handle = &rpck->pol;
 352         r.out.action_taken = NULL;
 353 
 354         status = dcerpc_winreg_CreateKey(parentkd->pipe, mem_ctx, &r);
 355 
 356         if (!NT_STATUS_IS_OK(status)) {
 357                 talloc_free(rpck);
 358                 DEBUG(1, ("CreateKey failed - %s\n", nt_errstr(status)));
 359                 return ntstatus_to_werror(status);
 360         }
 361 
 362         rpck->pipe = talloc_reference(rpck, parentkd->pipe);
 363         *key = (struct registry_key *)rpck;
 364 
 365         return r.out.result;
 366 }
 367 
 368 static WERROR rpc_query_key(TALLOC_CTX *mem_ctx, const struct registry_key *k)
     /* [<][>][^][v][top][bottom][index][help] */
 369 {
 370         struct winreg_QueryInfoKey r;
 371         struct rpc_key *mykeydata = talloc_get_type(k, struct rpc_key);
 372         struct winreg_String classname;
 373         NTSTATUS status;
 374 
 375         classname.name = NULL;
 376 
 377         ZERO_STRUCT(r);
 378         r.in.handle = &mykeydata->pol;
 379         r.in.classname = &classname;
 380         r.out.classname = &classname;
 381         r.out.num_subkeys = &mykeydata->num_subkeys;
 382         r.out.max_subkeylen = &mykeydata->max_subkeylen;
 383         r.out.max_classlen = &mykeydata->max_classlen;
 384         r.out.num_values = &mykeydata->num_values;
 385         r.out.max_valnamelen = &mykeydata->max_valnamelen;
 386         r.out.max_valbufsize = &mykeydata->max_valbufsize;
 387         r.out.secdescsize = &mykeydata->secdescsize;
 388         r.out.last_changed_time = &mykeydata->last_changed_time;
 389 
 390         status = dcerpc_winreg_QueryInfoKey(mykeydata->pipe, mem_ctx, &r);
 391 
 392         if (!NT_STATUS_IS_OK(status)) {
 393                 DEBUG(1, ("QueryInfoKey failed - %s\n", nt_errstr(status)));
 394                 return ntstatus_to_werror(status);
 395         }
 396 
 397         mykeydata->classname = talloc_reference(mem_ctx, r.out.classname->name);
 398 
 399         return r.out.result;
 400 }
 401 
 402 static WERROR rpc_del_key(struct registry_key *parent, const char *name)
     /* [<][>][^][v][top][bottom][index][help] */
 403 {
 404         NTSTATUS status;
 405         struct rpc_key *mykeydata = talloc_get_type(parent, struct rpc_key);
 406         struct winreg_DeleteKey r;
 407         TALLOC_CTX *mem_ctx = talloc_init("del_key");
 408 
 409         ZERO_STRUCT(r);
 410         r.in.handle = &mykeydata->pol;
 411         r.in.key.name = name;
 412 
 413         status = dcerpc_winreg_DeleteKey(mykeydata->pipe, mem_ctx, &r);
 414 
 415         talloc_free(mem_ctx);
 416 
 417         if (!NT_STATUS_IS_OK(status)) {
 418                 DEBUG(1, ("DeleteKey failed - %s\n", nt_errstr(status)));
 419                 return ntstatus_to_werror(status);
 420         }
 421 
 422         return r.out.result;
 423 }
 424 
 425 static WERROR rpc_get_info(TALLOC_CTX *mem_ctx, const struct registry_key *key,
     /* [<][>][^][v][top][bottom][index][help] */
 426                                                    const char **classname,
 427                                                    uint32_t *num_subkeys,
 428                                                    uint32_t *num_values,
 429                                                    NTTIME *last_changed_time,
 430                                                    uint32_t *max_subkeylen,
 431                                                    uint32_t *max_valnamelen,
 432                                                    uint32_t *max_valbufsize)
 433 {
 434         struct rpc_key *mykeydata = talloc_get_type(key, struct rpc_key);
 435         WERROR error;
 436 
 437         if (mykeydata->num_values == -1) {
 438                 error = rpc_query_key(mem_ctx, key);
 439                 if(!W_ERROR_IS_OK(error)) return error;
 440         }
 441 
 442         if (classname != NULL)
 443                 *classname = mykeydata->classname;
 444 
 445         if (num_subkeys != NULL)
 446                 *num_subkeys = mykeydata->num_subkeys;
 447 
 448         if (num_values != NULL)
 449                 *num_values = mykeydata->num_values;
 450 
 451         if (last_changed_time != NULL)
 452                 *last_changed_time = mykeydata->last_changed_time;
 453 
 454         if (max_subkeylen != NULL)
 455                 *max_subkeylen = mykeydata->max_subkeylen;
 456 
 457         if (max_valnamelen != NULL)
 458                 *max_valnamelen = mykeydata->max_valnamelen;
 459 
 460         if (max_valbufsize != NULL)
 461                 *max_valbufsize = mykeydata->max_valbufsize;
 462 
 463         return WERR_OK;
 464 }
 465 
 466 static struct registry_operations reg_backend_rpc = {
 467         .name = "rpc",
 468         .open_key = rpc_open_key,
 469         .get_predefined_key = rpc_get_predefined_key,
 470         .enum_key = rpc_get_subkey_by_index,
 471         .enum_value = rpc_get_value_by_index,
 472         .get_value = rpc_get_value_by_name,
 473         .create_key = rpc_add_key,
 474         .delete_key = rpc_del_key,
 475         .get_key_info = rpc_get_info,
 476         .get_predefined_key = rpc_get_predefined_key,
 477 };
 478 
 479 _PUBLIC_ WERROR reg_open_remote(struct registry_context **ctx,
     /* [<][>][^][v][top][bottom][index][help] */
 480                                 struct auth_session_info *session_info,
 481                                 struct cli_credentials *credentials,
 482                                 struct loadparm_context *lp_ctx,
 483                                 const char *location, struct tevent_context *ev)
 484 {
 485         NTSTATUS status;
 486         struct dcerpc_pipe *p;
 487         struct rpc_registry_context *rctx;
 488 
 489         dcerpc_init(lp_ctx);
 490 
 491         rctx = talloc(NULL, struct rpc_registry_context);
 492 
 493         /* Default to local smbd if no connection is specified */
 494         if (!location) {
 495                 location = talloc_strdup(rctx, "ncalrpc:");
 496         }
 497 
 498         status = dcerpc_pipe_connect(rctx /* TALLOC_CTX */,
 499                                      &p, location,
 500                                          &ndr_table_winreg,
 501                                      credentials, ev, lp_ctx);
 502         rctx->pipe = p;
 503 
 504         if(NT_STATUS_IS_ERR(status)) {
 505                 DEBUG(1, ("Unable to open '%s': %s\n", location,
 506                         nt_errstr(status)));
 507                 talloc_free(rctx);
 508                 *ctx = NULL;
 509                 return ntstatus_to_werror(status);
 510         }
 511 
 512         *ctx = (struct registry_context *)rctx;
 513         (*ctx)->ops = &reg_backend_rpc;
 514 
 515         return WERR_OK;
 516 }

/* [<][>][^][v][top][bottom][index][help] */