RpcImpersonateClient (and ImpersonateNamedPipeClient)

Luke Kenneth Casson Leighton lkcl at lkcl.net
Thu Jan 20 06:42:36 CST 2005

like the ImpersonateNamedPipeClient function, it's funny - i've
_just_ being dealing with this stuff in Samba TNG:

	lkcl        2005/01/20 13:05:50 CET

	Modified files:
	   source/lib             msrpc-client.c 
	   source/rpc_parse       parse_creds.c 
	new format for smbd <-> rpc-services intercommunication
	of "inherited" context.

	what was previously used was a uint32 to indicate blob
	length followed by a CREDS_CMD struct containing a
	user_struct, which also had in it a NET_USER_INFO_3.

	_now_ what is sent is a PDU with a "new" PDU number
	which had to be invented, followed by a modified
	CREDS_CMD struct containing an OPTIONAL user_struct

	discussions with elrond have been over what else should
	be transmitted (e.g. NT_USER_TOKEN) or transmitted
	_instead_ of NET_USER_INFO_3.

	also, and this is for informational purposes, there
	have been discussions on the Wine mailing lists about
	doing RpcImpersonateClient properly, for ReactOS and
	DCOM, and what's going on here is directly relevant:
	it's the data that must be passed to ReactOS, it's a
	long story...

	Revision  Changes    Path
	1.27      +44 -14    tng/source/lib/msrpc-client.c
	1.14      +37 -13    tng/source/rpc_parse/parse_creds.c

the data flow goes something like this:

* user logs in at workstation, types password, blah blah.

* LsaLogonEx is called, which ultimately works its way down to
  over-wire formats via ncacn_np:NETLOGON to contacting a PDC,
  or makes its way over kerberos PAC field.

  in the case of a PDC, you get a NET_USER_INFO_3 struct back.

  [btw, the username in the NET_USER_INFO_3 DOES NOT have to be
   the same as the username used in the first step - login!!!]

* a "security blob" is created, let's call it an NT_SEC_BLOB.
  the NT_SEC_BLOB caches the NET_USER_INFO_3 info, creates
  an NT_USER_TOKEN and caches that.

  this is what we know to be the "credentials" for the impersonation

* the user does something - oh, i dunno, runs USRMGR.EXE or something.

* USRMGR connects to ncacn_np:samr, which results in an SMB connection.
  samba tng will receive that, and go through the whole silly
  NETLOGON process again (no choice, sorry: it's one of the
  reasons why MS chose to use KRB5), to store *INTERNALLY*
  a NET_USER_INFO_3 set of credentials.

  this is part of the "SMB authentication" - see here:


  note the use in reply_sesssetup_and_X of "password_ok()" which is
  expected to receive a NET_USER_INFO_3.

* if this succeeds, then USRMGR.EXE fires off a connection to SMB IPC$
  over which a "NamedPipe" connection is established.

 the above cvs patch allows the NET_USER_INFO_3 structure to be
 "cleanly" passed over that to the server program that is "listening" on
 the "Named Pipe" on the other side - in this case, samrd.

* samrd receives the NET_USER_INFO_3 struct, and squirrels it away.

* then, if the user needs to do some "proper" stuff like adding a user
  to the SAM database, then the equivalent of "RpcImpersonateClient"
  must be performed - and SeAccessCheck called.


so you can see that this stuff all sort-of hangs together around doing
it vaguely correctly.

the reason for the change in format, above, of the
samba tng <-> namedpipe <-> rpc daemon "security inheritance" protocol
is because it'd be an absolute bastard to modify FreeDCE to understand
anything other than PDUs.

so instead, i am adding a "new" PDU format (embrace and extend!!!) to
FreeDCE and am extending the "state machine" in FreeDCE to cope with the
new PDU.

and _this_ new PDU would "drop" the NET_USER_INFO_3 stuff into the
rpc_context_handle, such that it could be picked up by
rpc_impersonate_client, and ta-daaa, we come back full circle.

it'll end up here:


which gets used _here_:


which ultimately exposes it to applications via an rpc_binding_rep_t
handle, via the auth_info member.

*whew* :)

... but like i said, this is a job for ReactOS and samba tng (and samba
if the samba team wish to) and all that Wine will see is that
RpcImpersonateClient and ImpersonateNamedPipeClient will just pass
around some pointers and just ... "work".

it _does_ mean careful design because i doubt very much whether people
will be happy to have samba tng as a dependency on Wine.

once you begin to appreciate the subtleties involved, here,
i will leave it up to you to relay the requirements to the
samba team: jelmer is the best person to speak to because i have
been explaining to him and negotiating the design of the "Named
Pipes" interoperability, on the tng-technical mailing lists.


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

More information about the wine-devel mailing list