Exemple #1
0
def test_090_test_auto_smb_quota(request, proto):
    """
    Since the share is configured wtih ixnas:base_user_quota parameter,
    the first SMB tree connect should have set a ZFS user quota on the
    underlying dataset. Test querying through the SMB protocol.

    Currently SMB1 protocol is disabled because of hard-coded check in
    source3/smbd/nttrans.c to only allow root to get/set quotas.
    """
    depends(request, ["BA_ADDED_TO_USER"])
    c = SMB()
    qt = c.get_quota(host=ip,
                     share=SMB_NAME,
                     username=SMB_USER,
                     password=SMB_PWD,
                     smb1=(proto == "SMB1"))

    # There should only be one quota entry
    assert len(qt) == 1, qt

    # username is prefixed with server netbios name "SERVER\user"
    assert qt[0]['user'].endswith(SMB_USER), qt

    # Hard and Soft limits should be set to value above (1GiB)
    assert qt[0]['soft_limit'] == (2**30), qt
    assert qt[0]['hard_limit'] == (2**30), qt
Exemple #2
0
def test_152_check_xattr_via_smb(request, xat):
    """
    Read xattr that was written via SSH and verify that
    data is same when viewed over SMB.
    """
    depends(request, ["SSH_XATTR_SET"])
    afptestfile = f'afp_xattr_testfile:{AFPXattr[xat]["smbname"]}'
    bytes = AFPXattr[xat][
        "smb_bytes"] if xat == "org.netatalk.Metadata" else AFPXattr[xat][
            "bytes"]
    c = SMB()
    c.connect(host=ip,
              share=SMB_NAME,
              username=SMB_USER,
              password=SMB_PWD,
              smb1=False)
    fd = c.create_file(afptestfile, "w")
    xat_bytes = c.read(fd, 0, len(bytes) + 1)
    c.close(fd)
    c.disconnect()

    err = {"name": xat, "b64data": b64encode(bytes)}

    # Python base64 library appends a `\t` to end of byte string
    assert xat_bytes == bytes, str(err)
Exemple #3
0
def test_007_check_shadow_copies(request, proto):
    """
    This is very basic validation of presence of snapshot
    over SMB1 and SMB2/3.
    """
    depends(request, ["VSS_USER_CREATED"])
    c = SMB()
    snaps = c.get_shadow_copies(host=ip,
                                share=SMB_NAME,
                                username=SMB_USER,
                                password=SMB_PWD,
                                smb1=(proto == "SMB1"))
    assert len(snaps) == 1, snaps
Exemple #4
0
def test_009_check_shadow_copies_count_after_setup(request, proto):
    """
    This is very basic validation of presence of snapshot
    over SMB1 and SMB2/3.
    """
    depends(request, ["VSS_USER_CREATED"])
    c = SMB()
    snaps = c.get_shadow_copies(host=ip,
                                share=SMB_NAME,
                                username=SMB_USER,
                                password=SMB_PWD,
                                smb1=(proto == "SMB1"))
    assert len(snaps) == 4, snaps
    snaps.sort()
    for idx, gmt in enumerate(snaps[1:]):
        snapshots[f'snapshot{idx + 1}']['gmt_string'] = gmt
Exemple #5
0
def test_060_create_base_file_for_streams_tests(request):
    """
    Create the base file that we will use for further stream tests.
    """
    depends(request, ["SMB_SHARE_CREATED"])
    c = SMB()
    c.connect(host=ip,
              share=SMB_NAME,
              username=SMB_USER,
              password=SMB_PWD,
              smb1=True)
    fd = c.create_file("streamstestfile", "w")
    c.close(fd)
    c.disconnect()
