[SCM] Samba Shared Repository - branch master updated - release-4-0-0alpha8-313-gd7809f6

Stefan Metzmacher metze at samba.org
Sun Jul 12 15:57:08 GMT 2009


The branch, master has been updated
       via  d7809f65cf25ea10b3edd7df209cbf67a43df138 (commit)
       via  64221bc3facde5d2e6d35516eb997d83c5f90d35 (commit)
       via  e9865150dfd9a81fdc3a8b13b086540641fb4c2e (commit)
       via  0851d73f4dbb916b6e83d89cf2e2959c1159b7e0 (commit)
       via  0ba532e1b2dedea3c07fa55631fac0d9a5032fcf (commit)
       via  ee690df294aab7a738bfec1976a2f015e918db1e (commit)
       via  8422e032339f624e6322a4a6a4938b1d84b347a0 (commit)
       via  20bc933c5b2f420f3588adf811a66aa886a1b41e (commit)
      from  2000421c592b672898f85758638be74d8485da1e (commit)

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit d7809f65cf25ea10b3edd7df209cbf67a43df138
Author: Stefan Metzmacher <metze at samba.org>
Date:   Fri Jul 10 20:39:08 2009 +0200

    s3:smbd: start SMB2 GetInfo support for File*Information levels
    
    TODO: the EA levels are not fully supported.
    
    metze

commit 64221bc3facde5d2e6d35516eb997d83c5f90d35
Author: Stefan Metzmacher <metze at samba.org>
Date:   Sun Jul 12 16:40:58 2009 +0200

    s3:smbd: add support for marshalling SMB2 FileFullEaInformation
    
    metze

commit e9865150dfd9a81fdc3a8b13b086540641fb4c2e
Author: Stefan Metzmacher <metze at samba.org>
Date:   Sun Jul 12 17:08:18 2009 +0200

    s3:smbd: add support for marshalling SMB2 FileAllInformation
    
    metze

commit 0851d73f4dbb916b6e83d89cf2e2959c1159b7e0
Author: Stefan Metzmacher <metze at samba.org>
Date:   Sun Jul 12 17:06:05 2009 +0200

    s3:smbd: filter out SMB2 specific private query info levels for SMB1
    
    metze

commit 0ba532e1b2dedea3c07fa55631fac0d9a5032fcf
Author: Stefan Metzmacher <metze at samba.org>
Date:   Fri Jul 10 20:02:44 2009 +0200

    s3:smbd: make smbd_do_qfilepathinfo() non static for use in SMB2
    
    metze

commit ee690df294aab7a738bfec1976a2f015e918db1e
Author: Stefan Metzmacher <metze at samba.org>
Date:   Sun Jul 12 16:37:49 2009 +0200

    s3:smbd: split calculation and mashalling of file index and access_mask
    
    metze

commit 8422e032339f624e6322a4a6a4938b1d84b347a0
Author: Stefan Metzmacher <metze at samba.org>
Date:   Fri Jul 10 19:04:58 2009 +0200

    s3:smbd: split out smbd_do_qfilepathinfo() from call_trans2qfilepathinfo()
    
    This prepares SMB2 GetInfo.
    
    metze

commit 20bc933c5b2f420f3588adf811a66aa886a1b41e
Author: Stefan Metzmacher <metze at samba.org>
Date:   Fri Jul 10 18:51:59 2009 +0200

    s3:smbd: add missing return after reply_nterror()
    
    metze

-----------------------------------------------------------------------

Summary of changes:
 source3/smbd/globals.h      |   16 +
 source3/smbd/smb2_getinfo.c |  140 ++++++-
 source3/smbd/trans2.c       | 1131 +++++++++++++++++++++++++------------------
 3 files changed, 815 insertions(+), 472 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source3/smbd/globals.h b/source3/smbd/globals.h
index 8163213..725a94a 100644
--- a/source3/smbd/globals.h
+++ b/source3/smbd/globals.h
@@ -185,6 +185,22 @@ NTSTATUS smbd_do_locking(struct smb_request *req,
 			 struct smbd_lock_element *locks,
 			 bool *async);
 
+NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn,
+			       TALLOC_CTX *mem_ctx,
+			       uint16_t info_level,
+			       files_struct *fsp,
+			       const struct smb_filename *smb_fname,
+			       bool delete_pending,
+			       struct timespec write_time_ts,
+			       bool ms_dfs_link,
+			       struct ea_list *ea_list,
+			       int lock_data_count,
+			       char *lock_data,
+			       uint16_t flags2,
+			       unsigned int max_data_bytes,
+			       char **ppdata,
+			       unsigned int *pdata_size);
+
 void smbd_server_connection_terminate_ex(struct smbd_server_connection *sconn,
 					 const char *reason,
 					 const char *location);
diff --git a/source3/smbd/smb2_getinfo.c b/source3/smbd/smb2_getinfo.c
index ba725fd..b6b7462 100644
--- a/source3/smbd/smb2_getinfo.c
+++ b/source3/smbd/smb2_getinfo.c
@@ -233,7 +233,145 @@ static struct tevent_req *smbd_smb2_getinfo_send(TALLOC_CTX *mem_ctx,
 		return tevent_req_post(req, ev);
 	}
 
-	tevent_req_nterror(req, NT_STATUS_NOT_IMPLEMENTED);
+	if (IS_IPC(conn)) {
+		tevent_req_nterror(req, NT_STATUS_NOT_SUPPORTED);
+		return tevent_req_post(req, ev);
+	}
+
+	switch (in_info_type) {
+	case 0x01:/* SMB2_GETINFO_FILE */
+	{
+		uint16_t file_info_level;
+		char *data = NULL;
+		unsigned int data_size = 0;
+		struct smb_filename *smb_fname = NULL;
+		bool delete_pending = false;
+		struct timespec write_time_ts;
+		struct file_id fileid;
+		struct ea_list *ea_list = NULL;
+		int lock_data_count = 0;
+		char *lock_data = NULL;
+		bool ms_dfs_link = false;
+		NTSTATUS status;
+
+		ZERO_STRUCT(write_time_ts);
+
+		switch (in_file_info_class) {
+		case 0x0F:/* RAW_FILEINFO_SMB2_ALL_EAS */
+			file_info_level = 0xFF00 | in_file_info_class;
+			break;
+
+		case 0x12:/* RAW_FILEINFO_SMB2_ALL_INFORMATION */
+			file_info_level = 0xFF00 | in_file_info_class;
+			break;
+
+		default:
+			/* the levels directly map to the passthru levels */
+			file_info_level = in_file_info_class + 1000;
+			break;
+		}
+
+		status = create_synthetic_smb_fname_split(state,
+							  fsp->fsp_name,
+							  NULL,
+							  &smb_fname);
+		if (!NT_STATUS_IS_OK(status)) {
+			tevent_req_nterror(req, status);
+			return tevent_req_post(req, ev);
+		}
+
+		if (fsp->fake_file_handle) {
+			/*
+			 * This is actually for the QUOTA_FAKE_FILE --metze
+			 */
+
+			/* We know this name is ok, it's already passed the checks. */
+
+		} else if (fsp && (fsp->is_directory || fsp->fh->fd == -1)) {
+			/*
+			 * This is actually a QFILEINFO on a directory
+			 * handle (returned from an NT SMB). NT5.0 seems
+			 * to do this call. JRA.
+			 */
+
+			if (INFO_LEVEL_IS_UNIX(file_info_level)) {
+				/* Always do lstat for UNIX calls. */
+				if (SMB_VFS_LSTAT(conn, smb_fname)) {
+					DEBUG(3,("call_trans2qfilepathinfo: "
+						 "SMB_VFS_LSTAT of %s failed "
+						 "(%s)\n",
+						 smb_fname_str_dbg(smb_fname),
+						 strerror(errno)));
+					status = map_nt_error_from_unix(errno);
+					tevent_req_nterror(req, status);
+					return tevent_req_post(req, ev);
+				}
+			} else if (SMB_VFS_STAT(conn, smb_fname)) {
+				DEBUG(3,("call_trans2qfilepathinfo: "
+					 "SMB_VFS_STAT of %s failed (%s)\n",
+					 smb_fname_str_dbg(smb_fname),
+					 strerror(errno)));
+				status = map_nt_error_from_unix(errno);
+				tevent_req_nterror(req, status);
+				return tevent_req_post(req, ev);
+			}
+
+			fileid = vfs_file_id_from_sbuf(conn, &smb_fname->st);
+			get_file_infos(fileid, &delete_pending, &write_time_ts);
+		} else {
+			/*
+			 * Original code - this is an open file.
+			 */
+
+			if (SMB_VFS_FSTAT(fsp, &smb_fname->st) != 0) {
+				DEBUG(3, ("fstat of fnum %d failed (%s)\n",
+					  fsp->fnum, strerror(errno)));
+				status = map_nt_error_from_unix(errno);
+				tevent_req_nterror(req, status);
+				return tevent_req_post(req, ev);
+			}
+			fileid = vfs_file_id_from_sbuf(conn, &smb_fname->st);
+			get_file_infos(fileid, &delete_pending, &write_time_ts);
+		}
+
+		status = smbd_do_qfilepathinfo(conn, state,
+					       file_info_level,
+					       fsp,
+					       smb_fname,
+					       delete_pending,
+					       write_time_ts,
+					       ms_dfs_link,
+					       ea_list,
+					       lock_data_count,
+					       lock_data,
+					       STR_UNICODE,
+					       in_output_buffer_length,
+					       &data,
+					       &data_size);
+		if (!NT_STATUS_IS_OK(status)) {
+			SAFE_FREE(data);
+			tevent_req_nterror(req, status);
+			return tevent_req_post(req, ev);
+		}
+		if (data_size > 0) {
+			state->out_output_buffer = data_blob_talloc(state,
+								    data,
+								    data_size);
+			SAFE_FREE(data);
+			if (tevent_req_nomem(state->out_output_buffer.data, req)) {
+				return tevent_req_post(req, ev);
+			}
+		}
+		SAFE_FREE(data);
+		break;
+	}
+
+	default:
+		tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
+		return tevent_req_post(req, ev);
+	}
+
+	tevent_req_done(req);
 	return tevent_req_post(req, ev);
 }
 
diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c
index 6a18f0f..6554fb6 100644
--- a/source3/smbd/trans2.c
+++ b/source3/smbd/trans2.c
@@ -367,6 +367,69 @@ static unsigned int fill_ea_buffer(TALLOC_CTX *mem_ctx, char *pdata, unsigned in
 	return ret_data_size;
 }
 
+static NTSTATUS fill_ea_chained_buffer(TALLOC_CTX *mem_ctx,
+				       char *pdata,
+				       unsigned int total_data_size,
+				       unsigned int *ret_data_size,
+				       connection_struct *conn,
+				       struct ea_list *ea_list)
+{
+	uint8_t *p = (uint8_t *)pdata;
+	uint8_t *last_start = NULL;
+
+	*ret_data_size = 0;
+
+	if (!lp_ea_support(SNUM(conn))) {
+		return NT_STATUS_NO_EAS_ON_FILE;
+	}
+
+	for (; ea_list; ea_list = ea_list->next) {
+		size_t dos_namelen;
+		fstring dos_ea_name;
+		size_t this_size;
+
+		if (last_start) {
+			SIVAL(last_start, 0, PTR_DIFF(p, last_start));
+		}
+		last_start = p;
+
+		push_ascii_fstring(dos_ea_name, ea_list->ea.name);
+		dos_namelen = strlen(dos_ea_name);
+		if (dos_namelen > 255 || dos_namelen == 0) {
+			return NT_STATUS_INTERNAL_ERROR;
+		}
+		if (ea_list->ea.value.length > 65535) {
+			return NT_STATUS_INTERNAL_ERROR;
+		}
+
+		this_size = 0x08 + dos_namelen + 1 + ea_list->ea.value.length;
+
+		if (ea_list->next) {
+			size_t pad = 4 - (this_size % 4);
+			this_size += pad;
+		}
+
+		if (this_size > total_data_size) {
+			return NT_STATUS_INFO_LENGTH_MISMATCH;
+		}
+
+		/* We know we have room. */
+		SIVAL(p, 0x00, 0); /* next offset */
+		SCVAL(p, 0x04, ea_list->ea.flags);
+		SCVAL(p, 0x05, dos_namelen);
+		SSVAL(p, 0x06, ea_list->ea.value.length);
+		fstrcpy((char *)(p+0x08), dos_ea_name);
+		memcpy(p + 0x08 + dos_namelen + 1, ea_list->ea.value.data, ea_list->ea.value.length);
+
+		total_data_size -= this_size;
+		p += this_size;
+	}
+
+	*ret_data_size = PTR_DIFF(p, pdata);
+	DEBUG(10,("fill_ea_chained_buffer: data_size = %u\n", *ret_data_size));
+	return NT_STATUS_OK;
+}
+
 static unsigned int estimate_ea_size(connection_struct *conn, files_struct *fsp, const char *fname)
 {
 	size_t total_ea_len = 0;
@@ -3878,296 +3941,54 @@ static void call_trans2qpipeinfo(connection_struct *conn,
 	return;
 }
 
-/****************************************************************************
- Reply to a TRANS2_QFILEPATHINFO or TRANSACT2_QFILEINFO (query file info by
- file name or file id).
-****************************************************************************/
-
-static void call_trans2qfilepathinfo(connection_struct *conn,
-				     struct smb_request *req,
-				     unsigned int tran_call,
-				     char **pparams, int total_params,
-				     char **ppdata, int total_data,
-				     unsigned int max_data_bytes)
+NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn,
+			       TALLOC_CTX *mem_ctx,
+			       uint16_t info_level,
+			       files_struct *fsp,
+			       const struct smb_filename *smb_fname,
+			       bool delete_pending,
+			       struct timespec write_time_ts,
+			       bool ms_dfs_link,
+			       struct ea_list *ea_list,
+			       int lock_data_count,
+			       char *lock_data,
+			       uint16_t flags2,
+			       unsigned int max_data_bytes,
+			       char **ppdata,
+			       unsigned int *pdata_size)
 {
-	char *params = *pparams;
 	char *pdata = *ppdata;
 	char *dstart, *dend;
-	uint16 info_level;
-	int mode=0;
-	int nlink;
-	SMB_OFF_T file_size=0;
-	uint64_t allocation_size=0;
-	unsigned int data_size = 0;
-	unsigned int param_size = 2;
+	unsigned int data_size;
+	struct timespec create_time_ts, mtime_ts, atime_ts;
+	time_t create_time, mtime, atime;
 	SMB_STRUCT_STAT sbuf;
-	char *dos_fname = NULL;
-	char *fname = NULL;
-	struct smb_filename *smb_fname = NULL;
-	char *fullpathname;
-	char *base_name;
 	char *p;
-	SMB_OFF_T pos = 0;
-	bool delete_pending = False;
-	int len;
-	time_t create_time, mtime, atime;
-	struct timespec create_time_ts, mtime_ts, atime_ts;
-	struct timespec write_time_ts;
-	files_struct *fsp = NULL;
-	struct file_id fileid;
-	struct ea_list *ea_list = NULL;
-	char *lock_data = NULL;
-	bool ms_dfs_link = false;
-	TALLOC_CTX *ctx = talloc_tos();
-	NTSTATUS status = NT_STATUS_OK;
-
-	if (!params) {
-		reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
-		return;
-	}
-
-	ZERO_STRUCT(write_time_ts);
-
-	if (tran_call == TRANSACT2_QFILEINFO) {
-		if (total_params < 4) {
-			reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
-			return;
-		}
-
-		if (IS_IPC(conn)) {
-			call_trans2qpipeinfo(conn, req,	tran_call,
-					     pparams, total_params,
-					     ppdata, total_data,
-					     max_data_bytes);
-			return;
-		}
-
-		fsp = file_fsp(req, SVAL(params,0));
-		info_level = SVAL(params,2);
-
-		DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QFILEINFO: level = %d\n", info_level));
-
-		if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions()) {
-			reply_nterror(req, NT_STATUS_INVALID_LEVEL);
-			return;
-		}
-
-		/* Initial check for valid fsp ptr. */
-		if (!check_fsp_open(conn, req, fsp)) {
-			return;
-		}
-
-		fname = talloc_strdup(talloc_tos(),fsp->fsp_name);
-		if (!fname) {
-			reply_nterror(req, NT_STATUS_NO_MEMORY);
-			return;
-		}
-
-		status = create_synthetic_smb_fname_split(talloc_tos(), fname,
-							  NULL, &smb_fname);
-		if (!NT_STATUS_IS_OK(status)) {
-			reply_nterror(req, status);
-			return;
-		}
-
-		if(fsp->fake_file_handle) {
-			/*
-			 * This is actually for the QUOTA_FAKE_FILE --metze
-			 */
-
-			/* We know this name is ok, it's already passed the checks. */
-
-		} else if(fsp && (fsp->is_directory || fsp->fh->fd == -1)) {
-			/*
-			 * This is actually a QFILEINFO on a directory
-			 * handle (returned from an NT SMB). NT5.0 seems
-			 * to do this call. JRA.
-			 */
-
-			if (INFO_LEVEL_IS_UNIX(info_level)) {
-				/* Always do lstat for UNIX calls. */
-				if (SMB_VFS_LSTAT(conn, smb_fname)) {
-					DEBUG(3,("call_trans2qfilepathinfo: "
-						 "SMB_VFS_LSTAT of %s failed "
-						 "(%s)\n",
-						 smb_fname_str_dbg(smb_fname),
-						 strerror(errno)));
-					reply_nterror(req,map_nt_error_from_unix(errno));
-					return;
-				}
-			} else if (SMB_VFS_STAT(conn, smb_fname)) {
-				DEBUG(3,("call_trans2qfilepathinfo: "
-					 "SMB_VFS_STAT of %s failed (%s)\n",
-					 smb_fname_str_dbg(smb_fname),
-					 strerror(errno)));
-				reply_nterror(req, map_nt_error_from_unix(errno));
-				return;
-			}
-
-			fileid = vfs_file_id_from_sbuf(conn, &smb_fname->st);
-			get_file_infos(fileid, &delete_pending, &write_time_ts);
-		} else {
-			/*
-			 * Original code - this is an open file.
-			 */
-			if (!check_fsp(conn, req, fsp)) {
-				return;
-			}
-
-			if (SMB_VFS_FSTAT(fsp, &smb_fname->st) != 0) {
-				DEBUG(3, ("fstat of fnum %d failed (%s)\n",
-					  fsp->fnum, strerror(errno)));
-				reply_nterror(req, map_nt_error_from_unix(errno));
-				return;
-			}
-			pos = fsp->fh->position_information;
-			fileid = vfs_file_id_from_sbuf(conn, &smb_fname->st);
-			get_file_infos(fileid, &delete_pending, &write_time_ts);
-		}
-
-	} else {
-		/* qpathinfo */
-		if (total_params < 7) {
-			reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
-			return;
-		}
-
-		info_level = SVAL(params,0);
-
-		DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QPATHINFO: level = %d\n", info_level));
-
-		if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions()) {
-			reply_nterror(req, NT_STATUS_INVALID_LEVEL);
-			return;
-		}
-
-		srvstr_get_path(ctx, params, req->flags2, &fname, &params[6],
-				total_params - 6,
-				STR_TERMINATE, &status);
-		if (!NT_STATUS_IS_OK(status)) {
-			reply_nterror(req, status);
-			return;
-		}
-
-		status = filename_convert(ctx,
-					conn,
-					req->flags2 & FLAGS2_DFS_PATHNAMES,
-					fname,
-					&smb_fname,
-					&fname);
-		if (!NT_STATUS_IS_OK(status)) {
-			if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
-				reply_botherror(req,
-						NT_STATUS_PATH_NOT_COVERED,
-						ERRSRV, ERRbadpath);
-				return;
-			}
-			reply_nterror(req, status);
-			return;
-		}
-
-		/* If this is a stream, check if there is a delete_pending. */
-		if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
-		    && is_ntfs_stream_smb_fname(smb_fname)) {
-			struct smb_filename *smb_fname_base = NULL;
-
-			/* Create an smb_filename with stream_name == NULL. */
-			status =
-			    create_synthetic_smb_fname(talloc_tos(),
-						       smb_fname->base_name,
-						       NULL, NULL,
-						       &smb_fname_base);
-			if (!NT_STATUS_IS_OK(status)) {
-				reply_nterror(req, status);
-				return;
-			}
-
-			if (INFO_LEVEL_IS_UNIX(info_level)) {
-				/* Always do lstat for UNIX calls. */
-				if (SMB_VFS_LSTAT(conn, smb_fname_base) != 0) {
-					DEBUG(3,("call_trans2qfilepathinfo: "
-						 "SMB_VFS_LSTAT of %s failed "
-						 "(%s)\n",
-						 smb_fname_str_dbg(smb_fname_base),
-						 strerror(errno)));
-					reply_nterror(req,map_nt_error_from_unix(errno));
-					TALLOC_FREE(smb_fname_base);
-					return;
-				}
-			} else {
-				if (SMB_VFS_STAT(conn, smb_fname_base) != 0) {
-					DEBUG(3,("call_trans2qfilepathinfo: "
-						 "fileinfo of %s failed "
-						 "(%s)\n",
-						 smb_fname_str_dbg(smb_fname_base),
-						 strerror(errno)));
-					reply_nterror(req,map_nt_error_from_unix(errno));
-					TALLOC_FREE(smb_fname_base);
-					return;


-- 
Samba Shared Repository


More information about the samba-cvs mailing list