wa2c / cifs-documents-provider

CIFS Documents Provider
MIT License
273 stars 24 forks source link

Can read but not write data #29

Open unoukujou opened 2 years ago

unoukujou commented 2 years ago

Unknown issue for me that only happens if I'm using cifs-documents-provider:

Read Files/Folders = YES Create Files/Folders = YES (but only 0 byte files can be created) Rename Files/Folder = YES Delete Files/Folders = YES Write/Modify Files = NO! (only happen with cifs-documents-provider. Access any other way is working fine)

I tried with 2 different Samba shares. One shared from Windows, another shared from Debian and both are the same way.

Both of my samba shares I can access from other apps and write files just fine. I can mount them in Windows/Linux/ChromeOS and all behaving properly where I can read and write without problem.

This is only happening to me with cifs-documents-provider but I don't know why. I tested with 2 of my android devices Samsung Galaxy and Google Pixel, Samsung is Android 12 and Pixel is Android 10.

I installed Material FIles ( https://github.com/zhanghai/MaterialFiles ) and it gives me this error when I try to write files through cifs-documents-provider:

error while writing
There was an error writing "file.txt". java.io.IOException: write failed: EBADF (Bad file descriptor)

Material Files also has ability to add network storage so when I add the samba server through Material FIles (Menu -> Add storage -> SMB Server) I can read/write perfectly with Material FIles. Only problem happens if I try to use cifs-documents-provider (Menu -> Add storage -> External storage -> choose CIFS Documents Provider from the side menu and add the share to Material Files).

Any app that I use and I want to open a file from CIFS Documents Provider, the file will open, but cannot write. Here Material Files is just for example of one app. But it happens for all apps.

I don't know why. I'll be happy to try anything if you have suggestions.

Otherwise it's a very good app at least for read-only. But to be able to write will be even better. Thanks.

zer0ring commented 1 year ago

I have this exact same issue with exactly the same symptoms in similar environment. Read ok, writes produce 0kb files with error Bad file descriptor, Android 11, SMB share (proto v2 & v3, no v1 support) provided by SAMBA running under Linux with anonymous access & operations from other apps work fine so it's not a permissions issue, it's an issue in cifs-documents-provider.

YanceyChiew commented 1 year ago

SAMBA running under Linux with anonymous acces

I'm not sure if the anonymous access mentioned here is consistent with what this app expects. Just for reference, you can uncheck the Anonymous Access box, and try leaving the username and password blank, or use guest as the username.

zer0ring commented 1 year ago

I unchecked the Anonymous Access box, left the username and password blank, same result (0kb files with error Bad file descriptor). I used guest as the username, left the password blank, same result ( 0kb files with error Bad file descriptor). During both these attempts I was able to connect, browse, create directories, but saving files fails with the above error.

Tried transferring a jpg file from Android downloads dir, same result. Tried saving mp4 from NewPipe, as usr="guest" pwd="", same result, error log is below if it helps (probably won't, identifying info redacted):

## Exception
* __User Action:__ download failed
* __Request:__ https://www.youtube.com/watch?v=xrrPG_VlvIQ [ {type=video format=MPEG-4 quality=480p videoOnly=true} {type=audio format=m4a bitrate=48} ]
* __Content Country:__ ██
* __Content Language:__ en-██
* __App Language:__ en_██
* __Service:__ YouTube
* __Version:__ 0.24.1
* __OS:__ Linux ██████/██████_retail/██████:11/████.██-██-██/dbe8d:user/release-keys 11 - ██
<details><summary><b>Crash log </b></summary><p>

java.io.IOException: write failed: EBADF (Bad file descriptor)
 at libcore.io.IoBridge.write(IoBridge.java:540)
 at java.io.FileOutputStream.write(FileOutputStream.java:398)
 at us.shandian.giga.io.FileStreamSAF.write(FileStreamSAF.java:133)
 at us.shandian.giga.get.DownloadRunnable.run(DownloadRunnable.java:120)
Caused by: android.system.ErrnoException: write failed: EBADF (Bad file descriptor)
 at libcore.io.Linux.writeBytes(Native Method)
 at libcore.io.Linux.write(Linux.java:293)
 at libcore.io.ForwardingOs.write(ForwardingOs.java:240)
 at libcore.io.BlockGuardOs.write(BlockGuardOs.java:418)
 at libcore.io.ForwardingOs.write(ForwardingOs.java:240)
 at libcore.io.IoBridge.write(IoBridge.java:535)
 ... 3 more


Target1 share is hosted by Linux system running LibreElec (Kodi). Retried the above but using a different SMB target hosted by another Linux system employing username & password access control, jpg transfer succeeded but NewPipe mp4 save failed as above. Downloaded the mp4 via NewPipe ensuring no whitespace or illegal chars in filename (just in case) to Android downloads dir (to ensure full file available before SMB transfer started) then used share function (long press, share) to transfer mp4 file to target1, mp4 transfer failed as above. Repeated the last test against target2, successfully transferred mp4.

It seems:

  1. Downloading files from remote host via NewPipe with output to either SMB target via CIFS Doc Prov fails (0kb, EBADF).
  2. Transferring local files to SMB target1 fails (0kb, EBADF).
  3. Transferring local files to SMB target2 succeeds.

Either way, I can't use CIFS Doc Prov to save mp4/m4a/etc from remote hosts via NewPipe to any SMB target, which is what I wanted to achieve to spare my phone storage from being worn down by local save then transfer via Total Commander LAN Plugin.

YanceyChiew commented 1 year ago

According to the above content, one possibility I can think of is that the smb account has write permission to the directory, so it can create/delete files, but it does not have write permission to the created file, so it cannot modify or truncate the file.

This is indeed a bit strange, because the creator of the file, that is, its owner, should have write permission to the file by default. To rule out this possibility, check the permission similarities and differences between the files that were written successfully and those that failed.

zer0ring commented 1 year ago

I just tried test transfer of locally stored xkcd.jpg file from Android via CDP to target1 (failed) & target2 (succeeded), ls -l of file in each target:

  1. -rwxr--r-- 1 root root 0 xkcd.jpg
  2. -rwxrwxrwx+ 1 user users 90874 xkcd.jpg

Further test via SSH in same targets/dirs as xkcd.jpg, using root in target1 & sudoer user in target2, touch test && ls -l test:

  1. -rw-r--r-- 1 root root 0 test
  2. -rwxrwxrwx+ 1 user users 0 test

Also, as above, running ls -l on the dir itself in each target:

  1. drwxr-xr-x 13 root root 1024 somedir
  2. drwxrwxrwx+ 1 user users 1040 somedir

Octal permissions in the target1:

Octal permissions in the target2:

zer0ring commented 1 year ago

In case it sheds some light, samba.conf in target1 is below:

# SPDX-License-Identifier: GPL-2.0-or-later
# Copyright (C) 2009-2016 Stephan Raue (stephan@openelec.tv)
# Copyright (C) 2017-present Team LibreELEC (https://libreelec.tv)

[global]
  server string = LibreELEC
  browseable = yes
  writeable = yes
  printable = no
  deadtime = 30
  mangled names = no
  name resolve order = host bcast
  printcap name = /dev/null
  load printers = no
  enable core files = no
  passdb backend = smbpasswd
  smb encrypt = disabled
  fruit:model = Xserve

  # samba share options
  map to guest = Bad User
  guest account = root
  security = user

  # samba tuning options
  socket options = TCP_NODELAY IPTOS_LOWDELAY
  min receivefile size = 16384
  aio read size = 16384
  aio write size = 16384
  use sendfile = yes

# Using the following configurations as a template allows you to add
# writeable shares of disks and paths under /storage

[Some Dir]
  path = /storage/somedir
  available = yes
  browseable = yes
  public = yes
  writeable = yes
  root preexec = mkdir -p /storage/somedir
jeyjai commented 1 year ago

Has anyone found a way to transfer files to your SMB through CDP? Or any other way to get around this? Im basically trying to download files with yt-dlp straight to my SMB drive

@zer0ring im a bit slow so I don't really understand your comment other than you managed to transfer a file with a specific setup, is that correct and if so, how do i replicate it on my phone with CDP?