Correct "overriden" typos.
[nivanova/samba-autobuild/.git] / auth / gensec / gensec.c
index abcbcb95067b5f1dbf7872eb304a1e5d9ec1a94b..d623613769174d5a920feb225572ce2750023f02 100644 (file)
 
 #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
@@ -40,9 +51,15 @@ _PUBLIC_ NTSTATUS gensec_unseal_packet(struct gensec_security *gensec_security,
        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,
@@ -80,6 +97,9 @@ _PUBLIC_ NTSTATUS gensec_seal_packet(struct gensec_security *gensec_security,
        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);
 }
@@ -108,6 +128,11 @@ _PUBLIC_ size_t gensec_sig_size(struct gensec_security *gensec_security, size_t
        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);
 }
@@ -202,20 +227,41 @@ _PUBLIC_ size_t gensec_max_update_size(struct gensec_security *gensec_security)
        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;
@@ -225,8 +271,25 @@ _PUBLIC_ NTSTATUS gensec_update(struct gensec_security *gensec_security, TALLOC_
 
        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;
                }
@@ -239,31 +302,9 @@ _PUBLIC_ NTSTATUS gensec_update(struct gensec_security *gensec_security, TALLOC_
                 * 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;
@@ -271,8 +312,23 @@ _PUBLIC_ NTSTATUS gensec_update(struct gensec_security *gensec_security, TALLOC_
 
        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);
@@ -285,6 +341,24 @@ _PUBLIC_ NTSTATUS gensec_update(struct gensec_security *gensec_security, TALLOC_
        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;
@@ -403,34 +477,9 @@ static void gensec_update_subreq_done(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);
@@ -492,7 +541,7 @@ _PUBLIC_ void gensec_want_feature(struct gensec_security *gensec_security,
 _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;
        }
 
@@ -561,7 +610,7 @@ _PUBLIC_ NTSTATUS gensec_set_target_hostname(struct gensec_security *gensec_secu
 
 _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;
        }