[svn.haxx.se] · SVN Dev · SVN Users · SVN Org · TSVN Dev · TSVN Users · Subclipse Dev · Subclipse Users · this month's index

Re: proposition: patching mod_authz_svn to be used as an authz provider for apache 2.4

From: Francisco L Fernandez Tortosa <fco.luis.fdez_at_es.ibm.com>
Date: Mon, 11 Feb 2019 14:12:35 +0000

Hello

First of all thank you for your reply. As I wasn't copied, didn't see it
until some days later looking at the archives. Sorry for the additional
delay, but had to invest some time to check properly your suggestions.

Branko Čibej <brane_at_apache.org> escribió el 23/01/2019 12:58:26:

> From: Branko Čibej <brane_at_apache.org>
> To: dev_at_subversion.apache.org
> Date: 23/01/2019 12:58
> Subject: Re: propositionl: patching mod_authz_svn to be used as an
> authz provider for apache 2.4
>
> On 23.01.2019 11:42, Francisco L Fernandez Tortosa wrote:
> > Hello,
> >
> > I am involved in a customer project to replace CVS with SVN. SVN was
> > chosen against more popular alternatives like git, because it is a
> > free, open-source, mature and, this was the main point, centralized
> > version control system. Repositories are to be accessed through https
> > protocol, served by apache httpd server 2.4. Some features of the
> > actual CVS service had to be ported to the SVN setup. For example,
> > normal users shouldn't be able to create top (first) level folders and
> > files. The straight forward to implement that requisite was through
> > path access cheking. But activate mod_authz_svn implies breaking any
> > other authz module, like for example mod_authnz_ldap, required for us
> > to control repository access based on LDAP group membership, or having
> > true read only service accounts for Redmine, to have just two
examples.
>
>
> How relevant is it to this discussion that I maintain a Subversion
> server with mod_authz_svn, that uses LDAP group membership (with
> mod_authnz_ldap) to have true read-only accounts? With no patches.
>
>

Absolutely relevant. It would be enough for us if it could work, but
unfortunately, that is not the case. See later on in the message.

> > Looking at the source code I have found that mod_authz_svn is coded to
> > support apache 2.2 authn / authz instead of native 2.4 model. As I
> > didn't consider it a major effort, I have dedicated a few hours to
> > analyze and patch the code, resulting in a functional 2.4 authz
> > provider. This way it can seamless combine with other authz providers
> > like in this example:
> >
> > svn01:~/src/subversion-1.10.0/source/subversion-1.10.0 # cat
> > /etc/apache2/vhosts.d/svn.d/repos/test.conf
> > <IfModule mod_dav_svn.c>
> >
> > SetEnvif Request_URI ^/repos/test Repo_test=1
> > CustomLog /svn/logs/repos/test/access.log "%h %t -
> > %{SVN-REPOS-NAME}e - %u - %{SVN-ACTION}e" env=Repo_test
> > <Location "/repos/test">
> > DAV svn
> > SVNPath /svn/repos/test
> > AuthzSVNAccessFile /svn/config/auth/accessfile-test
> > SVNReposName "Repositorio de TEST"
> > AuthzSVNAuthoritative Off
> > AuthzSVNAnonymous Off
> > AuthMerging And
> > <RequireAll>
> > <RequireAny>
> > Require control-point "GuardiasRedes"
> > Require control-point "Administradores Servidores Horizontales"
> > </RequireAny>
> > Require svnpathaccess "Granted"
> > </RequireAll>
> > </Location>
> > </IfModule>
> > svn01:~/src/subversion-1.10.0/source/subversion-1.10.0 #
> >
> > The "Granted" argument to the "require svnpathaccess" line for the
> > provider is just a placeholder / syntax sugar as all the info that the
> > provider needs is provided through the directory level clauses
> > AuthzSVNAccessFile, SVNReposName... etc.
>
>
> What does your proposed 'svnpathaccess' do? From your configuration I
> don't understand its purpose.
>

