s4/schema: Handle Object(OR-Name) syntax in extended_dn_out module
[gd/samba/.git] / source3 / smbd / smb2_server.c
index 1b22c8272459de7792691d0faa6380adfaa24469..9e5be404eff2c473fe20607ee5f121360aab0820 100644 (file)
@@ -420,10 +420,10 @@ struct smbd_smb2_request_pending_state {
 
 static void smbd_smb2_request_pending_writev_done(struct tevent_req *subreq);
 
-NTSTATUS smbd_smb2_request_pending_queue(struct smbd_smb2_request *req)
+NTSTATUS smbd_smb2_request_pending_queue(struct smbd_smb2_request *req,
+                                        struct tevent_req *subreq)
 {
        struct smbd_smb2_request_pending_state *state;
-       struct tevent_req *subreq;
        uint8_t *outhdr;
        int i = req->current_idx;
        uint32_t flags;
@@ -432,6 +432,13 @@ NTSTATUS smbd_smb2_request_pending_queue(struct smbd_smb2_request *req)
        uint8_t *hdr;
        uint8_t *body;
 
+       if (!tevent_req_is_in_progress(subreq)) {
+               return NT_STATUS_OK;
+       }
+
+       req->subreq = subreq;
+       subreq = NULL;
+
        outhdr = (uint8_t *)req->out.vector[i].iov_base;
 
        flags = IVAL(outhdr, SMB2_HDR_FLAGS);
@@ -559,8 +566,8 @@ static NTSTATUS smbd_smb2_request_process_cancel(struct smbd_smb2_request *req)
                }
        }
 
-       if (cur) {
-               /* TODO: try to cancel the request */
+       if (cur && cur->subreq) {
+               tevent_req_cancel(cur->subreq);
        }
 
        return NT_STATUS_OK;
@@ -574,6 +581,7 @@ static NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req)
        uint32_t flags;
        NTSTATUS status;
        NTSTATUS session_status;
+       uint32_t allowed_flags;
 
        inhdr = (const uint8_t *)req->in.vector[i].iov_base;
 
@@ -583,14 +591,15 @@ static NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req)
        opcode = IVAL(inhdr, SMB2_HDR_OPCODE);
        DEBUG(10,("smbd_smb2_request_dispatch: opcode[%u]\n", opcode));
 
-#define TMP_SMB2_ALLOWED_FLAGS ( \
-       SMB2_HDR_FLAG_CHAINED | \
-       SMB2_HDR_FLAG_SIGNED | \
-       SMB2_HDR_FLAG_DFS)
-       if ((flags & ~TMP_SMB2_ALLOWED_FLAGS) != 0) {
+       allowed_flags = SMB2_HDR_FLAG_CHAINED |
+                       SMB2_HDR_FLAG_SIGNED |
+                       SMB2_HDR_FLAG_DFS;
+       if (opcode == SMB2_OP_CANCEL) {
+               allowed_flags |= SMB2_HDR_FLAG_ASYNC;
+       }
+       if ((flags & ~allowed_flags) != 0) {
                return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
        }
-#undef TMP_SMB2_ALLOWED_FLAGS
 
        session_status = smbd_smb2_request_check_session(req);
 
@@ -795,6 +804,8 @@ static NTSTATUS smbd_smb2_request_reply(struct smbd_smb2_request *req)
 {
        struct tevent_req *subreq;
 
+       req->subreq = NULL;
+
        smb2_setup_nbt_length(req->out.vector, req->out.vector_count);
 
        if (req->do_signing) {
@@ -1328,7 +1339,13 @@ static int smbd_smb2_request_next_vector(struct tstream_context *stream,
                                 * body and let the caller deal with the error
                                 */
                                invalid = true;
-                       } else if (body_size > (full_size - SMB2_HDR_BODY)) {
+                       }
+
+                       if ((body_size % 2) != 0) {
+                               body_size -= 1;
+                       }
+
+                       if (body_size > (full_size - SMB2_HDR_BODY)) {
                                /*
                                 * this is invalid, just return a zero
                                 * body and let the caller deal with the error
@@ -1342,10 +1359,6 @@ static int smbd_smb2_request_next_vector(struct tstream_context *stream,
                        body_size = 2;
                }
 
-               if ((body_size % 2) != 0) {
-                       body_size -= 1;
-               }
-
                dyn_size = full_size - (SMB2_HDR_BODY + body_size);
 
                state->missing -= (body_size - 2) + dyn_size;