LCOV - code coverage report
Current view: top level - source3/rpc_server/winreg - srv_winreg_nt.c (source / functions) Hit Total Coverage
Test: coverage report for v4-17-test 1498b464 Lines: 148 430 34.4 %
Date: 2024-06-13 04:01:37 Functions: 20 40 50.0 %

          Line data    Source code
       1             : /*
       2             :  *  Unix SMB/CIFS implementation.
       3             :  *  RPC Pipe client / server routines
       4             :  *
       5             :  *  Copyright (C) Gerald Carter                 2002-2006.
       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             : /* Implementation of registry functions. */
      22             : 
      23             : #include "includes.h"
      24             : #include "ntdomain.h"
      25             : #include "librpc/rpc/dcesrv_core.h"
      26             : #include "librpc/gen_ndr/ndr_winreg.h"
      27             : #include "librpc/gen_ndr/ndr_winreg_scompat.h"
      28             : #include "registry.h"
      29             : #include "registry/reg_api.h"
      30             : #include "registry/reg_perfcount.h"
      31             : #include "rpc_misc.h"
      32             : #include "auth.h"
      33             : #include "lib/privileges.h"
      34             : #include "libcli/security/secdesc.h"
      35             : 
      36             : #undef DBGC_CLASS
      37             : #define DBGC_CLASS DBGC_RPC_SRV
      38             : 
      39             : enum handle_types { HTYPE_REGVAL, HTYPE_REGKEY };
      40             : 
      41             : /******************************************************************
      42             :  Find a registry key handle and return a struct registry_key *
      43             :  *****************************************************************/
      44             : 
      45        3315 : static struct registry_key *find_regkey_by_hnd(struct pipes_struct *p,
      46             :                                                struct policy_handle *hnd,
      47             :                                                enum handle_types type)
      48             : {
      49        3315 :         struct registry_key *regkey = NULL;
      50             :         NTSTATUS status;
      51             : 
      52        3315 :         regkey = find_policy_by_hnd(p,
      53             :                                     hnd,
      54             :                                     type,
      55             :                                     struct registry_key,
      56             :                                     &status);
      57        3315 :         if (!NT_STATUS_IS_OK(status)) {
      58           0 :                 DEBUG(2,("find_regkey_index_by_hnd: Registry Key not found: "));
      59           0 :                 return NULL;
      60             :         }
      61             : 
      62        3315 :         return regkey;
      63             : }
      64             : 
      65             : /*******************************************************************
      66             :  Function for open a new registry handle and creating a handle
      67             :  Note that P should be valid & hnd should already have space
      68             : 
      69             :  When we open a key, we store the full path to the key as
      70             :  HK[LM|U]\<key>\<key>\...
      71             :  *******************************************************************/
      72             : 
      73         232 : static WERROR open_registry_key(struct pipes_struct *p,
      74             :                                 struct policy_handle *hnd,
      75             :                                 struct registry_key *parent,
      76             :                                 const char *subkeyname,
      77             :                                 uint32_t access_desired)
      78             : {
      79         232 :         struct dcesrv_call_state *dce_call = p->dce_call;
      80         150 :         struct auth_session_info *session_info =
      81          82 :                 dcesrv_call_session_info(dce_call);
      82         232 :         WERROR result = WERR_OK;
      83             :         struct registry_key *key;
      84             : 
      85         232 :         if (parent == NULL) {
      86         104 :                 result = reg_openhive(p->mem_ctx, subkeyname, access_desired,
      87         104 :                                       session_info->security_token, &key);
      88             :         }
      89             :         else {
      90         128 :                 result = reg_openkey(p->mem_ctx, parent, subkeyname,
      91             :                                      access_desired, &key);
      92             :         }
      93             : 
      94         232 :         if ( !W_ERROR_IS_OK(result) ) {
      95          42 :                 return result;
      96             :         }
      97             : 
      98         190 :         if ( !create_policy_hnd( p, hnd, HTYPE_REGKEY, key ) ) {
      99           0 :                 return WERR_FILE_NOT_FOUND;
     100             :         }
     101             : 
     102         190 :         return WERR_OK;
     103             : }
     104             : 
     105             : /*******************************************************************
     106             :  Function for open a new registry handle and creating a handle
     107             :  Note that P should be valid & hnd should already have space
     108             :  *******************************************************************/
     109             : 
     110         439 : static bool close_registry_key(struct pipes_struct *p,
     111             :                                struct policy_handle *hnd,
     112             :                                enum handle_types type)
     113             : {
     114         439 :         struct registry_key *regkey = find_regkey_by_hnd(p, hnd, type);
     115             : 
     116         439 :         if ( !regkey ) {
     117           0 :                 DEBUG(2,("close_registry_key: Invalid handle (%s:%u:%u)\n",
     118             :                          OUR_HANDLE(hnd)));
     119           0 :                 return False;
     120             :         }
     121             : 
     122         439 :         close_policy_hnd(p, hnd);
     123             : 
     124         439 :         return True;
     125             : }
     126             : 
     127             : /********************************************************************
     128             :  _winreg_CloseKey
     129             :  ********************************************************************/
     130             : 
     131         439 : WERROR _winreg_CloseKey(struct pipes_struct *p,
     132             :                         struct winreg_CloseKey *r)
     133             : {
     134             :         bool ok;
     135             : 
     136             :         /* close the policy handle */
     137             : 
     138         439 :         ok = close_registry_key(p, r->in.handle, HTYPE_REGKEY);
     139         439 :         if (!ok) {
     140           0 :                 return WERR_INVALID_HANDLE;
     141             :         }
     142             : 
     143         439 :         ZERO_STRUCTP(r->out.handle);
     144             : 
     145         439 :         return WERR_OK;
     146             : }
     147             : 
     148             : /*******************************************************************
     149             :  _winreg_OpenHKLM
     150             :  ********************************************************************/
     151             : 
     152          95 : WERROR _winreg_OpenHKLM(struct pipes_struct *p,
     153             :                         struct winreg_OpenHKLM *r)
     154             : {
     155          95 :         return open_registry_key(p, r->out.handle, NULL, KEY_HKLM, r->in.access_mask);
     156             : }
     157             : 
     158             : /*******************************************************************
     159             :  _winreg_OpenHKPD
     160             :  ********************************************************************/
     161             : 
     162           0 : WERROR _winreg_OpenHKPD(struct pipes_struct *p,
     163             :                         struct winreg_OpenHKPD *r)
     164             : {
     165           0 :         return open_registry_key(p, r->out.handle, NULL, KEY_HKPD, r->in.access_mask);
     166             : }
     167             : 
     168             : /*******************************************************************
     169             :  _winreg_OpenHKPT
     170             :  ********************************************************************/
     171             : 
     172           0 : WERROR _winreg_OpenHKPT(struct pipes_struct *p,
     173             :                         struct winreg_OpenHKPT *r)
     174             : {
     175           0 :         return open_registry_key(p, r->out.handle, NULL, KEY_HKPT, r->in.access_mask);
     176             : }
     177             : 
     178             : /*******************************************************************
     179             :  _winreg_OpenHKCR
     180             :  ********************************************************************/
     181             : 
     182           3 : WERROR _winreg_OpenHKCR(struct pipes_struct *p,
     183             :                         struct winreg_OpenHKCR *r)
     184             : {
     185           3 :         return open_registry_key(p, r->out.handle, NULL, KEY_HKCR, r->in.access_mask);
     186             : }
     187             : 
     188             : /*******************************************************************
     189             :  _winreg_OpenHKU
     190             :  ********************************************************************/
     191             : 
     192           3 : WERROR _winreg_OpenHKU(struct pipes_struct *p,
     193             :                        struct winreg_OpenHKU *r)
     194             : {
     195           3 :         return open_registry_key(p, r->out.handle, NULL, KEY_HKU, r->in.access_mask);
     196             : }
     197             : 
     198             : /*******************************************************************
     199             :  _winreg_OpenHKCU
     200             :  ********************************************************************/
     201             : 
     202           3 : WERROR _winreg_OpenHKCU(struct pipes_struct *p,
     203             :                         struct winreg_OpenHKCU *r)
     204             : {
     205           3 :         return open_registry_key(p, r->out.handle, NULL, KEY_HKCU, r->in.access_mask);
     206             : }
     207             : 
     208             : /*******************************************************************
     209             :  _winreg_OpenHKCC
     210             :  ********************************************************************/
     211             : 
     212           0 : WERROR _winreg_OpenHKCC(struct pipes_struct *p,
     213             :                         struct winreg_OpenHKCC *r)
     214             : {
     215           0 :         return open_registry_key(p, r->out.handle, NULL, KEY_HKCC, r->in.access_mask);
     216             : }
     217             : 
     218             : /*******************************************************************
     219             :  _winreg_OpenHKDD
     220             :  ********************************************************************/
     221             : 
     222           0 : WERROR _winreg_OpenHKDD(struct pipes_struct *p,
     223             :                         struct winreg_OpenHKDD *r)
     224             : {
     225           0 :         return open_registry_key(p, r->out.handle, NULL, KEY_HKDD, r->in.access_mask);
     226             : }
     227             : 
     228             : /*******************************************************************
     229             :  _winreg_OpenHKPN
     230             :  ********************************************************************/
     231             : 
     232           0 : WERROR _winreg_OpenHKPN(struct pipes_struct *p,
     233             :                         struct winreg_OpenHKPN *r)
     234             : {
     235           0 :         return open_registry_key(p, r->out.handle, NULL, KEY_HKPN, r->in.access_mask);
     236             : }
     237             : 
     238             : /*******************************************************************
     239             :  _winreg_OpenKey
     240             :  ********************************************************************/
     241             : 
     242         128 : WERROR _winreg_OpenKey(struct pipes_struct *p,
     243             :                        struct winreg_OpenKey *r)
     244             : {
     245         128 :         struct registry_key *parent = find_regkey_by_hnd(p,
     246             :                                                          r->in.parent_handle,
     247             :                                                          HTYPE_REGKEY);
     248             : 
     249         128 :         if ( !parent )
     250           0 :                 return WERR_INVALID_HANDLE;
     251             : 
     252         128 :         return open_registry_key(p, r->out.handle, parent, r->in.keyname.name, r->in.access_mask);
     253             : }
     254             : 
     255             : /*******************************************************************
     256             :  _winreg_QueryValue
     257             :  ********************************************************************/
     258             : 
     259         606 : WERROR _winreg_QueryValue(struct pipes_struct *p,
     260             :                           struct winreg_QueryValue *r)
     261             : {
     262         606 :         WERROR        status = WERR_FILE_NOT_FOUND;
     263         606 :         struct registry_key *regkey = find_regkey_by_hnd(p,
     264             :                                                          r->in.handle,
     265             :                                                          HTYPE_REGKEY);
     266             :         prs_struct    prs_hkpd;
     267             : 
     268         606 :         uint8_t *outbuf = NULL;
     269         606 :         uint32_t outbuf_size = 0;
     270             : 
     271         606 :         bool free_buf = False;
     272         606 :         bool free_prs = False;
     273             : 
     274         606 :         if ( !regkey )
     275           0 :                 return WERR_INVALID_HANDLE;
     276             : 
     277         606 :         if (r->in.value_name->name == NULL) {
     278          84 :                 return WERR_INVALID_PARAMETER;
     279             :         }
     280             : 
     281         522 :         if ((r->out.data_length == NULL) || (r->out.type == NULL) || (r->out.data_size == NULL)) {
     282         189 :                 return WERR_INVALID_PARAMETER;
     283             :         }
     284             : 
     285         333 :         DEBUG(7,("_winreg_QueryValue: policy key name = [%s]\n", regkey->key->name));
     286         333 :         DEBUG(7,("_winreg_QueryValue: policy key type = [%08x]\n", regkey->key->type));
     287             : 
     288             :         /* Handle QueryValue calls on HKEY_PERFORMANCE_DATA */
     289         333 :         if(regkey->key->type == REG_KEY_HKPD)
     290             :         {
     291           0 :                 if (strequal(r->in.value_name->name, "Global")) {
     292           0 :                         if (!prs_init(&prs_hkpd, *r->in.data_size, p->mem_ctx, MARSHALL))
     293           0 :                                 return WERR_NOT_ENOUGH_MEMORY;
     294           0 :                         status = reg_perfcount_get_hkpd(
     295           0 :                                 &prs_hkpd, *r->in.data_size, &outbuf_size, NULL);
     296           0 :                         outbuf = (uint8_t *)prs_hkpd.data_p;
     297           0 :                         free_prs = True;
     298             :                 }
     299           0 :                 else if (strequal(r->in.value_name->name, "Counter 009")) {
     300           0 :                         outbuf_size = reg_perfcount_get_counter_names(
     301             :                                 reg_perfcount_get_base_index(),
     302             :                                 (char **)(void *)&outbuf);
     303           0 :                         free_buf = True;
     304             :                 }
     305           0 :                 else if (strequal(r->in.value_name->name, "Explain 009")) {
     306           0 :                         outbuf_size = reg_perfcount_get_counter_help(
     307             :                                 reg_perfcount_get_base_index(),
     308             :                                 (char **)(void *)&outbuf);
     309           0 :                         free_buf = True;
     310             :                 }
     311           0 :                 else if (isdigit(r->in.value_name->name[0])) {
     312             :                         /* we probably have a request for a specific object
     313             :                          * here */
     314           0 :                         if (!prs_init(&prs_hkpd, *r->in.data_size, p->mem_ctx, MARSHALL))
     315           0 :                                 return WERR_NOT_ENOUGH_MEMORY;
     316           0 :                         status = reg_perfcount_get_hkpd(
     317           0 :                                 &prs_hkpd, *r->in.data_size, &outbuf_size,
     318           0 :                                 r->in.value_name->name);
     319           0 :                         outbuf = (uint8_t *)prs_hkpd.data_p;
     320           0 :                         free_prs = True;
     321             :                 }
     322             :                 else {
     323           0 :                         DEBUG(3,("Unsupported key name [%s] for HKPD.\n",
     324             :                                  r->in.value_name->name));
     325           0 :                         return WERR_FILE_NOT_FOUND;
     326             :                 }
     327             : 
     328           0 :                 *r->out.type = REG_BINARY;
     329             :         }
     330             :         else {
     331             :                 struct registry_value *val;
     332             : 
     333         333 :                 status = reg_queryvalue(p->mem_ctx, regkey, r->in.value_name->name,
     334             :                                         &val);
     335         333 :                 if (!W_ERROR_IS_OK(status)) {
     336             : 
     337          54 :                         DEBUG(10,("_winreg_QueryValue: reg_queryvalue failed with: %s\n",
     338             :                                 win_errstr(status)));
     339             : 
     340          54 :                         if (r->out.data_size) {
     341          54 :                                 *r->out.data_size = 0;
     342             :                         }
     343          54 :                         if (r->out.data_length) {
     344          54 :                                 *r->out.data_length = 0;
     345             :                         }
     346          54 :                         return status;
     347             :                 }
     348             : 
     349         279 :                 outbuf = val->data.data;
     350         279 :                 outbuf_size = val->data.length;
     351         279 :                 *r->out.type = val->type;
     352             :         }
     353             : 
     354         279 :         status = WERR_FILE_NOT_FOUND;
     355             : 
     356         279 :         if (*r->in.data_size < outbuf_size) {
     357         168 :                 *r->out.data_size = outbuf_size;
     358         168 :                 status = r->in.data ? WERR_MORE_DATA : WERR_OK;
     359             :         } else {
     360         111 :                 *r->out.data_length = outbuf_size;
     361         111 :                 *r->out.data_size = outbuf_size;
     362         111 :                 if (r->out.data) {
     363         111 :                         memcpy(r->out.data, outbuf, outbuf_size);
     364             :                 }
     365         111 :                 status = WERR_OK;
     366             :         }
     367             : 
     368         279 :         if (free_prs) prs_mem_free(&prs_hkpd);
     369         279 :         if (free_buf) SAFE_FREE(outbuf);
     370             : 
     371         279 :         return status;
     372             : }
     373             : 
     374             : /*****************************************************************************
     375             :  _winreg_QueryInfoKey
     376             :  ****************************************************************************/
     377             : 
     378          74 : WERROR _winreg_QueryInfoKey(struct pipes_struct *p,
     379             :                             struct winreg_QueryInfoKey *r)
     380             : {
     381          74 :         WERROR  status = WERR_OK;
     382          74 :         struct registry_key *regkey = find_regkey_by_hnd(p,
     383             :                                                          r->in.handle,
     384             :                                                          HTYPE_REGKEY);
     385             : 
     386          74 :         if ( !regkey )
     387           0 :                 return WERR_INVALID_HANDLE;
     388             : 
     389          74 :         r->out.classname->name = NULL;
     390             : 
     391          74 :         status = reg_queryinfokey(regkey, r->out.num_subkeys, r->out.max_subkeylen,
     392             :                                   r->out.max_classlen, r->out.num_values, r->out.max_valnamelen,
     393             :                                   r->out.max_valbufsize, r->out.secdescsize,
     394             :                                   r->out.last_changed_time);
     395          74 :         if (!W_ERROR_IS_OK(status)) {
     396           0 :                 return status;
     397             :         }
     398             : 
     399             :         /*
     400             :          * These calculations account for the registry buffers being
     401             :          * UTF-16. They are inexact at best, but so far they worked.
     402             :          */
     403             : 
     404          74 :         *r->out.max_subkeylen *= 2;
     405             : 
     406          74 :         *r->out.max_valnamelen += 1;
     407          74 :         *r->out.max_valnamelen *= 2;
     408             : 
     409          74 :         return WERR_OK;
     410             : }
     411             : 
     412             : 
     413             : /*****************************************************************************
     414             :  _winreg_GetVersion
     415             :  ****************************************************************************/
     416             : 
     417          12 : WERROR _winreg_GetVersion(struct pipes_struct *p,
     418             :                           struct winreg_GetVersion *r)
     419             : {
     420          12 :         struct registry_key *regkey = find_regkey_by_hnd(p,
     421             :                                                          r->in.handle,
     422             :                                                          HTYPE_REGKEY);
     423             : 
     424          12 :         if ( !regkey )
     425           0 :                 return WERR_INVALID_HANDLE;
     426             : 
     427          12 :         return reg_getversion(r->out.version);
     428             : }
     429             : 
     430             : 
     431             : /*****************************************************************************
     432             :  _winreg_EnumKey
     433             :  ****************************************************************************/
     434             : 
     435         201 : WERROR _winreg_EnumKey(struct pipes_struct *p,
     436             :                        struct winreg_EnumKey *r)
     437             : {
     438         201 :         WERROR err = WERR_OK;
     439         201 :         struct registry_key *key = find_regkey_by_hnd(p,
     440             :                                                       r->in.handle,
     441             :                                                       HTYPE_REGKEY);
     442             :         char *name;
     443             : 
     444         201 :         if ( !key )
     445           0 :                 return WERR_INVALID_HANDLE;
     446             : 
     447         201 :         if ( !r->in.name || !r->in.keyclass )
     448           0 :                 return WERR_INVALID_PARAMETER;
     449             : 
     450         201 :         DEBUG(8,("_winreg_EnumKey: enumerating key [%s]\n", key->key->name));
     451             : 
     452         201 :         err = reg_enumkey(p->mem_ctx, key, r->in.enum_index, &name,
     453             :                           r->out.last_changed_time);
     454         201 :         if (!W_ERROR_IS_OK(err)) {
     455          12 :                 return err;
     456             :         }
     457         189 :         r->out.name->name = name;
     458         189 :         r->out.keyclass->name = "";
     459         189 :         return WERR_OK;
     460             : }
     461             : 
     462             : /*****************************************************************************
     463             :  _winreg_EnumValue
     464             :  ****************************************************************************/
     465             : 
     466          24 : WERROR _winreg_EnumValue(struct pipes_struct *p,
     467             :                          struct winreg_EnumValue *r)
     468             : {
     469          24 :         WERROR err = WERR_OK;
     470          24 :         struct registry_key *key = find_regkey_by_hnd(p,
     471             :                                                       r->in.handle,
     472             :                                                       HTYPE_REGKEY);
     473          24 :         char *valname = NULL;
     474          24 :         struct registry_value *val = NULL;
     475             : 
     476          24 :         if ( !key )
     477           0 :                 return WERR_INVALID_HANDLE;
     478             : 
     479          24 :         if ( !r->in.name )
     480           0 :                 return WERR_INVALID_PARAMETER;
     481             : 
     482          24 :         DEBUG(8,("_winreg_EnumValue: enumerating values for key [%s]\n",
     483             :                  key->key->name));
     484             : 
     485          24 :         err = reg_enumvalue(p->mem_ctx, key, r->in.enum_index, &valname, &val);
     486          24 :         if (!W_ERROR_IS_OK(err)) {
     487          24 :                 return err;
     488             :         }
     489             : 
     490           0 :         if (r->out.name != NULL) {
     491           0 :                 r->out.name->name = valname;
     492             :         }
     493             : 
     494           0 :         if (r->out.type != NULL) {
     495           0 :                 *r->out.type = val->type;
     496             :         }
     497             : 
     498           0 :         if (r->out.value != NULL) {
     499           0 :                 if ((r->out.size == NULL) || (r->out.length == NULL)) {
     500           0 :                         return WERR_INVALID_PARAMETER;
     501             :                 }
     502             : 
     503           0 :                 if (val->data.length > *r->out.size) {
     504           0 :                         return WERR_MORE_DATA;
     505             :                 }
     506             : 
     507           0 :                 memcpy( r->out.value, val->data.data, val->data.length );
     508             :         }
     509             : 
     510           0 :         if (r->out.length != NULL) {
     511           0 :                 *r->out.length = val->data.length;
     512             :         }
     513           0 :         if (r->out.size != NULL) {
     514           0 :                 *r->out.size = val->data.length;
     515             :         }
     516             : 
     517           0 :         return WERR_OK;
     518             : }
     519             : 
     520             : /*******************************************************************
     521             :  _winreg_InitiateSystemShutdown
     522             :  ********************************************************************/
     523             : 
     524           0 : WERROR _winreg_InitiateSystemShutdown(struct pipes_struct *p,
     525             :                                       struct winreg_InitiateSystemShutdown *r)
     526             : {
     527             :         struct winreg_InitiateSystemShutdownEx s;
     528             : 
     529           0 :         s.in.hostname = r->in.hostname;
     530           0 :         s.in.message = r->in.message;
     531           0 :         s.in.timeout = r->in.timeout;
     532           0 :         s.in.force_apps = r->in.force_apps;
     533           0 :         s.in.do_reboot = r->in.do_reboot;
     534           0 :         s.in.reason = 0;
     535             : 
     536             :         /* thunk down to _winreg_InitiateSystemShutdownEx()
     537             :            (just returns a status) */
     538             : 
     539           0 :         return _winreg_InitiateSystemShutdownEx( p, &s );
     540             : }
     541             : 
     542             : /*******************************************************************
     543             :  _winreg_InitiateSystemShutdownEx
     544             :  ********************************************************************/
     545             : 
     546             : #define SHUTDOWN_R_STRING "-r"
     547             : #define SHUTDOWN_F_STRING "-f"
     548             : 
     549             : 
     550           0 : WERROR _winreg_InitiateSystemShutdownEx(struct pipes_struct *p,
     551             :                                         struct winreg_InitiateSystemShutdownEx *r)
     552             : {
     553           0 :         struct dcesrv_call_state *dce_call = p->dce_call;
     554           0 :         struct auth_session_info *session_info =
     555           0 :                 dcesrv_call_session_info(dce_call);
     556           0 :         const struct loadparm_substitution *lp_sub =
     557           0 :                 loadparm_s3_global_substitution();
     558           0 :         char *shutdown_script = NULL;
     559           0 :         char *chkmsg = NULL;
     560             :         fstring str_timeout;
     561             :         fstring str_reason;
     562             :         fstring do_reboot;
     563             :         fstring f;
     564           0 :         int ret = -1;
     565           0 :         bool can_shutdown = false;
     566             : 
     567           0 :         shutdown_script = lp_shutdown_script(p->mem_ctx, lp_sub);
     568           0 :         if (!shutdown_script) {
     569           0 :                 return WERR_NOT_ENOUGH_MEMORY;
     570             :         }
     571           0 :         if (!*shutdown_script) {
     572           0 :                 return WERR_ACCESS_DENIED;
     573             :         }
     574             : 
     575             :         /* pull the message string and perform necessary sanity checks on it */
     576             : 
     577           0 :         if ( r->in.message && r->in.message->string ) {
     578           0 :                 chkmsg = talloc_alpha_strcpy(p->mem_ctx,
     579           0 :                                              r->in.message->string,
     580             :                                              NULL);
     581           0 :                 if (chkmsg == NULL) {
     582           0 :                         return WERR_NOT_ENOUGH_MEMORY;
     583             :                 }
     584             :         }
     585             : 
     586           0 :         fstr_sprintf(str_timeout, "%d", r->in.timeout);
     587           0 :         fstr_sprintf(do_reboot, r->in.do_reboot ? SHUTDOWN_R_STRING : "");
     588           0 :         fstr_sprintf(f, r->in.force_apps ? SHUTDOWN_F_STRING : "");
     589           0 :         fstr_sprintf(str_reason, "%d", r->in.reason );
     590             : 
     591           0 :         shutdown_script = talloc_all_string_sub(p->mem_ctx,
     592             :                                 shutdown_script, "%z", chkmsg ? chkmsg : "");
     593           0 :         if (!shutdown_script) {
     594           0 :                 return WERR_NOT_ENOUGH_MEMORY;
     595             :         }
     596           0 :         shutdown_script = talloc_all_string_sub(p->mem_ctx,
     597             :                                         shutdown_script, "%t", str_timeout);
     598           0 :         if (!shutdown_script) {
     599           0 :                 return WERR_NOT_ENOUGH_MEMORY;
     600             :         }
     601           0 :         shutdown_script = talloc_all_string_sub(p->mem_ctx,
     602             :                                                 shutdown_script, "%r", do_reboot);
     603           0 :         if (!shutdown_script) {
     604           0 :                 return WERR_NOT_ENOUGH_MEMORY;
     605             :         }
     606           0 :         shutdown_script = talloc_all_string_sub(p->mem_ctx,
     607             :                                                 shutdown_script, "%f", f);
     608           0 :         if (!shutdown_script) {
     609           0 :                 return WERR_NOT_ENOUGH_MEMORY;
     610             :         }
     611           0 :         shutdown_script = talloc_all_string_sub(p->mem_ctx,
     612             :                                         shutdown_script, "%x", str_reason);
     613           0 :         if (!shutdown_script) {
     614           0 :                 return WERR_NOT_ENOUGH_MEMORY;
     615             :         }
     616             : 
     617           0 :         can_shutdown = security_token_has_privilege(
     618           0 :                 session_info->security_token, SEC_PRIV_REMOTE_SHUTDOWN);
     619             : 
     620             :         /* IF someone has privs, run the shutdown script as root. OTHERWISE run it as not root
     621             :            Take the error return from the script and provide it as the Windows return code. */
     622             : 
     623             :         /********** BEGIN SeRemoteShutdownPrivilege BLOCK **********/
     624             : 
     625           0 :         if ( can_shutdown )
     626           0 :                 become_root();
     627             : 
     628           0 :         ret = smbrun(shutdown_script, NULL, NULL);
     629             : 
     630           0 :         if ( can_shutdown )
     631           0 :                 unbecome_root();
     632             : 
     633             :         /********** END SeRemoteShutdownPrivilege BLOCK **********/
     634             : 
     635           0 :         DEBUG(3,("_reg_shutdown_ex: Running the command `%s' gave %d\n",
     636             :                 shutdown_script, ret));
     637             : 
     638           0 :         return (ret == 0) ? WERR_OK : WERR_ACCESS_DENIED;
     639             : }
     640             : 
     641             : /*******************************************************************
     642             :  _winreg_AbortSystemShutdown
     643             :  ********************************************************************/
     644             : 
     645           0 : WERROR _winreg_AbortSystemShutdown(struct pipes_struct *p,
     646             :                                    struct winreg_AbortSystemShutdown *r)
     647             : {
     648           0 :         struct dcesrv_call_state *dce_call = p->dce_call;
     649           0 :         struct auth_session_info *session_info =
     650           0 :                 dcesrv_call_session_info(dce_call);
     651           0 :         const char *abort_shutdown_script = NULL;
     652           0 :         const struct loadparm_substitution *lp_sub =
     653           0 :                 loadparm_s3_global_substitution();
     654           0 :         int ret = -1;
     655           0 :         bool can_shutdown = false;
     656             : 
     657           0 :         abort_shutdown_script = lp_abort_shutdown_script(talloc_tos(), lp_sub);
     658           0 :         if (!*abort_shutdown_script)
     659           0 :                 return WERR_ACCESS_DENIED;
     660             : 
     661           0 :         can_shutdown = security_token_has_privilege(
     662           0 :                 session_info->security_token, SEC_PRIV_REMOTE_SHUTDOWN);
     663             : 
     664             :         /********** BEGIN SeRemoteShutdownPrivilege BLOCK **********/
     665             : 
     666           0 :         if ( can_shutdown )
     667           0 :                 become_root();
     668             : 
     669           0 :         ret = smbrun(abort_shutdown_script, NULL, NULL);
     670             : 
     671           0 :         if ( can_shutdown )
     672           0 :                 unbecome_root();
     673             : 
     674             :         /********** END SeRemoteShutdownPrivilege BLOCK **********/
     675             : 
     676           0 :         DEBUG(3,("_winreg_AbortSystemShutdown: Running the command `%s' gave %d\n",
     677             :                 abort_shutdown_script, ret));
     678             : 
     679           0 :         return (ret == 0) ? WERR_OK : WERR_ACCESS_DENIED;
     680             : }
     681             : 
     682             : /*******************************************************************
     683             :  _winreg_RestoreKey
     684             :  ********************************************************************/
     685             : 
     686           0 : WERROR _winreg_RestoreKey(struct pipes_struct *p,
     687             :                           struct winreg_RestoreKey *r)
     688             : {
     689           0 :         struct registry_key *regkey = find_regkey_by_hnd(p,
     690             :                                                          r->in.handle,
     691             :                                                          HTYPE_REGKEY);
     692             : 
     693           0 :         if ( !regkey ) {
     694           0 :                 return WERR_INVALID_HANDLE;
     695             :         }
     696           0 :         return WERR_BAD_PATHNAME;
     697             : }
     698             : 
     699             : /*******************************************************************
     700             :  _winreg_SaveKey
     701             :  ********************************************************************/
     702             : 
     703           0 : WERROR _winreg_SaveKey(struct pipes_struct *p,
     704             :                        struct winreg_SaveKey *r)
     705             : {
     706           0 :         struct registry_key *regkey = find_regkey_by_hnd(p,
     707             :                                                          r->in.handle,
     708             :                                                          HTYPE_REGKEY);
     709             : 
     710           0 :         if ( !regkey ) {
     711           0 :                 return WERR_INVALID_HANDLE;
     712             :         }
     713           0 :         return WERR_BAD_PATHNAME;
     714             : }
     715             : 
     716             : /*******************************************************************
     717             :  _winreg_SaveKeyEx
     718             :  ********************************************************************/
     719             : 
     720           0 : WERROR _winreg_SaveKeyEx(struct pipes_struct *p,
     721             :                          struct winreg_SaveKeyEx *r)
     722             : {
     723             :         /* fill in your code here if you think this call should
     724             :            do anything */
     725             : 
     726           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
     727           0 :         return WERR_NOT_SUPPORTED;
     728             : }
     729             : 
     730             : /*******************************************************************
     731             :  _winreg_CreateKey
     732             :  ********************************************************************/
     733             : 
     734         383 : WERROR _winreg_CreateKey(struct pipes_struct *p,
     735             :                          struct winreg_CreateKey *r)
     736             : {
     737         383 :         struct registry_key *parent = find_regkey_by_hnd(p,
     738             :                                                          r->in.handle,
     739             :                                                          HTYPE_REGKEY);
     740         383 :         struct registry_key *new_key = NULL;
     741         383 :         WERROR result = WERR_OK;
     742             : 
     743         383 :         if ( !parent )
     744           0 :                 return WERR_INVALID_HANDLE;
     745             : 
     746         383 :         DEBUG(10, ("_winreg_CreateKey called with parent key '%s' and "
     747             :                    "subkey name '%s'\n", parent->key->name, r->in.name.name));
     748             : 
     749         383 :         result = reg_createkey(NULL, parent, r->in.name.name, r->in.access_mask,
     750             :                                &new_key, r->out.action_taken);
     751         383 :         if (!W_ERROR_IS_OK(result)) {
     752           0 :                 return result;
     753             :         }
     754             : 
     755         383 :         if (!create_policy_hnd(p, r->out.new_handle, HTYPE_REGKEY, new_key)) {
     756           0 :                 TALLOC_FREE(new_key);
     757           0 :                 return WERR_FILE_NOT_FOUND;
     758             :         }
     759             : 
     760         383 :         return WERR_OK;
     761             : }
     762             : 
     763             : /*******************************************************************
     764             :  _winreg_SetValue
     765             :  ********************************************************************/
     766             : 
     767        1298 : WERROR _winreg_SetValue(struct pipes_struct *p,
     768             :                         struct winreg_SetValue *r)
     769             : {
     770        1298 :         struct registry_key *key = find_regkey_by_hnd(p,
     771             :                                                       r->in.handle,
     772             :                                                       HTYPE_REGKEY);
     773        1298 :         struct registry_value *val = NULL;
     774             : 
     775        1298 :         if ( !key )
     776           0 :                 return WERR_INVALID_HANDLE;
     777             : 
     778        1298 :         DEBUG(8,("_winreg_SetValue: Setting value for [%s:%s]\n",
     779             :                          key->key->name, r->in.name.name));
     780             : 
     781        1298 :         val = talloc_zero(p->mem_ctx, struct registry_value);
     782        1298 :         if (val == NULL) {
     783           0 :                 return WERR_NOT_ENOUGH_MEMORY;
     784             :         }
     785             : 
     786        1298 :         val->type = r->in.type;
     787        1298 :         val->data = data_blob_talloc(p->mem_ctx, r->in.data, r->in.size);
     788             : 
     789        1298 :         return reg_setvalue(key, r->in.name.name, val);
     790             : }
     791             : 
     792             : /*******************************************************************
     793             :  _winreg_DeleteKey
     794             :  ********************************************************************/
     795             : 
     796          96 : WERROR _winreg_DeleteKey(struct pipes_struct *p,
     797             :                          struct winreg_DeleteKey *r)
     798             : {
     799          96 :         struct registry_key *parent = find_regkey_by_hnd(p,
     800             :                                                          r->in.handle,
     801             :                                                          HTYPE_REGKEY);
     802             : 
     803          96 :         if ( !parent )
     804           0 :                 return WERR_INVALID_HANDLE;
     805             : 
     806          96 :         return reg_deletekey(parent, r->in.key.name);
     807             : }
     808             : 
     809             : 
     810             : /*******************************************************************
     811             :  _winreg_DeleteValue
     812             :  ********************************************************************/
     813             : 
     814          54 : WERROR _winreg_DeleteValue(struct pipes_struct *p,
     815             :                            struct winreg_DeleteValue *r)
     816             : {
     817          54 :         struct registry_key *key = find_regkey_by_hnd(p,
     818             :                                                       r->in.handle,
     819             :                                                       HTYPE_REGKEY);
     820             : 
     821          54 :         if ( !key )
     822           0 :                 return WERR_INVALID_HANDLE;
     823             : 
     824          54 :         return reg_deletevalue(key, r->in.value.name);
     825             : }
     826             : 
     827             : /*******************************************************************
     828             :  _winreg_GetKeySecurity
     829             :  ********************************************************************/
     830             : 
     831           0 : WERROR _winreg_GetKeySecurity(struct pipes_struct *p,
     832             :                               struct winreg_GetKeySecurity *r)
     833             : {
     834           0 :         struct registry_key *key = find_regkey_by_hnd(p,
     835             :                                                       r->in.handle,
     836             :                                                       HTYPE_REGKEY);
     837           0 :         WERROR err = WERR_OK;
     838           0 :         struct security_descriptor *secdesc = NULL;
     839           0 :         uint8_t *data = NULL;
     840           0 :         size_t len = 0;
     841             : 
     842           0 :         if ( !key )
     843           0 :                 return WERR_INVALID_HANDLE;
     844             : 
     845             :         /* access checks first */
     846             : 
     847           0 :         if ( !(key->key->access_granted & SEC_STD_READ_CONTROL) )
     848           0 :                 return WERR_ACCESS_DENIED;
     849             : 
     850           0 :         err = reg_getkeysecurity(p->mem_ctx, key, &secdesc);
     851           0 :         if (!W_ERROR_IS_OK(err)) {
     852           0 :                 return err;
     853             :         }
     854             : 
     855           0 :         err = ntstatus_to_werror(marshall_sec_desc(p->mem_ctx, secdesc,
     856             :                                                    &data, &len));
     857           0 :         if (!W_ERROR_IS_OK(err)) {
     858           0 :                 return err;
     859             :         }
     860             : 
     861           0 :         if (len > r->out.sd->size) {
     862           0 :                 r->out.sd->size = len;
     863           0 :                 return WERR_INSUFFICIENT_BUFFER;
     864             :         }
     865             : 
     866           0 :         r->out.sd->size = len;
     867           0 :         r->out.sd->len = len;
     868           0 :         r->out.sd->data = data;
     869             : 
     870           0 :         return WERR_OK;
     871             : }
     872             : 
     873             : /*******************************************************************
     874             :  _winreg_SetKeySecurity
     875             :  ********************************************************************/
     876             : 
     877           0 : WERROR _winreg_SetKeySecurity(struct pipes_struct *p,
     878             :                               struct winreg_SetKeySecurity *r)
     879             : {
     880           0 :         struct registry_key *key = find_regkey_by_hnd(p,
     881             :                                                       r->in.handle,
     882             :                                                       HTYPE_REGKEY);
     883           0 :         struct security_descriptor *secdesc = NULL;
     884           0 :         WERROR err = WERR_OK;
     885             : 
     886           0 :         if ( !key )
     887           0 :                 return WERR_INVALID_HANDLE;
     888             : 
     889             :         /* access checks first */
     890             : 
     891           0 :         if ( !(key->key->access_granted & SEC_STD_WRITE_DAC) )
     892           0 :                 return WERR_ACCESS_DENIED;
     893             : 
     894           0 :         err = ntstatus_to_werror(unmarshall_sec_desc(p->mem_ctx, r->in.sd->data,
     895           0 :                                                      r->in.sd->len, &secdesc));
     896           0 :         if (!W_ERROR_IS_OK(err)) {
     897           0 :                 return err;
     898             :         }
     899             : 
     900           0 :         return reg_setkeysecurity(key, secdesc);
     901             : }
     902             : 
     903             : /*******************************************************************
     904             :  _winreg_FlushKey
     905             :  ********************************************************************/
     906             : 
     907          24 : WERROR _winreg_FlushKey(struct pipes_struct *p,
     908             :                         struct winreg_FlushKey *r)
     909             : {
     910             :         /* I'm just replying OK because there's not a lot
     911             :            here I see to do i  --jerry */
     912             : 
     913          24 :         return WERR_OK;
     914             : }
     915             : 
     916             : /*******************************************************************
     917             :  _winreg_UnLoadKey
     918             :  ********************************************************************/
     919             : 
     920           0 : WERROR _winreg_UnLoadKey(struct pipes_struct *p,
     921             :                          struct winreg_UnLoadKey *r)
     922             : {
     923             :         /* fill in your code here if you think this call should
     924             :            do anything */
     925             : 
     926           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
     927           0 :         return WERR_NOT_SUPPORTED;
     928             : }
     929             : 
     930             : /*******************************************************************
     931             :  _winreg_ReplaceKey
     932             :  ********************************************************************/
     933             : 
     934           0 : WERROR _winreg_ReplaceKey(struct pipes_struct *p,
     935             :                           struct winreg_ReplaceKey *r)
     936             : {
     937             :         /* fill in your code here if you think this call should
     938             :            do anything */
     939             : 
     940           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
     941           0 :         return WERR_NOT_SUPPORTED;
     942             : }
     943             : 
     944             : /*******************************************************************
     945             :  _winreg_LoadKey
     946             :  ********************************************************************/
     947             : 
     948           0 : WERROR _winreg_LoadKey(struct pipes_struct *p,
     949             :                        struct winreg_LoadKey *r)
     950             : {
     951             :         /* fill in your code here if you think this call should
     952             :            do anything */
     953             : 
     954           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
     955           0 :         return WERR_NOT_SUPPORTED;
     956             : }
     957             : 
     958             : /*******************************************************************
     959             :  _winreg_NotifyChangeKeyValue
     960             :  ********************************************************************/
     961             : 
     962          12 : WERROR _winreg_NotifyChangeKeyValue(struct pipes_struct *p,
     963             :                                     struct winreg_NotifyChangeKeyValue *r)
     964             : {
     965          12 :         return WERR_NOT_SUPPORTED;
     966             : }
     967             : 
     968             : /*******************************************************************
     969             :  _winreg_QueryMultipleValues
     970             :  ********************************************************************/
     971             : 
     972           0 : WERROR _winreg_QueryMultipleValues(struct pipes_struct *p,
     973             :                                    struct winreg_QueryMultipleValues *r)
     974             : {
     975             :         struct winreg_QueryMultipleValues2 r2;
     976           0 :         uint32_t needed = 0;
     977             : 
     978           0 :         r2.in.key_handle        = r->in.key_handle;
     979           0 :         r2.in.values_in         = r->in.values_in;
     980           0 :         r2.in.num_values        = r->in.num_values;
     981           0 :         r2.in.offered           = r->in.buffer_size;
     982           0 :         r2.in.buffer            = r->in.buffer;
     983           0 :         r2.out.values_out       = r->out.values_out;
     984           0 :         r2.out.needed           = &needed;
     985           0 :         r2.out.buffer           = r->out.buffer;
     986             : 
     987           0 :         return _winreg_QueryMultipleValues2(p, &r2);
     988             : }
     989             : 
     990             : /*******************************************************************
     991             :  ********************************************************************/
     992             : 
     993           0 : static WERROR construct_multiple_entry(TALLOC_CTX *mem_ctx,
     994             :                                        const char *valuename,
     995             :                                        uint32_t value_length,
     996             :                                        uint32_t offset,
     997             :                                        enum winreg_Type type,
     998             :                                        struct QueryMultipleValue *r)
     999             : {
    1000           0 :         r->ve_valuename = talloc_zero(mem_ctx, struct winreg_ValNameBuf);
    1001           0 :         if (r->ve_valuename == NULL) {
    1002           0 :                 return WERR_NOT_ENOUGH_MEMORY;
    1003             :         }
    1004             : 
    1005           0 :         r->ve_valuename->name = talloc_strdup(r->ve_valuename, valuename ? valuename : "");
    1006           0 :         if (r->ve_valuename->name == NULL) {
    1007           0 :                 return WERR_NOT_ENOUGH_MEMORY;
    1008             :         }
    1009             : 
    1010           0 :         r->ve_valuename->size = strlen_m_term(r->ve_valuename->name)*2;
    1011           0 :         r->ve_valuelen = value_length;
    1012           0 :         r->ve_valueptr = offset;
    1013           0 :         r->ve_type = type;
    1014             : 
    1015           0 :         return WERR_OK;
    1016             : }
    1017             : 
    1018             : /*******************************************************************
    1019             :  _winreg_QueryMultipleValues2
    1020             :  ********************************************************************/
    1021             : 
    1022           0 : WERROR _winreg_QueryMultipleValues2(struct pipes_struct *p,
    1023             :                                     struct winreg_QueryMultipleValues2 *r)
    1024             : {
    1025           0 :         struct registry_key *regkey = find_regkey_by_hnd(p,
    1026             :                                                          r->in.key_handle,
    1027             :                                                          HTYPE_REGKEY);
    1028           0 :         struct registry_value *vals = NULL;
    1029           0 :         const char **names = NULL;
    1030           0 :         uint32_t offset = 0, num_vals = 0;
    1031           0 :         DATA_BLOB result = data_blob_null;
    1032           0 :         uint32_t i = 0;
    1033           0 :         WERROR err = WERR_OK;
    1034             : 
    1035           0 :         if (!regkey) {
    1036           0 :                 return WERR_INVALID_HANDLE;
    1037             :         }
    1038             : 
    1039           0 :         names = talloc_zero_array(p->mem_ctx, const char *, r->in.num_values);
    1040           0 :         if (names == NULL) {
    1041           0 :                 return WERR_NOT_ENOUGH_MEMORY;
    1042             :         }
    1043             : 
    1044           0 :         for (i=0; i < r->in.num_values; i++) {
    1045           0 :                 if (r->in.values_in[i].ve_valuename &&
    1046           0 :                     r->in.values_in[i].ve_valuename->name) {
    1047           0 :                         names[i] = talloc_strdup(names,
    1048           0 :                                 r->in.values_in[i].ve_valuename->name);
    1049           0 :                         if (names[i] == NULL) {
    1050           0 :                                 return WERR_NOT_ENOUGH_MEMORY;
    1051             :                         }
    1052             :                 }
    1053             :         }
    1054             : 
    1055           0 :         err = reg_querymultiplevalues(p->mem_ctx, regkey,
    1056             :                                       r->in.num_values, names,
    1057             :                                       &num_vals, &vals);
    1058           0 :         if (!W_ERROR_IS_OK(err)) {
    1059           0 :                 return err;
    1060             :         }
    1061             : 
    1062           0 :         result = data_blob_talloc(p->mem_ctx, NULL, 0);
    1063             : 
    1064           0 :         for (i=0; i < r->in.num_values; i++) {
    1065           0 :                 const char *valuename = NULL;
    1066             : 
    1067           0 :                 if (vals[i].data.length > 0) {
    1068           0 :                         if (!data_blob_append(p->mem_ctx, &result,
    1069           0 :                                               vals[i].data.data,
    1070           0 :                                               vals[i].data.length)) {
    1071           0 :                                 return WERR_NOT_ENOUGH_MEMORY;
    1072             :                         }
    1073             :                 }
    1074             : 
    1075           0 :                 if (r->in.values_in[i].ve_valuename &&
    1076           0 :                     r->in.values_in[i].ve_valuename->name) {
    1077           0 :                         valuename = r->in.values_in[i].ve_valuename->name;
    1078             :                 }
    1079             : 
    1080           0 :                 err = construct_multiple_entry(r->out.values_out,
    1081             :                                                valuename,
    1082           0 :                                                vals[i].data.length,
    1083             :                                                offset,
    1084           0 :                                                vals[i].type,
    1085           0 :                                                &r->out.values_out[i]);
    1086           0 :                 if (!W_ERROR_IS_OK(err)) {
    1087           0 :                         return err;
    1088             :                 }
    1089             : 
    1090           0 :                 offset += vals[i].data.length;
    1091             :         }
    1092             : 
    1093           0 :         *r->out.needed = result.length;
    1094             : 
    1095           0 :         if (r->in.num_values != num_vals) {
    1096           0 :                 return WERR_FILE_NOT_FOUND;
    1097             :         }
    1098             : 
    1099           0 :         if (*r->in.offered >= *r->out.needed) {
    1100           0 :                 if (r->out.buffer) {
    1101           0 :                         memcpy(r->out.buffer, result.data, MIN(result.length, *r->in.offered));
    1102             :                 }
    1103           0 :                 return WERR_OK;
    1104             :         } else {
    1105           0 :                 return WERR_MORE_DATA;
    1106             :         }
    1107             : }
    1108             : 
    1109             : /*******************************************************************
    1110             :  _winreg_DeleteKeyEx
    1111             :  ********************************************************************/
    1112             : 
    1113           0 : WERROR _winreg_DeleteKeyEx(struct pipes_struct *p,
    1114             :                            struct winreg_DeleteKeyEx *r)
    1115             : {
    1116             :         /* fill in your code here if you think this call should
    1117             :            do anything */
    1118             : 
    1119           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    1120           0 :         return WERR_NOT_SUPPORTED;
    1121             : }
    1122             : 
    1123             : /* include the generated boilerplate */
    1124             : #include "librpc/gen_ndr/ndr_winreg_scompat.c"

Generated by: LCOV version 1.13