/* * Common create file function. The file is opened in compatibility * mode with read/write access. */ uint32_t smb_common_create(smb_request_t *sr) { struct open_param *op = &sr->arg.open; uint32_t status; if ((op->mtime.tv_sec != 0) && (op->mtime.tv_sec != UINT_MAX)) op->mtime.tv_sec = smb_time_local_to_gmt(sr, op->mtime.tv_sec); op->mtime.tv_nsec = 0; op->dsize = 0; op->omode = SMB_DA_ACCESS_READ_WRITE | SMB_DA_SHARE_COMPATIBILITY; op->desired_access = smb_omode_to_amask(op->omode); op->share_access = smb_denymode_to_sharemode(op->omode, op->fqi.fq_path.pn_path); if (sr->smb_flg & SMB_FLAGS_OPLOCK) { if (sr->smb_flg & SMB_FLAGS_OPLOCK_NOTIFY_ANY) op->op_oplock_level = SMB_OPLOCK_BATCH; else op->op_oplock_level = SMB_OPLOCK_EXCLUSIVE; } else { op->op_oplock_level = SMB_OPLOCK_NONE; } op->op_oplock_levelII = B_FALSE; status = smb_common_open(sr); if (op->op_oplock_level == SMB_OPLOCK_NONE) { sr->smb_flg &= ~(SMB_FLAGS_OPLOCK | SMB_FLAGS_OPLOCK_NOTIFY_ANY); } return (status); }
/* * smb_pre_open_andx * For compatibility with windows servers, the search attributes * specified in the request are ignored. */ smb_sdrc_t smb_pre_open_andx(smb_request_t *sr) { struct open_param *op = &sr->arg.open; uint16_t flags; uint32_t creation_time; uint16_t file_attr, sattr; int rc; bzero(op, sizeof (sr->arg.open)); rc = smbsr_decode_vwv(sr, "b.wwwwwlwll4.", &sr->andx_com, &sr->andx_off, &flags, &op->omode, &sattr, &file_attr, &creation_time, &op->ofun, &op->dsize, &op->timeo); if (rc == 0) { rc = smbsr_decode_data(sr, "%u", sr, &op->fqi.fq_path.pn_path); op->dattr = file_attr; if (flags & 2) op->op_oplock_level = SMB_OPLOCK_EXCLUSIVE; else if (flags & 4) op->op_oplock_level = SMB_OPLOCK_BATCH; else op->op_oplock_level = SMB_OPLOCK_NONE; if ((creation_time != 0) && (creation_time != UINT_MAX)) op->crtime.tv_sec = smb_time_local_to_gmt(sr, creation_time); op->crtime.tv_nsec = 0; op->create_disposition = smb_ofun_to_crdisposition(op->ofun); } DTRACE_SMB_2(op__OpenX__start, smb_request_t *, sr, struct open_param *, op); return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR); }
smb_sdrc_t smb_com_trans2_open2(smb_request_t *sr, smb_xa_t *xa) { struct open_param *op = &sr->arg.open; uint32_t creation_time; uint32_t alloc_size; uint16_t flags; uint16_t file_attr; int rc; bzero(op, sizeof (sr->arg.open)); rc = smb_mbc_decodef(&xa->req_param_mb, "%wwwwlwl10.u", sr, &flags, &op->omode, &op->fqi.fq_sattr, &file_attr, &creation_time, &op->ofun, &alloc_size, &op->fqi.fq_path.pn_path); if (rc != 0) return (SDRC_ERROR); if ((creation_time != 0) && (creation_time != UINT_MAX)) op->crtime.tv_sec = smb_time_local_to_gmt(sr, creation_time); op->crtime.tv_nsec = 0; op->dattr = file_attr; op->dsize = alloc_size; op->create_options = FILE_NON_DIRECTORY_FILE; op->desired_access = smb_omode_to_amask(op->omode); op->share_access = smb_denymode_to_sharemode(op->omode, op->fqi.fq_path.pn_path); op->create_disposition = smb_ofun_to_crdisposition(op->ofun); if (op->create_disposition > FILE_MAXIMUM_DISPOSITION) op->create_disposition = FILE_CREATE; if (op->omode & SMB_DA_WRITE_THROUGH) op->create_options |= FILE_WRITE_THROUGH; if (sr->smb_flg & SMB_FLAGS_OPLOCK) { if (sr->smb_flg & SMB_FLAGS_OPLOCK_NOTIFY_ANY) op->op_oplock_level = SMB_OPLOCK_BATCH; else op->op_oplock_level = SMB_OPLOCK_EXCLUSIVE; } else { op->op_oplock_level = SMB_OPLOCK_NONE; } if (smb_common_open(sr) != NT_STATUS_SUCCESS) return (SDRC_ERROR); if (op->op_oplock_level != SMB_OPLOCK_NONE) op->action_taken |= SMB_OACT_LOCK; else op->action_taken &= ~SMB_OACT_LOCK; file_attr = op->dattr & FILE_ATTRIBUTE_MASK; if (!STYPE_ISDSK(sr->tid_tree->t_res_type)) op->dsize = 0; (void) smb_mbc_encodef(&xa->rep_param_mb, "wwllwwwwlwl", sr->smb_fid, file_attr, (uint32_t)0, /* creation time */ (uint32_t)op->dsize, op->omode, op->ftype, op->devstate, op->action_taken, op->fileid, (uint16_t)0, /* EA error offset */ (uint32_t)0); /* EA list length */ return (SDRC_SUCCESS); }