[Date Prev][Date Next] [Chronological] [Thread] [Top]

openldap/sasl/krb5 authentication question:



So, I'd like to do all of my authenticating via krb5 with openldap.  I've 
been working on getting a kerberos service ticket from the kdc using 
GSSAPI, and I've finally had much success doing that.  However, now, when 
I get the service ticket, I can't write to the database.  I'm using stock 
patched Red Hat 9 across the board.  I'm using 
openldap-*-2.0.27-8
cyrus-sasl-*-2.1.10-4
krb5-*-1.2.7-14

Here's the relavant config files:

]# more /etc/openldap/slapd.conf
# $OpenLDAP: pkg/ldap/servers/slapd/slapd.conf,v 1.8.8.7 2001/09/27 
20:00:31 kur
t Exp $
#
# See slapd.conf(5) for details on configuration options.
# This file should NOT be world readable.
#
include         /etc/openldap/schema/core.schema
include         /etc/openldap/schema/cosine.schema
include         /etc/openldap/schema/inetorgperson.schema
include         /etc/openldap/schema/nis.schema
include         /etc/openldap/schema/redhat/rfc822-MailMember.schema
include         /etc/openldap/schema/redhat/autofs.schema
#include                /etc/openldap/schema/redhat/kerberosobject.schema

# Define global ACLs to disable default read access.

# Do not enable referrals until AFTER you have a working directory
# service AND an understanding of referrals.
#referral       ldap://root.openldap.org
#loglevel               552
loglevel                -1
pidfile         /var/run/slapd.pid
argsfile        /var/run/slapd.args

# Create a replication log in /var/lib/ldap for use by slurpd.
#replogfile     /var/lib/ldap/master-slapd.replog

# Load dynamic backend modules:
# modulepath    /usr/sbin/openldap
# moduleload    back_ldap.la
# moduleload    back_ldbm.la
# moduleload    back_passwd.la
# moduleload    back_shell.la

#
# The next three lines allow use of TLS for connections using a dummy test
# certificate, but you should generate a proper certificate by changing to
# /usr/share/ssl/certs, running "make slapd.pem", and fixing permissions 
on
# slapd.pem so that the ldap user or group can read it.
 TLSCipherSuite HIGH:MEDIUM:+SSLv2 
 TLSCertificateFile /usr/share/ssl/certs/slapd.pem
 TLSCertificateKeyFile /usr/share/ssl/certs/newkey.pem
 TLSCACertificateFile /usr/share/ssl/certs/ca-bundle.crt
 TLSVerityClient demand
sasl-host ldap.blah.edu
sasl-realm LSA.UMICH.EDU
#sasl-secprops noplain,noanonymous,minssf=56,maxssf=56

#######################################################################
# ldbm database definitions
#######################################################################

database        ldbm
suffix          "dc=blah,dc=edu"
#suffix         "o=My Organization Name,c=US"
rootdn          "uid=astrldapadmin,realm=LSA.UMICH.EDU,cn=gssapi,cn=auth"
# Cleartext passwords, especially for the rootdn, should
# be avoided.  See slappasswd(8) and slapd.conf(5) for details.
# Use of strong authentication encouraged.
# rootpw                secret
#rootpw  {SSHA}fpGzGx5vDjeR674L7txcsAX+UgHXFEd6
sasl-regexp
     uid=(.*),cn=LSA.UMICH.EDU,cn=gssapi,cn=auth
     uid=$1,ou=admin,dc=blah,dc=edu

# The database directory MUST exist prior to running slapd AND 
# should only be accessible by the slapd/tools. Mode 700 recommended.
directory       /var/lib/ldap
mode            0600
#defaultaccess   search
# Indices to maintain
index   objectClass,uid,uidNumber,gidNumber,memberUid   eq
index   cn,mail,surname,givenname                       eq,subinitial

# Replicas to which we should propagate changes
#replica host=ldap-1.example.com:389 tls=yes
#       bindmethod=sasl saslmech=GSSAPI
#       authcId=host/ldap-master.example.com@EXAMPLE.COM


---



Here's what I'm trying to do.


I'm trying to create a testuser:

dn: cn=testuser,ou=people,dc=blah,dc=edu
cn: testuser
sn: test
objectclass: person

with the command:

ldapmodify -v  -a -H ldap://ldap/  -f testuser.ldif

