Exemplo n.º 1
0
 def reload_systemwide_ca_store(self):
     try:
         ipautil.run([paths.UPDATE_CA_TRUST])
     except CalledProcessError, e:
         root_logger.error(
             "Could not update systemwide CA trust database: %s", e)
         return False
Exemplo n.º 2
0
    def store_session_cookie(self, cookie_header):
        '''
        Given the contents of a Set-Cookie header scan the header and
        extract each cookie contained within until the session cookie
        is located. Examine the session cookie if the domain and path
        are specified, if not update the cookie with those values from
        the request URL. Then write the session cookie into the key
        store for the principal. If the cookie header is None or the
        session cookie is not present in the header no action is
        taken.

        Context Dependencies:

        The per thread context is expected to contain:
            principal
                The current pricipal the HTTP request was issued for.
            request_url
                The URL of the HTTP request.

        '''

        if cookie_header is None:
            return

        principal = getattr(context, 'principal', None)
        request_url = getattr(context, 'request_url', None)
        root_logger.debug("received Set-Cookie '%s'", cookie_header)

        # Search for the session cookie
        try:
            session_cookie = Cookie.get_named_cookie_from_string(cookie_header,
                                                                 COOKIE_NAME, request_url)
        except Exception, e:
            root_logger.error("unable to parse cookie header '%s': %s", cookie_header, e)
            return
Exemplo n.º 3
0
    def setup_pkinit(self):
        ca_db = certs.CertDB(self.realm, host_name=self.fqdn,
                                subject_base=self.subject_base)

        if self.pkcs12_info:
            ca_db.install_pem_from_p12(self.pkcs12_info[0],
                                       self.pkcs12_info[1],
                                       paths.KDC_CERT)
            ca_db.install_key_from_p12(self.pkcs12_info[0],
                                       self.pkcs12_info[1],
                                       paths.KDC_KEY)
        else:
            subject = str(DN(('cn', self.fqdn), self.subject_base))
            krbtgt = "krbtgt/" + self.realm + "@" + self.realm
            certpath = (paths.KDC_CERT, paths.KDC_KEY)
            try:
                reqid = certmonger.request_cert(certpath, u'KDC-Cert',
                                                subject, krbtgt,
                                                dns=self.fqdn, storage='FILE',
                                                profile='KDCs_PKINIT_Certs')
            except dbus.DBusException as e:
                # if the certificate is already tracked, ignore the error
                name = e.get_dbus_name()
                if name != 'org.fedorahosted.certmonger.duplicate':
                    root_logger.error("Failed to initiate the request: %s", e)
                return

            try:
                certmonger.wait_for_request(reqid)
            except RuntimeError as e:
                root_logger.error("Failed to wait for request: %s", e)

        # Finally copy the cacert in the krb directory so we don't
        # have any selinux issues with the file context
        shutil.copyfile(paths.IPA_CA_CRT, paths.CACERT_PEM)
Exemplo n.º 4
0
    def _create_socket(self):
        ssl_enable_renegotiation = getattr(
            ssl, 'SSL_ENABLE_RENEGOTIATION', 20)
        ssl_require_safe_negotiation = getattr(
            ssl,'SSL_REQUIRE_SAFE_NEGOTIATION', 21)
        ssl_renegotiate_requires_xtn = getattr(
            ssl, 'SSL_RENEGOTIATE_REQUIRES_XTN', 2)

        # Create the socket here so we can do things like let the caller
        # override the NSS callbacks
        self.sock = ssl.SSLSocket(family=self.family)
        self.sock.set_ssl_option(ssl.SSL_SECURITY, True)
        self.sock.set_ssl_option(ssl.SSL_HANDSHAKE_AS_CLIENT, True)
        try:
            self.sock.set_ssl_version_range(self.tls_version_min, self.tls_version_max)
        except NSPRError:
            root_logger.error('Failed to set TLS range to %s, %s' % (self.tls_version_min, self.tls_version_max))
            raise
        self.sock.set_ssl_option(ssl_require_safe_negotiation, False)
        self.sock.set_ssl_option(ssl_enable_renegotiation, ssl_renegotiate_requires_xtn)
        # Provide a callback which notifies us when the SSL handshake is complete
        self.sock.set_handshake_callback(self.handshake_callback)

        # Provide a callback to verify the servers certificate
        self.sock.set_auth_certificate_callback(auth_certificate_callback,
                                                nss.get_default_certdb())
        self.sock.set_hostname(self.host)
Exemplo n.º 5
0
def stop_tracking(secdir=None, request_id=None, nickname=None, certfile=None):
    """
    Stop tracking the current request using either the request_id or nickname.

    Returns True or False
    """
    if request_id is None and nickname is None and certfile is None:
        raise RuntimeError('One of request_id, nickname and certfile is'
                           ' required.')
    if secdir is not None and certfile is not None:
        raise RuntimeError("Can't specify both secdir and certfile.")

    criteria = dict()
    if secdir:
        criteria['cert-database'] = secdir
    if request_id:
        criteria['nickname'] = request_id
    if nickname:
        criteria['cert-nickname'] = nickname
    if certfile:
        criteria['cert-file'] = certfile
    try:
        request = _get_request(criteria)
    except RuntimeError as e:
        root_logger.error('Failed to get request: %s' % e)
        raise
    if request:
        request.parent.obj_if.remove_request(request.path)
Exemplo n.º 6
0
    def __enable(self):
        if self.get_state("enabled") is None:
            self.backup_state("enabled", self.is_running())
            self.backup_state("named-regular-enabled",
                              self.named_regular.is_running())
        # We do not let the system start IPA components on its own,
        # Instead we reply on the IPA init script to start only enabled
        # components as found in our LDAP configuration tree
        try:
            self.ldap_enable('DNS', self.fqdn, self.dm_password, self.suffix)
        except errors.DuplicateEntry:
            # service already exists (forced DNS reinstall)
            # don't crash, just report error
            root_logger.error("DNS service already exists")

        # disable named, we need to run named-pkcs11 only
        if self.get_state("named-regular-running") is None:
            # first time store status
            self.backup_state("named-regular-running",
                              self.named_regular.is_running())
        try:
            self.named_regular.stop()
        except Exception as e:
            root_logger.debug("Unable to stop named (%s)", e)

        try:
            self.named_regular.mask()
        except Exception as e:
            root_logger.debug("Unable to mask named (%s)", e)
Exemplo n.º 7
0
def release_ipa_ccache(ccache_name):
    '''
    Stop using the current request's ccache.
      * Remove KRB5CCNAME from the enviroment
      * Remove the ccache file from the file system

    Note, we do not demand any of these elements exist, but if they
    do we'll remove them.
    '''

    if 'KRB5CCNAME' in os.environ:
        if ccache_name != os.environ['KRB5CCNAME']:
            root_logger.error('release_ipa_ccache: ccache_name (%s) != KRB5CCNAME environment variable (%s)',
                              ccache_name, os.environ['KRB5CCNAME'])
        del os.environ['KRB5CCNAME']
    else:
        root_logger.debug('release_ipa_ccache: KRB5CCNAME environment variable not set')

    scheme, name = krb5_parse_ccache(ccache_name)
    if scheme == 'FILE':
        if os.path.exists(name):
            try:
                os.unlink(name)
            except Exception as e:
                root_logger.error('unable to delete session ccache file "%s", %s', name, e)
    else:
        raise ValueError('ccache scheme "%s" unsupported (%s)', scheme, ccache_name)
