2 Unix SMB/Netbios implementation.
5 Copyright (C) Andrew Tridgell 1992-1998
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.
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.
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.
24 extern int DEBUGLEVEL;
26 /* Oplock ipc UDP socket. */
28 uint16 oplock_port = 0;
30 /* Current number of oplocks we have outstanding. */
31 int32 global_oplocks_open = 0;
32 BOOL global_oplock_break = False;
35 extern int smb_read_error;
38 /****************************************************************************
39 open the oplock IPC socket communication
40 ****************************************************************************/
41 BOOL open_oplock_ipc(void)
43 struct sockaddr_in sock_name;
44 int len = sizeof(sock_name);
46 DEBUG(3,("open_oplock_ipc: opening loopback UDP socket.\n"));
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)
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)));
58 /* Find out the transient UDP port we have been allocated. */
59 if(getsockname(oplock_sock, (struct sockaddr *)&sock_name, &len)<0)
61 DEBUG(0,("open_oplock_ipc: Failed to get local UDP port. Error was %s\n",
68 oplock_port = ntohs(sock_name.sin_port);
70 DEBUG(3,("open_oplock ipc: pid = %d, oplock_port = %u\n",
71 (int)getpid(), oplock_port));
76 /****************************************************************************
77 process an oplock break message.
78 ****************************************************************************/
79 BOOL process_local_message(int sock, char *buffer, int buf_size)
85 msg_len = IVAL(buffer,UDP_CMD_LEN_OFFSET);
86 from_port = SVAL(buffer,UDP_CMD_PORT_OFFSET);
88 msg_start = &buffer[UDP_CMD_HEADER_LEN];
90 DEBUG(5,("process_local_message: Got a message of length %d from port (%d)\n",
93 /* Switch on message command - currently OPLOCK_BREAK_CMD is the
94 only valid request. */
96 switch(SVAL(msg_start,UDP_MESSAGE_CMD_OFFSET))
98 case OPLOCK_BREAK_CMD:
99 /* Ensure that the msg length is correct. */
100 if(msg_len != OPLOCK_BREAK_MSG_LEN)
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));
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);
111 struct sockaddr_in toaddr;
113 tval.tv_sec = IVAL(msg_start, OPLOCK_BREAK_SEC_OFFSET);
114 tval.tv_usec = IVAL(msg_start, OPLOCK_BREAK_USEC_OFFSET);
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));
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.
126 if(global_oplocks_open != 0)
128 if(oplock_break(dev, inode, &tval) == False)
130 DEBUG(0,("process_local_message: oplock break failed - \
131 not returning udp message.\n"));
137 DEBUG(3,("process_local_message: oplock break requested with no outstanding \
138 oplocks. Returning success.\n"));
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);
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;
149 if(sendto( sock, msg_start, OPLOCK_BREAK_MSG_LEN, 0,
150 (struct sockaddr *)&toaddr, sizeof(toaddr)) < 0)
152 DEBUG(0,("process_local_message: sendto process %d failed. Errno was %s\n",
153 remotepid, strerror(errno)));
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));
164 * Keep this as a debug case - eventually we can remove it.
167 DEBUG(0,("process_local_message: Received unsolicited break \
168 reply - dumping info.\n"));
170 if(msg_len != OPLOCK_BREAK_MSG_LEN)
172 DEBUG(0,("process_local_message: ubr: incorrect length for reply \
173 (was %d, should be %d).\n", msg_len, OPLOCK_BREAK_MSG_LEN));
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);
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));
189 DEBUG(0,("process_local_message: unknown UDP message command code (%x) - ignoring.\n",
190 (unsigned int)SVAL(msg_start,0)));
196 /****************************************************************************
197 Process an oplock break directly.
198 ****************************************************************************/
199 BOOL oplock_break(uint32 dev, uint32 inode, struct timeval *tval)
201 extern struct current_user current_user;
205 files_struct *fsp = NULL;
207 BOOL shutdown_server = False;
208 connection_struct *saved_conn;
214 dbgtext( "oplock_break: called for dev = %x, inode = %x.\n", dev, inode );
215 dbgtext( "Current global_oplocks_open = %d\n", global_oplocks_open );
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);
225 /* The file could have been closed in the meantime - return success. */
228 dbgtext( "oplock_break: cannot find open file with " );
229 dbgtext( "dev = %x, inode = %x ", dev, inode);
230 dbgtext( "allowing break to succeed.\n" );
235 /* Ensure we have an oplock on the file */
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.
244 if(!fsp->granted_oplock)
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" );
255 /* mark the oplock break as sent - we don't want to send twice! */
256 if (fsp->sent_oplock_break)
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 );
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
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.
280 if((inbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN))==NULL)
282 DEBUG(0,("oplock_break: malloc fail for input buffer.\n"));
286 if((outbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN))==NULL)
288 DEBUG(0,("oplock_break: malloc fail for output buffer.\n"));
294 /* Prepare the SMBlockingX message. */
295 bzero(outbuf,smb_size);
296 set_message(outbuf,8,0,True);
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);
309 send_smb(Client, outbuf);
311 /* Remember we just sent an oplock break on this file. */
312 fsp->sent_oplock_break = True;
314 /* We need this in case a readraw crosses on the wire. */
315 global_oplock_break = True;
317 /* Process incoming messages. */
319 /* JRA - If we don't get a break from the client in OPLOCK_BREAK_TIMEOUT
320 seconds we should just die.... */
322 start_time = time(NULL);
325 * Save the information we need to re-become the
326 * user, then unbecome the user whilst we're doing this.
328 saved_conn = fsp->conn;
329 saved_vuid = current_user.vuid;
333 while(OPEN_FSP(fsp) && fsp->granted_oplock)
335 if(receive_smb(Client,inbuf,OPLOCK_BREAK_TIMEOUT * 1000) == False)
338 * Die if we got an error.
341 if (smb_read_error == READ_EOF)
342 DEBUG( 0, ( "oplock_break: end of file from client\n" ) );
344 if (smb_read_error == READ_ERROR)
345 DEBUG( 0, ("oplock_break: receive_smb error (%s)\n", strerror(errno)) );
347 if (smb_read_error == READ_TIMEOUT)
348 DEBUG( 0, ( "oplock_break: receive_smb timed out after %d seconds.\n",
349 OPLOCK_BREAK_TIMEOUT ) );
351 DEBUGADD( 0, ( "oplock_break failed for file %s ", fsp->fsp_name ) );
352 DEBUGADD( 0, ( "(dev = %x, inode = %x).\n", dev, inode));
353 shutdown_server = True;
358 * There are certain SMB requests that we shouldn't allow
359 * to recurse. opens, renames and deletes are the obvious
360 * ones. This is handled in the switch_message() function.
361 * If global_oplock_break is set they will push the packet onto
362 * the pending smb queue and return -1 (no reply).
366 process_smb(inbuf, outbuf);
369 * Die if we go over the time limit.
372 if((time(NULL) - start_time) > OPLOCK_BREAK_TIMEOUT)
376 dbgtext( "oplock_break: no break received from client " );
377 dbgtext( "within %d seconds.\n", OPLOCK_BREAK_TIMEOUT );
378 dbgtext( "oplock_break failed for file %s ", fsp->fsp_name );
379 dbgtext( "(dev = %x, inode = %x).\n", dev, inode );
381 shutdown_server = True;
387 * Go back to being the user who requested the oplock
390 if(!become_user(saved_conn, saved_vuid))
392 DEBUG( 0, ( "oplock_break: unable to re-become user!" ) );
393 DEBUGADD( 0, ( "Shutting down server\n" ) );
396 exit_server("unable to re-become user");
398 /* Including the directory. */
401 /* Free the buffers we've been using to recurse. */
405 /* We need this in case a readraw crossed on the wire. */
406 if(global_oplock_break)
407 global_oplock_break = False;
410 * If the client did not respond we must die.
415 DEBUG( 0, ( "oplock_break: client failure in break - " ) );
416 DEBUGADD( 0, ( "shutting down this smbd.\n" ) );
419 exit_server("oplock break failure");
424 /* The lockingX reply will have removed the oplock flag
425 from the sharemode. */
427 fsp->granted_oplock = False;
428 fsp->sent_oplock_break = False;
429 global_oplocks_open--;
432 /* Santity check - remove this later. JRA */
433 if(global_oplocks_open < 0)
435 DEBUG(0,("oplock_break: global_oplocks_open < 0 (%d). PANIC ERROR\n",
436 global_oplocks_open));
437 exit_server("oplock_break: global_oplocks_open < 0");
442 dbgtext( "oplock_break: returning success for " );
443 dbgtext( "dev = %x, inode = %x.\n", dev, inode );
444 dbgtext( "Current global_oplocks_open = %d\n", global_oplocks_open );
450 /****************************************************************************
451 Send an oplock break message to another smbd process. If the oplock is held
452 by the local smbd then call the oplock break function directly.
453 ****************************************************************************/
455 BOOL request_oplock_break(share_mode_entry *share_entry,
456 uint32 dev, uint32 inode)
458 char op_break_msg[OPLOCK_BREAK_MSG_LEN];
459 struct sockaddr_in addr_out;
464 if(pid == share_entry->pid)
466 /* We are breaking our own oplock, make sure it's us. */
467 if(share_entry->op_port != oplock_port)
469 DEBUG(0,("request_oplock_break: corrupt share mode entry - pid = %d, port = %d \
470 should be %d\n", pid, share_entry->op_port, oplock_port));
474 DEBUG(5,("request_oplock_break: breaking our own oplock\n"));
476 /* Call oplock break direct. */
477 return oplock_break(dev, inode, &share_entry->time);
480 /* We need to send a OPLOCK_BREAK_CMD message to the
481 port in the share mode entry. */
483 SSVAL(op_break_msg,UDP_MESSAGE_CMD_OFFSET,OPLOCK_BREAK_CMD);
484 SIVAL(op_break_msg,OPLOCK_BREAK_PID_OFFSET,pid);
485 SIVAL(op_break_msg,OPLOCK_BREAK_DEV_OFFSET,dev);
486 SIVAL(op_break_msg,OPLOCK_BREAK_INODE_OFFSET,inode);
487 SIVAL(op_break_msg,OPLOCK_BREAK_SEC_OFFSET,(uint32)share_entry->time.tv_sec);
488 SIVAL(op_break_msg,OPLOCK_BREAK_USEC_OFFSET,(uint32)share_entry->time.tv_usec);
490 /* set the address and port */
491 bzero((char *)&addr_out,sizeof(addr_out));
492 addr_out.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
493 addr_out.sin_port = htons( share_entry->op_port );
494 addr_out.sin_family = AF_INET;
498 dbgtext( "request_oplock_break: sending a oplock break message to " );
499 dbgtext( "pid %d on port %d ", share_entry->pid, share_entry->op_port );
500 dbgtext( "for dev = %x, inode = %x\n", dev, inode );
503 if(sendto(oplock_sock,op_break_msg,OPLOCK_BREAK_MSG_LEN,0,
504 (struct sockaddr *)&addr_out,sizeof(addr_out)) < 0)
508 dbgtext( "request_oplock_break: failed when sending a oplock " );
509 dbgtext( "break message to pid %d ", share_entry->pid );
510 dbgtext( "on port %d ", share_entry->op_port );
511 dbgtext( "for dev = %x, inode = %x.\n", dev, inode );
512 dbgtext( "Error was %s\n", strerror(errno) );
518 * Now we must await the oplock broken message coming back
519 * from the target smbd process. Timeout if it fails to
520 * return in (OPLOCK_BREAK_TIMEOUT + OPLOCK_BREAK_TIMEOUT_FUDGEFACTOR) seconds.
521 * While we get messages that aren't ours, loop.
524 start_time = time(NULL);
525 time_left = OPLOCK_BREAK_TIMEOUT+OPLOCK_BREAK_TIMEOUT_FUDGEFACTOR;
527 while(time_left >= 0)
529 char op_break_reply[UDP_CMD_HEADER_LEN+OPLOCK_BREAK_MSG_LEN];
531 uint16 reply_from_port;
532 char *reply_msg_start;
534 if(receive_local_message(oplock_sock, op_break_reply, sizeof(op_break_reply),
535 time_left ? time_left * 1000 : 1) == False)
537 if(smb_read_error == READ_TIMEOUT)
541 dbgtext( "request_oplock_break: no response received to oplock " );
542 dbgtext( "break request to pid %d ", share_entry->pid );
543 dbgtext( "on port %d ", share_entry->op_port );
544 dbgtext( "for dev = %x, inode = %x\n", dev, inode );
547 * This is a hack to make handling of failing clients more robust.
548 * If a oplock break response message is not received in the timeout
549 * period we may assume that the smbd servicing that client holding
550 * the oplock has died and the client changes were lost anyway, so
551 * we should continue to try and open the file.
558 dbgtext( "request_oplock_break: error in response received " );
559 dbgtext( "to oplock break request to pid %d ", share_entry->pid );
560 dbgtext( "on port %d ", share_entry->op_port );
561 dbgtext( "for dev = %x, inode = %x.\n", dev, inode );
562 dbgtext( "Error was (%s).\n", strerror(errno) );
567 reply_msg_len = IVAL(op_break_reply,UDP_CMD_LEN_OFFSET);
568 reply_from_port = SVAL(op_break_reply,UDP_CMD_PORT_OFFSET);
570 reply_msg_start = &op_break_reply[UDP_CMD_HEADER_LEN];
572 if(reply_msg_len != OPLOCK_BREAK_MSG_LEN)
575 DEBUG( 0, ( "request_oplock_break: invalid message length received." ) );
576 DEBUGADD( 0, ( " Ignoring.\n" ) );
581 * Test to see if this is the reply we are awaiting.
584 if((SVAL(reply_msg_start,UDP_MESSAGE_CMD_OFFSET) & CMD_REPLY) &&
585 (reply_from_port == share_entry->op_port) &&
586 (memcmp(&reply_msg_start[OPLOCK_BREAK_PID_OFFSET],
587 &op_break_msg[OPLOCK_BREAK_PID_OFFSET],
588 OPLOCK_BREAK_MSG_LEN - OPLOCK_BREAK_PID_OFFSET) == 0))
591 * This is the reply we've been waiting for.
598 * This is another message - probably a break request.
599 * Process it to prevent potential deadlock.
600 * Note that the code in switch_message() prevents
601 * us from recursing into here as any SMB requests
602 * we might process that would cause another oplock
603 * break request to be made will be queued.
607 process_local_message(oplock_sock, op_break_reply, sizeof(op_break_reply));
610 time_left -= (time(NULL) - start_time);
613 DEBUG(3,("request_oplock_break: broke oplock.\n"));
619 /****************************************************************************
620 Attempt to break an oplock on a file (if oplocked).
621 Returns True if the file was closed as a result of
622 the oplock break, False otherwise.
623 Used as a last ditch attempt to free a space in the
624 file table when we have run out.
625 ****************************************************************************/
626 BOOL attempt_close_oplocked_file(files_struct *fsp)
629 DEBUG(5,("attempt_close_oplocked_file: checking file %s.\n", fsp->fsp_name));
631 if (fsp->open && fsp->granted_oplock && !fsp->sent_oplock_break) {
633 /* Try and break the oplock. */
634 file_fd_struct *fd_ptr = fsp->fd_ptr;
635 if(oplock_break( fd_ptr->dev, fd_ptr->inode, &fsp->open_time)) {
636 if(!fsp->open) /* Did the oplock break close the file ? */