From 952799d9afe028d822181831715b85521c89a7ef Mon Sep 17 00:00:00 2001 From: Shirish Kalele Date: Wed, 8 Mar 2000 22:14:30 +0000 Subject: 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) --- source3/smbd/negprot.c | 5 +++++ source3/smbd/nttrans.c | 5 ++++- source3/smbd/process.c | 6 +++-- source3/smbd/reply.c | 35 +++++++++++++++++++++++++++++- source3/smbd/server.c | 14 ++++++++++-- source3/smbd/trans2.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++--- 6 files changed, 115 insertions(+), 9 deletions(-) (limited to 'source3/smbd') 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,¶ms[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))) { @@ -2120,6 +2125,49 @@ static int call_trans2findnotifynext(connection_struct *conn, return(-1); } +/**************************************************************************** + reply to a TRANS2_GET_DFS_REFERRAL - Shirish Kalele +****************************************************************************/ +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, ¶ms[2]); + DEBUG(10,("UNICODE referral for %s\n",pathname)); + } + else + pstrcpy(pathname,¶ms[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) ****************************************************************************/ @@ -2353,6 +2401,11 @@ int reply_trans2(connection_struct *conn, outsize = call_trans2mkdir(conn, inbuf, outbuf, length, bufsize, ¶ms, &data); break; + + case TRANSACT2_GET_DFS_REFERRAL: + outsize = call_trans2getdfsreferral(conn,inbuf,outbuf,length, + bufsize, ¶ms, &data); + break; default: /* Error in request */ DEBUG(2,("Unknown request %d in trans2 call\n", tran_call)); -- cgit