Exemplo n.º 8
0
def retrieve_entries_without_sid(api):
    """
    Retrieve a list of entries without assigned SIDs.
    :returns: a list of entries or an empty list if an error occurs
    """
    # The filter corresponds to ipa_sidgen_task.c LDAP search filter
    filter = '(&(objectclass=ipaobject)(!(objectclass=mepmanagedentry))' \
             '(|(objectclass=posixaccount)(objectclass=posixgroup)' \
             '(objectclass=ipaidobject))(!(ipantsecurityidentifier=*)))'
    base_dn = api.env.basedn
    try:
        root_logger.debug(
            "Searching for objects with missing SID with "
            "filter=%s, base_dn=%s", filter, base_dn)
        entries, _truncated = api.Backend.ldap2.find_entries(
            filter=filter, base_dn=base_dn, attrs_list=[''])
        return entries
    except errors.NotFound:
        # All objects have SIDs assigned
        pass
    except (errors.DatabaseError, errors.NetworkError) as e:
        root_logger.error(
            "Could not retrieve a list of objects that need a SID "
            "identifier assigned: %s", e)

    return []
Exemplo n.º 9
0
def retrieve_potential_adtrust_agents(api):
    """
    Retrieve a sorted list of potential AD trust agents

    :param api: initialized API instance
    :returns: sorted list of FQDNs of masters which are not AD trust agents
    """
    try:
        # Search only masters which have support for domain levels
        # because only these masters will have SSSD recent enough
        # to support AD trust agents
        dl_enabled_masters = api.Command.server_find(
            ipamindomainlevel=DOMAIN_LEVEL_0, all=True)['result']
    except (errors.DatabaseError, errors.NetworkError) as e:
        root_logger.error(
            "Could not retrieve a list of existing IPA masters: %s", e)
        return

    try:
        # search for existing AD trust agents
        adtrust_agents = api.Command.server_find(
            servrole=u'AD trust agent', all=True)['result']
    except (errors.DatabaseError, errors.NetworkError) as e:
        root_logger.error("Could not retrieve a list of adtrust agents: %s", e)
        return

    dl_enabled_master_cns = {m['cn'][0] for m in dl_enabled_masters}
    adtrust_agents_cns = {m['cn'][0] for m in adtrust_agents}

    potential_agents_cns = dl_enabled_master_cns - adtrust_agents_cns

    # remove the local host from the potential agents since it will be set up
    # by adtrustinstance configuration code
    potential_agents_cns -= {api.env.host}
    return sorted(potential_agents_cns)
Exemplo n.º 10
0
def request_cert(
        nssdb, nickname, subject, principal, passwd_fname=None,
        dns=None):
    """
    Execute certmonger to request a server certificate.

    ``dns``
        A sequence of DNS names to appear in SAN request extension.
    """
    cm = _certmonger()
    ca_path = cm.obj_if.find_ca_by_nickname('IPA')
    if not ca_path:
        raise RuntimeError('IPA CA not found')
    request_parameters = dict(KEY_STORAGE='NSSDB', CERT_STORAGE='NSSDB',
                              CERT_LOCATION=nssdb, CERT_NICKNAME=nickname,
                              KEY_LOCATION=nssdb, KEY_NICKNAME=nickname,
                              SUBJECT=subject, PRINCIPAL=[principal],
                              CA=ca_path)
    if dns is not None and len(dns) > 0:
        request_parameters['DNS'] = dns
    if passwd_fname:
        request_parameters['KEY_PIN_FILE'] = passwd_fname
    result = cm.obj_if.add_request(request_parameters)
    try:
        if result[0]:
            request = _cm_dbus_object(cm.bus, cm, result[1], DBUS_CM_REQUEST_IF,
                                      DBUS_CM_IF, True)
        else:
            raise RuntimeError('add_request() returned False')
    except Exception as e:
        root_logger.error('Failed to create a new request: {error}'
                          .format(error=e))
        raise
    return request.obj_if.get_nickname()
Exemplo n.º 11
0
    def __enable(self):

        try:
            self.ldap_enable('DNSKeyExporter', self.fqdn, self.dm_password,
                             self.suffix)
        except errors.DuplicateEntry:
            root_logger.error("DNSKeyExporter service already exists")
Exemplo n.º 12
0
    def decorated(installer):
        success = False

        try:
            func(installer)
            success = True
        except KeyboardInterrupt:
            ds = installer._ds
            print("\nCleaning up...")
            if ds:
                print("Removing configuration for %s instance" % ds.serverid)
                ds.stop()
                if ds.serverid:
                    try:
                        dsinstance.remove_ds_instance(ds.serverid)
                    except ipautil.CalledProcessError:
                        root_logger.error("Failed to remove DS instance. You "
                                          "may need to remove instance data "
                                          "manually")
            raise ScriptError()
        finally:
            if not success and installer._installation_cleanup:
                # Do a cautious clean up as we don't know what failed and
                # what is the state of the environment
                try:
                    installer._fstore.restore_file(paths.HOSTS)
                except Exception:
                    pass
Exemplo n.º 13
0
    def __setup_resolv_conf(self):
        if not self.fstore.has_file(RESOLV_CONF):
            self.fstore.backup_file(RESOLV_CONF)

        resolv_txt = "search "+self.domain+"\n"

        for ip_address in self.ip_addresses:
            if ip_address.version == 4:
                resolv_txt += "nameserver 127.0.0.1\n"
                break

        for ip_address in self.ip_addresses:
            if ip_address.version == 6:
                resolv_txt += "nameserver ::1\n"
                break
        try:
            resolv_fd = open(RESOLV_CONF, 'w')
            resolv_fd.seek(0)
            resolv_fd.truncate(0)
            resolv_fd.write(resolv_txt)
            resolv_fd.close()
        except IOError as e:
            root_logger.error('Could not write to resolv.conf: %s', e)
        else:
            # python DNS might have global resolver cached in this variable
            # we have to re-initialize it because resolv.conf has changed
            dns.resolver.default_resolver = None
Exemplo n.º 14
0
    def decorated(*args, **kwargs):
        success = False

        try:
            try:
                func(*args, **kwargs)
            except BaseException:
                destroy_private_ccache()
                raise
            success = True
        except KeyboardInterrupt:
            global ds
            print "\nCleaning up..."
            if ds:
                print "Removing configuration for %s instance" % ds.serverid
                ds.stop()
                if ds.serverid:
                    try:
                        dsinstance.remove_ds_instance(ds.serverid)
                    except ipautil.CalledProcessError:
                        root_logger.error("Failed to remove DS instance. You "
                                          "may need to remove instance data "
                                          "manually")
            sys.exit(1)
        finally:
            global installation_cleanup
            if not success and installation_cleanup:
                # Do a cautious clean up as we don't know what failed and
                # what is the state of the environment
                try:
                    fstore.restore_file(paths.HOSTS)
                except:
                    pass
