home *** CD-ROM | disk | FTP | other *** search
/ SGI Freeware 1999 August / SGI Freeware 1999 August.iso / dist / samba.idb / usr / samba / src / source / server.c.z / server.c
Encoding:
C/C++ Source or Header  |  1998-10-28  |  161.5 KB  |  5,749 lines

  1. /* 
  2.    Unix SMB/Netbios implementation.
  3.    Version 1.9.
  4.    Main SMB server routines
  5.    Copyright (C) Andrew Tridgell 1992-1998
  6.    
  7.    This program is free software; you can redistribute it and/or modify
  8.    it under the terms of the GNU General Public License as published by
  9.    the Free Software Foundation; either version 2 of the License, or
  10.    (at your option) any later version.
  11.    
  12.    This program is distributed in the hope that it will be useful,
  13.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15.    GNU General Public License for more details.
  16.    
  17.    You should have received a copy of the GNU General Public License
  18.    along with this program; if not, write to the Free Software
  19.    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  20. */
  21.  
  22. #include "includes.h"
  23. #include "trans2.h"
  24.  
  25. pstring servicesf = CONFIGFILE;
  26. extern pstring debugf;
  27. extern pstring sesssetup_user;
  28. extern fstring myworkgroup;
  29.  
  30. char *InBuffer = NULL;
  31. char *OutBuffer = NULL;
  32. char *last_inbuf = NULL;
  33.  
  34. int am_parent = 1;
  35. int atexit_set = 0;
  36.  
  37. /* the last message the was processed */
  38. int last_message = -1;
  39.  
  40. /* a useful macro to debug the last message processed */
  41. #define LAST_MESSAGE() smb_fn_name(last_message)
  42.  
  43. extern pstring scope;
  44. extern int DEBUGLEVEL;
  45. extern int case_default;
  46. extern BOOL case_sensitive;
  47. extern BOOL case_preserve;
  48. extern BOOL use_mangled_map;
  49. extern BOOL short_case_preserve;
  50. extern BOOL case_mangle;
  51. time_t smb_last_time=(time_t)0;
  52.  
  53. extern int smb_read_error;
  54.  
  55. extern pstring user_socket_options;
  56.  
  57. #ifdef DFS_AUTH
  58. extern int dcelogin_atmost_once;
  59. #endif /* DFS_AUTH */
  60.  
  61. connection_struct Connections[MAX_CONNECTIONS];
  62. files_struct Files[MAX_OPEN_FILES];
  63.  
  64. /*
  65.  * Indirection for file fd's. Needed as POSIX locking
  66.  * is based on file/process, not fd/process.
  67.  */
  68. file_fd_struct FileFd[MAX_OPEN_FILES];
  69. int max_file_fd_used = 0;
  70.  
  71. extern int Protocol;
  72.  
  73. /* 
  74.  * Size of data we can send to client. Set
  75.  *  by the client for all protocols above CORE.
  76.  *  Set by us for CORE protocol.
  77.  */
  78. int max_send = BUFFER_SIZE;
  79. /*
  80.  * Size of the data we can receive. Set by us.
  81.  * Can be modified by the max xmit parameter.
  82.  */
  83. int max_recv = BUFFER_SIZE;
  84.  
  85. /* a fnum to use when chaining */
  86. int chain_fnum = -1;
  87.  
  88. /* number of open connections */
  89. static int num_connections_open = 0;
  90.  
  91. /* Oplock ipc UDP socket. */
  92. int oplock_sock = -1;
  93. uint16 oplock_port = 0;
  94. /* Current number of oplocks we have outstanding. */
  95. int32 global_oplocks_open = 0;
  96.  
  97. BOOL global_oplock_break = False;
  98.  
  99. extern fstring remote_machine;
  100.  
  101. extern pstring OriginalDir;
  102.  
  103. /* these can be set by some functions to override the error codes */
  104. int unix_ERR_class=SMB_SUCCESS;
  105. int unix_ERR_code=0;
  106.  
  107.  
  108. extern int extra_time_offset;
  109.  
  110. extern pstring myhostname;
  111.  
  112. static int find_free_connection(int hash);
  113.  
  114. /* for readability... */
  115. #define IS_DOS_READONLY(test_mode) (((test_mode) & aRONLY) != 0)
  116. #define IS_DOS_DIR(test_mode) (((test_mode) & aDIR) != 0)
  117. #define IS_DOS_ARCHIVE(test_mode) (((test_mode) & aARCH) != 0)
  118. #define IS_DOS_SYSTEM(test_mode) (((test_mode) & aSYSTEM) != 0)
  119. #define IS_DOS_HIDDEN(test_mode) (((test_mode) & aHIDDEN) != 0)
  120.  
  121. /****************************************************************************
  122.   when exiting, take the whole family
  123. ****************************************************************************/
  124. void  *dflt_sig(void)
  125. {
  126.   exit_server("caught signal");
  127.   return 0; /* Keep -Wall happy :-) */
  128. }
  129. /****************************************************************************
  130.   Send a SIGTERM to our process group.
  131. *****************************************************************************/
  132. void  killkids(void)
  133. {
  134.   if(am_parent) kill(0,SIGTERM);
  135. }
  136.  
  137. /****************************************************************************
  138.   change a dos mode to a unix mode
  139.     base permission for files:
  140.          everybody gets read bit set
  141.          dos readonly is represented in unix by removing everyone's write bit
  142.          dos archive is represented in unix by the user's execute bit
  143.          dos system is represented in unix by the group's execute bit
  144.          dos hidden is represented in unix by the other's execute bit
  145.          Then apply create mask,
  146.          then add force bits.
  147.     base permission for directories:
  148.          dos directory is represented in unix by unix's dir bit and the exec bit
  149.          Then apply create mask,
  150.          then add force bits.
  151. ****************************************************************************/
  152. mode_t unix_mode(int cnum,int dosmode)
  153. {
  154.   mode_t result = (S_IRUSR | S_IRGRP | S_IROTH);
  155.  
  156.   if ( !IS_DOS_READONLY(dosmode) )
  157.     result |= (S_IWUSR | S_IWGRP | S_IWOTH);
  158.  
  159.   if (IS_DOS_DIR(dosmode)) {
  160.     /* We never make directories read only for the owner as under DOS a user
  161.        can always create a file in a read-only directory. */
  162.     result |= (S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH | S_IWUSR);
  163.     /* Apply directory mask */
  164.     result &= lp_dir_mode(SNUM(cnum));
  165.     /* Add in force bits */
  166.     result |= lp_force_dir_mode(SNUM(cnum));
  167.   } else { 
  168.     if (MAP_ARCHIVE(cnum) && IS_DOS_ARCHIVE(dosmode))
  169.       result |= S_IXUSR;
  170.  
  171.     if (MAP_SYSTEM(cnum) && IS_DOS_SYSTEM(dosmode))
  172.       result |= S_IXGRP;
  173.  
  174.     if (MAP_HIDDEN(cnum) && IS_DOS_HIDDEN(dosmode))
  175.       result |= S_IXOTH;  
  176.  
  177.     /* Apply mode mask */
  178.     result &= lp_create_mode(SNUM(cnum));
  179.     /* Add in force bits */
  180.     result |= lp_force_create_mode(SNUM(cnum));
  181.   }
  182.   return(result);
  183. }
  184.  
  185.  
  186. /****************************************************************************
  187.   change a unix mode to a dos mode
  188. ****************************************************************************/
  189. int dos_mode(int cnum,char *path,struct stat *sbuf)
  190. {
  191.   int result = 0;
  192.   extern struct current_user current_user;
  193.  
  194.   DEBUG(8,("dos_mode: %d %s\n", cnum, path));
  195.  
  196.   if (CAN_WRITE(cnum) && !lp_alternate_permissions(SNUM(cnum))) {
  197.     if (!((sbuf->st_mode & S_IWOTH) ||
  198.       Connections[cnum].admin_user ||
  199.       ((sbuf->st_mode & S_IWUSR) && current_user.uid==sbuf->st_uid) ||
  200.       ((sbuf->st_mode & S_IWGRP) && 
  201.        in_group(sbuf->st_gid,current_user.gid,
  202.             current_user.ngroups,current_user.igroups))))
  203.       result |= aRONLY;
  204.   } else {
  205.     if ((sbuf->st_mode & S_IWUSR) == 0)
  206.       result |= aRONLY;
  207.   }
  208.  
  209.   if (MAP_ARCHIVE(cnum) && ((sbuf->st_mode & S_IXUSR) != 0))
  210.     result |= aARCH;
  211.  
  212.   if (MAP_SYSTEM(cnum) && ((sbuf->st_mode & S_IXGRP) != 0))
  213.     result |= aSYSTEM;
  214.  
  215.   if (MAP_HIDDEN(cnum) && ((sbuf->st_mode & S_IXOTH) != 0))
  216.     result |= aHIDDEN;   
  217.   
  218.   if (S_ISDIR(sbuf->st_mode))
  219.     result = aDIR | (result & aRONLY);
  220.  
  221. #ifdef S_ISLNK
  222. #if LINKS_READ_ONLY
  223.   if (S_ISLNK(sbuf->st_mode) && S_ISDIR(sbuf->st_mode))
  224.     result |= aRONLY;
  225. #endif
  226. #endif
  227.  
  228.   /* hide files with a name starting with a . */
  229.   if (lp_hide_dot_files(SNUM(cnum)))
  230.     {
  231.       char *p = strrchr(path,'/');
  232.       if (p)
  233.     p++;
  234.       else
  235.     p = path;
  236.       
  237.       if (p[0] == '.' && p[1] != '.' && p[1] != 0)
  238.     result |= aHIDDEN;
  239.     }
  240.  
  241.   /* Optimization : Only call is_hidden_path if it's not already
  242.      hidden. */
  243.   if (!(result & aHIDDEN) && IS_HIDDEN_PATH(cnum,path))
  244.   {
  245.     result |= aHIDDEN;
  246.   }
  247.  
  248.   DEBUG(8,("dos_mode returning "));
  249.  
  250.   if (result & aHIDDEN) DEBUG(8, ("h"));
  251.   if (result & aRONLY ) DEBUG(8, ("r"));
  252.   if (result & aSYSTEM) DEBUG(8, ("s"));
  253.   if (result & aDIR   ) DEBUG(8, ("d"));
  254.   if (result & aARCH  ) DEBUG(8, ("a"));
  255.  
  256.   DEBUG(8,("\n"));
  257.  
  258.   return(result);
  259. }
  260.  
  261. /*******************************************************************
  262. chmod a file - but preserve some bits
  263. ********************************************************************/
  264. int dos_chmod(int cnum,char *fname,int dosmode,struct stat *st)
  265. {
  266.   struct stat st1;
  267.   int mask=0;
  268.   int tmp;
  269.   int unixmode;
  270.  
  271.   if (!st) {
  272.     st = &st1;
  273.     if (sys_stat(fname,st)) return(-1);
  274.   }
  275.  
  276.   if (S_ISDIR(st->st_mode)) dosmode |= aDIR;
  277.  
  278.   if (dos_mode(cnum,fname,st) == dosmode) return(0);
  279.  
  280.   unixmode = unix_mode(cnum,dosmode);
  281.  
  282.   /* preserve the s bits */
  283.   mask |= (S_ISUID | S_ISGID);
  284.  
  285.   /* preserve the t bit */
  286. #ifdef S_ISVTX
  287.   mask |= S_ISVTX;
  288. #endif
  289.  
  290.   /* possibly preserve the x bits */
  291.   if (!MAP_ARCHIVE(cnum)) mask |= S_IXUSR;
  292.   if (!MAP_SYSTEM(cnum)) mask |= S_IXGRP;
  293.   if (!MAP_HIDDEN(cnum)) mask |= S_IXOTH;
  294.  
  295.   unixmode |= (st->st_mode & mask);
  296.  
  297.   /* if we previously had any r bits set then leave them alone */
  298.   if ((tmp = st->st_mode & (S_IRUSR|S_IRGRP|S_IROTH))) {
  299.     unixmode &= ~(S_IRUSR|S_IRGRP|S_IROTH);
  300.     unixmode |= tmp;
  301.   }
  302.  
  303.   /* if we previously had any w bits set then leave them alone 
  304.    if the new mode is not rdonly */
  305.   if (!IS_DOS_READONLY(dosmode) &&
  306.       (tmp = st->st_mode & (S_IWUSR|S_IWGRP|S_IWOTH))) {
  307.     unixmode &= ~(S_IWUSR|S_IWGRP|S_IWOTH);
  308.     unixmode |= tmp;
  309.   }
  310.  
  311.   return(sys_chmod(fname,unixmode));
  312. }
  313.  
  314. /*******************************************************************
  315. Wrapper around sys_utime that possibly allows DOS semantics rather
  316. than POSIX.
  317. *******************************************************************/
  318.  
  319. int file_utime(int cnum, char *fname, struct utimbuf *times)
  320. {
  321.   extern struct current_user current_user;
  322.   struct stat sb;
  323.   int ret = -1;
  324.  
  325.   errno = 0;
  326.  
  327.   if(sys_utime(fname, times) == 0)
  328.     return 0;
  329.  
  330.   if((errno != EPERM) && (errno != EACCES))
  331.     return -1;
  332.  
  333.   if(!lp_dos_filetimes(SNUM(cnum)))
  334.     return -1;
  335.  
  336.   /* We have permission (given by the Samba admin) to
  337.      break POSIX semantics and allow a user to change
  338.      the time on a file they don't own but can write to
  339.      (as DOS does).
  340.    */
  341.  
  342.   if(sys_stat(fname,&sb) != 0)
  343.     return -1;
  344.  
  345.   /* Check if we have write access. */
  346.   if (CAN_WRITE(cnum)) {
  347.       if (((sb.st_mode & S_IWOTH) ||
  348.            Connections[cnum].admin_user ||
  349.            ((sb.st_mode & S_IWUSR) && current_user.uid==sb.st_uid) ||
  350.            ((sb.st_mode & S_IWGRP) &&
  351.         in_group(sb.st_gid,current_user.gid,
  352.              current_user.ngroups,current_user.igroups)))) {
  353.           /* We are allowed to become root and change the filetime. */
  354.           become_root(False);
  355.           ret = sys_utime(fname, times);
  356.           unbecome_root(False);
  357.       }
  358.   }
  359.  
  360.   return ret;
  361. }
  362.   
  363. /*******************************************************************
  364. Change a filetime - possibly allowing DOS semantics.
  365. *******************************************************************/
  366.  
  367. BOOL set_filetime(int cnum, char *fname, time_t mtime)
  368. {
  369.   struct utimbuf times;
  370.  
  371.   if (null_mtime(mtime)) return(True);
  372.  
  373.   times.modtime = times.actime = mtime;
  374.  
  375.   if (file_utime(cnum, fname, ×)) {
  376.     DEBUG(4,("set_filetime(%s) failed: %s\n",fname,strerror(errno)));
  377.   }
  378.   
  379.   return(True);
  380.  
  381. /****************************************************************************
  382. check if two filenames are equal
  383.  
  384. this needs to be careful about whether we are case sensitive
  385. ****************************************************************************/
  386. static BOOL fname_equal(char *name1, char *name2)
  387. {
  388.   int l1 = strlen(name1);
  389.   int l2 = strlen(name2);
  390.  
  391.   /* handle filenames ending in a single dot */
  392.   if (l1-l2 == 1 && name1[l1-1] == '.' && lp_strip_dot())
  393.     {
  394.       BOOL ret;
  395.       name1[l1-1] = 0;
  396.       ret = fname_equal(name1,name2);
  397.       name1[l1-1] = '.';
  398.       return(ret);
  399.     }
  400.  
  401.   if (l2-l1 == 1 && name2[l2-1] == '.' && lp_strip_dot())
  402.     {
  403.       BOOL ret;
  404.       name2[l2-1] = 0;
  405.       ret = fname_equal(name1,name2);
  406.       name2[l2-1] = '.';
  407.       return(ret);
  408.     }
  409.  
  410.   /* now normal filename handling */
  411.   if (case_sensitive)
  412.     return(strcmp(name1,name2) == 0);
  413.  
  414.   return(strequal(name1,name2));
  415. }
  416.  
  417.  
  418. /****************************************************************************
  419. mangle the 2nd name and check if it is then equal to the first name
  420. ****************************************************************************/
  421. static BOOL mangled_equal(char *name1, char *name2)
  422. {
  423.   pstring tmpname;
  424.  
  425.   if (is_8_3(name2, True))
  426.     return(False);
  427.  
  428.   pstrcpy(tmpname,name2);
  429.   mangle_name_83(tmpname,sizeof(pstring)-1);
  430.  
  431.   return(strequal(name1,tmpname));
  432. }
  433.  
  434.  
  435. /****************************************************************************
  436. scan a directory to find a filename, matching without case sensitivity
  437.  
  438. If the name looks like a mangled name then try via the mangling functions
  439. ****************************************************************************/
  440. static BOOL scan_directory(char *path, char *name,int cnum,BOOL docache)
  441. {
  442.   void *cur_dir;
  443.   char *dname;
  444.   BOOL mangled;
  445.   pstring name2;
  446.  
  447.   mangled = is_mangled(name);
  448.  
  449.   /* handle null paths */
  450.   if (*path == 0)
  451.     path = ".";
  452.  
  453.   if (docache && (dname = DirCacheCheck(path,name,SNUM(cnum)))) {
  454.     pstrcpy(name, dname);    
  455.     return(True);
  456.   }      
  457.  
  458.   /*
  459.    * The incoming name can be mangled, and if we de-mangle it
  460.    * here it will not compare correctly against the filename (name2)
  461.    * read from the directory and then mangled by the name_map_mangle()
  462.    * call. We need to mangle both names or neither.
  463.    * (JRA).
  464.    */
  465.   if (mangled)
  466.     mangled = !check_mangled_stack(name);
  467.  
  468.   /* open the directory */
  469.   if (!(cur_dir = OpenDir(cnum, path, True))) 
  470.     {
  471.       DEBUG(3,("scan dir didn't open dir [%s]\n",path));
  472.       return(False);
  473.     }
  474.  
  475.   /* now scan for matching names */
  476.   while ((dname = ReadDirName(cur_dir))) 
  477.     {
  478.       if (*dname == '.' &&
  479.       (strequal(dname,".") || strequal(dname,"..")))
  480.     continue;
  481.  
  482.       pstrcpy(name2,dname);
  483.       if (!name_map_mangle(name2,False,SNUM(cnum))) continue;
  484.  
  485.       if ((mangled && mangled_equal(name,name2))
  486.       || fname_equal(name, name2))
  487.     {
  488.       /* we've found the file, change it's name and return */
  489.       if (docache) DirCacheAdd(path,name,dname,SNUM(cnum));
  490.       pstrcpy(name, dname);
  491.       CloseDir(cur_dir);
  492.       return(True);
  493.     }
  494.     }
  495.  
  496.   CloseDir(cur_dir);
  497.   return(False);
  498. }
  499.  
  500. /****************************************************************************
  501. This routine is called to convert names from the dos namespace to unix
  502. namespace. It needs to handle any case conversions, mangling, format
  503. changes etc.
  504.  
  505. We assume that we have already done a chdir() to the right "root" directory
  506. for this service.
  507.  
  508. The function will return False if some part of the name except for the last
  509. part cannot be resolved
  510.  
  511. If the saved_last_component != 0, then the unmodified last component
  512. of the pathname is returned there. This is used in an exceptional
  513. case in reply_mv (so far). If saved_last_component == 0 then nothing
  514. is returned there.
  515.  
  516. The bad_path arg is set to True if the filename walk failed. This is
  517. used to pick the correct error code to return between ENOENT and ENOTDIR
  518. as Windows applications depend on ERRbadpath being returned if a component
  519. of a pathname does not exist.
  520. ****************************************************************************/
  521. BOOL unix_convert(char *name,int cnum,pstring saved_last_component, BOOL *bad_path)
  522. {
  523.   struct stat st;
  524.   char *start, *end;
  525.   pstring dirpath;
  526.   int saved_errno;
  527.  
  528.   *dirpath = 0;
  529.   *bad_path = False;
  530.  
  531.   if(saved_last_component)
  532.     *saved_last_component = 0;
  533.  
  534.   /* convert to basic unix format - removing \ chars and cleaning it up */
  535.   unix_format(name);
  536.   unix_clean_name(name);
  537.  
  538.   /* names must be relative to the root of the service - trim any leading /.
  539.    also trim trailing /'s */
  540.   trim_string(name,"/","/");
  541.  
  542.   /*
  543.    * Ensure saved_last_component is valid even if file exists.
  544.    */
  545.   if(saved_last_component) {
  546.     end = strrchr(name, '/');
  547.     if(end)
  548.       pstrcpy(saved_last_component, end + 1);
  549.     else
  550.       pstrcpy(saved_last_component, name);
  551.   }
  552.  
  553.   if (!case_sensitive && 
  554.       (!case_preserve || (is_8_3(name, False) && !short_case_preserve)))
  555.     strnorm(name);
  556.  
  557.   /* check if it's a printer file */
  558.   if (Connections[cnum].printer)
  559.     {
  560.       if ((! *name) || strchr(name,'/') || !is_8_3(name, True))
  561.     {
  562.       char *s;
  563.       fstring name2;
  564.       slprintf(name2,sizeof(name2)-1,"%.6s.XXXXXX",remote_machine);
  565.       /* sanitise the name */
  566.       for (s=name2 ; *s ; s++)
  567.         if (!issafe(*s)) *s = '_';
  568.       pstrcpy(name,(char *)mktemp(name2));      
  569.     }      
  570.       return(True);
  571.     }
  572.  
  573.   /* stat the name - if it exists then we are all done! */
  574.   if (sys_stat(name,&st) == 0)
  575.     return(True);
  576.  
  577.   saved_errno = errno;
  578.  
  579.   DEBUG(5,("unix_convert(%s,%d)\n",name,cnum));
  580.  
  581.   /* a special case - if we don't have any mangling chars and are case
  582.      sensitive then searching won't help */
  583.   if (case_sensitive && !is_mangled(name) && 
  584.       !lp_strip_dot() && !use_mangled_map && (saved_errno != ENOENT))
  585.     return(False);
  586.  
  587.   /* now we need to recursively match the name against the real 
  588.      directory structure */
  589.  
  590.   start = name;
  591.   while (strncmp(start,"./",2) == 0)
  592.     start += 2;
  593.  
  594.   /* now match each part of the path name separately, trying the names
  595.      as is first, then trying to scan the directory for matching names */
  596.   for (;start;start = (end?end+1:(char *)NULL)) 
  597.     {
  598.       /* pinpoint the end of this section of the filename */
  599.       end = strchr(start, '/');
  600.  
  601.       /* chop the name at this point */
  602.       if (end)     *end = 0;
  603.  
  604.       if(saved_last_component != 0)
  605.         pstrcpy(saved_last_component, end ? end + 1 : start);
  606.  
  607.       /* check if the name exists up to this point */
  608.       if (sys_stat(name, &st) == 0) 
  609.     {
  610.       /* it exists. it must either be a directory or this must be
  611.          the last part of the path for it to be OK */
  612.       if (end && !(st.st_mode & S_IFDIR)) 
  613.         {
  614.           /* an intermediate part of the name isn't a directory */
  615.           DEBUG(5,("Not a dir %s\n",start));
  616.           *end = '/';
  617.           return(False);
  618.         }
  619.     }
  620.       else 
  621.     {
  622.       pstring rest;
  623.  
  624.       *rest = 0;
  625.  
  626.       /* remember the rest of the pathname so it can be restored
  627.          later */
  628.       if (end) pstrcpy(rest,end+1);
  629.  
  630.       /* try to find this part of the path in the directory */
  631.       if (strchr(start,'?') || strchr(start,'*') ||
  632.           !scan_directory(dirpath, start, cnum, end?True:False))
  633.         {
  634.           if (end) 
  635.         {
  636.           /* an intermediate part of the name can't be found */
  637.           DEBUG(5,("Intermediate not found %s\n",start));
  638.           *end = '/';
  639.                   /* We need to return the fact that the intermediate
  640.                      name resolution failed. This is used to return an
  641.                      error of ERRbadpath rather than ERRbadfile. Some
  642.                      Windows applications depend on the difference between
  643.                      these two errors.
  644.                    */
  645.                   *bad_path = True;
  646.           return(False);
  647.         }
  648.           
  649.           /* just the last part of the name doesn't exist */
  650.           /* we may need to strupper() or strlower() it in case
  651.          this conversion is being used for file creation 
  652.          purposes */
  653.           /* if the filename is of mixed case then don't normalise it */
  654.           if (!case_preserve && 
  655.           (!strhasupper(start) || !strhaslower(start)))        
  656.         strnorm(start);
  657.  
  658.           /* check on the mangled stack to see if we can recover the 
  659.          base of the filename */
  660.           if (is_mangled(start))
  661.         check_mangled_stack(start);
  662.  
  663.           DEBUG(5,("New file %s\n",start));
  664.           return(True); 
  665.         }
  666.  
  667.       /* restore the rest of the string */
  668.       if (end) 
  669.         {
  670.           pstrcpy(start+strlen(start)+1,rest);
  671.           end = start + strlen(start);
  672.         }
  673.     }
  674.  
  675.       /* add to the dirpath that we have resolved so far */
  676.       if (*dirpath) pstrcat(dirpath,"/");
  677.       pstrcat(dirpath,start);
  678.  
  679.       /* restore the / that we wiped out earlier */
  680.       if (end) *end = '/';
  681.     }
  682.   
  683.   /* the name has been resolved */
  684.   DEBUG(5,("conversion finished %s\n",name));
  685.   return(True);
  686. }
  687.  
  688.  
  689. /****************************************************************************
  690. normalise for DOS usage 
  691. ****************************************************************************/
  692. static void disk_norm(int *bsize,int *dfree,int *dsize)
  693. {
  694.   /* check if the disk is beyond the max disk size */
  695.   int maxdisksize = lp_maxdisksize();
  696.   if (maxdisksize) {
  697.     /* convert to blocks - and don't overflow */
  698.     maxdisksize = ((maxdisksize*1024)/(*bsize))*1024;
  699.     if (*dsize > maxdisksize) *dsize = maxdisksize;
  700.     if (*dfree > maxdisksize) *dfree = maxdisksize-1; /* the -1 should stop 
  701.                              applications getting 
  702.                              div by 0 errors */
  703.   }  
  704.  
  705.   while (*dfree > WORDMAX || *dsize > WORDMAX || *bsize < 512) 
  706.     {
  707.       *dfree /= 2;
  708.       *dsize /= 2;
  709.       *bsize *= 2;
  710.       if (*bsize > WORDMAX )
  711.     {
  712.       *bsize = WORDMAX;
  713.       if (*dsize > WORDMAX)
  714.         *dsize = WORDMAX;
  715.       if (*dfree >  WORDMAX)
  716.         *dfree = WORDMAX;
  717.       break;
  718.     }
  719.     }
  720. }
  721.  
  722. /****************************************************************************
  723.   return number of 1K blocks available on a path and total number 
  724. ****************************************************************************/
  725. int disk_free(char *path,int *bsize,int *dfree,int *dsize)
  726. {
  727.   char *df_command = lp_dfree_command();
  728.   int dfree_retval;
  729. #ifdef QUOTAS
  730.   int dfreeq_retval;
  731.   int dfreeq = 0;
  732.   int bsizeq = *bsize;
  733.   int dsizeq = *dsize;
  734. #endif
  735.  
  736. #ifndef NO_STATFS
  737. #ifdef USE_STATVFS
  738.   struct statvfs fs;
  739. #else
  740. #ifdef ULTRIX
  741.   struct fs_data fs;
  742. #else
  743.   struct statfs fs;
  744. #endif
  745. #endif
  746. #endif
  747.  
  748.   /* possibly use system() to get the result */
  749.   if (df_command && *df_command)
  750.     {
  751.       int ret;
  752.       pstring syscmd;
  753.       pstring outfile;
  754.       
  755.       slprintf(outfile,sizeof(outfile)-1, "%s/dfree.smb.%d",tmpdir(),(int)getpid());
  756.       slprintf(syscmd,sizeof(syscmd)-1,"%s %s",df_command,path);
  757.       standard_sub_basic(syscmd);
  758.  
  759.       ret = smbrun(syscmd,outfile,False);
  760.       DEBUG(3,("Running the command `%s' gave %d\n",syscmd,ret));
  761.       
  762.       {
  763.         FILE *f = fopen(outfile,"r");    
  764.         *dsize = 0;
  765.         *dfree = 0;
  766.         *bsize = 1024;
  767.         if (f)
  768.           {
  769.             fscanf(f,"%d %d %d",dsize,dfree,bsize);
  770.             fclose(f);
  771.           }
  772.         else
  773.           DEBUG(0,("Can't open %s\n",outfile));
  774.       }
  775.       
  776.       unlink(outfile);
  777.       disk_norm(bsize,dfree,dsize);
  778.       dfree_retval = ((*bsize)/1024)*(*dfree);
  779. #ifdef QUOTAS
  780.       /* Ensure we return the min value between the users quota and
  781.          what's free on the disk. Thanks to Albrecht Gebhardt 
  782.          <albrecht.gebhardt@uni-klu.ac.at> for this fix.
  783.       */
  784.       if (disk_quotas(path, &bsizeq, &dfreeq, &dsizeq))
  785.         {
  786.           disk_norm(&bsizeq, &dfreeq, &dsizeq);
  787.           dfreeq_retval = ((bsizeq)/1024)*(dfreeq);
  788.           dfree_retval =  ( dfree_retval < dfreeq_retval ) ? 
  789.                            dfree_retval : dfreeq_retval ;
  790.           /* maybe dfree and dfreeq are calculated using different bsizes 
  791.              so convert dfree from bsize into bsizeq */
  792.           /* avoid overflows due to multiplication, so do not:
  793.                 *dfree = ((*dfree) * (*bsize)) / (bsizeq); 
  794.              bsize and bsizeq are powers of 2 so its better to
  795.              to divide them getting a multiplication or division factor
  796.              for dfree. Rene Nieuwenhuizen (07-10-1997) */
  797.           if (*bsize >= bsizeq) 
  798.             *dfree = *dfree * (*bsize / bsizeq);
  799.           else 
  800.             *dfree = *dfree / (bsizeq / *bsize);
  801.           *dfree = ( *dfree < dfreeq ) ? *dfree : dfreeq ; 
  802.           *bsize = bsizeq;
  803.           *dsize = dsizeq;
  804.         }
  805. #endif
  806.       return(dfree_retval);
  807.     }
  808.  
  809. #ifdef NO_STATFS
  810.   DEBUG(1,("Warning - no statfs function\n"));
  811.   return(1);
  812. #else
  813. #ifdef STATFS4
  814.   if (statfs(path,&fs,sizeof(fs),0) != 0)
  815. #else
  816. #ifdef USE_STATVFS
  817.     if (statvfs(path, &fs))
  818. #else
  819. #ifdef STATFS3
  820.       if (statfs(path,&fs,sizeof(fs)) == -1)     
  821. #else
  822.     if (statfs(path,&fs) == -1)
  823. #endif /* STATFS3 */
  824. #endif /* USE_STATVFS */
  825. #endif /* STATFS4 */
  826.       {
  827.         DEBUG(3,("dfree call failed code errno=%d\n",errno));
  828.         *bsize = 1024;
  829.         *dfree = 1;
  830.         *dsize = 1;
  831.         return(((*bsize)/1024)*(*dfree));
  832.       }
  833.  
  834. #ifdef ULTRIX
  835.   *bsize = 1024;
  836.   *dfree = fs.fd_req.bfree;
  837.   *dsize = fs.fd_req.btot;
  838. #else
  839. #ifdef USE_STATVFS
  840.   *bsize = fs.f_frsize;
  841. #else
  842. #ifdef USE_F_FSIZE
  843.   /* eg: osf1 has f_fsize = fundamental filesystem block size, 
  844.      f_bsize = optimal transfer block size (MX: 94-04-19) */
  845.   *bsize = fs.f_fsize;
  846. #else
  847.   *bsize = fs.f_bsize;
  848. #endif /* STATFS3 */
  849. #endif /* USE_STATVFS */
  850.  
  851. #ifdef STATFS4
  852.   *dfree = fs.f_bfree;
  853. #else
  854.   *dfree = fs.f_bavail;
  855. #endif /* STATFS4 */
  856.   *dsize = fs.f_blocks;
  857. #endif /* ULTRIX */
  858.  
  859. #if defined(SCO) || defined(ISC) || defined(MIPS)
  860.   *bsize = 512;
  861. #endif
  862.  
  863. /* handle rediculous bsize values - some OSes are broken */
  864. if ((*bsize) < 512 || (*bsize)>0xFFFF) *bsize = 1024;
  865.  
  866.   disk_norm(bsize,dfree,dsize);
  867.  
  868.   if (*bsize < 256)
  869.     *bsize = 512;
  870.   if ((*dsize)<1)
  871.     {
  872.       DEBUG(0,("dfree seems to be broken on your system\n"));
  873.       *dsize = 20*1024*1024/(*bsize);
  874.       *dfree = MAX(1,*dfree);
  875.     }
  876.   dfree_retval = ((*bsize)/1024)*(*dfree);
  877. #ifdef QUOTAS
  878.   /* Ensure we return the min value between the users quota and
  879.      what's free on the disk. Thanks to Albrecht Gebhardt 
  880.      <albrecht.gebhardt@uni-klu.ac.at> for this fix.
  881.   */
  882.   if (disk_quotas(path, &bsizeq, &dfreeq, &dsizeq))
  883.     {
  884.       disk_norm(&bsizeq, &dfreeq, &dsizeq);
  885.       dfreeq_retval = ((bsizeq)/1024)*(dfreeq);
  886.       dfree_retval = ( dfree_retval < dfreeq_retval ) ? 
  887.                        dfree_retval : dfreeq_retval ;
  888.       /* maybe dfree and dfreeq are calculated using different bsizes 
  889.          so convert dfree from bsize into bsizeq */
  890.       /* avoid overflows due to multiplication, so do not:
  891.               *dfree = ((*dfree) * (*bsize)) / (bsizeq); 
  892.        bsize and bsizeq are powers of 2 so its better to
  893.        to divide them getting a multiplication or division factor
  894.        for dfree. Rene Nieuwenhuizen (07-10-1997) */
  895.       if (*bsize >= bsizeq)
  896.         *dfree = *dfree * (*bsize / bsizeq);
  897.       else
  898.         *dfree = *dfree / (bsizeq / *bsize);
  899.       *dfree = ( *dfree < dfreeq ) ? *dfree : dfreeq ;
  900.       *bsize = bsizeq;
  901.       *dsize = dsizeq;
  902.     }
  903. #endif
  904.   return(dfree_retval);
  905. #endif
  906. }
  907.  
  908.  
  909. /****************************************************************************
  910. wrap it to get filenames right
  911. ****************************************************************************/
  912. int sys_disk_free(char *path,int *bsize,int *dfree,int *dsize)
  913. {
  914.   return(disk_free(dos_to_unix(path,False),bsize,dfree,dsize));
  915. }
  916.  
  917.  
  918.  
  919. /****************************************************************************
  920. check a filename - possibly caling reducename
  921.  
  922. This is called by every routine before it allows an operation on a filename.
  923. It does any final confirmation necessary to ensure that the filename is
  924. a valid one for the user to access.
  925. ****************************************************************************/
  926. BOOL check_name(char *name,int cnum)
  927. {
  928.   BOOL ret;
  929.  
  930.   errno = 0;
  931.  
  932.   if( IS_VETO_PATH(cnum, name)) 
  933.     {
  934.       DEBUG(5,("file path name %s vetoed\n",name));
  935.       return(0);
  936.     }
  937.  
  938.   ret = reduce_name(name,Connections[cnum].connectpath,lp_widelinks(SNUM(cnum)));
  939.  
  940.   /* Check if we are allowing users to follow symlinks */
  941.   /* Patch from David Clerc <David.Clerc@cui.unige.ch>
  942.      University of Geneva */
  943.  
  944. #ifdef S_ISLNK
  945.   if (!lp_symlinks(SNUM(cnum)))
  946.     {
  947.       struct stat statbuf;
  948.       if ( (sys_lstat(name,&statbuf) != -1) &&
  949.           (S_ISLNK(statbuf.st_mode)) )
  950.         {
  951.           DEBUG(3,("check_name: denied: file path name %s is a symlink\n",name));
  952.           ret=0; 
  953.         }
  954.     }
  955. #endif
  956.  
  957.   if (!ret)
  958.     DEBUG(5,("check_name on %s failed\n",name));
  959.  
  960.   return(ret);
  961. }
  962.  
  963. /****************************************************************************
  964. check a filename - possibly caling reducename
  965. ****************************************************************************/
  966. static void check_for_pipe(char *fname)
  967. {
  968.   /* special case of pipe opens */
  969.   char s[10];
  970.   StrnCpy(s,fname,9);
  971.   strlower(s);
  972.   if (strstr(s,"pipe/"))
  973.     {
  974.       DEBUG(3,("Rejecting named pipe open for %s\n",fname));
  975.       unix_ERR_class = ERRSRV;
  976.       unix_ERR_code = ERRaccess;
  977.     }
  978. }
  979.  
  980. /****************************************************************************
  981. fd support routines - attempt to do a sys_open
  982. ****************************************************************************/
  983. static int fd_attempt_open(char *fname, int flags, int mode)
  984. {
  985.   int fd = sys_open(fname,flags,mode);
  986.  
  987.   /* Fix for files ending in '.' */
  988.   if((fd == -1) && (errno == ENOENT) &&
  989.      (strchr(fname,'.')==NULL))
  990.     {
  991.       pstrcat(fname,".");
  992.       fd = sys_open(fname,flags,mode);
  993.     }
  994.  
  995. #if (defined(ENAMETOOLONG) && defined(HAVE_PATHCONF))
  996.   if ((fd == -1) && (errno == ENAMETOOLONG))
  997.     {
  998.       int max_len;
  999.       char *p = strrchr(fname, '/');
  1000.  
  1001.       if (p == fname)   /* name is "/xxx" */
  1002.         {
  1003.           max_len = pathconf("/", _PC_NAME_MAX);
  1004.           p++;
  1005.         }
  1006.       else if ((p == NULL) || (p == fname))
  1007.         {
  1008.           p = fname;
  1009.           max_len = pathconf(".", _PC_NAME_MAX);
  1010.         }
  1011.       else
  1012.         {
  1013.           *p = '\0';
  1014.           max_len = pathconf(fname, _PC_NAME_MAX);
  1015.           *p = '/';
  1016.           p++;
  1017.         }
  1018.       if (strlen(p) > max_len)
  1019.         {
  1020.           char tmp = p[max_len];
  1021.  
  1022.           p[max_len] = '\0';
  1023.           if ((fd = sys_open(fname,flags,mode)) == -1)
  1024.             p[max_len] = tmp;
  1025.         }
  1026.     }
  1027. #endif
  1028.   return fd;
  1029. }
  1030.  
  1031. /****************************************************************************
  1032. Cache a uid_t currently with this file open. This is an optimization only
  1033. used when multiple sessionsetup's have been done to one smbd.
  1034. ****************************************************************************/
  1035. static void fd_add_to_uid_cache(file_fd_struct *fd_ptr, uid_t u)
  1036. {
  1037.   if(fd_ptr->uid_cache_count >= sizeof(fd_ptr->uid_users_cache)/sizeof(uid_t))
  1038.     return;
  1039.   fd_ptr->uid_users_cache[fd_ptr->uid_cache_count++] = u;
  1040. }
  1041.  
  1042. /****************************************************************************
  1043. Remove a uid_t that currently has this file open. This is an optimization only
  1044. used when multiple sessionsetup's have been done to one smbd.
  1045. ****************************************************************************/
  1046. static void fd_remove_from_uid_cache(file_fd_struct *fd_ptr, uid_t u)
  1047. {
  1048.   int i;
  1049.   for(i = 0; i < fd_ptr->uid_cache_count; i++)
  1050.     if(fd_ptr->uid_users_cache[i] == u) {
  1051.       if(i < (fd_ptr->uid_cache_count-1))
  1052.         memmove((char *)&fd_ptr->uid_users_cache[i], (char *)&fd_ptr->uid_users_cache[i+1],
  1053.                sizeof(uid_t)*(fd_ptr->uid_cache_count-1-i) );
  1054.       fd_ptr->uid_cache_count--;
  1055.     }
  1056.   return;
  1057. }
  1058.  
  1059. /****************************************************************************
  1060. Check if a uid_t that currently has this file open is present. This is an
  1061. optimization only used when multiple sessionsetup's have been done to one smbd.
  1062. ****************************************************************************/
  1063. static BOOL fd_is_in_uid_cache(file_fd_struct *fd_ptr, uid_t u)
  1064. {
  1065.   int i;
  1066.   for(i = 0; i < fd_ptr->uid_cache_count; i++)
  1067.     if(fd_ptr->uid_users_cache[i] == u)
  1068.       return True;
  1069.   return False;
  1070. }
  1071.  
  1072. /****************************************************************************
  1073. fd support routines - attempt to find an already open file by dev
  1074. and inode - increments the ref_count of the returned file_fd_struct *.
  1075. ****************************************************************************/
  1076. static file_fd_struct *fd_get_already_open(struct stat *sbuf)
  1077. {
  1078.   int i;
  1079.   file_fd_struct *fd_ptr;
  1080.  
  1081.   if(sbuf == 0)
  1082.     return 0;
  1083.  
  1084.   for(i = 0; i <= max_file_fd_used; i++) {
  1085.     fd_ptr = &FileFd[i];
  1086.     if((fd_ptr->ref_count > 0) &&
  1087.        (((uint32)sbuf->st_dev) == fd_ptr->dev) &&
  1088.        (((uint32)sbuf->st_ino) == fd_ptr->inode)) {
  1089.       fd_ptr->ref_count++;
  1090.       DEBUG(3,
  1091.        ("Re-used file_fd_struct %d, dev = %x, inode = %x, ref_count = %d\n",
  1092.         i, fd_ptr->dev, fd_ptr->inode, fd_ptr->ref_count));
  1093.       return fd_ptr;
  1094.     }
  1095.   }
  1096.   return 0;
  1097. }
  1098.  
  1099. /****************************************************************************
  1100. fd support routines - attempt to find a empty slot in the FileFd array.
  1101. Increments the ref_count of the returned entry.
  1102. ****************************************************************************/
  1103. static file_fd_struct *fd_get_new(void)
  1104. {
  1105.   extern struct current_user current_user;
  1106.   int i;
  1107.   file_fd_struct *fd_ptr;
  1108.  
  1109.   for(i = 0; i < MAX_OPEN_FILES; i++) {
  1110.     fd_ptr = &FileFd[i];
  1111.     if(fd_ptr->ref_count == 0) {
  1112.       fd_ptr->dev = (uint32)-1;
  1113.       fd_ptr->inode = (uint32)-1;
  1114.       fd_ptr->fd = -1;
  1115.       fd_ptr->fd_readonly = -1;
  1116.       fd_ptr->fd_writeonly = -1;
  1117.       fd_ptr->real_open_flags = -1;
  1118.       fd_ptr->uid_cache_count = 0;
  1119.       fd_add_to_uid_cache(fd_ptr, (uid_t)current_user.uid);
  1120.       fd_ptr->ref_count++;
  1121.       /* Increment max used counter if neccessary, cuts down
  1122.          on search time when re-using */
  1123.       if(i > max_file_fd_used)
  1124.         max_file_fd_used = i;
  1125.       DEBUG(3,("Allocated new file_fd_struct %d, dev = %x, inode = %x\n",
  1126.                i, fd_ptr->dev, fd_ptr->inode));
  1127.       return fd_ptr;
  1128.     }
  1129.   }
  1130.   DEBUG(1,("ERROR! Out of file_fd structures - perhaps increase MAX_OPEN_FILES?\n"));
  1131.   return 0;
  1132. }
  1133.  
  1134. /****************************************************************************
  1135. fd support routines - attempt to re-open an already open fd as O_RDWR.
  1136. Save the already open fd (we cannot close due to POSIX file locking braindamage.
  1137. ****************************************************************************/
  1138. static void fd_attempt_reopen(char *fname, int mode, file_fd_struct *fd_ptr)
  1139. {
  1140.   int fd = sys_open( fname, O_RDWR, mode);
  1141.  
  1142.   if(fd == -1)
  1143.     return;
  1144.  
  1145.   if(fd_ptr->real_open_flags == O_RDONLY)
  1146.     fd_ptr->fd_readonly = fd_ptr->fd;
  1147.   if(fd_ptr->real_open_flags == O_WRONLY)
  1148.     fd_ptr->fd_writeonly = fd_ptr->fd;
  1149.  
  1150.   fd_ptr->fd = fd;
  1151.   fd_ptr->real_open_flags = O_RDWR;
  1152. }
  1153.  
  1154. /****************************************************************************
  1155. fd support routines - attempt to close the file referenced by this fd.
  1156. Decrements the ref_count and returns it.
  1157. ****************************************************************************/
  1158. static int fd_attempt_close(file_fd_struct *fd_ptr)
  1159. {
  1160.   extern struct current_user current_user;
  1161.  
  1162.   DEBUG(3,("fd_attempt_close on file_fd_struct %d, fd = %d, dev = %x, inode = %x, open_flags = %d, ref_count = %d.\n",
  1163.           fd_ptr - &FileFd[0],
  1164.           fd_ptr->fd, fd_ptr->dev, fd_ptr->inode,
  1165.           fd_ptr->real_open_flags,
  1166.           fd_ptr->ref_count));
  1167.   if(fd_ptr->ref_count > 0) {
  1168.     fd_ptr->ref_count--;
  1169.     if(fd_ptr->ref_count == 0) {
  1170.       if(fd_ptr->fd != -1)
  1171.         close(fd_ptr->fd);
  1172.       if(fd_ptr->fd_readonly != -1)
  1173.         close(fd_ptr->fd_readonly);
  1174.       if(fd_ptr->fd_writeonly != -1)
  1175.         close(fd_ptr->fd_writeonly);
  1176.       fd_ptr->fd = -1;
  1177.       fd_ptr->fd_readonly = -1;
  1178.       fd_ptr->fd_writeonly = -1;
  1179.       fd_ptr->real_open_flags = -1;
  1180.       fd_ptr->dev = (uint32)-1;
  1181.       fd_ptr->inode = (uint32)-1;
  1182.       fd_ptr->uid_cache_count = 0;
  1183.     } else
  1184.       fd_remove_from_uid_cache(fd_ptr, (uid_t)current_user.uid);
  1185.   } 
  1186.  return fd_ptr->ref_count;
  1187. }
  1188.  
  1189. /****************************************************************************
  1190. fd support routines - check that current user has permissions
  1191. to open this file. Used when uid not found in optimization cache.
  1192. This is really ugly code, as due to POSIX locking braindamage we must
  1193. fork and then attempt to open the file, and return success or failure
  1194. via an exit code.
  1195. ****************************************************************************/
  1196. static BOOL check_access_allowed_for_current_user( char *fname, int accmode )
  1197. {
  1198.   pid_t child_pid;
  1199.  
  1200.   if((child_pid = fork()) < 0) {
  1201.     DEBUG(0,("check_access_allowed_for_current_user: fork failed.\n"));
  1202.     return False;
  1203.   }
  1204.  
  1205.   if(child_pid) {
  1206.     /*
  1207.      * Parent.
  1208.      */
  1209.     pid_t wpid;
  1210.     int status_code;
  1211.     if ((wpid = sys_waitpid(child_pid, &status_code, 0)) < 0) {
  1212.       DEBUG(0,("check_access_allowed_for_current_user: The process is no longer waiting!\n"));
  1213.       return(False);
  1214.     }
  1215.  
  1216.     if (child_pid != wpid) {
  1217.       DEBUG(0,("check_access_allowed_for_current_user: We were waiting for the wrong process ID\n"));
  1218.       return(False);
  1219.     }
  1220. #if defined(WIFEXITED) && defined(WEXITSTATUS)
  1221.     if (WIFEXITED(status_code) == 0) {
  1222.       DEBUG(0,("check_access_allowed_for_current_user: The process exited while we were waiting\n"));
  1223.       return(False);
  1224.     }
  1225.     if (WEXITSTATUS(status_code) != 0) {
  1226.       DEBUG(9,("check_access_allowed_for_current_user: The status of the process exiting was %d. Returning access denied.\n", status_code));
  1227.       return(False);
  1228.     }
  1229. #else /* defined(WIFEXITED) && defined(WEXITSTATUS) */
  1230.     if(status_code != 0) {
  1231.       DEBUG(9,("check_access_allowed_for_current_user: The status of the process exiting was %d. Returning access denied.\n", status_code));
  1232.       return(False);
  1233.     }
  1234. #endif /* defined(WIFEXITED) && defined(WEXITSTATUS) */
  1235.  
  1236.     /*
  1237.      * Success - the child could open the file.
  1238.      */
  1239.     DEBUG(9,("check_access_allowed_for_current_user: The status of the process exiting was %d. Returning access allowed.\n", status_code));
  1240.     return True;
  1241.   } else {
  1242.     /*
  1243.      * Child.
  1244.      */
  1245.     int fd;
  1246.     DEBUG(9,("check_access_allowed_for_current_user: Child - attempting to open %s with mode %d.\n", fname, accmode ));
  1247.     if((fd = fd_attempt_open( fname, accmode, 0)) < 0) {
  1248.       /* Access denied. */
  1249.       _exit(EACCES);
  1250.     }
  1251.     close(fd);
  1252.     DEBUG(9,("check_access_allowed_for_current_user: Child - returning ok.\n"));
  1253.     _exit(0);
  1254.   }
  1255.  
  1256.   return False;
  1257. }
  1258.  
  1259. /****************************************************************************
  1260. open a file
  1261. ****************************************************************************/
  1262. static void open_file(int fnum,int cnum,char *fname1,int flags,int mode, struct stat *sbuf)
  1263. {
  1264.   extern struct current_user current_user;
  1265.   pstring fname;
  1266.   struct stat statbuf;
  1267.   file_fd_struct *fd_ptr;
  1268.   files_struct *fsp = &Files[fnum];
  1269.   int accmode = (flags & (O_RDONLY | O_WRONLY | O_RDWR));
  1270.  
  1271.   fsp->open = False;
  1272.   fsp->fd_ptr = 0;
  1273.   fsp->granted_oplock = False;
  1274.   errno = EPERM;
  1275.  
  1276.   pstrcpy(fname,fname1);
  1277.  
  1278.   /* check permissions */
  1279.  
  1280.   /*
  1281.    * This code was changed after seeing a client open request 
  1282.    * containing the open mode of (DENY_WRITE/read-only) with
  1283.    * the 'create if not exist' bit set. The previous code
  1284.    * would fail to open the file read only on a read-only share
  1285.    * as it was checking the flags parameter  directly against O_RDONLY,
  1286.    * this was failing as the flags parameter was set to O_RDONLY|O_CREAT.
  1287.    * JRA.
  1288.    */
  1289.  
  1290.   if (!CAN_WRITE(cnum) && !Connections[cnum].printer) {
  1291.     /* It's a read-only share - fail if we wanted to write. */
  1292.     if(accmode != O_RDONLY) {
  1293.       DEBUG(3,("Permission denied opening %s\n",fname));
  1294.       check_for_pipe(fname);
  1295.       return;
  1296.     }
  1297.     else if(flags & O_CREAT) {
  1298.       /* We don't want to write - but we must make sure that O_CREAT
  1299.          doesn't create the file if we have write access into the
  1300.          directory.
  1301.        */
  1302.       flags &= ~O_CREAT;
  1303.     }
  1304.   }
  1305.  
  1306.   /* this handles a bug in Win95 - it doesn't say to create the file when it 
  1307.      should */
  1308.   if (Connections[cnum].printer)
  1309.     flags |= O_CREAT;
  1310.  
  1311. /*
  1312.   if (flags == O_WRONLY)
  1313.     DEBUG(3,("Bug in client? Set O_WRONLY without O_CREAT\n"));
  1314. */
  1315.  
  1316.   /*
  1317.    * Ensure we have a valid struct stat so we can search the
  1318.    * open fd table.
  1319.    */
  1320.   if(sbuf == 0) {
  1321.     if(sys_stat(fname, &statbuf) < 0) {
  1322.       if(errno != ENOENT) {
  1323.         DEBUG(3,("Error doing stat on file %s (%s)\n",
  1324.                  fname,strerror(errno)));
  1325.  
  1326.         check_for_pipe(fname);
  1327.         return;
  1328.       }
  1329.       sbuf = 0;
  1330.     } else {
  1331.       sbuf = &statbuf;
  1332.     }
  1333.   }
  1334.  
  1335.   /*
  1336.    * Check to see if we have this file already
  1337.    * open. If we do, just use the already open fd and increment the
  1338.    * reference count (fd_get_already_open increments the ref_count).
  1339.    */
  1340.   if((fd_ptr = fd_get_already_open(sbuf))!= 0) {
  1341.     /*
  1342.      * File was already open.
  1343.      */
  1344.  
  1345.     /* 
  1346.      * Check it wasn't open for exclusive use.
  1347.      */
  1348.     if((flags & O_CREAT) && (flags & O_EXCL)) {
  1349.       fd_ptr->ref_count--;
  1350.       errno = EEXIST;
  1351.       return;
  1352.     }
  1353.  
  1354.     /*
  1355.      * Ensure that the user attempting to open
  1356.      * this file has permissions to do so, if
  1357.      * the user who originally opened the file wasn't
  1358.      * the same as the current user.
  1359.      */
  1360.  
  1361.     if(!fd_is_in_uid_cache(fd_ptr, (uid_t)current_user.uid)) {
  1362.       if(!check_access_allowed_for_current_user( fname, accmode )) {
  1363.         /* Error - permission denied. */
  1364.         DEBUG(3,("Permission denied opening file %s (flags=%d, accmode = %d)\n",
  1365.               fname, flags, accmode));
  1366.         /* Ensure the ref_count is decremented. */
  1367.         fd_ptr->ref_count--;
  1368.         fd_remove_from_uid_cache(fd_ptr, (uid_t)current_user.uid);
  1369.         errno = EACCES;
  1370.         return;
  1371.       }
  1372.     }
  1373.  
  1374.     fd_add_to_uid_cache(fd_ptr, (uid_t)current_user.uid);
  1375.  
  1376.     /* 
  1377.      * If not opened O_RDWR try
  1378.      * and do that here - a chmod may have been done
  1379.      * between the last open and now. 
  1380.      */
  1381.     if(fd_ptr->real_open_flags != O_RDWR)
  1382.       fd_attempt_reopen(fname, mode, fd_ptr);
  1383.  
  1384.     /*
  1385.      * Ensure that if we wanted write access
  1386.      * it has been opened for write, and if we wanted read it
  1387.      * was open for read. 
  1388.      */
  1389.     if(((accmode == O_WRONLY) && (fd_ptr->real_open_flags == O_RDONLY)) ||
  1390.        ((accmode == O_RDONLY) && (fd_ptr->real_open_flags == O_WRONLY)) ||
  1391.        ((accmode == O_RDWR) && (fd_ptr->real_open_flags != O_RDWR))) {
  1392.       DEBUG(3,("Error opening (already open for flags=%d) file %s (%s) (flags=%d)\n",
  1393.                fd_ptr->real_open_flags, fname,strerror(EACCES),flags));
  1394.       check_for_pipe(fname);
  1395.       fd_remove_from_uid_cache(fd_ptr, (uid_t)current_user.uid);
  1396.       fd_ptr->ref_count--;
  1397.       return;
  1398.     }
  1399.  
  1400.   } else {
  1401.     int open_flags;
  1402.     /* We need to allocate a new file_fd_struct (this increments the
  1403.        ref_count). */
  1404.     if((fd_ptr = fd_get_new()) == 0)
  1405.       return;
  1406.     /*
  1407.      * Whatever the requested flags, attempt read/write access,
  1408.      * as we don't know what flags future file opens may require.
  1409.      * If this fails, try again with the required flags. 
  1410.      * Even if we open read/write when only read access was 
  1411.      * requested the setting of the can_write flag in
  1412.      * the file_struct will protect us from errant
  1413.      * write requests. We never need to worry about O_APPEND
  1414.      * as this is not set anywhere in Samba.
  1415.      */
  1416.     fd_ptr->real_open_flags = O_RDWR;
  1417.     /* Set the flags as needed without the read/write modes. */
  1418.     open_flags = flags & ~(O_RDWR|O_WRONLY|O_RDONLY);
  1419.     fd_ptr->fd = fd_attempt_open(fname, open_flags|O_RDWR, mode);
  1420.     /*
  1421.      * On some systems opening a file for R/W access on a read only
  1422.      * filesystems sets errno to EROFS.
  1423.      */
  1424. #ifdef EROFS
  1425.     if((fd_ptr->fd == -1) && ((errno == EACCES) || (errno == EROFS))) {
  1426. #else /* No EROFS */
  1427.     if((fd_ptr->fd == -1) && (errno == EACCES)) {
  1428. #endif /* EROFS */
  1429.       if(accmode != O_RDWR) {
  1430.         fd_ptr->fd = fd_attempt_open(fname, open_flags|accmode, mode);
  1431.         fd_ptr->real_open_flags = accmode;
  1432.       }
  1433.     }
  1434.   }
  1435.  
  1436.   if ((fd_ptr->fd >=0) && 
  1437.       Connections[cnum].printer && lp_minprintspace(SNUM(cnum))) {
  1438.     pstring dname;
  1439.     int dum1,dum2,dum3;
  1440.     char *p;
  1441.     pstrcpy(dname,fname);
  1442.     p = strrchr(dname,'/');
  1443.     if (p) *p = 0;
  1444.     if (sys_disk_free(dname,&dum1,&dum2,&dum3) < 
  1445.     lp_minprintspace(SNUM(cnum))) {
  1446.       fd_attempt_close(fd_ptr);
  1447.       fsp->fd_ptr = 0;
  1448.       if(fd_ptr->ref_count == 0)
  1449.         sys_unlink(fname);
  1450.       errno = ENOSPC;
  1451.       return;
  1452.     }
  1453.   }
  1454.     
  1455.   if (fd_ptr->fd < 0)
  1456.   {
  1457.     DEBUG(3,("Error opening file %s (%s) (flags=%d)\n",
  1458.       fname,strerror(errno),flags));
  1459.     /* Ensure the ref_count is decremented. */
  1460.     fd_attempt_close(fd_ptr);
  1461.     check_for_pipe(fname);
  1462.     return;
  1463.   }
  1464.  
  1465.   if (fd_ptr->fd >= 0)
  1466.   {
  1467.     if(sbuf == 0) {
  1468.       /* Do the fstat */
  1469.       if(fstat(fd_ptr->fd, &statbuf) == -1) {
  1470.         /* Error - backout !! */
  1471.         DEBUG(3,("Error doing fstat on fd %d, file %s (%s)\n",
  1472.                  fd_ptr->fd, fname,strerror(errno)));
  1473.         /* Ensure the ref_count is decremented. */
  1474.         fd_attempt_close(fd_ptr);
  1475.         return;
  1476.       }
  1477.       sbuf = &statbuf;
  1478.     }
  1479.  
  1480.     /* Set the correct entries in fd_ptr. */
  1481.     fd_ptr->dev = (uint32)sbuf->st_dev;
  1482.     fd_ptr->inode = (uint32)sbuf->st_ino;
  1483.  
  1484.     fsp->fd_ptr = fd_ptr;
  1485.     Connections[cnum].num_files_open++;
  1486.     fsp->mode = sbuf->st_mode;
  1487.     GetTimeOfDay(&fsp->open_time);
  1488.     fsp->vuid = current_user.vuid;
  1489.     fsp->size = 0;
  1490.     fsp->pos = -1;
  1491.     fsp->open = True;
  1492.     fsp->mmap_ptr = NULL;
  1493.     fsp->mmap_size = 0;
  1494.     fsp->can_lock = True;
  1495.     fsp->can_read = ((flags & O_WRONLY)==0);
  1496.     fsp->can_write = ((flags & (O_WRONLY|O_RDWR))!=0);
  1497.     fsp->share_mode = 0;
  1498.     fsp->print_file = Connections[cnum].printer;
  1499.     fsp->modified = False;
  1500.     fsp->granted_oplock = False;
  1501.     fsp->sent_oplock_break = False;
  1502.     fsp->cnum = cnum;
  1503.     /*
  1504.      * Note that the file name here is the *untranslated* name
  1505.      * ie. it is still in the DOS codepage sent from the client.
  1506.      * All use of this filename will pass though the sys_xxxx
  1507.      * functions which will do the dos_to_unix translation before
  1508.      * mapping into a UNIX filename. JRA.
  1509.      */
  1510.     string_set(&fsp->name,fname);
  1511.     fsp->wbmpx_ptr = NULL;      
  1512.  
  1513.     /*
  1514.      * If the printer is marked as postscript output a leading
  1515.      * file identifier to ensure the file is treated as a raw
  1516.      * postscript file.
  1517.      * This has a similar effect as CtrlD=0 in WIN.INI file.
  1518.      * tim@fsg.com 09/06/94
  1519.      */
  1520.     if (fsp->print_file && POSTSCRIPT(cnum) && fsp->can_write) 
  1521.     {
  1522.       DEBUG(3,("Writing postscript line\n"));
  1523.       write_file(fnum,"%!\n",3);
  1524.     }
  1525.       
  1526.     DEBUG(2,("%s %s opened file %s read=%s write=%s (numopen=%d fnum=%d)\n",
  1527.           timestring(),
  1528.           *sesssetup_user ? sesssetup_user : Connections[cnum].user,fname,
  1529.           BOOLSTR(fsp->can_read),BOOLSTR(fsp->can_write),
  1530.           Connections[cnum].num_files_open,fnum));
  1531.  
  1532.   }
  1533.  
  1534. #if USE_MMAP
  1535.   /* mmap it if read-only */
  1536.   if (!fsp->can_write)
  1537.   {
  1538.     fsp->mmap_size = file_size(fname);
  1539.     fsp->mmap_ptr = (char *)mmap(NULL,fsp->mmap_size,
  1540.                                  PROT_READ,MAP_SHARED,fsp->fd_ptr->fd,0);
  1541.  
  1542.     if (fsp->mmap_ptr == (char *)-1 || !fsp->mmap_ptr)
  1543.     {
  1544.       DEBUG(3,("Failed to mmap() %s - %s\n",fname,strerror(errno)));
  1545.       fsp->mmap_ptr = NULL;
  1546.     }
  1547.   }
  1548. #endif
  1549. }
  1550.  
  1551. /*******************************************************************
  1552. sync a file
  1553. ********************************************************************/
  1554. void sync_file(int cnum, int fnum)
  1555. {
  1556. #ifndef NO_FSYNC
  1557.   if(lp_strict_sync(SNUM(cnum)))
  1558.     fsync(Files[fnum].fd_ptr->fd);
  1559. #endif
  1560. }
  1561.  
  1562. /****************************************************************************
  1563. run a file if it is a magic script
  1564. ****************************************************************************/
  1565. static void check_magic(int fnum,int cnum)
  1566. {
  1567.   if (!*lp_magicscript(SNUM(cnum)))
  1568.     return;
  1569.  
  1570.   DEBUG(5,("checking magic for %s\n",Files[fnum].name));
  1571.  
  1572.   {
  1573.     char *p;
  1574.     if (!(p = strrchr(Files[fnum].name,'/')))
  1575.       p = Files[fnum].name;
  1576.     else
  1577.       p++;
  1578.  
  1579.     if (!strequal(lp_magicscript(SNUM(cnum)),p))
  1580.       return;
  1581.   }
  1582.  
  1583.   {
  1584.     int ret;
  1585.     pstring magic_output;
  1586.     pstring fname;
  1587.     pstrcpy(fname,Files[fnum].name);
  1588.  
  1589.     if (*lp_magicoutput(SNUM(cnum)))
  1590.       pstrcpy(magic_output,lp_magicoutput(SNUM(cnum)));
  1591.     else
  1592.       slprintf(magic_output,sizeof(fname)-1, "%s.out",fname);
  1593.  
  1594.     chmod(fname,0755);
  1595.     ret = smbrun(fname,magic_output,False);
  1596.     DEBUG(3,("Invoking magic command %s gave %d\n",fname,ret));
  1597.     unlink(fname);
  1598.   }
  1599. }
  1600.  
  1601.  
  1602. /****************************************************************************
  1603. close a file - possibly invalidating the read prediction
  1604.  
  1605. If normal_close is 1 then this came from a normal SMBclose (or equivalent)
  1606. operation otherwise it came as the result of some other operation such as
  1607. the closing of the connection. In the latter case printing and
  1608. magic scripts are not run
  1609. ****************************************************************************/
  1610. void close_file(int fnum, BOOL normal_close)
  1611. {
  1612.   files_struct *fs_p = &Files[fnum];
  1613.   int cnum = fs_p->cnum;
  1614.   uint32 dev = fs_p->fd_ptr->dev;
  1615.   uint32 inode = fs_p->fd_ptr->inode;
  1616.   int token;
  1617.  
  1618.   Files[fnum].reserved = False;
  1619.  
  1620. #if USE_READ_PREDICTION
  1621.   invalidate_read_prediction(fs_p->fd_ptr->fd);
  1622. #endif
  1623.  
  1624.   fs_p->open = False;
  1625.   Connections[cnum].num_files_open--;
  1626.   if(fs_p->wbmpx_ptr) 
  1627.   {
  1628.     free((char *)fs_p->wbmpx_ptr);
  1629.     fs_p->wbmpx_ptr = NULL;
  1630.   }
  1631.  
  1632. #if USE_MMAP
  1633.   if(fs_p->mmap_ptr) 
  1634.   {
  1635.     munmap(fs_p->mmap_ptr,fs_p->mmap_size);
  1636.     fs_p->mmap_ptr = NULL;
  1637.   }
  1638. #endif
  1639.  
  1640.   if (lp_share_modes(SNUM(cnum)))
  1641.   {
  1642.     lock_share_entry( cnum, dev, inode, &token);
  1643.     del_share_mode(token, fnum);
  1644.   }
  1645.  
  1646.   fd_attempt_close(fs_p->fd_ptr);
  1647.  
  1648.   if (lp_share_modes(SNUM(cnum)))
  1649.     unlock_share_entry( cnum, dev, inode, token);
  1650.  
  1651.   /* NT uses smbclose to start a print - weird */
  1652.   if (normal_close && fs_p->print_file)
  1653.     print_file(fnum);
  1654.  
  1655.   /* check for magic scripts */
  1656.   if (normal_close)
  1657.     check_magic(fnum,cnum);
  1658.  
  1659.   if(fs_p->granted_oplock == True)
  1660.     global_oplocks_open--;
  1661.  
  1662.   fs_p->sent_oplock_break = False;
  1663.  
  1664.   DEBUG(2,("%s %s closed file %s (numopen=%d)\n",
  1665.        timestring(),Connections[cnum].user,fs_p->name,
  1666.        Connections[cnum].num_files_open));
  1667.  
  1668.   if (fs_p->name) {
  1669.       string_free(&fs_p->name);
  1670.   }
  1671.  
  1672.   /* we will catch bugs faster by zeroing this structure */
  1673.   memset(fs_p, 0, sizeof(*fs_p));
  1674. }
  1675.  
  1676. enum {AFAIL,AREAD,AWRITE,AALL};
  1677.  
  1678. /*******************************************************************
  1679. reproduce the share mode access table
  1680. ********************************************************************/
  1681. static int access_table(int new_deny,int old_deny,int old_mode,
  1682.             int share_pid,char *fname)
  1683. {
  1684.   if (new_deny == DENY_ALL || old_deny == DENY_ALL) return(AFAIL);
  1685.  
  1686.   if (new_deny == DENY_DOS || old_deny == DENY_DOS) {
  1687.     int pid = getpid();
  1688.     if (old_deny == new_deny && share_pid == pid) 
  1689.     return(AALL);    
  1690.  
  1691.     if (old_mode == 0) return(AREAD);
  1692.  
  1693.     /* the new smbpub.zip spec says that if the file extension is
  1694.        .com, .dll, .exe or .sym then allow the open. I will force
  1695.        it to read-only as this seems sensible although the spec is
  1696.        a little unclear on this. */
  1697.     if ((fname = strrchr(fname,'.'))) {
  1698.       if (strequal(fname,".com") ||
  1699.       strequal(fname,".dll") ||
  1700.       strequal(fname,".exe") ||
  1701.       strequal(fname,".sym"))
  1702.     return(AREAD);
  1703.     }
  1704.  
  1705.     return(AFAIL);
  1706.   }
  1707.  
  1708.   switch (new_deny) 
  1709.     {
  1710.     case DENY_WRITE:
  1711.       if (old_deny==DENY_WRITE && old_mode==0) return(AREAD);
  1712.       if (old_deny==DENY_READ && old_mode==0) return(AWRITE);
  1713.       if (old_deny==DENY_NONE && old_mode==0) return(AALL);
  1714.       return(AFAIL);
  1715.     case DENY_READ:
  1716.       if (old_deny==DENY_WRITE && old_mode==1) return(AREAD);
  1717.       if (old_deny==DENY_READ && old_mode==1) return(AWRITE);
  1718.       if (old_deny==DENY_NONE && old_mode==1) return(AALL);
  1719.       return(AFAIL);
  1720.     case DENY_NONE:
  1721.       if (old_deny==DENY_WRITE) return(AREAD);
  1722.       if (old_deny==DENY_READ) return(AWRITE);
  1723.       if (old_deny==DENY_NONE) return(AALL);
  1724.       return(AFAIL);      
  1725.     }
  1726.   return(AFAIL);      
  1727. }
  1728.  
  1729. /*******************************************************************
  1730. check if the share mode on a file allows it to be deleted or unlinked
  1731. return True if sharing doesn't prevent the operation
  1732. ********************************************************************/
  1733. BOOL check_file_sharing(int cnum,char *fname, BOOL rename_op)
  1734. {
  1735.   int i;
  1736.   int ret = False;
  1737.   share_mode_entry *old_shares = 0;
  1738.   int num_share_modes;
  1739.   struct stat sbuf;
  1740.   int token;
  1741.   int pid = getpid();
  1742.   uint32 dev, inode;
  1743.  
  1744.   if(!lp_share_modes(SNUM(cnum)))
  1745.     return True;
  1746.  
  1747.   if (sys_stat(fname,&sbuf) == -1) return(True);
  1748.  
  1749.   dev = (uint32)sbuf.st_dev;
  1750.   inode = (uint32)sbuf.st_ino;
  1751.  
  1752.   lock_share_entry(cnum, dev, inode, &token);
  1753.   num_share_modes = get_share_modes(cnum, token, dev, inode, &old_shares);
  1754.  
  1755.   /*
  1756.    * Check if the share modes will give us access.
  1757.    */
  1758.  
  1759.   if(num_share_modes != 0)
  1760.   {
  1761.     BOOL broke_oplock;
  1762.  
  1763.     do
  1764.     {
  1765.  
  1766.       broke_oplock = False;
  1767.       for(i = 0; i < num_share_modes; i++)
  1768.       {
  1769.         share_mode_entry *share_entry = &old_shares[i];
  1770.  
  1771.         /* 
  1772.          * Break oplocks before checking share modes. See comment in
  1773.          * open_file_shared for details. 
  1774.          * Check if someone has an oplock on this file. If so we must 
  1775.          * break it before continuing. 
  1776.          */
  1777.         if(share_entry->op_type & BATCH_OPLOCK)
  1778.         {
  1779.  
  1780.           /*
  1781.            * It appears that the NT redirector may have a bug, in that
  1782.            * it tries to do an SMBmv on a file that it has open with a
  1783.            * batch oplock, and then fails to respond to the oplock break
  1784.            * request. This only seems to occur when the client is doing an
  1785.            * SMBmv to the smbd it is using - thus we try and detect this
  1786.            * condition by checking if the file being moved is open and oplocked by
  1787.            * this smbd process, and then not sending the oplock break in this
  1788.            * special case. If the file was open with a deny mode that 
  1789.            * prevents the move the SMBmv will fail anyway with a share
  1790.            * violation error. JRA.
  1791.            */
  1792.           if(rename_op && (share_entry->pid == pid))
  1793.           {
  1794.             DEBUG(0,("check_file_sharing: NT redirector workaround - rename attempted on \
  1795. batch oplocked file %s, dev = %x, inode = %x\n", fname, dev, inode));
  1796.             /* 
  1797.              * This next line is a test that allows the deny-mode
  1798.              * processing to be skipped. This seems to be needed as
  1799.              * NT insists on the rename succeeding (in Office 9x no less !).
  1800.              * This should be removed as soon as (a) MS fix the redirector
  1801.              * bug or (b) NT SMB support in Samba makes NT not issue the
  1802.              * call (as is my fervent hope). JRA.
  1803.              */ 
  1804.             continue;
  1805.           }
  1806.           else
  1807.           {
  1808.             DEBUG(5,("check_file_sharing: breaking oplock (%x) on file %s, \
  1809. dev = %x, inode = %x\n", share_entry->op_type, fname, dev, inode));
  1810.  
  1811.             /* Oplock break.... */
  1812.             unlock_share_entry(cnum, dev, inode, token);
  1813.             if(request_oplock_break(share_entry, dev, inode) == False)
  1814.             {
  1815.               free((char *)old_shares);
  1816.               DEBUG(0,("check_file_sharing: FAILED when breaking oplock (%x) on file %s, \
  1817. dev = %x, inode = %x\n", old_shares[i].op_type, fname, dev, inode));
  1818.               return False;
  1819.             }
  1820.             lock_share_entry(cnum, dev, inode, &token);
  1821.             broke_oplock = True;
  1822.             break;
  1823.           }
  1824.         }
  1825.  
  1826.         /* someone else has a share lock on it, check to see 
  1827.            if we can too */
  1828.         if ((share_entry->share_mode != DENY_DOS) || (share_entry->pid != pid))
  1829.           goto free_and_exit;
  1830.  
  1831.       } /* end for */
  1832.  
  1833.       if(broke_oplock)
  1834.       {
  1835.         free((char *)old_shares);
  1836.         num_share_modes = get_share_modes(cnum, token, dev, inode, &old_shares);
  1837.       }
  1838.     } while(broke_oplock);
  1839.   }
  1840.  
  1841.   /* XXXX exactly what share mode combinations should be allowed for
  1842.      deleting/renaming? */
  1843.   /* If we got here then either there were no share modes or
  1844.      all share modes were DENY_DOS and the pid == getpid() */
  1845.   ret = True;
  1846.  
  1847. free_and_exit:
  1848.  
  1849.   unlock_share_entry(cnum, dev, inode, token);
  1850.   if(old_shares != NULL)
  1851.     free((char *)old_shares);
  1852.   return(ret);
  1853. }
  1854.  
  1855. /****************************************************************************
  1856.   C. Hoch 11/22/95
  1857.   Helper for open_file_shared. 
  1858.   Truncate a file after checking locking; close file if locked.
  1859.   **************************************************************************/
  1860. static void truncate_unless_locked(int fnum, int cnum, int token, 
  1861.                    BOOL *share_locked)
  1862. {
  1863.   if (Files[fnum].can_write){
  1864.     if (is_locked(fnum,cnum,0x3FFFFFFF,0,F_WRLCK)){
  1865.       /* If share modes are in force for this connection we
  1866.          have the share entry locked. Unlock it before closing. */
  1867.       if (*share_locked && lp_share_modes(SNUM(cnum)))
  1868.         unlock_share_entry( cnum, Files[fnum].fd_ptr->dev, 
  1869.                             Files[fnum].fd_ptr->inode, token);
  1870.       close_file(fnum,False);   
  1871.       /* Share mode no longer locked. */
  1872.       *share_locked = False;
  1873.       errno = EACCES;
  1874.       unix_ERR_class = ERRDOS;
  1875.       unix_ERR_code = ERRlock;
  1876.     }
  1877.     else
  1878.       ftruncate(Files[fnum].fd_ptr->fd,0); 
  1879.   }
  1880. }
  1881.  
  1882. /****************************************************************************
  1883. check if we can open a file with a share mode
  1884. ****************************************************************************/
  1885. int check_share_mode( share_mode_entry *share, int deny_mode, char *fname,
  1886.                       BOOL fcbopen, int *flags)
  1887. {
  1888.   int old_open_mode = share->share_mode &0xF;
  1889.   int old_deny_mode = (share->share_mode >>4)&7;
  1890.  
  1891.   if (old_deny_mode > 4 || old_open_mode > 2)
  1892.   {
  1893.     DEBUG(0,("Invalid share mode found (%d,%d,%d) on file %s\n",
  1894.                deny_mode,old_deny_mode,old_open_mode,fname));
  1895.     return False;
  1896.   }
  1897.  
  1898.   {
  1899.     int access_allowed = access_table(deny_mode,old_deny_mode,old_open_mode,
  1900.                                 share->pid,fname);
  1901.  
  1902.     if ((access_allowed == AFAIL) ||
  1903.         (!fcbopen && (access_allowed == AREAD && *flags == O_RDWR)) ||
  1904.         (access_allowed == AREAD && *flags == O_WRONLY) ||
  1905.         (access_allowed == AWRITE && *flags == O_RDONLY))
  1906.     {
  1907.       DEBUG(2,("Share violation on file (%d,%d,%d,%d,%s,fcbopen = %d, flags = %d) = %d\n",
  1908.                 deny_mode,old_deny_mode,old_open_mode,
  1909.                 share->pid,fname, fcbopen, *flags, access_allowed));
  1910.       return False;
  1911.     }
  1912.  
  1913.     if (access_allowed == AREAD)
  1914.       *flags = O_RDONLY;
  1915.  
  1916.     if (access_allowed == AWRITE)
  1917.       *flags = O_WRONLY;
  1918.  
  1919.   }
  1920.   return True;
  1921. }
  1922.  
  1923. /****************************************************************************
  1924. open a file with a share mode
  1925. ****************************************************************************/
  1926. void open_file_shared(int fnum,int cnum,char *fname,int share_mode,int ofun,
  1927.               int mode,int oplock_request, int *Access,int *action)
  1928. {
  1929.   files_struct *fs_p = &Files[fnum];
  1930.   int flags=0;
  1931.   int flags2=0;
  1932.   int deny_mode = (share_mode>>4)&7;
  1933.   struct stat sbuf;
  1934.   BOOL file_existed = file_exist(fname,&sbuf);
  1935.   BOOL share_locked = False;
  1936.   BOOL fcbopen = False;
  1937.   int token;
  1938.   uint32 dev = 0;
  1939.   uint32 inode = 0;
  1940.   int num_share_modes = 0;
  1941.  
  1942.   fs_p->open = False;
  1943.   fs_p->fd_ptr = 0;
  1944.  
  1945.   /* this is for OS/2 EAs - try and say we don't support them */
  1946.   if (strstr(fname,".+,;=[].")) 
  1947.   {
  1948.     unix_ERR_class = ERRDOS;
  1949.     /* OS/2 Workplace shell fix may be main code stream in a later release. */ 
  1950. #if 1 /* OS2_WPS_FIX - Recent versions of OS/2 need this. */
  1951.     unix_ERR_code = ERRcannotopen;
  1952. #else /* OS2_WPS_FIX */
  1953.     unix_ERR_code = ERROR_EAS_NOT_SUPPORTED;
  1954. #endif /* OS2_WPS_FIX */
  1955.  
  1956.     return;
  1957.   }
  1958.  
  1959.   if ((ofun & 0x3) == 0 && file_existed)  
  1960.   {
  1961.     errno = EEXIST;
  1962.     return;
  1963.   }
  1964.       
  1965.   if (ofun & 0x10)
  1966.     flags2 |= O_CREAT;
  1967.   if ((ofun & 0x3) == 2)
  1968.     flags2 |= O_TRUNC;
  1969.  
  1970.   /* note that we ignore the append flag as 
  1971.      append does not mean the same thing under dos and unix */
  1972.  
  1973.   switch (share_mode&0xF)
  1974.   {
  1975.     case 1: 
  1976.       flags = O_WRONLY; 
  1977.       break;
  1978.     case 0xF: 
  1979.       fcbopen = True;
  1980.       flags = O_RDWR; 
  1981.       break;
  1982.     case 2: 
  1983.       flags = O_RDWR; 
  1984.       break;
  1985.     default:
  1986.       flags = O_RDONLY;
  1987.       break;
  1988.   }
  1989.   
  1990.   if (flags != O_RDONLY && file_existed && 
  1991.       (!CAN_WRITE(cnum) || IS_DOS_READONLY(dos_mode(cnum,fname,&sbuf)))) 
  1992.   {
  1993.     if (!fcbopen) 
  1994.     {
  1995.       errno = EACCES;
  1996.       return;
  1997.     }
  1998.     flags = O_RDONLY;
  1999.   }
  2000.  
  2001.   if (deny_mode > DENY_NONE && deny_mode!=DENY_FCB) 
  2002.   {
  2003.     DEBUG(2,("Invalid deny mode %d on file %s\n",deny_mode,fname));
  2004.     errno = EINVAL;
  2005.     return;
  2006.   }
  2007.  
  2008.   if (deny_mode == DENY_FCB) deny_mode = DENY_DOS;
  2009.  
  2010.   if (lp_share_modes(SNUM(cnum))) 
  2011.   {
  2012.     int i;
  2013.     share_mode_entry *old_shares = 0;
  2014.  
  2015.     if (file_existed)
  2016.     {
  2017.       dev = (uint32)sbuf.st_dev;
  2018.       inode = (uint32)sbuf.st_ino;
  2019.       lock_share_entry(cnum, dev, inode, &token);
  2020.       share_locked = True;
  2021.       num_share_modes = get_share_modes(cnum, token, dev, inode, &old_shares);
  2022.     }
  2023.  
  2024.     /*
  2025.      * Check if the share modes will give us access.
  2026.      */
  2027.  
  2028.     if(share_locked && (num_share_modes != 0))
  2029.     {
  2030.       BOOL broke_oplock;
  2031.  
  2032.       do
  2033.       {
  2034.  
  2035.         broke_oplock = False;
  2036.         for(i = 0; i < num_share_modes; i++)
  2037.         {
  2038.           share_mode_entry *share_entry = &old_shares[i];
  2039.  
  2040.           /* 
  2041.            * By observation of NetBench, oplocks are broken *before* share
  2042.            * modes are checked. This allows a file to be closed by the client
  2043.            * if the share mode would deny access and the client has an oplock. 
  2044.            * Check if someone has an oplock on this file. If so we must break 
  2045.            * it before continuing. 
  2046.            */
  2047.           if(share_entry->op_type & (EXCLUSIVE_OPLOCK|BATCH_OPLOCK))
  2048.           {
  2049.  
  2050.             DEBUG(5,("open_file_shared: breaking oplock (%x) on file %s, \
  2051. dev = %x, inode = %x\n", share_entry->op_type, fname, dev, inode));
  2052.  
  2053.             /* Oplock break.... */
  2054.             unlock_share_entry(cnum, dev, inode, token);
  2055.             if(request_oplock_break(share_entry, dev, inode) == False)
  2056.             {
  2057.               free((char *)old_shares);
  2058.               DEBUG(0,("open_file_shared: FAILED when breaking oplock (%x) on file %s, \
  2059. dev = %x, inode = %x\n", old_shares[i].op_type, fname, dev, inode));
  2060.               errno = EACCES;
  2061.               unix_ERR_class = ERRDOS;
  2062.               unix_ERR_code = ERRbadshare;
  2063.               return;
  2064.             }
  2065.             lock_share_entry(cnum, dev, inode, &token);
  2066.             broke_oplock = True;
  2067.             break;
  2068.           }
  2069.  
  2070.           /* someone else has a share lock on it, check to see 
  2071.              if we can too */
  2072.           if(check_share_mode(share_entry, deny_mode, fname, fcbopen, &flags) == False)
  2073.           {
  2074.             free((char *)old_shares);
  2075.             unlock_share_entry(cnum, dev, inode, token);
  2076.             errno = EACCES;
  2077.             unix_ERR_class = ERRDOS;
  2078.             unix_ERR_code = ERRbadshare;
  2079.             return;
  2080.           }
  2081.  
  2082.         } /* end for */
  2083.  
  2084.         if(broke_oplock)
  2085.         {
  2086.           free((char *)old_shares);
  2087.           num_share_modes = get_share_modes(cnum, token, dev, inode, &old_shares);
  2088.         }
  2089.       } while(broke_oplock);
  2090.     }
  2091.  
  2092.     if(old_shares != 0)
  2093.       free((char *)old_shares);
  2094.   }
  2095.  
  2096.   DEBUG(4,("calling open_file with flags=0x%X flags2=0x%X mode=0%o\n",
  2097.        flags,flags2,mode));
  2098.  
  2099.   open_file(fnum,cnum,fname,flags|(flags2&~(O_TRUNC)),mode,file_existed ? &sbuf : 0);
  2100.   if (!fs_p->open && flags==O_RDWR && errno!=ENOENT && fcbopen) 
  2101.   {
  2102.     flags = O_RDONLY;
  2103.     open_file(fnum,cnum,fname,flags,mode,file_existed ? &sbuf : 0 );
  2104.   }
  2105.  
  2106.   if (fs_p->open) 
  2107.   {
  2108.     int open_mode=0;
  2109.  
  2110.     if((share_locked == False) && lp_share_modes(SNUM(cnum)))
  2111.     {
  2112.       /* We created the file - thus we must now lock the share entry before creating it. */
  2113.       dev = fs_p->fd_ptr->dev;
  2114.       inode = fs_p->fd_ptr->inode;
  2115.       lock_share_entry(cnum, dev, inode, &token);
  2116.       share_locked = True;
  2117.     }
  2118.  
  2119.     switch (flags) 
  2120.     {
  2121.       case O_RDONLY:
  2122.         open_mode = 0;
  2123.         break;
  2124.       case O_RDWR:
  2125.         open_mode = 2;
  2126.         break;
  2127.       case O_WRONLY:
  2128.         open_mode = 1;
  2129.         break;
  2130.     }
  2131.  
  2132.     fs_p->share_mode = (deny_mode<<4) | open_mode;
  2133.  
  2134.     if (Access)
  2135.       (*Access) = open_mode;
  2136.  
  2137.     if (action) 
  2138.     {
  2139.       if (file_existed && !(flags2 & O_TRUNC)) *action = 1;
  2140.       if (!file_existed) *action = 2;
  2141.       if (file_existed && (flags2 & O_TRUNC)) *action = 3;
  2142.     }
  2143.     /* We must create the share mode entry before truncate as
  2144.        truncate can fail due to locking and have to close the
  2145.        file (which expects the share_mode_entry to be there).
  2146.      */
  2147.     if (lp_share_modes(SNUM(cnum)))
  2148.     {
  2149.       uint16 port = 0;
  2150.       /* JRA. Currently this only services Exlcusive and batch
  2151.          oplocks (no other opens on this file). This needs to
  2152.          be extended to level II oplocks (multiple reader
  2153.          oplocks). */
  2154.  
  2155.       if(oplock_request && (num_share_modes == 0) && lp_oplocks(SNUM(cnum)) && 
  2156.           !IS_VETO_OPLOCK_PATH(cnum,fname))
  2157.       {
  2158.         fs_p->granted_oplock = True;
  2159.         fs_p->sent_oplock_break = False;
  2160.         global_oplocks_open++;
  2161.         port = oplock_port;
  2162.  
  2163.         DEBUG(5,("open_file_shared: granted oplock (%x) on file %s, \
  2164. dev = %x, inode = %x\n", oplock_request, fname, dev, inode));
  2165.  
  2166.       }
  2167.       else
  2168.       {
  2169.         port = 0;
  2170.         oplock_request = 0;
  2171.       }
  2172.       set_share_mode(token, fnum, port, oplock_request);
  2173.     }
  2174.  
  2175.     if ((flags2&O_TRUNC) && file_existed)
  2176.       truncate_unless_locked(fnum,cnum,token,&share_locked);
  2177.   }
  2178.  
  2179.   if (share_locked && lp_share_modes(SNUM(cnum)))
  2180.     unlock_share_entry( cnum, dev, inode, token);
  2181. }
  2182.  
  2183. /****************************************************************************
  2184. seek a file. Try to avoid the seek if possible
  2185. ****************************************************************************/
  2186. int seek_file(int fnum,uint32 pos)
  2187. {
  2188.   uint32 offset = 0;
  2189.   if (Files[fnum].print_file && POSTSCRIPT(Files[fnum].cnum))
  2190.     offset = 3;
  2191.  
  2192.   Files[fnum].pos = (int)(lseek(Files[fnum].fd_ptr->fd,pos+offset,SEEK_SET) 
  2193.                                   - offset);
  2194.   return(Files[fnum].pos);
  2195. }
  2196.  
  2197. /****************************************************************************
  2198. read from a file
  2199. ****************************************************************************/
  2200. int read_file(int fnum,char *data,uint32 pos,int n)
  2201. {
  2202.   int ret=0,readret;
  2203.  
  2204. #if USE_READ_PREDICTION
  2205.   if (!Files[fnum].can_write)
  2206.     {
  2207.       ret = read_predict(Files[fnum].fd_ptr->fd,pos,data,NULL,n);
  2208.  
  2209.       data += ret;
  2210.       n -= ret;
  2211.       pos += ret;
  2212.     }
  2213. #endif
  2214.  
  2215. #if USE_MMAP
  2216.   if (Files[fnum].mmap_ptr)
  2217.     {
  2218.       int num = (Files[fnum].mmap_size > pos) ? (Files[fnum].mmap_size - pos) : -1;
  2219.       num = MIN(n,num);
  2220.       if (num > 0)
  2221.     {
  2222.       memcpy(data,Files[fnum].mmap_ptr+pos,num);
  2223.       data += num;
  2224.       pos += num;
  2225.       n -= num;
  2226.       ret += num;
  2227.     }
  2228.     }
  2229. #endif
  2230.  
  2231.   if (n <= 0)
  2232.     return(ret);
  2233.  
  2234.   if (seek_file(fnum,pos) != pos)
  2235.     {
  2236.       DEBUG(3,("Failed to seek to %d\n",pos));
  2237.       return(ret);
  2238.     }
  2239.   
  2240.   if (n > 0) {
  2241.     readret = read(Files[fnum].fd_ptr->fd,data,n);
  2242.     if (readret > 0) ret += readret;
  2243.   }
  2244.  
  2245.   return(ret);
  2246. }
  2247.  
  2248.  
  2249. /****************************************************************************
  2250. write to a file
  2251. ****************************************************************************/
  2252. int write_file(int fnum,char *data,int n)
  2253. {
  2254.   if (!Files[fnum].can_write) {
  2255.     errno = EPERM;
  2256.     return(0);
  2257.   }
  2258.  
  2259.   if (!Files[fnum].modified) {
  2260.     struct stat st;
  2261.     Files[fnum].modified = True;
  2262.     if (fstat(Files[fnum].fd_ptr->fd,&st) == 0) {
  2263.       int dosmode = dos_mode(Files[fnum].cnum,Files[fnum].name,&st);
  2264.       if (MAP_ARCHIVE(Files[fnum].cnum) && !IS_DOS_ARCHIVE(dosmode)) {    
  2265.     dos_chmod(Files[fnum].cnum,Files[fnum].name,dosmode | aARCH,&st);
  2266.       }
  2267.     }  
  2268.   }
  2269.  
  2270.   return(write_data(Files[fnum].fd_ptr->fd,data,n));
  2271. }
  2272.  
  2273.  
  2274. /****************************************************************************
  2275. load parameters specific to a connection/service
  2276. ****************************************************************************/
  2277. BOOL become_service(int cnum,BOOL do_chdir)
  2278. {
  2279.   extern char magic_char;
  2280.   static int last_cnum = -1;
  2281.   int snum;
  2282.  
  2283.   if (!OPEN_CNUM(cnum))
  2284.     {
  2285.       last_cnum = -1;
  2286.       return(False);
  2287.     }
  2288.  
  2289.   Connections[cnum].lastused = smb_last_time;
  2290.  
  2291.   snum = SNUM(cnum);
  2292.   
  2293.   if (do_chdir &&
  2294.       ChDir(Connections[cnum].connectpath) != 0 &&
  2295.       ChDir(Connections[cnum].origpath) != 0)
  2296.     {
  2297.       DEBUG(0,("%s chdir (%s) failed cnum=%d\n",timestring(),
  2298.         Connections[cnum].connectpath,cnum));     
  2299.       return(False);
  2300.     }
  2301.  
  2302.   if (cnum == last_cnum)
  2303.     return(True);
  2304.  
  2305.   last_cnum = cnum;
  2306.  
  2307.   case_default = lp_defaultcase(snum);
  2308.   case_preserve = lp_preservecase(snum);
  2309.   short_case_preserve = lp_shortpreservecase(snum);
  2310.   case_mangle = lp_casemangle(snum);
  2311.   case_sensitive = lp_casesensitive(snum);
  2312.   magic_char = lp_magicchar(snum);
  2313.   use_mangled_map = (*lp_mangled_map(snum) ? True:False);
  2314.   return(True);
  2315. }
  2316.  
  2317.  
  2318. /****************************************************************************
  2319.   find a service entry
  2320. ****************************************************************************/
  2321. int find_service(char *service)
  2322. {
  2323.    int iService;
  2324.  
  2325.    string_sub(service,"\\","/");
  2326.  
  2327.    iService = lp_servicenumber(service);
  2328.  
  2329.    /* now handle the special case of a home directory */
  2330.    if (iService < 0)
  2331.    {
  2332.       char *phome_dir = get_home_dir(service);
  2333.  
  2334.       if(!phome_dir)
  2335.       {
  2336.         /*
  2337.          * Try mapping the servicename, it may
  2338.          * be a Windows to unix mapped user name.
  2339.          */
  2340.         if(map_username(service))
  2341.           phome_dir = get_home_dir(service);
  2342.       }
  2343.  
  2344.       DEBUG(3,("checking for home directory %s gave %s\n",service,
  2345.         phome_dir?phome_dir:"(NULL)"));
  2346.       if (phome_dir)
  2347.       {   
  2348.      int iHomeService;
  2349.      if ((iHomeService = lp_servicenumber(HOMES_NAME)) >= 0)
  2350.      {
  2351.         lp_add_home(service,iHomeService,phome_dir);
  2352.         iService = lp_servicenumber(service);
  2353.      }
  2354.       }
  2355.    }
  2356.  
  2357.    /* If we still don't have a service, attempt to add it as a printer. */
  2358.    if (iService < 0)
  2359.    {
  2360.       int iPrinterService;
  2361.  
  2362.       if ((iPrinterService = lp_servicenumber(PRINTERS_NAME)) >= 0)
  2363.       {
  2364.          char *pszTemp;
  2365.  
  2366.          DEBUG(3,("checking whether %s is a valid printer name...\n", service));
  2367.          pszTemp = PRINTCAP;
  2368.          if ((pszTemp != NULL) && pcap_printername_ok(service, pszTemp))
  2369.          {
  2370.             DEBUG(3,("%s is a valid printer name\n", service));
  2371.             DEBUG(3,("adding %s as a printer service\n", service));
  2372.             lp_add_printer(service,iPrinterService);
  2373.             iService = lp_servicenumber(service);
  2374.             if (iService < 0)
  2375.                DEBUG(0,("failed to add %s as a printer service!\n", service));
  2376.          }
  2377.          else
  2378.             DEBUG(3,("%s is not a valid printer name\n", service));
  2379.       }
  2380.    }
  2381.  
  2382.    /* just possibly it's a default service? */
  2383.    if (iService < 0) 
  2384.      {
  2385.        char *pdefservice = lp_defaultservice();
  2386.        if (pdefservice && *pdefservice && !strequal(pdefservice,service)) {
  2387.          /*
  2388.           * We need to do a local copy here as lp_defaultservice() 
  2389.           * returns one of the rotating lp_string buffers that
  2390.           * could get overwritten by the recursive find_service() call
  2391.           * below. Fix from Josef Hinteregger <joehtg@joehtg.co.at>.
  2392.           */
  2393.          pstring defservice;
  2394.          pstrcpy(defservice, pdefservice);
  2395.      iService = find_service(defservice);
  2396.      if (iService >= 0) {
  2397.        string_sub(service,"_","/");
  2398.        iService = lp_add_service(service,iService);
  2399.      }
  2400.        }
  2401.      }
  2402.  
  2403.    if (iService >= 0)
  2404.       if (!VALID_SNUM(iService))
  2405.       {
  2406.          DEBUG(0,("Invalid snum %d for %s\n",iService,service));
  2407.      iService = -1;
  2408.       }
  2409.  
  2410.    if (iService < 0)
  2411.       DEBUG(3,("find_service() failed to find service %s\n", service));
  2412.  
  2413.    return (iService);
  2414. }
  2415.  
  2416.  
  2417. /****************************************************************************
  2418.   create an error packet from a cached error.
  2419. ****************************************************************************/
  2420. int cached_error_packet(char *inbuf,char *outbuf,int fnum,int line)
  2421. {
  2422.   write_bmpx_struct *wbmpx = Files[fnum].wbmpx_ptr;
  2423.  
  2424.   int32 eclass = wbmpx->wr_errclass;
  2425.   int32 err = wbmpx->wr_error;
  2426.  
  2427.   /* We can now delete the auxiliary struct */
  2428.   free((char *)wbmpx);
  2429.   Files[fnum].wbmpx_ptr = NULL;
  2430.   return error_packet(inbuf,outbuf,eclass,err,line);
  2431. }
  2432.  
  2433.  
  2434. struct
  2435. {
  2436.   int unixerror;
  2437.   int smbclass;
  2438.   int smbcode;
  2439. } unix_smb_errmap[] =
  2440. {
  2441.   {EPERM,ERRDOS,ERRnoaccess},
  2442.   {EACCES,ERRDOS,ERRnoaccess},
  2443.   {ENOENT,ERRDOS,ERRbadfile},
  2444.   {ENOTDIR,ERRDOS,ERRbadpath},
  2445.   {EIO,ERRHRD,ERRgeneral},
  2446.   {EBADF,ERRSRV,ERRsrverror},
  2447.   {EINVAL,ERRSRV,ERRsrverror},
  2448.   {EEXIST,ERRDOS,ERRfilexists},
  2449.   {ENFILE,ERRDOS,ERRnofids},
  2450.   {EMFILE,ERRDOS,ERRnofids},
  2451.   {ENOSPC,ERRHRD,ERRdiskfull},
  2452. #ifdef EDQUOT
  2453.   {EDQUOT,ERRHRD,ERRdiskfull},
  2454. #endif
  2455. #ifdef ENOTEMPTY
  2456.   {ENOTEMPTY,ERRDOS,ERRnoaccess},
  2457. #endif
  2458. #ifdef EXDEV
  2459.   {EXDEV,ERRDOS,ERRdiffdevice},
  2460. #endif
  2461.   {EROFS,ERRHRD,ERRnowrite},
  2462.   {0,0,0}
  2463. };
  2464.  
  2465. /****************************************************************************
  2466.   create an error packet from errno
  2467. ****************************************************************************/
  2468. int unix_error_packet(char *inbuf,char *outbuf,int def_class,uint32 def_code,int line)
  2469. {
  2470.   int eclass=def_class;
  2471.   int ecode=def_code;
  2472.   int i=0;
  2473.  
  2474.   if (unix_ERR_class != SMB_SUCCESS)
  2475.     {
  2476.       eclass = unix_ERR_class;
  2477.       ecode = unix_ERR_code;
  2478.       unix_ERR_class = SMB_SUCCESS;
  2479.       unix_ERR_code = 0;
  2480.     }
  2481.   else
  2482.     {
  2483.       while (unix_smb_errmap[i].smbclass != 0)
  2484.       {
  2485.         if (unix_smb_errmap[i].unixerror == errno)
  2486.         {
  2487.           eclass = unix_smb_errmap[i].smbclass;
  2488.           ecode = unix_smb_errmap[i].smbcode;
  2489.           break;
  2490.         }
  2491.       i++;
  2492.       }
  2493.     }
  2494.  
  2495.   return(error_packet(inbuf,outbuf,eclass,ecode,line));
  2496. }
  2497.  
  2498.  
  2499. /****************************************************************************
  2500.   create an error packet. Normally called using the ERROR() macro
  2501. ****************************************************************************/
  2502. int error_packet(char *inbuf,char *outbuf,int error_class,uint32 error_code,int line)
  2503. {
  2504.   int outsize = set_message(outbuf,0,0,True);
  2505.   int cmd;
  2506.   cmd = CVAL(inbuf,smb_com);
  2507.   
  2508.   CVAL(outbuf,smb_rcls) = error_class;
  2509.   SSVAL(outbuf,smb_err,error_code);  
  2510.   
  2511.   DEBUG(3,("%s error packet at line %d cmd=%d (%s) eclass=%d ecode=%d\n",
  2512.        timestring(),
  2513.        line,
  2514.        (int)CVAL(inbuf,smb_com),
  2515.        smb_fn_name(CVAL(inbuf,smb_com)),
  2516.        error_class,
  2517.        error_code));
  2518.  
  2519.   if (errno != 0)
  2520.     DEBUG(3,("error string = %s\n",strerror(errno)));
  2521.   
  2522.   return(outsize);
  2523. }
  2524.  
  2525.  
  2526. #ifndef SIGCLD_IGNORE
  2527. /****************************************************************************
  2528. this prevents zombie child processes
  2529. ****************************************************************************/
  2530. static int sig_cld(void)
  2531. {
  2532.   static int depth = 0;
  2533.   if (depth != 0)
  2534.     {
  2535.       DEBUG(0,("ERROR: Recursion in sig_cld? Perhaps you need `#define USE_WAITPID'?\n"));
  2536.       depth=0;
  2537.       return(0);
  2538.     }
  2539.   depth++;
  2540.  
  2541.   BlockSignals(True,SIGCLD);
  2542.   DEBUG(5,("got SIGCLD\n"));
  2543.  
  2544. #ifdef USE_WAITPID
  2545.   while (sys_waitpid((pid_t)-1,(int *)NULL, WNOHANG) > 0);
  2546. #endif
  2547.  
  2548.   /* Stop zombies */
  2549.   /* Stevens, Adv. Unix Prog. says that on system V you must call
  2550.      wait before reinstalling the signal handler, because the kernel
  2551.      calls the handler from within the signal-call when there is a
  2552.      child that has exited. This would lead to an infinite recursion
  2553.      if done vice versa. */
  2554.         
  2555. #ifndef DONT_REINSTALL_SIG
  2556. #ifdef SIGCLD_IGNORE
  2557.   signal(SIGCLD, SIG_IGN);  
  2558. #else
  2559.   signal(SIGCLD, SIGNAL_CAST sig_cld);
  2560. #endif
  2561. #endif
  2562.  
  2563. #ifndef USE_WAITPID
  2564.   while (wait3(WAIT3_CAST1 NULL, WNOHANG, WAIT3_CAST2 NULL) > 0);
  2565. #endif
  2566.   depth--;
  2567.   BlockSignals(False,SIGCLD);
  2568.   return 0;
  2569. }
  2570. #endif
  2571.  
  2572. /****************************************************************************
  2573.   this is called when the client exits abruptly
  2574.   **************************************************************************/
  2575. static int sig_pipe(void)
  2576. {
  2577.     struct cli_state *cli;
  2578.     BlockSignals(True,SIGPIPE);
  2579.  
  2580.     if ((cli = server_client()) && cli->initialised) {
  2581.         DEBUG(3,("lost connection to password server\n"));
  2582.         cli_shutdown(cli);
  2583. #ifndef DONT_REINSTALL_SIG
  2584.         signal(SIGPIPE, SIGNAL_CAST sig_pipe);
  2585. #endif
  2586.         BlockSignals(False,SIGPIPE);
  2587.         return 0;
  2588.     }
  2589.  
  2590.     exit_server("Got sigpipe\n");
  2591.     return(0);
  2592. }
  2593.  
  2594. /****************************************************************************
  2595.   open the socket communication
  2596. ****************************************************************************/
  2597. static BOOL open_sockets(BOOL is_daemon,int port)
  2598. {
  2599.   extern int Client;
  2600.  
  2601.   if (is_daemon)
  2602.   {
  2603.     int num_interfaces = iface_count();
  2604.     int fd_listenset[FD_SETSIZE];
  2605.     fd_set listen_set;
  2606.     int s;
  2607.     int i;
  2608.  
  2609.     /* Stop zombies */
  2610. #ifdef SIGCLD_IGNORE
  2611.     signal(SIGCLD, SIG_IGN);
  2612. #else
  2613.     signal(SIGCLD, SIGNAL_CAST sig_cld);
  2614. #endif
  2615.  
  2616.     if(atexit_set == 0)
  2617.       atexit(killkids);
  2618.  
  2619.     FD_ZERO(&listen_set);
  2620.  
  2621.     if(lp_interfaces() && lp_bind_interfaces_only())
  2622.     {
  2623.        /* We have been given an interfaces line, and been 
  2624.           told to only bind to those interfaces. Create a
  2625.           socket per interface and bind to only these.
  2626.         */
  2627.  
  2628.       if(num_interfaces > FD_SETSIZE)
  2629.       {
  2630.         DEBUG(0,("open_sockets: Too many interfaces specified to bind to. Number was %d \
  2631. max can be %d\n", num_interfaces, FD_SETSIZE));
  2632.         return False;
  2633.       }
  2634.  
  2635.       /* Now open a listen socket for each of the interfaces. */
  2636.       for(i = 0; i < num_interfaces; i++)
  2637.       {
  2638.         struct in_addr *ifip = iface_n_ip(i);
  2639.  
  2640.         if(ifip == NULL)
  2641.         {
  2642.           DEBUG(0,("open_sockets: interface %d has NULL IP address !\n", i));
  2643.           continue;
  2644.         }
  2645.         s = fd_listenset[i] = open_socket_in(SOCK_STREAM, port, 0, ifip->s_addr);
  2646.         if(s == -1)
  2647.           return False;
  2648.         /* ready to listen */
  2649.         if (listen(s, 5) == -1) 
  2650.         {
  2651.           DEBUG(0,("listen: %s\n",strerror(errno)));
  2652.           close(s);
  2653.           return False;
  2654.         }
  2655.         FD_SET(s,&listen_set);
  2656.       }
  2657.     }
  2658.     else
  2659.     {
  2660.       /* Just bind to 0.0.0.0 - accept connections from anywhere. */
  2661.       num_interfaces = 1;
  2662.  
  2663.       /* open an incoming socket */
  2664.       s = open_socket_in(SOCK_STREAM, port, 0,interpret_addr(lp_socket_address()));
  2665.       if (s == -1)
  2666.         return(False);
  2667.  
  2668.       /* ready to listen */
  2669.       if (listen(s, 5) == -1) 
  2670.       {
  2671.         DEBUG(0,("open_sockets: listen: %s\n",strerror(errno)));
  2672.         close(s);
  2673.         return False;
  2674.       }
  2675.  
  2676.       fd_listenset[0] = s;
  2677.       FD_SET(s,&listen_set);
  2678.     }      
  2679.  
  2680.     /* now accept incoming connections - forking a new process
  2681.        for each incoming connection */
  2682.     DEBUG(2,("waiting for a connection\n"));
  2683.     while (1)
  2684.     {
  2685.       fd_set lfds;
  2686.       int num;
  2687.  
  2688.       memcpy((char *)&lfds, (char *)&listen_set, sizeof(listen_set));
  2689.  
  2690.       num = sys_select(&lfds,NULL);
  2691.  
  2692.       if (num == -1 && errno == EINTR)
  2693.         continue;
  2694.  
  2695.       /* Find the sockets that are read-ready - accept on these. */
  2696.       for( ; num > 0; num--)
  2697.       {
  2698.         struct sockaddr addr;
  2699.         int in_addrlen = sizeof(addr);
  2700.  
  2701.         s = -1;
  2702.         for(i = 0; i < num_interfaces; i++)
  2703.         {
  2704.           if(FD_ISSET(fd_listenset[i],&lfds))
  2705.           {
  2706.             s = fd_listenset[i];
  2707.             /* Clear this so we don't look at it again. */
  2708.             FD_CLR(fd_listenset[i],&lfds);
  2709.             break;
  2710.           }
  2711.         }
  2712.  
  2713.         Client = accept(s,&addr,&in_addrlen);
  2714.  
  2715.         if (Client == -1 && errno == EINTR)
  2716.           continue;
  2717.  
  2718.         if (Client == -1)
  2719.         {
  2720.           DEBUG(0,("open_sockets: accept: %s\n",strerror(errno)));
  2721.           continue;
  2722.         }
  2723.  
  2724. #ifdef NO_FORK_DEBUG
  2725. #ifndef NO_SIGNAL_TEST
  2726.         signal(SIGPIPE, SIGNAL_CAST sig_pipe);
  2727.         signal(SIGCLD, SIGNAL_CAST SIG_DFL);
  2728. #endif /* NO_SIGNAL_TEST */
  2729.         return True;
  2730. #else /* NO_FORK_DEBUG */
  2731.         if (Client != -1 && fork()==0)
  2732.         {
  2733.           /* Child code ... */
  2734.  
  2735. #ifndef NO_SIGNAL_TEST
  2736.           signal(SIGPIPE, SIGNAL_CAST sig_pipe);
  2737.           signal(SIGCLD, SIGNAL_CAST SIG_DFL);
  2738. #endif /* NO_SIGNAL_TEST */
  2739.           /* close the listening socket(s) */
  2740.           for(i = 0; i < num_interfaces; i++)
  2741.             close(fd_listenset[i]);
  2742.  
  2743.           /* close our standard file descriptors */
  2744.           close_low_fds();
  2745.           am_parent = 0;
  2746.   
  2747.           set_socket_options(Client,"SO_KEEPALIVE");
  2748.           set_socket_options(Client,user_socket_options);
  2749.  
  2750.           /* Reset global variables in util.c so that
  2751.              client substitutions will be done correctly
  2752.              in the process.
  2753.            */
  2754.           reset_globals_after_fork();
  2755.           return True; 
  2756.         }
  2757.         close(Client); /* The parent doesn't need this socket */
  2758.  
  2759.         /*
  2760.          * Force parent to check log size after spawning child.
  2761.          * Fix from klausr@ITAP.Physik.Uni-Stuttgart.De.
  2762.          * The parent smbd will log to logserver.smb.
  2763.          * It writes only two messages for each child
  2764.          * started/finished. But each child writes, say, 50 messages also in
  2765.          * logserver.smb, begining with the debug_count of the parent, before the
  2766.          * child opens its own log file logserver.client. In a worst case
  2767.          * scenario the size of logserver.smb would be checked after about
  2768.          * 50*50=2500 messages (ca. 100kb).
  2769.          */
  2770.         force_check_log_size();
  2771.  
  2772. #endif /* NO_FORK_DEBUG */
  2773.       } /* end for num */
  2774.     } /* end while 1 */
  2775.   } /* end if is_daemon */
  2776.   else
  2777.   {
  2778.     /* Started from inetd. fd 0 is the socket. */
  2779.     /* We will abort gracefully when the client or remote system 
  2780.        goes away */
  2781. #ifndef NO_SIGNAL_TEST
  2782.     signal(SIGPIPE, SIGNAL_CAST sig_pipe);
  2783. #endif
  2784.     Client = dup(0);
  2785.  
  2786.     /* close our standard file descriptors */
  2787.     close_low_fds();
  2788.  
  2789.     set_socket_options(Client,"SO_KEEPALIVE");
  2790.     set_socket_options(Client,user_socket_options);
  2791.   }
  2792.  
  2793.   return True;
  2794. }
  2795.  
  2796. /****************************************************************************
  2797.   process an smb from the client - split out from the process() code so
  2798.   it can be used by the oplock break code.
  2799. ****************************************************************************/
  2800.  
  2801. static void process_smb(char *inbuf, char *outbuf)
  2802. {
  2803.   extern int Client;
  2804.   static int trans_num;
  2805.   int msg_type = CVAL(inbuf,0);
  2806.   int32 len = smb_len(inbuf);
  2807.   int nread = len + 4;
  2808.  
  2809.   if (trans_num == 0) {
  2810.       /* on the first packet, check the global hosts allow/ hosts
  2811.          deny parameters before doing any parsing of the packet
  2812.          passed to us by the client.  This prevents attacks on our
  2813.          parsing code from hosts not in the hosts allow list */
  2814.       if (!check_access(-1)) {
  2815.           /* send a negative session response "not listining on calling
  2816.            name" */
  2817.           static unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
  2818.           DEBUG(1,("%s Connection denied from %s\n",
  2819.                timestring(),client_addr()));
  2820.           send_smb(Client,(char *)buf);
  2821.           exit_server("connection denied");
  2822.       }
  2823.   }
  2824.  
  2825.   DEBUG(6,("got message type 0x%x of len 0x%x\n",msg_type,len));
  2826.   DEBUG(3,("%s Transaction %d of length %d\n",timestring(),trans_num,nread));
  2827.  
  2828. #ifdef WITH_VTP
  2829.   if(trans_num == 1 && VT_Check(inbuf)) 
  2830.   {
  2831.     VT_Process();
  2832.     return;
  2833.   }
  2834. #endif
  2835.  
  2836.   if (msg_type == 0)
  2837.     show_msg(inbuf);
  2838.   else if(msg_type == 0x85)
  2839.     return; /* Keepalive packet. */
  2840.  
  2841.   nread = construct_reply(inbuf,outbuf,nread,max_send);
  2842.       
  2843.   if(nread > 0) 
  2844.   {
  2845.     if (CVAL(outbuf,0) == 0)
  2846.       show_msg(outbuf);
  2847.     
  2848.     if (nread != smb_len(outbuf) + 4) 
  2849.     {
  2850.       DEBUG(0,("ERROR: Invalid message response size! %d %d\n",
  2851.                  nread, smb_len(outbuf)));
  2852.     }
  2853.     else
  2854.       send_smb(Client,outbuf);
  2855.   }
  2856.   trans_num++;
  2857. }
  2858.  
  2859. /****************************************************************************
  2860.   open the oplock IPC socket communication
  2861. ****************************************************************************/
  2862. static BOOL open_oplock_ipc(void)
  2863. {
  2864.   struct sockaddr_in sock_name;
  2865.   int len = sizeof(sock_name);
  2866.  
  2867.   DEBUG(3,("open_oplock_ipc: opening loopback UDP socket.\n"));
  2868.  
  2869.   /* Open a lookback UDP socket on a random port. */
  2870.   oplock_sock = open_socket_in(SOCK_DGRAM, 0, 0, htonl(INADDR_LOOPBACK));
  2871.   if (oplock_sock == -1)
  2872.   {
  2873.     DEBUG(0,("open_oplock_ipc: Failed to get local UDP socket for \
  2874. address %x. Error was %s\n", htonl(INADDR_LOOPBACK), strerror(errno)));
  2875.     oplock_port = 0;
  2876.     return(False);
  2877.   }
  2878.  
  2879.   /* Find out the transient UDP port we have been allocated. */
  2880.   if(getsockname(oplock_sock, (struct sockaddr *)&sock_name, &len)<0)
  2881.   {
  2882.     DEBUG(0,("open_oplock_ipc: Failed to get local UDP port. Error was %s\n",
  2883.             strerror(errno)));
  2884.     close(oplock_sock);
  2885.     oplock_sock = -1;
  2886.     oplock_port = 0;
  2887.     return False;
  2888.   }
  2889.   oplock_port = ntohs(sock_name.sin_port);
  2890.  
  2891.   DEBUG(3,("open_oplock ipc: pid = %d, oplock_port = %u\n", 
  2892.             getpid(), oplock_port));
  2893.  
  2894.   return True;
  2895. }
  2896.  
  2897. /****************************************************************************
  2898.   process an oplock break message.
  2899. ****************************************************************************/
  2900. static BOOL process_local_message(int sock, char *buffer, int buf_size)
  2901. {
  2902.   int32 msg_len;
  2903.   uint16 from_port;
  2904.   char *msg_start;
  2905.  
  2906.   msg_len = IVAL(buffer,UDP_CMD_LEN_OFFSET);
  2907.   from_port = SVAL(buffer,UDP_CMD_PORT_OFFSET);
  2908.  
  2909.   msg_start = &buffer[UDP_CMD_HEADER_LEN];
  2910.  
  2911.   DEBUG(5,("process_local_message: Got a message of length %d from port (%d)\n", 
  2912.             msg_len, from_port));
  2913.  
  2914.   /* Switch on message command - currently OPLOCK_BREAK_CMD is the
  2915.      only valid request. */
  2916.  
  2917.   switch(SVAL(msg_start,UDP_MESSAGE_CMD_OFFSET))
  2918.   {
  2919.     case OPLOCK_BREAK_CMD:
  2920.       /* Ensure that the msg length is correct. */
  2921.       if(msg_len != OPLOCK_BREAK_MSG_LEN)
  2922.       {
  2923.         DEBUG(0,("process_local_message: incorrect length for OPLOCK_BREAK_CMD (was %d, \
  2924. should be %d).\n", msg_len, OPLOCK_BREAK_MSG_LEN));
  2925.         return False;
  2926.       }
  2927.       {
  2928.         uint32 remotepid = IVAL(msg_start,OPLOCK_BREAK_PID_OFFSET);
  2929.         uint32 dev = IVAL(msg_start,OPLOCK_BREAK_DEV_OFFSET);
  2930.         uint32 inode = IVAL(msg_start, OPLOCK_BREAK_INODE_OFFSET);
  2931.         struct timeval tval;
  2932.         struct sockaddr_in toaddr;
  2933.  
  2934.         tval.tv_sec = IVAL(msg_start, OPLOCK_BREAK_SEC_OFFSET);
  2935.         tval.tv_usec = IVAL(msg_start, OPLOCK_BREAK_USEC_OFFSET);
  2936.  
  2937.         DEBUG(5,("process_local_message: oplock break request from \
  2938. pid %d, port %d, dev = %x, inode = %x\n", remotepid, from_port, dev, inode));
  2939.  
  2940.         /*
  2941.          * If we have no record of any currently open oplocks,
  2942.          * it's not an error, as a close command may have
  2943.          * just been issued on the file that was oplocked.
  2944.          * Just return success in this case.
  2945.          */
  2946.  
  2947.         if(global_oplocks_open != 0)
  2948.         {
  2949.           if(oplock_break(dev, inode, &tval) == False)
  2950.           {
  2951.             DEBUG(0,("process_local_message: oplock break failed - \
  2952. not returning udp message.\n"));
  2953.             return False;
  2954.           }
  2955.         }
  2956.         else
  2957.         {
  2958.           DEBUG(3,("process_local_message: oplock break requested with no outstanding \
  2959. oplocks. Returning success.\n"));
  2960.         }
  2961.  
  2962.         /* Send the message back after OR'ing in the 'REPLY' bit. */
  2963.         SSVAL(msg_start,UDP_MESSAGE_CMD_OFFSET,OPLOCK_BREAK_CMD | CMD_REPLY);
  2964.   
  2965.         bzero((char *)&toaddr,sizeof(toaddr));
  2966.         toaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
  2967.         toaddr.sin_port = htons(from_port);
  2968.         toaddr.sin_family = AF_INET;
  2969.  
  2970.         if(sendto( sock, msg_start, OPLOCK_BREAK_MSG_LEN, 0,
  2971.                 (struct sockaddr *)&toaddr, sizeof(toaddr)) < 0) 
  2972.         {
  2973.           DEBUG(0,("process_local_message: sendto process %d failed. Errno was %s\n",
  2974.                     remotepid, strerror(errno)));
  2975.           return False;
  2976.         }
  2977.  
  2978.         DEBUG(5,("process_local_message: oplock break reply sent to \
  2979. pid %d, port %d, for file dev = %x, inode = %x\n", remotepid, 
  2980.                 from_port, dev, inode));
  2981.  
  2982.       }
  2983.       break;
  2984.     /* 
  2985.      * Keep this as a debug case - eventually we can remove it.
  2986.      */
  2987.     case 0x8001:
  2988.       DEBUG(0,("process_local_message: Received unsolicited break \
  2989. reply - dumping info.\n"));
  2990.  
  2991.       if(msg_len != OPLOCK_BREAK_MSG_LEN)
  2992.       {
  2993.         DEBUG(0,("process_local_message: ubr: incorrect length for reply \
  2994. (was %d, should be %d).\n", msg_len, OPLOCK_BREAK_MSG_LEN));
  2995.         return False;
  2996.       }
  2997.  
  2998.       {
  2999.         uint32 remotepid = IVAL(msg_start,OPLOCK_BREAK_PID_OFFSET);
  3000.         uint32 dev = IVAL(msg_start,OPLOCK_BREAK_DEV_OFFSET);
  3001.         uint32 inode = IVAL(msg_start, OPLOCK_BREAK_INODE_OFFSET);
  3002.  
  3003.         DEBUG(0,("process_local_message: unsolicited oplock break reply from \
  3004. pid %d, port %d, dev = %x, inode = %x\n", remotepid, from_port, dev, inode));
  3005.  
  3006.        }
  3007.        return False;
  3008.  
  3009.     default:
  3010.       DEBUG(0,("process_local_message: unknown UDP message command code (%x) - ignoring.\n",
  3011.                 (unsigned int)SVAL(msg_start,0)));
  3012.       return False;
  3013.   }
  3014.   return True;
  3015. }
  3016.  
  3017. /****************************************************************************
  3018.  Process an oplock break directly.
  3019. ****************************************************************************/
  3020. BOOL oplock_break(uint32 dev, uint32 inode, struct timeval *tval)
  3021. {
  3022.   extern struct current_user current_user;
  3023.   extern int Client;
  3024.   char *inbuf = NULL;
  3025.   char *outbuf = NULL;
  3026.   files_struct *fsp = NULL;
  3027.   int fnum;
  3028.   time_t start_time;
  3029.   BOOL shutdown_server = False;
  3030.   int saved_cnum;
  3031.   int saved_vuid;
  3032.   pstring saved_dir; 
  3033.  
  3034.   DEBUG(3,("%s oplock_break: called for dev = %x, inode = %x. Current \
  3035. global_oplocks_open = %d\n", timestring(), dev, inode, global_oplocks_open));
  3036.  
  3037.   /* We need to search the file open table for the
  3038.      entry containing this dev and inode, and ensure
  3039.      we have an oplock on it. */
  3040.   for( fnum = 0; fnum < MAX_OPEN_FILES; fnum++)
  3041.   {
  3042.     if(OPEN_FNUM(fnum))
  3043.     {
  3044.       if((Files[fnum].fd_ptr->dev == dev) && (Files[fnum].fd_ptr->inode == inode) &&
  3045.          (Files[fnum].open_time.tv_sec == tval->tv_sec) && 
  3046.          (Files[fnum].open_time.tv_usec == tval->tv_usec)) {
  3047.           fsp = &Files[fnum];
  3048.           break;
  3049.       }
  3050.     }
  3051.   }
  3052.  
  3053.   if(fsp == NULL)
  3054.   {
  3055.     /* The file could have been closed in the meantime - return success. */
  3056.     DEBUG(0,("%s oplock_break: cannot find open file with dev = %x, inode = %x (fnum = %d) \
  3057. allowing break to succeed.\n", timestring(), dev, inode, fnum));
  3058.     return True;
  3059.   }
  3060.  
  3061.   /* Ensure we have an oplock on the file */
  3062.  
  3063.   /* There is a potential race condition in that an oplock could
  3064.      have been broken due to another udp request, and yet there are
  3065.      still oplock break messages being sent in the udp message
  3066.      queue for this file. So return true if we don't have an oplock,
  3067.      as we may have just freed it.
  3068.    */
  3069.  
  3070.   if(!fsp->granted_oplock)
  3071.   {
  3072.     DEBUG(0,("%s oplock_break: file %s (fnum = %d, dev = %x, inode = %x) has no oplock. Allowing break to succeed regardless.\n", timestring(), fsp->name, fnum, dev, inode));
  3073.     return True;
  3074.   }
  3075.  
  3076.   /* mark the oplock break as sent - we don't want to send twice! */
  3077.   if (fsp->sent_oplock_break)
  3078.   {
  3079.     DEBUG(0,("%s oplock_break: ERROR: oplock_break already sent for file %s (fnum = %d, dev = %x, inode = %x)\n", timestring(), fsp->name, fnum, dev, inode));
  3080.  
  3081.     /* We have to fail the open here as we cannot send another oplock break on this
  3082.        file whilst we are awaiting a response from the client - neither can we
  3083.        allow another open to succeed while we are waiting for the client. */
  3084.     return False;
  3085.   }
  3086.  
  3087.   /* Now comes the horrid part. We must send an oplock break to the client,
  3088.      and then process incoming messages until we get a close or oplock release.
  3089.      At this point we know we need a new inbuf/outbuf buffer pair.
  3090.      We cannot use these staticaly as we may recurse into here due to
  3091.      messages crossing on the wire.
  3092.    */
  3093.  
  3094.   if((inbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN))==NULL)
  3095.   {
  3096.     DEBUG(0,("oplock_break: malloc fail for input buffer.\n"));
  3097.     return False;
  3098.   }
  3099.  
  3100.   if((outbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN))==NULL)
  3101.   {
  3102.     DEBUG(0,("oplock_break: malloc fail for output buffer.\n"));
  3103.     free(inbuf);
  3104.     inbuf = NULL;
  3105.     return False;
  3106.   }
  3107.  
  3108.   /* Prepare the SMBlockingX message. */
  3109.   bzero(outbuf,smb_size);
  3110.   set_message(outbuf,8,0,True);
  3111.  
  3112.   SCVAL(outbuf,smb_com,SMBlockingX);
  3113.   SSVAL(outbuf,smb_tid,fsp->cnum);
  3114.   SSVAL(outbuf,smb_pid,0xFFFF);
  3115.   SSVAL(outbuf,smb_uid,0);
  3116.   SSVAL(outbuf,smb_mid,0xFFFF);
  3117.   SCVAL(outbuf,smb_vwv0,0xFF);
  3118.   SSVAL(outbuf,smb_vwv2,fnum);
  3119.   SCVAL(outbuf,smb_vwv3,LOCKING_ANDX_OPLOCK_RELEASE);
  3120.   /* Change this when we have level II oplocks. */
  3121.   SCVAL(outbuf,smb_vwv3+1,OPLOCKLEVEL_NONE);
  3122.  
  3123.   send_smb(Client, outbuf);
  3124.  
  3125.   /* Remember we just sent an oplock break on this file. */
  3126.   fsp->sent_oplock_break = True;
  3127.  
  3128.   /* We need this in case a readraw crosses on the wire. */
  3129.   global_oplock_break = True;
  3130.  
  3131.   /* Process incoming messages. */
  3132.  
  3133.   /* JRA - If we don't get a break from the client in OPLOCK_BREAK_TIMEOUT
  3134.      seconds we should just die.... */
  3135.  
  3136.   start_time = time(NULL);
  3137.  
  3138.   /*
  3139.    * Save the information we need to re-become the
  3140.    * user, then unbecome the user whilst we're doing this.
  3141.    */
  3142.   saved_cnum = fsp->cnum;
  3143.   saved_vuid = current_user.vuid;
  3144.   GetWd(saved_dir);
  3145.   unbecome_user();
  3146.  
  3147.   while(OPEN_FNUM(fnum) && fsp->granted_oplock)
  3148.   {
  3149.     if(receive_smb(Client,inbuf,OPLOCK_BREAK_TIMEOUT * 1000) == False)
  3150.     {
  3151.       /*
  3152.        * Die if we got an error.
  3153.        */
  3154.  
  3155.       if (smb_read_error == READ_EOF)
  3156.         DEBUG(0,("%s oplock_break: end of file from client\n", timestring()));
  3157.  
  3158.       if (smb_read_error == READ_ERROR)
  3159.         DEBUG(0,("%s oplock_break: receive_smb error (%s)\n",
  3160.                   timestring(), strerror(errno)));
  3161.  
  3162.       if (smb_read_error == READ_TIMEOUT)
  3163.         DEBUG(0,("%s oplock_break: receive_smb timed out after %d seconds.\n",
  3164.                   timestring(), OPLOCK_BREAK_TIMEOUT));
  3165.  
  3166.       DEBUG(0,("%s oplock_break failed for file %s (fnum = %d, dev = %x, \
  3167. inode = %x).\n", timestring(), fsp->name, fnum, dev, inode));
  3168.       shutdown_server = True;
  3169.       break;
  3170.     }
  3171.  
  3172.     /*
  3173.      * There are certain SMB requests that we shouldn't allow
  3174.      * to recurse. opens, renames and deletes are the obvious
  3175.      * ones. This is handled in the switch_message() function.
  3176.      * If global_oplock_break is set they will push the packet onto
  3177.      * the pending smb queue and return -1 (no reply).
  3178.      * JRA.
  3179.      */
  3180.  
  3181.     process_smb(inbuf, outbuf);
  3182.  
  3183.     /*
  3184.      * Die if we go over the time limit.
  3185.      */
  3186.  
  3187.     if((time(NULL) - start_time) > OPLOCK_BREAK_TIMEOUT)
  3188.     {
  3189.       DEBUG(0,("%s oplock_break: no break received from client within \
  3190. %d seconds.\n", timestring(), OPLOCK_BREAK_TIMEOUT));
  3191.       DEBUG(0,("%s oplock_break failed for file %s (fnum = %d, dev = %x, \
  3192. inode = %x).\n", timestring(), fsp->name, fnum, dev, inode));
  3193.       shutdown_server = True;
  3194.       break;
  3195.     }
  3196.   }
  3197.  
  3198.   /*
  3199.    * Go back to being the user who requested the oplock
  3200.    * break.
  3201.    */
  3202.   if(!become_user(&Connections[saved_cnum], saved_cnum, saved_vuid))
  3203.   {
  3204.     DEBUG(0,("%s oplock_break: unable to re-become user ! Shutting down server\n",
  3205.           timestring()));
  3206.     close_sockets();
  3207.     close(oplock_sock);
  3208.     exit_server("unable to re-become user");
  3209.   }
  3210.   /* Including the directory. */
  3211.   ChDir(saved_dir);
  3212.  
  3213.   /* Free the buffers we've been using to recurse. */
  3214.   free(inbuf);
  3215.   free(outbuf);
  3216.  
  3217.   /* We need this in case a readraw crossed on the wire. */
  3218.   if(global_oplock_break)
  3219.     global_oplock_break = False;
  3220.  
  3221.   /*
  3222.    * If the client did not respond we must die.
  3223.    */
  3224.  
  3225.   if(shutdown_server)
  3226.   {
  3227.     DEBUG(0,("%s oplock_break: client failure in break - shutting down this smbd.\n",
  3228.           timestring()));
  3229.     close_sockets();
  3230.     close(oplock_sock);
  3231.     exit_server("oplock break failure");
  3232.   }
  3233.  
  3234.   if(OPEN_FNUM(fnum))
  3235.   {
  3236.     /* The lockingX reply will have removed the oplock flag 
  3237.        from the sharemode. */
  3238.     /* Paranoia.... */
  3239.     fsp->granted_oplock = False;
  3240.     fsp->sent_oplock_break = False;
  3241.     global_oplocks_open--;
  3242.   }
  3243.  
  3244.   /* Santity check - remove this later. JRA */
  3245.   if(global_oplocks_open < 0)
  3246.   {
  3247.     DEBUG(0,("oplock_break: global_oplocks_open < 0 (%d). PANIC ERROR\n",
  3248.               global_oplocks_open));
  3249.     exit_server("oplock_break: global_oplocks_open < 0");
  3250.   }
  3251.  
  3252.   DEBUG(3,("%s oplock_break: returning success for fnum = %d, dev = %x, inode = %x. Current \
  3253. global_oplocks_open = %d\n", timestring(), fnum, dev, inode, global_oplocks_open));
  3254.  
  3255.   return True;
  3256. }
  3257.  
  3258. /****************************************************************************
  3259. Send an oplock break message to another smbd process. If the oplock is held 
  3260. by the local smbd then call the oplock break function directly.
  3261. ****************************************************************************/
  3262.  
  3263. BOOL request_oplock_break(share_mode_entry *share_entry, 
  3264.                           uint32 dev, uint32 inode)
  3265. {
  3266.   char op_break_msg[OPLOCK_BREAK_MSG_LEN];
  3267.   struct sockaddr_in addr_out;
  3268.   int pid = getpid();
  3269.   time_t start_time;
  3270.   int time_left;
  3271.  
  3272.   if(pid == share_entry->pid)
  3273.   {
  3274.     /* We are breaking our own oplock, make sure it's us. */
  3275.     if(share_entry->op_port != oplock_port)
  3276.     {
  3277.       DEBUG(0,("request_oplock_break: corrupt share mode entry - pid = %d, port = %d \
  3278. should be %d\n", pid, share_entry->op_port, oplock_port));
  3279.       return False;
  3280.     }
  3281.  
  3282.     DEBUG(5,("request_oplock_break: breaking our own oplock\n"));
  3283.  
  3284.     /* Call oplock break direct. */
  3285.     return oplock_break(dev, inode, &share_entry->time);
  3286.   }
  3287.  
  3288.   /* We need to send a OPLOCK_BREAK_CMD message to the
  3289.      port in the share mode entry. */
  3290.  
  3291.   SSVAL(op_break_msg,UDP_MESSAGE_CMD_OFFSET,OPLOCK_BREAK_CMD);
  3292.   SIVAL(op_break_msg,OPLOCK_BREAK_PID_OFFSET,pid);
  3293.   SIVAL(op_break_msg,OPLOCK_BREAK_DEV_OFFSET,dev);
  3294.   SIVAL(op_break_msg,OPLOCK_BREAK_INODE_OFFSET,inode);
  3295.   SIVAL(op_break_msg,OPLOCK_BREAK_SEC_OFFSET,(uint32)share_entry->time.tv_sec);
  3296.   SIVAL(op_break_msg,OPLOCK_BREAK_USEC_OFFSET,(uint32)share_entry->time.tv_usec);
  3297.  
  3298.   /* set the address and port */
  3299.   bzero((char *)&addr_out,sizeof(addr_out));
  3300.   addr_out.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
  3301.   addr_out.sin_port = htons( share_entry->op_port );
  3302.   addr_out.sin_family = AF_INET;
  3303.    
  3304.   DEBUG(3,("%s request_oplock_break: sending a oplock break message to pid %d on port %d \
  3305. for dev = %x, inode = %x\n", timestring(), share_entry->pid, share_entry->op_port, dev, inode));
  3306.  
  3307.   if(sendto(oplock_sock,op_break_msg,OPLOCK_BREAK_MSG_LEN,0,
  3308.          (struct sockaddr *)&addr_out,sizeof(addr_out)) < 0)
  3309.   {
  3310.     DEBUG(0,("%s request_oplock_break: failed when sending a oplock break message \
  3311. to pid %d on port %d for dev = %x, inode = %x. Error was %s\n",
  3312.          timestring(), share_entry->pid, share_entry->op_port, dev, inode,
  3313.          strerror(errno)));
  3314.     return False;
  3315.   }
  3316.  
  3317.   /*
  3318.    * Now we must await the oplock broken message coming back
  3319.    * from the target smbd process. Timeout if it fails to
  3320.    * return in (OPLOCK_BREAK_TIMEOUT + OPLOCK_BREAK_TIMEOUT_FUDGEFACTOR) seconds.
  3321.    * While we get messages that aren't ours, loop.
  3322.    */
  3323.  
  3324.   start_time = time(NULL);
  3325.   time_left = OPLOCK_BREAK_TIMEOUT+OPLOCK_BREAK_TIMEOUT_FUDGEFACTOR;
  3326.  
  3327.   while(time_left >= 0)
  3328.   {
  3329.     char op_break_reply[UDP_CMD_HEADER_LEN+OPLOCK_BREAK_MSG_LEN];
  3330.     int32 reply_msg_len;
  3331.     uint16 reply_from_port;
  3332.     char *reply_msg_start;
  3333.  
  3334.     if(receive_local_message(oplock_sock, op_break_reply, sizeof(op_break_reply),
  3335.                time_left ? time_left * 1000 : 1) == False)
  3336.     {
  3337.       if(smb_read_error == READ_TIMEOUT)
  3338.       {
  3339.         DEBUG(0,("%s request_oplock_break: no response received to oplock break request to \
  3340. pid %d on port %d for dev = %x, inode = %x\n", timestring(), share_entry->pid, 
  3341.                            share_entry->op_port, dev, inode));
  3342.         /*
  3343.          * This is a hack to make handling of failing clients more robust.
  3344.          * If a oplock break response message is not received in the timeout
  3345.          * period we may assume that the smbd servicing that client holding
  3346.          * the oplock has died and the client changes were lost anyway, so
  3347.          * we should continue to try and open the file.
  3348.          */
  3349.         break;
  3350.       }
  3351.       else
  3352.         DEBUG(0,("%s request_oplock_break: error in response received to oplock break request to \
  3353. pid %d on port %d for dev = %x, inode = %x. Error was (%s).\n", timestring(), share_entry->pid, 
  3354.                          share_entry->op_port, dev, inode, strerror(errno)));
  3355.       return False;
  3356.     }
  3357.  
  3358.     reply_msg_len = IVAL(op_break_reply,UDP_CMD_LEN_OFFSET);
  3359.     reply_from_port = SVAL(op_break_reply,UDP_CMD_PORT_OFFSET);
  3360.  
  3361.     reply_msg_start = &op_break_reply[UDP_CMD_HEADER_LEN];
  3362.  
  3363.     if(reply_msg_len != OPLOCK_BREAK_MSG_LEN)
  3364.     {
  3365.       /* Ignore it. */
  3366.       DEBUG(0,("%s request_oplock_break: invalid message length received. Ignoring\n",
  3367.              timestring()));
  3368.       continue;
  3369.     }
  3370.  
  3371.     /*
  3372.      * Test to see if this is the reply we are awaiting.
  3373.      */
  3374.  
  3375.     if((SVAL(reply_msg_start,UDP_MESSAGE_CMD_OFFSET) & CMD_REPLY) &&
  3376.        (reply_from_port == share_entry->op_port) && 
  3377.        (memcmp(&reply_msg_start[OPLOCK_BREAK_PID_OFFSET], 
  3378.                &op_break_msg[OPLOCK_BREAK_PID_OFFSET],
  3379.                OPLOCK_BREAK_MSG_LEN - OPLOCK_BREAK_PID_OFFSET) == 0))
  3380.     {
  3381.       /*
  3382.        * This is the reply we've been waiting for.
  3383.        */
  3384.       break;
  3385.     }
  3386.     else
  3387.     {
  3388.       /*
  3389.        * This is another message - probably a break request.
  3390.        * Process it to prevent potential deadlock.
  3391.        * Note that the code in switch_message() prevents
  3392.        * us from recursing into here as any SMB requests
  3393.        * we might process that would cause another oplock
  3394.        * break request to be made will be queued.
  3395.        * JRA.
  3396.        */
  3397.  
  3398.       process_local_message(oplock_sock, op_break_reply, sizeof(op_break_reply));
  3399.     }
  3400.  
  3401.     time_left -= (time(NULL) - start_time);
  3402.   }
  3403.  
  3404.   DEBUG(3,("%s request_oplock_break: broke oplock.\n", timestring()));
  3405.  
  3406.   return True;
  3407. }
  3408.  
  3409. /****************************************************************************
  3410. Get the next SMB packet, doing the local message processing automatically.
  3411. ****************************************************************************/
  3412.  
  3413. BOOL receive_next_smb(int smbfd, int oplockfd, char *inbuf, int bufsize, int timeout)
  3414. {
  3415.   BOOL got_smb = False;
  3416.   BOOL ret;
  3417.  
  3418.   do
  3419.   {
  3420.     ret = receive_message_or_smb(smbfd,oplockfd,inbuf,bufsize,
  3421.                                  timeout,&got_smb);
  3422.  
  3423.     if(ret && !got_smb)
  3424.     {
  3425.       /* Deal with oplock break requests from other smbd's. */
  3426.       process_local_message(oplock_sock, inbuf, bufsize);
  3427.       continue;
  3428.     }
  3429.  
  3430.     if(ret && (CVAL(inbuf,0) == 0x85))
  3431.     {
  3432.       /* Keepalive packet. */
  3433.       got_smb = False;
  3434.     }
  3435.  
  3436.   }
  3437.   while(ret && !got_smb);
  3438.  
  3439.   return ret;
  3440. }
  3441.  
  3442. /****************************************************************************
  3443. check if a snum is in use
  3444. ****************************************************************************/
  3445. BOOL snum_used(int snum)
  3446. {
  3447.   int i;
  3448.   for (i=0;i<MAX_CONNECTIONS;i++)
  3449.     if (OPEN_CNUM(i) && (SNUM(i) == snum))
  3450.       return(True);
  3451.   return(False);
  3452. }
  3453.  
  3454. /****************************************************************************
  3455.   reload the services file
  3456.   **************************************************************************/
  3457. BOOL reload_services(BOOL test)
  3458. {
  3459.   BOOL ret;
  3460.  
  3461.   if (lp_loaded())
  3462.     {
  3463.       pstring fname;
  3464.       pstrcpy(fname,lp_configfile());
  3465.       if (file_exist(fname,NULL) && !strcsequal(fname,servicesf))
  3466.     {
  3467.       pstrcpy(servicesf,fname);
  3468.       test = False;
  3469.     }
  3470.     }
  3471.  
  3472.   reopen_logs();
  3473.  
  3474.   if (test && !lp_file_list_changed())
  3475.     return(True);
  3476.  
  3477.   lp_killunused(snum_used);
  3478.  
  3479.   ret = lp_load(servicesf,False);
  3480.  
  3481.   /* perhaps the config filename is now set */
  3482.   if (!test)
  3483.     reload_services(True);
  3484.  
  3485.   reopen_logs();
  3486.  
  3487.   load_interfaces();
  3488.  
  3489.   {
  3490.     extern int Client;
  3491.     if (Client != -1) {      
  3492.       set_socket_options(Client,"SO_KEEPALIVE");
  3493.       set_socket_options(Client,user_socket_options);
  3494.     }
  3495.   }
  3496.  
  3497.   reset_mangled_stack( lp_mangledstack() );
  3498.  
  3499.   /* this forces service parameters to be flushed */
  3500.   become_service(-1,True);
  3501.  
  3502.   return(ret);
  3503. }
  3504.  
  3505.  
  3506.  
  3507. /****************************************************************************
  3508. this prevents zombie child processes
  3509. ****************************************************************************/
  3510. static BOOL reload_after_sighup = False;
  3511.  
  3512. static int sig_hup(void)
  3513. {
  3514.   BlockSignals(True,SIGHUP);
  3515.   DEBUG(0,("Got SIGHUP\n"));
  3516.  
  3517.   /*
  3518.    * Fix from <branko.cibej@hermes.si> here.
  3519.    * We used to reload in the signal handler - this
  3520.    * is a *BIG* no-no.
  3521.    */
  3522.  
  3523.   reload_after_sighup = True;
  3524. #ifndef DONT_REINSTALL_SIG
  3525.   signal(SIGHUP,SIGNAL_CAST sig_hup);
  3526. #endif
  3527.   BlockSignals(False,SIGHUP);
  3528.   return(0);
  3529. }
  3530.  
  3531. /****************************************************************************
  3532. Setup the groups a user belongs to.
  3533. ****************************************************************************/
  3534. int setup_groups(char *user, int uid, int gid, int *p_ngroups, 
  3535.          int **p_igroups, gid_t **p_groups,
  3536.          int **p_attrs)
  3537. {
  3538.   if (-1 == initgroups(user,gid))
  3539.     {
  3540.       if (getuid() == 0)
  3541.     {
  3542.       DEBUG(0,("Unable to initgroups!\n"));
  3543.       if (gid < 0 || gid > 16000 || uid < 0 || uid > 16000)
  3544.         DEBUG(0,("This is probably a problem with the account %s\n",user));
  3545.     }
  3546.     }
  3547.   else
  3548.     {
  3549.       int i,ngroups;
  3550.       int *igroups;
  3551.       int *attrs;
  3552.       gid_t grp = 0;
  3553.       ngroups = getgroups(0,&grp);
  3554.       if (ngroups <= 0)
  3555.         ngroups = 32;
  3556.       igroups = (int *)malloc(sizeof(int)*ngroups);
  3557.       attrs   = (int *)malloc(sizeof(int)*ngroups);
  3558.       for (i=0;i<ngroups;i++)
  3559.       {
  3560.         attrs  [i] = 0x7; /* XXXX don't know what NT user attributes are yet! */
  3561.         igroups[i] = 0x42424242;
  3562.       }
  3563.       ngroups = getgroups(ngroups,(gid_t *)igroups);
  3564.  
  3565.       if (igroups[0] == 0x42424242)
  3566.         ngroups = 0;
  3567.  
  3568.       *p_ngroups = ngroups;
  3569.       *p_attrs   = attrs;
  3570.  
  3571.       /* The following bit of code is very strange. It is due to the
  3572.          fact that some OSes use int* and some use gid_t* for
  3573.          getgroups, and some (like SunOS) use both, one in prototypes,
  3574.          and one in man pages and the actual code. Thus we detect it
  3575.          dynamically using some very ugly code */
  3576.       if (ngroups > 0)
  3577.         {
  3578.       /* does getgroups return ints or gid_t ?? */
  3579.       static BOOL groups_use_ints = True;
  3580.  
  3581.       if (groups_use_ints && 
  3582.           ngroups == 1 && 
  3583.           SVAL(igroups,2) == 0x4242)
  3584.         groups_use_ints = False;
  3585.       
  3586.           for (i=0;groups_use_ints && i<ngroups;i++)
  3587.             if (igroups[i] == 0x42424242)
  3588.               groups_use_ints = False;
  3589.           
  3590.           if (groups_use_ints)
  3591.           {
  3592.               *p_igroups = igroups;
  3593.               *p_groups = (gid_t *)igroups;      
  3594.           }
  3595.           else
  3596.           {
  3597.           gid_t *groups = (gid_t *)igroups;
  3598.           igroups = (int *)malloc(sizeof(int)*ngroups);
  3599.           for (i=0;i<ngroups;i++)
  3600.           {
  3601.             igroups[i] = groups[i];
  3602.           }
  3603.           *p_igroups = igroups;
  3604.           *p_groups = (gid_t *)groups;
  3605.         }
  3606.     }
  3607.       DEBUG(3,("%s is in %d groups\n",user,ngroups));
  3608.       for (i=0;i<ngroups;i++)
  3609.         DEBUG(3,("%d ",igroups[i]));
  3610.       DEBUG(3,("\n"));
  3611.     }
  3612.   return 0;
  3613. }
  3614.  
  3615. /****************************************************************************
  3616.   make a connection to a service
  3617. ****************************************************************************/
  3618. int make_connection(char *service,char *user,char *password, int pwlen, char *dev,uint16 vuid)
  3619. {
  3620.   int cnum;
  3621.   int snum;
  3622.   struct passwd *pass = NULL;
  3623.   connection_struct *pcon;
  3624.   BOOL guest = False;
  3625.   BOOL force = False;
  3626.   static BOOL first_connection = True;
  3627.  
  3628.   strlower(service);
  3629.  
  3630.   snum = find_service(service);
  3631.   if (snum < 0)
  3632.     {
  3633.       if (strequal(service,"IPC$"))
  3634.     {      
  3635.       DEBUG(3,("%s refusing IPC connection\n",timestring()));
  3636.       return(-3);
  3637.     }
  3638.  
  3639.       DEBUG(0,("%s %s (%s) couldn't find service %s\n",timestring(),remote_machine,client_addr(),service));      
  3640.       return(-2);
  3641.     }
  3642.  
  3643.   if (strequal(service,HOMES_NAME))
  3644.     {
  3645.       if (*user && Get_Pwnam(user,True))
  3646.     return(make_connection(user,user,password,pwlen,dev,vuid));
  3647.  
  3648.       if(lp_security() != SEC_SHARE)
  3649.       {
  3650.         if (validated_username(vuid))
  3651.         {
  3652.           pstrcpy(user,validated_username(vuid));
  3653.           return(make_connection(user,user,password,pwlen,dev,vuid));
  3654.         }
  3655.       }
  3656.       else
  3657.       {
  3658.         /*
  3659.          * Security = share. Try with sesssetup_user as the username.
  3660.          */
  3661.         if(*sesssetup_user)
  3662.         {
  3663.           pstrcpy(user,sesssetup_user);
  3664.           return(make_connection(user,user,password,pwlen,dev,vuid));
  3665.         }
  3666.       }
  3667.     }
  3668.  
  3669.   if (!lp_snum_ok(snum) || !check_access(snum)) {    
  3670.     return(-4);
  3671.   }
  3672.  
  3673.   /* you can only connect to the IPC$ service as an ipc device */
  3674.   if (strequal(service,"IPC$"))
  3675.     pstrcpy(dev,"IPC");
  3676.  
  3677.   if (*dev == '?' || !*dev)
  3678.     {
  3679.       if (lp_print_ok(snum))
  3680.     pstrcpy(dev,"LPT1:");
  3681.       else
  3682.     pstrcpy(dev,"A:");
  3683.     }
  3684.  
  3685.   /* if the request is as a printer and you can't print then refuse */
  3686.   strupper(dev);
  3687.   if (!lp_print_ok(snum) && (strncmp(dev,"LPT",3) == 0)) {
  3688.     DEBUG(1,("Attempt to connect to non-printer as a printer\n"));
  3689.     return(-6);
  3690.   }
  3691.  
  3692.   /* lowercase the user name */
  3693.   strlower(user);
  3694.  
  3695.   /* add it as a possible user name */
  3696.   add_session_user(service);
  3697.  
  3698.   /* shall we let them in? */
  3699.   if (!authorise_login(snum,user,password,pwlen,&guest,&force,vuid))
  3700.     {
  3701.       DEBUG(2,("%s invalid username/password for %s\n",timestring(),service));
  3702.       return(-1);
  3703.     }
  3704.   
  3705.   cnum = find_free_connection(str_checksum(service) + str_checksum(user));
  3706.   if (cnum < 0)
  3707.     {
  3708.       DEBUG(0,("%s couldn't find free connection\n",timestring()));      
  3709.       return(-1);
  3710.     }
  3711.  
  3712.   pcon = &Connections[cnum];
  3713.   bzero((char *)pcon,sizeof(*pcon));
  3714.  
  3715.   /* find out some info about the user */
  3716.   pass = Get_Pwnam(user,True);
  3717.  
  3718.   if (pass == NULL)
  3719.     {
  3720.       DEBUG(0,("%s couldn't find account %s\n",timestring(),user)); 
  3721.       return(-7);
  3722.     }
  3723.  
  3724.   pcon->read_only = lp_readonly(snum);
  3725.  
  3726.   {
  3727.     pstring list;
  3728.     StrnCpy(list,lp_readlist(snum),sizeof(pstring)-1);
  3729.     string_sub(list,"%S",service);
  3730.  
  3731.     if (user_in_list(user,list))
  3732.       pcon->read_only = True;
  3733.  
  3734.     StrnCpy(list,lp_writelist(snum),sizeof(pstring)-1);
  3735.     string_sub(list,"%S",service);
  3736.  
  3737.     if (user_in_list(user,list))
  3738.       pcon->read_only = False;    
  3739.   }
  3740.  
  3741.   /* admin user check */
  3742.  
  3743.   /* JRA - original code denied admin user if the share was
  3744.      marked read_only. Changed as I don't think this is needed,
  3745.      but old code left in case there is a problem here.
  3746.    */
  3747.   if (user_in_list(user,lp_admin_users(snum)) 
  3748. #if 0
  3749.       && !pcon->read_only)
  3750. #else
  3751.       )
  3752. #endif
  3753.     {
  3754.       pcon->admin_user = True;
  3755.       DEBUG(0,("%s logged in as admin user (root privileges)\n",user));
  3756.     }
  3757.   else
  3758.     pcon->admin_user = False;
  3759.     
  3760.   pcon->force_user = force;
  3761.   pcon->vuid = vuid;
  3762.   pcon->uid = pass->pw_uid;
  3763.   pcon->gid = pass->pw_gid;
  3764.   pcon->num_files_open = 0;
  3765.   pcon->lastused = time(NULL);
  3766.   pcon->service = snum;
  3767.   pcon->used = True;
  3768.   pcon->printer = (strncmp(dev,"LPT",3) == 0);
  3769.   pcon->ipc = (strncmp(dev,"IPC",3) == 0);
  3770.   pcon->dirptr = NULL;
  3771.   pcon->veto_list = NULL;
  3772.   pcon->hide_list = NULL;
  3773.   pcon->veto_oplock_list = NULL;
  3774.   string_set(&pcon->dirpath,"");
  3775.   string_set(&pcon->user,user);
  3776.  
  3777. #if HAVE_GETGRNAM 
  3778.   if (*lp_force_group(snum))
  3779.     {
  3780.       struct group *gptr;
  3781.       pstring gname;
  3782.  
  3783.       StrnCpy(gname,lp_force_group(snum),sizeof(pstring)-1);
  3784.       /* default service may be a group name         */
  3785.       string_sub(gname,"%S",service);
  3786.       gptr = (struct group *)getgrnam(gname);
  3787.  
  3788.       if (gptr)
  3789.     {
  3790.       pcon->gid = gptr->gr_gid;
  3791.       DEBUG(3,("Forced group %s\n",gname));
  3792.     }
  3793.       else
  3794.     DEBUG(1,("Couldn't find group %s\n",gname));
  3795.     }
  3796. #endif
  3797.  
  3798.   if (*lp_force_user(snum))
  3799.     {
  3800.       struct passwd *pass2;
  3801.       fstring fuser;
  3802.       fstrcpy(fuser,lp_force_user(snum));
  3803.       pass2 = (struct passwd *)Get_Pwnam(fuser,True);
  3804.       if (pass2)
  3805.     {
  3806.       pcon->uid = pass2->pw_uid;
  3807.       string_set(&pcon->user,fuser);
  3808.       fstrcpy(user,fuser);
  3809.       pcon->force_user = True;
  3810.       DEBUG(3,("Forced user %s\n",fuser));      
  3811.     }
  3812.       else
  3813.     DEBUG(1,("Couldn't find user %s\n",fuser));
  3814.     }
  3815.  
  3816.   {
  3817.     pstring s;
  3818.     pstrcpy(s,lp_pathname(snum));
  3819.     standard_sub(cnum,s);
  3820.     string_set(&pcon->connectpath,s);
  3821.     DEBUG(3,("Connect path is %s\n",s));
  3822.   }
  3823.  
  3824.   /* groups stuff added by ih */
  3825.   pcon->ngroups = 0;
  3826.   pcon->igroups = NULL;
  3827.   pcon->groups = NULL;
  3828.   pcon->attrs = NULL;
  3829.  
  3830.   if (!IS_IPC(cnum))
  3831.     {
  3832.       /* Find all the groups this uid is in and store them. Used by become_user() */
  3833.       setup_groups(pcon->user,pcon->uid,pcon->gid,
  3834.                   &pcon->ngroups,&pcon->igroups,&pcon->groups,&pcon->attrs);
  3835.       
  3836.       /* check number of connections */
  3837.       if (!claim_connection(cnum,
  3838.                 lp_servicename(SNUM(cnum)),
  3839.                 lp_max_connections(SNUM(cnum)),False))
  3840.     {
  3841.       DEBUG(1,("too many connections - rejected\n"));
  3842.       return(-8);
  3843.     }  
  3844.  
  3845.       if (lp_status(SNUM(cnum)))
  3846.     claim_connection(cnum,"STATUS.",MAXSTATUS,first_connection);
  3847.  
  3848.       first_connection = False;
  3849.     } /* IS_IPC */
  3850.  
  3851.   pcon->open = True;
  3852.  
  3853.   /* execute any "root preexec = " line */
  3854.   if (*lp_rootpreexec(SNUM(cnum)))
  3855.     {
  3856.       pstring cmd;
  3857.       pstrcpy(cmd,lp_rootpreexec(SNUM(cnum)));
  3858.       standard_sub(cnum,cmd);
  3859.       DEBUG(5,("cmd=%s\n",cmd));
  3860.       smbrun(cmd,NULL,False);
  3861.     }
  3862.  
  3863.   if (!become_user(&Connections[cnum], cnum,pcon->vuid))
  3864.     {
  3865.       DEBUG(0,("Can't become connected user!\n"));
  3866.       pcon->open = False;
  3867.       if (!IS_IPC(cnum)) {
  3868.     yield_connection(cnum,
  3869.              lp_servicename(SNUM(cnum)),
  3870.              lp_max_connections(SNUM(cnum)));
  3871.     if (lp_status(SNUM(cnum))) yield_connection(cnum,"STATUS.",MAXSTATUS);
  3872.       }
  3873.       return(-1);
  3874.     }
  3875.  
  3876.   if (ChDir(pcon->connectpath) != 0)
  3877.     {
  3878.       DEBUG(0,("Can't change directory to %s (%s)\n",
  3879.            pcon->connectpath,strerror(errno)));
  3880.       pcon->open = False;
  3881.       unbecome_user();
  3882.       if (!IS_IPC(cnum)) {
  3883.     yield_connection(cnum,
  3884.              lp_servicename(SNUM(cnum)),
  3885.              lp_max_connections(SNUM(cnum)));
  3886.     if (lp_status(SNUM(cnum))) yield_connection(cnum,"STATUS.",MAXSTATUS);
  3887.       }
  3888.       return(-5);      
  3889.     }
  3890.  
  3891.   string_set(&pcon->origpath,pcon->connectpath);
  3892.  
  3893. #if SOFTLINK_OPTIMISATION
  3894.   /* resolve any soft links early */
  3895.   {
  3896.     pstring s;
  3897.     pstrcpy(s,pcon->connectpath);
  3898.     GetWd(s);
  3899.     string_set(&pcon->connectpath,s);
  3900.     ChDir(pcon->connectpath);
  3901.   }
  3902. #endif
  3903.  
  3904.   num_connections_open++;
  3905.   add_session_user(user);
  3906.   
  3907.   /* execute any "preexec = " line */
  3908.   if (*lp_preexec(SNUM(cnum)))
  3909.     {
  3910.       pstring cmd;
  3911.       pstrcpy(cmd,lp_preexec(SNUM(cnum)));
  3912.       standard_sub(cnum,cmd);
  3913.       smbrun(cmd,NULL,False);
  3914.     }
  3915.   
  3916.   /* we've finished with the sensitive stuff */
  3917.   unbecome_user();
  3918.  
  3919.   /* Add veto/hide lists */
  3920.   if (!IS_IPC(cnum) && !IS_PRINT(cnum))
  3921.   {
  3922.     set_namearray( &pcon->veto_list, lp_veto_files(SNUM(cnum)));
  3923.     set_namearray( &pcon->hide_list, lp_hide_files(SNUM(cnum)));
  3924.     set_namearray( &pcon->veto_oplock_list, lp_veto_oplocks(SNUM(cnum)));
  3925.   }
  3926.  
  3927.   {
  3928.     DEBUG(IS_IPC(cnum)?3:1,("%s %s (%s) connect to service %s as user %s (uid=%d,gid=%d) (pid %d)\n",
  3929.                 timestring(),
  3930.                 remote_machine,
  3931.                 client_addr(),
  3932.                 lp_servicename(SNUM(cnum)),user,
  3933.                 pcon->uid,
  3934.                 pcon->gid,
  3935.                 (int)getpid()));
  3936.   }
  3937.  
  3938.   return(cnum);
  3939. }
  3940.  
  3941. /****************************************************************************
  3942.   Attempt to break an oplock on a file (if oplocked).
  3943.   Returns True if the file was closed as a result of
  3944.   the oplock break, False otherwise.
  3945.   Used as a last ditch attempt to free a space in the 
  3946.   file table when we have run out.
  3947. ****************************************************************************/
  3948.  
  3949. static BOOL attempt_close_oplocked_file(files_struct *fp)
  3950. {
  3951.  
  3952.   DEBUG(5,("attempt_close_oplocked_file: checking file %s.\n", fp->name));
  3953.  
  3954.   if (fp->open && fp->granted_oplock && !fp->sent_oplock_break) {
  3955.  
  3956.     /* Try and break the oplock. */
  3957.     file_fd_struct *fsp = fp->fd_ptr;
  3958.     if(oplock_break( fsp->dev, fsp->inode, &fp->open_time)) {
  3959.       if(!fp->open) /* Did the oplock break close the file ? */
  3960.         return True;
  3961.     }
  3962.   }
  3963.  
  3964.   return False;
  3965. }
  3966.  
  3967. /****************************************************************************
  3968.   find first available file slot
  3969. ****************************************************************************/
  3970. int find_free_file(void )
  3971. {
  3972.     int i;
  3973.     static int first_file;
  3974.  
  3975.     /* we want to give out file handles differently on each new
  3976.        connection because of a common bug in MS clients where they try to
  3977.        reuse a file descriptor from an earlier smb connection. This code
  3978.        increases the chance that the errant client will get an error rather
  3979.        than causing corruption */
  3980.     if (first_file == 0) {
  3981.         first_file = (getpid() ^ (int)time(NULL)) % MAX_OPEN_FILES;
  3982.         if (first_file == 0) first_file = 1;
  3983.     }
  3984.  
  3985.     if (first_file >= MAX_OPEN_FILES)
  3986.         first_file = 1;
  3987.  
  3988.     for (i=first_file;i<MAX_OPEN_FILES;i++)
  3989.         if (!Files[i].open && !Files[i].reserved) {
  3990.             memset(&Files[i], 0, sizeof(Files[i]));
  3991.             first_file = i+1;
  3992.             Files[i].reserved = True;
  3993.             return(i);
  3994.         }
  3995.  
  3996.     /* returning a file handle of 0 is a bad idea - so we start at 1 */
  3997.     for (i=1;i<first_file;i++)
  3998.         if (!Files[i].open && !Files[i].reserved) {
  3999.             memset(&Files[i], 0, sizeof(Files[i]));
  4000.             first_file = i+1;
  4001.             Files[i].reserved = True;
  4002.             return(i);
  4003.         }
  4004.  
  4005.         /* 
  4006.          * Before we give up, go through the open files 
  4007.          * and see if there are any files opened with a
  4008.          * batch oplock. If so break the oplock and then
  4009.          * re-use that entry (if it becomes closed).
  4010.          * This may help as NT/95 clients tend to keep
  4011.          * files batch oplocked for quite a long time
  4012.          * after they have finished with them.
  4013.          */
  4014.         for (i=first_file;i<MAX_OPEN_FILES;i++) {
  4015.           if(attempt_close_oplocked_file( &Files[i])) {
  4016.             memset(&Files[i], 0, sizeof(Files[i]));
  4017.             first_file = i+1;
  4018.             Files[i].reserved = True;
  4019.             return(i);
  4020.           }
  4021.         }
  4022.  
  4023.         for (i=1;i<MAX_OPEN_FILES;i++) {
  4024.           if(attempt_close_oplocked_file( &Files[i])) {
  4025.             memset(&Files[i], 0, sizeof(Files[i]));
  4026.             first_file = i+1;
  4027.             Files[i].reserved = True;
  4028.             return(i);
  4029.           }
  4030.         }
  4031.  
  4032.     DEBUG(1,("ERROR! Out of file structures - perhaps increase MAX_OPEN_FILES?\n"));
  4033.     return(-1);
  4034. }
  4035.  
  4036. /****************************************************************************
  4037.   find first available connection slot, starting from a random position.
  4038. The randomisation stops problems with the server dieing and clients
  4039. thinking the server is still available.
  4040. ****************************************************************************/
  4041. static int find_free_connection(int hash )
  4042. {
  4043.   int i;
  4044.   BOOL used=False;
  4045.   hash = (hash % (MAX_CONNECTIONS-2))+1;
  4046.  
  4047.  again:
  4048.  
  4049.   for (i=hash+1;i!=hash;)
  4050.     {
  4051.       if (!Connections[i].open && Connections[i].used == used) 
  4052.     {
  4053.       DEBUG(3,("found free connection number %d\n",i));
  4054.       return(i);
  4055.     }
  4056.       i++;
  4057.       if (i == MAX_CONNECTIONS)
  4058.     i = 1;
  4059.     }
  4060.  
  4061.   if (!used)
  4062.     {
  4063.       used = !used;
  4064.       goto again;
  4065.     }
  4066.  
  4067.   DEBUG(1,("ERROR! Out of connection structures\n"));
  4068.   return(-1);
  4069. }
  4070.  
  4071.  
  4072. /****************************************************************************
  4073. reply for the core protocol
  4074. ****************************************************************************/
  4075. int reply_corep(char *outbuf)
  4076. {
  4077.   int outsize = set_message(outbuf,1,0,True);
  4078.  
  4079.   Protocol = PROTOCOL_CORE;
  4080.  
  4081.   return outsize;
  4082. }
  4083.  
  4084.  
  4085. /****************************************************************************
  4086. reply for the coreplus protocol
  4087. ****************************************************************************/
  4088. int reply_coreplus(char *outbuf)
  4089. {
  4090.   int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
  4091.   int outsize = set_message(outbuf,13,0,True);
  4092.   SSVAL(outbuf,smb_vwv5,raw); /* tell redirector we support
  4093.                  readbraw and writebraw (possibly) */
  4094.   CVAL(outbuf,smb_flg) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
  4095.   SSVAL(outbuf,smb_vwv1,0x1); /* user level security, don't encrypt */    
  4096.  
  4097.   Protocol = PROTOCOL_COREPLUS;
  4098.  
  4099.   return outsize;
  4100. }
  4101.  
  4102.  
  4103. /****************************************************************************
  4104. reply for the lanman 1.0 protocol
  4105. ****************************************************************************/
  4106. int reply_lanman1(char *outbuf)
  4107. {
  4108.   int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
  4109.   int secword=0;
  4110.   BOOL doencrypt = SMBENCRYPT();
  4111.   time_t t = time(NULL);
  4112.  
  4113.   if (lp_security()>=SEC_USER) secword |= 1;
  4114.   if (doencrypt) secword |= 2;
  4115.  
  4116.   set_message(outbuf,13,doencrypt?8:0,True);
  4117.   SSVAL(outbuf,smb_vwv1,secword); 
  4118.   /* Create a token value and add it to the outgoing packet. */
  4119.   if (doencrypt) 
  4120.     generate_next_challenge(smb_buf(outbuf));
  4121.  
  4122.   Protocol = PROTOCOL_LANMAN1;
  4123.  
  4124.   CVAL(outbuf,smb_flg) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
  4125.   SSVAL(outbuf,smb_vwv2,max_recv);
  4126.   SSVAL(outbuf,smb_vwv3,lp_maxmux()); /* maxmux */
  4127.   SSVAL(outbuf,smb_vwv4,1);
  4128.   SSVAL(outbuf,smb_vwv5,raw); /* tell redirector we support
  4129.                  readbraw writebraw (possibly) */
  4130.   SIVAL(outbuf,smb_vwv6,getpid());
  4131.   SSVAL(outbuf,smb_vwv10, TimeDiff(t)/60);
  4132.  
  4133.   put_dos_date(outbuf,smb_vwv8,t);
  4134.  
  4135.   return (smb_len(outbuf)+4);
  4136. }
  4137.  
  4138.  
  4139. /****************************************************************************
  4140. reply for the lanman 2.0 protocol
  4141. ****************************************************************************/
  4142. int reply_lanman2(char *outbuf)
  4143. {
  4144.   int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
  4145.   int secword=0;
  4146.   BOOL doencrypt = SMBENCRYPT();
  4147.   time_t t = time(NULL);
  4148.   struct cli_state *cli = NULL;
  4149.   char cryptkey[8];
  4150.   char crypt_len = 0;
  4151.  
  4152.   if (lp_security() == SEC_SERVER) {
  4153.       cli = server_cryptkey();
  4154.   }
  4155.  
  4156.   if (cli) {
  4157.       DEBUG(3,("using password server validation\n"));
  4158.       doencrypt = ((cli->sec_mode & 2) != 0);
  4159.   }
  4160.  
  4161.   if (lp_security()>=SEC_USER) secword |= 1;
  4162.   if (doencrypt) secword |= 2;
  4163.  
  4164.   if (doencrypt) {
  4165.       crypt_len = 8;
  4166.       if (!cli) {
  4167.           generate_next_challenge(cryptkey);
  4168.       } else {
  4169.           memcpy(cryptkey, cli->cryptkey, 8);
  4170.           set_challenge(cli->cryptkey);
  4171.       }
  4172.   }
  4173.  
  4174.   set_message(outbuf,13,crypt_len,True);
  4175.   SSVAL(outbuf,smb_vwv1,secword); 
  4176.   SIVAL(outbuf,smb_vwv6,getpid());
  4177.   if (doencrypt) 
  4178.       memcpy(smb_buf(outbuf), cryptkey, 8);
  4179.  
  4180.   Protocol = PROTOCOL_LANMAN2;
  4181.  
  4182.   CVAL(outbuf,smb_flg) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
  4183.   SSVAL(outbuf,smb_vwv2,max_recv);
  4184.   SSVAL(outbuf,smb_vwv3,lp_maxmux()); 
  4185.   SSVAL(outbuf,smb_vwv4,1);
  4186.   SSVAL(outbuf,smb_vwv5,raw); /* readbraw and/or writebraw */
  4187.   SSVAL(outbuf,smb_vwv10, TimeDiff(t)/60);
  4188.   put_dos_date(outbuf,smb_vwv8,t);
  4189.  
  4190.   return (smb_len(outbuf)+4);
  4191. }
  4192.  
  4193.  
  4194. /****************************************************************************
  4195. reply for the nt protocol
  4196. ****************************************************************************/
  4197. int reply_nt1(char *outbuf)
  4198. {
  4199.   /* dual names + lock_and_read + nt SMBs + remote API calls */
  4200.   int capabilities = CAP_NT_FIND|CAP_LOCK_AND_READ;
  4201. /*
  4202.   other valid capabilities which we may support at some time...
  4203.                      CAP_LARGE_FILES|CAP_NT_SMBS|CAP_RPC_REMOTE_APIS;
  4204.                      CAP_LARGE_READX|CAP_STATUS32|CAP_LEVEL_II_OPLOCKS;
  4205.  */
  4206.  
  4207.   int secword=0;
  4208.   BOOL doencrypt = SMBENCRYPT();
  4209.   time_t t = time(NULL);
  4210.   int data_len;
  4211.   struct cli_state *cli = NULL;
  4212.   char cryptkey[8];
  4213.   char crypt_len = 0;
  4214.  
  4215.   if (lp_security() == SEC_SERVER) {
  4216.       cli = server_cryptkey();
  4217.   }
  4218.  
  4219.   if (cli) {
  4220.       DEBUG(3,("using password server validation\n"));
  4221.       doencrypt = ((cli->sec_mode & 2) != 0);
  4222.   }
  4223.  
  4224.   if (doencrypt) {
  4225.       crypt_len = 8;
  4226.       if (!cli) {
  4227.           generate_next_challenge(cryptkey);
  4228.       } else {
  4229.           memcpy(cryptkey, cli->cryptkey, 8);
  4230.           set_challenge(cli->cryptkey);
  4231.       }
  4232.   }
  4233.  
  4234.   if (lp_readraw() && lp_writeraw()) {
  4235.       capabilities |= CAP_RAW_MODE;
  4236.   }
  4237.  
  4238.   if (lp_security() >= SEC_USER) secword |= 1;
  4239.   if (doencrypt) secword |= 2;
  4240.  
  4241.   /* decide where (if) to put the encryption challenge, and
  4242.      follow it with the OEM'd domain name
  4243.    */
  4244.   data_len = crypt_len + strlen(myworkgroup) + 1;
  4245.  
  4246.   set_message(outbuf,17,data_len,True);
  4247.   pstrcpy(smb_buf(outbuf)+crypt_len, myworkgroup);
  4248.  
  4249.   CVAL(outbuf,smb_vwv1) = secword;
  4250.   SSVALS(outbuf,smb_vwv16+1,crypt_len);
  4251.   if (doencrypt) 
  4252.       memcpy(smb_buf(outbuf), cryptkey, 8);
  4253.  
  4254.   Protocol = PROTOCOL_NT1;
  4255.  
  4256.   SSVAL(outbuf,smb_vwv1+1,lp_maxmux()); /* maxmpx */
  4257.   SSVAL(outbuf,smb_vwv2+1,1); /* num vcs */
  4258.   SIVAL(outbuf,smb_vwv3+1,0xffff); /* max buffer. LOTS! */
  4259.   SIVAL(outbuf,smb_vwv5+1,0xffff); /* raw size. LOTS! */
  4260.   SIVAL(outbuf,smb_vwv7+1,getpid()); /* session key */
  4261.   SIVAL(outbuf,smb_vwv9+1,capabilities); /* capabilities */
  4262.   put_long_date(outbuf+smb_vwv11+1,t);
  4263.   SSVALS(outbuf,smb_vwv15+1,TimeDiff(t)/60);
  4264.   SSVAL(outbuf,smb_vwv17,data_len); /* length of challenge+domain strings */
  4265.  
  4266.   return (smb_len(outbuf)+4);
  4267. }
  4268.  
  4269. /* these are the protocol lists used for auto architecture detection:
  4270.  
  4271. WinNT 3.51:
  4272. protocol [PC NETWORK PROGRAM 1.0]
  4273. protocol [XENIX CORE]
  4274. protocol [MICROSOFT NETWORKS 1.03]
  4275. protocol [LANMAN1.0]
  4276. protocol [Windows for Workgroups 3.1a]
  4277. protocol [LM1.2X002]
  4278. protocol [LANMAN2.1]
  4279. protocol [NT LM 0.12]
  4280.  
  4281. Win95:
  4282. protocol [PC NETWORK PROGRAM 1.0]
  4283. protocol [XENIX CORE]
  4284. protocol [MICROSOFT NETWORKS 1.03]
  4285. protocol [LANMAN1.0]
  4286. protocol [Windows for Workgroups 3.1a]
  4287. protocol [LM1.2X002]
  4288. protocol [LANMAN2.1]
  4289. protocol [NT LM 0.12]
  4290.  
  4291. OS/2:
  4292. protocol [PC NETWORK PROGRAM 1.0]
  4293. protocol [XENIX CORE]
  4294. protocol [LANMAN1.0]
  4295. protocol [LM1.2X002]
  4296. protocol [LANMAN2.1]
  4297. */
  4298.  
  4299. /*
  4300.   * Modified to recognize the architecture of the remote machine better.
  4301.   *
  4302.   * This appears to be the matrix of which protocol is used by which
  4303.   * MS product.
  4304.        Protocol                       WfWg    Win95   WinNT  OS/2
  4305.        PC NETWORK PROGRAM 1.0          1       1       1      1
  4306.        XENIX CORE                                      2      2
  4307.        MICROSOFT NETWORKS 3.0          2       2       
  4308.        DOS LM1.2X002                   3       3       
  4309.        MICROSOFT NETWORKS 1.03                         3
  4310.        DOS LANMAN2.1                   4       4       
  4311.        LANMAN1.0                                       4      3
  4312.        Windows for Workgroups 3.1a     5       5       5
  4313.        LM1.2X002                                       6      4
  4314.        LANMAN2.1                                       7      5
  4315.        NT LM 0.12                              6       8
  4316.   *
  4317.   *  tim@fsg.com 09/29/95
  4318.   */
  4319.   
  4320. #define ARCH_WFWG     0x3      /* This is a fudge because WfWg is like Win95 */
  4321. #define ARCH_WIN95    0x2
  4322. #define    ARCH_OS2      0xC      /* Again OS/2 is like NT */
  4323. #define ARCH_WINNT    0x8
  4324. #define ARCH_SAMBA    0x10
  4325.  
  4326. #define ARCH_ALL      0x1F
  4327.  
  4328. /* List of supported protocols, most desired first */
  4329. struct {
  4330.   char *proto_name;
  4331.   char *short_name;
  4332.   int (*proto_reply_fn)(char *);
  4333.   int protocol_level;
  4334. } supported_protocols[] = {
  4335.   {"NT LANMAN 1.0",           "NT1",      reply_nt1,      PROTOCOL_NT1},
  4336.   {"NT LM 0.12",              "NT1",      reply_nt1,      PROTOCOL_NT1},
  4337.   {"LM1.2X002",               "LANMAN2",  reply_lanman2,  PROTOCOL_LANMAN2},
  4338.   {"Samba",                   "LANMAN2",  reply_lanman2,  PROTOCOL_LANMAN2},
  4339.   {"DOS LM1.2X002",           "LANMAN2",  reply_lanman2,  PROTOCOL_LANMAN2},
  4340.   {"LANMAN1.0",               "LANMAN1",  reply_lanman1,  PROTOCOL_LANMAN1},
  4341.   {"MICROSOFT NETWORKS 3.0",  "LANMAN1",  reply_lanman1,  PROTOCOL_LANMAN1},
  4342.   {"MICROSOFT NETWORKS 1.03", "COREPLUS", reply_coreplus, PROTOCOL_COREPLUS},
  4343.   {"PC NETWORK PROGRAM 1.0",  "CORE",     reply_corep,    PROTOCOL_CORE}, 
  4344.   {NULL,NULL},
  4345. };
  4346.  
  4347.  
  4348. /****************************************************************************
  4349.   reply to a negprot
  4350. ****************************************************************************/
  4351. static int reply_negprot(char *inbuf,char *outbuf, int size, int bufsize)
  4352. {
  4353.   int outsize = set_message(outbuf,1,0,True);
  4354.   int Index=0;
  4355.   int choice= -1;
  4356.   int protocol;
  4357.   char *p;
  4358.   int bcc = SVAL(smb_buf(inbuf),-2);
  4359.   int arch = ARCH_ALL;
  4360.  
  4361.   p = smb_buf(inbuf)+1;
  4362.   while (p < (smb_buf(inbuf) + bcc))
  4363.     { 
  4364.       Index++;
  4365.       DEBUG(3,("Requested protocol [%s]\n",p));
  4366.       if (strcsequal(p,"Windows for Workgroups 3.1a"))
  4367.     arch &= ( ARCH_WFWG | ARCH_WIN95 | ARCH_WINNT );
  4368.       else if (strcsequal(p,"DOS LM1.2X002"))
  4369.     arch &= ( ARCH_WFWG | ARCH_WIN95 );
  4370.       else if (strcsequal(p,"DOS LANMAN2.1"))
  4371.     arch &= ( ARCH_WFWG | ARCH_WIN95 );
  4372.       else if (strcsequal(p,"NT LM 0.12"))
  4373.     arch &= ( ARCH_WIN95 | ARCH_WINNT );
  4374.       else if (strcsequal(p,"LANMAN2.1"))
  4375.     arch &= ( ARCH_WINNT | ARCH_OS2 );
  4376.       else if (strcsequal(p,"LM1.2X002"))
  4377.     arch &= ( ARCH_WINNT | ARCH_OS2 );
  4378.       else if (strcsequal(p,"MICROSOFT NETWORKS 1.03"))
  4379.     arch &= ARCH_WINNT;
  4380.       else if (strcsequal(p,"XENIX CORE"))
  4381.     arch &= ( ARCH_WINNT | ARCH_OS2 );
  4382.       else if (strcsequal(p,"Samba")) {
  4383.     arch = ARCH_SAMBA;
  4384.     break;
  4385.       }
  4386.  
  4387.       p += strlen(p) + 2;
  4388.     }
  4389.     
  4390.   switch ( arch ) {
  4391.   case ARCH_SAMBA:
  4392.     set_remote_arch(RA_SAMBA);
  4393.     break;
  4394.   case ARCH_WFWG:
  4395.     set_remote_arch(RA_WFWG);
  4396.     break;
  4397.   case ARCH_WIN95:
  4398.     set_remote_arch(RA_WIN95);
  4399.     break;
  4400.   case ARCH_WINNT:
  4401.     set_remote_arch(RA_WINNT);
  4402.     break;
  4403.   case ARCH_OS2:
  4404.     set_remote_arch(RA_OS2);
  4405.     break;
  4406.   default:
  4407.     set_remote_arch(RA_UNKNOWN);
  4408.     break;
  4409.   }
  4410.  
  4411.   /* possibly reload - change of architecture */
  4412.   reload_services(True);      
  4413.     
  4414.   /* a special case to stop password server loops */
  4415.   if (Index == 1 && strequal(remote_machine,myhostname) && 
  4416.       lp_security()==SEC_SERVER)
  4417.     exit_server("Password server loop!");
  4418.   
  4419.   /* Check for protocols, most desirable first */
  4420.   for (protocol = 0; supported_protocols[protocol].proto_name; protocol++)
  4421.     {
  4422.       p = smb_buf(inbuf)+1;
  4423.       Index = 0;
  4424.       if (lp_maxprotocol() >= supported_protocols[protocol].protocol_level)
  4425.     while (p < (smb_buf(inbuf) + bcc))
  4426.       { 
  4427.         if (strequal(p,supported_protocols[protocol].proto_name))
  4428.           choice = Index;
  4429.         Index++;
  4430.         p += strlen(p) + 2;
  4431.       }
  4432.       if(choice != -1)
  4433.     break;
  4434.     }
  4435.   
  4436.   SSVAL(outbuf,smb_vwv0,choice);
  4437.   if(choice != -1) {
  4438.     extern fstring remote_proto;
  4439.     fstrcpy(remote_proto,supported_protocols[protocol].short_name);
  4440.     reload_services(True);          
  4441.     outsize = supported_protocols[protocol].proto_reply_fn(outbuf);
  4442.     DEBUG(3,("Selected protocol %s\n",supported_protocols[protocol].proto_name));
  4443.   }
  4444.   else {
  4445.     DEBUG(0,("No protocol supported !\n"));
  4446.   }
  4447.   SSVAL(outbuf,smb_vwv0,choice);
  4448.   
  4449.   DEBUG(5,("%s negprot index=%d\n",timestring(),choice));
  4450.  
  4451.   return(outsize);
  4452. }
  4453.  
  4454.  
  4455. /****************************************************************************
  4456. close all open files for a connection
  4457. ****************************************************************************/
  4458. static void close_open_files(int cnum)
  4459. {
  4460.   int i;
  4461.   for (i=0;i<MAX_OPEN_FILES;i++)
  4462.     if( Files[i].cnum == cnum && Files[i].open) {
  4463.       close_file(i,False);
  4464.     }
  4465. }
  4466.  
  4467.  
  4468.  
  4469. /****************************************************************************
  4470. close a cnum
  4471. ****************************************************************************/
  4472. void close_cnum(int cnum, uint16 vuid)
  4473. {
  4474.   DirCacheFlush(SNUM(cnum));
  4475.  
  4476.   unbecome_user();
  4477.  
  4478.   if (!OPEN_CNUM(cnum))
  4479.     {
  4480.       DEBUG(0,("Can't close cnum %d\n",cnum));
  4481.       return;
  4482.     }
  4483.  
  4484.   DEBUG(IS_IPC(cnum)?3:1,("%s %s (%s) closed connection to service %s\n",
  4485.               timestring(),
  4486.               remote_machine,client_addr(),
  4487.               lp_servicename(SNUM(cnum))));
  4488.  
  4489.   yield_connection(cnum,
  4490.            lp_servicename(SNUM(cnum)),
  4491.            lp_max_connections(SNUM(cnum)));
  4492.  
  4493.   if (lp_status(SNUM(cnum)))
  4494.     yield_connection(cnum,"STATUS.",MAXSTATUS);
  4495.  
  4496.   close_open_files(cnum);
  4497.   dptr_closecnum(cnum);
  4498.  
  4499.   /* execute any "postexec = " line */
  4500.   if (*lp_postexec(SNUM(cnum)) && become_user(&Connections[cnum], cnum,vuid))
  4501.     {
  4502.       pstring cmd;
  4503.       pstrcpy(cmd,lp_postexec(SNUM(cnum)));
  4504.       standard_sub(cnum,cmd);
  4505.       smbrun(cmd,NULL,False);
  4506.       unbecome_user();
  4507.     }
  4508.  
  4509.   unbecome_user();
  4510.   /* execute any "root postexec = " line */
  4511.   if (*lp_rootpostexec(SNUM(cnum)))
  4512.     {
  4513.       pstring cmd;
  4514.       pstrcpy(cmd,lp_rootpostexec(SNUM(cnum)));
  4515.       standard_sub(cnum,cmd);
  4516.       smbrun(cmd,NULL,False);
  4517.     }
  4518.  
  4519.   Connections[cnum].open = False;
  4520.   num_connections_open--;
  4521.   if (Connections[cnum].ngroups && Connections[cnum].groups)
  4522.     {
  4523.       if (Connections[cnum].igroups != (int *)Connections[cnum].groups)
  4524.     free(Connections[cnum].groups);
  4525.       free(Connections[cnum].igroups);
  4526.       Connections[cnum].groups = NULL;
  4527.       Connections[cnum].igroups = NULL;
  4528.       Connections[cnum].ngroups = 0;
  4529.     }
  4530.  
  4531.   free_namearray(Connections[cnum].veto_list);
  4532.   free_namearray(Connections[cnum].hide_list);
  4533.   free_namearray(Connections[cnum].veto_oplock_list);
  4534.  
  4535.   string_set(&Connections[cnum].user,"");
  4536.   string_set(&Connections[cnum].dirpath,"");
  4537.   string_set(&Connections[cnum].connectpath,"");
  4538. }
  4539.  
  4540.  
  4541. /****************************************************************************
  4542. simple routines to do connection counting
  4543. ****************************************************************************/
  4544. BOOL yield_connection(int cnum,char *name,int max_connections)
  4545. {
  4546.   struct connect_record crec;
  4547.   pstring fname;
  4548.   FILE *f;
  4549.   int mypid = getpid();
  4550.   int i;
  4551.  
  4552.   DEBUG(3,("Yielding connection to %d %s\n",cnum,name));
  4553.  
  4554.   if (max_connections <= 0)
  4555.     return(True);
  4556.  
  4557.   bzero(&crec,sizeof(crec));
  4558.  
  4559.   pstrcpy(fname,lp_lockdir());
  4560.   standard_sub(cnum,fname);
  4561.   trim_string(fname,"","/");
  4562.  
  4563.   pstrcat(fname,"/");
  4564.   pstrcat(fname,name);
  4565.   pstrcat(fname,".LCK");
  4566.  
  4567.   f = fopen(fname,"r+");
  4568.   if (!f)
  4569.     {
  4570.       DEBUG(2,("Couldn't open lock file %s (%s)\n",fname,strerror(errno)));
  4571.       return(False);
  4572.     }
  4573.  
  4574.   fseek(f,0,SEEK_SET);
  4575.  
  4576.   /* find a free spot */
  4577.   for (i=0;i<max_connections;i++)
  4578.     {
  4579.       if (fread(&crec,sizeof(crec),1,f) != 1)
  4580.     {
  4581.       DEBUG(2,("Entry not found in lock file %s\n",fname));
  4582.       fclose(f);
  4583.       return(False);
  4584.     }
  4585.       if (crec.pid == mypid && crec.cnum == cnum)
  4586.     break;
  4587.     }
  4588.  
  4589.   if (crec.pid != mypid || crec.cnum != cnum)
  4590.     {
  4591.       fclose(f);
  4592.       DEBUG(2,("Entry not found in lock file %s\n",fname));
  4593.       return(False);
  4594.     }
  4595.  
  4596.   bzero((void *)&crec,sizeof(crec));
  4597.   
  4598.   /* remove our mark */
  4599.   if (fseek(f,i*sizeof(crec),SEEK_SET) != 0 ||
  4600.       fwrite(&crec,sizeof(crec),1,f) != 1)
  4601.     {
  4602.       DEBUG(2,("Couldn't update lock file %s (%s)\n",fname,strerror(errno)));
  4603.       fclose(f);
  4604.       return(False);
  4605.     }
  4606.  
  4607.   DEBUG(3,("Yield successful\n"));
  4608.  
  4609.   fclose(f);
  4610.   return(True);
  4611. }
  4612.  
  4613.  
  4614. /****************************************************************************
  4615. simple routines to do connection counting
  4616. ****************************************************************************/
  4617. BOOL claim_connection(int cnum,char *name,int max_connections,BOOL Clear)
  4618. {
  4619.   struct connect_record crec;
  4620.   pstring fname;
  4621.   FILE *f;
  4622.   int snum = SNUM(cnum);
  4623.   int i,foundi= -1;
  4624.   int total_recs;
  4625.  
  4626.   if (max_connections <= 0)
  4627.     return(True);
  4628.  
  4629.   DEBUG(5,("trying claim %s %s %d\n",lp_lockdir(),name,max_connections));
  4630.  
  4631.   pstrcpy(fname,lp_lockdir());
  4632.   standard_sub(cnum,fname);
  4633.   trim_string(fname,"","/");
  4634.  
  4635.   if (!directory_exist(fname,NULL))
  4636.     mkdir(fname,0755);
  4637.  
  4638.   pstrcat(fname,"/");
  4639.   pstrcat(fname,name);
  4640.   pstrcat(fname,".LCK");
  4641.  
  4642.   if (!file_exist(fname,NULL))
  4643.     {
  4644.       int oldmask = umask(022);
  4645.       f = fopen(fname,"w");
  4646.       if (f) fclose(f);
  4647.       umask(oldmask);
  4648.     }
  4649.  
  4650.   total_recs = file_size(fname) / sizeof(crec);
  4651.  
  4652.   f = fopen(fname,"r+");
  4653.  
  4654.   if (!f)
  4655.     {
  4656.       DEBUG(1,("couldn't open lock file %s\n",fname));
  4657.       return(False);
  4658.     }
  4659.  
  4660.   /* find a free spot */
  4661.   for (i=0;i<max_connections;i++)
  4662.     {
  4663.  
  4664.       if (i>=total_recs || 
  4665.       fseek(f,i*sizeof(crec),SEEK_SET) != 0 ||
  4666.       fread(&crec,sizeof(crec),1,f) != 1)
  4667.     {
  4668.       if (foundi < 0) foundi = i;
  4669.       break;
  4670.     }
  4671.  
  4672.       if (Clear && crec.pid && !process_exists(crec.pid))
  4673.     {
  4674.       fseek(f,i*sizeof(crec),SEEK_SET);
  4675.       bzero((void *)&crec,sizeof(crec));
  4676.       fwrite(&crec,sizeof(crec),1,f);
  4677.       if (foundi < 0) foundi = i;
  4678.       continue;
  4679.     }
  4680.       if (foundi < 0 && (!crec.pid || !process_exists(crec.pid)))
  4681.     {
  4682.       foundi=i;
  4683.       if (!Clear) break;
  4684.     }
  4685.     }  
  4686.  
  4687.   if (foundi < 0)
  4688.     {
  4689.       DEBUG(3,("no free locks in %s\n",fname));
  4690.       fclose(f);
  4691.       return(False);
  4692.     }      
  4693.  
  4694.   /* fill in the crec */
  4695.   bzero((void *)&crec,sizeof(crec));
  4696.   crec.magic = 0x280267;
  4697.   crec.pid = getpid();
  4698.   crec.cnum = cnum;
  4699.   crec.uid = Connections[cnum].uid;
  4700.   crec.gid = Connections[cnum].gid;
  4701.   StrnCpy(crec.name,lp_servicename(snum),sizeof(crec.name)-1);
  4702.   crec.start = time(NULL);
  4703.  
  4704.   StrnCpy(crec.machine,remote_machine,sizeof(crec.machine)-1);
  4705.   StrnCpy(crec.addr,client_addr(),sizeof(crec.addr)-1);
  4706.   
  4707.   /* make our mark */
  4708.   if (fseek(f,foundi*sizeof(crec),SEEK_SET) != 0 ||
  4709.       fwrite(&crec,sizeof(crec),1,f) != 1)
  4710.     {
  4711.       fclose(f);
  4712.       return(False);
  4713.     }
  4714.  
  4715.   fclose(f);
  4716.   return(True);
  4717. }
  4718.  
  4719. #if DUMP_CORE
  4720. /*******************************************************************
  4721. prepare to dump a core file - carefully!
  4722. ********************************************************************/
  4723. static BOOL dump_core(void)
  4724. {
  4725.   char *p;
  4726.   pstring dname;
  4727.   pstrcpy(dname,debugf);
  4728.   if ((p=strrchr(dname,'/'))) *p=0;
  4729.   pstrcat(dname,"/corefiles");
  4730.   mkdir(dname,0700);
  4731.   sys_chown(dname,getuid(),getgid());
  4732.   chmod(dname,0700);
  4733.   if (chdir(dname)) return(False);
  4734.   umask(~(0700));
  4735.  
  4736. #ifndef NO_GETRLIMIT
  4737. #ifdef RLIMIT_CORE
  4738.   {
  4739.     struct rlimit rlp;
  4740.     getrlimit(RLIMIT_CORE, &rlp);
  4741.     rlp.rlim_cur = MAX(4*1024*1024,rlp.rlim_cur);
  4742.     setrlimit(RLIMIT_CORE, &rlp);
  4743.     getrlimit(RLIMIT_CORE, &rlp);
  4744.     DEBUG(3,("Core limits now %d %d\n",rlp.rlim_cur,rlp.rlim_max));
  4745.   }
  4746. #endif
  4747. #endif
  4748.  
  4749.  
  4750.   DEBUG(0,("Dumping core in %s\n",dname));
  4751.   return(True);
  4752. }
  4753. #endif
  4754.  
  4755. /****************************************************************************
  4756. exit the server
  4757. ****************************************************************************/
  4758. void exit_server(char *reason)
  4759. {
  4760.   static int firsttime=1;
  4761.   int i;
  4762.  
  4763.   if (!firsttime) exit(0);
  4764.   firsttime = 0;
  4765.  
  4766.   unbecome_user();
  4767.   DEBUG(2,("Closing connections\n"));
  4768.   for (i=0;i<MAX_CONNECTIONS;i++)
  4769.     if (Connections[i].open)
  4770.       close_cnum(i,(uint16)-1);
  4771. #ifdef DFS_AUTH
  4772.   if (dcelogin_atmost_once)
  4773.     dfs_unlogin();
  4774. #endif
  4775.   if (!reason) {   
  4776.     int oldlevel = DEBUGLEVEL;
  4777.     DEBUGLEVEL = 10;
  4778.     DEBUG(0,("Last message was %s\n",smb_fn_name(last_message)));
  4779.     if (last_inbuf)
  4780.       show_msg(last_inbuf);
  4781.     DEBUGLEVEL = oldlevel;
  4782.     DEBUG(0,("===============================================================\n"));
  4783. #if DUMP_CORE
  4784.     if (dump_core()) return;
  4785. #endif
  4786.   }    
  4787.  
  4788.   locking_end();
  4789.  
  4790.   DEBUG(3,("%s Server exit  (%s)\n",timestring(),reason?reason:""));
  4791.   exit(0);
  4792. }
  4793.  
  4794. /****************************************************************************
  4795. do some standard substitutions in a string
  4796. ****************************************************************************/
  4797. void standard_sub(int cnum,char *str)
  4798. {
  4799.   if (VALID_CNUM(cnum)) {
  4800.     char *p, *s, *home;
  4801.  
  4802.     for ( s=str ; (p=strchr(s, '%')) != NULL ; s=p ) {
  4803.       switch (*(p+1)) {
  4804.         case 'H' : if ((home = get_home_dir(Connections[cnum].user))!=NULL)
  4805.                      string_sub(p,"%H",home);
  4806.                    else
  4807.                      p += 2;
  4808.                    break;
  4809.         case 'P' : string_sub(p,"%P",Connections[cnum].connectpath); break;
  4810.         case 'S' : string_sub(p,"%S",lp_servicename(Connections[cnum].service)); break;
  4811.         case 'g' : string_sub(p,"%g",gidtoname(Connections[cnum].gid)); break;
  4812.         case 'u' : string_sub(p,"%u",Connections[cnum].user); break;
  4813.     /* 
  4814.          * Patch from jkf@soton.ac.uk
  4815.          * Left the %N (NIS server name) in standard_sub_basic as it
  4816.          * is a feature for logon servers, hence uses the username.
  4817.      * The %p (NIS server path) code is here as it is used
  4818.      * instead of the default "path =" string in [homes] and so
  4819.      * needs the service name, not the username. 
  4820.          */
  4821.     case 'p' : string_sub(p,"%p",automount_path(lp_servicename(Connections[cnum].service))); break;
  4822.         case '\0' : p++; break; /* don't run off the end of the string */
  4823.         default  : p+=2; break;
  4824.       }
  4825.     }
  4826.   }
  4827.   standard_sub_basic(str);
  4828. }
  4829.  
  4830. /*
  4831. These flags determine some of the permissions required to do an operation 
  4832.  
  4833. Note that I don't set NEED_WRITE on some write operations because they
  4834. are used by some brain-dead clients when printing, and I don't want to
  4835. force write permissions on print services.
  4836. */
  4837. #define AS_USER (1<<0)
  4838. #define NEED_WRITE (1<<1)
  4839. #define TIME_INIT (1<<2)
  4840. #define CAN_IPC (1<<3)
  4841. #define AS_GUEST (1<<5)
  4842. #define QUEUE_IN_OPLOCK (1<<6)
  4843.  
  4844. /* 
  4845.    define a list of possible SMB messages and their corresponding
  4846.    functions. Any message that has a NULL function is unimplemented -
  4847.    please feel free to contribute implementations!
  4848. */
  4849.  
  4850. struct smb_message_struct
  4851. {
  4852.   int code;
  4853.   char *name;
  4854.   int (*fn)(char *, char *, int, int);
  4855.   int flags;
  4856. #if PROFILING
  4857.   unsigned long time;
  4858. #endif
  4859. }
  4860.  smb_messages[] = {
  4861.  
  4862.     /* CORE PROTOCOL */
  4863.  
  4864.    {SMBnegprot,"SMBnegprot",reply_negprot,0},
  4865.    {SMBtcon,"SMBtcon",reply_tcon,0},
  4866.    {SMBtdis,"SMBtdis",reply_tdis,0},
  4867.    {SMBexit,"SMBexit",reply_exit,0},
  4868.    {SMBioctl,"SMBioctl",reply_ioctl,0},
  4869.    {SMBecho,"SMBecho",reply_echo,0},
  4870.    {SMBsesssetupX,"SMBsesssetupX",reply_sesssetup_and_X,0},
  4871.    {SMBtconX,"SMBtconX",reply_tcon_and_X,0},
  4872.    {SMBulogoffX, "SMBulogoffX",reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
  4873.    {SMBgetatr,"SMBgetatr",reply_getatr,AS_USER},
  4874.    {SMBsetatr,"SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
  4875.    {SMBchkpth,"SMBchkpth",reply_chkpth,AS_USER},
  4876.    {SMBsearch,"SMBsearch",reply_search,AS_USER},
  4877.    {SMBopen,"SMBopen",reply_open,AS_USER | QUEUE_IN_OPLOCK },
  4878.  
  4879.    /* note that SMBmknew and SMBcreate are deliberately overloaded */   
  4880.    {SMBcreate,"SMBcreate",reply_mknew,AS_USER},
  4881.    {SMBmknew,"SMBmknew",reply_mknew,AS_USER}, 
  4882.  
  4883.    {SMBunlink,"SMBunlink",reply_unlink,AS_USER | NEED_WRITE | QUEUE_IN_OPLOCK},
  4884.    {SMBread,"SMBread",reply_read,AS_USER},
  4885.    {SMBwrite,"SMBwrite",reply_write,AS_USER},
  4886.    {SMBclose,"SMBclose",reply_close,AS_USER | CAN_IPC},
  4887.    {SMBmkdir,"SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
  4888.    {SMBrmdir,"SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
  4889.    {SMBdskattr,"SMBdskattr",reply_dskattr,AS_USER},
  4890.    {SMBmv,"SMBmv",reply_mv,AS_USER | NEED_WRITE | QUEUE_IN_OPLOCK},
  4891.  
  4892.    /* this is a Pathworks specific call, allowing the 
  4893.       changing of the root path */
  4894.    {pSETDIR,"pSETDIR",reply_setdir,AS_USER}, 
  4895.  
  4896.    {SMBlseek,"SMBlseek",reply_lseek,AS_USER},
  4897.    {SMBflush,"SMBflush",reply_flush,AS_USER},
  4898.    {SMBctemp,"SMBctemp",reply_ctemp,AS_USER | QUEUE_IN_OPLOCK },
  4899.    {SMBsplopen,"SMBsplopen",reply_printopen,AS_USER | QUEUE_IN_OPLOCK },
  4900.    {SMBsplclose,"SMBsplclose",reply_printclose,AS_USER},
  4901.    {SMBsplretq,"SMBsplretq",reply_printqueue,AS_USER|AS_GUEST},
  4902.    {SMBsplwr,"SMBsplwr",reply_printwrite,AS_USER},
  4903.    {SMBlock,"SMBlock",reply_lock,AS_USER},
  4904.    {SMBunlock,"SMBunlock",reply_unlock,AS_USER},
  4905.    
  4906.    /* CORE+ PROTOCOL FOLLOWS */
  4907.    
  4908.    {SMBreadbraw,"SMBreadbraw",reply_readbraw,AS_USER},
  4909.    {SMBwritebraw,"SMBwritebraw",reply_writebraw,AS_USER},
  4910.    {SMBwriteclose,"SMBwriteclose",reply_writeclose,AS_USER},
  4911.    {SMBlockread,"SMBlockread",reply_lockread,AS_USER},
  4912.    {SMBwriteunlock,"SMBwriteunlock",reply_writeunlock,AS_USER},
  4913.    
  4914.    /* LANMAN1.0 PROTOCOL FOLLOWS */
  4915.    
  4916.    {SMBreadBmpx,"SMBreadBmpx",reply_readbmpx,AS_USER},
  4917.    {SMBreadBs,"SMBreadBs",NULL,AS_USER},
  4918.    {SMBwriteBmpx,"SMBwriteBmpx",reply_writebmpx,AS_USER},
  4919.    {SMBwriteBs,"SMBwriteBs",reply_writebs,AS_USER},
  4920.    {SMBwritec,"SMBwritec",NULL,AS_USER},
  4921.    {SMBsetattrE,"SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE},
  4922.    {SMBgetattrE,"SMBgetattrE",reply_getattrE,AS_USER},
  4923.    {SMBtrans,"SMBtrans",reply_trans,AS_USER | CAN_IPC},
  4924.    {SMBtranss,"SMBtranss",NULL,AS_USER | CAN_IPC},
  4925.    {SMBioctls,"SMBioctls",NULL,AS_USER},
  4926.    {SMBcopy,"SMBcopy",reply_copy,AS_USER | NEED_WRITE | QUEUE_IN_OPLOCK },
  4927.    {SMBmove,"SMBmove",NULL,AS_USER | NEED_WRITE | QUEUE_IN_OPLOCK },
  4928.    
  4929.    {SMBopenX,"SMBopenX",reply_open_and_X,AS_USER | CAN_IPC | QUEUE_IN_OPLOCK },
  4930.    {SMBreadX,"SMBreadX",reply_read_and_X,AS_USER},
  4931.    {SMBwriteX,"SMBwriteX",reply_write_and_X,AS_USER},
  4932.    {SMBlockingX,"SMBlockingX",reply_lockingX,AS_USER},
  4933.    
  4934.    {SMBffirst,"SMBffirst",reply_search,AS_USER},
  4935.    {SMBfunique,"SMBfunique",reply_search,AS_USER},
  4936.    {SMBfclose,"SMBfclose",reply_fclose,AS_USER},
  4937.  
  4938.    /* LANMAN2.0 PROTOCOL FOLLOWS */
  4939.    {SMBfindnclose, "SMBfindnclose",reply_findnclose, AS_USER},
  4940.    {SMBfindclose, "SMBfindclose",reply_findclose,AS_USER},
  4941.    {SMBtrans2, "SMBtrans2",reply_trans2, AS_USER},
  4942.    {SMBtranss2, "SMBtranss2",reply_transs2, AS_USER},
  4943.  
  4944.    /* messaging routines */
  4945.    {SMBsends,"SMBsends",reply_sends,AS_GUEST},
  4946.    {SMBsendstrt,"SMBsendstrt",reply_sendstrt,AS_GUEST},
  4947.    {SMBsendend,"SMBsendend",reply_sendend,AS_GUEST},
  4948.    {SMBsendtxt,"SMBsendtxt",reply_sendtxt,AS_GUEST},
  4949.  
  4950.    /* NON-IMPLEMENTED PARTS OF THE CORE PROTOCOL */
  4951.    
  4952.    {SMBsendb,"SMBsendb",NULL,AS_GUEST},
  4953.    {SMBfwdname,"SMBfwdname",NULL,AS_GUEST},
  4954.    {SMBcancelf,"SMBcancelf",NULL,AS_GUEST},
  4955.    {SMBgetmac,"SMBgetmac",NULL,AS_GUEST}
  4956.  };
  4957.  
  4958. /****************************************************************************
  4959. return a string containing the function name of a SMB command
  4960. ****************************************************************************/
  4961. char *smb_fn_name(int type)
  4962. {
  4963.   static char *unknown_name = "SMBunknown";
  4964.   static int num_smb_messages = 
  4965.     sizeof(smb_messages) / sizeof(struct smb_message_struct);
  4966.   int match;
  4967.  
  4968.   for (match=0;match<num_smb_messages;match++)
  4969.     if (smb_messages[match].code == type)
  4970.       break;
  4971.  
  4972.   if (match == num_smb_messages)
  4973.     return(unknown_name);
  4974.  
  4975.   return(smb_messages[match].name);
  4976. }
  4977.  
  4978.  
  4979. /****************************************************************************
  4980. do a switch on the message type, and return the response size
  4981. ****************************************************************************/
  4982. static int switch_message(int type,char *inbuf,char *outbuf,int size,int bufsize)
  4983. {
  4984.   static int pid= -1;
  4985.   int outsize = 0;
  4986.   static int num_smb_messages = 
  4987.     sizeof(smb_messages) / sizeof(struct smb_message_struct);
  4988.   int match;
  4989.  
  4990. #if PROFILING
  4991.   struct timeval msg_start_time;
  4992.   struct timeval msg_end_time;
  4993.   static unsigned long total_time = 0;
  4994.  
  4995.   GetTimeOfDay(&msg_start_time);
  4996. #endif
  4997.  
  4998.   if (pid == -1)
  4999.     pid = getpid();
  5000.  
  5001.   errno = 0;
  5002.   last_message = type;
  5003.  
  5004.   /* make sure this is an SMB packet */
  5005.   if (strncmp(smb_base(inbuf),"\377SMB",4) != 0)
  5006.     {
  5007.       DEBUG(2,("Non-SMB packet of length %d\n",smb_len(inbuf)));
  5008.       return(-1);
  5009.     }
  5010.  
  5011.   for (match=0;match<num_smb_messages;match++)
  5012.     if (smb_messages[match].code == type)
  5013.       break;
  5014.  
  5015.   if (match == num_smb_messages)
  5016.     {
  5017.       DEBUG(0,("Unknown message type %d!\n",type));
  5018.       outsize = reply_unknown(inbuf,outbuf);
  5019.     }
  5020.   else
  5021.     {
  5022.       DEBUG(3,("switch message %s (pid %d)\n",smb_messages[match].name,pid));
  5023.  
  5024.       if(global_oplock_break && (smb_messages[match].flags & QUEUE_IN_OPLOCK))
  5025.       {
  5026.         /* 
  5027.          * Queue this message as we are the process of an oplock break.
  5028.          */
  5029.  
  5030.         DEBUG(2,("%s: switch_message: queueing message due to being in oplock break state.\n",
  5031.                timestring() ));
  5032.  
  5033.         push_smb_message( inbuf, size);
  5034.         return -1;
  5035.       }          
  5036.  
  5037.       if (smb_messages[match].fn)
  5038.     {
  5039.       int cnum = SVAL(inbuf,smb_tid);
  5040.       int flags = smb_messages[match].flags;
  5041.           static uint16 last_session_tag = UID_FIELD_INVALID;
  5042.           /* In share mode security we must ignore the vuid. */
  5043.       uint16 session_tag = (lp_security() == SEC_SHARE) ? UID_FIELD_INVALID : SVAL(inbuf,smb_uid);
  5044.           /* Ensure this value is replaced in the incoming packet. */
  5045.           SSVAL(inbuf,smb_uid,session_tag);
  5046.  
  5047.           /*
  5048.            * Ensure the correct username is in sesssetup_user.
  5049.            * This is a really ugly bugfix for problems with
  5050.            * multiple session_setup_and_X's being done and
  5051.            * allowing %U and %G substitutions to work correctly.
  5052.            * There is a reason this code is done here, don't
  5053.            * move it unless you know what you're doing... :-).
  5054.            * JRA.
  5055.            */
  5056.           if(session_tag != last_session_tag ) {
  5057.             user_struct *vuser = NULL;
  5058.  
  5059.             last_session_tag = session_tag;
  5060.             if(session_tag != UID_FIELD_INVALID)
  5061.               vuser = get_valid_user_struct(session_tag);
  5062.             if(vuser != NULL)
  5063.               pstrcpy( sesssetup_user, vuser->requested_name);
  5064.           }
  5065.  
  5066.       /* does this protocol need to be run as root? */
  5067.       if (!(flags & AS_USER))
  5068.         unbecome_user();
  5069.  
  5070.       /* does this protocol need to be run as the connected user? */
  5071.       if ((flags & AS_USER) && !become_user(&Connections[cnum], cnum,session_tag)) {
  5072.         if (flags & AS_GUEST) 
  5073.           flags &= ~AS_USER;
  5074.         else
  5075.           return(ERROR(ERRSRV,ERRinvnid));
  5076.       }
  5077.       /* this code is to work around a bug is MS client 3 without
  5078.          introducing a security hole - it needs to be able to do
  5079.          print queue checks as guest if it isn't logged in properly */
  5080.       if (flags & AS_USER)
  5081.         flags &= ~AS_GUEST;
  5082.  
  5083.       /* does it need write permission? */
  5084.       if ((flags & NEED_WRITE) && !CAN_WRITE(cnum))
  5085.         return(ERROR(ERRSRV,ERRaccess));
  5086.  
  5087.       /* ipc services are limited */
  5088.       if (IS_IPC(cnum) && (flags & AS_USER) && !(flags & CAN_IPC))
  5089.         return(ERROR(ERRSRV,ERRaccess));        
  5090.  
  5091.       /* load service specific parameters */
  5092.       if (OPEN_CNUM(cnum) && !become_service(cnum,(flags & AS_USER)?True:False))
  5093.         return(ERROR(ERRSRV,ERRaccess));
  5094.  
  5095.       /* does this protocol need to be run as guest? */
  5096.       if ((flags & AS_GUEST) && (!become_guest() || !check_access(-1)))
  5097.         return(ERROR(ERRSRV,ERRaccess));
  5098.  
  5099.       last_inbuf = inbuf;
  5100.  
  5101.       outsize = smb_messages[match].fn(inbuf,outbuf,size,bufsize);
  5102.     }
  5103.       else
  5104.     {
  5105.       outsize = reply_unknown(inbuf,outbuf);
  5106.     }
  5107.     }
  5108.  
  5109. #if PROFILING
  5110.   GetTimeOfDay(&msg_end_time);
  5111.   if (!(smb_messages[match].flags & TIME_INIT))
  5112.     {
  5113.       smb_messages[match].time = 0;
  5114.       smb_messages[match].flags |= TIME_INIT;
  5115.     }
  5116.   {
  5117.     unsigned long this_time =     
  5118.       (msg_end_time.tv_sec - msg_start_time.tv_sec)*1e6 +
  5119.     (msg_end_time.tv_usec - msg_start_time.tv_usec);
  5120.     smb_messages[match].time += this_time;
  5121.     total_time += this_time;
  5122.   }
  5123.   DEBUG(2,("TIME %s  %d usecs   %g pct\n",
  5124.        smb_fn_name(type),smb_messages[match].time,
  5125.     (100.0*smb_messages[match].time) / total_time));
  5126. #endif
  5127.  
  5128.   return(outsize);
  5129. }
  5130.  
  5131.  
  5132. /****************************************************************************
  5133.   construct a chained reply and add it to the already made reply
  5134.   **************************************************************************/
  5135. int chain_reply(char *inbuf,char *outbuf,int size,int bufsize)
  5136. {
  5137.   static char *orig_inbuf;
  5138.   static char *orig_outbuf;
  5139.   int smb_com1, smb_com2 = CVAL(inbuf,smb_vwv0);
  5140.   unsigned smb_off2 = SVAL(inbuf,smb_vwv1);
  5141.   char *inbuf2, *outbuf2;
  5142.   int outsize2;
  5143.   char inbuf_saved[smb_wct];
  5144.   char outbuf_saved[smb_wct];
  5145.   extern int chain_size;
  5146.   int wct = CVAL(outbuf,smb_wct);
  5147.   int outsize = smb_size + 2*wct + SVAL(outbuf,smb_vwv0+2*wct);
  5148.  
  5149.   /* maybe its not chained */
  5150.   if (smb_com2 == 0xFF) {
  5151.     CVAL(outbuf,smb_vwv0) = 0xFF;
  5152.     return outsize;
  5153.   }
  5154.  
  5155.   if (chain_size == 0) {
  5156.     /* this is the first part of the chain */
  5157.     orig_inbuf = inbuf;
  5158.     orig_outbuf = outbuf;
  5159.   }
  5160.  
  5161.   /* we need to tell the client where the next part of the reply will be */
  5162.   SSVAL(outbuf,smb_vwv1,smb_offset(outbuf+outsize,outbuf));
  5163.   CVAL(outbuf,smb_vwv0) = smb_com2;
  5164.  
  5165.   /* remember how much the caller added to the chain, only counting stuff
  5166.      after the parameter words */
  5167.   chain_size += outsize - smb_wct;
  5168.  
  5169.   /* work out pointers into the original packets. The
  5170.      headers on these need to be filled in */
  5171.   inbuf2 = orig_inbuf + smb_off2 + 4 - smb_wct;
  5172.   outbuf2 = orig_outbuf + SVAL(outbuf,smb_vwv1) + 4 - smb_wct;
  5173.  
  5174.   /* remember the original command type */
  5175.   smb_com1 = CVAL(orig_inbuf,smb_com);
  5176.  
  5177.   /* save the data which will be overwritten by the new headers */
  5178.   memcpy(inbuf_saved,inbuf2,smb_wct);
  5179.   memcpy(outbuf_saved,outbuf2,smb_wct);
  5180.  
  5181.   /* give the new packet the same header as the last part of the SMB */
  5182.   memmove(inbuf2,inbuf,smb_wct);
  5183.  
  5184.   /* create the in buffer */
  5185.   CVAL(inbuf2,smb_com) = smb_com2;
  5186.  
  5187.   /* create the out buffer */
  5188.   bzero(outbuf2,smb_size);
  5189.   set_message(outbuf2,0,0,True);
  5190.   CVAL(outbuf2,smb_com) = CVAL(inbuf2,smb_com);
  5191.   
  5192.   memcpy(outbuf2+4,inbuf2+4,4);
  5193.   CVAL(outbuf2,smb_rcls) = SMB_SUCCESS;
  5194.   CVAL(outbuf2,smb_reh) = 0;
  5195.   CVAL(outbuf2,smb_flg) = 0x80 | (CVAL(inbuf2,smb_flg) & 0x8); /* bit 7 set 
  5196.                                   means a reply */
  5197.   SSVAL(outbuf2,smb_flg2,1); /* say we support long filenames */
  5198.   SSVAL(outbuf2,smb_err,SMB_SUCCESS);
  5199.   SSVAL(outbuf2,smb_tid,SVAL(inbuf2,smb_tid));
  5200.   SSVAL(outbuf2,smb_pid,SVAL(inbuf2,smb_pid));
  5201.   SSVAL(outbuf2,smb_uid,SVAL(inbuf2,smb_uid));
  5202.   SSVAL(outbuf2,smb_mid,SVAL(inbuf2,smb_mid));
  5203.  
  5204.   DEBUG(3,("Chained message\n"));
  5205.   show_msg(inbuf2);
  5206.  
  5207.   /* process the request */
  5208.   outsize2 = switch_message(smb_com2,inbuf2,outbuf2,size-chain_size,
  5209.                 bufsize-chain_size);
  5210.  
  5211.   /* copy the new reply and request headers over the old ones, but
  5212.      preserve the smb_com field */
  5213.   memmove(orig_outbuf,outbuf2,smb_wct);
  5214.   CVAL(orig_outbuf,smb_com) = smb_com1;
  5215.  
  5216.   /* restore the saved data, being careful not to overwrite any
  5217.    data from the reply header */
  5218.   memcpy(inbuf2,inbuf_saved,smb_wct);
  5219.   {
  5220.     int ofs = smb_wct - PTR_DIFF(outbuf2,orig_outbuf);
  5221.     if (ofs < 0) ofs = 0;
  5222.     memmove(outbuf2+ofs,outbuf_saved+ofs,smb_wct-ofs);
  5223.   }
  5224.  
  5225.   return outsize2;
  5226. }
  5227.  
  5228.  
  5229.  
  5230. /****************************************************************************
  5231.   construct a reply to the incoming packet
  5232. ****************************************************************************/
  5233. int construct_reply(char *inbuf,char *outbuf,int size,int bufsize)
  5234. {
  5235.   int type = CVAL(inbuf,smb_com);
  5236.   int outsize = 0;
  5237.   int msg_type = CVAL(inbuf,0);
  5238.   extern int chain_size;
  5239.  
  5240.   smb_last_time = time(NULL);
  5241.  
  5242.   chain_size = 0;
  5243.   chain_fnum = -1;
  5244.   reset_chain_pnum();
  5245.  
  5246.   bzero(outbuf,smb_size);
  5247.  
  5248.   if (msg_type != 0)
  5249.     return(reply_special(inbuf,outbuf));  
  5250.  
  5251.   CVAL(outbuf,smb_com) = CVAL(inbuf,smb_com);
  5252.   set_message(outbuf,0,0,True);
  5253.   
  5254.   memcpy(outbuf+4,inbuf+4,4);
  5255.   CVAL(outbuf,smb_rcls) = SMB_SUCCESS;
  5256.   CVAL(outbuf,smb_reh) = 0;
  5257.   CVAL(outbuf,smb_flg) = 0x80 | (CVAL(inbuf,smb_flg) & 0x8); /* bit 7 set 
  5258.                                  means a reply */
  5259.   SSVAL(outbuf,smb_flg2,1); /* say we support long filenames */
  5260.   SSVAL(outbuf,smb_err,SMB_SUCCESS);
  5261.   SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
  5262.   SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
  5263.   SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
  5264.   SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
  5265.  
  5266.   outsize = switch_message(type,inbuf,outbuf,size,bufsize);
  5267.  
  5268.   outsize += chain_size;
  5269.  
  5270.   if(outsize > 4)
  5271.     smb_setlen(outbuf,outsize - 4);
  5272.   return(outsize);
  5273. }
  5274.  
  5275. /****************************************************************************
  5276.   process commands from the client
  5277. ****************************************************************************/
  5278. static void process(void)
  5279. {
  5280.   extern int Client;
  5281.  
  5282.   InBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
  5283.   OutBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
  5284.   if ((InBuffer == NULL) || (OutBuffer == NULL)) 
  5285.     return;
  5286.  
  5287.   InBuffer += SMB_ALIGNMENT;
  5288.   OutBuffer += SMB_ALIGNMENT;
  5289.  
  5290. #if PRIME_NMBD
  5291.   DEBUG(3,("priming nmbd\n"));
  5292.   {
  5293.     struct in_addr ip;
  5294.     ip = *interpret_addr2("localhost");
  5295.     if (zero_ip(ip)) ip = *interpret_addr2("127.0.0.1");
  5296.     *OutBuffer = 0;
  5297.     send_one_packet(OutBuffer,1,ip,NMB_PORT,SOCK_DGRAM);
  5298.   }
  5299. #endif    
  5300.  
  5301.   /* re-initialise the timezone */
  5302.   TimeInit();
  5303.  
  5304.   while (True)
  5305.   {
  5306.     int deadtime = lp_deadtime()*60;
  5307.     int counter;
  5308.     int last_keepalive=0;
  5309.     int service_load_counter = 0;
  5310.     BOOL got_smb = False;
  5311.  
  5312.     if (deadtime <= 0)
  5313.       deadtime = DEFAULT_SMBD_TIMEOUT;
  5314.  
  5315. #if USE_READ_PREDICTION
  5316.     if (lp_readprediction())
  5317.       do_read_prediction();
  5318. #endif
  5319.  
  5320.     errno = 0;      
  5321.  
  5322.     for (counter=SMBD_SELECT_LOOP; 
  5323.           !receive_message_or_smb(Client,oplock_sock,
  5324.                       InBuffer,BUFFER_SIZE,SMBD_SELECT_LOOP*1000,&got_smb); 
  5325.           counter += SMBD_SELECT_LOOP)
  5326.     {
  5327.       int i;
  5328.       time_t t;
  5329.       BOOL allidle = True;
  5330.       extern int keepalive;
  5331.  
  5332.       if (counter > 365 * 3600) /* big number of seconds. */
  5333.       {
  5334.         counter = 0;
  5335.         service_load_counter = 0;
  5336.       }
  5337.  
  5338.       if (smb_read_error == READ_EOF) 
  5339.       {
  5340.         DEBUG(3,("end of file from client\n"));
  5341.         return;
  5342.       }
  5343.  
  5344.       if (smb_read_error == READ_ERROR) 
  5345.       {
  5346.         DEBUG(3,("receive_smb error (%s) exiting\n",
  5347.                   strerror(errno)));
  5348.         return;
  5349.       }
  5350.  
  5351.       t = time(NULL);
  5352.  
  5353.       /* become root again if waiting */
  5354.       unbecome_user();
  5355.  
  5356.       /* check for smb.conf reload */
  5357.       if (counter >= service_load_counter + SMBD_RELOAD_CHECK)
  5358.       {
  5359.         service_load_counter = counter;
  5360.  
  5361.         /* reload services, if files have changed. */
  5362.         reload_services(True);
  5363.       }
  5364.  
  5365.       /*
  5366.        * If reload_after_sighup == True then we got a SIGHUP
  5367.        * and are being asked to reload. Fix from <branko.cibej@hermes.si>
  5368.        */
  5369.   
  5370.       if (reload_after_sighup)
  5371.       { 
  5372.         DEBUG(0,("Reloading services after SIGHUP\n"));
  5373.         reload_services(False);
  5374.         reload_after_sighup = False;
  5375.       }
  5376.  
  5377.       /* automatic timeout if all connections are closed */      
  5378.       if (num_connections_open==0 && counter >= IDLE_CLOSED_TIMEOUT) 
  5379.       {
  5380.         DEBUG(2,("%s Closing idle connection\n",timestring()));
  5381.         return;
  5382.       }
  5383.  
  5384.       if (keepalive && (counter-last_keepalive)>keepalive) 
  5385.       {
  5386.           struct cli_state *cli = server_client();
  5387.           if (!send_keepalive(Client)) { 
  5388.               DEBUG(2,("%s Keepalive failed - exiting\n",timestring()));
  5389.               return;
  5390.           }        
  5391.           /* also send a keepalive to the password server if its still
  5392.          connected */
  5393.           if (cli && cli->initialised)
  5394.               send_keepalive(cli->fd);
  5395.           last_keepalive = counter;
  5396.       }
  5397.  
  5398.       /* check for connection timeouts */
  5399.       for (i=0;i<MAX_CONNECTIONS;i++)
  5400.         if (Connections[i].open)
  5401.         {
  5402.           /* close dirptrs on connections that are idle */
  5403.           if ((t-Connections[i].lastused)>DPTR_IDLE_TIMEOUT)
  5404.             dptr_idlecnum(i);
  5405.  
  5406.           if (Connections[i].num_files_open > 0 ||
  5407.                      (t-Connections[i].lastused)<deadtime)
  5408.             allidle = False;
  5409.         }
  5410.  
  5411.       if (allidle && num_connections_open>0) 
  5412.       {
  5413.         DEBUG(2,("%s Closing idle connection 2\n",timestring()));
  5414.         return;
  5415.       }
  5416.     }
  5417.  
  5418.     if(got_smb)
  5419.       process_smb(InBuffer, OutBuffer);
  5420.     else
  5421.       process_local_message(oplock_sock, InBuffer, BUFFER_SIZE);
  5422.   }
  5423. }
  5424.  
  5425.  
  5426. /****************************************************************************
  5427.   initialise connect, service and file structs
  5428. ****************************************************************************/
  5429. static void init_structs(void )
  5430. {
  5431.   int i;
  5432.   get_myname(myhostname,NULL);
  5433.  
  5434.   for (i=0;i<MAX_CONNECTIONS;i++)
  5435.     {
  5436.       Connections[i].open = False;
  5437.       Connections[i].num_files_open=0;
  5438.       Connections[i].lastused=0;
  5439.       Connections[i].used=False;
  5440.       string_init(&Connections[i].user,"");
  5441.       string_init(&Connections[i].dirpath,"");
  5442.       string_init(&Connections[i].connectpath,"");
  5443.       string_init(&Connections[i].origpath,"");
  5444.     }
  5445.  
  5446.   for (i=0;i<MAX_OPEN_FILES;i++)
  5447.     {
  5448.       Files[i].open = False;
  5449.       string_init(&Files[i].name,"");
  5450.  
  5451.     }
  5452.  
  5453.   for (i=0;i<MAX_OPEN_FILES;i++)
  5454.     {
  5455.       file_fd_struct *fd_ptr = &FileFd[i];
  5456.       fd_ptr->ref_count = 0;
  5457.       fd_ptr->dev = (int32)-1;
  5458.       fd_ptr->inode = (int32)-1;
  5459.       fd_ptr->fd = -1;
  5460.       fd_ptr->fd_readonly = -1;
  5461.       fd_ptr->fd_writeonly = -1;
  5462.       fd_ptr->real_open_flags = -1;
  5463.     }
  5464.  
  5465.   /* for RPC pipes */
  5466.   init_rpc_pipe_hnd();
  5467.  
  5468. #ifdef NTDOMAIN
  5469.   /* for LSA handles */
  5470.   init_lsa_policy_hnd();
  5471. #endif
  5472.  
  5473.   init_dptrs();
  5474. }
  5475.  
  5476. /****************************************************************************
  5477. usage on the program
  5478. ****************************************************************************/
  5479. static void usage(char *pname)
  5480. {
  5481.   DEBUG(0,("Incorrect program usage - are you sure the command line is correct?\n"));
  5482.  
  5483.   printf("Usage: %s [-D] [-p port] [-d debuglevel] [-l log basename] [-s services file]\n",pname);
  5484.   printf("Version %s\n",VERSION);
  5485.   printf("\t-D                    become a daemon\n");
  5486.   printf("\t-p port               listen on the specified port\n");
  5487.   printf("\t-d debuglevel         set the debuglevel\n");
  5488.   printf("\t-l log basename.      Basename for log/debug files\n");
  5489.   printf("\t-s services file.     Filename of services file\n");
  5490.   printf("\t-P                    passive only\n");
  5491.   printf("\t-a                    overwrite log file, don't append\n");
  5492.   printf("\n");
  5493. }
  5494.  
  5495.  
  5496. /****************************************************************************
  5497.   main program
  5498. ****************************************************************************/
  5499.  int main(int argc,char *argv[])
  5500. {
  5501.   extern BOOL append_log;
  5502.   /* shall I run as a daemon */
  5503.   BOOL is_daemon = False;
  5504.   int port = SMB_PORT;
  5505.   int opt;
  5506.   extern char *optarg;
  5507.   char pidFile[100];
  5508.  
  5509.   *pidFile = '\0';
  5510.  
  5511. #ifdef NEED_AUTH_PARAMETERS
  5512.   set_auth_parameters(argc,argv);
  5513. #endif
  5514.  
  5515. #ifdef SecureWare
  5516.   setluid(0);
  5517. #endif
  5518.  
  5519.   append_log = True;
  5520.  
  5521.   TimeInit();
  5522.  
  5523.   pstrcpy(debugf,SMBLOGFILE);  
  5524.  
  5525.   pstrcpy(remote_machine, "smb");
  5526.  
  5527.   setup_logging(argv[0],False);
  5528.  
  5529.   charset_initialise();
  5530.  
  5531.   /* make absolutely sure we run as root - to handle cases where people
  5532.      are crazy enough to have it setuid */
  5533. #ifdef USE_SETRES
  5534.   setresuid(0,0,0);
  5535. #else
  5536.   setuid(0);
  5537.   seteuid(0);
  5538.   setuid(0);
  5539.   seteuid(0);
  5540. #endif
  5541.  
  5542.   fault_setup((void (*)(void *))exit_server);
  5543.   signal(SIGTERM , SIGNAL_CAST dflt_sig);
  5544.  
  5545.   /* we want total control over the permissions on created files,
  5546.      so set our umask to 0 */
  5547.   umask(0);
  5548.  
  5549.   GetWd(OriginalDir);
  5550.  
  5551.   init_uid();
  5552.  
  5553.   /* this is for people who can't start the program correctly */
  5554.   while (argc > 1 && (*argv[1] != '-'))
  5555.     {
  5556.       argv++;
  5557.       argc--;
  5558.     }
  5559.  
  5560.   while ((opt = getopt(argc, argv, "O:i:l:s:d:Dp:hPaf:")) != EOF)
  5561.     switch (opt)
  5562.       {
  5563.       case 'f':
  5564.         strncpy(pidFile, optarg, sizeof(pidFile));
  5565.         break;
  5566.       case 'O':
  5567.     pstrcpy(user_socket_options,optarg);
  5568.     break;
  5569.       case 'i':
  5570.     pstrcpy(scope,optarg);
  5571.     break;
  5572.       case 'P':
  5573.     {
  5574.       extern BOOL passive;
  5575.       passive = True;
  5576.     }
  5577.     break;    
  5578.       case 's':
  5579.     pstrcpy(servicesf,optarg);
  5580.     break;
  5581.       case 'l':
  5582.     pstrcpy(debugf,optarg);
  5583.     break;
  5584.       case 'a':
  5585.     {
  5586.       extern BOOL append_log;
  5587.       append_log = !append_log;
  5588.     }
  5589.     break;
  5590.       case 'D':
  5591.     is_daemon = True;
  5592.     break;
  5593.       case 'd':
  5594.     if (*optarg == 'A')
  5595.       DEBUGLEVEL = 10000;
  5596.     else
  5597.       DEBUGLEVEL = atoi(optarg);
  5598.     break;
  5599.       case 'p':
  5600.     port = atoi(optarg);
  5601.     break;
  5602.       case 'h':
  5603.     usage(argv[0]);
  5604.     exit(0);
  5605.     break;
  5606.       default:
  5607.     usage(argv[0]);
  5608.     exit(1);
  5609.       }
  5610.  
  5611.   reopen_logs();
  5612.  
  5613.   DEBUG(2,("%s smbd version %s started\n",timestring(),VERSION));
  5614.   DEBUG(2,("Copyright Andrew Tridgell 1992-1997\n"));
  5615.  
  5616. #ifndef NO_GETRLIMIT
  5617. #ifdef RLIMIT_NOFILE
  5618.   {
  5619.     struct rlimit rlp;
  5620.     getrlimit(RLIMIT_NOFILE, &rlp);
  5621.     /*
  5622.      * Set the fd limit to be MAX_OPEN_FILES + 10 to account for the
  5623.      * extra fd we need to read directories, as well as the log files
  5624.      * and standard handles etc.
  5625.      */
  5626.     rlp.rlim_cur = (MAX_OPEN_FILES+10>rlp.rlim_max)? rlp.rlim_max:MAX_OPEN_FILES+10;
  5627.     setrlimit(RLIMIT_NOFILE, &rlp);
  5628.     getrlimit(RLIMIT_NOFILE, &rlp);
  5629.     DEBUG(3,("Maximum number of open files per session is %d\n",rlp.rlim_cur));
  5630.   }
  5631. #endif
  5632. #endif
  5633.  
  5634.   
  5635.   DEBUG(2,("uid=%d gid=%d euid=%d egid=%d\n",
  5636.     getuid(),getgid(),geteuid(),getegid()));
  5637.  
  5638.   if (sizeof(uint16) < 2 || sizeof(uint32) < 4)
  5639.     {
  5640.       DEBUG(0,("ERROR: Samba is not configured correctly for the word size on your machine\n"));
  5641.       exit(1);
  5642.     }
  5643.  
  5644.   init_structs();
  5645.  
  5646.   if (!reload_services(False))
  5647.     return(-1);    
  5648.  
  5649.   codepage_initialise(lp_client_code_page());
  5650.  
  5651.   pstrcpy(myworkgroup, lp_workgroup());
  5652.  
  5653. #ifndef NO_SIGNAL_TEST
  5654.   signal(SIGHUP,SIGNAL_CAST sig_hup);
  5655. #endif
  5656.  
  5657.   /* Setup the signals that allow the debug log level
  5658.      to by dynamically changed. */
  5659.  
  5660.   /* If we are using the malloc debug code we can't use
  5661.      SIGUSR1 and SIGUSR2 to do debug level changes. */
  5662.  
  5663. #ifndef MEM_MAN
  5664. #if defined(SIGUSR1)
  5665.   signal( SIGUSR1, SIGNAL_CAST sig_usr1 );
  5666. #endif /* SIGUSR1 */
  5667.    
  5668. #if defined(SIGUSR2)
  5669.   signal( SIGUSR2, SIGNAL_CAST sig_usr2 );
  5670. #endif /* SIGUSR2 */
  5671. #endif /* MEM_MAN */
  5672.  
  5673.   DEBUG(3,("%s loaded services\n",timestring()));
  5674.  
  5675.   if (!is_daemon && !is_a_socket(0))
  5676.     {
  5677.       DEBUG(0,("standard input is not a socket, assuming -D option\n"));
  5678.       is_daemon = True;
  5679.     }
  5680.  
  5681.   if (is_daemon)
  5682.     {
  5683.       DEBUG(3,("%s becoming a daemon\n",timestring()));
  5684.       become_daemon();
  5685.     }
  5686.  
  5687.   if (!directory_exist(lp_lockdir(), NULL)) {
  5688.       mkdir(lp_lockdir(), 0755);
  5689.   }
  5690.  
  5691.   if (*pidFile)
  5692.     {
  5693.       int     fd;
  5694.       char    buf[20];
  5695.  
  5696.       if ((fd = open(pidFile,
  5697. #ifdef O_NONBLOCK
  5698.          O_NONBLOCK | 
  5699. #endif
  5700.          O_CREAT | O_WRONLY | O_TRUNC, 0644)) < 0)
  5701.         {
  5702.            DEBUG(0,("ERROR: can't open %s: %s\n", pidFile, strerror(errno)));
  5703.            exit(1);
  5704.         }
  5705.       if(fcntl_lock(fd,F_SETLK,0,1,F_WRLCK)==False)
  5706.         {
  5707.           DEBUG(0,("ERROR: smbd is already running\n"));
  5708.           exit(1);
  5709.         }
  5710.       slprintf(buf, sizeof(buf)-1, "%u\n", (unsigned int) getpid());
  5711.       if (write(fd, buf, strlen(buf)) < 0)
  5712.         {
  5713.           DEBUG(0,("ERROR: can't write to %s: %s\n", pidFile, strerror(errno)));
  5714.           exit(1);
  5715.         }
  5716.       /* Leave pid file open & locked for the duration... */
  5717.     }
  5718.  
  5719.   if (!open_sockets(is_daemon,port))
  5720.     exit(1);
  5721.  
  5722.   if (!locking_init(0))
  5723.     exit(1);
  5724.  
  5725.   /* possibly reload the services file. */
  5726.   reload_services(True);
  5727.  
  5728.   max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
  5729.  
  5730.   if (*lp_rootdir())
  5731.     {
  5732.       if (sys_chroot(lp_rootdir()) == 0)
  5733.     DEBUG(2,("%s changed root to %s\n",timestring(),lp_rootdir()));
  5734.     }
  5735.  
  5736.   /* Setup the oplock IPC socket. */
  5737.   if(!open_oplock_ipc())
  5738.     exit(1);
  5739.  
  5740.   process();
  5741.   close_sockets();
  5742.  
  5743.   exit_server("normal exit");
  5744.   return(0);
  5745. }
  5746.  
  5747.  
  5748.