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
Log:
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
and an OPTIONAL NET_USER_INFO_3.
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
stuff.
* 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:
http://viewcvs.samba-tng.org/cgi-bin/viewcvs.cgi/tng/source/smbd/sesssetup.c?rev=1.10&content-type=text/vnd.viewcvs-markup
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.
etc.
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:
http://cvs.sourceforge.net/viewcvs.py/freedce/freedce/include/dce/linux-gnu/sec_authn.h?rev=1.2&view=markup
which gets used _here_:
http://cvs.sourceforge.net/viewcvs.py/freedce/freedce/ncklib/include/cn.h?view=markup
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.
l.
--
--
<a href="http://lkcl.net">http://lkcl.net</a>
--
More information about the wine-devel
mailing list