LCOV - code coverage report
Current view: top level - source3/rpc_server - rpc_handles.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 50 76 65.8 %
Date: 2024-04-21 15:09:00 Functions: 6 8 75.0 %

          Line data    Source code
       1             : /* 
       2             :  *  Unix SMB/CIFS implementation.
       3             :  *  RPC Pipe client / server routines
       4             :  *  Copyright (C) Andrew Tridgell              1992-1997,
       5             :  *  Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
       6             :  *  Copyright (C) Jeremy Allison                           2001.
       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 "system/passwd.h" /* uid_wrapper */
      24             : #include "../librpc/gen_ndr/ndr_lsa.h"
      25             : #include "../librpc/gen_ndr/ndr_samr.h"
      26             : #include "auth.h"
      27             : #include "rpc_server/rpc_pipes.h"
      28             : #include "../libcli/security/security.h"
      29             : #include "lib/tsocket/tsocket.h"
      30             : #include "librpc/ndr/ndr_table.h"
      31             : #include "librpc/rpc/dcesrv_core.h"
      32             : 
      33             : #undef DBGC_CLASS
      34             : #define DBGC_CLASS DBGC_RPC_SRV
      35             : 
      36             : static size_t num_handles = 0;
      37             : 
      38           0 : bool check_open_pipes(void)
      39             : {
      40           0 :         if (num_handles > 0) {
      41           0 :                 return true;
      42             :         }
      43             : 
      44           0 :         return false;
      45             : }
      46             : 
      47           0 : size_t num_pipe_handles(void)
      48             : {
      49           0 :        return num_handles;
      50             : }
      51             : 
      52             : /****************************************************************************
      53             :   find first available policy slot.  creates a policy handle for you.
      54             : 
      55             :   If "data_ptr" is given, this must be a talloc'ed object, create_policy_hnd
      56             :   talloc_moves this into the handle. If the policy_hnd is closed,
      57             :   data_ptr is TALLOC_FREE()'ed
      58             : ****************************************************************************/
      59             : 
      60             : struct hnd_cnt {
      61             :         bool _dummy;
      62             : };
      63             : 
      64       98705 : static int hnd_cnt_destructor(struct hnd_cnt *cnt)
      65             : {
      66       98705 :         num_handles--;
      67       98705 :         return 0;
      68             : }
      69             : 
      70       98705 : void *create_policy_hnd(struct pipes_struct *p,
      71             :                         struct policy_handle *hnd,
      72             :                         uint8_t handle_type,
      73             :                         void *data_ptr)
      74             : {
      75       98705 :         struct dcesrv_handle *rpc_hnd = NULL;
      76       98705 :         struct hnd_cnt *cnt = NULL;
      77             : 
      78       98705 :         rpc_hnd = dcesrv_handle_create(p->dce_call, handle_type);
      79       98705 :         if (rpc_hnd == NULL) {
      80           0 :                 return NULL;
      81             :         }
      82             : 
      83       98705 :         cnt = talloc_zero(rpc_hnd, struct hnd_cnt);
      84       98705 :         if (cnt == NULL) {
      85           0 :                 TALLOC_FREE(rpc_hnd);
      86           0 :                 return NULL;
      87             :         }
      88       98705 :         talloc_set_destructor(cnt, hnd_cnt_destructor);
      89             : 
      90       98705 :         if (data_ptr != NULL) {
      91       98705 :                 rpc_hnd->data = talloc_move(rpc_hnd, &data_ptr);
      92             :         }
      93             : 
      94       98705 :         *hnd = rpc_hnd->wire_handle;
      95             : 
      96       98705 :         num_handles++;
      97             : 
      98       98705 :         return rpc_hnd;
      99             : }
     100             : 
     101             : /****************************************************************************
     102             :   find policy by handle - internal version.
     103             : ****************************************************************************/
     104             : 
     105      651700 : static struct dcesrv_handle *find_policy_by_hnd_internal(
     106             :                                         struct pipes_struct *p,
     107             :                                         const struct policy_handle *hnd,
     108             :                                         uint8_t handle_type,
     109             :                                         void **data_p)
     110             : {
     111      651700 :         struct dcesrv_handle *h = NULL;
     112             : 
     113      651700 :         if (data_p) {
     114      555023 :                 *data_p = NULL;
     115             :         }
     116             : 
     117             :         /*
     118             :          * Do not pass an empty policy_handle to dcesrv_handle_lookup() or
     119             :          * it will create a new empty handle
     120             :          */
     121      651700 :         if (ndr_policy_handle_empty(hnd)) {
     122          50 :                 p->fault_state = DCERPC_FAULT_CONTEXT_MISMATCH;
     123          50 :                 return NULL;
     124             :         }
     125             : 
     126             :         /*
     127             :          * Do not pass handle_type to avoid setting the fault_state in the
     128             :          * pipes_struct if the handle type does not match
     129             :          */
     130      651650 :         h = dcesrv_handle_lookup(p->dce_call, hnd, DCESRV_HANDLE_ANY);
     131      651650 :         if (h == NULL) {
     132          10 :                 p->fault_state = DCERPC_FAULT_CONTEXT_MISMATCH;
     133          10 :                 return NULL;
     134             :         }
     135             : 
     136      651640 :         if (handle_type != DCESRV_HANDLE_ANY &&
     137      501719 :             h->wire_handle.handle_type != handle_type) {
     138             :                 /* Just return NULL, do not set a fault
     139             :                  * state in pipes_struct */
     140           0 :                 return NULL;
     141             :         }
     142             : 
     143      651640 :         if (data_p) {
     144      554963 :                 *data_p = h->data;
     145             :         }
     146             : 
     147      651640 :         return h;
     148             : }
     149             : 
     150             : /****************************************************************************
     151             :   find policy by handle
     152             : ****************************************************************************/
     153             : 
     154      555023 : void *_find_policy_by_hnd(struct pipes_struct *p,
     155             :                           const struct policy_handle *hnd,
     156             :                           uint8_t handle_type,
     157             :                           NTSTATUS *pstatus)
     158             : {
     159      555023 :         struct dcesrv_handle *rpc_hnd = NULL;
     160      555023 :         void *data = NULL;
     161             : 
     162      555023 :         rpc_hnd = find_policy_by_hnd_internal(p, hnd, handle_type, &data);
     163      555023 :         if (rpc_hnd == NULL) {
     164          60 :                 *pstatus = NT_STATUS_INVALID_HANDLE;
     165          60 :                 return NULL;
     166             :         }
     167             : 
     168      554963 :         *pstatus = NT_STATUS_OK;
     169      554963 :         return data;
     170             : }
     171             : 
     172             : /****************************************************************************
     173             :   Close a policy.
     174             : ****************************************************************************/
     175             : 
     176       96677 : bool close_policy_hnd(struct pipes_struct *p,
     177             :                       struct policy_handle *hnd)
     178             : {
     179       96677 :         struct dcesrv_handle *rpc_hnd = NULL;
     180             : 
     181       96677 :         rpc_hnd = find_policy_by_hnd_internal(p, hnd, DCESRV_HANDLE_ANY, NULL);
     182       96677 :         if (rpc_hnd == NULL) {
     183           0 :                 DEBUG(3, ("Error closing policy (policy not found)\n"));
     184           0 :                 return false;
     185             :         }
     186             : 
     187       96677 :         TALLOC_FREE(rpc_hnd);
     188             : 
     189       96677 :         return true;
     190             : }
     191             : 
     192             : /*******************************************************************
     193             : Shall we allow access to this rpc?  Currently this function
     194             : implements the 'restrict anonymous' setting by denying access to
     195             : anonymous users if the restrict anonymous level is > 0.  Further work
     196             : will be checking a security descriptor to determine whether a user
     197             : token has enough access to access the pipe.
     198             : ********************************************************************/
     199             : 
     200         890 : bool pipe_access_check(struct pipes_struct *p)
     201             : {
     202             :         /* Don't let anonymous users access this RPC if restrict
     203             :            anonymous > 0 */
     204             : 
     205         890 :         if (lp_restrict_anonymous() > 0) {
     206             : 
     207           0 :                 struct dcesrv_call_state *dce_call = p->dce_call;
     208           0 :                 struct dcesrv_auth *auth_state = dce_call->auth_state;
     209           0 :                 enum dcerpc_AuthType auth_type = DCERPC_AUTH_TYPE_NONE;
     210           0 :                 struct auth_session_info *session_info = NULL;
     211           0 :                 enum security_user_level user_level;
     212             : 
     213           0 :                 if (!auth_state->auth_finished) {
     214           0 :                         return false;
     215             :                 }
     216             : 
     217           0 :                 dcesrv_call_auth_info(dce_call, &auth_type, NULL);
     218             : 
     219             :                 /* schannel, so we must be ok */
     220           0 :                 if (auth_type == DCERPC_AUTH_TYPE_SCHANNEL) {
     221           0 :                         return True;
     222             :                 }
     223             : 
     224           0 :                 session_info = dcesrv_call_session_info(dce_call);
     225           0 :                 user_level = security_session_user_level(session_info, NULL);
     226             : 
     227           0 :                 if (user_level < SECURITY_USER) {
     228           0 :                         return False;
     229             :                 }
     230             :         }
     231             : 
     232         890 :         return True;
     233             : }

Generated by: LCOV version 1.14