Ignore:
Timestamp:
Nov 27, 2012, 4:43:17 PM (13 years ago)
Author:
Silvan Scherrer
Message:

Samba Server: updated trunk to 3.6.0

Location:
trunk/server
Files:
3 deleted
20 edited
30 copied

Legend:

Unmodified
Added
Removed
  • trunk/server

  • trunk/server/source3/registry/reg_api.c

    r590 r745  
    33 *  Virtual Windows Registry Layer
    44 *  Copyright (C) Volker Lendecke 2006
    5  *  Copyright (C) Michael Adam 2007-2008
     5 *  Copyright (C) Michael Adam 2007-2010
    66 *
    77 *  This program is free software; you can redistribute it and/or modify
     
    5454 * 0x1b         winreg_OpenHKCC
    5555 * 0x1c         winreg_OpenHKDD
    56  * 0x1d         winreg_QueryMultipleValues
     56 * 0x1d         winreg_QueryMultipleValues              reg_querymultiplevalues
    5757 * 0x1e         winreg_InitiateSystemShutdownEx
    5858 * 0x1f         winreg_SaveKeyEx
    5959 * 0x20         winreg_OpenHKPT
    6060 * 0x21         winreg_OpenHKPN
    61  * 0x22         winreg_QueryMultipleValues2
     61 * 0x22         winreg_QueryMultipleValues2             reg_querymultiplevalues
    6262 *
    6363 */
    6464
    6565#include "includes.h"
    66 #include "regfio.h"
     66#include "registry.h"
     67#include "reg_api.h"
     68#include "reg_cachehook.h"
     69#include "reg_backend_db.h"
     70#include "reg_dispatcher.h"
     71#include "reg_objects.h"
     72#include "../librpc/gen_ndr/ndr_security.h"
    6773
    6874#undef DBGC_CLASS
     
    7682static WERROR fill_value_cache(struct registry_key *key)
    7783{
     84        WERROR werr;
     85
    7886        if (key->values != NULL) {
    7987                if (!reg_values_need_update(key->key, key->values)) {
     
    8290        }
    8391
    84         if (!(key->values = TALLOC_ZERO_P(key, struct regval_ctr))) {
    85                 return WERR_NOMEM;
    86         }
     92        werr = regval_ctr_init(key, &(key->values));
     93        W_ERROR_NOT_OK_RETURN(werr);
     94
    8795        if (fetch_reg_values(key->key, key->values) == -1) {
    8896                TALLOC_FREE(key->values);
     
    122130                                   struct registry_key *parent,
    123131                                   const char *name,
    124                                    const struct nt_user_token *token,
     132                                   const struct security_token *token,
    125133                                   uint32 access_desired,
    126134                                   struct registry_key **pregkey)
     
    149157        key = regkey->key;
    150158        talloc_set_destructor(key, regkey_destructor);
    151                
     159
    152160        /* initialization */
    153        
     161
    154162        key->type = REG_KEY_GENERIC;
    155163
     
    183191        if( StrnCaseCmp(key->name, KEY_HKPD, strlen(KEY_HKPD)) == 0 )
    184192                key->type = REG_KEY_HKPD;
    185        
     193
    186194        /* Look up the table of registry I/O operations */
    187195
     
    216224        *pregkey = regkey;
    217225        result = WERR_OK;
    218        
     226
    219227done:
    220228        if ( !W_ERROR_IS_OK(result) ) {
     
    227235WERROR reg_openhive(TALLOC_CTX *mem_ctx, const char *hive,
    228236                    uint32 desired_access,
    229                     const struct nt_user_token *token,
     237                    const struct security_token *token,
    230238                    struct registry_key **pkey)
    231239{
     
    332340{
    333341        struct registry_value *val;
     342        struct regval_blob *blob;
    334343        WERROR err;
    335344
     
    342351        }
    343352
    344         if (idx >= key->values->num_values) {
     353        if (idx >= regval_ctr_numvals(key->values)) {
    345354                return WERR_NO_MORE_ITEMS;
    346355        }
    347356
    348         err = registry_pull_value(mem_ctx, &val,
    349                                   key->values->values[idx]->type,
    350                                   key->values->values[idx]->data_p,
    351                                   key->values->values[idx]->size,
    352                                   key->values->values[idx]->size);
    353         if (!W_ERROR_IS_OK(err)) {
    354                 return err;
    355         }
     357        blob = regval_ctr_specific_value(key->values, idx);
     358
     359        val = talloc_zero(mem_ctx, struct registry_value);
     360        if (val == NULL) {
     361                return WERR_NOMEM;
     362        }
     363
     364        val->type = regval_type(blob);
     365        val->data = data_blob_talloc(mem_ctx, regval_data_p(blob), regval_size(blob));
    356366
    357367        if (pname
    358368            && !(*pname = talloc_strdup(
    359                          mem_ctx, key->values->values[idx]->valuename))) {
    360                 SAFE_FREE(val);
     369                         mem_ctx, regval_name(blob)))) {
     370                TALLOC_FREE(val);
    361371                return WERR_NOMEM;
    362372        }
     
    380390        }
    381391
    382         for (i=0; i<key->values->num_values; i++) {
    383                 if (strequal(key->values->values[i]->valuename, name)) {
     392        for (i=0; i < regval_ctr_numvals(key->values); i++) {
     393                struct regval_blob *blob;
     394                blob = regval_ctr_specific_value(key->values, i);
     395                if (strequal(regval_name(blob), name)) {
    384396                        return reg_enumvalue(mem_ctx, key, i, NULL, pval);
    385397                }
     
    387399
    388400        return WERR_BADFILE;
     401}
     402
     403WERROR reg_querymultiplevalues(TALLOC_CTX *mem_ctx,
     404                               struct registry_key *key,
     405                               uint32_t num_names,
     406                               const char **names,
     407                               uint32_t *pnum_vals,
     408                               struct registry_value **pvals)
     409{
     410        WERROR err;
     411        uint32_t i, n, found = 0;
     412        struct registry_value *vals;
     413
     414        if (num_names == 0) {
     415                return WERR_OK;
     416        }
     417
     418        if (!(key->key->access_granted & KEY_QUERY_VALUE)) {
     419                return WERR_ACCESS_DENIED;
     420        }
     421
     422        if (!(W_ERROR_IS_OK(err = fill_value_cache(key)))) {
     423                return err;
     424        }
     425
     426        vals = talloc_zero_array(mem_ctx, struct registry_value, num_names);
     427        if (vals == NULL) {
     428                return WERR_NOMEM;
     429        }
     430
     431        for (n=0; n < num_names; n++) {
     432                for (i=0; i < regval_ctr_numvals(key->values); i++) {
     433                        struct regval_blob *blob;
     434                        blob = regval_ctr_specific_value(key->values, i);
     435                        if (strequal(regval_name(blob), names[n])) {
     436                                struct registry_value *v;
     437                                err = reg_enumvalue(mem_ctx, key, i, NULL, &v);
     438                                if (!W_ERROR_IS_OK(err)) {
     439                                        return err;
     440                                }
     441                                vals[n] = *v;
     442                                found++;
     443                        }
     444                }
     445        }
     446
     447        *pvals = vals;
     448        *pnum_vals = found;
     449
     450        return WERR_OK;
    389451}
    390452
     
    422484        max_len = 0;
    423485        max_size = 0;
    424         for (i=0; i<key->values->num_values; i++) {
    425                 max_len = MAX(max_len,
    426                               strlen(key->values->values[i]->valuename));
    427                 max_size = MAX(max_size, key->values->values[i]->size);
    428         }
    429 
    430         *num_values = key->values->num_values;
     486        for (i=0; i < regval_ctr_numvals(key->values); i++) {
     487                struct regval_blob *blob;
     488                blob = regval_ctr_specific_value(key->values, i);
     489                max_len = MAX(max_len, strlen(regval_name(blob)));
     490                max_size = MAX(max_size, regval_size(blob));
     491        }
     492
     493        *num_values = regval_ctr_numvals(key->values);
    431494        *max_valnamelen = max_len;
    432495        *max_valbufsize = max_size;
     
    442505        }
    443506
    444         *secdescsize = ndr_size_security_descriptor(secdesc, NULL, 0);
     507        *secdescsize = ndr_size_security_descriptor(secdesc, 0);
    445508        TALLOC_FREE(mem_ctx);
    446509
     
    461524        WERROR err;
    462525
    463         /*
    464          * We must refuse to handle subkey-paths containing
    465          * a '/' character because at a lower level, after
    466          * normalization, '/' is treated as a key separator
    467          * just like '\\'.
    468          */
    469         if (strchr(subkeypath, '/') != NULL) {
    470                 return WERR_INVALID_PARAM;
    471         }
    472 
    473526        if (!(mem_ctx = talloc_new(ctx))) return WERR_NOMEM;
    474527
     
    606659                    const struct registry_value *val)
    607660{
    608         WERROR err;
    609         DATA_BLOB value_data;
     661        struct regval_blob *existing;
     662        WERROR err;
    610663        int res;
    611664
     
    618671        }
    619672
    620         err = registry_push_value(key, val, &value_data);
    621         if (!W_ERROR_IS_OK(err)) {
    622                 return err;
     673        existing = regval_ctr_getvalue(key->values, name);
     674
     675        if ((existing != NULL) &&
     676            (regval_size(existing) == val->data.length) &&
     677            (memcmp(regval_data_p(existing), val->data.data,
     678                    val->data.length) == 0)) {
     679                return WERR_OK;
    623680        }
    624681
    625682        res = regval_ctr_addvalue(key->values, name, val->type,
    626                                   (char *)value_data.data, value_data.length);
    627         TALLOC_FREE(value_data.data);
     683                                  val->data.data, val->data.length);
    628684
    629685        if (res == 0) {
     
    642698static WERROR reg_value_exists(struct registry_key *key, const char *name)
    643699{
    644         int i;
    645 
    646         for (i=0; i<key->values->num_values; i++) {
    647                 if (strequal(key->values->values[i]->valuename, name)) {
    648                         return WERR_OK;
    649                 }
    650         }
    651 
    652         return WERR_BADFILE;
     700        struct regval_blob *blob;
     701
     702        blob = regval_ctr_getvalue(key->values, name);
     703
     704        if (blob == NULL) {
     705                return WERR_BADFILE;
     706        } else {
     707                return WERR_OK;
     708        }
    653709}
    654710
     
    702758}
    703759
    704 /*******************************************************************
    705  Note: topkeypat is the *full* path that this *key will be
    706  loaded into (including the name of the key)
    707  ********************************************************************/
    708 
    709 static WERROR reg_load_tree(REGF_FILE *regfile, const char *topkeypath,
    710                             REGF_NK_REC *key)
    711 {
    712         REGF_NK_REC *subkey;
    713         struct registry_key_handle registry_key;
    714         struct regval_ctr *values;
    715         struct regsubkey_ctr *subkeys;
    716         int i;
    717         char *path = NULL;
    718         WERROR result = WERR_OK;
    719 
    720         /* initialize the struct registry_key_handle structure */
    721 
    722         registry_key.ops = reghook_cache_find(topkeypath);
    723         if (!registry_key.ops) {
    724                 DEBUG(0, ("reg_load_tree: Failed to assign registry_ops "
    725                           "to [%s]\n", topkeypath));
    726                 return WERR_BADFILE;
    727         }
    728 
    729         registry_key.name = talloc_strdup(regfile->mem_ctx, topkeypath);
    730         if (!registry_key.name) {
    731                 DEBUG(0, ("reg_load_tree: Talloc failed for reg_key.name!\n"));
    732                 return WERR_NOMEM;
    733         }
    734 
    735         /* now start parsing the values and subkeys */
    736 
    737         result = regsubkey_ctr_init(regfile->mem_ctx, &subkeys);
    738         W_ERROR_NOT_OK_RETURN(result);
    739 
    740         values = TALLOC_ZERO_P(subkeys, struct regval_ctr);
    741         if (values == NULL) {
    742                 return WERR_NOMEM;
    743         }
    744 
    745         /* copy values into the struct regval_ctr */
    746 
    747         for (i=0; i<key->num_values; i++) {
    748                 regval_ctr_addvalue(values, key->values[i].valuename,
    749                                     key->values[i].type,
    750                                     (char*)key->values[i].data,
    751                                     (key->values[i].data_size & ~VK_DATA_IN_OFFSET));
    752         }
    753 
    754         /* copy subkeys into the struct regsubkey_ctr */
    755 
    756         key->subkey_index = 0;
    757         while ((subkey = regfio_fetch_subkey( regfile, key ))) {
    758                 result = regsubkey_ctr_addkey(subkeys, subkey->keyname);
    759                 if (!W_ERROR_IS_OK(result)) {
    760                         TALLOC_FREE(subkeys);
    761                         return result;
    762                 }
    763         }
    764 
    765         /* write this key and values out */
    766 
    767         if (!store_reg_values(&registry_key, values)
    768             || !store_reg_keys(&registry_key, subkeys))
    769         {
    770                 DEBUG(0,("reg_load_tree: Failed to load %s!\n", topkeypath));
    771                 result = WERR_REG_IO_FAILURE;
    772         }
    773 
    774         TALLOC_FREE(subkeys);
    775 
    776         if (!W_ERROR_IS_OK(result)) {
    777                 return result;
    778         }
    779 
    780         /* now continue to load each subkey registry tree */
    781 
    782         key->subkey_index = 0;
    783         while ((subkey = regfio_fetch_subkey(regfile, key))) {
    784                 path = talloc_asprintf(regfile->mem_ctx,
    785                                        "%s\\%s",
    786                                        topkeypath,
    787                                        subkey->keyname);
    788                 if (path == NULL) {
    789                         return WERR_NOMEM;
    790                 }
    791                 result = reg_load_tree(regfile, path, subkey);
    792                 if (!W_ERROR_IS_OK(result)) {
    793                         break;
    794                 }
    795         }
    796 
    797         return result;
    798 }
    799 
    800 /*******************************************************************
    801  ********************************************************************/
    802 
    803 static WERROR restore_registry_key(struct registry_key_handle *krecord,
    804                                    const char *fname)
    805 {
    806         REGF_FILE *regfile;
    807         REGF_NK_REC *rootkey;
    808         WERROR result;
    809 
    810         /* open the registry file....fail if the file already exists */
    811 
    812         regfile = regfio_open(fname, (O_RDONLY), 0);
    813         if (regfile == NULL) {
    814                 DEBUG(0, ("restore_registry_key: failed to open \"%s\" (%s)\n",
    815                           fname, strerror(errno)));
    816                 return ntstatus_to_werror(map_nt_error_from_unix(errno));
    817         }
    818 
    819         /* get the rootkey from the regf file and then load the tree
    820            via recursive calls */
    821 
    822         if (!(rootkey = regfio_rootkey(regfile))) {
    823                 regfio_close(regfile);
    824                 return WERR_REG_FILE_INVALID;
    825         }
    826 
    827         result = reg_load_tree(regfile, krecord->name, rootkey);
    828 
    829         /* cleanup */
    830 
    831         regfio_close(regfile);
    832 
    833         return result;
    834 }
    835 
    836 WERROR reg_restorekey(struct registry_key *key, const char *fname)
    837 {
    838         return restore_registry_key(key->key, fname);
    839 }
    840 
    841 /********************************************************************
    842 ********************************************************************/
    843 
    844 static WERROR reg_write_tree(REGF_FILE *regfile, const char *keypath,
    845                              REGF_NK_REC *parent)
    846 {
    847         REGF_NK_REC *key;
    848         struct regval_ctr *values;
    849         struct regsubkey_ctr *subkeys;
    850         int i, num_subkeys;
    851         char *key_tmp = NULL;
    852         char *keyname, *parentpath;
    853         char *subkeypath = NULL;
    854         char *subkeyname;
    855         struct registry_key_handle registry_key;
    856         WERROR result = WERR_OK;
    857         SEC_DESC *sec_desc = NULL;
    858 
    859         if (!regfile) {
    860                 return WERR_GENERAL_FAILURE;
    861         }
    862 
    863         if (!keypath) {
    864                 return WERR_OBJECT_PATH_INVALID;
    865         }
    866 
    867         /* split up the registry key path */
    868 
    869         key_tmp = talloc_strdup(regfile->mem_ctx, keypath);
    870         if (!key_tmp) {
    871                 return WERR_NOMEM;
    872         }
    873         if (!reg_split_key(key_tmp, &parentpath, &keyname)) {
    874                 return WERR_OBJECT_PATH_INVALID;
    875         }
    876 
    877         if (!keyname) {
    878                 keyname = parentpath;
    879         }
    880 
    881         /* we need a registry_key_handle object here to enumerate subkeys and values */
    882 
    883         ZERO_STRUCT(registry_key);
    884 
    885         registry_key.name = talloc_strdup(regfile->mem_ctx, keypath);
    886         if (registry_key.name == NULL) {
    887                 return WERR_NOMEM;
    888         }
    889 
    890         registry_key.ops = reghook_cache_find(registry_key.name);
    891         if (registry_key.ops == NULL) {
    892                 return WERR_BADFILE;
    893         }
    894 
    895         /* lookup the values and subkeys */
    896 
    897         result = regsubkey_ctr_init(regfile->mem_ctx, &subkeys);
    898         W_ERROR_NOT_OK_RETURN(result);
    899 
    900         values = TALLOC_ZERO_P(subkeys, struct regval_ctr);
    901         if (values == NULL) {
    902                 return WERR_NOMEM;
    903         }
    904 
    905         fetch_reg_keys(&registry_key, subkeys);
    906         fetch_reg_values(&registry_key, values);
    907 
    908         result = regkey_get_secdesc(regfile->mem_ctx, &registry_key, &sec_desc);
    909         if (!W_ERROR_IS_OK(result)) {
    910                 goto done;
    911         }
    912 
    913         /* write out this key */
    914 
    915         key = regfio_write_key(regfile, keyname, values, subkeys, sec_desc,
    916                                parent);
    917         if (key == NULL) {
    918                 result = WERR_CAN_NOT_COMPLETE;
    919                 goto done;
    920         }
    921 
    922         /* write each one of the subkeys out */
    923 
    924         num_subkeys = regsubkey_ctr_numkeys(subkeys);
    925         for (i=0; i<num_subkeys; i++) {
    926                 subkeyname = regsubkey_ctr_specific_key(subkeys, i);
    927                 subkeypath = talloc_asprintf(regfile->mem_ctx, "%s\\%s",
    928                                              keypath, subkeyname);
    929                 if (subkeypath == NULL) {
    930                         result = WERR_NOMEM;
    931                         goto done;
    932                 }
    933                 result = reg_write_tree(regfile, subkeypath, key);
    934                 if (!W_ERROR_IS_OK(result))
    935                         goto done;
    936         }
    937 
    938         DEBUG(6, ("reg_write_tree: wrote key [%s]\n", keypath));
    939 
    940 done:
    941         TALLOC_FREE(subkeys);
    942         TALLOC_FREE(registry_key.name);
    943 
    944         return result;
    945 }
    946 
    947 static WERROR backup_registry_key(struct registry_key_handle *krecord,
    948                                   const char *fname)
    949 {
    950         REGF_FILE *regfile;
    951         WERROR result;
    952 
    953         /* open the registry file....fail if the file already exists */
    954 
    955         regfile = regfio_open(fname, (O_RDWR|O_CREAT|O_EXCL),
    956                               (S_IRUSR|S_IWUSR));
    957         if (regfile == NULL) {
    958                 DEBUG(0,("backup_registry_key: failed to open \"%s\" (%s)\n",
    959                          fname, strerror(errno) ));
    960                 return ntstatus_to_werror(map_nt_error_from_unix(errno));
    961         }
    962 
    963         /* write the registry tree to the file  */
    964 
    965         result = reg_write_tree(regfile, krecord->name, NULL);
    966 
    967         /* cleanup */
    968 
    969         regfio_close(regfile);
    970 
    971         return result;
    972 }
    973 
    974 WERROR reg_savekey(struct registry_key *key, const char *fname)
    975 {
    976         return backup_registry_key(key->key, fname);
    977 }
    978 
    979760/**********************************************************************
    980761 * Higher level utility functions
     
    994775        }
    995776
    996         for (i=0; i<key->values->num_values; i++) {
    997                 regval_ctr_delvalue(key->values, key->values->values[i]->valuename);
     777        for (i=0; i < regval_ctr_numvals(key->values); i++) {
     778                struct regval_blob *blob;
     779                blob = regval_ctr_specific_value(key->values, i);
     780                regval_ctr_delvalue(key->values, regval_name(blob));
    998781        }
    999782
     
    1003786        }
    1004787
    1005         return WERR_OK;
    1006 }
    1007 
    1008 /*
    1009  * Utility function to open a complete registry path including the hive prefix.
    1010  */
    1011 
    1012 WERROR reg_open_path(TALLOC_CTX *mem_ctx, const char *orig_path,
    1013                      uint32 desired_access, const struct nt_user_token *token,
    1014                      struct registry_key **pkey)
    1015 {
    1016         struct registry_key *hive, *key;
    1017         char *path, *p;
    1018         WERROR err;
    1019 
    1020         if (!(path = SMB_STRDUP(orig_path))) {
    1021                 return WERR_NOMEM;
    1022         }
    1023 
    1024         p = strchr(path, '\\');
    1025 
    1026         if ((p == NULL) || (p[1] == '\0')) {
    1027                 /*
    1028                  * No key behind the hive, just return the hive
    1029                  */
    1030 
    1031                 err = reg_openhive(mem_ctx, path, desired_access, token,
    1032                                    &hive);
    1033                 if (!W_ERROR_IS_OK(err)) {
    1034                         SAFE_FREE(path);
    1035                         return err;
    1036                 }
    1037                 SAFE_FREE(path);
    1038                 *pkey = hive;
    1039                 return WERR_OK;
    1040         }
    1041 
    1042         *p = '\0';
    1043 
    1044         err = reg_openhive(mem_ctx, path, KEY_ENUMERATE_SUB_KEYS, token,
    1045                            &hive);
    1046         if (!W_ERROR_IS_OK(err)) {
    1047                 SAFE_FREE(path);
    1048                 return err;
    1049         }
    1050 
    1051         err = reg_openkey(mem_ctx, hive, p+1, desired_access, &key);
    1052 
    1053         TALLOC_FREE(hive);
    1054         SAFE_FREE(path);
    1055 
    1056         if (!W_ERROR_IS_OK(err)) {
    1057                 return err;
    1058         }
    1059 
    1060         *pkey = key;
    1061788        return WERR_OK;
    1062789}
     
    1067794 * key that has subkeys.
    1068795 */
    1069 static WERROR reg_deletekey_recursive_internal(TALLOC_CTX *ctx,
    1070                                                struct registry_key *parent,
     796static WERROR reg_deletekey_recursive_internal(struct registry_key *parent,
    1071797                                               const char *path,
    1072798                                               bool del_key)
    1073799{
    1074         TALLOC_CTX *mem_ctx = NULL;
    1075800        WERROR werr = WERR_OK;
    1076801        struct registry_key *key;
    1077802        char *subkey_name = NULL;
    1078803        uint32 i;
    1079 
    1080         mem_ctx = talloc_new(ctx);
    1081         if (mem_ctx == NULL) {
    1082                 werr = WERR_NOMEM;
    1083                 goto done;
    1084         }
     804        TALLOC_CTX *mem_ctx = talloc_stackframe();
    1085805
    1086806        /* recurse through subkeys first */
     
    1099819        for (i = regsubkey_ctr_numkeys(key->subkeys) ; i > 0; i--) {
    1100820                subkey_name = regsubkey_ctr_specific_key(key->subkeys, i-1);
    1101                 werr = reg_deletekey_recursive_internal(mem_ctx, key,
    1102                                         subkey_name,
    1103                                         true);
     821                werr = reg_deletekey_recursive_internal(key, subkey_name, true);
    1104822                W_ERROR_NOT_OK_GOTO_DONE(werr);
    1105823        }
     
    1115833}
    1116834
    1117 static WERROR reg_deletekey_recursive_trans(TALLOC_CTX *ctx,
    1118                                             struct registry_key *parent,
     835static WERROR reg_deletekey_recursive_trans(struct registry_key *parent,
    1119836                                            const char *path,
    1120837                                            bool del_key)
     
    1130847        }
    1131848
    1132         werr = reg_deletekey_recursive_internal(ctx, parent, path, del_key);
     849        werr = reg_deletekey_recursive_internal(parent, path, del_key);
    1133850
    1134851        if (!W_ERROR_IS_OK(werr)) {
     852                WERROR werr2;
     853
    1135854                DEBUG(1, (__location__ " failed to delete key '%s' from key "
    1136855                          "'%s': %s\n", path, parent->key->name,
    1137856                          win_errstr(werr)));
    1138                 werr = regdb_transaction_cancel();
    1139                 if (!W_ERROR_IS_OK(werr)) {
     857
     858                werr2 = regdb_transaction_cancel();
     859                if (!W_ERROR_IS_OK(werr2)) {
    1140860                        DEBUG(0, ("reg_deletekey_recursive_trans: "
    1141861                                  "error cancelling transaction: %s\n",
    1142                                   win_errstr(werr)));
     862                                  win_errstr(werr2)));
     863                        /*
     864                         * return the original werr or the
     865                         * error from cancelling the transaction?
     866                         */
    1143867                }
    1144868        } else {
     
    1154878}
    1155879
    1156 WERROR reg_deletekey_recursive(TALLOC_CTX *ctx,
    1157                                struct registry_key *parent,
     880WERROR reg_deletekey_recursive(struct registry_key *parent,
    1158881                               const char *path)
    1159882{
    1160         return reg_deletekey_recursive_trans(ctx, parent, path, true);
    1161 }
    1162 
    1163 WERROR reg_deletesubkeys_recursive(TALLOC_CTX *ctx,
    1164                                    struct registry_key *parent,
     883        return reg_deletekey_recursive_trans(parent, path, true);
     884}
     885
     886WERROR reg_deletesubkeys_recursive(struct registry_key *parent,
    1165887                                   const char *path)
    1166888{
    1167         return reg_deletekey_recursive_trans(ctx, parent, path, false);
    1168 }
    1169 
    1170 #if 0
    1171 /* these two functions are unused. */
    1172 
    1173 /**
    1174  * Utility function to create a registry key without opening the hive
    1175  * before. Assumes the hive already exists.
    1176  */
    1177 
    1178 WERROR reg_create_path(TALLOC_CTX *mem_ctx, const char *orig_path,
    1179                        uint32 desired_access,
    1180                        const struct nt_user_token *token,
    1181                        enum winreg_CreateAction *paction,
    1182                        struct registry_key **pkey)
    1183 {
    1184         struct registry_key *hive;
    1185         char *path, *p;
    1186         WERROR err;
    1187 
    1188         if (!(path = SMB_STRDUP(orig_path))) {
    1189                 return WERR_NOMEM;
    1190         }
    1191 
    1192         p = strchr(path, '\\');
    1193 
    1194         if ((p == NULL) || (p[1] == '\0')) {
    1195                 /*
    1196                  * No key behind the hive, just return the hive
    1197                  */
    1198 
    1199                 err = reg_openhive(mem_ctx, path, desired_access, token,
    1200                                    &hive);
    1201                 if (!W_ERROR_IS_OK(err)) {
    1202                         SAFE_FREE(path);
    1203                         return err;
    1204                 }
    1205                 SAFE_FREE(path);
    1206                 *pkey = hive;
    1207                 *paction = REG_OPENED_EXISTING_KEY;
    1208                 return WERR_OK;
    1209         }
    1210 
    1211         *p = '\0';
    1212 
    1213         err = reg_openhive(mem_ctx, path,
    1214                            (strchr(p+1, '\\') != NULL) ?
    1215                            KEY_ENUMERATE_SUB_KEYS : KEY_CREATE_SUB_KEY,
    1216                            token, &hive);
    1217         if (!W_ERROR_IS_OK(err)) {
    1218                 SAFE_FREE(path);
    1219                 return err;
    1220         }
    1221 
    1222         err = reg_createkey(mem_ctx, hive, p+1, desired_access, pkey, paction);
    1223         SAFE_FREE(path);
    1224         TALLOC_FREE(hive);
    1225         return err;
    1226 }
    1227 
    1228 /*
    1229  * Utility function to create a registry key without opening the hive
    1230  * before. Will not delete a hive.
    1231  */
    1232 
    1233 WERROR reg_delete_path(const struct nt_user_token *token,
    1234                        const char *orig_path)
    1235 {
    1236         struct registry_key *hive;
    1237         char *path, *p;
    1238         WERROR err;
    1239 
    1240         if (!(path = SMB_STRDUP(orig_path))) {
    1241                 return WERR_NOMEM;
    1242         }
    1243 
    1244         p = strchr(path, '\\');
    1245 
    1246         if ((p == NULL) || (p[1] == '\0')) {
    1247                 SAFE_FREE(path);
    1248                 return WERR_INVALID_PARAM;
    1249         }
    1250 
    1251         *p = '\0';
    1252 
    1253         err = reg_openhive(NULL, path,
    1254                            (strchr(p+1, '\\') != NULL) ?
    1255                            KEY_ENUMERATE_SUB_KEYS : KEY_CREATE_SUB_KEY,
    1256                            token, &hive);
    1257         if (!W_ERROR_IS_OK(err)) {
    1258                 SAFE_FREE(path);
    1259                 return err;
    1260         }
    1261 
    1262         err = reg_deletekey(hive, p+1);
    1263         SAFE_FREE(path);
    1264         TALLOC_FREE(hive);
    1265         return err;
    1266 }
    1267 #endif /* #if 0 */
     889        return reg_deletekey_recursive_trans(parent, path, false);
     890}
     891
  • trunk/server/source3/registry/reg_backend_current_version.c

    r414 r745  
    2626
    2727#include "includes.h"
     28#include "registry.h"
     29#include "reg_util_internal.h"
     30#include "reg_objects.h"
    2831
    2932#undef DBGC_CLASS
     
    3235extern struct registry_ops regdb_ops;
    3336
    34 #define KEY_CURRENT_VERSION_NORM "HKLM/SOFTWARE/MICROSOFT/WINDOWS NT/CURRENTVERSION"
     37#define KEY_CURRENT_VERSION_NORM "HKLM\\SOFTWARE\\MICROSOFT\\WINDOWS NT\\CURRENTVERSION"
    3538
    3639static int current_version_fetch_values(const char *key, struct regval_ctr *values)
  • trunk/server/source3/registry/reg_backend_db.c

    r429 r745  
    2222
    2323#include "includes.h"
     24#include "system/filesys.h"
     25#include "registry.h"
     26#include "reg_db.h"
     27#include "reg_util_internal.h"
     28#include "reg_backend_db.h"
     29#include "reg_objects.h"
     30#include "nt_printing.h"
     31#include "util_tdb.h"
     32#include "dbwrap.h"
    2433
    2534#undef DBGC_CLASS
     
    4049                                        struct regval_ctr *values);
    4150
     51static NTSTATUS create_sorted_subkeys(const char *key);
     52
    4253/* List the deepest path into the registry.  All part components will be created.*/
    4354
     
    5465        KEY_PRINTING_PORTS,
    5566        KEY_PRINTING,
     67        KEY_PRINTING "\\Forms",
     68        KEY_PRINTING "\\Printers",
     69        KEY_PRINTING "\\Environments\\Windows NT x86\\Print Processors\\winprint",
    5670        KEY_SHARES,
    5771        KEY_EVENTLOG,
     
    6680        KEY_GP_USER_POLICY,
    6781        KEY_GP_USER_WIN_POLICY,
    68         KEY_WINLOGON_GPEXT_PATH,
     82        "HKLM\\Software\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon\\GPExtensions",
    6983        "HKLM\\SYSTEM\\CurrentControlSet\\Control\\Print\\Monitors",
    7084        KEY_PROD_OPTIONS,
     
    94108                "DefaultSpoolDirectory", REG_SZ, { "C:\\Windows\\System32\\Spool\\Printers" } },
    95109        { KEY_EVENTLOG,
    96                 "DisplayName", REG_SZ, { "Event Log" } }, 
     110                "DisplayName", REG_SZ, { "Event Log" } },
    97111        { KEY_EVENTLOG,
    98112                "ErrorControl", REG_DWORD, { (char*)0x00000001 } },
     
    254268        case REG_DWORD:
    255269                regval_ctr_addvalue(ctr, value->valuename, REG_DWORD,
    256                                     (char*)&value->data.dw_value,
     270                                    (uint8_t *)&value->data.dw_value,
    257271                                    sizeof(uint32));
    258272                break;
     
    293307
    294308        for (i=0; builtin_registry_values[i].path != NULL; i++) {
    295 
    296                 values = TALLOC_ZERO_P(frame, struct regval_ctr);
    297                 if (values == NULL) {
    298                         status = NT_STATUS_NO_MEMORY;
     309                WERROR werr;
     310
     311                werr = regval_ctr_init(frame, &values);
     312                if (!W_ERROR_IS_OK(werr)) {
     313                        status = werror_to_ntstatus(werr);
    299314                        goto done;
    300315                }
     
    344359
    345360        for (i=0; builtin_registry_values[i].path != NULL; i++) {
    346                 values = TALLOC_ZERO_P(frame, struct regval_ctr);
    347                 if (values == NULL) {
    348                         werr = WERR_NOMEM;
    349                         goto done;
    350                 }
     361                werr = regval_ctr_init(frame, &values);
     362                W_ERROR_NOT_OK_GOTO_DONE(werr);
    351363
    352364                regdb_fetch_values_internal(regdb,
     
    385397}
    386398
     399static int regdb_normalize_keynames_fn(struct db_record *rec,
     400                                       void *private_data)
     401{
     402        TALLOC_CTX *mem_ctx = talloc_tos();
     403        const char *keyname;
     404        NTSTATUS status;
     405
     406        if (rec->key.dptr == NULL || rec->key.dsize == 0) {
     407                return 0;
     408        }
     409
     410        keyname = strchr((const char *) rec->key.dptr, '/');
     411        if (keyname) {
     412                struct db_record new_rec;
     413
     414                keyname = talloc_string_sub(mem_ctx,
     415                                            (const char *) rec->key.dptr,
     416                                            "/",
     417                                            "\\");
     418
     419                DEBUG(2, ("regdb_normalize_keynames_fn: Convert %s to %s\n",
     420                          (const char *) rec->key.dptr,
     421                          keyname));
     422
     423                new_rec.value = rec->value;
     424                new_rec.key = string_term_tdb_data(keyname);
     425                new_rec.private_data = rec->private_data;
     426
     427                /* Delete the original record and store the normalized key */
     428                status = rec->delete_rec(rec);
     429                if (!NT_STATUS_IS_OK(status)) {
     430                        DEBUG(0,("regdb_normalize_keynames_fn: "
     431                                 "tdb_delete for [%s] failed!\n",
     432                                 rec->key.dptr));
     433                        return 1;
     434                }
     435
     436                status = rec->store(&new_rec, new_rec.value, TDB_REPLACE);
     437                if (!NT_STATUS_IS_OK(status)) {
     438                        DEBUG(0,("regdb_normalize_keynames_fn: "
     439                                 "failed to store new record for [%s]!\n",
     440                                 keyname));
     441                        return 1;
     442                }
     443        }
     444
     445        return 0;
     446}
     447
     448static WERROR regdb_store_regdb_version(uint32_t version)
     449{
     450        NTSTATUS status;
     451        const char *version_keyname = "INFO/version";
     452
     453        if (!regdb) {
     454                return WERR_CAN_NOT_COMPLETE;
     455        }
     456
     457        status = dbwrap_trans_store_int32(regdb, version_keyname, version);
     458        if (!NT_STATUS_IS_OK(status)) {
     459                DEBUG(1, ("regdb_store_regdb_version: error storing %s = %d: %s\n",
     460                          version_keyname, version, nt_errstr(status)));
     461                return ntstatus_to_werror(status);
     462        } else {
     463                DEBUG(10, ("regdb_store_regdb_version: stored %s = %d\n",
     464                          version_keyname, version));
     465                return WERR_OK;
     466        }
     467}
     468
     469static WERROR regdb_upgrade_v1_to_v2(void)
     470{
     471        TALLOC_CTX *mem_ctx;
     472        int rc;
     473        WERROR werr;
     474
     475        mem_ctx = talloc_stackframe();
     476        if (mem_ctx == NULL) {
     477                return WERR_NOMEM;
     478        }
     479
     480        rc = regdb->traverse(regdb, regdb_normalize_keynames_fn, mem_ctx);
     481
     482        talloc_destroy(mem_ctx);
     483
     484        if (rc == -1) {
     485                return WERR_REG_IO_FAILURE;
     486        }
     487
     488        werr = regdb_store_regdb_version(REGVER_V2);
     489        return werr;
     490}
     491
    387492/***********************************************************************
    388493 Open the registry database
    389494 ***********************************************************************/
    390  
     495
    391496WERROR regdb_init(void)
    392497{
    393498        const char *vstring = "INFO/version";
    394         uint32 vers_id;
     499        uint32 vers_id, expected_version;
    395500        WERROR werr;
    396501
    397502        if (regdb) {
    398                 DEBUG(10, ("regdb_init: incrementing refcount (%d)\n",
    399                           regdb_refcount));
     503                DEBUG(10, ("regdb_init: incrementing refcount (%d->%d)\n",
     504                           regdb_refcount, regdb_refcount+1));
    400505                regdb_refcount++;
    401506                return WERR_OK;
     
    413518                        return werr;
    414519                }
    415                
     520
    416521                DEBUG(10,("regdb_init: Successfully created registry tdb\n"));
    417522        }
    418523
    419524        regdb_refcount = 1;
     525        DEBUG(10, ("regdb_init: registry db openend. refcount reset (%d)\n",
     526                   regdb_refcount));
     527
     528        expected_version = REGVER_V2;
    420529
    421530        vers_id = dbwrap_fetch_int32(regdb, vstring);
    422 
    423         if ( vers_id != REGVER_V1 ) {
    424                 NTSTATUS status;
    425                 /* any upgrade code here if needed */
    426                 DEBUG(10, ("regdb_init: got %s = %d != %d\n", vstring,
    427                            vers_id, REGVER_V1));
    428                 status = dbwrap_trans_store_int32(regdb, vstring, REGVER_V1);
    429                 if (!NT_STATUS_IS_OK(status)) {
    430                         DEBUG(1, ("regdb_init: error storing %s = %d: %s\n",
    431                                   vstring, REGVER_V1, nt_errstr(status)));
    432                         return ntstatus_to_werror(status);
    433                 } else {
    434                         DEBUG(10, ("regdb_init: stored %s = %d\n",
    435                                   vstring, REGVER_V1));
    436                 }
    437         }
     531        if (vers_id == -1) {
     532                DEBUG(10, ("regdb_init: registry version uninitialized "
     533                           "(got %d), initializing to version %d\n",
     534                           vers_id, expected_version));
     535
     536                werr = regdb_store_regdb_version(expected_version);
     537                return werr;
     538        }
     539
     540        if (vers_id > expected_version || vers_id == 0) {
     541                DEBUG(1, ("regdb_init: unknown registry version %d "
     542                          "(code version = %d), refusing initialization\n",
     543                          vers_id, expected_version));
     544                return WERR_CAN_NOT_COMPLETE;
     545        }
     546
     547        if (vers_id == REGVER_V1) {
     548                DEBUG(10, ("regdb_init: got registry db version %d, upgrading "
     549                           "to version %d\n", REGVER_V1, REGVER_V2));
     550
     551                if (regdb->transaction_start(regdb) != 0) {
     552                        return WERR_REG_IO_FAILURE;
     553                }
     554
     555                werr = regdb_upgrade_v1_to_v2();
     556                if (!W_ERROR_IS_OK(werr)) {
     557                        regdb->transaction_cancel(regdb);
     558                        return werr;
     559                }
     560
     561                if (regdb->transaction_commit(regdb) != 0) {
     562                        return WERR_REG_IO_FAILURE;
     563                }
     564
     565                vers_id = REGVER_V2;
     566        }
     567
     568        /* future upgrade code should go here */
    438569
    439570        return WERR_OK;
     
    449580
    450581        if ( regdb ) {
    451                 DEBUG(10,("regdb_open: incrementing refcount (%d)\n", regdb_refcount));
     582                DEBUG(10, ("regdb_open: incrementing refcount (%d->%d)\n",
     583                           regdb_refcount, regdb_refcount+1));
    452584                regdb_refcount++;
    453585                return WERR_OK;
    454586        }
    455        
     587
    456588        become_root();
    457589
     
    460592        if ( !regdb ) {
    461593                result = ntstatus_to_werror( map_nt_error_from_unix( errno ) );
    462                 DEBUG(0,("regdb_open: Failed to open %s! (%s)\n", 
     594                DEBUG(0,("regdb_open: Failed to open %s! (%s)\n",
    463595                        state_path("registry.tdb"), strerror(errno) ));
    464596        }
     
    467599
    468600        regdb_refcount = 1;
    469         DEBUG(10,("regdb_open: refcount reset (%d)\n", regdb_refcount));
     601        DEBUG(10, ("regdb_open: registry db opened. refcount reset (%d)\n",
     602                   regdb_refcount));
    470603
    471604        return result;
     
    483616        regdb_refcount--;
    484617
    485         DEBUG(10,("regdb_close: decrementing refcount (%d)\n", regdb_refcount));
     618        DEBUG(10, ("regdb_close: decrementing refcount (%d->%d)\n",
     619                   regdb_refcount+1, regdb_refcount));
    486620
    487621        if ( regdb_refcount > 0 )
     
    539673                path = discard_const_p(char, keyname);
    540674        } else {
    541                 path = talloc_asprintf(mem_ctx, "%s/%s", prefix, keyname);
     675                path = talloc_asprintf(mem_ctx, "%s\\%s", prefix, keyname);
    542676                if (path == NULL) {
    543677                        goto done;
     
    584718        werr = regdb_delete_values(db, keyname);
    585719        if (!W_ERROR_IS_OK(werr)) {
    586                 DEBUG(1, (__location__ " Deleting %s/%s failed: %s\n",
     720                DEBUG(1, (__location__ " Deleting %s\\%s failed: %s\n",
    587721                          REG_VALUE_PREFIX, keyname, win_errstr(werr)));
    588722                goto done;
     
    591725        werr = regdb_delete_secdesc(db, keyname);
    592726        if (!W_ERROR_IS_OK(werr)) {
    593                 DEBUG(1, (__location__ " Deleting %s/%s failed: %s\n",
     727                DEBUG(1, (__location__ " Deleting %s\\%s failed: %s\n",
    594728                          REG_SECDESC_PREFIX, keyname, win_errstr(werr)));
    595729                goto done;
     
    701835
    702836        /*
    703          * Delete a sorted subkey cache for regdb_key_exists, will be
    704          * recreated automatically
     837         * recreate the sorted subkey cache for regdb_key_exists()
    705838         */
    706         keyname = talloc_asprintf(ctx, "%s/%s", REG_SORTED_SUBKEYS_PREFIX,
    707                                   keyname);
    708         if (keyname == NULL) {
    709                 werr = WERR_NOMEM;
    710                 goto done;
    711         }
    712 
    713         werr = ntstatus_to_werror(dbwrap_delete_bystring(db, keyname));
    714 
    715         /* don't treat WERR_NOT_FOUND as an error here */
    716         if (W_ERROR_EQUAL(werr, WERR_NOT_FOUND)) {
    717                 werr = WERR_OK;
    718         }
     839        werr = ntstatus_to_werror(create_sorted_subkeys(keyname));
    719840
    720841done:
     
    795916                }
    796917
    797                 path = talloc_asprintf(mem_ctx, "%s/%s", store_ctx->key,
     918                path = talloc_asprintf(mem_ctx, "%s\\%s", store_ctx->key,
    798919                                       oldkeyname);
    799920                if (!path) {
     
    839960
    840961        for (i=0; i<num_subkeys; i++) {
    841                 path = talloc_asprintf(mem_ctx, "%s/%s", store_ctx->key,
     962                path = talloc_asprintf(mem_ctx, "%s\\%s", store_ctx->key,
    842963                                regsubkey_ctr_specific_key(store_ctx->ctr, i));
    843964                if (!path) {
     
    10821203        }
    10831204
    1084         path = talloc_asprintf(mem_ctx, "%s/%s", key, subkey);
     1205        path = talloc_asprintf(mem_ctx, "%s\\%s", key, subkey);
    10851206        if (path == NULL) {
    10861207                werr = WERR_NOMEM;
     
    11261247/**
    11271248 * check whether a given key name represents a base key,
    1128  * i.e one without a subkey separator ('/' or '\').
     1249 * i.e one without a subkey separator ('\').
    11291250 */
    11301251static bool regdb_key_is_base_key(const char *key)
     
    11481269        }
    11491270
    1150         ret = (strrchr(path, '/') == NULL);
     1271        ret = (strrchr(path, '\\') == NULL);
    11511272
    11521273done:
     
    11781299 */
    11791300
    1180 static int cmp_keynames(const void *p1, const void *p2)
    1181 {
    1182         return StrCaseCmp(*((char **)p1), *((char **)p2));
     1301static int cmp_keynames(char **p1, char **p2)
     1302{
     1303        return StrCaseCmp(*p1, *p2);
    11831304}
    11841305
     
    12491370        }
    12501371
    1251         qsort(sorted_subkeys, num_subkeys, sizeof(char *), cmp_keynames);
     1372        TYPESAFE_QSORT(sorted_subkeys, num_subkeys, cmp_keynames);
    12521373
    12531374        buf = talloc_array(ctr, char, len);
     
    12771398}
    12781399
    1279 static bool create_sorted_subkeys(const char *key, const char *sorted_keyname)
     1400static NTSTATUS create_sorted_subkeys_internal(const char *key,
     1401                                               const char *sorted_keyname)
    12801402{
    12811403        NTSTATUS status;
     
    12891411                                 &sorted_ctx);
    12901412
    1291         return NT_STATUS_IS_OK(status);
     1413        return status;
     1414}
     1415
     1416static NTSTATUS create_sorted_subkeys(const char *key)
     1417{
     1418        char *sorted_subkeys_keyname;
     1419        NTSTATUS status;
     1420
     1421        sorted_subkeys_keyname = talloc_asprintf(talloc_tos(), "%s\\%s",
     1422                                                 REG_SORTED_SUBKEYS_PREFIX,
     1423                                                 key);
     1424        if (sorted_subkeys_keyname == NULL) {
     1425                status = NT_STATUS_NO_MEMORY;
     1426                goto done;
     1427        }
     1428
     1429        status = create_sorted_subkeys_internal(key, sorted_subkeys_keyname);
     1430
     1431done:
     1432        return status;
    12921433}
    12931434
     
    13511492        }
    13521493
    1353         key = talloc_asprintf(talloc_tos(), "%s/%s",
     1494        key = talloc_asprintf(talloc_tos(), "%s\\%s",
    13541495                              REG_SORTED_SUBKEYS_PREFIX, path);
    13551496        if (key == NULL) {
     
    13691510                result = state.found;
    13701511        } else {
     1512                NTSTATUS status;
     1513
    13711514                res = db->transaction_start(db);
    13721515                if (res != 0) {
    1373                         DEBUG(0, ("error starting transacion\n"));
     1516                        DEBUG(0, ("error starting transaction\n"));
    13741517                        goto fail;
    13751518                }
    13761519
    1377                 if (!create_sorted_subkeys(path, key)) {
     1520                DEBUG(2, (__location__ " WARNING: recreating the sorted "
     1521                          "subkeys cache for key '%s' from scan_parent_subkeys "
     1522                          "this should not happen (too frequently)...\n",
     1523                          path));
     1524
     1525                status = create_sorted_subkeys_internal(path, key);
     1526                if (!NT_STATUS_IS_OK(status)) {
    13781527                        res = db->transaction_cancel(db);
    13791528                        if (res != 0) {
     
    14311580        }
    14321581
    1433         p = strrchr(path, '/');
     1582        p = strrchr(path, '\\');
    14341583        if (p == NULL) {
    14351584                /* this is a base key */
     
    14651614
    14661615        DEBUG(11,("regdb_fetch_keys: Enter key => [%s]\n", key ? key : "NULL"));
    1467 
    1468         frame = talloc_stackframe();
    14691616
    14701617        if (!regdb_key_exists(db, key)) {
     
    15571704                                  &data_p);
    15581705
    1559                 /* add the new value. Paranoid protective code -- make sure data_p is valid */
    1560 
    1561                 if (*valuename && size && data_p) {
    1562                         regval_ctr_addvalue(values, valuename, type,
    1563                                         (const char *)data_p, size);
    1564                 }
     1706                regval_ctr_addvalue(values, valuename, type,
     1707                                (uint8_t *)data_p, size);
    15651708                SAFE_FREE(data_p); /* 'B' option to tdb_unpack does a malloc() */
    15661709
     
    16171760        int ret = 0;
    16181761        TDB_DATA value;
     1762        WERROR werr;
    16191763
    16201764        DEBUG(10,("regdb_fetch_values: Looking for value of key [%s] \n", key));
     
    16241768        }
    16251769
    1626         keystr = talloc_asprintf(ctx, "%s/%s", REG_VALUE_PREFIX, key);
     1770        keystr = talloc_asprintf(ctx, "%s\\%s", REG_VALUE_PREFIX, key);
    16271771        if (!keystr) {
    16281772                goto done;
    16291773        }
    16301774
    1631         values->seqnum = db->get_seqnum(db);
     1775        werr = regval_ctr_set_seqnum(values, db->get_seqnum(db));
     1776        W_ERROR_NOT_OK_GOTO_DONE(werr);
    16321777
    16331778        value = regdb_fetch_key_internal(db, ctx, keystr);
     
    16821827        SMB_ASSERT( len == data.dsize );
    16831828
    1684         keystr = talloc_asprintf(ctx, "%s/%s", REG_VALUE_PREFIX, key );
     1829        keystr = talloc_asprintf(ctx, "%s\\%s", REG_VALUE_PREFIX, key );
    16851830        if (!keystr) {
    16861831                goto done;
     
    17311876        }
    17321877
    1733         tdbkey = talloc_asprintf(tmp_ctx, "%s/%s", REG_SECDESC_PREFIX, key);
     1878        tdbkey = talloc_asprintf(tmp_ctx, "%s\\%s", REG_SECDESC_PREFIX, key);
    17341879        if (tdbkey == NULL) {
    17351880                err = WERR_NOMEM;
    17361881                goto done;
    17371882        }
    1738         normalize_dbkey(tdbkey);
     1883
     1884        tdbkey = normalize_reg_path(tmp_ctx, tdbkey);
     1885        if (tdbkey == NULL) {
     1886                err = WERR_NOMEM;
     1887                goto done;
     1888        }
    17391889
    17401890        data = dbwrap_fetch_bystring(regdb, tmp_ctx, tdbkey);
     
    17711921        }
    17721922
    1773         tdbkey = talloc_asprintf(mem_ctx, "%s/%s", REG_SECDESC_PREFIX, key);
     1923        tdbkey = talloc_asprintf(mem_ctx, "%s\\%s", REG_SECDESC_PREFIX, key);
    17741924        if (tdbkey == NULL) {
    17751925                goto done;
    17761926        }
    1777         normalize_dbkey(tdbkey);
     1927
     1928        tdbkey = normalize_reg_path(mem_ctx, tdbkey);
     1929        if (tdbkey == NULL) {
     1930                err = WERR_NOMEM;
     1931                goto done;
     1932        }
    17781933
    17791934        if (secdesc == NULL) {
     
    18041959bool regdb_values_need_update(struct regval_ctr *values)
    18051960{
    1806         return (regdb_get_seqnum() != values->seqnum);
    1807 }
    1808 
    1809 /* 
     1961        return (regdb_get_seqnum() != regval_ctr_get_seqnum(values));
     1962}
     1963
     1964/*
    18101965 * Table of function pointers for default access
    18111966 */
    1812  
     1967
    18131968struct registry_ops regdb_ops = {
    18141969        .fetch_subkeys = regdb_fetch_keys,
  • trunk/server/source3/registry/reg_backend_hkpt_params.c

    r414 r745  
    2626
    2727#include "includes.h"
     28#include "registry.h"
     29#include "reg_perfcount.h"
     30#include "reg_objects.h"
    2831
    2932#undef DBGC_CLASS
     
    4346        base_index = reg_perfcount_get_base_index();
    4447        buffer_size = reg_perfcount_get_counter_names(base_index, &buffer);
    45         regval_ctr_addvalue(regvals, "Counters", REG_MULTI_SZ, buffer,
     48        regval_ctr_addvalue(regvals, "Counters", REG_MULTI_SZ, (uint8 *)buffer,
    4649                            buffer_size);
    4750
     
    5154
    5255        buffer_size = reg_perfcount_get_counter_help(base_index, &buffer);
    53         regval_ctr_addvalue(regvals, "Help", REG_MULTI_SZ, buffer, buffer_size);
     56        regval_ctr_addvalue(regvals, "Help", REG_MULTI_SZ, (uint8 *)buffer, buffer_size);
    5457        if(buffer_size > 0) {
    5558                SAFE_FREE(buffer);
  • trunk/server/source3/registry/reg_backend_netlogon_params.c

    r414 r745  
    2626
    2727#include "includes.h"
     28#include "registry.h"
     29#include "reg_objects.h"
     30#include "passdb.h"
    2831
    2932#undef DBGC_CLASS
     
    4144
    4245        regval_ctr_addvalue(regvals, "RefusePasswordChange", REG_DWORD,
    43                             (char*)&dwValue, sizeof(dwValue));
     46                            (uint8_t *)&dwValue, sizeof(dwValue));
    4447
    4548        return regval_ctr_numvals(regvals);
  • trunk/server/source3/registry/reg_backend_perflib.c

    r414 r745  
    2626
    2727#include "includes.h"
     28#include "registry.h"
     29#include "reg_util_internal.h"
     30#include "reg_perfcount.h"
     31#include "reg_objects.h"
    2832
    2933#undef DBGC_CLASS
     
    3236extern struct registry_ops regdb_ops;
    3337
    34 #define KEY_PERFLIB_NORM        "HKLM/SOFTWARE/MICROSOFT/WINDOWS NT/CURRENTVERSION/PERFLIB"
    35 #define KEY_PERFLIB_009_NORM    "HKLM/SOFTWARE/MICROSOFT/WINDOWS NT/CURRENTVERSION/PERFLIB/009"
     38#define KEY_PERFLIB_NORM        "HKLM\\SOFTWARE\\MICROSOFT\\WINDOWS NT\\CURRENTVERSION\\PERFLIB"
     39#define KEY_PERFLIB_009_NORM    "HKLM\\SOFTWARE\\MICROSOFT\\WINDOWS NT\\CURRENTVERSION\\PERFLIB\\009"
    3640
    3741static int perflib_params(struct regval_ctr *regvals)
     
    4347       
    4448        base_index = reg_perfcount_get_base_index();
    45         regval_ctr_addvalue(regvals, "Base Index", REG_DWORD, (char *)&base_index, sizeof(base_index));
     49        regval_ctr_addvalue(regvals, "Base Index", REG_DWORD, (uint8_t *)&base_index, sizeof(base_index));
    4650        last_counter = reg_perfcount_get_last_counter(base_index);
    47         regval_ctr_addvalue(regvals, "Last Counter", REG_DWORD, (char *)&last_counter, sizeof(last_counter));
     51        regval_ctr_addvalue(regvals, "Last Counter", REG_DWORD, (uint8_t *)&last_counter, sizeof(last_counter));
    4852        last_help = reg_perfcount_get_last_help(last_counter);
    49         regval_ctr_addvalue(regvals, "Last Help", REG_DWORD, (char *)&last_help, sizeof(last_help));
    50         regval_ctr_addvalue(regvals, "Version", REG_DWORD, (char *)&version, sizeof(version));
     53        regval_ctr_addvalue(regvals, "Last Help", REG_DWORD, (uint8_t *)&last_help, sizeof(last_help));
     54        regval_ctr_addvalue(regvals, "Version", REG_DWORD, (uint8_t *)&version, sizeof(version));
    5155
    5256        return regval_ctr_numvals( regvals );
     
    6165        base_index = reg_perfcount_get_base_index();
    6266        buffer_size = reg_perfcount_get_counter_names(base_index, &buffer);
    63         regval_ctr_addvalue(regvals, "Counter", REG_MULTI_SZ, buffer, buffer_size);
     67        regval_ctr_addvalue(regvals, "Counter", REG_MULTI_SZ, (uint8_t *)buffer, buffer_size);
    6468        if(buffer_size > 0)
    6569                SAFE_FREE(buffer);
    6670        buffer_size = reg_perfcount_get_counter_help(base_index, &buffer);
    67         regval_ctr_addvalue(regvals, "Help", REG_MULTI_SZ, buffer, buffer_size);
     71        regval_ctr_addvalue(regvals, "Help", REG_MULTI_SZ, (uint8_t *)buffer, buffer_size);
    6872        if(buffer_size > 0)
    6973                SAFE_FREE(buffer);
  • trunk/server/source3/registry/reg_backend_printing.c

    r414 r745  
    33 *  Virtual Windows Registry Layer
    44 *  Copyright (C) Gerald Carter                     2002-2005
     5 *  Copyright (c) Andreas Schneider <asn@samba.org> 2010
    56 *
    67 *  This program is free software; you can redistribute it and/or modify
     
    2122
    2223#include "includes.h"
     24#include "registry.h"
     25#include "reg_util_internal.h"
     26#include "reg_backend_db.h"
    2327
    2428#undef DBGC_CLASS
    2529#define DBGC_CLASS DBGC_REGISTRY
    2630
    27 /* registrt paths used in the print_registry[] */
    28 
    29 #define KEY_MONITORS            "HKLM/SYSTEM/CURRENTCONTROLSET/CONTROL/PRINT/MONITORS"
    30 #define KEY_FORMS               "HKLM/SYSTEM/CURRENTCONTROLSET/CONTROL/PRINT/FORMS"
    31 #define KEY_CONTROL_PRINTERS    "HKLM/SYSTEM/CURRENTCONTROLSET/CONTROL/PRINT/PRINTERS"
    32 #define KEY_ENVIRONMENTS        "HKLM/SYSTEM/CURRENTCONTROLSET/CONTROL/PRINT/ENVIRONMENTS"
    33 #define KEY_CONTROL_PRINT       "HKLM/SYSTEM/CURRENTCONTROLSET/CONTROL/PRINT"
    34 #define KEY_WINNT_PRINTERS      "HKLM/SOFTWARE/MICROSOFT/WINDOWS NT/CURRENTVERSION/PRINT/PRINTERS"
    35 #define KEY_WINNT_PRINT         "HKLM/SOFTWARE/MICROSOFT/WINDOWS NT/CURRENTVERSION/PRINT"
    36 #define KEY_PORTS               "HKLM/SOFTWARE/MICROSOFT/WINDOWS NT/CURRENTVERSION/PORTS"
     31/* registry paths used in the print_registry[] */
     32#define KEY_CONTROL_PRINTERS    "HKLM\\SYSTEM\\CURRENTCONTROLSET\\CONTROL\\PRINT\\PRINTERS"
     33#define KEY_WINNT_PRINTERS      "HKLM\\SOFTWARE\\MICROSOFT\\WINDOWS NT\\CURRENTVERSION\\PRINT\\PRINTERS"
    3734
    3835/* callback table for various registry paths below the ones we service in this module */
     
    5148/*********************************************************************
    5249 *********************************************************************
    53  ** Utility Functions
    54  *********************************************************************
    55  *********************************************************************/
    56 
    57 /***********************************************************************
    58  simple function to prune a pathname down to the basename of a file
    59  **********************************************************************/
    60 
    61 static const char *dos_basename(const char *path)
    62 {
    63         const char *p;
    64 
    65         if (!(p = strrchr( path, '\\'))) {
    66                 p = path;
    67         } else {
    68                 p++;
    69         }
    70 
    71         return p;
    72 }
    73 
    74 /*********************************************************************
    75  *********************************************************************
    76  ** "HKLM/SYSTEM/CURRENTCONTROLSET/CONTROL/PRINT/FORMS"
    77  *********************************************************************
    78  *********************************************************************/
    79 
    80 static int key_forms_fetch_keys(const char *key, struct regsubkey_ctr *subkeys)
    81 {
    82         char *p = reg_remaining_path(talloc_tos(), key + strlen(KEY_FORMS));
    83 
    84         /* no keys below Forms */
    85 
    86         if (p) {
    87                 return -1;
    88         }
    89 
    90         return 0;
    91 }
    92 
    93 /**********************************************************************
    94  *********************************************************************/
    95 
    96 static int key_forms_fetch_values(const char *key, struct regval_ctr *values)
    97 {
    98         uint32          data[8];
    99         int             i, num_values, form_index = 1;
    100         nt_forms_struct *forms_list = NULL;
    101         nt_forms_struct *form;
    102 
    103         DEBUG(10,("print_values_forms: key=>[%s]\n", key ? key : "NULL" ));
    104 
    105         num_values = get_ntforms( &forms_list );
    106 
    107         DEBUG(10,("hive_forms_fetch_values: [%d] user defined forms returned\n",
    108                 num_values));
    109 
    110         /* handle user defined forms */
    111 
    112         for ( i=0; i<num_values; i++ ) {
    113                 form = &forms_list[i];
    114 
    115                 data[0] = form->width;
    116                 data[1] = form->length;
    117                 data[2] = form->left;
    118                 data[3] = form->top;
    119                 data[4] = form->right;
    120                 data[5] = form->bottom;
    121                 data[6] = form_index++;
    122                 data[7] = form->flag;
    123 
    124                 regval_ctr_addvalue( values, form->name, REG_BINARY, (char*)data, sizeof(data) );       
    125         }
    126 
    127         SAFE_FREE( forms_list );
    128         forms_list = NULL;
    129 
    130         /* handle built-on forms */
    131 
    132         num_values = get_builtin_ntforms( &forms_list );
    133 
    134         DEBUG(10,("print_subpath_values_forms: [%d] built-in forms returned\n",
    135                 num_values));
    136 
    137         for ( i=0; i<num_values; i++ ) {
    138                 form = &forms_list[i];
    139 
    140                 data[0] = form->width;
    141                 data[1] = form->length;
    142                 data[2] = form->left;
    143                 data[3] = form->top;
    144                 data[4] = form->right;
    145                 data[5] = form->bottom;
    146                 data[6] = form_index++;
    147                 data[7] = form->flag;
    148 
    149                 regval_ctr_addvalue(values, form->name, REG_BINARY, (char*)data, sizeof(data) );
    150         }
    151 
    152         SAFE_FREE(forms_list);
    153 
    154         return regval_ctr_numvals(values);
    155 }
    156 
    157 /*********************************************************************
    158  *********************************************************************
    15950 ** "HKLM/SYSTEM/CURRENTCONTROLSET/CONTROL/PRINT/PRINTERS"
    16051 ** "HKLM/SOFTWARE/MICROSOFT/WINDOWS NT/CURRENTVERSION/PRINT/PRINTERS"
     
    16253 *********************************************************************/
    16354
     55static char *create_printer_registry_path(TALLOC_CTX *mem_ctx, const char *key) {
     56        char *path;
     57        char *subkey = NULL;
     58
     59        path = talloc_strdup(mem_ctx, key);
     60        if (path == NULL) {
     61                return NULL;
     62        }
     63
     64        path = normalize_reg_path(mem_ctx, path);
     65        if (path == NULL) {
     66                return NULL;
     67        }
     68
     69        if (strncmp(path, KEY_CONTROL_PRINTERS, strlen(KEY_CONTROL_PRINTERS)) == 0) {
     70                subkey = reg_remaining_path(mem_ctx, key + strlen(KEY_CONTROL_PRINTERS));
     71                if (subkey == NULL) {
     72                        return NULL;
     73                }
     74                return talloc_asprintf(mem_ctx, "%s\\%s", KEY_WINNT_PRINTERS, subkey);
     75        }
     76
     77        return NULL;
     78}
     79
    16480/*********************************************************************
    165  strip off prefix for printers key.  DOes return a pointer to static
    166  memory.
    167  *********************************************************************/
    168 
    169 static char *strip_printers_prefix(const char *key)
    170 {
    171         char *subkeypath = NULL;
    172         char *path = NULL;
    173         TALLOC_CTX *ctx = talloc_tos();
    174 
    175         path = talloc_strdup(ctx, key);
    176         if (!path) {
    177                 return NULL;
    178         }
    179         path = normalize_reg_path(ctx, path);
    180         if (!path) {
    181                 return NULL;
    182         }
    183 
    184         /* normalizing the path does not change length, just key delimiters and case */
    185 
    186         if (strncmp(path, KEY_WINNT_PRINTERS, strlen(KEY_WINNT_PRINTERS)) == 0) {
    187                 subkeypath = reg_remaining_path(ctx, key + strlen(KEY_WINNT_PRINTERS));
    188         } else {
    189                 subkeypath = reg_remaining_path(ctx, key + strlen(KEY_CONTROL_PRINTERS));
    190         }
    191 
    192         TALLOC_FREE(path);
    193         return subkeypath;
    194 }
    195 
    196 /*********************************************************************
    19781 *********************************************************************/
    19882
    19983static int key_printers_fetch_keys( const char *key, struct regsubkey_ctr *subkeys )
    20084{
    201         int n_services = lp_numservices();
    202         int snum;
    203         fstring sname;
    204         int i;
    205         int num_subkeys = 0;
    206         char *printers_key;
    207         char *printername, *printerdatakey;
    208         NT_PRINTER_INFO_LEVEL *printer = NULL;
    209         fstring *subkey_names = NULL;
    210 
    211         DEBUG(10,("key_printers_fetch_keys: key=>[%s]\n", key ? key : "NULL" ));
    212 
    213         printers_key = strip_printers_prefix( key );
    214 
    215         if ( !printers_key ) {
    216                 /* enumerate all printers */
    217 
    218                 for (snum=0; snum<n_services; snum++) {
    219                         if ( !(lp_snum_ok(snum) && lp_print_ok(snum) ) )
    220                                 continue;
    221 
    222                         /* don't report the [printers] share */
    223 
    224                         if ( strequal( lp_servicename(snum), PRINTERS_NAME ) )
    225                                 continue;
    226 
    227                         fstrcpy( sname, lp_servicename(snum) );
    228 
    229                         regsubkey_ctr_addkey( subkeys, sname );
    230                 }
    231 
    232                 num_subkeys = regsubkey_ctr_numkeys( subkeys );
    233                 goto done;
    234         }
    235 
    236         /* get information for a specific printer */
    237 
    238         if (!reg_split_path( printers_key, &printername, &printerdatakey )) {
    239                 return -1;
    240         }
    241 
    242         /* validate the printer name */
    243 
    244         for (snum=0; snum<n_services; snum++) {
    245                 if ( !lp_snum_ok(snum) || !lp_print_ok(snum) )
    246                         continue;
    247                 if (strequal( lp_servicename(snum), printername ) )
    248                         break;
    249         }
    250 
    251         if ( snum>=n_services
    252                 || !W_ERROR_IS_OK( get_a_printer(NULL, &printer, 2, printername) ) )
    253         {
    254                 return -1;
    255         }
    256 
    257         num_subkeys = get_printer_subkeys( printer->info_2->data, printerdatakey?printerdatakey:"", &subkey_names );
    258        
    259         for ( i=0; i<num_subkeys; i++ )
    260                 regsubkey_ctr_addkey( subkeys, subkey_names[i] );
    261        
    262         free_a_printer( &printer, 2 );
    263                        
    264         /* no other subkeys below here */
    265 
    266 done:   
    267         SAFE_FREE( subkey_names );
    268        
    269         return num_subkeys;
    270 }
    271 
    272 /**********************************************************************
    273  Take a list of names and call add_printer_hook() if necessary
    274  Note that we do this a little differently from Windows since the
    275  keyname is the sharename and not the printer name.
    276  *********************************************************************/
    277 
    278 static bool add_printers_by_registry( struct regsubkey_ctr *subkeys )
    279 {
    280         int i, num_keys, snum;
    281         char *printername;
    282         NT_PRINTER_INFO_LEVEL_2 info2;
    283         NT_PRINTER_INFO_LEVEL printer;
    284        
    285         ZERO_STRUCT( info2 );
    286         printer.info_2 = &info2;
    287        
    288         num_keys = regsubkey_ctr_numkeys( subkeys );
    289        
    290         become_root();
    291         for ( i=0; i<num_keys; i++ ) {
    292                 printername = regsubkey_ctr_specific_key( subkeys, i );
    293                 snum = find_service( printername );
    294                
    295                 /* just verify a valied snum for now */
    296                 if ( snum == -1 ) {
    297                         fstrcpy( info2.printername, printername );
    298                         fstrcpy( info2.sharename, printername );
    299                         if ( !add_printer_hook(talloc_tos(), NULL, &printer ) ) {
    300                                 DEBUG(0,("add_printers_by_registry: Failed to add printer [%s]\n",
    301                                         printername));
    302                         }       
    303                 }
    304         }
    305         unbecome_root();
    306 
    307         return True;
     85        TALLOC_CTX *ctx = talloc_tos();
     86        char *printers_key;
     87
     88        printers_key = create_printer_registry_path(ctx, key);
     89        if (printers_key == NULL) {
     90                /* normalize on the 'HKLM\SOFTWARE\....\Print\Printers' key */
     91                return regdb_fetch_keys(KEY_WINNT_PRINTERS, subkeys);
     92        }
     93
     94        return regdb_fetch_keys(printers_key, subkeys);
    30895}
    30996
     
    313100static bool key_printers_store_keys( const char *key, struct regsubkey_ctr *subkeys )
    314101{
    315         char *printers_key;
    316         char *printername, *printerdatakey;
    317         NT_PRINTER_INFO_LEVEL *printer = NULL;
    318         int i, num_subkeys, num_existing_keys;
    319         char *subkeyname;
    320         fstring *existing_subkeys = NULL;
    321        
    322         printers_key = strip_printers_prefix( key );
    323        
    324         if ( !printers_key ) {
    325                 /* have to deal with some new or deleted printer */
    326                 return add_printers_by_registry( subkeys );
    327         }
    328        
    329         if (!reg_split_path( printers_key, &printername, &printerdatakey )) {
    330                 return False;
    331         }
    332        
    333         /* lookup the printer */
    334        
    335         if ( !W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2, printername)) ) {
    336                 DEBUG(0,("key_printers_store_keys: Tried to store subkey for bad printername %s\n",
    337                         printername));
    338                 return False;
    339         }
    340        
    341         /* get the top level printer keys */
    342        
    343         num_existing_keys = get_printer_subkeys( printer->info_2->data, "", &existing_subkeys );
    344        
    345         for ( i=0; i<num_existing_keys; i++ ) {
    346        
    347                 /* remove the key if it has been deleted */
    348                
    349                 if ( !regsubkey_ctr_key_exists( subkeys, existing_subkeys[i] ) ) {
    350                         DEBUG(5,("key_printers_store_keys: deleting key %s\n",
    351                                 existing_subkeys[i]));
    352                         delete_printer_key( printer->info_2->data, existing_subkeys[i] );
    353                 }
    354         }
    355 
    356         num_subkeys = regsubkey_ctr_numkeys( subkeys );
    357         for ( i=0; i<num_subkeys; i++ ) {
    358                 subkeyname = regsubkey_ctr_specific_key(subkeys, i);
    359                 /* add any missing printer keys */
    360                 if ( lookup_printerkey(printer->info_2->data, subkeyname) == -1 ) {
    361                         DEBUG(5,("key_printers_store_keys: adding key %s\n",
    362                                 existing_subkeys[i]));
    363                         if ( add_new_printer_key( printer->info_2->data, subkeyname ) == -1 ) {
    364                                 SAFE_FREE( existing_subkeys );
    365                                 return False;
    366                         }
    367                 }
    368         }
    369        
    370         /* write back to disk */
    371        
    372         mod_a_printer( printer, 2 );
    373        
    374         /* cleanup */
    375        
    376         free_a_printer( &printer, 2 );
    377 
    378         SAFE_FREE( existing_subkeys );
    379 
    380         return True;
    381 }
    382 
    383 /**********************************************************************
    384  *********************************************************************/
    385 
    386 static void fill_in_printer_values(NT_PRINTER_INFO_LEVEL_2 *info2, struct regval_ctr *values)
    387 {
    388         struct spoolss_DeviceMode *devmode;
    389         char            *p;
    390         uint32 printer_status = PRINTER_STATUS_OK;
    391        
    392         regval_ctr_addvalue( values, "Attributes",       REG_DWORD, (char*)&info2->attributes,       sizeof(info2->attributes) );
    393         regval_ctr_addvalue( values, "Priority",         REG_DWORD, (char*)&info2->priority,         sizeof(info2->attributes) );
    394         regval_ctr_addvalue( values, "ChangeID",         REG_DWORD, (char*)&info2->changeid,         sizeof(info2->changeid) );
    395         regval_ctr_addvalue( values, "Default Priority", REG_DWORD, (char*)&info2->default_priority, sizeof(info2->default_priority) );
    396        
    397         /* lie and say everything is ok since we don't want to call print_queue_length() to get the real status */
    398         regval_ctr_addvalue( values, "Status",           REG_DWORD, (char*)&printer_status,          sizeof(info2->status) );
    399 
    400         regval_ctr_addvalue( values, "StartTime",        REG_DWORD, (char*)&info2->starttime,        sizeof(info2->starttime) );
    401         regval_ctr_addvalue( values, "UntilTime",        REG_DWORD, (char*)&info2->untiltime,        sizeof(info2->untiltime) );
    402 
    403         /* strip the \\server\ from this string */
    404         if ( !(p = strrchr( info2->printername, '\\' ) ) )
    405                 p = info2->printername;
    406         else
    407                 p++;
    408 
    409         regval_ctr_addvalue_sz(values, "Name", p);
    410         regval_ctr_addvalue_sz(values, "Location", info2->location);
    411         regval_ctr_addvalue_sz(values, "Description", info2->comment);
    412         regval_ctr_addvalue_sz(values, "Parameters", info2->parameters);
    413         regval_ctr_addvalue_sz(values, "Port", info2->portname);
    414         regval_ctr_addvalue_sz(values, "Share Name", info2->sharename);
    415         regval_ctr_addvalue_sz(values, "Printer Driver", info2->drivername);
    416         regval_ctr_addvalue_sz(values, "Separator File", info2->sepfile);
    417         regval_ctr_addvalue_sz(values, "Print Processor", "WinPrint");
    418         regval_ctr_addvalue_sz(values, "Datatype", "RAW");
    419 
    420         /* stream the device mode */
    421 
    422         devmode = construct_dev_mode(values,info2->sharename);
    423         if (devmode) {
    424                 DATA_BLOB blob;
    425                 enum ndr_err_code ndr_err;
    426 
    427                 ndr_err = ndr_push_struct_blob(&blob, values, NULL, devmode,
    428                                 (ndr_push_flags_fn_t)ndr_push_spoolss_DeviceMode);
    429 
    430                 if (NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
    431                         regval_ctr_addvalue(values, "Default Devmode", REG_BINARY,
    432                                             (const char *)blob.data, blob.length);
    433                 }
    434         }
    435 
    436         /* stream the printer security descriptor */
    437 
    438         if (info2->secdesc_buf &&
    439             info2->secdesc_buf->sd &&
    440             info2->secdesc_buf->sd_size)
    441         {
    442                 NTSTATUS status;
    443                 DATA_BLOB blob;
    444 
    445                 status = marshall_sec_desc(values, info2->secdesc_buf->sd,
    446                                            &blob.data, &blob.length);
    447                 if (NT_STATUS_IS_OK(status)) {
    448                         regval_ctr_addvalue(values, "Security", REG_BINARY,
    449                                             (const char *)blob.data, blob.length);
    450                 }
    451         }
    452 
    453         return;
     102        TALLOC_CTX *ctx = talloc_tos();
     103        char *printers_key;
     104
     105        printers_key = create_printer_registry_path(ctx, key);
     106        if (printers_key == NULL) {
     107                /* normalize on the 'HKLM\SOFTWARE\....\Print\Printers' key */
     108                return regdb_store_keys(KEY_WINNT_PRINTERS, subkeys);
     109        }
     110
     111        return regdb_store_keys(printers_key, subkeys);
    454112}
    455113
     
    459117static int key_printers_fetch_values(const char *key, struct regval_ctr *values)
    460118{
    461         int             num_values;
    462         char            *printers_key;
    463         char            *printername, *printerdatakey;
    464         NT_PRINTER_INFO_LEVEL   *printer = NULL;
    465         NT_PRINTER_DATA *p_data;
    466         int             i, key_index;
    467        
    468         printers_key = strip_printers_prefix( key );   
    469        
    470         /* top level key values stored in the registry has no values */
    471        
    472         if ( !printers_key ) {
    473                 /* normalize to the 'HKLM\SOFTWARE\...\Print\Printers' key */
    474                 return regdb_fetch_values( KEY_WINNT_PRINTERS, values );
    475         }
    476        
    477         /* lookup the printer object */
    478        
    479         if (!reg_split_path( printers_key, &printername, &printerdatakey )) {
    480                 return -1;
    481         }
    482        
    483         if ( !W_ERROR_IS_OK( get_a_printer(NULL, &printer, 2, printername) ) )
    484                 goto done;
    485                
    486         if ( !printerdatakey ) {
    487                 fill_in_printer_values( printer->info_2, values );
    488                 goto done;
    489         }
    490                
    491         /* iterate over all printer data keys and fill the regval container */
    492        
    493         p_data = printer->info_2->data;
    494         if ( (key_index = lookup_printerkey( p_data, printerdatakey )) == -1  ) {
    495                 /* failure....should never happen if the client has a valid open handle first */
    496                 DEBUG(10,("key_printers_fetch_values: Unknown keyname [%s]\n", printerdatakey));
    497                 free_a_printer( &printer, 2 );
    498                 return -1;
    499         }
    500        
    501         num_values = regval_ctr_numvals( p_data->keys[key_index].values );     
    502         for ( i=0; i<num_values; i++ )
    503                 regval_ctr_copyvalue( values, regval_ctr_specific_value(p_data->keys[key_index].values, i) );
    504                        
    505 
    506 done:
    507         if ( printer )
    508                 free_a_printer( &printer, 2 );
    509                
    510         return regval_ctr_numvals( values );
    511 }
    512 
    513 /**********************************************************************
    514  *********************************************************************/
    515 
    516 #define REG_IDX_ATTRIBUTES              1
    517 #define REG_IDX_PRIORITY                2
    518 #define REG_IDX_DEFAULT_PRIORITY        3
    519 #define REG_IDX_CHANGEID                4
    520 #define REG_IDX_STATUS                  5
    521 #define REG_IDX_STARTTIME               6
    522 #define REG_IDX_NAME                    7
    523 #define REG_IDX_LOCATION                8
    524 #define REG_IDX_DESCRIPTION             9
    525 #define REG_IDX_PARAMETERS              10
    526 #define REG_IDX_PORT                    12
    527 #define REG_IDX_SHARENAME               13
    528 #define REG_IDX_DRIVER                  14
    529 #define REG_IDX_SEP_FILE                15
    530 #define REG_IDX_PRINTPROC               16
    531 #define REG_IDX_DATATYPE                17
    532 #define REG_IDX_DEVMODE                 18
    533 #define REG_IDX_SECDESC                 19
    534 #define REG_IDX_UNTILTIME               20
    535 
    536 struct {
    537         const char *name;
    538         int index;     
    539 } printer_values_map[] = {
    540         { "Attributes",         REG_IDX_ATTRIBUTES },
    541         { "Priority",           REG_IDX_PRIORITY },
    542         { "Default Priority",   REG_IDX_DEFAULT_PRIORITY },
    543         { "ChangeID",           REG_IDX_CHANGEID },
    544         { "Status",             REG_IDX_STATUS },
    545         { "StartTime",          REG_IDX_STARTTIME },
    546         { "UntilTime",          REG_IDX_UNTILTIME },
    547         { "Name",               REG_IDX_NAME },
    548         { "Location",           REG_IDX_LOCATION },
    549         { "Description",        REG_IDX_DESCRIPTION },
    550         { "Parameters",         REG_IDX_PARAMETERS },
    551         { "Port",               REG_IDX_PORT },
    552         { "Share Name",         REG_IDX_SHARENAME },
    553         { "Printer Driver",     REG_IDX_DRIVER },
    554         { "Separator File",     REG_IDX_SEP_FILE },
    555         { "Print Processor",    REG_IDX_PRINTPROC },
    556         { "Datatype",           REG_IDX_DATATYPE },
    557         { "Default Devmode",    REG_IDX_DEVMODE },
    558         { "Security",           REG_IDX_SECDESC },
    559         { NULL, -1 }
    560 };
    561 
    562 
    563 static int find_valuename_index( const char *valuename )
    564 {
    565         int i;
    566        
    567         for ( i=0; printer_values_map[i].name; i++ ) {
    568                 if ( strequal( valuename, printer_values_map[i].name ) )
    569                         return printer_values_map[i].index;
    570         }
    571        
    572         return -1;
    573 }
    574 
    575 /**********************************************************************
    576  *********************************************************************/
    577 
    578 static void pull_reg_sz_fstring(TALLOC_CTX *mem_ctx, const DATA_BLOB *blob, fstring s)
    579 {
    580         const char *str;
    581         pull_reg_sz(mem_ctx, blob, &str);
    582         fstrcpy(s, str);
    583 }
    584 
    585 static void convert_values_to_printer_info_2(TALLOC_CTX *mem_ctx,
    586                                              NT_PRINTER_INFO_LEVEL_2 *printer2,
    587                                              struct regval_ctr *values)
    588 {
    589         int num_values = regval_ctr_numvals( values );
    590         uint32 value_index;
    591         struct regval_blob *val;
    592         int i;
    593        
    594         for ( i=0; i<num_values; i++ ) {
    595                 DATA_BLOB blob;
    596                 val = regval_ctr_specific_value( values, i );
    597                 value_index = find_valuename_index( regval_name( val ) );
    598 
    599                 blob = data_blob_const(regval_data_p(val), regval_size(val));
    600                
    601                 switch( value_index ) {
    602                         case REG_IDX_ATTRIBUTES:
    603                                 printer2->attributes = (uint32)(*regval_data_p(val));
    604                                 break;
    605                         case REG_IDX_PRIORITY:
    606                                 printer2->priority = (uint32)(*regval_data_p(val));
    607                                 break;
    608                         case REG_IDX_DEFAULT_PRIORITY:
    609                                 printer2->default_priority = (uint32)(*regval_data_p(val));
    610                                 break;
    611                         case REG_IDX_CHANGEID:
    612                                 printer2->changeid = (uint32)(*regval_data_p(val));
    613                                 break;
    614                         case REG_IDX_STARTTIME:
    615                                 printer2->starttime = (uint32)(*regval_data_p(val));
    616                                 break;
    617                         case REG_IDX_UNTILTIME:
    618                                 printer2->untiltime = (uint32)(*regval_data_p(val));
    619                                 break;
    620                         case REG_IDX_NAME:
    621                                 pull_reg_sz_fstring(mem_ctx, &blob, printer2->printername);
    622                                 break;
    623                         case REG_IDX_LOCATION:
    624                                 pull_reg_sz_fstring(mem_ctx, &blob, printer2->location);
    625                                 break;
    626                         case REG_IDX_DESCRIPTION:
    627                                 pull_reg_sz_fstring(mem_ctx, &blob, printer2->comment);
    628                                 break;
    629                         case REG_IDX_PARAMETERS:
    630                                 pull_reg_sz_fstring(mem_ctx, &blob, printer2->parameters);
    631                                 break;
    632                         case REG_IDX_PORT:
    633                                 pull_reg_sz_fstring(mem_ctx, &blob, printer2->portname);
    634                                 break;
    635                         case REG_IDX_SHARENAME:
    636                                 pull_reg_sz_fstring(mem_ctx, &blob, printer2->sharename);
    637                                 break;
    638                         case REG_IDX_DRIVER:
    639                                 pull_reg_sz_fstring(mem_ctx, &blob, printer2->drivername);
    640                                 break;
    641                         case REG_IDX_SEP_FILE:
    642                                 pull_reg_sz_fstring(mem_ctx, &blob, printer2->sepfile);
    643                                 break;
    644                         case REG_IDX_PRINTPROC:
    645                                 pull_reg_sz_fstring(mem_ctx, &blob, printer2->printprocessor);
    646                                 break;
    647                         case REG_IDX_DATATYPE:
    648                                 pull_reg_sz_fstring(mem_ctx, &blob, printer2->datatype);
    649                                 break;
    650                         case REG_IDX_DEVMODE:
    651                                 break;
    652                         case REG_IDX_SECDESC:
    653                                 break;         
    654                         default:
    655                                 /* unsupported value...throw away */
    656                                 DEBUG(8,("convert_values_to_printer_info_2: Unsupported registry value [%s]\n",
    657                                         regval_name( val ) ));
    658                 }
    659         }
    660        
    661         return;
    662 }       
     119        TALLOC_CTX *ctx = talloc_tos();
     120        char *printers_key;
     121
     122        printers_key = create_printer_registry_path(ctx, key);
     123        if (printers_key == NULL) {
     124                /* normalize on the 'HKLM\SOFTWARE\....\Print\Printers' key */
     125                return regdb_fetch_values(KEY_WINNT_PRINTERS, values);
     126        }
     127
     128        return regdb_fetch_values(printers_key, values);
     129}
    663130
    664131/**********************************************************************
     
    667134static bool key_printers_store_values(const char *key, struct regval_ctr *values)
    668135{
    669         char *printers_key;
    670         char *printername, *keyname;
    671         NT_PRINTER_INFO_LEVEL   *printer = NULL;
    672         WERROR result;
    673         TALLOC_CTX *mem_ctx = talloc_init("key_printers_store_values");
    674        
    675         printers_key = strip_printers_prefix( key );
    676        
    677         /* values in the top level key get stored in the registry */
    678 
    679         if ( !printers_key ) {
    680                 /* normalize on the 'HKLM\SOFTWARE\....\Print\Printers' key */
    681                 return regdb_store_values( KEY_WINNT_PRINTERS, values );
    682         }
    683        
    684         if (!reg_split_path( printers_key, &printername, &keyname )) {
    685                 return False;
    686         }
    687 
    688         if ( !W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2, printername) ) )
    689                 return False;
    690 
    691         /* deal with setting values directly under the printername */
    692 
    693         if ( !keyname ) {
    694                 convert_values_to_printer_info_2(mem_ctx, printer->info_2, values );
    695         }
    696         else {
    697                 int num_values = regval_ctr_numvals( values );
    698                 int i;
    699                 struct regval_blob *val;
    700                
    701                 delete_printer_key( printer->info_2->data, keyname );
    702                
    703                 /* deal with any subkeys */
    704                 for ( i=0; i<num_values; i++ ) {
    705                         val = regval_ctr_specific_value( values, i );
    706                         result = set_printer_dataex( printer, keyname,
    707                                 regval_name( val ),
    708                                 regval_type( val ),
    709                                 regval_data_p( val ),
    710                                 regval_size( val ) );
    711                         if ( !W_ERROR_IS_OK(result) ) {
    712                                 DEBUG(0,("key_printers_store_values: failed to set printer data [%s]!\n",
    713                                         keyname));
    714                                 free_a_printer( &printer, 2 );
    715                                 talloc_destroy(mem_ctx);
    716                                 return False;
    717                         }
    718                 }
    719         }
    720 
    721         result = mod_a_printer( printer, 2 );
    722 
    723         free_a_printer( &printer, 2 );
    724         talloc_destroy(mem_ctx);
    725 
    726         return W_ERROR_IS_OK(result);
    727 }
    728 
    729 /*********************************************************************
    730  *********************************************************************
    731  ** "HKLM/SYSTEM/CURRENTCONTROLSET/CONTROL/PRINT/ENVIRONMENTS"
    732  *********************************************************************
    733  *********************************************************************/
    734 
    735 static int key_driver_fetch_keys( const char *key, struct regsubkey_ctr *subkeys )
    736 {
    737         const char *environments[] = {
    738                 "Windows 4.0",
    739                 "Windows NT x86",
    740                 "Windows NT R4000",
    741                 "Windows NT Alpha_AXP",
    742                 "Windows NT PowerPC",
    743                 "Windows IA64",
    744                 "Windows x64",
    745                 NULL };
    746         fstring *drivers = NULL;
    747         int i, env_index, num_drivers;
    748         char *keystr, *base, *subkeypath;
    749         char *key2 = NULL;
    750         int num_subkeys = -1;
    751         int version;
    752         TALLOC_CTX *ctx = talloc_tos();
    753 
    754         DEBUG(10,("key_driver_fetch_keys key=>[%s]\n", key ? key : "NULL" ));
    755 
    756         keystr = reg_remaining_path(ctx, key + strlen(KEY_ENVIRONMENTS) );
    757 
    758         /* list all possible architectures */
    759 
    760         if ( !keystr ) {
    761                 for ( num_subkeys=0; environments[num_subkeys]; num_subkeys++ )
    762                         regsubkey_ctr_addkey( subkeys,  environments[num_subkeys] );
    763 
    764                 return num_subkeys;
    765         }
    766 
    767         /* we are dealing with a subkey of "Environments */
    768         key2 = talloc_strdup(ctx, keystr);
    769         if (!key2) {
    770                 return -1;
    771         }
    772         keystr = key2;
    773         if (!reg_split_path(keystr, &base, &subkeypath )) {
    774                 return -1;
    775         }
    776 
    777         /* sanity check */
    778 
    779         for ( env_index=0; environments[env_index]; env_index++ ) {
    780                 if ( strequal( environments[env_index], base ) )
    781                         break;
    782         }
    783         if ( !environments[env_index] )
    784                 return -1;
    785 
    786         /* ...\Print\Environements\...\ */
    787 
    788         if ( !subkeypath ) {
    789                 regsubkey_ctr_addkey( subkeys, "Drivers" );
    790                 regsubkey_ctr_addkey( subkeys, "Print Processors" );
    791 
    792                 return 2;
    793         }
    794 
    795         /* more of the key path to process */
    796 
    797         keystr = subkeypath;
    798         if (!reg_split_path( keystr, &base, &subkeypath )) {
    799                 return -1;
    800         }
    801 
    802         /* ...\Print\Environements\...\Drivers\ */
    803 
    804         if ( !subkeypath ) {
    805                 if ( strequal(base, "Drivers") ) {
    806                         switch ( env_index ) {
    807                                 case 0: /* Win9x */
    808                                         regsubkey_ctr_addkey( subkeys, "Version-0" );
    809                                         break;
    810                                 default: /* Windows NT based systems */
    811                                         regsubkey_ctr_addkey( subkeys, "Version-2" );
    812                                         regsubkey_ctr_addkey( subkeys, "Version-3" );
    813                                         break;
    814                         }
    815 
    816                         return regsubkey_ctr_numkeys( subkeys );
    817                 } else if ( strequal(base, "Print Processors") ) {
    818                         if ( env_index == 1 || env_index == 5 || env_index == 6 )
    819 
    820 
    821                         return regsubkey_ctr_numkeys( subkeys );
    822                 } else
    823                         return -1;      /* bad path */
    824         }
    825 
    826         /* we finally get to enumerate the drivers */
    827 
    828         /* only one possible subkey below PrintProc key */
    829 
    830         if ( strequal(base, "Print Processors") ) {
    831                 keystr = subkeypath;
    832                 if (!reg_split_path( keystr, &base, &subkeypath )) {
    833                         return -1;
    834                 }
    835 
    836                 /* no subkeys below this point */
    837 
    838                 if ( subkeypath )
    839                         return -1;
    840 
    841                 /* only allow one keyname here -- 'winprint' */
    842 
    843                 return strequal( base, "winprint" ) ? 0 : -1;
    844         }
    845 
    846         /* only dealing with drivers from here on out */
    847 
    848         keystr = subkeypath;
    849         if (!reg_split_path( keystr, &base, &subkeypath )) {
    850                 return -1;
    851         }
    852 
    853         version = atoi(&base[strlen(base)-1]);
    854 
    855         switch (env_index) {
    856         case 0:
    857                 if ( version != 0 )
    858                         return -1;
    859                 break;
    860         default:
    861                 if ( version != 2 && version != 3 )
    862                         return -1;
    863                 break;
    864         }
    865 
    866 
    867         if ( !subkeypath ) {
    868                 num_drivers = get_ntdrivers( &drivers, environments[env_index], version );
    869                 for ( i=0; i<num_drivers; i++ )
    870                         regsubkey_ctr_addkey( subkeys, drivers[i] );
    871 
    872                 return regsubkey_ctr_numkeys( subkeys );
    873         }
    874 
    875         /* if anything else left, just say if has no subkeys */
    876 
    877         DEBUG(1,("key_driver_fetch_keys unhandled key [%s] (subkey == %s)\n",
    878                 key, subkeypath ));
    879 
    880         return 0;
    881 }
    882 
    883 
    884 /**********************************************************************
    885  *********************************************************************/
    886 
    887 static void fill_in_driver_values(const struct spoolss_DriverInfo8 *r,
    888                                   struct regval_ctr *values)
    889 {
    890         char *buffer = NULL;
    891         int buffer_size = 0;
    892         int i, length;
    893         const char *filename;
    894         DATA_BLOB data;
    895 
    896         filename = dos_basename(r->driver_path);
    897         regval_ctr_addvalue_sz(values, "Driver", filename);
    898 
    899         filename = dos_basename(r->config_file);
    900         regval_ctr_addvalue_sz(values, "Configuration File", filename);
    901 
    902         filename = dos_basename(r->data_file);
    903         regval_ctr_addvalue_sz(values, "Data File", filename);
    904 
    905         filename = dos_basename(r->help_file);
    906         regval_ctr_addvalue_sz(values, "Help File", filename);
    907 
    908         regval_ctr_addvalue_sz(values, "Data Type", r->default_datatype);
    909 
    910         regval_ctr_addvalue( values, "Version", REG_DWORD, (char*)&r->version,
    911                 sizeof(r->version) );
    912 
    913         if (r->dependent_files) {
    914                 /* place the list of dependent files in a single
    915                    character buffer, separating each file name by
    916                    a NULL */
    917 
    918                 for (i=0; r->dependent_files[i] && strcmp(r->dependent_files[i], ""); i++) {
    919                         /* strip the path to only the file's base name */
    920 
    921                         filename = dos_basename(r->dependent_files[i]);
    922 
    923                         length = strlen(filename);
    924 
    925                         buffer = (char *)SMB_REALLOC( buffer, buffer_size + (length + 1)*sizeof(uint16) );
    926                         if ( !buffer ) {
    927                                 break;
    928                         }
    929 
    930                         push_reg_sz(talloc_tos(), &data, filename);
    931                         memcpy( buffer+buffer_size, (char*)data.data, data.length);
    932 
    933                         buffer_size += (length + 1)*sizeof(uint16);
    934                 }
    935 
    936                 /* terminated by double NULL.  Add the final one here */
    937 
    938                 buffer = (char *)SMB_REALLOC( buffer, buffer_size + 2 );
    939                 if ( !buffer ) {
    940                         buffer_size = 0;
    941                 } else {
    942                         buffer[buffer_size++] = '\0';
    943                         buffer[buffer_size++] = '\0';
    944                 }
    945         }
    946 
    947         regval_ctr_addvalue( values, "Dependent Files",    REG_MULTI_SZ, buffer, buffer_size );
    948 
    949         SAFE_FREE( buffer );
    950 
    951         return;
    952 }
    953 
    954 /**********************************************************************
    955  *********************************************************************/
    956 
    957 static int driver_arch_fetch_values(char *key, struct regval_ctr *values)
    958 {
    959         char            *keystr, *base, *subkeypath;
    960         fstring         arch_environment;
    961         fstring         driver;
    962         int             version;
    963         struct spoolss_DriverInfo8 *driver_ctr;
    964         WERROR          w_result;
    965 
    966         if (!reg_split_path( key, &base, &subkeypath )) {
    967                 return -1;
    968         }
    969 
    970         /* no values in 'Environments\Drivers\Windows NT x86' */
    971 
    972         if ( !subkeypath )
    973                 return 0;
    974 
    975         /* We have the Architecture string and some subkey name:
    976            Currently we only support
    977            * Drivers
    978            * Print Processors
    979            Anything else is an error.
    980            */
    981 
    982         fstrcpy( arch_environment, base );
    983 
    984         keystr = subkeypath;
    985         if (!reg_split_path( keystr, &base, &subkeypath )) {
    986                 return -1;
    987         }
    988 
    989         if ( strequal(base, "Print Processors") )
    990                 return 0;
    991 
    992         /* only Drivers key can be left */
    993 
    994         if ( !strequal(base, "Drivers") )
    995                 return -1;
    996 
    997         if ( !subkeypath )
    998                 return 0;
    999 
    1000         /* We know that we have Architechure\Drivers with some subkey name
    1001            The subkey name has to be Version-XX */
    1002 
    1003         keystr = subkeypath;
    1004         if (!reg_split_path( keystr, &base, &subkeypath )) {
    1005                 return -1;
    1006         }
    1007 
    1008         if ( !subkeypath )
    1009                 return 0;
    1010 
    1011         version = atoi(&base[strlen(base)-1]);
    1012 
    1013         /* BEGIN PRINTER DRIVER NAME BLOCK */
    1014 
    1015         keystr = subkeypath;
    1016         if (!reg_split_path( keystr, &base, &subkeypath )) {
    1017                 return -1;
    1018         }
    1019 
    1020         /* don't go any deeper for now */
    1021 
    1022         fstrcpy( driver, base );
    1023 
    1024         w_result = get_a_printer_driver(talloc_tos(), &driver_ctr, driver, arch_environment, version);
    1025 
    1026         if ( !W_ERROR_IS_OK(w_result) )
    1027                 return -1;
    1028 
    1029         fill_in_driver_values(driver_ctr, values);
    1030 
    1031         free_a_printer_driver(driver_ctr);
    1032 
    1033         /* END PRINTER DRIVER NAME BLOCK */
    1034 
    1035 
    1036         DEBUG(8,("key_driver_fetch_values: Exit\n"));
    1037 
    1038         return regval_ctr_numvals( values );
    1039 }
    1040 
    1041 /**********************************************************************
    1042  *********************************************************************/
    1043 
    1044 static int key_driver_fetch_values(const char *key, struct regval_ctr *values)
    1045 {
    1046         char *keystr = NULL;
    1047         char *subkey = NULL;
    1048         TALLOC_CTX *ctx = talloc_tos();
    1049 
    1050         DEBUG(8,("key_driver_fetch_values: Enter key => [%s]\n", key ? key : "NULL"));
    1051 
    1052         /* no values in the Environments key */
    1053 
    1054         if (!(keystr = reg_remaining_path(ctx, key + strlen(KEY_ENVIRONMENTS))))
    1055                 return 0;
    1056 
    1057         subkey = talloc_strdup(ctx, keystr);
    1058         if (!subkey) {
    1059                 return 0;
    1060         }
    1061 
    1062         /* pass off to handle subkeys */
    1063 
    1064         return driver_arch_fetch_values( subkey, values );
    1065 }
    1066 
    1067 /*********************************************************************
    1068  *********************************************************************
    1069  ** "HKLM/SYSTEM/CURRENTCONTROLSET/CONTROL/PRINT"
    1070  *********************************************************************
    1071  *********************************************************************/
    1072 
    1073 static int key_print_fetch_keys( const char *key, struct regsubkey_ctr *subkeys )
    1074 {
    1075         int key_len = strlen(key);
    1076 
    1077         /* no keys below 'Print' handled here */
    1078 
    1079         if ( (key_len != strlen(KEY_CONTROL_PRINT)) && (key_len != strlen(KEY_WINNT_PRINT)) )
    1080                 return -1;
    1081 
    1082         regsubkey_ctr_addkey( subkeys, "Environments" );
    1083         regsubkey_ctr_addkey( subkeys, "Monitors" );
    1084         regsubkey_ctr_addkey( subkeys, "Forms" );
    1085         regsubkey_ctr_addkey( subkeys, "Printers" );
    1086 
    1087         return regsubkey_ctr_numkeys( subkeys );
     136        TALLOC_CTX *ctx = talloc_tos();
     137        char *printers_key;
     138
     139        printers_key = create_printer_registry_path(ctx, key);
     140        if (printers_key == NULL) {
     141                /* normalize on the 'HKLM\SOFTWARE\....\Print\Printers' key */
     142                return regdb_store_values(KEY_WINNT_PRINTERS, values);
     143        }
     144
     145        return regdb_store_values(printers_key, values);
    1088146}
    1089147
     
    1097155
    1098156static struct reg_dyn_tree print_registry[] = {
    1099 /* just pass the monitor onto the registry tdb */
    1100 { KEY_MONITORS,
    1101         &regdb_fetch_keys,
    1102         &regdb_store_keys,
    1103         &regdb_fetch_values,
    1104         &regdb_store_values },
    1105 { KEY_FORMS,
    1106         &key_forms_fetch_keys,
    1107         NULL,
    1108         &key_forms_fetch_values,
    1109         NULL },
    1110157{ KEY_CONTROL_PRINTERS,
    1111158        &key_printers_fetch_keys,
     
    1113160        &key_printers_fetch_values,
    1114161        &key_printers_store_values },
    1115 { KEY_ENVIRONMENTS,
    1116         &key_driver_fetch_keys,
    1117         NULL,
    1118         &key_driver_fetch_values,
    1119         NULL },
    1120 { KEY_CONTROL_PRINT,
    1121         &key_print_fetch_keys,
    1122         NULL,
    1123         NULL,
    1124         NULL },
    1125 { KEY_WINNT_PRINTERS,
    1126         &key_printers_fetch_keys,
    1127         &key_printers_store_keys,
    1128         &key_printers_fetch_values,
    1129         &key_printers_store_values },
    1130 { KEY_PORTS,
    1131         &regdb_fetch_keys,
    1132         &regdb_store_keys,
    1133         &regdb_fetch_values,
    1134         &regdb_store_values },
    1135162
    1136163{ NULL, NULL, NULL, NULL, NULL }
  • trunk/server/source3/registry/reg_backend_prod_options.c

    r414 r745  
    2626
    2727#include "includes.h"
     28#include "registry.h"
     29#include "reg_objects.h"
    2830
    2931#undef DBGC_CLASS
  • trunk/server/source3/registry/reg_backend_shares.c

    r414 r745  
    2121
    2222#include "includes.h"
     23#include "registry.h"
     24#include "reg_objects.h"
    2325
    2426#undef DBGC_CLASS
     
    2628
    2729/**********************************************************************
    28  It is safe to assume that every registry path passed into on of
    29  the exported functions here begins with KEY_PRINTING else
     30 It is safe to assume that every registry path passed into one of
     31 the exported functions here begins with KEY_SHARES else
    3032 these functions would have never been called.  This is a small utility
    31  function to strip the beginning of the path and make a copy that the 
     33 function to strip the beginning of the path and make a copy that the
    3234 caller can modify.  Note that the caller is responsible for releasing
    3335 the memory allocated here.
     
    3840        const char *p;
    3941        uint16 key_len = strlen(KEY_SHARES);
    40        
     42
    4143        /*
    4244         * sanity check...this really should never be True.
     
    4446         * the path buffer in the extreme case.
    4547         */
    46        
     48
    4749        if ( strlen(path) < key_len ) {
    4850                DEBUG(0,("trim_reg_path: Registry path too short! [%s]\n", path));
    4951                return NULL;
    5052        }
    51        
    52        
     53
    5354        p = path + strlen( KEY_SHARES );
    54        
     55
    5556        if ( *p == '\\' )
    5657                p++;
    57        
     58
    5859        if ( *p )
    5960                return SMB_STRDUP(p);
     
    6667 Caller is responsible for freeing memory to **subkeys
    6768 *********************************************************************/
    68  
     69
    6970static int shares_subkey_info( const char *key, struct regsubkey_ctr *subkey_ctr )
    7071{
     
    7273        bool            top_level = False;
    7374        int             num_subkeys = 0;
    74        
    75         DEBUG(10,("printing_subkey_info: key=>[%s]\n", key));
    76        
     75
     76        DEBUG(10, ("shares_subkey_info: key=>[%s]\n", key));
     77
    7778        path = trim_reg_path( key );
    78        
     79
    7980        /* check to see if we are dealing with the top level key */
    80        
     81
    8182        if ( !path )
    8283                top_level = True;
    83                
     84
    8485        if ( top_level ) {
    8586                num_subkeys = 1;
     
    9091                num_subkeys = handle_share_subpath( path, subkey_ctr, NULL );
    9192#endif
    92        
     93
    9394        SAFE_FREE( path );
    94        
     95
    9596        return num_subkeys;
    9697}
     
    106107        bool            top_level = False;
    107108        int             num_values = 0;
    108        
    109         DEBUG(10,("printing_value_info: key=>[%s]\n", key));
    110        
     109
     110        DEBUG(10, ("shares_value_info: key=>[%s]\n", key));
     111
    111112        path = trim_reg_path( key );
    112        
     113
    113114        /* check to see if we are dealing with the top level key */
    114        
     115
    115116        if ( !path )
    116117                top_level = True;
    117        
     118
    118119        /* fill in values from the getprinterdata_printer_server() */
    119120        if ( top_level )
     
    123124                num_values = handle_printing_subpath( path, NULL, val );
    124125#endif
    125                
     126
    126127        SAFE_FREE(path);
    127        
     128
    128129        return num_values;
    129130}
     
    131132/**********************************************************************
    132133 Stub function which always returns failure since we don't want
    133  people storing printing information directly via regostry calls
     134 people storing share information directly via registry calls
    134135 (for now at least)
    135136 *********************************************************************/
     
    142143/**********************************************************************
    143144 Stub function which always returns failure since we don't want
    144  people storing printing information directly via regostry calls
     145 people storing share information directly via registry calls
    145146 (for now at least)
    146147 *********************************************************************/
  • trunk/server/source3/registry/reg_backend_smbconf.c

    r414 r745  
    2020
    2121#include "includes.h"
     22#include "registry.h"
     23#include "lib/privileges.h"
    2224
    2325#undef DBGC_CLASS
     
    5860static bool smbconf_reg_access_check(const char *keyname, uint32 requested,
    5961                                     uint32 *granted,
    60                                      const struct nt_user_token *token)
     62                                     const struct security_token *token)
    6163{
    62         if (!(user_has_privileges(token, &se_disk_operators))) {
     64        if (!security_token_has_privilege(token, SEC_PRIV_DISK_OPERATOR)) {
    6365                return False;
    6466        }
  • trunk/server/source3/registry/reg_backend_tcpip_params.c

    r414 r745  
    2626
    2727#include "includes.h"
     28#include "registry.h"
     29#include "reg_objects.h"
    2830
    2931#undef DBGC_CLASS
  • trunk/server/source3/registry/reg_cachehook.c

    r414 r745  
    33 *  Virtual Windows Registry Layer
    44 *  Copyright (C) Gerald Carter                     2002.
     5 *  Copyright (C) Michael Adam                      2008
    56 *
    67 *  This program is free software; you can redistribute it and/or modify
     
    2223#include "includes.h"
    2324#include "adt_tree.h"
     25#include "registry.h"
     26#include "reg_cachehook.h"
    2427
    2528#undef DBGC_CLASS
    2629#define DBGC_CLASS DBGC_REGISTRY
    2730
    28 static SORTED_TREE *cache_tree = NULL;
     31static struct sorted_tree *cache_tree = NULL;
    2932extern struct registry_ops regdb_ops;           /* these are the default */
    3033
     
    4144        if (tmp_path == NULL) {
    4245                DEBUG(0, ("talloc_asprintf failed!\n"));
    43                 return WERR_NOMEM;
    44         }
    45 
    46         tmp_path = talloc_string_sub(mem_ctx, tmp_path, "\\", "/");
    47         if (tmp_path == NULL) {
    48                 DEBUG(0, ("talloc_string_sub_failed!\n"));
    4946                return WERR_NOMEM;
    5047        }
     
    6562        }
    6663
    67         cache_tree = pathtree_init(&regdb_ops, NULL);
     64        cache_tree = pathtree_init(&regdb_ops);
    6865        if (cache_tree == NULL) {
    6966                return WERR_NOMEM;
     
    7774/**********************************************************************
    7875 Add a new registry hook to the cache.  Note that the keyname
    79  is not in the exact format that a SORTED_TREE expects.
     76 is not in the exact format that a struct sorted_tree expects.
    8077 *********************************************************************/
    8178
  • trunk/server/source3/registry/reg_dispatcher.c

    r414 r745  
    2525
    2626#include "includes.h"
     27#include "registry.h"
     28#include "reg_dispatcher.h"
     29#include "../libcli/security/security.h"
    2730
    2831#undef DBGC_CLASS
     
    3538********************************************************************/
    3639
    37 static WERROR construct_registry_sd(TALLOC_CTX *ctx, SEC_DESC **psd)
    38 {
    39         SEC_ACE ace[3];
     40static WERROR construct_registry_sd(TALLOC_CTX *ctx, struct security_descriptor **psd)
     41{
     42        struct security_ace ace[3];
    4043        size_t i = 0;
    41         SEC_DESC *sd;
    42         SEC_ACL *theacl;
     44        struct security_descriptor *sd;
     45        struct security_acl *theacl;
    4346        size_t sd_size;
    4447
     
    6568        }
    6669
    67         sd = make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE,
     70        sd = make_sec_desc(ctx, SD_REVISION, SEC_DESC_SELF_RELATIVE,
    6871                           &global_sid_Builtin_Administrators,
    6972                           &global_sid_System, NULL, theacl,
     
    160163bool regkey_access_check(struct registry_key_handle *key, uint32 requested,
    161164                         uint32 *granted,
    162                          const struct nt_user_token *token )
    163 {
    164         SEC_DESC *sec_desc;
     165                         const struct security_token *token )
     166{
     167        struct security_descriptor *sec_desc;
    165168        NTSTATUS status;
    166169        WERROR err;
     170
     171        /* root free-pass, like we have on all other pipes like samr, lsa, etc. */
     172        if (geteuid() == sec_initial_uid()) {
     173                *granted = REG_KEY_ALL;
     174                return true;
     175        }
    167176
    168177        /* use the default security check if the backend has not defined its
  • trunk/server/source3/registry/reg_init_basic.c

    r414 r745  
    1919
    2020#include "includes.h"
     21#include "registry.h"
     22#include "reg_init_basic.h"
     23#include "reg_cachehook.h"
     24#include "reg_backend_db.h"
    2125
    2226#undef DBGC_CLASS
  • trunk/server/source3/registry/reg_init_full.c

    r414 r745  
    2222
    2323#include "includes.h"
     24#include "registry.h"
     25#include "reg_cachehook.h"
     26#include "reg_backend_db.h"
     27#include "reg_init_basic.h"
     28#include "reg_init_full.h"
    2429
    2530#undef DBGC_CLASS
     
    4146/* #define REG_TDB_ONLY         1 */
    4247
     48struct registry_hook {
     49        const char      *keyname;       /* full path to name of key */
     50        struct registry_ops     *ops;   /* registry function hooks */
     51};
     52
    4353struct registry_hook reg_hooks[] = {
    4454#ifndef REG_TDB_ONLY
    45   { KEY_PRINTING,               &printing_ops },
    46   { KEY_PRINTING_2K,            &printing_ops },
    47   { KEY_PRINTING_PORTS,         &printing_ops },
     55  { KEY_PRINTING "\\Printers",  &printing_ops },
     56  { KEY_PRINTING_2K,            &regdb_ops },
     57  { KEY_PRINTING_PORTS,         &regdb_ops },
    4858  { KEY_SHARES,                 &shares_reg_ops },
    4959  { KEY_SMBCONF,                &smbconf_reg_ops },
     
    8595                reghook_dump_cache(20);
    8696
    87         /* add any keys for other services */
    88 
    89         svcctl_init_keys();
    90         eventlog_init_keys();
    91         perfcount_init_keys();
    92 
    9397fail:
    9498        /* close and let each smbd open up as necessary */
  • trunk/server/source3/registry/reg_init_smbconf.c

    r414 r745  
    1919
    2020#include "includes.h"
     21#include "registry.h"
     22#include "reg_cachehook.h"
     23#include "reg_backend_db.h"
     24#include "reg_init_basic.h"
     25#include "reg_init_smbconf.h"
    2126
    2227#undef DBGC_CLASS
     
    2429
    2530extern struct registry_ops smbconf_reg_ops;
    26 
    27 /*
    28  * create a fake token just with enough rights to
    29  * locally access the registry:
    30  *
    31  * - builtin administrators sid
    32  * - disk operators privilege
    33  */
    34 NTSTATUS registry_create_admin_token(TALLOC_CTX *mem_ctx,
    35                                      NT_USER_TOKEN **ptoken)
    36 {
    37         NTSTATUS status;
    38         NT_USER_TOKEN *token = NULL;
    39 
    40         if (ptoken == NULL) {
    41                 return NT_STATUS_INVALID_PARAMETER;
    42         }
    43 
    44         token = TALLOC_ZERO_P(mem_ctx, NT_USER_TOKEN);
    45         if (token == NULL) {
    46                 DEBUG(1, ("talloc failed\n"));
    47                 status = NT_STATUS_NO_MEMORY;
    48                 goto done;
    49         }
    50         token->privileges = se_disk_operators;
    51         status = add_sid_to_array(token, &global_sid_Builtin_Administrators,
    52                                   &token->user_sids, &token->num_sids);
    53         if (!NT_STATUS_IS_OK(status)) {
    54                 DEBUG(1, ("Error adding builtin administrators sid "
    55                           "to fake token.\n"));
    56                 goto done;
    57         }
    58 
    59         *ptoken = token;
    60 
    61 done:
    62         return status;
    63 }
    6431
    6532/*
  • trunk/server/source3/registry/reg_objects.c

    r414 r745  
    33 *  Virtual Windows Registry Layer
    44 *  Copyright (C) Gerald Carter                     2002-2005
     5 *  Copyright (C) Michael Adam                      2007-2010
    56 *
    67 *  This program is free software; you can redistribute it and/or modify
     
    2122
    2223#include "includes.h"
     24#include "registry.h"
     25#include "reg_objects.h"
     26#include "util_tdb.h"
     27#include "dbwrap.h"
     28#include "../libcli/registry/util_reg.h"
    2329
    2430#undef DBGC_CLASS
    2531#define DBGC_CLASS DBGC_REGISTRY
     32
     33/* low level structure to contain registry values */
     34
     35struct regval_blob {
     36        fstring         valuename;
     37        uint32_t        type;
     38        /* this should be encapsulated in an RPC_DATA_BLOB */
     39        uint32_t        size;   /* in bytes */
     40        uint8_t         *data_p;
     41};
     42
     43/* container for registry values */
     44
     45struct regval_ctr {
     46        uint32_t num_values;
     47        struct regval_blob **values;
     48        int seqnum;
     49};
    2650
    2751struct regsubkey_ctr {
     
    109133static WERROR regsubkey_ctr_hash_keyname(struct regsubkey_ctr *ctr,
    110134                                         const char *keyname,
    111                                          uint32 idx)
     135                                         uint32_t idx)
    112136{
    113137        WERROR werr;
     
    115139        werr = ntstatus_to_werror(dbwrap_store_bystring_upper(ctr->subkeys_hash,
    116140                                                keyname,
    117                                                 make_tdb_data((uint8 *)&idx,
     141                                                make_tdb_data((uint8_t *)&idx,
    118142                                                              sizeof(idx)),
    119143                                                TDB_REPLACE));
     
    143167static WERROR regsubkey_ctr_index_for_keyname(struct regsubkey_ctr *ctr,
    144168                                              const char *keyname,
    145                                               uint32 *idx)
     169                                              uint32_t *idx)
    146170{
    147171        TDB_DATA data;
     
    162186
    163187        if (idx != NULL) {
    164                 *idx = *(uint32 *)data.dptr;
     188                *idx = *(uint32_t *)data.dptr;
    165189        }
    166190
     
    218242{
    219243        WERROR werr;
    220         uint32 idx, j;
     244        uint32_t idx, j;
    221245
    222246        if (keyname == NULL) {
     
    293317 */
    294318
     319/**
     320 * allocate a regval_ctr structure.
     321 */
     322WERROR regval_ctr_init(TALLOC_CTX *mem_ctx, struct regval_ctr **ctr)
     323{
     324        if (ctr == NULL) {
     325                return WERR_INVALID_PARAM;
     326        }
     327
     328        *ctr = talloc_zero(mem_ctx, struct regval_ctr);
     329        if (*ctr == NULL) {
     330                return WERR_NOMEM;
     331        }
     332
     333        return WERR_OK;
     334}
     335
    295336/***********************************************************************
    296337 How many keys does the container hold ?
     
    328369        if ( val->data_p && val->size )
    329370        {
    330                 if ( !(copy->data_p = (uint8 *)memdup( val->data_p,
     371                if ( !(copy->data_p = (uint8_t *)memdup( val->data_p,
    331372                                                       val->size )) ) {
    332373                        DEBUG(0,("dup_registry_value: memdup() failed for [%d] "
     
    359400 *********************************************************************/
    360401
    361 uint8* regval_data_p(struct regval_blob *val)
     402uint8_t* regval_data_p(struct regval_blob *val)
    362403{
    363404        return val->data_p;
     
    367408 *********************************************************************/
    368409
    369 uint32 regval_size(struct regval_blob *val)
     410uint32_t regval_size(struct regval_blob *val)
    370411{
    371412        return val->size;
     
    383424 *********************************************************************/
    384425
    385 uint32 regval_type(struct regval_blob *val)
     426uint32_t regval_type(struct regval_blob *val)
    386427{
    387428        return val->type;
     
    394435
    395436struct regval_blob *regval_ctr_specific_value(struct regval_ctr *ctr,
    396                                               uint32 idx)
     437                                              uint32_t idx)
    397438{
    398439        if ( !(idx < ctr->num_values) )
     
    423464
    424465struct regval_blob *regval_compose(TALLOC_CTX *ctx, const char *name,
    425                                    uint16 type,
    426                                    const char *data_p, size_t size)
     466                                   uint32_t type,
     467                                   const uint8_t *data_p, size_t size)
    427468{
    428469        struct regval_blob *regval = TALLOC_P(ctx, struct regval_blob);
     
    435476        regval->type = type;
    436477        if (size) {
    437                 regval->data_p = (uint8 *)TALLOC_MEMDUP(regval, data_p, size);
     478                regval->data_p = (uint8_t *)TALLOC_MEMDUP(regval, data_p, size);
    438479                if (!regval->data_p) {
    439480                        TALLOC_FREE(regval);
     
    452493 **********************************************************************/
    453494
    454 int regval_ctr_addvalue(struct regval_ctr *ctr, const char *name, uint16 type,
    455                         const char *data_p, size_t size)
     495int regval_ctr_addvalue(struct regval_ctr *ctr, const char *name, uint32_t type,
     496                        const uint8_t *data_p, size_t size)
    456497{
    457498        if ( !name )
     
    503544
    504545        return regval_ctr_addvalue(ctr, name, REG_SZ,
    505                                    (const char *)blob.data,
     546                                   (const uint8_t *)blob.data,
    506547                                   blob.length);
    507548}
     
    520561
    521562        return regval_ctr_addvalue(ctr, name, REG_MULTI_SZ,
    522                                    (const char *)blob.data,
     563                                   (const uint8_t *)blob.data,
    523564                                   blob.length);
    524565}
     
    532573        if ( val ) {
    533574                regval_ctr_addvalue(ctr, val->valuename, val->type,
    534                                     (char *)val->data_p, val->size);
     575                                    (uint8_t *)val->data_p, val->size);
    535576        }
    536577
     
    586627}
    587628
    588 /***********************************************************************
    589  return the data_p as a uint32
    590  **********************************************************************/
    591 
    592 uint32 regval_dword(struct regval_blob *val)
    593 {
    594         uint32 data;
     629int regval_ctr_get_seqnum(struct regval_ctr *ctr)
     630{
     631        if (ctr == NULL) {
     632                return -1;
     633        }
     634
     635        return ctr->seqnum;
     636}
     637
     638WERROR regval_ctr_set_seqnum(struct regval_ctr *ctr, int seqnum)
     639{
     640        if (ctr == NULL) {
     641                return WERR_INVALID_PARAM;
     642        }
     643
     644        ctr->seqnum = seqnum;
     645
     646        return WERR_OK;
     647}
     648
     649/***********************************************************************
     650 return the data_p as a uint32_t
     651 **********************************************************************/
     652
     653uint32_t regval_dword(struct regval_blob *val)
     654{
     655        uint32_t data;
    595656
    596657        data = IVAL( regval_data_p(val), 0 );
  • trunk/server/source3/registry/reg_perfcount.c

    r414 r745  
    2121
    2222#include "includes.h"
     23#include "system/filesys.h"
     24#include "../librpc/gen_ndr/perfcount.h"
     25#include "registry.h"
     26#include "reg_perfcount.h"
     27#include "../libcli/registry/util_reg.h"
     28#include "util_tdb.h"
    2329
    2430#undef DBGC_CLASS
     
    4248        TALLOC_CTX *ctx = talloc_tos();
    4349
     50        path = state_path(PERFCOUNTDIR);
     51        if (!directory_exist(path)) {
     52                mkdir(path, 0755);
     53        }
     54
    4455        path = talloc_asprintf(ctx, "%s/%s", PERFCOUNTDIR, dbname);
    4556        if (!path) {
     
    5061        TALLOC_FREE(path);
    5162        return ret;
    52 }
    53 
    54 /*********************************************************************
    55 *********************************************************************/
    56 
    57 void perfcount_init_keys( void )
    58 {
    59         char *p = state_path(PERFCOUNTDIR);
    60 
    61         /* no registry keys; just create the perfmon directory */
    62 
    63         if ( !directory_exist( p ) )
    64                 mkdir( p, 0755 );
    65 
    66         return;
    6763}
    6864
     
    619615        memset(buf, 0, PERFCOUNT_MAX_LEN);
    620616        memcpy(buf, data.dptr, data.dsize);
    621         begin = index(buf, '[');
    622         end = index(buf, ']');
     617        begin = strchr(buf, '[');
     618        end = strchr(buf, ']');
    623619        if(begin == NULL || end == NULL)
    624620                return False;
     
    626622
    627623        while(start < end) {
    628                 stop = index(start, ',');
     624                stop = strchr(start, ',');
    629625                if(stop == NULL)
    630626                        stop = end;
  • trunk/server/source3/registry/regfio.c

    r414 r745  
    1919
    2020#include "includes.h"
     21#include "system/filesys.h"
    2122#include "regfio.h"
     23#include "../librpc/gen_ndr/ndr_security.h"
     24#include "../libcli/security/security_descriptor.h"
    2225
    2326#undef DBGC_CLASS
     
    3033 ******************************************************************/
    3134
     35#if defined(PARANOID_MALLOC_CHECKER)
     36#define PRS_ALLOC_MEM(ps, type, count) (type *)prs_alloc_mem_((ps),sizeof(type),(count))
     37#else
     38#define PRS_ALLOC_MEM(ps, type, count) (type *)prs_alloc_mem((ps),sizeof(type),(count))
     39#endif
     40
     41/*******************************************************************
     42 Reads or writes an NTTIME structure.
     43********************************************************************/
     44
     45static bool smb_io_time(const char *desc, NTTIME *nttime, prs_struct *ps, int depth)
     46{
     47        uint32 low, high;
     48        if (nttime == NULL)
     49                return False;
     50
     51        prs_debug(ps, depth, desc, "smb_io_time");
     52        depth++;
     53
     54        if(!prs_align(ps))
     55                return False;
     56
     57        if (MARSHALLING(ps)) {
     58                low = *nttime & 0xFFFFFFFF;
     59                high = *nttime >> 32;
     60        }
     61
     62        if(!prs_uint32("low ", ps, depth, &low)) /* low part */
     63                return False;
     64        if(!prs_uint32("high", ps, depth, &high)) /* high part */
     65                return False;
     66
     67        if (UNMARSHALLING(ps)) {
     68                *nttime = (((uint64_t)high << 32) + low);
     69        }
     70
     71        return True;
     72}
    3273
    3374/*******************************************************************
     
    954995*******************************************************************/
    955996
    956 static REGF_SK_REC* find_sk_record_by_sec_desc( REGF_FILE *file, SEC_DESC *sd )
     997static REGF_SK_REC* find_sk_record_by_sec_desc( REGF_FILE *file, struct security_descriptor *sd )
    957998{
    958999        REGF_SK_REC *p;
     
    14381479
    14391480        hbin->free_off       = HBIN_HEADER_REC_SIZE;
    1440         hbin->free_size      = block_size - hbin->free_off + sizeof(uint32);;
     1481        hbin->free_size      = block_size - hbin->free_off + sizeof(uint32);
    14411482
    14421483        hbin->block_size     = block_size;
     
    15681609*******************************************************************/
    15691610
    1570 static uint32 sk_record_data_size( SEC_DESC * sd )
     1611static uint32 sk_record_data_size( struct security_descriptor * sd )
    15711612{
    15721613        uint32 size, size_mod8;
     
    15761617        /* the record size is sizeof(hdr) + name + static members + data_size_field */
    15771618
    1578         size = sizeof(uint32)*5 + ndr_size_security_descriptor(sd, NULL, 0) + sizeof(uint32);
     1619        size = sizeof(uint32)*5 + ndr_size_security_descriptor(sd, 0) + sizeof(uint32);
    15791620
    15801621        /* multiple of 8 */
     
    17181759 REGF_NK_REC* regfio_write_key( REGF_FILE *file, const char *name,
    17191760                               struct regval_ctr *values, struct regsubkey_ctr *subkeys,
    1720                                SEC_DESC *sec_desc, REGF_NK_REC *parent )
     1761                               struct security_descriptor *sec_desc, REGF_NK_REC *parent )
    17211762{
    17221763        REGF_NK_REC *nk;
     
    17681809
    17691810                /* sort the list by keyname */
    1770 
    1771                 qsort( parent->subkeys.hashes, parent->subkey_index, sizeof(REGF_HASH_REC), QSORT_CAST hashrec_cmp );
     1811                TYPESAFE_QSORT(parent->subkeys.hashes, parent->subkey_index, hashrec_cmp);
    17721812
    17731813                if ( !hbin_prs_lf_records( "lf_rec", parent->subkeys.hbin, 0, parent ) )
     
    18071847                       
    18081848                        /* size value must be self-inclusive */
    1809                         nk->sec_desc->size      = ndr_size_security_descriptor(sec_desc, NULL, 0)
     1849                        nk->sec_desc->size      = ndr_size_security_descriptor(sec_desc, 0)
    18101850                                + sizeof(uint32);
    18111851
     
    18161856                           offsets to ourself. */
    18171857
    1818                         if ( nk->sec_desc->prev ) {
    1819                                 REGF_SK_REC *prev = nk->sec_desc->prev;
     1858                        if ( DLIST_PREV(nk->sec_desc) ) {
     1859                                REGF_SK_REC *prev = DLIST_PREV(nk->sec_desc);
    18201860
    18211861                                nk->sec_desc->prev_sk_off = prev->hbin_off + prev->hbin->first_hbin_off - HBIN_HDR_SIZE;
Note: See TracChangeset for help on using the changeset viewer.