Exemplo n.º 15
0
    def execute(self, **options):

        root_logger.debug("Upgrading referential integrity plugin configuration")
        ldap = self.api.Backend.ldap2
        try:
            entry = ldap.get_entry(self.referint_dn)
        except errors.NotFound:
            root_logger.error("Referential integrity configuration not found")
            return False, []

        referint_membership_attrs = []

        root_logger.debug("Initial value: %s", repr(entry))

        # nsslapd-pluginArg0    -> referint-update-delay
        update_delay = entry.get('nsslapd-pluginArg0')
        if update_delay:
            root_logger.debug("add: referint-update-delay: %s", update_delay)
            entry['referint-update-delay'] = update_delay
            entry['nsslapd-pluginArg0'] = None
        else:
            root_logger.info("Plugin already uses new style, skipping")
            return False, []

        # nsslapd-pluginArg1    -> referint-logfile
        logfile = entry.get('nsslapd-pluginArg1')
        if logfile:
            root_logger.debug("add: referint-logfile: %s", logfile)
            entry['referint-logfile'] = logfile
            entry['nsslapd-pluginArg1'] = None

        # nsslapd-pluginArg2    -> referint-logchanges
        logchanges = entry.get('nsslapd-pluginArg2')
        if logchanges:
            root_logger.debug("add: referint-logchanges: %s", logchanges)
            entry['referint-logchanges'] = logchanges
            entry['nsslapd-pluginArg2'] = None

        # nsslapd-pluginArg3..N -> referint-membership-attr [3..N]
        for key in entry.keys():
            if key.lower().startswith('nsslapd-pluginarg'):
                arg_val = entry.single_value[key]
                if arg_val:
                    referint_membership_attrs.append(arg_val)
                entry[key] = None

        if referint_membership_attrs:
            # entry['referint-membership-attr'] is None, plugin doesn't allow
            # mixing old and new style
            entry['referint-membership-attr'] = referint_membership_attrs

        root_logger.debug("Final value: %s", repr(entry))
        try:
            ldap.update_entry(entry)
        except errors.EmptyModlist:
            root_logger.debug("No modifications required")
            return False, []

        return False, []
Exemplo n.º 16
0
def auth_certificate_callback(sock, check_sig, is_server, certdb):
    cert_is_valid = False

    cert = sock.get_peer_certificate()

    pin_args = sock.get_pkcs11_pin_arg()
    if pin_args is None:
        pin_args = ()

    # Define how the cert is being used based upon the is_server flag.  This may
    # seem backwards, but isn't. If we're a server we're trying to validate a
    # client cert. If we're a client we're trying to validate a server cert.
    if is_server:
        intended_usage = nss.certificateUsageSSLClient
    else:
        intended_usage = nss.certificateUsageSSLServer

    try:
        # If the cert fails validation it will raise an exception, the errno attribute
        # will be set to the error code matching the reason why the validation failed
        # and the strerror attribute will contain a string describing the reason.
        approved_usage = cert.verify_now(certdb, check_sig, intended_usage, *pin_args)
    except Exception as e:
        root_logger.error('cert validation failed for "%s" (%s)', cert.subject, e.strerror)  # pylint: disable=no-member
        cert_is_valid = False
        return cert_is_valid

    root_logger.debug(
        "approved_usage = %s intended_usage = %s",
        ", ".join(nss.cert_usage_flags(approved_usage)),
        ", ".join(nss.cert_usage_flags(intended_usage)),
    )

    # Is the intended usage a proper subset of the approved usage
    cert_is_valid = bool(approved_usage & intended_usage)

    # If this is a server, we're finished
    if is_server or not cert_is_valid:
        root_logger.debug('cert valid %s for "%s"', cert_is_valid, cert.subject)
        return cert_is_valid

    # Certificate is OK.  Since this is the client side of an SSL
    # connection, we need to verify that the name field in the cert
    # matches the desired hostname.  This is our defense against
    # man-in-the-middle attacks.

    hostname = sock.get_hostname()
    try:
        # If the cert fails validation it will raise an exception
        cert_is_valid = cert.verify_hostname(hostname)
    except Exception as e:
        root_logger.error(
            'failed verifying socket hostname "%s" matches cert subject "%s" (%s)', hostname, cert.subject, e.strerror
        )  # pylint: disable=no-member
        cert_is_valid = False
        return cert_is_valid

    root_logger.debug('cert valid %s for "%s"', cert_is_valid, cert.subject)
    return cert_is_valid
Exemplo n.º 17
0
def application(environ, start_response):
    try:
        index = get_plugin_index()
        status = "200 OK"
    except Exception, e:
        root_logger.error("plugin index generation failed: %s" % e)
        status = "200 OK"
        index = get_failed()
Exemplo n.º 18
0
    def parse(self):
        ldif.LDIFParser.parse(self)

        # check if there are any remaining modifications
        remaining_changes = set(self.modifications.keys()) - self.dn_updated
        for dn in remaining_changes:
            root_logger.error(
                "DN: %s does not exists or haven't been updated", dn)
Exemplo n.º 19
0
 def untrack_server_cert(self, nickname):
     """
     Tell certmonger to stop tracking the given certificate nickname.
     """
     try:
         certmonger.stop_tracking(self.secdir, nickname=nickname)
     except RuntimeError as e:
         root_logger.error("certmonger failed to stop tracking certificate: %s" % str(e))
Exemplo n.º 20
0
def remove_file(filename):
    """
    Remove a file and log any exceptions raised.
    """
    try:
        if os.path.lexists(filename):
            os.unlink(filename)
    except Exception as e:
        root_logger.error('Error removing %s: %s' % (filename, str(e)))
Exemplo n.º 21
0
    def execute(self, **options):
        ldap = self.api.Backend.ldap2

        old_style_plugin_search_filter = (
            "(&"
            "(objectclass=nsSlapdPlugin)"
            "(nsslapd-pluginId=NSUniqueAttr)"
            "(nsslapd-pluginPath=libattr-unique-plugin)"
            "(nsslapd-pluginarg0=*)"  # only entries with old configuration
            ")"
        )

        try:
            entries, truncated = ldap.find_entries(
                filter=old_style_plugin_search_filter,
                base_dn=self.plugins_dn,
            )
        except errors.NotFound:
            root_logger.debug("No uniqueness plugin entries with old style "
                              "configuration found")
            return False, []

        update_list = []
        new_attributes = [
            'uniqueness-subtree-entries-oc',
            'uniqueness-top-entry-oc',
            'uniqueness-attribute-name',
            'uniqueness-subtrees',
            'uniqueness-across-all-subtrees',
        ]

        for entry in entries:
            # test for mixed configuration
            if any(attr in entry for attr in new_attributes):
                root_logger.critical("Mixed old and new style configuration "
                                     "for plugin %s. Plugin will not work. "
                                     "Skipping plugin migration, please fix it "
                                     "manually",
                                     entry.dn)
                continue
            root_logger.debug("Configuration of plugin %s will be migrated "
                             "to new style", entry.dn)
            try:
                # detect which configuration was used
                arg0 = entry.get('nsslapd-pluginarg0')
                if '=' in arg0:
                    update = self.__objectclass_style(entry)
                else:
                    update = self.__subtree_style(entry)
            except ValueError as e:
                root_logger.error("Unable to migrate configuration of "
                                  "plugin %s (%s)",
                                  entry.dn, e)
            else:
                update_list.append(update)

        return False, update_list
