Author: jra Date: 2007-04-23 16:32:24 +0000 (Mon, 23 Apr 2007) New Revision: 22490
WebSVN: http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=22490 Log: Fix a couple of bugs found whist investigating CSC Vista issues. Ensure we correctly NULL out allocation size fields. Allow QFILEINFO on pipes (Vista bug ?). Jerry - don't automatically merge for 3.0.25. Jeremy. Modified: branches/SAMBA_3_0/source/smbd/trans2.c branches/SAMBA_3_0_25/source/smbd/trans2.c Changeset: Modified: branches/SAMBA_3_0/source/smbd/trans2.c =================================================================== --- branches/SAMBA_3_0/source/smbd/trans2.c 2007-04-23 16:31:31 UTC (rev 22489) +++ branches/SAMBA_3_0/source/smbd/trans2.c 2007-04-23 16:32:24 UTC (rev 22490) @@ -2235,6 +2235,12 @@ return(-1); } +unsigned char *create_volume_objectid(connection_struct *conn, unsigned char objid[16]) +{ + E_md4hash(lp_servicename(SNUM(conn)),objid); + return objid; +} + /**************************************************************************** Reply to a TRANS2_QFSINFO (query filesystem info). ****************************************************************************/ @@ -2342,6 +2348,8 @@ SIVAL(pdata,0,FILE_CASE_PRESERVED_NAMES|FILE_CASE_SENSITIVE_SEARCH| (lp_nt_acl_support(SNUM(conn)) ? FILE_PERSISTENT_ACLS : 0)| + FILE_SUPPORTS_OBJECT_IDS| + FILE_UNICODE_ON_DISK| quota_flag); /* FS ATTRIBUTES */ SIVAL(pdata,4,255); /* Max filename component length */ @@ -2523,8 +2531,12 @@ } #endif /* HAVE_SYS_QUOTAS */ case SMB_FS_OBJECTID_INFORMATION: + { + unsigned char objid[16]; + memcpy(pdata,create_volume_objectid(conn, objid),16); data_len = 64; break; + } /* * Query the version and capabilities of the CIFS UNIX extensions @@ -3194,6 +3206,68 @@ } /**************************************************************************** + Reply to a TRANSACT2_QFILEINFO on a PIPE ! +****************************************************************************/ + +static int call_trans2qpipeinfo(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize, + unsigned int tran_call, + char **pparams, int total_params, char **ppdata, int total_data, + unsigned int max_data_bytes) +{ + char *params = *pparams; + char *pdata = *ppdata; + unsigned int data_size = 0; + unsigned int param_size = 2; + uint16 info_level; + smb_np_struct *p_pipe = NULL; + + if (!params) { + return ERROR_NT(NT_STATUS_INVALID_PARAMETER); + } + + if (total_params < 4) { + return ERROR_NT(NT_STATUS_INVALID_PARAMETER); + } + + p_pipe = get_rpc_pipe_p(params,0); + if (p_pipe == NULL) { + return ERROR_NT(NT_STATUS_INVALID_HANDLE); + } + + info_level = SVAL(params,2); + + *pparams = (char *)SMB_REALLOC(*pparams,2); + if (*pparams == NULL) { + return ERROR_NT(NT_STATUS_NO_MEMORY); + } + params = *pparams; + SSVAL(params,0,0); + data_size = max_data_bytes + DIR_ENTRY_SAFETY_MARGIN; + *ppdata = (char *)SMB_REALLOC(*ppdata, data_size); + if (*ppdata == NULL ) { + return ERROR_NT(NT_STATUS_NO_MEMORY); + } + pdata = *ppdata; + + switch (info_level) { + case SMB_FILE_STANDARD_INFORMATION: + memset(pdata,24,0); + SOFF_T(pdata,0,4096LL); + SIVAL(pdata,16,1); + SIVAL(pdata,20,1); + data_size = 24; + break; + + default: + return ERROR_NT(NT_STATUS_INVALID_LEVEL); + } + + send_trans2_replies(outbuf, bufsize, params, param_size, *ppdata, data_size, max_data_bytes); + + return(-1); +} + +/**************************************************************************** Reply to a TRANS2_QFILEPATHINFO or TRANSACT2_QFILEINFO (query file info by file name or file id). ****************************************************************************/ @@ -3238,6 +3312,20 @@ return ERROR_NT(NT_STATUS_INVALID_PARAMETER); } + if (IS_IPC(conn)) { + return call_trans2qpipeinfo(conn, + inbuf, + outbuf, + length, + bufsize, + tran_call, + pparams, + total_params, + ppdata, + total_data, + max_data_bytes); + } + fsp = file_fsp(params,0); info_level = SVAL(params,2); @@ -3769,8 +3857,7 @@ SIVAL(pdata,0,0); /* ??? */ SIVAL(pdata,4,byte_len); /* Byte length of unicode string ::$DATA */ SOFF_T(pdata,8,file_size); - SIVAL(pdata,16,allocation_size); - SIVAL(pdata,20,0); /* ??? */ + SOFF_T(pdata,16,allocation_size); data_size = 24 + byte_len; } break; @@ -3790,7 +3877,7 @@ put_long_date_timespec(pdata+8,atime_ts); put_long_date_timespec(pdata+16,mtime_ts); /* write time */ put_long_date_timespec(pdata+24,mtime_ts); /* change time */ - SIVAL(pdata,32,allocation_size); + SOFF_T(pdata,32,allocation_size); SOFF_T(pdata,40,file_size); SIVAL(pdata,48,mode); SIVAL(pdata,52,0); /* ??? */ @@ -6525,7 +6612,8 @@ } if (IS_IPC(conn) && (tran_call != TRANSACT2_OPEN) - && (tran_call != TRANSACT2_GET_DFS_REFERRAL)) { + && (tran_call != TRANSACT2_GET_DFS_REFERRAL) + && (tran_call != TRANSACT2_QFILEINFO)) { END_PROFILE(SMBtrans2); return ERROR_DOS(ERRSRV,ERRaccess); } Modified: branches/SAMBA_3_0_25/source/smbd/trans2.c =================================================================== --- branches/SAMBA_3_0_25/source/smbd/trans2.c 2007-04-23 16:31:31 UTC (rev 22489) +++ branches/SAMBA_3_0_25/source/smbd/trans2.c 2007-04-23 16:32:24 UTC (rev 22490) @@ -2219,6 +2219,12 @@ return(-1); } +unsigned char *create_volume_objectid(connection_struct *conn, unsigned char objid[16]) +{ + E_md4hash(lp_servicename(SNUM(conn)),objid); + return objid; +} + /**************************************************************************** Reply to a TRANS2_QFSINFO (query filesystem info). ****************************************************************************/ @@ -2326,6 +2332,8 @@ SIVAL(pdata,0,FILE_CASE_PRESERVED_NAMES|FILE_CASE_SENSITIVE_SEARCH| (lp_nt_acl_support(SNUM(conn)) ? FILE_PERSISTENT_ACLS : 0)| + FILE_SUPPORTS_OBJECT_IDS| + FILE_UNICODE_ON_DISK| quota_flag); /* FS ATTRIBUTES */ SIVAL(pdata,4,255); /* Max filename component length */ @@ -2507,8 +2515,12 @@ } #endif /* HAVE_SYS_QUOTAS */ case SMB_FS_OBJECTID_INFORMATION: + { + unsigned char objid[16]; + memcpy(pdata,create_volume_objectid(conn, objid),16); data_len = 64; break; + } /* * Query the version and capabilities of the CIFS UNIX extensions @@ -3142,6 +3154,68 @@ } /**************************************************************************** + Reply to a TRANSACT2_QFILEINFO on a PIPE ! +****************************************************************************/ + +static int call_trans2qpipeinfo(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize, + unsigned int tran_call, + char **pparams, int total_params, char **ppdata, int total_data, + unsigned int max_data_bytes) +{ + char *params = *pparams; + char *pdata = *ppdata; + unsigned int data_size = 0; + unsigned int param_size = 2; + uint16 info_level; + smb_np_struct *p_pipe = NULL; + + if (!params) { + return ERROR_NT(NT_STATUS_INVALID_PARAMETER); + } + + if (total_params < 4) { + return ERROR_NT(NT_STATUS_INVALID_PARAMETER); + } + + p_pipe = get_rpc_pipe_p(params,0); + if (p_pipe == NULL) { + return ERROR_NT(NT_STATUS_INVALID_HANDLE); + } + + info_level = SVAL(params,2); + + *pparams = (char *)SMB_REALLOC(*pparams,2); + if (*pparams == NULL) { + return ERROR_NT(NT_STATUS_NO_MEMORY); + } + params = *pparams; + SSVAL(params,0,0); + data_size = max_data_bytes + DIR_ENTRY_SAFETY_MARGIN; + *ppdata = (char *)SMB_REALLOC(*ppdata, data_size); + if (*ppdata == NULL ) { + return ERROR_NT(NT_STATUS_NO_MEMORY); + } + pdata = *ppdata; + + switch (info_level) { + case SMB_FILE_STANDARD_INFORMATION: + memset(pdata,24,0); + SOFF_T(pdata,0,4096LL); + SIVAL(pdata,16,1); + SIVAL(pdata,20,1); + data_size = 24; + break; + + default: + return ERROR_NT(NT_STATUS_INVALID_LEVEL); + } + + send_trans2_replies(outbuf, bufsize, params, param_size, *ppdata, data_size, max_data_bytes); + + return(-1); +} + +/**************************************************************************** Reply to a TRANS2_QFILEPATHINFO or TRANSACT2_QFILEINFO (query file info by file name or file id). ****************************************************************************/ @@ -3186,6 +3260,20 @@ return ERROR_NT(NT_STATUS_INVALID_PARAMETER); } + if (IS_IPC(conn)) { + return call_trans2qpipeinfo(conn, + inbuf, + outbuf, + length, + bufsize, + tran_call, + pparams, + total_params, + ppdata, + total_data, + max_data_bytes); + } + fsp = file_fsp(params,0); info_level = SVAL(params,2); @@ -3717,8 +3805,7 @@ SIVAL(pdata,0,0); /* ??? */ SIVAL(pdata,4,byte_len); /* Byte length of unicode string ::$DATA */ SOFF_T(pdata,8,file_size); - SIVAL(pdata,16,allocation_size); - SIVAL(pdata,20,0); /* ??? */ + SOFF_T(pdata,16,allocation_size); data_size = 24 + byte_len; } break; @@ -3738,7 +3825,7 @@ put_long_date_timespec(pdata+8,atime_ts); put_long_date_timespec(pdata+16,mtime_ts); /* write time */ put_long_date_timespec(pdata+24,mtime_ts); /* change time */ - SIVAL(pdata,32,allocation_size); + SOFF_T(pdata,32,allocation_size); SOFF_T(pdata,40,file_size); SIVAL(pdata,48,mode); SIVAL(pdata,52,0); /* ??? */ @@ -6473,7 +6560,8 @@ } if (IS_IPC(conn) && (tran_call != TRANSACT2_OPEN) - && (tran_call != TRANSACT2_GET_DFS_REFERRAL)) { + && (tran_call != TRANSACT2_GET_DFS_REFERRAL) + && (tran_call != TRANSACT2_QFILEINFO)) { END_PROFILE(SMBtrans2); return ERROR_DOS(ERRSRV,ERRaccess); }