/*
 * FileAlternateNameInformation
 */
static uint32_t
smb2_qif_altname(smb_request_t *sr, smb_queryinfo_t *qi)
{
	smb_ofile_t *of = sr->fid_ofile;

	ASSERT(qi->qi_namelen > 0);
	ASSERT(qi->qi_attr.sa_mask & SMB_AT_NODEID);

	if (of->f_ftype != SMB_FTYPE_DISK)
		return (NT_STATUS_OBJECT_NAME_NOT_FOUND);
	if ((of->f_tree->t_flags & SMB_TREE_SHORTNAMES) == 0)
		return (NT_STATUS_OBJECT_NAME_NOT_FOUND);

	smb_query_shortname(of->f_node, qi);

	return (0);
}
Esempio n. 2
0
/*
 * FileAlternateNameInformation
 * See also:
 *	SMB_QUERY_FILE_ALT_NAME_INFO
 *	SMB_FILE_ALT_NAME_INFORMATION
 */
static uint32_t
smb2_qif_altname(smb_request_t *sr, smb_queryinfo_t *qi)
{
    smb_ofile_t *of = sr->fid_ofile;

    ASSERT(qi->qi_namelen > 0);
    ASSERT(qi->qi_attr.sa_mask & SMB_AT_NODEID);

    if (of->f_ftype != SMB_FTYPE_DISK)
        return (NT_STATUS_OBJECT_NAME_NOT_FOUND);
    if ((of->f_tree->t_flags & SMB_TREE_SHORTNAMES) == 0)
        return (NT_STATUS_OBJECT_NAME_NOT_FOUND);

    /* fill in qi->qi_shortname */
    smb_query_shortname(of->f_node, qi);

    (void) smb_mbc_encodef(
        &sr->raw_data, "%lU", sr,
        smb_wcequiv_strlen(qi->qi_shortname),
        qi->qi_shortname);

    return (0);
}
/*
 * smb_query_fileinfo
 *
 * Populate smb_queryinfo_t structure for SMB_FTYPE_DISK
 * (This should become an smb_ofile / smb_node function.)
 */
int
smb_query_fileinfo(smb_request_t *sr, smb_node_t *node, uint16_t infolev,
    smb_queryinfo_t *qinfo)
{
	int rc = 0;

	/* If shortname required but not supported -> OBJECT_NAME_NOT_FOUND */
	if ((infolev == SMB_QUERY_FILE_ALT_NAME_INFO) ||
	    (infolev == SMB_FILE_ALT_NAME_INFORMATION)) {
		if (!smb_tree_has_feature(sr->tid_tree, SMB_TREE_SHORTNAMES)) {
			smbsr_error(sr, NT_STATUS_OBJECT_NAME_NOT_FOUND,
			    ERRDOS, ERROR_FILE_NOT_FOUND);
			return (-1);
		}
	}

	(void) bzero(qinfo, sizeof (smb_queryinfo_t));

	/* See: smb_query_encode_response */
	qinfo->qi_attr.sa_mask = SMB_AT_ALL;
	rc = smb_node_getattr(sr, node, sr->user_cr, sr->fid_ofile,
	    &qinfo->qi_attr);
	if (rc != 0) {
		smbsr_error(sr, NT_STATUS_INTERNAL_ERROR,
		    ERRDOS, ERROR_INTERNAL_ERROR);
		return (-1);
	}

	qinfo->qi_node = node;
	qinfo->qi_delete_on_close =
	    (node->flags & NODE_FLAGS_DELETE_ON_CLOSE) != 0;

	/*
	 * The number of links reported should be the number of
	 * non-deleted links. Thus if delete_on_close is set,
	 * decrement the link count.
	 */
	if (qinfo->qi_delete_on_close &&
	    qinfo->qi_attr.sa_vattr.va_nlink > 0) {
		--(qinfo->qi_attr.sa_vattr.va_nlink);
	}

	/*
	 * populate name, namelen and shortname ONLY for the information
	 * levels that require these fields
	 */
	switch (infolev) {
	case SMB_QUERY_FILE_ALL_INFO:
	case SMB_FILE_ALL_INFORMATION:
		rc = smb_query_pathname(sr, node, B_TRUE, qinfo);
		break;
	case SMB_QUERY_FILE_NAME_INFO:
	case SMB_FILE_NAME_INFORMATION:
		rc = smb_query_pathname(sr, node, B_FALSE, qinfo);
		break;
	case SMB_QUERY_FILE_ALT_NAME_INFO:
	case SMB_FILE_ALT_NAME_INFORMATION:
		smb_query_shortname(node, qinfo);
		break;
	default:
		break;
	}

	if (rc != 0) {
		smbsr_errno(sr, rc);
		return (-1);
	}
	return (0);
}