#50069 Ticket 50065 - lib389 aci parsing is too strict
Closed 3 years ago by spichugi. Opened 5 years ago by mreynolds.
mreynolds/389-ds-base ticket50065  into  master

file modified
+17 -2
@@ -235,7 +235,7 @@ 

              # This converts the dict to a list of tuples,

              lt = []

              for k in self.data.keys():

-                 # l here is the 

+                 # l here is the

                  vals = None

                  if isinstance(self.data[k], list) or isinstance(self.data[k], tuple):

                      vals = ensure_list_bytes(self.data[k])
@@ -503,6 +503,21 @@ 

          rawaci += ")"

          return ensure_bytes(rawaci)

  

+     def _normalize_term(self, term):

+         """Normalize the term, remove duplicate spaces around sensitive keywords,

+         and remove spaces around "version 3.0 ;"

+         :retuns: normalized term string

+         """

+ 

+         # First reduce multiple consecutive spaces

+         new_term = ' '.join(term.split())

+ 

+         # Our parsing of version 3.0; is strict, need to take special care

+         if new_term.lower().startswith('version 3.0'):

+             parts = new_term.split(';', 1)

+             new_term = parts[0].rstrip() + ';' + parts[1]

+         return new_term

+ 

      def _find_terms(self, aci):

          if self.verbose:

              print("_find_terms aci: %s" % aci)
@@ -525,7 +540,7 @@ 

              print("_find_terms lbr_list" % lbr_list)

              print("_find_terms rbr_list" % rbr_list)

          for lb, rb in zip(lbr_list, rbr_list):

-             terms.append(aci[lb + 1:rb])

+             terms.append(self._normalize_term(aci[lb + 1:rb]))

          if self.verbose:

              print("_find_terms terms: %s" % terms)

          return terms

@@ -0,0 +1,57 @@ 

+ from lib389._entry import EntryAci

+ from lib389.utils import *

+ import pytest

+ import os

+ 

+ DEBUGGING = os.getenv("DEBUGGING", default=False)

+ if DEBUGGING:

+     logging.getLogger(__name__).setLevel(logging.DEBUG)

+ else:

+     logging.getLogger(__name__).setLevel(logging.INFO)

+ log = logging.getLogger(__name__)

+ 

+ 

+ rawaci0 = ('(  targetattr =  "objectclass")( target = "ldap:///cn=retrieve '

+            'certificate,cn=virtual operations,cn=etc,dc=ipa,dc=example"   )('

+            '   version 3.0    ;    acl "permission:Retrieve   Certificates '

+            'from the CA";allow (write) groupdn = "ldap:///cn=Retrieve Certif'

+            'icates from the CA,cn=permissions,cn=pbac,dc=ipa,dc=example;)')

+ rawaci2 = ('(targetattr = "objectclass")(target = "ldap:///cn=retrieve certi'

+            'ficate,cn=virtual operations,cn=etc,dc=ipa,dc=example" )(version'

+            ' 3.0; acl "permission:Retrieve Certificates from the CA" ; allow '

+            '(write) groupdn = "ldap:///cn=Retrieve Certificates from the CA,'

+            'cn=permissions,cn=pbac,dc=ipa,dc=example;)')

+ rawaci3 = ('(targetfilter ="(ou=groups)")(targetattr ="uniqueMember || member")'

+            '(version 3.0; acl "Allow test aci";allow (read, search, write)'

+            '(userdn="ldap:///dc=example,dc=com??sub?(ou=engineering)" '

+            'and userdn="ldap:///dc=example,dc=com??sub?(manager=uid='

+            'wbrown,ou=managers,dc=example,dc=com) || ldap:///dc=examp'

+            'le,dc=com??subrawaci?(manager=uid=tbrown,ou=managers,dc=exampl'

+            'e,dc=com)" );)')

+ rawaci4 = ('(  targetattr =  "objectclass")( target = "ldap:///cn=retrieve '

+            'certificate,cn=virtual operations,cn=etc,dc=ipa,dc=example"   )('

+            '   version   3.0  ;  acl "permission:Retrieve Certificates '

+            'from the CA";allow (write) groupdn =   "ldap:///cn=Retrieve Certif'

+            'icates from the CA,cn=permissions,cn=pbac,dc=ipa,dc=example;)')

+ rawaci5 = ('(targetfilter ="(ou=groups)")( targetattr =    "uniqueMember  ||   member")'

+            '(version 3.0; acl "Allow test aci";allow (read, search, write)'

+            '(userdn="ldap:///dc=example,dc=com??sub?(ou=engineering)" '

+            'and userdn="ldap:///dc=example,dc=com??sub?(manager=uid='

+            'wbrown,ou=managers,dc=example,dc=com)   ||  ldap:///dc=examp'

+            'le,dc=com??subrawaci?(manager=uid=tbrown,ou=managers,dc=exampl'

+            'e,dc=com)" );)')

+ 

+ acis = [rawaci0, rawaci2, rawaci3, rawaci4, rawaci5]

+ 

+ 

+ def test_parse_aci():

+     for rawaci in acis:

+         # parse the aci - there should be no exceptions

+         aci_obj = EntryAci(None, rawaci)

+         aci_obj.getRawAci()

+ 

+ 

+ if __name__ == "__main__":

+     CURRENT_FILE = os.path.realpath(__file__)

+     pytest.main("-s -vv %s" % CURRENT_FILE)

+ 

Bug Description:

ACI parsing is very strict around parsing "version 3.0;".
If there are any spaces around the semicolon parsing fails.

Fix Description:

Add a normalization function that removes duplicate
consecutive spaces, and handles spaces around the version string.

https://pagure.io/389-ds-base/issue/50065

Reviewed by: ?

rebased onto 4c98c3336e26e39c3df22992a03eb07750b11d05

5 years ago

rebased onto 5eab3b5

5 years ago

Pull-Request has been merged by mreynolds

5 years ago

389-ds-base is moving from Pagure to Github. This means that new issues and pull requests
will be accepted only in 389-ds-base's github repository.

This pull request has been cloned to Github as issue and is available here:
- https://github.com/389ds/389-ds-base/issues/3128

If you want to continue to work on the PR, please navigate to the github issue,
download the patch from the attachments and file a new pull request.

Thank you for understanding. We apologize for all inconvenience.

Pull-Request has been closed by spichugi

3 years ago