# Administrate
#rootdn "uid=admin,ou=users,dc=debian,dc=org"
-#rootpw
+#rootpw
# Restrict reading/modification of the password to administration and self
-access to attrs=userpassword
+access to attrs=userpassword,sshrsaauthkey
by self write
by dn="uid=admin,ou=users,dc=debian,dc=org" write
- by * compare
+ by group="uid=admin,ou=users,dc=debian,dc=org" write
+ by * compare
-# Reading of eamil forward is restricted by machine
access to attrs=emailforward
by dn="uid=admin,ou=users,dc=debian,dc=org" write
+ by group="uid=admin,ou=users,dc=debian,dc=org" write
by self write
by addr=127.0.0.1 read
- by domain=.*\.debian\.org read
- by * none
-
-# Public self modifyable attributes
+ by domain=.*\.debian\.org read
+ by * none
access to attrs=c,l,loginShell,ircNick,labeledURL
by dn="uid=admin,ou=users,dc=debian,dc=org" write
+ by group="uid=admin,ou=users,dc=debian,dc=org" write
by self write
-
-# Private self modifyable fields that are still viewable by other users
-# in the directory.
-access to attrs=facsimileTelephoneNumber,telephoneNumber,postalAddress,postalCode,loginShell,onvacation
+access to attrs=facsimileTelephoneNumber,telephoneNumber,postalAddress,postalC
+ode,loginShell,onvacation,privateSub,latitude,longitude
by dn="uid=admin,ou=users,dc=debian,dc=org" write
+ by group="uid=admin,ou=users,dc=debian,dc=org" write
by self write
- by dn="uid=.*,ou=users,dc=debian,dc=org" read
- by * none
-
-# Remainder
+ by dn="uid=.*,ou=users,dc=debian,dc=org" read
+ by * none
access to *
by dn="uid=admin,ou=users,dc=debian,dc=org" write
+ by group="uid=admin,ou=users,dc=debian,dc=org" write
+
+# End----------
+
+Here is the initial seed file to import and setup the proper entries:
+
+dn: dc=org
+dc: net
+objectClass: top
+objectClass: domain
+
+dn: dc=debian,dc=org
+dc: visi
+objectClass: top
+objectClass: domain
+
+dn: ou=users,dc=debian,dc=org
+ou: users
+objectClass: top
+objectClass: organizationalUnit
+
+dn: uid=admin,ou=users,dc=debian,dc=org
+uid: admin
+cn: LDAP administrator
+objectClass: top
+objectClass: groupOfNames
+userPassword: {crypt}?????
+member: uid=jgg,ou=users,dc=debian,dc=org
+member: uid=joey,ou=users,dc=debian,dc=org
+member: uid=troup,ou=users,dc=debian,dc=org
+mail: debian-admin@debian.org
it() loginshell - Full path to the prefered Unix login shell. e.g. file(/bin/bash)
it() emailforward - Destination email address.
it() userpassword - Encrypted version of the password. [root]
+ it() sshrsaauthkey - SSH RSA public authentication key.
it() supplementarygid - A list of group names that the user belongs.
This field emulates the functionality of the traditional Unix group
file. [root]
[postalcode, postal address, lat/long] telephone numbers, and the vacation
message.
-Admin-only/maintainer-only information includes email forwarding and the
-encrypted password. Note that email forwarding is necessarily publicly viewable
-from accounts on the actual machines.
+Admin-only/user-only information includes email forwarding, ssh keys and
+the encrypted password. Note that email forwarding is necessarily publicly
+viewable from accounts on the actual machines.
manpagesection(LAT/LONG POSITION)
There are three possible formats for giving position information and several
graph and looking for people to sign keys, not for coordinates accurate
enough to land an ICBM on your doorstop!
-manpagesection(Editing Supplemental GIDs)
+manpagesection(EDITING SUPPLEMENTAL GIDS)
When the root function is activated then the supplemental GIDs can be
manipulated as a list of items. It is possible to add and remove items from
-the list by name. Proper prompts are given.
+the list by name. Proper prompts are given. A similar editing function is
+made available for the host acl list.
+
+manpagesection(ENCRYPTION PUBLIC KEYS)
+The directory associates two types of public encryption keys with the user,
+a PGP key fingerprint and a SSH RSA authentication key. It is not possible for
+a user to change their associated key fingerprint, that can only be done by
+the keyring maintainers after performing reasonable verification of the new
+key. Who ever controls the PGP key can make any modification to the LDAP
+account by using the PGP mail gateways.
+
+SSH RSA authentication keys are used by the SSH protocol to authenticate a
+user based on a cryptographic challenge. These keys pairs are created by the
+ssh-keygen program. The public version that is stored in the directory is
+generally placed in a file called identity.pub. SSH RSA authentication keys
+are password equivelents, whoever has the private half of the key can use it
+to login to any machine, but not affect changes to the LDAP entry. SSH
+authentication keys are kept private.
manpageoptions()
startdit()
Allowed = None;
CurrentHost = "";
+def Sanitize(Str):
+ return string.translate(Str,string.maketrans("\n\r\t","$$$"));
+
# See if this user is in the group list
def IsInGroup(DnRecord):
global Allowed,CurrentHost;
for x in PasswdAttrs:
if x[1].has_key("uidnumber") == 0 or IsInGroup(x) == 0:
continue;
-
+
+ # Do not let people try to buffer overflow some busted passwd parser.
+ if len(GetAttr(x,"gecos")) > 100 or len(GetAttr(x,"loginshell")) > 50:
+ continue;
+
Line = "%s:x:%s:%s:%s:%s%s:%s\n" % (GetAttr(x,"uid"),\
GetAttr(x,"uidnumber"),GetAttr(x,"gidnumber"),\
GetAttr(x,"gecos"),HomePrefix,GetAttr(x,"uid"),\
continue;
Pass = GetAttr(x,"userpassword");
- if Pass[0:7] != "{crypt}":
+ if Pass[0:7] != "{crypt}" or len(Pass) > 50:
Pass = '*';
else:
Pass = Pass[7:];
- Line = "%s:%s:%s:%s:%s:%s:%s:%s:\n" % (GetAttr(x,"uid"),\
+ Line = "%s:%s:%s:%s:%s:%s:%s:%s:" % (GetAttr(x,"uid"),\
Pass,GetAttr(x,"shadowlastchange"),\
GetAttr(x,"shadowmin"),GetAttr(x,"shadowmax"),\
GetAttr(x,"shadowwarning"),GetAttr(x,"shadowinactive"),\
GetAttr(x,"shadowexpire"));
+ Line = Sanitize(Line) + "\n";
F.write(Line);
Fdb.write("0%u %s" % (I,Line));
Fdb.write(".%s %s" % (GetAttr(x,"uid"),Line));
raise;
Done(File,F,Fdb);
+# Generate the shadow list
+def GenSSHShadow(l,File):
+ F = None;
+ Fdb = None;
+ try:
+ OldMask = os.umask(0077);
+ F = open(File + ".tmp","w",0600);
+ Fdb = None;
+ os.umask(OldMask);
+
+ # Fetch all the users
+ global PasswdAttrs;
+ if PasswdAttrs == None:
+ raise "No Users";
+
+ I = 0;
+ for x in PasswdAttrs:
+ if x[1].has_key("uidnumber") == 0 or IsInGroup(x) == 0 or \
+ x[1].has_key("sshrsaauthkey") == 0:
+ continue;
+ for I in x[1]["sshrsaauthkey"]:
+ Line = "%s: %s" %(GetAttr(x,"uid"),I);
+ Line = Sanitize(Line) + "\n";
+ F.write(Line);
+
+ # Oops, something unspeakable happened.
+ except:
+ Die(F,Fdb);
+ raise;
+ Done(File,F,Fdb);
+
# Generate the group list
def GenGroup(l,File):
F = None;
for I in GroupMap[x]:
Line = Line + ("%s%s" % (Comma,I));
Comma = ',';
- Line = Line + '\n';
+ Line = Sanitize(Line) + "\n";
F.write(Line);
Fdb.write("0%u %s" % (Counter,Line));
Fdb.write(".%s %s" % (x,Line));
for x in PasswdAttrs:
if x[1].has_key("emailforward") == 0 or IsInGroup(x) == 0:
continue;
- Line = "%s: %s\n" % (GetAttr(x,"uid"),GetAttr(x,"emailforward"));
+
+ # Do not allow people to try to buffer overflow busted parsers
+ if len(GetAttr(x,"emailforward")) > 200:
+ continue;
+
+ Line = "%s: %s" % (GetAttr(x,"uid"),GetAttr(x,"emailforward"));
+ Line = Sanitize(Line) + "\n";
F.write(Line);
# Oops, something unspeakable happened.
if x[1].has_key("latitude") == 0 or x[1].has_key("longitude") == 0:
continue;
try:
- F.write("%8s %8s \"\"\n"%(DecDegree(x,"latitude",1),DecDegree(x,"longitude",1)));
+ Line = "%8s %8s \"\""%(DecDegree(x,"latitude",1),DecDegree(x,"longitude",1));
+ Line = Sanitize(Line) + "\n";
+ F.write(Line);
except:
pass;
"gecos","loginshell","userpassword","shadowlastchange",\
"shadowmin","shadowmax","shadowwarning","shadowinactive",
"shadowexpire","emailforward","latitude","longitude",\
- "allowedhosts"]);
+ "allowedhosts","sshrsaauthkey"]);
# Open the control file
if len(sys.argv) == 1:
GenPasswd(l,OutDir+"passwd",Split[1]);
GenGroup(l,OutDir+"group");
GenShadow(l,OutDir+"shadow");
+ GenSSHShadow(l,OutDir+"ssh-rsa-shadow");
GenForward(l,OutDir+"forward-alias");
GenMarkers(l,OutDir+"markers");
print x,
print;
+# Print the SSH RSA Authentication keys for a user
+def PrintSshRSAKeys(Attrs):
+ if Attrs[1].has_key("sshrsaauthkey") == 0:
+ return;
+ First = 0;
+ for x in Attrs[1]["sshrsaauthkey"]:
+ if First == 0:
+ print "%-24s:" % ("SSH RSA Auth Keys"),
+ First = 1;
+ else:
+ print "%-24s:" % (""),
+ Split = string.split(x," ");
+
+ if len(Split) != 4:
+ del Split[0];
+ print Split[0],Split[1],Split[2][:8]+".."+Split[2][-8:],string.join(Split[3:]);
+
# Display all of the attributes in a numbered list
def ShowAttrs(Attrs):
print;
PrintModTime(Attrs);
PrintShadow(Attrs);
PrintKeys(Attrs);
+ PrintSshRSAKeys(Attrs);
for at in Attrs[1].keys():
if AttrInfo.has_key(at):
# Query the server for all of the attributes
Attrs = l.search_s(BaseDn,ldap.SCOPE_ONELEVEL,"uid=" + User);
+if len(Attrs) == 0:
+ print "User",User,"was not found.";
+ sys.exit(0);
# repeatedly show the account configuration
while(1):
NewUser = raw_input("User? ");
if NewUser == "":
continue;
+ NAttrs = l.search_s(BaseDn,ldap.SCOPE_ONELEVEL,"uid=" + NewUser);
+ if len(NAttrs) == 0:
+ print "User",NewUser,"was not found.";
+ continue;
+ Attrs = NAttrs;
User = NewUser;
UserDn = "uid=" + User + "," + BaseDn;
- Attrs = l.search_s(BaseDn,ldap.SCOPE_ONELEVEL,"uid=" + User);
OrderedIndex = copy.deepcopy(OrigOrderedIndex);
continue;