/* trans2 open implementation */ static NTSTATUS trans2_open(struct smbsrv_request *req, struct trans_op *op) { struct smb_trans2 *trans = op->trans; union smb_open *io; /* make sure we got enough parameters */ if (trans->in.params.length < 29) { return NT_STATUS_FOOBAR; } io = talloc(op, union smb_open); NT_STATUS_HAVE_NO_MEMORY(io); io->t2open.level = RAW_OPEN_T2OPEN; io->t2open.in.flags = SVAL(trans->in.params.data, VWV(0)); io->t2open.in.open_mode = SVAL(trans->in.params.data, VWV(1)); io->t2open.in.search_attrs = SVAL(trans->in.params.data, VWV(2)); io->t2open.in.file_attrs = SVAL(trans->in.params.data, VWV(3)); io->t2open.in.write_time = srv_pull_dos_date(req->smb_conn, trans->in.params.data + VWV(4)); io->t2open.in.open_func = SVAL(trans->in.params.data, VWV(6)); io->t2open.in.size = IVAL(trans->in.params.data, VWV(7)); io->t2open.in.timeout = IVAL(trans->in.params.data, VWV(9)); io->t2open.in.num_eas = 0; io->t2open.in.eas = NULL; smbsrv_blob_pull_string(&req->in.bufinfo, &trans->in.params, 28, &io->t2open.in.fname, 0); if (io->t2open.in.fname == NULL) { return NT_STATUS_FOOBAR; } TRANS2_CHECK(ea_pull_list(&trans->in.data, io, &io->t2open.in.num_eas, &io->t2open.in.eas)); op->op_info = io; op->send_fn = trans2_open_send; return ntvfs_open(req->ntvfs, io); }
NTSTATUS smbsrv_pull_passthru_sfileinfo(TALLOC_CTX *mem_ctx, enum smb_setfileinfo_level level, union smb_setfileinfo *st, const DATA_BLOB *blob, int default_str_flags, struct smbsrv_request *req) { uint32_t len; DATA_BLOB str_blob; switch (level) { case SMB_SFILEINFO_BASIC_INFORMATION: BLOB_CHECK_MIN_SIZE(blob, 36); st->basic_info.in.create_time = pull_nttime(blob->data, 0); st->basic_info.in.access_time = pull_nttime(blob->data, 8); st->basic_info.in.write_time = pull_nttime(blob->data, 16); st->basic_info.in.change_time = pull_nttime(blob->data, 24); st->basic_info.in.attrib = IVAL(blob->data, 32); return NT_STATUS_OK; case SMB_SFILEINFO_DISPOSITION_INFORMATION: BLOB_CHECK_MIN_SIZE(blob, 1); st->disposition_info.in.delete_on_close = CVAL(blob->data, 0); return NT_STATUS_OK; case SMB_SFILEINFO_ALLOCATION_INFORMATION: BLOB_CHECK_MIN_SIZE(blob, 8); st->allocation_info.in.alloc_size = BVAL(blob->data, 0); return NT_STATUS_OK; case RAW_SFILEINFO_END_OF_FILE_INFORMATION: BLOB_CHECK_MIN_SIZE(blob, 8); st->end_of_file_info.in.size = BVAL(blob->data, 0); return NT_STATUS_OK; case RAW_SFILEINFO_RENAME_INFORMATION: if (!req) { /* * TODO: get rid of smbsrv_request argument of * smbsrv_blob_pull_string() */ return NT_STATUS_NOT_IMPLEMENTED; } BLOB_CHECK_MIN_SIZE(blob, 12); st->rename_information.in.overwrite = CVAL(blob->data, 0); st->rename_information.in.root_fid = IVAL(blob->data, 4); len = IVAL(blob->data, 8); str_blob.data = blob->data+12; str_blob.length = MIN(blob->length, len); smbsrv_blob_pull_string(req, &str_blob, 0, &st->rename_information.in.new_name, STR_UNICODE); if (st->rename_information.in.new_name == NULL) { return NT_STATUS_FOOBAR; } return NT_STATUS_OK; case RAW_SFILEINFO_POSITION_INFORMATION: BLOB_CHECK_MIN_SIZE(blob, 8); st->position_information.in.position = BVAL(blob->data, 0); return NT_STATUS_OK; case RAW_SFILEINFO_MODE_INFORMATION: BLOB_CHECK_MIN_SIZE(blob, 4); st->mode_information.in.mode = IVAL(blob->data, 0); return NT_STATUS_OK; default: return NT_STATUS_INVALID_LEVEL; } return NT_STATUS_INVALID_LEVEL; }
NTSTATUS smbsrv_pull_passthru_sfileinfo(TALLOC_CTX *mem_ctx, enum smb_setfileinfo_level level, union smb_setfileinfo *st, const DATA_BLOB *blob, int default_str_flags, struct request_bufinfo *bufinfo) { uint32_t len, ofs; DATA_BLOB str_blob; switch (level) { case SMB_SFILEINFO_BASIC_INFORMATION: BLOB_CHECK_MIN_SIZE(blob, 40); st->basic_info.in.create_time = pull_nttime(blob->data, 0); st->basic_info.in.access_time = pull_nttime(blob->data, 8); st->basic_info.in.write_time = pull_nttime(blob->data, 16); st->basic_info.in.change_time = pull_nttime(blob->data, 24); st->basic_info.in.attrib = IVAL(blob->data, 32); st->basic_info.in.reserved = IVAL(blob->data, 36); return NT_STATUS_OK; case SMB_SFILEINFO_DISPOSITION_INFORMATION: BLOB_CHECK_MIN_SIZE(blob, 1); st->disposition_info.in.delete_on_close = CVAL(blob->data, 0); return NT_STATUS_OK; case SMB_SFILEINFO_ALLOCATION_INFORMATION: BLOB_CHECK_MIN_SIZE(blob, 8); st->allocation_info.in.alloc_size = BVAL(blob->data, 0); return NT_STATUS_OK; case RAW_SFILEINFO_END_OF_FILE_INFORMATION: BLOB_CHECK_MIN_SIZE(blob, 8); st->end_of_file_info.in.size = BVAL(blob->data, 0); return NT_STATUS_OK; case RAW_SFILEINFO_RENAME_INFORMATION: if (!bufinfo) { return NT_STATUS_INTERNAL_ERROR; } BLOB_CHECK_MIN_SIZE(blob, 12); st->rename_information.in.overwrite = CVAL(blob->data, 0); st->rename_information.in.root_fid = IVAL(blob->data, 4); len = IVAL(blob->data, 8); ofs = 12; str_blob = *blob; str_blob.length = MIN(str_blob.length, ofs+len); smbsrv_blob_pull_string(bufinfo, &str_blob, ofs, &st->rename_information.in.new_name, STR_UNICODE); if (st->rename_information.in.new_name == NULL) { return NT_STATUS_FOOBAR; } return NT_STATUS_OK; case RAW_SFILEINFO_LINK_INFORMATION: if (!bufinfo) { return NT_STATUS_INTERNAL_ERROR; } BLOB_CHECK_MIN_SIZE(blob, 20); st->link_information.in.overwrite = CVAL(blob->data, 0); st->link_information.in.root_fid = IVAL(blob->data, 8); len = IVAL(blob->data, 16); ofs = 20; str_blob = *blob; str_blob.length = MIN(str_blob.length, ofs+len); smbsrv_blob_pull_string(bufinfo, &str_blob, ofs, &st->link_information.in.new_name, STR_UNICODE); if (st->link_information.in.new_name == NULL) { return NT_STATUS_FOOBAR; } return NT_STATUS_OK; case RAW_SFILEINFO_RENAME_INFORMATION_SMB2: /* SMB2 uses a different format for rename information */ if (!bufinfo) { return NT_STATUS_INTERNAL_ERROR; } BLOB_CHECK_MIN_SIZE(blob, 20); st->rename_information.in.overwrite = CVAL(blob->data, 0); st->rename_information.in.root_fid = BVAL(blob->data, 8); len = IVAL(blob->data,16); ofs = 20; str_blob = *blob; str_blob.length = MIN(str_blob.length, ofs+len); smbsrv_blob_pull_string(bufinfo, &str_blob, ofs, &st->rename_information.in.new_name, STR_UNICODE); if (st->rename_information.in.new_name == NULL) { return NT_STATUS_FOOBAR; } return NT_STATUS_OK; case RAW_SFILEINFO_POSITION_INFORMATION: BLOB_CHECK_MIN_SIZE(blob, 8); st->position_information.in.position = BVAL(blob->data, 0); return NT_STATUS_OK; case RAW_SFILEINFO_MODE_INFORMATION: BLOB_CHECK_MIN_SIZE(blob, 4); st->mode_information.in.mode = IVAL(blob->data, 0); return NT_STATUS_OK; default: return NT_STATUS_INVALID_LEVEL; } }