In the function 'make_connection_snum' there is a call to vfs_ChDir within a CHECK_PATH_ON_TCONX block that is called before SMB_VFS_CONNECT. This might not have been noticed because it works as long as the local directory, which 'vfs_ChDir' refers to, exists. In the case of our global file systems (http://www.nirvanastorage.com) this is almost never the case so that this call always fails if we don't create a dummy local directory.
If you look closely, you'll see that CHECK_PATH_ON_TCONX is never defined so all we do is a stat() to confirm that the path is indeed a directory. Same end result though. This is by design. We have to somehow check the validity of a share at connection time. I'm not familiar with gfs but can't you just trigger the gfs access via a preexec script ? Of course, I'm always willing to look at patches.
There are two problems with the code: 1) IF and ONLY IF the CHECK_PATH_ON_TCONX IS DEFINED, a vfs_ChDir will be called BEFORE a SMB_VFS_CONNECT. This cannot work. 2) IF CHECK_PATH_ON_TCONX IS NOT DEFINED, a call to 'stat' is made to verify the validity of the share, which should be replaced by a call to SMB_VFS_STAT since the share path is not necessarily local. The code below shows a suggested fix for the 2 problems: /*********************************************************************/ /* this code block was moved up from the end of make_connection_snum */ /*********************************************************************/ /* Invoke VFS make connection hook */ if (SMB_VFS_CONNECT(conn, lp_servicename(snum), user) < 0) { DEBUG(0,("make_connection: VFS make connection failed!\n")); change_to_root_user(); conn_free(conn); *status = NT_STATUS_UNSUCCESSFUL; return NULL; } #if CHECK_PATH_ON_TCONX /* win2000 does not check the permissions on the directory during the tree connect, instead relying on permission check during individual operations. To match this behaviour I have disabled this chdir check (tridge) */ if (vfs_ChDir(conn,conn->connectpath) != 0) { DEBUG(0,("%s (%s) Can't change directory to %s (%s)\n", get_remote_machine_name(), conn->client_address, conn->connectpath,strerror(errno))); change_to_root_user(); yield_connection(conn, lp_servicename(SNUM(conn))); conn_free(conn); *status = NT_STATUS_BAD_NETWORK_NAME; return NULL; } #else /* the alternative is just to check the directory exists */ /******************************************************************************* ******************************/ /* this code was changed from 'stat(conn->connectpath, &st)' to 'SMB_VFS_STAT (conn, conn->connectpath, &st)' */ /******************************************************************************* ******************************/ if (SMB_VFS_STAT(conn, conn->connectpath, &st) != 0 || !S_ISDIR (st.st_mode)) { DEBUG(0,("'%s' does not exist or is not a directory, when connecting to [%s]\n", conn->connectpath, lp_servicename(SNUM(conn)))); change_to_root_user(); yield_connection(conn, lp_servicename(SNUM(conn))); conn_free(conn); *status = NT_STATUS_BAD_NETWORK_NAME; return NULL; } #endif
Fixed in SVN - thanks. Jeremy.
Jeremy, you only applied the obviously correct portion of the patch (s/stat/SMB_VFS_STAT/g)
(In reply to comment #2) > There are two problems with the code: > 1) IF and ONLY IF the CHECK_PATH_ON_TCONX IS DEFINED, > a vfs_ChDir will be called BEFORE a SMB_VFS_CONNECT. This cannot work. That code should be removed. It will never be used again. > 2) IF CHECK_PATH_ON_TCONX IS NOT DEFINED, a call to 'stat' > is made to verify the validity of the share, which should be > replaced by a call to SMB_VFS_STAT since the share path > is not necessarily local. ok. That makes sense. What doesn't make sense is the move of the SMB_VFS_CONNECT() before the SMB_VFS_STAT() call. Do you have your opwn vfs module ? I can't find any reference to one if your bug report. That would help me understand why the reordering would help. The default nfswrap_dummy_connect() just returns 0.
The SMB_VFS_CONNECT() call needs to happen before any other calls to any VFS module. It doesn't make a difference for a local file system (where nfswrap_dummy_connect is used) but a real VFS module needs to initialize itself and potentially create a connection to a remote file system. Without this connection (established in SMB_VFS_CONNECT) any subsequent VFS calls will fail.
this bug is only partially fixed in 3.0.14a. The SMB_VFS_CONNECT block still needs to move BEFORE the SMB_VFS_STAT block. How can you perform a VFS operation on a VFS module without first establishing a connection to the VFS module? Thanks for looking into this, Constantin
Fixed in 3.0.20pre code. Jeremy.
sorry for the same, cleaning up the database to prevent unecessary reopens of bugs.