# -*- python -*- # -*- coding: utf-8 -*- # # Copyright (C) 2007, 2008 by Jan Dittberner. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, # USA. # # Version: $Id$ """Tools for handling user and group information.""" import pwd, grp class PasswdUser(object): """This class represents users in the user database.""" def __init__(self, username, pw, uid, gid, gecos, home, shell): """Create a new PasswdUser.""" self.username = username self.uid = int(uid) self.gid = int(gid) self.gecos = gecos self.home = home self.shell = shell def __repr__(self): """Returns a user string representation.""" return "%s(%s:%d:%d:%s:%s:%s)" % (self.__class__.__name__, self.username, self.uid, self.gid, self.gecos, self.home, self.shell) class PasswdGroup(object): """This class represents lines in the groups database.""" def __init__(self, groupname, pw, gid, members): """Create a new PasswdGroup.""" self.groupname = groupname self.gid = int(gid) self.members = members def __repr__(self): """Returns a group string representation.""" return "%s(%s:%d:%s)" % (self.__class__.__name__, self.groupname, self.gid, ",".join(self.members)) def parse_groups(): """Parses all available groups to PasswdGroup instances.""" return [PasswdGroup(*arr) for arr in grp.getgrall()] def parse_users(): """Parses all available users to PasswdUser instances.""" return [PasswdUser(*arr) for arr in pwd.getpwall()] def find_user_by_prefix(prefix): """Finds all user entries with the given prefix.""" return [user for user in parse_users() if user.username.startswith(prefix)] def get_user_by_id(uid): """Gets the user with the given user id.""" users = [user for user in parse_users() if user.uid == uid] if users: return users[0] return None def get_group_by_id(gid): """Gets the group with the given group id.""" groups = [group for group in parse_groups() if group.gid == gid] if groups: return groups[0] return None def get_next_uid(lowerboundary = 10000, upperboundary = 65536): """Gets the first available user id in the given range. The returned uid is a value between lowerboundary and upper boundary. An exception is raised if no uid can be found. Keyword arguments: lowerboundary -- lower boundary for uid range upperboundary -- upper boundary for uid range """ for uid in range(lowerboundary, upperboundary): try: user = pwd.getpwuid(uid) except KeyError: return uid raise Exception("no free uid found in range %d to %d", lowerboundary, upperboundary) def get_max_uid(boundary = 65536): """Gets the highest uid value.""" return max([user.uid for user in parse_users() if user.uid <= boundary]) def get_max_gid(boundary = 65536): """Gets the highest gid value.""" return max([group.gid for group in parse_groups() \ if group.gid <= boundary]) if __name__ == "__main__": print "Max UID is %d" % (get_max_uid(40000)) print "Max GID is %d" % (get_max_gid(40000)) print "User with max UID is %s" % (get_user_by_id(get_max_uid(40000))) print "Group with max GID is %s" % (get_group_by_id(get_max_gid(40000))) print "First free UID is %s" % (get_next_uid(10000, 40000))