summaryrefslogtreecommitdiff
path: root/source4
diff options
context:
space:
mode:
Diffstat (limited to 'source4')
-rw-r--r--source4/auth/session.c147
-rw-r--r--source4/auth/session.h10
-rw-r--r--source4/ntvfs/ipc/vfs_ipc.c56
-rw-r--r--source4/smbd/service_named_pipe.c138
4 files changed, 177 insertions, 174 deletions
diff --git a/source4/auth/session.c b/source4/auth/session.c
index a6b8b2688c..cf5514cbf7 100644
--- a/source4/auth/session.c
+++ b/source4/auth/session.c
@@ -24,10 +24,14 @@
#include "includes.h"
#include "auth/auth.h"
#include "auth/auth_sam.h"
+#include "auth/credentials/credentials.h"
+#include "auth/credentials/credentials_krb5.h"
#include "libcli/security/security.h"
#include "libcli/auth/libcli_auth.h"
#include "dsdb/samdb/samdb.h"
#include "auth/session_proto.h"
+#include "system/kerberos.h"
+#include <gssapi/gssapi.h>
_PUBLIC_ struct auth_session_info *anonymous_session(TALLOC_CTX *mem_ctx,
struct loadparm_context *lp_ctx)
@@ -151,6 +155,149 @@ _PUBLIC_ NTSTATUS auth_generate_session_info(TALLOC_CTX *mem_ctx,
return NT_STATUS_OK;
}
+/* Create a session_info structure from the
+ * auth_session_info_transport we were forwarded over named pipe
+ * forwarding.
+ *
+ * NOTE: The stucture members of session_info_transport are stolen
+ * with talloc_move() into auth_session_info for long term use
+ */
+struct auth_session_info *auth_session_info_from_transport(TALLOC_CTX *mem_ctx,
+ struct auth_session_info_transport *session_info_transport,
+ struct loadparm_context *lp_ctx,
+ const char **reason)
+{
+ struct auth_session_info *session_info;
+ session_info = talloc_zero(mem_ctx, struct auth_session_info);
+ if (!session_info) {
+ *reason = "failed to allocate session_info";
+ return NULL;
+ }
+
+ session_info->security_token = talloc_move(session_info, &session_info_transport->security_token);
+ session_info->info = talloc_move(session_info, &session_info_transport->info);
+ session_info->session_key = session_info_transport->session_key;
+ session_info->session_key.data = talloc_move(session_info, &session_info_transport->session_key.data);
+
+ if (session_info_transport->exported_gssapi_credentials.length) {
+ struct cli_credentials *creds;
+ OM_uint32 minor_status;
+ gss_buffer_desc cred_token;
+ gss_cred_id_t cred_handle;
+ const char *error_string;
+ int ret;
+
+ DEBUG(10, ("Delegated credentials supplied by client\n"));
+
+ cred_token.value = session_info_transport->exported_gssapi_credentials.data;
+ cred_token.length = session_info_transport->exported_gssapi_credentials.length;
+
+ ret = gss_import_cred(&minor_status,
+ &cred_token,
+ &cred_handle);
+ if (ret != GSS_S_COMPLETE) {
+ *reason = "Internal error in gss_import_cred()";
+ return NULL;
+ }
+
+ creds = cli_credentials_init(session_info);
+ if (!creds) {
+ *reason = "Out of memory in cli_credentials_init()";
+ return NULL;
+ }
+ session_info->credentials = creds;
+
+ cli_credentials_set_conf(creds, lp_ctx);
+ /* Just so we don't segfault trying to get at a username */
+ cli_credentials_set_anonymous(creds);
+
+ ret = cli_credentials_set_client_gss_creds(creds,
+ lp_ctx,
+ cred_handle,
+ CRED_SPECIFIED,
+ &error_string);
+ if (ret) {
+ *reason = talloc_asprintf(mem_ctx,
+ "Failed to set pipe forwarded"
+ "creds: %s\n", error_string);
+ return NULL;
+ }
+
+ /* This credential handle isn't useful for password
+ * authentication, so ensure nobody tries to do that */
+ cli_credentials_set_kerberos_state(creds,
+ CRED_MUST_USE_KERBEROS);
+
+ }
+
+ return session_info;
+}
+
+
+/* Create a auth_session_info_transport from an auth_session_info.
+ *
+ * NOTE: Members of the auth_session_info_transport structure are not talloc_referenced, but simply assigned. They are only valid for the lifetime of the struct auth_session_info
+ *
+ * This isn't normally an issue, as the auth_session_info has a very long typical life
+ */
+NTSTATUS auth_session_info_transport_from_session(TALLOC_CTX *mem_ctx,
+ struct auth_session_info *session_info,
+ struct tevent_context *event_ctx,
+ struct loadparm_context *lp_ctx,
+ struct auth_session_info_transport **transport_out)
+{
+
+ struct auth_session_info_transport *session_info_transport = talloc_zero(mem_ctx, struct auth_session_info_transport);
+ session_info_transport->security_token = talloc_reference(session_info, session_info->security_token);
+ NT_STATUS_HAVE_NO_MEMORY(session_info_transport->security_token);
+
+ session_info_transport->info = talloc_reference(session_info, session_info->info);
+ NT_STATUS_HAVE_NO_MEMORY(session_info_transport->info);
+
+ session_info_transport->session_key = session_info->session_key;
+ session_info_transport->session_key.data = talloc_reference(session_info, session_info->session_key.data);
+ if (!session_info_transport->session_key.data && session_info->session_key.length) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ if (session_info->credentials) {
+ struct gssapi_creds_container *gcc;
+ OM_uint32 gret;
+ OM_uint32 minor_status;
+ gss_buffer_desc cred_token;
+ const char *error_string;
+ int ret;
+
+ ret = cli_credentials_get_client_gss_creds(session_info->credentials,
+ event_ctx,
+ lp_ctx,
+ &gcc, &error_string);
+ if (ret != 0) {
+ *transport_out = session_info_transport;
+ return NT_STATUS_OK;
+ }
+
+ gret = gss_export_cred(&minor_status,
+ gcc->creds,
+ &cred_token);
+ if (gret != GSS_S_COMPLETE) {
+ return NT_STATUS_INTERNAL_ERROR;
+ }
+
+ if (cred_token.length) {
+ session_info_transport->exported_gssapi_credentials
+ = data_blob_talloc(session_info_transport,
+ cred_token.value,
+ cred_token.length);
+ gss_release_buffer(&minor_status, &cred_token);
+ NT_STATUS_HAVE_NO_MEMORY(session_info_transport->exported_gssapi_credentials.data);
+ }
+ }
+ *transport_out = session_info_transport;
+ return NT_STATUS_OK;
+}
+
+
/* Produce a session_info for an arbitary DN or principal in the local
* DB, assuming the local DB holds all the groups
*
diff --git a/source4/auth/session.h b/source4/auth/session.h
index d8c00a39a4..795497ea8f 100644
--- a/source4/auth/session.h
+++ b/source4/auth/session.h
@@ -52,6 +52,16 @@ NTSTATUS auth_generate_session_info(TALLOC_CTX *mem_ctx,
NTSTATUS auth_anonymous_session_info(TALLOC_CTX *parent_ctx,
struct loadparm_context *lp_ctx,
struct auth_session_info **session_info);
+struct auth_session_info *auth_session_info_from_transport(TALLOC_CTX *mem_ctx,
+ struct auth_session_info_transport *session_info_transport,
+ struct loadparm_context *lp_ctx,
+ const char **reason);
+NTSTATUS auth_session_info_transport_from_session(TALLOC_CTX *mem_ctx,
+ struct auth_session_info *session_info,
+ struct tevent_context *event_ctx,
+ struct loadparm_context *lp_ctx,
+ struct auth_session_info_transport **transport_out);
+
/* Produce a session_info for an arbitary DN or principal in the local
* DB, assuming the local DB holds all the groups
*
diff --git a/source4/ntvfs/ipc/vfs_ipc.c b/source4/ntvfs/ipc/vfs_ipc.c
index 19127a29bc..185e72cfb0 100644
--- a/source4/ntvfs/ipc/vfs_ipc.c
+++ b/source4/ntvfs/ipc/vfs_ipc.c
@@ -217,7 +217,7 @@ struct ipc_open_state {
struct pipe_state *p;
struct ntvfs_request *req;
union smb_open *oi;
- struct netr_SamInfo3 *info3;
+ struct auth_session_info_transport *session_info_transport;
};
static void ipc_open_done(struct tevent_req *subreq);
@@ -253,9 +253,6 @@ static NTSTATUS ipc_open(struct ntvfs_module_context *ntvfs,
const char *directory;
const struct tsocket_address *client_addr;
const struct tsocket_address *server_addr;
- int ret;
- DATA_BLOB delegated_creds = data_blob_null;
- struct auth_user_info_dc user_info_dc;
switch (oi->generic.level) {
case RAW_OPEN_NTCREATEX:
@@ -310,54 +307,17 @@ static NTSTATUS ipc_open(struct ntvfs_module_context *ntvfs,
state->req = req;
state->oi = oi;
- /* Disgusting hack to recreate the user_info_dc that should
- * not be used that this layer in this way */
- ZERO_STRUCT(user_info_dc);
- user_info_dc.info = req->session_info->info;
- user_info_dc.num_sids = req->session_info->torture->num_dc_sids;
- user_info_dc.sids = req->session_info->torture->dc_sids;
+ status = auth_session_info_transport_from_session(state,
+ req->session_info,
+ ipriv->ntvfs->ctx->event_ctx,
+ ipriv->ntvfs->ctx->lp_ctx,
+ &state->session_info_transport);
- status = auth_convert_user_info_dc_saminfo3(state,
- &user_info_dc,
- &state->info3);
NT_STATUS_NOT_OK_RETURN(status);
client_addr = ntvfs_get_local_address(ipriv->ntvfs);
server_addr = ntvfs_get_remote_address(ipriv->ntvfs);
- if (req->session_info->credentials) {
- struct gssapi_creds_container *gcc;
- OM_uint32 gret;
- OM_uint32 minor_status;
- gss_buffer_desc cred_token;
- const char *error_string;
-
- ret = cli_credentials_get_client_gss_creds(req->session_info->credentials,
- ipriv->ntvfs->ctx->event_ctx,
- ipriv->ntvfs->ctx->lp_ctx,
- &gcc, &error_string);
- if (ret) {
- goto skip;
- }
-
- gret = gss_export_cred(&minor_status,
- gcc->creds,
- &cred_token);
- if (gret != GSS_S_COMPLETE) {
- return NT_STATUS_INTERNAL_ERROR;
- }
-
- if (cred_token.length) {
- delegated_creds = data_blob_talloc(req,
- cred_token.value,
- cred_token.length);
- gss_release_buffer(&minor_status, &cred_token);
- NT_STATUS_HAVE_NO_MEMORY(delegated_creds.data);
- }
- }
-
-skip:
-
subreq = tstream_npa_connect_send(p,
ipriv->ntvfs->ctx->event_ctx,
directory,
@@ -366,9 +326,7 @@ skip:
NULL,
server_addr,
NULL,
- state->info3,
- req->session_info->session_key,
- delegated_creds);
+ state->session_info_transport);
NT_STATUS_HAVE_NO_MEMORY(subreq);
tevent_req_set_callback(subreq, ipc_open_done, state);
diff --git a/source4/smbd/service_named_pipe.c b/source4/smbd/service_named_pipe.c
index 148d4fdf80..086a037b69 100644
--- a/source4/smbd/service_named_pipe.c
+++ b/source4/smbd/service_named_pipe.c
@@ -33,8 +33,7 @@
#include "system/passwd.h"
#include "system/network.h"
#include "libcli/raw/smb.h"
-#include "auth/credentials/credentials.h"
-#include "auth/credentials/credentials_krb5.h"
+#include "auth/session.h"
#include "libcli/security/security.h"
#include "libcli/named_pipe_auth/npa_tstream.h"
@@ -93,18 +92,9 @@ static void named_pipe_accept_done(struct tevent_req *subreq)
char *client_name;
struct tsocket_address *server;
char *server_name;
- struct netr_SamInfo3 *info3;
- DATA_BLOB session_key;
- DATA_BLOB delegated_creds;
-
- union netr_Validation val;
- struct auth_user_info_dc *user_info_dc;
- struct auth_context *auth_context;
- uint32_t session_flags = 0;
- struct dom_sid *anonymous_sid;
+ struct auth_session_info_transport *session_info_transport;
const char *reason = NULL;
TALLOC_CTX *tmp_ctx;
- NTSTATUS status;
int error;
int ret;
@@ -115,14 +105,12 @@ static void named_pipe_accept_done(struct tevent_req *subreq)
}
ret = tstream_npa_accept_existing_recv(subreq, &error, tmp_ctx,
- &conn->tstream,
- &client,
- &client_name,
- &server,
- &server_name,
- &info3,
- &session_key,
- &delegated_creds);
+ &conn->tstream,
+ &client,
+ &client_name,
+ &server,
+ &server_name,
+ &session_info_transport);
TALLOC_FREE(subreq);
if (ret != 0) {
reason = talloc_asprintf(conn,
@@ -137,111 +125,11 @@ static void named_pipe_accept_done(struct tevent_req *subreq)
client_name, tsocket_address_string(client, tmp_ctx),
server_name, tsocket_address_string(server, tmp_ctx)));
- if (info3) {
- val.sam3 = info3;
-
- status = make_user_info_dc_netlogon_validation(conn,
- val.sam3->base.account_name.string,
- 3, &val, &user_info_dc);
- if (!NT_STATUS_IS_OK(status)) {
- reason = talloc_asprintf(conn,
- "make_user_info_dc_netlogon_validation "
- "returned: %s", nt_errstr(status));
- goto out;
- }
-
- status = auth_context_create(conn, conn->event.ctx,
- conn->msg_ctx, conn->lp_ctx,
- &auth_context);
- if (!NT_STATUS_IS_OK(status)) {
- reason = talloc_asprintf(conn,
- "auth_context_create returned: %s",
- nt_errstr(status));
- goto out;
- }
-
- anonymous_sid = dom_sid_parse_talloc(auth_context,
- SID_NT_ANONYMOUS);
- if (anonymous_sid == NULL) {
- talloc_free(auth_context);
- reason = "Failed to parse Anonymous SID ";
- goto out;
- }
-
- session_flags = AUTH_SESSION_INFO_DEFAULT_GROUPS;
- if (user_info_dc->num_sids > 1 && !dom_sid_equal(anonymous_sid, &user_info_dc->sids[0])) {
- session_flags |= AUTH_SESSION_INFO_AUTHENTICATED;
- }
-
-
- /* setup the session_info on the connection */
- status = auth_context->generate_session_info(conn,
- auth_context,
- user_info_dc,
- session_flags,
- &conn->session_info);
- talloc_free(auth_context);
- if (!NT_STATUS_IS_OK(status)) {
- reason = talloc_asprintf(conn,
- "auth_generate_session_info "
- "returned: %s", nt_errstr(status));
- goto out;
- }
- }
-
- if (session_key.length) {
- conn->session_info->session_key = session_key;
- talloc_steal(conn->session_info, session_key.data);
- }
-
- if (delegated_creds.length) {
- struct cli_credentials *creds;
- OM_uint32 minor_status;
- gss_buffer_desc cred_token;
- gss_cred_id_t cred_handle;
- const char *error_string;
-
- DEBUG(10, ("Delegated credentials supplied by client\n"));
-
- cred_token.value = delegated_creds.data;
- cred_token.length = delegated_creds.length;
-
- ret = gss_import_cred(&minor_status,
- &cred_token,
- &cred_handle);
- if (ret != GSS_S_COMPLETE) {
- reason = "Internal error in gss_import_cred()";
- goto out;
- }
-
- creds = cli_credentials_init(conn->session_info);
- if (!creds) {
- reason = "Out of memory in cli_credentials_init()";
- goto out;
- }
- conn->session_info->credentials = creds;
-
- cli_credentials_set_conf(creds, conn->lp_ctx);
- /* Just so we don't segfault trying to get at a username */
- cli_credentials_set_anonymous(creds);
-
- ret = cli_credentials_set_client_gss_creds(creds,
- conn->lp_ctx,
- cred_handle,
- CRED_SPECIFIED,
- &error_string);
- if (ret) {
- reason = talloc_asprintf(conn,
- "Failed to set pipe forwarded"
- "creds: %s\n", error_string);
- goto out;
- }
-
- /* This credential handle isn't useful for password
- * authentication, so ensure nobody tries to do that */
- cli_credentials_set_kerberos_state(creds,
- CRED_MUST_USE_KERBEROS);
-
+ conn->session_info = auth_session_info_from_transport(conn, session_info_transport,
+ conn->lp_ctx,
+ &reason);
+ if (!conn->session_info) {
+ goto out;
}
/*