Exemplo n.º 22
0
def rmtree(path):
    """
    Remove a directory structure and log any exceptions raised.
    """
    try:
        if os.path.exists(path):
            shutil.rmtree(path)
    except Exception as e:
        root_logger.error('Error removing %s: %s' % (path, str(e)))
Exemplo n.º 23
0
 def remove_httpd_service_ipa_conf(self):
     """Remove systemd config for httpd service of IPA"""
     try:
         os.unlink(paths.SYSTEMD_SYSTEM_HTTPD_IPA_CONF)
     except OSError as e:
         root_logger.error(
             'Error removing %s: %s',
             paths.SYSTEMD_SYSTEM_HTTPD_IPA_CONF, e
         )
Exemplo n.º 24
0
def create_replica_config(dirman_password, filename, options):
    top_dir = None
    try:
        top_dir, dir = expand_replica_info(filename, dirman_password)
    except Exception, e:
        root_logger.error("Failed to decrypt or open the replica file.")
        print "ERROR: Failed to decrypt or open the replica file."
        print "Verify you entered the correct Directory Manager password."
        sys.exit(1)
Exemplo n.º 25
0
    def store_session_cookie(self, cookie_header):
        '''
        Given the contents of a Set-Cookie header scan the header and
        extract each cookie contained within until the session cookie
        is located. Examine the session cookie if the domain and path
        are specified, if not update the cookie with those values from
        the request URL. Then write the session cookie into the key
        store for the principal. If the cookie header is None or the
        session cookie is not present in the header no action is
        taken.

        Context Dependencies:

        The per thread context is expected to contain:
            principal
                The current pricipal the HTTP request was issued for.
            request_url
                The URL of the HTTP request.

        '''

        if cookie_header is None:
            return

        principal = getattr(context, 'principal', None)
        request_url = getattr(context, 'request_url', None)
        root_logger.debug("received Set-Cookie (%s)'%s'", type(cookie_header),
                          cookie_header)

        if not isinstance(cookie_header, list):
            cookie_header = [cookie_header]

        # Search for the session cookie
        session_cookie = None
        try:
            for cookie in cookie_header:
                session_cookie = (
                    Cookie.get_named_cookie_from_string(
                        cookie, COOKIE_NAME, request_url,
                        timestamp=datetime.datetime.utcnow())
                    )
                if session_cookie is not None:
                    break
        except Exception as e:
            root_logger.error("unable to parse cookie header '%s': %s", cookie_header, e)
            return

        if session_cookie is None:
            return

        cookie_string = self._slice_session_cookie(session_cookie)
        root_logger.debug("storing cookie '%s' for principal %s", cookie_string, principal)
        try:
            update_persistent_client_session_data(principal, cookie_string)
        except Exception as e:
            # Not fatal, we just can't use the session cookie we were sent.
            pass
Exemplo n.º 26
0
 def __start(self):
     try:
         if self.get_state("running") is None:
             # first time store status
             self.backup_state("running", self.is_running())
         self.restart()
     except Exception as e:
         root_logger.error("Named service failed to start (%s)", e)
         print("named service failed to start")
Exemplo n.º 27
0
    def execute(self, **options):
        ldap = self.api.Backend.ldap2

        base_dn = DN(self.api.env.container_ranges, self.api.env.basedn)
        search_filter = ("(&(objectClass=ipaTrustedADDomainRange)"
                         "(ipaRangeType=ipa-ad-trust-posix)"
                         "(!(ipaBaseRID=0)))")
        root_logger.debug(
            "update_idrange_baserid: search for ipa-ad-trust-posix ID ranges "
            "with ipaBaseRID != 0"
        )

        try:
            (entries, truncated) = ldap.find_entries(
                search_filter, ['ipabaserid'], base_dn,
                paged_search=True, time_limit=0, size_limit=0)

        except errors.NotFound:
            root_logger.debug("update_idrange_baserid: no AD domain "
                              "range with posix attributes found")
            return False, []

        except errors.ExecutionError as e:
            root_logger.error("update_idrange_baserid: cannot retrieve "
                              "list of affected ranges: %s", e)
            return False, []

        root_logger.debug("update_idrange_baserid: found %d "
                          "idranges possible to update",
                          len(entries))

        error = False

        # Set the range type
        for entry in entries:
            entry['ipabaserid'] = 0
            try:
                root_logger.debug("Updating existing idrange: %s" % (entry.dn))
                ldap.update_entry(entry)
                root_logger.info("Done")
            except (errors.EmptyModlist, errors.NotFound):
                pass
            except errors.ExecutionError as e:
                root_logger.debug("update_idrange_type: cannot "
                                  "update idrange: %s", e)
                error = True

        if error:
            root_logger.error("update_idrange_baserid: error(s) "
                              "detected during idrange baserid update")
        else:
            # All affected entries updated, exit the loop
            root_logger.debug("update_idrange_baserid: all affected "
                              "idranges updated")

        return False, []
Exemplo n.º 28
0
 def reload_systemwide_ca_store(self):
     try:
         ipautil.run([paths.UPDATE_CA_TRUST])
     except CalledProcessError as e:
         root_logger.error(
             "Could not update systemwide CA trust database: %s", e)
         return False
     else:
         root_logger.info("Systemwide CA database updated.")
         return True
Exemplo n.º 29
0
 def issue_ipa_ca_signed_pkinit_certs(self):
     try:
         self._call_certmonger()
         self._install_pkinit_ca_bundle()
         self.pkinit_enable()
     except RuntimeError as e:
         root_logger.error("PKINIT certificate request failed: %s", e)
         root_logger.error("Failed to configure PKINIT")
         self.stop_tracking_certs()
         self.issue_selfsigned_pkinit_certs()
Exemplo n.º 30
0
 def issue_ipa_ca_signed_pkinit_certs(self):
     try:
         self._call_certmonger()
         self._install_pkinit_ca_bundle()
         self.pkinit_enable()
     except RuntimeError as e:
         root_logger.error("PKINIT certificate request failed: %s", e)
         root_logger.error("Failed to configure PKINIT")
         self.stop_tracking_certs()
         self.issue_selfsigned_pkinit_certs()
