#include "includes.h"
#include "system/network.h"
+#define TEVENT_DEPRECATED 1
#include <tevent.h>
#include "lib/tsocket/tsocket.h"
#include "lib/util/tevent_ntstatus.h"
#include "auth/gensec/gensec.h"
#include "auth/gensec/gensec_internal.h"
-#include "librpc/rpc/dcerpc.h"
+#include "librpc/gen_ndr/dcerpc.h"
+
+_PRIVATE_ NTSTATUS gensec_may_reset_crypto(struct gensec_security *gensec_security,
+ bool full_reset)
+{
+ if (!gensec_security->ops->may_reset_crypto) {
+ return NT_STATUS_OK;
+ }
+
+ return gensec_security->ops->may_reset_crypto(gensec_security, full_reset);
+}
/*
wrappers for the gensec function pointers
if (!gensec_security->ops->unseal_packet) {
return NT_STATUS_NOT_IMPLEMENTED;
}
+ if (!gensec_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
if (!gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL)) {
return NT_STATUS_INVALID_PARAMETER;
}
+ if (!gensec_have_feature(gensec_security, GENSEC_FEATURE_DCE_STYLE)) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
return gensec_security->ops->unseal_packet(gensec_security,
data, length,
if (!gensec_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) {
return NT_STATUS_INVALID_PARAMETER;
}
+ if (!gensec_have_feature(gensec_security, GENSEC_FEATURE_DCE_STYLE)) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
return gensec_security->ops->seal_packet(gensec_security, mem_ctx, data, length, whole_pdu, pdu_length, sig);
}
if (!gensec_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) {
return 0;
}
+ if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL)) {
+ if (!gensec_have_feature(gensec_security, GENSEC_FEATURE_DCE_STYLE)) {
+ return 0;
+ }
+ }
return gensec_security->ops->sig_size(gensec_security, data_size);
}
return gensec_security->max_update_size;
}
-/**
- * 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.
- */
+static NTSTATUS gensec_verify_features(struct gensec_security *gensec_security)
+{
+ /*
+ * gensec_want_feature(GENSEC_FEATURE_SIGN)
+ * and
+ * gensec_want_feature(GENSEC_FEATURE_SEAL)
+ * require these flags to be available.
+ */
+ if (gensec_security->want_features & GENSEC_FEATURE_SIGN) {
+ if (!gensec_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) {
+ DEBUG(0,("Did not manage to negotiate mandatory feature "
+ "SIGN\n"));
+ return NT_STATUS_ACCESS_DENIED;
+ }
+ }
+ if (gensec_security->want_features & GENSEC_FEATURE_SEAL) {
+ if (!gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL)) {
+ DEBUG(0,("Did not manage to negotiate mandatory feature "
+ "SEAL\n"));
+ return NT_STATUS_ACCESS_DENIED;
+ }
+ if (!gensec_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) {
+ DEBUG(0,("Did not manage to negotiate mandatory feature "
+ "SIGN for SEAL\n"));
+ return NT_STATUS_ACCESS_DENIED;
+ }
+ }
-_PUBLIC_ NTSTATUS gensec_update(struct gensec_security *gensec_security, TALLOC_CTX *out_mem_ctx,
- struct tevent_context *ev,
- const DATA_BLOB in, DATA_BLOB *out)
+ return NT_STATUS_OK;
+}
+
+_PUBLIC_ NTSTATUS gensec_update_ev(struct gensec_security *gensec_security,
+ TALLOC_CTX *out_mem_ctx,
+ struct tevent_context *ev,
+ const DATA_BLOB in, DATA_BLOB *out)
{
NTSTATUS status;
const struct gensec_security_ops *ops = gensec_security->ops;
if (ops->update_send == NULL) {
+ if (ev == NULL) {
+ frame = talloc_stackframe();
+
+ ev = samba_tevent_context_init(frame);
+ if (ev == NULL) {
+ status = NT_STATUS_NO_MEMORY;
+ goto fail;
+ }
+
+ /*
+ * TODO: remove this hack once the backends
+ * are fixed.
+ */
+ tevent_loop_allow_nesting(ev);
+ }
+
status = ops->update(gensec_security, out_mem_ctx,
ev, in, out);
+ TALLOC_FREE(frame);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
* these are not points of negotiation, but are
* asserted by the client
*/
- switch (gensec_security->dcerpc_auth_level) {
- case DCERPC_AUTH_LEVEL_INTEGRITY:
- if (!gensec_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) {
- DEBUG(0,("Did not manage to negotiate mandetory feature "
- "SIGN for dcerpc auth_level %u\n",
- gensec_security->dcerpc_auth_level));
- return NT_STATUS_ACCESS_DENIED;
- }
- break;
- case DCERPC_AUTH_LEVEL_PRIVACY:
- if (!gensec_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) {
- DEBUG(0,("Did not manage to negotiate mandetory feature "
- "SIGN for dcerpc auth_level %u\n",
- gensec_security->dcerpc_auth_level));
- return NT_STATUS_ACCESS_DENIED;
- }
- if (!gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL)) {
- DEBUG(0,("Did not manage to negotiate mandetory feature "
- "SEAL for dcerpc auth_level %u\n",
- gensec_security->dcerpc_auth_level));
- return NT_STATUS_ACCESS_DENIED;
- }
- break;
- default:
- break;
+ status = gensec_verify_features(gensec_security);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
}
return NT_STATUS_OK;
frame = talloc_stackframe();
+ if (ev == NULL) {
+ ev = samba_tevent_context_init(frame);
+ if (ev == NULL) {
+ status = NT_STATUS_NO_MEMORY;
+ goto fail;
+ }
+
+ /*
+ * TODO: remove this hack once the backends
+ * are fixed.
+ */
+ tevent_loop_allow_nesting(ev);
+ }
+
subreq = ops->update_send(frame, ev, gensec_security, in);
if (subreq == NULL) {
+ status = NT_STATUS_NO_MEMORY;
goto fail;
}
ok = tevent_req_poll_ntstatus(subreq, ev, &status);
return status;
}
+/**
+ * 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.
+ */
+
+_PUBLIC_ NTSTATUS gensec_update(struct gensec_security *gensec_security,
+ TALLOC_CTX *out_mem_ctx,
+ const DATA_BLOB in, DATA_BLOB *out)
+{
+ return gensec_update_ev(gensec_security, out_mem_ctx, NULL, in, out);
+}
+
struct gensec_update_state {
const struct gensec_security_ops *ops;
struct tevent_req *subreq;
* these are not points of negotiation, but are
* asserted by the client
*/
- switch (state->gensec_security->dcerpc_auth_level) {
- case DCERPC_AUTH_LEVEL_INTEGRITY:
- if (!gensec_have_feature(state->gensec_security, GENSEC_FEATURE_SIGN)) {
- DEBUG(0,("Did not manage to negotiate mandetory feature "
- "SIGN for dcerpc auth_level %u\n",
- state->gensec_security->dcerpc_auth_level));
- tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
- return;
- }
- break;
- case DCERPC_AUTH_LEVEL_PRIVACY:
- if (!gensec_have_feature(state->gensec_security, GENSEC_FEATURE_SIGN)) {
- DEBUG(0,("Did not manage to negotiate mandetory feature "
- "SIGN for dcerpc auth_level %u\n",
- state->gensec_security->dcerpc_auth_level));
- tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
- return;
- }
- if (!gensec_have_feature(state->gensec_security, GENSEC_FEATURE_SEAL)) {
- DEBUG(0,("Did not manage to negotiate mandetory feature "
- "SEAL for dcerpc auth_level %u\n",
- state->gensec_security->dcerpc_auth_level));
- tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
- return;
- }
- break;
- default:
- break;
+ status = gensec_verify_features(state->gensec_security);
+ if (tevent_req_nterror(req, status)) {
+ return;
}
tevent_req_done(req);
_PUBLIC_ bool gensec_have_feature(struct gensec_security *gensec_security,
uint32_t feature)
{
- if (!gensec_security->ops->have_feature) {
+ if (!gensec_security->ops || !gensec_security->ops->have_feature) {
return false;
}
_PUBLIC_ const char *gensec_get_target_hostname(struct gensec_security *gensec_security)
{
- /* We allow the target hostname to be overriden for testing purposes */
+ /* We allow the target hostname to be overridden for testing purposes */
if (gensec_security->settings->target_hostname) {
return gensec_security->settings->target_hostname;
}