Пример #1
0
    def renew_user(self, uid, num_terms=None):
        "Renews the user 'uid' for the current term, or a number of terms."
        if num_terms is None:
            num_terms = 1
        if num_terms > 3:
            debug('Warning: I can only renew a member for up to 3 terms at a '
                  'time! I will renew for the maximum possible number.')
            term = 3
        if num_terms < 1:
            error("Your number of terms doesn't make any sense! You said: %s" %
                  num_terms)
            return

        terms = []
        for num in range(num_terms):
            terms.append(
                get_term(datetime.date.today() +
                         relativedelta(months=(num * 4))))

        for term in terms:
            try:
                debug('Renewing user for term ' + term)
                verbose('dn: uid=%s,ou=People,%s' % (uid, BASE))
                ml = [(ldap.MOD_ADD, 'term', term)]
                verbose('modlist: ' + str(ml))

                self.ldap_wics.modify_s('uid=%s,ou=People,%s' % (uid, BASE),
                                        ml)
            except:
                print_exc(sys.exc_info())
                error('Failed to renew user for term ' + term + '!')
Пример #2
0
    def unlock(self, dn, newdn):
        '''
        This helper performs an unlock using LDAP attributes.

        dn: the distinguished name of our mutex object
        newdn: new distinguished name object, e.g. "cn=newuid"
        '''
        self.ldap_wics.modrdn_s(dn, newdn)
        debug('Unlocked database.')
Пример #3
0
    def add_princ(self, uid, password=None):
        '''
        Adds a Kerberos principal.

        uid: the user id for the principal
        password: (optional) a string consisting of the user's password; if no
            string is provided the user will be prompted to enter one
        '''
        if password is None:
            password = get_user_password(
                'Enter password for principal %s@%s: ' % (uid, REALM))

        debug('Adding Kerberos principal...')
        self.krb_wics.addprinc('%s@%s' % (uid, REALM), password)
Пример #4
0
    def lock(self, dn, newdn):
        '''
        This helper performs a simple atomic test and set lock using LDAP
        attributes.

        dn: the distinguished name of our mutex object
        newdn: new distinguished name object, e.g. "cn=newuid"
        '''
        debug('Locking LDAP database...')
        for x in range(NUM_TRIES):
            try:
                self.ldap_wics.modrdn_s(dn, newdn)
                return
            except:
                print_exc(sys.exc_info())
                time.sleep(SLEEP_DUR)

        raise ldap.TIMEOUT('Could not obtain lock on ' + dn)
Пример #5
0
    def remove_user_from_group(self, gid, uid):
        '''
        Removes a user from an LDAP group.

        gid: the group to remove the user from
        uid: the user to remove from the group
        '''
        try:
            debug('Removing user from group...')
            verbose('dn: cn=%s,ou=Group,%s' % (gid, BASE))
            ml = [(ldap.MOD_DELETE, 'uniqueMember',
                   'uid=%s,ou=People,%s' % (uid, BASE))]
            verbose('modlist: ' + str(ml))

            self.ldap_wics.modify_s('cn=%s,ou=Group,%s' % (gid, BASE), ml)
        except:
            print_exc(sys.exc_info())
            error('Failed to remove user from group!')
Пример #6
0
    def add_user_to_group(self, gid, uid):
        '''
        Adds a user to an LDAP group.

        gid: the group to add the user to
        uid: the user to add to the group
        '''
        try:
            debug('Adding user to group...')
            verbose('dn: cn=%s,ou=Group,%s' % (gid, BASE))
            ml = [(ldap.MOD_ADD, 'uniqueMember',
                   'uid=%s,ou=People,%s' % (uid, BASE))]
            verbose('modlist: ' + str(ml))

            self.ldap_wics.modify_s('cn=%s,ou=Group,%s' % (gid, BASE), ml)
        except:
            print_exc(sys.exc_info())
            error('Failed to add user to group!')
Пример #7
0
    def add_group(self, gid, desc):
        '''
        Adds a group to the LDAP database.

        gid: the unique group id for our new group
        desc: a longer, descriptive name for the group
        '''
        self.lock('cn=nextgid,ou=Group,' + BASE, 'cn=inuse')
        nextgid = self.ldap_wics.search_s('cn=inuse,ou=Group,' + BASE,
                                          ldap.SCOPE_BASE)

        nextgid = nextgid[0][1]
        next_gid = int(nextgid['gidNumber'][0])

        attrs = {
            'cn': gid,
            'objectClass': ['group', 'posixGroup', 'top'],
            'gidNumber': str(next_gid),
            'description': desc,
        }

        try:
            self.ldap_wics.modify_s(
                'cn=inuse,ou=Group,' + BASE,
                [(ldap.MOD_REPLACE, 'gidNumber', str(next_gid + 1))])

            debug('Adding group...')
            verbose('dn: cn=%s,ou=Group,%s' % (gid, BASE))
            ml = modlist.addModlist(attrs)
            verbose('modlist: ' + str(ml))

            self.ldap_wics.add_s('cn=%s,ou=Group,%s' % (gid, BASE), ml)

        except:
            print_exc(sys.exc_info())
            error('Failed to add group!')

            # Reset GID before unlocking
            self.ldap_wics.modify_s(
                'cn=inuse,ou=Group,' + BASE,
                [(ldap.MOD_REPLACE, 'gidNumber', str(next_gid))])

        finally:
            self.unlock('cn=inuse,ou=Group,' + BASE, 'cn=nextgid')