Exemplo n.º 31
0
    def insert_ca_certs_into_systemwide_ca_store(self, ca_certs):
        new_cacert_path = paths.SYSTEMWIDE_IPA_CA_CRT

        if os.path.exists(new_cacert_path):
            try:
                os.remove(new_cacert_path)
            except OSError, e:
                root_logger.error(
                    "Could not remove %s: %s", new_cacert_path, e)
                return False
Exemplo n.º 32
0
def request_cert(
        certpath, nickname, subject, principal, passwd_fname=None,
        dns=None, ca='IPA', profile=None,
        pre_command=None, post_command=None, storage='NSSDB'):
    """
    Execute certmonger to request a server certificate.

    ``dns``
        A sequence of DNS names to appear in SAN request extension.
    """
    if storage == 'FILE':
        certfile, keyfile = certpath
    else:
        certfile = certpath
        keyfile = certpath

    cm = _certmonger()
    ca_path = cm.obj_if.find_ca_by_nickname(ca)
    if not ca_path:
        raise RuntimeError('{} CA not found'.format(ca))
    request_parameters = dict(KEY_STORAGE=storage, CERT_STORAGE=storage,
                              CERT_LOCATION=certfile, CERT_NICKNAME=nickname,
                              KEY_LOCATION=keyfile, KEY_NICKNAME=nickname,
                              SUBJECT=subject, CA=ca_path)
    if principal:
        request_parameters['PRINCIPAL'] = [principal]
    if dns is not None and len(dns) > 0:
        request_parameters['DNS'] = dns
    if passwd_fname:
        request_parameters['KEY_PIN_FILE'] = passwd_fname
    if profile:
        request_parameters['ca-profile'] = profile

    certmonger_cmd_template = paths.CERTMONGER_COMMAND_TEMPLATE
    if pre_command:
        if not os.path.isabs(pre_command):
            pre_command = certmonger_cmd_template % (pre_command)
        request_parameters['cert-presave-command'] = pre_command
    if post_command:
        if not os.path.isabs(post_command):
            post_command = certmonger_cmd_template % (post_command)
        request_parameters['cert-postsave-command'] = post_command

    result = cm.obj_if.add_request(request_parameters)
    try:
        if result[0]:
            request = _cm_dbus_object(cm.bus, cm, result[1], DBUS_CM_REQUEST_IF,
                                      DBUS_CM_IF, True)
        else:
            raise RuntimeError('add_request() returned False')
    except Exception as e:
        root_logger.error('Failed to create a new request: {error}'
                          .format(error=e))
        raise
    return request.obj_if.get_nickname()
Exemplo n.º 33
0
    def setup_pkinit(self):
        if self.pkcs12_info:
            certs.install_pem_from_p12(self.pkcs12_info[0],
                                       self.pkcs12_info[1],
                                       paths.KDC_CERT)
            certs.install_key_from_p12(self.pkcs12_info[0],
                                       self.pkcs12_info[1],
                                       paths.KDC_KEY)
        else:
            subject = str(DN(('cn', self.fqdn), self.subject_base))
            krbtgt = "krbtgt/" + self.realm + "@" + self.realm
            certpath = (paths.KDC_CERT, paths.KDC_KEY)

            try:
                prev_helper = None
                if self.master_fqdn is None:
                    ca_args = [
                        paths.CERTMONGER_DOGTAG_SUBMIT,
                        '--ee-url', 'https://%s:8443/ca/ee/ca' % self.fqdn,
                        '--certfile', paths.RA_AGENT_PEM,
                        '--keyfile', paths.RA_AGENT_KEY,
                        '--cafile', paths.IPA_CA_CRT,
                        '--agent-submit'
                    ]
                    helper = " ".join(ca_args)
                    prev_helper = certmonger.modify_ca_helper('IPA', helper)
                else:
                    self._wait_for_replica_kdc_entry()

                certmonger.request_and_wait_for_cert(
                    certpath,
                    subject,
                    krbtgt,
                    dns=self.fqdn,
                    storage='FILE',
                    profile='KDCs_PKINIT_Certs')
            except dbus.DBusException as e:
                # if the certificate is already tracked, ignore the error
                name = e.get_dbus_name()
                if name != 'org.fedorahosted.certmonger.duplicate':
                    root_logger.error("Failed to initiate the request: %s", e)
                return
            finally:
                if prev_helper is not None:
                    certmonger.modify_ca_helper('IPA', prev_helper)

        # Finally copy the cacert in the krb directory so we don't
        # have any selinux issues with the file context
        shutil.copyfile(paths.IPA_CA_CRT, paths.CACERT_PEM)

        try:
            self.restart()
        except Exception:
            root_logger.critical("krb5kdc service failed to restart")
            raise
Exemplo n.º 34
0
def get_base_dn(ldap_uri):
    """
    Retrieve LDAP server base DN.
    """
    try:
        conn = IPAdmin(ldap_uri=ldap_uri)
        conn.do_simple_bind(DN(), '')
        base_dn = get_ipa_basedn(conn)
    except Exception, e:
        root_logger.error('migration context search failed: %s' % e)
        return ''
Exemplo n.º 35
0
    def find_subject_base(self):
        """
        Try to find the current value of certificate subject base.
        1) Look in sysupgrade first
        2) If no value is found there, look in DS (start DS if necessary)
        3) If all fails, log loudly and return None

        Note that this method can only be executed AFTER the ipa server
        is configured, the api is initialized elsewhere and
        that a ticket already have been acquired.
        """
        root_logger.debug(
            'Trying to find certificate subject base in sysupgrade')
        subject_base = sysupgrade.get_upgrade_state('certmap.conf',
                                                    'subject_base')

        if subject_base:
            root_logger.debug(
                'Found certificate subject base in sysupgrade: %s',
                subject_base)
            return subject_base

        root_logger.debug(
            'Unable to find certificate subject base in sysupgrade')
        root_logger.debug('Trying to find certificate subject base in DS')

        ds_is_running = is_ds_running()
        if not ds_is_running:
            try:
                self.start()
                ds_is_running = True
            except ipautil.CalledProcessError as e:
                root_logger.error(
                    'Cannot start DS to find certificate '
                    'subject base: %s', e)

        if ds_is_running:
            try:
                ret = api.Command['config_show']()
                subject_base = str(
                    ret['result']['ipacertificatesubjectbase'][0])
                root_logger.debug('Found certificate subject base in DS: %s',
                                  subject_base)
            except errors.PublicError as e:
                root_logger.error(
                    'Cannot connect to DS to find certificate '
                    'subject base: %s', e)

        if subject_base:
            return subject_base

        root_logger.debug('Unable to find certificate subject base in '
                          'certmap.conf')
        return None
Exemplo n.º 36
0
def add_request_value(request_id, directive, value):
    """
    Add a new directive to a certmonger request file.
    """
    try:
        request = _get_request({'nickname': request_id})
    except RuntimeError as e:
        root_logger.error('Failed to get request: %s' % e)
        raise
    if request:
        request.obj_if.modify({directive: value})
