Date: Fri, 20 Mar 2009 05:50:02 GMT From: Toby Burress <kurin@delete.org> To: freebsd-doc@FreeBSD.org Subject: Re: docs/132839: Fix example script in ldap-auth Message-ID: <200903200550.n2K5o2ad049022@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
The following reply was made to PR docs/132839; it has been noted by GNATS. From: Toby Burress <kurin@delete.org> To: FreeBSD-gnats-submit@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 ---
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200903200550.n2K5o2ad049022>