In its actual design, the module is always active as long as
AuthzSVNAccessFile or equivalent directives are specified on the location.
With the PATH applied, it is a pure apache 2.4 authz provider, and
therefore, it is only called when used inside a Require* directive, aud
thus it can be called as an alternative (logic OR / Require any block) or
a requisite (logic AND / RequireAll block). Usually, an apache 2.4 authz
provider (as mod_authnz_ldap does) needs an argument, for example "require
ldap-group", "require ldap-attr" and so on. We don't need any argument
because the access file contains all the info we could think about, and
the own access file path is specified via directives and made known
globally to all C functions. To change this would requiere broader
changes. In this very example, as Require svnpathaccess "Granted" is
placed inside a RequireAll first level block, SVN path access is checked
additionally to other constraints as LDAP group membership.

>
> Here is an example of the configuration I mentioned above; it uses
> mod_authz_core, mod_authz_user, mod_authnz_ldap and mod_authz_svn.
>
> <Location /repos/>
> AuthType basic
> AuthName "Example"
> AuthBasicProvider ldap
>
> AuthLDAPUrl ...
> # (rest of LDAP config omitted)
>
> <RequireAll>
> Require valid-user
> <Limit HEAD GET OPTIONS PROPFIND REPORT>
> <RequireAny>
> Require ldap-group
cn=write,ou=group,dc=example,dc=com
> Require ldap-group
cn=read,ou=group,dc=example,dc=com
> # More reader groups here
> </RequireAny>
> </Limit>
> <LimitExcept HEAD GET OPTIONS PROPFIND REPORT>
> <RequireAny>
> Require ldap-group
cn=write,ou=group,dc=example,dc=com
> # More writer groups here
> </RequireAny>
> </LimitExcept>
> </RequireAll>
>
> DAV svn
> SVNParentPath ${SVN_REPO_DIR}
> SVNListParentPath on
> SVNPathAuthz short_circuit
> AuthzSVNAccessFile ${SVN_AUTHZ_FILE}
> </Location>
>
>

Well, We have been evaluating your config, and I must say that it works
when using svn 1.8 and httpd 2.4.23, (SLES 12 SP3) but definitely doesn't
work when using svn 1.10 and httpd 2.4.33 (SLES 15). In the second case,
when I insert mod_authz_svn directives on the location, the LDAP groups
are not evaluated in the second authz (authenticated user found) phase,
only in the first. I attach logs and configs.

What works:

svnsmm:~ # cat /etc/apache2/vhosts.d/svn.d/repos/test_svn_authz.conf
<IfModule mod_dav_svn.c>

SetEnvif Request_URI ^/repos/test Repo_Test=1
CustomLog /svn/logs/repos/test/access.log "%h %t - %{SVN-REPOS-NAME}e -
%u - %{SVN-ACTION}e %b %>s \"%r\"" env=Repo_Test

<Location "/repos/test">
        DAV svn
        SVNPath /svn/repos/test

        SVNReposName "Repositorios de Test"

        AuthMerging And

        ###--- Limite de fichero de 1 Mb ---###
        LimitRequestBody 1048576

        <RequireAll>
                #Require ldap-group
cn=DESPRECSTAT,ou=EXGS,ou=WWW.AEAT,o=Autorizaciones,O=AEAT
                Require ldap-group
cn=EXPLOTACION,ou=PROXY,ou=SEG,o=Autorizaciones,O=AEAT
                #Require ldap-user f00997ze
        </RequireAll>

        ###--- svn path control ---###
    SVNPathAuthz short_circuit

    AuthzSVNAuthoritative Off
    AuthzForceUsernameCase Lower
    AuthzSVNAnonymous On
    AuthzSVNNoAuthWhenAnonymousAllowed Off
    AuthzSVNAccessFile /svn/repos/test/conf/authz
    ###--- ---------------- ---###

</Location>

</IfModule>
svnsmm:~ #

