LCOV - code coverage report
Current view: top level - source3/rpc_client - cli_winreg.c (source / functions) Hit Total Coverage
Test: coverage report for abartlet/fix-coverage dd10fb34 Lines: 265 366 72.4 %
Date: 2021-09-23 10:06:22 Functions: 15 15 100.0 %

          Line data    Source code
       1             : /*
       2             :  *  Unix SMB/CIFS implementation.
       3             :  *
       4             :  *  WINREG client routines
       5             :  *
       6             :  *  Copyright (c) 2011      Andreas Schneider <asn@samba.org>
       7             :  *
       8             :  *  This program is free software; you can redistribute it and/or modify
       9             :  *  it under the terms of the GNU General Public License as published by
      10             :  *  the Free Software Foundation; either version 3 of the License, or
      11             :  *  (at your option) any later version.
      12             :  *
      13             :  *  This program is distributed in the hope that it will be useful,
      14             :  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
      15             :  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      16             :  *  GNU General Public License for more details.
      17             :  *
      18             :  *  You should have received a copy of the GNU General Public License
      19             :  *  along with this program; if not, see <http://www.gnu.org/licenses/>.
      20             :  */
      21             : 
      22             : #include "includes.h"
      23             : #include "../librpc/gen_ndr/ndr_winreg_c.h"
      24             : #include "../librpc/gen_ndr/ndr_security.h"
      25             : #include "rpc_client/cli_winreg.h"
      26             : #include "../libcli/registry/util_reg.h"
      27             : 
      28         360 : NTSTATUS dcerpc_winreg_query_dword(TALLOC_CTX *mem_ctx,
      29             :                                    struct dcerpc_binding_handle *h,
      30             :                                    struct policy_handle *key_handle,
      31             :                                    const char *value,
      32             :                                    uint32_t *data,
      33             :                                    WERROR *pwerr)
      34             : {
      35             :         struct winreg_String wvalue;
      36         360 :         enum winreg_Type type = REG_NONE;
      37         360 :         uint32_t value_len = 0;
      38         360 :         uint32_t data_size = 0;
      39             :         NTSTATUS status;
      40             :         DATA_BLOB blob;
      41             : 
      42         360 :         wvalue.name = value;
      43             : 
      44         360 :         status = dcerpc_winreg_QueryValue(h,
      45             :                                           mem_ctx,
      46             :                                           key_handle,
      47             :                                           &wvalue,
      48             :                                           &type,
      49             :                                           NULL,
      50             :                                           &data_size,
      51             :                                           &value_len,
      52             :                                           pwerr);
      53         360 :         if (!NT_STATUS_IS_OK(status)) {
      54           0 :                 return status;
      55             :         }
      56         360 :         if (!W_ERROR_IS_OK(*pwerr)) {
      57           0 :                 return status;
      58             :         }
      59             : 
      60         360 :         if (type != REG_DWORD) {
      61           0 :                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
      62             :         }
      63             : 
      64         360 :         if (data_size != 4) {
      65           0 :                 return NT_STATUS_INVALID_PARAMETER;
      66             :         }
      67             : 
      68         360 :         blob = data_blob_talloc_zero(mem_ctx, data_size);
      69         360 :         if (blob.data == NULL) {
      70           0 :                 return NT_STATUS_NO_MEMORY;
      71             :         }
      72         360 :         value_len = 0;
      73             : 
      74         360 :         status = dcerpc_winreg_QueryValue(h,
      75             :                                           mem_ctx,
      76             :                                           key_handle,
      77             :                                           &wvalue,
      78             :                                           &type,
      79             :                                           blob.data,
      80             :                                           &data_size,
      81             :                                           &value_len,
      82             :                                           pwerr);
      83         360 :         if (!NT_STATUS_IS_OK(status)) {
      84           0 :                 return status;
      85             :         }
      86         360 :         if (!W_ERROR_IS_OK(*pwerr)) {
      87           0 :                 return status;
      88             :         }
      89             : 
      90         360 :         if (data) {
      91         360 :                 *data = IVAL(blob.data, 0);
      92             :         }
      93             : 
      94         360 :         return status;
      95             : }
      96             : 
      97       20916 : NTSTATUS dcerpc_winreg_query_binary(TALLOC_CTX *mem_ctx,
      98             :                                     struct dcerpc_binding_handle *h,
      99             :                                     struct policy_handle *key_handle,
     100             :                                     const char *value,
     101             :                                     DATA_BLOB *data,
     102             :                                     WERROR *pwerr)
     103             : {
     104             :         struct winreg_String wvalue;
     105       20916 :         enum winreg_Type type = REG_NONE;
     106       20916 :         uint32_t value_len = 0;
     107       20916 :         uint32_t data_size = 0;
     108             :         NTSTATUS status;
     109             :         DATA_BLOB blob;
     110             : 
     111       20916 :         ZERO_STRUCT(wvalue);
     112       20916 :         wvalue.name = value;
     113             : 
     114       20916 :         status = dcerpc_winreg_QueryValue(h,
     115             :                                           mem_ctx,
     116             :                                           key_handle,
     117             :                                           &wvalue,
     118             :                                           &type,
     119             :                                           NULL,
     120             :                                           &data_size,
     121             :                                           &value_len,
     122             :                                           pwerr);
     123       20916 :         if (!NT_STATUS_IS_OK(status)) {
     124           0 :                 return status;
     125             :         }
     126       20916 :         if (!W_ERROR_IS_OK(*pwerr)) {
     127        7441 :                 return status;
     128             :         }
     129             : 
     130       13475 :         if (type != REG_BINARY) {
     131           0 :                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
     132             :         }
     133             : 
     134       13475 :         blob = data_blob_talloc_zero(mem_ctx, data_size);
     135       13475 :         if (blob.data == NULL) {
     136           0 :                 return NT_STATUS_NO_MEMORY;
     137             :         }
     138       13475 :         value_len = 0;
     139             : 
     140       13475 :         status = dcerpc_winreg_QueryValue(h,
     141             :                                           mem_ctx,
     142             :                                           key_handle,
     143             :                                           &wvalue,
     144             :                                           &type,
     145             :                                           blob.data,
     146             :                                           &data_size,
     147             :                                           &value_len,
     148             :                                           pwerr);
     149       13475 :         if (!NT_STATUS_IS_OK(status)) {
     150           0 :                 return status;
     151             :         }
     152       13475 :         if (!W_ERROR_IS_OK(*pwerr)) {
     153           0 :                 return status;
     154             :         }
     155             : 
     156       13475 :         if (data) {
     157       13475 :                 data->data = blob.data;
     158       13475 :                 data->length = blob.length;
     159             :         }
     160             : 
     161       13475 :         return status;
     162             : }
     163             : 
     164          56 : NTSTATUS dcerpc_winreg_query_multi_sz(TALLOC_CTX *mem_ctx,
     165             :                                       struct dcerpc_binding_handle *h,
     166             :                                       struct policy_handle *key_handle,
     167             :                                       const char *value,
     168             :                                       const char ***data,
     169             :                                       WERROR *pwerr)
     170             : {
     171             :         struct winreg_String wvalue;
     172          56 :         enum winreg_Type type = REG_NONE;
     173          56 :         uint32_t value_len = 0;
     174          56 :         uint32_t data_size = 0;
     175             :         NTSTATUS status;
     176             :         DATA_BLOB blob;
     177             : 
     178          56 :         wvalue.name = value;
     179             : 
     180          56 :         status = dcerpc_winreg_QueryValue(h,
     181             :                                           mem_ctx,
     182             :                                           key_handle,
     183             :                                           &wvalue,
     184             :                                           &type,
     185             :                                           NULL,
     186             :                                           &data_size,
     187             :                                           &value_len,
     188             :                                           pwerr);
     189          56 :         if (!NT_STATUS_IS_OK(status)) {
     190           0 :                 return status;
     191             :         }
     192          56 :         if (!W_ERROR_IS_OK(*pwerr)) {
     193          56 :                 return status;
     194             :         }
     195             : 
     196           0 :         if (type != REG_MULTI_SZ) {
     197           0 :                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
     198             :         }
     199             : 
     200           0 :         blob = data_blob_talloc_zero(mem_ctx, data_size);
     201           0 :         if (blob.data == NULL) {
     202           0 :                 return NT_STATUS_NO_MEMORY;
     203             :         }
     204           0 :         value_len = 0;
     205             : 
     206           0 :         status = dcerpc_winreg_QueryValue(h,
     207             :                                           mem_ctx,
     208             :                                           key_handle,
     209             :                                           &wvalue,
     210             :                                           &type,
     211             :                                           blob.data,
     212             :                                           &data_size,
     213             :                                           &value_len,
     214             :                                           pwerr);
     215           0 :         if (!NT_STATUS_IS_OK(status)) {
     216           0 :                 return status;
     217             :         }
     218           0 :         if (!W_ERROR_IS_OK(*pwerr)) {
     219           0 :                 return status;
     220             :         }
     221             : 
     222           0 :         if (data) {
     223             :                 bool ok;
     224             : 
     225           0 :                 ok = pull_reg_multi_sz(mem_ctx, &blob, data);
     226           0 :                 if (!ok) {
     227           0 :                         status = NT_STATUS_NO_MEMORY;
     228             :                 }
     229             :         }
     230             : 
     231           0 :         return status;
     232             : }
     233             : 
     234          88 : NTSTATUS dcerpc_winreg_query_sz(TALLOC_CTX *mem_ctx,
     235             :                                       struct dcerpc_binding_handle *h,
     236             :                                       struct policy_handle *key_handle,
     237             :                                       const char *value,
     238             :                                       const char **data,
     239             :                                       WERROR *pwerr)
     240             : {
     241             :         struct winreg_String wvalue;
     242          88 :         enum winreg_Type type = REG_NONE;
     243          88 :         uint32_t value_len = 0;
     244          88 :         uint32_t data_size = 0;
     245             :         NTSTATUS status;
     246             :         DATA_BLOB blob;
     247             : 
     248          88 :         wvalue.name = value;
     249             : 
     250          88 :         status = dcerpc_winreg_QueryValue(h,
     251             :                                           mem_ctx,
     252             :                                           key_handle,
     253             :                                           &wvalue,
     254             :                                           &type,
     255             :                                           NULL,
     256             :                                           &data_size,
     257             :                                           &value_len,
     258             :                                           pwerr);
     259          88 :         if (!NT_STATUS_IS_OK(status)) {
     260           0 :                 return status;
     261             :         }
     262          88 :         if (!W_ERROR_IS_OK(*pwerr)) {
     263           0 :                 return status;
     264             :         }
     265             : 
     266          88 :         if (type != REG_SZ) {
     267           0 :                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
     268             :         }
     269             : 
     270          88 :         blob = data_blob_talloc_zero(mem_ctx, data_size);
     271          88 :         if (blob.data == NULL) {
     272           0 :                 return NT_STATUS_NO_MEMORY;
     273             :         }
     274          88 :         value_len = 0;
     275             : 
     276          88 :         status = dcerpc_winreg_QueryValue(h,
     277             :                                           mem_ctx,
     278             :                                           key_handle,
     279             :                                           &wvalue,
     280             :                                           &type,
     281             :                                           blob.data,
     282             :                                           &data_size,
     283             :                                           &value_len,
     284             :                                           pwerr);
     285          88 :         if (!NT_STATUS_IS_OK(status)) {
     286           0 :                 return status;
     287             :         }
     288          88 :         if (!W_ERROR_IS_OK(*pwerr)) {
     289           0 :                 return status;
     290             :         }
     291             : 
     292          88 :         if (data) {
     293             :                 bool ok;
     294             : 
     295          88 :                 ok = pull_reg_sz(mem_ctx, &blob, data);
     296          88 :                 if (!ok) {
     297           0 :                         status = NT_STATUS_NO_MEMORY;
     298             :                 }
     299             :         }
     300             : 
     301          88 :         return status;
     302             : }
     303             : 
     304       10567 : NTSTATUS dcerpc_winreg_query_sd(TALLOC_CTX *mem_ctx,
     305             :                                 struct dcerpc_binding_handle *h,
     306             :                                 struct policy_handle *key_handle,
     307             :                                 const char *value,
     308             :                                 struct security_descriptor **data,
     309             :                                 WERROR *pwerr)
     310             : {
     311             :         NTSTATUS status;
     312             :         DATA_BLOB blob;
     313             : 
     314       10567 :         status = dcerpc_winreg_query_binary(mem_ctx,
     315             :                                             h,
     316             :                                             key_handle,
     317             :                                             value,
     318             :                                             &blob,
     319             :                                             pwerr);
     320       10567 :         if (!NT_STATUS_IS_OK(status)) {
     321           0 :                 return status;
     322             :         }
     323       10567 :         if (!W_ERROR_IS_OK(*pwerr)) {
     324           4 :                 return status;
     325             :         }
     326             : 
     327       10563 :         if (data) {
     328             :                 struct security_descriptor *sd;
     329             :                 enum ndr_err_code ndr_err;
     330             : 
     331       10563 :                 sd = talloc_zero(mem_ctx, struct security_descriptor);
     332       10563 :                 if (sd == NULL) {
     333           0 :                         return NT_STATUS_NO_MEMORY;
     334             :                 }
     335             : 
     336       10563 :                 ndr_err = ndr_pull_struct_blob(&blob,
     337             :                                                sd,
     338             :                                                sd,
     339             :                                                (ndr_pull_flags_fn_t) ndr_pull_security_descriptor);
     340       10563 :                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     341           0 :                         DEBUG(2, ("dcerpc_winreg_query_sd: Failed to marshall "
     342             :                                   "security descriptor\n"));
     343           0 :                         return NT_STATUS_NO_MEMORY;
     344             :                 }
     345             : 
     346       10563 :                 *data = sd;
     347             :         }
     348             : 
     349       10563 :         return status;
     350             : }
     351             : 
     352        5396 : NTSTATUS dcerpc_winreg_set_dword(TALLOC_CTX *mem_ctx,
     353             :                                  struct dcerpc_binding_handle *h,
     354             :                                  struct policy_handle *key_handle,
     355             :                                  const char *value,
     356             :                                  uint32_t data,
     357             :                                  WERROR *pwerr)
     358             : {
     359             :         struct winreg_String wvalue;
     360             :         DATA_BLOB blob;
     361             :         NTSTATUS status;
     362             : 
     363        5396 :         ZERO_STRUCT(wvalue);
     364        5396 :         wvalue.name = value;
     365        5396 :         blob = data_blob_talloc_zero(mem_ctx, 4);
     366        5396 :         SIVAL(blob.data, 0, data);
     367             : 
     368        5396 :         status = dcerpc_winreg_SetValue(h,
     369             :                                         mem_ctx,
     370             :                                         key_handle,
     371             :                                         wvalue,
     372             :                                         REG_DWORD,
     373             :                                         blob.data,
     374        5396 :                                         blob.length,
     375             :                                         pwerr);
     376             : 
     377        5396 :         return status;
     378             : }
     379             : 
     380        4060 : NTSTATUS dcerpc_winreg_set_sz(TALLOC_CTX *mem_ctx,
     381             :                               struct dcerpc_binding_handle *h,
     382             :                               struct policy_handle *key_handle,
     383             :                               const char *value,
     384             :                               const char *data,
     385             :                               WERROR *pwerr)
     386             : {
     387        4060 :         struct winreg_String wvalue = { 0, };
     388             :         DATA_BLOB blob;
     389             :         NTSTATUS status;
     390             : 
     391        4060 :         wvalue.name = value;
     392        4060 :         if (data == NULL) {
     393          80 :                 blob = data_blob_string_const("");
     394             :         } else {
     395        3980 :                 if (!push_reg_sz(mem_ctx, &blob, data)) {
     396           0 :                         DEBUG(2, ("dcerpc_winreg_set_sz: Could not marshall "
     397             :                                   "string %s for %s\n",
     398             :                                   data, wvalue.name));
     399           0 :                         return NT_STATUS_NO_MEMORY;
     400             :                 }
     401             :         }
     402             : 
     403        4060 :         status = dcerpc_winreg_SetValue(h,
     404             :                                         mem_ctx,
     405             :                                         key_handle,
     406             :                                         wvalue,
     407             :                                         REG_SZ,
     408             :                                         blob.data,
     409        4060 :                                         blob.length,
     410             :                                         pwerr);
     411             : 
     412        4060 :         return status;
     413             : }
     414             : 
     415         112 : NTSTATUS dcerpc_winreg_set_expand_sz(TALLOC_CTX *mem_ctx,
     416             :                                      struct dcerpc_binding_handle *h,
     417             :                                      struct policy_handle *key_handle,
     418             :                                      const char *value,
     419             :                                      const char *data,
     420             :                                      WERROR *pwerr)
     421             : {
     422         112 :         struct winreg_String wvalue = { 0, };
     423             :         DATA_BLOB blob;
     424             :         NTSTATUS status;
     425             : 
     426         112 :         wvalue.name = value;
     427         112 :         if (data == NULL) {
     428           0 :                 blob = data_blob_string_const("");
     429             :         } else {
     430         112 :                 if (!push_reg_sz(mem_ctx, &blob, data)) {
     431           0 :                         DEBUG(2, ("dcerpc_winreg_set_expand_sz: Could not marshall "
     432             :                                   "string %s for %s\n",
     433             :                                   data, wvalue.name));
     434           0 :                         return NT_STATUS_NO_MEMORY;
     435             :                 }
     436             :         }
     437             : 
     438         112 :         status = dcerpc_winreg_SetValue(h,
     439             :                                         mem_ctx,
     440             :                                         key_handle,
     441             :                                         wvalue,
     442             :                                         REG_EXPAND_SZ,
     443             :                                         blob.data,
     444         112 :                                         blob.length,
     445             :                                         pwerr);
     446             : 
     447         112 :         return status;
     448             : }
     449             : 
     450          58 : NTSTATUS dcerpc_winreg_set_multi_sz(TALLOC_CTX *mem_ctx,
     451             :                                     struct dcerpc_binding_handle *h,
     452             :                                     struct policy_handle *key_handle,
     453             :                                     const char *value,
     454             :                                     const char **data,
     455             :                                     WERROR *pwerr)
     456             : {
     457          58 :         struct winreg_String wvalue = { 0, };
     458             :         DATA_BLOB blob;
     459             :         NTSTATUS status;
     460             : 
     461          58 :         wvalue.name = value;
     462          58 :         if (!push_reg_multi_sz(mem_ctx, &blob, data)) {
     463           0 :                 DEBUG(2, ("dcerpc_winreg_set_multi_sz: Could not marshall "
     464             :                           "string multi sz for %s\n",
     465             :                           wvalue.name));
     466           0 :                 return NT_STATUS_NO_MEMORY;
     467             :         }
     468             : 
     469          58 :         status = dcerpc_winreg_SetValue(h,
     470             :                                         mem_ctx,
     471             :                                         key_handle,
     472             :                                         wvalue,
     473             :                                         REG_MULTI_SZ,
     474             :                                         blob.data,
     475          58 :                                         blob.length,
     476             :                                         pwerr);
     477             : 
     478          58 :         return status;
     479             : }
     480             : 
     481         634 : NTSTATUS dcerpc_winreg_set_binary(TALLOC_CTX *mem_ctx,
     482             :                                   struct dcerpc_binding_handle *h,
     483             :                                   struct policy_handle *key_handle,
     484             :                                   const char *value,
     485             :                                   DATA_BLOB *data,
     486             :                                   WERROR *pwerr)
     487             : {
     488         634 :         struct winreg_String wvalue = { 0, };
     489             :         NTSTATUS status;
     490             : 
     491         634 :         wvalue.name = value;
     492             : 
     493         634 :         status = dcerpc_winreg_SetValue(h,
     494             :                                         mem_ctx,
     495             :                                         key_handle,
     496             :                                         wvalue,
     497             :                                         REG_BINARY,
     498             :                                         data->data,
     499         634 :                                         data->length,
     500             :                                         pwerr);
     501             : 
     502         634 :         return status;
     503             : }
     504             : 
     505         362 : NTSTATUS dcerpc_winreg_set_sd(TALLOC_CTX *mem_ctx,
     506             :                               struct dcerpc_binding_handle *h,
     507             :                               struct policy_handle *key_handle,
     508             :                               const char *value,
     509             :                               const struct security_descriptor *data,
     510             :                               WERROR *pwerr)
     511             : {
     512             :         enum ndr_err_code ndr_err;
     513             :         DATA_BLOB blob;
     514             : 
     515         362 :         ndr_err = ndr_push_struct_blob(&blob,
     516             :                                        mem_ctx,
     517             :                                        data,
     518             :                                        (ndr_push_flags_fn_t) ndr_push_security_descriptor);
     519         362 :         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     520           0 :                 DEBUG(2, ("dcerpc_winreg_set_sd: Failed to marshall security "
     521             :                           "descriptor\n"));
     522           0 :                 return NT_STATUS_NO_MEMORY;
     523             :         }
     524             : 
     525         362 :         return dcerpc_winreg_set_binary(mem_ctx,
     526             :                                         h,
     527             :                                         key_handle,
     528             :                                         value,
     529             :                                         &blob,
     530             :                                         pwerr);
     531             : }
     532             : 
     533          56 : NTSTATUS dcerpc_winreg_add_multi_sz(TALLOC_CTX *mem_ctx,
     534             :                                     struct dcerpc_binding_handle *h,
     535             :                                     struct policy_handle *key_handle,
     536             :                                     const char *value,
     537             :                                     const char *data,
     538             :                                     WERROR *pwerr)
     539             : {
     540          56 :         const char **a = NULL;
     541             :         const char **p;
     542             :         uint32_t i;
     543             :         NTSTATUS status;
     544             : 
     545          56 :         status = dcerpc_winreg_query_multi_sz(mem_ctx,
     546             :                                               h,
     547             :                                               key_handle,
     548             :                                               value,
     549             :                                               &a,
     550             :                                               pwerr);
     551             : 
     552             :         /* count the elements */
     553          56 :         for (p = a, i = 0; p && *p; p++, i++);
     554             : 
     555          56 :         p = talloc_realloc(mem_ctx, a, const char *, i + 2);
     556          56 :         if (p == NULL) {
     557           0 :                 return NT_STATUS_NO_MEMORY;
     558             :         }
     559             : 
     560          56 :         p[i] = data;
     561          56 :         p[i + 1] = NULL;
     562             : 
     563          56 :         status = dcerpc_winreg_set_multi_sz(mem_ctx,
     564             :                                             h,
     565             :                                             key_handle,
     566             :                                             value,
     567             :                                             p,
     568             :                                             pwerr);
     569             : 
     570          56 :         return status;
     571             : }
     572             : 
     573        5072 : NTSTATUS dcerpc_winreg_enum_keys(TALLOC_CTX *mem_ctx,
     574             :                                  struct dcerpc_binding_handle *h,
     575             :                                  struct policy_handle *key_hnd,
     576             :                                  uint32_t *pnum_subkeys,
     577             :                                  const char ***psubkeys,
     578             :                                  WERROR *pwerr)
     579             : {
     580             :         const char **subkeys;
     581             :         uint32_t num_subkeys, max_subkeylen, max_classlen;
     582             :         uint32_t num_values, max_valnamelen, max_valbufsize;
     583             :         uint32_t i;
     584             :         NTTIME last_changed_time;
     585             :         uint32_t secdescsize;
     586             :         struct winreg_String classname;
     587             :         NTSTATUS status;
     588             :         TALLOC_CTX *tmp_ctx;
     589             : 
     590        5072 :         tmp_ctx = talloc_stackframe();
     591        5072 :         if (tmp_ctx == NULL) {
     592           0 :                 return NT_STATUS_NO_MEMORY;
     593             :         }
     594             : 
     595        5072 :         ZERO_STRUCT(classname);
     596             : 
     597        5072 :         status = dcerpc_winreg_QueryInfoKey(h,
     598             :                                             tmp_ctx,
     599             :                                             key_hnd,
     600             :                                             &classname,
     601             :                                             &num_subkeys,
     602             :                                             &max_subkeylen,
     603             :                                             &max_classlen,
     604             :                                             &num_values,
     605             :                                             &max_valnamelen,
     606             :                                             &max_valbufsize,
     607             :                                             &secdescsize,
     608             :                                             &last_changed_time,
     609             :                                             pwerr);
     610        5072 :         if (!NT_STATUS_IS_OK(status)) {
     611           0 :                 goto error;
     612             :         }
     613        5072 :         if (!W_ERROR_IS_OK(*pwerr)) {
     614           0 :                 goto error;
     615             :         }
     616             : 
     617        5072 :         subkeys = talloc_zero_array(tmp_ctx, const char *, num_subkeys + 2);
     618        5072 :         if (subkeys == NULL) {
     619           0 :                 status = NT_STATUS_NO_MEMORY;
     620           0 :                 goto error;
     621             :         }
     622             : 
     623        5072 :         if (num_subkeys == 0) {
     624        1908 :                 subkeys[0] = talloc_strdup(subkeys, "");
     625        1908 :                 if (subkeys[0] == NULL) {
     626           0 :                         status = NT_STATUS_NO_MEMORY;
     627           0 :                         goto error;
     628             :                 }
     629        1908 :                 *pnum_subkeys = 0;
     630        1908 :                 if (psubkeys) {
     631        1908 :                         *psubkeys = talloc_move(mem_ctx, &subkeys);
     632             :                 }
     633             : 
     634        1908 :                 TALLOC_FREE(tmp_ctx);
     635        1908 :                 return NT_STATUS_OK;
     636             :         }
     637             : 
     638      135226 :         for (i = 0; i < num_subkeys; i++) {
     639       65195 :                 char c = '\0';
     640       65195 :                 char n = '\0';
     641       65195 :                 char *name = NULL;
     642             :                 struct winreg_StringBuf class_buf;
     643             :                 struct winreg_StringBuf name_buf;
     644             :                 NTTIME modtime;
     645             : 
     646       65195 :                 class_buf.name = &c;
     647       65195 :                 class_buf.size = max_classlen + 2;
     648       65195 :                 class_buf.length = 0;
     649             : 
     650       65195 :                 name_buf.name = &n;
     651       65195 :                 name_buf.size = max_subkeylen + 2;
     652       65195 :                 name_buf.length = 0;
     653             : 
     654       65195 :                 ZERO_STRUCT(modtime);
     655             : 
     656       65195 :                 status = dcerpc_winreg_EnumKey(h,
     657             :                                                tmp_ctx,
     658             :                                                key_hnd,
     659             :                                                i,
     660             :                                                &name_buf,
     661             :                                                &class_buf,
     662             :                                                &modtime,
     663             :                                                pwerr);
     664       65195 :                 if (!NT_STATUS_IS_OK(status)) {
     665           0 :                         DEBUG(5, ("dcerpc_winreg_enum_keys: Could not enumerate keys: %s\n",
     666             :                                   nt_errstr(status)));
     667           0 :                         goto error;
     668             :                 }
     669             : 
     670       65195 :                 if (W_ERROR_EQUAL(*pwerr, WERR_NO_MORE_ITEMS)) {
     671           0 :                         *pwerr = WERR_OK;
     672           0 :                         break;
     673             :                 }
     674       65195 :                 if (!W_ERROR_IS_OK(*pwerr)) {
     675           0 :                         DEBUG(5, ("dcerpc_winreg_enum_keys: Could not enumerate keys: %s\n",
     676             :                                   win_errstr(*pwerr)));
     677           0 :                         goto error;
     678             :                 }
     679             : 
     680       65195 :                 if (name_buf.name == NULL) {
     681           0 :                         *pwerr = WERR_INVALID_PARAMETER;
     682           0 :                         goto error;
     683             :                 }
     684             : 
     685       65195 :                 name = talloc_strdup(subkeys, name_buf.name);
     686       65195 :                 if (name == NULL) {
     687           0 :                         status = NT_STATUS_NO_MEMORY;
     688           0 :                         goto error;
     689             :                 }
     690             : 
     691       65195 :                 subkeys[i] = name;
     692             :         }
     693             : 
     694        3164 :         *pnum_subkeys = num_subkeys;
     695        3164 :         if (psubkeys) {
     696        3164 :                 *psubkeys = talloc_move(mem_ctx, &subkeys);
     697             :         }
     698             : 
     699        2554 :  error:
     700        3164 :         TALLOC_FREE(tmp_ctx);
     701             : 
     702        3164 :         return status;
     703             : }
     704             : 
     705       14849 : NTSTATUS dcerpc_winreg_enumvals(TALLOC_CTX *mem_ctx,
     706             :                                         struct dcerpc_binding_handle *h,
     707             :                                         struct policy_handle *key_hnd,
     708             :                                         uint32_t *pnum_values,
     709             :                                         const char ***pnames,
     710             :                                         enum winreg_Type **_type,
     711             :                                         DATA_BLOB **pdata,
     712             :                                         WERROR *pwerr)
     713             : {
     714       14849 :         TALLOC_CTX *tmp_ctx = talloc_stackframe();
     715       14849 :         uint32_t num_subkeys = 0, max_subkeylen = 0, max_classlen = 0;
     716       14849 :         uint32_t num_values = 0, max_valnamelen = 0, max_valbufsize = 0;
     717       14849 :         uint32_t secdescsize = 0;
     718             :         uint32_t i;
     719       14849 :         NTTIME last_changed_time = 0;
     720       14849 :         struct winreg_String classname = { .name = NULL };
     721             : 
     722       14849 :         const char **enum_names = NULL;
     723       14849 :         enum winreg_Type *enum_types = NULL;
     724       14849 :         DATA_BLOB *enum_data_blobs = NULL;
     725             : 
     726             : 
     727       14849 :         WERROR result = WERR_OK;
     728             :         NTSTATUS status;
     729             : 
     730       14849 :         status = dcerpc_winreg_QueryInfoKey(h,
     731             :                                             tmp_ctx,
     732             :                                             key_hnd,
     733             :                                             &classname,
     734             :                                             &num_subkeys,
     735             :                                             &max_subkeylen,
     736             :                                             &max_classlen,
     737             :                                             &num_values,
     738             :                                             &max_valnamelen,
     739             :                                             &max_valbufsize,
     740             :                                             &secdescsize,
     741             :                                             &last_changed_time,
     742             :                                             &result);
     743       14849 :         if (!NT_STATUS_IS_OK(status)) {
     744           0 :                 DEBUG(0, ("dcerpc_winreg_enumvals: Could not query info: %s\n",
     745             :                           nt_errstr(status)));
     746           0 :                 goto error;
     747             :         }
     748       14849 :         if (!W_ERROR_IS_OK(result)) {
     749           0 :                 DEBUG(0, ("dcerpc_winreg_enumvals: Could not query info: %s\n",
     750             :                           win_errstr(result)));
     751           0 :                 *pwerr = result;
     752           0 :                 goto error;
     753             :         }
     754             : 
     755       14849 :         if (num_values == 0) {
     756         840 :                 *pnum_values = 0;
     757         840 :                 TALLOC_FREE(tmp_ctx);
     758         840 :                 *pwerr = WERR_OK;
     759         840 :                 return status;
     760             :         }
     761             : 
     762       14009 :         enum_names = talloc_zero_array(tmp_ctx, const char *, num_values);
     763             : 
     764       14009 :         if (enum_names == NULL) {
     765           0 :                 *pwerr = WERR_NOT_ENOUGH_MEMORY;
     766           0 :                 goto error;
     767             :         }
     768             : 
     769       14009 :         enum_types = talloc_zero_array(tmp_ctx, enum winreg_Type, num_values);
     770             : 
     771       14009 :         if (enum_types == NULL) {
     772           0 :                 *pwerr = WERR_NOT_ENOUGH_MEMORY;
     773           0 :                 goto error;
     774             :         }
     775             : 
     776       14009 :         enum_data_blobs = talloc_zero_array(tmp_ctx, DATA_BLOB, num_values);
     777             : 
     778       14009 :         if (enum_data_blobs == NULL) {
     779           0 :                 *pwerr = WERR_NOT_ENOUGH_MEMORY;
     780           0 :                 goto error;
     781             :         }
     782             : 
     783      353106 :         for (i = 0; i < num_values; i++) {
     784             :                 const char *name;
     785             :                 struct winreg_ValNameBuf name_buf;
     786      188069 :                 enum winreg_Type type = REG_NONE;
     787             :                 uint8_t *data;
     788             :                 uint32_t data_size;
     789             :                 uint32_t length;
     790      188069 :                 char n = '\0';
     791             : 
     792             : 
     793      188069 :                 name_buf.name = &n;
     794      188069 :                 name_buf.size = max_valnamelen + 2;
     795      188069 :                 name_buf.length = 0;
     796             : 
     797      188069 :                 data_size = max_valbufsize;
     798      188069 :                 data = NULL;
     799      188069 :                 if (data_size) {
     800      187997 :                         data = (uint8_t *) TALLOC(tmp_ctx, data_size);
     801             :                 }
     802      188069 :                 length = 0;
     803             : 
     804      188069 :                 status = dcerpc_winreg_EnumValue(h,
     805             :                                                  tmp_ctx,
     806             :                                                  key_hnd,
     807             :                                                  i,
     808             :                                                  &name_buf,
     809             :                                                  &type,
     810             :                                                  data,
     811      188069 :                                                  data_size ? &data_size : NULL,
     812             :                                                  &length,
     813             :                                                  &result);
     814      188069 :                 if (W_ERROR_EQUAL(result, WERR_NO_MORE_ITEMS) ) {
     815           0 :                         result = WERR_OK;
     816           0 :                         status = NT_STATUS_OK;
     817           0 :                         break;
     818             :                 }
     819             : 
     820      188069 :                 if (!NT_STATUS_IS_OK(status)) {
     821           0 :                         DEBUG(0, ("dcerpc_winreg_enumvals: Could not enumerate values: %s\n",
     822             :                                   nt_errstr(status)));
     823           0 :                         goto error;
     824             :                 }
     825      188069 :                 if (!W_ERROR_IS_OK(result)) {
     826           0 :                         DEBUG(0, ("dcerpc_winreg_enumvals: Could not enumerate values: %s\n",
     827             :                                   win_errstr(result)));
     828           0 :                         *pwerr = result;
     829           0 :                         goto error;
     830             :                 }
     831             : 
     832      188069 :                 if (name_buf.name == NULL) {
     833           0 :                         result = WERR_INVALID_PARAMETER;
     834           0 :                         *pwerr = result;
     835           0 :                         goto error;
     836             :                 }
     837             : 
     838      188069 :                 name = talloc_strdup(enum_names, name_buf.name);
     839      188069 :                 if (name == NULL) {
     840           0 :                         result = WERR_NOT_ENOUGH_MEMORY;
     841           0 :                         *pwerr = result;
     842           0 :                         goto error;
     843             :                 }
     844             :         /* place name, type and datablob in the enum return params */
     845             : 
     846      188069 :                 enum_data_blobs[i] = data_blob_talloc(enum_data_blobs, data, length);
     847      188069 :                 enum_names[i] = name;
     848      188069 :                 enum_types[i] = type;
     849             : 
     850             :         }
     851             :         /* move to the main mem context */
     852       14009 :         *pnum_values = num_values;
     853       14009 :         if (pnames) {
     854       14009 :                 *pnames = talloc_move(mem_ctx, &enum_names);
     855             :         }
     856             :         /* can this fail in any way? */
     857       14009 :         if (_type) {
     858       14009 :                 *_type = talloc_move(mem_ctx, &enum_types);
     859             :         }
     860             : 
     861       14009 :         if (pdata){
     862       14009 :                 *pdata = talloc_move(mem_ctx, &enum_data_blobs);
     863             :         }
     864             : 
     865             : 
     866       14009 :         result = WERR_OK;
     867             : 
     868       14009 :  error:
     869       14009 :         TALLOC_FREE(tmp_ctx);
     870       14009 :         *pwerr = result;
     871             : 
     872       14009 :         return status;
     873             : }
     874             : 
     875         918 : NTSTATUS dcerpc_winreg_delete_subkeys_recursive(TALLOC_CTX *mem_ctx,
     876             :                                                 struct dcerpc_binding_handle *h,
     877             :                                                 struct policy_handle *hive_handle,
     878             :                                                 uint32_t access_mask,
     879             :                                                 const char *key,
     880             :                                                 WERROR *pwerr)
     881             : {
     882         918 :         const char **subkeys = NULL;
     883         918 :         uint32_t num_subkeys = 0;
     884             :         struct policy_handle key_hnd;
     885         918 :         struct winreg_String wkey = { 0, };
     886         918 :         WERROR result = WERR_OK;
     887             :         NTSTATUS status;
     888             :         uint32_t i;
     889             : 
     890         918 :         ZERO_STRUCT(key_hnd);
     891         918 :         wkey.name = key;
     892             : 
     893         918 :         DEBUG(2, ("dcerpc_winreg_delete_subkeys_recursive: delete key %s\n", key));
     894             :         /* open the key */
     895         918 :         status = dcerpc_winreg_OpenKey(h,
     896             :                                        mem_ctx,
     897             :                                        hive_handle,
     898             :                                        wkey,
     899             :                                        0,
     900             :                                        access_mask,
     901             :                                        &key_hnd,
     902             :                                        &result);
     903         918 :         if (!NT_STATUS_IS_OK(status)) {
     904           0 :                 DEBUG(0, ("dcerpc_winreg_delete_subkeys_recursive: Could not open key %s: %s\n",
     905             :                           wkey.name, nt_errstr(status)));
     906           0 :                 goto done;
     907             :         }
     908         918 :         if (!W_ERROR_IS_OK(result)) {
     909           2 :                 DEBUG(0, ("dcerpc_winreg_delete_subkeys_recursive: Could not open key %s: %s\n",
     910             :                           wkey.name, win_errstr(result)));
     911           2 :                 *pwerr = result;
     912           2 :                 goto done;
     913             :         }
     914             : 
     915         916 :         status = dcerpc_winreg_enum_keys(mem_ctx,
     916             :                                          h,
     917             :                                          &key_hnd,
     918             :                                          &num_subkeys,
     919             :                                          &subkeys,
     920             :                                          &result);
     921         916 :         if (!NT_STATUS_IS_OK(status)) {
     922           0 :                 goto done;
     923             :         }
     924         916 :         if (!W_ERROR_IS_OK(result)) {
     925           0 :                 goto done;
     926             :         }
     927             : 
     928        1568 :         for (i = 0; i < num_subkeys; i++) {
     929             :                 /* create key + subkey */
     930         652 :                 char *subkey = talloc_asprintf(mem_ctx, "%s\\%s", key, subkeys[i]);
     931         652 :                 if (subkey == NULL) {
     932           0 :                         goto done;
     933             :                 }
     934             : 
     935         652 :                 DEBUG(2, ("dcerpc_winreg_delete_subkeys_recursive: delete subkey %s\n", subkey));
     936         652 :                 status = dcerpc_winreg_delete_subkeys_recursive(mem_ctx,
     937             :                                                                 h,
     938             :                                                                 hive_handle,
     939             :                                                                 access_mask,
     940             :                                                                 subkey,
     941             :                                                                 &result);
     942         652 :                 if (!W_ERROR_IS_OK(result)) {
     943           0 :                         goto done;
     944             :                 }
     945             :         }
     946             : 
     947         916 :         if (is_valid_policy_hnd(&key_hnd)) {
     948             :                 WERROR ignore;
     949         916 :                 dcerpc_winreg_CloseKey(h, mem_ctx, &key_hnd, &ignore);
     950             :         }
     951             : 
     952         916 :         wkey.name = key;
     953             : 
     954         916 :         status = dcerpc_winreg_DeleteKey(h,
     955             :                                          mem_ctx,
     956             :                                          hive_handle,
     957             :                                          wkey,
     958             :                                          &result);
     959         916 :         if (!NT_STATUS_IS_OK(status)) {
     960           0 :                 *pwerr = result;
     961           0 :                 goto done;
     962             :         }
     963             : 
     964        1762 : done:
     965         918 :         if (is_valid_policy_hnd(&key_hnd)) {
     966             :                 WERROR ignore;
     967             : 
     968           0 :                 dcerpc_winreg_CloseKey(h, mem_ctx, &key_hnd, &ignore);
     969             :         }
     970             : 
     971         918 :         *pwerr = result;
     972         918 :         return status;
     973             : }
     974             : 
     975             : /* vim: set ts=8 sw=8 noet cindent syntax=c.doxygen: */

Generated by: LCOV version 1.13