| Server IP : 182.53.201.61 / Your IP : 216.73.217.175 Web Server : Apache/2.2.15 (Fedora) System : Linux km10.dyndns.org 2.6.31.5-127.fc12.i686.PAE #1 SMP Sat Nov 7 21:25:57 EST 2009 i686 User : apache ( 48) PHP Version : 5.3.3 Disable Function : NONE MySQL : ON | cURL : ON | WGET : ON | Perl : ON | Python : ON | Sudo : ON | Pkexec : ON Directory : /usr/share/system-config-network/netconfpkg/conf/ |
Upload File : |
"Module handling /etc/{passwd, shadow, group} style files"
import os
from .Conf import Conf, SystemFull # pylint: disable-msg=W0403
class ConfPw(Conf):
"""ConfPw(Conf)
This class implements a dictionary based on a :-separated file.
It takes as arguments the filename and the field number to key on;
The data provided is a list including all fields including the key.
Has its own write method to keep files sane.
"""
def __init__(self, filename, keyfield, numfields):
self.keyfield = keyfield
self.numfields = numfields
Conf.__init__(self, filename, '', ':', ':', 0)
def read(self):
Conf.read(self)
self.initvars()
def initvars(self):
# pylint: disable-msg=W0201
self.vars = {}
# need to be able to return the keys in order to keep
# things consistent...
self.ordered_keys = []
self.rewind()
while self.findnextcodeline():
fields = self.getfields()
self.vars[fields[self.keyfield]] = fields
self.ordered_keys.append(fields[self.keyfield])
self.nextline()
self.rewind()
def __setitem__(self, key, value):
if not self.findlinewithfield(self.keyfield, key):
self.fsf()
self.ordered_keys.append(key)
self.setfields(value)
self.vars[key] = value
def __getitem__(self, key):
if self.vars.has_key(key):
return self.vars[key]
return []
def __delitem__(self, key):
place = self.tell()
self.rewind()
if self.findlinewithfield(self.keyfield, key):
self.deleteline()
if self.vars.has_key(key):
del self.vars[key]
for i in range(len(self.ordered_keys)):
if key in self.ordered_keys[i:i+1]:
self.ordered_keys[i:i+1] = []
break
self.seek(place)
def keys(self):
return self.ordered_keys
def has_key(self, key):
return self.vars.has_key(key)
def write(self):
mfile = open(self.filename + '.new', 'w', -1)
# change the mode of the new file to that of the old one
if os.path.isfile(self.filename) and self.mode == -1:
os.chmod(self.filename + '.new', os.stat(self.filename)[0])
if self.mode >= 0:
os.chmod(self.filename + '.new', self.mode)
# add newlines while writing
for index in range(len(self.lines)):
mfile.write(self.lines[index] + '\n')
mfile.close()
os.rename(self.filename + '.new', self.filename)
def kchangefield(self, key, fieldno, fieldtext):
self.rewind()
self.findlinewithfield(self.keyfield, key)
Conf.changefield(self, fieldno, fieldtext)
self.vars[key][fieldno:fieldno+1] = [fieldtext]
class ConfPwO(ConfPw):
"""ConfPwO
This class presents a data-oriented meta-class for making
changes to ConfPw-managed files. Applications should not
instantiate this class directly.
"""
def __init__(self, filename, keyfield, numfields, reflector):
ConfPw.__init__(self, filename, keyfield, numfields)
self.reflector = reflector
def __getitem__(self, key):
if self.vars.has_key(key):
return self.reflector(self, key)
else:
return None
def __setitem__(self, key, value):
# items are objects which the higher-level code can't touch
raise AttributeError, str('Object %s is immutable. Cannot set %s to %s'
% (self, str(key), str(value)))
# __delitem__ is inherited from ConfPw
# Do *not* use setitem for this; adding an entry should be
# a much different action than accessing an entry or changing
# fields in an entry.
def addentry_list(self, key, mlist):
if self.vars.has_key(key):
raise AttributeError, key + ' exists'
ConfPw.__setitem__(self, key, mlist)
def getfreeid(self, fieldnum):
freeid = 500
# first, we try not to re-use id's that have already been assigned.
for item in self.vars.keys():
mid = int(self.vars[item][fieldnum])
if mid >= freeid and mid < 65533: # ignore nobody on some systems
freeid = mid + 1
if freeid > 65533:
# if that didn't work, we go back and find any free id over 500
ids = {}
for item in self.vars.keys():
ids[int(self.vars[item][fieldnum])] = 1
i = 500
while i < 65535 and ids.has_key(i):
i = i + 1
if freeid > 65533:
raise SystemFull, 'No IDs available'
return freeid
class _passwd_reflector:
# first, we need a helper class...
def __init__(self, pw, user):
self.pw = pw
self.user = user
def setgecos(self, oldgecos, fieldnum, value):
gecosfields = oldgecos.split(', ')
# make sure that we have enough gecos fields
gecosfields += [''] * (6-len(gecosfields))
# for i in range(5-len(gecosfields)):
# gecosfields.append('')
gecosfields[fieldnum] = value
return ', '.join(gecosfields[0:5])
def getgecos(self, oldgecos, fieldnum):
gecosfields = oldgecos.split(', ')
# make sure that we have enough gecos fields
gecosfields += [''] * (6-len(gecosfields))
# for i in range(5-len(gecosfields)):
# gecosfields.append('')
return gecosfields[fieldnum]
def __getitem__(self, name):
return self.__getattr__(name)
def __setitem__(self, name, value):
return self.__setattr__(name, value)
def __getattr__(self, name):
if not self.pw.has_key(self.user):
raise AttributeError, self.user + ' has been deleted'
if not cmp(name, 'username'):
return self.pw.vars[self.user][0]
elif not cmp(name, 'password'):
return self.pw.vars[self.user][1]
elif not cmp(name, 'uid'):
return self.pw.vars[self.user][2]
elif not cmp(name, 'gid'):
return self.pw.vars[self.user][3]
elif not cmp(name, 'gecos'):
return self.pw.vars[self.user][4]
elif not cmp(name, 'fullname'):
return self.getgecos(self.pw.vars[self.user][4], 0)
elif not cmp(name, 'office'):
return self.getgecos(self.pw.vars[self.user][4], 1)
elif not cmp(name, 'officephone'):
return self.getgecos(self.pw.vars[self.user][4], 2)
elif not cmp(name, 'homephone'):
return self.getgecos(self.pw.vars[self.user][4], 3)
elif not cmp(name, 'homedir'):
return self.pw.vars[self.user][5]
elif not cmp(name, 'shell'):
return self.pw.vars[self.user][6]
else:
raise AttributeError, name
def __setattr__(self, name, value):
if not cmp(name, 'pw') or not cmp(name, 'user') \
or not cmp(name, 'setgecos') \
or not cmp(name, 'getgecos'):
self.__dict__[name] = value
return None
if not self.pw.has_key(self.user):
raise AttributeError, self.user + ' has been deleted'
if not cmp(name, 'username'):
# username is not an lvalue...
raise AttributeError, name + ': key is immutable'
elif not cmp(name, 'password'):
self.pw.kchangefield(self.user, 1, value)
elif not cmp(name, 'uid'):
self.pw.kchangefield(self.user, 2, str(value))
elif not cmp(name, 'gid'):
self.pw.kchangefield(self.user, 3, str(value))
elif not cmp(name, 'gecos'):
self.pw.kchangefield(self.user, 4, value)
elif not cmp(name, 'fullname'):
self.pw.kchangefield(self.user, 4,
self.setgecos(self.pw.vars[self.user][4], 0, value))
elif not cmp(name, 'office'):
self.pw.kchangefield(self.user, 4,
self.setgecos(self.pw.vars[self.user][4], 1, value))
elif not cmp(name, 'officephone'):
self.pw.kchangefield(self.user, 4,
self.setgecos(self.pw.vars[self.user][4], 2, value))
elif not cmp(name, 'homephone'):
self.pw.kchangefield(self.user, 4,
self.setgecos(self.pw.vars[self.user][4], 3, value))
elif not cmp(name, 'homedir'):
self.pw.kchangefield(self.user, 5, value)
elif not cmp(name, 'shell'):
self.pw.kchangefield(self.user, 6, value)
else:
raise AttributeError, name
class ConfPasswd(ConfPwO):
"""ConfPasswd(ConfPwO)
This class presents a data-oriented class for making changes
to the /etc/passwd file.
"""
def __init__(self):
ConfPwO.__init__(self, '/etc/passwd', 0, 7, _passwd_reflector)
def addentry(self, username, password, uid, gid, gecos, homedir, shell):
ConfPwO.addentry_list(self, username,
[username, password, uid, gid,
gecos, homedir, shell])
def addfullentry(self, username, password, uid, gid, fullname, office,
officephone, homephone, homedir, shell):
self.addentry(username, password, uid, gid, ', '.join([fullname,
office, officephone, homephone, '']), homedir, shell)
def getfreeuid(self):
try:
return self.getfreeid(2)
except:
raise SystemFull, 'No UIDs available'
class _shadow_reflector:
# first, we need a helper class...
def __init__(self, pw, user):
self.pw = pw
self.user = user
def _readstr(self, fieldno):
return self.pw.vars[self.user][fieldno]
def _readint(self, fieldno):
retval = self.pw.vars[self.user][fieldno]
try:
if len(retval):
retval = int(retval)
return retval
except ValueError:
return -1
return -1
def __getitem__(self, name):
return self.__getattr__(name)
def __setitem__(self, name, value):
return self.__setattr__(name, value)
def __getattr__(self, name):
if not self.pw.has_key(self.user):
raise AttributeError, self.user + ' has been deleted'
if not cmp(name, 'username'):
return self._readstr(0)
elif not cmp(name, 'password'):
return self._readstr(1)
elif not cmp(name, 'lastchanged'):
return self._readint(2)
elif not cmp(name, 'mindays'):
return self._readint(3)
elif not cmp(name, 'maxdays'):
return self._readint(4)
elif not cmp(name, 'warndays'):
return self._readint(5)
elif not cmp(name, 'gracedays'):
return self._readint(6)
elif not cmp(name, 'expires'):
return self._readint(7)
else:
raise AttributeError, name
def __setattr__(self, name, value):
if not cmp(name, 'pw') or not cmp(name, 'user'):
self.__dict__[name] = value
return None
if not self.pw.has_key(self.user):
raise AttributeError, self.user + ' has been deleted'
if not cmp(name, 'username'):
# username is not an lvalue...
raise AttributeError, name + ': key is immutable'
elif not cmp(name, 'password'):
self.pw.changefield(self.user, 1, value)
elif not cmp(name, 'lastchanged'):
if not len(str(value)) or value == -1:
raise AttributeError, 'illegal value for lastchanged'
self.pw.changefield(self.user, 2, str(value))
elif not cmp(name, 'mindays'):
if not len(str(value)) or value == -1:
value = ''
self.pw.changefield(self.user, 3, str(value))
elif not cmp(name, 'maxdays'):
if not len(str(value)) or value == -1:
value = ''
self.pw.changefield(self.user, 4, str(value))
elif not cmp(name, 'warndays'):
if not len(str(value)) or value == -1:
value = ''
self.pw.changefield(self.user, 5, str(value))
elif not cmp(name, 'gracedays'):
if not len(str(value)) or value == -1:
value = ''
self.pw.changefield(self.user, 6, str(value))
elif not cmp(name, 'expires'):
if not len(str(value)) or value == -1:
value = ''
self.pw.changefield(self.user, 7, str(value))
else:
raise AttributeError, name
class ConfShadow(ConfPwO):
"""ConfShadow(ConfPwO)
This class presents a data-oriented class for making changes
to the /etc/shadow file.
"""
def __init__(self):
ConfPwO.__init__(self, '/etc/shadow', 0, 9, _shadow_reflector)
def addentry(self, username, password, lastchanged,
mindays, maxdays, warndays, gracedays, expires):
# we need that final '' so that the final : (delimited the
# "reserved field" is preserved by ConfPwO.addentry())
ConfPwO.addentry_list(self, username,
[username, password, self._intfield(lastchanged),
self._intfield(mindays), self._intfield(maxdays),
self._intfield(warndays), self._intfield(gracedays),
self._intfield(expires), ''])
def _intfield(self, value):
try:
return int(value)
except ValueError:
if value == -1:
return ''
else:
return str(value)
class _group_reflector:
# first, we need a helper class...
def __init__(self, pw, group):
self.pw = pw
self.group = group
def __getitem__(self, name):
return self.__getattr__(name)
def __setitem__(self, name, value):
return self.__setattr__(name, value)
def __getattr__(self, name):
if not self.pw.has_key(self.group):
raise AttributeError, self.group + ' has been deleted'
if not cmp(name, 'name'):
return self.pw.vars[self.group][0]
elif not cmp(name, 'password'):
return self.pw.vars[self.group][1]
elif not cmp(name, 'gid'):
return self.pw.vars[self.group][2]
elif not cmp(name, 'userlist'):
return self.pw.vars[self.group][3]
else:
raise AttributeError, name
def __setattr__(self, name, value):
if not cmp(name, 'pw') or not cmp(name, 'group'):
self.__dict__[name] = value
return None
if not self.pw.has_key(self.group):
raise AttributeError, self.group + ' has been deleted'
if not cmp(name, 'name'):
# username is not an lvalue...
raise AttributeError, name + ': key is immutable'
elif not cmp(name, 'password'):
self.pw.changefield(self.group, 1, value)
elif not cmp(name, 'gid'):
self.pw.changefield(self.group, 2, str(value))
elif not cmp(name, 'userlist'):
self.pw.changefield(self.group, 3, value)
else:
raise AttributeError, name
class ConfGroup(ConfPwO):
"""ConfGroup(ConfPwO)
This class presents a data-oriented class for making changes
to the /etc/group file.
May be replaced by a pwdb-based module, we hope.
"""
def __init__(self):
ConfPwO.__init__(self, '/etc/group', 0, 4, _group_reflector)
def addentry(self, group, password, gid, userlist):
ConfPwO.addentry_list(self, group, [group, password, gid, userlist])
def getfreegid(self):
try:
return self.getfreeid(2)
except:
raise SystemFull, 'No GIDs available'
def nameofgid(self, gid):
try:
gid = int(gid)
for group in self.vars.keys():
mgid = int(self.vars[group][2])
if mgid == gid:
return self.vars[group][0]
except ValueError:
return ''
return ''
class _unix_reflector:
# first, we need a helper class...
def __init__(self, pw, user):
self.pw = pw
self.user = user
def __getitem__(self, name):
return self.__getattr__(name)
def __setitem__(self, name, value):
return self.__setattr__(name, value)
def __getattr__(self, name):
if not self.pw.passwd.has_key(self.user):
raise AttributeError, self.user + ' has been deleted'
if not cmp(name, 'username'):
if self.pw.shadow:
return self.pw.shadow[self.user].username
else:
return self.pw.passwd[self.user].username
elif not cmp(name, 'password'):
if self.pw.shadow:
return self.pw.shadow[self.user].password
else:
return self.pw.passwd[self.user].password
elif not cmp(name, 'uid'):
return self.pw.passwd[self.user].uid
elif not cmp(name, 'gid'):
return self.pw.passwd[self.user].gid
elif not cmp(name, 'gecos'):
return self.pw.passwd[self.user].gecos
elif not cmp(name, 'fullname'):
return self.pw.passwd[self.user].fullname
elif not cmp(name, 'office'):
return self.pw.passwd[self.user].office
elif not cmp(name, 'officephone'):
return self.pw.passwd[self.user].officephone
elif not cmp(name, 'homephone'):
return self.pw.passwd[self.user].homephone
elif not cmp(name, 'homedir'):
return self.pw.passwd[self.user].homedir
elif not cmp(name, 'shell'):
return self.pw.passwd[self.user].shell
elif not cmp(name, 'lastchanged'):
if self.pw.shadowexists():
return self.pw.shadow[self.user].lastchanged
else:
return -1
elif not cmp(name, 'mindays'):
if self.pw.shadowexists():
return self.pw.shadow[self.user].mindays
else:
return -1
elif not cmp(name, 'maxdays'):
if self.pw.shadowexists():
return self.pw.shadow[self.user].maxdays
else:
return -1
elif not cmp(name, 'warndays'):
if self.pw.shadowexists():
return self.pw.shadow[self.user].warndays
else:
return -1
elif not cmp(name, 'gracedays'):
if self.pw.shadowexists():
return self.pw.shadow[self.user].gracedays
else:
return -1
elif not cmp(name, 'expires'):
if self.pw.shadowexists():
return self.pw.shadow[self.user].expires
else:
return -1
else:
raise AttributeError, name
def __setattr__(self, name, value):
if not cmp(name, 'pw') or not cmp(name, 'user'):
self.__dict__[name] = value
return None
if not self.pw.passwd.has_key(self.user):
raise AttributeError, self.user + ' has been deleted'
if not cmp(name, 'username'):
# username is not an lvalue...
raise AttributeError, name + ': key is immutable'
elif not cmp(name, 'password'):
if self.pw.shadow:
self.pw.shadow[self.user].password = value
else:
self.pw.passwd[self.user].password = value
elif not cmp(name, 'uid'):
self.pw.passwd[self.user].uid = value
elif not cmp(name, 'gid'):
self.pw.passwd[self.user].gid = value
elif not cmp(name, 'gecos'):
self.pw.passwd[self.user].gecos = value
elif not cmp(name, 'fullname'):
self.pw.passwd[self.user].fullname = value
elif not cmp(name, 'office'):
self.pw.passwd[self.user].office = value
elif not cmp(name, 'officephone'):
self.pw.passwd[self.user].officephone = value
elif not cmp(name, 'homephone'):
self.pw.passwd[self.user].homephone = value
elif not cmp(name, 'homedir'):
self.pw.passwd[self.user].homedir = value
elif not cmp(name, 'shell'):
self.pw.passwd[self.user].shell = value
elif not cmp(name, 'lastchanged'):
if self.pw.shadowexists():
self.pw.shadow[self.user].lastchanged = value
elif not cmp(name, 'mindays'):
if self.pw.shadowexists():
self.pw.shadow[self.user].mindays = value
elif not cmp(name, 'maxdays'):
if self.pw.shadowexists():
self.pw.shadow[self.user].maxdays = value
elif not cmp(name, 'warndays'):
if self.pw.shadowexists():
self.pw.shadow[self.user].warndays = value
elif not cmp(name, 'gracedays'):
if self.pw.shadowexists():
self.pw.shadow[self.user].gracedays = value
elif not cmp(name, 'expires'):
if self.pw.shadowexists():
self.pw.shadow[self.user].expires = value
else:
raise AttributeError, name
# ConfUnix()
# This class presents a data-oriented class which uses the ConfPasswd
# and ConfShadow classes (if /etc/shadow exists) to hold data.
# Designed to be replaced by a pwdb module eventually, we hope.