Samba DFS root support

Nigel Williams nigel.williams at nomura.co.uk
Thu Jul 9 07:48:08 GMT 1998


I've attached some diffs to 1.9.18p8 which implement part of DFS root
and seems to work ok for an NT client.   The table of directory to share
mappings is hard coded and there are many things letf to do but at least
we can see that it works.

I will be working on this more soon so any suggestions would be
appreciated.

Nigel
-------------- next part --------------
Only in samba-1.9.18p8-mod: bin
Common subdirectories: samba-1.9.18p8/docs and samba-1.9.18p8-mod/docs
Common subdirectories: samba-1.9.18p8/examples and samba-1.9.18p8-mod/examples
Only in samba-1.9.18p8-mod: lib
Only in samba-1.9.18p8-mod: man
Common subdirectories: samba-1.9.18p8/packaging and samba-1.9.18p8-mod/packaging
Common subdirectories: samba-1.9.18p8/source and samba-1.9.18p8-mod/source
Common subdirectories: samba-1.9.18p8/docs/faq and samba-1.9.18p8-mod/docs/faq
Common subdirectories: samba-1.9.18p8/examples/dce-dfs and samba-1.9.18p8-mod/examples/dce-dfs
Common subdirectories: samba-1.9.18p8/examples/misc and samba-1.9.18p8-mod/examples/misc
Common subdirectories: samba-1.9.18p8/examples/printer-accounting and samba-1.9.18p8-mod/examples/printer-accounting
Common subdirectories: samba-1.9.18p8/examples/printing and samba-1.9.18p8-mod/examples/printing
Common subdirectories: samba-1.9.18p8/examples/simple and samba-1.9.18p8-mod/examples/simple
Common subdirectories: samba-1.9.18p8/examples/svr4-startup and samba-1.9.18p8-mod/examples/svr4-startup
Common subdirectories: samba-1.9.18p8/examples/thoralf and samba-1.9.18p8-mod/examples/thoralf
Common subdirectories: samba-1.9.18p8/examples/tridge and samba-1.9.18p8-mod/examples/tridge
Common subdirectories: samba-1.9.18p8/examples/validchars and samba-1.9.18p8-mod/examples/validchars
Common subdirectories: samba-1.9.18p8/packaging/Caldera and samba-1.9.18p8-mod/packaging/Caldera
Common subdirectories: samba-1.9.18p8/packaging/SGI and samba-1.9.18p8-mod/packaging/SGI
Common subdirectories: samba-1.9.18p8/packaging/Solaris and samba-1.9.18p8-mod/packaging/Solaris
Common subdirectories: samba-1.9.18p8/packaging/SuSE and samba-1.9.18p8-mod/packaging/SuSE
Common subdirectories: samba-1.9.18p8/packaging/redhat and samba-1.9.18p8-mod/packaging/redhat
Common subdirectories: samba-1.9.18p8/packaging/Solaris/pkg-specs and samba-1.9.18p8-mod/packaging/Solaris/pkg-specs
Common subdirectories: samba-1.9.18p8/packaging/SuSE/5.2 and samba-1.9.18p8-mod/packaging/SuSE/5.2
Common subdirectories: samba-1.9.18p8/packaging/redhat/RH42 and samba-1.9.18p8-mod/packaging/redhat/RH42
Common subdirectories: samba-1.9.18p8/packaging/redhat/RH50 and samba-1.9.18p8-mod/packaging/redhat/RH50
diff -rc samba-1.9.18p8/source/Makefile samba-1.9.18p8-mod/source/Makefile
*** samba-1.9.18p8/source/Makefile	Mon Jun  1 07:29:04 1998
--- samba-1.9.18p8-mod/source/Makefile	Fri Jul  3 15:29:45 1998
***************
*** 5,15 ****
  ###########################################################################
  
  # The base directory for all samba files
! BASEDIR = /usr/local/samba
  
  # The base manpages directory to put the man pages in
  # Note: $(MANDIR)/man1, $(MANDIR)/man5 and $(MANDIR)/man8 must exist.
! MANDIR = /usr/local/man
  
  # The directories to put things in. If you use multiple
  # architectures or share the samba binaries across NFS then
--- 5,17 ----
  ###########################################################################
  
  # The base directory for all samba files
! #BASEDIR = /usr/local/samba
! BASEDIR = ..
  
  # The base manpages directory to put the man pages in
  # Note: $(MANDIR)/man1, $(MANDIR)/man5 and $(MANDIR)/man8 must exist.
! #MANDIR = /usr/local/man
! MANDIR = $(BASEDIR)/man
  
  # The directories to put things in. If you use multiple
  # architectures or share the samba binaries across NFS then
***************
*** 20,26 ****
  BINDIR = $(BASEDIR)/bin
  SBINDIR = $(BASEDIR)/bin
  LIBDIR = $(BASEDIR)/lib
! VARDIR = $(BASEDIR)/var
  
  # The permissions to give the executables
  INSTALLPERMS = 0755
