LCOV - code coverage report
Current view: top level - source3/rpc_client - cli_winreg_int.c (source / functions) Hit Total Coverage
Test: coverage report for abartlet/fix-coverage dd10fb34 Lines: 22 113 19.5 %
Date: 2021-09-23 10:06:22 Functions: 2 4 50.0 %

          Line data    Source code
       1             : /*
       2             :  *  Unix SMB/CIFS implementation.
       3             :  *
       4             :  *  WINREG internal 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 "include/registry.h"
      24             : #include "librpc/gen_ndr/ndr_winreg_c.h"
      25             : #include "rpc_client/cli_winreg_int.h"
      26             : #include "rpc_server/rpc_ncacn_np.h"
      27             : #include "../lib/tsocket/tsocket.h"
      28             : 
      29             : /**
      30             :  * Split path into hive name and subkeyname
      31             :  * normalizations performed:
      32             :  *  - if the path contains no '\\' characters,
      33             :  *    assume that the legacy format of using '/'
      34             :  *    as a separator is used and  convert '/' to '\\'
      35             :  *  - strip trailing '\\' chars
      36             :  */
      37           0 : static WERROR _split_hive_key(TALLOC_CTX *mem_ctx,
      38             :                               const char *path,
      39             :                               char **hivename,
      40             :                               char **subkeyname)
      41             : {
      42             :         char *p;
      43             :         const char *tmp_subkeyname;
      44             : 
      45           0 :         if ((path == NULL) || (hivename == NULL) || (subkeyname == NULL)) {
      46           0 :                 return WERR_INVALID_PARAMETER;
      47             :         }
      48             : 
      49           0 :         if (strlen(path) == 0) {
      50           0 :                 return WERR_INVALID_PARAMETER;
      51             :         }
      52             : 
      53           0 :         if (strchr(path, '\\') == NULL) {
      54           0 :                 *hivename = talloc_string_sub(mem_ctx, path, "/", "\\");
      55             :         } else {
      56           0 :                 *hivename = talloc_strdup(mem_ctx, path);
      57             :         }
      58             : 
      59           0 :         if (*hivename == NULL) {
      60           0 :                 return WERR_NOT_ENOUGH_MEMORY;
      61             :         }
      62             : 
      63             :         /* strip trailing '\\' chars */
      64           0 :         p = strrchr(*hivename, '\\');
      65           0 :         while ((p != NULL) && (p[1] == '\0')) {
      66           0 :                 *p = '\0';
      67           0 :                 p = strrchr(*hivename, '\\');
      68             :         }
      69             : 
      70           0 :         p = strchr(*hivename, '\\');
      71             : 
      72           0 :         if ((p == NULL) || (*p == '\0')) {
      73             :                 /* just the hive - no subkey given */
      74           0 :                 tmp_subkeyname = "";
      75             :         } else {
      76           0 :                 *p = '\0';
      77           0 :                 tmp_subkeyname = p+1;
      78             :         }
      79           0 :         *subkeyname = talloc_strdup(mem_ctx, tmp_subkeyname);
      80           0 :         if (*subkeyname == NULL) {
      81           0 :                 return WERR_NOT_ENOUGH_MEMORY;
      82             :         }
      83             : 
      84           0 :         return WERR_OK;
      85             : }
      86             : 
      87         280 : static NTSTATUS _winreg_int_openkey(TALLOC_CTX *mem_ctx,
      88             :                                     const struct auth_session_info *session_info,
      89             :                                     struct messaging_context *msg_ctx,
      90             :                                     struct dcerpc_binding_handle **h,
      91             :                                     uint32_t reg_type,
      92             :                                     const char *key,
      93             :                                     bool create_key,
      94             :                                     uint32_t access_mask,
      95             :                                     struct policy_handle *hive_handle,
      96             :                                     struct policy_handle *key_handle,
      97             :                                     WERROR *pwerr)
      98             : {
      99             :         struct tsocket_address *local;
     100             :         struct dcerpc_binding_handle *binding_handle;
     101             :         struct winreg_String wkey, wkeyclass;
     102             :         NTSTATUS status;
     103         280 :         WERROR result = WERR_OK;
     104             :         int rc;
     105             : 
     106         280 :         rc = tsocket_address_inet_from_strings(mem_ctx,
     107             :                                                "ip",
     108             :                                                "127.0.0.1",
     109             :                                                0,
     110             :                                                &local);
     111         280 :         if (rc < 0) {
     112           0 :                 return NT_STATUS_NO_MEMORY;
     113             :         }
     114             : 
     115         280 :         status = rpcint_binding_handle(mem_ctx,
     116             :                                        &ndr_table_winreg,
     117             :                                        local,
     118             :                                        NULL,
     119             :                                        session_info,
     120             :                                        msg_ctx,
     121             :                                        &binding_handle);
     122         280 :         if (!NT_STATUS_IS_OK(status)) {
     123           0 :                 DBG_WARNING("Could not connect to winreg pipe: %s\n",
     124             :                             nt_errstr(status));
     125           0 :                 return status;
     126             :         }
     127             : 
     128         280 :         switch (reg_type) {
     129         280 :         case HKEY_LOCAL_MACHINE:
     130         280 :                 status = dcerpc_winreg_OpenHKLM(binding_handle,
     131             :                                                 mem_ctx,
     132             :                                                 NULL,
     133             :                                                 access_mask,
     134             :                                                 hive_handle,
     135             :                                                 &result);
     136         280 :                 break;
     137           0 :         case HKEY_CLASSES_ROOT:
     138           0 :                 status = dcerpc_winreg_OpenHKCR(binding_handle,
     139             :                                                 mem_ctx,
     140             :                                                 NULL,
     141             :                                                 access_mask,
     142             :                                                 hive_handle,
     143             :                                                 &result);
     144           0 :                 break;
     145           0 :         case HKEY_USERS:
     146           0 :                 status = dcerpc_winreg_OpenHKU(binding_handle,
     147             :                                                mem_ctx,
     148             :                                                NULL,
     149             :                                                access_mask,
     150             :                                                hive_handle,
     151             :                                                &result);
     152           0 :                 break;
     153           0 :         case HKEY_CURRENT_USER:
     154           0 :                 status = dcerpc_winreg_OpenHKCU(binding_handle,
     155             :                                                 mem_ctx,
     156             :                                                 NULL,
     157             :                                                 access_mask,
     158             :                                                 hive_handle,
     159             :                                                 &result);
     160           0 :                 break;
     161           0 :         case HKEY_PERFORMANCE_DATA:
     162           0 :                 status = dcerpc_winreg_OpenHKPD(binding_handle,
     163             :                                                 mem_ctx,
     164             :                                                 NULL,
     165             :                                                 access_mask,
     166             :                                                 hive_handle,
     167             :                                                 &result);
     168           0 :                 break;
     169           0 :         default:
     170           0 :                 result = WERR_INVALID_PARAMETER;
     171           0 :                 status = NT_STATUS_OK;
     172             :         }
     173         280 :         if (!NT_STATUS_IS_OK(status)) {
     174           0 :                 talloc_free(binding_handle);
     175           0 :                 return status;
     176             :         }
     177         280 :         if (!W_ERROR_IS_OK(result)) {
     178           0 :                 talloc_free(binding_handle);
     179           0 :                 *pwerr = result;
     180           0 :                 return status;
     181             :         }
     182             : 
     183         280 :         ZERO_STRUCT(wkey);
     184         280 :         wkey.name = key;
     185             : 
     186         280 :         if (create_key) {
     187           0 :                 enum winreg_CreateAction action = REG_ACTION_NONE;
     188             : 
     189           0 :                 ZERO_STRUCT(wkeyclass);
     190           0 :                 wkeyclass.name = "";
     191             : 
     192           0 :                 status = dcerpc_winreg_CreateKey(binding_handle,
     193             :                                                  mem_ctx,
     194             :                                                  hive_handle,
     195             :                                                  wkey,
     196             :                                                  wkeyclass,
     197             :                                                  0,
     198             :                                                  access_mask,
     199             :                                                  NULL,
     200             :                                                  key_handle,
     201             :                                                  &action,
     202             :                                                  &result);
     203           0 :                 switch (action) {
     204           0 :                         case REG_ACTION_NONE:
     205           0 :                                 DEBUG(8, ("dcerpc_winreg_int_openkey: createkey"
     206             :                                           " did nothing -- huh?\n"));
     207           0 :                                 break;
     208           0 :                         case REG_CREATED_NEW_KEY:
     209           0 :                                 DEBUG(8, ("dcerpc_winreg_int_openkey: createkey"
     210             :                                           " created %s\n", key));
     211           0 :                                 break;
     212           0 :                         case REG_OPENED_EXISTING_KEY:
     213           0 :                                 DEBUG(8, ("dcerpc_winreg_int_openkey: createkey"
     214             :                                           " opened existing %s\n", key));
     215           0 :                                 break;
     216             :                 }
     217             :         } else {
     218         280 :                 status = dcerpc_winreg_OpenKey(binding_handle,
     219             :                                                mem_ctx,
     220             :                                                hive_handle,
     221             :                                                wkey,
     222             :                                                0,
     223             :                                                access_mask,
     224             :                                                key_handle,
     225             :                                                &result);
     226             :         }
     227         280 :         if (!NT_STATUS_IS_OK(status)) {
     228           0 :                 talloc_free(binding_handle);
     229           0 :                 return status;
     230             :         }
     231         280 :         if (!W_ERROR_IS_OK(result)) {
     232           0 :                 talloc_free(binding_handle);
     233           0 :                 *pwerr = result;
     234           0 :                 return status;
     235             :         }
     236             : 
     237         280 :         *h = binding_handle;
     238             : 
     239         280 :         return status;
     240             : }
     241             : 
     242           0 : NTSTATUS dcerpc_winreg_int_openkey(TALLOC_CTX *mem_ctx,
     243             :                                    const struct auth_session_info *server_info,
     244             :                                    struct messaging_context *msg_ctx,
     245             :                                    struct dcerpc_binding_handle **h,
     246             :                                    const char *key,
     247             :                                    bool create_key,
     248             :                                    uint32_t access_mask,
     249             :                                    struct policy_handle *hive_handle,
     250             :                                    struct policy_handle *key_handle,
     251             :                                    WERROR *pwerr)
     252             : {
     253           0 :         char *hivename = NULL;
     254           0 :         char *subkey = NULL;
     255             :         uint32_t reg_type;
     256             :         WERROR result;
     257             : 
     258           0 :         result = _split_hive_key(mem_ctx, key, &hivename, &subkey);
     259           0 :         if (!W_ERROR_IS_OK(result)) {
     260           0 :                 *pwerr = result;
     261           0 :                 return NT_STATUS_OK;
     262             :         }
     263             : 
     264           0 :         if (strequal(hivename, "HKLM") ||
     265           0 :             strequal(hivename, "HKEY_LOCAL_MACHINE")) {
     266           0 :                 reg_type = HKEY_LOCAL_MACHINE;
     267           0 :         } else if (strequal(hivename, "HKCR") ||
     268           0 :                    strequal(hivename, "HKEY_CLASSES_ROOT")) {
     269           0 :                 reg_type = HKEY_CLASSES_ROOT;
     270           0 :         } else if (strequal(hivename, "HKU") ||
     271           0 :                    strequal(hivename, "HKEY_USERS")) {
     272           0 :                 reg_type = HKEY_USERS;
     273           0 :         } else if (strequal(hivename, "HKCU") ||
     274           0 :                    strequal(hivename, "HKEY_CURRENT_USER")) {
     275           0 :                 reg_type = HKEY_CURRENT_USER;
     276           0 :         } else if (strequal(hivename, "HKPD") ||
     277           0 :                    strequal(hivename, "HKEY_PERFORMANCE_DATA")) {
     278           0 :                 reg_type = HKEY_PERFORMANCE_DATA;
     279             :         } else {
     280           0 :                 DEBUG(10,("dcerpc_winreg_int_openkey: unrecognised hive key %s\n",
     281             :                           key));
     282           0 :                 *pwerr = WERR_INVALID_PARAMETER;
     283           0 :                 return NT_STATUS_OK;
     284             :         }
     285             : 
     286           0 :         return _winreg_int_openkey(mem_ctx,
     287             :                                    server_info,
     288             :                                    msg_ctx,
     289             :                                    h,
     290             :                                    reg_type,
     291             :                                    key,
     292             :                                    create_key,
     293             :                                    access_mask,
     294             :                                    hive_handle,
     295             :                                    key_handle,
     296             :                                    pwerr);
     297             : }
     298             : 
     299         280 : NTSTATUS dcerpc_winreg_int_hklm_openkey(TALLOC_CTX *mem_ctx,
     300             :                                         const struct auth_session_info *server_info,
     301             :                                         struct messaging_context *msg_ctx,
     302             :                                         struct dcerpc_binding_handle **h,
     303             :                                         const char *key,
     304             :                                         bool create_key,
     305             :                                         uint32_t access_mask,
     306             :                                         struct policy_handle *hive_handle,
     307             :                                         struct policy_handle *key_handle,
     308             :                                         WERROR *pwerr)
     309             : {
     310         280 :         return _winreg_int_openkey(mem_ctx,
     311             :                                    server_info,
     312             :                                    msg_ctx,
     313             :                                    h,
     314             :                                    HKEY_LOCAL_MACHINE,
     315             :                                    key,
     316             :                                    create_key,
     317             :                                    access_mask,
     318             :                                    hive_handle,
     319             :                                    key_handle,
     320             :                                    pwerr);
     321             : }
     322             : 
     323             : /* vim: set ts=8 sw=8 noet cindent syntax=c.doxygen: */

Generated by: LCOV version 1.13