Exemple #6
0
def test_153_unlink_xattr_via_smb(request, xat):
    """
    Open AFP xattr, set "delete on close" flag, then close.
    """
    depends(request, ["XATTR_CHECK_SMB_READ"])
    afptestfile = f'afp_xattr_testfile:{AFPXattr[xat]["smbname"]}'
    c = SMB()
    c.connect(host=ip,
              share=SMB_NAME,
              username=SMB_USER,
              password=SMB_PWD,
              smb1=False)
    fd = c.create_file(afptestfile, "w")
    c.close(fd, True)
    c.disconnect()
Exemple #7
0
def test_011_check_dos_ro_cred_handling(request):
    """
    This test creates a file with readonly attribute set, then
    uses the open fd to write data to the file.
    """
    depends(request, ["SHARE_IS_WRITABLE"])
    c = SMB()
    c.connect(host=ip,
              share=SMB_NAME,
              username=SMB_USER,
              password=SMB_PWD,
              smb1=False)
    fd = c.create_file("RO_TEST", "w", "r")
    c.write(fd, b"TESTING123\n")
    c.disconnect()
Exemple #8
0
def test_176_validate_microsoft_account_behavior(request, proto):
    """
    This test creates creates an empty file, sets "delete on close" flag, then
    closes it. NTStatusError should be raised containing failure details
    if we are for some reason unable to access the share.

    This test will fail if smb.conf / smb4.conf does not exist on client / server running test.
    """
    depends(request, ["SMB_SHARE_CREATED"])
    c = SMB()
    c.connect(host=ip,
              share=SMB_NAME,
              username=sample_email,
              password=SMB_PWD,
              smb1=(proto == 'SMB1'))
    fd = c.create_file("testfile", "w")
    c.close(fd, True)
    c.disconnect()
Exemple #9
0
def test_009_share_is_writable(request):
    """
    This test creates creates an empty file, sets "delete on close" flag, then
    closes it. NTStatusError should be raised containing failure details
    if we are for some reason unable to access the share.

    This test will fail if smb.conf / smb4.conf does not exist on client / server running test.
    """
    depends(request, ["SMB_SHARE_CREATED"])
    c = SMB()
    c.connect(host=ip,
              share=SMB_NAME,
              username=SMB_USER,
              password=SMB_PWD,
              smb1=False)
    fd = c.create_file("testfile", "w")
    c.close(fd, True)
    c.disconnect()
Exemple #10
0
def smb_connection(**kwargs):
    c = SMB()
    c.connect(**kwargs)

    try:
        yield c
    finally:
        c.disconnect()
Exemple #11
0
def test_067_stream_delete_on_close_smb1(request):
    """
    Set delete_on_close on alternate datastream over SMB1 protocol, close, then verify
    stream was deleted.

    TODO: I have open MR to expand samba python bindings to support stream enumeration.
    Verifcation of stream deletion will have to be added once this is merged.
    """
    depends(request, ["STREAM_WRITTEN_SMB1", "LARGE_STREAM_WRITTEN_SMB1"])
    c = SMB()
    c.connect(host=ip,
              share=SMB_NAME,
              username=SMB_USER,
              password=SMB_PWD,
              smb1=True)
    fd = c.create_file("streamstestfile:smb1_stream", "w")
    c.close(fd, True)

    c.disconnect()
Exemple #12
0
def test_051_share_is_writable_smb1(request):
    """
    This test creates creates an empty file, sets "delete on close" flag, then
    closes it. NTStatusError should be raised containing failure details
    if we are for some reason unable to access the share.

    This test will fail if client min protocol != NT1 in smb.conf of SMB client.
    Sample smb.conf entry:

    [global]
    client min protocol = nt1
    """
    depends(request, ["SMB_SHARE_CREATED"])
    c = SMB()
    c.connect(host=ip,
              share=SMB_NAME,
              username=SMB_USER,
              password=SMB_PWD,
              smb1=True)
    fd = c.create_file("testfile", "w")
    c.close(fd, True)
    c.disconnect()