--- 22,28 ----
  BINDIR = $(BASEDIR)/bin
  SBINDIR = $(BASEDIR)/bin
  LIBDIR = $(BASEDIR)/lib
! VARDIR = /var/tmp/samba
  
  # The permissions to give the executables
  INSTALLPERMS = 0755
***************
*** 27,38 ****
  
  # Add any optimisation or debugging flags here
  # add -DSYSLOG for syslog support
! FLAGS1 = -O
  LIBS1 = 
  
  # You will need to use a ANSI C compiler. This means under SunOS 4 you can't 
  # use cc, instead you will have to use gcc. 
! # CC = gcc
  
  # This may help with some versions of make
  SHELL = /bin/sh
--- 29,42 ----
  
  # Add any optimisation or debugging flags here
  # add -DSYSLOG for syslog support
! FLAGS1 = -g -pipe
  LIBS1 = 
  
  # You will need to use a ANSI C compiler. This means under SunOS 4 you can't 
  # use cc, instead you will have to use gcc. 
! CC = gcc
! #CC = cc
! CCXX = g++
  
  # This may help with some versions of make
  SHELL = /bin/sh
***************
*** 250,255 ****
--- 254,262 ----
  # FLAGSM = -DSUNOS5 -DSHADOW_PWD -DNETGROUP -DFAST_SHARE_MODES
  # LIBSM = -lsocket -lnsl
  # AWK = nawk 
+ #FLAGSM = -DSUNOS5 -DSHADOW_PWD -DNETGROUP -DFAST_SHARE_MODES -DAUTOMOUNT -DKANJI=\"sjis\"
+ #LIBSM = -lsocket -lnsl
+ #AWK = nawk 
  
  # This is for SUNOS 5.2 and 5.3 (also known as Solaris 2.2 and 2.3)
  # contributed by hdsi at newtech.net
***************
*** 256,261 ****
--- 263,271 ----
  # FLAGSM = -DSUNOS5 -DSHADOW_PWD -DNETGROUP -DNO_STRFTIME -DFAST_SHARE_MODES
  # LIBSM = -lsocket -lnsl
  # AWK = nawk 
+ FLAGSM = -DSUNOS5 -DSHADOW_PWD -DNETGROUP -DFAST_SHARE_MODES -DAUTOMOUNT -DSHARE_MODES_VIA_NLM -DKANJI=\"sjis\"
+ LIBSM = -lsocket -lkvm -lelf -lnsl
+ AWK = nawk 
  
  # This is for UXP/DS
  # contributed by dsfrost at oai6.yk.fujitsu.co.jp
Common subdirectories: samba-1.9.18p8/source/mem_man and samba-1.9.18p8-mod/source/mem_man
diff -rc samba-1.9.18p8/source/proto.h samba-1.9.18p8-mod/source/proto.h
*** samba-1.9.18p8/source/proto.h	Sat Jun 13 02:44:20 1998
--- samba-1.9.18p8-mod/source/proto.h	Wed Jul  1 16:24:36 1998
***************
*** 1448,1453 ****
--- 1448,1455 ----
  void unix_format(char *fname);
  void dos_format(char *fname);
  void show_msg(char *buf);
+ void show_msg_nodeb(char *buf);
+ void show_msg_data_nodeb(char *buf);
  int smb_len(char *buf);
  void _smb_setlen(char *buf,int len);
  void smb_setlen(char *buf,int len);
diff -rc samba-1.9.18p8/source/reply.c samba-1.9.18p8-mod/source/reply.c
*** samba-1.9.18p8/source/reply.c	Sat Jun 13 02:44:21 1998
--- samba-1.9.18p8-mod/source/reply.c	Mon Jul  6 13:37:37 1998
***************
*** 139,145 ****
  		return(0);
  	}
  	
! 	DEBUG(5,("%s init msg_type=0x%x msg_flags=0x%x\n",
  		 timestring(),msg_type,msg_flags));
  	
  	return(outsize);
--- 139,145 ----
  		return(0);
  	}
  	
! 	DEBUG(0,("%s init msg_type=0x%x msg_flags=0x%x\n",
  		 timestring(),msg_type,msg_flags));
  	
  	return(outsize);
***************
*** 709,714 ****
--- 709,716 ----
  }
  
  
+ extern int NT_error_packet(char *inbuf,char *outbuf,uint32 error_code,int line);
+ 
  /****************************************************************************
    reply to a chkpth
  ****************************************************************************/
***************
*** 721,726 ****
--- 723,734 ----
    BOOL bad_path = False;
   
    cnum = SVAL(inbuf,smb_tid);
+ 
+   if(!IsPathWithinThisDfsServer(cnum, smb_buf(inbuf)+1)) {
+ 
+     return NT_error_packet(inbuf,outbuf, NT_STATUS_PATH_NOT_COVERED | 0xc0000000,__LINE__);
+     /*return(ERROR(0xc000, NT_STATUS_PATH_NOT_COVERED));*/
+   }
    
    pstrcpy(name,smb_buf(inbuf) + 1);
    unix_convert(name,cnum,0,&bad_path);
