예제 #1
0
파일: kadmin.py 프로젝트: nwhalen/nixauth
    def runKadmin(self, query):
        """
        Executes kadmin or kadmin.local and runs the requested query.
        Returns the resulting text from the output of kadmin(.local).

        TODO: Strip the authentication prompts from the beginning of stdout
            before returning text.
            
        """
        # kadmin(.local) -r <realm> [-p <principal>] -q "request"
        options = ''

        if self.principal:
            options = " -p  '%s' " %self.principal
        if self.realm:
            options = " -r '%s' " %self.realm

        # Fetch the path to the requested kadmin app
        kadmin_path = self.app_paths[self.kadmin_type]

        if os.access(self.credentials_path, os.X_OK):
            raise KadminDaemonOpError('%s does not exist or is not executable: %s' %(self.kadmin_type,
                                                                        self.app_paths[self.kadmin_type]))

        # Run kadmin.local via runExternalProcess since it doesn't ask for a password
        if self.kadmin_type == 'kadmin.local':
            kadmin_info = nixcommon.runExternalProcess("%s -q '%s' " %(kadmin_path, query))

            if kadmin_info['return_code']:
                raise KadminExecError(kadmin_info['stdErr'] )

        # Run kadmin normally, utilizing a keytab or credentials cache for auth
        else:
            # Determine what kind of auth we're using
            if self.auth_type == KRB_AUTH_CC:   # Credentials Cache
                creds_switch = '-c'
            elif self.auth_type == KRB_AUTH_KT: # Keytab
                creds_switch = '-k -t'
            else:
                raise KadminInvalidAuthType(self.auth_type)

            # Make sure the credentials file exists
            if not os.access(self.credentials_path, os.R_OK):
                raise KadminInvalidCredentials(self.credentials_path)

            # Build auth into options list
            options = "%s %s %s" %(creds_switch, self.credentials_path, options)

            kadmin_cmd = "%s %s -q %s" %(kadmin_path, options, query)
            kadmin_info = nixcommon.runExternalProcess(kadmin_cmd)

            if kadmin_info['return_code']:
                raise KadminExecError(kadmin_info['stderr'])

        return kadmin_info
예제 #2
0
    def setHostName(self):
        """
        Sets the system's hostname.  This includes modifying /etc/hosts, /etc/hostname and applying the hostname
        to the running server with ``hostname -F``.

        """

        fqhn = "%s.%s" %(self.na_setup_config['hostName'], self.na_setup_config['dnsDomain'])
        hosts = {
            '127.0.0.1' : ('localhost'),
            '::1' : ('ip6-localhost', 'ip6-loopback'),
            'fe00::0' : ('ip6-localnet'),
            'ff00::0' : ('ip6-mcastprefix'),
            'ff02::1' : ('ip6-allnodes'),
            'ff02::2' : ('ip6-allrouters'),
            self.host_ip : (fqhn, self.na_setup_config['hostName']),
        }

        hosts_file = ''
        for ip in hosts:
            hosts_file += "%s\t" %ip
            if type(hosts[ip]) == tuple:
                for name in hosts[ip]:
                    hosts_file += "%s\t" %name
            else:
                hosts_file += "%s" %hosts[ip]
            hosts_file += "\n"

        # Write /etc/hosts
        if not self.configFiles.backUpOriginalConfig('/etc/hosts'):
            raise HostnameSetupError('/etc/hosts doesn\'t exist!  Your OS is broken, I can\'t continue!')

        try:
            fh = open('/etc/hosts', 'w')
            fh.write(hosts_file)
            fh.close()
        except:
            raise HostnameSetupError('Failed to write /etc/hosts')

        # Write /etc/hostname
        if not self.configFiles.backUpOriginalConfig('/etc/hostname'):
            raise HostnameSetupError('/etc/hostname doesn\'t exist!  Your OS is broken, I can\'t continue!')

        try:
            fh = open('/etc/hostname', 'w')
            fh.write("%s\n" %self.na_setup_config['hostName'])
            fh.close()
        except:
            raise HostnameSetupError('Failed to write /etc/hostname')

        hostname_info = nixcommon.runExternalProcess('hostname -F /etc/hostname')

        if not hostname_info['return_code'] == 0:
            raise HostnameSetupError(hostname_info['std_err'])

        return
