Fixed bug introduced by the recent changes where the chain_fnum
[samba.git] / source3 / smbd / oplock.c
1 /* 
2    Unix SMB/Netbios implementation.
3    Version 1.9.
4    oplock processing
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
24 extern int DEBUGLEVEL;
25
26 /* Oplock ipc UDP socket. */
27 int oplock_sock = -1;
28 uint16 oplock_port = 0;
29
30 /* Current number of oplocks we have outstanding. */
31 int32 global_oplocks_open = 0;
32 BOOL global_oplock_break = False;
33
34
35 extern int smb_read_error;
36
37
38 /****************************************************************************
39   open the oplock IPC socket communication
40 ****************************************************************************/
41 BOOL open_oplock_ipc(void)
42 {
43   struct sockaddr_in sock_name;
44   int len = sizeof(sock_name);
45
46   DEBUG(3,("open_oplock_ipc: opening loopback UDP socket.\n"));
47
48   /* Open a lookback UDP socket on a random port. */
49   oplock_sock = open_socket_in(SOCK_DGRAM, 0, 0, htonl(INADDR_LOOPBACK));
50   if (oplock_sock == -1)
51   {
52     DEBUG(0,("open_oplock_ipc: Failed to get local UDP socket for \
53 address %x. Error was %s\n", htonl(INADDR_LOOPBACK), strerror(errno)));
54     oplock_port = 0;
55     return(False);
56   }
57
58   /* Find out the transient UDP port we have been allocated. */
59   if(getsockname(oplock_sock, (struct sockaddr *)&sock_name, &len)<0)
60   {
61     DEBUG(0,("open_oplock_ipc: Failed to get local UDP port. Error was %s\n",
62             strerror(errno)));
63     close(oplock_sock);
64     oplock_sock = -1;
65     oplock_port = 0;
66     return False;
67   }
68   oplock_port = ntohs(sock_name.sin_port);
69
70   DEBUG(3,("open_oplock ipc: pid = %d, oplock_port = %u\n", 
71             (int)getpid(), oplock_port));
72
73   return True;
74 }
75
76 /****************************************************************************
77   process an oplock break message.
78 ****************************************************************************/
79 BOOL process_local_message(int sock, char *buffer, int buf_size)
80 {
81   int32 msg_len;
82   uint16 from_port;
83   char *msg_start;
84
85   msg_len = IVAL(buffer,UDP_CMD_LEN_OFFSET);
86   from_port = SVAL(buffer,UDP_CMD_PORT_OFFSET);
87
88   msg_start = &buffer[UDP_CMD_HEADER_LEN];
89
90   DEBUG(5,("process_local_message: Got a message of length %d from port (%d)\n", 
91             msg_len, from_port));
92
93   /* Switch on message command - currently OPLOCK_BREAK_CMD is the
94      only valid request. */
95
96   switch(SVAL(msg_start,UDP_MESSAGE_CMD_OFFSET))
97   {
98     case OPLOCK_BREAK_CMD:
99       /* Ensure that the msg length is correct. */
100       if(msg_len != OPLOCK_BREAK_MSG_LEN)
101       {
102         DEBUG(0,("process_local_message: incorrect length for OPLOCK_BREAK_CMD (was %d, \
103 should be %d).\n", msg_len, OPLOCK_BREAK_MSG_LEN));
104         return False;
105       }
106       {
107         uint32 remotepid = IVAL(msg_start,OPLOCK_BREAK_PID_OFFSET);
108         uint32 dev = IVAL(msg_start,OPLOCK_BREAK_DEV_OFFSET);
109         uint32 inode = IVAL(msg_start, OPLOCK_BREAK_INODE_OFFSET);
110         struct timeval tval;
111         struct sockaddr_in toaddr;
112
113         tval.tv_sec = IVAL(msg_start, OPLOCK_BREAK_SEC_OFFSET);
114         tval.tv_usec = IVAL(msg_start, OPLOCK_BREAK_USEC_OFFSET);
115
116         DEBUG(5,("process_local_message: oplock break request from \
117 pid %d, port %d, dev = %x, inode = %x\n", remotepid, from_port, dev, inode));
118
119         /*
120          * If we have no record of any currently open oplocks,
121          * it's not an error, as a close command may have
122          * just been issued on the file that was oplocked.
123          * Just return success in this case.
124          */
125
126         if(global_oplocks_open != 0)
127         {
128           if(oplock_break(dev, inode, &tval) == False)
129           {
130             DEBUG(0,("process_local_message: oplock break failed - \
131 not returning udp message.\n"));
132             return False;
133           }
134         }
135         else
136         {
137           DEBUG(3,("process_local_message: oplock break requested with no outstanding \
138 oplocks. Returning success.\n"));
139         }
140
141         /* Send the message back after OR'ing in the 'REPLY' bit. */
142         SSVAL(msg_start,UDP_MESSAGE_CMD_OFFSET,OPLOCK_BREAK_CMD | CMD_REPLY);
143   
144         bzero((char *)&toaddr,sizeof(toaddr));
145         toaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
146         toaddr.sin_port = htons(from_port);
147         toaddr.sin_family = AF_INET;
148
149         if(sendto( sock, msg_start, OPLOCK_BREAK_MSG_LEN, 0,
150                 (struct sockaddr *)&toaddr, sizeof(toaddr)) < 0) 
151         {
152           DEBUG(0,("process_local_message: sendto process %d failed. Errno was %s\n",
153                     remotepid, strerror(errno)));
154           return False;
155         }
156
157         DEBUG(5,("process_local_message: oplock break reply sent to \
158 pid %d, port %d, for file dev = %x, inode = %x\n", remotepid, 
159                 from_port, dev, inode));
160
161       }
162       break;
163     /* 
164      * Keep this as a debug case - eventually we can remove it.
165      */
166     case 0x8001:
167       DEBUG(0,("process_local_message: Received unsolicited break \
168 reply - dumping info.\n"));
169
170       if(msg_len != OPLOCK_BREAK_MSG_LEN)
171       {
172         DEBUG(0,("process_local_message: ubr: incorrect length for reply \
173 (was %d, should be %d).\n", msg_len, OPLOCK_BREAK_MSG_LEN));
174         return False;
175       }
176
177       {
178         uint32 remotepid = IVAL(msg_start,OPLOCK_BREAK_PID_OFFSET);
179         uint32 dev = IVAL(msg_start,OPLOCK_BREAK_DEV_OFFSET);
180         uint32 inode = IVAL(msg_start, OPLOCK_BREAK_INODE_OFFSET);
181
182         DEBUG(0,("process_local_message: unsolicited oplock break reply from \
183 pid %d, port %d, dev = %x, inode = %x\n", remotepid, from_port, dev, inode));
184
185        }
186        return False;
187
188     default:
189       DEBUG(0,("process_local_message: unknown UDP message command code (%x) - ignoring.\n",
190                 (unsigned int)SVAL(msg_start,0)));
191       return False;
192   }
193   return True;
194 }
195
196 /****************************************************************************
197  Process an oplock break directly.
198 ****************************************************************************/
199 BOOL oplock_break(uint32 dev, uint32 inode, struct timeval *tval)
200 {
201   extern struct current_user current_user;
202   extern int Client;
203   char *inbuf = NULL;
204   char *outbuf = NULL;
205   files_struct *fsp = NULL;
206   time_t start_time;
207   BOOL shutdown_server = False;
208   connection_struct *saved_conn;
209   int saved_vuid;
210   pstring saved_dir; 
211
212   if( DEBUGLVL( 3 ) )
213     {
214     dbgtext( "oplock_break: called for dev = %x, inode = %x.\n", dev, inode );
215     dbgtext( "Current global_oplocks_open = %d\n", global_oplocks_open );
216     }
217
218   /* We need to search the file open table for the
219      entry containing this dev and inode, and ensure
220      we have an oplock on it. */
221   fsp = file_find_dit(dev, inode, tval);
222
223   if(fsp == NULL)
224   {
225     /* The file could have been closed in the meantime - return success. */
226     if( DEBUGLVL( 0 ) )
227       {
228       dbgtext( "oplock_break: cannot find open file with " );
229       dbgtext( "dev = %x, inode = %x ", dev, inode);
230       dbgtext( "allowing break to succeed.\n" );
231       }
232     return True;
233   }
234
235   /* Ensure we have an oplock on the file */
236
237   /* There is a potential race condition in that an oplock could
238      have been broken due to another udp request, and yet there are
239      still oplock break messages being sent in the udp message
240      queue for this file. So return true if we don't have an oplock,
241      as we may have just freed it.
242    */
243
244   if(!fsp->granted_oplock)
245   {
246     if( DEBUGLVL( 0 ) )
247       {
248       dbgtext( "oplock_break: file %s ", fsp->fsp_name );
249       dbgtext( "(dev = %x, inode = %x) has no oplock.\n", dev, inode );
250       dbgtext( "Allowing break to succeed regardless.\n" );
251       }
252     return True;
253   }
254
255   /* mark the oplock break as sent - we don't want to send twice! */
256   if (fsp->sent_oplock_break)
257   {
258     if( DEBUGLVL( 0 ) )
259       {
260       dbgtext( "oplock_break: ERROR: oplock_break already sent for " );
261       dbgtext( "file %s ", fsp->fsp_name);
262       dbgtext( "(dev = %x, inode = %x)\n", dev, inode );
263       }
264
265     /* We have to fail the open here as we cannot send another oplock break on
266        this file whilst we are awaiting a response from the client - neither
267        can we allow another open to succeed while we are waiting for the
268        client.
269      */
270     return False;
271   }
272
273   /* Now comes the horrid part. We must send an oplock break to the client,
274      and then process incoming messages until we get a close or oplock release.
275      At this point we know we need a new inbuf/outbuf buffer pair.
276      We cannot use these staticaly as we may recurse into here due to
277      messages crossing on the wire.
278    */
279
280   if((inbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN))==NULL)
281   {
282     DEBUG(0,("oplock_break: malloc fail for input buffer.\n"));
283     return False;
284   }
285
286   if((outbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN))==NULL)
287   {
288     DEBUG(0,("oplock_break: malloc fail for output buffer.\n"));
289     free(inbuf);
290     inbuf = NULL;
291     return False;
292   }
293
294   /* Prepare the SMBlockingX message. */
295   bzero(outbuf,smb_size);
296   set_message(outbuf,8,0,True);
297
298   SCVAL(outbuf,smb_com,SMBlockingX);
299   SSVAL(outbuf,smb_tid,fsp->conn->cnum);
300   SSVAL(outbuf,smb_pid,0xFFFF);
301   SSVAL(outbuf,smb_uid,0);
302   SSVAL(outbuf,smb_mid,0xFFFF);
303   SCVAL(outbuf,smb_vwv0,0xFF);
304   SSVAL(outbuf,smb_vwv2,fsp->fnum);
305   SCVAL(outbuf,smb_vwv3,LOCKING_ANDX_OPLOCK_RELEASE);
306   /* Change this when we have level II oplocks. */
307   SCVAL(outbuf,smb_vwv3+1,OPLOCKLEVEL_NONE);
308  
309   send_smb(Client, outbuf);
310
311   /* Remember we just sent an oplock break on this file. */
312   fsp->sent_oplock_break = True;
313
314   /* We need this in case a readraw crosses on the wire. */
315   global_oplock_break = True;
316  
317   /* Process incoming messages. */
318
319   /* JRA - If we don't get a break from the client in OPLOCK_BREAK_TIMEOUT
320      seconds we should just die.... */
321
322   start_time = time(NULL);
323
324   /*
325    * Save the information we need to re-become the
326    * user, then unbecome the user whilst we're doing this.
327    */
328   saved_conn = fsp->conn;
329   saved_vuid = current_user.vuid;
330   GetWd(saved_dir);
331   unbecome_user();
332   /* Save the chain fnum. */
333   file_chain_save();
334
335   while(OPEN_FSP(fsp) && fsp->granted_oplock)
336   {
337     if(receive_smb(Client,inbuf,OPLOCK_BREAK_TIMEOUT * 1000) == False)
338     {
339       /*
340        * Die if we got an error.
341        */
342
343       if (smb_read_error == READ_EOF)
344         DEBUG( 0, ( "oplock_break: end of file from client\n" ) );
345  
346       if (smb_read_error == READ_ERROR)
347         DEBUG( 0, ("oplock_break: receive_smb error (%s)\n", strerror(errno)) );
348
349       if (smb_read_error == READ_TIMEOUT)
350         DEBUG( 0, ( "oplock_break: receive_smb timed out after %d seconds.\n",
351                      OPLOCK_BREAK_TIMEOUT ) );
352
353       DEBUGADD( 0, ( "oplock_break failed for file %s ", fsp->fsp_name ) );
354       DEBUGADD( 0, ( "(dev = %x, inode = %x).\n", dev, inode));
355       shutdown_server = True;
356       break;
357     }
358
359     /*
360      * There are certain SMB requests that we shouldn't allow
361      * to recurse. opens, renames and deletes are the obvious
362      * ones. This is handled in the switch_message() function.
363      * If global_oplock_break is set they will push the packet onto
364      * the pending smb queue and return -1 (no reply).
365      * JRA.
366      */
367
368     process_smb(inbuf, outbuf);
369
370     /*
371      * Die if we go over the time limit.
372      */
373
374     if((time(NULL) - start_time) > OPLOCK_BREAK_TIMEOUT)
375     {
376       if( DEBUGLVL( 0 ) )
377         {
378         dbgtext( "oplock_break: no break received from client " );
379         dbgtext( "within %d seconds.\n", OPLOCK_BREAK_TIMEOUT );
380         dbgtext( "oplock_break failed for file %s ", fsp->fsp_name );
381         dbgtext( "(dev = %x, inode = %x).\n", dev, inode );
382         }
383       shutdown_server = True;
384       break;
385     }
386   }
387
388   /*
389    * Go back to being the user who requested the oplock
390    * break.
391    */
392   if(!become_user(saved_conn, saved_vuid))
393   {
394     DEBUG( 0, ( "oplock_break: unable to re-become user!" ) );
395     DEBUGADD( 0, ( "Shutting down server\n" ) );
396     close_sockets();
397     close(oplock_sock);
398     exit_server("unable to re-become user");
399   }
400   /* Including the directory. */
401   ChDir(saved_dir);
402
403   /* Restore the chain fnum. */
404   file_chain_restore();
405
406   /* Free the buffers we've been using to recurse. */
407   free(inbuf);
408   free(outbuf);
409
410   /* We need this in case a readraw crossed on the wire. */
411   if(global_oplock_break)
412     global_oplock_break = False;
413
414   /*
415    * If the client did not respond we must die.
416    */
417
418   if(shutdown_server)
419   {
420     DEBUG( 0, ( "oplock_break: client failure in break - " ) );
421     DEBUGADD( 0, ( "shutting down this smbd.\n" ) );
422     close_sockets();
423     close(oplock_sock);
424     exit_server("oplock break failure");
425   }
426
427   if(OPEN_FSP(fsp))
428   {
429     /* The lockingX reply will have removed the oplock flag 
430        from the sharemode. */
431     /* Paranoia.... */
432     fsp->granted_oplock = False;
433     fsp->sent_oplock_break = False;
434     global_oplocks_open--;
435   }
436
437   /* Santity check - remove this later. JRA */
438   if(global_oplocks_open < 0)
439   {
440     DEBUG(0,("oplock_break: global_oplocks_open < 0 (%d). PANIC ERROR\n",
441               global_oplocks_open));
442     exit_server("oplock_break: global_oplocks_open < 0");
443   }
444
445   if( DEBUGLVL( 3 ) )
446     {
447     dbgtext( "oplock_break: returning success for " );
448     dbgtext( "dev = %x, inode = %x.\n", dev, inode );
449     dbgtext( "Current global_oplocks_open = %d\n", global_oplocks_open );
450     }
451
452   return True;
453 }
454
455 /****************************************************************************
456 Send an oplock break message to another smbd process. If the oplock is held 
457 by the local smbd then call the oplock break function directly.
458 ****************************************************************************/
459
460 BOOL request_oplock_break(share_mode_entry *share_entry, 
461                           uint32 dev, uint32 inode)
462 {
463   char op_break_msg[OPLOCK_BREAK_MSG_LEN];
464   struct sockaddr_in addr_out;
465   int pid = getpid();
466   time_t start_time;
467   int time_left;
468
469   if(pid == share_entry->pid)
470   {
471     /* We are breaking our own oplock, make sure it's us. */
472     if(share_entry->op_port != oplock_port)
473     {
474       DEBUG(0,("request_oplock_break: corrupt share mode entry - pid = %d, port = %d \
475 should be %d\n", pid, share_entry->op_port, oplock_port));
476       return False;
477     }
478
479     DEBUG(5,("request_oplock_break: breaking our own oplock\n"));
480
481     /* Call oplock break direct. */
482     return oplock_break(dev, inode, &share_entry->time);
483   }
484
485   /* We need to send a OPLOCK_BREAK_CMD message to the
486      port in the share mode entry. */
487
488   SSVAL(op_break_msg,UDP_MESSAGE_CMD_OFFSET,OPLOCK_BREAK_CMD);
489   SIVAL(op_break_msg,OPLOCK_BREAK_PID_OFFSET,pid);
490   SIVAL(op_break_msg,OPLOCK_BREAK_DEV_OFFSET,dev);
491   SIVAL(op_break_msg,OPLOCK_BREAK_INODE_OFFSET,inode);
492   SIVAL(op_break_msg,OPLOCK_BREAK_SEC_OFFSET,(uint32)share_entry->time.tv_sec);
493   SIVAL(op_break_msg,OPLOCK_BREAK_USEC_OFFSET,(uint32)share_entry->time.tv_usec);
494
495   /* set the address and port */
496   bzero((char *)&addr_out,sizeof(addr_out));
497   addr_out.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
498   addr_out.sin_port = htons( share_entry->op_port );
499   addr_out.sin_family = AF_INET;
500    
501   if( DEBUGLVL( 3 ) )
502     {
503     dbgtext( "request_oplock_break: sending a oplock break message to " );
504     dbgtext( "pid %d on port %d ", share_entry->pid, share_entry->op_port );
505     dbgtext( "for dev = %x, inode = %x\n", dev, inode );
506     }
507
508   if(sendto(oplock_sock,op_break_msg,OPLOCK_BREAK_MSG_LEN,0,
509          (struct sockaddr *)&addr_out,sizeof(addr_out)) < 0)
510   {
511     if( DEBUGLVL( 0 ) )
512       {
513       dbgtext( "request_oplock_break: failed when sending a oplock " );
514       dbgtext( "break message to pid %d ", share_entry->pid );
515       dbgtext( "on port %d ", share_entry->op_port );
516       dbgtext( "for dev = %x, inode = %x.\n", dev, inode );
517       dbgtext( "Error was %s\n", strerror(errno) );
518       }
519     return False;
520   }
521
522   /*
523    * Now we must await the oplock broken message coming back
524    * from the target smbd process. Timeout if it fails to
525    * return in (OPLOCK_BREAK_TIMEOUT + OPLOCK_BREAK_TIMEOUT_FUDGEFACTOR) seconds.
526    * While we get messages that aren't ours, loop.
527    */
528
529   start_time = time(NULL);
530   time_left = OPLOCK_BREAK_TIMEOUT+OPLOCK_BREAK_TIMEOUT_FUDGEFACTOR;
531
532   while(time_left >= 0)
533   {
534     char op_break_reply[UDP_CMD_HEADER_LEN+OPLOCK_BREAK_MSG_LEN];
535     int32 reply_msg_len;
536     uint16 reply_from_port;
537     char *reply_msg_start;
538
539     if(receive_local_message(oplock_sock, op_break_reply, sizeof(op_break_reply),
540                time_left ? time_left * 1000 : 1) == False)
541     {
542       if(smb_read_error == READ_TIMEOUT)
543       {
544         if( DEBUGLVL( 0 ) )
545           {
546           dbgtext( "request_oplock_break: no response received to oplock " );
547           dbgtext( "break request to pid %d ", share_entry->pid );
548           dbgtext( "on port %d ", share_entry->op_port );
549           dbgtext( "for dev = %x, inode = %x\n", dev, inode );
550           }
551         /*
552          * This is a hack to make handling of failing clients more robust.
553          * If a oplock break response message is not received in the timeout
554          * period we may assume that the smbd servicing that client holding
555          * the oplock has died and the client changes were lost anyway, so
556          * we should continue to try and open the file.
557          */
558         break;
559       }
560       else
561         if( DEBUGLVL( 0 ) )
562           {
563           dbgtext( "request_oplock_break: error in response received " );
564           dbgtext( "to oplock break request to pid %d ", share_entry->pid );
565           dbgtext( "on port %d ", share_entry->op_port );
566           dbgtext( "for dev = %x, inode = %x.\n", dev, inode );
567           dbgtext( "Error was (%s).\n", strerror(errno) );
568           }
569       return False;
570     }
571
572     reply_msg_len = IVAL(op_break_reply,UDP_CMD_LEN_OFFSET);
573     reply_from_port = SVAL(op_break_reply,UDP_CMD_PORT_OFFSET);
574
575     reply_msg_start = &op_break_reply[UDP_CMD_HEADER_LEN];
576
577     if(reply_msg_len != OPLOCK_BREAK_MSG_LEN)
578     {
579       /* Ignore it. */
580       DEBUG( 0, ( "request_oplock_break: invalid message length received." ) );
581       DEBUGADD( 0, ( "  Ignoring.\n" ) );
582       continue;
583     }
584
585     /*
586      * Test to see if this is the reply we are awaiting.
587      */
588
589     if((SVAL(reply_msg_start,UDP_MESSAGE_CMD_OFFSET) & CMD_REPLY) &&
590        (reply_from_port == share_entry->op_port) && 
591        (memcmp(&reply_msg_start[OPLOCK_BREAK_PID_OFFSET], 
592                &op_break_msg[OPLOCK_BREAK_PID_OFFSET],
593                OPLOCK_BREAK_MSG_LEN - OPLOCK_BREAK_PID_OFFSET) == 0))
594     {
595       /*
596        * This is the reply we've been waiting for.
597        */
598       break;
599     }
600     else
601     {
602       /*
603        * This is another message - probably a break request.
604        * Process it to prevent potential deadlock.
605        * Note that the code in switch_message() prevents
606        * us from recursing into here as any SMB requests
607        * we might process that would cause another oplock
608        * break request to be made will be queued.
609        * JRA.
610        */
611
612       process_local_message(oplock_sock, op_break_reply, sizeof(op_break_reply));
613     }
614
615     time_left -= (time(NULL) - start_time);
616   }
617
618   DEBUG(3,("request_oplock_break: broke oplock.\n"));
619
620   return True;
621 }
622
623
624 /****************************************************************************
625   Attempt to break an oplock on a file (if oplocked).
626   Returns True if the file was closed as a result of
627   the oplock break, False otherwise.
628   Used as a last ditch attempt to free a space in the 
629   file table when we have run out.
630 ****************************************************************************/
631 BOOL attempt_close_oplocked_file(files_struct *fsp)
632 {
633
634   DEBUG(5,("attempt_close_oplocked_file: checking file %s.\n", fsp->fsp_name));
635
636   if (fsp->open && fsp->granted_oplock && !fsp->sent_oplock_break) {
637
638     /* Try and break the oplock. */
639     file_fd_struct *fd_ptr = fsp->fd_ptr;
640     if(oplock_break( fd_ptr->dev, fd_ptr->inode, &fsp->open_time)) {
641       if(!fsp->open) /* Did the oplock break close the file ? */
642         return True;
643     }
644   }
645
646   return False;
647 }
648