Exemplo n.º 37
0
 def remove_httpd_service_ipa_conf(self):
     """Remove systemd config for httpd service of IPA"""
     try:
         os.unlink(paths.SYSTEMD_SYSTEM_HTTPD_IPA_CONF)
     except OSError as e:
         if e.errno == errno.ENOENT:
             root_logger.debug(
                 'Trying to remove %s but file does not exist',
                 paths.SYSTEMD_SYSTEM_HTTPD_IPA_CONF)
         else:
             root_logger.error('Error removing %s: %s',
                               paths.SYSTEMD_SYSTEM_HTTPD_IPA_CONF, e)
Exemplo n.º 38
0
def application(environ, start_response):
    try:
        index = get_plugin_index()
        status = '200 OK'
    except Exception as e:
        root_logger.error('plugin index generation failed: %s' % e)
        status = '200 OK'
        index = get_failed()
    headers = [('Content-type', 'application/javascript'),
               ('Content-Length', str(len(index)))]
    start_response(status, headers)
    return [index]
Exemplo n.º 39
0
 def _stop_private_conn(self):
     if self._proc:
         retcode = self._proc.poll()
         if retcode is not None:
             return
         self._proc.terminate()
         for _t in range(0, self.timeout, 5):
             retcode = self._proc.poll()
             if retcode is not None:
                 return
             time.sleep(5)
         root_logger.error("Failed to stop certmonger.")
Exemplo n.º 40
0
def bind(ldap_uri, base_dn, username, password):
    if not base_dn:
        root_logger.error('migration unable to get base dn')
        raise IOError(errno.EIO, 'Cannot get Base DN')
    bind_dn = DN(('uid', username), ('cn', 'users'), ('cn', 'accounts'),
                 base_dn)
    try:
        conn = IPAdmin(ldap_uri=ldap_uri)
        conn.do_simple_bind(bind_dn, password)
    except (errors.ACIError, errors.DatabaseError, errors.NotFound), e:
        root_logger.error('migration invalid credentials for %s: %s' %
                          (bind_dn, e))
        raise IOError(errno.EPERM,
                      'Invalid LDAP credentials for user %s' % username)
Exemplo n.º 41
0
 def __upgrade(self):
     try:
         ld = ldapupdate.LDAPUpdate(dm_password='', ldapi=True)
         if len(self.files) == 0:
             self.files = ld.get_all_files(ldapupdate.UPDATES_DIR)
         self.modified = (ld.update(self.files) or self.modified)
     except ldapupdate.BadSyntax as e:
         root_logger.error('Bad syntax in upgrade %s', e)
         raise
     except Exception as e:
         # Bad things happened, return gracefully
         root_logger.error('Upgrade failed with %s', e)
         root_logger.debug('%s', traceback.format_exc())
         raise RuntimeError(e)
Exemplo n.º 42
0
    def restore_hostname(self, fstore, statestore):
        old_hostname = statestore.get_state('network', 'hostname')

        if old_hostname is not None:
            try:
                self.set_hostname(old_hostname)
            except ipautil.CalledProcessError as e:
                root_logger.debug(traceback.format_exc())
                root_logger.error(
                    "Failed to restore this machine hostname to %s (%s).",
                    old_hostname, e)

        filepath = paths.ETC_HOSTNAME
        if fstore.has_file(filepath):
            fstore.restore_file(filepath)
Exemplo n.º 43
0
    def uninstall(self):
        if self.is_configured():
            self.print_msg("Unconfiguring directory server")

        enabled = self.restore_state("enabled")

        # Just eat this state if it exists
        self.restore_state("running")

        try:
            self.fstore.restore_file(paths.LIMITS_CONF)
            self.fstore.restore_file(paths.SYSCONFIG_DIRSRV)
        except ValueError as error:
            root_logger.debug(error)

        # disabled during IPA installation
        if enabled:
            self.enable()

        serverid = self.restore_state("serverid")
        if serverid is not None:
            self.stop_tracking_certificates(serverid)
            root_logger.debug("Removing DS instance %s" % serverid)
            try:
                remove_ds_instance(serverid)
                installutils.remove_keytab(paths.DS_KEYTAB)
                installutils.remove_ccache(run_as=DS_USER)
            except ipautil.CalledProcessError:
                root_logger.error("Failed to remove DS instance. You may "
                                  "need to remove instance data manually")

        # Just eat this state
        self.restore_state("user_exists")

        # Make sure some upgrade-related state is removed. This could cause
        # re-installation problems.
        self.restore_state('nsslapd-port')
        self.restore_state('nsslapd-security')
        self.restore_state('nsslapd-ldapiautobind')

        # If any dirsrv instances remain after we've removed ours then
        # (re)start them.
        for ds_instance in get_ds_instances():
            try:
                services.knownservices.dirsrv.restart(ds_instance, wait=False)
            except Exception as e:
                root_logger.error('Unable to restart DS instance %s: %s',
                                  ds_instance, e)
Exemplo n.º 44
0
    def store_session_cookie(self, cookie_header):
        '''
        Given the contents of a Set-Cookie header scan the header and
        extract each cookie contained within until the session cookie
        is located. Examine the session cookie if the domain and path
        are specified, if not update the cookie with those values from
        the request URL. Then write the session cookie into the key
        store for the principal. If the cookie header is None or the
        session cookie is not present in the header no action is
        taken.

        Context Dependencies:

        The per thread context is expected to contain:
            principal
                The current pricipal the HTTP request was issued for.
            request_url
                The URL of the HTTP request.

        '''

        if cookie_header is None:
            return

        principal = getattr(context, 'principal', None)
        request_url = getattr(context, 'request_url', None)
        root_logger.debug("received Set-Cookie '%s'", cookie_header)

        # Search for the session cookie
        try:
            session_cookie = Cookie.get_named_cookie_from_string(
                cookie_header, COOKIE_NAME, request_url)
        except Exception as e:
            root_logger.error("unable to parse cookie header '%s': %s",
                              cookie_header, e)
            return

        if session_cookie is None:
            return

        cookie_string = str(session_cookie)
        root_logger.debug("storing cookie '%s' for principal %s",
                          cookie_string, principal)
        try:
            update_persistent_client_session_data(principal, cookie_string)
        except Exception as e:
            # Not fatal, we just can't use the session cookie we were sent.
            pass
Exemplo n.º 45
0
def host_port_open(host,
                   port,
                   socket_type=socket.SOCK_STREAM,
                   socket_timeout=None,
                   log_errors=False):
    """
    host: either hostname or IP address;
          if hostname is provided, port MUST be open on ALL resolved IPs

    returns True is port is open, False otherwise
    """
    port_open = True

    # port has to be open on ALL resolved IPs
    for res in socket.getaddrinfo(host, port, socket.AF_UNSPEC, socket_type):
        af, socktype, proto, _canonname, sa = res
        s = None
        try:
            s = socket.socket(af, socktype, proto)

            if socket_timeout is not None:
                s.settimeout(socket_timeout)

            s.connect(sa)

            if socket_type == socket.SOCK_DGRAM:
                s.send('')
                s.recv(512)
        except socket.error:
            port_open = False

            if log_errors:
                msg = ('Failed to connect to port %(port)d %(proto)s on '
                       '%(addr)s' % dict(port=port,
                                         proto=PROTOCOL_NAMES[socket_type],
                                         addr=sa[0]))

                # Do not log udp failures as errors (to be consistent with
                # the rest of the code that checks for open ports)
                if socket_type == socket.SOCK_DGRAM:
                    root_logger.warning(msg)
                else:
                    root_logger.error(msg)
        finally:
            if s is not None:
                s.close()

    return port_open