예제 #3
0
파일: pre_sasl.py 프로젝트: nwhalen/nixauth
    def setPermissions(self):
        from lib import nixcommon

        # Add openldap to sasl group (OpenLDAP can't access SASL mux pipe otherwise)
        userMod = nixcommon.runExternalProcess("/usr/sbin/usermod -G sasl openldap")

        if not userMod["return_code"] == 0:
            raise PermissionsSetError(userMod)

        return
예제 #4
0
    def removeGroup(self, groupname):
        """
        Removes the added group.  Used for rollback procedures.
        """

        groupdel = '%s %s' %(paths.General['groupdel'], groupname)

        groupdel_info = nixcommon.runExternalProcess(groupdel)

        if groupdel_info['return_code']:
            raise RollbackError(groupdel_info['stderr'])
예제 #5
0
파일: kdc.py 프로젝트: nwhalen/nixauth
    def restart(self):
        """
        Stops and starts the krb5kdc daemon.

        """
        kdc_info = nixcommon.runExternalProcess("%s %s" %(self.init_script, 'restart'))

        if kdc_info['return_code']:
            raise KDCDaemonOpError('Init script returned a bad status.',  kdc_info)

        return
예제 #6
0
파일: kadmin.py 프로젝트: nwhalen/nixauth
    def restart(self):
        """
        Restarts the kadmind daemon by stopping and starting it.

        """
        kdcInfo = nixcommon.runExternalProcess("%s %s" %(self.init_script, 'restart'))

        if kdcInfo['return_code']:
            raise KDCDaemonOpError('Init script returned a bad status.',  kdcInfo)
        else:
            return True
예제 #7
0
파일: openssl.py 프로젝트: nwhalen/nixauth
    def runOpenSSL(self, args):
        """
        Runs the openssl command-line tool with the passed arguments.
        :param args: Argument string for openssl.

        """
        cmd = '%s %s' %(paths['openssl'], args)

        openssl = nixcommon.runExternalProcess(cmd)

        return openssl
예제 #8
0
파일: debian.py 프로젝트: nwhalen/nixauth
    def installNixAuthPackageKeys(self):
        """
        Installs the latest package signing key(s) from pi.nixauth.org (required for apt to install packages without
        errors).

        """
        key_import_cmd = 'wget -O - http://pi.nixauth.org/package-signer.gpg.key | apt-key add -'
        key_import_info = nixcommon.runExternalProcess(key_import_cmd)

        if key_import_info['return_code']:
            raise KeyInstallError('Error installing gpg for apt:\n%s' %key_import_info['stderr'])
예제 #9
0
파일: sasl.py 프로젝트: nwhalen/nixauth
    def restart(self):
        """
        Stops and starts the saslauthd server.

        """
        sasl_info = nixcommon.runExternalProcess("%s %s" %(self.init_script, 'restart'))

        if sasl_info['return_code']:
            raise DaemonOpFailed('Init script returned a bad status.',  sasl_info)
        
        return
예제 #10
0
    def removeUser(self, username):
        """
        Removes the added user.  Used for rollback procedures.

        """
        userdel = '%s %s' %(paths.General['userdel'], username)

        userdel_info = nixcommon.runExternalProcess(userdel)

        if userdel_info['return_code']:
            raise RollbackError(userdel_info['stderr'])
예제 #11
0
    def addUser(self, username):
        """
        Adds nixAuth's UNIX user (and group atm via the -user-group switch).

        """
        useradd = '%s -d "%s" -M -s /bin/false --user-group -c "nixAuth role account" %s' %(paths.General['useradd'],
                    self.na_setup_config['nixAuthRoot'], username)

        useradd_info = nixcommon.runExternalProcess(useradd)

        if useradd_info['return_code']:
            raise AddUserError(useradd_info['stderr'])
예제 #12
0
파일: bind.py 프로젝트: nwhalen/nixauth
    def _runRndc(self, cmd_line):
        """
        Runs the requested command on rndc and returns the output.
        Protected function, this is not part of the API.

        """
        # Format a proper rndc command and run it
        rndc_cmd = "%s %s" %(self._rndc, re.escape(cmd_line))
        rndc_info = nixcommon.runExternalProcess(rndc_cmd)

        self.logger.debug('_runRndc: %s: returned: %s' %(rndc_cmd,rndc_info['return_code']))

        return rndc_info
예제 #13
0
파일: ntp.py 프로젝트: nwhalen/nixauth
    def isRunning(self):
        """
        Checks to see if the ntpd daemon is running.

        :return: ``True`` if daemon is running, ``False`` otherwise.

        """
        ntpd_info = nixcommon.runExternalProcess("%s %s" %(self.init_script, 'status'))

        # Non-zero means the daemon isn't running
        if ntpd_info['return_code']:
            return False
        # Zero means daemon is running
        elif not ntpd_info['return_code']:
            return True
