LCOV - code coverage report
Current view: top level - source4/torture/rpc - winreg.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 543 1246 43.6 %
Date: 2024-04-21 15:09:00 Functions: 32 69 46.4 %

          Line data    Source code
       1             : /*
       2             :    Unix SMB/CIFS implementation.
       3             :    test suite for winreg rpc operations
       4             : 
       5             :    Copyright (C) Tim Potter 2003
       6             :    Copyright (C) Jelmer Vernooij 2004-2007
       7             :    Copyright (C) Günther Deschner 2007,2010
       8             : 
       9             :    This program is free software; you can redistribute it and/or modify
      10             :    it under the terms of the GNU General Public License as published by
      11             :    the Free Software Foundation; either version 3 of the License, or
      12             :    (at your option) any later version.
      13             : 
      14             :    This program is distributed in the hope that it will be useful,
      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      17             :    GNU General Public License for more details.
      18             : 
      19             :    You should have received a copy of the GNU General Public License
      20             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      21             : */
      22             : 
      23             : #include "includes.h"
      24             : #include "librpc/gen_ndr/ndr_winreg_c.h"
      25             : #include "librpc/gen_ndr/ndr_security.h"
      26             : #include "libcli/security/security.h"
      27             : #include "torture/rpc/torture_rpc.h"
      28             : #include "param/param.h"
      29             : #include "lib/registry/registry.h"
      30             : 
      31             : #define TEST_KEY_BASE "winreg_torture_test"
      32             : #define TEST_KEY1 "spottyfoot"
      33             : #define TEST_KEY2 "with a SD (#1)"
      34             : #define TEST_KEY3 "with a subkey"
      35             : #define TEST_KEY4 "sd_tests"
      36             : #define TEST_SUBKEY "subkey"
      37             : #define TEST_SUBKEY_SD  "subkey_sd"
      38             : #define TEST_SUBSUBKEY_SD "subkey_sd\\subsubkey_sd"
      39             : #define TEST_VALUE "torture_value_name"
      40             : #define TEST_KEY_VOLATILE "torture_volatile_key"
      41             : #define TEST_SUBKEY_VOLATILE "torture_volatile_subkey"
      42             : #define TEST_KEY_SYMLINK "torture_symlink_key"
      43             : #define TEST_KEY_SYMLINK_DEST "torture_symlink_dest"
      44             : 
      45             : #define TEST_SID "S-1-5-21-1234567890-1234567890-1234567890-500"
      46             : 
      47           0 : static void init_lsa_StringLarge(struct lsa_StringLarge *name, const char *s)
      48             : {
      49           0 :         name->string = s;
      50           0 : }
      51             : 
      52       19554 : static void init_winreg_String(struct winreg_String *name, const char *s)
      53             : {
      54       19554 :         name->name = s;
      55       19554 :         if (s) {
      56       14922 :                 name->name_len = 2 * (strlen_m(s) + 1);
      57       14922 :                 name->name_size = name->name_len;
      58             :         } else {
      59        4632 :                 name->name_len = 0;
      60        4632 :                 name->name_size = 0;
      61             :         }
      62       19554 : }
      63             : 
      64         348 : static bool test_GetVersion(struct dcerpc_binding_handle *b,
      65             :                             struct torture_context *tctx,
      66             :                             struct policy_handle *handle)
      67             : {
      68           0 :         struct winreg_GetVersion r;
      69           0 :         uint32_t v;
      70             : 
      71         348 :         torture_comment(tctx, "Testing GetVersion\n");
      72             : 
      73         348 :         ZERO_STRUCT(r);
      74         348 :         r.in.handle = handle;
      75         348 :         r.out.version = &v;
      76             : 
      77         348 :         torture_assert_ntstatus_ok(tctx, dcerpc_winreg_GetVersion_r(b, tctx, &r),
      78             :                                    "GetVersion failed");
      79             : 
      80         348 :         torture_assert_werr_ok(tctx, r.out.result, "GetVersion failed");
      81             : 
      82         348 :         return true;
      83             : }
      84             : 
      85         268 : static bool test_NotifyChangeKeyValue(struct dcerpc_binding_handle *b,
      86             :                                       struct torture_context *tctx,
      87             :                                       struct policy_handle *handle)
      88             : {
      89           0 :         struct winreg_NotifyChangeKeyValue r;
      90             : 
      91         268 :         ZERO_STRUCT(r);
      92         268 :         r.in.handle = handle;
      93         268 :         r.in.watch_subtree = true;
      94         268 :         r.in.notify_filter = 0;
      95         268 :         r.in.unknown = r.in.unknown2 = 0;
      96         268 :         init_winreg_String(&r.in.string1, NULL);
      97         268 :         init_winreg_String(&r.in.string2, NULL);
      98             : 
      99         268 :         torture_assert_ntstatus_ok(tctx,
     100             :                                    dcerpc_winreg_NotifyChangeKeyValue_r(b, tctx, &r),
     101             :                                    "NotifyChangeKeyValue failed");
     102             : 
     103         268 :         if (!W_ERROR_IS_OK(r.out.result)) {
     104         268 :                 torture_comment(tctx,
     105             :                                 "NotifyChangeKeyValue failed - %s - not considering\n",
     106             :                                 win_errstr(r.out.result));
     107         268 :                 return true;
     108             :         }
     109             : 
     110           0 :         return true;
     111             : }
     112             : 
     113        1827 : static bool test_CreateKey_opts(struct torture_context *tctx,
     114             :                                 struct dcerpc_binding_handle *b,
     115             :                                 struct policy_handle *handle,
     116             :                                 const char *name,
     117             :                                 const char *kclass,
     118             :                                 uint32_t options,
     119             :                                 uint32_t access_mask,
     120             :                                 struct winreg_SecBuf *secdesc,
     121             :                                 WERROR expected_result,
     122             :                                 enum winreg_CreateAction *action_taken_p,
     123             :                                 struct policy_handle *new_handle_p)
     124             : {
     125           0 :         struct winreg_CreateKey r;
     126           0 :         struct policy_handle newhandle;
     127        1827 :         enum winreg_CreateAction action_taken = 0;
     128             : 
     129        1827 :         torture_comment(tctx, "Testing CreateKey(%s)\n", name);
     130             : 
     131        1827 :         ZERO_STRUCT(r);
     132        1827 :         r.in.handle = handle;
     133        1827 :         init_winreg_String(&r.in.name, name);
     134        1827 :         init_winreg_String(&r.in.keyclass, kclass);
     135        1827 :         r.in.options = options;
     136        1827 :         r.in.access_mask = access_mask;
     137        1827 :         r.in.action_taken = &action_taken;
     138        1827 :         r.in.secdesc = secdesc;
     139        1827 :         r.out.new_handle = &newhandle;
     140        1827 :         r.out.action_taken = &action_taken;
     141             : 
     142        1827 :         torture_assert_ntstatus_ok(tctx, dcerpc_winreg_CreateKey_r(b, tctx, &r),
     143             :                                    "CreateKey failed");
     144             : 
     145        1827 :         torture_assert_werr_equal(tctx, r.out.result, expected_result, "CreateKey failed");
     146             : 
     147        1827 :         if (new_handle_p) {
     148         435 :                 *new_handle_p = newhandle;
     149             :         }
     150        1827 :         if (action_taken_p) {
     151         435 :                 *action_taken_p = *r.out.action_taken;
     152             :         }
     153             : 
     154        1827 :         return true;
     155             : }
     156             : 
     157        1392 : static bool test_CreateKey(struct dcerpc_binding_handle *b,
     158             :                            struct torture_context *tctx,
     159             :                            struct policy_handle *handle, const char *name,
     160             :                            const char *kclass)
     161             : {
     162        2784 :         return test_CreateKey_opts(tctx, b, handle, name, kclass,
     163             :                                    REG_OPTION_NON_VOLATILE,
     164             :                                    SEC_FLAG_MAXIMUM_ALLOWED,
     165             :                                    NULL, /* secdesc */
     166        1392 :                                    WERR_OK,
     167             :                                    NULL, /* action_taken */
     168             :                                    NULL /* new_handle */);
     169             : }
     170             : 
     171             : /*
     172             :   createkey testing with a SD
     173             : */
     174           0 : static bool test_CreateKey_sd(struct dcerpc_binding_handle *b,
     175             :                               struct torture_context *tctx,
     176             :                               struct policy_handle *handle, const char *name,
     177             :                               const char *kclass,
     178             :                               struct policy_handle *newhandle)
     179             : {
     180             :         struct winreg_CreateKey r;
     181           0 :         enum winreg_CreateAction action_taken = 0;
     182             :         struct security_descriptor *sd;
     183             :         DATA_BLOB sdblob;
     184             :         struct winreg_SecBuf secbuf;
     185             : 
     186           0 :         sd = security_descriptor_dacl_create(tctx,
     187             :                                         0,
     188             :                                         NULL, NULL,
     189             :                                         SID_NT_AUTHENTICATED_USERS,
     190             :                                         SEC_ACE_TYPE_ACCESS_ALLOWED,
     191             :                                         SEC_GENERIC_ALL,
     192             :                                         SEC_ACE_FLAG_OBJECT_INHERIT |
     193             :                                         SEC_ACE_FLAG_CONTAINER_INHERIT,
     194             :                                         NULL);
     195             : 
     196           0 :         torture_assert_ndr_success(tctx,
     197             :                 ndr_push_struct_blob(&sdblob, tctx, sd,
     198             :                                      (ndr_push_flags_fn_t)ndr_push_security_descriptor),
     199             :                                      "Failed to push security_descriptor ?!\n");
     200             : 
     201           0 :         secbuf.sd.data = sdblob.data;
     202           0 :         secbuf.sd.len = sdblob.length;
     203           0 :         secbuf.sd.size = sdblob.length;
     204           0 :         secbuf.length = sdblob.length-10;
     205           0 :         secbuf.inherit = 0;
     206             : 
     207           0 :         ZERO_STRUCT(r);
     208           0 :         r.in.handle = handle;
     209           0 :         r.out.new_handle = newhandle;
     210           0 :         init_winreg_String(&r.in.name, name);
     211           0 :         init_winreg_String(&r.in.keyclass, kclass);
     212           0 :         r.in.options = 0x0;
     213           0 :         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
     214           0 :         r.in.action_taken = r.out.action_taken = &action_taken;
     215           0 :         r.in.secdesc = &secbuf;
     216             : 
     217           0 :         torture_assert_ntstatus_ok(tctx, dcerpc_winreg_CreateKey_r(b, tctx, &r),
     218             :                                    "CreateKey with sd failed");
     219             : 
     220           0 :         torture_assert_werr_ok(tctx, r.out.result, "CreateKey with sd failed");
     221             : 
     222           0 :         return true;
     223             : }
     224             : 
     225           0 : static bool _test_GetKeySecurity(struct dcerpc_pipe *p,
     226             :                                  struct torture_context *tctx,
     227             :                                  struct policy_handle *handle,
     228             :                                  uint32_t *sec_info_ptr,
     229             :                                  WERROR get_werr,
     230             :                                  struct security_descriptor **sd_out)
     231             : {
     232           0 :         struct winreg_GetKeySecurity r;
     233           0 :         struct security_descriptor *sd = NULL;
     234           0 :         uint32_t sec_info;
     235           0 :         DATA_BLOB sdblob;
     236           0 :         struct dcerpc_binding_handle *b = p->binding_handle;
     237             : 
     238           0 :         if (sec_info_ptr) {
     239           0 :                 sec_info = *sec_info_ptr;
     240             :         } else {
     241           0 :                 sec_info = SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL;
     242             :         }
     243             : 
     244           0 :         ZERO_STRUCT(r);
     245             : 
     246           0 :         r.in.handle = handle;
     247           0 :         r.in.sec_info = sec_info;
     248           0 :         r.in.sd = r.out.sd = talloc_zero(tctx, struct KeySecurityData);
     249           0 :         r.in.sd->size = 0x1000;
     250             : 
     251           0 :         torture_assert_ntstatus_ok(tctx,
     252             :                                    dcerpc_winreg_GetKeySecurity_r(b, tctx, &r),
     253             :                                    "GetKeySecurity failed");
     254             : 
     255           0 :         torture_assert_werr_equal(tctx, r.out.result, get_werr,
     256             :                                   "GetKeySecurity failed");
     257             : 
     258           0 :         sdblob.data = r.out.sd->data;
     259           0 :         sdblob.length = r.out.sd->len;
     260             : 
     261           0 :         sd = talloc_zero(tctx, struct security_descriptor);
     262             : 
     263           0 :         torture_assert_ndr_success(tctx,
     264             :                 ndr_pull_struct_blob(&sdblob, tctx, sd,
     265             :                                      (ndr_pull_flags_fn_t)ndr_pull_security_descriptor),
     266             :                                      "pull_security_descriptor failed");
     267             : 
     268           0 :         if (p->conn->flags & DCERPC_DEBUG_PRINT_OUT) {
     269           0 :                 NDR_PRINT_DEBUG(security_descriptor, sd);
     270             :         }
     271             : 
     272           0 :         if (sd_out) {
     273           0 :                 *sd_out = sd;
     274             :         } else {
     275           0 :                 talloc_free(sd);
     276             :         }
     277             : 
     278           0 :         return true;
     279             : }
     280             : 
     281           0 : static bool test_GetKeySecurity(struct dcerpc_pipe *p,
     282             :                                 struct torture_context *tctx,
     283             :                                 struct policy_handle *handle,
     284             :                                 struct security_descriptor **sd_out)
     285             : {
     286           0 :         return _test_GetKeySecurity(p, tctx, handle, NULL, WERR_OK, sd_out);
     287             : }
     288             : 
     289           0 : static bool _test_SetKeySecurity(struct dcerpc_pipe *p,
     290             :                                  struct torture_context *tctx,
     291             :                                  struct policy_handle *handle,
     292             :                                  uint32_t *sec_info_ptr,
     293             :                                  struct security_descriptor *sd,
     294             :                                  WERROR werr)
     295             : {
     296             :         struct winreg_SetKeySecurity r;
     297           0 :         struct KeySecurityData *sdata = NULL;
     298             :         DATA_BLOB sdblob;
     299             :         uint32_t sec_info;
     300           0 :         struct dcerpc_binding_handle *b = p->binding_handle;
     301             : 
     302           0 :         ZERO_STRUCT(r);
     303             : 
     304           0 :         if (sd && (p->conn->flags & DCERPC_DEBUG_PRINT_OUT)) {
     305           0 :                 NDR_PRINT_DEBUG(security_descriptor, sd);
     306             :         }
     307             : 
     308           0 :         torture_assert_ndr_success(tctx,
     309             :                 ndr_push_struct_blob(&sdblob, tctx, sd,
     310             :                                      (ndr_push_flags_fn_t)ndr_push_security_descriptor),
     311             :                                      "push_security_descriptor failed");
     312             : 
     313           0 :         sdata = talloc_zero(tctx, struct KeySecurityData);
     314           0 :         sdata->data = sdblob.data;
     315           0 :         sdata->size = sdblob.length;
     316           0 :         sdata->len = sdblob.length;
     317             : 
     318           0 :         if (sec_info_ptr) {
     319           0 :                 sec_info = *sec_info_ptr;
     320             :         } else {
     321           0 :                 sec_info = SECINFO_UNPROTECTED_SACL |
     322             :                            SECINFO_UNPROTECTED_DACL;
     323           0 :                 if (sd->owner_sid) {
     324           0 :                         sec_info |= SECINFO_OWNER;
     325             :                 }
     326           0 :                 if (sd->group_sid) {
     327           0 :                         sec_info |= SECINFO_GROUP;
     328             :                 }
     329           0 :                 if (sd->sacl) {
     330           0 :                         sec_info |= SECINFO_SACL;
     331             :                 }
     332           0 :                 if (sd->dacl) {
     333           0 :                         sec_info |= SECINFO_DACL;
     334             :                 }
     335             :         }
     336             : 
     337           0 :         r.in.handle = handle;
     338           0 :         r.in.sec_info = sec_info;
     339           0 :         r.in.sd = sdata;
     340             : 
     341           0 :         torture_assert_ntstatus_ok(tctx,
     342             :                                    dcerpc_winreg_SetKeySecurity_r(b, tctx, &r),
     343             :                                    "SetKeySecurity failed");
     344             : 
     345           0 :         torture_assert_werr_equal(tctx, r.out.result, werr,
     346             :                                   "SetKeySecurity failed");
     347             : 
     348           0 :         return true;
     349             : }
     350             : 
     351           0 : static bool test_SetKeySecurity(struct dcerpc_pipe *p,
     352             :                                 struct torture_context *tctx,
     353             :                                 struct policy_handle *handle,
     354             :                                 struct security_descriptor *sd)
     355             : {
     356           0 :         return _test_SetKeySecurity(p, tctx, handle, NULL, sd, WERR_OK);
     357             : }
     358             : 
     359         703 : static bool test_CloseKey(struct dcerpc_binding_handle *b,
     360             :                           struct torture_context *tctx,
     361             :                           struct policy_handle *handle)
     362             : {
     363           0 :         struct winreg_CloseKey r;
     364             : 
     365         703 :         ZERO_STRUCT(r);
     366         703 :         r.in.handle = r.out.handle = handle;
     367             : 
     368         703 :         torture_assert_ntstatus_ok(tctx, dcerpc_winreg_CloseKey_r(b, tctx, &r),
     369             :                                    "CloseKey failed");
     370             : 
     371         703 :         torture_assert_werr_ok(tctx, r.out.result, "CloseKey failed");
     372             : 
     373         703 :         return true;
     374             : }
     375             : 
     376         696 : static bool test_FlushKey(struct dcerpc_binding_handle *b,
     377             :                           struct torture_context *tctx,
     378             :                           struct policy_handle *handle)
     379             : {
     380           0 :         struct winreg_FlushKey r;
     381             : 
     382         696 :         ZERO_STRUCT(r);
     383         696 :         r.in.handle = handle;
     384             : 
     385         696 :         torture_assert_ntstatus_ok(tctx, dcerpc_winreg_FlushKey_r(b, tctx, &r),
     386             :                                    "FlushKey failed");
     387             : 
     388         696 :         torture_assert_werr_ok(tctx, r.out.result, "FlushKey failed");
     389             : 
     390         696 :         return true;
     391             : }
     392             : 
     393         804 : static bool test_OpenKey_opts(struct torture_context *tctx,
     394             :                               struct dcerpc_binding_handle *b,
     395             :                               struct policy_handle *hive_handle,
     396             :                               const char *keyname,
     397             :                               uint32_t options,
     398             :                               uint32_t access_mask,
     399             :                               struct policy_handle *key_handle,
     400             :                               WERROR expected_result)
     401             : {
     402           0 :         struct winreg_OpenKey r;
     403             : 
     404         804 :         ZERO_STRUCT(r);
     405         804 :         r.in.parent_handle = hive_handle;
     406         804 :         init_winreg_String(&r.in.keyname, keyname);
     407         804 :         r.in.options = options;
     408         804 :         r.in.access_mask = access_mask;
     409         804 :         r.out.handle = key_handle;
     410             : 
     411         804 :         torture_assert_ntstatus_ok(tctx, dcerpc_winreg_OpenKey_r(b, tctx, &r),
     412             :                                    "OpenKey failed");
     413             : 
     414         804 :         torture_assert_werr_equal(tctx, r.out.result, expected_result,
     415             :                                   "OpenKey failed");
     416             : 
     417         804 :         return true;
     418             : }
     419             : 
     420         452 : static bool test_OpenKey(struct dcerpc_binding_handle *b,
     421             :                          struct torture_context *tctx,
     422             :                          struct policy_handle *hive_handle,
     423             :                          const char *keyname, struct policy_handle *key_handle)
     424             : {
     425         904 :         return test_OpenKey_opts(tctx, b, hive_handle, keyname,
     426             :                                  REG_OPTION_NON_VOLATILE,
     427             :                                  SEC_FLAG_MAXIMUM_ALLOWED,
     428             :                                  key_handle,
     429         452 :                                  WERR_OK);
     430             : }
     431             : 
     432         696 : static bool test_Cleanup(struct dcerpc_binding_handle *b,
     433             :                          struct torture_context *tctx,
     434             :                          struct policy_handle *handle, const char *key)
     435             : {
     436           0 :         struct winreg_DeleteKey r;
     437             : 
     438         696 :         ZERO_STRUCT(r);
     439         696 :         r.in.handle = handle;
     440             : 
     441         696 :         init_winreg_String(&r.in.key, key);
     442         696 :         dcerpc_winreg_DeleteKey_r(b, tctx, &r);
     443             : 
     444         696 :         return true;
     445             : }
     446             : 
     447           0 : static bool _test_GetSetSecurityDescriptor(struct dcerpc_pipe *p,
     448             :                                            struct torture_context *tctx,
     449             :                                            struct policy_handle *handle,
     450             :                                            WERROR get_werr,
     451             :                                            WERROR set_werr)
     452             : {
     453           0 :         struct security_descriptor *sd = NULL;
     454             : 
     455           0 :         if (!_test_GetKeySecurity(p, tctx, handle, NULL, get_werr, &sd)) {
     456           0 :                 return false;
     457             :         }
     458             : 
     459           0 :         if (!_test_SetKeySecurity(p, tctx, handle, NULL, sd, set_werr)) {
     460           0 :                 return false;
     461             :         }
     462             : 
     463           0 :         return true;
     464             : }
     465             : 
     466           0 : static bool test_SecurityDescriptor(struct dcerpc_pipe *p,
     467             :                                     struct torture_context *tctx,
     468             :                                     struct policy_handle *handle,
     469             :                                     const char *key)
     470             : {
     471             :         struct policy_handle new_handle;
     472           0 :         bool ret = true;
     473           0 :         struct dcerpc_binding_handle *b = p->binding_handle;
     474             : 
     475           0 :         torture_comment(tctx, "SecurityDescriptor get & set\n");
     476             : 
     477           0 :         if (!test_OpenKey(b, tctx, handle, key, &new_handle)) {
     478           0 :                 return false;
     479             :         }
     480             : 
     481           0 :         if (!_test_GetSetSecurityDescriptor(p, tctx, &new_handle,
     482           0 :                                             WERR_OK, WERR_OK)) {
     483           0 :                 ret = false;
     484             :         }
     485             : 
     486           0 :         if (!test_CloseKey(b, tctx, &new_handle)) {
     487           0 :                 return false;
     488             :         }
     489             : 
     490           0 :         return ret;
     491             : }
     492             : 
     493           0 : static bool _test_SecurityDescriptor(struct dcerpc_pipe *p,
     494             :                                      struct torture_context *tctx,
     495             :                                      struct policy_handle *handle,
     496             :                                      uint32_t access_mask,
     497             :                                      const char *key,
     498             :                                      WERROR open_werr,
     499             :                                      WERROR get_werr,
     500             :                                      WERROR set_werr)
     501             : {
     502             :         struct policy_handle new_handle;
     503           0 :         bool ret = true;
     504           0 :         struct dcerpc_binding_handle *b = p->binding_handle;
     505             : 
     506           0 :         torture_assert(tctx,
     507             :                 test_OpenKey_opts(tctx, b, handle, key,
     508             :                                   REG_OPTION_NON_VOLATILE,
     509             :                                   access_mask,
     510             :                                   &new_handle,
     511             :                                   open_werr),
     512             :                 "failed to open key");
     513             : 
     514           0 :         if (!W_ERROR_IS_OK(open_werr)) {
     515           0 :                 return true;
     516             :         }
     517             : 
     518           0 :         if (!_test_GetSetSecurityDescriptor(p, tctx, &new_handle,
     519             :                                             get_werr, set_werr)) {
     520           0 :                 ret = false;
     521             :         }
     522             : 
     523           0 :         if (!test_CloseKey(b, tctx, &new_handle)) {
     524           0 :                 return false;
     525             :         }
     526             : 
     527           0 :         return ret;
     528             : }
     529             : 
     530           0 : static bool test_dacl_trustee_present(struct dcerpc_pipe *p,
     531             :                                       struct torture_context *tctx,
     532             :                                       struct policy_handle *handle,
     533             :                                       const struct dom_sid *sid)
     534             : {
     535           0 :         struct security_descriptor *sd = NULL;
     536             :         int i;
     537             : 
     538           0 :         if (!test_GetKeySecurity(p, tctx, handle, &sd)) {
     539           0 :                 return false;
     540             :         }
     541             : 
     542           0 :         if (!sd || !sd->dacl) {
     543           0 :                 return false;
     544             :         }
     545             : 
     546           0 :         for (i = 0; i < sd->dacl->num_aces; i++) {
     547           0 :                 if (dom_sid_equal(&sd->dacl->aces[i].trustee, sid)) {
     548           0 :                         return true;
     549             :                 }
     550             :         }
     551             : 
     552           0 :         return false;
     553             : }
     554             : 
     555           0 : static bool _test_dacl_trustee_present(struct dcerpc_pipe *p,
     556             :                                        struct torture_context *tctx,
     557             :                                        struct policy_handle *handle,
     558             :                                        const char *key,
     559             :                                        const struct dom_sid *sid)
     560             : {
     561             :         struct policy_handle new_handle;
     562           0 :         bool ret = true;
     563           0 :         struct dcerpc_binding_handle *b = p->binding_handle;
     564             : 
     565           0 :         if (!test_OpenKey(b, tctx, handle, key, &new_handle)) {
     566           0 :                 return false;
     567             :         }
     568             : 
     569           0 :         ret = test_dacl_trustee_present(p, tctx, &new_handle, sid);
     570             : 
     571           0 :         test_CloseKey(b, tctx, &new_handle);
     572             : 
     573           0 :         return ret;
     574             : }
     575             : 
     576           0 : static bool test_sacl_trustee_present(struct dcerpc_pipe *p,
     577             :                                       struct torture_context *tctx,
     578             :                                       struct policy_handle *handle,
     579             :                                       const struct dom_sid *sid)
     580             : {
     581           0 :         struct security_descriptor *sd = NULL;
     582             :         int i;
     583           0 :         uint32_t sec_info = SECINFO_SACL;
     584             : 
     585           0 :         if (!_test_GetKeySecurity(p, tctx, handle, &sec_info, WERR_OK, &sd)) {
     586           0 :                 return false;
     587             :         }
     588             : 
     589           0 :         if (!sd || !sd->sacl) {
     590           0 :                 return false;
     591             :         }
     592             : 
     593           0 :         for (i = 0; i < sd->sacl->num_aces; i++) {
     594           0 :                 if (dom_sid_equal(&sd->sacl->aces[i].trustee, sid)) {
     595           0 :                         return true;
     596             :                 }
     597             :         }
     598             : 
     599           0 :         return false;
     600             : }
     601             : 
     602           0 : static bool _test_sacl_trustee_present(struct dcerpc_pipe *p,
     603             :                                        struct torture_context *tctx,
     604             :                                        struct policy_handle *handle,
     605             :                                        const char *key,
     606             :                                        const struct dom_sid *sid)
     607             : {
     608             :         struct policy_handle new_handle;
     609           0 :         bool ret = true;
     610           0 :         struct dcerpc_binding_handle *b = p->binding_handle;
     611             : 
     612           0 :         torture_assert(tctx,
     613             :                 test_OpenKey_opts(tctx, b, handle, key,
     614             :                                   REG_OPTION_NON_VOLATILE,
     615             :                                   SEC_FLAG_SYSTEM_SECURITY,
     616             :                                   &new_handle,
     617             :                                   WERR_OK),
     618             :                 "failed to open key");
     619             : 
     620           0 :         ret = test_sacl_trustee_present(p, tctx, &new_handle, sid);
     621             : 
     622           0 :         test_CloseKey(b, tctx, &new_handle);
     623             : 
     624           0 :         return ret;
     625             : }
     626             : 
     627           0 : static bool test_owner_present(struct dcerpc_pipe *p,
     628             :                                struct torture_context *tctx,
     629             :                                struct policy_handle *handle,
     630             :                                const struct dom_sid *sid)
     631             : {
     632           0 :         struct security_descriptor *sd = NULL;
     633           0 :         uint32_t sec_info = SECINFO_OWNER;
     634             : 
     635           0 :         if (!_test_GetKeySecurity(p, tctx, handle, &sec_info, WERR_OK, &sd)) {
     636           0 :                 return false;
     637             :         }
     638             : 
     639           0 :         if (!sd || !sd->owner_sid) {
     640           0 :                 return false;
     641             :         }
     642             : 
     643           0 :         return dom_sid_equal(sd->owner_sid, sid);
     644             : }
     645             : 
     646           0 : static bool _test_owner_present(struct dcerpc_pipe *p,
     647             :                                 struct torture_context *tctx,
     648             :                                 struct policy_handle *handle,
     649             :                                 const char *key,
     650             :                                 const struct dom_sid *sid)
     651             : {
     652             :         struct policy_handle new_handle;
     653           0 :         bool ret = true;
     654           0 :         struct dcerpc_binding_handle *b = p->binding_handle;
     655             : 
     656           0 :         if (!test_OpenKey(b, tctx, handle, key, &new_handle)) {
     657           0 :                 return false;
     658             :         }
     659             : 
     660           0 :         ret = test_owner_present(p, tctx, &new_handle, sid);
     661             : 
     662           0 :         test_CloseKey(b, tctx, &new_handle);
     663             : 
     664           0 :         return ret;
     665             : }
     666             : 
     667           0 : static bool test_group_present(struct dcerpc_pipe *p,
     668             :                                struct torture_context *tctx,
     669             :                                struct policy_handle *handle,
     670             :                                const struct dom_sid *sid)
     671             : {
     672           0 :         struct security_descriptor *sd = NULL;
     673           0 :         uint32_t sec_info = SECINFO_GROUP;
     674             : 
     675           0 :         if (!_test_GetKeySecurity(p, tctx, handle, &sec_info, WERR_OK, &sd)) {
     676           0 :                 return false;
     677             :         }
     678             : 
     679           0 :         if (!sd || !sd->group_sid) {
     680           0 :                 return false;
     681             :         }
     682             : 
     683           0 :         return dom_sid_equal(sd->group_sid, sid);
     684             : }
     685             : 
     686           0 : static bool _test_group_present(struct dcerpc_pipe *p,
     687             :                                 struct torture_context *tctx,
     688             :                                 struct policy_handle *handle,
     689             :                                 const char *key,
     690             :                                 const struct dom_sid *sid)
     691             : {
     692             :         struct policy_handle new_handle;
     693           0 :         bool ret = true;
     694           0 :         struct dcerpc_binding_handle *b = p->binding_handle;
     695             : 
     696           0 :         if (!test_OpenKey(b, tctx, handle, key, &new_handle)) {
     697           0 :                 return false;
     698             :         }
     699             : 
     700           0 :         ret = test_group_present(p, tctx, &new_handle, sid);
     701             : 
     702           0 :         test_CloseKey(b, tctx, &new_handle);
     703             : 
     704           0 :         return ret;
     705             : }
     706             : 
     707           0 : static bool test_dacl_trustee_flags_present(struct dcerpc_pipe *p,
     708             :                                             struct torture_context *tctx,
     709             :                                             struct policy_handle *handle,
     710             :                                             const struct dom_sid *sid,
     711             :                                             uint8_t flags)
     712             : {
     713           0 :         struct security_descriptor *sd = NULL;
     714             :         int i;
     715             : 
     716           0 :         if (!test_GetKeySecurity(p, tctx, handle, &sd)) {
     717           0 :                 return false;
     718             :         }
     719             : 
     720           0 :         if (!sd || !sd->dacl) {
     721           0 :                 return false;
     722             :         }
     723             : 
     724           0 :         for (i = 0; i < sd->dacl->num_aces; i++) {
     725           0 :                 if ((dom_sid_equal(&sd->dacl->aces[i].trustee, sid)) &&
     726           0 :                     (sd->dacl->aces[i].flags == flags)) {
     727           0 :                         return true;
     728             :                 }
     729             :         }
     730             : 
     731           0 :         return false;
     732             : }
     733             : 
     734           0 : static bool test_dacl_ace_present(struct dcerpc_pipe *p,
     735             :                                   struct torture_context *tctx,
     736             :                                   struct policy_handle *handle,
     737             :                                   const struct security_ace *ace)
     738             : {
     739           0 :         struct security_descriptor *sd = NULL;
     740             :         int i;
     741             : 
     742           0 :         if (!test_GetKeySecurity(p, tctx, handle, &sd)) {
     743           0 :                 return false;
     744             :         }
     745             : 
     746           0 :         if (!sd || !sd->dacl) {
     747           0 :                 return false;
     748             :         }
     749             : 
     750           0 :         for (i = 0; i < sd->dacl->num_aces; i++) {
     751           0 :                 if (security_ace_equal(&sd->dacl->aces[i], ace)) {
     752           0 :                         return true;
     753             :                 }
     754             :         }
     755             : 
     756           0 :         return false;
     757             : }
     758             : 
     759           0 : static bool test_RestoreSecurity(struct dcerpc_pipe *p,
     760             :                                  struct torture_context *tctx,
     761             :                                  struct policy_handle *handle,
     762             :                                  const char *key,
     763             :                                  struct security_descriptor *sd)
     764             : {
     765             :         struct policy_handle new_handle;
     766           0 :         bool ret = true;
     767           0 :         struct dcerpc_binding_handle *b = p->binding_handle;
     768             : 
     769           0 :         if (!test_OpenKey(b, tctx, handle, key, &new_handle)) {
     770           0 :                 return false;
     771             :         }
     772             : 
     773           0 :         if (!test_SetKeySecurity(p, tctx, &new_handle, sd)) {
     774           0 :                 ret = false;
     775             :         }
     776             : 
     777           0 :         if (!test_CloseKey(b, tctx, &new_handle)) {
     778           0 :                 ret = false;
     779             :         }
     780             : 
     781           0 :         return ret;
     782             : }
     783             : 
     784           0 : static bool test_BackupSecurity(struct dcerpc_pipe *p,
     785             :                                 struct torture_context *tctx,
     786             :                                 struct policy_handle *handle,
     787             :                                 const char *key,
     788             :                                 struct security_descriptor **sd)
     789             : {
     790             :         struct policy_handle new_handle;
     791           0 :         bool ret = true;
     792           0 :         struct dcerpc_binding_handle *b = p->binding_handle;
     793             : 
     794           0 :         if (!test_OpenKey(b, tctx, handle, key, &new_handle)) {
     795           0 :                 return false;
     796             :         }
     797             : 
     798           0 :         if (!test_GetKeySecurity(p, tctx, &new_handle, sd)) {
     799           0 :                 ret = false;
     800             :         }
     801             : 
     802           0 :         if (!test_CloseKey(b, tctx, &new_handle)) {
     803           0 :                 ret = false;
     804             :         }
     805             : 
     806           0 :         return ret;
     807             : }
     808             : 
     809           0 : static bool test_SecurityDescriptorInheritance(struct dcerpc_pipe *p,
     810             :                                                struct torture_context *tctx,
     811             :                                                struct policy_handle *handle,
     812             :                                                const char *key)
     813             : {
     814             :         /* get sd
     815             :            add ace SEC_ACE_FLAG_CONTAINER_INHERIT
     816             :            set sd
     817             :            get sd
     818             :            check ace
     819             :            add subkey
     820             :            get sd
     821             :            check ace
     822             :            add subsubkey
     823             :            get sd
     824             :            check ace
     825             :            del subsubkey
     826             :            del subkey
     827             :            reset sd
     828             :         */
     829             : 
     830           0 :         struct security_descriptor *sd = NULL;
     831           0 :         struct security_descriptor *sd_orig = NULL;
     832           0 :         struct security_ace *ace = NULL;
     833             :         struct policy_handle new_handle;
     834           0 :         bool ret = true;
     835           0 :         struct dcerpc_binding_handle *b = p->binding_handle;
     836             :         const char *test_subkey_sd;
     837             :         const char *test_subsubkey_sd;
     838             : 
     839           0 :         torture_comment(tctx, "SecurityDescriptor inheritance\n");
     840             : 
     841           0 :         if (!test_OpenKey(b, tctx, handle, key, &new_handle)) {
     842           0 :                 return false;
     843             :         }
     844             : 
     845           0 :         if (!_test_GetKeySecurity(p, tctx, &new_handle, NULL, WERR_OK, &sd)) {
     846           0 :                 return false;
     847             :         }
     848             : 
     849           0 :         sd_orig = security_descriptor_copy(tctx, sd);
     850           0 :         if (sd_orig == NULL) {
     851           0 :                 return false;
     852             :         }
     853             : 
     854           0 :         ace = security_ace_create(tctx,
     855             :                                   TEST_SID,
     856             :                                   SEC_ACE_TYPE_ACCESS_ALLOWED,
     857             :                                   SEC_STD_REQUIRED,
     858             :                                   SEC_ACE_FLAG_CONTAINER_INHERIT);
     859             : 
     860           0 :         torture_assert_ntstatus_ok(tctx,
     861             :                 security_descriptor_dacl_add(sd, ace),
     862             :                 "failed to add ace");
     863             : 
     864             :         /* FIXME: add further tests for these flags */
     865           0 :         sd->type |= SEC_DESC_DACL_AUTO_INHERIT_REQ |
     866             :                     SEC_DESC_SACL_AUTO_INHERITED;
     867             : 
     868           0 :         if (!test_SetKeySecurity(p, tctx, &new_handle, sd)) {
     869           0 :                 return false;
     870             :         }
     871             : 
     872           0 :         torture_assert(tctx,
     873             :                 test_dacl_ace_present(p, tctx, &new_handle, ace),
     874             :                 "new ACE not present!");
     875             : 
     876           0 :         if (!test_CloseKey(b, tctx, &new_handle)) {
     877           0 :                 return false;
     878             :         }
     879             : 
     880           0 :         test_subkey_sd = talloc_asprintf(tctx, "%s\\%s", key, TEST_SUBKEY_SD);
     881             : 
     882           0 :         if (!test_CreateKey(b, tctx, handle, test_subkey_sd, NULL)) {
     883           0 :                 ret = false;
     884           0 :                 goto out;
     885             :         }
     886             : 
     887           0 :         if (!test_OpenKey(b, tctx, handle, test_subkey_sd, &new_handle)) {
     888           0 :                 ret = false;
     889           0 :                 goto out;
     890             :         }
     891             : 
     892           0 :         if (!test_dacl_ace_present(p, tctx, &new_handle, ace)) {
     893           0 :                 torture_comment(tctx, "inherited ACE not present!\n");
     894           0 :                 ret = false;
     895           0 :                 goto out;
     896             :         }
     897             : 
     898           0 :         test_subsubkey_sd = talloc_asprintf(tctx, "%s\\%s", key, TEST_SUBSUBKEY_SD);
     899             : 
     900           0 :         test_CloseKey(b, tctx, &new_handle);
     901           0 :         if (!test_CreateKey(b, tctx, handle, test_subsubkey_sd, NULL)) {
     902           0 :                 ret = false;
     903           0 :                 goto out;
     904             :         }
     905             : 
     906           0 :         if (!test_OpenKey(b, tctx, handle, test_subsubkey_sd, &new_handle)) {
     907           0 :                 ret = false;
     908           0 :                 goto out;
     909             :         }
     910             : 
     911           0 :         if (!test_dacl_ace_present(p, tctx, &new_handle, ace)) {
     912           0 :                 torture_comment(tctx, "inherited ACE not present!\n");
     913           0 :                 ret = false;
     914           0 :                 goto out;
     915             :         }
     916             : 
     917           0 :  out:
     918           0 :         test_CloseKey(b, tctx, &new_handle);
     919           0 :         test_Cleanup(b, tctx, handle, test_subkey_sd);
     920           0 :         test_RestoreSecurity(p, tctx, handle, key, sd_orig);
     921             : 
     922           0 :         return ret;
     923             : }
     924             : 
     925           0 : static bool test_SecurityDescriptorBlockInheritance(struct dcerpc_pipe *p,
     926             :                                                     struct torture_context *tctx,
     927             :                                                     struct policy_handle *handle,
     928             :                                                     const char *key)
     929             : {
     930             :         /* get sd
     931             :            add ace SEC_ACE_FLAG_NO_PROPAGATE_INHERIT
     932             :            set sd
     933             :            add subkey/subkey
     934             :            get sd
     935             :            check ace
     936             :            get sd from subkey
     937             :            check ace
     938             :            del subkey/subkey
     939             :            del subkey
     940             :            reset sd
     941             :         */
     942             : 
     943           0 :         struct security_descriptor *sd = NULL;
     944           0 :         struct security_descriptor *sd_orig = NULL;
     945           0 :         struct security_ace *ace = NULL;
     946             :         struct policy_handle new_handle;
     947           0 :         struct dom_sid *sid = NULL;
     948           0 :         bool ret = true;
     949           0 :         uint8_t ace_flags = 0x0;
     950           0 :         struct dcerpc_binding_handle *b = p->binding_handle;
     951             :         const char *test_subkey_sd;
     952             :         const char *test_subsubkey_sd;
     953             : 
     954           0 :         torture_comment(tctx, "SecurityDescriptor inheritance block\n");
     955             : 
     956           0 :         if (!test_OpenKey(b, tctx, handle, key, &new_handle)) {
     957           0 :                 return false;
     958             :         }
     959             : 
     960           0 :         if (!_test_GetKeySecurity(p, tctx, &new_handle, NULL, WERR_OK, &sd)) {
     961           0 :                 return false;
     962             :         }
     963             : 
     964           0 :         sd_orig = security_descriptor_copy(tctx, sd);
     965           0 :         if (sd_orig == NULL) {
     966           0 :                 return false;
     967             :         }
     968             : 
     969           0 :         ace = security_ace_create(tctx,
     970             :                                   TEST_SID,
     971             :                                   SEC_ACE_TYPE_ACCESS_ALLOWED,
     972             :                                   SEC_STD_REQUIRED,
     973             :                                   SEC_ACE_FLAG_CONTAINER_INHERIT |
     974             :                                   SEC_ACE_FLAG_NO_PROPAGATE_INHERIT);
     975             : 
     976           0 :         torture_assert_ntstatus_ok(tctx,
     977             :                 security_descriptor_dacl_add(sd, ace),
     978             :                 "failed to add ace");
     979             : 
     980           0 :         if (!_test_SetKeySecurity(p, tctx, &new_handle, NULL, sd, WERR_OK)) {
     981           0 :                 return false;
     982             :         }
     983             : 
     984           0 :         torture_assert(tctx,
     985             :                 test_dacl_ace_present(p, tctx, &new_handle, ace),
     986             :                 "new ACE not present!");
     987             : 
     988           0 :         if (!test_CloseKey(b, tctx, &new_handle)) {
     989           0 :                 return false;
     990             :         }
     991             : 
     992           0 :         test_subkey_sd = talloc_asprintf(tctx, "%s\\%s", key, TEST_SUBKEY_SD);
     993           0 :         test_subsubkey_sd = talloc_asprintf(tctx, "%s\\%s", key, TEST_SUBSUBKEY_SD);
     994             : 
     995           0 :         if (!test_CreateKey(b, tctx, handle, test_subsubkey_sd, NULL)) {
     996           0 :                 return false;
     997             :         }
     998             : 
     999           0 :         if (!test_OpenKey(b, tctx, handle, test_subsubkey_sd, &new_handle)) {
    1000           0 :                 ret = false;
    1001           0 :                 goto out;
    1002             :         }
    1003             : 
    1004           0 :         if (test_dacl_ace_present(p, tctx, &new_handle, ace)) {
    1005           0 :                 torture_comment(tctx, "inherited ACE present but should not!\n");
    1006           0 :                 ret = false;
    1007           0 :                 goto out;
    1008             :         }
    1009             : 
    1010           0 :         sid = dom_sid_parse_talloc(tctx, TEST_SID);
    1011           0 :         if (sid == NULL) {
    1012           0 :                 return false;
    1013             :         }
    1014             : 
    1015           0 :         if (test_dacl_trustee_present(p, tctx, &new_handle, sid)) {
    1016           0 :                 torture_comment(tctx, "inherited trustee SID present but should not!\n");
    1017           0 :                 ret = false;
    1018           0 :                 goto out;
    1019             :         }
    1020             : 
    1021           0 :         test_CloseKey(b, tctx, &new_handle);
    1022             : 
    1023           0 :         if (!test_OpenKey(b, tctx, handle, test_subkey_sd, &new_handle)) {
    1024           0 :                 ret = false;
    1025           0 :                 goto out;
    1026             :         }
    1027             : 
    1028           0 :         if (test_dacl_ace_present(p, tctx, &new_handle, ace)) {
    1029           0 :                 torture_comment(tctx, "inherited ACE present but should not!\n");
    1030           0 :                 ret = false;
    1031           0 :                 goto out;
    1032             :         }
    1033             : 
    1034           0 :         if (!test_dacl_trustee_flags_present(p, tctx, &new_handle, sid, ace_flags)) {
    1035           0 :                 torture_comment(tctx, "inherited trustee SID with flags 0x%02x not present!\n",
    1036             :                         ace_flags);
    1037           0 :                 ret = false;
    1038           0 :                 goto out;
    1039             :         }
    1040             : 
    1041           0 :  out:
    1042           0 :         test_CloseKey(b, tctx, &new_handle);
    1043           0 :         test_Cleanup(b, tctx, handle, test_subkey_sd);
    1044           0 :         test_RestoreSecurity(p, tctx, handle, key, sd_orig);
    1045             : 
    1046           0 :         return ret;
    1047             : }
    1048             : 
    1049           0 : static bool test_SecurityDescriptorsMasks(struct dcerpc_pipe *p,
    1050             :                                           struct torture_context *tctx,
    1051             :                                           struct policy_handle *handle,
    1052             :                                           const char *key)
    1053             : {
    1054           0 :         bool ret = true;
    1055             :         int i;
    1056             : 
    1057             :         struct winreg_mask_result_table {
    1058             :                 uint32_t access_mask;
    1059             :                 WERROR open_werr;
    1060             :                 WERROR get_werr;
    1061             :                 WERROR set_werr;
    1062           0 :         } sd_mask_tests[] = {
    1063             :                 { 0,
    1064             :                         WERR_ACCESS_DENIED, WERR_FILE_NOT_FOUND, WERR_FOOBAR },
    1065             :                 { SEC_FLAG_MAXIMUM_ALLOWED,
    1066             :                         WERR_OK, WERR_OK, WERR_OK },
    1067             :                 { SEC_STD_WRITE_DAC,
    1068             :                         WERR_OK, WERR_ACCESS_DENIED, WERR_FOOBAR },
    1069             :                 { SEC_FLAG_SYSTEM_SECURITY,
    1070             :                         WERR_OK, WERR_ACCESS_DENIED, WERR_FOOBAR }
    1071             :         };
    1072             : 
    1073             :         /* FIXME: before this test can ever run successfully we need a way to
    1074             :          * correctly read a NULL security_descritpor in ndr, get the required
    1075             :          * length, requery, etc.
    1076             :          */
    1077             : 
    1078           0 :         return true;
    1079             : 
    1080             :         for (i=0; i < ARRAY_SIZE(sd_mask_tests); i++) {
    1081             : 
    1082             :                 torture_comment(tctx,
    1083             :                                 "SecurityDescriptor get & set with access_mask: 0x%08x\n",
    1084             :                                 sd_mask_tests[i].access_mask);
    1085             :                 torture_comment(tctx,
    1086             :                                 "expecting: open %s, get: %s, set: %s\n",
    1087             :                                 win_errstr(sd_mask_tests[i].open_werr),
    1088             :                                 win_errstr(sd_mask_tests[i].get_werr),
    1089             :                                 win_errstr(sd_mask_tests[i].set_werr));
    1090             : 
    1091             :                 if (_test_SecurityDescriptor(p, tctx, handle,
    1092             :                                              sd_mask_tests[i].access_mask, key,
    1093             :                                              sd_mask_tests[i].open_werr,
    1094             :                                              sd_mask_tests[i].get_werr,
    1095             :                                              sd_mask_tests[i].set_werr)) {
    1096             :                         ret = false;
    1097             :                 }
    1098             :         }
    1099             : 
    1100             :         return ret;
    1101             : }
    1102             : 
    1103             : typedef bool (*secinfo_verify_fn)(struct dcerpc_pipe *,
    1104             :                                   struct torture_context *,
    1105             :                                   struct policy_handle *,
    1106             :                                   const char *,
    1107             :                                   const struct dom_sid *);
    1108             : 
    1109           0 : static bool test_SetSecurityDescriptor_SecInfo(struct dcerpc_pipe *p,
    1110             :                                                struct torture_context *tctx,
    1111             :                                                struct policy_handle *handle,
    1112             :                                                const char *key,
    1113             :                                                const char *test,
    1114             :                                                uint32_t access_mask,
    1115             :                                                uint32_t sec_info,
    1116             :                                                struct security_descriptor *sd,
    1117             :                                                WERROR set_werr,
    1118             :                                                bool expect_present,
    1119             :                                                bool (*fn) (struct dcerpc_pipe *,
    1120             :                                                            struct torture_context *,
    1121             :                                                            struct policy_handle *,
    1122             :                                                            const char *,
    1123             :                                                            const struct dom_sid *),
    1124             :                                                const struct dom_sid *sid)
    1125             : {
    1126             :         struct policy_handle new_handle;
    1127           0 :         struct dcerpc_binding_handle *b = p->binding_handle;
    1128             : 
    1129           0 :         torture_comment(tctx, "SecurityDescriptor (%s) sets for secinfo: "
    1130             :                         "0x%08x, access_mask: 0x%08x\n",
    1131             :                         test, sec_info, access_mask);
    1132             : 
    1133           0 :         torture_assert(tctx,
    1134             :                 test_OpenKey_opts(tctx, b, handle, key,
    1135             :                                   REG_OPTION_NON_VOLATILE,
    1136             :                                   access_mask,
    1137             :                                   &new_handle,
    1138             :                                   WERR_OK),
    1139             :                 "failed to open key");
    1140             : 
    1141           0 :         if (!_test_SetKeySecurity(p, tctx, &new_handle, &sec_info,
    1142             :                                   sd,
    1143             :                                   set_werr)) {
    1144           0 :                 torture_warning(tctx,
    1145             :                                 "SetKeySecurity with secinfo: 0x%08x has failed\n",
    1146             :                                 sec_info);
    1147           0 :                 smb_panic("");
    1148             :                 test_CloseKey(b, tctx, &new_handle);
    1149             :                 return false;
    1150             :         }
    1151             : 
    1152           0 :         test_CloseKey(b, tctx, &new_handle);
    1153             : 
    1154           0 :         if (W_ERROR_IS_OK(set_werr)) {
    1155             :                 bool present;
    1156           0 :                 present = fn(p, tctx, handle, key, sid);
    1157           0 :                 if ((expect_present) && (!present)) {
    1158           0 :                         torture_warning(tctx,
    1159             :                                         "%s sid is not present!\n",
    1160             :                                         test);
    1161           0 :                         return false;
    1162             :                 }
    1163           0 :                 if ((!expect_present) && (present)) {
    1164           0 :                         torture_warning(tctx,
    1165             :                                         "%s sid is present but not expected!\n",
    1166             :                                         test);
    1167           0 :                         return false;
    1168             :                 }
    1169             :         }
    1170             : 
    1171           0 :         return true;
    1172             : }
    1173             : 
    1174           0 : static bool test_SecurityDescriptorsSecInfo(struct dcerpc_pipe *p,
    1175             :                                             struct torture_context *tctx,
    1176             :                                             struct policy_handle *handle,
    1177             :                                             const char *key)
    1178             : {
    1179           0 :         struct security_descriptor *sd_orig = NULL;
    1180           0 :         struct dom_sid *sid = NULL;
    1181           0 :         bool ret = true;
    1182             :         int i, a;
    1183             : 
    1184             :         struct security_descriptor *sd_owner =
    1185           0 :                 security_descriptor_dacl_create(tctx,
    1186             :                                                 0,
    1187             :                                                 TEST_SID, NULL, NULL);
    1188             : 
    1189             :         struct security_descriptor *sd_group =
    1190           0 :                 security_descriptor_dacl_create(tctx,
    1191             :                                                 0,
    1192             :                                                 NULL, TEST_SID, NULL);
    1193             : 
    1194             :         struct security_descriptor *sd_dacl =
    1195           0 :                 security_descriptor_dacl_create(tctx,
    1196             :                                                 0,
    1197             :                                                 NULL, NULL,
    1198             :                                                 TEST_SID,
    1199             :                                                 SEC_ACE_TYPE_ACCESS_ALLOWED,
    1200             :                                                 SEC_GENERIC_ALL,
    1201             :                                                 0,
    1202             :                                                 SID_NT_AUTHENTICATED_USERS,
    1203             :                                                 SEC_ACE_TYPE_ACCESS_ALLOWED,
    1204             :                                                 SEC_GENERIC_ALL,
    1205             :                                                 0,
    1206             :                                                 NULL);
    1207             : 
    1208             :         struct security_descriptor *sd_sacl =
    1209           0 :                 security_descriptor_sacl_create(tctx,
    1210             :                                                 0,
    1211             :                                                 NULL, NULL,
    1212             :                                                 TEST_SID,
    1213             :                                                 SEC_ACE_TYPE_SYSTEM_AUDIT,
    1214             :                                                 SEC_GENERIC_ALL,
    1215             :                                                 SEC_ACE_FLAG_SUCCESSFUL_ACCESS,
    1216             :                                                 NULL);
    1217             : 
    1218             :         struct winreg_secinfo_table {
    1219             :                 struct security_descriptor *sd;
    1220             :                 uint32_t sec_info;
    1221             :                 WERROR set_werr;
    1222             :                 bool sid_present;
    1223             :                 secinfo_verify_fn fn;
    1224             :         };
    1225             : 
    1226           0 :         struct winreg_secinfo_table sec_info_owner_tests[] = {
    1227             :                 {
    1228             :                         .sd          = sd_owner,
    1229             :                         .sec_info    = 0,
    1230             :                         .set_werr    = WERR_OK,
    1231             :                         .sid_present = false,
    1232             :                         .fn          = (secinfo_verify_fn)_test_owner_present,
    1233             :                 },
    1234             :                 {
    1235             :                         .sd          = sd_owner,
    1236             :                         .sec_info    = SECINFO_OWNER,
    1237             :                         .set_werr    = WERR_OK,
    1238             :                         .sid_present = true,
    1239             :                         .fn          = (secinfo_verify_fn)_test_owner_present,
    1240             :                 },
    1241             :                 {
    1242             :                         .sd          = sd_owner,
    1243             :                         .sec_info    = SECINFO_GROUP,
    1244             :                         .set_werr    = WERR_INVALID_PARAMETER,
    1245             :                         .sid_present  = false,
    1246             :                 },
    1247             :                 {
    1248             :                         .sd          = sd_owner,
    1249             :                         .sec_info    = SECINFO_DACL,
    1250             :                         .set_werr    = WERR_OK,
    1251             :                         .sid_present = true,
    1252             :                         .fn          = (secinfo_verify_fn)_test_owner_present,
    1253             :                 },
    1254             :                 {
    1255             :                         .sd          = sd_owner,
    1256             :                         .sec_info    = SECINFO_SACL,
    1257             :                         .set_werr    = WERR_ACCESS_DENIED,
    1258             :                         .sid_present  = false,
    1259             :                 },
    1260             :         };
    1261             : 
    1262           0 :         uint32_t sd_owner_good_access_masks[] = {
    1263             :                 SEC_FLAG_MAXIMUM_ALLOWED,
    1264             :                 /* SEC_STD_WRITE_OWNER, */
    1265             :         };
    1266             : 
    1267           0 :         struct winreg_secinfo_table sec_info_group_tests[] = {
    1268             :                 {
    1269             :                         .sd          = sd_group,
    1270             :                         .sec_info    = 0,
    1271             :                         .set_werr    = WERR_OK,
    1272             :                         .sid_present = false,
    1273             :                         .fn          = (secinfo_verify_fn)_test_group_present,
    1274             :                 },
    1275             :                 {
    1276             :                         .sd          = sd_group,
    1277             :                         .sec_info    = SECINFO_OWNER,
    1278             :                         .set_werr    = WERR_INVALID_PARAMETER,
    1279             :                         .sid_present = false,
    1280             :                 },
    1281             :                 {
    1282             :                         .sd          = sd_group,
    1283             :                         .sec_info    = SECINFO_GROUP,
    1284             :                         .set_werr    = WERR_OK,
    1285             :                         .sid_present = true,
    1286             :                         .fn          = (secinfo_verify_fn)_test_group_present,
    1287             :                 },
    1288             :                 {
    1289             :                         .sd          = sd_group,
    1290             :                         .sec_info    = SECINFO_DACL,
    1291             :                         .set_werr    = WERR_OK,
    1292             :                         .sid_present = true,
    1293             :                         .fn          = (secinfo_verify_fn)_test_group_present,
    1294             :                 },
    1295             :                 {
    1296             :                         .sd          = sd_group,
    1297             :                         .sec_info    = SECINFO_SACL,
    1298             :                         .set_werr    = WERR_ACCESS_DENIED,
    1299             :                         .sid_present = false,
    1300             :                 },
    1301             :         };
    1302             : 
    1303           0 :         uint32_t sd_group_good_access_masks[] = {
    1304             :                 SEC_FLAG_MAXIMUM_ALLOWED,
    1305             :         };
    1306             : 
    1307           0 :         struct winreg_secinfo_table sec_info_dacl_tests[] = {
    1308             :                 {
    1309             :                         .sd          = sd_dacl,
    1310             :                         .sec_info    = 0,
    1311             :                         .set_werr    = WERR_OK,
    1312             :                         .sid_present = false,
    1313             :                         .fn          = (secinfo_verify_fn)_test_dacl_trustee_present,
    1314             :                 },
    1315             :                 {
    1316             :                         .sd          = sd_dacl,
    1317             :                         .sec_info    = SECINFO_OWNER,
    1318             :                         .set_werr    = WERR_INVALID_PARAMETER,
    1319             :                         .sid_present = false,
    1320             :                 },
    1321             :                 {
    1322             :                         .sd          = sd_dacl,
    1323             :                         .sec_info    = SECINFO_GROUP,
    1324             :                         .set_werr    = WERR_INVALID_PARAMETER,
    1325             :                         .sid_present = false,
    1326             :                 },
    1327             :                 {
    1328             :                         .sd          = sd_dacl,
    1329             :                         .sec_info    = SECINFO_DACL,
    1330             :                         .set_werr    = WERR_OK,
    1331             :                         .sid_present = true,
    1332             :                         .fn          = (secinfo_verify_fn)_test_dacl_trustee_present
    1333             :                 },
    1334             :                 {
    1335             :                         .sd          = sd_dacl,
    1336             :                         .sec_info    = SECINFO_SACL,
    1337             :                         .set_werr    = WERR_ACCESS_DENIED,
    1338             :                         .sid_present = false,
    1339             :                 },
    1340             :         };
    1341             : 
    1342           0 :         uint32_t sd_dacl_good_access_masks[] = {
    1343             :                 SEC_FLAG_MAXIMUM_ALLOWED,
    1344             :                 SEC_STD_WRITE_DAC,
    1345             :         };
    1346             : 
    1347           0 :         struct winreg_secinfo_table sec_info_sacl_tests[] = {
    1348             :                 {
    1349             :                         .sd          = sd_sacl,
    1350             :                         .sec_info    = 0,
    1351             :                         .set_werr    = WERR_OK,
    1352             :                         .sid_present = false,
    1353             :                         .fn          = (secinfo_verify_fn)_test_sacl_trustee_present,
    1354             :                 },
    1355             :                 {
    1356             :                         .sd          = sd_sacl,
    1357             :                         .sec_info    = SECINFO_OWNER,
    1358             :                         .set_werr    = WERR_INVALID_PARAMETER,
    1359             :                         .sid_present = false,
    1360             :                 },
    1361             :                 {
    1362             :                         .sd          = sd_sacl,
    1363             :                         .sec_info    = SECINFO_GROUP,
    1364             :                         .set_werr    = WERR_INVALID_PARAMETER,
    1365             :                         .sid_present = false,
    1366             :                 },
    1367             :                 {
    1368             :                         .sd          = sd_sacl,
    1369             :                         .sec_info    = SECINFO_DACL,
    1370             :                         .set_werr    = WERR_OK,
    1371             :                         .sid_present = false,
    1372             :                         .fn          = (secinfo_verify_fn)_test_sacl_trustee_present,
    1373             :                 },
    1374             :                 {
    1375             :                         .sd          = sd_sacl,
    1376             :                         .sec_info    = SECINFO_SACL,
    1377             :                         .set_werr    = WERR_OK,
    1378             :                         .sid_present = true,
    1379             :                         .fn          = (secinfo_verify_fn)_test_sacl_trustee_present,
    1380             :                 },
    1381             :         };
    1382             : 
    1383           0 :         uint32_t sd_sacl_good_access_masks[] = {
    1384             :                 SEC_FLAG_MAXIMUM_ALLOWED | SEC_FLAG_SYSTEM_SECURITY,
    1385             :                 /* SEC_FLAG_SYSTEM_SECURITY, */
    1386             :         };
    1387             : 
    1388           0 :         sid = dom_sid_parse_talloc(tctx, TEST_SID);
    1389           0 :         if (sid == NULL) {
    1390           0 :                 return false;
    1391             :         }
    1392             : 
    1393           0 :         if (!test_BackupSecurity(p, tctx, handle, key, &sd_orig)) {
    1394           0 :                 return false;
    1395             :         }
    1396             : 
    1397             :         /* OWNER */
    1398             : 
    1399           0 :         for (i=0; i < ARRAY_SIZE(sec_info_owner_tests); i++) {
    1400             : 
    1401           0 :                 for (a=0; a < ARRAY_SIZE(sd_owner_good_access_masks); a++) {
    1402             : 
    1403           0 :                         if (!test_SetSecurityDescriptor_SecInfo(p, tctx, handle,
    1404             :                                         key,
    1405             :                                         "OWNER",
    1406             :                                         sd_owner_good_access_masks[a],
    1407             :                                         sec_info_owner_tests[i].sec_info,
    1408             :                                         sec_info_owner_tests[i].sd,
    1409             :                                         sec_info_owner_tests[i].set_werr,
    1410           0 :                                         sec_info_owner_tests[i].sid_present,
    1411             :                                         sec_info_owner_tests[i].fn,
    1412             :                                         sid))
    1413             :                         {
    1414           0 :                                 torture_comment(tctx, "test_SetSecurityDescriptor_SecInfo failed for OWNER\n");
    1415           0 :                                 ret = false;
    1416           0 :                                 goto out;
    1417             :                         }
    1418             :                 }
    1419             :         }
    1420             : 
    1421             :         /* GROUP */
    1422             : 
    1423           0 :         for (i=0; i < ARRAY_SIZE(sec_info_group_tests); i++) {
    1424             : 
    1425           0 :                 for (a=0; a < ARRAY_SIZE(sd_group_good_access_masks); a++) {
    1426             : 
    1427           0 :                         if (!test_SetSecurityDescriptor_SecInfo(p, tctx, handle,
    1428             :                                         key,
    1429             :                                         "GROUP",
    1430             :                                         sd_group_good_access_masks[a],
    1431             :                                         sec_info_group_tests[i].sec_info,
    1432             :                                         sec_info_group_tests[i].sd,
    1433             :                                         sec_info_group_tests[i].set_werr,
    1434           0 :                                         sec_info_group_tests[i].sid_present,
    1435             :                                         sec_info_group_tests[i].fn,
    1436             :                                         sid))
    1437             :                         {
    1438           0 :                                 torture_comment(tctx, "test_SetSecurityDescriptor_SecInfo failed for GROUP\n");
    1439           0 :                                 ret = false;
    1440           0 :                                 goto out;
    1441             :                         }
    1442             :                 }
    1443             :         }
    1444             : 
    1445             :         /* DACL */
    1446             : 
    1447           0 :         for (i=0; i < ARRAY_SIZE(sec_info_dacl_tests); i++) {
    1448             : 
    1449           0 :                 for (a=0; a < ARRAY_SIZE(sd_dacl_good_access_masks); a++) {
    1450             : 
    1451           0 :                         if (!test_SetSecurityDescriptor_SecInfo(p, tctx, handle,
    1452             :                                         key,
    1453             :                                         "DACL",
    1454             :                                         sd_dacl_good_access_masks[a],
    1455             :                                         sec_info_dacl_tests[i].sec_info,
    1456             :                                         sec_info_dacl_tests[i].sd,
    1457             :                                         sec_info_dacl_tests[i].set_werr,
    1458           0 :                                         sec_info_dacl_tests[i].sid_present,
    1459             :                                         sec_info_dacl_tests[i].fn,
    1460             :                                         sid))
    1461             :                         {
    1462           0 :                                 torture_comment(tctx, "test_SetSecurityDescriptor_SecInfo failed for DACL\n");
    1463           0 :                                 ret = false;
    1464           0 :                                 goto out;
    1465             :                         }
    1466             :                 }
    1467             :         }
    1468             : 
    1469             :         /* SACL */
    1470             : 
    1471           0 :         for (i=0; i < ARRAY_SIZE(sec_info_sacl_tests); i++) {
    1472             : 
    1473           0 :                 for (a=0; a < ARRAY_SIZE(sd_sacl_good_access_masks); a++) {
    1474             : 
    1475           0 :                         if (!test_SetSecurityDescriptor_SecInfo(p, tctx, handle,
    1476             :                                         key,
    1477             :                                         "SACL",
    1478             :                                         sd_sacl_good_access_masks[a],
    1479             :                                         sec_info_sacl_tests[i].sec_info,
    1480             :                                         sec_info_sacl_tests[i].sd,
    1481             :                                         sec_info_sacl_tests[i].set_werr,
    1482           0 :                                         sec_info_sacl_tests[i].sid_present,
    1483             :                                         sec_info_sacl_tests[i].fn,
    1484             :                                         sid))
    1485             :                         {
    1486           0 :                                 torture_comment(tctx, "test_SetSecurityDescriptor_SecInfo failed for SACL\n");
    1487           0 :                                 ret = false;
    1488           0 :                                 goto out;
    1489             :                         }
    1490             :                 }
    1491             :         }
    1492             : 
    1493           0 :  out:
    1494           0 :         test_RestoreSecurity(p, tctx, handle, key, sd_orig);
    1495             : 
    1496           0 :         return ret;
    1497             : }
    1498             : 
    1499           0 : static bool test_SecurityDescriptors(struct dcerpc_pipe *p,
    1500             :                                      struct torture_context *tctx,
    1501             :                                      struct policy_handle *handle,
    1502             :                                      const char *key)
    1503             : {
    1504           0 :         bool ret = true;
    1505             : 
    1506           0 :         if (!test_SecurityDescriptor(p, tctx, handle, key)) {
    1507           0 :                 torture_comment(tctx, "test_SecurityDescriptor failed\n");
    1508           0 :                 ret = false;
    1509             :         }
    1510             : 
    1511           0 :         if (!test_SecurityDescriptorInheritance(p, tctx, handle, key)) {
    1512           0 :                 torture_comment(tctx, "test_SecurityDescriptorInheritance failed\n");
    1513           0 :                 ret = false;
    1514             :         }
    1515             : 
    1516           0 :         if (!test_SecurityDescriptorBlockInheritance(p, tctx, handle, key)) {
    1517           0 :                 torture_comment(tctx, "test_SecurityDescriptorBlockInheritance failed\n");
    1518           0 :                 ret = false;
    1519             :         }
    1520             : 
    1521           0 :         if (!test_SecurityDescriptorsSecInfo(p, tctx, handle, key)) {
    1522           0 :                 torture_comment(tctx, "test_SecurityDescriptorsSecInfo failed\n");
    1523           0 :                 ret = false;
    1524             :         }
    1525             : 
    1526           0 :         if (!test_SecurityDescriptorsMasks(p, tctx, handle, key)) {
    1527           0 :                 torture_comment(tctx, "test_SecurityDescriptorsMasks failed\n");
    1528           0 :                 ret = false;
    1529             :         }
    1530             : 
    1531           0 :         return ret;
    1532             : }
    1533             : 
    1534        2088 : static bool test_DeleteKey_opts(struct dcerpc_binding_handle *b,
    1535             :                                 struct torture_context *tctx,
    1536             :                                 struct policy_handle *handle,
    1537             :                                 const char *key,
    1538             :                                 WERROR expected_result)
    1539             : {
    1540           0 :         struct winreg_DeleteKey r;
    1541             : 
    1542        2088 :         torture_comment(tctx, "Testing DeleteKey(%s)\n", key);
    1543             : 
    1544        2088 :         r.in.handle = handle;
    1545        2088 :         init_winreg_String(&r.in.key, key);
    1546             : 
    1547        2088 :         torture_assert_ntstatus_ok(tctx, dcerpc_winreg_DeleteKey_r(b, tctx, &r),
    1548             :                 "Delete Key failed");
    1549        2088 :         torture_assert_werr_equal(tctx, r.out.result, expected_result,
    1550             :                 "DeleteKey failed");
    1551             : 
    1552        2088 :         return true;
    1553             : }
    1554             : 
    1555        1044 : static bool test_DeleteKey(struct dcerpc_binding_handle *b,
    1556             :                            struct torture_context *tctx,
    1557             :                            struct policy_handle *handle, const char *key)
    1558             : {
    1559        1044 :         return test_DeleteKey_opts(b, tctx, handle, key, WERR_OK);
    1560             : }
    1561             : 
    1562         268 : static bool test_QueryInfoKey(struct dcerpc_binding_handle *b,
    1563             :                               struct torture_context *tctx,
    1564             :                               struct policy_handle *handle,
    1565             :                               char *kclass,
    1566             :                               uint32_t *pmax_valnamelen,
    1567             :                               uint32_t *pmax_valbufsize)
    1568             : {
    1569           0 :         struct winreg_QueryInfoKey r;
    1570           0 :         uint32_t num_subkeys, max_subkeylen, max_classlen,
    1571             :                 num_values, max_valnamelen, max_valbufsize,
    1572             :                 secdescsize;
    1573           0 :         NTTIME last_changed_time;
    1574             : 
    1575         268 :         ZERO_STRUCT(r);
    1576         268 :         r.in.handle = handle;
    1577         268 :         r.out.num_subkeys = &num_subkeys;
    1578         268 :         r.out.max_subkeylen = &max_subkeylen;
    1579         268 :         r.out.max_classlen = &max_classlen;
    1580         268 :         r.out.num_values = &num_values;
    1581         268 :         r.out.max_valnamelen = &max_valnamelen;
    1582         268 :         r.out.max_valbufsize = &max_valbufsize;
    1583         268 :         r.out.secdescsize = &secdescsize;
    1584         268 :         r.out.last_changed_time = &last_changed_time;
    1585             : 
    1586         268 :         r.out.classname = talloc(tctx, struct winreg_String);
    1587             : 
    1588         268 :         r.in.classname = talloc(tctx, struct winreg_String);
    1589         268 :         init_winreg_String(r.in.classname, kclass);
    1590             : 
    1591         268 :         torture_assert_ntstatus_ok(tctx,
    1592             :                                    dcerpc_winreg_QueryInfoKey_r(b, tctx, &r),
    1593             :                                    "QueryInfoKey failed");
    1594             : 
    1595         268 :         torture_assert_werr_ok(tctx, r.out.result, "QueryInfoKey failed");
    1596             : 
    1597         268 :         if (pmax_valnamelen) {
    1598         268 :                 *pmax_valnamelen = max_valnamelen;
    1599             :         }
    1600             : 
    1601         268 :         if (pmax_valbufsize) {
    1602         268 :                 *pmax_valbufsize = max_valbufsize;
    1603             :         }
    1604             : 
    1605         268 :         return true;
    1606             : }
    1607             : 
    1608        3840 : static bool test_SetValue(struct dcerpc_binding_handle *b,
    1609             :                           struct torture_context *tctx,
    1610             :                           struct policy_handle *handle,
    1611             :                           const char *value_name,
    1612             :                           enum winreg_Type type,
    1613             :                           uint8_t *data,
    1614             :                           uint32_t size)
    1615             : {
    1616           0 :         struct winreg_SetValue r;
    1617           0 :         struct winreg_String name;
    1618             : 
    1619        3840 :         torture_comment(tctx, "Testing SetValue(%s), type: %s, offered: 0x%08x)\n",
    1620             :                 value_name, str_regtype(type), size);
    1621             : 
    1622        3840 :         init_winreg_String(&name, value_name);
    1623             : 
    1624        3840 :         r.in.handle = handle;
    1625        3840 :         r.in.name = name;
    1626        3840 :         r.in.type = type;
    1627        3840 :         r.in.data = data;
    1628        3840 :         r.in.size = size;
    1629             : 
    1630        3840 :         torture_assert_ntstatus_ok(tctx, dcerpc_winreg_SetValue_r(b, tctx, &r),
    1631             :                 "winreg_SetValue failed");
    1632        3840 :         torture_assert_werr_ok(tctx, r.out.result,
    1633             :                 "winreg_SetValue failed");
    1634             : 
    1635        3840 :         return true;
    1636             : }
    1637             : 
    1638        3840 : static bool test_DeleteValue(struct dcerpc_binding_handle *b,
    1639             :                              struct torture_context *tctx,
    1640             :                              struct policy_handle *handle,
    1641             :                              const char *value_name)
    1642             : {
    1643           0 :         struct winreg_DeleteValue r;
    1644           0 :         struct winreg_String value;
    1645             : 
    1646        3840 :         torture_comment(tctx, "Testing DeleteValue(%s)\n", value_name);
    1647             : 
    1648        3840 :         init_winreg_String(&value, value_name);
    1649             : 
    1650        3840 :         r.in.handle = handle;
    1651        3840 :         r.in.value = value;
    1652             : 
    1653        3840 :         torture_assert_ntstatus_ok(tctx, dcerpc_winreg_DeleteValue_r(b, tctx, &r),
    1654             :                 "winreg_DeleteValue failed");
    1655        3840 :         torture_assert_werr_ok(tctx, r.out.result,
    1656             :                 "winreg_DeleteValue failed");
    1657             : 
    1658        3840 :         return true;
    1659             : }
    1660             : 
    1661             : static bool test_key(struct dcerpc_pipe *p, struct torture_context *tctx,
    1662             :                      struct policy_handle *handle, int depth,
    1663             :                      bool test_security);
    1664             : 
    1665         268 : static bool test_EnumKey(struct dcerpc_pipe *p, struct torture_context *tctx,
    1666             :                          struct policy_handle *handle, int depth,
    1667             :                          bool test_security)
    1668             : {
    1669           0 :         struct winreg_EnumKey r;
    1670           0 :         struct winreg_StringBuf kclass, name;
    1671           0 :         NTSTATUS status;
    1672         268 :         NTTIME t = 0;
    1673         268 :         struct dcerpc_binding_handle *b = p->binding_handle;
    1674             : 
    1675         268 :         kclass.name   = "";
    1676         268 :         kclass.size   = 1024;
    1677             : 
    1678         268 :         ZERO_STRUCT(r);
    1679         268 :         r.in.handle = handle;
    1680         268 :         r.in.enum_index = 0;
    1681         268 :         r.in.name = &name;
    1682         268 :         r.in.keyclass = &kclass;
    1683         268 :         r.out.name = &name;
    1684         268 :         r.in.last_changed_time = &t;
    1685             : 
    1686           0 :         do {
    1687         289 :                 name.name   = NULL;
    1688         289 :                 name.size   = 1024;
    1689             : 
    1690         289 :                 status = dcerpc_winreg_EnumKey_r(b, tctx, &r);
    1691             : 
    1692         289 :                 if (NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(r.out.result)) {
    1693           0 :                         struct policy_handle key_handle;
    1694             : 
    1695          21 :                         torture_comment(tctx, "EnumKey: %d: %s\n",
    1696             :                                         r.in.enum_index,
    1697          21 :                                         r.out.name->name);
    1698             : 
    1699          21 :                         if (!test_OpenKey(b, tctx, handle, r.out.name->name,
    1700             :                                           &key_handle)) {
    1701             :                         } else {
    1702          21 :                                 test_key(p, tctx, &key_handle,
    1703             :                                          depth + 1, test_security);
    1704             :                         }
    1705             :                 }
    1706             : 
    1707         289 :                 r.in.enum_index++;
    1708             : 
    1709         289 :         } while (NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(r.out.result));
    1710             : 
    1711         268 :         torture_assert_ntstatus_ok(tctx, status, "EnumKey failed");
    1712             : 
    1713         268 :         if (!W_ERROR_IS_OK(r.out.result) &&
    1714         268 :                 !W_ERROR_EQUAL(r.out.result, WERR_NO_MORE_ITEMS)) {
    1715           0 :                 torture_fail(tctx, "EnumKey failed");
    1716             :         }
    1717             : 
    1718         268 :         return true;
    1719             : }
    1720             : 
    1721           0 : static bool test_QueryMultipleValues(struct dcerpc_binding_handle *b,
    1722             :                                      struct torture_context *tctx,
    1723             :                                      struct policy_handle *handle,
    1724             :                                      const char *valuename)
    1725             : {
    1726           0 :         struct winreg_QueryMultipleValues r;
    1727           0 :         uint32_t bufsize=0;
    1728             : 
    1729           0 :         ZERO_STRUCT(r);
    1730             : 
    1731           0 :         r.in.key_handle = handle;
    1732           0 :         r.in.values_in = r.out.values_out = talloc_zero_array(tctx, struct QueryMultipleValue, 1);
    1733           0 :         r.in.values_in[0].ve_valuename = talloc(tctx, struct winreg_ValNameBuf);
    1734           0 :         r.in.values_in[0].ve_valuename->name = valuename;
    1735             :         /* size needs to be set manually for winreg_ValNameBuf */
    1736           0 :         r.in.values_in[0].ve_valuename->size = strlen_m_term(valuename)*2;
    1737             : 
    1738           0 :         r.in.num_values = 1;
    1739           0 :         r.in.buffer_size = r.out.buffer_size = talloc(tctx, uint32_t);
    1740           0 :         *r.in.buffer_size = bufsize;
    1741           0 :         do {
    1742           0 :                 *r.in.buffer_size = bufsize;
    1743           0 :                 r.in.buffer = r.out.buffer = talloc_zero_array(tctx, uint8_t,
    1744             :                                                                *r.in.buffer_size);
    1745             : 
    1746           0 :                 torture_assert_ntstatus_ok(tctx,
    1747             :                         dcerpc_winreg_QueryMultipleValues_r(b, tctx, &r),
    1748             :                         "QueryMultipleValues failed");
    1749             : 
    1750           0 :                 talloc_free(r.in.buffer);
    1751           0 :                 bufsize += 0x20;
    1752           0 :         } while (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA));
    1753             : 
    1754           0 :         torture_assert_werr_ok(tctx, r.out.result, "QueryMultipleValues failed");
    1755             : 
    1756           0 :         return true;
    1757             : }
    1758             : 
    1759          36 : static bool test_QueryMultipleValues_full(struct dcerpc_binding_handle *b,
    1760             :                                           struct torture_context *tctx,
    1761             :                                           struct policy_handle *handle,
    1762             :                                           uint32_t num_values,
    1763             :                                           const char * const *valuenames,
    1764             :                                           bool existing_value)
    1765             : {
    1766           0 :         struct winreg_QueryMultipleValues r;
    1767          36 :         uint32_t bufsize = 0;
    1768           0 :         int i;
    1769             : 
    1770          36 :         torture_comment(tctx, "Testing QueryMultipleValues\n");
    1771             : 
    1772          36 :         ZERO_STRUCT(r);
    1773             : 
    1774          36 :         r.in.key_handle = handle;
    1775          36 :         r.in.values_in = r.out.values_out = talloc_zero_array(tctx, struct QueryMultipleValue, 0);
    1776          36 :         r.in.buffer_size = r.out.buffer_size = &bufsize;
    1777             : 
    1778          36 :         torture_assert_ntstatus_ok(tctx,
    1779             :                 dcerpc_winreg_QueryMultipleValues_r(b, tctx, &r),
    1780             :                 "QueryMultipleValues failed");
    1781          36 :         torture_assert_werr_ok(tctx, r.out.result,
    1782             :                 "QueryMultipleValues failed");
    1783             : 
    1784             :         /* this test crashes w2k8 remote registry */
    1785             : #if 0
    1786             :         r.in.num_values = num_values;
    1787             :         r.in.values_in = r.out.values_out = talloc_zero_array(tctx, struct QueryMultipleValue, num_values);
    1788             : 
    1789             :         torture_assert_ntstatus_ok(tctx,
    1790             :                 dcerpc_winreg_QueryMultipleValues_r(b, tctx, &r),
    1791             :                 "QueryMultipleValues failed");
    1792             :         torture_assert_werr_ok(tctx, r.out.result,
    1793             :                 "QueryMultipleValues failed");
    1794             : #endif
    1795          36 :         r.in.num_values = num_values;
    1796          36 :         r.in.values_in = r.out.values_out = talloc_zero_array(tctx, struct QueryMultipleValue, num_values);
    1797         108 :         for (i=0; i < r.in.num_values; i++) {
    1798          72 :                 r.in.values_in[i].ve_valuename = talloc_zero(tctx, struct winreg_ValNameBuf);
    1799          72 :                 r.in.values_in[i].ve_valuename->name = talloc_strdup(tctx, valuenames[i]);
    1800          72 :                 r.in.values_in[i].ve_valuename->size = strlen_m_term(r.in.values_in[i].ve_valuename->name)*2;
    1801             :         }
    1802             : 
    1803          36 :         torture_assert_ntstatus_ok(tctx,
    1804             :                 dcerpc_winreg_QueryMultipleValues_r(b, tctx, &r),
    1805             :                 "QueryMultipleValues failed");
    1806          36 :         torture_assert_werr_equal(tctx, r.out.result, existing_value ? WERR_MORE_DATA : WERR_FILE_NOT_FOUND,
    1807             :                 "QueryMultipleValues failed");
    1808             : 
    1809          36 :         if (W_ERROR_EQUAL(r.out.result, WERR_FILE_NOT_FOUND)) {
    1810          20 :                 return true;
    1811             :         }
    1812             : 
    1813          16 :         if (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA)) {
    1814          16 :                 *r.in.buffer_size = 0xff;
    1815          16 :                 r.in.buffer = r.out.buffer = talloc_zero_array(tctx, uint8_t, *r.in.buffer_size);
    1816             : 
    1817          16 :                 torture_assert_ntstatus_ok(tctx,
    1818             :                         dcerpc_winreg_QueryMultipleValues_r(b, tctx, &r),
    1819             :                         "QueryMultipleValues failed");
    1820             :         }
    1821             : 
    1822          16 :         torture_assert_werr_ok(tctx, r.out.result,
    1823             :                 "QueryMultipleValues failed");
    1824             : 
    1825          16 :         return true;
    1826             : }
    1827             : 
    1828             : 
    1829          36 : static bool test_QueryMultipleValues2_full(struct dcerpc_binding_handle *b,
    1830             :                                            struct torture_context *tctx,
    1831             :                                            struct policy_handle *handle,
    1832             :                                            uint32_t num_values,
    1833             :                                            const char * const *valuenames,
    1834             :                                            bool existing_value)
    1835             : {
    1836           0 :         struct winreg_QueryMultipleValues2 r;
    1837          36 :         uint32_t offered = 0, needed;
    1838           0 :         int i;
    1839             : 
    1840          36 :         torture_comment(tctx, "Testing QueryMultipleValues2\n");
    1841             : 
    1842          36 :         ZERO_STRUCT(r);
    1843             : 
    1844          36 :         r.in.key_handle = handle;
    1845          36 :         r.in.offered = &offered;
    1846          36 :         r.in.values_in = r.out.values_out = talloc_zero_array(tctx, struct QueryMultipleValue, 0);
    1847          36 :         r.out.needed = &needed;
    1848             : 
    1849          36 :         torture_assert_ntstatus_ok(tctx,
    1850             :                 dcerpc_winreg_QueryMultipleValues2_r(b, tctx, &r),
    1851             :                 "QueryMultipleValues2 failed");
    1852          36 :         torture_assert_werr_ok(tctx, r.out.result,
    1853             :                 "QueryMultipleValues2 failed");
    1854             : 
    1855             :         /* this test crashes w2k8 remote registry */
    1856             : #if 0
    1857             :         r.in.num_values = num_values;
    1858             :         r.in.values_in = r.out.values_out = talloc_zero_array(tctx, struct QueryMultipleValue, num_values);
    1859             : 
    1860             :         torture_assert_ntstatus_ok(tctx,
    1861             :                 dcerpc_winreg_QueryMultipleValues2_r(b, tctx, &r),
    1862             :                 "QueryMultipleValues2 failed");
    1863             :         torture_assert_werr_ok(tctx, r.out.result,
    1864             :                 "QueryMultipleValues2 failed");
    1865             : #endif
    1866          36 :         r.in.num_values = num_values;
    1867          36 :         r.in.values_in = r.out.values_out = talloc_zero_array(tctx, struct QueryMultipleValue, num_values);
    1868         108 :         for (i=0; i < r.in.num_values; i++) {
    1869          72 :                 r.in.values_in[i].ve_valuename = talloc_zero(tctx, struct winreg_ValNameBuf);
    1870          72 :                 r.in.values_in[i].ve_valuename->name = talloc_strdup(tctx, valuenames[i]);
    1871          72 :                 r.in.values_in[i].ve_valuename->size = strlen_m_term(r.in.values_in[i].ve_valuename->name)*2;
    1872             :         }
    1873             : 
    1874          36 :         torture_assert_ntstatus_ok(tctx,
    1875             :                 dcerpc_winreg_QueryMultipleValues2_r(b, tctx, &r),
    1876             :                 "QueryMultipleValues2 failed");
    1877          36 :         torture_assert_werr_equal(tctx, r.out.result, existing_value ? WERR_MORE_DATA : WERR_FILE_NOT_FOUND,
    1878             :                 "QueryMultipleValues2 failed");
    1879             : 
    1880          36 :         if (W_ERROR_EQUAL(r.out.result, WERR_FILE_NOT_FOUND)) {
    1881          20 :                 return true;
    1882             :         }
    1883             : 
    1884          16 :         if (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA)) {
    1885          16 :                 *r.in.offered = *r.out.needed;
    1886          16 :                 r.in.buffer = r.out.buffer = talloc_zero_array(tctx, uint8_t, *r.in.offered);
    1887             : 
    1888          16 :                 torture_assert_ntstatus_ok(tctx,
    1889             :                         dcerpc_winreg_QueryMultipleValues2_r(b, tctx, &r),
    1890             :                         "QueryMultipleValues2 failed");
    1891             :         }
    1892             : 
    1893          16 :         torture_assert_werr_ok(tctx, r.out.result,
    1894             :                 "QueryMultipleValues2 failed");
    1895             : 
    1896          16 :         return true;
    1897             : }
    1898             : 
    1899           0 : static bool test_QueryMultipleValues2(struct dcerpc_binding_handle *b,
    1900             :                                       struct torture_context *tctx,
    1901             :                                       struct policy_handle *handle,
    1902             :                                       const char *valuename)
    1903             : {
    1904           0 :         struct winreg_QueryMultipleValues2 r;
    1905           0 :         uint32_t offered = 0, needed;
    1906             : 
    1907           0 :         ZERO_STRUCT(r);
    1908             : 
    1909           0 :         r.in.key_handle = handle;
    1910           0 :         r.in.values_in = r.out.values_out = talloc_zero_array(tctx, struct QueryMultipleValue, 1);
    1911           0 :         r.in.values_in[0].ve_valuename = talloc(tctx, struct winreg_ValNameBuf);
    1912           0 :         r.in.values_in[0].ve_valuename->name = valuename;
    1913             :         /* size needs to be set manually for winreg_ValNameBuf */
    1914           0 :         r.in.values_in[0].ve_valuename->size = strlen_m_term(valuename)*2;
    1915             : 
    1916           0 :         r.in.num_values = 1;
    1917           0 :         r.in.offered = &offered;
    1918           0 :         r.out.needed = &needed;
    1919             : 
    1920           0 :         torture_assert_ntstatus_ok(tctx,
    1921             :                 dcerpc_winreg_QueryMultipleValues2_r(b, tctx, &r),
    1922             :                 "QueryMultipleValues2 failed");
    1923           0 :         if (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA)) {
    1924           0 :                 *r.in.offered = *r.out.needed;
    1925           0 :                 r.in.buffer = r.out.buffer = talloc_zero_array(tctx, uint8_t, *r.in.offered);
    1926             : 
    1927           0 :                 torture_assert_ntstatus_ok(tctx,
    1928             :                         dcerpc_winreg_QueryMultipleValues2_r(b, tctx, &r),
    1929             :                         "QueryMultipleValues2 failed");
    1930             :         }
    1931             : 
    1932           0 :         torture_assert_werr_ok(tctx, r.out.result,
    1933             :                 "QueryMultipleValues2 failed");
    1934             : 
    1935           0 :         return true;
    1936             : }
    1937             : 
    1938           0 : static bool test_QueryValue(struct dcerpc_binding_handle *b,
    1939             :                             struct torture_context *tctx,
    1940             :                             struct policy_handle *handle,
    1941             :                             const char *valuename)
    1942             : {
    1943           0 :         struct winreg_QueryValue r;
    1944           0 :         NTSTATUS status;
    1945           0 :         enum winreg_Type zero_type = 0;
    1946           0 :         uint32_t offered = 0xfff;
    1947           0 :         uint32_t zero = 0;
    1948             : 
    1949           0 :         ZERO_STRUCT(r);
    1950           0 :         r.in.handle = handle;
    1951           0 :         r.in.data = NULL;
    1952           0 :         r.in.value_name = talloc_zero(tctx, struct winreg_String);
    1953           0 :         r.in.value_name->name = valuename;
    1954           0 :         r.in.type = &zero_type;
    1955           0 :         r.in.data_size = &offered;
    1956           0 :         r.in.data_length = &zero;
    1957             : 
    1958           0 :         status = dcerpc_winreg_QueryValue_r(b, tctx, &r);
    1959           0 :         if (NT_STATUS_IS_ERR(status)) {
    1960           0 :                 torture_fail(tctx, "QueryValue failed");
    1961             :         }
    1962             : 
    1963           0 :         torture_assert_werr_ok(tctx, r.out.result, "QueryValue failed");
    1964             : 
    1965           0 :         return true;
    1966             : }
    1967             : 
    1968        1914 : static bool test_QueryValue_full(struct dcerpc_binding_handle *b,
    1969             :                                  struct torture_context *tctx,
    1970             :                                  struct policy_handle *handle,
    1971             :                                  const char *valuename,
    1972             :                                  bool existing_value)
    1973             : {
    1974           0 :         struct winreg_QueryValue r;
    1975           0 :         struct winreg_String value_name;
    1976        1914 :         enum winreg_Type type = REG_NONE;
    1977        1914 :         uint32_t data_size = 0;
    1978        1914 :         uint32_t real_data_size = 0;
    1979        1914 :         uint32_t data_length = 0;
    1980        1914 :         uint8_t *data = NULL;
    1981        1914 :         WERROR expected_error = WERR_FILE_NOT_FOUND;
    1982        1914 :         const char *errmsg_nonexisting = "expected WERR_FILE_NOT_FOUND for nonexisting value";
    1983             : 
    1984        1914 :         if (valuename == NULL) {
    1985          87 :                 expected_error = WERR_INVALID_PARAMETER;
    1986          87 :                 errmsg_nonexisting = "expected WERR_INVALID_PARAMETER for NULL valuename";
    1987             :         }
    1988             : 
    1989        1914 :         ZERO_STRUCT(r);
    1990             : 
    1991        1914 :         init_winreg_String(&value_name, NULL);
    1992             : 
    1993        1914 :         torture_comment(tctx, "Testing QueryValue(%s)\n", valuename);
    1994             : 
    1995        1914 :         r.in.handle = handle;
    1996        1914 :         r.in.value_name = &value_name;
    1997             : 
    1998        1914 :         torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r), "QueryValue failed");
    1999        1914 :         torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_PARAMETER,
    2000             :                 "expected WERR_INVALID_PARAMETER for NULL winreg_String.name");
    2001             : 
    2002        1914 :         init_winreg_String(&value_name, valuename);
    2003        1914 :         r.in.value_name = &value_name;
    2004             : 
    2005        1914 :         torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r),
    2006             :                 "QueryValue failed");
    2007        1914 :         torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_PARAMETER,
    2008             :                 "expected WERR_INVALID_PARAMETER for missing type length and size");
    2009             : 
    2010        1914 :         r.in.type = &type;
    2011        1914 :         r.out.type = &type;
    2012        1914 :         torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r),
    2013             :                 "QueryValue failed");
    2014        1914 :         torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_PARAMETER,
    2015             :                 "expected WERR_INVALID_PARAMETER for missing length and size");
    2016             : 
    2017        1914 :         r.in.data_length = &data_length;
    2018        1914 :         r.out.data_length = &data_length;
    2019        1914 :         torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r),
    2020             :                 "QueryValue failed");
    2021        1914 :         torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_PARAMETER,
    2022             :                 "expected WERR_INVALID_PARAMETER for missing size");
    2023             : 
    2024        1914 :         r.in.data_size = &data_size;
    2025        1914 :         r.out.data_size = &data_size;
    2026        1914 :         torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r),
    2027             :                 "QueryValue failed");
    2028        1914 :         if (existing_value) {
    2029        1653 :                 torture_assert_werr_ok(tctx, r.out.result,
    2030             :                         "QueryValue failed");
    2031             :         } else {
    2032         261 :                 torture_assert_werr_equal(tctx, r.out.result, expected_error,
    2033             :                         errmsg_nonexisting);
    2034             :         }
    2035             : 
    2036        1914 :         real_data_size = *r.out.data_size;
    2037             : 
    2038        1914 :         data = talloc_zero_array(tctx, uint8_t, 0);
    2039        1914 :         r.in.data = data;
    2040        1914 :         r.out.data = data;
    2041        1914 :         *r.in.data_size = 0;
    2042        1914 :         *r.out.data_size = 0;
    2043        1914 :         torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r),
    2044             :                 "QueryValue failed");
    2045        1914 :         if (existing_value) {
    2046        1653 :                 torture_assert_werr_equal(tctx, r.out.result, WERR_MORE_DATA,
    2047             :                         "expected WERR_MORE_DATA for query with too small buffer");
    2048             :         } else {
    2049         261 :                 torture_assert_werr_equal(tctx, r.out.result, expected_error,
    2050             :                         errmsg_nonexisting);
    2051             :         }
    2052             : 
    2053        1914 :         data = talloc_zero_array(tctx, uint8_t, real_data_size);
    2054        1914 :         r.in.data = data;
    2055        1914 :         r.out.data = data;
    2056        1914 :         r.in.data_size = &real_data_size;
    2057        1914 :         r.out.data_size = &real_data_size;
    2058        1914 :         torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r),
    2059             :                 "QueryValue failed");
    2060        1914 :         if (existing_value) {
    2061        1653 :                 torture_assert_werr_ok(tctx, r.out.result,
    2062             :                         "QueryValue failed");
    2063             :         } else {
    2064         261 :                 torture_assert_werr_equal(tctx, r.out.result, expected_error,
    2065             :                         errmsg_nonexisting);
    2066             :         }
    2067             : 
    2068        1914 :         return true;
    2069             : }
    2070             : 
    2071         529 : static bool test_EnumValue_one(struct dcerpc_binding_handle *b,
    2072             :                                struct torture_context *tctx,
    2073             :                                struct policy_handle *handle,
    2074             :                                int max_valnamelen)
    2075             : {
    2076           0 :         struct winreg_EnumValue r;
    2077         529 :         bool ret = true;
    2078           0 :         DATA_BLOB blob;
    2079             : 
    2080         529 :         blob = data_blob_string_const("data_1");
    2081         529 :         torture_assert_goto(tctx,
    2082             :                 test_SetValue(b, tctx, handle, "v1", REG_BINARY, blob.data, blob.length),
    2083             :                 ret, done,
    2084             :                 "test_SetValue failed");
    2085             : 
    2086         529 :         blob = data_blob_string_const("data_2");
    2087         529 :         torture_assert_goto(tctx,
    2088             :                 test_SetValue(b, tctx, handle, "v2", REG_BINARY, blob.data, blob.length),
    2089             :                 ret, done,
    2090             :                 "test_SetValue failed");
    2091             : 
    2092         529 :         ZERO_STRUCT(r);
    2093             : 
    2094         529 :         r.in.handle = handle;
    2095         529 :         r.in.enum_index = 0;
    2096             : 
    2097           0 :         do {
    2098        1587 :                 enum winreg_Type type = REG_NONE;
    2099        1587 :                 uint32_t size = 0, zero = 0;
    2100           0 :                 struct winreg_ValNameBuf name;
    2101        1587 :                 char n = '\0';
    2102             : 
    2103        1587 :                 r.in.name = &name;
    2104        1587 :                 r.in.type = &type;
    2105        1587 :                 r.in.length = &zero;
    2106        1587 :                 r.in.size = &size;
    2107        1587 :                 r.out.name = &name;
    2108        1587 :                 r.out.size = &size;
    2109             : 
    2110        1587 :                 name.name = &n;
    2111        1587 :                 name.size = max_valnamelen + 2;
    2112        1587 :                 name.length = 0;
    2113             : 
    2114        1587 :                 r.in.value = talloc_array(tctx, uint8_t, 0);
    2115        1587 :                 torture_assert(tctx, r.in.value, "nomem");
    2116             : 
    2117        1587 :                 torture_assert_ntstatus_ok_goto(tctx,
    2118             :                         dcerpc_winreg_EnumValue_r(b, tctx, &r),
    2119             :                         ret, done,
    2120             :                         "EnumValue failed");
    2121        1587 :                 if (W_ERROR_EQUAL(r.out.result, WERR_NO_MORE_ITEMS)) {
    2122         529 :                         break;
    2123             :                 }
    2124        1058 :                 torture_assert_werr_equal_goto(tctx,
    2125             :                         r.out.result, WERR_MORE_DATA,
    2126             :                         ret, done,
    2127             :                         "unexpected return code");
    2128             : 
    2129        1058 :                 *r.in.size = *r.out.size;
    2130        1058 :                 r.in.value = talloc_zero_array(tctx, uint8_t, *r.in.size);
    2131        1058 :                 torture_assert(tctx, r.in.value, "nomem");
    2132             : 
    2133        1058 :                 torture_assert_ntstatus_ok_goto(tctx,
    2134             :                         dcerpc_winreg_EnumValue_r(b, tctx, &r),
    2135             :                         ret, done,
    2136             :                         "EnumValue failed");
    2137        1058 :                 torture_assert_werr_ok_goto(tctx, r.out.result,
    2138             :                         ret, done,
    2139             :                         "unexpected return code");
    2140             : 
    2141        1058 :                 r.in.enum_index++;
    2142             : 
    2143        1058 :         } while (W_ERROR_IS_OK(r.out.result));
    2144             : 
    2145         529 :         torture_assert_werr_equal_goto(tctx, r.out.result, WERR_NO_MORE_ITEMS,
    2146             :                 ret, done,
    2147             :                 "EnumValue failed");
    2148         529 :  done:
    2149         529 :         test_DeleteValue(b, tctx, handle, "v1");
    2150         529 :         test_DeleteValue(b, tctx, handle, "v2");
    2151             : 
    2152         529 :         return ret;
    2153             : }
    2154             : 
    2155         536 : static bool test_EnumValue(struct dcerpc_binding_handle *b,
    2156             :                            struct torture_context *tctx,
    2157             :                            struct policy_handle *handle, int max_valnamelen,
    2158             :                            int max_valbufsize)
    2159             : {
    2160           0 :         struct winreg_EnumValue r;
    2161         536 :         enum winreg_Type type = 0;
    2162         536 :         uint32_t size = max_valbufsize, zero = 0;
    2163         536 :         bool ret = true;
    2164         536 :         uint8_t *data = NULL;
    2165           0 :         struct winreg_ValNameBuf name;
    2166         536 :         char n = '\0';
    2167             : 
    2168         536 :         ZERO_STRUCT(r);
    2169         536 :         r.in.handle = handle;
    2170         536 :         r.in.enum_index = 0;
    2171         536 :         r.in.name = &name;
    2172         536 :         r.out.name = &name;
    2173         536 :         r.in.type = &type;
    2174         536 :         r.in.length = &zero;
    2175         536 :         r.in.size = &size;
    2176             : 
    2177           0 :         do {
    2178         536 :                 name.name = &n;
    2179         536 :                 name.size = max_valnamelen + 2;
    2180         536 :                 name.length = 0;
    2181             : 
    2182         536 :                 data = NULL;
    2183         536 :                 if (size) {
    2184         268 :                         data = talloc_array(tctx, uint8_t, size);
    2185             :                 }
    2186         536 :                 r.in.value = data;
    2187             : 
    2188         536 :                 torture_assert_ntstatus_ok(tctx,
    2189             :                                            dcerpc_winreg_EnumValue_r(b, tctx, &r),
    2190             :                                            "EnumValue failed");
    2191             : 
    2192         536 :                 if (W_ERROR_IS_OK(r.out.result)) {
    2193           0 :                         ret &= test_QueryValue(b, tctx, handle,
    2194           0 :                                                r.out.name->name);
    2195           0 :                         ret &= test_QueryMultipleValues(b, tctx, handle,
    2196           0 :                                                         r.out.name->name);
    2197           0 :                         ret &= test_QueryMultipleValues2(b, tctx, handle,
    2198           0 :                                                          r.out.name->name);
    2199             :                 }
    2200             : 
    2201         536 :                 talloc_free(data);
    2202             : 
    2203         536 :                 r.in.enum_index++;
    2204         536 :         } while (W_ERROR_IS_OK(r.out.result));
    2205             : 
    2206         536 :         torture_assert_werr_equal(tctx, r.out.result, WERR_NO_MORE_ITEMS,
    2207             :                                   "EnumValue failed");
    2208             : 
    2209         536 :         return ret;
    2210             : }
    2211             : 
    2212           0 : static bool test_AbortSystemShutdown(struct dcerpc_binding_handle *b,
    2213             :                                      struct torture_context *tctx)
    2214             : {
    2215           0 :         struct winreg_AbortSystemShutdown r;
    2216           0 :         uint16_t server = 0x0;
    2217             : 
    2218           0 :         ZERO_STRUCT(r);
    2219           0 :         r.in.server = &server;
    2220             : 
    2221           0 :         torture_assert_ntstatus_ok(tctx,
    2222             :                                    dcerpc_winreg_AbortSystemShutdown_r(b, tctx, &r),
    2223             :                                    "AbortSystemShutdown failed");
    2224             : 
    2225           0 :         torture_assert_werr_ok(tctx, r.out.result,
    2226             :                                "AbortSystemShutdown failed");
    2227             : 
    2228           0 :         return true;
    2229             : }
    2230             : 
    2231           0 : static bool test_InitiateSystemShutdown(struct torture_context *tctx,
    2232             :                                         struct dcerpc_pipe *p)
    2233             : {
    2234           0 :         struct winreg_InitiateSystemShutdown r;
    2235           0 :         uint16_t hostname = 0x0;
    2236           0 :         struct dcerpc_binding_handle *b = p->binding_handle;
    2237             : 
    2238           0 :         ZERO_STRUCT(r);
    2239           0 :         r.in.hostname = &hostname;
    2240           0 :         r.in.message = talloc(tctx, struct lsa_StringLarge);
    2241           0 :         init_lsa_StringLarge(r.in.message, "spottyfood");
    2242           0 :         r.in.force_apps = 1;
    2243           0 :         r.in.timeout = 30;
    2244           0 :         r.in.do_reboot = 1;
    2245             : 
    2246           0 :         torture_assert_ntstatus_ok(tctx,
    2247             :                                    dcerpc_winreg_InitiateSystemShutdown_r(b, tctx, &r),
    2248             :                                    "InitiateSystemShutdown failed");
    2249             : 
    2250           0 :         torture_assert_werr_ok(tctx, r.out.result,
    2251             :                                "InitiateSystemShutdown failed");
    2252             : 
    2253           0 :         return test_AbortSystemShutdown(b, tctx);
    2254             : }
    2255             : 
    2256             : 
    2257           0 : static bool test_InitiateSystemShutdownEx(struct torture_context *tctx,
    2258             :                                           struct dcerpc_pipe *p)
    2259             : {
    2260           0 :         struct winreg_InitiateSystemShutdownEx r;
    2261           0 :         uint16_t hostname = 0x0;
    2262           0 :         struct dcerpc_binding_handle *b = p->binding_handle;
    2263             : 
    2264           0 :         ZERO_STRUCT(r);
    2265           0 :         r.in.hostname = &hostname;
    2266           0 :         r.in.message = talloc(tctx, struct lsa_StringLarge);
    2267           0 :         init_lsa_StringLarge(r.in.message, "spottyfood");
    2268           0 :         r.in.force_apps = 1;
    2269           0 :         r.in.timeout = 30;
    2270           0 :         r.in.do_reboot = 1;
    2271           0 :         r.in.reason = 0;
    2272             : 
    2273           0 :         torture_assert_ntstatus_ok(tctx,
    2274             :                 dcerpc_winreg_InitiateSystemShutdownEx_r(b, tctx, &r),
    2275             :                 "InitiateSystemShutdownEx failed");
    2276             : 
    2277           0 :         torture_assert_werr_ok(tctx, r.out.result,
    2278             :                                "InitiateSystemShutdownEx failed");
    2279             : 
    2280           0 :         return test_AbortSystemShutdown(b, tctx);
    2281             : }
    2282             : #define MAX_DEPTH 2             /* Only go this far down the tree */
    2283             : 
    2284         282 : static bool test_key(struct dcerpc_pipe *p, struct torture_context *tctx,
    2285             :                      struct policy_handle *handle, int depth,
    2286             :                      bool test_security)
    2287             : {
    2288         282 :         struct dcerpc_binding_handle *b = p->binding_handle;
    2289         282 :         uint32_t max_valnamelen = 0;
    2290         282 :         uint32_t max_valbufsize = 0;
    2291             : 
    2292         282 :         if (depth == MAX_DEPTH)
    2293          14 :                 return true;
    2294             : 
    2295         268 :         if (!test_QueryInfoKey(b, tctx, handle, NULL,
    2296             :                                &max_valnamelen, &max_valbufsize)) {
    2297           0 :         }
    2298             : 
    2299         268 :         if (!test_NotifyChangeKeyValue(b, tctx, handle)) {
    2300           0 :         }
    2301             : 
    2302         268 :         if (test_security && !test_GetKeySecurity(p, tctx, handle, NULL)) {
    2303           0 :         }
    2304             : 
    2305         268 :         if (!test_EnumKey(p, tctx, handle, depth, test_security)) {
    2306           0 :         }
    2307             : 
    2308         268 :         if (!test_EnumValue(b, tctx, handle, max_valnamelen, max_valbufsize)) {
    2309           0 :         }
    2310             : 
    2311         268 :         if (!test_EnumValue(b, tctx, handle, max_valnamelen, 0xFFFF)) {
    2312           0 :         }
    2313             : 
    2314         268 :         if (!test_EnumValue_one(b, tctx, handle, 0xff)) {
    2315           0 :                 return false;
    2316             :         }
    2317             : 
    2318         268 :         test_CloseKey(b, tctx, handle);
    2319             : 
    2320         268 :         return true;
    2321             : }
    2322             : 
    2323          87 : static bool test_SetValue_simple(struct dcerpc_binding_handle *b,
    2324             :                                  struct torture_context *tctx,
    2325             :                                  struct policy_handle *handle)
    2326             : {
    2327          87 :         const char *value_name = TEST_VALUE;
    2328          87 :         uint32_t value = 0x12345678;
    2329          87 :         uint64_t value2 = 0x12345678;
    2330          87 :         const char *string = "torture";
    2331           0 :         const char *array[2];
    2332           0 :         DATA_BLOB blob;
    2333          87 :         enum winreg_Type types[] = {
    2334             :                 REG_DWORD,
    2335             :                 REG_DWORD_BIG_ENDIAN,
    2336             :                 REG_QWORD,
    2337             :                 REG_BINARY,
    2338             :                 REG_SZ,
    2339             :                 REG_MULTI_SZ
    2340             :         };
    2341           0 :         int t;
    2342             : 
    2343          87 :         array[0] = "array0";
    2344          87 :         array[1] = NULL;
    2345             : 
    2346          87 :         torture_comment(tctx, "Testing SetValue (standard formats)\n");
    2347             : 
    2348         609 :         for (t=0; t < ARRAY_SIZE(types); t++) {
    2349             : 
    2350           0 :                 enum winreg_Type w_type;
    2351           0 :                 uint32_t w_size, w_length;
    2352           0 :                 uint8_t *w_data;
    2353             : 
    2354         522 :                 switch (types[t]) {
    2355         174 :                 case REG_DWORD:
    2356             :                 case REG_DWORD_BIG_ENDIAN:
    2357         174 :                         blob = data_blob_talloc_zero(tctx, 4);
    2358         174 :                         SIVAL(blob.data, 0, value);
    2359         174 :                         break;
    2360          87 :                 case REG_QWORD:
    2361          87 :                         blob = data_blob_talloc_zero(tctx, 8);
    2362          87 :                         SBVAL(blob.data, 0, value2);
    2363          87 :                         break;
    2364          87 :                 case REG_BINARY:
    2365          87 :                         blob = data_blob_string_const("binary_blob");
    2366          87 :                         break;
    2367          87 :                 case REG_SZ:
    2368          87 :                         torture_assert(tctx, push_reg_sz(tctx, &blob, string), "failed to push REG_SZ");
    2369          87 :                         break;
    2370          87 :                 case REG_MULTI_SZ:
    2371          87 :                         torture_assert(tctx, push_reg_multi_sz(tctx, &blob, array), "failed to push REG_MULTI_SZ");
    2372          87 :                         break;
    2373           0 :                 default:
    2374           0 :                         break;
    2375             :                 }
    2376             : 
    2377         522 :                 torture_assert(tctx,
    2378             :                         test_SetValue(b, tctx, handle, value_name, types[t], blob.data, blob.length),
    2379             :                         "test_SetValue failed");
    2380         522 :                 torture_assert(tctx,
    2381             :                         test_QueryValue_full(b, tctx, handle, value_name, true),
    2382             :                         talloc_asprintf(tctx, "test_QueryValue_full for %s value failed", value_name));
    2383         522 :                 torture_assert(tctx,
    2384             :                         test_winreg_QueryValue(tctx, b, handle, value_name, &w_type, &w_size, &w_length, &w_data),
    2385             :                         "test_winreg_QueryValue failed");
    2386         522 :                 torture_assert(tctx,
    2387             :                         test_DeleteValue(b, tctx, handle, value_name),
    2388             :                         "test_DeleteValue failed");
    2389             : 
    2390         522 :                 torture_assert_int_equal(tctx, w_type, types[t], "winreg type mismatch");
    2391         522 :                 torture_assert_int_equal(tctx, w_size, blob.length, "winreg size mismatch");
    2392         522 :                 torture_assert_int_equal(tctx, w_length, blob.length, "winreg length mismatch");
    2393         522 :                 torture_assert_mem_equal(tctx, w_data, blob.data, blob.length, "winreg buffer mismatch");
    2394             :         }
    2395             : 
    2396          87 :         torture_comment(tctx, "Testing SetValue (standard formats) succeeded\n");
    2397             : 
    2398          87 :         return true;
    2399             : }
    2400             : 
    2401          87 : static bool test_SetValue_values(struct dcerpc_binding_handle *b,
    2402             :                                  struct torture_context *tctx,
    2403             :                                  struct policy_handle *handle)
    2404             : {
    2405           0 :         DATA_BLOB blob;
    2406          87 :         const char *values[] = {
    2407             :                 "torture_value",
    2408             :                 "torture value",
    2409             :                 "torture,value",
    2410             :                 "torture;value",
    2411             :                 "torture/value",
    2412             :                 "torture\\value",
    2413             :                 "torture_value_name",
    2414             :                 "torture value name",
    2415             :                 "torture,value,name",
    2416             :                 "torture;value;name",
    2417             :                 "torture/value/name",
    2418             :                 "torture\\value\\name",
    2419             :         };
    2420           0 :         int i;
    2421             : 
    2422          87 :         torture_comment(tctx, "Testing SetValue (values)\n");
    2423             : 
    2424        1131 :         for (i=0; i < ARRAY_SIZE(values); i++) {
    2425             : 
    2426           0 :                 enum winreg_Type w_type;
    2427           0 :                 uint32_t w_size, w_length;
    2428           0 :                 uint8_t *w_data;
    2429             : 
    2430        1044 :                 blob = data_blob_talloc(tctx, NULL, 32);
    2431             : 
    2432        1044 :                 generate_random_buffer(blob.data, 32);
    2433             : 
    2434        1044 :                 torture_assert(tctx,
    2435             :                         test_SetValue(b, tctx, handle, values[i], REG_BINARY, blob.data, blob.length),
    2436             :                         "test_SetValue failed");
    2437        1044 :                 torture_assert(tctx,
    2438             :                         test_QueryValue_full(b, tctx, handle, values[i], true),
    2439             :                         talloc_asprintf(tctx, "test_QueryValue_full for %s value failed", values[i]));
    2440        1044 :                 torture_assert(tctx,
    2441             :                         test_winreg_QueryValue(tctx, b, handle, values[i], &w_type, &w_size, &w_length, &w_data),
    2442             :                         "test_winreg_QueryValue failed");
    2443        1044 :                 torture_assert(tctx,
    2444             :                         test_DeleteValue(b, tctx, handle, values[i]),
    2445             :                         "test_DeleteValue failed");
    2446             : 
    2447        1044 :                 torture_assert_int_equal(tctx, w_type, REG_BINARY, "winreg type mismatch");
    2448        1044 :                 torture_assert_int_equal(tctx, w_size, blob.length, "winreg size mismatch");
    2449        1044 :                 torture_assert_int_equal(tctx, w_length, blob.length, "winreg length mismatch");
    2450        1044 :                 torture_assert_mem_equal(tctx, w_data, blob.data, blob.length, "winreg buffer mismatch");
    2451             :         }
    2452             : 
    2453          87 :         torture_comment(tctx, "Testing SetValue (values) succeeded\n");
    2454             : 
    2455          87 :         return true;
    2456             : }
    2457             : 
    2458             : typedef NTSTATUS (*winreg_open_fn)(struct dcerpc_binding_handle *, TALLOC_CTX *, void *);
    2459             : 
    2460          87 : static bool test_SetValue_extended(struct dcerpc_binding_handle *b,
    2461             :                                    struct torture_context *tctx,
    2462             :                                    struct policy_handle *handle)
    2463             : {
    2464          87 :         const char *value_name = TEST_VALUE;
    2465          87 :         enum winreg_Type types[] = {
    2466             :                 REG_NONE,
    2467             :                 REG_SZ,
    2468             :                 REG_EXPAND_SZ,
    2469             :                 REG_BINARY,
    2470             :                 REG_DWORD,
    2471             :                 REG_DWORD_BIG_ENDIAN,
    2472             :                 REG_LINK,
    2473             :                 REG_MULTI_SZ,
    2474             :                 REG_RESOURCE_LIST,
    2475             :                 REG_FULL_RESOURCE_DESCRIPTOR,
    2476             :                 REG_RESOURCE_REQUIREMENTS_LIST,
    2477             :                 REG_QWORD,
    2478             :                 12,
    2479             :                 13,
    2480             :                 14,
    2481             :                 55,
    2482             :                 123456,
    2483             :                 653210,
    2484             :                 __LINE__
    2485             :         };
    2486           0 :         int t, l;
    2487             : 
    2488          87 :         if (torture_setting_bool(tctx, "samba4", false)) {
    2489          83 :                 torture_skip(tctx, "skipping extended SetValue test against Samba4");
    2490             :         }
    2491             : 
    2492           4 :         torture_comment(tctx, "Testing SetValue (extended formats)\n");
    2493             : 
    2494          80 :         for (t=0; t < ARRAY_SIZE(types); t++) {
    2495        1292 :         for (l=0; l < 16; l++) {
    2496             : 
    2497           0 :                 enum winreg_Type w_type;
    2498           0 :                 uint32_t w_size, w_length;
    2499           0 :                 uint8_t *w_data;
    2500             : 
    2501           0 :                 uint32_t size;
    2502           0 :                 uint8_t *data;
    2503             : 
    2504        1216 :                 size = l;
    2505        1216 :                 data = talloc_array(tctx, uint8_t, size);
    2506             : 
    2507        1216 :                 generate_random_buffer(data, size);
    2508             : 
    2509        1216 :                 torture_assert(tctx,
    2510             :                         test_SetValue(b, tctx, handle, value_name, types[t], data, size),
    2511             :                         "test_SetValue failed");
    2512             : 
    2513        1216 :                 torture_assert(tctx,
    2514             :                         test_winreg_QueryValue(tctx, b, handle, value_name, &w_type, &w_size, &w_length, &w_data),
    2515             :                         "test_winreg_QueryValue failed");
    2516             : 
    2517        1216 :                 torture_assert(tctx,
    2518             :                         test_DeleteValue(b, tctx, handle, value_name),
    2519             :                         "test_DeleteValue failed");
    2520             : 
    2521        1216 :                 torture_assert_int_equal(tctx, w_type, types[t], "winreg type mismatch");
    2522        1216 :                 torture_assert_int_equal(tctx, w_size, size, "winreg size mismatch");
    2523        1216 :                 torture_assert_int_equal(tctx, w_length, size, "winreg length mismatch");
    2524        1216 :                 torture_assert_mem_equal(tctx, w_data, data, size, "winreg buffer mismatch");
    2525             :         }
    2526             :         }
    2527             : 
    2528           4 :         torture_comment(tctx, "Testing SetValue (extended formats) succeeded\n");
    2529             : 
    2530           4 :         return true;
    2531             : }
    2532             : 
    2533          87 : static bool test_create_keynames(struct dcerpc_binding_handle *b,
    2534             :                                  struct torture_context *tctx,
    2535             :                                  struct policy_handle *handle)
    2536             : {
    2537          87 :         const char *keys[] = {
    2538             :                 "torture_key",
    2539             :                 "torture key",
    2540             :                 "torture,key",
    2541             :                 "torture/key",
    2542             :                 "torture\\key",
    2543             :         };
    2544           0 :         int i;
    2545             : 
    2546         522 :         for (i=0; i < ARRAY_SIZE(keys); i++) {
    2547             : 
    2548           0 :                 enum winreg_CreateAction action_taken;
    2549           0 :                 struct policy_handle new_handle;
    2550           0 :                 char *q, *tmp;
    2551             : 
    2552         435 :                 torture_assert(tctx,
    2553             :                         test_CreateKey_opts(tctx, b, handle, keys[i], NULL,
    2554             :                                             REG_OPTION_NON_VOLATILE,
    2555             :                                             SEC_FLAG_MAXIMUM_ALLOWED,
    2556             :                                             NULL,
    2557             :                                             WERR_OK,
    2558             :                                             &action_taken,
    2559             :                                             &new_handle),
    2560             :                         talloc_asprintf(tctx, "failed to create '%s' key", keys[i]));
    2561             : 
    2562         435 :                 torture_assert_int_equal(tctx, action_taken, REG_CREATED_NEW_KEY, "unexpected action");
    2563             : 
    2564         435 :                 torture_assert(tctx,
    2565             :                         test_DeleteKey_opts(b, tctx, handle, keys[i], WERR_OK),
    2566             :                         "failed to delete key");
    2567             : 
    2568         435 :                 torture_assert(tctx,
    2569             :                         test_DeleteKey_opts(b, tctx, handle, keys[i], WERR_FILE_NOT_FOUND),
    2570             :                         "failed 2nd delete key");
    2571             : 
    2572         435 :                 tmp = talloc_strdup(tctx, keys[i]);
    2573             : 
    2574         435 :                 q = strchr(tmp, '\\');
    2575         435 :                 if (q != NULL) {
    2576          87 :                         *q = '\0';
    2577          87 :                         q++;
    2578             : 
    2579          87 :                         torture_assert(tctx,
    2580             :                                 test_DeleteKey_opts(b, tctx, handle, tmp, WERR_OK),
    2581             :                                 "failed to delete key");
    2582             : 
    2583          87 :                         torture_assert(tctx,
    2584             :                                 test_DeleteKey_opts(b, tctx, handle, tmp, WERR_FILE_NOT_FOUND),
    2585             :                                 "failed 2nd delete key");
    2586             :                 }
    2587             :         }
    2588             : 
    2589          87 :         return true;
    2590             : }
    2591             : 
    2592             : #define KEY_CURRENT_VERSION "SOFTWARE\\MICROSOFT\\WINDOWS NT\\CURRENTVERSION"
    2593             : #define VALUE_CURRENT_VERSION "CurrentVersion"
    2594             : #define VALUE_SYSTEM_ROOT "SystemRoot"
    2595             : 
    2596             : static const struct {
    2597             :         const char *values[3];
    2598             :         uint32_t num_values;
    2599             :         bool existing_value;
    2600             :         const char *error_message;
    2601             : } multiple_values_tests[] = {
    2602             :         {
    2603             :                 .values = { VALUE_CURRENT_VERSION, NULL, NULL },
    2604             :                 .num_values = 1,
    2605             :                 .existing_value = true,
    2606             :                 .error_message = NULL
    2607             :         },{
    2608             :                 .values = { VALUE_SYSTEM_ROOT, NULL, NULL },
    2609             :                 .num_values = 1,
    2610             :                 .existing_value = true,
    2611             :                 .error_message = NULL
    2612             :         },{
    2613             :                 .values = { VALUE_CURRENT_VERSION, VALUE_SYSTEM_ROOT, NULL },
    2614             :                 .num_values = 2,
    2615             :                 .existing_value = true,
    2616             :                 .error_message = NULL
    2617             :         },{
    2618             :                 .values = { VALUE_CURRENT_VERSION, VALUE_SYSTEM_ROOT,
    2619             :                             VALUE_CURRENT_VERSION },
    2620             :                 .num_values = 3,
    2621             :                 .existing_value = true,
    2622             :                 .error_message = NULL
    2623             :         },{
    2624             :                 .values = { VALUE_CURRENT_VERSION, NULL, VALUE_SYSTEM_ROOT },
    2625             :                 .num_values = 3,
    2626             :                 .existing_value = false,
    2627             :                 .error_message = NULL
    2628             :         },{
    2629             :                 .values = { VALUE_CURRENT_VERSION, "", VALUE_SYSTEM_ROOT },
    2630             :                 .num_values = 3,
    2631             :                 .existing_value = false,
    2632             :                 .error_message = NULL
    2633             :         },{
    2634             :                 .values = { "IDoNotExist", NULL, NULL },
    2635             :                 .num_values = 1,
    2636             :                 .existing_value = false,
    2637             :                 .error_message = NULL
    2638             :         },{
    2639             :                 .values = { "IDoNotExist", VALUE_CURRENT_VERSION, NULL },
    2640             :                 .num_values = 2,
    2641             :                 .existing_value = false,
    2642             :                 .error_message = NULL
    2643             :         },{
    2644             :                 .values = { VALUE_CURRENT_VERSION, "IDoNotExist", NULL },
    2645             :                 .num_values = 2,
    2646             :                 .existing_value = false,
    2647             :                 .error_message = NULL
    2648             :         }
    2649             : };
    2650             : 
    2651          87 : static bool test_HKLM_wellknown(struct torture_context *tctx,
    2652             :                                 struct dcerpc_binding_handle *b,
    2653             :                                 struct policy_handle *handle)
    2654             : {
    2655           0 :         struct policy_handle newhandle;
    2656           0 :         int i;
    2657             : 
    2658             :         /* FIXME: s3 does not support SEC_FLAG_MAXIMUM_ALLOWED yet */
    2659          87 :         if (torture_setting_bool(tctx, "samba3", false)) {
    2660           4 :                 torture_assert(tctx, test_OpenKey_opts(tctx, b, handle,
    2661             :                                KEY_CURRENT_VERSION,
    2662             :                                REG_OPTION_NON_VOLATILE,
    2663             :                                KEY_QUERY_VALUE,
    2664             :                                &newhandle,
    2665             :                                WERR_OK),
    2666             :                         "failed to open current version key");
    2667             :         } else {
    2668          83 :                 torture_assert(tctx, test_OpenKey(b, tctx, handle, KEY_CURRENT_VERSION, &newhandle),
    2669             :                         "failed to open current version key");
    2670             :         }
    2671             : 
    2672          87 :         torture_assert(tctx, test_QueryValue_full(b, tctx, &newhandle, VALUE_CURRENT_VERSION, true),
    2673             :                 "failed to query current version");
    2674          87 :         torture_assert(tctx, test_QueryValue_full(b, tctx, &newhandle, "IDoNotExist", false),
    2675             :                 "succeeded to query nonexistent value");
    2676          87 :         torture_assert(tctx, test_QueryValue_full(b, tctx, &newhandle, NULL, false),
    2677             :                 "succeeded to query value with NULL name");
    2678          87 :         torture_assert(tctx, test_QueryValue_full(b, tctx, &newhandle, "", false),
    2679             :                 "succeeded to query nonexistent default value (\"\")");
    2680             : 
    2681          87 :         if (torture_setting_bool(tctx, "samba4", false)) {
    2682          83 :                 torture_comment(tctx, "skipping QueryMultipleValues{2} tests against Samba4\n");
    2683          83 :                 goto close_key;
    2684             :         }
    2685             : 
    2686          40 :         for (i=0; i < ARRAY_SIZE(multiple_values_tests); i++) {
    2687           0 :                 const char *msg;
    2688          36 :                 msg = talloc_asprintf(tctx,
    2689             :                                 "failed to query %d %sexisting values\n",
    2690          36 :                                         multiple_values_tests[i].num_values,
    2691          36 :                                         multiple_values_tests[i].existing_value ? "":"non");
    2692             : 
    2693          36 :                 torture_assert(tctx,
    2694             :                         test_QueryMultipleValues_full(b, tctx, &newhandle,
    2695             :                                                       multiple_values_tests[i].num_values,
    2696             :                                                       multiple_values_tests[i].values,
    2697             :                                                       multiple_values_tests[i].existing_value),
    2698             :                         msg);
    2699          36 :                 torture_assert(tctx,
    2700             :                         test_QueryMultipleValues2_full(b, tctx, &newhandle,
    2701             :                                                        multiple_values_tests[i].num_values,
    2702             :                                                        multiple_values_tests[i].values,
    2703             :                                                        multiple_values_tests[i].existing_value),
    2704             :                         msg);
    2705             :         }
    2706             : 
    2707           4 :  close_key:
    2708          87 :         torture_assert(tctx, test_CloseKey(b, tctx, &newhandle),
    2709             :                 "failed to close current version key");
    2710             : 
    2711          87 :         return true;
    2712             : }
    2713             : 
    2714           0 : static bool test_OpenHive(struct torture_context *tctx,
    2715             :                           struct dcerpc_binding_handle *b,
    2716             :                           struct policy_handle *handle,
    2717             :                           int hkey)
    2718             : {
    2719           0 :         struct winreg_OpenHKLM r;
    2720             : 
    2721           0 :         r.in.system_name = 0;
    2722           0 :         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
    2723           0 :         r.out.handle = handle;
    2724             : 
    2725           0 :         switch (hkey) {
    2726           0 :         case HKEY_LOCAL_MACHINE:
    2727           0 :                 torture_assert_ntstatus_ok(tctx,
    2728             :                         dcerpc_winreg_OpenHKLM_r(b, tctx, &r),
    2729             :                         "failed to open HKLM");
    2730           0 :                 torture_assert_werr_ok(tctx, r.out.result,
    2731             :                         "failed to open HKLM");
    2732           0 :                 break;
    2733           0 :         case HKEY_CURRENT_USER:
    2734           0 :                 torture_assert_ntstatus_ok(tctx,
    2735             :                         dcerpc_winreg_OpenHKCU_r(b, tctx, (struct winreg_OpenHKCU *)(void *)&r),
    2736             :                         "failed to open HKCU");
    2737           0 :                 torture_assert_werr_ok(tctx, r.out.result,
    2738             :                         "failed to open HKCU");
    2739           0 :                 break;
    2740           0 :         case HKEY_USERS:
    2741           0 :                 torture_assert_ntstatus_ok(tctx,
    2742             :                         dcerpc_winreg_OpenHKU_r(b, tctx, (struct winreg_OpenHKU *)(void *)&r),
    2743             :                         "failed to open HKU");
    2744           0 :                 torture_assert_werr_ok(tctx, r.out.result,
    2745             :                         "failed to open HKU");
    2746           0 :                 break;
    2747           0 :         case HKEY_CLASSES_ROOT:
    2748           0 :                 torture_assert_ntstatus_ok(tctx,
    2749             :                         dcerpc_winreg_OpenHKCR_r(b, tctx, (struct winreg_OpenHKCR *)(void *)&r),
    2750             :                         "failed to open HKCR");
    2751           0 :                 torture_assert_werr_ok(tctx, r.out.result,
    2752             :                         "failed to open HKCR");
    2753           0 :                 break;
    2754           0 :         default:
    2755           0 :                 torture_warning(tctx, "unsupported hkey: 0x%08x\n", hkey);
    2756           0 :                 return false;
    2757             :         }
    2758             : 
    2759           0 :         return true;
    2760             : }
    2761             : 
    2762           0 : static bool test_volatile_keys(struct torture_context *tctx,
    2763             :                                struct dcerpc_binding_handle *b,
    2764             :                                struct policy_handle *handle,
    2765             :                                int hkey)
    2766             : {
    2767           0 :         struct policy_handle new_handle, hive_handle;
    2768           0 :         enum winreg_CreateAction action_taken = REG_ACTION_NONE;
    2769             : 
    2770           0 :         ZERO_STRUCT(new_handle);
    2771           0 :         ZERO_STRUCT(hive_handle);
    2772             : 
    2773           0 :         torture_comment(tctx, "Testing VOLATILE key\n");
    2774             : 
    2775           0 :         test_DeleteKey(b, tctx, handle, TEST_KEY_VOLATILE);
    2776             : 
    2777           0 :         torture_assert(tctx,
    2778             :                 test_CreateKey_opts(tctx, b, handle, TEST_KEY_VOLATILE, NULL,
    2779             :                                     REG_OPTION_VOLATILE,
    2780             :                                     SEC_FLAG_MAXIMUM_ALLOWED,
    2781             :                                     NULL,
    2782             :                                     WERR_OK,
    2783             :                                     &action_taken,
    2784             :                                     &new_handle),
    2785             :                 "failed to create REG_OPTION_VOLATILE type key");
    2786             : 
    2787           0 :         torture_assert_int_equal(tctx, action_taken, REG_CREATED_NEW_KEY, "unexpected action");
    2788             : 
    2789           0 :         torture_assert(tctx,
    2790             :                 test_CreateKey_opts(tctx, b, &new_handle, TEST_SUBKEY_VOLATILE, NULL,
    2791             :                                     REG_OPTION_NON_VOLATILE,
    2792             :                                     SEC_FLAG_MAXIMUM_ALLOWED,
    2793             :                                     NULL,
    2794             :                                     WERR_CHILD_MUST_BE_VOLATILE,
    2795             :                                     NULL,
    2796             :                                     NULL),
    2797             :                 "failed to fail create REG_OPTION_VOLATILE type key");
    2798             : 
    2799           0 :         torture_assert(tctx,
    2800             :                 test_CloseKey(b, tctx, &new_handle),
    2801             :                 "failed to close");
    2802             : 
    2803           0 :         torture_assert(tctx,
    2804             :                 test_OpenKey_opts(tctx, b, handle, TEST_KEY_VOLATILE,
    2805             :                                   REG_OPTION_NON_VOLATILE,
    2806             :                                   SEC_FLAG_MAXIMUM_ALLOWED,
    2807             :                                   &new_handle,
    2808             :                                   WERR_OK),
    2809             :                 "failed to open volatile key");
    2810             : 
    2811           0 :         torture_assert(tctx,
    2812             :                 test_DeleteKey(b, tctx, handle, TEST_KEY_VOLATILE),
    2813             :                 "failed to delete key");
    2814             : 
    2815           0 :         torture_assert(tctx,
    2816             :                 test_CreateKey_opts(tctx, b, handle, TEST_KEY_VOLATILE, NULL,
    2817             :                                     REG_OPTION_VOLATILE,
    2818             :                                     SEC_FLAG_MAXIMUM_ALLOWED,
    2819             :                                     NULL,
    2820             :                                     WERR_OK,
    2821             :                                     &action_taken,
    2822             :                                     &new_handle),
    2823             :                 "failed to create REG_OPTION_VOLATILE type key");
    2824             : 
    2825           0 :         torture_assert_int_equal(tctx, action_taken, REG_CREATED_NEW_KEY, "unexpected action");
    2826             : 
    2827           0 :         torture_assert(tctx,
    2828             :                 test_CloseKey(b, tctx, &new_handle),
    2829             :                 "failed to close");
    2830             : 
    2831           0 :         torture_assert(tctx,
    2832             :                 test_OpenKey_opts(tctx, b, handle, TEST_KEY_VOLATILE,
    2833             :                                   REG_OPTION_VOLATILE,
    2834             :                                   SEC_FLAG_MAXIMUM_ALLOWED,
    2835             :                                   &new_handle,
    2836             :                                   WERR_OK),
    2837             :                 "failed to open volatile key");
    2838             : 
    2839           0 :         torture_assert(tctx,
    2840             :                 test_CloseKey(b, tctx, &new_handle),
    2841             :                 "failed to close");
    2842             : 
    2843           0 :         torture_assert(tctx,
    2844             :                 test_OpenHive(tctx, b, &hive_handle, hkey),
    2845             :                 "failed top open hive");
    2846             : 
    2847           0 :         torture_assert(tctx,
    2848             :                 test_OpenKey_opts(tctx, b, &hive_handle, TEST_KEY_VOLATILE,
    2849             :                                   REG_OPTION_VOLATILE,
    2850             :                                   SEC_FLAG_MAXIMUM_ALLOWED,
    2851             :                                   &new_handle,
    2852             :                                   WERR_FILE_NOT_FOUND),
    2853             :                 "failed to open volatile key");
    2854             : 
    2855           0 :         torture_assert(tctx,
    2856             :                 test_OpenKey_opts(tctx, b, &hive_handle, TEST_KEY_VOLATILE,
    2857             :                                   REG_OPTION_NON_VOLATILE,
    2858             :                                   SEC_FLAG_MAXIMUM_ALLOWED,
    2859             :                                   &new_handle,
    2860             :                                   WERR_FILE_NOT_FOUND),
    2861             :                 "failed to open volatile key");
    2862             : 
    2863           0 :         torture_assert(tctx,
    2864             :                 test_CloseKey(b, tctx, &hive_handle),
    2865             :                 "failed to close");
    2866             : 
    2867           0 :         torture_assert(tctx,
    2868             :                 test_DeleteKey(b, tctx, handle, TEST_KEY_VOLATILE),
    2869             :                 "failed to delete key");
    2870             : 
    2871             : 
    2872           0 :         torture_comment(tctx, "Testing VOLATILE key succeeded\n");
    2873             : 
    2874           0 :         return true;
    2875             : }
    2876             : 
    2877           0 : static const char *kernel_mode_registry_path(struct torture_context *tctx,
    2878             :                                              int hkey,
    2879             :                                              const char *sid_string,
    2880             :                                              const char *path)
    2881             : {
    2882           0 :         switch (hkey) {
    2883           0 :         case HKEY_LOCAL_MACHINE:
    2884           0 :                 return talloc_asprintf(tctx, "\\Registry\\MACHINE\\%s", path);
    2885           0 :         case HKEY_CURRENT_USER:
    2886           0 :                 return talloc_asprintf(tctx, "\\Registry\\USER\\%s\\%s", sid_string, path);
    2887           0 :         case HKEY_USERS:
    2888           0 :                 return talloc_asprintf(tctx, "\\Registry\\USER\\%s", path);
    2889           0 :         case HKEY_CLASSES_ROOT:
    2890           0 :                 return talloc_asprintf(tctx, "\\Registry\\MACHINE\\Software\\Classes\\%s", path);
    2891           0 :         default:
    2892           0 :                 torture_warning(tctx, "unsupported hkey: 0x%08x\n", hkey);
    2893           0 :                 return NULL;
    2894             :         }
    2895             : }
    2896             : 
    2897           0 : static bool test_symlink_keys(struct torture_context *tctx,
    2898             :                               struct dcerpc_binding_handle *b,
    2899             :                               struct policy_handle *handle,
    2900             :                               const char *key,
    2901             :                               int hkey)
    2902             : {
    2903           0 :         struct policy_handle new_handle;
    2904           0 :         enum winreg_CreateAction action_taken;
    2905           0 :         DATA_BLOB blob;
    2906           0 :         uint32_t value = 42;
    2907           0 :         const char *test_key_symlink_dest;
    2908           0 :         const char *test_key_symlink;
    2909           0 :         const char *kernel_mode_path;
    2910             : 
    2911             :         /* disable until we know how to delete a symbolic link */
    2912           0 :         torture_skip(tctx, "symlink test disabled");
    2913             : 
    2914             :         torture_comment(tctx, "Testing REG_OPTION_CREATE_LINK key\n");
    2915             : 
    2916             :         /* create destination key with testvalue */
    2917             :         test_key_symlink = talloc_asprintf(tctx, "%s\\%s",
    2918             :                         key, TEST_KEY_SYMLINK);
    2919             :         test_key_symlink_dest = talloc_asprintf(tctx, "%s\\%s",
    2920             :                         key, TEST_KEY_SYMLINK_DEST);
    2921             : 
    2922             :         test_DeleteKey(b, tctx, handle, test_key_symlink);
    2923             : 
    2924             :         torture_assert(tctx,
    2925             :                 test_CreateKey_opts(tctx, b, handle, test_key_symlink_dest, NULL,
    2926             :                                     0,
    2927             :                                     SEC_FLAG_MAXIMUM_ALLOWED,
    2928             :                                     NULL,
    2929             :                                     WERR_OK,
    2930             :                                     &action_taken,
    2931             :                                     &new_handle),
    2932             :                 "failed to create symlink destination");
    2933             : 
    2934             :         blob = data_blob_talloc_zero(tctx, 4);
    2935             :         SIVAL(blob.data, 0, value);
    2936             : 
    2937             :         torture_assert(tctx,
    2938             :                 test_SetValue(b, tctx, &new_handle, "TestValue", REG_DWORD, blob.data, blob.length),
    2939             :                 "failed to create TestValue");
    2940             : 
    2941             :         torture_assert(tctx,
    2942             :                 test_CloseKey(b, tctx, &new_handle),
    2943             :                 "failed to close");
    2944             : 
    2945             :         /* create symlink */
    2946             : 
    2947             :         torture_assert(tctx,
    2948             :                 test_CreateKey_opts(tctx, b, handle, test_key_symlink, NULL,
    2949             :                                     REG_OPTION_CREATE_LINK | REG_OPTION_VOLATILE,
    2950             :                                     SEC_FLAG_MAXIMUM_ALLOWED,
    2951             :                                     NULL,
    2952             :                                     WERR_OK,
    2953             :                                     &action_taken,
    2954             :                                     &new_handle),
    2955             :                 "failed to create REG_OPTION_CREATE_LINK type key");
    2956             : 
    2957             :         torture_assert_int_equal(tctx, action_taken, REG_CREATED_NEW_KEY, "unexpected action");
    2958             : 
    2959             :         kernel_mode_path = kernel_mode_registry_path(tctx, hkey, NULL, test_key_symlink_dest);
    2960             : 
    2961             :         torture_assert(tctx,
    2962             :                 convert_string_talloc(tctx, CH_UNIX, CH_UTF16,
    2963             :                                       kernel_mode_path,
    2964             :                                       strlen(kernel_mode_path), /* not NULL terminated */
    2965             :                                       &blob.data, &blob.length),
    2966             :                 "failed to convert");
    2967             : 
    2968             :         torture_assert(tctx,
    2969             :                 test_SetValue(b, tctx, &new_handle, "SymbolicLinkValue", REG_LINK, blob.data, blob.length),
    2970             :                 "failed to create SymbolicLinkValue value");
    2971             : 
    2972             :         torture_assert(tctx,
    2973             :                 test_CloseKey(b, tctx, &new_handle),
    2974             :                 "failed to close");
    2975             : 
    2976             :         /* test follow symlink */
    2977             : 
    2978             :         torture_assert(tctx,
    2979             :                 test_OpenKey_opts(tctx, b, handle, test_key_symlink,
    2980             :                                   0,
    2981             :                                   SEC_FLAG_MAXIMUM_ALLOWED,
    2982             :                                   &new_handle,
    2983             :                                   WERR_OK),
    2984             :                 "failed to follow symlink key");
    2985             : 
    2986             :         torture_assert(tctx,
    2987             :                 test_QueryValue(b, tctx, &new_handle, "TestValue"),
    2988             :                 "failed to query value");
    2989             : 
    2990             :         torture_assert(tctx,
    2991             :                 test_CloseKey(b, tctx, &new_handle),
    2992             :                 "failed to close");
    2993             : 
    2994             :         /* delete link */
    2995             : 
    2996             :         torture_assert(tctx,
    2997             :                 test_OpenKey_opts(tctx, b, handle, test_key_symlink,
    2998             :                                   REG_OPTION_OPEN_LINK | REG_OPTION_VOLATILE,
    2999             :                                   SEC_FLAG_MAXIMUM_ALLOWED,
    3000             :                                   &new_handle,
    3001             :                                   WERR_OK),
    3002             :                 "failed to open symlink key");
    3003             : 
    3004             :         torture_assert(tctx,
    3005             :                 test_DeleteValue(b, tctx, &new_handle, "SymbolicLinkValue"),
    3006             :                 "failed to delete value SymbolicLinkValue");
    3007             : 
    3008             :         torture_assert(tctx,
    3009             :                 test_CloseKey(b, tctx, &new_handle),
    3010             :                 "failed to close");
    3011             : 
    3012             :         torture_assert(tctx,
    3013             :                 test_DeleteKey(b, tctx, handle, test_key_symlink),
    3014             :                 "failed to delete key");
    3015             : 
    3016             :         /* delete destination */
    3017             : 
    3018             :         torture_assert(tctx,
    3019             :                 test_DeleteKey(b, tctx, handle, test_key_symlink_dest),
    3020             :                 "failed to delete key");
    3021             : 
    3022             :         return true;
    3023             : }
    3024             : 
    3025         261 : static bool test_CreateKey_keytypes(struct torture_context *tctx,
    3026             :                                     struct dcerpc_binding_handle *b,
    3027             :                                     struct policy_handle *handle,
    3028             :                                     const char *key,
    3029             :                                     int hkey)
    3030             : {
    3031             : 
    3032         510 :         if (torture_setting_bool(tctx, "samba3", false) ||
    3033         249 :             torture_setting_bool(tctx, "samba4", false)) {
    3034         261 :                 torture_skip(tctx, "skipping CreateKey keytypes test against Samba");
    3035             :         }
    3036             : 
    3037           0 :         torture_assert(tctx,
    3038             :                 test_volatile_keys(tctx, b, handle, hkey),
    3039             :                 "failed to test volatile keys");
    3040             : 
    3041           0 :         torture_assert(tctx,
    3042             :                 test_symlink_keys(tctx, b, handle, key, hkey),
    3043             :                 "failed to test symlink keys");
    3044             : 
    3045           0 :         return true;
    3046             : }
    3047             : 
    3048         348 : static bool test_key_base(struct torture_context *tctx,
    3049             :                           struct dcerpc_binding_handle *b,
    3050             :                           struct policy_handle *handle,
    3051             :                           const char *base_key,
    3052             :                           int hkey)
    3053             : {
    3054           0 :         struct policy_handle newhandle;
    3055         348 :         bool ret = true, created = false, deleted = false;
    3056         348 :         bool created3 = false;
    3057           0 :         const char *test_key1;
    3058           0 :         const char *test_key3;
    3059           0 :         const char *test_subkey;
    3060             : 
    3061         348 :         test_Cleanup(b, tctx, handle, base_key);
    3062             : 
    3063         348 :         if (!test_CreateKey(b, tctx, handle, base_key, NULL)) {
    3064           0 :                 torture_comment(tctx,
    3065             :                                 "CreateKey(%s) failed\n", base_key);
    3066             :         }
    3067             : 
    3068         348 :         test_key1 = talloc_asprintf(tctx, "%s\\%s", base_key, TEST_KEY1);
    3069             : 
    3070         348 :         if (!test_CreateKey(b, tctx, handle, test_key1, NULL)) {
    3071           0 :                 torture_comment(tctx,
    3072             :                                 "CreateKey failed - not considering a failure\n");
    3073             :         } else {
    3074         348 :                 created = true;
    3075             :         }
    3076             : 
    3077         348 :         if (created) {
    3078         348 :                 if (!test_FlushKey(b, tctx, handle)) {
    3079           0 :                         torture_comment(tctx, "FlushKey failed\n");
    3080           0 :                         ret = false;
    3081             :                 }
    3082             : 
    3083         348 :                 if (!test_OpenKey(b, tctx, handle, test_key1, &newhandle)) {
    3084           0 :                         torture_fail(tctx,
    3085             :                                      "CreateKey failed (OpenKey after Create didn't work)\n");
    3086             :                 }
    3087             : 
    3088         348 :                 if (hkey == HKEY_CURRENT_USER) {
    3089          87 :                         torture_assert(tctx, test_SetValue_simple(b, tctx, &newhandle),
    3090             :                                 "simple SetValue test failed");
    3091          87 :                         torture_assert(tctx, test_SetValue_values(b, tctx, &newhandle),
    3092             :                                 "values SetValue test failed");
    3093          87 :                         torture_assert(tctx, test_SetValue_extended(b, tctx, &newhandle),
    3094             :                                 "extended SetValue test failed");
    3095          87 :                         torture_assert(tctx, test_create_keynames(b, tctx, &newhandle),
    3096             :                                 "keyname CreateKey test failed");
    3097             :                 } else {
    3098         261 :                         torture_assert(tctx, test_CreateKey_keytypes(tctx, b, &newhandle, test_key1, hkey),
    3099             :                                 "keytype test failed");
    3100         261 :                         torture_assert(tctx, test_EnumValue_one(b, tctx, &newhandle, 0xff),
    3101             :                                 "simple EnumValue test failed");
    3102             :                 }
    3103             : 
    3104         348 :                 if (!test_CloseKey(b, tctx, &newhandle)) {
    3105           0 :                         torture_fail(tctx,
    3106             :                                      "CreateKey failed (CloseKey after Open didn't work)\n");
    3107             :                 }
    3108             : 
    3109         348 :                 if (!test_DeleteKey(b, tctx, handle, test_key1)) {
    3110           0 :                         torture_comment(tctx, "DeleteKey(%s) failed\n",
    3111             :                                               test_key1);
    3112           0 :                         ret = false;
    3113             :                 } else {
    3114         348 :                         deleted = true;
    3115             :                 }
    3116             : 
    3117         348 :                 if (!test_FlushKey(b, tctx, handle)) {
    3118           0 :                         torture_comment(tctx, "FlushKey failed\n");
    3119           0 :                         ret = false;
    3120             :                 }
    3121             : 
    3122         348 :                 if (deleted) {
    3123         348 :                         if (!test_OpenKey_opts(tctx, b, handle, test_key1,
    3124             :                                                REG_OPTION_NON_VOLATILE,
    3125             :                                                SEC_FLAG_MAXIMUM_ALLOWED,
    3126             :                                                &newhandle,
    3127         348 :                                                WERR_FILE_NOT_FOUND)) {
    3128           0 :                                 torture_comment(tctx,
    3129             :                                                 "DeleteKey failed (OpenKey after Delete "
    3130             :                                                 "did not return WERR_FILE_NOT_FOUND)\n");
    3131           0 :                                 ret = false;
    3132             :                         }
    3133             :                 }
    3134             : 
    3135         348 :                 test_key3 = talloc_asprintf(tctx, "%s\\%s", base_key, TEST_KEY3);
    3136             : 
    3137         348 :                 if (test_CreateKey(b, tctx, handle, test_key3, NULL)) {
    3138         348 :                         created3 = true;
    3139             :                 }
    3140             : 
    3141         348 :                 test_subkey = talloc_asprintf(tctx, "%s\\%s", test_key3, TEST_SUBKEY);
    3142             : 
    3143         348 :                 if (created3) {
    3144         348 :                         if (test_CreateKey(b, tctx, handle, test_subkey, NULL)) {
    3145         348 :                                 if (!test_DeleteKey(b, tctx, handle, test_subkey)) {
    3146           0 :                                         torture_comment(tctx, "DeleteKey(%s) failed\n", test_subkey);
    3147           0 :                                         ret = false;
    3148             :                                 }
    3149             :                         }
    3150             : 
    3151         348 :                         if (!test_DeleteKey(b, tctx, handle, test_key3)) {
    3152           0 :                                 torture_comment(tctx, "DeleteKey(%s) failed\n", test_key3);
    3153           0 :                                 ret = false;
    3154             :                         }
    3155             :                 }
    3156             :         }
    3157             : 
    3158         348 :         test_Cleanup(b, tctx, handle, base_key);
    3159             : 
    3160         348 :         return ret;
    3161             : }
    3162             : 
    3163         348 : static bool test_key_base_sd(struct torture_context *tctx,
    3164             :                              struct dcerpc_pipe *p,
    3165             :                              struct policy_handle *handle,
    3166             :                              const char *base_key)
    3167             : {
    3168           0 :         struct policy_handle newhandle;
    3169         348 :         bool ret = true, created2 = false, created4 = false;
    3170         348 :         struct dcerpc_binding_handle *b = p->binding_handle;
    3171           0 :         const char *test_key2;
    3172           0 :         const char *test_key4;
    3173             : 
    3174         348 :         torture_skip(tctx, "security descriptor test disabled\n");
    3175             : 
    3176             :         if (torture_setting_bool(tctx, "samba3", false) ||
    3177             :             torture_setting_bool(tctx, "samba4", false)) {
    3178             :                 torture_skip(tctx, "skipping security descriptor tests against Samba");
    3179             :         }
    3180             : 
    3181             :         test_Cleanup(b, tctx, handle, base_key);
    3182             : 
    3183             :         if (!test_CreateKey(b, tctx, handle, base_key, NULL)) {
    3184             :                 torture_comment(tctx,
    3185             :                                 "CreateKey(%s) failed\n", base_key);
    3186             :         }
    3187             : 
    3188             :         test_key2 = talloc_asprintf(tctx, "%s\\%s", base_key, TEST_KEY2);
    3189             : 
    3190             :         if (test_CreateKey_sd(b, tctx, handle, test_key2,
    3191             :                               NULL, &newhandle)) {
    3192             :                 created2 = true;
    3193             :         }
    3194             : 
    3195             :         if (created2 && !test_CloseKey(b, tctx, &newhandle)) {
    3196             :                 torture_comment(tctx, "CloseKey failed\n");
    3197             :                 ret = false;
    3198             :         }
    3199             : 
    3200             :         test_key4 = talloc_asprintf(tctx, "%s\\%s", base_key, TEST_KEY4);
    3201             : 
    3202             :         if (test_CreateKey_sd(b, tctx, handle, test_key4, NULL, &newhandle)) {
    3203             :                 created4 = true;
    3204             :         }
    3205             : 
    3206             :         if (created4 && !test_CloseKey(b, tctx, &newhandle)) {
    3207             :                 torture_comment(tctx, "CloseKey failed\n");
    3208             :                 ret = false;
    3209             :         }
    3210             : 
    3211             :         if (created4 && !test_SecurityDescriptors(p, tctx, handle, test_key4)) {
    3212             :                 ret = false;
    3213             :         }
    3214             : 
    3215             :         if (created4 && !test_DeleteKey(b, tctx, handle, test_key4)) {
    3216             :                 torture_comment(tctx, "DeleteKey(%s) failed\n", test_key4);
    3217             :                 ret = false;
    3218             :         }
    3219             : 
    3220             :         if (created2 && !test_DeleteKey(b, tctx, handle, test_key4)) {
    3221             :                 torture_comment(tctx, "DeleteKey(%s) failed\n", test_key4);
    3222             :                 ret = false;
    3223             :         }
    3224             : 
    3225             :         test_Cleanup(b, tctx, handle, base_key);
    3226             : 
    3227             :         return ret;
    3228             : }
    3229             : 
    3230         348 : static bool test_Open(struct torture_context *tctx, struct dcerpc_pipe *p,
    3231             :                       void *userdata)
    3232             : {
    3233           0 :         struct policy_handle handle;
    3234         348 :         bool ret = true;
    3235           0 :         struct winreg_OpenHKLM r;
    3236         348 :         struct dcerpc_binding_handle *b = p->binding_handle;
    3237           0 :         const char *torture_base_key;
    3238         348 :         int hkey = 0;
    3239             : 
    3240         348 :         winreg_open_fn open_fn = (winreg_open_fn)userdata;
    3241             : 
    3242         348 :         r.in.system_name = 0;
    3243         348 :         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
    3244         348 :         r.out.handle = &handle;
    3245             : 
    3246         348 :         torture_assert_ntstatus_ok(tctx, open_fn(b, tctx, &r),
    3247             :                                    "open");
    3248             : 
    3249         348 :         if (!test_GetVersion(b, tctx, &handle)) {
    3250           0 :                 torture_comment(tctx, "GetVersion failed\n");
    3251           0 :                 ret = false;
    3252             :         }
    3253             : 
    3254         348 :         if (open_fn == (winreg_open_fn)dcerpc_winreg_OpenHKLM_r) {
    3255          87 :                 hkey = HKEY_LOCAL_MACHINE;
    3256          87 :                 torture_base_key = "SOFTWARE\\Samba\\" TEST_KEY_BASE;
    3257         261 :         } else if (open_fn == (winreg_open_fn)dcerpc_winreg_OpenHKU_r) {
    3258          87 :                 hkey = HKEY_USERS;
    3259          87 :                 torture_base_key = TEST_KEY_BASE;
    3260         174 :         } else if (open_fn == (winreg_open_fn)dcerpc_winreg_OpenHKCR_r) {
    3261          87 :                 hkey = HKEY_CLASSES_ROOT;
    3262          87 :                 torture_base_key = TEST_KEY_BASE;
    3263          87 :         } else if (open_fn == (winreg_open_fn)dcerpc_winreg_OpenHKCU_r) {
    3264          87 :                 hkey = HKEY_CURRENT_USER;
    3265          87 :                 torture_base_key = TEST_KEY_BASE;
    3266             :         } else {
    3267           0 :                 torture_fail(tctx, "unsupported hkey");
    3268             :         }
    3269             : 
    3270         348 :         if (hkey == HKEY_LOCAL_MACHINE) {
    3271          87 :                 torture_assert(tctx,
    3272             :                         test_HKLM_wellknown(tctx, b, &handle),
    3273             :                         "failed to test HKLM wellknown keys");
    3274             :         }
    3275             : 
    3276         348 :         if (!test_key_base(tctx, b, &handle, torture_base_key, hkey)) {
    3277           0 :                 torture_warning(tctx, "failed to test TEST_KEY_BASE(%s)",
    3278             :                                 torture_base_key);
    3279           0 :                 ret = false;
    3280             :         }
    3281             : 
    3282         348 :         if (!test_key_base_sd(tctx, p, &handle, torture_base_key)) {
    3283           0 :                 torture_warning(tctx, "failed to test TEST_KEY_BASE(%s) sd",
    3284             :                                 torture_base_key);
    3285           0 :                 ret = false;
    3286             :         }
    3287             : 
    3288             :         /* The HKCR hive has a very large fanout */
    3289         348 :         if (hkey == HKEY_CLASSES_ROOT) {
    3290          87 :                 if(!test_key(p, tctx, &handle, MAX_DEPTH - 1, false)) {
    3291           0 :                         ret = false;
    3292             :                 }
    3293         261 :         } else if (hkey == HKEY_LOCAL_MACHINE) {
    3294             :                 /* FIXME we are not allowed to enum values in the HKLM root */
    3295             :         } else {
    3296         174 :                 if (!test_key(p, tctx, &handle, 0, false)) {
    3297           0 :                         ret = false;
    3298             :                 }
    3299             :         }
    3300             : 
    3301         348 :         return ret;
    3302             : }
    3303             : 
    3304        2354 : struct torture_suite *torture_rpc_winreg(TALLOC_CTX *mem_ctx)
    3305             : {
    3306         125 :         struct torture_rpc_tcase *tcase;
    3307        2354 :         struct torture_suite *suite = torture_suite_create(mem_ctx, "winreg");
    3308         125 :         struct torture_test *test;
    3309             : 
    3310        2354 :         tcase = torture_suite_add_rpc_iface_tcase(suite, "winreg",
    3311             :                                                   &ndr_table_winreg);
    3312             : 
    3313        2354 :         test = torture_rpc_tcase_add_test(tcase, "InitiateSystemShutdown",
    3314             :                                           test_InitiateSystemShutdown);
    3315        2354 :         test->dangerous = true;
    3316             : 
    3317        2354 :         test = torture_rpc_tcase_add_test(tcase, "InitiateSystemShutdownEx",
    3318             :                                           test_InitiateSystemShutdownEx);
    3319        2354 :         test->dangerous = true;
    3320             : 
    3321        2354 :         torture_rpc_tcase_add_test_ex(tcase, "HKLM",
    3322             :                                       test_Open,
    3323             :                                       (void *)dcerpc_winreg_OpenHKLM_r);
    3324        2354 :         torture_rpc_tcase_add_test_ex(tcase, "HKU",
    3325             :                                       test_Open,
    3326             :                                       (void *)dcerpc_winreg_OpenHKU_r);
    3327        2354 :         torture_rpc_tcase_add_test_ex(tcase, "HKCR",
    3328             :                                       test_Open,
    3329             :                                       (void *)dcerpc_winreg_OpenHKCR_r);
    3330        2354 :         torture_rpc_tcase_add_test_ex(tcase, "HKCU",
    3331             :                                       test_Open,
    3332             :                                       (void *)dcerpc_winreg_OpenHKCU_r);
    3333             : 
    3334        2354 :         return suite;
    3335             : }

Generated by: LCOV version 1.14