Esempio n. 1
0
 def validate_hostname(self):
     if getdomainname() == "":
         # Should we return a message?
         raise AssertionError("Host does not have a domain name.")
     DirSrvTools.searchHostsFile(getfqdn())
Esempio n. 2
0
    def create_realm(self, ignore=False):
        self.validate_hostname()
        exists = self.check_realm()
        if exists is True and ignore is False:
            raise AssertionError("Realm already exists!")
        elif exists is True and ignore is True:
            # Realm exists, continue
            return
        # Raise a scary warning about eating your krb settings
        if self.warnings:
            print("This will alter / erase your krb5 and kdc settings.")
            input("Ctrl-C to exit, or press ENTER to continue.")
        print("Kerberos primary password: %s" % self.krb_primary_password)

        # If we don't have the directories for this, create them.
        # but if we create them there is no guarantee this will work ...
        if not os.path.exists(os.path.dirname(self.krb5confrealm)):
            os.makedirs(os.path.dirname(self.krb5confrealm))
        # Put the includedir statement into /etc/krb5.conf
        include = True
        with open(self.krb5conf, 'r') as kfile:
            for line in kfile.readlines():
                if 'includedir %s/' % os.path.dirname(self.krb5confrealm) \
                   in line:
                    include = False
        if include is True:
            with open(self.krb5conf, 'a') as kfile:
                kfile.write('\nincludedir %s/\n' %
                            os.path.dirname(self.krb5confrealm))

        # Write to  /etc/krb5.conf.d/example.com
        with open(self.krb5confrealm, 'w') as cfile:
            domainname = getdomainname()
            fqdn = getfqdn()
            realm = self.realm
            lrealm = self.realm.lower()
            cfile.write("""
[libdefaults]
 default_realm = {REALM}

[realms]
{REALM} = {{
 kdc = {HOST}
 admin_server = {HOST}
}}

[domain_realm]
.{LREALM} = {REALM}
{LREALM} = {REALM}
.{DOMAIN} = {REALM}
{DOMAIN} = {REALM}
""".format(HOST=fqdn, REALM=realm, LREALM=lrealm, DOMAIN=domainname))

        # Do we need to edit /var/kerberos/krb5kdc/kdc.conf ?
        with open(self.kdcconf, 'w') as kfile:
            kfile.write("""
[kdcdefaults]
 kdc_ports = 88
 kdc_tcp_ports = 88

[realms]
 {REALM} = {{
  acl_file = {KADM5ACL}
  dict_file = /usr/share/dict/words
  admin_keytab = {KADM5KEYTAB}
  # Just use strong enctypes
  # supported_enctypes = aes256-cts:normal aes128-cts:normal
 }}

""".format(REALM=self.realm,
            PREFIX=self.krb_prefix,
            KADM5ACL=self.kadm5acl,
            KADM5KEYTAB=self.kadm5keytab))
        # Invoke kdb5_util
        # Can this use -P
        p = Popen([
            self.kdb5_util, 'create', '-r', self.realm, '-s', '-P',
            self.krb_primary_password
        ],
                  env=self.krb_env)
        assert (p.wait() == 0)
        # Start the kdc
        p = Popen([self.krb5kdc, '-P', self.kdcpid, '-r', self.realm],
                  env=self.krb_env)
        assert (p.wait() == 0)
        # ???
        # PROFIT
        return
