diff options
author | Kevin McCarthy <kmccarth@redhat.com> | 2007-10-11 11:21:27 -0700 |
---|---|---|
committer | Kevin McCarthy <kmccarth@redhat.com> | 2007-10-11 11:21:27 -0700 |
commit | 52a57a9639e085205bab99582aa9b93d0bf46b38 (patch) | |
tree | 9ea7cd6dd1e4fa651e5a4bca041a72d56884397f /ipa-python/aci.py | |
parent | 4c2a33d0e895e5fddcbce3d2216893d6249699e9 (diff) | |
download | freeipa-52a57a9639e085205bab99582aa9b93d0bf46b38.tar.gz freeipa-52a57a9639e085205bab99582aa9b93d0bf46b38.tar.xz freeipa-52a57a9639e085205bab99582aa9b93d0bf46b38.zip |
This is a really simple (and dumb) ACI parser for the ACI's we
will need in the delegation UI.
Diffstat (limited to 'ipa-python/aci.py')
-rw-r--r-- | ipa-python/aci.py | 114 |
1 files changed, 114 insertions, 0 deletions
diff --git a/ipa-python/aci.py b/ipa-python/aci.py new file mode 100644 index 000000000..d834f8997 --- /dev/null +++ b/ipa-python/aci.py @@ -0,0 +1,114 @@ +# Copyright (C) 2007 Red Hat +# see file 'COPYING' for use and warranty information +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; version 2 or later +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +import re + +class ACI: + """ + Holds the basic data for an ACI entry, as stored in the cn=accounts + entry in LDAP. Has methods to parse an ACI string and export to an + ACI String. + """ + + def __init__(self,acistr=None): + self.source_group = '' + self.dest_group = '' + self.attrs = [] + self.name = '' + if acistr is not None: + self.parse_acistr(acistr) + + def export_to_string(self): + """Converts the ACI to a string suitable for an LDAP aci attribute.""" + attrs_str = ' || '.join(self.attrs) + + # dest_group and source_group are assumed to be pre-escaped. + # dn's aren't typed in, but searched for, and the search results + # will return escaped dns + + acistr = ('(targetattr = "%s")' + + '(targetfilter="(memberOf=%s)")' + + '(version 3.0;' + + 'acl "%s";' + + 'allow (write) ' + + 'groupdn="%s";)') % (attrs_str, + self.dest_group, + self.name, + self.source_group) + return acistr + + def _match(self, prefix, inputstr): + """Returns inputstr with prefix removed, or else raises a + SyntaxError.""" + if inputstr.startswith(prefix): + return inputstr[len(prefix):] + else: + raise SyntaxError, "'%s' not found at '%s'" % (prefix, inputstr) + + def _match_str(self, inputstr): + """Tries to extract a " delimited string from the front of inputstr. + Returns (string, inputstr) where: + - string is the extracted string (minus the enclosing " chars) + - inputstr is the parameter with the string removed. + Raises SyntaxError is a string is not found.""" + if not inputstr.startswith('"'): + raise SyntaxError, "string not found at '%s'" % inputstr + + found = False + start_index = 1 + final_index = 1 + while not found and (final_index < len(inputstr)): + if inputstr[final_index] == '\\': + final_index += 2 + elif inputstr[final_index] == '"': + found = True + else: + final_index += 1 + if not found: + raise SyntaxError, "string not found at '%s'" % inputstr + + match = inputstr[start_index:final_index] + inputstr = inputstr[final_index + 1:] + + return(match, inputstr) + + def parse_acistr(self, acistr): + """Parses the acistr. If the string isn't recognized, a SyntaxError + is raised.""" + acistr = self._match('(targetattr = ', acistr) + (attrstr, acistr) = self._match_str(acistr) + self.attrs = attrstr.split(' || ') + + acistr = self._match(')(targetfilter=', acistr) + (target_dn_str, acistr) = self._match_str(acistr) + target_dn_str = self._match('(memberOf=', target_dn_str) + if target_dn_str.endswith(')'): + self.dest_group = target_dn_str[:-1] + else: + raise SyntaxError, "illegal dest_group at '%s'" % target_dn_str + + acistr = self._match(')(version 3.0;acl ', acistr) + (name_str, acistr) = self._match_str(acistr) + self.name = name_str + + acistr = self._match(';allow (write) groupdn=', acistr) + (src_dn_str, acistr) = self._match_str(acistr) + self.source_group = src_dn_str + + acistr = self._match(';)', acistr) + if len(acistr) > 0: + raise SyntaxError, "unexpected aci suffix at '%s'" % acistr |