15331Samw /* 25331Samw * CDDL HEADER START 35331Samw * 45331Samw * The contents of this file are subject to the terms of the 55331Samw * Common Development and Distribution License (the "License"). 65331Samw * You may not use this file except in compliance with the License. 75331Samw * 85331Samw * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 95331Samw * or http://www.opensolaris.org/os/licensing. 105331Samw * See the License for the specific language governing permissions 115331Samw * and limitations under the License. 125331Samw * 135331Samw * When distributing Covered Code, include this CDDL HEADER in each 145331Samw * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 155331Samw * If applicable, add the following below this CDDL HEADER, with the 165331Samw * fields enclosed by brackets "[]" replaced with your own identifying 175331Samw * information: Portions Copyright [yyyy] [name of copyright owner] 185331Samw * 195331Samw * CDDL HEADER END 205331Samw */ 215331Samw /* 225772Sas200622 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 235331Samw * Use is subject to license terms. 245331Samw */ 255331Samw 26*7348SJose.Borrego@Sun.COM #pragma ident "@(#)smb_close.c 1.6 08/08/08 SMI" 275331Samw 285331Samw #include <smbsrv/smb_incl.h> 295331Samw 305331Samw 315331Samw /* 325331Samw * Close a file by fid. All locks or other resources held by the 335331Samw * requesting process on the file should be released by the server. 345331Samw * The requesting process can no longer use the fid for further 355331Samw * file access requests. 365331Samw * 375331Samw * If LastWriteTime is non-zero, it should be used to set the file 385331Samw * timestamp. Otherwise, file system should set the timestamp. 395331Samw * Failure to set the timestamp, even if requested by the client, 405331Samw * should not result in an error response from the server. 415331Samw */ 426030Sjb150015 smb_sdrc_t 436139Sjb150015 smb_pre_close(smb_request_t *sr) 445331Samw { 456139Sjb150015 int rc; 466139Sjb150015 476139Sjb150015 rc = smbsr_decode_vwv(sr, "wl", &sr->smb_fid, &sr->arg.timestamp); 486139Sjb150015 496139Sjb150015 DTRACE_SMB_1(op__Close__start, smb_request_t *, sr); 506139Sjb150015 return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR); 516139Sjb150015 } 525331Samw 536139Sjb150015 void 546139Sjb150015 smb_post_close(smb_request_t *sr) 556139Sjb150015 { 566139Sjb150015 DTRACE_SMB_1(op__Close__done, smb_request_t *, sr); 576139Sjb150015 } 586139Sjb150015 596139Sjb150015 smb_sdrc_t 606139Sjb150015 smb_com_close(smb_request_t *sr) 616139Sjb150015 { 625331Samw sr->fid_ofile = smb_ofile_lookup_by_fid(sr->tid_tree, sr->smb_fid); 635331Samw if (sr->fid_ofile == NULL) { 645772Sas200622 smbsr_error(sr, NT_STATUS_INVALID_HANDLE, ERRDOS, ERRbadfid); 656139Sjb150015 return (SDRC_ERROR); 665331Samw } 675331Samw 68*7348SJose.Borrego@Sun.COM smb_ofile_close(sr->fid_ofile, sr->arg.timestamp); 69*7348SJose.Borrego@Sun.COM 70*7348SJose.Borrego@Sun.COM if (smbsr_encode_empty_result(sr) != 0) 716139Sjb150015 return (SDRC_ERROR); 725331Samw 73*7348SJose.Borrego@Sun.COM return (SDRC_SUCCESS); 745331Samw } 755331Samw 765331Samw /* 775331Samw * Close the file represented by fid and then disconnect the 785331Samw * associated tree. 795331Samw */ 806030Sjb150015 smb_sdrc_t 816139Sjb150015 smb_pre_close_and_tree_disconnect(smb_request_t *sr) 825331Samw { 836139Sjb150015 int rc; 846139Sjb150015 856139Sjb150015 rc = smbsr_decode_vwv(sr, "wl", &sr->smb_fid, &sr->arg.timestamp); 866139Sjb150015 876139Sjb150015 DTRACE_SMB_1(op__CloseAndTreeDisconnect__start, smb_request_t *, sr); 886139Sjb150015 return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR); 896139Sjb150015 } 905331Samw 916139Sjb150015 void 926139Sjb150015 smb_post_close_and_tree_disconnect(smb_request_t *sr) 936139Sjb150015 { 946139Sjb150015 DTRACE_SMB_1(op__CloseAndTreeDisconnect__done, smb_request_t *, sr); 956139Sjb150015 } 966139Sjb150015 976139Sjb150015 smb_sdrc_t 986139Sjb150015 smb_com_close_and_tree_disconnect(smb_request_t *sr) 996139Sjb150015 { 1005331Samw sr->fid_ofile = smb_ofile_lookup_by_fid(sr->tid_tree, sr->smb_fid); 1015331Samw if (sr->fid_ofile == NULL) { 1025772Sas200622 smbsr_error(sr, NT_STATUS_INVALID_HANDLE, ERRDOS, ERRbadfid); 1036139Sjb150015 return (SDRC_ERROR); 1045331Samw } 1055331Samw 106*7348SJose.Borrego@Sun.COM smb_ofile_close(sr->fid_ofile, sr->arg.timestamp); 107*7348SJose.Borrego@Sun.COM smb_session_cancel_requests(sr->session, sr->tid_tree, sr); 1085331Samw smb_tree_disconnect(sr->tid_tree); 1095331Samw 110*7348SJose.Borrego@Sun.COM if (smbsr_encode_empty_result(sr) != 0) 1116139Sjb150015 return (SDRC_ERROR); 1125331Samw 113*7348SJose.Borrego@Sun.COM return (SDRC_SUCCESS); 1145331Samw } 1155331Samw 1165331Samw /* 1175331Samw * smb_commit_delete_on_close() 1185331Samw * 1195331Samw * Check for the DeleteOnClose flag on the smb file and set it on the 1205331Samw * smb node if it is not already set. This will inhibit subsequent 1215331Samw * open requests. The delete-on-close credentials should be set to the 1225331Samw * user credentials of the current open file instance. 1235331Samw * 1245331Samw * When DeleteOnClose is set on an smb_node, the common open code will 1255331Samw * reject subsequent open requests for the file. Observation of Windows 1265331Samw * 2000 indicates that subsequent opens should be allowed (assuming 1275331Samw * there would be no sharing violation) until the file is closed using 1285331Samw * the fid on which the DeleteOnClose was requested. 1295331Samw * 1305331Samw * If there are multiple opens with delete-on-close create options, 1315331Samw * whichever the first file handle is closed will trigger the node to be 1325331Samw * marked as delete-on-close. The credentials of that ofile will be used 1335331Samw * as the delete-on-close credentials of the node. 1345331Samw */ 1355331Samw void 1365331Samw smb_commit_delete_on_close(struct smb_ofile *ofile) 1375331Samw { 1385331Samw struct smb_node *node = ofile->f_node; 1395331Samw 1405331Samw if (!(node->flags & NODE_FLAGS_DELETE_ON_CLOSE) && 1415331Samw (ofile->f_flags & SMB_OFLAGS_SET_DELETE_ON_CLOSE)) { 1425331Samw node->flags |= NODE_FLAGS_DELETE_ON_CLOSE; 1435331Samw crhold(node->delete_on_close_cred = ofile->f_cr); 1445331Samw } 1455331Samw } 146