diff options
-rw-r--r-- | source3/include/msdfs.h | 20 | ||||
-rw-r--r-- | source3/smbd/msdfs.c | 32 | ||||
-rw-r--r-- | source3/smbd/nttrans.c | 21 | ||||
-rw-r--r-- | source3/smbd/reply.c | 80 | ||||
-rw-r--r-- | source3/smbd/trans2.c | 20 |
5 files changed, 126 insertions, 47 deletions
diff --git a/source3/include/msdfs.h b/source3/include/msdfs.h index 4e3487de0f..bf553f4a99 100644 --- a/source3/include/msdfs.h +++ b/source3/include/msdfs.h @@ -64,26 +64,6 @@ struct dfs_path { pstring reqpath; }; -#define RESOLVE_DFSPATH(name, conn, inbuf, outbuf) \ -{ if ((SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES) && \ - lp_host_msdfs() && lp_msdfs_root(SNUM(conn)) && \ - dfs_redirect(name, conn, False)) \ - return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED, \ - ERRSRV, ERRbadpath);; } - -#define RESOLVE_DFSPATH_STATUS(name, conn, inbuf, outbuf) \ -{ if ((SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES) && \ - lp_host_msdfs() && lp_msdfs_root(SNUM(conn)) && \ - dfs_redirect(name, conn, False)) \ - return NT_STATUS_PATH_NOT_COVERED;; } - -#define RESOLVE_DFSPATH_WCARD(name, conn, inbuf, outbuf) \ -{ if ((SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES) && \ - lp_host_msdfs() && lp_msdfs_root(SNUM(conn)) && \ - dfs_redirect(name,conn, True)) \ - return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED, \ - ERRSRV, ERRbadpath);; } - #define init_dfsroot(conn, inbuf, outbuf) \ { if (lp_msdfs_root(SNUM(conn)) && lp_host_msdfs()) { \ DEBUG(2,("Serving %s as a Dfs root\n", \ 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)) { |