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.
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.
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.
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/>.
23 #include "system/passwd.h" /* uid_wrapper */
24 #include "../librpc/gen_ndr/ndr_lsa.h"
25 #include "../librpc/gen_ndr/ndr_samr.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"
34 #define DBGC_CLASS DBGC_RPC_SRV
36 static size_t num_handles
= 0;
38 bool check_open_pipes(void)
40 if (num_handles
> 0) {
47 size_t num_pipe_handles(void)
52 /****************************************************************************
53 find first available policy slot. creates a policy handle for you.
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 ****************************************************************************/
64 static int hnd_cnt_destructor(struct hnd_cnt
*cnt
)
70 bool create_policy_hnd(struct pipes_struct
*p
,
71 struct policy_handle
*hnd
,
75 struct dcesrv_handle
*rpc_hnd
= NULL
;
76 struct hnd_cnt
*cnt
= NULL
;
78 rpc_hnd
= dcesrv_handle_create(p
->dce_call
, handle_type
);
79 if (rpc_hnd
== NULL
) {
83 cnt
= talloc_zero(rpc_hnd
, struct hnd_cnt
);
88 talloc_set_destructor(cnt
, hnd_cnt_destructor
);
90 if (data_ptr
!= NULL
) {
91 rpc_hnd
->data
= talloc_move(rpc_hnd
, &data_ptr
);
94 *hnd
= rpc_hnd
->wire_handle
;
101 /****************************************************************************
102 find policy by handle - internal version.
103 ****************************************************************************/
105 static struct dcesrv_handle
*find_policy_by_hnd_internal(
106 struct pipes_struct
*p
,
107 const struct policy_handle
*hnd
,
111 struct dcesrv_handle
*h
= NULL
;
118 * Do not pass an empty policy_handle to dcesrv_handle_lookup() or
119 * it will create a new empty handle
121 if (ndr_policy_handle_empty(hnd
)) {
122 p
->fault_state
= DCERPC_FAULT_CONTEXT_MISMATCH
;
127 * Do not pass handle_type to avoid setting the fault_state in the
128 * pipes_struct if the handle type does not match
130 h
= dcesrv_handle_lookup(p
->dce_call
, hnd
, DCESRV_HANDLE_ANY
);
132 p
->fault_state
= DCERPC_FAULT_CONTEXT_MISMATCH
;
136 if (handle_type
!= DCESRV_HANDLE_ANY
&&
137 h
->wire_handle
.handle_type
!= handle_type
) {
138 /* Just return NULL, do not set a fault
139 * state in pipes_struct */
150 /****************************************************************************
151 find policy by handle
152 ****************************************************************************/
154 void *_find_policy_by_hnd(struct pipes_struct
*p
,
155 const struct policy_handle
*hnd
,
159 struct dcesrv_handle
*rpc_hnd
= NULL
;
162 rpc_hnd
= find_policy_by_hnd_internal(p
, hnd
, handle_type
, &data
);
163 if (rpc_hnd
== NULL
) {
164 *pstatus
= NT_STATUS_INVALID_HANDLE
;
168 *pstatus
= NT_STATUS_OK
;
172 /****************************************************************************
174 ****************************************************************************/
176 bool close_policy_hnd(struct pipes_struct
*p
,
177 struct policy_handle
*hnd
)
179 struct dcesrv_handle
*rpc_hnd
= NULL
;
181 rpc_hnd
= find_policy_by_hnd_internal(p
, hnd
, DCESRV_HANDLE_ANY
, NULL
);
182 if (rpc_hnd
== NULL
) {
183 DEBUG(3, ("Error closing policy (policy not found)\n"));
187 TALLOC_FREE(rpc_hnd
);
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 ********************************************************************/
200 bool pipe_access_check(struct pipes_struct
*p
)
202 /* Don't let anonymous users access this RPC if restrict
205 if (lp_restrict_anonymous() > 0) {
207 struct dcesrv_call_state
*dce_call
= p
->dce_call
;
208 struct dcesrv_auth
*auth_state
= dce_call
->auth_state
;
209 enum dcerpc_AuthType auth_type
= DCERPC_AUTH_TYPE_NONE
;
210 struct auth_session_info
*session_info
= NULL
;
211 enum security_user_level user_level
;
213 if (!auth_state
->auth_finished
) {
217 dcesrv_call_auth_info(dce_call
, &auth_type
, NULL
);
219 /* schannel, so we must be ok */
220 if (auth_type
== DCERPC_AUTH_TYPE_SCHANNEL
) {
224 session_info
= dcesrv_call_session_info(dce_call
);
225 user_level
= security_session_user_level(session_info
, NULL
);
227 if (user_level
< SECURITY_USER
) {