uses for transmit_as in NT interoperability services

Luke Kenneth Casson Leighton lkcl at lkcl.net
Wed Jan 19 16:52:02 CST 2005


it's odd, innit?  you start to explore and go "uh, duh, _that's_ what
that's for".

there are a number of places in the NT services that i
network-reverse-engineered six years ago where i was thinking,
"hm, that's not NDR-formatted..." and had to continue anyway
bumbling along.

the areas i encountered which were most definitely _not_
NDR-formatted, despite appearances, were:

1) Security Descriptors

2) Spoolss (spoolss.idl) Data Structures
   (usually in case statements with horribly large unions)

3) Service Control Manager (svcctl.idl)

security descriptors that i encountered contained relative offsets
of members in the structure where it _mattered_ what the offset value
was, and the same thing i encountered in spoolss data.

unlike NDR, pointers are tokens: if it's non-zero, it's a
pointer, and the data can be "expected" at a known point
because the order in which structures are added is well-defined.

[no i know i haven't mentioned the difference between ptr
and unique]


what i believe may be being used is "transmit_as" - see an example code
from entegrity.com at:

	http://support.entegrity.com/private/doclib/docs/osfhtm/develop/apgstyle/Apgst193.htm

so, to follow the guidance and examples at the above link,
to send a Security Descriptor you would create this:

	typedef struct
	{
		int size;
		[ptr, size_is(size)] *security_descriptor_blob;
	} SECURITY_DESCRIPTOR_BLOB;

then you would do this

	typedef [transmit_as(SECURITY_DESCRIPTOR_BLOB)] PSECURITY_DESCRIPTOR;

and then, magically, you can do THIS:

	NTSTATUS SamrGetSecurityDescriptor(handle_t *hnd, [in, ref]
				PSECURITY_DESCRIPTOR);

and in the server-side thing you'd define:

	void PSECURITY_DESCRIPTOR_to_xmit(PSECURITY_DESCRIPTOR *sec_des,
					  SECURITY_DESCRIPTOR_BLOB *blob)
	{
		blob->size = get_security_descriptor_actual_size(sec_des);
		blob->data = malloc(blob_size);
		memcpy(blob->data, get_security_descriptor_blob(sec_des),
				   blob->size);
	}

not forgetting to do this!

	void PSECURITY_DESCRIPTOR_free_xmit( SECURITY_DESCRIPTOR_BLOB *blob)
	{
		free(blob->data);
	}


and i think that's just _so_ cool.

only took six years to realise it's possible.

... and i'd be fascinated to know if it's _right_ :)

l.


-- 
--
<a href="http://lkcl.net">http://lkcl.net</a>
--



More information about the wine-devel mailing list