Get Samba version or capability information from Windows

Corinna Vinschen corinna at vinschen.de
Sat Jan 19 14:04:20 GMT 2008


Hi,

On Jan 18 14:11, George Colley wrote:
>  I have been asking for something like this for a long time, without much 
> luck. In my case I just want a number that is incremented for each release. 
> A version number would be fine. Strings are a pain in the ass for me, but 
> even that would be ok. I would like the number to represent official Samba 
> releases, not vendor releases. I know what Samba is doing in each release 
> and what they fix. If vendors are changing this number then it really is 
> not worth much to me.

I guess we can have both of that in a rather easy to test way.

I've created a preliminary patch.  It builds (in the v3-2-test branch),
but it's not yet tested.  After some consideration, I created the
following structure for the version info:

  struct smb_extra_info {
	  uint32 samba_magic;
	  uint32 samba_version;
	  uint32 samba_subversion;
	  char   samba_version_string[36];
  };

samba_version contains the official version from major version number
down to the revision, basically like this:

  samba_version = SAMBA_VERSION_MAJOR    << 24
                | SAMBA_VERSION_MINOR    << 16
                | SAMBA_VERSION_RELEASE  <<  8
                | SAMBA_VERSION_REVISION

If that's not enough, samba_subversion contains information about the
build being from a RC or prerelease, with RCs being order as "later"
than a prerelease.  The subversion can be only a RC *or* a prelease, not
both.  Additionally the low word contains the vendor patch number, if it
exists.  So, basically, the subversion is created as

  samba_subversion = SAMBA_VERSION_RC_RELEASE  << 24
                   | SAMBA_VERSION_PRE_RELEASE << 16
                   | SAMBA_VERSION_VENDOR_PATCH

Last but not least, samba_version_string is the same as returned by
samba_version_string(), potentially truncated to 35 characters plus the
trailing \0.

I've put the structure defintion into include/smb.h, together with the
declaration of the new samba_extra_info_version() function.  The
function itself is implemented in lib/version.c.  If you don't like any
of this, please tell me.  I gladly move the stuff elsewhere, provided
you tell me where to :)

Ok, below you find the patch itself.  As I wrote above, it's against the
v3-2-test branch.  I hope that's ok.  If necessary I'll create the patch
against other branches as well, of course.


Thanks,
Corinna


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


diff --git a/source/include/smb.h b/source/include/smb.h
index 15e51db..7b9ed49 100644
--- a/source/include/smb.h
+++ b/source/include/smb.h
@@ -1929,4 +1929,15 @@ 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_EXTRA_INFO_MAGIC 0x536d4261 /* "SmBa" */
+#define SAMBA_EXTRA_INFO_VERSION_STRING_LENGTH 36
+struct smb_extra_info {
+	uint32 samba_magic;		/* Always SAMBA_EXTRA_INFO_MAGIC */
+	uint32 samba_version;		/* Major/Minor/Release/Revision */
+	uint32 samba_subversion;		/* Prerelease/RC/Vendor patch */
+	char   samba_version_string[SAMBA_EXTRA_INFO_VERSION_STRING_LENGTH];
+};
+extern struct smb_extra_info *samba_extra_info_version(void);
+
 #endif /* _SMB_H */
diff --git a/source/lib/version.c b/source/lib/version.c
index 204c204..e8c2ee3 100644
--- a/source/lib/version.c
+++ b/source/lib/version.c
@@ -57,3 +57,35 @@ const char *samba_version_string(void)
 	return samba_version;
 #endif
 }
+
+struct smb_extra_info *samba_extra_info_version()
+{
+	static struct smb_extra_info extra_info;
+
+	if (extra_info.samba_magic == SAMBA_EXTRA_INFO_MAGIC)
+	  return &extra_info;
+
+	extra_info.samba_version = ((SAMBA_VERSION_MAJOR & 0xff) << 24)
+				   | ((SAMBA_VERSION_MINOR & 0xff) << 16)
+				   | ((SAMBA_VERSION_RELEASE & 0xff) << 8);
+#ifdef SAMBA_VERSION_REVISION
+	extra_info.samba_version |= (tolower(*SAMBA_VERSION_REVISION) - 'a' + 1)
+				    & 0xff;
+#endif
+#ifdef SAMBA_VERSION_RC_RELEASE
+	extra_info.samba_subversion |= (SAMBA_VERSION_RC_RELEASE & 0xff) << 24;
+#else
+#ifdef SAMBA_VERSION_PRE_RELEASE
+	extra_info.samba_subversion |= (SAMBA_VERSION_PRE_RELEASE & 0xff) << 16;
+#endif
+#endif
+#ifdef SAMBA_VERSION_VENDOR_PATCH
+	extra_info.samba_subversion |= (SAMBA_VERSION_VENDOR_PATCH & 0xffff);
+#endif
+	snprintf (extra_info.samba_version_string,
+		  SAMBA_EXTRA_INFO_VERSION_STRING_LENGTH,
+		  "%s", samba_version_string());
+	/* Initialize magic last, just to be sure. */
+	extra_info.samba_magic = SAMBA_EXTRA_INFO_MAGIC;
+	return  &extra_info;
+}
diff --git a/source/smbd/trans2.c b/source/smbd/trans2.c
index 935a881..6214c23 100644
--- a/source/smbd/trans2.c
+++ b/source/smbd/trans2.c
@@ -2694,6 +2694,7 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAva
 		{
 			unsigned char objid[16];
 			memcpy(pdata,create_volume_objectid(conn, objid),16);
+			memcpy(pdata+16,samba_extra_info_version(),48);
 			data_len = 64;
 			break;
 		}


More information about the samba-technical mailing list