svnsmm:~ # cat /etc/os-release
NAME="SLES"
VERSION="12-SP3"
VERSION_ID="12.3"
PRETTY_NAME="SUSE Linux Enterprise Server 12 SP3"
ID="sles"
ANSI_COLOR="0;32"
CPE_NAME="cpe:/o:suse:sles:12:sp3"
svnsmm:~ # httpd -version
Server version: Apache/2.4.23 (Linux/SUSE)
Server built: 2018-04-04 10:24:21.000000000 +0000
svnsmm:~ #

What doesn't work:

vn01:~ # cat /etc/apache2/vhosts.d/svn.d/repos/test.conf

<IfModule mod_dav_svn.c>

SetEnvif Request_URI ^/repos/test Repo_test=1

CustomLog /svn/logs/repos/test/access.log "%h %t - %{SVN-REPOS-NAME}e -
%u - %{SVN-ACTION}e" env=Repo_test

<Location "/repos/test">

    DAV svn

    SVNPath /svn/repos/test

    SVNReposName "TEST Repository"

    AuthLDAPURL
"ldaps://10.30.244.59/dc=redes,dc=aeat?sAMAccountName?sub?(objectCategory=user)"
SSL

    AuthLDAPBindDN "usrdit_auth_sh_at_REDES.AEAT"

    AuthLDAPBindPassword XXXXXXXX

    AuthLDAPGroupAttributeIsDN on

    AuthLDAPGroupAttribute member

    SVNAllowBulkUpdates Prefer

<If "true">

    SVNPathAuthz short_circuit

    AuthzSVNNoAuthWhenAnonymousAllowed Off

    AuthzSVNAnonymous On

    AuthzForceUsernameCase Lower

    AuthzSVNAccessFile /svn/config/auth/accessfile-test

    AuthzSVNAuthoritative Off

</If>

    AuthMerging And

    <RequireAll>

    Require valid-user

    <RequireAny>

      Require ldap-group CN=Administradores Servidores
Horizontales,OU=Grupos que habilitan Perfiles funcionales de
usuarios,OU=AEAT,DC=redes,DC=aeat

      Require ldap-group CN=APPBD,OU=Puntos de Control
Corporativos,OU=Grupos,OU=AEAT_GIA,DC=redes,DC=aeat

    </RequireAny>

    </RequireAll>

 </Location>

</IfModule>

svn01:~ #

svn01:~ # cat /etc/os-release
NAME="SLES"
VERSION="15"
VERSION_ID="15"
PRETTY_NAME="SUSE Linux Enterprise Server 15"
ID="sles"
ID_LIKE="suse"
ANSI_COLOR="0;32"
CPE_NAME="cpe:/o:suse:sles:15"
svn01:~ # httpd -version
Server version: Apache/2.4.33 (Linux/SUSE)
Server built: 2018-10-01 15:05:14.000000000 +0000
svn01:~ #

In this second configuration, changing the mod_authz_svn directive block
to false, the user gets checked against the LDAP groups:

Fri Feb 08 15:31:34.027127 2019] [authnz_ldap:debug] [pid 19356:tid
140212235536128] mod_authnz_ldap.c(930): [client 10.30.79.62:63332]
AH01714: auth_ldap authorize: require group: testing for member:
CN=F00910Y6,OU=Explotaci\xc3\xb3n_Redes
Locales,OU=Usuarios_SG_Explotaci\xc3\xb3n,OU=Usuarios_Oficina,OU=Usuarios,OU=DSCDIT00.AEAT,OU=OCSCR,OU=9054000
- DPTO. INFORMATICA TRIBUTARIA,OU=AEAT_GIA,DC=redes,DC=aeat
(CN=Administradores Servidores Horizontales,OU=Grupos que habilitan
Perfiles funcionales de usuarios,OU=AEAT,DC=redes,DC=aeat)

[Fri Feb 08 15:31:34.027160 2019] [authnz_ldap:debug] [pid 19356:tid
140212235536128] mod_authnz_ldap.c(940): [client 10.30.79.62:63332]
AH01715: auth_ldap authorize: require group: authorization successful
(attribute member) [Comparison true (cached)][6 - Compare True]

