LCOV - code coverage report
Current view: top level - source3/registry - reg_dispatcher.c (source / functions) Hit Total Coverage
Test: coverage report for abartlet/fix-coverage dd10fb34 Lines: 60 77 77.9 %
Date: 2021-09-23 10:06:22 Functions: 10 12 83.3 %

          Line data    Source code
       1             : /*
       2             :  *  Unix SMB/CIFS implementation.
       3             :  *  Virtual Windows Registry Layer
       4             :  *  Copyright (C) Gerald Carter                     2002-2005
       5             :  *  Copyright (C) Michael Adam                      2006-2008
       6             :  *
       7             :  *  This program is free software; you can redistribute it and/or modify
       8             :  *  it under the terms of the GNU General Public License as published by
       9             :  *  the Free Software Foundation; either version 3 of the License, or
      10             :  *  (at your option) any later version.
      11             :  *
      12             :  *  This program is distributed in the hope that it will be useful,
      13             :  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
      14             :  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      15             :  *  GNU General Public License for more details.
      16             :  *
      17             :  *  You should have received a copy of the GNU General Public License
      18             :  *  along with this program; if not, see <http://www.gnu.org/licenses/>.
      19             :  */
      20             : 
      21             : /*
      22             :  * Implementation of registry frontend view functions.
      23             :  * Functions moved from reg_frontend.c to minimize linker deps.
      24             :  */
      25             : 
      26             : #include "includes.h"
      27             : #include "system/passwd.h" /* uid_wrapper */
      28             : #include "registry.h"
      29             : #include "reg_dispatcher.h"
      30             : #include "../libcli/security/security.h"
      31             : 
      32             : #undef DBGC_CLASS
      33             : #define DBGC_CLASS DBGC_REGISTRY
      34             : 
      35             : static const struct generic_mapping reg_generic_map =
      36             :         { REG_KEY_READ, REG_KEY_WRITE, REG_KEY_EXECUTE, REG_KEY_ALL };
      37             : 
      38             : /********************************************************************
      39             : ********************************************************************/
      40             : 
      41       20871 : static WERROR construct_registry_sd(TALLOC_CTX *ctx, struct security_descriptor **psd)
      42             : {
      43             :         struct security_ace ace[3];
      44       20871 :         size_t i = 0;
      45             :         struct security_descriptor *sd;
      46             :         struct security_acl *theacl;
      47             :         size_t sd_size;
      48             : 
      49             :         /* basic access for Everyone */
      50             : 
      51       20871 :         init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,
      52             :                      REG_KEY_READ, 0);
      53             : 
      54             :         /* Full Access 'BUILTIN\Administrators' */
      55             : 
      56       20871 :         init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators,
      57             :                      SEC_ACE_TYPE_ACCESS_ALLOWED, REG_KEY_ALL, 0);
      58             : 
      59             :         /* Full Access 'NT Authority\System' */
      60             : 
      61       20871 :         init_sec_ace(&ace[i++], &global_sid_System, SEC_ACE_TYPE_ACCESS_ALLOWED,
      62             :                      REG_KEY_ALL, 0);
      63             : 
      64             :         /* create the security descriptor */
      65             : 
      66       20871 :         theacl = make_sec_acl(ctx, NT4_ACL_REVISION, i, ace);
      67       20871 :         if (theacl == NULL) {
      68           0 :                 return WERR_NOT_ENOUGH_MEMORY;
      69             :         }
      70             : 
      71       20871 :         sd = make_sec_desc(ctx, SD_REVISION, SEC_DESC_SELF_RELATIVE,
      72             :                            &global_sid_Builtin_Administrators,
      73             :                            &global_sid_System, NULL, theacl,
      74             :                            &sd_size);
      75       20871 :         if (sd == NULL) {
      76           0 :                 return WERR_NOT_ENOUGH_MEMORY;
      77             :         }
      78             : 
      79       20871 :         *psd = sd;
      80       20871 :         return WERR_OK;
      81             : }
      82             : 
      83             : /***********************************************************************
      84             :  High level wrapper function for storing registry subkeys
      85             :  ***********************************************************************/
      86             : 
      87           0 : bool store_reg_keys(struct registry_key_handle *key,
      88             :                     struct regsubkey_ctr *subkeys)
      89             : {
      90           0 :         if (key->ops && key->ops->store_subkeys)
      91           0 :                 return key->ops->store_subkeys(key->name, subkeys);
      92             : 
      93           0 :         return false;
      94             : }
      95             : 
      96             : /***********************************************************************
      97             :  High level wrapper function for storing registry values
      98             :  ***********************************************************************/
      99             : 
     100       20982 : bool store_reg_values(struct registry_key_handle *key, struct regval_ctr *val)
     101             : {
     102       20982 :         if (key->ops && key->ops->store_values)
     103       20980 :                 return key->ops->store_values(key->name, val);
     104             : 
     105           2 :         return false;
     106             : }
     107             : 
     108        3712 : WERROR create_reg_subkey(struct registry_key_handle *key, const char *subkey)
     109             : {
     110        3712 :         if (key->ops && key->ops->create_subkey) {
     111        3712 :                 return key->ops->create_subkey(key->name, subkey);
     112             :         }
     113             : 
     114           0 :         return WERR_NOT_SUPPORTED;
     115             : }
     116             : 
     117        2831 : WERROR delete_reg_subkey(struct registry_key_handle *key, const char *subkey, bool lazy)
     118             : {
     119        2831 :         if (key->ops && key->ops->delete_subkey) {
     120        2831 :                 return key->ops->delete_subkey(key->name, subkey, lazy);
     121             :         }
     122             : 
     123           0 :         return WERR_NOT_SUPPORTED;
     124             : }
     125             : 
     126             : /***********************************************************************
     127             :  High level wrapper function for enumerating registry subkeys
     128             :  Initialize the TALLOC_CTX if necessary
     129             :  ***********************************************************************/
     130             : 
     131     2413318 : int fetch_reg_keys(struct registry_key_handle *key,
     132             :                    struct regsubkey_ctr *subkey_ctr)
     133             : {
     134     2413318 :         int result = -1;
     135             : 
     136     2413318 :         if (key->ops && key->ops->fetch_subkeys)
     137     2413318 :                 result = key->ops->fetch_subkeys(key->name, subkey_ctr);
     138             : 
     139     2413318 :         return result;
     140             : }
     141             : 
     142             : /***********************************************************************
     143             :  High level wrapper function for enumerating registry values
     144             :  ***********************************************************************/
     145             : 
     146       52679 : int fetch_reg_values(struct registry_key_handle *key, struct regval_ctr *val)
     147             : {
     148       52679 :         int result = -1;
     149             : 
     150       52679 :         DEBUG(10, ("fetch_reg_values called for key '%s' (ops %p)\n", key->name,
     151             :                    (key->ops) ? (void *)key->ops : NULL));
     152             : 
     153       52679 :         if (key->ops && key->ops->fetch_values)
     154       52679 :                 result = key->ops->fetch_values(key->name, val);
     155             : 
     156       52679 :         return result;
     157             : }
     158             : 
     159             : /***********************************************************************
     160             :  High level access check for passing the required access mask to the
     161             :  underlying registry backend
     162             :  ***********************************************************************/
     163             : 
     164      400391 : bool regkey_access_check(struct registry_key_handle *key, uint32_t requested,
     165             :                          uint32_t *granted,
     166             :                          const struct security_token *token )
     167             : {
     168             :         struct security_descriptor *sec_desc;
     169             :         NTSTATUS status;
     170             :         WERROR err;
     171             : 
     172             :         /* root free-pass, like we have on all other pipes like samr, lsa, etc. */
     173      400391 :         if (root_mode()) {
     174      399683 :                 *granted = REG_KEY_ALL;
     175      399683 :                 return true;
     176             :         }
     177             : 
     178             :         /* use the default security check if the backend has not defined its
     179             :          * own */
     180             : 
     181         708 :         if (key->ops && key->ops->reg_access_check) {
     182         136 :                 return key->ops->reg_access_check(key->name, requested,
     183             :                                                   granted, token);
     184             :         }
     185             : 
     186         572 :         err = regkey_get_secdesc(talloc_tos(), key, &sec_desc);
     187             : 
     188         572 :         if (!W_ERROR_IS_OK(err)) {
     189           0 :                 return false;
     190             :         }
     191             : 
     192         572 :         se_map_generic( &requested, &reg_generic_map );
     193             : 
     194         572 :         status =se_access_check(sec_desc, token, requested, granted);
     195         572 :         TALLOC_FREE(sec_desc);
     196         572 :         if (!NT_STATUS_IS_OK(status)) {
     197           0 :                 return false;
     198             :         }
     199             : 
     200         572 :         return NT_STATUS_IS_OK(status);
     201             : }
     202             : 
     203       20871 : WERROR regkey_get_secdesc(TALLOC_CTX *mem_ctx, struct registry_key_handle *key,
     204             :                           struct security_descriptor **psecdesc)
     205             : {
     206             :         struct security_descriptor *secdesc;
     207             :         WERROR werr;
     208             : 
     209       20871 :         if (key->ops && key->ops->get_secdesc) {
     210       20795 :                 werr = key->ops->get_secdesc(mem_ctx, key->name, psecdesc);
     211       20795 :                 if (W_ERROR_IS_OK(werr)) {
     212           0 :                         return WERR_OK;
     213             :                 }
     214             :         }
     215             : 
     216       20871 :         werr = construct_registry_sd(mem_ctx, &secdesc);
     217       20871 :         if (!W_ERROR_IS_OK(werr)) {
     218           0 :                 return werr;
     219             :         }
     220             : 
     221       20871 :         *psecdesc = secdesc;
     222       20871 :         return WERR_OK;
     223             : }
     224             : 
     225           0 : WERROR regkey_set_secdesc(struct registry_key_handle *key,
     226             :                           struct security_descriptor *psecdesc)
     227             : {
     228           0 :         if (key->ops && key->ops->set_secdesc) {
     229           0 :                 return key->ops->set_secdesc(key->name, psecdesc);
     230             :         }
     231             : 
     232           0 :         return WERR_ACCESS_DENIED;
     233             : }
     234             : 
     235             : /**
     236             :  * Check whether the in-memory version of the subkyes of a
     237             :  * registry key needs update from disk.
     238             :  */
     239      313185 : bool reg_subkeys_need_update(struct registry_key_handle *key,
     240             :                              struct regsubkey_ctr *subkeys)
     241             : {
     242      313185 :         if (key->ops && key->ops->subkeys_need_update)
     243             :         {
     244      313185 :                 return key->ops->subkeys_need_update(subkeys);
     245             :         }
     246             : 
     247           0 :         return true;
     248             : }
     249             : 
     250             : /**
     251             :  * Check whether the in-memory version of the values of a
     252             :  * registry key needs update from disk.
     253             :  */
     254      262669 : bool reg_values_need_update(struct registry_key_handle *key,
     255             :                             struct regval_ctr *values)
     256             : {
     257      262669 :         if (key->ops && key->ops->values_need_update)
     258             :         {
     259      261641 :                 return key->ops->values_need_update(values);
     260             :         }
     261             : 
     262        1028 :         return true;
     263             : }
     264             : 

Generated by: LCOV version 1.13