1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-23 17:34:34 +03:00

r25102: Rewrite msdfs code to use talloced filenames. Passes make test

and make valgrindtest. Final step will be to change srvstr_get_path()
to return talloced memory in the major codepaths.
Jeremy.
This commit is contained in:
Jeremy Allison 2007-09-11 18:31:29 +00:00 committed by Gerald (Jerry) Carter
parent aa768a4a20
commit cf6b6f9c3a
8 changed files with 980 additions and 519 deletions

View File

@ -44,23 +44,23 @@ typedef struct _client_referral {
} CLIENT_DFS_REFERRAL;
struct referral {
pstring alternate_path; /* contains the path referred */
char *alternate_path; /* contains the path referred */
uint32 proximity;
uint32 ttl; /* how long should client cache referral */
};
struct junction_map {
fstring service_name;
pstring volume_name;
pstring comment;
char *service_name;
char *volume_name;
char *comment;
int referral_count;
struct referral* referral_list;
};
struct dfs_path {
fstring hostname;
fstring servicename;
pstring reqpath;
char *hostname;
char *servicename;
char *reqpath;
BOOL posix_path;
};

View File

@ -1,20 +1,20 @@
/*
/*
* Unix SMB/CIFS implementation.
* RPC Pipe client / server routines for Dfs
* Copyright (C) Shirish Kalele 2000.
* Copyright (C) Jeremy Allison 2001.
* Copyright (C) Jeremy Allison 2001-2007.
* Copyright (C) Jelmer Vernooij 2005-2006.
*
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
@ -40,53 +40,68 @@ void _dfs_GetManagerVersion(pipes_struct *p, struct dfs_GetManagerVersion *r)
WERROR _dfs_Add(pipes_struct *p, struct dfs_Add *r)
{
struct junction_map jn;
struct referral* old_referral_list = NULL;
struct junction_map *jn = NULL;
struct referral *old_referral_list = NULL;
BOOL self_ref = False;
int consumedcnt = 0;
BOOL exists = False;
pstring altpath;
char *altpath = NULL;
NTSTATUS status;
TALLOC_CTX *ctx = talloc_tos();
if (p->pipe_user.ut.uid != 0) {
DEBUG(10,("_dfs_add: uid != 0. Access denied.\n"));
return WERR_ACCESS_DENIED;
}
jn = TALLOC_ZERO_P(ctx, struct junction_map);
if (!jn) {
return WERR_NOMEM;
}
DEBUG(5,("init_reply_dfs_add: Request to add %s -> %s\\%s.\n",
r->in.path, r->in.server, r->in.share));
pstrcpy(altpath, r->in.server);
pstrcat(altpath, "\\");
pstrcat(altpath, r->in.share);
altpath = talloc_asprintf(ctx, "%s\\%s",
r->in.server,
r->in.share);
if (!altpath) {
return WERR_NOMEM;
}
/* The following call can change the cwd. */
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;
} else {
jn.referral_count = 1;
status = get_referred_path(ctx, r->in.path, jn,
&consumedcnt, &self_ref);
if(!NT_STATUS_IS_OK(status)) {
return ntstatus_to_werror(status);
}
exists = True;
jn->referral_count += 1;
old_referral_list = jn->referral_list;
vfs_ChDir(p->conn,p->conn->connectpath);
jn.referral_list = TALLOC_ARRAY(p->mem_ctx, struct referral, jn.referral_count);
if(jn.referral_list == NULL) {
if (jn->referral_count < 1) {
return WERR_NOMEM;
}
jn->referral_list = TALLOC_ARRAY(ctx, struct referral, jn->referral_count);
if(jn->referral_list == NULL) {
DEBUG(0,("init_reply_dfs_add: talloc failed for referral list!\n"));
return WERR_DFS_INTERNAL_ERROR;
}
if(old_referral_list) {
memcpy(jn.referral_list, old_referral_list, sizeof(struct referral)*jn.referral_count-1);
if(old_referral_list && jn->referral_list) {
memcpy(jn->referral_list, old_referral_list,
sizeof(struct referral)*jn->referral_count-1);
}
jn.referral_list[jn.referral_count-1].proximity = 0;
jn.referral_list[jn.referral_count-1].ttl = REFERRAL_TTL;
pstrcpy(jn.referral_list[jn.referral_count-1].alternate_path, altpath);
if(!create_msdfs_link(&jn, exists)) {
jn->referral_list[jn->referral_count-1].proximity = 0;
jn->referral_list[jn->referral_count-1].ttl = REFERRAL_TTL;
jn->referral_list[jn->referral_count-1].alternate_path = altpath;
if(!create_msdfs_link(jn, exists)) {
vfs_ChDir(p->conn,p->conn->connectpath);
return WERR_DFS_CANT_CREATE_JUNCT;
}
@ -97,35 +112,43 @@ WERROR _dfs_Add(pipes_struct *p, struct dfs_Add *r)
WERROR _dfs_Remove(pipes_struct *p, struct dfs_Remove *r)
{
struct junction_map jn;
struct junction_map *jn = NULL;
BOOL self_ref = False;
int consumedcnt = 0;
BOOL found = False;
pstring altpath;
TALLOC_CTX *ctx = talloc_tos();
char *altpath = NULL;
if (p->pipe_user.ut.uid != 0) {
DEBUG(10,("_dfs_remove: uid != 0. Access denied.\n"));
return WERR_ACCESS_DENIED;
}
if (r->in.servername && r->in.sharename) {
pstrcpy(altpath, r->in.servername);
pstrcat(altpath, "\\");
pstrcat(altpath, r->in.sharename);
strlower_m(altpath);
jn = TALLOC_ZERO_P(ctx, struct junction_map);
if (!jn) {
return WERR_NOMEM;
}
DEBUG(5,("init_reply_dfs_remove: Request to remove %s -> %s\\%s.\n",
r->in.dfs_entry_path, r->in.servername, r->in.sharename));
if (r->in.servername && r->in.sharename) {
altpath = talloc_asprintf(ctx, "%s\\%s",
r->in.servername,
r->in.sharename);
strlower_m(altpath);
if (!altpath) {
return WERR_NOMEM;
}
DEBUG(5,("init_reply_dfs_remove: Request to remove %s -> %s\\%s.\n",
r->in.dfs_entry_path, r->in.servername, r->in.sharename));
}
if(!NT_STATUS_IS_OK(get_referred_path(p->mem_ctx, r->in.dfs_entry_path, &jn, &consumedcnt, &self_ref))) {
if(!NT_STATUS_IS_OK(get_referred_path(ctx, r->in.dfs_entry_path, jn,
&consumedcnt, &self_ref))) {
return WERR_DFS_NO_SUCH_VOL;
}
/* if no server-share pair given, remove the msdfs link completely */
if(!r->in.servername && !r->in.sharename) {
if(!remove_msdfs_link(&jn)) {
if(!remove_msdfs_link(jn)) {
vfs_ChDir(p->conn,p->conn->connectpath);
return WERR_DFS_NO_SUCH_VOL;
}
@ -133,14 +156,17 @@ WERROR _dfs_Remove(pipes_struct *p, struct dfs_Remove *r)
} else {
int i=0;
/* compare each referral in the list with the one to remove */
DEBUG(10,("altpath: .%s. refcnt: %d\n", altpath, jn.referral_count));
for(i=0;i<jn.referral_count;i++) {
pstring refpath;
pstrcpy(refpath,jn.referral_list[i].alternate_path);
DEBUG(10,("altpath: .%s. refcnt: %d\n", altpath, jn->referral_count));
for(i=0;i<jn->referral_count;i++) {
char *refpath = talloc_strdup(ctx,
jn->referral_list[i].alternate_path);
if (!refpath) {
return WERR_NOMEM;
}
trim_char(refpath, '\\', '\\');
DEBUG(10,("_dfs_remove: refpath: .%s.\n", refpath));
if(strequal(refpath, altpath)) {
*(jn.referral_list[i].alternate_path)='\0';
*(jn->referral_list[i].alternate_path)='\0';
DEBUG(10,("_dfs_remove: Removal request matches referral %s\n",
refpath));
found = True;
@ -152,13 +178,13 @@ WERROR _dfs_Remove(pipes_struct *p, struct dfs_Remove *r)
}
/* Only one referral, remove it */
if(jn.referral_count == 1) {
if(!remove_msdfs_link(&jn)) {
if(jn->referral_count == 1) {
if(!remove_msdfs_link(jn)) {
vfs_ChDir(p->conn,p->conn->connectpath);
return WERR_DFS_NO_SUCH_VOL;
}
} 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;
}
@ -169,10 +195,10 @@ WERROR _dfs_Remove(pipes_struct *p, struct dfs_Remove *r)
return WERR_OK;
}
static BOOL init_reply_dfs_info_1(TALLOC_CTX *mem_ctx, struct junction_map* j, struct dfs_Info1* dfs1)
static BOOL init_reply_dfs_info_1(TALLOC_CTX *mem_ctx, struct junction_map* j,struct dfs_Info1* dfs1)
{
dfs1->path = talloc_asprintf(mem_ctx,
"\\\\%s\\%s\\%s", global_myname(),
dfs1->path = talloc_asprintf(mem_ctx,
"\\\\%s\\%s\\%s", global_myname(),
j->service_name, j->volume_name);
if (dfs1->path == NULL)
return False;
@ -183,7 +209,7 @@ static BOOL init_reply_dfs_info_1(TALLOC_CTX *mem_ctx, struct junction_map* j, s
static BOOL init_reply_dfs_info_2(TALLOC_CTX *mem_ctx, struct junction_map* j, struct dfs_Info2* dfs2)
{
dfs2->path = talloc_asprintf(mem_ctx,
dfs2->path = talloc_asprintf(mem_ctx,
"\\\\%s\\%s\\%s", global_myname(), j->service_name, j->volume_name);
if (dfs2->path == NULL)
return False;
@ -209,7 +235,7 @@ static BOOL init_reply_dfs_info_3(TALLOC_CTX *mem_ctx, struct junction_map* j, s
dfs3->comment = talloc_strdup(mem_ctx, j->comment);
dfs3->state = 1;
dfs3->num_stores = j->referral_count;
/* also enumerate the stores */
if (j->referral_count) {
dfs3->stores = TALLOC_ARRAY(mem_ctx, struct dfs_StorageInfo, j->referral_count);
@ -221,12 +247,15 @@ static BOOL init_reply_dfs_info_3(TALLOC_CTX *mem_ctx, struct junction_map* j, s
}
for(ii=0;ii<j->referral_count;ii++) {
char* p;
pstring path;
struct dfs_StorageInfo* stor = &(dfs3->stores[ii]);
char* p;
char *path = NULL;
struct dfs_StorageInfo* stor = &(dfs3->stores[ii]);
struct referral* ref = &(j->referral_list[ii]);
pstrcpy(path, ref->alternate_path);
path = talloc_strdup(mem_ctx, ref->alternate_path);
if (!path) {
return False;
}
trim_char(path,'\\','\0');
p = strrchr_m(path,'\\');
if(p==NULL) {
@ -248,16 +277,20 @@ static BOOL init_reply_dfs_info_100(TALLOC_CTX *mem_ctx, struct junction_map* j,
return True;
}
WERROR _dfs_Enum(pipes_struct *p, struct dfs_Enum *r)
{
struct junction_map jn[MAX_MSDFS_JUNCTIONS];
int num_jn = 0;
int i;
struct junction_map *jn = NULL;
size_t num_jn = 0;
size_t i;
TALLOC_CTX *ctx = talloc_tos();
num_jn = enum_msdfs_links(p->mem_ctx, jn, ARRAY_SIZE(jn));
jn = enum_msdfs_links(ctx, &num_jn);
if (!jn || num_jn == 0) {
num_jn = 0;
jn = NULL;
}
vfs_ChDir(p->conn,p->conn->connectpath);
DEBUG(5,("_dfs_Enum: %d junctions found in Dfs, doing level %d\n", num_jn, r->in.level));
*r->out.total = num_jn;
@ -266,7 +299,7 @@ WERROR _dfs_Enum(pipes_struct *p, struct dfs_Enum *r)
switch (r->in.level) {
case 1:
if (num_jn) {
if ((r->out.info->e.info1->s = TALLOC_ARRAY(p->mem_ctx, struct dfs_Info1, num_jn)) == NULL) {
if ((r->out.info->e.info1->s = TALLOC_ARRAY(ctx, struct dfs_Info1, num_jn)) == NULL) {
return WERR_NOMEM;
}
} else {
@ -276,7 +309,7 @@ WERROR _dfs_Enum(pipes_struct *p, struct dfs_Enum *r)
break;
case 2:
if (num_jn) {
if ((r->out.info->e.info2->s = TALLOC_ARRAY(p->mem_ctx, struct dfs_Info2, num_jn)) == NULL) {
if ((r->out.info->e.info2->s = TALLOC_ARRAY(ctx, struct dfs_Info2, num_jn)) == NULL) {
return WERR_NOMEM;
}
} else {
@ -286,7 +319,7 @@ WERROR _dfs_Enum(pipes_struct *p, struct dfs_Enum *r)
break;
case 3:
if (num_jn) {
if ((r->out.info->e.info3->s = TALLOC_ARRAY(p->mem_ctx, struct dfs_Info3, num_jn)) == NULL) {
if ((r->out.info->e.info3->s = TALLOC_ARRAY(ctx, struct dfs_Info3, num_jn)) == NULL) {
return WERR_NOMEM;
}
} else {
@ -300,35 +333,44 @@ WERROR _dfs_Enum(pipes_struct *p, struct dfs_Enum *r)
for (i = 0; i < num_jn; i++) {
switch (r->in.level) {
case 1:
init_reply_dfs_info_1(p->mem_ctx, &jn[i], &r->out.info->e.info1->s[i]);
case 1:
init_reply_dfs_info_1(ctx, &jn[i], &r->out.info->e.info1->s[i]);
break;
case 2:
init_reply_dfs_info_2(p->mem_ctx, &jn[i], &r->out.info->e.info2->s[i]);
init_reply_dfs_info_2(ctx, &jn[i], &r->out.info->e.info2->s[i]);
break;
case 3:
init_reply_dfs_info_3(p->mem_ctx, &jn[i], &r->out.info->e.info3->s[i]);
init_reply_dfs_info_3(ctx, &jn[i], &r->out.info->e.info3->s[i]);
break;
default:
return WERR_INVALID_PARAM;
}
}
return WERR_OK;
}
WERROR _dfs_GetInfo(pipes_struct *p, struct dfs_GetInfo *r)
{
int consumedcnt = sizeof(pstring);
struct junction_map jn;
int consumedcnt = strlen(r->in.dfs_entry_path);
struct junction_map *jn = NULL;
BOOL self_ref = False;
TALLOC_CTX *ctx = talloc_tos();
BOOL ret;
if(!create_junction(r->in.dfs_entry_path, &jn))
jn = TALLOC_ZERO_P(ctx, struct junction_map);
if (!jn) {
return WERR_NOMEM;
}
if(!create_junction(ctx, r->in.dfs_entry_path, jn)) {
return WERR_DFS_NO_SUCH_SERVER;
}
/* The following call can change the cwd. */
if(!NT_STATUS_IS_OK(get_referred_path(p->mem_ctx, r->in.dfs_entry_path, &jn, &consumedcnt, &self_ref)) || consumedcnt < strlen(r->in.dfs_entry_path)) {
if(!NT_STATUS_IS_OK(get_referred_path(ctx, r->in.dfs_entry_path,
jn, &consumedcnt, &self_ref)) ||
consumedcnt < strlen(r->in.dfs_entry_path)) {
vfs_ChDir(p->conn,p->conn->connectpath);
return WERR_DFS_NO_SUCH_VOL;
}
@ -336,18 +378,18 @@ WERROR _dfs_GetInfo(pipes_struct *p, struct dfs_GetInfo *r)
vfs_ChDir(p->conn,p->conn->connectpath);
switch (r->in.level) {
case 1: ret = init_reply_dfs_info_1(p->mem_ctx, &jn, r->out.info->info1); break;
case 2: ret = init_reply_dfs_info_2(p->mem_ctx, &jn, r->out.info->info2); break;
case 3: ret = init_reply_dfs_info_3(p->mem_ctx, &jn, r->out.info->info3); break;
case 100: ret = init_reply_dfs_info_100(p->mem_ctx, &jn, r->out.info->info100); break;
case 1: ret = init_reply_dfs_info_1(ctx, jn, r->out.info->info1); break;
case 2: ret = init_reply_dfs_info_2(ctx, jn, r->out.info->info2); break;
case 3: ret = init_reply_dfs_info_3(ctx, jn, r->out.info->info3); break;
case 100: ret = init_reply_dfs_info_100(ctx, jn, r->out.info->info100); break;
default:
r->out.info->info1 = NULL;
return WERR_INVALID_PARAM;
}
if (!ret)
if (!ret)
return WERR_INVALID_PARAM;
return WERR_OK;
}

View File

@ -139,6 +139,9 @@ cat >$SERVERCONFFILE<<EOF
printing = bsd
printcap name = /dev/null
host msdfs = yes
panic action = "/bin/sleep 90000"
[tmp]
path = $PREFIX_ABS/tmp
read only = no

View File

@ -1019,7 +1019,6 @@ BOOL is_visible_file(connection_struct *conn, const char *dir_path, const char *
}
if (hide_unreadable || hide_unwriteable || hide_special) {
pstring link_target;
char *entry = NULL;
if (asprintf(&entry, "%s/%s", dir_path, name) == -1) {
@ -1029,7 +1028,7 @@ BOOL is_visible_file(connection_struct *conn, const char *dir_path, const char *
/* If it's a dfs symlink, ignore _hide xxxx_ options */
if (lp_host_msdfs() &&
lp_msdfs_root(SNUM(conn)) &&
is_msdfs_link(conn, entry, link_target, NULL)) {
is_msdfs_link(conn, entry, NULL)) {
SAFE_FREE(entry);
return True;
}

File diff suppressed because it is too large Load Diff

View File

@ -514,6 +514,7 @@ void reply_ntcreate_and_X(connection_struct *conn,
BOOL extended_oplock_granted = False;
NTSTATUS status;
struct case_semantics_state *case_state = NULL;
TALLOC_CTX *ctx = talloc_tos();
START_PROFILE(SMBntcreateX);
@ -682,12 +683,15 @@ void reply_ntcreate_and_X(connection_struct *conn,
return;
}
}
/*
* Now contruct the smb_open_mode value from the filename,
* Now contruct the smb_open_mode value from the filename,
* desired access and the share access.
*/
status = resolve_dfspath(conn, req->flags2 & FLAGS2_DFS_PATHNAMES, fname_in);
status = resolve_dfspath(ctx, conn,
req->flags2 & FLAGS2_DFS_PATHNAMES,
fname_in,
&fname);
if (!NT_STATUS_IS_OK(status)) {
if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
@ -718,7 +722,7 @@ void reply_ntcreate_and_X(connection_struct *conn,
file_attributes &= ~FILE_FLAG_POSIX_SEMANTICS;
}
status = unix_convert(conn, fname_in, False, &fname, NULL, &sbuf);
status = unix_convert(conn, fname, False, &fname, NULL, &sbuf);
if (!NT_STATUS_IS_OK(status)) {
TALLOC_FREE(case_state);
reply_nterror(req, status);
@ -1242,11 +1246,11 @@ static void call_nt_transact_create(connection_struct *conn,
struct timespec a_timespec;
struct timespec m_timespec;
struct ea_list *ea_list = NULL;
TALLOC_CTX *ctx = NULL;
char *pdata = NULL;
NTSTATUS status;
size_t param_len;
struct case_semantics_state *case_state = NULL;
TALLOC_CTX *ctx = talloc_tos();
DEBUG(5,("call_nt_transact_create\n"));
@ -1424,8 +1428,10 @@ static void call_nt_transact_create(connection_struct *conn,
file_attributes &= ~FILE_FLAG_POSIX_SEMANTICS;
}
status = resolve_dfspath(conn, req->flags2 & FLAGS2_DFS_PATHNAMES,
fname_in);
status = resolve_dfspath(ctx, conn,
req->flags2 & FLAGS2_DFS_PATHNAMES,
fname_in,
&fname);
if (!NT_STATUS_IS_OK(status)) {
TALLOC_FREE(case_state);
if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
@ -1437,7 +1443,7 @@ static void call_nt_transact_create(connection_struct *conn,
return;
}
status = unix_convert(conn, fname_in, False, &fname, NULL, &sbuf);
status = unix_convert(conn, fname, False, &fname, NULL, &sbuf);
if (!NT_STATUS_IS_OK(status)) {
TALLOC_FREE(case_state);
reply_nterror(req, status);
@ -1594,7 +1600,6 @@ static void call_nt_transact_create(connection_struct *conn,
status = set_sd( fsp, data, sd_len, ALL_SECURITY_INFORMATION);
if (!NT_STATUS_IS_OK(status)) {
talloc_destroy(ctx);
close_file(fsp,ERROR_CLOSE);
TALLOC_FREE(case_state);
reply_nterror(req, status);
@ -1918,14 +1923,17 @@ static NTSTATUS copy_internals(connection_struct *conn,
void reply_ntrename(connection_struct *conn, struct smb_request *req)
{
pstring oldname;
pstring newname;
pstring oldname_in;
pstring newname_in;
char *oldname = NULL;
char *newname = NULL;
char *p;
NTSTATUS status;
BOOL src_has_wcard = False;
BOOL dest_has_wcard = False;
uint32 attrs;
uint16 rename_type;
TALLOC_CTX *ctx = talloc_tos();
START_PROFILE(SMBntrename);
@ -1939,8 +1947,8 @@ void reply_ntrename(connection_struct *conn, struct smb_request *req)
rename_type = SVAL(req->inbuf,smb_vwv1);
p = smb_buf(req->inbuf) + 1;
p += srvstr_get_path_wcard((char *)req->inbuf, req->flags2, oldname, p,
sizeof(oldname), 0, STR_TERMINATE, &status,
p += srvstr_get_path_wcard((char *)req->inbuf, req->flags2, oldname_in, p,
sizeof(oldname_in), 0, STR_TERMINATE, &status,
&src_has_wcard);
if (!NT_STATUS_IS_OK(status)) {
reply_nterror(req, status);
@ -1948,31 +1956,33 @@ void reply_ntrename(connection_struct *conn, struct smb_request *req)
return;
}
if( is_ntfs_stream_name(oldname)) {
if( is_ntfs_stream_name(oldname_in)) {
/* Can't rename a stream. */
reply_nterror(req, NT_STATUS_ACCESS_DENIED);
END_PROFILE(SMBntrename);
return;
}
if (ms_has_wild(oldname)) {
if (ms_has_wild(oldname_in)) {
reply_nterror(req, NT_STATUS_OBJECT_PATH_SYNTAX_BAD);
END_PROFILE(SMBntrename);
return;
}
p++;
p += srvstr_get_path_wcard((char *)req->inbuf, req->flags2, newname, p,
sizeof(newname), 0, STR_TERMINATE, &status,
p += srvstr_get_path_wcard((char *)req->inbuf, req->flags2, newname_in, p,
sizeof(newname_in), 0, STR_TERMINATE, &status,
&dest_has_wcard);
if (!NT_STATUS_IS_OK(status)) {
reply_nterror(req, status);
END_PROFILE(SMBntrename);
return;
}
status = resolve_dfspath(conn, req->flags2 & FLAGS2_DFS_PATHNAMES,
oldname);
status = resolve_dfspath(ctx, conn,
req->flags2 & FLAGS2_DFS_PATHNAMES,
oldname_in,
&oldname);
if (!NT_STATUS_IS_OK(status)) {
if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
@ -1985,8 +1995,10 @@ void reply_ntrename(connection_struct *conn, struct smb_request *req)
return;
}
status = resolve_dfspath(conn, req->flags2 & FLAGS2_DFS_PATHNAMES,
newname);
status = resolve_dfspath(ctx, conn,
req->flags2 & FLAGS2_DFS_PATHNAMES,
newname_in,
&newname);
if (!NT_STATUS_IS_OK(status)) {
if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
@ -2000,7 +2012,7 @@ void reply_ntrename(connection_struct *conn, struct smb_request *req)
}
DEBUG(3,("reply_ntrename : %s -> %s\n",oldname,newname));
switch(rename_type) {
case RENAME_FLAG_RENAME:
status = rename_internals(conn, req, oldname, newname,

View File

@ -452,6 +452,7 @@ void reply_tcon(connection_struct *conn, struct smb_request *req)
NTSTATUS nt_status;
char *p;
DATA_BLOB password_blob;
TALLOC_CTX *ctx = talloc_tos();
START_PROFILE(SMBtcon);
@ -462,12 +463,12 @@ void reply_tcon(connection_struct *conn, struct smb_request *req)
}
p = smb_buf(req->inbuf)+1;
p += srvstr_pull_buf_talloc(req, req->inbuf, req->flags2,
p += srvstr_pull_buf_talloc(ctx, req->inbuf, req->flags2,
&service_buf, p, STR_TERMINATE) + 1;
pwlen = srvstr_pull_buf_talloc(req, req->inbuf, req->flags2,
pwlen = srvstr_pull_buf_talloc(ctx, req->inbuf, req->flags2,
&password, p, STR_TERMINATE) + 1;
p += pwlen;
p += srvstr_pull_buf_talloc(req, req->inbuf, req->flags2,
p += srvstr_pull_buf_talloc(ctx, req->inbuf, req->flags2,
&dev, p, STR_TERMINATE) + 1;
if (service_buf == NULL || password == NULL || dev == NULL) {
@ -515,8 +516,7 @@ void reply_tcon_and_X(connection_struct *conn, struct smb_request *req)
{
char *service = NULL;
DATA_BLOB password;
TALLOC_CTX *ctx = NULL;
TALLOC_CTX *ctx = talloc_tos();
/* what the cleint thinks the device is */
char *client_devicetype = NULL;
/* what the server tells the client the share represents */
@ -567,19 +567,11 @@ void reply_tcon_and_X(connection_struct *conn, struct smb_request *req)
p = smb_buf(req->inbuf) + passlen + 1;
}
ctx = talloc_init("reply_tcon_and_X");
if (!ctx) {
data_blob_clear_free(&password);
reply_nterror(req, NT_STATUS_NO_MEMORY);
END_PROFILE(SMBtconX);
return;
}
p += srvstr_pull_buf_talloc(ctx, req->inbuf, req->flags2, &path, p,
STR_TERMINATE);
if (path == NULL) {
data_blob_clear_free(&password);
TALLOC_FREE(ctx);
reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
END_PROFILE(SMBtconX);
return;
@ -593,7 +585,6 @@ void reply_tcon_and_X(connection_struct *conn, struct smb_request *req)
q = strchr_m(path+2,'\\');
if (!q) {
data_blob_clear_free(&password);
TALLOC_FREE(ctx);
reply_doserror(req, ERRDOS, ERRnosuchshare);
END_PROFILE(SMBtconX);
return;
@ -609,7 +600,6 @@ void reply_tcon_and_X(connection_struct *conn, struct smb_request *req)
if (client_devicetype == NULL) {
data_blob_clear_free(&password);
TALLOC_FREE(ctx);
reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
END_PROFILE(SMBtconX);
return;
@ -623,7 +613,6 @@ void reply_tcon_and_X(connection_struct *conn, struct smb_request *req)
data_blob_clear_free(&password);
if (!conn) {
TALLOC_FREE(ctx);
reply_nterror(req, nt_status);
END_PROFILE(SMBtconX);
return;
@ -640,7 +629,6 @@ void reply_tcon_and_X(connection_struct *conn, struct smb_request *req)
reply_outbuf(req, 2, 0);
if (message_push_string(&req->outbuf, server_devicetype,
STR_TERMINATE|STR_ASCII) == -1) {
TALLOC_FREE(ctx);
reply_nterror(req, NT_STATUS_NO_MEMORY);
END_PROFILE(SMBtconX);
return;
@ -675,7 +663,6 @@ void reply_tcon_and_X(connection_struct *conn, struct smb_request *req)
STR_TERMINATE|STR_ASCII) == -1)
|| (message_push_string(&req->outbuf, fstype,
STR_TERMINATE) == -1)) {
TALLOC_FREE(ctx);
reply_nterror(req, NT_STATUS_NO_MEMORY);
END_PROFILE(SMBtconX);
return;
@ -697,7 +684,6 @@ void reply_tcon_and_X(connection_struct *conn, struct smb_request *req)
SSVAL(req->inbuf,smb_tid,conn->cnum);
SSVAL(req->outbuf,smb_tid,conn->cnum);
TALLOC_FREE(ctx);
END_PROFILE(SMBtconX);
chain_reply(req);
@ -827,6 +813,7 @@ void reply_checkpath(connection_struct *conn, struct smb_request *req)
char *name = NULL;
SMB_STRUCT_STAT sbuf;
NTSTATUS status;
TALLOC_CTX *ctx = talloc_tos();
START_PROFILE(SMBcheckpath);
@ -840,7 +827,10 @@ void reply_checkpath(connection_struct *conn, struct smb_request *req)
return;
}
status = resolve_dfspath(conn, req->flags2 & FLAGS2_DFS_PATHNAMES, name_in);
status = resolve_dfspath(ctx, conn,
req->flags2 & FLAGS2_DFS_PATHNAMES,
name_in,
&name);
if (!NT_STATUS_IS_OK(status)) {
if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
@ -853,7 +843,7 @@ void reply_checkpath(connection_struct *conn, struct smb_request *req)
DEBUG(3,("reply_checkpath %s mode=%d\n", name_in, (int)SVAL(req->inbuf,smb_vwv0)));
status = unix_convert(conn, name_in, False, &name, NULL, &sbuf);
status = unix_convert(conn, name, False, &name, NULL, &sbuf);
if (!NT_STATUS_IS_OK(status)) {
goto path_err;
}
@ -922,6 +912,7 @@ void reply_getatr(connection_struct *conn, struct smb_request *req)
time_t mtime=0;
char *p;
NTSTATUS status;
TALLOC_CTX *ctx = talloc_tos();
START_PROFILE(SMBgetatr);
@ -934,8 +925,10 @@ void reply_getatr(connection_struct *conn, struct smb_request *req)
return;
}
status = resolve_dfspath(conn, req->flags2 & FLAGS2_DFS_PATHNAMES,
fname_in);
status = resolve_dfspath(ctx, conn,
req->flags2 & FLAGS2_DFS_PATHNAMES,
fname_in,
&fname);
if (!NT_STATUS_IS_OK(status)) {
if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
@ -947,10 +940,10 @@ void reply_getatr(connection_struct *conn, struct smb_request *req)
END_PROFILE(SMBgetatr);
return;
}
/* dos smetimes asks for a stat of "" - it returns a "hidden directory"
under WfWg - weird! */
if (*fname_in == '\0') {
if (*fname == '\0') {
mode = aHIDDEN | aDIR;
if (!CAN_WRITE(conn)) {
mode |= aRONLY;
@ -958,7 +951,7 @@ void reply_getatr(connection_struct *conn, struct smb_request *req)
size = 0;
mtime = 0;
} else {
status = unix_convert(conn, fname_in, False, &fname, NULL,&sbuf);
status = unix_convert(conn, fname, False, &fname, NULL,&sbuf);
if (!NT_STATUS_IS_OK(status)) {
reply_nterror(req, status);
END_PROFILE(SMBgetatr);
@ -1020,6 +1013,7 @@ void reply_setatr(connection_struct *conn, struct smb_request *req)
SMB_STRUCT_STAT sbuf;
char *p;
NTSTATUS status;
TALLOC_CTX *ctx = talloc_tos();
START_PROFILE(SMBsetatr);
@ -1037,8 +1031,10 @@ void reply_setatr(connection_struct *conn, struct smb_request *req)
return;
}
status = resolve_dfspath(conn, req->flags2 & FLAGS2_DFS_PATHNAMES,
fname_in);
status = resolve_dfspath(ctx, conn,
req->flags2 & FLAGS2_DFS_PATHNAMES,
fname_in,
&fname);
if (!NT_STATUS_IS_OK(status)) {
if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
@ -1051,7 +1047,7 @@ void reply_setatr(connection_struct *conn, struct smb_request *req)
return;
}
status = unix_convert(conn, fname_in, False, &fname, NULL, &sbuf);
status = unix_convert(conn, fname, False, &fname, NULL, &sbuf);
if (!NT_STATUS_IS_OK(status)) {
reply_nterror(req, status);
END_PROFILE(SMBsetatr);
@ -1175,7 +1171,8 @@ void reply_search(connection_struct *conn, struct smb_request *req)
BOOL finished = False;
char *p;
int status_len;
pstring path;
pstring path_in;
char *path = NULL;
char status[21];
int dptr_num= -1;
BOOL check_descend = False;
@ -1183,6 +1180,7 @@ void reply_search(connection_struct *conn, struct smb_request *req)
NTSTATUS nt_status;
BOOL mask_contains_wcard = False;
BOOL allow_long_path_components = (req->flags2 & FLAGS2_LONG_PATH_COMPONENTS) ? True : False;
TALLOC_CTX *ctx = talloc_tos();
START_PROFILE(SMBsearch);
@ -1209,8 +1207,8 @@ void reply_search(connection_struct *conn, struct smb_request *req)
maxentries = SVAL(req->inbuf,smb_vwv0);
dirtype = SVAL(req->inbuf,smb_vwv1);
p = smb_buf(req->inbuf) + 1;
p += srvstr_get_path_wcard((char *)req->inbuf, req->flags2, path, p,
sizeof(path), 0, STR_TERMINATE, &nt_status,
p += srvstr_get_path_wcard((char *)req->inbuf, req->flags2, path_in, p,
sizeof(path_in), 0, STR_TERMINATE, &nt_status,
&mask_contains_wcard);
if (!NT_STATUS_IS_OK(nt_status)) {
reply_nterror(req, nt_status);
@ -1218,9 +1216,11 @@ void reply_search(connection_struct *conn, struct smb_request *req)
return;
}
nt_status = resolve_dfspath_wcard(conn,
nt_status = resolve_dfspath_wcard(ctx, conn,
req->flags2 & FLAGS2_DFS_PATHNAMES,
path, &mask_contains_wcard);
path_in,
&path,
&mask_contains_wcard);
if (!NT_STATUS_IS_OK(nt_status)) {
if (NT_STATUS_EQUAL(nt_status,NT_STATUS_PATH_NOT_COVERED)) {
reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
@ -1232,11 +1232,11 @@ void reply_search(connection_struct *conn, struct smb_request *req)
END_PROFILE(SMBsearch);
return;
}
p++;
status_len = SVAL(p, 0);
p += 2;
/* dirtype &= ~aDIR; */
if (status_len == 0) {
@ -1512,6 +1512,7 @@ void reply_open(connection_struct *conn, struct smb_request *req)
uint32 create_disposition;
uint32 create_options = 0;
NTSTATUS status;
TALLOC_CTX *ctx = talloc_tos();
START_PROFILE(SMBopen);
@ -1520,7 +1521,7 @@ void reply_open(connection_struct *conn, struct smb_request *req)
END_PROFILE(SMBopen);
return;
}
oplock_request = CORE_OPLOCK_REQUEST(req->inbuf);
deny_mode = SVAL(req->inbuf,smb_vwv0);
dos_attr = SVAL(req->inbuf,smb_vwv1);
@ -1534,8 +1535,10 @@ void reply_open(connection_struct *conn, struct smb_request *req)
return;
}
status = resolve_dfspath(conn, req->flags2 & FLAGS2_DFS_PATHNAMES,
fname_in);
status = resolve_dfspath(ctx, conn,
req->flags2 & FLAGS2_DFS_PATHNAMES,
fname_in,
&fname);
if (!NT_STATUS_IS_OK(status)) {
if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
@ -1548,7 +1551,7 @@ void reply_open(connection_struct *conn, struct smb_request *req)
return;
}
status = unix_convert(conn, fname_in, False, &fname, NULL, &sbuf);
status = unix_convert(conn, fname, False, &fname, NULL, &sbuf);
if (!NT_STATUS_IS_OK(status)) {
reply_nterror(req, status);
END_PROFILE(SMBopen);
@ -1658,6 +1661,7 @@ void reply_open_and_X(connection_struct *conn, struct smb_request *req)
uint32 share_mode;
uint32 create_disposition;
uint32 create_options = 0;
TALLOC_CTX *ctx = talloc_tos();
START_PROFILE(SMBopenX);
@ -1697,8 +1701,10 @@ void reply_open_and_X(connection_struct *conn, struct smb_request *req)
return;
}
status = resolve_dfspath(conn, req->flags2 & FLAGS2_DFS_PATHNAMES,
fname_in);
status = resolve_dfspath(ctx, conn,
req->flags2 & FLAGS2_DFS_PATHNAMES,
fname_in,
&fname);
if (!NT_STATUS_IS_OK(status)) {
END_PROFILE(SMBopenX);
if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
@ -1710,7 +1716,7 @@ void reply_open_and_X(connection_struct *conn, struct smb_request *req)
return;
}
status = unix_convert(conn, fname_in, False, &fname, NULL, &sbuf);
status = unix_convert(conn, fname, False, &fname, NULL, &sbuf);
if (!NT_STATUS_IS_OK(status)) {
reply_nterror(req, status);
END_PROFILE(SMBopenX);
@ -1889,6 +1895,7 @@ void reply_mknew(connection_struct *conn, struct smb_request *req)
uint32 share_mode = FILE_SHARE_READ|FILE_SHARE_WRITE;
uint32 create_disposition;
uint32 create_options = 0;
TALLOC_CTX *ctx = talloc_tos();
START_PROFILE(SMBcreate);
@ -1915,8 +1922,10 @@ void reply_mknew(connection_struct *conn, struct smb_request *req)
return;
}
status = resolve_dfspath(conn, req->flags2 & FLAGS2_DFS_PATHNAMES,
fname_in);
status = resolve_dfspath(ctx, conn,
req->flags2 & FLAGS2_DFS_PATHNAMES,
fname_in,
&fname);
if (!NT_STATUS_IS_OK(status)) {
END_PROFILE(SMBcreate);
if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
@ -1928,7 +1937,7 @@ void reply_mknew(connection_struct *conn, struct smb_request *req)
return;
}
status = unix_convert(conn, fname_in, False, &fname, NULL, &sbuf);
status = unix_convert(conn, fname, False, &fname, NULL, &sbuf);
if (!NT_STATUS_IS_OK(status)) {
reply_nterror(req, status);
END_PROFILE(SMBcreate);
@ -2014,6 +2023,7 @@ void reply_ctemp(connection_struct *conn, struct smb_request *req)
SMB_STRUCT_STAT sbuf;
char *s;
NTSTATUS status;
TALLOC_CTX *ctx = talloc_tos();
START_PROFILE(SMBctemp);
@ -2040,8 +2050,10 @@ void reply_ctemp(connection_struct *conn, struct smb_request *req)
pstrcat(fname_in,"TMXXXXXX");
}
status = resolve_dfspath(conn, req->flags2 & FLAGS2_DFS_PATHNAMES,
fname_in);
status = resolve_dfspath(ctx, conn,
req->flags2 & FLAGS2_DFS_PATHNAMES,
fname_in,
&fname);
if (!NT_STATUS_IS_OK(status)) {
if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
@ -2054,20 +2066,20 @@ void reply_ctemp(connection_struct *conn, struct smb_request *req)
return;
}
status = unix_convert(conn, fname_in, False, &fname, NULL, &sbuf);
status = unix_convert(conn, fname, False, &fname, NULL, &sbuf);
if (!NT_STATUS_IS_OK(status)) {
reply_nterror(req, status);
END_PROFILE(SMBctemp);
return;
}
status = check_name(conn, fname);
status = check_name(conn, CONST_DISCARD(char *,fname));
if (!NT_STATUS_IS_OK(status)) {
reply_nterror(req, status);
END_PROFILE(SMBctemp);
return;
}
tmpfd = smb_mkstemp(fname);
if (tmpfd == -1) {
reply_unixerror(req, ERRDOS, ERRnoaccess);
@ -2446,10 +2458,12 @@ NTSTATUS unlink_internals(connection_struct *conn, struct smb_request *req,
void reply_unlink(connection_struct *conn, struct smb_request *req)
{
pstring name;
pstring name_in;
char *name = NULL;
uint32 dirtype;
NTSTATUS status;
BOOL path_contains_wcard = False;
TALLOC_CTX *ctx = talloc_tos();
START_PROFILE(SMBunlink);
@ -2460,9 +2474,9 @@ void reply_unlink(connection_struct *conn, struct smb_request *req)
}
dirtype = SVAL(req->inbuf,smb_vwv0);
srvstr_get_path_wcard((char *)req->inbuf, req->flags2, name,
smb_buf(req->inbuf) + 1, sizeof(name), 0,
srvstr_get_path_wcard((char *)req->inbuf, req->flags2, name_in,
smb_buf(req->inbuf) + 1, sizeof(name_in), 0,
STR_TERMINATE, &status, &path_contains_wcard);
if (!NT_STATUS_IS_OK(status)) {
reply_nterror(req, status);
@ -2470,9 +2484,11 @@ void reply_unlink(connection_struct *conn, struct smb_request *req)
return;
}
status = resolve_dfspath_wcard(conn,
status = resolve_dfspath_wcard(ctx, conn,
req->flags2 & FLAGS2_DFS_PATHNAMES,
name, &path_contains_wcard);
name_in,
&name,
&path_contains_wcard);
if (!NT_STATUS_IS_OK(status)) {
if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
@ -2484,9 +2500,9 @@ void reply_unlink(connection_struct *conn, struct smb_request *req)
END_PROFILE(SMBunlink);
return;
}
DEBUG(3,("reply_unlink : %s\n",name));
status = unlink_internals(conn, req, dirtype, name,
path_contains_wcard);
if (!NT_STATUS_IS_OK(status)) {
@ -4633,7 +4649,7 @@ void reply_printwrite(connection_struct *conn, struct smb_request *req)
}
DEBUG( 3, ( "printwrite fnum=%d num=%d\n", fsp->fnum, numtowrite ) );
END_PROFILE(SMBsplwr);
return;
}
@ -4648,9 +4664,10 @@ void reply_mkdir(connection_struct *conn, struct smb_request *req)
char *directory = NULL;
NTSTATUS status;
SMB_STRUCT_STAT sbuf;
TALLOC_CTX *ctx = talloc_tos();
START_PROFILE(SMBmkdir);
srvstr_get_path((char *)req->inbuf, req->flags2, directory_in,
smb_buf(req->inbuf) + 1, sizeof(directory_in), 0,
STR_TERMINATE, &status);
@ -4660,9 +4677,10 @@ void reply_mkdir(connection_struct *conn, struct smb_request *req)
return;
}
status = resolve_dfspath(conn,
status = resolve_dfspath(ctx, conn,
req->flags2 & FLAGS2_DFS_PATHNAMES,
directory_in);
directory_in,
&directory);
if (!NT_STATUS_IS_OK(status)) {
if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
@ -4675,7 +4693,7 @@ void reply_mkdir(connection_struct *conn, struct smb_request *req)
return;
}
status = unix_convert(conn, directory_in, False, &directory, NULL, &sbuf);
status = unix_convert(conn, directory, False, &directory, NULL, &sbuf);
if (!NT_STATUS_IS_OK(status)) {
reply_nterror(req, status);
END_PROFILE(SMBmkdir);
@ -4902,6 +4920,8 @@ void reply_rmdir(connection_struct *conn, struct smb_request *req)
char *directory = NULL;
SMB_STRUCT_STAT sbuf;
NTSTATUS status;
TALLOC_CTX *ctx = talloc_tos();
START_PROFILE(SMBrmdir);
srvstr_get_path((char *)req->inbuf, req->flags2, directory_in,
@ -4913,9 +4933,10 @@ void reply_rmdir(connection_struct *conn, struct smb_request *req)
return;
}
status = resolve_dfspath(conn,
status = resolve_dfspath(ctx, conn,
req->flags2 & FLAGS2_DFS_PATHNAMES,
directory_in);
directory_in,
&directory);
if (!NT_STATUS_IS_OK(status)) {
if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
@ -4928,14 +4949,14 @@ void reply_rmdir(connection_struct *conn, struct smb_request *req)
return;
}
status = unix_convert(conn, directory_in, False, &directory,
status = unix_convert(conn, directory, False, &directory,
NULL, &sbuf);
if (!NT_STATUS_IS_OK(status)) {
reply_nterror(req, status);
END_PROFILE(SMBrmdir);
return;
}
status = check_name(conn, directory);
if (!NT_STATUS_IS_OK(status)) {
reply_nterror(req, status);
@ -5662,13 +5683,16 @@ NTSTATUS rename_internals(connection_struct *conn, struct smb_request *req,
void reply_mv(connection_struct *conn, struct smb_request *req)
{
pstring name;
pstring newname;
pstring name_in;
pstring newname_in;
char *name = NULL;
char *newname = NULL;
char *p;
uint32 attrs;
NTSTATUS status;
BOOL src_has_wcard = False;
BOOL dest_has_wcard = False;
TALLOC_CTX *ctx = talloc_tos();
START_PROFILE(SMBmv);
@ -5681,8 +5705,8 @@ void reply_mv(connection_struct *conn, struct smb_request *req)
attrs = SVAL(req->inbuf,smb_vwv0);
p = smb_buf(req->inbuf) + 1;
p += srvstr_get_path_wcard((char *)req->inbuf, req->flags2, name, p,
sizeof(name), 0, STR_TERMINATE, &status,
p += srvstr_get_path_wcard((char *)req->inbuf, req->flags2, name_in, p,
sizeof(name_in), 0, STR_TERMINATE, &status,
&src_has_wcard);
if (!NT_STATUS_IS_OK(status)) {
reply_nterror(req, status);
@ -5690,18 +5714,20 @@ void reply_mv(connection_struct *conn, struct smb_request *req)
return;
}
p++;
p += srvstr_get_path_wcard((char *)req->inbuf, req->flags2, newname, p,
sizeof(newname), 0, STR_TERMINATE, &status,
p += srvstr_get_path_wcard((char *)req->inbuf, req->flags2, newname_in, p,
sizeof(newname_in), 0, STR_TERMINATE, &status,
&dest_has_wcard);
if (!NT_STATUS_IS_OK(status)) {
reply_nterror(req, status);
END_PROFILE(SMBmv);
return;
}
status = resolve_dfspath_wcard(conn,
status = resolve_dfspath_wcard(ctx, conn,
req->flags2 & FLAGS2_DFS_PATHNAMES,
name, &src_has_wcard);
name_in,
&name,
&src_has_wcard);
if (!NT_STATUS_IS_OK(status)) {
if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
@ -5714,9 +5740,11 @@ void reply_mv(connection_struct *conn, struct smb_request *req)
return;
}
status = resolve_dfspath_wcard(conn,
status = resolve_dfspath_wcard(ctx, conn,
req->flags2 & FLAGS2_DFS_PATHNAMES,
newname, &dest_has_wcard);
newname_in,
&newname,
&dest_has_wcard);
if (!NT_STATUS_IS_OK(status)) {
if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
@ -5728,9 +5756,9 @@ void reply_mv(connection_struct *conn, struct smb_request *req)
END_PROFILE(SMBmv);
return;
}
DEBUG(3,("reply_mv : %s -> %s\n",name,newname));
status = rename_internals(conn, req, name, newname, attrs, False,
src_has_wcard, dest_has_wcard);
if (!NT_STATUS_IS_OK(status)) {
@ -5745,7 +5773,7 @@ void reply_mv(connection_struct *conn, struct smb_request *req)
}
reply_outbuf(req, 0, 0);
END_PROFILE(SMBmv);
return;
}
@ -5893,6 +5921,7 @@ void reply_copy(connection_struct *conn, struct smb_request *req)
BOOL dest_has_wild = False;
SMB_STRUCT_STAT sbuf1, sbuf2;
NTSTATUS status;
TALLOC_CTX *ctx = talloc_tos();
START_PROFILE(SMBcopy);
@ -5925,9 +5954,9 @@ void reply_copy(connection_struct *conn, struct smb_request *req)
END_PROFILE(SMBcopy);
return;
}
DEBUG(3,("reply_copy : %s -> %s\n",name_in,newname_in));
if (tid2 != conn->cnum) {
/* can't currently handle inter share copies XXXX */
DEBUG(3,("Rejecting inter-share copy\n"));
@ -5936,9 +5965,11 @@ void reply_copy(connection_struct *conn, struct smb_request *req)
return;
}
status = resolve_dfspath_wcard(conn,
status = resolve_dfspath_wcard(ctx, conn,
req->flags2 & FLAGS2_DFS_PATHNAMES,
name_in, &source_has_wild);
name_in,
&name,
&source_has_wild);
if (!NT_STATUS_IS_OK(status)) {
if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
@ -5951,9 +5982,11 @@ void reply_copy(connection_struct *conn, struct smb_request *req)
return;
}
status = resolve_dfspath_wcard(conn,
status = resolve_dfspath_wcard(ctx, conn,
req->flags2 & FLAGS2_DFS_PATHNAMES,
newname_in, &dest_has_wild);
newname_in,
&newname,
&dest_has_wild);
if (!NT_STATUS_IS_OK(status)) {
if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
@ -5966,14 +5999,14 @@ void reply_copy(connection_struct *conn, struct smb_request *req)
return;
}
status = unix_convert(conn, name_in, source_has_wild, &name, NULL, &sbuf1);
status = unix_convert(conn, name, source_has_wild, &name, NULL, &sbuf1);
if (!NT_STATUS_IS_OK(status)) {
reply_nterror(req, status);
END_PROFILE(SMBcopy);
return;
}
status = unix_convert(conn, newname_in, dest_has_wild, &newname, NULL, &sbuf2);
status = unix_convert(conn, newname, dest_has_wild, &newname, NULL, &sbuf2);
if (!NT_STATUS_IS_OK(status)) {
reply_nterror(req, status);
END_PROFILE(SMBcopy);

View File

@ -1268,14 +1268,12 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn, uint16 flags2,
continue;
}
} else if (!VALID_STAT(sbuf) && SMB_VFS_STAT(conn,pathreal,&sbuf) != 0) {
pstring link_target;
/* Needed to show the msdfs symlinks as
/* Needed to show the msdfs symlinks as
* directories */
if(lp_host_msdfs() &&
if(lp_host_msdfs() &&
lp_msdfs_root(SNUM(conn)) &&
((ms_dfs_link = is_msdfs_link(conn, pathreal, link_target, &sbuf)) == True)) {
((ms_dfs_link = is_msdfs_link(conn, pathreal, &sbuf)) == True)) {
DEBUG(5,("get_lanman2_dir_entry: Masquerading msdfs link %s "
"as a directory\n",
pathreal));
@ -1778,6 +1776,7 @@ static void call_trans2findfirst(connection_struct *conn,
TALLOC_CTX *ea_ctx = NULL;
struct ea_list *ea_list = NULL;
NTSTATUS ntstatus = NT_STATUS_OK;
TALLOC_CTX *ctx = talloc_tos();
if (total_params < 13) {
reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
@ -1835,7 +1834,11 @@ close_if_end = %d requires_resume_key = %d level = 0x%x, max_data_bytes = %d\n",
return;
}
ntstatus = resolve_dfspath_wcard(conn, req->flags2 & FLAGS2_DFS_PATHNAMES, directory_in, &mask_contains_wcard);
ntstatus = resolve_dfspath_wcard(ctx, conn,
req->flags2 & FLAGS2_DFS_PATHNAMES,
directory_in,
&directory,
&mask_contains_wcard);
if (!NT_STATUS_IS_OK(ntstatus)) {
if (NT_STATUS_EQUAL(ntstatus,NT_STATUS_PATH_NOT_COVERED)) {
reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
@ -1846,7 +1849,7 @@ close_if_end = %d requires_resume_key = %d level = 0x%x, max_data_bytes = %d\n",
return;
}
ntstatus = unix_convert(conn, directory_in, True, &directory, NULL, &sbuf);
ntstatus = unix_convert(conn, directory, True, &directory, NULL, &sbuf);
if (!NT_STATUS_IS_OK(ntstatus)) {
reply_nterror(req, ntstatus);
return;
@ -3524,6 +3527,7 @@ static void call_trans2qfilepathinfo(connection_struct *conn,
struct ea_list *ea_list = NULL;
uint32 access_mask = 0x12019F; /* Default - GENERIC_EXECUTE mapping from Windows */
char *lock_data = NULL;
TALLOC_CTX *ctx = NULL;
if (!params) {
reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
@ -3642,9 +3646,11 @@ static void call_trans2qfilepathinfo(connection_struct *conn,
return;
}
status = resolve_dfspath(conn,
req->flags2 & FLAGS2_DFS_PATHNAMES,
fname_in);
status = resolve_dfspath(ctx,
conn,
req->flags2 & FLAGS2_DFS_PATHNAMES,
fname_in,
&fname);
if (!NT_STATUS_IS_OK(status)) {
if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
reply_botherror(req,
@ -3655,7 +3661,7 @@ static void call_trans2qfilepathinfo(connection_struct *conn,
return;
}
status = unix_convert(conn, fname_in, False, &fname, NULL, &sbuf);
status = unix_convert(conn, fname, False, &fname, NULL, &sbuf);
if (!NT_STATUS_IS_OK(status)) {
reply_nterror(req, status);
return;
@ -4431,8 +4437,8 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
****************************************************************************/
NTSTATUS hardlink_internals(connection_struct *conn,
char *oldname_in,
char *newname_in)
const char *oldname_in,
const char *newname_in)
{
SMB_STRUCT_STAT sbuf1, sbuf2;
char *last_component_oldname = NULL;
@ -4889,9 +4895,11 @@ static NTSTATUS smb_set_file_unix_link(connection_struct *conn,
static NTSTATUS smb_set_file_unix_hlink(connection_struct *conn,
struct smb_request *req,
const char *pdata, int total_data,
pstring fname)
const char *fname)
{
pstring oldname;
pstring oldname_in;
char *oldname = NULL;
TALLOC_CTX *ctx = talloc_tos();
NTSTATUS status = NT_STATUS_OK;
/* Set a hard link. */
@ -4899,14 +4907,16 @@ static NTSTATUS smb_set_file_unix_hlink(connection_struct *conn,
return NT_STATUS_INVALID_PARAMETER;
}
srvstr_get_path(pdata, req->flags2, oldname, pdata,
sizeof(oldname), total_data, STR_TERMINATE, &status);
srvstr_get_path(pdata, req->flags2, oldname_in, pdata,
sizeof(oldname_in), total_data, STR_TERMINATE, &status);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
status = resolve_dfspath(conn, req->flags2 & FLAGS2_DFS_PATHNAMES,
oldname);
status = resolve_dfspath(ctx, conn,
req->flags2 & FLAGS2_DFS_PATHNAMES,
oldname_in,
&oldname);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
@ -4932,10 +4942,12 @@ static NTSTATUS smb_file_rename_information(connection_struct *conn,
uint32 root_fid;
uint32 len;
pstring newname_in;
char *newname = NULL;
pstring base_name;
BOOL dest_has_wcard = False;
NTSTATUS status = NT_STATUS_OK;
char *p;
TALLOC_CTX *ctx = talloc_tos();
if (total_data < 13) {
return NT_STATUS_INVALID_PARAMETER;
@ -4956,15 +4968,17 @@ static NTSTATUS smb_file_rename_information(connection_struct *conn,
return status;
}
status = resolve_dfspath_wcard(conn,
status = resolve_dfspath_wcard(ctx, conn,
req->flags2 & FLAGS2_DFS_PATHNAMES,
newname_in, &dest_has_wcard);
newname_in,
&newname,
&dest_has_wcard);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
/* Check the new name has no '/' characters. */
if (strchr_m(newname_in, '/')) {
if (strchr_m(newname, '/')) {
return NT_STATUS_NOT_SUPPORTED;
}
@ -4977,16 +4991,15 @@ static NTSTATUS smb_file_rename_information(connection_struct *conn,
pstrcpy(base_name, "./");
}
/* Append the new name. */
pstrcat(base_name, newname_in);
pstrcat(base_name, newname);
if (fsp) {
SMB_STRUCT_STAT sbuf;
char *newname = NULL;
char *newname_last_component = NULL;
ZERO_STRUCT(sbuf);
status = unix_convert(conn, newname_in, False,
status = unix_convert(conn, newname, False,
&newname,
&newname_last_component,
&sbuf);
@ -6171,6 +6184,7 @@ static void call_trans2setfilepathinfo(connection_struct *conn,
files_struct *fsp = NULL;
NTSTATUS status = NT_STATUS_OK;
int data_return_size = 0;
TALLOC_CTX *ctx = talloc_tos();
if (!params) {
reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
@ -6268,9 +6282,10 @@ static void call_trans2setfilepathinfo(connection_struct *conn,
return;
}
status = resolve_dfspath(conn,
status = resolve_dfspath(ctx, conn,
req->flags2 & FLAGS2_DFS_PATHNAMES,
fname_in);
fname_in,
&fname);
if (!NT_STATUS_IS_OK(status)) {
if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
reply_botherror(req,
@ -6282,7 +6297,7 @@ static void call_trans2setfilepathinfo(connection_struct *conn,
return;
}
status = unix_convert(conn, fname_in, False, &fname, NULL, &sbuf);
status = unix_convert(conn, fname, False, &fname, NULL, &sbuf);
if (!NT_STATUS_IS_OK(status)) {
reply_nterror(req, status);
return;