Esempio n. 3
0
    def createInstance(args, verbose=0):
        """Create a new instance of directory server and return a connection
        to it.

        This function:
        - guesses the hostname where to create the DS, using
        localhost by default;
        - figures out if the given hostname is the local host or not.

        @param args -  a dict with the following values {
            # new instance compulsory values
            'newinstance': 'rpolli',
            'newsuffix': 'dc=example,dc=com',
            'newhost': 'localhost.localdomain',
            'newport': 22389,
            'newrootpw': 'password',

            # optionally register instance on an admin tree
            'have_admin': True,

            # optionally directory where to store instance backup
            'backupdir': [ /tmp ]

            # you can configure a new dirsrv-admin
            'setup_admin': True,

            # or you need the dirsrv-admin to be already setup
            'cfgdshost': 'localhost.localdomain',
            'cfgdsport': 22389,
            'cfgdsuser': '******',
            'cfgdspwd': 'admin',

        }
        """
        cfgdn = lib389.CFGSUFFIX
        isLocal = update_newhost_with_fqdn(args)

        # use prefix if binaries are relocated
        sroot = args.get('sroot', '')
        prefix = args.setdefault('prefix', '')

        # get the backup directory to store instance backup
        backupdir = args.get('backupdir', '/tmp')

        # new style - prefix or FHS?
        args['new_style'] = not args.get('sroot')

        # do we have ds only or ds+admin?
        if 'no_admin' not in args:
            ds_admin_path = os.path.join(_ds_paths.sbin_dir, PATH_SETUP_DS_ADMIN)
            if os.path.isfile(ds_admin_path):
                args['have_admin'] = True

        # set default values
        args['have_admin'] = args.get('have_admin', False)
        args['setup_admin'] = args.get('setup_admin', False)

        # get default values from adm.conf
        if args['new_style'] and args['have_admin']:
            admconf = LDIFConn(
                args['prefix'] + PATH_ADM_CONF)
            args['admconf'] = admconf.get('')

        # next, get the configuration ds host and port
        if args['have_admin']:
            args['cfgdshost'], args['cfgdsport'], cfgdn = getcfgdsinfo(args)
        #
        # if a Config DS is passed, get the userdn. This creates
        # a connection to the given DS. If you don't want to connect
        # to this server you should pass 'setup_admin' too.
        #
        if args['have_admin'] and not args['setup_admin']:
            cfgconn = getcfgdsuserdn(cfgdn, args)

        # next, get the server root if not given
        if not args['new_style']:
            getserverroot(cfgconn, isLocal, args)
        # next, get the admin domain
        if args['have_admin']:
            update_admin_domain(isLocal, args)
        # next, get the admin server port and any other information -
        # close the cfgconn
        if args['have_admin'] and not args['setup_admin']:
            asport, secure = getadminport(cfgconn, cfgdn, args)
        # next, get the posix username
        get_server_user(args)
        # fixup and verify other args
        args['newport'] = args.get('newport', 389)
        args['newrootdn'] = args.get('newrootdn', DN_DM)
        args['newsuffix'] = args.get('newsuffix',
                                     getdefaultsuffix(args['newhost']))

        if not isLocal or 'cfgdshost' in args:
            if 'admin_domain' not in args:
                args['admin_domain'] = getdomainname(args['newhost'])
            if isLocal and 'cfgdspwd' not in args:
                args['cfgdspwd'] = "dummy"
            if isLocal and 'cfgdshost' not in args:
                args['cfgdshost'] = args['newhost']
            if isLocal and 'cfgdsport' not in args:
                args['cfgdsport'] = 55555
        missing = False
        for param in ('newhost', 'newport', 'newrootdn', 'newrootpw',
                      'newinstance', 'newsuffix'):
            if param not in args:
                log.error("missing required argument: ", param)
                missing = True
        if missing:
            raise InvalidArgumentError("missing required arguments")

        # try to connect with the given parameters
        try:
            newconn = lib389.DirSrv(args['newhost'], args['newport'],
                                    args['newrootdn'], args['newrootpw'],
                                    args['newinstance'])
            newconn.prefix = prefix
            newconn.backupdir = backupdir
            newconn.isLocal = isLocal
            if args['have_admin'] and not args['setup_admin']:
                newconn.asport = asport
                newconn.cfgdsuser = args['cfgdsuser']
                newconn.cfgdspwd = args['cfgdspwd']

            host = args['newhost']
            port = args['newport']
            print("Warning: server at %s:%s " % (host, port) +
                  "already exists, returning connection to it")
            return newconn
        except ldap.SERVER_DOWN:
            pass  # not running - create new one

        if not isLocal or 'cfgdshost' in args:
            for param in ('cfgdshost', 'cfgdsport', 'cfgdsuser', 'cfgdspwd',
                          'admin_domain'):
                if param not in args:
                    print("missing required argument", param)
                    missing = True
        if not isLocal and not asport:
            print("missing required argument admin server port")
            missing = True
        if missing:
            raise InvalidArgumentError("missing required arguments")

        # construct a hash table with our CGI arguments - used with cgiPost
        # and cgiFake
        cgiargs = {
            'servname': args['newhost'],
            'servport': args['newport'],
            'rootdn': args['newrootdn'],
            'rootpw': args['newrootpw'],
            'servid': args['newinstance'],
            'suffix': args['newsuffix'],
            'servuser': args['newuserid'],
            'start_server': 1
        }
        if 'cfgdshost' in args:
            cgiargs['cfg_sspt_uid'] = args['cfgdsuser']
            cgiargs['cfg_sspt_uid_pw'] = args['cfgdspwd']
            cgiargs['ldap_url'] = "ldap://%s:%d/%s" % (
                args['cfgdshost'], args['cfgdsport'], cfgdn)
            cgiargs['admin_domain'] = args['admin_domain']

        if not isLocal:
            DirSrvTools.cgiPost(args['newhost'], asport, args['cfgdsuser'],
                                args['cfgdspwd'],
                                "/slapd/Tasks/Operation/Create",
                                verbose, secure, cgiargs)
        elif not args['new_style']:
            prog = sroot + "/bin/slapd/admin/bin/ds_create"
            if not os.access(prog, os.X_OK):
                prog = sroot + "/bin/slapd/admin/bin/ds_newinstance"
            DirSrvTools.cgiFake(sroot, verbose, prog, cgiargs)
        else:
            prog = ''
            if args['have_admin']:
                prog = os.path.join(_ds_paths.sbin_dir, PATH_SETUP_DS_ADMIN)
            else:
                prog = os.path.join(_ds_paths.sbin_dir, PATH_SETUP_DS)

            if not os.path.isfile(prog):
                log.error("Can't find file: %r, removing extension" % prog)
                prog = prog[:-3]

            content = formatInfData(args)
            DirSrvTools.runInfProg(prog, content, verbose)

        newconn = lib389.DirSrv(args['newhost'], args['newport'],
                                args['newrootdn'], args['newrootpw'],
                                args['newinstance'])
        newconn.prefix = prefix
        newconn.backupdir = backupdir
        newconn.isLocal = isLocal
        # Now the admin should have been created
        # but still I should have taken all the required infos
        # before.
        if args['have_admin'] and not args['setup_admin']:
            newconn.asport = asport
            newconn.cfgdsuser = args['cfgdsuser']
            newconn.cfgdspwd = args['cfgdspwd']
        return newconn
