scripts/gestion/ldap_passwd.py
chove 0c43bc40d8 crypt s'crit en minuscules contrairement aux autres methodes cites
pour infor, les anciens mot de passes sont en crypt,
certains sont en SMD5
d'autres sont en SSHA (les nouveaux)

darcs-hash:20060428000109-4ec08-3efc6459d169a2a85498f5dc23a86b041b6ca002.gz
2006-04-28 02:01:09 +02:00

141 lines
4.9 KiB
Python

# -*- coding: iso8859-15 -*-
###############################################################################
# ldap_passwd.py : manipulation des mots de passes LDAP
# $Id: ldap_passwd.py,v 1.2 2006-04-28 00:01:09 chove Exp $
###############################################################################
# The authors of this code are
# Bjorn Ove Grotan <bgrotan@grotan.com>
# Etienne Chové <etienne.chove@crans.org>
#
# Copyright (C) 2005 Bjorn Ove Grotan
# Copyright (C) 2006 Etienne Chové
# All rights reserved.
#
# 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
###############################################################################
# For extra strength passwords, we wanted SSHA in our LDAP-environment
# as the standard python-module 'sha' does not support ssha, but this can
# easily be implemented with a few extra functions.
#
# SSHA can be described as:
# the SHA1-digest of a password with a sequence of "salt" bytes, where
# the bytes are randomly chosen - followed by the same salt bytes
# For LDAP-use, the SHA1 and SSHA-digest has to be base64-encoded.
#
# Example-LDIF:
# {SSHA}oaEG3PJ10sHxGcSxsDRRooTifL55/2NOdN3nU1VEV+NFzc9Q
#
# This package should now support passwords compatible with [1] Samba using the [2]
# smbpasswd module for [3] Python. The samba compability is added for use with Samba
# as PDC with storing user and host-information in LDAP.
#
# [1] http://www.samba.org
# [2] http://barryp.org/software/py-smbpasswd/
# [3] http://www.python.org
import string,base64
import random,sys
import exceptions
import md5,sha,crypt
try:
import smbpasswd
smb = True
except:
smb = False
def getsalt(chars=string.letters+string.digits, length=16):
''' Generate a random salt. Default length is 16 '''
salt = ''
for i in range(int(length)):
salt += random.choice(chars)
return salt
def mkpasswd(pwd, sambaver=3, algo='SSHA', salt=getsalt()):
''' Make a given password cryptated, possibly with different
crypt-algorihtms. This module was written for use with
LDAP - so default is seeded sha
'''
alg = {
'SSHA':'Seeded SHA',
'SHA':'Secure Hash Algorithm',
'MD5':'MD5',
'SMD5':'Seeded MD5',
'crypt':'standard unix crypt'
}
if smb:
alg['LMPassword'] = 'lan man hash'
alg['NTPassword'] = 'nt hash'
if algo not in alg.keys():
raise TypeError, 'Algorithm <%s> not supported in this version.' % algo
if algo == 'SSHA':
pwdhash = "{SSHA}" + base64.encodestring(sha.new(str(pwd) + salt).digest() + salt)
elif algo =='SHA':
pwdhash = "{SHA}" + base64.encodestring(sha.new(str(pwd)).digest())
elif algo =='MD5':
pwdhash = "{MD5}" + base64.encodestring(md5.new(str(pwd)).digest())
elif algo == 'SMD5':
pwdhash = "{SMD5}" + base64.encodestring(md5.new(str(pwd) + salt).digest() + salt)
elif algo =='crypt':
pwdhash = "{crypt}" + crypt.crypt(str(pwd),getsalt(length=2)) # crypt only uses a salt of length 2
elif algo == 'LMPassword':
if sambaver==3:
pwdhash = "{sambaLMPassword}" + smbpasswd.lmhash(pwd)
elif sambaver==2:
pwdhash = "{lmPassword}" + smbpasswd.lmhash(pwd)
elif algo == 'NTPassword':
if sambaver == 3:
pwdhash = "{sambaNTPassword}" + smbpasswd.lmhash(pwd)
elif sambaver == 2:
pwdhash = "{NTPassword}" + smbpasswd.lmhash(pwd)
return pwdhash.strip()
def checkpwd(pwd, pwdhash):
''' Check if the password matches the hash '''
alg = {
'SSHA':'Seeded SHA',
'SHA':'Secure Hash Algorithm',
'MD5':'MD5',
'SMD5':'Seeded MD5',
'crypt':'standard unix crypt'
}
if smb:
alg['LMPassword'] = 'lan man hash'
alg['NTPassword'] = 'nt hash'
algo = pwdhash[1:].split('}')[0]
if algo.startswith('samba'):
sambaver = 3
algo = algo[5:]
else:
sambaver = 2
if not algo in alg.keys():
raise TypeError, 'Algorithm <%s> not supported in this version.' % algo
if alg[algo].startswith('Seeded '):
salt = base64.decodestring(pwdhash.split('}')[1])[-16:]
else:
salt = None
return mkpasswd(pwd, sambaver=sambaver, algo=algo, salt=salt) == pwdhash