diff options
Diffstat (limited to 'source4/libcli')
-rw-r--r-- | source4/libcli/auth/gensec.c | 405 | ||||
-rw-r--r-- | source4/libcli/auth/gensec.h | 39 | ||||
-rw-r--r-- | source4/libcli/auth/gensec_ntlmssp.c | 333 | ||||
-rw-r--r-- | source4/libcli/auth/ntlmssp_sign.c | 2 | ||||
-rw-r--r-- | source4/libcli/auth/spnego.c | 175 | ||||
-rw-r--r-- | source4/libcli/auth/spnego.h | 25 | ||||
-rw-r--r-- | source4/libcli/config.m4 | 3 |
7 files changed, 813 insertions, 169 deletions
diff --git a/source4/libcli/auth/gensec.c b/source4/libcli/auth/gensec.c index 138c4af35c..f6d6db9e62 100644 --- a/source4/libcli/auth/gensec.c +++ b/source4/libcli/auth/gensec.c @@ -23,46 +23,14 @@ #include "includes.h" -static const struct gensec_security_ops gensec_ntlmssp_security_ops = { - .name = "ntlmssp", - .sasl_name = "NTLM", - .auth_type = DCERPC_AUTH_TYPE_NTLMSSP, - .oid = OID_NTLMSSP, - .client_start = gensec_ntlmssp_client_start, - .update = gensec_ntlmssp_update, - .seal = gensec_ntlmssp_seal_packet, - .sign = gensec_ntlmssp_sign_packet, - .check_sig = gensec_ntlmssp_check_packet, - .unseal = gensec_ntlmssp_unseal_packet, - .session_key = gensec_ntlmssp_session_key, - .end = gensec_ntlmssp_end -}; - - -static const struct gensec_security_ops gensec_spnego_security_ops = { - .name = "spnego", - .sasl_name = "GSS-SPNEGO", - .oid = OID_SPNEGO, - .client_start = gensec_spnego_client_start, - .update = gensec_spnego_update, - .seal = gensec_spnego_seal_packet, - .sign = gensec_spnego_sign_packet, - .check_sig = gensec_spnego_check_packet, - .unseal = gensec_spnego_unseal_packet, - .session_key = gensec_spnego_session_key, - .end = gensec_spnego_end -}; - -static const struct gensec_security_ops *generic_security_ops[] = { - &gensec_ntlmssp_security_ops, - &gensec_spnego_security_ops, - NULL -}; - -const struct gensec_security_ops *gensec_security_by_authtype(uint8_t auth_type) +/* the list of currently registered GENSEC backends */ +const static struct gensec_security_ops **generic_security_ops; +static int num_backends; + +static const struct gensec_security_ops *gensec_security_by_authtype(uint8_t auth_type) { int i; - for (i=0; generic_security_ops[i]; i++) { + for (i=0; i < num_backends; i++) { if (generic_security_ops[i]->auth_type == auth_type) { return generic_security_ops[i]; } @@ -71,10 +39,10 @@ const struct gensec_security_ops *gensec_security_by_authtype(uint8_t auth_type) return NULL; } -const struct gensec_security_ops *gensec_security_by_oid(const char *oid) +static const struct gensec_security_ops *gensec_security_by_oid(const char *oid) { int i; - for (i=0; generic_security_ops[i]; i++) { + for (i=0; i < num_backends; i++) { if (generic_security_ops[i]->oid && (strcmp(generic_security_ops[i]->oid, oid) == 0)) { return generic_security_ops[i]; @@ -84,10 +52,10 @@ const struct gensec_security_ops *gensec_security_by_oid(const char *oid) return NULL; } -const struct gensec_security_ops *gensec_security_by_sasl_name(const char *sasl_name) +static const struct gensec_security_ops *gensec_security_by_sasl_name(const char *sasl_name) { int i; - for (i=0; generic_security_ops[i]; i++) { + for (i=0; i < num_backends; i++) { if (generic_security_ops[i]->sasl_name && (strcmp(generic_security_ops[i]->sasl_name, sasl_name) == 0)) { return generic_security_ops[i]; @@ -97,8 +65,359 @@ const struct gensec_security_ops *gensec_security_by_sasl_name(const char *sasl_ return NULL; } -const struct gensec_security_ops **gensec_security_all(void) +static const struct gensec_security_ops *gensec_security_by_name(const char *name) +{ + int i; + for (i=0; i < num_backends; i++) { + if (generic_security_ops[i]->name + && (strcmp(generic_security_ops[i]->name, name) == 0)) { + return generic_security_ops[i]; + } + } + + return NULL; +} + +const struct gensec_security_ops **gensec_security_all(int *num_backends_out) { + *num_backends_out = num_backends; return generic_security_ops; } +static NTSTATUS gensec_start(struct gensec_security **gensec_security) +{ + TALLOC_CTX *mem_ctx; + /* awaiting a correct fix from metze */ + if (!gensec_init()) { + return NT_STATUS_INTERNAL_ERROR; + } + + mem_ctx = talloc_init("gensec_security struct"); + if (!mem_ctx) { + return NT_STATUS_NO_MEMORY; + } + + (*gensec_security) = talloc_p(mem_ctx, struct gensec_security); + if (!(*gensec_security)) { + talloc_destroy(mem_ctx); + return NT_STATUS_NO_MEMORY; + } + + (*gensec_security)->mem_ctx = mem_ctx; + (*gensec_security)->ops = NULL; + + return NT_STATUS_OK; +} + +NTSTATUS gensec_client_start(struct gensec_security **gensec_security) +{ + NTSTATUS status; + status = gensec_start(gensec_security); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + (*gensec_security)->gensec_role = GENSEC_CLIENT; + (*gensec_security)->password_callback = NULL; + + ZERO_STRUCT((*gensec_security)->user); + + return status; +} + +NTSTATUS gensec_server_start(struct gensec_security **gensec_security) +{ + NTSTATUS status; + status = gensec_start(gensec_security); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + (*gensec_security)->gensec_role = GENSEC_SERVER; + + return status; +} + +static NTSTATUS gensec_start_mech(struct gensec_security *gensec_security) +{ + NTSTATUS status; + switch (gensec_security->gensec_role) { + case GENSEC_CLIENT: + if (gensec_security->ops->client_start) { + status = gensec_security->ops->client_start(gensec_security); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1, ("Faild to start GENSEC client mech %s: %s\n", + gensec_security->ops->name, nt_errstr(status))); + } + return status; + } + case GENSEC_SERVER: + if (gensec_security->ops->server_start) { + status = gensec_security->ops->server_start(gensec_security); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1, ("Faild to start GENSEC server mech %s: %s\n", + gensec_security->ops->name, nt_errstr(status))); + } + return status; + } + } + return NT_STATUS_INVALID_PARAMETER; +} + +NTSTATUS gensec_start_mech_by_authtype(struct gensec_security *gensec_security, + uint8_t authtype) +{ + gensec_security->ops = gensec_security_by_authtype(authtype); + if (!gensec_security->ops) { + DEBUG(1, ("Could not find GENSEC backend for authtype=%d\n", (int)authtype)); + return NT_STATUS_INVALID_PARAMETER; + } + return gensec_start_mech(gensec_security); +} + +NTSTATUS gensec_start_mech_by_oid(struct gensec_security *gensec_security, + const char *mech_oid) +{ + gensec_security->ops = gensec_security_by_oid(mech_oid); + if (!gensec_security->ops) { + DEBUG(1, ("Could not find GENSEC backend for oid=%s\n", mech_oid)); + return NT_STATUS_INVALID_PARAMETER; + } + return gensec_start_mech(gensec_security); +} + +NTSTATUS gensec_start_mech_by_sasl_name(struct gensec_security *gensec_security, + const char *sasl_name) +{ + gensec_security->ops = gensec_security_by_sasl_name(sasl_name); + if (!gensec_security->ops) { + DEBUG(1, ("Could not find GENSEC backend for sasl_name=%s\n", sasl_name)); + return NT_STATUS_INVALID_PARAMETER; + } + return gensec_start_mech(gensec_security); +} + +/* + wrappers for the gensec function pointers +*/ +NTSTATUS gensec_unseal_packet(struct gensec_security *gensec_security, + TALLOC_CTX *mem_ctx, + uint8_t *data, size_t length, DATA_BLOB *sig) +{ + return gensec_security->ops->unseal_packet(gensec_security, mem_ctx, data, length, sig); +} + +NTSTATUS gensec_check_packet(struct gensec_security *gensec_security, + TALLOC_CTX *mem_ctx, + const uint8_t *data, size_t length, + const DATA_BLOB *sig) +{ + return gensec_security->ops->check_packet(gensec_security, mem_ctx, data, length, sig); +} + +NTSTATUS gensec_seal_packet(struct gensec_security *gensec_security, + TALLOC_CTX *mem_ctx, + uint8_t *data, size_t length, + DATA_BLOB *sig) +{ + return gensec_security->ops->seal_packet(gensec_security, mem_ctx, data, length, sig); +} + +NTSTATUS gensec_sign_packet(struct gensec_security *gensec_security, + TALLOC_CTX *mem_ctx, + const uint8_t *data, size_t length, + DATA_BLOB *sig) +{ + return gensec_security->ops->sign_packet(gensec_security, mem_ctx, data, length, sig); +} + +NTSTATUS gensec_session_key(struct gensec_security *gensec_security, + DATA_BLOB *session_key) +{ + return gensec_security->ops->session_key(gensec_security, session_key); +} + +NTSTATUS gensec_session_info(struct gensec_security *gensec_security, + struct auth_session_info **session_info) +{ + return gensec_security->ops->session_info(gensec_security, session_info); +} + +/** + * Next state function for the GENSEC state machine + * + * @param gensec_security GENSEC State + * @param out_mem_ctx The TALLOC_CTX for *out to be allocated on + * @param in The request, as a DATA_BLOB + * @param out The reply, as an talloc()ed DATA_BLOB, on *out_mem_ctx + * @return Error, MORE_PROCESSING_REQUIRED if a reply is sent, + * or NT_STATUS_OK if the user is authenticated. + */ + +NTSTATUS gensec_update(struct gensec_security *gensec_security, TALLOC_CTX *out_mem_ctx, + const DATA_BLOB in, DATA_BLOB *out) +{ + return gensec_security->ops->update(gensec_security, out_mem_ctx, in, out); +} + +void gensec_end(struct gensec_security **gensec_security) +{ + if ((*gensec_security)->ops) { + (*gensec_security)->ops->end(*gensec_security); + } + (*gensec_security)->private_data = NULL; + talloc_destroy((*gensec_security)->mem_ctx); + + gensec_security = NULL; +} + +/** + * Set a username on a GENSEC context - ensures it is talloc()ed + * + */ + +NTSTATUS gensec_set_username(struct gensec_security *gensec_security, const char *user) +{ + gensec_security->user.name = talloc_strdup(gensec_security->mem_ctx, user); + if (!gensec_security->user.name) { + return NT_STATUS_NO_MEMORY; + } + return NT_STATUS_OK; +} + +/** + * Set a domain on a GENSEC context - ensures it is talloc()ed + * + */ + +NTSTATUS gensec_set_domain(struct gensec_security *gensec_security, const char *domain) +{ + gensec_security->user.domain = talloc_strdup(gensec_security->mem_ctx, domain); + if (!gensec_security->user.domain) { + return NT_STATUS_NO_MEMORY; + } + return NT_STATUS_OK; +} + +/** + * Set the password outright on GENSEC context - ensures it is talloc()ed, and that we will + * not do a callback + * + */ + +NTSTATUS gensec_set_password(struct gensec_security *gensec_security, + const char *password) +{ + gensec_security->user.password = talloc_strdup(gensec_security->mem_ctx, password); + if (!gensec_security->user.password) { + return NT_STATUS_NO_MEMORY; + } + return NT_STATUS_OK; +} + +/** + * Set a password callback, if the gensec module we use demands a password + */ + +void gensec_set_password_callback(struct gensec_security *gensec_security, + gensec_password_callback callback, void *callback_private_data) +{ + gensec_security->password_callback = callback; + gensec_security->password_callback_private = callback_private_data; +} + +/** + * Get (or call back for) a password. + */ + +NTSTATUS gensec_get_password(struct gensec_security *gensec_security, + TALLOC_CTX *mem_ctx, + char **password) +{ + if (gensec_security->user.password) { + *password = talloc_strdup(mem_ctx, gensec_security->user.password); + if (!*password) { + return NT_STATUS_NO_MEMORY; + } else { + return NT_STATUS_OK; + } + } + if (!gensec_security->password_callback) { + return NT_STATUS_INVALID_PARAMETER; + } + return gensec_security->password_callback(gensec_security, mem_ctx, password); +} + +/* + register a GENSEC backend. + + The 'name' can be later used by other backends to find the operations + structure for this backend. +*/ +static NTSTATUS gensec_register(const void *_ops) +{ + const struct gensec_security_ops *ops = _ops; + + if (gensec_security_by_name(ops->name) != NULL) { + /* its already registered! */ + DEBUG(0,("GENSEC backend '%s' already registered\n", + ops->name)); + return NT_STATUS_OBJECT_NAME_COLLISION; + } + + generic_security_ops = Realloc(generic_security_ops, sizeof(generic_security_ops[0]) * (num_backends+1)); + if (!generic_security_ops) { + smb_panic("out of memory in gensec_register"); + } + + generic_security_ops[num_backends] = ops; + + num_backends++; + + DEBUG(3,("GENSEC backend '%s' registered\n", + ops->name)); + + return NT_STATUS_OK; +} + +/* + return the GENSEC interface version, and the size of some critical types + This can be used by backends to either detect compilation errors, or provide + multiple implementations for different smbd compilation options in one module +*/ +const struct gensec_critical_sizes *gensec_interface_version(void) +{ + static const struct gensec_critical_sizes critical_sizes = { + GENSEC_INTERFACE_VERSION, + sizeof(struct gensec_security_ops), + sizeof(struct gensec_security), + }; + + return &critical_sizes; +} + +/* + initialise the GENSEC subsystem +*/ +BOOL gensec_init(void) +{ + static BOOL initialised; + NTSTATUS status; + + /* this is *completly* the wrong way to do this */ + if (initialised) { + return True; + } + + status = register_subsystem("gensec", gensec_register); + if (!NT_STATUS_IS_OK(status)) { + return False; + } + + /* FIXME: Perhaps panic if a basic backend, such as NTLMSSP, fails to initialise? */ + gensec_ntlmssp_init(); + gensec_spengo_init(); + gensec_dcerpc_schannel_init(); + + initialised = True; + DEBUG(3,("GENSEC subsystem version %d initialised\n", GENSEC_INTERFACE_VERSION)); + return True; +} diff --git a/source4/libcli/auth/gensec.h b/source4/libcli/auth/gensec.h index 2a469e0f57..463b484a7f 100644 --- a/source4/libcli/auth/gensec.h +++ b/source4/libcli/auth/gensec.h @@ -27,6 +27,7 @@ struct gensec_user { const char *domain; const char *name; const char *password; + char schan_session_key[16]; }; /* GENSEC mode */ enum gensec_role @@ -38,27 +39,47 @@ enum gensec_role struct gensec_security_ops { const char *name; const char *sasl_name; - uint8 auth_type; + uint8 auth_type; /* 0 if not offered on DCE-RPC */ const char *oid; /* NULL if not offered by SPENGO */ NTSTATUS (*client_start)(struct gensec_security *gensec_security); NTSTATUS (*server_start)(struct gensec_security *gensec_security); NTSTATUS (*update)(struct gensec_security *gensec_security, TALLOC_CTX *out_mem_ctx, const DATA_BLOB in, DATA_BLOB *out); - NTSTATUS (*seal)(struct gensec_security *gensec_security, TALLOC_CTX *sig_mem_ctx, + NTSTATUS (*seal_packet)(struct gensec_security *gensec_security, TALLOC_CTX *sig_mem_ctx, uint8_t *data, size_t length, DATA_BLOB *sig); - NTSTATUS (*sign)(struct gensec_security *gensec_security, TALLOC_CTX *sig_mem_ctx, + NTSTATUS (*sign_packet)(struct gensec_security *gensec_security, TALLOC_CTX *sig_mem_ctx, const uint8_t *data, size_t length, DATA_BLOB *sig); - NTSTATUS (*check_sig)(struct gensec_security *gensec_security, TALLOC_CTX *sig_mem_ctx, - const uint8_t *data, size_t length, const DATA_BLOB *sig); - NTSTATUS (*unseal)(struct gensec_security *gensec_security, TALLOC_CTX *sig_mem_ctx, - uint8_t *data, size_t length, DATA_BLOB *sig); + NTSTATUS (*check_packet)(struct gensec_security *gensec_security, TALLOC_CTX *sig_mem_ctx, + const uint8_t *data, size_t length, const DATA_BLOB *sig); + NTSTATUS (*unseal_packet)(struct gensec_security *gensec_security, TALLOC_CTX *sig_mem_ctx, + uint8_t *data, size_t length, DATA_BLOB *sig); NTSTATUS (*session_key)(struct gensec_security *gensec_security, DATA_BLOB *session_key); + NTSTATUS (*session_info)(struct gensec_security *gensec_security, + struct auth_session_info **session_info); void (*end)(struct gensec_security *gensec_security); }; +typedef NTSTATUS (*gensec_password_callback)(struct gensec_security *gensec_security, TALLOC_CTX *mem_ctx, + char **password); + +#define GENSEC_INTERFACE_VERSION 0 + struct gensec_security { - struct gensec_user user; - void *private_data; + TALLOC_CTX *mem_ctx; + gensec_password_callback password_callback; + void *password_callback_private; const struct gensec_security_ops *ops; + void *private_data; + struct gensec_user user; + enum gensec_role gensec_role; }; +/* this structure is used by backends to determine the size of some critical types */ +struct gensec_critical_sizes { + int interface_version; + int sizeof_gensec_security_ops; + int sizeof_gensec_security; +}; + + + diff --git a/source4/libcli/auth/gensec_ntlmssp.c b/source4/libcli/auth/gensec_ntlmssp.c index f7e9dddd2f..9f7c4c6f86 100644 --- a/source4/libcli/auth/gensec_ntlmssp.c +++ b/source4/libcli/auth/gensec_ntlmssp.c @@ -23,33 +23,220 @@ #include "includes.h" +struct gensec_ntlmssp_state { + TALLOC_CTX *mem_ctx; + struct auth_context *auth_context; + struct auth_serversupplied_info *server_info; + struct ntlmssp_state *ntlmssp_state; +}; -NTSTATUS gensec_ntlmssp_client_start(struct gensec_security *gensec_security) + +/** + * Return the challenge as determined by the authentication subsystem + * @return an 8 byte random challenge + */ + +static const uint8_t *auth_ntlmssp_get_challenge(const struct ntlmssp_state *ntlmssp_state) +{ + struct gensec_ntlmssp_state *gensec_ntlmssp_state = ntlmssp_state->auth_context; + + return gensec_ntlmssp_state->auth_context->get_ntlm_challenge(gensec_ntlmssp_state->auth_context); +} + +/** + * Some authentication methods 'fix' the challenge, so we may not be able to set it + * + * @return If the effective challenge used by the auth subsystem may be modified + */ +static BOOL auth_ntlmssp_may_set_challenge(const struct ntlmssp_state *ntlmssp_state) +{ + struct gensec_ntlmssp_state *gensec_ntlmssp_state = ntlmssp_state->auth_context; + + return gensec_ntlmssp_state->auth_context->challenge_may_be_modified; +} + +/** + * NTLM2 authentication modifies the effective challenge, + * @param challenge The new challenge value + */ +static NTSTATUS auth_ntlmssp_set_challenge(struct ntlmssp_state *ntlmssp_state, DATA_BLOB *challenge) +{ + struct gensec_ntlmssp_state *gensec_ntlmssp_state = ntlmssp_state->auth_context; + struct auth_context *auth_context = gensec_ntlmssp_state->auth_context; + + SMB_ASSERT(challenge->length == 8); + + auth_context->challenge = data_blob_talloc(auth_context->mem_ctx, + challenge->data, challenge->length); + + auth_context->challenge_set_by = "NTLMSSP callback (NTLM2)"; + + DEBUG(5, ("auth_context challenge set by %s\n", auth_context->challenge_set_by)); + DEBUG(5, ("challenge is: \n")); + dump_data(5, (const char *)auth_context->challenge.data, auth_context->challenge.length); + return NT_STATUS_OK; +} + +/** + * Check the password on an NTLMSSP login. + * + * Return the session keys used on the connection. + */ + +static NTSTATUS auth_ntlmssp_check_password(struct ntlmssp_state *ntlmssp_state, DATA_BLOB *user_session_key, DATA_BLOB *lm_session_key) +{ + struct gensec_ntlmssp_state *gensec_ntlmssp_state = ntlmssp_state->auth_context; + struct auth_usersupplied_info *user_info = NULL; + NTSTATUS nt_status; + +#if 0 + /* the client has given us its machine name (which we otherwise would not get on port 445). + we need to possibly reload smb.conf if smb.conf includes depend on the machine name */ + + set_remote_machine_name(gensec_ntlmssp_state->ntlmssp_state->workstation, True); + + /* setup the string used by %U */ + /* sub_set_smb_name checks for weird internally */ + sub_set_smb_name(gensec_ntlmssp_state->ntlmssp_state->user); + + reload_services(True); + +#endif + nt_status = make_user_info_map(&user_info, + gensec_ntlmssp_state->ntlmssp_state->user, + gensec_ntlmssp_state->ntlmssp_state->domain, + gensec_ntlmssp_state->ntlmssp_state->workstation, + gensec_ntlmssp_state->ntlmssp_state->lm_resp.data ? &gensec_ntlmssp_state->ntlmssp_state->lm_resp : NULL, + gensec_ntlmssp_state->ntlmssp_state->nt_resp.data ? &gensec_ntlmssp_state->ntlmssp_state->nt_resp : NULL, + NULL, NULL, NULL, + True); + + if (!NT_STATUS_IS_OK(nt_status)) { + return nt_status; + } + + nt_status = gensec_ntlmssp_state->auth_context->check_ntlm_password(gensec_ntlmssp_state->auth_context, + user_info, &gensec_ntlmssp_state->server_info); + + free_user_info(&user_info); + + if (!NT_STATUS_IS_OK(nt_status)) { + return nt_status; + } + if (gensec_ntlmssp_state->server_info->user_session_key.length) { + DEBUG(10, ("Got NT session key of length %u\n", gensec_ntlmssp_state->server_info->user_session_key.length)); + *user_session_key = data_blob_talloc(ntlmssp_state->mem_ctx, + gensec_ntlmssp_state->server_info->user_session_key.data, + gensec_ntlmssp_state->server_info->user_session_key.length); + } + if (gensec_ntlmssp_state->server_info->lm_session_key.length) { + DEBUG(10, ("Got LM session key of length %u\n", gensec_ntlmssp_state->server_info->lm_session_key.length)); + *lm_session_key = data_blob_talloc(ntlmssp_state->mem_ctx, + gensec_ntlmssp_state->server_info->lm_session_key.data, + gensec_ntlmssp_state->server_info->lm_session_key.length); + } + return nt_status; +} + +static NTSTATUS gensec_ntlmssp_start(struct gensec_security *gensec_security) +{ + struct gensec_ntlmssp_state *gensec_ntlmssp_state; + + TALLOC_CTX *mem_ctx = talloc_init("gensec_ntlmssp"); + if (!mem_ctx) { + return NT_STATUS_NO_MEMORY; + } + + gensec_ntlmssp_state = talloc_p(mem_ctx, struct gensec_ntlmssp_state); + if (!gensec_ntlmssp_state) { + return NT_STATUS_NO_MEMORY; + } + + gensec_ntlmssp_state->mem_ctx = mem_ctx; + gensec_ntlmssp_state->ntlmssp_state = NULL; + gensec_ntlmssp_state->auth_context = NULL; + gensec_ntlmssp_state->server_info = NULL; + + gensec_security->private_data = gensec_ntlmssp_state; + return NT_STATUS_OK; +} + +static NTSTATUS gensec_ntlmssp_server_start(struct gensec_security *gensec_security) +{ + NTSTATUS nt_status; + NTSTATUS status; + struct ntlmssp_state *ntlmssp_state; + struct gensec_ntlmssp_state *gensec_ntlmssp_state; + + status = gensec_ntlmssp_start(gensec_security); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + gensec_ntlmssp_state = gensec_security->private_data; + + if (!NT_STATUS_IS_OK(nt_status = ntlmssp_server_start(&gensec_ntlmssp_state->ntlmssp_state))) { + return nt_status; + } + + ntlmssp_state = gensec_ntlmssp_state->ntlmssp_state; + if (!NT_STATUS_IS_OK(nt_status = make_auth_context_subsystem(&gensec_ntlmssp_state->auth_context))) { + return nt_status; + } + + ntlmssp_state->auth_context = gensec_ntlmssp_state; + ntlmssp_state->get_challenge = auth_ntlmssp_get_challenge; + ntlmssp_state->may_set_challenge = auth_ntlmssp_may_set_challenge; + ntlmssp_state->set_challenge = auth_ntlmssp_set_challenge; + ntlmssp_state->check_password = auth_ntlmssp_check_password; + ntlmssp_state->server_role = lp_server_role(); + + return NT_STATUS_OK; +} + +static NTSTATUS gensec_ntlmssp_client_start(struct gensec_security *gensec_security) { - struct ntlmssp_state *ntlmssp_state = NULL; + struct gensec_ntlmssp_state *gensec_ntlmssp_state; + char *password = NULL; + NTSTATUS status; + status = gensec_ntlmssp_start(gensec_security); + if (!NT_STATUS_IS_OK(status)) { + return status; + } - status = ntlmssp_client_start(&ntlmssp_state); + gensec_ntlmssp_state = gensec_security->private_data; + status = ntlmssp_client_start(&gensec_ntlmssp_state->ntlmssp_state); if (!NT_STATUS_IS_OK(status)) { return status; } - status = ntlmssp_set_domain(ntlmssp_state, gensec_security->user.domain); + status = ntlmssp_set_domain(gensec_ntlmssp_state->ntlmssp_state, + gensec_security->user.domain); if (!NT_STATUS_IS_OK(status)) { return status; } - status = ntlmssp_set_username(ntlmssp_state, gensec_security->user.name); + status = ntlmssp_set_username(gensec_ntlmssp_state->ntlmssp_state, + gensec_security->user.name); if (!NT_STATUS_IS_OK(status)) { return status; } - status = ntlmssp_set_password(ntlmssp_state, gensec_security->user.password); + status = gensec_get_password(gensec_security, gensec_ntlmssp_state->mem_ctx, &password); if (!NT_STATUS_IS_OK(status)) { return status; } - - gensec_security->private_data = ntlmssp_state; + + if (password) { + status = ntlmssp_set_password(gensec_ntlmssp_state->ntlmssp_state, + password); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + } + + gensec_security->private_data = gensec_ntlmssp_state; return status; } @@ -57,66 +244,154 @@ NTSTATUS gensec_ntlmssp_client_start(struct gensec_security *gensec_security) /* wrappers for the ntlmssp_*() functions */ -NTSTATUS gensec_ntlmssp_unseal_packet(struct gensec_security *gensec_security, +static NTSTATUS gensec_ntlmssp_unseal_packet(struct gensec_security *gensec_security, TALLOC_CTX *mem_ctx, uint8_t *data, size_t length, DATA_BLOB *sig) { - struct ntlmssp_state *ntlmssp_state = gensec_security->private_data; + struct gensec_ntlmssp_state *gensec_ntlmssp_state = gensec_security->private_data; - return ntlmssp_unseal_packet(ntlmssp_state, mem_ctx, data, length, sig); + return ntlmssp_unseal_packet(gensec_ntlmssp_state->ntlmssp_state, mem_ctx, data, length, sig); } -NTSTATUS gensec_ntlmssp_check_packet(struct gensec_security *gensec_security, +static NTSTATUS gensec_ntlmssp_check_packet(struct gensec_security *gensec_security, TALLOC_CTX *mem_ctx, const uint8_t *data, size_t length, const DATA_BLOB *sig) { - struct ntlmssp_state *ntlmssp_state = gensec_security->private_data; + struct gensec_ntlmssp_state *gensec_ntlmssp_state = gensec_security->private_data; - return ntlmssp_check_packet(ntlmssp_state, mem_ctx, data, length, sig); + return ntlmssp_check_packet(gensec_ntlmssp_state->ntlmssp_state, mem_ctx, data, length, sig); } -NTSTATUS gensec_ntlmssp_seal_packet(struct gensec_security *gensec_security, +static NTSTATUS gensec_ntlmssp_seal_packet(struct gensec_security *gensec_security, TALLOC_CTX *mem_ctx, uint8_t *data, size_t length, DATA_BLOB *sig) { - struct ntlmssp_state *ntlmssp_state = gensec_security->private_data; + struct gensec_ntlmssp_state *gensec_ntlmssp_state = gensec_security->private_data; - return ntlmssp_seal_packet(ntlmssp_state, mem_ctx, data, length, sig); + return ntlmssp_seal_packet(gensec_ntlmssp_state->ntlmssp_state, mem_ctx, data, length, sig); } -NTSTATUS gensec_ntlmssp_sign_packet(struct gensec_security *gensec_security, +static NTSTATUS gensec_ntlmssp_sign_packet(struct gensec_security *gensec_security, TALLOC_CTX *mem_ctx, const uint8_t *data, size_t length, DATA_BLOB *sig) { - struct ntlmssp_state *ntlmssp_state = gensec_security->private_data; + struct gensec_ntlmssp_state *gensec_ntlmssp_state = gensec_security->private_data; - return ntlmssp_sign_packet(ntlmssp_state, mem_ctx, data, length, sig); + return ntlmssp_sign_packet(gensec_ntlmssp_state->ntlmssp_state, mem_ctx, data, length, sig); } -NTSTATUS gensec_ntlmssp_session_key(struct gensec_security *gensec_security, +static NTSTATUS gensec_ntlmssp_session_key(struct gensec_security *gensec_security, DATA_BLOB *session_key) { - struct ntlmssp_state *ntlmssp_state = gensec_security->private_data; + struct gensec_ntlmssp_state *gensec_ntlmssp_state = gensec_security->private_data; - return ntlmssp_session_key(ntlmssp_state, session_key); + return ntlmssp_session_key(gensec_ntlmssp_state->ntlmssp_state, session_key); } -NTSTATUS gensec_ntlmssp_update(struct gensec_security *gensec_security, TALLOC_CTX *out_mem_ctx, +/** + * Next state function for the wrapped NTLMSSP state machine + * + * @param gensec_ntlmssp_state NTLMSSP State + * @param out_mem_ctx The TALLOC_CTX for *out to be allocated on + * @param in The request, as a DATA_BLOB + * @param out The reply, as an talloc()ed DATA_BLOB, on *out_mem_ctx + * @return Error, MORE_PROCESSING_REQUIRED if a reply is sent, + * or NT_STATUS_OK if the user is authenticated. + */ + +static NTSTATUS gensec_ntlmssp_update(struct gensec_security *gensec_security, TALLOC_CTX *out_mem_ctx, const DATA_BLOB in, DATA_BLOB *out) { - struct ntlmssp_state *ntlmssp_state = gensec_security->private_data; + struct gensec_ntlmssp_state *gensec_ntlmssp_state = gensec_security->private_data; + + return ntlmssp_update(gensec_ntlmssp_state->ntlmssp_state, out_mem_ctx, in, out); +} + +/** + * Return the credentials of a logged on user, including session keys + * etc. + * + * Only valid after a successful authentication + * + * May only be called once per authentication. + * + */ + +static NTSTATUS gensec_ntlmssp_session_info(struct gensec_security *gensec_security, + struct auth_session_info **session_info) +{ + NTSTATUS nt_status; + struct gensec_ntlmssp_state *gensec_ntlmssp_state = gensec_security->private_data; + nt_status = make_session_info(gensec_ntlmssp_state->server_info, session_info); + + if (!NT_STATUS_IS_OK(nt_status)) { + return nt_status; + } + + /* the session_info owns this now */ + gensec_ntlmssp_state->server_info = NULL; + + (*session_info)->session_key = data_blob_talloc((*session_info)->mem_ctx, + gensec_ntlmssp_state->ntlmssp_state->session_key.data, + gensec_ntlmssp_state->ntlmssp_state->session_key.length); + + (*session_info)->workstation = talloc_strdup((*session_info)->mem_ctx, + gensec_ntlmssp_state->ntlmssp_state->workstation); - return ntlmssp_update(ntlmssp_state, out_mem_ctx, in, out); + return NT_STATUS_OK; } -void gensec_ntlmssp_end(struct gensec_security *gensec_security) +static void gensec_ntlmssp_end(struct gensec_security *gensec_security) { - struct ntlmssp_state *ntlmssp_state = gensec_security->private_data; + struct gensec_ntlmssp_state *gensec_ntlmssp_state = gensec_security->private_data; - ntlmssp_end(&ntlmssp_state); + if (gensec_ntlmssp_state->ntlmssp_state) { + ntlmssp_end(&gensec_ntlmssp_state->ntlmssp_state); + } + if (gensec_ntlmssp_state->auth_context) { + free_auth_context(&gensec_ntlmssp_state->auth_context); + } + if (gensec_ntlmssp_state->server_info) { + free_server_info(&gensec_ntlmssp_state->server_info); + } + talloc_destroy(gensec_ntlmssp_state->mem_ctx); gensec_security->private_data = NULL; } + +static const struct gensec_security_ops gensec_ntlmssp_security_ops = { + .name = "ntlmssp", + .sasl_name = "NTLM", + .auth_type = DCERPC_AUTH_TYPE_NTLMSSP, + .oid = OID_NTLMSSP, + .client_start = gensec_ntlmssp_client_start, + .server_start = gensec_ntlmssp_server_start, + .update = gensec_ntlmssp_update, + .seal_packet = gensec_ntlmssp_seal_packet, + .sign_packet = gensec_ntlmssp_sign_packet, + .check_packet = gensec_ntlmssp_check_packet, + .unseal_packet = gensec_ntlmssp_unseal_packet, + .session_key = gensec_ntlmssp_session_key, + .session_info = gensec_ntlmssp_session_info, + .end = gensec_ntlmssp_end +}; + + +NTSTATUS gensec_ntlmssp_init(void) +{ + NTSTATUS ret; + ret = register_backend("gensec", &gensec_ntlmssp_security_ops); + if (!NT_STATUS_IS_OK(ret)) { + DEBUG(0,("Failed to register '%s' gensec backend!\n", + gensec_ntlmssp_security_ops.name)); + return ret; + } + + /* ugly cludge, but we need the auth subsystem for this to work */ + auth_init(); + + return ret; +} diff --git a/source4/libcli/auth/ntlmssp_sign.c b/source4/libcli/auth/ntlmssp_sign.c index d680da9495..80ce1cccc0 100644 --- a/source4/libcli/auth/ntlmssp_sign.c +++ b/source4/libcli/auth/ntlmssp_sign.c @@ -160,8 +160,6 @@ static NTSTATUS ntlmssp_make_packet_signature(struct ntlmssp_state *ntlmssp_stat return NT_STATUS_NO_MEMORY; } - dump_data_pw("ntlmssp hash:\n", ntlmssp_state->ntlmssp_hash, - sizeof(ntlmssp_state->ntlmssp_hash)); NTLMSSPcalc_ap(ntlmssp_state->ntlmssp_hash, sig->data+4, sig->length-4); } dump_data_pw("calculated ntlmssp signature\n", sig->data, sig->length); diff --git a/source4/libcli/auth/spnego.c b/source4/libcli/auth/spnego.c index 321b13afdc..bb9d2504ac 100644 --- a/source4/libcli/auth/spnego.c +++ b/source4/libcli/auth/spnego.c @@ -27,7 +27,25 @@ #undef DBGC_CLASS #define DBGC_CLASS DBGC_AUTH -NTSTATUS gensec_spnego_client_start(struct gensec_security *gensec_security) +enum spnego_state_position { + SPNEGO_SERVER_START, + SPNEGO_CLIENT_GET_MECHS, + SPNEGO_CLIENT_SEND_MECHS, + SPNEGO_TARG, + SPNEGO_FALLBACK, + SPNEGO_DONE +}; + +struct spnego_state { + TALLOC_CTX *mem_ctx; + uint_t ref_count; + enum spnego_message_type expected_packet; + enum spnego_message_type state_position; + negResult_t result; + struct gensec_security *sub_sec_security; +}; + +static NTSTATUS gensec_spnego_client_start(struct gensec_security *gensec_security) { struct spnego_state *spnego_state; TALLOC_CTX *mem_ctx = talloc_init("gensec_spengo_client_start"); @@ -40,11 +58,11 @@ NTSTATUS gensec_spnego_client_start(struct gensec_security *gensec_security) return NT_STATUS_NO_MEMORY; } - spnego_state->role = SPNEGO_CLIENT; spnego_state->expected_packet = SPNEGO_NEG_TOKEN_INIT; spnego_state->state_position = SPNEGO_CLIENT_GET_MECHS; spnego_state->result = SPNEGO_ACCEPT_INCOMPLETE; spnego_state->mem_ctx = mem_ctx; + spnego_state->sub_sec_security = NULL; gensec_security->private_data = spnego_state; return NT_STATUS_OK; @@ -53,9 +71,9 @@ NTSTATUS gensec_spnego_client_start(struct gensec_security *gensec_security) /* wrappers for the spnego_*() functions */ -NTSTATUS gensec_spnego_unseal_packet(struct gensec_security *gensec_security, - TALLOC_CTX *mem_ctx, - uint8_t *data, size_t length, DATA_BLOB *sig) +static NTSTATUS gensec_spnego_unseal_packet(struct gensec_security *gensec_security, + TALLOC_CTX *mem_ctx, + uint8_t *data, size_t length, DATA_BLOB *sig) { struct spnego_state *spnego_state = gensec_security->private_data; @@ -64,11 +82,11 @@ NTSTATUS gensec_spnego_unseal_packet(struct gensec_security *gensec_security, return NT_STATUS_INVALID_PARAMETER; } - return spnego_state->sub_sec_security.ops->unseal(&spnego_state->sub_sec_security, - mem_ctx, data, length, sig); + return gensec_unseal_packet(spnego_state->sub_sec_security, + mem_ctx, data, length, sig); } -NTSTATUS gensec_spnego_check_packet(struct gensec_security *gensec_security, +static NTSTATUS gensec_spnego_check_packet(struct gensec_security *gensec_security, TALLOC_CTX *mem_ctx, const uint8_t *data, size_t length, const DATA_BLOB *sig) @@ -81,11 +99,11 @@ NTSTATUS gensec_spnego_check_packet(struct gensec_security *gensec_security, return NT_STATUS_INVALID_PARAMETER; } - return spnego_state->sub_sec_security.ops->check_sig(&spnego_state->sub_sec_security, - mem_ctx, data, length, sig); + return gensec_check_packet(spnego_state->sub_sec_security, + mem_ctx, data, length, sig); } -NTSTATUS gensec_spnego_seal_packet(struct gensec_security *gensec_security, +static NTSTATUS gensec_spnego_seal_packet(struct gensec_security *gensec_security, TALLOC_CTX *mem_ctx, uint8_t *data, size_t length, DATA_BLOB *sig) @@ -98,11 +116,11 @@ NTSTATUS gensec_spnego_seal_packet(struct gensec_security *gensec_security, return NT_STATUS_INVALID_PARAMETER; } - return spnego_state->sub_sec_security.ops->seal(&spnego_state->sub_sec_security, - mem_ctx, data, length, sig); + return gensec_seal_packet(spnego_state->sub_sec_security, + mem_ctx, data, length, sig); } -NTSTATUS gensec_spnego_sign_packet(struct gensec_security *gensec_security, +static NTSTATUS gensec_spnego_sign_packet(struct gensec_security *gensec_security, TALLOC_CTX *mem_ctx, const uint8_t *data, size_t length, DATA_BLOB *sig) @@ -114,11 +132,11 @@ NTSTATUS gensec_spnego_sign_packet(struct gensec_security *gensec_security, return NT_STATUS_INVALID_PARAMETER; } - return spnego_state->sub_sec_security.ops->sign(&spnego_state->sub_sec_security, - mem_ctx, data, length, sig); + return gensec_sign_packet(spnego_state->sub_sec_security, + mem_ctx, data, length, sig); } -NTSTATUS gensec_spnego_session_key(struct gensec_security *gensec_security, +static NTSTATUS gensec_spnego_session_key(struct gensec_security *gensec_security, DATA_BLOB *session_key) { struct spnego_state *spnego_state = gensec_security->private_data; @@ -127,11 +145,11 @@ NTSTATUS gensec_spnego_session_key(struct gensec_security *gensec_security, return NT_STATUS_INVALID_PARAMETER; } - return spnego_state->sub_sec_security.ops->session_key(&spnego_state->sub_sec_security, - session_key); + return gensec_session_key(spnego_state->sub_sec_security, + session_key); } -NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TALLOC_CTX *out_mem_ctx, +static NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TALLOC_CTX *out_mem_ctx, const DATA_BLOB in, DATA_BLOB *out) { struct spnego_state *spnego_state = gensec_security->private_data; @@ -139,7 +157,6 @@ NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TALLOC_CT DATA_BLOB unwrapped_out; struct spnego_data spnego_out; struct spnego_data spnego; - const struct gensec_security_ops *op; ssize_t len; @@ -148,32 +165,38 @@ NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TALLOC_CT } if (spnego_state->state_position == SPNEGO_FALLBACK) { - return spnego_state->sub_sec_security.ops->update(&spnego_state->sub_sec_security, - out_mem_ctx, in, out); + return gensec_update(spnego_state->sub_sec_security, + out_mem_ctx, in, out); } len = spnego_read_data(in, &spnego); if (len == -1 && spnego_state->state_position == SPNEGO_SERVER_START) { int i; - const struct gensec_security_ops **all_ops = gensec_security_all(); - for (i=0; all_ops[i]; i++) { + int num_ops; + const struct gensec_security_ops **all_ops = gensec_security_all(&num_ops); + for (i=0; i < num_ops; i++) { NTSTATUS nt_status; - op = all_ops[i]; - if (!op->oid) { + if (!all_ops[i]->oid) { continue; } - nt_status = op->server_start(&spnego_state->sub_sec_security); + nt_status = gensec_server_start(&spnego_state->sub_sec_security); if (!NT_STATUS_IS_OK(nt_status)) { + return nt_status; + } + nt_status = gensec_start_mech_by_oid(spnego_state->sub_sec_security, + all_ops[i]->oid); + if (!NT_STATUS_IS_OK(nt_status)) { + gensec_end(&spnego_state->sub_sec_security); continue; } - nt_status = op->update(&spnego_state->sub_sec_security, - out_mem_ctx, in, out); + nt_status = gensec_update(spnego_state->sub_sec_security, + out_mem_ctx, in, out); if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { spnego_state->state_position = SPNEGO_FALLBACK; return nt_status; } - op->end(&spnego_state->sub_sec_security); + gensec_end(&spnego_state->sub_sec_security); } DEBUG(1, ("Failed to parse SPENGO request\n")); return NT_STATUS_INVALID_PARAMETER; @@ -196,33 +219,33 @@ NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TALLOC_CT NTSTATUS nt_status; for (i=0; mechType[i]; i++) { - op = gensec_security_by_oid(mechType[i]); - if (!op) { - continue; + nt_status = gensec_client_start(&spnego_state->sub_sec_security); + if (!NT_STATUS_IS_OK(nt_status)) { + break; } - spnego_state->sub_sec_security.ops = op; - spnego_state->sub_sec_security.user = gensec_security->user; - - nt_status = op->client_start(&spnego_state->sub_sec_security); + nt_status = gensec_start_mech_by_oid(spnego_state->sub_sec_security, + mechType[i]); if (!NT_STATUS_IS_OK(nt_status)) { - op->end(&spnego_state->sub_sec_security); + gensec_end(&spnego_state->sub_sec_security); continue; } + if (i == 0) { - nt_status = op->update(&spnego_state->sub_sec_security, - out_mem_ctx, - spnego.negTokenInit.mechToken, - &unwrapped_out); + nt_status = gensec_update(spnego_state->sub_sec_security, + out_mem_ctx, + spnego.negTokenInit.mechToken, + &unwrapped_out); } else { /* only get the helping start blob for the first OID */ - nt_status = op->update(&spnego_state->sub_sec_security, - out_mem_ctx, - null_data_blob, - &unwrapped_out); + nt_status = gensec_update(spnego_state->sub_sec_security, + out_mem_ctx, + null_data_blob, + &unwrapped_out); } if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { - DEBUG(1, ("SPENGO(%s) NEG_TOKEN_INIT failed: %s\n", op->name, nt_errstr(nt_status))); - op->end(&spnego_state->sub_sec_security); + DEBUG(1, ("SPENGO(%s) NEG_TOKEN_INIT failed: %s\n", + spnego_state->sub_sec_security->ops->name, nt_errstr(nt_status))); + gensec_end(&spnego_state->sub_sec_security); } else { break; } @@ -237,7 +260,7 @@ NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TALLOC_CT } /* compose reply */ - my_mechs[0] = op->oid; + my_mechs[0] = spnego_state->sub_sec_security->ops->oid; spnego_out.type = SPNEGO_NEG_TOKEN_INIT; spnego_out.negTokenInit.mechTypes = my_mechs; @@ -261,12 +284,11 @@ NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TALLOC_CT return NT_STATUS_ACCESS_DENIED; } - op = spnego_state->sub_sec_security.ops; if (spnego.negTokenTarg.responseToken.length) { - nt_status = op->update(&spnego_state->sub_sec_security, - out_mem_ctx, - spnego.negTokenTarg.responseToken, - &unwrapped_out); + nt_status = gensec_update(spnego_state->sub_sec_security, + out_mem_ctx, + spnego.negTokenTarg.responseToken, + &unwrapped_out); } else { unwrapped_out = data_blob(NULL, 0); nt_status = NT_STATUS_OK; @@ -284,7 +306,9 @@ NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TALLOC_CT /* compose reply */ spnego_out.type = SPNEGO_NEG_TOKEN_TARG; spnego_out.negTokenTarg.negResult = SPNEGO_ACCEPT_INCOMPLETE; - spnego_out.negTokenTarg.supportedMech = op->oid; + spnego_out.negTokenTarg.supportedMech + = spnego_state->sub_sec_security->ops->oid; +; spnego_out.negTokenTarg.responseToken = unwrapped_out; spnego_out.negTokenTarg.mechListMIC = null_data_blob; @@ -296,7 +320,9 @@ NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TALLOC_CT } else if (NT_STATUS_IS_OK(nt_status)) { spnego_state->state_position = SPNEGO_DONE; } else { - DEBUG(1, ("SPENGO(%s) login failed: %s\n", op->name, nt_errstr(nt_status))); + DEBUG(1, ("SPENGO(%s) login failed: %s\n", + spnego_state->sub_sec_security->ops->name, + nt_errstr(nt_status))); return nt_status; } @@ -309,13 +335,42 @@ NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TALLOC_CT } } -void gensec_spnego_end(struct gensec_security *gensec_security) +static void gensec_spnego_end(struct gensec_security *gensec_security) { struct spnego_state *spnego_state = gensec_security->private_data; - - spnego_state->sub_sec_security.ops->end(&spnego_state->sub_sec_security); + + if (spnego_state->sub_sec_security) { + gensec_end(&spnego_state->sub_sec_security); + } talloc_destroy(spnego_state->mem_ctx); gensec_security->private_data = NULL; } + +static const struct gensec_security_ops gensec_spnego_security_ops = { + .name = "spnego", + .sasl_name = "GSS-SPNEGO", + .oid = OID_SPNEGO, + .client_start = gensec_spnego_client_start, + .update = gensec_spnego_update, + .seal_packet = gensec_spnego_seal_packet, + .sign_packet = gensec_spnego_sign_packet, + .check_packet = gensec_spnego_check_packet, + .unseal_packet = gensec_spnego_unseal_packet, + .session_key = gensec_spnego_session_key, + .end = gensec_spnego_end +}; + +NTSTATUS gensec_spengo_init(void) +{ + NTSTATUS ret; + ret = register_backend("gensec", &gensec_spnego_security_ops); + if (!NT_STATUS_IS_OK(ret)) { + DEBUG(0,("Failed to register '%s' gensec backend!\n", + gensec_spnego_security_ops.name)); + return ret; + } + + return ret; +} diff --git a/source4/libcli/auth/spnego.h b/source4/libcli/auth/spnego.h index 890301314b..60ef4c1d36 100644 --- a/source4/libcli/auth/spnego.h +++ b/source4/libcli/auth/spnego.h @@ -23,12 +23,6 @@ #ifndef SAMBA_SPNEGO_H #define SAMBA_SPNEGO_H -/* SPNEGO mode */ -enum spnego_role -{ - SPNEGO_SERVER, - SPNEGO_CLIENT -}; #define SPNEGO_DELEG_FLAG 0x01 #define SPNEGO_MUTUAL_FLAG 0x02 @@ -70,23 +64,4 @@ enum spnego_message_type { SPNEGO_NEG_TOKEN_TARG = 1, }; -enum spnego_state_position { - SPNEGO_SERVER_START, - SPNEGO_CLIENT_GET_MECHS, - SPNEGO_CLIENT_SEND_MECHS, - SPNEGO_TARG, - SPNEGO_FALLBACK, - SPNEGO_DONE -}; - -struct spnego_state { - TALLOC_CTX *mem_ctx; - uint_t ref_count; - enum spnego_role role; - enum spnego_message_type expected_packet; - enum spnego_message_type state_position; - negResult_t result; - struct gensec_security sub_sec_security; -}; - #endif diff --git a/source4/libcli/config.m4 b/source4/libcli/config.m4 index 992f84005d..9e19499003 100644 --- a/source4/libcli/config.m4 +++ b/source4/libcli/config.m4 @@ -54,7 +54,8 @@ SMB_SUBSYSTEM(LIBCLI_AUTH,[], libcli/auth/kerberos_verify.o libcli/auth/clikrb5.o libcli/auth/gensec.o - libcli/auth/gensec_ntlmssp.o]) + libcli/auth/gensec_ntlmssp.o], + [], [AUTH SCHANNELDB]) SMB_SUBSYSTEM(LIBCLI_NMB,[], [libcli/unexpected.o |