Esempio n. 4
0
    def createInstance(args, verbose=0):
        """Create a new instance of directory server and return a connection
        to it.

        This function:
        - guesses the hostname where to create the DS, using
        localhost by default;
        - figures out if the given hostname is the local host or not.

        @param args -  a dict with the following values {
            # new instance compulsory values
            'newinstance': 'rpolli',
            'newsuffix': 'dc=example,dc=com',
            'newhost': 'localhost.localdomain',
            'newport': 22389,
            'newrootpw': 'password',

            # optionally register instance on an admin tree
            'have_admin': True,

            # optionally directory where to store instance backup
            'backupdir': [ /tmp ]

            # you can configure a new dirsrv-admin
            'setup_admin': True,

            # or you need the dirsrv-admin to be already setup
            'cfgdshost': 'localhost.localdomain',
            'cfgdsport': 22389,
            'cfgdsuser': '******',
            'cfgdspwd': 'admin',

        }
        """
        cfgdn = lib389.CFGSUFFIX
        isLocal = update_newhost_with_fqdn(args)

        # use prefix if binaries are relocated
        sroot = args.get('sroot', '')
        prefix = args.setdefault('prefix', '')

        # get the backup directory to store instance backup
        backupdir = args.get('backupdir', '/tmp')

        # new style - prefix or FHS?
        args['new_style'] = not args.get('sroot')

        # do we have ds only or ds+admin?
        if 'no_admin' not in args:
            sbindir = get_sbin_dir(sroot, prefix)
            if os.path.isfile(sbindir + PATH_SETUP_DS_ADMIN):
                args['have_admin'] = True

        # set default values
        args['have_admin'] = args.get('have_admin', False)
        args['setup_admin'] = args.get('setup_admin', False)

        # get default values from adm.conf
        if args['new_style'] and args['have_admin']:
            admconf = LDIFConn(
                args['prefix'] + PATH_ADM_CONF)
            args['admconf'] = admconf.get('')

        # next, get the configuration ds host and port
        if args['have_admin']:
            args['cfgdshost'], args['cfgdsport'], cfgdn = getcfgdsinfo(args)
        #
        # if a Config DS is passed, get the userdn. This creates
        # a connection to the given DS. If you don't want to connect
        # to this server you should pass 'setup_admin' too.
        #
        if args['have_admin'] and not args['setup_admin']:
            cfgconn = getcfgdsuserdn(cfgdn, args)

        # next, get the server root if not given
        if not args['new_style']:
            getserverroot(cfgconn, isLocal, args)
        # next, get the admin domain
        if args['have_admin']:
            update_admin_domain(isLocal, args)
        # next, get the admin server port and any other information -
        # close the cfgconn
        if args['have_admin'] and not args['setup_admin']:
            asport, secure = getadminport(cfgconn, cfgdn, args)
        # next, get the posix username
        get_server_user(args)
        # fixup and verify other args
        args['newport'] = args.get('newport', 389)
        args['newrootdn'] = args.get('newrootdn', DN_DM)
        args['newsuffix'] = args.get('newsuffix',
                                     getdefaultsuffix(args['newhost']))

        if not isLocal or 'cfgdshost' in args:
            if 'admin_domain' not in args:
                args['admin_domain'] = getdomainname(args['newhost'])
            if isLocal and 'cfgdspwd' not in args:
                args['cfgdspwd'] = "dummy"
            if isLocal and 'cfgdshost' not in args:
                args['cfgdshost'] = args['newhost']
            if isLocal and 'cfgdsport' not in args:
                args['cfgdsport'] = 55555
        missing = False
        for param in ('newhost', 'newport', 'newrootdn', 'newrootpw',
                      'newinstance', 'newsuffix'):
            if param not in args:
                log.error("missing required argument: ", param)
                missing = True
        if missing:
            raise InvalidArgumentError("missing required arguments")

        # try to connect with the given parameters
        try:
            newconn = lib389.DirSrv(args['newhost'], args['newport'],
                                    args['newrootdn'], args['newrootpw'],
                                    args['newinstance'])
            newconn.prefix = prefix
            newconn.backupdir = backupdir
            newconn.isLocal = isLocal
            if args['have_admin'] and not args['setup_admin']:
                newconn.asport = asport
                newconn.cfgdsuser = args['cfgdsuser']
                newconn.cfgdspwd = args['cfgdspwd']

            host = args['newhost']
            port = args['newport']
            print("Warning: server at %s:%s " % (host, port) +
                  "already exists, returning connection to it")
            return newconn
        except ldap.SERVER_DOWN:
            pass  # not running - create new one

        if not isLocal or 'cfgdshost' in args:
            for param in ('cfgdshost', 'cfgdsport', 'cfgdsuser', 'cfgdspwd',
                          'admin_domain'):
                if param not in args:
                    print("missing required argument", param)
                    missing = True
        if not isLocal and not asport:
            print("missing required argument admin server port")
            missing = True
        if missing:
            raise InvalidArgumentError("missing required arguments")

        # construct a hash table with our CGI arguments - used with cgiPost
        # and cgiFake
        cgiargs = {
            'servname': args['newhost'],
            'servport': args['newport'],
            'rootdn': args['newrootdn'],
            'rootpw': args['newrootpw'],
            'servid': args['newinstance'],
            'suffix': args['newsuffix'],
            'servuser': args['newuserid'],
            'start_server': 1
        }
        if 'cfgdshost' in args:
            cgiargs['cfg_sspt_uid'] = args['cfgdsuser']
            cgiargs['cfg_sspt_uid_pw'] = args['cfgdspwd']
            cgiargs['ldap_url'] = "ldap://%s:%d/%s" % (
                args['cfgdshost'], args['cfgdsport'], cfgdn)
            cgiargs['admin_domain'] = args['admin_domain']

        if not isLocal:
            DirSrvTools.cgiPost(args['newhost'], asport, args['cfgdsuser'],
                                args['cfgdspwd'],
                                "/slapd/Tasks/Operation/Create",
                                verbose, secure, cgiargs)
        elif not args['new_style']:
            prog = sroot + "/bin/slapd/admin/bin/ds_create"
            if not os.access(prog, os.X_OK):
                prog = sroot + "/bin/slapd/admin/bin/ds_newinstance"
            DirSrvTools.cgiFake(sroot, verbose, prog, cgiargs)
        else:
            prog = ''
            if args['have_admin']:
                prog = get_sbin_dir(sroot, prefix) + '/' + PATH_SETUP_DS_ADMIN
            else:
                prog = get_sbin_dir(sroot, prefix) + '/' + PATH_SETUP_DS

            if not os.path.isfile(prog):
                log.error("Can't find file: %r, removing extension" % prog)
                prog = prog[:-3]

            content = formatInfData(args)
            DirSrvTools.runInfProg(prog, content, verbose)

        newconn = lib389.DirSrv(args['newhost'], args['newport'],
                                args['newrootdn'], args['newrootpw'],
                                args['newinstance'])
        newconn.prefix = prefix
        newconn.backupdir = backupdir
        newconn.isLocal = isLocal
        # Now the admin should have been created
        # but still I should have taken all the required infos
        # before.
        if args['have_admin'] and not args['setup_admin']:
            newconn.asport = asport
            newconn.cfgdsuser = args['cfgdsuser']
            newconn.cfgdspwd = args['cfgdspwd']
        return newconn
