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;
332 /* Save the chain fnum. */
335 while(OPEN_FSP(fsp) && fsp->granted_oplock)
337 if(receive_smb(Client,inbuf,OPLOCK_BREAK_TIMEOUT * 1000) == False)
340 * Die if we got an error.
343 if (smb_read_error == READ_EOF)
344 DEBUG( 0, ( "oplock_break: end of file from client\n" ) );
346 if (smb_read_error == READ_ERROR)
347 DEBUG( 0, ("oplock_break: receive_smb error (%s)\n", strerror(errno)) );
349 if (smb_read_error == READ_TIMEOUT)
350 DEBUG( 0, ( "oplock_break: receive_smb timed out after %d seconds.\n",
351 OPLOCK_BREAK_TIMEOUT ) );
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;
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).
368 process_smb(inbuf, outbuf);
371 * Die if we go over the time limit.
374 if((time(NULL) - start_time) > OPLOCK_BREAK_TIMEOUT)
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 );
383 shutdown_server = True;
389 * Go back to being the user who requested the oplock
392 if(!become_user(saved_conn, saved_vuid))
394 DEBUG( 0, ( "oplock_break: unable to re-become user!" ) );
395 DEBUGADD( 0, ( "Shutting down server\n" ) );
398 exit_server("unable to re-become user");
400 /* Including the directory. */
403 /* Restore the chain fnum. */
404 file_chain_restore();
406 /* Free the buffers we've been using to recurse. */
410 /* We need this in case a readraw crossed on the wire. */
411 if(global_oplock_break)
412 global_oplock_break = False;
415 * If the client did not respond we must die.
420 DEBUG( 0, ( "oplock_break: client failure in break - " ) );
421 DEBUGADD( 0, ( "shutting down this smbd.\n" ) );
424 exit_server("oplock break failure");
429 /* The lockingX reply will have removed the oplock flag
430 from the sharemode. */
432 fsp->granted_oplock = False;
433 fsp->sent_oplock_break = False;
434 global_oplocks_open--;
437 /* Santity check - remove this later. JRA */
438 if(global_oplocks_open < 0)
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");
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 );
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 ****************************************************************************/
460 BOOL request_oplock_break(share_mode_entry *share_entry,
461 uint32 dev, uint32 inode)
463 char op_break_msg[OPLOCK_BREAK_MSG_LEN];
464 struct sockaddr_in addr_out;
469 if(pid == share_entry->pid)
471 /* We are breaking our own oplock, make sure it's us. */
472 if(share_entry->op_port != oplock_port)
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));
479 DEBUG(5,("request_oplock_break: breaking our own oplock\n"));
481 /* Call oplock break direct. */
482 return oplock_break(dev, inode, &share_entry->time);
485 /* We need to send a OPLOCK_BREAK_CMD message to the
486 port in the share mode entry. */
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);
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;
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 );
508 if(sendto(oplock_sock,op_break_msg,OPLOCK_BREAK_MSG_LEN,0,
509 (struct sockaddr *)&addr_out,sizeof(addr_out)) < 0)
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) );
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.
529 start_time = time(NULL);
530 time_left = OPLOCK_BREAK_TIMEOUT+OPLOCK_BREAK_TIMEOUT_FUDGEFACTOR;
532 while(time_left >= 0)
534 char op_break_reply[UDP_CMD_HEADER_LEN+OPLOCK_BREAK_MSG_LEN];
536 uint16 reply_from_port;
537 char *reply_msg_start;
539 if(receive_local_message(oplock_sock, op_break_reply, sizeof(op_break_reply),
540 time_left ? time_left * 1000 : 1) == False)
542 if(smb_read_error == READ_TIMEOUT)
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 );
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.
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) );
572 reply_msg_len = IVAL(op_break_reply,UDP_CMD_LEN_OFFSET);
573 reply_from_port = SVAL(op_break_reply,UDP_CMD_PORT_OFFSET);
575 reply_msg_start = &op_break_reply[UDP_CMD_HEADER_LEN];
577 if(reply_msg_len != OPLOCK_BREAK_MSG_LEN)
580 DEBUG( 0, ( "request_oplock_break: invalid message length received." ) );
581 DEBUGADD( 0, ( " Ignoring.\n" ) );
586 * Test to see if this is the reply we are awaiting.
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))
596 * This is the reply we've been waiting for.
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.
612 process_local_message(oplock_sock, op_break_reply, sizeof(op_break_reply));
615 time_left -= (time(NULL) - start_time);
618 DEBUG(3,("request_oplock_break: broke oplock.\n"));
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)
634 DEBUG(5,("attempt_close_oplocked_file: checking file %s.\n", fsp->fsp_name));
636 if (fsp->open && fsp->granted_oplock && !fsp->sent_oplock_break) {
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 ? */