IF YOU WOULD LIKE TO GET AN ACCOUNT, please write an
email to Administrator. User accounts are meant only to access repo
and report issues and/or generate pull requests.
This is a purpose-specific Git hosting for
BaseALT
projects. Thank you for your understanding!
Только зарегистрированные пользователи имеют доступ к сервису!
Для получения аккаунта, обратитесь к администратору.
cli_rpc_pipe_open() now uses tcp transport for drsuapi and named pipe
transport for all other pipes.
This finally allows rpcclient to call dscracknames on windows
(don't forget to call "seal" in advance).
Guenther
(This used to be commit b243a03602)
This probably does not matter in current code, but without this it's not
possible to do the bind as a different user than the underlying smb user.
Jeremy, please check!
Thanks,
Volker
(This used to be commit b90062e33c)
In order to avoid receiving NT_STATUS_DOWNGRADE_DETECTED from a w2k8
netr_ServerAuthenticate2 reply, we need to start with the AD netlogon negotiate
flags everywhere (not only when running in security=ads). Only for NT4 we need
to do a downgrade to the returned negotiate flags.
Tested with w2k8, w2ksp4, w2k3r2 and nt4sp6.
Guenther
(This used to be commit 0970369ca0)
Refactor the actual retrieval of the session key through the
established netlogon pipe out of get_schannel_session_key()
and get_schannel_session_key_auth_ntlmssp() into a new
function get_schannel_session_key_common().
(To avoid code duplication.)
Michael
(This used to be commit e77c4022cf)
Up to now each caller used its own logic.
This eliminates code paths where there was a special treatment
of the following situation: the domain given is not our workgroup
(i.e. our own domain) and we are not a DC (i.e. it is not a typical
trusted domain situation). In situation the given domain name was
previously used as the machine account name, resulting in an account
name of DOMAIN\\DOMAIN$, which does not seem very reasonable to me.
get_trust_pw would not have obtained a password in this situation
anyways.
I hope I have not missed an important point here!
Michael
(This used to be commit 6ced4a7f88)
bugs in various places whilst doing this (places that assumed
BOOL == int). I also need to fix the Samba4 pidl generation
(next checkin).
Jeremy.
(This used to be commit f35a266b3c)
The translate_name() used by cli_session_setup_spnego() cann rely
Winbindd since it is needed by the join process (and hence before
Winbind can be run).
(This used to be commit 00a93ed336)
not specific for NTLMSSP
- it's possible that the server sends a mechOID and authdata
if negResult != SPNEGO_NEG_RESULT_INCOMPLETE, but we still
force the mechOID to be present if negResult == SPNEGO_NEG_RESULT_INCOMPLETE
metze
(This used to be commit e9f2aa22f9)
Jeremy, I'm afraid you removed the "domain->initialized" from the
set_dc_types_and_flags() call when the connect to PI_LSARPC_DS failed
(with rev. 19148).
This causes now that init_dc_connection_network is called again and
again which in turn rescans the DC each time (which of course fails each
time with NT_STATUS_BUFFER_TOO_SMALL). Just continue with the
non-PI_LSARPC_DS scan so that the domain is initialized properly.
Guenther
(This used to be commit c6f63a08f5)
For the winbind cached ADS LDAP connection handling
(ads_cached_connection()) we were (incorrectly) assuming that the
service ticket lifetime equaled the tgt lifetime. For setups where the
service ticket just lives 10 minutes, we were leaving hundreds of LDAP
connections in CLOSE_WAIT state, until we fail to service entirely with
"Too many open files".
Also sequence_number() in winbindd_ads.c needs to delete the cached LDAP
connection after the ads_do_search_retry() has failed to submit the
search request (although the bind succeeded (returning an expired
service ticket that we cannot delete from the memory cred cache - this
will get fixed later)).
Guenther
(This used to be commit 7e1a84b722)
in smb.conf. This did work before the join rewrite.
Samba will have problems if you try to run any of the daemons
with an incorrect workgroup but it should not fail to join.
The summary is that a member server should always use it's
own machine name when setting up schannel since that is
the only account it has. Thanks to Volker for the discussion.
(This used to be commit 95763b94f7)
With this change (and setting lanman auth = no in smb.conf)
we have *identical* NTLMSSP flags to W2K3 in SPNEGO auth.
Jeremy
(This used to be commit 93ca3eee55)
1. Fix a crash bug which should have reared its ugly head ages ago, but for
some reason, remained dormant until recently. The bug pertained to
libsmbclient doing a structure assignment of a cli after having opened a
pipe. The pipe open code makes a copy of the cli pointer that was passed
to it. If the cli is later copied (and that cli pointer that was saved
is no longer valid), the pipe code will cause a crash during shutdown or
when the copied cli is closed.
2. The 'type' field in enumerated shares was not being set correctly with
the new RPC-based mechanism for enumerating shares.
(This used to be commit 62a02b8f2a)
* \PIPE\unixinfo
* winbindd's {group,alias}membership new functions
* winbindd's lookupsids() functionality
* swat (trunk changes to be reverted as per discussion with Deryck)
(This used to be commit 939c3cb5d7)
tested this so I may have screwed this up - however it now follows the
DCE spec. valgrinded tests to follow....
Jeremy.
(This used to be commit 877e0a61f5)
supported pipe. Netlogon is still special, as we open that twice, one to do
the auth2, the other one with schannel.
The client interface is completely unchanged for those who only use a single
pie. cli->pipe_idx is used as the index for everything except the "real"
client rpc calls, which have been explicitly converted in my last commit. Next
step is to get winbind to just use a single smb connection for multiple pipes.
Volker
(This used to be commit dc294c52e0)
patches.
Pass down the pipe_idx down to all functions in cli_pipe where nt_pipe_fnum is
referenced. First step towards having multiple pipes on a cli_struct. The idea
is to not have a single nt_pipe_fnum but an array for the pipes we support.
Volker
(This used to be commit 93eab05020)
for setting up an schannel connection. This solves the problem
of a Samba DC running winbind, trusting a native mode AD domain,
and needing to enumerate AD users via wbinfo -u.
(This used to be commit e9f109d1b3)
would attempt to supply a password to the 'inside' NTLMSSP, which the
remote side naturally rejected.
Andrew Bartlett
(This used to be commit da408e0d5a)
defaults specified by the caller to prevail.
Don't use NTLM2 for RPC pipes, until we know how it works in signing or sealing.
Call ntlmssp_sign_init() unconditionally in the client - we setup the
session key, why not setup the rest of the data.
Andrew Bartlett
(This used to be commit 48123f7e42)
- NTLM2 support in the server
- KEY_EXCH support in the server
- variable length session keys.
In detail:
- NTLM2 is an extension of NTLMv1, that is compatible with existing
domain controllers (unlike NTLMv2, which requires a DC upgrade).
* This is known as 'NTLMv2 session security' *
(This is not yet implemented on the RPC pipes however, so there may
well still be issues for PDC setups, particuarly around password
changes. We do not fully understand the sign/seal implications of
NTLM2 on RPC pipes.)
This requires modifications to our authentication subsystem, as we
must handle the 'challege' input into the challenge-response algorithm
being changed. This also needs to be turned off for
'security=server', which does not support this.
- KEY_EXCH is another 'security' mechanism, whereby the session key
actually used by the server is sent by the client, rather than being
the shared-secret directly or indirectly.
- As both these methods change the session key, the auth subsystem
needed to be changed, to 'override' session keys provided by the
backend.
- There has also been a major overhaul of the NTLMSSP subsystem, to merge the 'client' and 'server' functions, so they both operate on a single structure. This should help the SPNEGO implementation.
- The 'names blob' in NTLMSSP is always in unicode - never in ascii.
Don't make an ascii version ever.
- The other big change is to allow variable length session keys. We
have always assumed that session keys are 16 bytes long - and padded
to this length if shorter. However, Kerberos session keys are 8 bytes
long, when the krb5 login uses DES.
* This fix allows SMB signging on machines not yet running MIT KRB5 1.3.1. *
- Add better DEBUG() messages to ntlm_auth, warning administrators of
misconfigurations that prevent access to the privileged pipe. This
should help reduce some of the 'it just doesn't work' issues.
- Fix data_blob_talloc() to behave the same way data_blob() does when
passed a NULL data pointer. (just allocate)
REMEMBER to make clean after this commit - I have changed plenty of data structures...
(This used to be commit f3bbc87b0d)
the bind response to WKSSVC it does not send \PIPE\ntsvcs as NT4 (did not
check w2k) but \PIPE\wkssvc. I'm not sure whether we should make this check at
all, so making it a bit more liberal should hopefully not really hurt.
Volker
(This used to be commit 029dcb351b)
- When connecting to the NETOGON pipe, we make a call to auth2, in order
to verify our identity. This call was being made with negotiation flags
of 0x1ff. This caused our account to be downgraded. If we instead make
the call with flags > 1ff (such as 0x701ff), then this does not occour.
- This is *not* related to the use of kerberos for the CIFS-level connection
My theory is that Win2k has a test to see if we are sending *exactly* what
NT4 sent - setting any other flags seems to cause us to remain intact.
Also ensure that we only have 'setup schannel' code in a few places, not
scattered around cmd_netlogon too.
Andrew Bartlett
(This used to be commit e10f0529fe)
NTLMSSP with "" username, NULL password), and add --machine-pass (-P) to
all of Samba's clients.
When connecting to an Active Directory DC, you must initiate the CIFS level
session setup with Kerberos, not a guest login. If you don't, your machine
account is demoted to NT4.
Andrew Bartlett
(This used to be commit 3547cb3def)
connection that set it up has been shut down.
(Also, pipes still connected, and reconnections to the same pipe (eg SAMR)
may continue to use that session key until their TCP/IP connection is shut
down)
Allow further testing by printing out the session key, and allowing it's input
into rpcclient.
Next step is automatic storage in a TDB.
Andrew Bartlett
(This used to be commit fa4d7be161)
the schannel code, but I've included that anyway. :-)
This patch revives the client-side NTLMSSP support for RPC named pipes
in Samba, and cleans up the client and server schannel code. The use of the
new code is enabled by the 'sign', 'seal' and 'schannel' commands in
rpcclient.
The aim was to prove that our separate NTLMSSP client library actually
implements NTLMSSP signing and sealing as per Microsoft's NTLMv1 implementation,
in the hope that knowing this will assist us in correctly implementing
NTLMSSP signing for SMB packets. (Still not yet functional)
This patch replaces the NTLMSSP implementation in rpc_client/cli_pipe.c with
calls to libsmb/ntlmssp.c. In the process, we have gained the ability to
use the more secure NT password, and the ability to sign-only, instead of
having to seal the pipe connection. (Previously we were limited to sealing,
and could only use the LM-password derived key).
Our new client-side NTLMSSP code also needed alteration to cope with our
comparatively simple server-side implementation. A future step is to replace
it with calls to the same NTLMSSP library.
Also included in this patch is the schannel 'sign only' patch I submitted to
the team earlier. While not enabled (and not functional, at this stage) the
work in this patch makes the code paths *much* easier to follow. I have also
included similar hooks in rpccleint to allow the use of schannel on *any* pipe.
rpcclient now defaults to not using schannel (or any other extra per-pipe
authenticiation) for any connection. The 'schannel' command enables schannel
for all pipes until disabled.
This code is also much more secure than the previous code, as changes to our
cli_pipe routines ensure that the authentication footer cannot be removed
by an attacker, and more error states are correctly handled.
(The same needs to be done to our server)
Andrew Bartlett
(This used to be commit 5472ddc9ea)
channel:
- If the domain name passed to create_rpc_bind_req() is empty, use
lp_workgroup()
- Correctly set the auth_padding field when the send_size is a multiple
of 8 bytes
I've tested with nt4sp6 and win2ksp0 and it seems to work, although
there are no password hashes transferred from win2k. The empty
passwords are being protected by the secure channel encryption though.
(This used to be commit a8c11e8556)
useful in the auth verifier yet. So this patch ignores it.
Really checking this would be a lot more intrusive: in rpc_api_pipe we
would have to distinguish between binds and normal requests, or have
more state in the netsec info of cli_state, which is also somewhat
hackish.
Volker
(This used to be commit 8de04fcf68)
important once we start doing schannel, as there would be a lot more
roundtrips for the second PIPE open and bind. With this patch logging
in to a member server is a matter of two (three if you count the
ack...) packets between us and the DC.
Volker
(This used to be commit 5b3cb7725a)
tidying up. Samsync still doesn't work due to bad parsing of net_io_sam_alias_info
with a blank description. Still working on this....
Jeremy.
(This used to be commit 942fede9a5)
rpcclient -S pdc -U% -c "samlogon user password"
and it should work with the schannel. Needs testing against platforms
different from NT4SP6.
Volker
(This used to be commit eaef0d8aef)
so that we can print it in later debug messages.
Call prs_dump to dump out requests sent by the client at sufficiently
high debug levels.
(This used to be commit 9973b22b34)
for and ignore ERRmoredata errors as the client library doesn't support
32-bit error messages.
Added some annotations for the RPC pipe code to make it a bit clearer
maybe.
(This used to be commit f179e0ff61)
on different pipes. This seriously confuses NT. Unfortunately HEAD
branch is limited to one rpc pipe per connection as the fnum is stored
inside the cli_state structure. It should really be broken out into
it's own structure so multiple pipes can be opened on one TCP/IP socket.
What a good idea! But look over here! I've already done it in another
workarea but it will require a day or two to refactor some of the internal
samba rpc client stuff (i.e netlogon requests) so it will remain uncommitted
for another while.
(This used to be commit 657804f3be)
We were reading the endainness in the RPC header and then never propagating
it to the internal parse_structs used to parse the data.
Also removed the "align" argument to prs_init as it was *always* set to
4, and if needed can be set differently on a case by case basis.
Now ready for AS/U testing when Herb gets it set up :-).
Jeremy.
(This used to be commit 0cd37c831d)
in the RPC code. This change was prompted by trying to save a long (>256)
character comment in the printer properties page.
The new system associates a TALLOC_CTX with the pipe struct, and frees
the pool on return of a complete PDU.
A global TALLOC_CTX is used for the odd buffer allocated in the BUFFERxx
code, and is freed in the main loop.
This code works with insure, and seems to be free of memory leaks and
crashes (so far) but there are probably the occasional problem with
code that uses UNISTRxx structs on the stack and expects them to contain
storage without doing a init_unistrXX().
This means that rpcclient will probably be horribly broken.
A TALLOC_CTX also needed associating with the struct cli_state also,
to make the prs_xx code there work.
The main interface change is the addition of a TALLOC_CTX to the
prs_init calls - used for dynamic allocation in the prs_XXX calls.
Now this is in place it should make dynamic allocation of all RPC
memory on unmarshall *much* easier to fix.
Jeremy.
(This used to be commit 0ff2ce543e)
* fixes some readline bugs from the merge
* first attempt at commands (spoolenum almost works)
* no changes to existing functions in HEAD; only additions
of new functions. I'll weed out what I can as I go.
--jerry
(This used to be commit 61d2aad5dc)
pdus, and then feeds them over either a "local" function call or a "remote"
function call to an msrpc service. the "remote" msrpc daemon, on the
other side of a unix socket, then calls the same "local" function that
smbd would, if the msrpc service were being run from inside smbd.
this allows a transition from local msrpc services (inside the same smbd
process) to remote (over a unix socket).
removed reference to pipes_struct in msrpc services. all msrpc processing
functions take rpcsrv_struct which is a structure containing state info
for the msrpc functions to decode and create pdus.
created become_vuser() which does everything not related to connection_struct
that become_user() does.
removed, as best i could, connection_struct dependencies from the nt spoolss
printing code.
todo: remove dcinfo from rpcsrv_struct because this stores NETLOGON-specific
info on a per-connection basis, and if the connection dies then so does
the info, and that's a fairly serious problem.
had to put pretty much everything that is in user_struct into parse_creds.c
to feed unix user info over to the msrpc daemons. why? because it's
expensive to do unix password/group database lookups, and it's definitely
expensive to do nt user profile lookups, not to mention pretty difficult
and if you did either of these it would introduce a complication /
unnecessary interdependency. so, send uid/gid/num_groups/gid_t* +
SID+num_rids+domain_group_rids* + unix username + nt username + nt domain
+ user session key etc. this is the MINIMUM info identified so far that's
actually implemented. missing bits include the called and calling
netbios names etc. (basically, anything that can be loaded into
standard_sub() and standard_sub_basic()...)
(This used to be commit aa3c659a8d)
if microsoft bothered to publish it. actually, there are good reasons
for not publishing it: people might write programs for it, and then
those programs wouldn't work on nt5, for example...
(This used to be commit 8ce93b80d3)
verified that lsaquery, lsalookupsids work, and found some bugs in the
parameters of these commands :-)
soo... we now have an lsa_* api that has the same arguments as the nt
Lsa* api! cool!
the only significant coding difference is the introduction of a
user_credentials structure, containing user, domain, pass and ntlmssp
flags.
(This used to be commit 57bff6fe82)
msrpc client code. the intent is to hide / abstract / associate
connection info behind policy handles.
this makes the msrpc functions look more and more like their nt equivalents.
who-hou!
(This used to be commit c01b18e632)
have we got. and what data do we have. hmm.. i wonder what the NTLMv2
user session key can be... hmmm... weell.... there's some hidden data
here, generated from the user password that doesn't go over-the-wire,
so that's _got_ to be involved. and... that bit of data took a lot of
computation to produce, so it's probably _also_ involved... and md4 no, md5?
no, how about hmac_md5 yes let's try that one (the other's didn't work)
oh goodie, it worked!
i love it when this sort of thing happens. took all of fifteen minutes to
guess it. tried concatenating client and server challenges. tried
concatenating _random_ bits of client and server challenges. tried
md5 of the above. tried hmac_md5 of the above. eventually, it boils down
to this:
kr = MD4(NT#,username,domainname)
hmacntchal=hmac_md5(kr, nt server challenge)
sess_key = hmac_md5(kr, hmacntchal);
(This used to be commit ab174759cd)
to mention, there's a spooljobs <printer name> command, and it uses
command-line completion? prints out NT print jobs really nicely, too.
(This used to be commit e6e5caf16c)
samr_lookup_rids() moved to a dynamic memory structure not a
static one limited to 32 RIDs. cli_pipe.c reading wasn't checking
ERRmoredata when DOS error codes negotiated (this terminates
MSRPC code with prejudice).
(This used to be commit 8976eca2db)
a problem i was having.
- added rudimentary CAP_STATUS32 support for same reason.
- added hard-coded, copy-the-same-data-from-over-the-wire version of
CAP_EXTENDED_SECURITY, which is a security-blob to encapsulate
GSSAPI which encodes
SPNEGO which is used to negotiate
Kerberos or NTLMSSP. i have implemented
NTLMSSP which negotiates
NTLMv1 or NTLMv2 and 40-bit or 128-bit etc. i have implemented
NTLMv1 / 40-bit.
*whew*.
(This used to be commit e5b80bd2f7)
Added synchronise_passdb function to update accounts in a BDC's smbpasswd.
Improved rpc_read, which was still somewhat broken for multiple PDU's.
modify_trust_password must initialise cli.pwd (pwd_set_nullpwd).
(This used to be commit 4783ac3968)
LsaLookupSids etc from within SamrQueryAliasMembers, for example.
fnum is now a parameter to client functions. thanks to mike black
for starting the ball rolling.
(This used to be commit bee8f7fa6b)
the pre-alpha "domain group" etc parameters have disappeared.
- interactive debug detection
- re-added mem_man (andrew's memory management, detects memory corruption)
- american spellings of "initialise" replaced with english spelling of
"initialise".
- started on "lookup_name()" and "lookup_sid()" functions. proper ones.
- moved lots of functions around. created some modules of commonly used
code. e.g the password file locking code, which is used in groupfile.c
and aliasfile.c and smbpass.c
- moved RID_TYPE_MASK up another bit. this is really unfortunate, but
there is no other "fast" way to identify users from groups from aliases.
i do not believe that this code saves us anything (the multipliers)
and puts us at a disadvantage (reduces the useable rid space).
the designers of NT aren't silly: if they can get away with a user-
interface-speed LsaLookupNames / LsaLookupSids, then so can we. i
spoke with isaac at the cifs conference, the only time for example that
they do a security context check is on file create. certainly not on
individual file reads / writes, which would drastically hit their
performance and ours, too.
- renamed myworkgroup to global_sam_name, amongst other things, when used
in the rpc code. there is also a global_member_name, as we are always
responsible for a SAM database, the scope of which is limited by the role
of the machine (e.g if a member of a workgroup, your SAM is for _local_
logins only, and its name is the name of your server. you even still
have a SID. see LsaQueryInfoPolicy, levels 3 and 5).
- updated functionality of groupname.c to be able to cope with names
like DOMAIN\group and SERVER\alias. used this code to be able to
do aliases as well as groups. this code may actually be better
off being used in username mapping, too.
- created a connect to serverlist function in clientgen.c and used it
in password.c
- initialisation in server.c depends on the role of the server. well,
it does now.
- rpctorture. smbtorture. EXERCISE EXTREME CAUTION.
(This used to be commit 0d21e1e609)
groupdb/aliasdb.c groupdb/aliasfile.c groupdb/groupfile.c: Don't use snprinf, use slprintf.
include/includes.h: Fix YP problem.
include/smb.h: Fix ZERO_STRUCTP.
lib/util_sock.c: Added strerror() in debugs.
passdb/ldap.c: Don't use snprinf, use slprintf.
rpc_client/cli_lsarpc.c rpc_client/cli_pipe.c rpc_parse/parse_sec.c rpc_server/srv_pipe.c: Don't use snprinf, use slprintf.
script/installman.sh: DGUX changes.
smbd/open.c smbd/oplock.c: Fixed gcc warnings.
web/swat.c: Changes USER to SWAT_USER.
(This used to be commit 4c2b5a0098)
changes from yesterday by me, jeremy and andrew.
jeremy, your ACB_PWNOTREQ mod would have caused a crash if the user
didn't exist (first check should be for smb_pass != NULL)
(This used to be commit cbac0f165d)
rpc_client/cli_pipe.c: Inlined code removed from smbdes.c
rpc_server/srv_samr.c: Fixed unused variable warning.
rpc_server/srv_util.c: Inlined code removed from smbdes.c
Luke - the above changes are the first part of the changes
you and I discussed as being neccessary at the CIFS conference.
*PLEASE REVIEW THESE CHANGES* - make sure I haven't broken
any of the authenticated DCE/RPC code.
smbd/nttrans.c: Fixed to allow NT5.0beta2 to use Samba shares
with NT SMB support.
smbd/open.c: Fixed mkdir when called from nttrans calls.
smbd/server.c: Set correct size for strcpy of global_myworkgroup.
Jeremy.
(This used to be commit d891421d16)
smbd/chgpasswd.c: Fixed (my) stupid bug where I was returning stack based variables. Doh !
smbd/trans2.c: Allows SETFILEINFO as well as QFILEINFO on directory handles.
Jeremy.
(This used to be commit 0b44d27d0b)
put unicode strings after SAMLOGON query regardless of whether it's
an NT mailslot or a non-NT mailslot, after having observed this behaviour
out of NT machines.
(This used to be commit c101113ec2)
smb.tgz file from my portable.
particularly the call to mem_data followed by a realloc of that data in
cli_pipe.c's rpc_read() function.
smbd responses now use p->rdata_i which is a faked-up pointer into
p->rdata's response data. rdata can be very long; rdata_i is limited
to point to no more than max_tsize - 0x18 in length. this will make
it an almost trivial task to add the encrypted rpc headers after
rdata_i, and mem_buf_copy will cope admirably with rhdr chained to
rdata_i chained to auth_verifier etc etc...
(This used to be commit 05a297e3a9)
- removed debug info in struni2 and unistr2 (security risk)
- rpc_pipe function was getting pointer to data then calling realloc *dur*
- password check function, the start of "credential checking",
user, wks, domain, pass as the credentials (not just user,pass which
is incorrect in a domain context)
- cli_write needs to return ssize_t not size_t, because total can be -1
if the write fails.
- fixed signed / unsigned warnings (how come i don't get those any more
when i compile with gcc???)
- nt password change added in smbd. yes, jeremy, i verified that the
SMBtrans2 version still works.
(This used to be commit fcfb40d2b0)
AS/U:
it returns dce/rpc "first" and "last" bits _clear_ in a bind/ack
response, when they should be set in a (small) packet. they also,
in the bind/ack do not set a secondary address string at all, so
we can't check against that...
Win95:
client-side dce/rpc code is a bit odd. it does a "WaitNamedPipeState"
and has slightly different pipe-naming (\PIPE\LANMAN is joined by
\PIPE\SRVSVC, \PIPE\WINREG etc whereas nt just has \PIPE\LANMAN
and \PIPE\).
Win95-USRMGR.EXE:
added LsaOpenPolicy (renamed existing to LsaOpenPolicy2).
added SamrConnect (renamed existing to SamrConnect2).
(This used to be commit a7fccd807b)