2 Unix SMB/CIFS implementation.
4 dcerpc ncalrpc as system operations
6 Copyright (C) 2014 Andreas Schneider <asn@samba.org>
7 Copyright (C) 2014 Stefan Metzmacher <metze@samba.org>
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>.
24 #include "auth/auth.h"
25 #include "auth/gensec/gensec.h"
26 #include "auth/gensec/gensec_internal.h"
27 #include "librpc/gen_ndr/dcerpc.h"
28 #include "lib/param/param.h"
31 _PUBLIC_ NTSTATUS
gensec_ncalrpc_as_system_init(void);
33 struct gensec_ncalrpc_state
{
41 struct auth_user_info_dc
*user_info_dc
;
44 static NTSTATUS
gensec_ncalrpc_client_start(struct gensec_security
*gensec_security
)
46 struct gensec_ncalrpc_state
*state
;
48 state
= talloc_zero(gensec_security
,
49 struct gensec_ncalrpc_state
);
51 return NT_STATUS_NO_MEMORY
;
53 gensec_security
->private_data
= state
;
55 state
->step
= GENSEC_NCALRPC_START
;
59 static NTSTATUS
gensec_ncalrpc_server_start(struct gensec_security
*gensec_security
)
61 struct gensec_ncalrpc_state
*state
;
63 state
= talloc_zero(gensec_security
,
64 struct gensec_ncalrpc_state
);
66 return NT_STATUS_NO_MEMORY
;
68 gensec_security
->private_data
= state
;
70 state
->step
= GENSEC_NCALRPC_START
;
74 static NTSTATUS
gensec_ncalrpc_update(struct gensec_security
*gensec_security
,
76 struct tevent_context
*ev
,
80 struct gensec_ncalrpc_state
*state
=
81 talloc_get_type_abort(gensec_security
->private_data
,
82 struct gensec_ncalrpc_state
);
83 DATA_BLOB magic_req
= data_blob_string_const("NCALRPC_AUTH_TOKEN");
84 DATA_BLOB magic_ok
= data_blob_string_const("NCALRPC_AUTH_OK");
85 DATA_BLOB magic_fail
= data_blob_string_const("NCALRPC_AUTH_FAIL");
86 char *unix_path
= NULL
;
90 *out
= data_blob_null
;
92 if (state
->step
>= GENSEC_NCALRPC_DONE
) {
93 return NT_STATUS_INVALID_PARAMETER
;
96 switch (gensec_security
->gensec_role
) {
98 switch (state
->step
) {
99 case GENSEC_NCALRPC_START
:
100 *out
= data_blob_dup_talloc(mem_ctx
, magic_req
);
101 if (out
->data
== NULL
) {
102 state
->step
= GENSEC_NCALRPC_ERROR
;
103 return NT_STATUS_NO_MEMORY
;
106 state
->step
= GENSEC_NCALRPC_MORE
;
107 return NT_STATUS_MORE_PROCESSING_REQUIRED
;
109 case GENSEC_NCALRPC_MORE
:
110 cmp
= data_blob_cmp(&in
, &magic_ok
);
112 state
->step
= GENSEC_NCALRPC_ERROR
;
113 return NT_STATUS_LOGON_FAILURE
;
116 state
->step
= GENSEC_NCALRPC_DONE
;
119 case GENSEC_NCALRPC_DONE
:
120 case GENSEC_NCALRPC_ERROR
:
124 state
->step
= GENSEC_NCALRPC_ERROR
;
125 return NT_STATUS_INTERNAL_ERROR
;
128 if (state
->step
!= GENSEC_NCALRPC_START
) {
129 state
->step
= GENSEC_NCALRPC_ERROR
;
130 return NT_STATUS_INTERNAL_ERROR
;
133 cmp
= data_blob_cmp(&in
, &magic_req
);
135 state
->step
= GENSEC_NCALRPC_ERROR
;
136 *out
= data_blob_dup_talloc(mem_ctx
, magic_fail
);
137 if (out
->data
== NULL
) {
138 return NT_STATUS_NO_MEMORY
;
140 return NT_STATUS_LOGON_FAILURE
;
143 if (gensec_security
->remote_addr
== NULL
) {
144 state
->step
= GENSEC_NCALRPC_ERROR
;
145 *out
= data_blob_dup_talloc(mem_ctx
, magic_fail
);
146 if (out
->data
== NULL
) {
147 return NT_STATUS_NO_MEMORY
;
149 return NT_STATUS_LOGON_FAILURE
;
152 unix_path
= tsocket_address_unix_path(gensec_security
->remote_addr
,
154 if (unix_path
== NULL
) {
155 state
->step
= GENSEC_NCALRPC_ERROR
;
156 *out
= data_blob_dup_talloc(mem_ctx
, magic_fail
);
157 if (out
->data
== NULL
) {
158 return NT_STATUS_NO_MEMORY
;
160 return NT_STATUS_LOGON_FAILURE
;
163 cmp
= strcmp(unix_path
, "/root/ncalrpc_as_system");
164 TALLOC_FREE(unix_path
);
166 state
->step
= GENSEC_NCALRPC_ERROR
;
167 *out
= data_blob_dup_talloc(mem_ctx
, magic_fail
);
168 if (out
->data
== NULL
) {
169 return NT_STATUS_NO_MEMORY
;
171 return NT_STATUS_LOGON_FAILURE
;
174 status
= auth_system_user_info_dc(state
,
175 lpcfg_netbios_name(gensec_security
->settings
->lp_ctx
),
176 &state
->user_info_dc
);
177 if (!NT_STATUS_IS_OK(status
)) {
178 state
->step
= GENSEC_NCALRPC_ERROR
;
179 *out
= data_blob_dup_talloc(mem_ctx
, magic_fail
);
180 if (out
->data
== NULL
) {
181 return NT_STATUS_NO_MEMORY
;
186 *out
= data_blob_dup_talloc(mem_ctx
, magic_ok
);
187 if (out
->data
== NULL
) {
188 state
->step
= GENSEC_NCALRPC_ERROR
;
189 return NT_STATUS_NO_MEMORY
;
192 state
->step
= GENSEC_NCALRPC_DONE
;
196 state
->step
= GENSEC_NCALRPC_ERROR
;
197 return NT_STATUS_INTERNAL_ERROR
;
200 static NTSTATUS
gensec_ncalrpc_session_info(struct gensec_security
*gensec_security
,
202 struct auth_session_info
**psession_info
)
204 struct gensec_ncalrpc_state
*state
=
205 talloc_get_type_abort(gensec_security
->private_data
,
206 struct gensec_ncalrpc_state
);
207 struct auth4_context
*auth_ctx
= gensec_security
->auth_context
;
208 struct auth_session_info
*session_info
= NULL
;
209 uint32_t session_info_flags
= 0;
212 if (gensec_security
->gensec_role
!= GENSEC_SERVER
) {
213 return NT_STATUS_INVALID_PARAMETER
;
216 if (state
->step
!= GENSEC_NCALRPC_DONE
) {
217 return NT_STATUS_INVALID_PARAMETER
;
220 if (auth_ctx
== NULL
) {
221 DEBUG(0, ("Cannot generate a session_info without the auth_context\n"));
222 return NT_STATUS_INTERNAL_ERROR
;
225 if (auth_ctx
->generate_session_info
== NULL
) {
226 DEBUG(0, ("Cannot generate a session_info without the generate_session_info hook\n"));
227 return NT_STATUS_INTERNAL_ERROR
;
230 if (gensec_security
->want_features
& GENSEC_FEATURE_UNIX_TOKEN
) {
231 session_info_flags
|= AUTH_SESSION_INFO_UNIX_TOKEN
;
234 session_info_flags
|= AUTH_SESSION_INFO_SIMPLE_PRIVILEGES
;
236 status
= auth_ctx
->generate_session_info(
240 state
->user_info_dc
->info
->account_name
,
243 if (!NT_STATUS_IS_OK(status
)) {
247 *psession_info
= session_info
;
251 /* We have no features */
252 static bool gensec_ncalrpc_have_feature(struct gensec_security
*gensec_security
,
255 if (feature
& GENSEC_FEATURE_DCE_STYLE
) {
262 static const struct gensec_security_ops gensec_ncalrpc_security_ops
= {
263 .name
= "naclrpc_as_system",
264 .auth_type
= DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM
,
265 .client_start
= gensec_ncalrpc_client_start
,
266 .server_start
= gensec_ncalrpc_server_start
,
267 .update
= gensec_ncalrpc_update
,
268 .session_info
= gensec_ncalrpc_session_info
,
269 .have_feature
= gensec_ncalrpc_have_feature
,
271 .priority
= GENSEC_EXTERNAL
,
274 _PUBLIC_ NTSTATUS
gensec_ncalrpc_as_system_init(void)
278 status
= gensec_register(&gensec_ncalrpc_security_ops
);
279 if (!NT_STATUS_IS_OK(status
)) {
280 DEBUG(0, ("Failed to register '%s' gensec backend!\n",
281 gensec_ncalrpc_security_ops
.name
));