I kinit with the proper account:

# klist
Ticket cache: FILE:/tmp/krb5cc_0
Default principal: astrldapadmin@LSA.UMICH.EDU

Valid starting     Expires            Service principal
12/18/03 10:55:27  12/18/03 20:53:58  krbtgt/LSA.UMICH.EDU@LSA.UMICH.EDU

and when I type in the proper invocation:

# ldapmodify -v  -a -H ldap://ldap/  -f testuser.ldif
ldap_initialize( ldap://ldap/ )
SASL/GSSAPI authentication started
SASL SSF: 56
SASL installing layers
add cn:
        testuser
add sn:
        test
add objectclass:
        person
adding new entry "cn=testuser,ou=people,dc=blah,dc=edu"
ldap_add: Insufficient access
        additional info: no write access to parent

ldif_record() = 50

afterward klist shows:

# klist
Ticket cache: FILE:/tmp/krb5cc_0
Default principal: astrldapadmin@LSA.UMICH.EDU

Valid starting     Expires            Service principal
12/18/03 10:55:27  12/18/03 20:53:58  krbtgt/LSA.UMICH.EDU@LSA.UMICH.EDU
12/18/03 10:56:21  12/18/03 20:53:58  ldap/machine@LSA.UMICH.EDU


So I know that GSSAPI is doing it's business, right?   So what's not 
getting the proper authentication to the ldap server?  I think I'm 
confused here.  astrldapadmin, as the admin account should have write 
access, right?  So I'm correct in assuming that, for some reason, it's not 
thinking I'm admin, correct?  Any hints as to what I'm doing wrong? I have 
a very long log entry in ldap for this particular 
instance, if you are so interested, below:  Thanks for any help you can 
give:



Dec 18 11:03:22 selune slapd[18275]: daemon: activity on 1 descriptors 
Dec 18 11:03:22 selune slapd[18275]: daemon: new connection on 7 
Dec 18 11:03:22 selune slapd[18275]: daemon: conn=0 fd=7 connection from 
IP=141.211.xxx.xxx:1169 (IP=0.0.0.0:389) accepted. 
Dec 18 11:03:22 selune slapd[18275]: daemon: added 7r 
Dec 18 11:03:22 selune slapd[18275]: daemon: activity on:
Dec 18 11:03:22 selune slapd[18275]:  
Dec 18 11:03:22 selune slapd[18275]: daemon: select: listen=6 
active_threads=0 tvp=NULL 
Dec 18 11:03:22 selune slapd[18275]: daemon: activity on 1 descriptors 
Dec 18 11:03:22 selune slapd[18275]: daemon: activity on:
Dec 18 11:03:22 selune slapd[18275]:  7r
Dec 18 11:03:22 selune slapd[18275]:  
Dec 18 11:03:22 selune slapd[18275]: daemon: read activity on 7 
Dec 18 11:03:22 selune slapd[18275]: connection_get(7) 
Dec 18 11:03:22 selune slapd[18275]: connection_get(7): got connid=0 
Dec 18 11:03:22 selune slapd[18275]: connection_read(7): checking for 
input on id=0 
Dec 18 11:03:22 selune slapd[18275]: do_search 
Dec 18 11:03:22 selune slapd[18275]: SRCH "" 0 0
Dec 18 11:03:22 selune slapd[18275]: ber_get_next on fd 7 failed errno=11 
(Resource temporarily unavailable) 
Dec 18 11:03:22 selune slapd[18275]:     0 0 0 
Dec 18 11:03:22 selune slapd[18275]: daemon: select: listen=6 
active_threads=1 tvp=NULL 
Dec 18 11:03:22 selune slapd[18275]: begin get_filter 
Dec 18 11:03:22 selune slapd[18275]: PRESENT 
Dec 18 11:03:22 selune slapd[18275]: end get_filter 0 
Dec 18 11:03:22 selune slapd[18275]:     filter: (objectClass=*) 
Dec 18 11:03:22 selune slapd[18275]:     attrs:
Dec 18 11:03:22 selune slapd[18275]:  supportedSASLMechanisms
Dec 18 11:03:22 selune slapd[18275]:  
Dec 18 11:03:22 selune slapd[18275]: conn=0 op=0 SRCH base="" scope=0 
filter="(objectClass=*)" 
Dec 18 11:03:22 selune slapd[18275]: => test_filter 
Dec 18 11:03:22 selune slapd[18275]:     PRESENT 
Dec 18 11:03:22 selune slapd[18275]: => access_allowed: search access to 
"" "objectClass" requested 
Dec 18 11:03:22 selune slapd[18275]: => access_allowed: backend default 
search access granted to "" 
Dec 18 11:03:22 selune slapd[18275]: <= test_filter 6 
Dec 18 11:03:22 selune slapd[18275]: => send_search_entry: "" 
Dec 18 11:03:22 selune slapd[18275]: => access_allowed: read access to "" 
"entry" requested 
Dec 18 11:03:22 selune slapd[18275]: => access_allowed: backend default 
read access granted to "" 
Dec 18 11:03:22 selune slapd[18275]: => access_allowed: read access to "" 
"supportedSASLMechanisms" requested 
Dec 18 11:03:22 selune slapd[18275]: => access_allowed: backend default 
read access granted to "" 
Dec 18 11:03:22 selune slapd[18275]: => access_allowed: read access to "" 
"supportedSASLMechanisms" requested 
Dec 18 11:03:22 selune slapd[18275]: => access_allowed: backend default 
read access granted to "" 
Dec 18 11:03:22 selune slapd[18275]: conn=0 op=0 ENTRY dn="" 
Dec 18 11:03:22 selune slapd[18275]: <= send_search_entry 
Dec 18 11:03:22 selune slapd[18275]: send_ldap_result: conn=0 op=0 p=3 
Dec 18 11:03:22 selune slapd[18275]: send_ldap_result: 0:: 
Dec 18 11:03:22 selune slapd[18275]: send_ldap_response: msgid=1 tag=101 
err=0 
Dec 18 11:03:22 selune slapd[18275]: conn=0 op=0 RESULT tag=101 err=0 
text= 
Dec 18 11:03:22 selune slapd[18275]: daemon: activity on 1 descriptors 
Dec 18 11:03:22 selune slapd[18275]: daemon: activity on:
Dec 18 11:03:22 selune slapd[18275]:  7r
Dec 18 11:03:22 selune slapd[18275]:  
Dec 18 11:03:22 selune slapd[18275]: daemon: read activity on 7 
Dec 18 11:03:22 selune slapd[18275]: connection_get(7) 
Dec 18 11:03:22 selune slapd[18275]: connection_get(7): got connid=0 
Dec 18 11:03:22 selune slapd[18275]: connection_read(7): checking for 
input on id=0 
Dec 18 11:03:22 selune slapd[18275]: ber_get_next on fd 7 failed errno=11 
(Resource temporarily unavailable) 
Dec 18 11:03:22 selune slapd[18275]: do_bind 
Dec 18 11:03:22 selune slapd[18275]: do_sasl_bind: dn () mech GSSAPI 
Dec 18 11:03:22 selune slapd[18275]: conn=0 op=1 BIND dn="" method=163 
Dec 18 11:03:22 selune slapd[18275]: ==> sasl_bind: dn="" mech=GSSAPI 
datalen=508 
Dec 18 11:03:22 selune slapd[18275]: daemon: select: listen=6 
active_threads=1 tvp=NULL 
Dec 18 11:03:22 selune slapd[18275]: send_ldap_sasl: err=14 len=106 
Dec 18 11:03:22 selune slapd[18275]: send_ldap_response: msgid=2 tag=97 
err=14 
Dec 18 11:03:22 selune slapd[18275]: <== slap_sasl_bind: rc=14 
Dec 18 11:03:22 selune slapd[18275]: daemon: activity on 1 descriptors 
Dec 18 11:03:22 selune slapd[18275]: daemon: activity on:
Dec 18 11:03:22 selune slapd[18275]:  7r
Dec 18 11:03:22 selune slapd[18275]:  
Dec 18 11:03:22 selune slapd[18275]: daemon: read activity on 7 
Dec 18 11:03:22 selune slapd[18275]: connection_get(7) 
Dec 18 11:03:22 selune slapd[18275]: connection_get(7): got connid=0 
Dec 18 11:03:22 selune slapd[18275]: connection_read(7): checking for 
input on id=0 
Dec 18 11:03:22 selune slapd[18275]: ber_get_next on fd 7 failed errno=11 
(Resource temporarily unavailable) 
Dec 18 11:03:22 selune slapd[18275]: do_bind 
Dec 18 11:03:22 selune slapd[18275]: daemon: select: listen=6 
active_threads=1 tvp=NULL 
Dec 18 11:03:22 selune slapd[18275]: do_sasl_bind: dn () mech GSSAPI 
Dec 18 11:03:22 selune slapd[18275]: conn=0 op=2 BIND dn="" method=163 
Dec 18 11:03:22 selune slapd[18275]: ==> sasl_bind: dn="" 
mech=<continuing> datalen=0 
Dec 18 11:03:22 selune slapd[18275]: send_ldap_sasl: err=14 len=53 
Dec 18 11:03:22 selune slapd[18275]: send_ldap_response: msgid=3 tag=97 
err=14 
Dec 18 11:03:22 selune slapd[18275]: <== slap_sasl_bind: rc=14 
Dec 18 11:03:22 selune slapd[18275]: daemon: activity on 1 descriptors 
Dec 18 11:03:22 selune slapd[18275]: daemon: activity on:
Dec 18 11:03:22 selune slapd[18275]:  7r
Dec 18 11:03:22 selune slapd[18275]:  
Dec 18 11:03:22 selune slapd[18275]: daemon: read activity on 7 
Dec 18 11:03:22 selune slapd[18275]: connection_get(7) 
Dec 18 11:03:22 selune slapd[18275]: connection_get(7): got connid=0 
Dec 18 11:03:22 selune slapd[18275]: connection_read(7): checking for 
input on id=0 
Dec 18 11:03:22 selune slapd[18275]: ber_get_next on fd 7 failed errno=11 
(Resource temporarily unavailable) 
Dec 18 11:03:22 selune slapd[18275]: do_bind 
Dec 18 11:03:22 selune slapd[18275]: daemon: select: listen=6 
active_threads=1 tvp=NULL 
Dec 18 11:03:22 selune slapd[18275]: do_sasl_bind: dn () mech GSSAPI 
Dec 18 11:03:22 selune slapd[18275]: conn=0 op=3 BIND dn="" method=163 
Dec 18 11:03:22 selune slapd[18275]: ==> sasl_bind: dn="" 
mech=<continuing> datalen=53 
Dec 18 11:03:22 selune slapd[18275]: SASL Authorize [conn=0]: 
authcid="astrldapadmin" authzid="<empty>" 
Dec 18 11:03:22 selune slapd[18275]: SASL Authorize [conn=0]: 
"astrldapadmin" as "u:astrldapadmin" 
Dec 18 11:03:22 selune slapd[18275]: slap_sasl_bind: 
username="u:astrldapadmin" realm="LSA.UMICH.EDU" ssf=56 
Dec 18 11:03:22 selune slapd[18275]: <== slap_sasl_bind: authzdn: 
"uid=astrldapadmin + realm=LSA.UMICH.EDU" 
Dec 18 11:03:22 selune slapd[18275]: send_ldap_sasl: err=0 len=-1 
Dec 18 11:03:22 selune slapd[18275]: send_ldap_response: msgid=4 tag=97 
err=0 
Dec 18 11:03:22 selune slapd[18275]: <== slap_sasl_bind: rc=0 
Dec 18 11:03:22 selune slapd[18275]: daemon: activity on 1 descriptors 
Dec 18 11:03:22 selune slapd[18275]: daemon: activity on:
Dec 18 11:03:22 selune slapd[18275]:  7r
Dec 18 11:03:22 selune slapd[18275]:  
Dec 18 11:03:22 selune slapd[18275]: daemon: read activity on 7 
Dec 18 11:03:22 selune slapd[18275]: connection_get(7) 
Dec 18 11:03:22 selune slapd[18275]: connection_get(7): got connid=0 
Dec 18 11:03:22 selune slapd[18275]: connection_read(7): checking for 
input on id=0 
Dec 18 11:03:22 selune slapd[18275]: ber_get_next on fd 7 failed errno=11 
(Resource temporarily unavailable) 
Dec 18 11:03:22 selune slapd[18275]: do_add 
Dec 18 11:03:22 selune slapd[18275]: daemon: select: listen=6 
active_threads=1 tvp=NULL 
Dec 18 11:03:22 selune slapd[18275]: do_add: ndn 
(CN=TESTUSER,OU=PEOPLE,DC=BLAH,DC=EDU) 
Dec 18 11:03:22 selune slapd[18275]: conn=0 op=4 ADD 
dn="CN=TESTUSER,OU=PEOPLE,DC=BLAH,DC=EDU" 
Dec 18 11:03:22 selune slapd[18275]: dn2entry_r: dn: 
"CN=TESTUSER,OU=PEOPLE,DC=BLAH,DC=EDU" 
Dec 18 11:03:22 selune slapd[18275]: => dn2id( 
"CN=TESTUSER,OU=PEOPLE,DC=BLAH,DC=EDU" ) 
Dec 18 11:03:22 selune slapd[18275]: => ldbm_cache_open( "dn2id.dbb", 9, 
600 ) 
Dec 18 11:03:22 selune slapd[18275]: ldbm_cache_open (blksize 8192) 
(maxids 2046) (maxindirect 5) 
Dec 18 11:03:22 selune slapd[18275]: <= ldbm_cache_open (opened 0) 
Dec 18 11:03:22 selune slapd[18275]: <= dn2id NOID 
Dec 18 11:03:22 selune slapd[18275]: dn2entry_r: dn: 
"OU=PEOPLE,DC=BLAH,DC=EDU" 
Dec 18 11:03:22 selune slapd[18275]: => dn2id( 
"OU=PEOPLE,DC=BLAH,DC=EDU" ) 
Dec 18 11:03:22 selune slapd[18275]: => ldbm_cache_open( "dn2id.dbb", 9, 
600 ) 
Dec 18 11:03:22 selune slapd[18275]: <= ldbm_cache_open (cache 0) 
Dec 18 11:03:22 selune slapd[18275]: <= dn2id 229 
Dec 18 11:03:22 selune slapd[18275]: => id2entry_r( 229 ) 
Dec 18 11:03:22 selune slapd[18275]: => ldbm_cache_open( "id2entry.dbb", 
9, 600 ) 
Dec 18 11:03:22 selune slapd[18275]: ldbm_cache_open (blksize 8192) 
(maxids 2046) (maxindirect 5) 
Dec 18 11:03:22 selune slapd[18275]: <= ldbm_cache_open (opened 1) 
Dec 18 11:03:22 selune slapd[18275]: => str2entry 
Dec 18 11:03:22 selune slapd[18275]: <= 
str2entry(ou=people,dc=blah,dc=edu) -> -1 (0x81785c8) 
Dec 18 11:03:22 selune slapd[18275]: <= id2entry_r( 229 ) 0x81785c8 (disk) 
Dec 18 11:03:22 selune slapd[18275]: ldbm_referrals: op=104 
target="cn=testuser,ou=people,dc=blah,dc=edu" 
matched="ou=people,dc=blah,dc=edu" 
Dec 18 11:03:22 selune slapd[18275]: ====> cache_return_entry_r( 229 ): 
created (0) 
Dec 18 11:03:22 selune slapd[18275]: ==> ldbm_back_add: 
cn=testuser,ou=people,dc=blah,dc=edu 
Dec 18 11:03:22 selune slapd[18275]: => dn2id( 
"CN=TESTUSER,OU=PEOPLE,DC=BLAH,DC=EDU" ) 
Dec 18 11:03:22 selune slapd[18275]: => ldbm_cache_open( "dn2id.dbb", 9, 
600 ) 
Dec 18 11:03:22 selune slapd[18275]: <= ldbm_cache_open (cache 0) 
Dec 18 11:03:22 selune slapd[18275]: <= dn2id NOID 
Dec 18 11:03:22 selune slapd[18275]: oc_check_required entry 
(cn=testuser,ou=people,dc=blah,dc=edu), objectClass "person" 
Dec 18 11:03:22 selune slapd[18275]: oc_check_allowed type "cn" 
Dec 18 11:03:22 selune slapd[18275]: oc_check_allowed type "sn" 
Dec 18 11:03:22 selune slapd[18275]: oc_check_allowed type "objectClass" 
Dec 18 11:03:22 selune slapd[18275]: oc_check_allowed type "creatorsName" 
Dec 18 11:03:22 selune slapd[18275]: oc_check_allowed type 
"createTimestamp" 
Dec 18 11:03:22 selune slapd[18275]: oc_check_allowed type "modifiersName" 
Dec 18 11:03:22 selune slapd[18275]: oc_check_allowed type 
"modifyTimestamp" 
Dec 18 11:03:22 selune slapd[18275]: dn2entry_w: dn: 
"OU=PEOPLE,DC=BLAH,DC=EDU" 
Dec 18 11:03:22 selune slapd[18275]: => dn2id( 
"OU=PEOPLE,DC=BLAH,DC=EDU" ) 
Dec 18 11:03:22 selune slapd[18275]: ====> 
cache_find_entry_dn2id("OU=PEOPLE,DC=BLAH,DC=EDU"): 229 (1 
tries) 
Dec 18 11:03:22 selune slapd[18275]: <= dn2id 229 (in cache) 
Dec 18 11:03:22 selune slapd[18275]: => id2entry_w( 229 ) 
Dec 18 11:03:22 selune slapd[18275]: ====> cache_find_entry_id( 229 ) 
"ou=people,dc=blah,dc=edu" (found) (1 tries) 
Dec 18 11:03:22 selune slapd[18275]: <= id2entry_w( 229 ) 0x81785c8 
(cache) 
Dec 18 11:03:22 selune slapd[18275]: => access_allowed: write access to 
"ou=people,dc=blah,dc=edu" "children" requested 
Dec 18 11:03:22 selune slapd[18275]: => access_allowed: backend default 
write access denied to "uid=astrldapadmin + realm=LSA.UMICH.EDU" 
Dec 18 11:03:22 selune slapd[18275]: ====> cache_return_entry_w( 229 ): 
returned (0) 
Dec 18 11:03:22 selune slapd[18275]: no write access to parent 
Dec 18 11:03:22 selune slapd[18275]: send_ldap_result: conn=0 op=4 p=3 
Dec 18 11:03:22 selune slapd[18275]: send_ldap_result: 50::no write access 
to parent 
Dec 18 11:03:22 selune slapd[18275]: send_ldap_response: msgid=5 tag=105 
err=50 
Dec 18 11:03:22 selune slapd[18275]: conn=0 op=4 RESULT tag=105 err=50 
text=no write access to parent 
Dec 18 11:03:22 selune slapd[18275]: daemon: activity on 1 descriptors 
Dec 18 11:03:22 selune slapd[18275]: daemon: activity on:
Dec 18 11:03:22 selune slapd[18275]:  7r
Dec 18 11:03:22 selune slapd[18275]:  
Dec 18 11:03:22 selune slapd[18275]: daemon: read activity on 7 
Dec 18 11:03:22 selune slapd[18275]: connection_get(7) 
Dec 18 11:03:22 selune slapd[18275]: connection_get(7): got connid=0 
Dec 18 11:03:22 selune slapd[18275]: connection_read(7): checking for 
input on id=0 
Dec 18 11:03:22 selune slapd[18275]: ber_get_next on fd 7 failed errno=0 
(Success) 
Dec 18 11:03:22 selune slapd[18275]: connection_read(7): input error=-2 
id=0, closing. 
Dec 18 11:03:22 selune slapd[18275]: connection_closing: readying conn=0 
sd=7 for close 
Dec 18 11:03:22 selune slapd[18275]: connection_close: deferring conn=0 
sd=7 
Dec 18 11:03:22 selune slapd[18275]: do_unbind 
Dec 18 11:03:22 selune slapd[18275]: daemon: select: listen=6 
active_threads=1 tvp=NULL 
Dec 18 11:03:22 selune slapd[18275]: daemon: activity on 1 descriptors 
Dec 18 11:03:22 selune slapd[18275]: daemon: select: listen=6 
active_threads=1 tvp=NULL 
Dec 18 11:03:22 selune slapd[18275]: conn=0 op=5 UNBIND 
Dec 18 11:03:22 selune slapd[18275]: connection_resched: attempting 
closing conn=0 sd=7 
Dec 18 11:03:22 selune slapd[18275]: connection_close: conn=0 sd=7 
Dec 18 11:03:22 selune slapd[18275]: daemon: removing 7 
Dec 18 11:03:22 selune slapd[18275]: conn=-1 fd=7 closed 


-- 
--
+================================================================+
  Jeremy Hallum, System Manager , Astronomy, University of Michigan
              jhallum@umich.edu::jhallum@dreamt.org
                    "Audentis Fortuna Iuvat"