|
#!/usr/bin/python |
|
|
|
# Used ideas from here, but perl + gssapi + ldap doesn't work on RHEL6 |
|
# http://www.sysadmin.org.au/index.php/2012/12/authorizedkeyscommand/ |
|
|
|
import pprint |
|
import ldap |
|
import ldap.sasl |
|
import os |
|
import socket |
|
import krbV |
|
from sys import argv |
|
import uuid |
|
|
|
#get username from command line |
|
script, username = argv |
|
|
|
#variables |
|
ccache_filename = '/tmp/'+str(uuid.uuid4()) |
|
principal = socket.gethostname().split('.')[0].upper()+"$" |
|
keytabfile = '/etc/krb5.keytab' |
|
ldapserver = 'ldap://dc.domain.com' |
|
tracelevel = 0 |
|
base_dn = 'ou=Staff,dc=domain,dc=com' |
|
filter = "(samaccountname=%s)" % username |
|
attributes = ['altSecurityIdentities' ] |
|
|
|
#instantiate keytab file into a kerberos ticket |
|
ccache_file = 'FILE:' + ccache_filename |
|
krbcontext = krbV.default_context() |
|
|
|
keytab = krbV.Keytab(name=keytabfile, context=krbcontext) |
|
|
|
principal = krbV.Principal(name=principal, context=krbcontext) |
|
os.environ['KRB5CCNAME'] = ccache_file |
|
|
|
cache = krbV.CCache(name=ccache_file, context=krbcontext,primary_principal=principal) |
|
|
|
cache.init(principal) |
|
#instantiated here: |
|
cache.init_creds_keytab(keytab=keytab, principal=principal) |
|
|
|
#spark up ldap connection |
|
conn=ldap.initialize(ldapserver,trace_level=tracelevel) |
|
|
|
conn.set_option(ldap.OPT_PROTOCOL_VERSION, ldap.VERSION3) |
|
conn.set_option(ldap.OPT_REFERRALS,0) |
|
|
|
#spark up sasl connection |
|
sasl = ldap.sasl.gssapi() |
|
|
|
#bind to ad with sasl |
|
conn.sasl_interactive_bind_s('', sasl) |
|
|
|
#do ad search |
|
results = conn.search_s( |
|
base_dn, |
|
ldap.SCOPE_SUBTREE, |
|
filter, |
|
attributes |
|
) |
|
|
|
#sort of useful debugging stuff. Won't work with running SSH env though. |
|
if tracelevel > 0: |
|
print len(results) |
|
print len(results[0][1]) |
|
pp = pprint.PrettyPrinter(indent=4) |
|
print |
|
print "full results:" |
|
pp.pprint(results) |
|
print |
|
print "only key:" |
|
pp.pprint(results[0][1]['altSecurityIdentities'][0]) |
|
print |
|
|
|
#python evaluates conditionals left to right, so: |
|
# ( handle no user ) ( handle user without ssh key set) |
|
if (len(results) > 0 and len(results[0][1]) > 0): |
|
for values in results[0][1]['altSecurityIdentities']: |
|
#Remove extra bit at beginning of key |
|
# -> used to namespace out key in AD |
|
# see website for why/how. |
|
output = values.replace("SSHKey:","") |
|
|
|
#print just key for SSH |
|
print output |
|
|
|
|
|
#clean up cache filename, so can't be trivially be borrowed by other things. |
|
os.unlink(ccache_filename) |
|
|