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;
37 static BOOL oplock_break(SMB_DEV_T dev, SMB_INO_T inode, struct timeval *tval);
40 /****************************************************************************
41 open the oplock IPC socket communication
42 ****************************************************************************/
43 BOOL open_oplock_ipc(void)
45 struct sockaddr_in sock_name;
46 int len = sizeof(sock_name);
48 DEBUG(3,("open_oplock_ipc: opening loopback UDP socket.\n"));
50 /* Open a lookback UDP socket on a random port. */
51 oplock_sock = open_socket_in(SOCK_DGRAM, 0, 0, htonl(INADDR_LOOPBACK));
52 if (oplock_sock == -1)
54 DEBUG(0,("open_oplock_ipc: Failed to get local UDP socket for \
55 address %x. Error was %s\n", htonl(INADDR_LOOPBACK), strerror(errno)));
60 /* Find out the transient UDP port we have been allocated. */
61 if(getsockname(oplock_sock, (struct sockaddr *)&sock_name, &len)<0)
63 DEBUG(0,("open_oplock_ipc: Failed to get local UDP port. Error was %s\n",
70 oplock_port = ntohs(sock_name.sin_port);
72 DEBUG(3,("open_oplock ipc: pid = %d, oplock_port = %u\n",
73 (int)getpid(), oplock_port));
78 /****************************************************************************
79 process an oplock break message.
80 ****************************************************************************/
81 BOOL process_local_message(int sock, char *buffer, int buf_size)
87 msg_len = IVAL(buffer,UDP_CMD_LEN_OFFSET);
88 from_port = SVAL(buffer,UDP_CMD_PORT_OFFSET);
90 msg_start = &buffer[UDP_CMD_HEADER_LEN];
92 DEBUG(5,("process_local_message: Got a message of length %d from port (%d)\n",
95 /* Switch on message command - currently OPLOCK_BREAK_CMD is the
96 only valid request. */
98 switch(SVAL(msg_start,UDP_MESSAGE_CMD_OFFSET))
100 case OPLOCK_BREAK_CMD:
101 /* Ensure that the msg length is correct. */
102 if(msg_len != OPLOCK_BREAK_MSG_LEN)
104 DEBUG(0,("process_local_message: incorrect length for OPLOCK_BREAK_CMD (was %d, \
105 should be %d).\n", msg_len, OPLOCK_BREAK_MSG_LEN));
109 uint32 remotepid = IVAL(msg_start,OPLOCK_BREAK_PID_OFFSET);
110 SMB_DEV_T dev = IVAL(msg_start,OPLOCK_BREAK_DEV_OFFSET);
112 * Warning - beware of SMB_INO_T <> 4 bytes. !!
114 #ifdef LARGE_SMB_INO_T
115 SMB_INO_T inode_low = IVAL(msg_start, OPLOCK_BREAK_INODE_OFFSET);
116 SMB_INO_T inode_high = IVAL(msg_start, OPLOCK_BREAK_INODE_OFFSET + 4);
117 SMB_INO_T inode = inode_low | (inode_high << 32);
118 #else /* LARGE_SMB_INO_T */
119 SMB_INO_T inode = IVAL(msg_start, OPLOCK_BREAK_INODE_OFFSET);
120 #endif /* LARGE_SMB_INO_T */
122 struct sockaddr_in toaddr;
124 tval.tv_sec = IVAL(msg_start, OPLOCK_BREAK_SEC_OFFSET);
125 tval.tv_usec = IVAL(msg_start, OPLOCK_BREAK_USEC_OFFSET);
127 DEBUG(5,("process_local_message: oplock break request from \
128 pid %d, port %d, dev = %x, inode = %.0f\n", remotepid, from_port, (unsigned int)dev, (double)inode));
131 * If we have no record of any currently open oplocks,
132 * it's not an error, as a close command may have
133 * just been issued on the file that was oplocked.
134 * Just return success in this case.
137 if(global_oplocks_open != 0)
139 if(oplock_break(dev, inode, &tval) == False)
141 DEBUG(0,("process_local_message: oplock break failed - \
142 not returning udp message.\n"));
148 DEBUG(3,("process_local_message: oplock break requested with no outstanding \
149 oplocks. Returning success.\n"));
152 /* Send the message back after OR'ing in the 'REPLY' bit. */
153 SSVAL(msg_start,UDP_MESSAGE_CMD_OFFSET,OPLOCK_BREAK_CMD | CMD_REPLY);
155 bzero((char *)&toaddr,sizeof(toaddr));
156 toaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
157 toaddr.sin_port = htons(from_port);
158 toaddr.sin_family = AF_INET;
160 if(sendto( sock, msg_start, OPLOCK_BREAK_MSG_LEN, 0,
161 (struct sockaddr *)&toaddr, sizeof(toaddr)) < 0)
163 DEBUG(0,("process_local_message: sendto process %d failed. Errno was %s\n",
164 remotepid, strerror(errno)));
168 DEBUG(5,("process_local_message: oplock break reply sent to \
169 pid %d, port %d, for file dev = %x, inode = %.0f\n",
170 remotepid, from_port, (unsigned int)dev, (double)inode));
175 * Keep this as a debug case - eventually we can remove it.
178 DEBUG(0,("process_local_message: Received unsolicited break \
179 reply - dumping info.\n"));
181 if(msg_len != OPLOCK_BREAK_MSG_LEN)
183 DEBUG(0,("process_local_message: ubr: incorrect length for reply \
184 (was %d, should be %d).\n", msg_len, OPLOCK_BREAK_MSG_LEN));
189 uint32 remotepid = IVAL(msg_start,OPLOCK_BREAK_PID_OFFSET);
190 SMB_DEV_T dev = IVAL(msg_start,OPLOCK_BREAK_DEV_OFFSET);
192 * Warning - beware of SMB_INO_T <> 4 bytes. !!
194 #ifdef LARGE_SMB_INO_T
195 SMB_INO_T inode_low = IVAL(msg_start, OPLOCK_BREAK_INODE_OFFSET);
196 SMB_INO_T inode_high = IVAL(msg_start, OPLOCK_BREAK_INODE_OFFSET + 4);
197 SMB_INO_T inode = inode_low | (inode_high << 32);
198 #else /* LARGE_SMB_INO_T */
199 SMB_INO_T inode = IVAL(msg_start, OPLOCK_BREAK_INODE_OFFSET);
200 #endif /* LARGE_SMB_INO_T */
202 DEBUG(0,("process_local_message: unsolicited oplock break reply from \
203 pid %d, port %d, dev = %x, inode = %.0f\n", remotepid, from_port, (unsigned int)dev, (double)inode));
209 DEBUG(0,("process_local_message: unknown UDP message command code (%x) - ignoring.\n",
210 (unsigned int)SVAL(msg_start,0)));
216 /****************************************************************************
217 Process an oplock break directly.
218 ****************************************************************************/
219 static BOOL oplock_break(SMB_DEV_T dev, SMB_INO_T inode, struct timeval *tval)
221 extern struct current_user current_user;
225 files_struct *fsp = NULL;
227 BOOL shutdown_server = False;
228 connection_struct *saved_conn;
234 dbgtext( "oplock_break: called for dev = %x, inode = %.0f.\n", (unsigned int)dev, (double)inode );
235 dbgtext( "Current global_oplocks_open = %d\n", global_oplocks_open );
238 /* We need to search the file open table for the
239 entry containing this dev and inode, and ensure
240 we have an oplock on it. */
241 fsp = file_find_dit(dev, inode, tval);
245 /* The file could have been closed in the meantime - return success. */
248 dbgtext( "oplock_break: cannot find open file with " );
249 dbgtext( "dev = %x, inode = %.0f ", (unsigned int)dev, (double)inode);
250 dbgtext( "allowing break to succeed.\n" );
255 /* Ensure we have an oplock on the file */
257 /* There is a potential race condition in that an oplock could
258 have been broken due to another udp request, and yet there are
259 still oplock break messages being sent in the udp message
260 queue for this file. So return true if we don't have an oplock,
261 as we may have just freed it.
264 if(!fsp->granted_oplock)
268 dbgtext( "oplock_break: file %s ", fsp->fsp_name );
269 dbgtext( "(dev = %x, inode = %.0f) has no oplock.\n", (unsigned int)dev, (double)inode );
270 dbgtext( "Allowing break to succeed regardless.\n" );
275 /* mark the oplock break as sent - we don't want to send twice! */
276 if (fsp->sent_oplock_break)
280 dbgtext( "oplock_break: ERROR: oplock_break already sent for " );
281 dbgtext( "file %s ", fsp->fsp_name);
282 dbgtext( "(dev = %x, inode = %.0f)\n", (unsigned int)dev, (double)inode );
285 /* We have to fail the open here as we cannot send another oplock break on
286 this file whilst we are awaiting a response from the client - neither
287 can we allow another open to succeed while we are waiting for the
293 /* Now comes the horrid part. We must send an oplock break to the client,
294 and then process incoming messages until we get a close or oplock release.
295 At this point we know we need a new inbuf/outbuf buffer pair.
296 We cannot use these staticaly as we may recurse into here due to
297 messages crossing on the wire.
300 if((inbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN))==NULL)
302 DEBUG(0,("oplock_break: malloc fail for input buffer.\n"));
306 if((outbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN))==NULL)
308 DEBUG(0,("oplock_break: malloc fail for output buffer.\n"));
314 /* Prepare the SMBlockingX message. */
315 bzero(outbuf,smb_size);
316 set_message(outbuf,8,0,True);
318 SCVAL(outbuf,smb_com,SMBlockingX);
319 SSVAL(outbuf,smb_tid,fsp->conn->cnum);
320 SSVAL(outbuf,smb_pid,0xFFFF);
321 SSVAL(outbuf,smb_uid,0);
322 SSVAL(outbuf,smb_mid,0xFFFF);
323 SCVAL(outbuf,smb_vwv0,0xFF);
324 SSVAL(outbuf,smb_vwv2,fsp->fnum);
325 SCVAL(outbuf,smb_vwv3,LOCKING_ANDX_OPLOCK_RELEASE);
326 /* Change this when we have level II oplocks. */
327 SCVAL(outbuf,smb_vwv3+1,OPLOCKLEVEL_NONE);
329 send_smb(Client, outbuf);
331 /* Remember we just sent an oplock break on this file. */
332 fsp->sent_oplock_break = True;
334 /* We need this in case a readraw crosses on the wire. */
335 global_oplock_break = True;
337 /* Process incoming messages. */
339 /* JRA - If we don't get a break from the client in OPLOCK_BREAK_TIMEOUT
340 seconds we should just die.... */
342 start_time = time(NULL);
345 * Save the information we need to re-become the
346 * user, then unbecome the user whilst we're doing this.
348 saved_conn = fsp->conn;
349 saved_vuid = current_user.vuid;
352 /* Save the chain fnum. */
355 while(OPEN_FSP(fsp) && fsp->granted_oplock)
357 if(receive_smb(Client,inbuf,OPLOCK_BREAK_TIMEOUT * 1000) == False)
360 * Die if we got an error.
363 if (smb_read_error == READ_EOF)
364 DEBUG( 0, ( "oplock_break: end of file from client\n" ) );
366 if (smb_read_error == READ_ERROR)
367 DEBUG( 0, ("oplock_break: receive_smb error (%s)\n", strerror(errno)) );
369 if (smb_read_error == READ_TIMEOUT)
370 DEBUG( 0, ( "oplock_break: receive_smb timed out after %d seconds.\n",
371 OPLOCK_BREAK_TIMEOUT ) );
373 DEBUGADD( 0, ( "oplock_break failed for file %s ", fsp->fsp_name ) );
374 DEBUGADD( 0, ( "(dev = %x, inode = %.0f).\n", (unsigned int)dev, (double)inode));
376 shutdown_server = True;
381 * There are certain SMB requests that we shouldn't allow
382 * to recurse. opens, renames and deletes are the obvious
383 * ones. This is handled in the switch_message() function.
384 * If global_oplock_break is set they will push the packet onto
385 * the pending smb queue and return -1 (no reply).
389 process_smb(inbuf, outbuf);
392 * Die if we go over the time limit.
395 if((time(NULL) - start_time) > OPLOCK_BREAK_TIMEOUT)
399 dbgtext( "oplock_break: no break received from client " );
400 dbgtext( "within %d seconds.\n", OPLOCK_BREAK_TIMEOUT );
401 dbgtext( "oplock_break failed for file %s ", fsp->fsp_name );
402 dbgtext( "(dev = %x, inode = %.0f).\n", (unsigned int)dev, (double)inode );
405 shutdown_server = True;
411 * Go back to being the user who requested the oplock
414 if(!become_user(saved_conn, saved_vuid))
416 DEBUG( 0, ( "oplock_break: unable to re-become user!" ) );
417 DEBUGADD( 0, ( "Shutting down server\n" ) );
420 exit_server("unable to re-become user");
422 /* Including the directory. */
425 /* Restore the chain fnum. */
426 file_chain_restore();
428 /* Free the buffers we've been using to recurse. */
432 /* We need this in case a readraw crossed on the wire. */
433 if(global_oplock_break)
434 global_oplock_break = False;
437 * If the client did not respond we must die.
442 DEBUG( 0, ( "oplock_break: client failure in break - " ) );
443 DEBUGADD( 0, ( "shutting down this smbd.\n" ) );
446 exit_server("oplock break failure");
451 /* The lockingX reply will have removed the oplock flag
452 from the sharemode. */
454 fsp->granted_oplock = False;
455 fsp->sent_oplock_break = False;
456 global_oplocks_open--;
459 /* Santity check - remove this later. JRA */
460 if(global_oplocks_open < 0)
462 DEBUG(0,("oplock_break: global_oplocks_open < 0 (%d). PANIC ERROR\n",
463 global_oplocks_open));
464 exit_server("oplock_break: global_oplocks_open < 0");
469 dbgtext( "oplock_break: returning success for " );
470 dbgtext( "dev = %x, inode = %.0f\n", (unsigned int)dev, (double)inode );
471 dbgtext( "Current global_oplocks_open = %d\n", global_oplocks_open );
477 /****************************************************************************
478 Send an oplock break message to another smbd process. If the oplock is held
479 by the local smbd then call the oplock break function directly.
480 ****************************************************************************/
482 BOOL request_oplock_break(share_mode_entry *share_entry,
483 SMB_DEV_T dev, SMB_INO_T inode)
485 char op_break_msg[OPLOCK_BREAK_MSG_LEN];
486 struct sockaddr_in addr_out;
491 if(pid == share_entry->pid)
493 /* We are breaking our own oplock, make sure it's us. */
494 if(share_entry->op_port != oplock_port)
496 DEBUG(0,("request_oplock_break: corrupt share mode entry - pid = %d, port = %d \
497 should be %d\n", pid, share_entry->op_port, oplock_port));
501 DEBUG(5,("request_oplock_break: breaking our own oplock\n"));
503 /* Call oplock break direct. */
504 return oplock_break(dev, inode, &share_entry->time);
507 /* We need to send a OPLOCK_BREAK_CMD message to the
508 port in the share mode entry. */
510 SSVAL(op_break_msg,UDP_MESSAGE_CMD_OFFSET,OPLOCK_BREAK_CMD);
511 SIVAL(op_break_msg,OPLOCK_BREAK_PID_OFFSET,pid);
512 SIVAL(op_break_msg,OPLOCK_BREAK_SEC_OFFSET,(uint32)share_entry->time.tv_sec);
513 SIVAL(op_break_msg,OPLOCK_BREAK_USEC_OFFSET,(uint32)share_entry->time.tv_usec);
514 SIVAL(op_break_msg,OPLOCK_BREAK_DEV_OFFSET,dev);
516 * WARNING - beware of SMB_INO_T <> 4 bytes.
518 #ifdef LARGE_SMB_INO_T
519 SIVAL(op_break_msg,OPLOCK_BREAK_INODE_OFFSET,(inode & 0xFFFFFFFFL));
520 SIVAL(op_break_msg,OPLOCK_BREAK_INODE_OFFSET+4,((inode >> 32) & 0xFFFFFFFFL));
521 #else /* LARGE_SMB_INO_T */
522 SIVAL(op_break_msg,OPLOCK_BREAK_INODE_OFFSET,inode);
523 #endif /* LARGE_SMB_INO_T */
525 /* set the address and port */
526 bzero((char *)&addr_out,sizeof(addr_out));
527 addr_out.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
528 addr_out.sin_port = htons( share_entry->op_port );
529 addr_out.sin_family = AF_INET;
533 dbgtext( "request_oplock_break: sending a oplock break message to " );
534 dbgtext( "pid %d on port %d ", share_entry->pid, share_entry->op_port );
535 dbgtext( "for dev = %x, inode = %.0f\n", (unsigned int)dev, (double)inode );
539 if(sendto(oplock_sock,op_break_msg,OPLOCK_BREAK_MSG_LEN,0,
540 (struct sockaddr *)&addr_out,sizeof(addr_out)) < 0)
544 dbgtext( "request_oplock_break: failed when sending a oplock " );
545 dbgtext( "break message to pid %d ", share_entry->pid );
546 dbgtext( "on port %d ", share_entry->op_port );
547 dbgtext( "for dev = %x, inode = %.0f\n", (unsigned int)dev, (double)inode );
548 dbgtext( "Error was %s\n", strerror(errno) );
554 * Now we must await the oplock broken message coming back
555 * from the target smbd process. Timeout if it fails to
556 * return in (OPLOCK_BREAK_TIMEOUT + OPLOCK_BREAK_TIMEOUT_FUDGEFACTOR) seconds.
557 * While we get messages that aren't ours, loop.
560 start_time = time(NULL);
561 time_left = OPLOCK_BREAK_TIMEOUT+OPLOCK_BREAK_TIMEOUT_FUDGEFACTOR;
563 while(time_left >= 0)
565 char op_break_reply[UDP_CMD_HEADER_LEN+OPLOCK_BREAK_MSG_LEN];
567 uint16 reply_from_port;
568 char *reply_msg_start;
570 if(receive_local_message(oplock_sock, op_break_reply, sizeof(op_break_reply),
571 time_left ? time_left * 1000 : 1) == False)
573 if(smb_read_error == READ_TIMEOUT)
577 dbgtext( "request_oplock_break: no response received to oplock " );
578 dbgtext( "break request to pid %d ", share_entry->pid );
579 dbgtext( "on port %d ", share_entry->op_port );
580 dbgtext( "for dev = %x, inode = %.0f\n", (unsigned int)dev, (double)inode );
584 * This is a hack to make handling of failing clients more robust.
585 * If a oplock break response message is not received in the timeout
586 * period we may assume that the smbd servicing that client holding
587 * the oplock has died and the client changes were lost anyway, so
588 * we should continue to try and open the file.
595 dbgtext( "request_oplock_break: error in response received " );
596 dbgtext( "to oplock break request to pid %d ", share_entry->pid );
597 dbgtext( "on port %d ", share_entry->op_port );
598 dbgtext( "for dev = %x, inode = %.0f\n", (unsigned int)dev, (double)inode );
599 dbgtext( "Error was (%s).\n", strerror(errno) );
604 reply_msg_len = IVAL(op_break_reply,UDP_CMD_LEN_OFFSET);
605 reply_from_port = SVAL(op_break_reply,UDP_CMD_PORT_OFFSET);
607 reply_msg_start = &op_break_reply[UDP_CMD_HEADER_LEN];
609 if(reply_msg_len != OPLOCK_BREAK_MSG_LEN)
612 DEBUG( 0, ( "request_oplock_break: invalid message length received." ) );
613 DEBUGADD( 0, ( " Ignoring.\n" ) );
618 * Test to see if this is the reply we are awaiting.
621 if((SVAL(reply_msg_start,UDP_MESSAGE_CMD_OFFSET) & CMD_REPLY) &&
622 (reply_from_port == share_entry->op_port) &&
623 (memcmp(&reply_msg_start[OPLOCK_BREAK_PID_OFFSET],
624 &op_break_msg[OPLOCK_BREAK_PID_OFFSET],
625 OPLOCK_BREAK_MSG_LEN - OPLOCK_BREAK_PID_OFFSET) == 0))
628 * This is the reply we've been waiting for.
635 * This is another message - probably a break request.
636 * Process it to prevent potential deadlock.
637 * Note that the code in switch_message() prevents
638 * us from recursing into here as any SMB requests
639 * we might process that would cause another oplock
640 * break request to be made will be queued.
644 process_local_message(oplock_sock, op_break_reply, sizeof(op_break_reply));
647 time_left -= (time(NULL) - start_time);
650 DEBUG(3,("request_oplock_break: broke oplock.\n"));
656 /****************************************************************************
657 Attempt to break an oplock on a file (if oplocked).
658 Returns True if the file was closed as a result of
659 the oplock break, False otherwise.
660 Used as a last ditch attempt to free a space in the
661 file table when we have run out.
662 ****************************************************************************/
663 BOOL attempt_close_oplocked_file(files_struct *fsp)
666 DEBUG(5,("attempt_close_oplocked_file: checking file %s.\n", fsp->fsp_name));
668 if (fsp->open && fsp->granted_oplock && !fsp->sent_oplock_break) {
670 /* Try and break the oplock. */
671 file_fd_struct *fd_ptr = fsp->fd_ptr;
672 if(oplock_break( fd_ptr->dev, fd_ptr->inode, &fsp->open_time)) {
673 if(!fsp->open) /* Did the oplock break close the file ? */