#define DBGC_CLASS DBGC_MSDFS
#include "includes.h"
-
-extern uint32 global_client_caps;
+#include "smbd/globals.h"
/**********************************************************************
Parse a DFS pathname of the form \hostname\service\reqpath
Note this CHANGES CWD !!!! JRA.
*********************************************************/
-static NTSTATUS create_conn_struct(TALLOC_CTX *ctx,
+NTSTATUS create_conn_struct(TALLOC_CTX *ctx,
connection_struct **pconn,
int snum,
- const char *path)
+ const char *path,
+ struct auth_serversupplied_info *server_info,
+ char **poldcwd)
{
connection_struct *conn;
char *connpath;
+ char *oldcwd;
conn = TALLOC_ZERO_P(ctx, connection_struct);
if (conn == NULL) {
conn->params->service = snum;
+ if (server_info != NULL) {
+ conn->server_info = copy_serverinfo(conn, server_info);
+ if (conn->server_info == NULL) {
+ DEBUG(0, ("copy_serverinfo failed\n"));
+ TALLOC_FREE(conn);
+ return NT_STATUS_NO_MEMORY;
+ }
+ }
+
set_conn_connectpath(conn, connpath);
if (!smbd_vfs_init(conn)) {
* user we will fail.... WTF ? JRA.
*/
+ oldcwd = vfs_GetWd(ctx, conn);
+ if (oldcwd == NULL) {
+ NTSTATUS status = map_nt_error_from_unix(errno);
+ DEBUG(3, ("vfs_GetWd failed: %s\n", strerror(errno)));
+ conn_free_internal(conn);
+ return status;
+ }
+
if (vfs_ChDir(conn,conn->connectpath) != 0) {
NTSTATUS status = map_nt_error_from_unix(errno);
DEBUG(3,("create_conn_struct: Can't ChDir to new conn path %s. "
}
*pconn = conn;
+ *poldcwd = oldcwd;
return NT_STATUS_OK;
}
NTSTATUS status = NT_STATUS_NOT_FOUND;
bool dummy;
struct dfs_path *pdp = TALLOC_P(ctx, struct dfs_path);
+ char *oldpath;
if (!pdp) {
return NT_STATUS_NO_MEMORY;
return NT_STATUS_OK;
}
- status = create_conn_struct(ctx, &conn, snum, lp_pathname(snum));
+ status = create_conn_struct(ctx, &conn, snum, lp_pathname(snum),
+ NULL, &oldpath);
if (!NT_STATUS_IS_OK(status)) {
TALLOC_FREE(pdp);
return status;
if (!NT_STATUS_EQUAL(status, NT_STATUS_PATH_NOT_COVERED)) {
DEBUG(3,("get_referred_path: No valid referrals for path %s\n",
dfs_path));
+ vfs_ChDir(conn, oldpath);
conn_free_internal(conn);
TALLOC_FREE(pdp);
return status;
&jucn->referral_count)) {
DEBUG(3,("get_referred_path: failed to parse symlink "
"target %s\n", targetpath ));
+ vfs_ChDir(conn, oldpath);
conn_free_internal(conn);
TALLOC_FREE(pdp);
return NT_STATUS_NOT_FOUND;
}
+ vfs_ChDir(conn, oldpath);
conn_free_internal(conn);
TALLOC_FREE(pdp);
return NT_STATUS_OK;
static int setup_ver2_dfs_referral(const char *pathname,
char **ppdata,
struct junction_map *junction,
- int consumedcnt,
bool self_referral)
{
char* pdata = *ppdata;
memcpy(pdata+uni_reqpathoffset2,uni_requestedpath,requestedpathlen);
/* create the header */
- SSVAL(pdata,0,consumedcnt * 2); /* path consumed */
+ SSVAL(pdata,0,requestedpathlen - 2); /* UCS2 of path consumed minus
+ 2 byte null */
/* number of referral in this pkt */
SSVAL(pdata,2,junction->referral_count);
if(self_referral) {
static int setup_ver3_dfs_referral(const char *pathname,
char **ppdata,
struct junction_map *junction,
- int consumedcnt,
bool self_referral)
{
char *pdata = *ppdata;
*ppdata = pdata;
/* create the header */
- SSVAL(pdata,0,consumedcnt * 2); /* path consumed */
+ SSVAL(pdata,0,reqpathlen - 2); /* UCS2 of path consumed minus
+ 2 byte null */
SSVAL(pdata,2,junction->referral_count); /* number of referral */
if(self_referral) {
SIVAL(pdata,4,DFSREF_REFERRAL_SERVER | DFSREF_STORAGE_SERVER);
case 2:
reply_size = setup_ver2_dfs_referral(pathnamep,
ppdata, junction,
- consumedcnt, self_referral);
+ self_referral);
break;
case 3:
reply_size = setup_ver3_dfs_referral(pathnamep, ppdata,
- junction, consumedcnt, self_referral);
+ junction, self_referral);
break;
default:
DEBUG(0,("setup_dfs_referral: Invalid dfs referral "
**********************************************************************/
static bool junction_to_local_path(const struct junction_map *jucn,
- char **pp_path_out,
- connection_struct **conn_out)
+ char **pp_path_out,
+ connection_struct **conn_out,
+ char **oldpath)
{
int snum;
+ NTSTATUS status;
snum = lp_servicenumber(jucn->service_name);
if(snum < 0) {
return False;
}
- if (!NT_STATUS_IS_OK(create_conn_struct(talloc_tos(),
- conn_out, snum,
- lp_pathname(snum)))) {
+ status = create_conn_struct(talloc_tos(), conn_out, snum,
+ lp_pathname(snum), NULL, oldpath);
+ if (!NT_STATUS_IS_OK(status)) {
return False;
}
lp_pathname(snum),
jucn->volume_name);
if (!*pp_path_out) {
+ vfs_ChDir(*conn_out, *oldpath);
+ conn_free_internal(*conn_out);
return False;
}
return True;
bool create_msdfs_link(const struct junction_map *jucn)
{
char *path = NULL;
+ char *cwd;
char *msdfs_link = NULL;
connection_struct *conn;
int i=0;
bool insert_comma = False;
bool ret = False;
- if(!junction_to_local_path(jucn, &path, &conn)) {
+ if(!junction_to_local_path(jucn, &path, &conn, &cwd)) {
return False;
}
ret = True;
out:
-
+ vfs_ChDir(conn, cwd);
conn_free_internal(conn);
return ret;
}
bool remove_msdfs_link(const struct junction_map *jucn)
{
char *path = NULL;
+ char *cwd;
connection_struct *conn;
bool ret = False;
- if( junction_to_local_path(jucn, &path, &conn) ) {
- if( SMB_VFS_UNLINK(conn, path) == 0 ) {
- ret = True;
- }
+ if (!junction_to_local_path(jucn, &path, &conn, &cwd)) {
+ return false;
+ }
+
+ if( SMB_VFS_UNLINK(conn, path) == 0 ) {
+ ret = True;
}
+ vfs_ChDir(conn, cwd);
conn_free_internal(conn);
return ret;
}
const char *connect_path = lp_pathname(snum);
const char *msdfs_proxy = lp_msdfs_proxy(snum);
connection_struct *conn;
+ NTSTATUS status;
+ char *cwd;
if(*connect_path == '\0') {
return 0;
* Fake up a connection struct for the VFS layer.
*/
- if (!NT_STATUS_IS_OK(create_conn_struct(talloc_tos(),
- &conn, snum, connect_path))) {
+ status = create_conn_struct(talloc_tos(), &conn, snum, connect_path,
+ NULL, &cwd);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(3, ("create_conn_struct failed: %s\n",
+ nt_errstr(status)));
return 0;
}
SMB_VFS_CLOSEDIR(conn,dirp);
out:
-
+ vfs_ChDir(conn, cwd);
conn_free_internal(conn);
return cnt;
}
const char *msdfs_proxy = lp_msdfs_proxy(snum);
connection_struct *conn;
struct referral *ref = NULL;
+ char *cwd;
+ NTSTATUS status;
if (jn_remain == 0) {
return 0;
* Fake up a connection struct for the VFS layer.
*/
- if (!NT_STATUS_IS_OK(create_conn_struct(ctx, &conn, snum, connect_path))) {
+ status = create_conn_struct(ctx, &conn, snum, connect_path, NULL,
+ &cwd);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(3, ("create_conn_struct failed: %s\n",
+ nt_errstr(status)));
return 0;
}
SMB_VFS_CLOSEDIR(conn,dirp);
}
+ vfs_ChDir(conn, cwd);
conn_free_internal(conn);
return cnt;
}