summaryrefslogtreecommitdiff
path: root/source3/smbd
diff options
context:
space:
mode:
Diffstat (limited to 'source3/smbd')
-rw-r--r--source3/smbd/msdfs.c32
-rw-r--r--source3/smbd/nttrans.c21
-rw-r--r--source3/smbd/reply.c80
-rw-r--r--source3/smbd/trans2.c20
4 files changed, 126 insertions, 27 deletions
diff --git a/source3/smbd/msdfs.c b/source3/smbd/msdfs.c
index c24cdcc708..f06bb3b044 100644
--- a/source3/smbd/msdfs.c
+++ b/source3/smbd/msdfs.c
@@ -3,6 +3,7 @@
Version 3.0
MSDfs services for Samba
Copyright (C) Shirish Kalele 2000
+ Copyright (C) Jeremy Allison 2007
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
@@ -435,7 +436,7 @@ static BOOL resolve_dfs_path(TALLOC_CTX *ctx,
for details.
*****************************************************************/
-BOOL dfs_redirect( pstring pathname, connection_struct *conn, BOOL search_wcard_flag )
+static BOOL dfs_redirect( connection_struct *conn, pstring pathname, BOOL search_wcard_flag )
{
struct dfs_path dp;
@@ -1149,3 +1150,32 @@ int enum_msdfs_links(TALLOC_CTX *ctx, struct junction_map *jucn, int jn_max)
}
return jn_count;
}
+
+/******************************************************************************
+ Core function to resolve a dfs pathname.
+******************************************************************************/
+
+BOOL resolve_dfspath(connection_struct *conn, BOOL dfs_pathnames, pstring name)
+{
+ if (dfs_pathnames && lp_host_msdfs() && lp_msdfs_root(SNUM(conn)) &&
+ dfs_redirect(conn, name, False)) {
+ return False; /* Pathname didn't resolve. */
+ }
+ return True;
+}
+
+/******************************************************************************
+ Core function to resolve a dfs pathname possibly containing a wildcard.
+ This function is identical to the above except for the BOOL param to
+ dfs_redirect but I need this to be separate so it's really clear when
+ we're allowing wildcards and when we're not. JRA.
+******************************************************************************/
+
+BOOL resolve_dfspath_wcard(connection_struct *conn, BOOL dfs_pathnames, pstring name)
+{
+ if (dfs_pathnames && lp_host_msdfs() && lp_msdfs_root(SNUM(conn)) &&
+ dfs_redirect(conn, name, True)) {
+ return False; /* Pathname didn't resolve. */
+ }
+ return True;
+}
diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c
index 19989d2178..0cc7193170 100644
--- a/source3/smbd/nttrans.c
+++ b/source3/smbd/nttrans.c
@@ -615,7 +615,10 @@ int reply_ntcreate_and_X(connection_struct *conn,
* Now contruct the smb_open_mode value from the filename,
* desired access and the share access.
*/
- RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
+ if (!resolve_dfspath(conn, SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES, fname)) {
+ END_PROFILE(SMBntcreateX);
+ return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED, ERRSRV, ERRbadpath);
+ }
oplock_request = (flags & REQUEST_OPLOCK) ? EXCLUSIVE_OPLOCK : 0;
if (oplock_request) {
@@ -1270,7 +1273,9 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o
new_file_attributes = set_posix_case_semantics(conn, file_attributes);
- RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
+ if (!resolve_dfspath(conn, SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES, fname)) {
+ return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED, ERRSRV, ERRbadpath);
+ }
status = unix_convert(conn, fname, False, NULL, &sbuf);
if (!NT_STATUS_IS_OK(status)) {
@@ -1749,9 +1754,15 @@ int reply_ntrename(connection_struct *conn,
return ERROR_NT(status);
}
- RESOLVE_DFSPATH(oldname, conn, inbuf, outbuf);
- RESOLVE_DFSPATH(newname, conn, inbuf, outbuf);
-
+ if (!resolve_dfspath(conn, SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES, oldname)) {
+ END_PROFILE(SMBntrename);
+ return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED, ERRSRV, ERRbadpath);
+ }
+ if (!resolve_dfspath(conn, SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES, newname)) {
+ END_PROFILE(SMBntrename);
+ return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED, ERRSRV, ERRbadpath);
+ }
+
DEBUG(3,("reply_ntrename : %s -> %s\n",oldname,newname));
switch(rename_type) {
diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c
index df560390c9..f85f635d6b 100644
--- a/source3/smbd/reply.c
+++ b/source3/smbd/reply.c
@@ -632,7 +632,10 @@ int reply_checkpath(connection_struct *conn, char *inbuf,char *outbuf, int dum_s
return ERROR_NT(status);
}
- RESOLVE_DFSPATH(name, conn, inbuf, outbuf);
+ if (!resolve_dfspath(conn, SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES, name)) {
+ END_PROFILE(SMBcheckpath);
+ return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED, ERRSRV, ERRbadpath);
+ }
DEBUG(3,("reply_checkpath %s mode=%d\n", name, (int)SVAL(inbuf,smb_vwv0)));
@@ -711,7 +714,10 @@ int reply_getatr(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
return ERROR_NT(status);
}
- RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
+ if (!resolve_dfspath(conn, SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES, fname)) {
+ END_PROFILE(SMBgetatr);
+ return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED, ERRSRV, ERRbadpath);
+ }
/* dos smetimes asks for a stat of "" - it returns a "hidden directory"
under WfWg - weird! */
@@ -790,7 +796,10 @@ int reply_setatr(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
return ERROR_NT(status);
}
- RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
+ if (!resolve_dfspath(conn, SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES, fname)) {
+ END_PROFILE(SMBsetatr);
+ return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED, ERRSRV, ERRbadpath);
+ }
status = unix_convert(conn, fname, False, NULL, &sbuf);
if (!NT_STATUS_IS_OK(status)) {
@@ -945,7 +954,10 @@ int reply_search(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
return ERROR_NT(nt_status);
}
- RESOLVE_DFSPATH_WCARD(path, conn, inbuf, outbuf);
+ if (!resolve_dfspath_wcard(conn, SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES, path)) {
+ END_PROFILE(SMBsearch);
+ return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED, ERRSRV, ERRbadpath);
+ }
p++;
status_len = SVAL(p, 0);
@@ -1203,7 +1215,10 @@ int reply_open(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
return ERROR_NT(status);
}
- RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
+ if (!resolve_dfspath(conn, SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES, fname)) {
+ END_PROFILE(SMBopen);
+ return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED, ERRSRV, ERRbadpath);
+ }
status = unix_convert(conn, fname, False, NULL, &sbuf);
if (!NT_STATUS_IS_OK(status)) {
@@ -1327,7 +1342,10 @@ int reply_open_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
return ERROR_NT(status);
}
- RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
+ if (!resolve_dfspath(conn, SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES, fname)) {
+ END_PROFILE(SMBopenX);
+ return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED, ERRSRV, ERRbadpath);
+ }
status = unix_convert(conn, fname, False, NULL, &sbuf);
if (!NT_STATUS_IS_OK(status)) {
@@ -1505,7 +1523,10 @@ int reply_mknew(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
return ERROR_NT(status);
}
- RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
+ if (!resolve_dfspath(conn, SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES, fname)) {
+ END_PROFILE(SMBcreate);
+ return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED, ERRSRV, ERRbadpath);
+ }
status = unix_convert(conn, fname, False, NULL, &sbuf);
if (!NT_STATUS_IS_OK(status)) {
@@ -1601,7 +1622,10 @@ int reply_ctemp(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
pstrcat(fname,"TMXXXXXX");
}
- RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
+ if (!resolve_dfspath(conn, SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES, fname)) {
+ END_PROFILE(SMBctemp);
+ return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED, ERRSRV, ERRbadpath);
+ }
status = unix_convert(conn, fname, False, NULL, &sbuf);
if (!NT_STATUS_IS_OK(status)) {
@@ -2004,7 +2028,10 @@ int reply_unlink(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
return ERROR_NT(status);
}
- RESOLVE_DFSPATH_WCARD(name, conn, inbuf, outbuf);
+ if (!resolve_dfspath_wcard(conn, SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES, name)) {
+ END_PROFILE(SMBunlink);
+ return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED, ERRSRV, ERRbadpath);
+ }
DEBUG(3,("reply_unlink : %s\n",name));
@@ -3634,7 +3661,10 @@ int reply_mkdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
return ERROR_NT(status);
}
- RESOLVE_DFSPATH(directory, conn, inbuf, outbuf);
+ if (!resolve_dfspath(conn, SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES, directory)) {
+ END_PROFILE(SMBmkdir);
+ return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED, ERRSRV, ERRbadpath);
+ }
status = unix_convert(conn, directory, False, NULL, &sbuf);
if (!NT_STATUS_IS_OK(status)) {
@@ -3852,7 +3882,10 @@ int reply_rmdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
return ERROR_NT(status);
}
- RESOLVE_DFSPATH(directory, conn, inbuf, outbuf)
+ if (!resolve_dfspath(conn, SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES, directory)) {
+ END_PROFILE(SMBrmdir);
+ return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED, ERRSRV, ERRbadpath);
+ }
status = unix_convert(conn, directory, False, NULL, &sbuf);
if (!NT_STATUS_IS_OK(status)) {
@@ -4604,8 +4637,14 @@ int reply_mv(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
return ERROR_NT(status);
}
- RESOLVE_DFSPATH_WCARD(name, conn, inbuf, outbuf);
- RESOLVE_DFSPATH_WCARD(newname, conn, inbuf, outbuf);
+ if (!resolve_dfspath_wcard(conn, SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES, name)) {
+ END_PROFILE(SMBmv);
+ return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED, ERRSRV, ERRbadpath);
+ }
+ if (!resolve_dfspath_wcard(conn, SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES, newname)) {
+ END_PROFILE(SMBmv);
+ return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED, ERRSRV, ERRbadpath);
+ }
DEBUG(3,("reply_mv : %s -> %s\n",name,newname));
@@ -4791,8 +4830,14 @@ int reply_copy(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
return ERROR_DOS(ERRSRV,ERRinvdevice);
}
- RESOLVE_DFSPATH_WCARD(name, conn, inbuf, outbuf);
- RESOLVE_DFSPATH_WCARD(newname, conn, inbuf, outbuf);
+ if (!resolve_dfspath_wcard(conn, SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES, name)) {
+ END_PROFILE(SMBcopy);
+ return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED, ERRSRV, ERRbadpath);
+ }
+ if (!resolve_dfspath_wcard(conn, SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES, newname)) {
+ END_PROFILE(SMBcopy);
+ return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED, ERRSRV, ERRbadpath);
+ }
status = unix_convert(conn, name, source_has_wild, NULL, &sbuf1);
if (!NT_STATUS_IS_OK(status)) {
@@ -4983,7 +5028,10 @@ int reply_setdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
return ERROR_NT(status);
}
- RESOLVE_DFSPATH(newdir, conn, inbuf, outbuf);
+ if (!resolve_dfspath(conn, SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES, newdir)) {
+ END_PROFILE(pathworks_setdir);
+ return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED, ERRSRV, ERRbadpath);
+ }
if (strlen(newdir) != 0) {
if (!vfs_directory_exist(conn,newdir,NULL)) {
diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c
index 0951160b3c..00327ddf45 100644
--- a/source3/smbd/trans2.c
+++ b/source3/smbd/trans2.c
@@ -1746,7 +1746,9 @@ close_if_end = %d requires_resume_key = %d level = 0x%x, max_data_bytes = %d\n",
return ERROR_NT(ntstatus);
}
- RESOLVE_DFSPATH_WCARD(directory, conn, inbuf, outbuf);
+ if (!resolve_dfspath_wcard(conn, SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES, directory)) {
+ return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED, ERRSRV, ERRbadpath);
+ }
ntstatus = unix_convert(conn, directory, True, NULL, &sbuf);
if (!NT_STATUS_IS_OK(ntstatus)) {
@@ -3140,7 +3142,9 @@ static int call_trans2qfilepathinfo(connection_struct *conn, char *inbuf, char *
return ERROR_NT(status);
}
- RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
+ if (!resolve_dfspath(conn, SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES, fname)) {
+ return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED, ERRSRV, ERRbadpath);
+ }
status = unix_convert(conn, fname, False, NULL, &sbuf);
if (!NT_STATUS_IS_OK(status)) {
@@ -4304,7 +4308,9 @@ static NTSTATUS smb_set_file_unix_hlink(connection_struct *conn,
return status;
}
- RESOLVE_DFSPATH_STATUS(oldname, conn, inbuf, outbuf);
+ if (!resolve_dfspath(conn, SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES, oldname)) {
+ return NT_STATUS_PATH_NOT_COVERED;
+ }
DEBUG(10,("smb_set_file_unix_hlink: SMB_SET_FILE_UNIX_LINK doing hard link %s -> %s\n",
fname, oldname));
@@ -4350,7 +4356,9 @@ static NTSTATUS smb_file_rename_information(connection_struct *conn,
return status;
}
- RESOLVE_DFSPATH_STATUS(newname, conn, inbuf, outbuf);
+ if (!resolve_dfspath(conn, SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES, newname)) {
+ return NT_STATUS_PATH_NOT_COVERED;
+ }
/* Check the new name has no '/' characters. */
if (strchr_m(newname, '/')) {
@@ -5432,7 +5440,9 @@ static int call_trans2setfilepathinfo(connection_struct *conn, char *inbuf, char
return ERROR_NT(status);
}
- RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
+ if (!resolve_dfspath(conn, SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES, fname)) {
+ ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED, ERRSRV, ERRbadpath);
+ }
status = unix_convert(conn, fname, False, NULL, &sbuf);
if (!NT_STATUS_IS_OK(status)) {