From patchwork Fri Jun 28 07:08:37 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Steve French X-Patchwork-Id: 1124003 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-cifs-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="aA4yKQ92"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 45ZntW5Ht4z9s7h for ; Fri, 28 Jun 2019 17:08:51 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726828AbfF1HIu (ORCPT ); Fri, 28 Jun 2019 03:08:50 -0400 Received: from mail-pl1-f171.google.com ([209.85.214.171]:45634 "EHLO mail-pl1-f171.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726947AbfF1HIt (ORCPT ); Fri, 28 Jun 2019 03:08:49 -0400 Received: by mail-pl1-f171.google.com with SMTP id bi6so2706947plb.12 for ; Fri, 28 Jun 2019 00:08:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:from:date:message-id:subject:to; bh=sbCtySyG/9fHGgOfVGmRAFyptQXgGv58u3Mjq2Ac6B8=; b=aA4yKQ92O1sHsx8lEfkHqJTA/7EVik9dzllu9yAcMzSXoVJewQKBZtSeSJb0Ni3wLa K/yUAl/3S3MpOlWX+Fa5sPHFk9HhEYzKx43sDE5naSrTGPD1oVsuWdt3Ug20lH9/47jc vJibtNZioN/WJo3aumfb4zhbf8CSt0iA8Ukbvm1m2MS10bPerSJaBBfPeQZL30i+Givy S/5hZ+uhgnacpGGr7MqfzWKusve8wCwBTUoueVYUYOSKgx03Q6EMbj3+nLOJIiNztW/e BMcIrCfachYJyDWsfB8Z/KBKVPFnUNkleUYdOb9H9XOPiynaoxCQW18QZh8Bosi8DZ/K IKnQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:from:date:message-id:subject:to; bh=sbCtySyG/9fHGgOfVGmRAFyptQXgGv58u3Mjq2Ac6B8=; b=AYDeSxnVFM3KgE61DK01ddmE7UG69/xj1H+pYcfUGQTwhZ3i0evZTcTs17+hU+0ArO NxSZTwcx09ofHzNHThZQOb79K5XUUUTK+zEd+VluexEhliwPXoviIOO4VEZlcHUpR/0U XW6bXggQ1hNRYkn66RY3fkOTxfK8hXkVGoSJo1Y7ui9WgZmwxu41en7ZwanwBWW4x9iC sQ47wl3WaxsxbqXmwE7hhqgedT6hY/4MuopdCQ87bz5uv7RCiUAJVfYyHJ27ZQwo/6zg SFTE7CgZBSjFPS+BoSsor7Hyz+8N4Hk7FydAUDjWDQyEGGxZxpBvPQxuFSVkmTohvxRQ SeNw== X-Gm-Message-State: APjAAAUDYp+PVWvycSleFzOfw5AxeIdUTbeXh2rXAy59AfWiKyCIkF/G Yhrl0Uj8nRqm9yqzDUzSQcfTqvTlMq8a/LZimZq7eMXs X-Google-Smtp-Source: APXvYqwVb5nnwm9cm3oprVXuEFHi1uBZp34+mpFGqQ3N6LMf+N3K2RAOIf/I1ZFj62w6shCvPrbXICF9mQsE278dO5U= X-Received: by 2002:a17:902:20b:: with SMTP id 11mr9852924plc.78.1561705728498; Fri, 28 Jun 2019 00:08:48 -0700 (PDT) MIME-Version: 1.0 From: Steve French Date: Fri, 28 Jun 2019 02:08:37 -0500 Message-ID: Subject: [PATCH]Fix querying symlinks To: CIFS , samba-technical Sender: linux-cifs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org Querying of symlinks to the Samba server with POSIX extensions works! (Also would work for querying symlinks generated in Windows NFS server) # stat /mnt1/symlink-source File: /mnt1/symlink-source -> symlink-target Size: 14 Blocks: 2048 IO Block: 16384 symbolic link Device: 39h/57d Inode: 10354691 Links: 1 Access: (0000/l---------) Uid: ( 0/ root) Gid: ( 0/ root) Access: 2019-06-28 01:43:37.145324400 -0500 Modify: 2019-06-28 01:43:37.145324400 -0500 Change: 2019-06-28 01:43:37.145324400 -0500 Birth: - From aaaead73b2fe84bfe56423ca528a6fcf5c2ea4f6 Mon Sep 17 00:00:00 2001 From: Steve French Date: Fri, 28 Jun 2019 02:04:18 -0500 Subject: [PATCH] smb3: Allow query of symlinks stored as reparse points The 'NFS' style symlinks (see MS-FSCC 2.1.2.4) were not being queried properly in query_symlink. Fix this. Signed-off-by: Steve French --- fs/cifs/smb2ops.c | 60 ++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 54 insertions(+), 6 deletions(-) diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c index 75f3348a471e..c4047ad7b43f 100644 --- a/fs/cifs/smb2ops.c +++ b/fs/cifs/smb2ops.c @@ -2373,6 +2373,39 @@ smb2_get_dfs_refer(const unsigned int xid, struct cifs_ses *ses, return rc; } +static int +parse_reparse_posix(struct reparse_posix_data *symlink_buf, + u32 plen, char **target_path, + struct cifs_sb_info *cifs_sb) +{ + unsigned int len; + + /* See MS-FSCC 2.1.2.6 for the 'NFS' style reparse tags */ + len = le16_to_cpu(symlink_buf->ReparseDataLength); + + if (len + sizeof(struct reparse_data_buffer) > plen) { + cifs_dbg(VFS, "srv returned malformed symlink buffer\n"); + return -EINVAL; + } + + if (le64_to_cpu(symlink_buf->InodeType) != NFS_SPECFILE_LNK) { + cifs_dbg(VFS, "%lld not a supported symlink type\n", + le64_to_cpu(symlink_buf->InodeType)); + return -EOPNOTSUPP; + } + + *target_path = cifs_strndup_from_utf16( + symlink_buf->PathBuffer, + len, true, cifs_sb->local_nls); + if (!(*target_path)) + return -ENOMEM; + + convert_delimiter(*target_path, '/'); + cifs_dbg(FYI, "%s: target path: %s\n", __func__, *target_path); + + return 0; +} + static int parse_reparse_symlink(struct reparse_symlink_data_buffer *symlink_buf, u32 plen, char **target_path, @@ -2381,11 +2414,7 @@ parse_reparse_symlink(struct reparse_symlink_data_buffer *symlink_buf, unsigned int sub_len; unsigned int sub_offset; - /* We only handle Symbolic Link : MS-FSCC 2.1.2.4 */ - if (le32_to_cpu(symlink_buf->ReparseTag) != IO_REPARSE_TAG_SYMLINK) { - cifs_dbg(VFS, "srv returned invalid symlink buffer\n"); - return -EIO; - } + /* We handle Symbolic Link reparse tag here. See: MS-FSCC 2.1.2.4 */ sub_offset = le16_to_cpu(symlink_buf->SubstituteNameOffset); sub_len = le16_to_cpu(symlink_buf->SubstituteNameLength); @@ -2407,6 +2436,25 @@ parse_reparse_symlink(struct reparse_symlink_data_buffer *symlink_buf, return 0; } +static int +parse_reparse_point(struct reparse_symlink_data_buffer *buf, + u32 plen, char **target_path, + struct cifs_sb_info *cifs_sb) +{ + /* See MS-FSCC 2.1.2 */ + if (le32_to_cpu(buf->ReparseTag) == IO_REPARSE_TAG_NFS) + return parse_reparse_posix((struct reparse_posix_data *)buf, + plen, target_path, cifs_sb); + else if (le32_to_cpu(buf->ReparseTag) == IO_REPARSE_TAG_SYMLINK) + return parse_reparse_symlink(buf, plen, target_path, + cifs_sb); + + cifs_dbg(VFS, "srv returned invalid symlink buffer tag:%d\n", + le32_to_cpu(buf->ReparseTag)); + + return -EIO; +} + #define SMB2_SYMLINK_STRUCT_SIZE \ (sizeof(struct smb2_err_rsp) - 1 + sizeof(struct smb2_symlink_err_rsp)) @@ -2547,7 +2595,7 @@ smb2_query_symlink(const unsigned int xid, struct cifs_tcon *tcon, goto querty_exit; } - rc = parse_reparse_symlink( + rc = parse_reparse_point( (struct reparse_symlink_data_buffer *)reparse_buf, plen, target_path, cifs_sb); goto querty_exit; -- 2.20.1