/* handle any authentication that is being requested */
if (!dcesrv_auth_bind(call)) {
- talloc_free(call->context);
- call->context = NULL;
- return dcesrv_bind_nak(call, DCERPC_BIND_REASON_INVALID_AUTH_TYPE);
+ struct dcesrv_auth *auth = &call->conn->auth_state;
+
+ TALLOC_FREE(call->context);
+
+ if (auth->auth_level != DCERPC_AUTH_LEVEL_NONE) {
+ /*
+ * We only give INVALID_AUTH_TYPE if the auth_level was
+ * valid.
+ */
+ return dcesrv_bind_nak(call,
+ DCERPC_BIND_NAK_REASON_INVALID_AUTH_TYPE);
+ }
+ return dcesrv_bind_nak(call,
+ DCERPC_BIND_NAK_REASON_NOT_SPECIFIED);
}
/* setup a bind_ack */
return false;
}
+ switch (call->in_auth_info.auth_level) {
+ case DCERPC_AUTH_LEVEL_CONNECT:
+ case DCERPC_AUTH_LEVEL_CALL:
+ case DCERPC_AUTH_LEVEL_PACKET:
+ case DCERPC_AUTH_LEVEL_INTEGRITY:
+ case DCERPC_AUTH_LEVEL_PRIVACY:
+ /*
+ * We evaluate auth_type only if auth_level was valid
+ */
+ break;
+ default:
+ /*
+ * Setting DCERPC_AUTH_LEVEL_NONE,
+ * gives the caller a chance to decide what
+ * reject_reason to use
+ *
+ * Note: DCERPC_AUTH_LEVEL_NONE == 1
+ */
+ auth->auth_type = DCERPC_AUTH_TYPE_NONE;
+ auth->auth_level = DCERPC_AUTH_LEVEL_NONE;
+ auth->auth_context_id = 0;
+ return false;
+ }
+
auth->auth_type = call->in_auth_info.auth_type;
auth->auth_level = call->in_auth_info.auth_level;
auth->auth_context_id = call->in_auth_info.auth_context_id;