summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVolker Lendecke <vlendec@samba.org>2007-01-09 15:50:40 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 12:17:00 -0500
commit87bd4d2723e806ac0bc751ccf36fcdb8ed01c03c (patch)
tree36ddf3515f04e11ff91b6f1d5f749e73deec58dd
parent7f88a7c948bec050ac34599922f1a76cced88f11 (diff)
downloadsamba-87bd4d2723e806ac0bc751ccf36fcdb8ed01c03c.tar.gz
samba-87bd4d2723e806ac0bc751ccf36fcdb8ed01c03c.tar.bz2
samba-87bd4d2723e806ac0bc751ccf36fcdb8ed01c03c.zip
r20632: The extended RAW-SAMBA3BADPATH test led me to some wrong assumptions, in
particular the NT_STATUS_INVALID_PARAMETER thing was badly wrong. Remove the changes based on it. Using gentest is much more effective in this respect, but it will take a while to figure out the wildcard error handling of W2k3. Volker (This used to be commit 58b8a242a7f08c1292d24fc73df170dbcd68c10d)
-rw-r--r--source3/smbd/reply.c112
1 files changed, 59 insertions, 53 deletions
diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c
index e0f074a7ca..cc181223f2 100644
--- a/source3/smbd/reply.c
+++ b/source3/smbd/reply.c
@@ -1899,7 +1899,7 @@ static NTSTATUS can_rename(connection_struct *conn, char *fname, uint16 dirtype,
********************************************************************/
static NTSTATUS can_delete(connection_struct *conn, char *fname,
- uint32 dirtype)
+ uint32 dirtype, BOOL bad_path)
{
SMB_STRUCT_STAT sbuf;
uint32 fattr;
@@ -1913,6 +1913,13 @@ static NTSTATUS can_delete(connection_struct *conn, char *fname,
}
if (SMB_VFS_LSTAT(conn,fname,&sbuf) != 0) {
+ if(errno == ENOENT) {
+ if (bad_path) {
+ return NT_STATUS_OBJECT_PATH_NOT_FOUND;
+ } else {
+ return NT_STATUS_OBJECT_NAME_NOT_FOUND;
+ }
+ }
return map_nt_error_from_unix(errno);
}
@@ -1977,6 +1984,7 @@ NTSTATUS unlink_internals(connection_struct *conn, uint32 dirtype,
{
pstring directory;
pstring mask;
+ pstring orig_name;
char *p;
int count=0;
NTSTATUS error = NT_STATUS_OK;
@@ -1987,12 +1995,12 @@ NTSTATUS unlink_internals(connection_struct *conn, uint32 dirtype,
*directory = *mask = 0;
rc = unix_convert(name,conn,0,&bad_path,&sbuf);
- if (bad_path) {
- return has_wild
- ? NT_STATUS_INVALID_PARAMETER
- : NT_STATUS_OBJECT_PATH_NOT_FOUND;
- }
+ /*
+ * Feel my pain, this code needs rewriting *very* badly! -- vl
+ */
+ pstrcpy(orig_name, name);
+
p = strrchr_m(name,'/');
if (!p) {
pstrcpy(directory,".");
@@ -2018,84 +2026,82 @@ NTSTATUS unlink_internals(connection_struct *conn, uint32 dirtype,
if (!has_wild) {
pstrcat(directory,"/");
pstrcat(directory,mask);
- error = can_delete(conn,directory,dirtype);
+ error = can_delete(conn,directory,dirtype,bad_path);
if (!NT_STATUS_IS_OK(error))
return error;
if (SMB_VFS_UNLINK(conn,directory) == 0) {
count++;
- notify_fname(conn, directory, -1,
+ notify_fname(conn, orig_name, -1,
NOTIFY_ACTION_REMOVED);
}
} else {
struct smb_Dir *dir_hnd = NULL;
const char *dname;
- long offset = 0;
if (strequal(mask,"????????.???"))
pstrcpy(mask,"*");
- if (!check_name(directory,conn)) {
- return NT_STATUS_OBJECT_PATH_NOT_FOUND;
- }
-
- if (!(dir_hnd = OpenDir(conn, directory, mask, dirtype))) {
- return NT_STATUS_NO_SUCH_FILE;
- }
+ if (check_name(directory,conn))
+ dir_hnd = OpenDir(conn, directory, mask, dirtype);
/* XXXX the CIFS spec says that if bit0 of the flags2 field is set then
the pattern matches against the long name, otherwise the short name
We don't implement this yet XXXX
*/
- error = NT_STATUS_NO_SUCH_FILE;
+ if (dir_hnd) {
+ long offset = 0;
+ error = NT_STATUS_NO_SUCH_FILE;
- while ((dname = ReadDirName(dir_hnd, &offset))) {
- SMB_STRUCT_STAT st;
- pstring fname;
- BOOL sys_direntry = False;
- pstrcpy(fname,dname);
+ while ((dname = ReadDirName(dir_hnd, &offset))) {
+ SMB_STRUCT_STAT st;
+ pstring fname;
+ BOOL sys_direntry = False;
+ pstrcpy(fname,dname);
- if (!is_visible_file(conn, directory, dname, &st, True)) {
- continue;
- }
+ if (!is_visible_file(conn, directory, dname, &st, True)) {
+ continue;
+ }
- /* Quick check for "." and ".." */
- if (fname[0] == '.') {
- if (!fname[1] || (fname[1] == '.' && !fname[2])) {
- if (dirtype & FILE_ATTRIBUTE_DIRECTORY) {
- sys_direntry = True;
- } else {
- continue;
+ /* Quick check for "." and ".." */
+ if (fname[0] == '.') {
+ if (!fname[1] || (fname[1] == '.' && !fname[2])) {
+ if (dirtype & FILE_ATTRIBUTE_DIRECTORY) {
+ sys_direntry = True;
+ } else {
+ continue;
+ }
}
}
- }
- if(!mask_match(fname, mask, conn->case_sensitive))
- continue;
+ if(!mask_match(fname, mask, conn->case_sensitive))
+ continue;
- if (sys_direntry) {
- error = NT_STATUS_OBJECT_NAME_INVALID;
- DEBUG(3,("unlink_internals: system directory delete denied [%s] mask [%s]\n",
- fname, mask));
- break;
- }
+ if (sys_direntry) {
+ error = NT_STATUS_OBJECT_NAME_INVALID;
+ DEBUG(3,("unlink_internals: system directory delete denied [%s] mask [%s]\n",
+ fname, mask));
+ break;
+ }
- slprintf(fname,sizeof(fname)-1, "%s/%s",directory,dname);
- error = can_delete(conn, fname, dirtype);
- if (!NT_STATUS_IS_OK(error)) {
- continue;
- }
- if (SMB_VFS_UNLINK(conn,fname) == 0) {
- count++;
- notify_action(
- conn, directory, dname,
- -1, NOTIFY_ACTION_REMOVED);
+ slprintf(fname,sizeof(fname)-1, "%s/%s",directory,dname);
+ error = can_delete(conn, fname, dirtype,
+ bad_path);
+ if (!NT_STATUS_IS_OK(error)) {
+ continue;
+ }
+ if (SMB_VFS_UNLINK(conn,fname) == 0) {
+ count++;
+ notify_action(
+ conn, directory, dname,
+ -1, NOTIFY_ACTION_REMOVED);
+ }
+ DEBUG(3,("unlink_internals: succesful unlink [%s]\n",fname));
}
- DEBUG(3,("unlink_internals: succesful unlink [%s]\n",fname));
+ CloseDir(dir_hnd);
}
- CloseDir(dir_hnd);
}
if (count == 0 && NT_STATUS_IS_OK(error)) {