***************
*** 781,786 ****
--- 789,801 ----
   
    cnum = SVAL(inbuf,smb_tid);
  
+   if(!IsPathWithinThisDfsServer(cnum, smb_buf(inbuf)+1)) {
+ 
+     return NT_error_packet(inbuf,outbuf, NT_STATUS_PATH_NOT_COVERED | 0xc0000000,__LINE__);
+ 
+     /*return(ERROR(0xc0, NT_STATUS_PATH_NOT_COVERED)); */
+   }
+ 
    pstrcpy(fname,smb_buf(inbuf) + 1);
    unix_convert(fname,cnum,0,&bad_path);
  
Common subdirectories: samba-1.9.18p8/source/rpc_pipes and samba-1.9.18p8-mod/source/rpc_pipes
diff -rc samba-1.9.18p8/source/server.c samba-1.9.18p8-mod/source/server.c
*** samba-1.9.18p8/source/server.c	Sat Jun 13 02:44:21 1998
--- samba-1.9.18p8-mod/source/server.c	Mon Jul  6 13:32:18 1998
***************
*** 2493,2498 ****
--- 2493,2521 ----
  
  
  /****************************************************************************
+   create an NT error packet. Normally called using the ERROR() macro
+ ****************************************************************************/
+ int NT_error_packet(char *inbuf,char *outbuf,uint32 error_code,int line)
+ {
+   int outsize = set_message(outbuf,0,0,True);
+   int cmd;
+   cmd = CVAL(inbuf,smb_com);
+ 
+   /*0=long filenames, 1=extended attrs, 12=not DFS capable, 13=no paging of IO, 14=NT status codes, 15=using UNICODE strings*/ 
+   SSVAL(outbuf, smb_flg2, 0xc003 | (1<<12)); /* PAXX: Someone please unhack this */
+   SIVAL(outbuf, smb_rcls, error_code);
+   
+   DEBUG(3,("%s error packet at line %d cmd=%d (%s) ecode=%x\n",
+ 	   timestring(),
+ 	   line,
+ 	   (int)CVAL(inbuf,smb_com),
+ 	   smb_fn_name(CVAL(inbuf,smb_com)),
+ 	   error_code));
+ 
+   return(outsize);
+ }
+ 
+ /****************************************************************************
    create an error packet. Normally called using the ERROR() macro
  ****************************************************************************/
  int error_packet(char *inbuf,char *outbuf,int error_class,uint32 error_code,int line)
***************
*** 2785,2790 ****
--- 2808,2814 ----
    extern int Client;
    static int trans_num;
    int msg_type = CVAL(inbuf,0);
+   int flags2 = SVAL(inbuf, smb_flg2);
    int32 len = smb_len(inbuf);
    int nread = len + 4;
  
***************
*** 2815,2820 ****
--- 2839,2853 ----
    }
  #endif
  
+   if((flags2 & (1<<12))) {
+ 
+     /*Resolve in distributed file system name space*/
+ 
+     DEBUG(0, ("SMB has 'Resolve in DFS' set!"));
+ 
+     show_msg_nodeb(inbuf);
+   }
+ 
    if (msg_type == 0)
      show_msg(inbuf);
    else if(msg_type == 0x85)