예제 #14
0
파일: kadmin.py 프로젝트: nwhalen/nixauth
    def start(self):
        """
        Starts the kadmind daemon, if it is not already running.

        """
        # if self.isRunning():
            # return True

        kdcInfo = nixcommon.runExternalProcess("%s %s" %(self.init_script, 'start'))

        # Daemon was already running
        if kdcInfo['return_code'] == 1:
            return True
        # Bad Status, fail properly
        elif kdcInfo['return_code']:
            raise KDCDaemonOpError('Init script returned a bad status.',  kdcInfo)
        else:
            return True
예제 #15
0
파일: ntp.py 프로젝트: nwhalen/nixauth
    def stop(self):
        """
        Stops the ntpd daemon if it's running.

        """
        if not self.isRunning():
            return

        ntpd_info = nixcommon.runExternalProcess("%s %s" %(self.init_script, 'stop'))

        # Daemon was already running
        if ntpd_info['return_code'] == 1:
            return
        # Bad Status, fail properly
        elif ntpd_info['return_code']:
            raise NTPDaemonOpError('Stop failed.  Init script returned a bad status.')

        return
예제 #16
0
파일: ntp.py 프로젝트: nwhalen/nixauth
    def restart(self):
        """
        Restarts the ntpd daemon.

        """
        if not self.isRunning():
            return

        ntpd_info = nixcommon.runExternalProcess("%s %s" %(self.init_script, 'restart'))

        # Restart failed
        if ntpd_info['return_code']:
            raise NTPDaemonOpError('Restart failed.  Init script returned a bad status.')
        # Zero means we're good
        elif ntpd_info['return_code']:
            return
        
        return
예제 #17
0
파일: sasl.py 프로젝트: nwhalen/nixauth
    def stop(self):
        """
        Stops the saslauthd server, if it is running.
        
        """
        if not self.isRunning():
            return

        sasl_info = nixcommon.runExternalProcess("%s %s" %(self.init_script, 'stop'))

        # Daemon was already stopped
        if sasl_info['return_code'] == 1:
            return
        # Bad Status, fail properly
        elif sasl_info['return_code']:
            raise DaemonOpFailed('Init script returned a bad status.',  sasl_info)

        return
예제 #18
0
파일: kdc.py 프로젝트: nwhalen/nixauth
    def stop(self):
        """
        Stops the krb5kdc daemon, if running.

        """
        # if not self.isRunning():
            # return True

        kdc_info = nixcommon.runExternalProcess("%s %s" %(self.init_script, 'stop'))

        # Daemon was already stopped
        if kdc_info['return_code'] == 1:
            return
        # Bad Status, fail properly
        elif kdc_info['return_code']:
            raise KDCDaemonOpError('Init script returned a bad status.',  kdc_info)

        return
예제 #19
0
파일: bind.py 프로젝트: nwhalen/nixauth
    def start(self):
        """
        Starts named if it isn't running.  This function calls the BIND init script since rndc isn't available
        to start the nameserver.

        """
        self.logger.info('Attempting to start named')
        if self.isRunning():
            self.logger.info('named is already running, doing nothing')
            return

        # Run the init script to start the nameserver
        init_script_cmd = "%s start" %self.init_script
        named_info = nixcommon.runExternalProcess(init_script_cmd)

        if named_info['return_code']:
            self.logger.error('named failed to start: %s' %named_info['stderr'])
            raise DaemonControlError('Init script did not complete properly.  STDERR follows:\n%s\n'
                                        %named_info['stderr'])

        self.logger.info('named started successfully')
        return
예제 #20
0
    def test_runExternalProcess(self, subprocess_mock):
        command = '/bin/ls'
        # This matches subprocess.PIPE since it's used in the default parameter values (which are not mockable)
        PIPE_value = -1

        # Set up all needed values (incl a fake class for Popen)
        subprocess_mock.Popen.return_value.__enter__ = lambda s: s
        subprocess_mock.Popen.return_value.__exit__ = mock.Mock()
        subprocess_mock.Popen.return_value.communicate.return_value = ('TEST_STDOUT', 'TEST_STDERR')
        subprocess_mock.Popen.poll.return_value = 100
        subprocess_mock.PIPE = PIPE_value

        nixcommon.subprocess = subprocess_mock

        return_values = nixcommon.runExternalProcess(command)
        nixcommon.subprocess.Popen.assert_called_once_with(command, shell=True, stderr=PIPE_value, stdout=PIPE_value)
        nixcommon.subprocess.Popen.return_value.communicate.assert_called_once_with()
        nixcommon.subprocess.Popen.poll.assert_called_once_with(nixcommon.subprocess.Popen.return_value)

        # Check the return values
        assert return_values['stdout'] == 'TEST_STDOUT'
        assert return_values['stderr'] == 'TEST_STDERR'
        assert return_values['return_code'] == 100
