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 690 : static int hnd_cnt_destructor(struct hnd_cnt *cnt)
65 : {
66 690 : num_handles--;
67 690 : return 0;
68 : }
69 :
70 696 : bool create_policy_hnd(struct pipes_struct *p,
71 : struct policy_handle *hnd,
72 : uint8_t handle_type,
73 : void *data_ptr)
74 : {
75 696 : struct dcesrv_handle *rpc_hnd = NULL;
76 696 : struct hnd_cnt *cnt = NULL;
77 :
78 696 : rpc_hnd = dcesrv_handle_create(p->dce_call, handle_type);
79 696 : if (rpc_hnd == NULL) {
80 0 : return false;
81 : }
82 :
83 696 : cnt = talloc_zero(rpc_hnd, struct hnd_cnt);
84 696 : if (cnt == NULL) {
85 0 : TALLOC_FREE(rpc_hnd);
86 0 : return false;
87 : }
88 696 : talloc_set_destructor(cnt, hnd_cnt_destructor);
89 :
90 696 : if (data_ptr != NULL) {
91 696 : rpc_hnd->data = talloc_move(rpc_hnd, &data_ptr);
92 : }
93 :
94 696 : *hnd = rpc_hnd->wire_handle;
95 :
96 696 : num_handles++;
97 :
98 696 : return true;
99 : }
100 :
101 : /****************************************************************************
102 : find policy by handle - internal version.
103 : ****************************************************************************/
104 :
105 3896 : 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 3896 : struct dcesrv_handle *h = NULL;
112 :
113 3896 : if (data_p) {
114 3455 : *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 3896 : if (ndr_policy_handle_empty(hnd)) {
122 0 : p->fault_state = DCERPC_FAULT_CONTEXT_MISMATCH;
123 0 : 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 3896 : h = dcesrv_handle_lookup(p->dce_call, hnd, DCESRV_HANDLE_ANY);
131 3896 : if (h == NULL) {
132 0 : p->fault_state = DCERPC_FAULT_CONTEXT_MISMATCH;
133 0 : return NULL;
134 : }
135 :
136 6306 : if (handle_type != DCESRV_HANDLE_ANY &&
137 3430 : 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 3896 : if (data_p) {
144 3455 : *data_p = h->data;
145 : }
146 :
147 3896 : return h;
148 : }
149 :
150 : /****************************************************************************
151 : find policy by handle
152 : ****************************************************************************/
153 :
154 3455 : 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 3455 : struct dcesrv_handle *rpc_hnd = NULL;
160 3455 : void *data = NULL;
161 :
162 3455 : rpc_hnd = find_policy_by_hnd_internal(p, hnd, handle_type, &data);
163 3455 : if (rpc_hnd == NULL) {
164 0 : *pstatus = NT_STATUS_INVALID_HANDLE;
165 0 : return NULL;
166 : }
167 :
168 3455 : *pstatus = NT_STATUS_OK;
169 3455 : return data;
170 : }
171 :
172 : /****************************************************************************
173 : Close a policy.
174 : ****************************************************************************/
175 :
176 441 : bool close_policy_hnd(struct pipes_struct *p,
177 : struct policy_handle *hnd)
178 : {
179 441 : struct dcesrv_handle *rpc_hnd = NULL;
180 :
181 441 : rpc_hnd = find_policy_by_hnd_internal(p, hnd, DCESRV_HANDLE_ANY, NULL);
182 441 : if (rpc_hnd == NULL) {
183 0 : DEBUG(3, ("Error closing policy (policy not found)\n"));
184 0 : return false;
185 : }
186 :
187 441 : TALLOC_FREE(rpc_hnd);
188 :
189 441 : 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 98 : 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 98 : 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 : 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 98 : return True;
233 : }
|