scripts/gestion/ldap_passwd.py
chove 65a8a6de58 la longueur des salt est variable... le script naceptait que les mots de
passes avec une salt de longueur 16... maintant il accepte tout, notament
les salt de longueur 4 comme ceux gnrs par la commande ldappasswd

darcs-hash:20060504174658-4ec08-732d56aaa54e5e9f660801b6943d0df756d1db42.gz
2006-05-04 19:46:58 +02:00

138 lines
4.8 KiB
Python

# -*- coding: iso8859-15 -*-
###############################################################################
# ldap_passwd.py : manipulation des mots de passes LDAP
# $Id: ldap_passwd.py,v 1.7 2006-05-04 17:46:58 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
algos={}
algos = {
'ssha':'Seeded SHA',
'sha':'Secure Hash Algorithm',
'md5':'MD5',
'smd5':'Seeded MD5',
'crypt':'standard unix crypt',
'cleartext':'clear text'
}
if smb:
algos['lmpassword'] = 'lan man hash'
algos['ntpassword'] = 'nt hash'
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=None):
''' Make a given password cryptated, possibly with different
crypt-algorihtms. This module was written for use with
LDAP - so default is seeded sha
'''
if salt == None:
salt = getsalt()
algo = algo.lower()
if algo not in algos.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)
elif algo == 'cleartext':
pwdhash = "{CLEARTEXT}" + pwd
return pwdhash.strip()
def checkpwd(pwd, pwdhash):
''' Check if the password matches the hash '''
algo = pwdhash[1:].split('}')[0]
algo = algo.lower()
if algo.startswith('samba'):
sambaver = 3
algo = algo[5:]
else:
sambaver = 2
if not algo in algos.keys():
raise TypeError, 'Algorithm <%s> not supported in this version.' % algo
if algos[algo].startswith('Seeded '):
salt = base64.decodestring(pwdhash.split('}')[1])[20:]
else:
salt = None
return mkpasswd(pwd, sambaver=sambaver, algo=algo, salt=salt) == pwdhash