예제 #21
0
    def rollback(self):
        """
        naSetup API call.  Rolls back all configuration changes performed by the :meth:`run` method.

        """
        # Reset DNS resolution
        self.configFiles.restoreOriginalConfig('/etc/resolv.conf')

        # Remove DNS zone and config
        rcNameserver = bind.BIND()      # Server control object
        rcNameserver.removeZone(self.domain)

        # Hostname setup rollback
        self.configFiles.restoreOriginalConfig('/etc/hosts')
        self.configFiles.restoreOriginalConfig('/etc/hostname')

        # Make sure we reload the hostname or weird stuff will happen
        hostname_info = nixcommon.runExternalProcess('hostname -F /etc/hostname')

        if not hostname_info['return_code'] == 0:
            raise HostnameSetupError(hostname_info['std_err'])

        return
예제 #22
0
    def isTimeValid(self):
        """
        Uses ntpdate to check the time against a ntp.org pool.  This gives us the best chance to reach an active server.

        """

        cmd = '%s -q 0.pool.ntp.org' %paths['ntpdate']
        ntpdate_info = nixcommon.runExternalProcess(cmd)
        if ntpdate_info['return_code']:
            raise NTPInvalidTimeError("ntpdate returned an error: %s" %ntpdate_info['stderr'])
        time_info = ntpdate_info['stdout'].strip().split('\n')[-1:] # Get the final ntpdate output, with offset

        srv_info,offset = time_info[0].split('offset')

        if offset.strip() > config['Settings']['max_time_offset']:
            raise NTPInvalidTimeError("Time skew is greater than defined limit.  Set: %s sec  Actual: %s" %(
                                        config['Settings']['max_time_offset'],offset.strip()))

        return
    #---

    
#---
예제 #23
0
    def authentication( self ):
        """
        Tests authentication with saslauthd.  This test requires that Kerberos is configured correctly!

        :return: ``True`` if passed, ``False`` otherwise

        """
        testsaslauthd = self.app_paths.getConfigItem( 'SASL', 'testsaslauthd' )
        cmd = '%s -r %s -u %s -p %s' %(testsaslauthd, self.na_setup_config['kerberosRealm'],
                self.na_setup_config['userAccount']['username'], self.na_setup_config['userAccount']['password'])

        testsaslauthd_info = nixcommon.runExternalProcess( cmd )

        if not testsaslauthd_info['return_code'] == 0:
            raise AuthenticationFailed( testsaslauthd_info )

        stdOut = testsaslauthd_info['stdout'].split( "\n" )
        for line in stdOut:
            auth_info = line.split( ' ' )
            if auth_info[1] == 'OK' and auth_info[2] == '"Success."':
                return True

        return False
예제 #24
0
파일: sasl.py 프로젝트: nwhalen/nixauth
    def isRunning(self):
        """
        Determines if the saslauthd server is running.

        :return: True if running, False otherwise

        """
        running = False

        try:
            pidFile = open(config['Locations']['pidFile'], 'r')
        except IOError:
            return False

        saslPid = pidFile.read()
        sasl_info = nixcommon.runExternalProcess("/bin/ps ax | grep %s" %saslPid)

        stdOut = sasl_info['stdOut'].split("\n")
        for line in stdOut:
            if line[:len(saslPid.strip())] == saslPid.strip():
                running = True
                break

        return running
