2 Unix SMB/CIFS implementation.
4 server side dcerpc handle code
6 Copyright (C) Andrew Tridgell 2003
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 "lib/util/dlinklist.h"
24 #include "rpc_server/dcerpc_server.h"
25 #include "libcli/security/security.h"
26 #include "librpc/gen_ndr/auth.h"
31 static int dcesrv_handle_destructor(struct dcesrv_handle
*h
)
33 DLIST_REMOVE(h
->assoc_group
->handles
, h
);
39 allocate a new rpc handle
42 struct dcesrv_handle
*dcesrv_handle_create(struct dcesrv_call_state
*call
,
45 struct dcesrv_connection_context
*context
= call
->context
;
46 struct auth_session_info
*session_info
=
47 dcesrv_call_session_info(call
);
48 struct dcesrv_handle
*h
;
52 * For simplicty, ensure we abort here for an interface that has no handles (programmer error)
54 SMB_ASSERT((context
->iface
->flags
& DCESRV_INTERFACE_FLAGS_HANDLES_NOT_USED
) == 0);
56 sid
= &session_info
->security_token
->sids
[PRIMARY_USER_SID_INDEX
];
58 h
= talloc_zero(context
->conn
->assoc_group
, struct dcesrv_handle
);
63 h
->sid
= dom_sid_dup(h
, sid
);
68 h
->min_auth_level
= call
->auth_state
->auth_level
;
69 h
->assoc_group
= context
->conn
->assoc_group
;
70 h
->iface
= context
->iface
;
71 h
->wire_handle
.handle_type
= handle_type
;
72 h
->wire_handle
.uuid
= GUID_random();
74 DLIST_ADD(context
->conn
->assoc_group
->handles
, h
);
76 talloc_set_destructor(h
, dcesrv_handle_destructor
);
82 find an internal handle given a wire handle. If the wire handle is NULL then
87 struct dcesrv_handle
*dcesrv_handle_lookup(struct dcesrv_call_state
*call
,
88 const struct policy_handle
*p
,
91 struct dcesrv_connection_context
*context
= call
->context
;
92 struct auth_session_info
*session_info
=
93 dcesrv_call_session_info(call
);
94 struct dcesrv_handle
*h
;
98 * For simplicty, ensure we abort here for an interface that has no handles (programmer error)
100 SMB_ASSERT((context
->iface
->flags
& DCESRV_INTERFACE_FLAGS_HANDLES_NOT_USED
) == 0);
102 sid
= &session_info
->security_token
->sids
[PRIMARY_USER_SID_INDEX
];
104 if (ndr_policy_handle_empty(p
)) {
105 /* TODO: we should probably return a NULL handle here */
106 return dcesrv_handle_create(call
, handle_type
);
109 for (h
=context
->conn
->assoc_group
->handles
; h
; h
=h
->next
) {
110 if (h
->wire_handle
.handle_type
== p
->handle_type
&&
111 GUID_equal(&p
->uuid
, &h
->wire_handle
.uuid
)) {
112 if (handle_type
!= DCESRV_HANDLE_ANY
&&
113 p
->handle_type
!= handle_type
) {
114 DEBUG(0,("client gave us the wrong handle type (%d should be %d)\n",
115 p
->handle_type
, handle_type
));
118 if (!dom_sid_equal(h
->sid
, sid
)) {
119 struct dom_sid_buf buf1
, buf2
;
120 DBG_ERR("Attempt to use invalid sid %s - %s\n",
121 dom_sid_str_buf(h
->sid
, &buf1
),
122 dom_sid_str_buf(sid
, &buf2
));
125 if (call
->auth_state
->auth_level
< h
->min_auth_level
) {
126 DEBUG(0,(__location__
": Attempt to use invalid auth_level %u < %u\n",
127 call
->auth_state
->auth_level
,
131 if (h
->iface
!= context
->iface
) {
132 DEBUG(0,(__location__
": Attempt to use invalid iface\n"));
142 struct dcesrv_iface_state
{
143 struct dcesrv_iface_state
*prev
, *next
;
144 struct dcesrv_assoc_group
*assoc
;
145 const struct dcesrv_interface
*iface
;
146 struct dom_sid owner
;
147 const struct dcesrv_connection
*conn
;
148 const struct dcesrv_auth
*auth
;
149 const struct dcesrv_connection_context
*pres
;
152 const char *location
;
155 static int dcesrv_iface_state_destructor(struct dcesrv_iface_state
*istate
)
157 DLIST_REMOVE(istate
->assoc
->iface_states
, istate
);
161 static void *dcesrv_iface_state_find(struct dcesrv_assoc_group
*assoc
,
162 const struct dcesrv_interface
*iface
,
163 const struct dom_sid
*owner
,
164 const struct dcesrv_connection
*conn
,
165 const struct dcesrv_auth
*auth
,
166 const struct dcesrv_connection_context
*pres
,
170 struct dcesrv_iface_state
*cur
= NULL
;
172 for (cur
= assoc
->iface_states
; cur
!= NULL
; cur
= cur
->next
) {
175 SMB_ASSERT(cur
->assoc
== assoc
);
177 if (cur
->ptr
== ptr
) {
181 if (cur
->iface
!= iface
) {
185 match
= dom_sid_equal(&cur
->owner
, owner
);
190 if (cur
->conn
!= conn
) {
194 if (cur
->auth
!= auth
) {
198 if (cur
->pres
!= pres
) {
202 if (cur
->magic
!= magic
) {
212 static NTSTATUS
dcesrv_iface_state_store(struct dcesrv_assoc_group
*assoc
,
213 const struct dcesrv_interface
*iface
,
214 const struct dom_sid
*owner
,
215 const struct dcesrv_connection
*conn
,
216 const struct dcesrv_auth
*auth
,
217 const struct dcesrv_connection_context
*pres
,
221 const char *location
)
223 struct dcesrv_iface_state
*istate
= NULL
;
226 optr
= dcesrv_iface_state_find(assoc
,
235 return NT_STATUS_OBJECTID_EXISTS
;
238 istate
= talloc_zero(ptr
, struct dcesrv_iface_state
);
239 if (istate
== NULL
) {
240 return NT_STATUS_NO_MEMORY
;
243 *istate
= (struct dcesrv_iface_state
) {
251 .location
= location
,
254 istate
->ptr
= talloc_steal(mem_ctx
, ptr
);
256 talloc_set_destructor(istate
, dcesrv_iface_state_destructor
);
258 DLIST_ADD_END(assoc
->iface_states
, istate
);
263 NTSTATUS
_dcesrv_iface_state_store_assoc(struct dcesrv_call_state
*call
,
266 const char *location
)
268 struct auth_session_info
*session_info
=
269 dcesrv_call_session_info(call
);
270 const struct dom_sid
*owner
=
271 &session_info
->security_token
->sids
[0];
274 status
= dcesrv_iface_state_store(call
->conn
->assoc_group
,
275 call
->context
->iface
,
281 call
->conn
->assoc_group
, /* mem_ctx */
284 if (!NT_STATUS_IS_OK(status
)) {
291 void *_dcesrv_iface_state_find_assoc(struct dcesrv_call_state
*call
, uint64_t magic
)
293 struct auth_session_info
*session_info
=
294 dcesrv_call_session_info(call
);
295 const struct dom_sid
*owner
=
296 &session_info
->security_token
->sids
[0];
299 ptr
= dcesrv_iface_state_find(call
->conn
->assoc_group
,
300 call
->context
->iface
,
314 NTSTATUS
_dcesrv_iface_state_store_conn(struct dcesrv_call_state
*call
,
317 const char *location
)
319 struct auth_session_info
*session_info
=
320 dcesrv_call_session_info(call
);
321 const struct dom_sid
*owner
=
322 &session_info
->security_token
->sids
[0];
325 status
= dcesrv_iface_state_store(call
->conn
->assoc_group
,
326 call
->context
->iface
,
332 call
->conn
, /* mem_ctx */
335 if (!NT_STATUS_IS_OK(status
)) {
342 void *_dcesrv_iface_state_find_conn(struct dcesrv_call_state
*call
, uint64_t magic
)
344 struct auth_session_info
*session_info
=
345 dcesrv_call_session_info(call
);
346 const struct dom_sid
*owner
=
347 &session_info
->security_token
->sids
[0];
350 ptr
= dcesrv_iface_state_find(call
->conn
->assoc_group
,
351 call
->context
->iface
,