sync with 2.2
authorGerald Carter <jerry@samba.org>
Wed, 26 Dec 2001 05:35:40 +0000 (05:35 +0000)
committerGerald Carter <jerry@samba.org>
Wed, 26 Dec 2001 05:35:40 +0000 (05:35 +0000)
(This used to be commit aca58b0b72d2eb5024b4d5103fde5b281212d714)

examples/LDAP/README [new file with mode: 0644]
examples/LDAP/export2_smbpasswd.pl [new file with mode: 0644]
examples/LDAP/export_smbpasswd.pl [new file with mode: 0644]
examples/LDAP/import2_smbpasswd.pl [new file with mode: 0644]
examples/LDAP/import_smbpasswd.pl [new file with mode: 0644]
examples/LDAP/ldapchpasswd [new file with mode: 0644]
examples/LDAP/ldapsync.pl [new file with mode: 0644]
examples/LDAP/samba.schema [new file with mode: 0644]

diff --git a/examples/LDAP/README b/examples/LDAP/README
new file mode 100644 (file)
index 0000000..281a66e
--- /dev/null
@@ -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 (file)
index 0000000..90f5805
--- /dev/null
@@ -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 (file)
index 0000000..3f67dc6
--- /dev/null
@@ -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 (file)
index 0000000..bf64339
--- /dev/null
@@ -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 (file)
index 0000000..14aeff9
--- /dev/null
@@ -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 (file)
index 0000000..0776d9b
--- /dev/null
@@ -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 (file)
index 0000000..fecc594
--- /dev/null
@@ -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 (file)
index 0000000..6ab43bc
--- /dev/null
@@ -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 ))