summaryrefslogtreecommitdiff
path: root/source3
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2012-01-02 15:38:38 +1100
committerStefan Metzmacher <metze@samba.org>2012-01-18 16:23:22 +0100
commit0c1b4c232135ebdef58bb5e697dfc60ddbb358bc (patch)
tree7032ecc992927aa684e1cd38310b39ca05571a69 /source3
parent53cc9c6a3016b6ba95f280eb68600bdc21a6eed7 (diff)
downloadsamba-0c1b4c232135ebdef58bb5e697dfc60ddbb358bc.tar.gz
samba-0c1b4c232135ebdef58bb5e697dfc60ddbb358bc.tar.bz2
samba-0c1b4c232135ebdef58bb5e697dfc60ddbb358bc.zip
s3-librpc Call SPENGO/GSSAPI via the auth_generic layer and gensec
This simplifies a lot of code, as we know we are always dealing with a struct gensec_security, and allows the gensec module being used to implement GSSAPI to be swapped for AD-server operation. Andrew Bartlett Signed-off-by: Stefan Metzmacher <metze@samba.org>
Diffstat (limited to 'source3')
-rw-r--r--source3/librpc/crypto/cli_spnego.c98
-rw-r--r--source3/librpc/crypto/spnego.h14
-rw-r--r--source3/librpc/rpc/dcerpc_helpers.c27
-rw-r--r--source3/rpc_client/cli_pipe.c16
-rw-r--r--source3/rpc_server/dcesrv_spnego.c58
-rw-r--r--source3/rpc_server/srv_pipe.c71
6 files changed, 53 insertions, 231 deletions
diff --git a/source3/librpc/crypto/cli_spnego.c b/source3/librpc/crypto/cli_spnego.c
index 97e6a8152b..0a4bd18b22 100644
--- a/source3/librpc/crypto/cli_spnego.c
+++ b/source3/librpc/crypto/cli_spnego.c
@@ -46,44 +46,6 @@ static NTSTATUS spnego_context_init(TALLOC_CTX *mem_ctx,
return NT_STATUS_OK;
}
-NTSTATUS spnego_gssapi_init_client(TALLOC_CTX *mem_ctx,
- bool do_sign, bool do_seal,
- bool is_dcerpc,
- const char *ccache_name,
- const char *server,
- const char *service,
- const char *username,
- const char *password,
- struct spnego_context **spnego_ctx)
-{
- struct spnego_context *sp_ctx = NULL;
- uint32_t add_gss_c_flags = 0;
- NTSTATUS status;
-
- status = spnego_context_init(mem_ctx, do_sign, do_seal, &sp_ctx);
- if (!NT_STATUS_IS_OK(status)) {
- return status;
- }
- sp_ctx->mech = SPNEGO_KRB5;
-
- if (is_dcerpc) {
- add_gss_c_flags = GSS_C_DCE_STYLE;
- }
-
- status = gse_init_client(sp_ctx,
- do_sign, do_seal,
- ccache_name, server, service,
- username, password, add_gss_c_flags,
- &sp_ctx->mech_ctx.gssapi_state);
- if (!NT_STATUS_IS_OK(status)) {
- TALLOC_FREE(sp_ctx);
- return status;
- }
-
- *spnego_ctx = sp_ctx;
- return NT_STATUS_OK;
-}
-
NTSTATUS spnego_generic_init_client(TALLOC_CTX *mem_ctx,
const char *oid,
bool do_sign, bool do_seal,
@@ -181,7 +143,6 @@ NTSTATUS spnego_get_client_auth_token(TALLOC_CTX *mem_ctx,
DATA_BLOB *spnego_in,
DATA_BLOB *spnego_out)
{
- struct gse_context *gse_ctx;
struct gensec_security *gensec_security;
struct spnego_data sp_in, sp_out;
DATA_BLOB token_in = data_blob_null;
@@ -190,7 +151,6 @@ NTSTATUS spnego_get_client_auth_token(TALLOC_CTX *mem_ctx,
char *principal = NULL;
ssize_t len_in = 0;
ssize_t len_out = 0;
- bool mech_wants_more = false;
NTSTATUS status;
if (!spnego_in->length) {
@@ -228,33 +188,11 @@ NTSTATUS spnego_get_client_auth_token(TALLOC_CTX *mem_ctx,
switch (sp_ctx->mech) {
case SPNEGO_KRB5:
-
- gse_ctx = sp_ctx->mech_ctx.gssapi_state;
- status = gse_get_client_auth_token(mem_ctx, gse_ctx,
- &token_in, &token_out);
- if (!NT_STATUS_IS_OK(status)) {
- goto done;
- }
-
mech_oids[0] = OID_KERBEROS5;
- mech_wants_more = gse_require_more_processing(gse_ctx);
-
break;
case SPNEGO_NTLMSSP:
-
- gensec_security = sp_ctx->mech_ctx.gensec_security;
- status = gensec_update(gensec_security, mem_ctx, NULL,
- token_in, &token_out);
- if (NT_STATUS_EQUAL(status,
- NT_STATUS_MORE_PROCESSING_REQUIRED)) {
- mech_wants_more = true;
- } else if (!NT_STATUS_IS_OK(status)) {
- goto done;
- }
-
mech_oids[0] = OID_NTLMSSP;
-
break;
default:
@@ -262,6 +200,17 @@ NTSTATUS spnego_get_client_auth_token(TALLOC_CTX *mem_ctx,
goto done;
}
+ gensec_security = sp_ctx->mech_ctx.gensec_security;
+ status = gensec_update(gensec_security, mem_ctx, NULL,
+ token_in, &token_out);
+ sp_ctx->more_processing = false;
+ if (NT_STATUS_EQUAL(status,
+ NT_STATUS_MORE_PROCESSING_REQUIRED)) {
+ sp_ctx->more_processing = true;
+ } else if (!NT_STATUS_IS_OK(status)) {
+ goto done;
+ }
+
switch (sp_ctx->state) {
case SPNEGO_CONV_INIT:
*spnego_out = spnego_gen_negTokenInit(mem_ctx, mech_oids,
@@ -293,7 +242,7 @@ NTSTATUS spnego_get_client_auth_token(TALLOC_CTX *mem_ctx,
goto done;
}
- if (!mech_wants_more) {
+ if (!sp_ctx->more_processing) {
/* we still need to get an ack from the server */
sp_ctx->state = SPNEGO_CONV_AUTH_CONFIRM;
}
@@ -317,7 +266,6 @@ done:
bool spnego_require_more_processing(struct spnego_context *sp_ctx)
{
- struct gse_context *gse_ctx;
/* see if spnego processing itself requires more */
if (sp_ctx->state == SPNEGO_CONV_AUTH_MORE ||
@@ -328,10 +276,8 @@ bool spnego_require_more_processing(struct spnego_context *sp_ctx)
/* otherwise see if underlying mechnism does */
switch (sp_ctx->mech) {
case SPNEGO_KRB5:
- gse_ctx = sp_ctx->mech_ctx.gssapi_state;
- return gse_require_more_processing(gse_ctx);
case SPNEGO_NTLMSSP:
- return false;
+ return sp_ctx->more_processing;
default:
DEBUG(0, ("Unsupported type in request!\n"));
return false;
@@ -340,12 +286,10 @@ bool spnego_require_more_processing(struct spnego_context *sp_ctx)
NTSTATUS spnego_get_negotiated_mech(struct spnego_context *sp_ctx,
enum spnego_mech *type,
- void **auth_context)
+ struct gensec_security **auth_context)
{
switch (sp_ctx->mech) {
case SPNEGO_KRB5:
- *auth_context = sp_ctx->mech_ctx.gssapi_state;
- break;
case SPNEGO_NTLMSSP:
*auth_context = sp_ctx->mech_ctx.gensec_security;
break;
@@ -364,8 +308,6 @@ DATA_BLOB spnego_get_session_key(TALLOC_CTX *mem_ctx,
NTSTATUS status;
switch (sp_ctx->mech) {
case SPNEGO_KRB5:
- return gse_get_session_key(mem_ctx,
- sp_ctx->mech_ctx.gssapi_state);
case SPNEGO_NTLMSSP:
status = gensec_session_key(sp_ctx->mech_ctx.gensec_security, mem_ctx, &sk);
if (!NT_STATUS_IS_OK(status)) {
@@ -385,9 +327,6 @@ NTSTATUS spnego_sign(TALLOC_CTX *mem_ctx,
{
switch(sp_ctx->mech) {
case SPNEGO_KRB5:
- return gse_sign(mem_ctx,
- sp_ctx->mech_ctx.gssapi_state,
- data, signature);
case SPNEGO_NTLMSSP:
return gensec_sign_packet(
sp_ctx->mech_ctx.gensec_security,
@@ -407,9 +346,6 @@ NTSTATUS spnego_sigcheck(TALLOC_CTX *mem_ctx,
{
switch(sp_ctx->mech) {
case SPNEGO_KRB5:
- return gse_sigcheck(mem_ctx,
- sp_ctx->mech_ctx.gssapi_state,
- data, signature);
case SPNEGO_NTLMSSP:
return gensec_check_packet(
sp_ctx->mech_ctx.gensec_security,
@@ -428,9 +364,6 @@ NTSTATUS spnego_seal(TALLOC_CTX *mem_ctx,
{
switch(sp_ctx->mech) {
case SPNEGO_KRB5:
- return gse_seal(mem_ctx,
- sp_ctx->mech_ctx.gssapi_state,
- data, signature);
case SPNEGO_NTLMSSP:
return gensec_seal_packet(
sp_ctx->mech_ctx.gensec_security,
@@ -450,9 +383,6 @@ NTSTATUS spnego_unseal(TALLOC_CTX *mem_ctx,
{
switch(sp_ctx->mech) {
case SPNEGO_KRB5:
- return gse_unseal(mem_ctx,
- sp_ctx->mech_ctx.gssapi_state,
- data, signature);
case SPNEGO_NTLMSSP:
return gensec_unseal_packet(
sp_ctx->mech_ctx.gensec_security,
diff --git a/source3/librpc/crypto/spnego.h b/source3/librpc/crypto/spnego.h
index a31f997ab6..57396a63c5 100644
--- a/source3/librpc/crypto/spnego.h
+++ b/source3/librpc/crypto/spnego.h
@@ -31,7 +31,6 @@ struct spnego_context {
union {
struct gensec_security *gensec_security;
- struct gse_context *gssapi_state;
} mech_ctx;
char *oid_list[ASN1_MAX_OIDS];
@@ -50,17 +49,10 @@ struct spnego_context {
bool is_dcerpc;
struct tsocket_address *remote_address;
+
+ bool more_processing; /* Current mech state requires more processing */
};
-NTSTATUS spnego_gssapi_init_client(TALLOC_CTX *mem_ctx,
- bool do_sign, bool do_seal,
- bool is_dcerpc,
- const char *ccache_name,
- const char *server,
- const char *service,
- const char *username,
- const char *password,
- struct spnego_context **spengo_ctx);
NTSTATUS spnego_generic_init_client(TALLOC_CTX *mem_ctx,
const char *oid,
bool do_sign, bool do_seal,
@@ -81,7 +73,7 @@ bool spnego_require_more_processing(struct spnego_context *sp_ctx);
NTSTATUS spnego_get_negotiated_mech(struct spnego_context *sp_ctx,
enum spnego_mech *type,
- void **auth_context);
+ struct gensec_security **auth_context);
DATA_BLOB spnego_get_session_key(TALLOC_CTX *mem_ctx,
struct spnego_context *sp_ctx);
diff --git a/source3/librpc/rpc/dcerpc_helpers.c b/source3/librpc/rpc/dcerpc_helpers.c
index 4cfe7933fe..ed0e0fe932 100644
--- a/source3/librpc/rpc/dcerpc_helpers.c
+++ b/source3/librpc/rpc/dcerpc_helpers.c
@@ -268,10 +268,7 @@ NTSTATUS dcerpc_guess_sizes(struct pipe_auth_data *auth,
struct gensec_security *gensec_security;
struct schannel_state *schannel_auth;
struct spnego_context *spnego_ctx;
- struct gse_context *gse_ctx;
enum spnego_mech auth_type;
- void *auth_ctx;
- bool seal = false;
NTSTATUS status;
/* no auth token cases first */
@@ -287,7 +284,6 @@ NTSTATUS dcerpc_guess_sizes(struct pipe_auth_data *auth,
return NT_STATUS_OK;
case DCERPC_AUTH_LEVEL_PRIVACY:
- seal = true;
break;
case DCERPC_AUTH_LEVEL_INTEGRITY:
@@ -308,30 +304,11 @@ NTSTATUS dcerpc_guess_sizes(struct pipe_auth_data *auth,
spnego_ctx = talloc_get_type_abort(auth->auth_ctx,
struct spnego_context);
status = spnego_get_negotiated_mech(spnego_ctx,
- &auth_type, &auth_ctx);
+ &auth_type, &gensec_security);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
- switch (auth_type) {
- case SPNEGO_NTLMSSP:
- gensec_security = talloc_get_type_abort(auth_ctx,
- struct gensec_security);
- *auth_len = gensec_sig_size(gensec_security, max_len);
- break;
-
- case SPNEGO_KRB5:
- gse_ctx = talloc_get_type_abort(auth_ctx,
- struct gse_context);
- if (!gse_ctx) {
- return NT_STATUS_INVALID_PARAMETER;
- }
- *auth_len = gse_get_signature_length(gse_ctx,
- seal, max_len);
- break;
-
- default:
- return NT_STATUS_INVALID_PARAMETER;
- }
+ *auth_len = gensec_sig_size(gensec_security, max_len);
break;
case DCERPC_AUTH_TYPE_NTLMSSP:
diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c
index ce8ab819c5..f3a334a052 100644
--- a/source3/rpc_client/cli_pipe.c
+++ b/source3/rpc_client/cli_pipe.c
@@ -2939,6 +2939,7 @@ NTSTATUS cli_rpc_pipe_open_spnego_krb5(struct cli_state *cli,
struct pipe_auth_data *auth;
struct spnego_context *spnego_ctx;
NTSTATUS status;
+ const char *target_service = "cifs"; /* TODO: Determine target service from the bindings or interface table */
status = cli_rpc_pipe_open(cli, transport, interface, &result);
if (!NT_STATUS_IS_OK(status)) {
@@ -2969,15 +2970,16 @@ NTSTATUS cli_rpc_pipe_open_spnego_krb5(struct cli_state *cli,
goto err_out;
}
- status = spnego_gssapi_init_client(auth,
- (auth->auth_level ==
+ status = spnego_generic_init_client(auth,
+ GENSEC_OID_KERBEROS5,
+ (auth->auth_level ==
DCERPC_AUTH_LEVEL_INTEGRITY),
- (auth->auth_level ==
+ (auth->auth_level ==
DCERPC_AUTH_LEVEL_PRIVACY),
- true,
- NULL, server, "cifs",
- username, password,
- &spnego_ctx);
+ true,
+ server, target_service,
+ auth->domain, auth->user_name, password,
+ &spnego_ctx);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(0, ("spnego_init_client returned %s\n",
nt_errstr(status)));
diff --git a/source3/rpc_server/dcesrv_spnego.c b/source3/rpc_server/dcesrv_spnego.c
index e89563a9fb..1bea2321ef 100644
--- a/source3/rpc_server/dcesrv_spnego.c
+++ b/source3/rpc_server/dcesrv_spnego.c
@@ -23,6 +23,7 @@
#include "dcesrv_auth_generic.h"
#include "dcesrv_gssapi.h"
#include "dcesrv_spnego.h"
+#include "auth/gensec/gensec.h"
static NTSTATUS spnego_init_server(TALLOC_CTX *mem_ctx,
bool do_sign, bool do_seal,
@@ -55,51 +56,38 @@ static NTSTATUS spnego_server_mech_init(struct spnego_context *sp_ctx,
DATA_BLOB *token_out)
{
struct gensec_security *gensec_security;
- struct gse_context *gse_ctx;
NTSTATUS status;
+ const char *oid;
switch (sp_ctx->mech) {
case SPNEGO_KRB5:
- status = gssapi_server_auth_start(sp_ctx,
- sp_ctx->do_sign,
- sp_ctx->do_seal,
- sp_ctx->is_dcerpc,
- token_in,
- token_out,
- &gse_ctx);
- if (!NT_STATUS_IS_OK(status)) {
- DEBUG(0, ("Failed to init gssapi server "
- "(%s)\n", nt_errstr(status)));
- return status;
- }
-
- sp_ctx->mech_ctx.gssapi_state = gse_ctx;
+ oid = GENSEC_OID_KERBEROS5;
break;
-
case SPNEGO_NTLMSSP:
- status = auth_generic_server_start(sp_ctx,
- OID_NTLMSSP,
- sp_ctx->do_sign,
- sp_ctx->do_seal,
- sp_ctx->is_dcerpc,
- token_in,
- token_out,
- sp_ctx->remote_address,
- &gensec_security);
- if (!NT_STATUS_IS_OK(status)) {
- DEBUG(0, ("Failed to init ntlmssp server "
- "(%s)\n", nt_errstr(status)));
- return status;
- }
-
- sp_ctx->mech_ctx.gensec_security = gensec_security;
+ oid = GENSEC_OID_NTLMSSP;
break;
-
default:
DEBUG(3, ("No known mechanisms available\n"));
return NT_STATUS_INVALID_PARAMETER;
}
+ status = auth_generic_server_start(sp_ctx,
+ oid,
+ sp_ctx->do_sign,
+ sp_ctx->do_seal,
+ sp_ctx->is_dcerpc,
+ token_in,
+ token_out,
+ sp_ctx->remote_address,
+ &gensec_security);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0, ("Failed to init ntlmssp server "
+ "(%s)\n", nt_errstr(status)));
+ return status;
+ }
+
+ sp_ctx->mech_ctx.gensec_security = gensec_security;
+
return NT_STATUS_OK;
}
@@ -150,10 +138,6 @@ NTSTATUS spnego_server_step(struct spnego_context *sp_ctx,
switch(sp_ctx->mech) {
case SPNEGO_KRB5:
- status = gssapi_server_step(
- sp_ctx->mech_ctx.gssapi_state,
- mem_ctx, &token_in, &token_out);
- break;
case SPNEGO_NTLMSSP:
status = auth_generic_server_step(
sp_ctx->mech_ctx.gensec_security,
diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c
index 605ed5420c..18389b42e0 100644
--- a/source3/rpc_server/srv_pipe.c
+++ b/source3/rpc_server/srv_pipe.c
@@ -676,52 +676,11 @@ static bool pipe_auth_generic_verify_final(TALLOC_CTX *mem_ctx,
return true;
}
-static NTSTATUS pipe_gssapi_verify_final(TALLOC_CTX *mem_ctx,
- struct gse_context *gse_ctx,
- const struct tsocket_address *remote_address,
- struct auth_session_info **session_info)
-{
- NTSTATUS status;
- bool bret;
-
- /* Finally - if the pipe negotiated integrity (sign) or privacy (seal)
- ensure the underlying flags are also set. If not we should
- refuse the bind. */
-
- status = gssapi_server_check_flags(gse_ctx);
- if (!NT_STATUS_IS_OK(status)) {
- DEBUG(0, ("Requested Security Layers not honored!\n"));
- return status;
- }
-
- status = gssapi_server_get_user_info(gse_ctx, mem_ctx,
- remote_address, session_info);
- if (!NT_STATUS_IS_OK(status)) {
- DEBUG(0, (__location__ ": failed to obtain the server info "
- "for authenticated user: %s\n", nt_errstr(status)));
- return status;
- }
-
- /*
- * We're an authenticated bind over smb, so the session key needs to
- * be set to "SystemLibraryDTC". Weird, but this is what Windows
- * does. See the RPC-SAMBA3SESSIONKEY.
- */
-
- bret = session_info_set_session_key((*session_info), generic_session_key());
- if (!bret) {
- return NT_STATUS_ACCESS_DENIED;
- }
-
- return NT_STATUS_OK;
-}
-
static NTSTATUS pipe_auth_verify_final(struct pipes_struct *p)
{
enum spnego_mech auth_type;
struct gensec_security *gensec_security;
struct spnego_context *spnego_ctx;
- struct gse_context *gse_ctx;
void *mech_ctx;
NTSTATUS status;
@@ -740,37 +699,15 @@ static NTSTATUS pipe_auth_verify_final(struct pipes_struct *p)
spnego_ctx = talloc_get_type_abort(p->auth.auth_ctx,
struct spnego_context);
status = spnego_get_negotiated_mech(spnego_ctx,
- &auth_type, &mech_ctx);
+ &auth_type, &gensec_security);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(0, ("Bad SPNEGO state (%s)\n",
nt_errstr(status)));
return status;
}
- switch(auth_type) {
- case SPNEGO_KRB5:
- gse_ctx = talloc_get_type_abort(mech_ctx,
- struct gse_context);
- status = pipe_gssapi_verify_final(p, gse_ctx,
- p->remote_address,
- &p->session_info);
- if (!NT_STATUS_IS_OK(status)) {
- DEBUG(1, ("gssapi bind failed with: %s",
- nt_errstr(status)));
- return status;
- }
- break;
- case SPNEGO_NTLMSSP:
- gensec_security = talloc_get_type_abort(mech_ctx,
- struct gensec_security);
- if (!pipe_auth_generic_verify_final(p, gensec_security,
- p->auth.auth_level,
- &p->session_info)) {
- return NT_STATUS_ACCESS_DENIED;
- }
- break;
- default:
- DEBUG(0, (__location__ ": incorrect spnego type "
- "(%d).\n", auth_type));
+ if (!pipe_auth_generic_verify_final(p, gensec_security,
+ p->auth.auth_level,
+ &p->session_info)) {
return NT_STATUS_ACCESS_DENIED;
}
break;