diff options
author | Jeremy Allison <jra@samba.org> | 2003-10-28 00:51:19 +0000 |
---|---|---|
committer | Jeremy Allison <jra@samba.org> | 2003-10-28 00:51:19 +0000 |
commit | 3638769e02ca8d1ab9cb17d7b10e6e9cdb6ea2e5 (patch) | |
tree | ef492304b579ad03db86ea3e2e0cfdd3bf918187 | |
parent | 0b86dcc634fb3dab1abc8a1f56b281093af12969 (diff) | |
download | samba-3638769e02ca8d1ab9cb17d7b10e6e9cdb6ea2e5.tar.gz samba-3638769e02ca8d1ab9cb17d7b10e6e9cdb6ea2e5.tar.bz2 samba-3638769e02ca8d1ab9cb17d7b10e6e9cdb6ea2e5.zip |
Fix for bug #667. DFS filenames can now have arbitrary case.
Jeremy.
(This used to be commit cbefb5c4f983ca49fcc563111d8704d3770daf81)
-rw-r--r-- | source3/msdfs/msdfs.c | 93 | ||||
-rw-r--r-- | source3/rpc_server/srv_dfs_nt.c | 58 | ||||
-rw-r--r-- | source3/smbd/trans2.c | 2 |
3 files changed, 86 insertions, 67 deletions
diff --git a/source3/msdfs/msdfs.c b/source3/msdfs/msdfs.c index 5cc4bf45d6..20814c2ceb 100644 --- a/source3/msdfs/msdfs.c +++ b/source3/msdfs/msdfs.c @@ -78,6 +78,7 @@ static BOOL parse_dfs_path(char* pathname, struct dfs_path* pdp) /******************************************************** Fake up a connection struct for the VFS layer. + Note this CHANGES CWD !!!! JRA. *********************************************************/ static BOOL create_conn_struct( connection_struct *conn, int snum, char *path) @@ -99,6 +100,11 @@ static BOOL create_conn_struct( connection_struct *conn, int snum, char *path) talloc_destroy( conn->mem_ctx ); return False; } + if (vfs_ChDir(conn,conn->connectpath) != 0) { + DEBUG(0,("create_conn_struct: Can't ChDir to new conn path %s\n", conn->connectpath)); + talloc_destroy( conn->mem_ctx ); + return False; + } return True; } @@ -161,7 +167,8 @@ static BOOL parse_symlink(char* buf,struct referral** preflist, /********************************************************************** Returns true if the unix path is a valid msdfs symlink **********************************************************************/ -BOOL is_msdfs_link(connection_struct* conn, char* path, + +BOOL is_msdfs_link(connection_struct* conn, char * path, struct referral** reflistp, int* refcnt, SMB_STRUCT_STAT *sbufp) { @@ -172,8 +179,6 @@ BOOL is_msdfs_link(connection_struct* conn, char* path, if (!path || !conn) return False; - strlower_m(path); - if (sbufp == NULL) sbufp = &st; @@ -212,17 +217,21 @@ they request referrals for dfs roots on a server. consumedcntp: how much of the dfs path is being redirected. the client should try the remaining path on the redirected server. + *****************************************************************/ -static BOOL resolve_dfs_path(char* dfspath, struct dfs_path* dp, + +static BOOL resolve_dfs_path(pstring dfspath, struct dfs_path* dp, connection_struct* conn, BOOL findfirst_flag, struct referral** reflistpp, int* refcntp, BOOL* self_referralp, int* consumedcntp) { - fstring localpath; + pstring localpath; int consumed_level = 1; char *p; - fstring reqpath; + BOOL bad_path = False; + SMB_STRUCT_STAT sbuf; + pstring reqpath; if (!dp || !conn) { DEBUG(1,("resolve_dfs_path: NULL dfs_path* or NULL connection_struct*!\n")); @@ -237,10 +246,13 @@ static BOOL resolve_dfs_path(char* dfspath, struct dfs_path* dp, return False; } + DEBUG(10,("resolve_dfs_path: Conn path = %s req_path = %s\n", conn->connectpath, dp->reqpath)); + + unix_convert(dp->reqpath,conn,0,&bad_path,&sbuf); + /* JRA... should we strlower the last component here.... ? */ + pstrcpy(localpath, dp->reqpath); + /* check if need to redirect */ - fstrcpy(localpath, conn->connectpath); - fstrcat(localpath, "/"); - fstrcat(localpath, dp->reqpath); if (is_msdfs_link(conn, localpath, reflistpp, refcntp, NULL)) { if (findfirst_flag) { DEBUG(6,("resolve_dfs_path (FindFirst) No redirection " @@ -256,13 +268,11 @@ static BOOL resolve_dfs_path(char* dfspath, struct dfs_path* dp, } /* redirect if any component in the path is a link */ - fstrcpy(reqpath, dp->reqpath); + pstrcpy(reqpath, dp->reqpath); p = strrchr(reqpath, '/'); while (p) { *p = '\0'; - fstrcpy(localpath, conn->connectpath); - fstrcat(localpath, "/"); - fstrcat(localpath, reqpath); + pstrcpy(localpath, reqpath); if (is_msdfs_link(conn, localpath, reflistpp, refcntp, NULL)) { DEBUG(4, ("resolve_dfs_path: Redirecting %s because parent %s is dfs link\n", dfspath, localpath)); @@ -278,7 +288,8 @@ static BOOL resolve_dfs_path(char* dfspath, struct dfs_path* dp, trim_char(buf, '\0', '\\'); for (; consumed_level; consumed_level--) { q = strrchr(buf, '\\'); - if (q) *q = 0; + if (q) + *q = 0; } *consumedcntp = strlen(buf); DEBUG(10, ("resolve_dfs_path: Path consumed: %s (%d)\n", buf, *consumedcntp)); @@ -297,7 +308,8 @@ static BOOL resolve_dfs_path(char* dfspath, struct dfs_path* dp, Decides if a dfs pathname should be redirected or not. If not, the pathname is converted to a tcon-relative local unix path *****************************************************************/ -BOOL dfs_redirect(char* pathname, connection_struct* conn, + +BOOL dfs_redirect(pstring pathname, connection_struct* conn, BOOL findfirst_flag) { struct dfs_path dp; @@ -310,7 +322,7 @@ BOOL dfs_redirect(char* pathname, connection_struct* conn, /* if dfs pathname for a non-dfs share, convert to tcon-relative path and return false */ if (!lp_msdfs_root(SNUM(conn))) { - fstrcpy(pathname, dp.reqpath); + pstrcpy(pathname, dp.reqpath); return False; } @@ -325,7 +337,7 @@ BOOL dfs_redirect(char* pathname, connection_struct* conn, DEBUG(3,("dfs_redirect: Not redirecting %s.\n", pathname)); /* Form non-dfs tcon-relative path */ - fstrcpy(pathname, dp.reqpath); + pstrcpy(pathname, dp.reqpath); DEBUG(3,("dfs_redirect: Path converted to non-dfs path %s\n", pathname)); return False; @@ -338,6 +350,7 @@ BOOL dfs_redirect(char* pathname, connection_struct* conn, Gets valid referrals for a dfs path and fills up the junction_map structure **********************************************************************/ + BOOL get_referred_path(char *pathname, struct junction_map* jn, int* consumedcntp, BOOL* self_referralp) { @@ -363,14 +376,12 @@ BOOL get_referred_path(char *pathname, struct junction_map* jn, /* Verify hostname in path */ if (local_machine && (!strequal(local_machine, dp.hostname))) { - - /* Hostname mismatch, check if one of our IP addresses */ - if (!ismyip(*interpret_addr2(dp.hostname))) { - - DEBUG(3, ("get_referred_path: Invalid hostname %s in path %s\n", - dp.hostname, pathname)); - return False; - } + /* Hostname mismatch, check if one of our IP addresses */ + if (!ismyip(*interpret_addr2(dp.hostname))) { + DEBUG(3, ("get_referred_path: Invalid hostname %s in path %s\n", + dp.hostname, pathname)); + return False; + } } pstrcpy(jn->service_name, dp.servicename); @@ -386,7 +397,7 @@ BOOL get_referred_path(char *pathname, struct junction_map* jn, pstrcpy(conn_path, lp_pathname(snum)); if (!create_conn_struct(conn, snum, conn_path)) return False; - + if (!lp_msdfs_root(SNUM(conn))) { DEBUG(3,("get_referred_path: .%s. in dfs path %s is not a dfs root.\n", dp.servicename, pathname)); @@ -626,7 +637,7 @@ static int setup_ver3_dfs_referral(char* pathname, char** ppdata, * Set up the Dfs referral for the dfs pathname ******************************************************************/ -int setup_dfs_referral(char* pathname, int max_referral_level, char** ppdata) +int setup_dfs_referral(connection_struct *orig_conn, char *pathname, int max_referral_level, char** ppdata) { struct junction_map junction; int consumedcnt; @@ -648,12 +659,14 @@ int setup_dfs_referral(char* pathname, int max_referral_level, char** ppdata) pathnamep++; pstrcpy(buf, pathnamep); - if (!get_referred_path(buf, &junction, &consumedcnt, - &self_referral)) + /* The following call can change cwd. */ + if (!get_referred_path(buf, &junction, &consumedcnt, &self_referral)) { + vfs_ChDir(orig_conn,orig_conn->connectpath); return -1; + } + vfs_ChDir(orig_conn,orig_conn->connectpath); - if (!self_referral) - { + if (!self_referral) { pathnamep[consumedcnt] = '\0'; if( DEBUGLVL( 3 ) ) { @@ -672,24 +685,18 @@ int setup_dfs_referral(char* pathname, int max_referral_level, char** ppdata) switch(max_referral_level) { case 2: - { reply_size = setup_ver2_dfs_referral(pathnamep, ppdata, &junction, consumedcnt, self_referral); SAFE_FREE(junction.referral_list); break; - } case 3: - { reply_size = setup_ver3_dfs_referral(pathnamep, ppdata, &junction, consumedcnt, self_referral); SAFE_FREE(junction.referral_list); break; - } default: - { DEBUG(0,("setup_dfs_referral: Invalid dfs referral version: %d\n", max_referral_level)); return -1; - } } DEBUG(10,("DFS Referral pdata:\n")); @@ -752,7 +759,6 @@ static BOOL junction_to_local_path(struct junction_map* jn, char* path, safe_strcpy(path, lp_pathname(snum), max_pathlen-1); safe_strcat(path, "/", max_pathlen-1); - strlower_m(jn->volume_name); safe_strcat(path, jn->volume_name, max_pathlen-1); pstrcpy(conn_path, lp_pathname(snum)); @@ -885,18 +891,12 @@ static BOOL form_junctions(int snum, struct junction_map* jn, int* jn_count) cnt++; /* Now enumerate all dfs links */ - dirp = SMB_VFS_OPENDIR(conn, connect_path); + dirp = SMB_VFS_OPENDIR(conn, "."); if(!dirp) goto out; while((dname = vfs_readdirname(conn, dirp)) != NULL) { - pstring pathreal; - - pstrcpy(pathreal, connect_path); - pstrcat(pathreal, "/"); - pstrcat(pathreal, dname); - - if (is_msdfs_link(conn, pathreal, &(jn[cnt].referral_list), + if (is_msdfs_link(conn, dname, &(jn[cnt].referral_list), &(jn[cnt].referral_count), NULL)) { pstrcpy(jn[cnt].service_name, service_name); pstrcpy(jn[cnt].volume_name, dname); @@ -925,4 +925,3 @@ int enum_msdfs_links(struct junction_map* jn) } return jn_count; } - diff --git a/source3/rpc_server/srv_dfs_nt.c b/source3/rpc_server/srv_dfs_nt.c index 751cb6e642..ac3ed9c394 100644 --- a/source3/rpc_server/srv_dfs_nt.c +++ b/source3/rpc_server/srv_dfs_nt.c @@ -70,6 +70,7 @@ WERROR _dfs_add(pipes_struct *p, DFS_Q_DFS_ADD* q_u, DFS_R_DFS_ADD *r_u) pstrcat(altpath, "\\"); pstrcat(altpath, sharename); + /* The following call can change the cwd. */ if(get_referred_path(dfspath, &jn, NULL, NULL)) { exists = True; @@ -79,6 +80,8 @@ WERROR _dfs_add(pipes_struct *p, DFS_Q_DFS_ADD* q_u, DFS_R_DFS_ADD *r_u) else jn.referral_count = 1; + vfs_ChDir(p->conn,p->conn->connectpath); + jn.referral_list = (struct referral*) talloc(p->mem_ctx, jn.referral_count * sizeof(struct referral)); @@ -100,8 +103,11 @@ WERROR _dfs_add(pipes_struct *p, DFS_Q_DFS_ADD* q_u, DFS_R_DFS_ADD *r_u) pstrcpy(jn.referral_list[jn.referral_count-1].alternate_path, altpath); - if(!create_msdfs_link(&jn, exists)) + if(!create_msdfs_link(&jn, exists)) { + vfs_ChDir(p->conn,p->conn->connectpath); return WERR_DFS_CANT_CREATE_JUNCT; + } + vfs_ChDir(p->conn,p->conn->connectpath); return WERR_OK; } @@ -147,8 +153,11 @@ WERROR _dfs_remove(pipes_struct *p, DFS_Q_DFS_REMOVE *q_u, /* if no server-share pair given, remove the msdfs link completely */ if(!q_u->ptr_ServerName && !q_u->ptr_ShareName) { - if(!remove_msdfs_link(&jn)) + if(!remove_msdfs_link(&jn)) { + vfs_ChDir(p->conn,p->conn->connectpath); return WERR_DFS_NO_SUCH_VOL; + } + vfs_ChDir(p->conn,p->conn->connectpath); } else { @@ -175,13 +184,19 @@ WERROR _dfs_remove(pipes_struct *p, DFS_Q_DFS_REMOVE *q_u, /* Only one referral, remove it */ if(jn.referral_count == 1) { - if(!remove_msdfs_link(&jn)) + if(!remove_msdfs_link(&jn)) { + vfs_ChDir(p->conn,p->conn->connectpath); return WERR_DFS_NO_SUCH_VOL; + } + vfs_ChDir(p->conn,p->conn->connectpath); } else { - if(!create_msdfs_link(&jn, True)) + if(!create_msdfs_link(&jn, True)) { + vfs_ChDir(p->conn,p->conn->connectpath); return WERR_DFS_CANT_CREATE_JUNCT; + } + vfs_ChDir(p->conn,p->conn->connectpath); } } @@ -325,7 +340,8 @@ WERROR _dfs_enum(pipes_struct *p, DFS_Q_DFS_ENUM *q_u, DFS_R_DFS_ENUM *r_u) int num_jn = 0; num_jn = enum_msdfs_links(jn); - + vfs_ChDir(p->conn,p->conn->connectpath); + DEBUG(5,("make_reply_dfs_enum: %d junctions found in Dfs, doing level %d\n", num_jn, level)); r_u->ptr_buffer = level; @@ -351,21 +367,25 @@ WERROR _dfs_enum(pipes_struct *p, DFS_Q_DFS_ENUM *q_u, DFS_R_DFS_ENUM *r_u) WERROR _dfs_get_info(pipes_struct *p, DFS_Q_DFS_GET_INFO *q_u, DFS_R_DFS_GET_INFO *r_u) { - UNISTR2* uni_path = &q_u->uni_path; - uint32 level = q_u->level; - pstring path; - struct junction_map jn; - - unistr2_to_ascii(path, uni_path, sizeof(path)-1); - if(!create_junction(path, &jn)) - return WERR_DFS_NO_SUCH_SERVER; + UNISTR2* uni_path = &q_u->uni_path; + uint32 level = q_u->level; + pstring path; + struct junction_map jn; + + unistr2_to_ascii(path, uni_path, sizeof(path)-1); + if(!create_junction(path, &jn)) + return WERR_DFS_NO_SUCH_SERVER; - if(!get_referred_path(path, &jn, NULL, NULL)) - return WERR_DFS_NO_SUCH_VOL; + /* The following call can change the cwd. */ + if(!get_referred_path(path, &jn, NULL, NULL)) { + vfs_ChDir(p->conn,p->conn->connectpath); + return WERR_DFS_NO_SUCH_VOL; + } - r_u->level = level; - r_u->ptr_ctr = 1; - r_u->status = init_reply_dfs_ctr(p->mem_ctx, level, &r_u->ctr, &jn, 1); + vfs_ChDir(p->conn,p->conn->connectpath); + r_u->level = level; + r_u->ptr_ctr = 1; + r_u->status = init_reply_dfs_ctr(p->mem_ctx, level, &r_u->ctr, &jn, 1); - return r_u->status; + return r_u->status; } diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 0f02403184..5677fb9a41 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -3297,7 +3297,7 @@ static int call_trans2getdfsreferral(connection_struct *conn, char* inbuf, srvstr_pull(inbuf, pathname, ¶ms[2], sizeof(pathname), -1, STR_TERMINATE); - if((reply_size = setup_dfs_referral(pathname,max_referral_level,ppdata)) < 0) + if((reply_size = setup_dfs_referral(conn, pathname,max_referral_level,ppdata)) < 0) return ERROR_DOS(ERRDOS,ERRbadfile); SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2) | FLAGS2_DFS_PATHNAMES); |