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