Exemple #13
0
def test_092_set_smb_quota(request, proto):
    """
    This test checks our ability to set a ZFS quota
    through the SMB protocol by first setting a 2 GiB
    quota, then reading it through the SMB protocol, then
    resetting to zero.
    """
    depends(request, ["BA_ADDED_TO_USER"])
    new_quota = 2 * (2**30)
    c = SMB()
    qt = c.set_quota(host=ip,
                     share=SMB_NAME,
                     username=SMB_USER,
                     password=SMB_PWD,
                     hardlimit=new_quota,
                     target=SMB_USER,
                     smb1=(proto == "SMB1"))
    assert len(qt) == 1, qt
    assert qt[0]['user'].endswith(SMB_USER), qt
    assert qt[0]['soft_limit'] == new_quota, qt
    assert qt[0]['hard_limit'] == new_quota, qt

    qt = c.get_quota(host=ip,
                     share=SMB_NAME,
                     username=SMB_USER,
                     password=SMB_PWD,
                     smb1=(proto == "SMB1"))
    assert len(qt) == 1, qt
    assert qt[0]['user'].endswith(SMB_USER), qt
    assert qt[0]['soft_limit'] == new_quota, qt
    assert qt[0]['hard_limit'] == new_quota, qt

    qt = c.set_quota(host=ip,
                     share=SMB_NAME,
                     username=SMB_USER,
                     password=SMB_PWD,
                     hardlimit=-1,
                     target=SMB_USER,
                     smb1=(proto == "SMB1"))
    assert len(qt) == 1, qt
    assert qt[0]['user'].endswith(SMB_USER), qt
    assert qt[0]['soft_limit'] is None, qt
    assert qt[0]['hard_limit'] is None, qt

    qt = c.get_quota(host=ip,
                     share=SMB_NAME,
                     username=SMB_USER,
                     password=SMB_PWD,
                     smb1=(proto == "SMB1"))
    assert len(qt) == 1, qt
    assert qt[0]['user'].endswith(SMB_USER), qt
    assert qt[0]['soft_limit'] is None, qt
    assert qt[0]['hard_limit'] is None, qt
Exemple #14
0
def test_154_write_afp_xattr_via_smb(request, xat):
    """
    Write xattr over SMB
    """
    depends(request, ["XATTR_CHECK_SMB_UNLINK"])
    afptestfile = f'afp_xattr_testfile:{AFPXattr[xat]["smbname"]}'
    payload = AFPXattr[xat][
        "smb_bytes"] if xat == "org.netatalk.Metadata" else AFPXattr[xat][
            "bytes"]
    c = SMB()
    c.connect(host=ip,
              share=SMB_NAME,
              username=SMB_USER,
              password=SMB_PWD,
              smb1=False)
    fd = c.create_file(afptestfile, "w")
    c.write(fd, payload)
    c.close(fd)
    c.disconnect()
Exemple #15
0
def test_052_check_dosmode_create_smb1(request, dm):
    """
    This tests the setting of different DOS attributes through SMB1 create.
    after setting
    """
    depends(request, ["SHARE_IS_WRITABLE"])
    if dm.value > DOSmode.SYSTEM.value:
        return

    c = SMB()
    c.connect(host=ip,
              share=SMB_NAME,
              username=SMB_USER,
              password=SMB_PWD,
              smb1=True)
    if dm == DOSmode.READONLY:
        c.create_file(f'{dm.name}_smb1', "w", "r")
    elif dm == DOSmode.HIDDEN:
        c.create_file(f'{dm.name}_smb1', "w", "h")
    elif dm == DOSmode.SYSTEM:
        c.create_file(f'{dm.name}_smb1', "w", "s")
    dir_listing = c.ls("/")
    for f in dir_listing:
        if f['name'] != f'{dm.name}_smb1':
            continue
        # Archive is automatically set by kernel
        to_check = f['attrib'] & ~DOSmode.ARCHIVE.value
        c.disconnect()
        assert (to_check & dm.value) != 0, f
