summaryrefslogtreecommitdiff
path: root/source3/smbd
diff options
context:
space:
mode:
authorShirish Kalele <kalele@samba.org>2000-03-08 22:14:30 +0000
committerShirish Kalele <kalele@samba.org>2000-03-08 22:14:30 +0000
commit952799d9afe028d822181831715b85521c89a7ef (patch)
treecb4884e78037baa26ae2a0985b337a8dc0944558 /source3/smbd
parent3958c3910658e99fe1cfd737e0cfc126dffc75da (diff)
downloadsamba-952799d9afe028d822181831715b85521c89a7ef.tar.gz
samba-952799d9afe028d822181831715b85521c89a7ef.tar.bz2
samba-952799d9afe028d822181831715b85521c89a7ef.zip
dded Microsoft Dfs services.
* added a new msdfs/ directory under source/ * added msdfs sources under this directory. * modified configure setup to add a --with-msdfs configure time option Modified Files: Makefile.in acconfig.h configure configure.in include/config.h.in include/includes.h include/proto.h include/smb.h include/smb_macros.h param/loadparm.c smbd/negprot.c smbd/nttrans.c smbd/process.c smbd/reply.c smbd/server.c smbd/trans2.c Added Files: include/msdfs.h msdfs/README msdfs/msdfs.c msdfs/msdfs_tdb.c msdfs/parse_dfs_map.c ---------------------------------------------------------------------- (This used to be commit 4684b4a188b54493dbe7f0de2909a8d3c5c3ebf9)
Diffstat (limited to 'source3/smbd')
-rw-r--r--source3/smbd/negprot.c5
-rw-r--r--source3/smbd/nttrans.c5
-rw-r--r--source3/smbd/process.c6
-rw-r--r--source3/smbd/reply.c35
-rw-r--r--source3/smbd/server.c14
-rw-r--r--source3/smbd/trans2.c59
6 files changed, 115 insertions, 9 deletions
diff --git a/source3/smbd/negprot.c b/source3/smbd/negprot.c
index 3cabc6b229..47a82c6e31 100644
--- a/source3/smbd/negprot.c
+++ b/source3/smbd/negprot.c
@@ -199,6 +199,11 @@ static int reply_nt1(char *outbuf)
capabilities |= CAP_RAW_MODE;
}
+#ifdef MS_DFS
+ if(lp_host_msdfs())
+ capabilities |= CAP_DFS;
+#endif
+
if (lp_security() >= SEC_USER) secword |= 1;
if (doencrypt) secword |= 2;
diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c
index a4d59004e8..c57c9c56cc 100644
--- a/source3/smbd/nttrans.c
+++ b/source3/smbd/nttrans.c
@@ -692,7 +692,8 @@ 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((smb_open_mode = map_share_mode(&stat_open_only, fname, desired_access,
share_access,
file_attributes)) == -1)
@@ -1059,6 +1060,8 @@ static int call_nt_transact_create(connection_struct *conn,
*/
set_posix_case_semantics(file_attributes);
+
+ RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
unix_convert(fname,conn,0,&bad_path,NULL);
diff --git a/source3/smbd/process.c b/source3/smbd/process.c
index 7d6e171d05..403990a79d 100644
--- a/source3/smbd/process.c
+++ b/source3/smbd/process.c
@@ -385,7 +385,7 @@ struct smb_message_struct
/* LANMAN2.0 PROTOCOL FOLLOWS */
{SMBfindnclose, "SMBfindnclose", reply_findnclose, AS_USER},
{SMBfindclose, "SMBfindclose", reply_findclose,AS_USER},
- {SMBtrans2, "SMBtrans2", reply_trans2, AS_USER | QUEUE_IN_OPLOCK },
+ {SMBtrans2, "SMBtrans2", reply_trans2, AS_USER | QUEUE_IN_OPLOCK | CAN_IPC },
{SMBtranss2, "SMBtranss2", reply_transs2, AS_USER},
/* NT PROTOCOL FOLLOWS */
@@ -704,7 +704,9 @@ void construct_reply_common(char *inbuf,char *outbuf)
CVAL(outbuf,smb_reh) = 0;
SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES)); /* bit 7 set
means a reply */
- SSVAL(outbuf,smb_flg2,FLAGS2_LONG_PATH_COMPONENTS); /* say we support long filenames */
+ SSVAL(outbuf,smb_flg2,FLAGS2_LONG_PATH_COMPONENTS);
+ /* say we support long filenames */
+
SSVAL(outbuf,smb_err,SMB_SUCCESS);
SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c
index 3715bd224f..6b1d28abe0 100644
--- a/source3/smbd/reply.c
+++ b/source3/smbd/reply.c
@@ -352,7 +352,10 @@ int reply_tcon_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
/* what does setting this bit do? It is set by NT4 and
may affect the ability to autorun mounted cdroms */
SSVAL(outbuf, smb_vwv2, SMB_SUPPORT_SEARCH_BITS);
+
+ init_dfsroot(conn, inbuf, outbuf);
}
+
DEBUG(3,("tconX service=%s user=%s\n",
service, user));
@@ -1024,6 +1027,9 @@ int reply_chkpth(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
SMB_STRUCT_STAT st;
pstrcpy(name,smb_buf(inbuf) + 1);
+
+ RESOLVE_DFSPATH(name, conn, inbuf, outbuf);
+
unix_convert(name,conn,0,&bad_path,&st);
mode = SVAL(inbuf,smb_vwv0);
@@ -1085,6 +1091,10 @@ int reply_getatr(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
pstrcpy(fname,smb_buf(inbuf) + 1);
+ RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
+
+ /* if((SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES) && dfs_redirect(fname,conn)) return(dfs_path_error(inbuf,outbuf));
+ */
/* dos smetimes asks for a stat of "" - it returns a "hidden directory"
under WfWg - weird! */
if (! (*fname))
@@ -1530,6 +1540,9 @@ int reply_open(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
share_mode = SVAL(inbuf,smb_vwv0);
pstrcpy(fname,smb_buf(inbuf)+1);
+
+ RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
+
unix_convert(fname,conn,0,&bad_path,NULL);
fsp = file_new();
@@ -1632,6 +1645,9 @@ int reply_open_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
/* XXXX we need to handle passed times, sattr and flags */
pstrcpy(fname,smb_buf(inbuf));
+
+ RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
+
unix_convert(fname,conn,0,&bad_path,NULL);
fsp = file_new();
@@ -1766,6 +1782,9 @@ int reply_mknew(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
createmode = SVAL(inbuf,smb_vwv0);
pstrcpy(fname,smb_buf(inbuf)+1);
+
+ RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
+
unix_convert(fname,conn,0,&bad_path,NULL);
if (createmode & aVOLID)
@@ -1851,6 +1870,9 @@ int reply_ctemp(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
createmode = SVAL(inbuf,smb_vwv0);
pstrcpy(fname,smb_buf(inbuf)+1);
pstrcat(fname,"/TMXXXXXX");
+
+ RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
+
unix_convert(fname,conn,0,&bad_path,NULL);
unixmode = unix_mode(conn,createmode,fname);
@@ -1955,6 +1977,8 @@ int reply_unlink(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
pstrcpy(name,smb_buf(inbuf) + 1);
+ RESOLVE_DFSPATH(name, conn, inbuf, outbuf);
+
DEBUG(3,("reply_unlink : %s\n",name));
rc = unix_convert(name,conn,0,&bad_path,NULL);
@@ -3419,6 +3443,9 @@ int reply_rmdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
BOOL bad_path = False;
pstrcpy(directory,smb_buf(inbuf) + 1);
+
+ RESOLVE_DFSPATH(directory, conn, inbuf, outbuf)
+
unix_convert(directory,conn, NULL,&bad_path,NULL);
if (check_name(directory,conn))
@@ -3749,7 +3776,10 @@ int reply_mv(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, in
pstrcpy(name,smb_buf(inbuf) + 1);
pstrcpy(newname,smb_buf(inbuf) + 3 + strlen(name));
-
+
+ RESOLVE_DFSPATH(name, conn, inbuf, outbuf);
+ RESOLVE_DFSPATH(newname, conn, inbuf, outbuf);
+
DEBUG(3,("reply_mv : %s -> %s\n",name,newname));
outsize = rename_internals(conn, inbuf, outbuf, name, newname, False);
@@ -3882,6 +3912,9 @@ int reply_copy(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
return(ERROR(ERRSRV,ERRinvdevice));
}
+ RESOLVE_DFSPATH(name, conn, inbuf, outbuf);
+ RESOLVE_DFSPATH(newname, conn, inbuf, outbuf);
+
rc = unix_convert(name,conn,0,&bad_path1,NULL);
unix_convert(newname,conn,0,&bad_path2,NULL);
diff --git a/source3/smbd/server.c b/source3/smbd/server.c
index d1788678a7..1c4a4e3752 100644
--- a/source3/smbd/server.c
+++ b/source3/smbd/server.c
@@ -282,7 +282,8 @@ max can be %d\n",
BOOL reload_services(BOOL test)
{
BOOL ret;
-
+ int i=0;
+
if (lp_loaded()) {
pstring fname;
pstrcpy(fname,lp_configfile());
@@ -298,9 +299,15 @@ BOOL reload_services(BOOL test)
return(True);
lp_killunused(conn_snum_used);
-
+
ret = lp_load(servicesf,False,False,True);
+ /* load the dfs maps of all the services having
+ a dfs_map parameter
+ we don't want to do this in lp_load because we want just the smbd
+ server to load up the dfs maps into msdfds.tdb. not nmbd, swat etc*/
+ load_dfsmaps();
+
load_printers();
/* perhaps the config filename is now set */
@@ -431,6 +438,9 @@ void exit_server(char *reason)
}
locking_end();
+#ifdef MS_DFS
+ msdfs_end();
+#endif
DEBUG(3,("Server exit (%s)\n", (reason ? reason : "")));
exit(0);
diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c
index dff57a41c2..21fa9b5cc5 100644
--- a/source3/smbd/trans2.c
+++ b/source3/smbd/trans2.c
@@ -101,8 +101,8 @@ static int send_trans2_replies(char *outbuf, int bufsize, char *params,
* the length of the data we send over the wire, as the alignment offsets
* are sent here. Fix from Marc_Jacobsen@hp.com.
*/
- total_sent_thistime = MIN(total_sent_thistime, useable_space +
- alignment_offset + data_alignment_offset);
+ total_sent_thistime = MIN(total_sent_thistime, useable_space+
+ alignment_offset + data_alignment_offset);
set_message(outbuf, 10, total_sent_thistime, True);
@@ -120,7 +120,7 @@ static int send_trans2_replies(char *outbuf, int bufsize, char *params,
SSVAL(outbuf,smb_prcnt, params_sent_thistime);
if(params_sent_thistime == 0)
{
- SSVAL(outbuf,smb_proff,0);
+ SSVAL(outbuf,smb_proff,((smb_buf(outbuf)+alignment_offset) - smb_base(outbuf)));
SSVAL(outbuf,smb_prdisp,0);
}
else
@@ -693,6 +693,8 @@ static int call_trans2findfirst(connection_struct *conn,
pstrcpy(directory, params + 12); /* Complete directory path with
wildcard mask appended */
+ RESOLVE_FINDFIRST_DFSPATH(directory, conn, inbuf, outbuf);
+
DEBUG(5,("path=%s\n",directory));
unix_convert(directory,conn,0,&bad_path,NULL);
@@ -1354,6 +1356,9 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
fname = &fname1[0];
pstrcpy(fname,&params[6]);
+
+ RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
+
unix_convert(fname,conn,0,&bad_path,&sbuf);
if (!check_name(fname,conn) ||
(!VALID_STAT(sbuf) && conn->vfs_ops.stat(dos_to_unix(fname,False),&sbuf))) {
@@ -2121,6 +2126,49 @@ static int call_trans2findnotifynext(connection_struct *conn,
}
/****************************************************************************
+ reply to a TRANS2_GET_DFS_REFERRAL - Shirish Kalele <kalele@veritas.com>
+****************************************************************************/
+static int call_trans2getdfsreferral(connection_struct *conn, char* inbuf,
+ char* outbuf, int length, int bufsize,
+ char** pparams, char** ppdata)
+{
+ char *params = *pparams;
+ enum remote_arch_types ra_type = get_remote_arch();
+ BOOL NT_arch = ((ra_type == RA_WINNT) || (ra_type == RA_WIN2K));
+ pstring pathname;
+ int reply_size = 0;
+ char* dfs_referral = NULL;
+ int max_referral_level = SVAL(params,0);
+
+ DEBUG(10,("call_trans2getdfsreferral\n"));
+#ifdef MS_DFS
+ if(!lp_host_msdfs())
+ return(ERROR(ERRDOS,ERRbadfunc));
+
+ /* if pathname is in UNICODE, convert to DOS */
+ /* NT always sends in UNICODE, may not set UNICODE flag */
+ if(NT_arch || (SVAL(inbuf,smb_flg2) & FLAGS2_UNICODE_STRINGS))
+ {
+ unistr_to_dos(pathname, &params[2]);
+ DEBUG(10,("UNICODE referral for %s\n",pathname));
+ }
+ else
+ pstrcpy(pathname,&params[2]);
+
+ if((reply_size = setup_dfs_referral(pathname,max_referral_level,ppdata)) < 0)
+ return(ERROR(ERRDOS,ERRbadfile));
+
+ SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2) | FLAGS2_UNICODE_STRINGS |
+ FLAGS2_DFS_PATHNAMES);
+ send_trans2_replies(outbuf,bufsize,0,0,*ppdata,reply_size);
+#else
+ DEBUG(0,("Unexpected DFS referral request!\n"));
+ return(ERROR(ERRDOS,ERRbadfunc));
+#endif
+}
+
+
+/****************************************************************************
reply to a SMBfindclose (stop trans2 directory search)
****************************************************************************/
int reply_findclose(connection_struct *conn,
@@ -2353,6 +2401,11 @@ int reply_trans2(connection_struct *conn,
outsize = call_trans2mkdir(conn, inbuf, outbuf, length,
bufsize, &params, &data);
break;
+
+ case TRANSACT2_GET_DFS_REFERRAL:
+ outsize = call_trans2getdfsreferral(conn,inbuf,outbuf,length,
+ bufsize, &params, &data);
+ break;
default:
/* Error in request */
DEBUG(2,("Unknown request %d in trans2 call\n", tran_call));