Пример #8
0
    def add_user(self, uid, username):
        '''
        Adds a user to the LDAP database.

        uid: the unique user id for our new user
        username: the user's full name
        '''
        self.lock('uid=nextuid,ou=People,' + BASE, 'uid=inuse')
        nextuid = self.ldap_wics.search_s('uid=inuse,ou=People,' + BASE,
                                          ldap.SCOPE_BASE)

        nextuid_obj = nextuid[0][1]
        next_uid = int(nextuid_obj['uidNumber'][0])
        next_gid = int(nextuid_obj['gidNumber'][0])

        if next_uid != next_gid:
            # This isn't enforced at the schema level but close enough
            raise ldap.OBJECT_CLASS_VIOLATION(
                "UID and GID on nextuid are out of sync. Tell the sysadmin!")

        current_term = get_term()

        attrs_user = {
            # 'uid': uid,
            'cn':
            username,
            'objectClass':
            ['account', 'member', 'posixAccount', 'shadowAccount', 'top'],
            'homeDirectory':
            '/home/' + uid,
            'loginShell':
            '/bin/bash',
            'uidNumber':
            str(next_uid),
            'gidNumber':
            str(next_gid),
            'term':
            current_term,
            # 'program': program,  TODO: add query to uwldap for autocompletion
            # 'cn': name,
        }

        attrs_grp = {
            'cn': uid,
            'objectClass': ['group', 'posixGroup', 'top'],
            'gidNumber': str(next_gid),
        }

        try:
            self.ldap_wics.modify_s(
                'uid=inuse,ou=People,' + BASE,
                [(ldap.MOD_REPLACE, 'uidNumber', str(next_uid + 1)),
                 (ldap.MOD_REPLACE, 'gidNumber', str(next_gid + 1))])

            debug('Adding user...')
            verbose('dn: uid=%s,ou=People,%s' % (uid, BASE))
            ml = modlist.addModlist(attrs_user)
            verbose('modlist: ' + str(ml))

            self.ldap_wics.add_s('uid=%s,ou=People,%s' % (uid, BASE), ml)

            debug("Adding user's group...")
            verbose('dn: cn=%s,ou=Group,%s' % (uid, BASE))
            ml = modlist.addModlist(attrs_grp)
            verbose('modlist: ' + str(ml))

            self.ldap_wics.add_s('cn=%s,ou=Group,%s' % (uid, BASE), ml)

        except:
            print_exc(sys.exc_info())
            error('Failed to add user!')

            # Reset UID/GID before unlocking
            self.ldap_wics.modify_s(
                'uid=inuse,ou=People,' + BASE,
                [(ldap.MOD_REPLACE, 'uidNumber', str(next_uid)),
                 (ldap.MOD_REPLACE, 'gidNumber', str(next_gid))])

        finally:
            self.unlock('uid=inuse,ou=People,' + BASE, 'uid=nextuid')
