docs/132839: Fix example script in ldap-auth

Toby Burress kurin at delete.org
Fri Mar 20 05:50:03 UTC 2009


The following reply was made to PR docs/132839; it has been noted by GNATS.

From: Toby Burress <kurin at delete.org>
To: FreeBSD-gnats-submit at FreeBSD.org
Cc:  
Subject: Re: docs/132839: Fix example script in ldap-auth
Date: Fri, 20 Mar 2009 01:42:27 -0400

 Oops.  I just realized I had some typos, and I didn't use the
 standard example.org domain.  Revised patch follows.
 
 --- patch begins here ---
 --- article.sgml.old	2009-03-20 00:57:22.000000000 -0400
 +++ article.sgml	2009-03-20 01:03:08.000000000 -0400
 @@ -307,7 +307,6 @@
  	organizational unit will look like:</para>
  
        <programlisting>dn: ou=people,dc=example,dc=org
 -objectClass: top
  objectClass: organizationalUnit
  ou: people</programlisting>
  
 @@ -336,7 +335,6 @@
  objectClass: person
  objectClass: posixAccount
  objectClass: shadowAccount
 -objectClass: top
  uidNumber: 10000
  gidNumber: 10000
  homeDirectory: /home/tuser
 @@ -352,13 +350,11 @@
  	user entries, but we will use the defaults below:</para>
  
        <programlisting>dn: ou=groups,dc=example,dc=org
 -objectClass: top
  objectClass: organizationalUnit
  ou: groups
  
  dn: cn=tuser,ou=groups,dc=example,dc=org
  objectClass: posixGroup
 -objectClass: top
  gidNumber: 10000
  cn: tuser</programlisting>
  
 @@ -604,51 +600,74 @@
  	<screen>&prompt.root; <userinput>sysctl security.bsd.see_other_uids=0</userinput>.</screen>
        </caution>
  
 -      <para>A more flexible (and probably more secure) approach can be
 -	used by writing a custom program, or even a web interface.  The
 -	following is part of a <application>Ruby</application> library
 -	that can change LDAP passwords.  It sees use both on the command
 -	line, and on the web.</para>
 +  <para>A more flexible (and probably more secure) approach can be
 +	used by writing a custom program, or even a web interface.
 +	The following is modeled on a <application>Python</application>
 +	library that can change LDAP passwords.  It sees use both
 +	on the command line, and on the web.</para>
  
 -      <example id="chpw-ruby">
 -	<title>Ruby script for changing passwords</title>
 +      <example id="chpw-python">
 +	<title>Python script for changing passwords</title>
          
 -	<programlisting><![CDATA[require 'ldap'
 -require 'base64'
 -require 'digest'
 -require 'password' # ruby-password
 -
 -ldap_server = "ldap.example.org"
 -luser = "uid=#{ENV['USER']},ou=people,dc=example,dc=org"
 -
 -# get the new password, check it, and create a salted hash from it
 -def get_password
 -  pwd1 = Password.get("New Password: ")
 -  pwd2 = Password.get("Retype New Password: ")
 -
 -  raise if pwd1 != pwd2
 -  pwd1.check # check password strength
 -  
 -  salt = rand.to_s.gsub(/0\./, '')
 -  pass = pwd1.to_s
 -  hash = "{SSHA}"+Base64.encode64(Digest::SHA1.digest("#{pass}#{salt}")+salt).chomp!
 -  return hash
 -end
 -
 -oldp = Password.get("Old Password: ")
 -newp = get_password
 -
 -# We'll just replace it.  That we can bind proves that we either know
 -# the old password or are an admin.
 -
 -replace = LDAP::Mod.new(LDAP::LDAP_MOD_REPLACE | LDAP::LDAP_MOD_BVALUES,
 -                        "userPassword",
 -                        [newp])
 -
 -conn = LDAP::SSLConn.new(ldap_server, 389, true)
 -conn.set_option(LDAP::LDAP_OPT_PROTOCOL_VERSION, 3)
 -conn.bind(luser, oldp)
 -conn.modify(luser, [replace])]]></programlisting>
 +	<programlisting><![CDATA[import ldap # python-ldap
 +import os, sys
 +from getpass import getpass
 +
 +uri = "ldap://ldap1.example.org"
 +searchbase = "ou=people,dc=example,dc=org"
 +filter = "(&(objectClass=posixAccount)(uid=%s))"
 +
 +# get the username; if none is given, use the current user
 +user = os.environ['USER']
 +if len(sys.argv) > 1:
 +    user = sys.argv[1]
 +
 +ldapobj = ldap.initialize(uri)
 +ldapobj.start_tls_s() # this is pretty important
 +
 +# Get the users DN, and then bind as that.
 +# The way to do this is first bind anonymously (if you don't allow anon
 +# binds, there's probably some standard account you use for this).
 +ldapobj.simple_bind_s()
 +
 +# Search for a user with the uid we gave.  We search everything under
 +# the "base" we configure above (as there may be other users with the same
 +# UID elsewhere in the tree; we don't want to return those).
 +result = ldapobj.search_s(searchbase, ldap.SCOPE_SUBTREE, filter%user)
 +
 +if len(result) > 1:
 +    # This is kind of suspicious; we only want one user.
 +    print "I found several users that match that user id."
 +    print "Talk to your sysadmin."
 +    sys.exit(1)
 +
 +# The results are an array of (dn, attrlist) tuples.
 +dn = result[0][0]
 +
 +# Now we get the user's old password, and bind to the server with it
 +# and his DN.  If it succeeds, he (and we) have the proper credentials to
 +# change his password.
 +passwd = getpass("current password: ")
 +try:
 +    ldapobj.simple_bind_s(dn, passwd)
 +except ldap.INVALID_CREDENTIALS:
 +    print "Bad password."
 +    sys.exit(1)
 +
 +# Get and confirm new password.
 +npass1 = 'a'
 +npass2 = 'b'
 +while npass1 != npass2:
 +    npass1 = getpass("new password: ")
 +    npass2 = getpass("new password (again): ")
 +
 +# This is the key.  This uses the LDAP Password Modify Extended Operation.
 +# It is important to use this when you can, although not all libraries
 +# (e.g. ruby-ldap) support it.  See rfc3062.
 +ldapobj.passwd_s(dn, passwd, npass1)
 +
 +# And we're done.
 +ldapobj.unbind()]]></programlisting>
        </example>
  
        <para>Although not guaranteed to be free of security holes (the
 @@ -759,7 +778,6 @@
  	  <title>Creating a management group</title>
  
  	  <programlisting>dn: cn=homemanagement,dc=example,dc=org
 -objectClass: top
  objectClass: posixGroup
  cn: homemanagement
  gidNumber: 121 # required for posixGroup
 --- patch ends here ---



More information about the freebsd-doc mailing list