Exemple #16
0
def test_065_create_and_write_stream_smb1(request):
    """
    Create our initial stream and write to it over SMB1 protocol.
    Start with offset 0.
    """
    depends(request, ["STREAM_TESTFILE_CREATED"])
    c = SMB()
    c.connect(host=ip,
              share=SMB_NAME,
              username=SMB_USER,
              password=SMB_PWD,
              smb1=True)
    fd = c.create_file("streamstestfile:smb1_stream", "w")
    c.write(fd, b'test1', 0)
    c.close(fd)

    fd2 = c.create_file("streamstestfile:smb1_stream", "w")
    contents = c.read(fd2, 0, 5)
    c.close(fd2)
    c.disconnect()
    assert (contents.decode() == "test1")
Exemple #17
0
def test_066_write_stream_large_offset_smb1(request):
    """
    Append to our existing stream over SMB1 protocol. Specify an offset that will
    cause resuling xattr to exceed 64KiB default xattr size limit in Linux.
    """
    depends(request, ["STREAM_WRITTEN_SMB1"])
    c = SMB()
    c.connect(host=ip,
              share=SMB_NAME,
              username=SMB_USER,
              password=SMB_PWD,
              smb1=True)
    fd = c.create_file("streamstestfile:smb1_stream", "w")
    c.write(fd, b'test2', 131072)
    c.close(fd)

    fd2 = c.create_file("streamstestfile:smb1_stream", "w")
    contents = c.read(fd2, 131072, 5)
    c.close(fd2)
    c.disconnect()
    assert (contents.decode() == "test2")
Exemple #18
0
def test_069_normal_rename(request):
    """
    This verifies that renames are successfully completed
    """
    depends(request, ["SHARE_IS_WRITABLE"])
    c = SMB()
    c.connect(host=ip,
              share=SMB_NAME,
              username=SMB_USER,
              password=SMB_PWD,
              smb1=True)
    fd = c.create_file("old_file_to_rename", "w")
    c.close(fd)
    c.rename("old_file_to_rename", "renamed_new_file")
    files = [x['name'] for x in c.ls('\\')]
    c.disconnect()
    assert ("renamed_new_file" in files)
Exemple #19
0
def test_068_case_insensitive_rename(request):
    """
    ZFS is case sensitive, but case preserving when casesensitivity == insensitive

    rename of to_rename -> To_rename should succeed and new file appear
    correctly in directory listing.

    Will fail with NT_STATUS_OBJECT_NAME_COLLISION if we have regression and
    samba identifies files as same.
    """
    depends(request, ["SHARE_IS_WRITABLE"])
    c = SMB()
    c.connect(host=ip,
              share=SMB_NAME,
              username=SMB_USER,
              password=SMB_PWD,
              smb1=True)
    fd = c.create_file("to_rename", "w")
    c.close(fd)
    c.rename("to_rename", "To_rename")
    files = [x['name'] for x in c.ls('\\')]
    c.disconnect()
    assert ("To_rename" in files)
Exemple #20
0
def test_008_set_up_testfiles(request, payload):
    depends(request, ["SHARE_HAS_SHADOW_COPIES"])
    i = int(payload[-1])
    offset = i * 2 * len(payload)
    c = SMB()
    c.connect(host=ip,
              share=SMB_NAME,
              username=SMB_USER,
              password=SMB_PWD,
              smb1=False)

    for f in to_check:
        fd = c.create_file(f, "w")
        c.write(fd, payload.encode(), offset)
        c.close(fd)

        fd = c.create_file(f'{f}:smb2_stream', 'w')
        c.write(fd, payload.encode(), offset)
        c.close(fd)

    sleep(5)
    result = POST("/zfs/snapshot/", {
        "dataset": dataset,
        "name": payload,
        "recursive": True,
    })
    assert result.status_code == 200, results.text