Exemplo n.º 46
0
    def remove_httpd_service_ipa_conf(self):
        """Remove systemd config for httpd service of IPA"""
        try:
            os.unlink(paths.SYSTEMD_SYSTEM_HTTPD_IPA_CONF)
        except OSError as e:
            if e.errno == errno.ENOENT:
                root_logger.debug(
                    'Trying to remove %s but file does not exist',
                    paths.SYSTEMD_SYSTEM_HTTPD_IPA_CONF)
            else:
                root_logger.error('Error removing %s: %s',
                                  paths.SYSTEMD_SYSTEM_HTTPD_IPA_CONF, e)
            return

        ipautil.run([paths.SYSTEMCTL, "--system", "daemon-reload"],
                    raiseonerr=False)
Exemplo n.º 47
0
    def remove_ca_certs_from_systemwide_ca_store(self):
        result = True
        update = False

        # Remove CA cert from systemwide store
        for new_cacert_path in (paths.IPA_P11_KIT,
                                paths.SYSTEMWIDE_IPA_CA_CRT):
            if not os.path.exists(new_cacert_path):
                continue
            try:
                os.remove(new_cacert_path)
            except OSError, e:
                root_logger.error("Could not remove %s: %s", new_cacert_path,
                                  e)
                result = False
            else:
                update = True
Exemplo n.º 48
0
    def _call_certmonger(self, certmonger_ca='IPA'):
        subject = str(DN(('cn', self.fqdn), self.subject_base))
        krbtgt = "krbtgt/" + self.realm + "@" + self.realm
        certpath = (paths.KDC_CERT, paths.KDC_KEY)

        try:
            prev_helper = None
            # on the first CA-ful master without '--no-pkinit', we issue the
            # certificate by contacting Dogtag directly
            use_dogtag_submit = all([
                self.master_fqdn is None, self.pkcs12_info is None,
                self.config_pkinit
            ])

            if use_dogtag_submit:
                ca_args = [
                    paths.CERTMONGER_DOGTAG_SUBMIT, '--ee-url',
                    'https://%s:8443/ca/ee/ca' % self.fqdn, '--certfile',
                    paths.RA_AGENT_PEM, '--keyfile', paths.RA_AGENT_KEY,
                    '--cafile', paths.IPA_CA_CRT, '--agent-submit'
                ]
                helper = " ".join(ca_args)
                prev_helper = certmonger.modify_ca_helper(
                    certmonger_ca, helper)

            certmonger.request_and_wait_for_cert(certpath,
                                                 subject,
                                                 krbtgt,
                                                 ca=certmonger_ca,
                                                 dns=self.fqdn,
                                                 storage='FILE',
                                                 profile=KDC_PROFILE,
                                                 post_command='renew_kdc_cert',
                                                 perms=(0o644, 0o600))
        except dbus.DBusException as e:
            # if the certificate is already tracked, ignore the error
            name = e.get_dbus_name()
            if name != 'org.fedorahosted.certmonger.duplicate':
                root_logger.error("Failed to initiate the request: %s", e)
            return
        finally:
            if prev_helper is not None:
                certmonger.modify_ca_helper(certmonger_ca, prev_helper)
Exemplo n.º 49
0
def get_request_value(request_id, directive):
    """
    Get property of request.
    """
    try:
        request = _get_request(dict(nickname=request_id))
    except RuntimeError as e:
        root_logger.error('Failed to get request: %s' % e)
        raise
    if request:
        if directive == 'ca-name':
            ca_path = request.obj_if.get_ca()
            ca = _cm_dbus_object(request.bus, request, ca_path, DBUS_CM_CA_IF,
                                 DBUS_CM_IF)
            return ca.obj_if.get_nickname()
        else:
            return request.prop_if.Get(DBUS_CM_REQUEST_IF, directive)
    else:
        return None
Exemplo n.º 50
0
def get_request_id(criteria):
    """
    If you don't know the certmonger request_id then try to find it by looking
    through all the requests.

    criteria is a tuple of key/value to search for. The more specific
    the better. An error is raised if multiple request_ids are returned for
    the same criteria.

    None is returned if none of the criteria match.
    """
    try:
        request = _get_request(criteria)
    except RuntimeError as e:
        root_logger.error('Failed to get request: %s' % e)
        raise
    if request:
        return request.prop_if.Get(DBUS_CM_REQUEST_IF, 'nickname')
    else:
        return None
Exemplo n.º 51
0
    def track_server_cert(self, nickname, principal, password_file=None, command=None):
        """
        Tell certmonger to track the given certificate nickname.

        If command is not a full path then it is prefixed with
        /usr/lib[64]/ipa/certmonger.
        """
        if command is not None and not os.path.isabs(command):
            command = paths.CERTMONGER_COMMAND_TEMPLATE % (command)
        try:
            request_id = certmonger.start_tracking(nickname, self.secdir, password_file, command)
        except RuntimeError as e:
            root_logger.error("certmonger failed starting to track certificate: %s" % str(e))
            return

        cert = self.get_cert_from_db(nickname)
        cert_obj = x509.load_certificate(cert)
        subject = str(DN(cert_obj.subject))
        certmonger.add_principal(request_id, principal)
        certmonger.add_subject(request_id, subject)
Exemplo n.º 52
0
def read_reverse_zone(default, ip_address, allow_zone_overlap=False):
    while True:
        zone = ipautil.user_input("Please specify the reverse zone name",
                                  default=default)
        if not zone:
            return None
        if not verify_reverse_zone(zone, ip_address):
            root_logger.error("Invalid reverse zone %s for IP address %s" %
                              (zone, ip_address))
            continue
        if not allow_zone_overlap:
            try:
                dnsutil.check_zone_overlap(zone, raise_on_error=False)
            except ValueError as e:
                root_logger.error("Reverse zone %s will not be used: %s" %
                                  (zone, e))
                continue
        break

    return normalize_zone(zone)
