summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGerald Carter <jerry@samba.org>2001-12-26 05:35:40 +0000
committerGerald Carter <jerry@samba.org>2001-12-26 05:35:40 +0000
commitb6bbc39204a4676922099ab78b6c48009266d1bb (patch)
tree3307ed65ee88888b0f71aa84b00383de07ae3d7e
parent480b5c815864d35196053016b7bbcb2fe7f65ece (diff)
downloadsamba-b6bbc39204a4676922099ab78b6c48009266d1bb.tar.gz
samba-b6bbc39204a4676922099ab78b6c48009266d1bb.tar.bz2
samba-b6bbc39204a4676922099ab78b6c48009266d1bb.zip
sync with 2.2
(This used to be commit aca58b0b72d2eb5024b4d5103fde5b281212d714)
-rw-r--r--examples/LDAP/README114
-rw-r--r--examples/LDAP/export2_smbpasswd.pl64
-rw-r--r--examples/LDAP/export_smbpasswd.pl63
-rw-r--r--examples/LDAP/import2_smbpasswd.pl108
-rw-r--r--examples/LDAP/import_smbpasswd.pl65
-rw-r--r--examples/LDAP/ldapchpasswd152
-rw-r--r--examples/LDAP/ldapsync.pl117
-rw-r--r--examples/LDAP/samba.schema107
8 files changed, 790 insertions, 0 deletions
diff --git a/examples/LDAP/README b/examples/LDAP/README
new file mode 100644
index 0000000000..281a66e65a
--- /dev/null
+++ b/examples/LDAP/README
@@ -0,0 +1,114 @@
+!==
+!== README File for storing smbpasswd in LDAP
+!==
+!== written by Gerald Carter <jerry@samba.org>
+!==
+
+This is a quick and dirty means of storing smbpasswd entries
+in smbpasswd. Samba 2.2.x does not have any ability to grab
+this information directly from LDAP so you will need to
+periodically generate an smbpasswd from an ldapsearch
+"(objectclass=smbPasswordEntry)".
+
+Be aware of search limits on your client or server which prevent
+all entries from being returned in the search result.
+
+
+Pre-requisites for import_smbpasswd.pl & export_smbpasswd.pl
+------------------------------------------------------------
+You must install Mozilla PerLDAP which is available at:
+
+ http://www.mozilla.org/directory
+
+PerLDAP depends on the Netscape (aka iPlanet) C-SDK which is
+available for download at:
+
+ http:// www.iplanet.com/downloads/developer/
+
+
+Pre-requisites for import2_smbpasswd.pl & export2_smbpasswd.pl
+--------------------------------------------------------------
+These two scripts are modified versions of
+[import|export]_smbpasswd.pl rewritten to use the Net::LDAP
+perl module available from
+
+ http://perl-ldap.sourceforge.net
+
+
+
+OpenLDAP 2.0.x
+--------------
+
+A sample schema file (samba.schema) has been included for use
+with OpenLDAP 2.0.x. The OIDs used in this file are owned by
+the Samba team and generated from its own Enterprise number
+of 7165 (as issued by IANA).
+
+Copy the samba.schema file into your /etc/openldap/schema directory,
+and add an include for it in the /etc/openldap/slapd.conf file.
+Note that samba.schema relies upon the uid and uidNumber attributes
+from the RFC2307 schema (i.e. nis.schema)
+
+If you choose to import /etc/passwd, nis, or nisplus tables
+into ldap, you can use migration tools provided by PADL Software
+which are located at
+
+ http://www.padl.com/tools.html
+
+It is not a requirement that a user's /etc/passwd account
+is stored in LDAP for the samba.schema file to work (although
+the whole point of storing smbpasswd in LDAP is to have a
+single location for user accounts, right?)
+
+The padl tools will leave you with LDIF files which you can import
+into OpenLDAP. Before you can import them, you need to include
+nis.schema and cosine.schema in your slapd.conf file.
+
+You must restart the LDAP server for these new included schema files
+to become active.
+
+
+import[2]_smbpasswd.pl
+----------------------
+
+Make sure you customize the local site variable in the perl script
+(i.e. ldapserver, rootdn, rootpw, etc...). The script reads from
+standard input and requires that user entries already exist
+in your directories containing the 'objectclass: posixAccount'
+value pair. For more information on this object and related schema,
+refer to RFC2307 and http://www.padl.com/software.html).
+
+The following will import an smbpasswd file into an LDAP directory
+
+ $ cat smbpasswd | import[2]_smbpasswd.pl
+
+
+export[2]_smbpasswd.pl
+----------------------
+
+Make sure you customize the local site variable in the perl script
+(i.e. ldapserver, rootdn, rootpw, etc...). You can then generate
+an smbpasswd file by executing
+
+ $ export[2]_smbpasswd.pl > smbpasswd
+
+NOTE: Server side (or client side) search limites may prevent
+all users from being listed. Check you directory server documentation
+for details.
+
+
+
+ldapsync.pl & ldapchgpasswd.pl
+------------------------------
+For more information on these scripts, see
+
+ http://www.mami.net/univr/tng-ldap/howto/
+
+
+The ldapsync.pl script requires a small command (smbencrypt)
+for generating LanMan and NT password hashes which
+can be found at ftp://samba.org/pub/samba/contributed/
+
+!==
+!== end of README
+!==
diff --git a/examples/LDAP/export2_smbpasswd.pl b/examples/LDAP/export2_smbpasswd.pl
new file mode 100644
index 0000000000..90f5805e55
--- /dev/null
+++ b/examples/LDAP/export2_smbpasswd.pl
@@ -0,0 +1,64 @@
+#!/usr/bin/perl
+##
+## Example script to export ldap entries into an smbpasswd file format
+## using the Mozilla PerLDAP module.
+##
+## writen by jerry@samba.org
+##
+## ported to Net::LDAP by dkrovich@slackworks.com
+
+use Net::LDAP;
+
+######################################################
+## Set these values to whatever you need for your site
+##
+
+$DN="dc=samba,dc=my-domain,dc=com";
+$ROOTDN="cn=Manager,dc=my-domain,dc=com";
+$rootpw = "secret";
+$LDAPSERVER="localhost";
+
+##
+## end local site variables
+######################################################
+
+$ldap = Net::LDAP->new($LDAPSERVER) or die "Unable to connect to LDAP server $LDAPSERVER";
+
+print "##\n";
+print "## Autogenerated smbpasswd file via ldapsearch\n";
+print "## from $LDAPSERVER ($DN)\n";
+print "##\n";
+
+## scheck for the existence of the posixAccount first
+$result = $ldap->search ( base => "$DN",
+ scope => "sub",
+ filter => "(objectclass=smbpasswordentry)"
+ );
+
+
+
+## loop over the entries we found
+while ( $entry = $result->shift_entry() ) {
+
+ @uid = $entry->get_value("uid");
+ @uidNumber = $entry->get_value("uidNumber");
+ @lm_pw = $entry->get_value("lmpassword");
+ @nt_pw = $entry->get_value("ntpassword");
+ @acct = $entry->get_value("acctFlags");
+ @pwdLastSet = $entry->get_value("pwdLastSet");
+
+ if (($#uid+1) && ($#uidNumber+1)) {
+
+ $lm_pw[0] = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" if (! ($#lm_pw+1));
+ $nt_pw[0] = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" if (! ($#nt_pw+1));
+ $acct[0] = "[DU ]" if (! ($#acct+1));
+ $pwdLastSet[0] = "FFFFFFFF" if (! ($#pwdLastSet+1));
+
+ print "$uid[0]:$uidNumber[0]:$lm_pw[0]:$nt_pw[0]:$acct[0]:LCT-$pwdLastSet[0]\n";
+ }
+
+}
+
+$ldap->unbind();
+exit 0;
+
diff --git a/examples/LDAP/export_smbpasswd.pl b/examples/LDAP/export_smbpasswd.pl
new file mode 100644
index 0000000000..3f67dc6242
--- /dev/null
+++ b/examples/LDAP/export_smbpasswd.pl
@@ -0,0 +1,63 @@
+#!/usr/bin/perl
+##
+## Example script to export ldap entries into an smbpasswd file format
+## using the Mozilla PerLDAP module.
+##
+## writen by jerry@samba.org
+##
+
+use Mozilla::LDAP::Conn;
+use Mozilla::LDAP::Entry;
+
+######################################################
+## Set these values to whatever you need for your site
+##
+
+$DN="ou=people,dc=plainjoe,dc=org";
+$ROOTDN="cn=Manager,dc=plainjoe,dc=org";
+$rootpw = "secret";
+$LDAPSERVER="localhost";
+
+##
+## end local site variables
+######################################################
+
+
+$conn = new Mozilla::LDAP::Conn ("$LDAPSERVER", "389", $ROOTDN, $rootpw );
+die "Unable to connect to LDAP server $LDAPSERVER" unless $conn;
+
+print "##\n";
+print "## Autogenerated smbpasswd file via ldapsearch\n";
+print "## from $LDAPSERVER ($DN)\n";
+print "##\n";
+
+## scheck for the existence of the posixAccount first
+$result = $conn->search ("$DN", "sub", "(objectclass=smbPasswordEntry)");
+
+
+## loop over the entries we found
+while ($result) {
+
+ @uid = $result->getValue("uid");
+ @uidNumber = $result->getValue("uidNumber");
+ @lm_pw = $result->getValue("lmpassword");
+ @nt_pw = $result->getValue("ntpassword");
+ @acct = $result->getValue("acctFlags");
+ @pwdLastSet = $result->getValue("pwdLastSet");
+
+ if (($#uid+1) && ($#uidNumber+1)) {
+
+ $lm_pw[0] = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" if (! ($#lm_pw+1));
+ $nt_pw[0] = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" if (! ($#nt_pw+1));
+ $acct[0] = "[DU ]" if (! ($#acct+1));
+ $pwdLastSet[0] = "FFFFFFFF" if (! ($#pwdLastSet+1));
+
+ print "$uid[0]:$uidNumber[0]:$lm_pw[0]:$nt_pw[0]:$acct[0]:LCT-$pwdLastSet[0]\n";
+ }
+
+ $result = $conn->nextEntry();
+
+}
+
+$conn->close();
+exit 0;
diff --git a/examples/LDAP/import2_smbpasswd.pl b/examples/LDAP/import2_smbpasswd.pl
new file mode 100644
index 0000000000..bf643391a7
--- /dev/null
+++ b/examples/LDAP/import2_smbpasswd.pl
@@ -0,0 +1,108 @@
+#!/usr/bin/perl
+##
+## Example script of how you could import a smbpasswd file into an LDAP
+## directory using the Mozilla PerLDAP module.
+##
+## writen by jerry@samba.org
+##
+## ported to Net::LDAP by dkrovich@slackworks.com
+
+use Net::LDAP;
+
+#################################################
+## set these to a value appropriate for your site
+##
+
+$DN="dc=samba,dc=my-domain,dc=com";
+$ROOTDN="cn=Manager,dc=my-domain,dc=com";
+$rootpw = "secret";
+$LDAPSERVER="localhost";
+
+##
+## end local site variables
+#################################################
+
+$ldap = Net::LDAP->new($LDAPSERVER) or die "Unable to connect to LDAP server $LDAPSERVER";
+
+## Bind as $ROOTDN so you can do updates
+$mesg = $ldap->bind($ROOTDN, password => $rootpw);
+
+while ( $string = <STDIN> ) {
+ chop ($string);
+
+ ## Get the account info from the smbpasswd file
+ @smbentry = split (/:/, $string);
+
+ ## Check for the existence of a system account
+ @getpwinfo = getpwnam($smbentry[0]);
+ if (! @getpwinfo ) {
+ print STDERR "$smbentry[0] does not have a system account... skipping\n";
+ next;
+ }
+
+ ## check and see if account info already exists in LDAP.
+ $result = $ldap->search ( base => "$DN",
+ scope => "sub",
+ filter => "(&(|(objectclass=posixAccount)(objectclass=smbPasswordEntry))(uid=$smbentry[0]))"
+ );
+
+ ## If no LDAP entry exists, create one.
+ if ( $result->count == 0 ) {
+ $entry = $ldap->add ( dn => "uid=$smbentry[0]\,$DN",
+ attrs => [
+ uid => $smbentry[0],
+ uidNumber => @getpwinfo[2],
+ lmPassword => $smbentry[2],
+ ntPassword => $smbentry[3],
+ acctFlags => $smbentry[4],
+ pwdLastSet => substr($smbentry[5],4),
+ objectclass => [ 'top', 'smbPasswordEntry' ]
+ ]
+ );
+ print "Adding [uid=" . $smbentry[0] . "," . $DN . "]\n";
+
+ ## Otherwise, supplement/update the existing entry.
+ } elsif ($result->count == 1) {
+ # Put the search results into an entry object
+ $entry = $result->shift_entry;
+
+ print "Updating [" . $entry->dn . "]\n";
+
+ ## Add the objectclass: smbPasswordEntry attribute if it's not there
+ @values = $entry->get_value( "objectclass" );
+ $flag = 1;
+ foreach $item (@values) {
+ if ( lc($item) eq "smbpasswordentry" ) {
+ print $item . "\n";
+ $flag = 0;
+ }
+ }
+ if ( $flag ) {
+ $entry->add(objectclass => "smbPasswordEntry");
+ }
+
+ ## Set the other attribute values
+ $entry->replace(lmPassword => $smbentry[2],
+ ntPassword => $smbentry[3],
+ acctFlags => $smbentry[4],
+ pwdLastSet => substr($smbentry[5],4)
+ );
+
+ ## Apply changes to the LDAP server
+ $updatemesg = $entry->update($ldap);
+ if ( $updatemesg->code ) {
+ print "Error updating $smbentry[0]!\n";
+ }
+
+ ## If we get here, the LDAP search returned more than one value
+ ## which shouldn't happen under normal circumstances.
+ } else {
+ print STDERR "LDAP search returned more than one entry for $smbentry[0]... skipping!\n";
+ next;
+ }
+}
+
+$ldap->unbind();
+exit 0;
+
+
diff --git a/examples/LDAP/import_smbpasswd.pl b/examples/LDAP/import_smbpasswd.pl
new file mode 100644
index 0000000000..14aeff967f
--- /dev/null
+++ b/examples/LDAP/import_smbpasswd.pl
@@ -0,0 +1,65 @@
+#!/usr/bin/perl
+##
+## Example script of how you could import and smbpasswd file into an LDAP
+## directory using the Mozilla PerLDAP module.
+##
+## writen by jerry@samba.org
+##
+
+use Mozilla::LDAP::Conn;
+use Mozilla::LDAP::Entry;
+
+#################################################
+## set these to a value appropriate for your site
+##
+
+$DN="ou=people,dc=plainjoe,dc=org";
+$ROOTDN="cn=Manager,dc=plainjoe,dc=org";
+$rootpw = "secret";
+$LDAPSERVER="localhost";
+
+##
+## end local site variables
+#################################################
+
+$conn = new Mozilla::LDAP::Conn ("$LDAPSERVER", "389", $ROOTDN, $rootpw );
+die "Unable to connect to LDAP server $LDAPSERVER" unless $conn;
+
+
+while ( $string = <STDIN> ) {
+ chop ($string);
+
+ ## get the account information
+ @smbentry = split (/:/, $string);
+
+ ## check for the existence of the posixAccount first
+
+ ## FIXME!! Should do a getownam() and let the NSS modules lookup the account
+ ## This way you can have a UNIX account in /etc/passwd and the smbpasswd i
+ ## entry in LDAP.
+ $result = $conn->search ("$DN", "sub", "(&(uid=$smbentry[0])(objectclass=posixAccount))");
+ if ( ! $result ) {
+ print STDERR "uid=$smbentry[0] does not have a posixAccount entry in the directory!\n";
+ next;
+ }
+
+ print "Updating [" . $result->getDN() . "]\n";
+
+ ## Do we need to add the 'objectclass: smbPasswordEntry' attribute?
+ if (! $result->hasValue("objectclass", "smbPasswordEntry")) {
+ $result->addValue("objectclass", "smbPasswordEntry");
+ }
+
+ ## Set other attribute values
+ $result->setValues ("lmPassword", $smbentry[2]);
+ $result->setValues ("ntPassword", $smbentry[3]);
+ $result->setValues ("acctFlags", $smbentry[4]);
+ $result->setValues ("pwdLastSet", substr($smbentry[5],4));
+
+ if (! $conn->update($result)) {
+ print "Error updating!\n";
+ }
+}
+
+$conn->close();
+exit 0;
diff --git a/examples/LDAP/ldapchpasswd b/examples/LDAP/ldapchpasswd
new file mode 100644
index 0000000000..0776d9bed1
--- /dev/null
+++ b/examples/LDAP/ldapchpasswd
@@ -0,0 +1,152 @@
+#!/usr/bin/perl -w
+
+# LDAP to unix password sync script for samba-tng
+# originally by Jody Haynes <Jody.Haynes@isunnetworks.com>
+# 2000/12/12 milos@interactivesi.com
+# modified for use with MD5 passwords
+# 2000/12/16 mami@arena.sci.univr.it
+# modified to change lmpassword and ntpassword for samba
+# 2001/01/05 mami@arena.sci.univr.it
+# modified for being also a /bin/passwd replacement
+# 2001/01/29 mami@arena.sci.univr.it
+# now there are two small programs: ldapchpasswd to
+# change password from unix and ldapsync.pl to sync
+# from NT/2000. ldapchpasswd do not need clear password.
+# 2001/01/31 mami@arena.sci.univr.it
+# add server parameter to ldap commands
+# 2001/06/20 mami@arena.sci.univr.it
+# add pwdlastset and shadowlastchange update
+
+$basedn = "ou=Students,dc=univr, dc=it";
+$binddn = "uid=root,dc=univr,dc=it";
+$scope = "sub";
+$server = "my_server";
+
+foreach $arg (@ARGV) {
+ if ($< != 0) {
+ die "Only root can specify parameters\n";
+ } else {
+ if ( ($arg eq '-?') || ($arg eq '--help') ) {
+ print "Usage: $0 [-o] [username]\n";
+ print " -o, --without-old-password do not ask for old password (root only)\n";
+ print " -?, --help show this help message\n";
+ exit (-1);
+ } elsif ( ($arg eq '-o') || ($arg eq '--without-old-password') ) {
+ $oldpass = 1;
+ } elsif (substr($arg,0) ne '-') {
+ $user = $arg;
+ if (!defined(getpwnam($user))) {
+ die "$0: Unknown user name '$user'\n"; ;
+ }
+ }
+ }
+}
+
+if (!defined($user)) {
+ $user=$ENV{"USER"};
+}
+
+# current user's dn
+my $dn = '';
+
+if ($< == 0) {
+ system "stty -echo";
+ print "LDAP password for root DN: ";
+ chomp($passwd=<STDIN>);
+ print "\n";
+ system "stty echo";
+ # Find dn for user $user binding as root's dn
+ chomp($dn=`ldapsearch -h '$server' -b '$basedn' -s '$scope' -D '$binddn' -w '$passwd' '(uid=$user)'|head -1`);
+ if ( ($dn eq '') || ($passwd eq '') ) {
+ print "Wrong LDAP password for root DN!\n";
+ exit (-1);
+ }
+} else {
+ if (!defined($oldpass)) {
+ system "stty -echo";
+ print "Old password for user $user: ";
+ chomp($oldpass=<STDIN>);
+ print "\n";
+ system "stty echo";
+
+ # Find path to uid
+ chomp($path_to_uid=`ldapsearch -h '$server' -b '$basedn' -s '$scope' '(uid=$user)'|head -1`);
+ # Find old password for user $user binding as self
+ chomp($dn=`ldapsearch -h '$server' -b '$basedn' -s '$scope' -D '$path_to_uid' -w '$oldpass' '(uid=$user)'|head -1`);
+
+ if ( ($dn eq '') || ($oldpass eq '') ) {
+ print "Wrong password for user $user!\n";
+ exit (-1);
+ }
+ }
+}
+
+system "stty -echo";
+print "New password for user $user: ";
+chomp($pass=<STDIN>);
+print "\n";
+system "stty echo";
+
+system "stty -echo";
+print "Retype new password for user $user: ";
+chomp($pass2=<STDIN>);
+print "\n";
+system "stty echo";
+
+if ( ($pass ne $pass2) || (length($pass)<1) ) {
+ die "Wrong password!\n";
+} else {
+# MD5 password
+$random = join '', ('.', '/', 0..9, 'A'..'Z', 'a'..'z')[rand 64, rand 64, rand 64, rand 64, rand 64, rand 64, rand 64, rand 64];
+$bsalt = "\$1\$"; $esalt = "\$";
+$modsalt = $bsalt.$random.$esalt;
+$password = crypt($pass, $modsalt);
+
+# LanManager and NT clear text passwords
+$ntpwd = `/usr/local/sbin/mkntpwd '$pass'`;
+chomp($lmpassword = substr($ntpwd, 0, index($ntpwd, ':')));
+chomp($ntpassword = substr($ntpwd, index($ntpwd, ':')+1));
+
+#$FILE="|/usr/bin/ldapmodify -h '$server' -D '$binddn' -w $passwd";
+if ($< != 0) {
+ $FILE="|/usr/bin/ldapmodify -h '$server' -D '$dn' -w '$oldpass'";
+} else {
+ $FILE="|/usr/bin/ldapmodify -h '$server' -D '$binddn' -w '$passwd'";
+}
+
+# Chenge time
+$shadowlastchange=int(time/24/3600);
+$pwdlastset=sprintf('%x',time);
+
+open FILE or die;
+
+print FILE <<EOF;
+dn: $dn
+changetype: modify
+replace: userPassword
+userPassword: {crypt}$password
+-
+changetype: modify
+replace: lmpassword
+lmpassword: $lmpassword
+-
+changetype: modify
+replace: ntpassword
+ntpassword: $ntpassword
+-
+changetype: modify
+replace: shadowlastchange
+shadowlastchange: $shadowlastchange
+-
+changetype: modify
+replace: pwdlastset
+pwdlastset: $pwdlastset
+-
+
+EOF
+close FILE;
+
+}
+
+exit 0;
+
diff --git a/examples/LDAP/ldapsync.pl b/examples/LDAP/ldapsync.pl
new file mode 100644
index 0000000000..fecc594c2d
--- /dev/null
+++ b/examples/LDAP/ldapsync.pl
@@ -0,0 +1,117 @@
+#!/usr/bin/perl -w
+
+# LDAP to unix password sync script for samba-tng
+# originally by Jody Haynes <Jody.Haynes@isunnetworks.com>
+# 12/12/2000 milos@interactivesi.com
+# modified for use with MD5 passwords
+# 12/16/2000 mami@arena.sci.univr.it
+# modified to change lmpassword and ntpassword for samba
+# 05/01/2001 mami@arena.sci.univr.it
+# modified for being also a /bin/passwd replacement
+
+$basedn = "ou=Students,dc=univr, dc=it";
+$binddn = "uid=root,dc=univr,dc=it";
+$scope = "sub";
+$passwd = "mysecret";
+
+foreach $arg (@ARGV) {
+ if ($< != 0) {
+ die "Only root can specify parameters\n";
+ } else {
+ if ( ($arg eq '-?') || ($arg eq '--help') ) {
+ print "Usage: $0 [-o] [username]\n";
+ print " -o, --without-old-password do not ask for old password (root only)\n";
+ print " -?, --help show this help message\n";
+ exit (-1);
+ } elsif ( ($arg eq '-o') || ($arg eq '--without-old-password') ) {
+ $oldpass = 1;
+ } elsif (substr($arg,0) ne '-') {
+ $user = $arg;
+ if (!defined(getpwnam($user))) {
+ die "$0: Unknown user name '$user'\n"; ;
+ }
+ }
+ }
+}
+
+if (!defined($user)) {
+ $user=$ENV{"USER"};
+}
+
+if (!defined($oldpass)) {
+ system "stty -echo";
+ print "Old password for user $user: ";
+ chomp($oldpass=<STDIN>);
+ print "\n";
+ system "stty echo";
+
+ $ntpwd = `/usr/local/sbin/smbencrypt '$oldpass'`;
+ $lmpassword = substr($ntpwd, 0, index($ntpwd, ':')); chomp $lmpassword;
+ $ntpassword = substr($ntpwd, index($ntpwd, ':')+1); chomp $ntpassword;
+
+ # Find dn for user $user (maybe check unix password too?)
+ $dn=`ldapsearch -b '$basedn' -s '$scope' '(&(uid=$user)(lmpassword=$lmpassword)(ntpassword=$ntpassword))'|head -1`;
+ chomp $dn;
+
+ if ($dn eq '') {
+ print "Wrong password for user $user!\n";
+ exit (-1);
+ }
+} else {
+ # Find dn for user $user
+ $dn=`ldapsearch -b '$basedn' -s '$scope' '(uid=$user)'|head -1`;
+ chomp $dn;
+}
+
+system "stty -echo";
+print "New password for user $user: ";
+chomp($pass=<STDIN>);
+print "\n";
+system "stty echo";
+
+system "stty -echo";
+print "Retype new password for user $user: ";
+chomp($pass2=<STDIN>);
+print "\n";
+system "stty echo";
+
+if ($pass ne $pass2) {
+ die "Wrong password!\n";
+} else {
+# MD5 password
+$random = join '', ('.', '/', 0..9, 'A'..'Z', 'a'..'z')[rand 64, rand 64, rand 64, rand 64, rand 64, rand 64, rand 64, rand 64];
+$bsalt = "\$1\$"; $esalt = "\$";
+$modsalt = $bsalt.$random.$esalt;
+$password = crypt($pass, $modsalt);
+
+# LanManager and NT clear text passwords
+$ntpwd = `/usr/local/sbin/smbencrypt '$pass'`;
+chomp($lmpassword = substr($ntpwd, 0, index($ntpwd, ':')));
+chomp($ntpassword = substr($ntpwd, index($ntpwd, ':')+1));
+
+$FILE="|/usr/bin/ldapmodify -D '$binddn' -w $passwd";
+
+open FILE or die;
+
+print FILE <<EOF;
+dn: $dn
+changetype: modify
+replace: userPassword
+userPassword: {crypt}$password
+-
+changetype: modify
+replace: lmpassword
+lmpassword: $lmpassword
+-
+changetype: modify
+replace: ntpassword
+ntpassword: $ntpassword
+-
+
+EOF
+close FILE;
+
+}
+
+exit 0;
+
diff --git a/examples/LDAP/samba.schema b/examples/LDAP/samba.schema
new file mode 100644
index 0000000000..6ab43bcf5a
--- /dev/null
+++ b/examples/LDAP/samba.schema
@@ -0,0 +1,107 @@
+##
+## schema file for OpenLDAP 2.0.x
+## Schema for storing Samba's smbpasswd file in LDAP
+## OIDs are owned by the Samba Team
+##
+## Prerequisite schemas - uid & uidNumber (nis.schema)
+##
+## 1.3.1.5.1.4.1.7165.2.1.x - attributetypes
+## 1.3.1.5.1.4.1.7165.2.2.x - objectclasses
+##
+
+attributetype ( 1.3.6.1.4.1.7165.2.1.1 NAME 'lmPassword'
+ DESC 'LanManager Passwd'
+ EQUALITY caseIgnoreIA5Match
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{32} SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.7165.2.1.2 NAME 'ntPassword'
+ DESC 'NT Passwd'
+ EQUALITY caseIgnoreIA5Match
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{32} SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.7165.2.1.3 NAME 'pwdLastSet'
+ DESC 'NT pwdLastSet'
+ EQUALITY caseIgnoreIA5Match
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{32} SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.7165.2.1.4 NAME 'acctFlags'
+ DESC 'Account Flags'
+ EQUALITY caseIgnoreIA5Match
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{16} SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.7165.2.1.5 NAME 'logonTime'
+ DESC 'NT logonTime'
+ EQUALITY caseIgnoreIA5Match
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{32} SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.7165.2.1.6 NAME 'logoffTime'
+ DESC 'NT logoffTime'
+ EQUALITY caseIgnoreIA5Match
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{32} SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.7165.2.1.7 NAME 'kickoffTime'
+ DESC 'NT kickoffTime'
+ EQUALITY caseIgnoreIA5Match
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{32} SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.7165.2.1.8 NAME 'pwdCanChange'
+ DESC 'NT pwdCanChange'
+ EQUALITY caseIgnoreIA5Match
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{32} SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.7165.2.1.9 NAME 'pwdMustChange'
+ DESC 'NT pwdMustChange'
+ EQUALITY caseIgnoreIA5Match
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{32} SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.7165.2.1.10 NAME 'homeDrive'
+ DESC 'NT homeDrive'
+ EQUALITY caseIgnoreIA5Match
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{4} SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.7165.2.1.11 NAME 'scriptPath'
+ DESC 'NT scriptPath'
+ EQUALITY caseIgnoreIA5Match
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{255} SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.7165.2.1.12 NAME 'profilePath'
+ DESC 'NT profilePath'
+ EQUALITY caseIgnoreIA5Match
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{255} SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.7165.2.1.13 NAME 'userWorkstations'
+ DESC 'userWorkstations'
+ EQUALITY caseIgnoreIA5Match
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{255} SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.7165.2.1.14 NAME 'rid'
+ DESC 'NT rid'
+ EQUALITY caseIgnoreIA5Match
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{255} SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.7165.2.1.15 NAME 'primaryGroupID'
+ DESC 'NT Group RID'
+ EQUALITY caseIgnoreIA5Match
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{255} SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.7165.2.1.17 NAME 'smbHome'
+ DESC 'smbHome'
+ EQUALITY caseIgnoreIA5Match
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{128} )
+
+##
+## The smbPasswordEntry objectclass has been depreciated in favor of the
+## sambaAccount objectclass
+##
+#objectclass ( 1.3.1.5.1.4.1.7165.2.2.1 NAME 'smbPasswordEntry' SUP top AUXILIARY
+# DESC 'Samba smbpasswd entry'
+# MUST ( uid $ uidNumber )
+# MAY ( lmPassword $ ntPassword $ pwdLastSet $ acctFlags ))
+
+objectclass ( 1.3.1.5.1.4.1.7165.2.2.2 NAME 'sambaAccount' SUP top STRUCTURAL
+ DESC 'Samba Account'
+ MUST ( uid $ uidNumber )
+ MAY ( cn $ gidNumber $ lmPassword $ ntPassword $ pwdLastSet $ logonTime $
+ logoffTime $ kickoffTime $ pwdCanChange $ pwdMustChange $ acctFlags $
+ displayName $ smbHome $ homeDrive $ scriptPath $ profilePath $
+ description $ userWorkstations $ rid $ primaryGroupID ))