Пример #9
0
def main():
    'CLI dispatch logic'

    def print_usage():
        print '''
Usage: python weo.py [OPTIONS...]

  -h, --help    Prints this help message
  -v            Turns on verbose mode

  Standard commands
  -----------------
  --renew                   Renews a user's account. Can optionally
                            specify number of terms, up to three (i.e.
                            --num-terms=2). Must specify --username
  --adduser                 Adds a user. Must also specify
                            --username and --fullname
  --addgroup                Adds a group. Must also specify
                            --groupname and --groupdesc
  --add-user-to-group       Adds a user to a group. Must also specify
                            --groupname and --username
  --remove-user-from-group  Removes a user from a group. Must
                            also specify --groupname and --username

  Parameters:
  --username=[name]         A user's id. Must be 3-8 lowercase ASCII
                            characters.
  --fullname=["N. Ame"]     A user's full name. Use quotes if it
                            contains spaces.
  --groupname=[name]        A group's id. Must be 3-10 lowercase ASCII
                            characters.
  --groupdesc=["D Esc"]     A group's description. Use quotes if it
                            contains spaces.

  Advanced commands
  -----------------
  LDAP Only:
  --add-ldap-user           Adds a user to the LDAP database. Must also
                            specify --username and --fullname
  --unlock-nextuid          Unlocks the special nextuid user.
  --unlock-nextgid          Unlocks the special nextgid group.

  Kerberos Only:
  --add-krb-princ           Adds a Kerberos principal for a user. Must
                            also specify --username
'''

    # getopt returns options and arguments, but we take no arguments
    (opts, _) = getopt.getopt(
        sys.argv[1:],
        'hv',
        [
            'help',
            'unlock-nextuid',
            'unlock-nextgid',
            'add-ldap-user',
            'add-krb-princ',
            'adduser',
            'addgroup',
            'add-user-to-group',
            'remove-user-from-group',
            'renew',
            'username='******'fullname=',
            'groupname=',
            'groupdesc=',
            'num-terms=',
        ])

    opts = dict(opts)
    if '-v' in opts:
        weo.log.VERBOSE = True

    verbose('opts: ' + str(opts))

    if not opts or '--help' in opts or '-h' in opts:
        print_usage()
        sys.exit(0)

    if '--add-ldap-user' in opts:
        if opts.get('--username') and opts.get('--fullname'):
            username = check_username(opts['--username'])
            debug('Okay, adding user %s' % username)

            l = wics_ldap()
            l.add_user(username, opts['--fullname'])

            exit_with_msg(
                'Failed to add user %s :(' % username,
                'User %s successfully added.' % username)

    if '--add-krb-princ' in opts:
        if opts.get('--username'):
            username = check_username(opts['--username'])
            debug('Okay, adding Kerberos principal %s@%s' %
                  (username, REALM))

            k = wics_krb5()
            k.add_princ(username)

            exit_with_msg(
                'Failed to add Kerberos principal %s@%s :(' % (username,
                                                               REALM),
                'Principal %s@%s successfully added.' % (username, REALM))

    if '--adduser' in opts:
        if opts.get('--username') and opts.get('--fullname'):
            username = check_username(opts['--username'])
            debug('Okay, adding user %s' % username)

            # Throws an exception before opening LDAP/KRB connections
            # if passwords don't match
            password = get_user_password(
                "Please enter the new user's password: ")

            l = wics_ldap()
            k = wics_krb5()
            l.add_user(username, opts['--fullname'])
            k.add_princ(username, password=password)

            exit_with_msg(
                'Failed to add user %s :(' % username,
                'User %s successfully added.' % username)

    if '--addgroup' in opts:
        if opts.get('--groupname') and opts.get('--groupdesc'):
            groupname = check_username(opts['--groupname'], maxlen=10)
            debug('Okay, adding group %s' % groupname)

            l = wics_ldap()
            l.add_group(groupname, opts['--groupdesc'])

            exit_with_msg(
                'Failed to add group %s :(' % groupname,
                'Group %s successfully added.' % groupname)

    if '--add-user-to-group' in opts:
        if opts.get('--username') and opts.get('--groupname'):
            username = opts['--username']
            groupname = opts['--groupname']
            debug('Okay, adding user %s to group %s' % (username, groupname))

            l = wics_ldap()
            l.add_user_to_group(groupname, username)

            exit_with_msg(
                'Failed to add user %s to group %s :(' % (username, groupname),
                'User %s successfully added to group %s' %
                (username, groupname))

    if '--remove-user-from-group' in opts:
        if opts.get('--username') and opts.get('--groupname'):
            username = opts['--username']
            groupname = opts['--groupname']
            debug('Okay, removing user %s from group %s' %
                  (username, groupname))

            l = wics_ldap()
            l.remove_user_from_group(groupname, username)

            exit_with_msg(
                'Failed to remove user %s from group %s :(' %
                (username, groupname),
                'User %s successfully removed from group %s' %
                (username, groupname))

    if '--renew' in opts:
        if opts.get('--username'):
            username = opts['--username']
            num_terms = opts.get('--num-terms')

            l = wics_ldap()
            if num_terms is not None:
                debug('Okay, renewing user %s for %s terms' %
                      (username, num_terms))
                l.renew_user(username, num_terms=int(num_terms))
            else:
                debug('Okay, renewing user %s' % username)
                l.renew_user(username)

            exit_with_msg(
                'Failed to renew user %s for specified terms :(' % username,
                'User %s successfully renewed!' % username)

    if '--unlock-nextuid' in opts:
        l = wics_ldap()
        l.unlock('uid=inuse,ou=People,' + BASE, 'uid=nextuid')
        sys.exit(0)

    if '--unlock-nextgid' in opts:
        l = wics_ldap()
        l.unlock('cn=inuse,ou=Group,' + BASE, 'cn=nextgid')
        sys.exit(0)