Exemplo n.º 53
0
def request_cert(nssdb,
                 nickname,
                 subject,
                 principal,
                 passwd_fname=None,
                 dns=None):
    """
    Execute certmonger to request a server certificate.

    ``dns``
        A sequence of DNS names to appear in SAN request extension.
    """
    cm = _certmonger()
    ca_path = cm.obj_if.find_ca_by_nickname('IPA')
    if not ca_path:
        raise RuntimeError('IPA CA not found')
    request_parameters = dict(KEY_STORAGE='NSSDB',
                              CERT_STORAGE='NSSDB',
                              CERT_LOCATION=nssdb,
                              CERT_NICKNAME=nickname,
                              KEY_LOCATION=nssdb,
                              KEY_NICKNAME=nickname,
                              SUBJECT=subject,
                              PRINCIPAL=[principal],
                              CA=ca_path)
    if dns is not None and len(dns) > 0:
        request_parameters['DNS'] = dns
    if passwd_fname:
        request_parameters['KEY_PIN_FILE'] = passwd_fname
    result = cm.obj_if.add_request(request_parameters)
    try:
        if result[0]:
            request = _cm_dbus_object(cm.bus, cm, result[1],
                                      DBUS_CM_REQUEST_IF, DBUS_CM_IF, True)
        else:
            raise RuntimeError('add_request() returned False')
    except Exception as e:
        root_logger.error(
            'Failed to create a new request: {error}'.format(error=e))
        raise
    return request.obj_if.get_nickname()
Exemplo n.º 54
0
def remove_ds_instance(serverid, force=False):
    """A wrapper around the 'remove-ds.pl' script used by
    389ds to remove a single directory server instance. In case of error
    additional call with the '-f' flag is performed (forced removal). If this
    also fails, then an exception is raised.
    """
    instance_name = ''.join([DS_INSTANCE_PREFIX, serverid])
    args = [paths.REMOVE_DS_PL, '-i', instance_name]
    if force:
        args.append('-f')
        root_logger.debug("Forcing instance removal")

    try:
        ipautil.run(args)
    except ipautil.CalledProcessError:
        if force:
            root_logger.error("Instance removal failed.")
            raise
        root_logger.debug("'%s' failed. "
                          "Attempting to force removal" % paths.REMOVE_DS_PL)
        remove_ds_instance(serverid, force=True)
Exemplo n.º 55
0
    def __enable(self):
        try:
            self.ldap_enable('DNSSEC', self.fqdn, None, self.suffix,
                             self.extra_config)
        except errors.DuplicateEntry:
            root_logger.error("DNSSEC service already exists")

        # add the KEYMASTER identifier into ipaConfigString
        # this is needed for the re-enabled DNSSEC master
        dn = DN(('cn', 'DNSSEC'), ('cn', self.fqdn), api.env.container_masters,
                api.env.basedn)
        try:
            entry = api.Backend.ldap2.get_entry(dn, ['ipaConfigString'])
        except errors.NotFound as e:
            root_logger.error(
                "DNSSEC service entry not found in the LDAP (%s)", e)
        else:
            config = entry.setdefault('ipaConfigString', [])
            if KEYMASTER not in config:
                config.append(KEYMASTER)
                api.Backend.ldap2.update_entry(entry)
Exemplo n.º 56
0
def stop_tracking(secdir, request_id=None, nickname=None):
    """
    Stop tracking the current request using either the request_id or nickname.

    Returns True or False
    """
    if request_id is None and nickname is None:
        raise RuntimeError('Both request_id and nickname are missing.')

    criteria = {'cert-database': secdir}
    if request_id:
        criteria['nickname'] = request_id
    if nickname:
        criteria['cert-nickname'] = nickname
    try:
        request = _get_request(criteria)
    except RuntimeError as e:
        root_logger.error('Failed to get request: %s' % e)
        raise
    if request:
        request.parent.obj_if.remove_request(request.path)
Exemplo n.º 57
0
    def modifications_from_ldif(self, ldif_file):
        """
        Parse ldif file. Default operation is add, only changetypes "add"
        and "modify" are supported.
        :param ldif_file: an opened file for read
        :raises: ValueError
        """
        parser = ldif.LDIFRecordList(ldif_file)
        parser.parse()

        last_dn = None
        for dn, entry in parser.all_records:
            if dn is None:
                # ldif parser return None, if records belong to previous DN
                dn = last_dn
            else:
                last_dn = dn

            if "replace" in entry:
                for attr in entry["replace"]:
                    try:
                        self.replace_value(dn, attr, entry[attr])
                    except KeyError:
                        raise ValueError("replace: {dn}, {attr}: values are "
                                         "missing".format(dn=dn, attr=attr))
            elif "delete" in entry:
                for attr in entry["delete"]:
                    self.remove_value(dn, attr, entry.get(attr, None))
            elif "add" in entry:
                for attr in entry["add"]:
                    try:
                        self.replace_value(dn, attr, entry[attr])
                    except KeyError:
                        raise ValueError("add: {dn}, {attr}: values are "
                                         "missing".format(dn=dn, attr=attr))
            else:
                root_logger.error(
                    "Ignoring entry: %s : only modifications "
                    "are allowed (missing \"changetype: "
                    "modify\")", dn)
Exemplo n.º 58
0
    def untrack_file(self, path):
        """Remove file at path @path from list of backed up files.

        Does not remove any files from the filesystem.

        Returns #True if the file was untracked, #False if there
        was no backup file to restore
        """

        root_logger.debug("Untracking system configuration file '%s'", path)

        if not os.path.isabs(path):
            raise ValueError("Absolute path required")

        filename = None

        for (key, value) in self.files.items():
            _mode, _uid, _gid, filepath = value.split(',', 3)
            if (filepath == path):
                filename = key
                break

        if not filename:
            raise ValueError("No such file name in the index")

        backup_path = os.path.join(self._path, filename)
        if not os.path.exists(backup_path):
            root_logger.debug("  -> Not restoring - '%s' doesn't exist",
                              backup_path)
            return False

        try:
            os.unlink(backup_path)
        except Exception as e:
            root_logger.error('Error removing %s: %s' % (backup_path, str(e)))

        del self.files[filename]
        self.save()

        return True
Exemplo n.º 59
0
def start_tracking(nickname, secdir, password_file=None, command=None):
    """
    Tell certmonger to track the given certificate nickname in NSS
    database in secdir protected by optional password file password_file.

    command is an optional parameter which specifies a command for
    certmonger to run when it renews a certificate. This command must
    reside in /usr/lib/ipa/certmonger to work with SELinux.

    Returns certificate nickname.
    """
    cm = _certmonger()
    params = {'TRACK': True}
    params['cert-nickname'] = nickname
    params['cert-database'] = os.path.abspath(secdir)
    params['cert-storage'] = 'NSSDB'
    params['key-nickname'] = nickname
    params['key-database'] = os.path.abspath(secdir)
    params['key-storage'] = 'NSSDB'
    ca_path = cm.obj_if.find_ca_by_nickname('IPA')
    if not ca_path:
        raise RuntimeError('IPA CA not found')
    params['ca'] = ca_path
    if command:
        params['cert-postsave-command'] = command
    if password_file:
        params['KEY_PIN_FILE'] = os.path.abspath(password_file)
    result = cm.obj_if.add_request(params)
    try:
        if result[0]:
            request = _cm_dbus_object(cm.bus, cm, result[1], DBUS_CM_REQUEST_IF,
                                      DBUS_CM_IF, True)
        else:
            raise RuntimeError('add_request() returned False')
    except Exception as e:
        root_logger.error('Failed to add new request: {error}'
                          .format(error=e))
        raise
    return request.prop_if.Get(DBUS_CM_REQUEST_IF, 'nickname')