summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2007-04-03 22:59:55 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 12:19:08 -0500
commitcab91684e51356215a4c764e1673e4fd8420b8e8 (patch)
treec8aacdb5da2d1ef69d1e5a01a8d3bbf2aa8f1757
parent7f8d89bc5488cea1b85161dec98dc1a2dddd7b45 (diff)
downloadsamba-cab91684e51356215a4c764e1673e4fd8420b8e8.tar.gz
samba-cab91684e51356215a4c764e1673e4fd8420b8e8.tar.bz2
samba-cab91684e51356215a4c764e1673e4fd8420b8e8.zip
r22064: Fix the DFS code to work better with Vista clients. Allow
"host msdfs = true" to be set in the [global] section and allow Vista to see shares with "msdfs root = yes" and "msdfs root = no" off the same server. Down to an error message really :-). Jeremy. (This used to be commit 1a0f69bb21fd03a18514dfc93c84568708144e28)
-rw-r--r--source3/rpc_server/srv_dfs_nt.c6
-rw-r--r--source3/smbd/msdfs.c68
-rw-r--r--source3/smbd/trans2.c5
3 files changed, 42 insertions, 37 deletions
diff --git a/source3/rpc_server/srv_dfs_nt.c b/source3/rpc_server/srv_dfs_nt.c
index c7adffd62f..56c1ce00ab 100644
--- a/source3/rpc_server/srv_dfs_nt.c
+++ b/source3/rpc_server/srv_dfs_nt.c
@@ -61,7 +61,7 @@ WERROR _dfs_Add(pipes_struct *p, struct dfs_Add *r)
pstrcat(altpath, r->in.share);
/* The following call can change the cwd. */
- if(get_referred_path(p->mem_ctx, r->in.path, &jn, &consumedcnt, &self_ref)) {
+ if(NT_STATUS_IS_OK(get_referred_path(p->mem_ctx, r->in.path, &jn, &consumedcnt, &self_ref))) {
exists = True;
jn.referral_count += 1;
old_referral_list = jn.referral_list;
@@ -119,7 +119,7 @@ WERROR _dfs_Remove(pipes_struct *p, struct dfs_Remove *r)
DEBUG(5,("init_reply_dfs_remove: Request to remove %s -> %s\\%s.\n",
r->in.path, r->in.server, r->in.share));
- if(!get_referred_path(p->mem_ctx, r->in.path, &jn, &consumedcnt, &self_ref)) {
+ if(!NT_STATUS_IS_OK(get_referred_path(p->mem_ctx, r->in.path, &jn, &consumedcnt, &self_ref))) {
return WERR_DFS_NO_SUCH_VOL;
}
@@ -313,7 +313,7 @@ WERROR _dfs_GetInfo(pipes_struct *p, struct dfs_GetInfo *r)
return WERR_DFS_NO_SUCH_SERVER;
/* The following call can change the cwd. */
- if(!get_referred_path(p->mem_ctx, r->in.path, &jn, &consumedcnt, &self_ref) || consumedcnt < strlen(r->in.path)) {
+ if(!NT_STATUS_IS_OK(get_referred_path(p->mem_ctx, r->in.path, &jn, &consumedcnt, &self_ref)) || consumedcnt < strlen(r->in.path)) {
vfs_ChDir(p->conn,p->conn->connectpath);
return WERR_DFS_NO_SUCH_VOL;
}
diff --git a/source3/smbd/msdfs.c b/source3/smbd/msdfs.c
index 397d43b8bb..effe868657 100644
--- a/source3/smbd/msdfs.c
+++ b/source3/smbd/msdfs.c
@@ -170,7 +170,7 @@ static NTSTATUS parse_dfs_path(const char *pathname,
Note this CHANGES CWD !!!! JRA.
*********************************************************/
-static BOOL create_conn_struct(connection_struct *conn, int snum, const char *path)
+static NTSTATUS create_conn_struct(connection_struct *conn, int snum, const char *path)
{
pstring connpath;
@@ -183,12 +183,12 @@ static BOOL create_conn_struct(connection_struct *conn, int snum, const char *pa
if ((conn->mem_ctx=talloc_init("connection_struct")) == NULL) {
DEBUG(0,("talloc_init(connection_struct) failed!\n"));
- return False;
+ return NT_STATUS_NO_MEMORY;
}
if (!(conn->params = TALLOC_ZERO_P(conn->mem_ctx, struct share_params))) {
DEBUG(0, ("TALLOC failed\n"));
- return False;
+ return NT_STATUS_NO_MEMORY;
}
conn->params->service = snum;
@@ -196,9 +196,10 @@ static BOOL create_conn_struct(connection_struct *conn, int snum, const char *pa
set_conn_connectpath(conn, connpath);
if (!smbd_vfs_init(conn)) {
+ NTSTATUS status = map_nt_error_from_unix(errno);
DEBUG(0,("create_conn_struct: smbd_vfs_init failed.\n"));
conn_free_internal(conn);
- return False;
+ return status;
}
/*
@@ -208,13 +209,14 @@ static BOOL create_conn_struct(connection_struct *conn, int snum, const char *pa
*/
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. Error was %s\n",
conn->connectpath, strerror(errno) ));
conn_free_internal(conn);
- return False;
+ return status;
}
- return True;
+ return NT_STATUS_OK;
}
/**********************************************************************
@@ -542,7 +544,7 @@ static NTSTATUS dfs_redirect( connection_struct *conn,
Return a self referral.
**********************************************************************/
-static BOOL self_ref(TALLOC_CTX *ctx,
+static NTSTATUS self_ref(TALLOC_CTX *ctx,
const char *dfs_path,
struct junction_map *jucn,
int *consumedcntp,
@@ -555,7 +557,7 @@ static BOOL self_ref(TALLOC_CTX *ctx,
jucn->referral_count = 1;
if((ref = TALLOC_ZERO_P(ctx, struct referral)) == NULL) {
DEBUG(0,("self_ref: talloc failed for referral\n"));
- return False;
+ return NT_STATUS_NO_MEMORY;
}
pstrcpy(ref->alternate_path,dfs_path);
@@ -563,7 +565,7 @@ static BOOL self_ref(TALLOC_CTX *ctx,
ref->ttl = REFERRAL_TTL;
jucn->referral_list = ref;
*consumedcntp = strlen(dfs_path);
- return True;
+ return NT_STATUS_OK;
}
/**********************************************************************
@@ -571,7 +573,7 @@ static BOOL self_ref(TALLOC_CTX *ctx,
junction_map structure.
**********************************************************************/
-BOOL get_referred_path(TALLOC_CTX *ctx,
+NTSTATUS get_referred_path(TALLOC_CTX *ctx,
const char *dfs_path,
struct junction_map *jucn,
int *consumedcntp,
@@ -583,8 +585,7 @@ BOOL get_referred_path(TALLOC_CTX *ctx,
pstring conn_path;
pstring targetpath;
int snum;
- NTSTATUS status;
- BOOL ret = False;
+ NTSTATUS status = NT_STATUS_NOT_FOUND;
BOOL dummy;
ZERO_STRUCT(conns);
@@ -593,14 +594,14 @@ BOOL get_referred_path(TALLOC_CTX *ctx,
status = parse_dfs_path(dfs_path, False, &dp, &dummy);
if (!NT_STATUS_IS_OK(status)) {
- return False;
+ return status;
}
/* Verify hostname in path */
if (!is_myname_or_ipaddr(dp.hostname)) {
DEBUG(3, ("get_referred_path: Invalid hostname %s in path %s\n",
dp.hostname, dfs_path));
- return False;
+ return NT_STATUS_NOT_FOUND;
}
fstrcpy(jucn->service_name, dp.servicename);
@@ -610,14 +611,14 @@ BOOL get_referred_path(TALLOC_CTX *ctx,
snum = lp_servicenumber(jucn->service_name);
if(snum < 0) {
if ((snum = find_service(jucn->service_name)) < 0) {
- return False;
+ return NT_STATUS_NOT_FOUND;
}
}
if (!lp_msdfs_root(snum)) {
DEBUG(3,("get_referred_path: |%s| in dfs path %s is not a dfs root.\n",
dp.servicename, dfs_path));
- goto out;
+ return NT_STATUS_NOT_FOUND;
}
/*
@@ -646,7 +647,7 @@ BOOL get_referred_path(TALLOC_CTX *ctx,
jucn->referral_count = 1;
if ((ref = TALLOC_ZERO_P(ctx, struct referral)) == NULL) {
DEBUG(0, ("malloc failed for referral\n"));
- goto out;
+ return NT_STATUS_NO_MEMORY;
}
pstrcpy(ref->alternate_path, lp_msdfs_proxy(snum));
@@ -657,13 +658,13 @@ BOOL get_referred_path(TALLOC_CTX *ctx,
ref->ttl = REFERRAL_TTL;
jucn->referral_list = ref;
*consumedcntp = strlen(dfs_path);
- ret = True;
- goto out;
+ return NT_STATUS_OK;
}
pstrcpy(conn_path, lp_pathname(snum));
- if (!create_conn_struct(conn, snum, conn_path)) {
- return False;
+ status = create_conn_struct(conn, snum, conn_path);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
}
/* If this is a DFS path dfs_lookup should return
@@ -675,7 +676,8 @@ BOOL get_referred_path(TALLOC_CTX *ctx,
if (!NT_STATUS_EQUAL(status, NT_STATUS_PATH_NOT_COVERED)) {
DEBUG(3,("get_referred_path: No valid referrals for path %s\n",
dfs_path));
- goto out;
+ conn_free_internal(conn);
+ return status;
}
/* We know this is a valid dfs link. Parse the targetpath. */
@@ -684,15 +686,12 @@ BOOL get_referred_path(TALLOC_CTX *ctx,
&jucn->referral_count)) {
DEBUG(3,("get_referred_path: failed to parse symlink "
"target %s\n", targetpath ));
- goto out;
+ conn_free_internal(conn);
+ return NT_STATUS_NOT_FOUND;
}
- ret = True;
-
-out:
-
conn_free_internal(conn);
- return ret;
+ return NT_STATUS_OK;
}
static int setup_ver2_dfs_referral(const char *pathname,
@@ -890,7 +889,7 @@ static int setup_ver3_dfs_referral(const char *pathname,
int setup_dfs_referral(connection_struct *orig_conn,
const char *dfs_path,
int max_referral_level,
- char **ppdata)
+ char **ppdata, NTSTATUS *pstatus)
{
struct junction_map junction;
int consumedcnt = 0;
@@ -901,6 +900,7 @@ int setup_dfs_referral(connection_struct *orig_conn,
TALLOC_CTX *ctx;
if (!(ctx=talloc_init("setup_dfs_referral"))) {
+ *pstatus = NT_STATUS_NO_MEMORY;
return -1;
}
@@ -909,6 +909,7 @@ int setup_dfs_referral(connection_struct *orig_conn,
/* get the junction entry */
if (!dfs_path) {
talloc_destroy(ctx);
+ *pstatus = NT_STATUS_NOT_FOUND;
return -1;
}
@@ -924,7 +925,8 @@ int setup_dfs_referral(connection_struct *orig_conn,
}
/* The following call can change cwd. */
- if (!get_referred_path(ctx, pathnamep, &junction, &consumedcnt, &self_referral)) {
+ *pstatus = get_referred_path(ctx, pathnamep, &junction, &consumedcnt, &self_referral);
+ if (!NT_STATUS_IS_OK(*pstatus)) {
vfs_ChDir(orig_conn,orig_conn->connectpath);
talloc_destroy(ctx);
return -1;
@@ -965,6 +967,7 @@ int setup_dfs_referral(connection_struct *orig_conn,
default:
DEBUG(0,("setup_dfs_referral: Invalid dfs referral version: %d\n", max_referral_level));
talloc_destroy(ctx);
+ *pstatus = NT_STATUS_INVALID_LEVEL;
return -1;
}
@@ -974,6 +977,7 @@ int setup_dfs_referral(connection_struct *orig_conn,
}
talloc_destroy(ctx);
+ *pstatus = NT_STATUS_OK;
return reply_size;
}
@@ -1041,7 +1045,7 @@ static BOOL junction_to_local_path(struct junction_map *jucn,
safe_strcat(path, jucn->volume_name, max_pathlen-1);
pstrcpy(conn_path, lp_pathname(snum));
- if (!create_conn_struct(conn_out, snum, conn_path)) {
+ if (!NT_STATUS_IS_OK(create_conn_struct(conn_out, snum, conn_path))) {
return False;
}
@@ -1160,7 +1164,7 @@ static int form_junctions(TALLOC_CTX *ctx,
* Fake up a connection struct for the VFS layer.
*/
- if (!create_conn_struct(&conn, snum, connect_path)) {
+ if (!NT_STATUS_IS_OK(create_conn_struct(&conn, snum, connect_path))) {
return 0;
}
diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c
index dfba188b74..04969784c0 100644
--- a/source3/smbd/trans2.c
+++ b/source3/smbd/trans2.c
@@ -6214,6 +6214,7 @@ static int call_trans2getdfsreferral(connection_struct *conn, char* inbuf, char*
pstring pathname;
int reply_size = 0;
int max_referral_level;
+ NTSTATUS status = NT_STATUS_OK;
DEBUG(10,("call_trans2getdfsreferral\n"));
@@ -6227,8 +6228,8 @@ static int call_trans2getdfsreferral(connection_struct *conn, char* inbuf, char*
return ERROR_DOS(ERRDOS,ERRbadfunc);
srvstr_pull(inbuf, pathname, &params[2], sizeof(pathname), total_params - 2, STR_TERMINATE);
- if((reply_size = setup_dfs_referral(conn, pathname,max_referral_level,ppdata)) < 0)
- return UNIXERROR(ERRDOS,ERRbadfile);
+ if((reply_size = setup_dfs_referral(conn, pathname,max_referral_level,ppdata,&status)) < 0)
+ return ERROR_NT(status);
SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2) | FLAGS2_DFS_PATHNAMES);
send_trans2_replies(outbuf,bufsize,0,0,*ppdata,reply_size, max_data_bytes);