#include "includes.h"
#include <tevent.h>
-#include "lib/socket/socket.h"
#include "smbd/service.h"
#include "param/param.h"
#include "auth/session.h"
#include "lib/stream/packet.h"
#include "librpc/gen_ndr/ndr_named_pipe_auth.h"
#include "system/passwd.h"
+#include "libcli/raw/smb.h"
+#include "auth/credentials/credentials.h"
+#include "auth/credentials/credentials_krb5.h"
struct named_pipe_socket {
const char *pipe_name;
TEVENT_FD_NOT_WRITEABLE(conn->event.fde);
+ packet_set_socket(pipe_conn->packet, NULL);
+ packet_set_event_context(pipe_conn->packet, NULL);
+ packet_set_fde(pipe_conn->packet, NULL);
+ TALLOC_FREE(pipe_conn->packet);
+
if (!NT_STATUS_IS_OK(pipe_conn->status)) {
stream_terminate_connection(conn, nt_errstr(pipe_conn->status));
return;
*/
conn->ops = pipe_conn->pipe_sock->ops;
conn->private_data = pipe_conn->pipe_sock->private_data;
- talloc_free(pipe_conn);
+ talloc_unlink(conn, pipe_conn);
/* we're now ready to start receiving events on this stream */
TEVENT_FD_READABLE(conn->event.fde);
DEBUG(10,("named_pipe_auth: req_blob.length[%u]\n",
(unsigned int)req_blob.length));
- dump_data(10, req_blob.data, req_blob.length);
+ dump_data(11, req_blob.data, req_blob.length);
/* parse the passed credentials */
ndr_err = ndr_pull_struct_blob_all(
goto reply;
}
+ if (DEBUGLVL(10)) {
+ NDR_PRINT_DEBUG(named_pipe_auth_req, &req);
+ }
+
if (strcmp(NAMED_PIPE_AUTH_MAGIC, req.magic) != 0) {
DEBUG(2, ("named_pipe_auth_req: invalid magic '%s' != %s\n",
req.magic, NAMED_PIPE_AUTH_MAGIC));
goto reply;
}
+ break;
+ case 2:
+ rep.level = 2;
+ rep.info.info2.file_type = FILE_TYPE_MESSAGE_MODE_PIPE;
+ rep.info.info2.device_state = 0xff | 0x0400 | 0x0100;
+ rep.info.info2.allocation_size = 4096;
+
+ if (!req.info.info2.sam_info3) {
+ /*
+ * anon connection, we don't create a session info
+ * and leave it NULL
+ */
+ rep.status = NT_STATUS_OK;
+ break;
+ }
+
+ val.sam3 = req.info.info2.sam_info3;
+
+ rep.status = make_server_info_netlogon_validation(pipe_conn,
+ val.sam3->base.account_name.string,
+ 3, &val, &server_info);
+ if (!NT_STATUS_IS_OK(rep.status)) {
+ DEBUG(2, ("make_server_info_netlogon_validation returned "
+ "%s\n", nt_errstr(rep.status)));
+ goto reply;
+ }
+
+ /* setup the session_info on the connection */
+ rep.status = auth_generate_session_info(conn,
+ conn->event.ctx,
+ conn->lp_ctx,
+ server_info,
+ &conn->session_info);
+ if (!NT_STATUS_IS_OK(rep.status)) {
+ DEBUG(2, ("auth_generate_session_info failed: %s\n",
+ nt_errstr(rep.status)));
+ goto reply;
+ }
+
+ conn->session_info->session_key = data_blob_const(req.info.info2.session_key,
+ req.info.info2.session_key_length);
+ talloc_steal(conn->session_info, req.info.info2.session_key);
+
+ break;
+ case 3:
+ rep.level = 3;
+ rep.info.info3.file_type = FILE_TYPE_MESSAGE_MODE_PIPE;
+ rep.info.info3.device_state = 0xff | 0x0400 | 0x0100;
+ rep.info.info3.allocation_size = 4096;
+
+ if (!req.info.info3.sam_info3) {
+ /*
+ * anon connection, we don't create a session info
+ * and leave it NULL
+ */
+ rep.status = NT_STATUS_OK;
+ break;
+ }
+
+ val.sam3 = req.info.info3.sam_info3;
+
+ rep.status = make_server_info_netlogon_validation(pipe_conn,
+ val.sam3->base.account_name.string,
+ 3, &val, &server_info);
+ if (!NT_STATUS_IS_OK(rep.status)) {
+ DEBUG(2, ("make_server_info_netlogon_validation returned "
+ "%s\n", nt_errstr(rep.status)));
+ goto reply;
+ }
+
+ /* setup the session_info on the connection */
+ rep.status = auth_generate_session_info(conn,
+ conn->event.ctx,
+ conn->lp_ctx,
+ server_info,
+ &conn->session_info);
+ if (!NT_STATUS_IS_OK(rep.status)) {
+ DEBUG(2, ("auth_generate_session_info failed: %s\n",
+ nt_errstr(rep.status)));
+ goto reply;
+ }
+
+ if (req.info.info3.gssapi_delegated_creds_length) {
+ OM_uint32 minor_status;
+ gss_buffer_desc cred_token;
+ gss_cred_id_t cred_handle;
+ int ret;
+
+ DEBUG(10, ("named_pipe_auth: delegated credentials supplied by client\n"));
+
+ cred_token.value = req.info.info3.gssapi_delegated_creds;
+ cred_token.length = req.info.info3.gssapi_delegated_creds_length;
+
+ ret = gss_import_cred(&minor_status,
+ &cred_token,
+ &cred_handle);
+ if (ret != GSS_S_COMPLETE) {
+ rep.status = NT_STATUS_INTERNAL_ERROR;
+ goto reply;
+ }
+
+ conn->session_info->credentials = cli_credentials_init(conn->session_info);
+ if (!conn->session_info->credentials) {
+ rep.status = NT_STATUS_NO_MEMORY;
+ goto reply;
+ }
+
+ cli_credentials_set_conf(conn->session_info->credentials,
+ conn->lp_ctx);
+ /* Just so we don't segfault trying to get at a username */
+ cli_credentials_set_anonymous(conn->session_info->credentials);
+
+ ret = cli_credentials_set_client_gss_creds(conn->session_info->credentials,
+ conn->event.ctx,
+ conn->lp_ctx,
+ cred_handle,
+ CRED_SPECIFIED);
+ if (ret) {
+ rep.status = NT_STATUS_INTERNAL_ERROR;
+ goto reply;
+ }
+
+ /* This credential handle isn't useful for password authentication, so ensure nobody tries to do that */
+ cli_credentials_set_kerberos_state(conn->session_info->credentials,
+ CRED_MUST_USE_KERBEROS);
+ }
+
+ conn->session_info->session_key = data_blob_const(req.info.info3.session_key,
+ req.info.info3.session_key_length);
+ talloc_steal(conn->session_info, req.info.info3.session_key);
+
break;
default:
DEBUG(2, ("named_pipe_auth_req: unknown level %u\n",
return status;
}
- pipe_conn->status = rep.status;
+ DEBUG(10,("named_pipe_auth reply[%u]\n", (unsigned)rep_blob.length));
+ dump_data(11, rep_blob.data, rep_blob.length);
+ if (DEBUGLVL(10)) {
+ NDR_PRINT_DEBUG(named_pipe_auth_rep, &rep);
+ }
- DEBUG(10,("named_pipe_auth reply[%u]\n", rep_blob.length));
- dump_data(10, rep_blob.data, rep_blob.length);
+ pipe_conn->status = rep.status;
status = packet_send_callback(pipe_conn->packet, rep_blob,
named_pipe_handover_connection,
pipe_conn);
if (!directory_create_or_exist(dirname, geteuid(), 0700)) {
status = map_nt_error_from_unix(errno);
+ DEBUG(0,(__location__ ": Failed to create stream pipe directory %s - %s\n",
+ dirname, nt_errstr(status)));
goto fail;
}