***************
*** 4170,4176 ****
  int reply_nt1(char *outbuf)
  {
    /* dual names + lock_and_read + nt SMBs + remote API calls */
!   int capabilities = CAP_NT_FIND|CAP_LOCK_AND_READ;
  /*
    other valid capabilities which we may support at some time...
                       CAP_LARGE_FILES|CAP_NT_SMBS|CAP_RPC_REMOTE_APIS;
--- 4203,4212 ----
  int reply_nt1(char *outbuf)
  {
    /* dual names + lock_and_read + nt SMBs + remote API calls */
!   int capabilities = CAP_NT_FIND|CAP_LOCK_AND_READ|CAP_DFS;
!   /*
!     int capabilities = CAP_NT_FIND|CAP_LOCK_AND_READ;
!   */
  /*
    other valid capabilities which we may support at some time...
                       CAP_LARGE_FILES|CAP_NT_SMBS|CAP_RPC_REMOTE_APIS;
***************
*** 4911,4917 ****
     /* LANMAN2.0 PROTOCOL FOLLOWS */
     {SMBfindnclose, "SMBfindnclose",reply_findnclose, AS_USER},
     {SMBfindclose, "SMBfindclose",reply_findclose,AS_USER},
!    {SMBtrans2, "SMBtrans2",reply_trans2, AS_USER},
     {SMBtranss2, "SMBtranss2",reply_transs2, AS_USER},
  
     /* messaging routines */
--- 4947,4954 ----
     /* LANMAN2.0 PROTOCOL FOLLOWS */
     {SMBfindnclose, "SMBfindnclose",reply_findnclose, AS_USER},
     {SMBfindclose, "SMBfindclose",reply_findclose,AS_USER},
!    {SMBtrans2, "SMBtrans2",reply_trans2, AS_USER | CAN_IPC},
!    /*   {SMBtrans2, "SMBtrans2",reply_trans2, AS_USER},*/
     {SMBtranss2, "SMBtranss2",reply_transs2, AS_USER},
  
     /* messaging routines */
***************
*** 5205,5211 ****
  ****************************************************************************/
  int construct_reply(char *inbuf,char *outbuf,int size,int bufsize)
  {
!   int type = CVAL(inbuf,smb_com);
    int outsize = 0;
    int msg_type = CVAL(inbuf,0);
    extern int chain_size;
--- 5242,5249 ----
  ****************************************************************************/
  int construct_reply(char *inbuf,char *outbuf,int size,int bufsize)
  {
!   int type   = CVAL(inbuf,smb_com);
! 
    int outsize = 0;
    int msg_type = CVAL(inbuf,0);
    extern int chain_size;
Only in samba-1.9.18p8-mod/source: server.doc
diff -rc samba-1.9.18p8/source/trans2.c samba-1.9.18p8-mod/source/trans2.c
*** samba-1.9.18p8/source/trans2.c	Mon Jun  1 07:29:09 1998
--- samba-1.9.18p8-mod/source/trans2.c	Mon Jul  6 17:27:07 1998
***************
*** 115,121 ****
        SSVAL(outbuf,smb_prcnt, params_sent_thistime);
        if(params_sent_thistime == 0)
  	{
! 	  SSVAL(outbuf,smb_proff,0);
  	  SSVAL(outbuf,smb_prdisp,0);
  	} else {
  	  /* smb_proff is the offset from the start of the SMB header to the
--- 115,122 ----
        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 {
  	  /* smb_proff is the offset from the start of the SMB header to the
***************
*** 135,143 ****
  	} else {
  	  /* The offset of the data bytes is the offset of the
  	     parameter bytes plus the number of parameters being sent this time */
! 	  SSVAL(outbuf,smb_droff,((smb_buf(outbuf)+alignment_offset) - 
! 				  smb_base(outbuf)) + 
! 		params_sent_thistime + data_alignment_offset);
  	  SSVAL(outbuf,smb_drdisp, pd - pdata);
  	}
  
--- 136,142 ----
  	} else {
  	  /* The offset of the data bytes is the offset of the
  	     parameter bytes plus the number of parameters being sent this time */
! 	  SSVAL(outbuf,smb_droff,((smb_buf(outbuf)+alignment_offset) - smb_base(outbuf)) + params_sent_thistime + data_alignment_offset);
  	  SSVAL(outbuf,smb_drdisp, pd - pdata);
  	}
  
***************
*** 153,158 ****
--- 152,159 ----
        DEBUG(9,("t2_rep: params_to_send = %d, data_to_send = %d, paramsize = %d, datasize = %d\n",
  	       params_to_send, data_to_send, paramsize, datasize));
  
+       show_msg_nodeb(outbuf);
+ 
        /* Send the packet */
        send_smb(Client,outbuf);
  
***************
*** 1684,1689 ****
--- 1685,2124 ----
  }
  
  /****************************************************************************
+   reply to a TRANS2_GET_DFS_REFERRAL
+ ****************************************************************************/
+ 
+ enum DFSNODETYPE {DFS_SERVER=1,DFS_LEAF=2};
+ 
+ struct PKE {
+   char *localPath;
+   char *eightdot3Path;
+   char *shareName;
+   enum DFSNODETYPE dfsNodeType;
+   unsigned long weight;
+   char *comment;
+ } DFSTab[] = {
+   {"\\UW0506\\dfs_root"   ,                              "", "\\UW0506\\dfs_root",  DFS_SERVER|DFS_LEAF, 0, "root volume"},
+   {"\\UW0506\\dfs_root\\H",                              "", "\\US0633\\pcdata",    DFS_LEAF,            0, "home area"},
+   {"\\UW0506\\dfs_root\\O",                              "", "\\US0633\\pc300",     DFS_LEAF,            0, "home area"},
+   {"\\UW0506\\dfs_root\\Applications\\Library",          "", "\\ns0003\\library",   DFS_LEAF,            0, "3 lib"},
+   {"\\UW0506\\dfs_root\\Applications\\Software Library", "", "\\ns0005\\library$",  DFS_LEAF,            0, "5 lib"}
+ };
+ 
+ 
+ static char *convertToEightDot3(const char *path) {
+   /*
+     Take a path such as 
+     
+     \NW3936\Nirvana\Applications\Apps 
+     
+     and convert to
+     
+     \NW3936\Nirvana\APPLIC~LW\Apps 
+     
+     This must be on this server if there was a match to the DFSTab
+     
+     So we can strip off \<server>\<sharename>
+     
+     and replace with the path for that share
+     
+     mangle the complete filename from beyond the share.
+   */
+ 
+   /* Just cycle through name and replace parts longer than 8 with a mangled version */
+ 
+   const char *p=path;
+ 
+   int cLen=strlen((char *)p)+1;
+ 
+   char *converted=malloc(cLen);
+ 
+   char *c=converted;
+ 
+   int slashCount=0;
+ 
+   while(*p && slashCount<3) {
+     if(*p == '\\') {
+       slashCount++;
+     }
+     *c++ = *p++;
+   }
+ 
+   *c='\0';
+ 
+   DEBUG(0,("Converted 1 %s.\n", converted));
+   
+   while(*p) {
+     const char *s=strchr((char*)p, '\\');
+ 
+     DEBUG(0,("converting p=%s, s=%s.\n", p, s?s:"<null>"));
+ 
+     if(s>p) {
+       /*  xxxxx/ */
+ 
+       strncat(c, p, s-p);
+       
+       DEBUG(0,("Check %s.\n", c));
+       
+       if(!is_8_3(c, True)) {
+ 
+ 	int sBuf=cLen-(int)(c-converted);
+ 
+ 	mangle_name_83(c, sBuf);
+ 
+       }
+ 
+       c+=strlen(c);
+       p=s;
+ 
+       *c++=*p++; /*add in the slash*/
+ 
+     } else if(!s) {
+       /*  xxxxx */
+ 
+       strncat(c, p, strlen((char *)p));
+ 
+       DEBUG(0,("Check %s.\n",c));
+       
+       if(!is_8_3(c, True)) {
+ 
+ 	int sBuf=cLen-(int)(c-converted);
+ 
+ 	mangle_name_83(c, sBuf);
+ 
+       }
+ 
+       c+=strlen(c);
+       p+=strlen((char*)p);
+ 
+     } else {
+       /* *s==*p=='\\'*/
+ 
+       *c++=*p++;
+ 
+     }
+ 
+     *c='\0';
+ 
+     DEBUG(0,("Converted %s.\n", converted));
+ 
+   }
+ 
+   DEBUG(0,("convertToEightDot3 got %s returned %s.\n", path, converted));
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+   return converted;
+ }
+ 
+ int IsPathWithinThisDfsServer(int cnum, const char *path) {
+   
+   char *sn;
+ 
+   char *fullpath;
+ 
+   int entries=sizeof(DFSTab)/sizeof(DFSTab[0]);
+ 
+   int i;
+ 
+   char *server;
+ 
+   int retVal=1;
+ 
+   int pLen;
+   
+   sn=lp_servicename(SNUM(cnum));
+ 
+   pLen=1+strlen(local_machine)+1+strlen(sn)+strlen((char*)path)+1;
+ 
+   fullpath=malloc(pLen);
+ 
+   safe_strcat(safe_strcat(safe_strcat(safe_strcat(safe_strcpy(fullpath, "\\", pLen),local_machine, pLen),"\\", pLen),sn, pLen), (char*)path, pLen);
+ 
+   pLen=strlen(fullpath);		
+ 
+   DEBUG(0,("IPWTDS: machine %s, service %s, path %s, fullpath %s.\n", local_machine, sn, path, fullpath));
+ 
+   for(i=0;i<entries;i++) {
+     int dLen,len=strlen(DFSTab[i].localPath);
+ 
+     if(!*DFSTab[i].eightdot3Path) {
+       DFSTab[i].eightdot3Path=convertToEightDot3(DFSTab[i].localPath);
+     }
+ 
+     dLen=strlen(DFSTab[i].eightdot3Path);
+ 
+     if(!strcasecmp(DFSTab[i].localPath, DFSTab[i].shareName)) {
+ 
+       DEBUG(0,("IPWTDS: Ignoring %s.\n", DFSTab[i].localPath));
+ 
+       continue;
+     }
+     
+     if(len<=pLen && !strncasecmp(DFSTab[i].localPath, fullpath, len)) {
+ 
+       DEBUG(0,("IPWTDS: substring(%s) of %s is on share %s.\n", DFSTab[i].localPath, fullpath, DFSTab[i].shareName));
+ 
+       retVal=0;
+       break;
+     }
+ 
+     if(dLen<=pLen && !strncasecmp(DFSTab[i].eightdot3Path, fullpath, dLen)) {
+ 
+       DEBUG(0,("IPWTDS: substring(%s) of %s is on share %s.\n", DFSTab[i].eightdot3Path, fullpath, DFSTab[i].shareName));
+ 
+       retVal=0;
+       break;
+     }
+ 
+   }
+ 
+   free(fullpath);
+ 
+   return retVal;
+ }
+ 
+ static int call_trans2getdfsreferral(char *inbuf, char *outbuf, int length, int bufsize, int cnum, char **pparams, char **ppdata)
+ {
+   char *params = *pparams;
+ 
+   unsigned int total_params = SVAL(inbuf, smb_tpscnt);
+ 
+   struct ReferrPB {
+     unsigned short MaxReferralLevel;
+     unsigned short RequestFilename[1];
+   } *referrPB=(struct ReferrPB *)params;
+ 
+   typedef struct ReferrELV1 {
+     unsigned short ServerType;
+     unsigned short ReferralFlags;
+     unsigned short Node[1];
+   } REFERRELV1;
+ 
+   typedef struct ReferrELV2 {
+     unsigned short ServerType;
+     unsigned short ReferralFlags;
+     unsigned long  Proximity;
+     unsigned long  TimeToLive;
+     unsigned short DfsPathOffset;
+     unsigned short DfsAlternatePathOffset;
+     unsigned short NetworkAddressOffset;  /*share name*/
+     unsigned short pad;
+   } REFERRELV2;
+ 
+   typedef struct ReferrELW {
+     unsigned short VersionNumber;
+     unsigned short ReferralSize;
+     REFERRELV2 elementV2;
+   } REFERRAL_LIST;
+ 
+   typedef struct ResponseHeader {
+     unsigned short PathConsumed;
+     unsigned short NumberOfReferrals;
+     unsigned long  Flags;
+   } RESPONSEHEADER;
+ 
+   typedef struct Response {
+     RESPONSEHEADER header;
+     REFERRAL_LIST  Referrals[1];
+   } RESPONSE;
+ 
+   int bytesReq=0;
+ 
+   unsigned char *requestFilename=NULL;
+ 
+   DEBUG(0,("call_trans2getdfsreferral\n"));
+ 
+   /*the parameters block is of the following structure*/
+ 
+   {
+     /*get the length of the unicode string*/
+ 
+     int len=0;
+     unsigned int paramBytes=total_params-sizeof(referrPB->MaxReferralLevel);
+     unsigned short *unip=(unsigned short *)referrPB->RequestFilename;
+ 
+     DEBUG(0,("paramBytes %u.\n", paramBytes));
+ 
+     while(paramBytes && *unip) {
+       len++;
+       unip++;
+       paramBytes-=sizeof(*unip);
+     }
+ 
+     if(*unip) {
+       /*cope with unterminated strings*/
+       len++;
+     }
+ 
+     requestFilename=malloc(len+1);
+ 
+     requestFilename[len]='\0';
+ 
+     unip=referrPB->RequestFilename;
+ 
+     while(len--) {
+       requestFilename[len]=(unsigned char)SVAL(&unip[len],0);
+     }
+ 
+   }
+ 
+   DEBUG(0,("Got DFS referral for connection %d. Referral level %u. REQUESTFILENAME %s.\n", 
+ 	   cnum, SVAL(&referrPB->MaxReferralLevel,0), requestFilename));
+ 
+   /*reply is all specified in data*/
+ 
+   {
+     int i;
+     int l=-1;
+     int nTags=1;
+     int tag=0;
+     int *tags=malloc(sizeof(*tags)*nTags);
+     int tLen, dLen, rLen=strlen((char *)requestFilename);
+     int entriesInPke=sizeof(DFSTab)/sizeof(DFSTab[0]);
+     int fixStringOffset;
+     RESPONSE *rh;
+     unsigned short *us=NULL;
+ 
+     for(i=0;i<entriesInPke;i++) {
+       tLen=strlen(DFSTab[i].localPath);
+ 
+       if(!*DFSTab[i].eightdot3Path) {
+ 	DFSTab[i].eightdot3Path=convertToEightDot3(DFSTab[i].localPath);
+       }
+ 
+       if(tLen<=rLen && tLen>=l && !strncasecmp((const char *)requestFilename, DFSTab[i].localPath, tLen)) {
+ 
+ 	DEBUG(0,("Got match to %s. Share is %s.\n",DFSTab[i].localPath, DFSTab[i].shareName));
+ 
+ 	if(tLen>l) {
+ 	  l=tLen;
+ 	  tag=0;
+ 	} 
+ 
+ 	if(tag>=nTags) {
+ 	  int *old=tags;
+ 	  tags=malloc(sizeof(*tags)*(tag+1));
+ 	  memcpy(tags,old,sizeof(*old)*nTags);
+ 	  free(old);
+ 	  nTags=tag+1;
+ 	}
+ 
+ 	tags[tag++]=i;
+       }
+     }
+ 
+     bytesReq=sizeof(RESPONSEHEADER)+tag*sizeof(REFERRAL_LIST);
+ 
+     DEBUG(0,("sizeof(RESPONSEHEADER)=%d, sizeof(REFERRAL_LIST)=%d.\n", sizeof(RESPONSEHEADER), sizeof(REFERRAL_LIST)));
+ 
+     fixStringOffset=bytesReq;
+ 
+     if(tag>0) {
+       tLen=l;
+ 
+       DEBUG(0,("long %s => 8.3 %s.\n", DFSTab[tags[0]].localPath, DFSTab[tags[0]].eightdot3Path));
+ 
+       dLen=strlen(DFSTab[tags[0]].eightdot3Path);
+       
+       bytesReq+=tLen*2+2+dLen*2+2;
+ 
+       for(i=0; i<tag; i++) {
+ 	bytesReq+=strlen(DFSTab[tags[i]].shareName)*2+2;
+       }
+ 
+     }
+ 
+     if(*ppdata) {
+       *ppdata=Realloc(*ppdata, bytesReq); bzero(*ppdata, bytesReq);
+     } else {
+       *ppdata=malloc(bytesReq); bzero(*ppdata, bytesReq);
+     }
+ 
+     if(tag>0) {
+       us=(unsigned short *)((*ppdata)+fixStringOffset) ;
+ 
+       rh=(RESPONSE *)*ppdata;
+       SSVAL(&rh->header.PathConsumed, 0, tLen*2);
+       SSVAL(&rh->header.NumberOfReferrals, 0, tag);
+       SIVAL(&rh->header.Flags, 0, (unsigned int)DFSTab[tags[0]].dfsNodeType);
+ 
+       fixStringOffset-=sizeof(RESPONSEHEADER);
+ 
+       for(i=0;i<tLen;i++) {
+ 	SSVAL(us, 0, (unsigned short)DFSTab[tags[0]].localPath[i]);us++;
+       }
+       SSVAL(us, 0, 0);us++;
+ 
+       for(i=0;i<dLen;i++) {
+ 	SSVAL(us, 0, (unsigned short)DFSTab[tags[0]].eightdot3Path[i]);us++;
+       }
+       SSVAL(us, 0, 0);us++;
+     }
+ 
+     for(i=0;i<tag;i++) {
+       DEBUG(0,("Referring %s to %s => %s.\n", requestFilename, DFSTab[tags[i]].localPath, DFSTab[tags[i]].shareName));
+ 
+       if(SVAL(&referrPB->MaxReferralLevel, 0)<2) {
+ 
+ 
+       } else {
+ 	int j;
+ 	int sLen=strlen(DFSTab[tags[i]].shareName);
+ 
+ 	SSVAL(&rh->Referrals[i].VersionNumber, 0, 2);
+ 	SSVAL(&rh->Referrals[i].ReferralSize, 0, sizeof(rh->Referrals[i]));
+ 	SSVAL(&rh->Referrals[i].elementV2.ServerType, 0, 0);           /*NT uses don't know here*/
+ 	SSVAL(&rh->Referrals[i].elementV2.ReferralFlags, 0, 0);                    /*NT sets this to 0*/
+ 	SIVAL(&rh->Referrals[i].elementV2.Proximity, 0, 0);
+ 	/*SIVAL(&rh->Referrals[i].elementV2.TimeToLive, 0, 604800);*/                  /*NT uses this value*/
+ 	SIVAL(&rh->Referrals[i].elementV2.TimeToLive, 0, 5);                  
+ 	SSVAL(&rh->Referrals[i].elementV2.DfsPathOffset, 0, fixStringOffset);
+ 	SSVAL(&rh->Referrals[i].elementV2.DfsAlternatePathOffset, 0, fixStringOffset+tLen*2+2);
+ 	SSVAL(&rh->Referrals[i].elementV2.NetworkAddressOffset, 0, ((unsigned char *)us)-((unsigned char *)(rh->Referrals+i)));
+ 
+ 	fixStringOffset-=sizeof(rh->Referrals[i]);
+ 
+ 	for(j=0;j<sLen;j++) {
+ 	  SSVAL(us, 0, DFSTab[tags[i]].shareName[j]);us++;
+ 	}
+ 
+ 	SSVAL(us, 0, 0);us++;
+       }
+ 
+     }
+     
+     free(tags);
+     free(requestFilename);
+   }
+ 
+   send_trans2_replies(outbuf, bufsize, params, 0, *ppdata, bytesReq);
+   
+   return(-1);
+ }
+ 
+ /****************************************************************************
+   reply to a TRANS2_REPORT_DFS_INCONSISTANCY
+ ****************************************************************************/
+ static int call_trans2reportdfsinconsistancy(char *inbuf, char *outbuf, int length, int bufsize,
+ 					     int cnum, char **pparams, char **ppdata)
+ {
+   char *params = *pparams;
+ 
+   DEBUG(0,("call_trans2reportdfsinconsistancy\n"));
+ 
+   
+ 
+   send_trans2_replies(outbuf, bufsize, params, 4, *ppdata, 0);
+   
+   return(-1);
+ }
+ 
+ /****************************************************************************
    reply to a SMBfindclose (stop trans2 directory search)
  ****************************************************************************/
  int reply_findclose(char *inbuf,char *outbuf,int length,int bufsize)
***************
*** 1890,1895 ****
--- 2325,2336 ----
      case TRANSACT2_MKDIR:
        outsize = call_trans2mkdir(inbuf, outbuf, length, bufsize, cnum, &params, &data);
        break;
+     case TRANSACT2_GET_DFS_REFERRAL:
+       outsize = call_trans2getdfsreferral(inbuf, outbuf, length, bufsize, cnum, &params, &data);
+       break;
+     case TRANSACT2_REPORT_DFS_INCONSISTANCY:
+       outsize = call_trans2reportdfsinconsistancy(inbuf, outbuf, length, bufsize, cnum, &params, &data);
+       break;
      default:
        /* Error in request */
        DEBUG(2,("%s Unknown request %d in trans2 call\n",timestring(), tran_call));
Common subdirectories: samba-1.9.18p8/source/ubiqx and samba-1.9.18p8-mod/source/ubiqx
diff -rc samba-1.9.18p8/source/util.c samba-1.9.18p8-mod/source/util.c
*** samba-1.9.18p8/source/util.c	Sat Jun 13 02:44:21 1998
--- samba-1.9.18p8-mod/source/util.c	Wed Jul  1 16:23:04 1998
***************
*** 1252,1257 ****
--- 1252,1327 ----
  /*******************************************************************
    show a smb message structure
  ********************************************************************/
+ void show_msg_nodeb(char *buf)
+ {
+   int i;
+   int bcc=0;
+ 
+   DEBUG(0,("size=%d\nsmb_com=0x%x\nsmb_rcls=%d\nsmb_reh=%d\nsmb_err=%d\nsmb_flg=%d\nsmb_flg2=%d\n",
+ 	  smb_len(buf),
+ 	  (int)CVAL(buf,smb_com),
+ 	  (int)CVAL(buf,smb_rcls),
+ 	  (int)CVAL(buf,smb_reh),
+ 	  (int)SVAL(buf,smb_err),
+ 	  (int)CVAL(buf,smb_flg),
+ 	  (int)SVAL(buf,smb_flg2)));
+   DEBUG(0,("smb_tid=%d\nsmb_pid=%d\nsmb_uid=%d\nsmb_mid=%d\nsmt_wct=%d\n",
+ 	  (int)SVAL(buf,smb_tid),
+ 	  (int)SVAL(buf,smb_pid),
+ 	  (int)SVAL(buf,smb_uid),
+ 	  (int)SVAL(buf,smb_mid),
+ 	  (int)CVAL(buf,smb_wct)));
+ 
+   for (i=0;i<(int)CVAL(buf,smb_wct);i++)
+     DEBUG(0,("smb_vwv[%d]=%d (0x%X)\n",i,
+ 	  SVAL(buf,smb_vwv+2*i),SVAL(buf,smb_vwv+2*i)));
+ 
+   bcc = (int)SVAL(buf,smb_vwv+2*(CVAL(buf,smb_wct)));
+   DEBUG(0,("smb_bcc=%d\n",bcc));
+ 
+   if (DEBUGLEVEL < 10) return;
+ 
+   dump_data(10, smb_buf(buf), MIN(bcc, 512));
+ }
+ 
+ /*******************************************************************
+   show a smb message structure
+ ********************************************************************/
+ void show_msg_data_nodeb(char *buf)
+ {
+   int i;
+   int bcc=0;
+ 
+   /*if (DEBUGLEVEL < 5) return;*/
+ 
+   DEBUG(0,("size=%d\nsmb_com=0x%x\nsmb_rcls=%d\nsmb_reh=%d\nsmb_err=%d\nsmb_flg=%d\nsmb_flg2=%d\n",
+ 	  smb_len(buf),
+ 	  (int)CVAL(buf,smb_com),
+ 	  (int)CVAL(buf,smb_rcls),
+ 	  (int)CVAL(buf,smb_reh),
+ 	  (int)SVAL(buf,smb_err),
+ 	  (int)CVAL(buf,smb_flg),
+ 	  (int)SVAL(buf,smb_flg2)));
+   DEBUG(0,("smb_tid=%d\nsmb_pid=%d\nsmb_uid=%d\nsmb_mid=%d\nsmt_wct=%d\n",
+ 	  (int)SVAL(buf,smb_tid),
+ 	  (int)SVAL(buf,smb_pid),
+ 	  (int)SVAL(buf,smb_uid),
+ 	  (int)SVAL(buf,smb_mid),
+ 	  (int)CVAL(buf,smb_wct)));
+ 
+   for (i=0;i<(int)CVAL(buf,smb_wct);i++)
+     DEBUG(0,("smb_vwv[%d]=%d (0x%X)\n",i,
+ 	  SVAL(buf,smb_vwv+2*i),SVAL(buf,smb_vwv+2*i)));
+ 
+   bcc = (int)SVAL(buf,smb_vwv+2*(CVAL(buf,smb_wct)));
+   DEBUG(0,("smb_bcc=%d\n",bcc));
+ 
+   dump_data(0, smb_buf(buf), MIN(bcc, 512));
+ }
+ 
+ /*******************************************************************
+   show a smb message structure
+ ********************************************************************/
  void show_msg(char *buf)
  {
    int i;
Common subdirectories: samba-1.9.18p8/source/web and samba-1.9.18p8-mod/source/web


More information about the samba-technical mailing list