/* * smb2_sign_reply * * Calculates MAC signature for the given mbuf chain, * and write it to the signature field in the mbuf. * */ void smb2_sign_reply(smb_request_t *sr) { uint8_t reply_sig[SMB2_SIG_SIZE]; struct mbuf_chain tmp_mbc; smb_session_t *s = sr->session; smb_user_t *u = sr->uid_user; int hdr_off, msg_len; if (u == NULL) return; if (s->sign_calc == NULL) return; msg_len = sr->reply.chain_offset - sr->smb2_reply_hdr; (void) MBC_SHADOW_CHAIN(&tmp_mbc, &sr->reply, sr->smb2_reply_hdr, msg_len); /* * Calculate the MAC signature for this reply. * smb2_sign_calc() or smb3_sign_calc() */ if (s->sign_calc(sr, &tmp_mbc, reply_sig) != 0) return; /* * Poke the signature into the response. */ hdr_off = sr->smb2_reply_hdr + SMB2_SIG_OFFS; (void) smb_mbc_poke(&sr->reply, hdr_off, "#c", SMB2_SIG_SIZE, reply_sig); }
/* * smb2_sign_reply * * Calculates MAC signature for the given mbuf chain, * and write it to the signature field in the mbuf. * */ void smb2_sign_reply(smb_request_t *sr) { uint8_t digest[SHA256_DIGEST_LENGTH]; struct mbuf_chain tmp_mbc; struct smb_sign *sign = &sr->session->signing; int hdr_off, msg_len; msg_len = sr->reply.chain_offset - sr->smb2_reply_hdr; (void) MBC_SHADOW_CHAIN(&tmp_mbc, &sr->reply, sr->smb2_reply_hdr, msg_len); /* * Calculate MAC signature */ if (smb2_sign_calc(&tmp_mbc, sign, digest) != 0) return; /* * Poke the signature into the response. */ hdr_off = sr->smb2_reply_hdr + SMB2_SIG_OFFS; (void) smb_mbc_poke(&sr->reply, hdr_off, "#c", SMB2_SIG_SIZE, digest); }
int smb2_encode_header(smb_request_t *sr, boolean_t overwrite) { uint64_t ssnid = sr->smb_uid; uint64_t pid_tid_aid; /* pid+tid, or async id */ int rc; if (sr->smb2_hdr_flags & SMB2_FLAGS_ASYNC_COMMAND) { pid_tid_aid = sr->smb2_async_id; } else { pid_tid_aid = sr->smb_pid | ((uint64_t)sr->smb_tid) << 32; } if (overwrite) { rc = smb_mbc_poke(&sr->reply, sr->smb2_reply_hdr, "Nwwlwwllqqq16c", SMB2_HDR_SIZE, /* w */ sr->smb2_credit_charge, /* w */ sr->smb2_status, /* l */ sr->smb2_cmd_code, /* w */ sr->smb2_credit_response, /* w */ sr->smb2_hdr_flags, /* l */ sr->smb2_next_reply, /* l */ sr->smb2_messageid, /* q */ pid_tid_aid, /* q */ ssnid, /* q */ sr->smb2_sig); /* 16c */ } else { rc = smb_mbc_encodef(&sr->reply, "Nwwlwwllqqq16c", SMB2_HDR_SIZE, /* w */ sr->smb2_credit_charge, /* w */ sr->smb2_status, /* l */ sr->smb2_cmd_code, /* w */ sr->smb2_credit_response, /* w */ sr->smb2_hdr_flags, /* l */ sr->smb2_next_reply, /* l */ sr->smb2_messageid, /* q */ pid_tid_aid, /* q */ ssnid, /* q */ sr->smb2_sig); /* 16c */ } return (rc); }
void smb_reply_notify_change_request(smb_request_t *sr) { smb_node_t *node; smb_srqueue_t *srq; int total_bytes, n_setup, n_param, n_data; int param_off, param_pad, data_off, data_pad; struct smb_xa *xa; smb_error_t err; SMB_REQ_VALID(sr); srq = sr->session->s_srqueue; smb_srqueue_waitq_to_runq(srq); xa = sr->r_xa; node = sr->sr_ncr.nc_node; if (--node->waiting_event == 0) { node->flags &= ~(NODE_FLAGS_NOTIFY_CHANGE | NODE_FLAGS_CHANGED); smb_fem_fcn_uninstall(node); } mutex_enter(&sr->sr_mutex); switch (sr->sr_state) { case SMB_REQ_STATE_EVENT_OCCURRED: sr->sr_state = SMB_REQ_STATE_ACTIVE; /* many things changed */ (void) smb_mbc_encodef(&xa->rep_data_mb, "l", 0L); /* setup the NT transact reply */ n_setup = MBC_LENGTH(&xa->rep_setup_mb); n_param = MBC_LENGTH(&xa->rep_param_mb); n_data = MBC_LENGTH(&xa->rep_data_mb); n_setup = (n_setup + 1) / 2; /* Convert to setup words */ param_pad = 1; /* must be one */ param_off = param_pad + 32 + 37 + (n_setup << 1) + 2; /* Pad to 4 bytes */ data_pad = (4 - ((param_off + n_param) & 3)) % 4; /* Param off from hdr */ data_off = param_off + n_param + data_pad; total_bytes = param_pad + n_param + data_pad + n_data; (void) smbsr_encode_result(sr, 18+n_setup, total_bytes, "b3.llllllllbCw#.C#.C", 18 + n_setup, /* wct */ n_param, /* Total Parameter Bytes */ n_data, /* Total Data Bytes */ n_param, /* Total Parameter Bytes this buffer */ param_off, /* Param offset from header start */ 0, /* Param displacement */ n_data, /* Total Data Bytes this buffer */ data_off, /* Data offset from header start */ 0, /* Data displacement */ n_setup, /* suwcnt */ &xa->rep_setup_mb, /* setup[] */ total_bytes, /* Total data bytes */ param_pad, &xa->rep_param_mb, data_pad, &xa->rep_data_mb); break; case SMB_REQ_STATE_CANCELED: err.status = NT_STATUS_CANCELLED; err.errcls = ERRDOS; err.errcode = ERROR_OPERATION_ABORTED; smbsr_set_error(sr, &err); (void) smb_mbc_encodef(&sr->reply, "bwbw", (short)0, 0L, (short)0, 0L); sr->smb_wct = 0; sr->smb_bcc = 0; break; default: ASSERT(0); } mutex_exit(&sr->sr_mutex); /* Setup the header */ (void) smb_mbc_poke(&sr->reply, 0, SMB_HEADER_ED_FMT, sr->first_smb_com, sr->smb_rcls, sr->smb_reh, sr->smb_err, sr->smb_flg | SMB_FLAGS_REPLY, sr->smb_flg2, sr->smb_pid_high, sr->smb_sig, sr->smb_tid, sr->smb_pid, sr->smb_uid, sr->smb_mid); if (sr->session->signing.flags & SMB_SIGNING_ENABLED) smb_sign_reply(sr, NULL); /* send the reply */ DTRACE_PROBE1(ncr__reply, struct smb_request *, sr) (void) smb_session_send(sr->session, 0, &sr->reply); smbsr_cleanup(sr); mutex_enter(&sr->sr_mutex); sr->sr_state = SMB_REQ_STATE_COMPLETED; mutex_exit(&sr->sr_mutex); smb_srqueue_runq_exit(srq); smb_request_free(sr); }