Get Samba version or capability information from Windows

Corinna Vinschen corinna at vinschen.de
Mon Jan 21 18:20:25 GMT 2008


On Jan 21 17:10, Corinna Vinschen wrote:
> On Jan 21 16:45, Volker Lendecke wrote:
> > On Mon, Jan 21, 2008 at 04:34:51PM +0100, Corinna Vinschen wrote:
> > 
> > > So, what exactly shall I ignore, just your last comment or your request
> > > to put extra_info on the stack?
> > 
> > Tough call. I seriously don't have a full answer to this.
> > The "right" thing is not to add global variables. If you
> > need to cache it depends on the cost it has to compute that
> > info. If it is potentially expensive, we nowadays have the
> > memcache (see include/memcache.h) as a place where you can
> > store this kind of info. If it's relatively cheap or called
> > infrequently, then compute it on demand.
> 
> Ok.  It looks a rather unexpensive operation, given that it's all
> numbers and only one string which is precomputed anyway so I go
> for the stack.

New patch attached.  Changes:

- I changed the name.  The offical MSDN documentation calls the second
  parameter "ExtendedInfo", not "ExtraInfo", so I replaced all "extra"
  with "extended". 

- I added a `time_t samba_gitcommitdate' to the structure for the sake
  of a GIT commit date as soon as somebody added it to version.h.  Right
  now it just contains the current server time.

- The structure is now created on the stack and given as parameter to
  the samba_extended_info_version() function.  

- The struct members are marshalled into pdata now.

Additionally I created a test case on a Windows XP client, which calls
ZwQueryVolumeInformationFile(FileFsObjectIdInformation).  The
information gets transmitted as expected and the test for Samba succeeds.

Patch is against v3-2-test.  If it's ok to be applied, do I have to
create matching patches against v3-0-test and v4-0-test as well?


Thanks,
Corinna

	* include/smb.h (struct smb_extended_info): Define.
	(samba_extended_info_version): Declare.
	* lib/version.c (samba_extended_info_version): New function.
	* smbd/trans2.c (call_trans2qfsinfo): Transmit extended version info
	in SMB_FS_OBJECTID_INFORMATION request.


diff --git a/source/include/smb.h b/source/include/smb.h
index 15e51db..9e3fec7 100644
--- a/source/include/smb.h
+++ b/source/include/smb.h
@@ -1929,4 +1929,16 @@ enum usershare_err {
 /* Different reasons for closing a file. */
 enum file_close_type {NORMAL_CLOSE=0,SHUTDOWN_CLOSE,ERROR_CLOSE};
 
+/* Used in SMB_FS_OBJECTID_INFORMATION requests.  Must be exactly 48 bytes. */
+#define SAMBA_EXTENDED_INFO_MAGIC 0x536d4261 /* "SmBa" */
+#define SAMBA_EXTENDED_INFO_VERSION_STRING_LENGTH 32
+struct smb_extended_info {
+	uint32 samba_magic;		/* Always SAMBA_EXTRA_INFO_MAGIC */
+	uint32 samba_version;		/* Major/Minor/Release/Revision */
+	uint32 samba_subversion;	/* Prerelease/RC/Vendor patch */
+	time_t samba_gitcommitdate;
+	char   samba_version_string[SAMBA_EXTENDED_INFO_VERSION_STRING_LENGTH];
+};
+extern void samba_extended_info_version(struct smb_extended_info *);
+
 #endif /* _SMB_H */
diff --git a/source/lib/version.c b/source/lib/version.c
index 204c204..c6de702 100644
--- a/source/lib/version.c
+++ b/source/lib/version.c
@@ -57,3 +57,32 @@ const char *samba_version_string(void)
 	return samba_version;
 #endif
 }
+
+void samba_extended_info_version(struct smb_extended_info *extended_info)
+{
+	assert(extended_info != NULL);
+
+	extended_info->samba_magic = SAMBA_EXTENDED_INFO_MAGIC;
+	extended_info->samba_version = ((SAMBA_VERSION_MAJOR & 0xff) << 24)
+				       | ((SAMBA_VERSION_MINOR & 0xff) << 16)
+				       | ((SAMBA_VERSION_RELEASE & 0xff) << 8);
+#ifdef SAMBA_VERSION_REVISION
+	extended_info->samba_version |= (tolower(*SAMBA_VERSION_REVISION) - 'a' + 1) & 0xff;
+#endif
+#ifdef SAMBA_VERSION_RC_RELEASE
+	extended_info->samba_subversion |= (SAMBA_VERSION_RC_RELEASE & 0xff) << 24;
+#else
+#ifdef SAMBA_VERSION_PRE_RELEASE
+	extended_info->samba_subversion |= (SAMBA_VERSION_PRE_RELEASE & 0xff) << 16;
+#endif
+#endif
+#ifdef SAMBA_VERSION_VENDOR_PATCH
+	extended_info->samba_subversion |= (SAMBA_VERSION_VENDOR_PATCH & 0xffff);
+#endif
+	/* FIXME: samba_gitcommitdate should contain the git commit date. */
+	extended_info->samba_gitcommitdate = time(NULL);
+
+	snprintf (extended_info->samba_version_string,
+		  SAMBA_EXTENDED_INFO_VERSION_STRING_LENGTH,
+		  "%s", samba_version_string());
+}
diff --git a/source/smbd/trans2.c b/source/smbd/trans2.c
index 935a881..7c1b397 100644
--- a/source/smbd/trans2.c
+++ b/source/smbd/trans2.c
@@ -2693,7 +2693,14 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAva
 		case SMB_FS_OBJECTID_INFORMATION:
 		{
 			unsigned char objid[16];
+			struct smb_extended_info extended_info;
 			memcpy(pdata,create_volume_objectid(conn, objid),16);
+			samba_extended_info_version (&extended_info);
+			SIVAL(pdata,16,extended_info.samba_magic);
+			SIVAL(pdata,20,extended_info.samba_version);
+			SIVAL(pdata,24,extended_info.samba_subversion);
+			SIVAL(pdata,28,extended_info.samba_gitcommitdate);
+			memcpy(pdata+32,extended_info.samba_version_string,32);
 			data_len = 64;
 			break;
 		}


More information about the samba-technical mailing list