Esempio n. 5
0
    def create_realm(self, ignore=False):
        self.validate_hostname()
        exists = self.check_realm()
        if exists is True and ignore is False:
            raise AssertionError("Realm already exists!")
        elif exists is True and ignore is True:
            # Realm exists, continue
            return
        # Raise a scary warning about eating your krb settings
        if self.warnings:
            print("This will alter / erase your krb5 and kdc settings.")
            raw_input("Ctrl-C to exit, or press ENTER to continue.")
        print("Kerberos master password: %s" % self.krb_master_password)

        # If we don't have the directories for this, create them.
        # but if we create them there is no guarantee this will work ...
        if not os.path.exists(os.path.dirname(self.krb5confrealm)):
            os.makedirs(os.path.dirname(self.krb5confrealm))
        # Put the includedir statement into /etc/krb5.conf
        include = True
        with open(self.krb5conf, 'r') as kfile:
            for line in kfile.readlines():
                if 'includedir %s/' % os.path.dirname(self.krb5confrealm) \
                   in line:
                    include = False
        if include is True:
            with open(self.krb5conf, 'a') as kfile:
                kfile.write('\nincludedir %s/\n' %
                            os.path.dirname(self.krb5confrealm))

        # Write to  /etc/krb5.conf.d/example.com
        with open(self.krb5confrealm, 'w') as cfile:
            domainname = getdomainname()
            fqdn = getfqdn()
            realm = self.realm
            lrealm = self.realm.lower()
            cfile.write("""
[realms]
{REALM} = {{
 kdc = {HOST}
 admin_server = {HOST}
}}

[domain_realm]
.{LREALM} = {REALM}
{LREALM} = {REALM}
.{DOMAIN} = {REALM}
{DOMAIN} = {REALM}
""".format(HOST=fqdn, REALM=realm, LREALM=lrealm, DOMAIN=domainname))

        # Do we need to edit /var/kerberos/krb5kdc/kdc.conf ?
        with open(self.kdcconf, 'w') as kfile:
            kfile.write("""
[kdcdefaults]
 kdc_ports = 88
 kdc_tcp_ports = 88

[realms]
 {REALM} = {{
  #master_key_type = aes256-cts
  acl_file = {PREFIX}/var/kerberos/krb5kdc/kadm5.acl
  dict_file = /usr/share/dict/words
  admin_keytab = {PREFIX}/var/kerberos/krb5kdc/kadm5.keytab
  # Just use strong enctypes
  supported_enctypes = aes256-cts:normal aes128-cts:normal
 }}

""".format(REALM=self.realm, PREFIX=self.krb_prefix))
        # Invoke kdb5_util
        # Can this use -P
        p = Popen([self.kdb5_util, 'create', '-r', self.realm, '-s', '-P',
                   self.krb_master_password], env=self.krb_env)
        assert(p.wait() == 0)
        # Start the kdc
        p = Popen([self.krb5kdc, '-P', self.kdcpid, '-r', self.realm],
                  env=self.krb_env)
        assert(p.wait() == 0)
        # ???
        # PROFIT
        return
Esempio n. 6
0
 def validate_hostname(self):
     if getdomainname() == "":
         # Should we return a message?
         raise AssertionError("Host does not have a domain name.")
     DirSrvTools.searchHostsFile(getfqdn())