mirror of
https://github.com/samba-team/samba.git
synced 2025-01-11 05:18:09 +03:00
parent
67dd1c4366
commit
74148111e1
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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* 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_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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user