[Fri Feb 08 15:31:34.027186 2019] [authz_core:debug] [pid 19356:tid
140212235536128] mod_authz_core.c(809): [client 10.30.79.62:63332]
AH01626: authorization result of Require ldap-group CN=Administradores
Servidores Horizontales,OU=Grupos que habilitan Perfiles funcionales de
usuarios,OU=AEAT,DC=redes,DC=aeat: granted

But leaving it to true, results in only path access being evaluated:

[Fri Feb 08 15:39:59.226458 2019] [authnz_ldap:debug] [pid 22635:tid
139689608455936] mod_authnz_ldap.c(523): [client 10.30.79.62:63619]
AH01691: auth_ldap authenticate: using URL
ldaps://10.30.244.59/dc=redes,dc=aeat?sAMAccountName?sub?(objectCategory=user)

[Fri Feb 08 15:39:59.226514 2019] [authnz_ldap:debug] [pid 22635:tid
139689608455936] mod_authnz_ldap.c(620): [client 10.30.79.62:63619]
AH01697: auth_ldap authenticate: accepting f00910y6

[Fri Feb 08 15:39:59.226550 2019] [authz_svn:debug] [pid 22635:tid
139689608455936] subversion/mod_authz_svn/mod_authz_svn.c(450): [client
10.30.79.62:63619] Path to authz file is /svn/config/auth/accessfile-test

[Fri Feb 08 15:39:59.226587 2019] [authz_svn:info] [pid 22635:tid
139689608455936] [client 10.30.79.62:63619] Access granted: 'F00910Y6'
MERGE test:

[Fri Feb 08 15:39:59.250228 2019] [ssl:debug] [pid 22635:tid
139689608455936] ssl_engine_io.c(1103): [client 10.30.79.62:63619]
AH02001: Connection closed to child 1044 with standard shutdown (server
svn01.desa.aeat:443)

> > The patched code suits our needs, but we are very concerned about
> > support and maintenance. Would it be possible for the SVN dev team to
> > integrate in the official code a patch like this and provide the
> > module full apache 2.4 integration?.
>
> Of course it's possible, once we agree on why it's necessary and how to
> actually do it.
>
>

Great! Should it be needed or not today, I will consider nevertheless to
prepare the code for future apache httpd versions breaking backwards
compatibility.

> > Attached goes the patch for your consideration. It is written against
> > 1.10 code. Perhaps you should correct some white spaces in the patch
> > to apply cleanly because security restrictions at the customer don't
> > allow the employes or subcontractors to send any type mail
> > attachments, and I had to copy it in the body.
>
> First of all, please make patches from trunk. Your patch duplicates some
> changes that are already in our code, so it doesn't apply cleanly, which
> makes it hard to test and evaluate.
>

Ok. I have redone the patch against the trunk (2019-02-08) to ease your
work.

> I also see that the patch adds quite a lot of new conditional code; I'd
> like to understand if it's really necessary; that's not clear from
> comments in the patch.
>

Sorry. It was not commented properly as it was a proof of concept, but the
conditional code is there to preserve the original 2.2 compatibility when
built against a 2.0 / 2.2 httpd version. Hooks must be registered other
way in each case. Also with 2.4 provider approach , we only need a wrapper
function por authorization instead of three (for authn, authz and access
control).

To briefly explain it, first come some httpd version detection
conditionals and then the code is branched depending on if we are
compiling against 2.4 or earlier APR.

>
> -- Brane
>

Thanks in advance

Salvo indicado de otro modo más arriba / Unless stated otherwise above:
International Business Machines, S.A.
Santa Hortensia, 26-28, 28002 Madrid
Registro Mercantil de Madrid; Folio 1; Tomo 1525; Hoja M-28146
CIF A28-010791

Received on 2019-02-11 15:12:58 CET

This is an archived mail posted to the Subversion Dev mailing list.