예제 #25
0
    def arePeersValid(self):
        """
        Uses the ntpq program to ensure that the ntp server's peers are all available and of a reasonable stratum
        level (<=4 by default).

        """
        # Run ntpq to fetch the peers list
        cmd = '%s -c lpeer localhost' %paths['ntpq']
        ntpq_info = nixcommon.runExternalProcess(cmd)
        if ntpq_info['return_code']:
            raise NTPInvalidPeersError("ntpq returned an error: %s" %ntpq_info['stderr'])
        peers = ntpq_info['stdout'].strip().split('\n')[2:] # Fetch only the peer info, no decoration or headers

        if len(peers) < 1:
            raise NTPInvalidPeersError('No peers available.')
        
        for peer in peers:
            # remote,referenceid,stratum,t,when,poll,reach,delay,offset,jitter
            peer_info = peer.strip().split()

            if not (peer_info[2] <= config['Settings']['max_peer_stratum']):    # Check stratum
                raise NTPStratumToHighError("Peer %s is stratum %s. Peers must be stratum %s or lower." %(peer_info[0],
                                                peer_info[2], config['Settings']['max_peer_stratum']))
        return
예제 #26
0
파일: nasetup.py 프로젝트: nwhalen/nixauth
if na_run_from:
    log.debug('nasetup run from %s' %na_run_from)
    con.prints('Running from %s' %na_run_from)
elif not nixcommon.runningAsRoot():
    log.error('Exiting due to lack of root privileges')
    con.prints('This script must be run as root!  Exiting...')
    exit(-1)


# -----------------------------------------------------------------------------
#  System Clock Sync
# -----------------------------------------------------------------------------
con.prints('Setting system clock to a public time server...')
time_server = 'time.nixauth.org'
ntpdate = nixcommon.runExternalProcess('ntpdate ' + time_server)    # Need to localize this for people not in the US
if not ntpdate['return_code']:
    log.warn('Failed to sync the system clock using NTP from server %s' %time_server)
    con.printError("Syncing this computer\'s clock to the ntp.org pool %s failed!" %time_server, False)
else:
    log.info('Synced the system clock to %s with ntpdate' %time_server)

# -----------------------------------------------------------------------------
# Set up the distro config
# -----------------------------------------------------------------------------
distro = distrodetermine.whichDistro()

if not distro['supported']:
    raise UnsupportedDistroError()

log.debug('Symlinking distro and integration config')
예제 #27
0
        con.prints(con.color('ERROR', 'red'))
    else:
        con.prints(con.color('OK', 'green'), no_newline = True)

con.prints()

# If we're missing files, alert the user and quit
if needInstall:
    log.error('Detected missing applications: %s' %missing_apps)
    message = 'The following applications are missing: \n%s' %missing_apps
    con.printStatus('Error', message, quiet_mode)
    # Prevent recursive f*ckery
    if not na_run_from == 'napkginstall':
        if con.askBoolQuestion('Would you like me to run napkginstaller to install these applications'):
            log.info('Running package installer to fix missing packages')
            pkg_install_status = nixcommon.runExternalProcess('./napkginstall.py', True, None, None )
            if not pkg_install_status['return_code']:
                log.error('naPkgInstall returned a non-zero code: %s' %pkg_install_status['return_code'])
                con.prints('Package installer returned an error, I can\'t continue.')
                exit(3)

            # TODO: Um... the generation needs to be re-run at this point
        else:
            exit(3)
    else:
        log.error('naPkgInstall failed to install some packages.  This error is fatal, exiting')
        con.prints('Some applications were not installed by napkginstall!')
        exit(3)
else:
    log.info('Writing paths config')
    # Store the paths to their config file
예제 #28
0
        con.prints('Installing packages for %s, this could take a while...' %group_name)

        try:
            log.info('Installing packages for app group: %s' %group_name)
            distro_helper.installPackagesInGroup(group_name)
        except not KeyboardInterrupt:
            exception_info = sys.exc_info()
            log.error('Encountered error while installing packages: %s' %exception_info)
            con.printException(exception_info, 'Package install error occurred...', exit_on_err=True, exit_value=8)
else:
    log.info('No missing packages installed, skipping installs')

#-------------------------------------------------
# Wrap Up
#-------------------------------------------------
log.info('All packages installed, starting PathBuilder')
con.prints('\nLooks like everything we need is installed.  Starting PathBuilder...')

# Record the location of the binaries in the config
path_builder = nixcommon.runExternalProcess('%s/bin/pathbuilder.py --narunfrom napkginstall' %NA_ROOT,
                                            stdout=None, stderr=None)
if path_builder['return_code']:
    con.prints('PathBuilder did not complete properly, exiting package installer.')
    log.error('PathBuilder exited with non-zero code: %s' %path_builder['return_code'])
    exit(9)

# Everything is installed!
con.prints('\nAll required packages are installed and paths are set!')
log.info('naPkgInstall completed')
exit(0)