*** empty log message ***
[samba.git] / source / smbd / server.c
index bf66e1ca4bee0de210df9c4e8bdfa9281c9a6abb..a83e865f9e4feb3db2631658020cf09f9bb5ef94 100644 (file)
@@ -1151,6 +1151,7 @@ static void open_file(int fnum,int cnum,char *fname1,int flags,int mode, struct
   struct stat statbuf;
   file_fd_struct *fd_ptr;
   files_struct *fsp = &Files[fnum];
+  int accmode = (flags & (O_RDONLY | O_WRONLY | O_RDWR));
 
   fsp->open = False;
   fsp->fd_ptr = 0;
@@ -1160,12 +1161,32 @@ static void open_file(int fnum,int cnum,char *fname1,int flags,int mode, struct
   pstrcpy(fname,fname1);
 
   /* check permissions */
-  if ((flags != O_RDONLY) && !CAN_WRITE(cnum) && !Connections[cnum].printer)
-    {
+
+  /*
+   * This code was changed after seeing a client open request 
+   * containing the open mode of (DENY_WRITE/read-only) with
+   * the 'create if not exist' bit set. The previous code
+   * would fail to open the file read only on a read-only share
+   * as it was checking the flags parameter  directly against O_RDONLY,
+   * this was failing as the flags parameter was set to O_RDONLY|O_CREAT.
+   * JRA.
+   */
+
+  if (!CAN_WRITE(cnum) && !Connections[cnum].printer) {
+    /* It's a read-only share - fail if we wanted to write. */
+    if(accmode != O_RDONLY) {
       DEBUG(3,("Permission denied opening %s\n",fname));
       check_for_pipe(fname);
       return;
     }
+    else if(flags & O_CREAT) {
+      /* We don't want to write - but we must make sure that O_CREAT
+         doesn't create the file if we have write access into the
+         directory.
+       */
+      flags &= ~O_CREAT;
+    }
+  }
 
   /* this handles a bug in Win95 - it doesn't say to create the file when it 
      should */
@@ -1203,8 +1224,6 @@ static void open_file(int fnum,int cnum,char *fname1,int flags,int mode, struct
    */
   if((fd_ptr = fd_get_already_open(sbuf))!= 0) {
 
-    int accmode = (flags & (O_RDONLY | O_WRONLY | O_RDWR));
-
     /* File was already open. */
     if((flags & O_CREAT) && (flags & O_EXCL)) {
       fd_ptr->ref_count--;
@@ -2529,7 +2548,7 @@ max can be %d\n", num_interfaces, FD_SETSIZE));
           return True; 
         }
         close(Client); /* The parent doesn't need this socket */
-#endif /NO_FORK_DEBUG */
+#endif /NO_FORK_DEBUG */
       } /* end for num */
     } /* end while 1 */
   } /* end if is_daemon */
@@ -2595,6 +2614,8 @@ static void process_smb(char *inbuf, char *outbuf)
 
   if (msg_type == 0)
     show_msg(inbuf);
+  else if(msg_type == 0x85)
+    return; /* Keepalive packet. */
 
   nread = construct_reply(inbuf,outbuf,nread,max_send);
       
@@ -2778,8 +2799,8 @@ pid %d, port %d, dev = %x, inode = %x\n", remotepid, from_port, dev, inode));
 BOOL oplock_break(uint32 dev, uint32 inode, struct timeval *tval)
 {
   extern int Client;
-  static char *inbuf = NULL;
-  static char *outbuf = NULL;
+  char *inbuf = NULL;
+  char *outbuf = NULL;
   files_struct *fsp = NULL;
   int fnum;
   time_t start_time;
@@ -3142,6 +3163,13 @@ BOOL receive_next_smb(int smbfd, int oplockfd, char *inbuf, int bufsize, int tim
       process_local_message(oplock_sock, inbuf, bufsize);
       continue;
     }
+
+    if(ret && (CVAL(inbuf,0) == 0x85))
+    {
+      /* Keepalive packet. */
+      got_smb = False;
+    }
+
   }
   while(ret && !got_smb);
 
@@ -3643,9 +3671,13 @@ int find_free_file(void )
                if (first_file == 0) first_file = 1;
        }
 
+       if (first_file == MAX_OPEN_FILES)
+               first_file = 0;
+
        for (i=first_file;i<MAX_OPEN_FILES;i++)
                if (!Files[i].open) {
                        memset(&Files[i], 0, sizeof(Files[i]));
+                       first_file++;
                        return(i);
                }
 
@@ -3653,6 +3685,7 @@ int find_free_file(void )
        for (i=1;i<first_file;i++)
                if (!Files[i].open) {
                        memset(&Files[i], 0, sizeof(Files[i]));
+                       first_file++;
                        return(i);
                }
 
@@ -4642,7 +4675,8 @@ static int switch_message(int type,char *inbuf,char *outbuf,int size,int bufsize
        {
          int cnum = SVAL(inbuf,smb_tid);
          int flags = smb_messages[match].flags;
-         uint16 session_tag = SVAL(inbuf,smb_uid);
+          /* In share mode security we must ignore the vuid. */
+         uint16 session_tag = (lp_security() == SEC_SHARE) ? UID_FIELD_INVALID : SVAL(inbuf,smb_uid);
 
          /* does this protocol need to be run as root? */
          if (!(flags & AS_USER))
@@ -5095,7 +5129,7 @@ static void usage(char *pname)
 
   charset_initialise();
 
-  /* make absolutely sure we run as root - to handle cases whre people
+  /* make absolutely sure we run as root - to handle cases where people
      are crazy enough to have it setuid */
 #ifdef USE_SETRES
   setresuid(0,0,0);
@@ -5215,7 +5249,18 @@ static void usage(char *pname)
 #ifndef NO_SIGNAL_TEST
   signal(SIGHUP,SIGNAL_CAST sig_hup);
 #endif
-  
+
+  /* Setup the signals that allow the debug log level
+     to by dynamically changed. */
+#if defined(SIGUSR1)
+  signal( SIGUSR1, SIGNAL_CAST sig_usr1 );
+#endif /* SIGUSR1 */
+   
+#if defined(SIGUSR2)
+  signal( SIGUSR2, SIGNAL_CAST sig_usr2 );
+#endif /* SIGUSR2 */
+
   DEBUG(3,("%s loaded services\n",timestring()));
 
   if (!is_daemon && !is_a_socket(0))