When the client uses SMB2 to communicate with a server, and performs a stat on a non-existing file when operating through a DFS link, and is authenticated, the call gets an EINVAL error code rather than the expected ENOENT (which is correctly returned when operating in SMB1/CIFS mode). The bug was observed in these specific conditions, however it also likely applies for a direct stat without DFS getting in the way. I traced the bug to a difference in the SMB1 and SMB2 code paths - in the SMB1 code path, cli->raw_status is set to the status code from the SMB operation, but in the SMB2 code paths that does not occur. To reproduce, run a Samba server with a DFS link and an available user, then compile and run the following program, making sure to have `client max protocol = SMB2` set in smb.conf. Notice the '22' error code (EINVAL) while '2' is expected (ENOENT): ``` #include <libsmbclient.h> #include <stdio.h> #include <errno.h> #include <string.h> const char *guser = "test"; const char *gpass = "test"; /* example url uses DFS root /dfs, with link /dfs/public, and Test.pdf does not exist */ const char *url = "smb://172.17.0.2/dfs/public/Test.pdf"; void authfn(SMBCCTX *ctx, const char *server, const char *share, char *wkgp, int wkgplen, char *user, int userlen, char *pass, int passlen) { strcpy(user, guser); strcpy(pass, gpass); } int main() { SMBCCTX *ctx = smbc_new_context(); smbc_setFunctionAuthDataWithContext(ctx, authfn); ctx = smbc_init_context(ctx); smbc_stat_fn smbc_stat = smbc_getFunctionStat(ctx); struct stat statbuf; printf("smbc_stat(): %d\n", smbc_stat(ctx, url, &statbuf)); printf("errno: %d\n", errno); smbc_free_context(ctx, 1); return 0; } ```
Potential patch at https://github.com/samba-team/samba/pull/59
Just reproduced the bug without DFS or authentication, so it's unrelated to them. The bug is now simpler: performing a stat on a non-existing file at the SMB2 protocol level will result in an EINVAL, not the expected ENOENT.
*** This bug has been marked as a duplicate of bug 11276 ***