possible solution for "outsourcing" authentication from samba 4 to
samba 3
Luke Kenneth Casson Leighton
lkcl at lkcl.net
Sat Dec 11 13:49:40 GMT 2004
dear samba people,
given that the benefits of the namedpipe "outsourcing" are clear, i
thought i might describe to you the solution that i use in samba tng to
manage authentication.
in samba tng, the solution _does_ have performance penalties
(about 10ms), which can be mitigated against (by employing
techniques used by apache such as pre-forking), which are also
quietly irrelevant on order-of-magnitude scales involved in
network traffic communications, which are completely DWARFED
by the O(N^3) problems associated with samba tng's group lookup
code :)
one administrator solved the group lookup code problem - by
removing it (!) - and consequently was able to support 2,000
users - approximately 4 to 5 hundred of them simultaneously
logging in regularly at the beginning of lectures, up until the time
where the two nt admins got jealous of their part-time colleague and
stipulated that the samba tng server be replaced with nt.
_but_ never mind...
the approach taken by samba tng is very straightforward:
1) implement NT domain client-side authentication code (security=domain)
2) use it - ALL THE TIME!
the issue of implementing an authentication mechanism inside smbd
then just... goes away: all authentication code in TNG has gone into one
service: samrd!
both netlogond and lsad (including LsaQuerySecret and
LsaSetSecret and also a slightly bodged form of inter-domain
trust account passing-through) _have_ to be fully implemented
for this to work, and bizarrely, it is not necessary to do
any special-casing even inside netlogond: only inside samrd
(or whatever you choose to place behind \\pipe\samr).
a whole boat-load of code was therefore removed from smbd in samba tng -
the entire authentication subsystem ripped out and replaced pretty much
with a single function call.
well, actually that's not _quite_ true - the authentication subsystem
"slipped sideways" into samrd, to be replaced with a single function
call.
to improve efficiency, a "special" ncacn_np nomenclature was
"invented" (or borrowed from nt, more like) to indicate that,
as root, rather than to use libsmb to go via _yet_ another
smbd process as an anonymous user, the "outsourcing" process
was to be bypassed _completely_ and the root-only-accesible
unix-domain-socket to be used instead.
this nomenclature is "ncacn_np:\\.\netlogon".
what this meant was that security=domain could just use
"ncacn_np:\\THEPDC\netlogon" and security=user could just use
"ncacn_np:\\.\netlogon" and it would just... work!
the only other "special" thing that was needed was to actually add - and
use - a MACHINE.ACC$ account _for_ the samba TNG server itself.
the reason is because at both ends (the client-side implementation of
the NETLOGON library call _and_ the server-side implementation of
NETLOGON) they were both expecting to be able to look up a well-known
shared secret - the MACHINE.ACC$ name.
the fact that this MACHINE.ACC$ name is in the same database was
irrelevant to both client and server code!
okay, i think what i did was, in the client-side code, go "if servername
== '.' then lookup MACHINE.ACC$ in the lsa, else lookup WORKSTATION$ in
the lsa" - that was about it.
because i loved doing this sort of thing so much, i also (and
at this point it might get a _bit_ much for you - see below
for a way round the problem * :) made the NETLOGON client-side
code _also_ use samr client-side functions and lsa client-side
functions where possible.
[why? because i can. because it makes porting the code to NT
to replace samr, NETLOGON and lsass much easier. because it
makes porting the code to Wine so much easier. because it
makes porting the code to that Open Source Windows replacement
project so much easier. anyway]
consequently, calling the client-side NETLOGON function to perform
NT Domain authentication would fire up a samrd daemon _and_ an lsa
daemon _and_ a netlogon daemon (at the remote end) because lsa
client-side functions were used to obtain the SID, samr client-side
functions were used to look up the MACHINE.ACC$ secret in the sam
database, and client-side NETLOGON functions then used that secret to
make a secured login session... you get the idea).
_fortunately_ and i say fortunately, because you are
running as root and have access to the root-only-accessible
namedpipe unix-domain-sockets, it was NOT necessary to cause
authentication to occur for access to the services at the
other end of the sockets!
otherwise, the whole thing would have gotten into a COMPLETE nightmare
scenario (which i did end up getting into during the development
process, which caused me to invent / reinvent / borrow / steal the
"\\.\pipe" nomenclature.
possible questions that might be asked:
1) how do you implement kerberos in this scheme?
ans: you don't: instead of calling the NETLOGON client-side
authentication function directly, you invent _another_ layer
(named LsaLogonEx in NT terminology) which is responsible
for determining "am i using nt domain 4.0 or am i using nt
5.0 authentication? if 4.0, call netlogon_authenticate,
if 5.0, call kerberos_authenticate)"
2) why suffer the performance penalty associated with this mad approach?
ans: it's not that big a deal: security=domain already uses
_exactly_ the same mechanism, and some people use that all
the time already: you're just saying that everyone must use it
_all_ the time because it's so much simpler to code up, and
you can put in special cases that help speed things up,
such as pre-forking your smbd server, just like apache does,
cache/pre-loading the smb.conf file (which constituted the
largest bit of the performance hit associated with tng's
approach), etc.
3) how do you put in different authentication back-ends [in tng]?
ans: write - and use - a different samrd. stop using the default
samrd and use samrtdbd or samrsqld or samrldapd. job done.
4) is it _completely_ necessary to go to the insane non-unixy extent
that you did?
ans: no, of course not. i simply wanted to have some fun exploring
the limits and also to do a _full_ implementation of the NT domain
authentication, not just the gribbly bits that make it vaguely
possible to interact with NT.
it's perfectly reasonable to implement a client-side NETLOGON
function that "bypasses" the DCE/RPC bits (even the grungy
unix-domain-socket thing) altogether.
effectively what you end up doing is to call the server-side
stub implementation (e.g. lsa_query_secret() to get the $MACHINE.ACC)
DIRECTLY, etc.
or, you invent your own API (e.g. get_machine_secret()) and use that.
oh - and remember if you do implement e.g. lsa_query_secret(), you have
to call / translate to your own API (e.g. get_machine_secret()) in
the lsa server _too_...
the reason why i did a full NT-style implementation was
because i considered the alternatives to be... well... messy
(as the paragraph above begins to hint at)
if you _provide_ a samr interface behind a nice DCE/RPC thing, why go
to all the trouble of bypassing it, thereby giving yourself a
maintenance headache?
because you're implementing NT-land, you will never need anything
other than the interfaces that the NT developers have already
kindly provided...
anyway.
the whole reason why i mention this is because no doubt you
have already implemented or are considering implementing as
a high priority "security=domain".
"security=domain" is something i presume that _does_ need to
_be_ implemented.
and the design architecture i have outlined above means
that you are in a position to leverage "security=domain"
_immediately_ to provide "security=user" semantics with
virtually no extra design effort.
of course, it goes without saying that this is simply what samba tng
does, and i hope that the efforts of samba 3 and samba 4 do save time
and development effort by implementing something similar, even if it is
only used as a transitional and testing phase to minimise the number
and size of components needed to be developed in samba 4 for each
milestone.
less is more. minimum necessary change. end of eternity (isaac asimov).
l.
--
--
<a href="http://lkcl.net">http://lkcl.net</a>
--
More information about the samba-technical
mailing list