From 1e6e5b299c235b513095a76a4cd9fffc41e8fc9c Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Mon, 17 Jun 2002 18:36:36 +0000 Subject: beginning to sync up for 2.2.5 release.... --- examples/LDAP/README | 31 +- examples/LDAP/export2_smbpasswd.pl | 64 -- examples/LDAP/export_smbpasswd.pl | 51 +- examples/LDAP/import2_smbpasswd.pl | 108 -- examples/LDAP/import_smbpasswd.pl | 122 +- examples/LDAP/samba-schema-netscapeds4.x | 2 +- examples/LDAP/samba-schema-netscapeds5.x | 4 +- examples/LDAP/samba-schema.IBMSecureWay | 2 +- examples/LDAP/samba.schema | 16 +- examples/LDAP/smbldap-tools/AUTHORS | 0 examples/LDAP/smbldap-tools/CONTRIBUTORS | 29 + examples/LDAP/smbldap-tools/COPYING | 340 ++++++ examples/LDAP/smbldap-tools/ChangeLog | 29 + examples/LDAP/smbldap-tools/FILES | 43 + examples/LDAP/smbldap-tools/INFRASTRUCTURE | 84 ++ examples/LDAP/smbldap-tools/INSTALL | 28 + examples/LDAP/smbldap-tools/Makefile | 35 + examples/LDAP/smbldap-tools/NEWS | 0 examples/LDAP/smbldap-tools/README | 87 ++ examples/LDAP/smbldap-tools/TODO | 27 + examples/LDAP/smbldap-tools/cgi/README | 27 + examples/LDAP/smbldap-tools/cgi/ldappass.cgi | 202 ++++ examples/LDAP/smbldap-tools/mkntpwd/Makefile | 62 ++ examples/LDAP/smbldap-tools/mkntpwd/getopt.c | 756 +++++++++++++ examples/LDAP/smbldap-tools/mkntpwd/getopt.h | 133 +++ examples/LDAP/smbldap-tools/mkntpwd/md4.c | 171 +++ examples/LDAP/smbldap-tools/mkntpwd/mkntpwd.c | 253 +++++ examples/LDAP/smbldap-tools/mkntpwd/mkntpwd.h | 17 + examples/LDAP/smbldap-tools/mkntpwd/smbdes.c | 337 ++++++ examples/LDAP/smbldap-tools/smbldap-groupadd.pl | 86 ++ examples/LDAP/smbldap-tools/smbldap-groupdel.pl | 95 ++ examples/LDAP/smbldap-tools/smbldap-groupmod.pl | 213 ++++ examples/LDAP/smbldap-tools/smbldap-groupshow.pl | 74 ++ .../LDAP/smbldap-tools/smbldap-migrate-accounts.pl | 236 ++++ .../LDAP/smbldap-tools/smbldap-migrate-groups.pl | 227 ++++ examples/LDAP/smbldap-tools/smbldap-passwd.pl | 217 ++++ examples/LDAP/smbldap-tools/smbldap-populate.pl | 296 +++++ examples/LDAP/smbldap-tools/smbldap-tools.spec | 169 +++ examples/LDAP/smbldap-tools/smbldap-useradd.pl | 462 ++++++++ examples/LDAP/smbldap-tools/smbldap-userdel.pl | 124 +++ examples/LDAP/smbldap-tools/smbldap-usermod.pl | 405 +++++++ examples/LDAP/smbldap-tools/smbldap-usershow.pl | 71 ++ examples/LDAP/smbldap-tools/smbldap_conf.pm | 251 +++++ examples/LDAP/smbldap-tools/smbldap_tools.pm | 585 ++++++++++ examples/VFS/.cvsignore | 4 + examples/VFS/Makefile | 35 - examples/VFS/Makefile.in | 31 + examples/VFS/README | 11 +- examples/VFS/block/Makefile | 37 - examples/VFS/block/block.c | 14 +- examples/VFS/configure | 1161 ++++++++++++++++++++ examples/VFS/configure.in | 92 ++ examples/VFS/recycle.c | 287 ----- examples/VFS/recycle/README | 83 ++ examples/VFS/recycle/cleanup_recycle.pl | 25 + examples/VFS/recycle/recycle.c | 556 ++++++++++ examples/VFS/recycle/recycle.conf | 17 + examples/libsmbclient/testsmbc.c | 126 ++- examples/smb.conf.default | 459 +++++--- 59 files changed, 8697 insertions(+), 812 deletions(-) delete mode 100644 examples/LDAP/export2_smbpasswd.pl delete mode 100644 examples/LDAP/import2_smbpasswd.pl create mode 100644 examples/LDAP/smbldap-tools/AUTHORS create mode 100644 examples/LDAP/smbldap-tools/CONTRIBUTORS create mode 100644 examples/LDAP/smbldap-tools/COPYING create mode 100644 examples/LDAP/smbldap-tools/ChangeLog create mode 100644 examples/LDAP/smbldap-tools/FILES create mode 100644 examples/LDAP/smbldap-tools/INFRASTRUCTURE create mode 100644 examples/LDAP/smbldap-tools/INSTALL create mode 100644 examples/LDAP/smbldap-tools/Makefile create mode 100644 examples/LDAP/smbldap-tools/NEWS create mode 100644 examples/LDAP/smbldap-tools/README create mode 100644 examples/LDAP/smbldap-tools/TODO create mode 100644 examples/LDAP/smbldap-tools/cgi/README create mode 100755 examples/LDAP/smbldap-tools/cgi/ldappass.cgi create mode 100644 examples/LDAP/smbldap-tools/mkntpwd/Makefile create mode 100644 examples/LDAP/smbldap-tools/mkntpwd/getopt.c create mode 100644 examples/LDAP/smbldap-tools/mkntpwd/getopt.h create mode 100644 examples/LDAP/smbldap-tools/mkntpwd/md4.c create mode 100644 examples/LDAP/smbldap-tools/mkntpwd/mkntpwd.c create mode 100644 examples/LDAP/smbldap-tools/mkntpwd/mkntpwd.h create mode 100644 examples/LDAP/smbldap-tools/mkntpwd/smbdes.c create mode 100755 examples/LDAP/smbldap-tools/smbldap-groupadd.pl create mode 100755 examples/LDAP/smbldap-tools/smbldap-groupdel.pl create mode 100755 examples/LDAP/smbldap-tools/smbldap-groupmod.pl create mode 100755 examples/LDAP/smbldap-tools/smbldap-groupshow.pl create mode 100755 examples/LDAP/smbldap-tools/smbldap-migrate-accounts.pl create mode 100644 examples/LDAP/smbldap-tools/smbldap-migrate-groups.pl create mode 100755 examples/LDAP/smbldap-tools/smbldap-passwd.pl create mode 100755 examples/LDAP/smbldap-tools/smbldap-populate.pl create mode 100755 examples/LDAP/smbldap-tools/smbldap-tools.spec create mode 100755 examples/LDAP/smbldap-tools/smbldap-useradd.pl create mode 100755 examples/LDAP/smbldap-tools/smbldap-userdel.pl create mode 100755 examples/LDAP/smbldap-tools/smbldap-usermod.pl create mode 100755 examples/LDAP/smbldap-tools/smbldap-usershow.pl create mode 100644 examples/LDAP/smbldap-tools/smbldap_conf.pm create mode 100755 examples/LDAP/smbldap-tools/smbldap_tools.pm delete mode 100644 examples/VFS/Makefile create mode 100644 examples/VFS/Makefile.in delete mode 100644 examples/VFS/block/Makefile create mode 100755 examples/VFS/configure create mode 100644 examples/VFS/configure.in delete mode 100644 examples/VFS/recycle.c create mode 100644 examples/VFS/recycle/README create mode 100644 examples/VFS/recycle/cleanup_recycle.pl create mode 100644 examples/VFS/recycle/recycle.c create mode 100644 examples/VFS/recycle/recycle.conf (limited to 'examples') diff --git a/examples/LDAP/README b/examples/LDAP/README index 281a66e65aa..c7ff16ad083 100644 --- a/examples/LDAP/README +++ b/examples/LDAP/README @@ -4,29 +4,11 @@ !== written by Gerald Carter !== -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. +This is a quick and dirty means of converting smbpasswd entries +to sambaAccount entriues in an LDAP directory. 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 @@ -36,6 +18,7 @@ perl module available from + OpenLDAP 2.0.x -------------- @@ -68,7 +51,7 @@ You must restart the LDAP server for these new included schema files to become active. -import[2]_smbpasswd.pl +import_smbpasswd.pl ---------------------- Make sure you customize the local site variable in the perl script @@ -80,17 +63,17 @@ 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 + $ cat smbpasswd | import_smbpasswd.pl -export[2]_smbpasswd.pl +export_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 + $ export_smbpasswd.pl > smbpasswd NOTE: Server side (or client side) search limites may prevent all users from being listed. Check you directory server documentation diff --git a/examples/LDAP/export2_smbpasswd.pl b/examples/LDAP/export2_smbpasswd.pl deleted file mode 100644 index 90f5805e55f..00000000000 --- a/examples/LDAP/export2_smbpasswd.pl +++ /dev/null @@ -1,64 +0,0 @@ -#!/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 index 3f67dc62427..90f5805e55f 100644 --- a/examples/LDAP/export_smbpasswd.pl +++ b/examples/LDAP/export_smbpasswd.pl @@ -5,16 +5,16 @@ ## ## writen by jerry@samba.org ## +## ported to Net::LDAP by dkrovich@slackworks.com -use Mozilla::LDAP::Conn; -use Mozilla::LDAP::Entry; +use Net::LDAP; ###################################################### ## Set these values to whatever you need for your site ## -$DN="ou=people,dc=plainjoe,dc=org"; -$ROOTDN="cn=Manager,dc=plainjoe,dc=org"; +$DN="dc=samba,dc=my-domain,dc=com"; +$ROOTDN="cn=Manager,dc=my-domain,dc=com"; $rootpw = "secret"; $LDAPSERVER="localhost"; @@ -22,9 +22,7 @@ $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; +$ldap = Net::LDAP->new($LDAPSERVER) or die "Unable to connect to LDAP server $LDAPSERVER"; print "##\n"; print "## Autogenerated smbpasswd file via ldapsearch\n"; @@ -32,32 +30,35 @@ print "## from $LDAPSERVER ($DN)\n"; print "##\n"; ## scheck for the existence of the posixAccount first -$result = $conn->search ("$DN", "sub", "(objectclass=smbPasswordEntry)"); - - +$result = $ldap->search ( base => "$DN", + scope => "sub", + filter => "(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"); - +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"; } - - $result = $conn->nextEntry(); - + } -$conn->close(); +$ldap->unbind(); exit 0; + diff --git a/examples/LDAP/import2_smbpasswd.pl b/examples/LDAP/import2_smbpasswd.pl deleted file mode 100644 index 0f83b5cae45..00000000000 --- a/examples/LDAP/import2_smbpasswd.pl +++ /dev/null @@ -1,108 +0,0 @@ -#!/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 = ) { - 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=sambaAccount))(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', 'sambaAccount', 'posixAccount'] - ] - ); - 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: sambaAccount attribute if it's not there - @values = $entry->get_value( "objectclass" ); - $flag = 1; - foreach $item (@values) { - if ( lc($item) eq "sambaaccount" ) { - print $item . "\n"; - $flag = 0; - } - } - if ( $flag ) { - $entry->add(objectclass => "sambaAccount"); - } - - ## 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 index 14aeff967f1..61ad33c8099 100644 --- a/examples/LDAP/import_smbpasswd.pl +++ b/examples/LDAP/import_smbpasswd.pl @@ -1,13 +1,13 @@ #!/usr/bin/perl ## -## Example script of how you could import and smbpasswd file into an LDAP +## 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 Mozilla::LDAP::Conn; -use Mozilla::LDAP::Entry; +use Net::LDAP; ################################################# ## set these to a value appropriate for your site @@ -15,51 +15,105 @@ use Mozilla::LDAP::Entry; $DN="ou=people,dc=plainjoe,dc=org"; $ROOTDN="cn=Manager,dc=plainjoe,dc=org"; -$rootpw = "secret"; -$LDAPSERVER="localhost"; +# If you use perl special character in your +# rootpw, escape them: +# $rootpw = "secr\@t" instead of $rootpw = "secr@t" +$rootpw = "n0pass"; +$LDAPSERVER="scooby"; ## ## end local site variables ################################################# -$conn = new Mozilla::LDAP::Conn ("$LDAPSERVER", "389", $ROOTDN, $rootpw ); -die "Unable to connect to LDAP server $LDAPSERVER" unless $conn; +$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); +$mesg->error() if $mesg->code(); while ( $string = ) { - chop ($string); + chomp ($string); - ## get the account information + ## Get the account info from the smbpasswd file @smbentry = split (/:/, $string); - ## check for the existence of the posixAccount first + ## Check for the existence of a system account + @getpwinfo = getpwnam($smbentry[0]); + if (! @getpwinfo ) { + print STDERR "**$smbentry[0] does not have a system account... \n"; + next; + } + ## Calculate RID = uid*2 +1000 + $rid=@getpwinfo[2]*2+1000; + + ## check and see if account info already exists in LDAP. + $result = $ldap->search ( base => "$DN", + scope => "sub", + filter => "(uid=$smbentry[0])" + ); - ## 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; - } + ## If no LDAP entry exists, create one. + if ( $result->count == 0 ) { + $new_entry = Net::LDAP::Entry->new(); + $new_entry->add( dn => "uid=$smbentry[0],$DN", + uid => $smbentry[0], + rid => $rid, + lmPassword => $smbentry[2], + ntPassword => $smbentry[3], + acctFlags => $smbentry[4], + cn => $smbentry[0], + pwdLastSet => hex(substr($smbentry[5],4)), + objectclass => 'sambaAccount' ); - print "Updating [" . $result->getDN() . "]\n"; + $result = $ldap->add( $new_entry ); + $result->error() if $result->code(); + print "Adding [uid=" . $smbentry[0] . "," . $DN . "]\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"; - } + ## Otherwise, supplement/update the existing entry. + } + elsif ($result->count == 1) + { + # Put the search results into an entry object + $entry = $result->entry(0); + + print "Updating [" . $entry->dn . "]\n"; + + ## Add the objectclass: sambaAccount attribute if it's not there + @values = $entry->get_value( "objectclass" ); + $flag = 1; + foreach $item (@values) { + print "$item\n"; + if ( "$item" eq "sambaAccount" ) { + $flag = 0; + } + } + if ( $flag ) { + ## Adding sambaAccount objectclass requires adding at least rid: + ## uid attribute already exists we know since we searched on it + $entry->add(objectclass => "sambaAccount", + rid => $rid ); + } + + ## Set the other attribute values + $entry->replace(rid => $rid, + lmPassword => $smbentry[2], + ntPassword => $smbentry[3], + acctFlags => $smbentry[4], + pwdLastSet => hex(substr($smbentry[5],4))); + + ## Apply changes to the LDAP server + $updatemesg = $entry->update($ldap); + $updatemesg->error() if $updatemesg->code(); + + ## 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; + } } -$conn->close(); +$ldap->unbind(); exit 0; + + diff --git a/examples/LDAP/samba-schema-netscapeds4.x b/examples/LDAP/samba-schema-netscapeds4.x index c5a11b8b66c..074b78c52cc 100644 --- a/examples/LDAP/samba-schema-netscapeds4.x +++ b/examples/LDAP/samba-schema-netscapeds4.x @@ -24,7 +24,7 @@ attribute domain 1.3.6.1.4.1.7165.2.1.18 cis single objectclass sambaAccount oid - 1.3.1.5.1.4.1.7165.2.2.2 + 1.3.1.5.1.4.1.7165.2.2.3 superior top requires diff --git a/examples/LDAP/samba-schema-netscapeds5.x b/examples/LDAP/samba-schema-netscapeds5.x index 0abc9d82e27..888758f67f3 100644 --- a/examples/LDAP/samba-schema-netscapeds5.x +++ b/examples/LDAP/samba-schema-netscapeds5.x @@ -21,8 +21,8 @@ aci: (targetattr = "*")(version 3.0; acl "SIE Group"; allow (all)groupdn = "ld ap:///cn=slapd-sambaldap, cn=iPlanet Directory Server, cn=Server Group, cn=iPlanetDirectory.samba.org, ou=samba.org, o=NetscapeRoot";) modifiersName: cn=directory manager modifyTimestamp: 20020322124844Z -objectClasses: ( 1.3.1.5.1.4.1.7165.2.2.2 NAME 'sambaAccount' SUP top STRUCTUR - AL MAY ( acctFlags $ domain $ homeDrive $ kickoffTime $ lmPassword $ logofft +objectClasses: ( 1.3.1.5.1.4.1.7165.2.2.3 NAME 'sambaAccount' SUP top AUXILIARY + MAY ( acctFlags $ domain $ homeDrive $ kickoffTime $ lmPassword $ logofft ime $ logonTime $ ntPassword $ primaryGroupID $ profilePath $ pwdCanChange $ pwdLastSet $ pwdMustChange $ rid $ scriptPath $ smbHome $ userWorkstations ) X-ORIGIN 'user defined' ) diff --git a/examples/LDAP/samba-schema.IBMSecureWay b/examples/LDAP/samba-schema.IBMSecureWay index 1fca4a749a6..73d767b03c8 100644 --- a/examples/LDAP/samba-schema.IBMSecureWay +++ b/examples/LDAP/samba-schema.IBMSecureWay @@ -10,7 +10,7 @@ ## ibm-slapdIncludeSchema: /etc/lapschema/samba.schema ## objectClasses { -( 1.3.1.5.1.4.1.7165.2.2.2 NAME 'sambaAccount' DESC 'Samba Account' SUP top MUST uid $ rid MAY ( acctFlags $ cn $ description $ displayName $ homeDrive $ kickoffTime $ lmPassword $ logoffTime $ logonTime $ ntPassword $ primaryGroupID $ profilePath $ pwdCanChange $ pwdLastSet $ pwdMustChange $ scriptPath $ smbHome $ userWorkstations ) ) +( 1.3.1.5.1.4.1.7165.2.2.3 NAME 'sambaAccount' DESC 'Samba Account' SUP top MUST uid $ rid MAY ( acctFlags $ cn $ description $ displayName $ homeDrive $ kickoffTime $ lmPassword $ logoffTime $ logonTime $ ntPassword $ primaryGroupID $ profilePath $ pwdCanChange $ pwdLastSet $ pwdMustChange $ scriptPath $ smbHome $ userWorkstations ) ) } attributeTypes { diff --git a/examples/LDAP/samba.schema b/examples/LDAP/samba.schema index be088c74033..61dface0a20 100644 --- a/examples/LDAP/samba.schema +++ b/examples/LDAP/samba.schema @@ -119,8 +119,20 @@ attributetype ( 1.3.6.1.4.1.7165.2.1.15 NAME 'primaryGroupID' # MUST ( uid $ uidNumber ) # MAY ( lmPassword $ ntPassword $ pwdLastSet $ acctFlags )) -objectclass ( 1.3.6.1.4.1.7165.2.2.2 NAME 'sambaAccount' SUP top STRUCTURAL - DESC 'Samba Account' +#objectclass ( 1.3.6.1.4.1.7165.2.2.2 NAME 'sambaAccount' SUP top STRUCTURAL +# DESC 'Samba Account' +# MUST ( uid $ rid ) +# MAY ( cn $ lmPassword $ ntPassword $ pwdLastSet $ logonTime $ +# logoffTime $ kickoffTime $ pwdCanChange $ pwdMustChange $ acctFlags $ +# displayName $ smbHome $ homeDrive $ scriptPath $ profilePath $ +# description $ userWorkstations $ primaryGroupID $ domain )) + +## The X.500 data model (and therefore LDAPv3) says that each entry can +## only have one structural objectclass. OpenLDAP 2.0 does not enforce +## this currently but will in v2.1 + +objectclass ( 1.3.6.1.4.1.7165.2.2.3 NAME 'sambaAccount' SUP top AUXILIARY + DESC 'Samba Auxilary Account' MUST ( uid $ rid ) MAY ( cn $ lmPassword $ ntPassword $ pwdLastSet $ logonTime $ logoffTime $ kickoffTime $ pwdCanChange $ pwdMustChange $ acctFlags $ diff --git a/examples/LDAP/smbldap-tools/AUTHORS b/examples/LDAP/smbldap-tools/AUTHORS new file mode 100644 index 00000000000..e69de29bb2d diff --git a/examples/LDAP/smbldap-tools/CONTRIBUTORS b/examples/LDAP/smbldap-tools/CONTRIBUTORS new file mode 100644 index 00000000000..9765a57e60d --- /dev/null +++ b/examples/LDAP/smbldap-tools/CONTRIBUTORS @@ -0,0 +1,29 @@ +# $Source: /data/src/mirror/cvs/samba/examples/LDAP/smbldap-tools/CONTRIBUTORS,v $ +# +## Authors and actives contributors to SMBLDAP-TOOLS + +Have contributed directly to this tools, or are always in charge of +some aspects of it developments (alphabetical order): + . Terry Davis + . David Le Corfec + . Olivier Lemaire + . Jérôme Tournier + +Many thanks to contributors for bug report and patches: + . Gert-Jan Braas + bug report for 2.2.3 samba.schema + . Jody Haynes + originaly passwd.pl + . Brad Langhorst + package relocatability + . Mirko Manea + originaly useradd.pl + . Alain Richard + bug report and Perl tips + . Roland Schulz + bug report for smbldap-passwd + . Xavier Boschian + bug report for smbldap-populate + + +# - The End diff --git a/examples/LDAP/smbldap-tools/COPYING b/examples/LDAP/smbldap-tools/COPYING new file mode 100644 index 00000000000..32d0e6014a7 --- /dev/null +++ b/examples/LDAP/smbldap-tools/COPYING @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) 19yy + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) 19yy name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/examples/LDAP/smbldap-tools/ChangeLog b/examples/LDAP/smbldap-tools/ChangeLog new file mode 100644 index 00000000000..9a0bc744e19 --- /dev/null +++ b/examples/LDAP/smbldap-tools/ChangeLog @@ -0,0 +1,29 @@ +# $Source: /data/src/mirror/cvs/samba/examples/LDAP/smbldap-tools/ChangeLog,v $ +# +## ChangeLog for SMBLDAP-TOOLS + +* 2002-06-03: notes to webmin.idealx.org (idxldapaccounts) +* 2002-06-01: release 0.7. tested with 2.2.4 +* 2002-05-31: fixed smbldap-populate compliance to smbldap_conf + cleaned up smbldap_conf to be more readable + some more documentation + bugfixes on smbldap-passwd and smbldap-populate +* 2002-05-16: modified default mode on homes: now 700 +* 2002-05-13: fixed spec (relocation and reqs) +* 2002-03-02: fixed 2.2.3 sambaAccount bug with smbldap-useradd.pl + (rid is now mandatory in the sambaAccount objectClass) +* 2002-02-14: just modified default populate for Administrator +* 2002-02-05: release 0.6. enable/disable user in usermod +* 2002-02-04: release 0.5. added smbldap-migrate-groups to migrate NT groups + from a net group dump. added samba parameters to smbldap-useradd + and smbldap-usermod. +* 2002-01-12: added smbldap-migrate-accounts to migrate users/machines + accounts from a PWDUMP dump +* 2001-12-13: added smbldap-populate to create the initial base +* 2001-12-13: initial release 0.1 +* 2001-12-12: fixed the SPEC file for RedHat +* 2001-12-03: cleaned the code and use strict; +* 2001-11-20: initial needs (for testing purpose on Samba-2.2.2 an Samba-TNG) + + +# - The End diff --git a/examples/LDAP/smbldap-tools/FILES b/examples/LDAP/smbldap-tools/FILES new file mode 100644 index 00000000000..48ee571b29d --- /dev/null +++ b/examples/LDAP/smbldap-tools/FILES @@ -0,0 +1,43 @@ +# $Source: /data/src/mirror/cvs/samba/examples/LDAP/smbldap-tools/FILES,v $ +# +## File listing for SMBLDAP-TOOLS + +CONTRIBUTORS : authors and contributors +COPYING : licence +FILES : this file listing +README : introduction and usage +TODO : feature request and bug report list +ChangeLog : changelog + +Core: +=-=-= +smbldap-groupadd.pl : to add a new group + (objectclass: posixGroup) +smbldap-groupdel.pl : to delete a group + (objectclass: posixGroup) +smbldap-groupmod.pl : to modify a group (mostly used to add user to a group) + (objectclass: posixGroup) +smbldap-groupshow.pl : to view a group + (objectclass: posixGroup) +smbldap_conf.pm : global configuration datas +smbldap_tools.pm : functions +smbldap-useradd.pl : to add a new user + (objectclass: posixAccount and/or sambaAccount) +smbldap-userdel.pl : to delete a user + (objectclass: posixAccount and/or sambaAccount) +smbldap-usermod.pl : to modify an user datas + (objectclass: posixAccount and/or sambaAccount) +smbldap-usershow.pl : to view an user datas + (objectclass: posixAccount and/or sambaAccount) +smbldap-passwd.pl : to sync passwd (Unix and Samba) + (a replacement for the system passwd utility) +smbldap-populate.pl : to add a builtin ldif to initialize your LDAP master for + smbldap use, or to add a specified ldif +smbldap-tools.spec : SPEC file for RedHat RPM package format + +Migration: +=-=-=-=-=- +smbldap-migrate-accounts.pl : add NT sam entries from pwdump to ldap +smbldap-migrate-groups.pl : add any LDAP posixGroups from the output of the 'net group' NT command + +# - The End diff --git a/examples/LDAP/smbldap-tools/INFRASTRUCTURE b/examples/LDAP/smbldap-tools/INFRASTRUCTURE new file mode 100644 index 00000000000..75b80bb4c8b --- /dev/null +++ b/examples/LDAP/smbldap-tools/INFRASTRUCTURE @@ -0,0 +1,84 @@ +# $Source: /data/src/mirror/cvs/samba/examples/LDAP/smbldap-tools/INFRASTRUCTURE,v $ +# +## Some notes about the architecture + + +Global Architecture for smbdlap-tools +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +smbldap-tools help you manage users and groups for Unix and Samba, +using LDAP. They may be used in any context, and are kept relatively +simplier enought to let you customize them to you needs. + +They need the following objectClasses to work: + . sambaAccount: from samba.schema for Samba 2.2 branch + . posixAccount and posixGroup : from nis.schema + . organizationalUnit and dcObject: from core.schema + +They will probably use in a near future some additional objectClasses +to support : + . mail features (sendmail/postfix/qmail/courier). + . conform to RFC2307 best practices (and so some maps too like merging + Netbios computers (sambaAccounts) with ipHosts + +For ease of visualization of the LDAP objects by human standards, we +used a DIT like this one : + . dc=IDEALX,dc=org : the company/organization suffix + . ou=Users : to store users accounts + . ou=Computers : to store computers accounts + . ou=Groups : to store system groups +Of course, you're free to use a different naming scheme and DIT (see +smbldap_conf.pm). + + +Built in groups initial population +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +smbldap-populate.pl populate the LDAP directory with some built in groups +using gidNumber according to Well Know RID of Windows NT4 Srv. In fact, As +far a Samba 2.2.x is concerned, only the 'Domain Admins' (gidNumber 512) have +real inpact on the Samba and Windows population. To activate this group as +the Domain Administrators Group, use the following smb.conf directive (see +man smb.conf for more): + + domain admin group = " @"Domain Admins" " + +Other built in groups are really cosmetic ones with Samba 2.2.x. We did not +removed them because one of these days, we whish to use Samba 3.0 where +Windows Group Support should be operational. + +Why these specific gidNumbers ? +It's about unix/windows mapping of numerical ids with Samba. Ids below 1024 +are NT special ids. In fact, 512 is the RID (Windows uid/gid) for the +"Domain Administrators" NT group. The magic number is found in Samba sources +and possibly other Samba/Windows documentations. + +The goal is to have a set of Unix users who are Domain Administrators and can +modify Samba datas (eg. LDAP content), with commandline tools or within +Windows via Samba. + +Say you want to add a NT4 ws to an NT domain (controlled by a samba/ldap +server). You give the domain administrator's login and password in the +appropriate ws settings, then the ws contacts the samba server, which checks +the credentials and use them as unix user to run the smbldap-tools (if I +remember). Giving 512 as a RID to a LDAP entry marks it as a domain admin +for Samba (thus Windows). Using nss_ldap, you also have an account with +gid 512. + + +Known BUGS and WORKAROUND used +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +The 2.2.2 has at least a bug : rid/primaryGroupID are read as hex in LDAP, +but written as decimal. Fixed in CVS by reading as decimal. By default +smbldap-useradd.pl writes decimal to LDAP. Use -x to support the odd +behaviour. + +The samba-2.2.4-ldapbindnotuid0.patch is not a perfect solution however +as the check is there because Samba store admin credentials to establish the +LDAP connection. The uid == 0 check was to ensure that a normal user could +not get write access to the LDAP backend. A more logical situation should be +done for 2.2.5 by checking if the user is a member of the domain admin group +(reported to Jerremy and Gerald 2002-05-28). + +# - The End diff --git a/examples/LDAP/smbldap-tools/INSTALL b/examples/LDAP/smbldap-tools/INSTALL new file mode 100644 index 00000000000..f4c72751a75 --- /dev/null +++ b/examples/LDAP/smbldap-tools/INSTALL @@ -0,0 +1,28 @@ +# $Source: /data/src/mirror/cvs/samba/examples/LDAP/smbldap-tools/INSTALL,v $ +# +## How To Install SMBLDAP-TOOLS + +Quick & Dirty: +=-=-=-=-=-=-=- + . Copy all those scripts in /usr/local/sbin/ + . Modify smbldap_conf.pm to match your configuration + . If not already done : "smbpasswd -w secret" to set up + the ldap admin password in secrets.tdb + . Either add /usr/local/sbin in $PERLLIB or run the scripts + from this directory, or make a symlink from /usr/local/sbin/*.pm + to /usr/lib/perl5/. + . to allow a domain admin to add user using "add user script" in smb.conf : + chmod 753 smbldap_conf.pm + chmod 750 smbldap-useradd.pl + chgrp 512 smbldap_conf.pm smbldap-useradd.pl (512 = 0x200 = Domain Admins) + Have your admin belong to this group + In smb.conf : domain admin group = " @"Domain Admins" " + +RedHat RPM: +=-=-=-=-=-= +Install smbldap-tools-0.7-1.i386.rpm +Modify /usr/local/sbin/smbldap_conf.pm to match you configuration +If not already done : "smbpasswd -w secret" to set up +the ldap admin password in secrets.tdb + +# - The End diff --git a/examples/LDAP/smbldap-tools/Makefile b/examples/LDAP/smbldap-tools/Makefile new file mode 100644 index 00000000000..3e5eac427d7 --- /dev/null +++ b/examples/LDAP/smbldap-tools/Makefile @@ -0,0 +1,35 @@ +PACKAGE=smbldap-tools +RELEASE=0.7 +DESTDIR = $(PACKAGE)-$(RELEASE) + +dist: distclean $(DESTDIR).tgz + +$(DESTDIR).tgz: .diststamp + rm -rf $(DESTDIR) + mkdir $(DESTDIR) + # copy files + cp CONTRIBUTORS $(DESTDIR) + cp COPYING $(DESTDIR) + cp ChangeLog $(DESTDIR) + cp FILES $(DESTDIR) + cp INSTALL $(DESTDIR) + cp README $(DESTDIR) + cp TODO $(DESTDIR) + cp INFRASTRUCTURE $(DESTDIR) + tar cf mkntpwd.tar mkntpwd + gzip mkntpwd.tar + cp mkntpwd.tar.gz $(DESTDIR) + cp smbldap-*.pl $(DESTDIR) + cp smbldap_*.pm $(DESTDIR) + # copy directories + tar cvzf $(DESTDIR).tgz $(DESTDIR) + rm -rf $(DESTDIR) + touch .diststamp + +.diststamp: + +distclean: + rm -f *~ + rm -f $(DESTDIR).tgz + rm -f mkntpwd.tar.gz + diff --git a/examples/LDAP/smbldap-tools/NEWS b/examples/LDAP/smbldap-tools/NEWS new file mode 100644 index 00000000000..e69de29bb2d diff --git a/examples/LDAP/smbldap-tools/README b/examples/LDAP/smbldap-tools/README new file mode 100644 index 00000000000..add0175c0ce --- /dev/null +++ b/examples/LDAP/smbldap-tools/README @@ -0,0 +1,87 @@ +# $Source: /data/src/mirror/cvs/samba/examples/LDAP/smbldap-tools/README,v $ +# + +Latest version may be found at http://samba.idealx.org/ + + +What those tools are for? +=-=-=-=-=-=-=-=-=-=-=-=-= + +A collection of scripts, «over» user{add,del,mod} and group{add,del,mod} +system tools to manipulate users and groups stored in LDAP directory, +for DEN system like SAMBA-LDAP and pam/nss_ldap systems. + +Additionnaly, some scripts are designed to ease your migration from +a Windows NT 4.0 PDC Server to a Samba-LDAP PDC Server (Killer?;-): +smbldap-populate, smbldap-migrate-groups, smbldap-migrate-accounts. + +They are currently used with Samba 2.2.4, therefore you may (will) have +to make some fixes for Samba TNG and Samba 3.0. Hint: contribs welcome :) + +In the future, some other function may come (like backup and restore, +Novell migration tools, samba system activity report, dealing with +mail functions, compliance to RFC2307...): consult TODO. + + +What do SMBLDAP-TOOLS provide? +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +Those tools provide the following functions : + . populate LDAP database with a basic LDIF + . add a user or group + . delete a user or group + . modify all users or groups data (all attributes types stored in + posixAccount and sambaAccount object class) +Taking care of : + . staying compatible with all standard system tools options + (user/group{add,del,mod}) + . be extensible for future developments + (manipulation of shadow account options, for example) + . error management, in the way system tools do +Constraints : + . usage of PERL (portability) + . all options must be placed in an external configuration file + . english localization + +The current release uses the "mkntpwd" program, in mkntpwd.tar.gz +in the current directory. It comes from +http://www.demog.berkeley.edu/~aperrin/tips/src/mkntpwd.tar.gz +It allows to not use smbpasswd (if $with_smbpasswd == 0 in smbldap_conf.pm) + +What do SMBLDAP-TOOLS deliver? +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +Contents : + . scripts (see FILES) + . user documentation in pod format, included in the sources + (or just use the -? option) + +These tools aim at delivering the same functionality as the corresponding +system tools. However they may not be all implemented yet. +Current limitations : + . no shadow support + . cannot change uid with usermod + . no UTF-8 support (thus ASCII-7 only) + + +How to generate documentation? +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +Just issue the following command: + perldoc name_of_script.pl (ex: perldoc smbldap-useradd.pl) + +Where can I find the latest release of those scripts? +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +Just fire any web browser to http://samba.IDEALX.org/ +and/or contact samba@IDEALX.org + +Additionnaly, you will find an useful Webmin module +at http://webmin.IDEALX.org/ if interested in a graphical +user interface to manager user and groups accounts via Webmin +for your Samba+LDAP PDC. + +Let us know if these tools helped you, or if we should enhance +them with some functions you want them to support. + +Sincerly, + LEM + +# - The End diff --git a/examples/LDAP/smbldap-tools/TODO b/examples/LDAP/smbldap-tools/TODO new file mode 100644 index 00000000000..57424d462af --- /dev/null +++ b/examples/LDAP/smbldap-tools/TODO @@ -0,0 +1,27 @@ +# $Source: /data/src/mirror/cvs/samba/examples/LDAP/smbldap-tools/TODO,v $ +# +## TODO list - First In, Last in the list... +## (BF: Bug Report / FR: Feature Request) + + +FR * use RFC2307 best practices (Luke, next time you visit Paris, have a + beer at IDEALX'cantina ;-) +FR * add mail (sendmail/postfix/qmail/courier) support +FR * bugfix, really : allow non-root users to change passwd + (currently the config must be unreadable because of bindpasswd) +FR * make smbldap-tools to use system configuration files + (/etc/login.defs and /etc/ldap.conf for example) +FR * rewrite smbldap-tools using perl-ldap. In fact, this 0.x + release use ldap system tools (ldapadd,ldapdelete,ldapmodify) +FR * add shadowAccounts manipulation support +FR * internationalize the SMBLDAP-TOOLS +FR * add smbldap-sar : Samba System Activity Report to help + supporting Samba/LDAP sysadmin activity +FR * add smbldap-backup/smbldap-restore to backup and restore + a SAM (in LDAP) database. No sorcery, just LDIF, but usefull + for non-LDAP gurus +FR * adding migration tools from migration from W2K and NetWare to Samba-LDAP +FR * adapt smbldap-tools to use Samba 3.0 + + +# - The End diff --git a/examples/LDAP/smbldap-tools/cgi/README b/examples/LDAP/smbldap-tools/cgi/README new file mode 100644 index 00000000000..7a4fc0c02b9 --- /dev/null +++ b/examples/LDAP/smbldap-tools/cgi/README @@ -0,0 +1,27 @@ +Description: + A cgi to allow users to change their passwords via a web browser. + +Installation: + Drop this into a cgi-enabled directory on your webserver. + Edit it and change the CONFIGURATION section to suit your environment. + READ THE NOTES SECTION. + +Notes: This script will run as the user who runs your web server. So, to invoke the smbpasswd call, you must implement sudo. + Example of /etc/sudoers: + + # Host alias specification + # User alias specification + User_Alias PASSWD = apache + # Cmnd alias specification + Cmnd_Alias PASSWD = /usr/bin/smbpasswd + # User privilege specification + root ALL=(ALL) ALL + PASSWD ALL= NOPASSWD: PASSWD + + This concept is probably very insecure and broken. That is why this is a 0.1 release. :) + + +Feel free to drop me suggestions. I am a perl learner so I am always open to suggestions. + +Terry Davis +tdavis@approbation.org diff --git a/examples/LDAP/smbldap-tools/cgi/ldappass.cgi b/examples/LDAP/smbldap-tools/cgi/ldappass.cgi new file mode 100755 index 00000000000..4a5ecb8f3a9 --- /dev/null +++ b/examples/LDAP/smbldap-tools/cgi/ldappass.cgi @@ -0,0 +1,202 @@ +#!/usr/bin/perl + +################################################################################ +# +# changepass.pl - A program to allow users to change their passwords +# via a web browser. +# Terry Davis +# +# URLs +# Net::LDAP - http:// +# usermod and this file - http://www.cloudamster.com/cloudmaster/projects +# +# Release History: +# Version 0.1 - initial write +# +# ToDo: +# ... the ToDo section is on the ToDo list... +# +# Limitations: +# The password cannot contain single and double quotes.....welcome to quoting hell.... +# +# Notes: +# This code is largely based on work done by Danny Sauer - http://www.cloudamster.com/cloudmaster/projects +# His work is not licensed and is marked as 'freely distributable'. +# Thank you to Danny for his hard work on the initial work. +# +################################################################################ + +use CGI qw(:standard); +use Net::LDAP; + +# CONFIGURATION SECTION +$masterLDAP = "ldap.idealx.org"; +$basedn = "dc=IDEALX,dc=org"; +$masterPw = ""; +$masterDN = "cn=manager,$basedn"; +$ldap_path = "/usr/bin"; +$ldap_opts = "-x"; +$ldappasswd = "$ldap_path/ldappasswd $ldap_opts -h $masterLDAP -D '$masterDN' -w '$masterPw'"; +$usersdn = "ou=Users,$basedn"; +# END CONFIGURATION + + + +# DONT EDIT ANYTHING BELOW THIS LINE +$logtag = "Login:"; +$passtag = "Current password:"; +$npasstag1 = "New password:"; +$npasstag2 = "Retype new pasword:"; +$error = ""; +$color = ""; +$stopcolor = ""; + +if(param()){ + nologin() unless ($username = param('login')); + nopass() unless ($oldpass = param('oldpass')); + nonewpass(1) unless ($newpass1 = param('newpass')); + nonewpass(2) unless ($newpass2 = param('newpass2')); + verifyuser($username) or die "bad user"; + verifypass($username, $oldpass) or die "bad pass"; + testnewpass($newpass1, $newpass2) or die "bad new pass"; + changepass($username, $newpass1) or die "couldn't change pass"; + printsuccess(); +}else{ + printpage(); +} +exit(0); + +sub verifyuser{ + local $user = shift; + $ldap = Net::LDAP->new($masterLDAP) or die "can't make new LDAP object: $@"; + $ldap->bind(); + if (0 < $ldap->search(base => $basedn, filter => "(uid=$user)")->count){ + return 1; + } + $logtag = $color . $logtag . $color; + $error = "No such user"; + printpage(); + return 0; +} + +sub verifypass{ + $uid = shift; + $pass = shift; + $ldap = Net::LDAP->new($masterLDAP) or die "can't make new LDAP object: $@"; + $binddn = "uid=$uid,ou=People,$basedn"; + return 1 if($ldap->bind( $binddn, password => $pass)->code == 0); + if($ldap->bind()){ + $passtag = $color . $passtag . $color; + $error = "Incorrect password"; + printpage(); + return 0; + }else{ + print header, start_html(-title=>"LDAP dead"); + print h2("
The LDAP server is temporarily unavailable."), + p,"Please try again later
"; + return 0; + }die "Something (or someone) is defective, contact your friendly Systems Administrator"; +} + +sub testnewpass{ + $p1 = shift; $p2 = shift; + if ($p1 ne $p2){ + $npasstag1 = $color . $npasstag1 . $color; + $npasstag2 = $color . $npasstag2 . $color; + $error = "Passwords don't match ($p1 vs $p2)"; + printpage(); + return 0; + } + if ($p1 =~ /"/ ){ + $npasstag1 = $color . $npasstag1 . $color; + $npasstag2 = $color . $npasstag2 . $color; + $error = "Passwords cannot contain double quotes. Sorry"; + printpage(); + return 0; + } + if ($p1 =~ /'/ ){ + $npasstag1 = $color . $npasstag1 . $color; + $npasstag2 = $color . $npasstag2 . $color; + $error = "Passwords cannot contain single quotes. Sorry"; + printpage(); + return 0; + } + return 1; +} + +sub changepass{ + local $user = shift; + local $newpass = shift; + local $dn = "uid=$user,$usersdn"; + system "$ldappasswd $dn -s '$newpass' > /dev/null"; + `/usr/bin/sudo /usr/bin/smbpasswd $user "$newpass"`; + exit(1); +} + +sub nologin{ + $logtag = $color . $logtag . $color; + $error = "You need to enter a Login Name"; + printpage(); + exit(1); +} + +sub nopass{ + $passtag = $color . $passtag . $color; + $error = "Please enter your old password"; + printpage(); + exit(1); +} + +sub nonewpass{ + $f=shift; + $npasstag1 = $color . $npasstag1 . $color if($f==1); + $npasstag2 = $color . $npasstag2 . $color if($f==2); + $error = "You need to enter your new password"; + $error .= " twice" if($f==2); + printpage(); + exit(1); +} + +sub printpage{ + print header, + start_html(-title=> "Password Change Page", + -author=> 'tdavis@birddog.com', + -BGCOLOR=> 'WHITE'), + h3('Password Change Page'), + startform(-method=>'POST'), + "", + "", + "
", + $logtag, + "", + textfield(-name=>'login', -default=>$login, + -size=>15, -maxlength=>20), + "
", + $passtag, + "", + password_field(-name=>'oldpass', -size=>15, -maxlength=>25), + "
", + $npasstag1, + "", + password_field(-name=>'newpass', -size=>15, -maxlength=>25), + "
", + $npasstag2, + "", + password_field(-name=>'newpass2', -size=>15, -maxlength=>25), + "
", + submit(-name=>"change"),reset(), + "
", + "", + endform(), + "$error", + end_html; +} + +sub printsuccess(){ + print header, + start_html(-title=> "Success", + -BGCOLOR=> 'WHITE'), + h1("Password Succesfully Changed"), + "
", + end_html; +} diff --git a/examples/LDAP/smbldap-tools/mkntpwd/Makefile b/examples/LDAP/smbldap-tools/mkntpwd/Makefile new file mode 100644 index 00000000000..23c9d471b0a --- /dev/null +++ b/examples/LDAP/smbldap-tools/mkntpwd/Makefile @@ -0,0 +1,62 @@ +# Makefile for l0phtcrack - mudge@l0pht.com 11/1/96 + +# C compiler +#CC=cc +CC=gcc + +# Uncomment the following to add symbols to the code for debugging +#DEBUG=-g -Wall -D_DEBUG +#DEBUG=-D_DEBUG + +# Optimization for the compiler +#OPTIMIZE= +OPTIMIZE=-O2 + +# Choose your architecture +# note that if you are on a big-endian machine like SUN's +# I haven't tweaked the mem-cmp's and md4 stuff to be in +# the correct order yet. You're on your own right now. +# +# FreeBSD +ARCH=-DMPU8086 +STATIC= +XLIBS= +# +# SUNOS +#ARCH=-DBIGENDIAN +#STATIC= +#OPTIMIZE=-O2 +#XLIBS= +# +# ULTRA_SPARC w/ native compiler +#ARCH=-DBIGENDIAN +#STATIC= +#OPTIMIZE=-fast -xO4 -xdepend -xchip=ultra -xarch=v8plus +#XLIBS= +# +# SunOS/Solaris w/gcc +#ARCH=-DBIGENDIAN -DTEST +#STATIC= +#OPTIMIZE=-O2 +#XLIBS= +# +# NeXTStep 3.2 +#CC=cc +#ARCH=-DBIGENDIAN +#STATIC=-Bstatic +#OPTIMIZE= +#XLIBS= + +CFLAGS= $(DEBUG) $(OPTIMIZE) $(ARCH) $(VISUAL) $(PERMUTE) $(STATIC) + +OBJS = getopt.o md4.o mkntpwd.o smbdes.o + +mkntpwd: $(OBJS) + $(CC) $(CFLAGS) $(XLIBS) -o mkntpwd $(OBJS) + +clean: + rm -f core *.o mkntpwd + +install: mkntpwd + install -m 555 mkntpwd $(PREFIX)/sbin/mkntpwd + diff --git a/examples/LDAP/smbldap-tools/mkntpwd/getopt.c b/examples/LDAP/smbldap-tools/mkntpwd/getopt.c new file mode 100644 index 00000000000..5b2e7a9100b --- /dev/null +++ b/examples/LDAP/smbldap-tools/mkntpwd/getopt.c @@ -0,0 +1,756 @@ +/* Getopt for GNU. + NOTE: getopt is now part of the C library, so if you don't know what + "Keep this file name-space clean" means, talk to roland@gnu.ai.mit.edu + before changing it! + + Copyright (C) 1987, 88, 89, 90, 91, 92, 93, 94 + Free Software Foundation, Inc. + +This file is part of the GNU C Library. Its master source is NOT part of +the C library, however. The master source lives in /gd/gnu/lib. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* This tells Alpha OSF/1 not to define a getopt prototype in . + Ditto for AIX 3.2 and . */ +#ifndef _NO_PROTO +#define _NO_PROTO +#endif + +#ifdef HAVE_CONFIG_H +#include +#endif + +#if !defined (__STDC__) || !__STDC__ +/* This is a separate conditional since some stdc systems + reject `defined (const)'. */ +#ifndef const +#define const +#endif +#endif + +#include + +#ifdef WIN32 +#include +#endif + +/* Comment out all this code if we are using the GNU C Library, and are not + actually compiling the library itself. This code is part of the GNU C + Library, but also included in many other GNU distributions. Compiling + and linking in this code is a waste when using the GNU C library + (especially if it is a shared library). Rather than having every GNU + program understand `configure --with-gnu-libc' and omit the object files, + it is simpler to just do this in the source for each such file. */ + +#if defined (_LIBC) || !defined (__GNU_LIBRARY__) + + +/* This needs to come after some library #include + to get __GNU_LIBRARY__ defined. */ +#ifdef __GNU_LIBRARY__ +/* Don't include stdlib.h for non-GNU C libraries because some of them + contain conflicting prototypes for getopt. */ +#include +#endif /* GNU C library. */ + +/* This version of `getopt' appears to the caller like standard Unix `getopt' + but it behaves differently for the user, since it allows the user + to intersperse the options with the other arguments. + + As `getopt' works, it permutes the elements of ARGV so that, + when it is done, all the options precede everything else. Thus + all application programs are extended to handle flexible argument order. + + Setting the environment variable POSIXLY_CORRECT disables permutation. + Then the behavior is completely standard. + + GNU application programs can use a third alternative mode in which + they can distinguish the relative order of options and other arguments. */ + +#include "getopt.h" + +/* For communication from `getopt' to the caller. + When `getopt' finds an option that takes an argument, + the argument value is returned here. + Also, when `ordering' is RETURN_IN_ORDER, + each non-option ARGV-element is returned here. */ + +char *optarg = NULL; + +/* Index in ARGV of the next element to be scanned. + This is used for communication to and from the caller + and for communication between successive calls to `getopt'. + + On entry to `getopt', zero means this is the first call; initialize. + + When `getopt' returns EOF, this is the index of the first of the + non-option elements that the caller should itself scan. + + Otherwise, `optind' communicates from one call to the next + how much of ARGV has been scanned so far. */ + +/* XXX 1003.2 says this must be 1 before any call. */ +int optind = 0; + +/* The next char to be scanned in the option-element + in which the last option character we returned was found. + This allows us to pick up the scan where we left off. + + If this is zero, or a null string, it means resume the scan + by advancing to the next ARGV-element. */ + +static char *nextchar; + +/* Callers store zero here to inhibit the error message + for unrecognized options. */ + +int opterr = 1; + +/* Set to an option character which was unrecognized. + This must be initialized on some systems to avoid linking in the + system's own getopt implementation. */ + +int optopt = '?'; + +/* Describe how to deal with options that follow non-option ARGV-elements. + + If the caller did not specify anything, + the default is REQUIRE_ORDER if the environment variable + POSIXLY_CORRECT is defined, PERMUTE otherwise. + + REQUIRE_ORDER means don't recognize them as options; + stop option processing when the first non-option is seen. + This is what Unix does. + This mode of operation is selected by either setting the environment + variable POSIXLY_CORRECT, or using `+' as the first character + of the list of option characters. + + PERMUTE is the default. We permute the contents of ARGV as we scan, + so that eventually all the non-options are at the end. This allows options + to be given in any order, even with programs that were not written to + expect this. + + RETURN_IN_ORDER is an option available to programs that were written + to expect options and other ARGV-elements in any order and that care about + the ordering of the two. We describe each non-option ARGV-element + as if it were the argument of an option with character code 1. + Using `-' as the first character of the list of option characters + selects this mode of operation. + + The special argument `--' forces an end of option-scanning regardless + of the value of `ordering'. In the case of RETURN_IN_ORDER, only + `--' can cause `getopt' to return EOF with `optind' != ARGC. */ + +static enum +{ + REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER +} ordering; + +/* Value of POSIXLY_CORRECT environment variable. */ +static char *posixly_correct; + +#ifdef __GNU_LIBRARY__ +/* We want to avoid inclusion of string.h with non-GNU libraries + because there are many ways it can cause trouble. + On some systems, it contains special magic macros that don't work + in GCC. */ +#include +#define my_index strchr +#else + +/* Avoid depending on library functions or files + whose names are inconsistent. */ + +char *getenv (); + +static char * +my_index (str, chr) + const char *str; + int chr; +{ + while (*str) + { + if (*str == chr) + return (char *) str; + str++; + } + return 0; +} + +/* If using GCC, we can safely declare strlen this way. + If not using GCC, it is ok not to declare it. */ +#ifdef __GNUC__ +/* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h. + That was relevant to code that was here before. */ +#if !defined (__STDC__) || !__STDC__ +/* gcc with -traditional declares the built-in strlen to return int, + and has done so at least since version 2.4.5. -- rms. */ +extern int strlen (const char *); +#endif /* not __STDC__ */ +#endif /* __GNUC__ */ + +#endif /* not __GNU_LIBRARY__ */ + +/* Handle permutation of arguments. */ + +/* Describe the part of ARGV that contains non-options that have + been skipped. `first_nonopt' is the index in ARGV of the first of them; + `last_nonopt' is the index after the last of them. */ + +static int first_nonopt; +static int last_nonopt; + +/* Exchange two adjacent subsequences of ARGV. + One subsequence is elements [first_nonopt,last_nonopt) + which contains all the non-options that have been skipped so far. + The other is elements [last_nonopt,optind), which contains all + the options processed since those non-options were skipped. + + `first_nonopt' and `last_nonopt' are relocated so that they describe + the new indices of the non-options in ARGV after they are moved. */ + +static void +exchange (argv) + char **argv; +{ + int bottom = first_nonopt; + int middle = last_nonopt; + int top = optind; + char *tem; + + /* Exchange the shorter segment with the far end of the longer segment. + That puts the shorter segment into the right place. + It leaves the longer segment in the right place overall, + but it consists of two parts that need to be swapped next. */ + + while (top > middle && middle > bottom) + { + if (top - middle > middle - bottom) + { + /* Bottom segment is the short one. */ + int len = middle - bottom; + register int i; + + /* Swap it with the top part of the top segment. */ + for (i = 0; i < len; i++) + { + tem = argv[bottom + i]; + argv[bottom + i] = argv[top - (middle - bottom) + i]; + argv[top - (middle - bottom) + i] = tem; + } + /* Exclude the moved bottom segment from further swapping. */ + top -= len; + } + else + { + /* Top segment is the short one. */ + int len = top - middle; + register int i; + + /* Swap it with the bottom part of the bottom segment. */ + for (i = 0; i < len; i++) + { + tem = argv[bottom + i]; + argv[bottom + i] = argv[middle + i]; + argv[middle + i] = tem; + } + /* Exclude the moved top segment from further swapping. */ + bottom += len; + } + } + + /* Update records for the slots the non-options now occupy. */ + + first_nonopt += (optind - last_nonopt); + last_nonopt = optind; +} + +/* Initialize the internal data when the first call is made. */ + +static const char * +_getopt_initialize (optstring) + const char *optstring; +{ + /* Start processing options with ARGV-element 1 (since ARGV-element 0 + is the program name); the sequence of previously skipped + non-option ARGV-elements is empty. */ + + first_nonopt = last_nonopt = optind = 1; + + nextchar = NULL; + + posixly_correct = getenv ("POSIXLY_CORRECT"); + + /* Determine how to handle the ordering of options and nonoptions. */ + + if (optstring[0] == '-') + { + ordering = RETURN_IN_ORDER; + ++optstring; + } + else if (optstring[0] == '+') + { + ordering = REQUIRE_ORDER; + ++optstring; + } + else if (posixly_correct != NULL) + ordering = REQUIRE_ORDER; + else + ordering = PERMUTE; + + return optstring; +} + +/* Scan elements of ARGV (whose length is ARGC) for option characters + given in OPTSTRING. + + If an element of ARGV starts with '-', and is not exactly "-" or "--", + then it is an option element. The characters of this element + (aside from the initial '-') are option characters. If `getopt' + is called repeatedly, it returns successively each of the option characters + from each of the option elements. + + If `getopt' finds another option character, it returns that character, + updating `optind' and `nextchar' so that the next call to `getopt' can + resume the scan with the following option character or ARGV-element. + + If there are no more option characters, `getopt' returns `EOF'. + Then `optind' is the index in ARGV of the first ARGV-element + that is not an option. (The ARGV-elements have been permuted + so that those that are not options now come last.) + + OPTSTRING is a string containing the legitimate option characters. + If an option character is seen that is not listed in OPTSTRING, + return '?' after printing an error message. If you set `opterr' to + zero, the error message is suppressed but we still return '?'. + + If a char in OPTSTRING is followed by a colon, that means it wants an arg, + so the following text in the same ARGV-element, or the text of the following + ARGV-element, is returned in `optarg'. Two colons mean an option that + wants an optional arg; if there is text in the current ARGV-element, + it is returned in `optarg', otherwise `optarg' is set to zero. + + If OPTSTRING starts with `-' or `+', it requests different methods of + handling the non-option ARGV-elements. + See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above. + + Long-named options begin with `--' instead of `-'. + Their names may be abbreviated as long as the abbreviation is unique + or is an exact match for some defined option. If they have an + argument, it follows the option name in the same ARGV-element, separated + from the option name by a `=', or else the in next ARGV-element. + When `getopt' finds a long-named option, it returns 0 if that option's + `flag' field is nonzero, the value of the option's `val' field + if the `flag' field is zero. + + The elements of ARGV aren't really const, because we permute them. + But we pretend they're const in the prototype to be compatible + with other systems. + + LONGOPTS is a vector of `struct option' terminated by an + element containing a name which is zero. + + LONGIND returns the index in LONGOPT of the long-named option found. + It is only valid when a long-named option has been found by the most + recent call. + + If LONG_ONLY is nonzero, '-' as well as '--' can introduce + long-named options. */ + +int +_getopt_internal (argc, argv, optstring, longopts, longind, long_only) + int argc; + char *const *argv; + const char *optstring; + const struct option *longopts; + int *longind; + int long_only; +{ + optarg = NULL; + + if (optind == 0) + optstring = _getopt_initialize (optstring); + + if (nextchar == NULL || *nextchar == '\0') + { + /* Advance to the next ARGV-element. */ + + if (ordering == PERMUTE) + { + /* If we have just processed some options following some non-options, + exchange them so that the options come first. */ + + if (first_nonopt != last_nonopt && last_nonopt != optind) + exchange ((char **) argv); + else if (last_nonopt != optind) + first_nonopt = optind; + + /* Skip any additional non-options + and extend the range of non-options previously skipped. */ + + while (optind < argc + && (argv[optind][0] != '-' || argv[optind][1] == '\0')) + optind++; + last_nonopt = optind; + } + + /* The special ARGV-element `--' means premature end of options. + Skip it like a null option, + then exchange with previous non-options as if it were an option, + then skip everything else like a non-option. */ + + if (optind != argc && !strcmp (argv[optind], "--")) + { + optind++; + + if (first_nonopt != last_nonopt && last_nonopt != optind) + exchange ((char **) argv); + else if (first_nonopt == last_nonopt) + first_nonopt = optind; + last_nonopt = argc; + + optind = argc; + } + + /* If we have done all the ARGV-elements, stop the scan + and back over any non-options that we skipped and permuted. */ + + if (optind == argc) + { + /* Set the next-arg-index to point at the non-options + that we previously skipped, so the caller will digest them. */ + if (first_nonopt != last_nonopt) + optind = first_nonopt; + return EOF; + } + + /* If we have come to a non-option and did not permute it, + either stop the scan or describe it to the caller and pass it by. */ + + if ((argv[optind][0] != '-' || argv[optind][1] == '\0')) + { + if (ordering == REQUIRE_ORDER) + return EOF; + optarg = argv[optind++]; + return 1; + } + + /* We have found another option-ARGV-element. + Skip the initial punctuation. */ + + nextchar = (argv[optind] + 1 + + (longopts != NULL && argv[optind][1] == '-')); + } + + /* Decode the current option-ARGV-element. */ + + /* Check whether the ARGV-element is a long option. + + If long_only and the ARGV-element has the form "-f", where f is + a valid short option, don't consider it an abbreviated form of + a long option that starts with f. Otherwise there would be no + way to give the -f short option. + + On the other hand, if there's a long option "fubar" and + the ARGV-element is "-fu", do consider that an abbreviation of + the long option, just like "--fu", and not "-f" with arg "u". + + This distinction seems to be the most useful approach. */ + + if (longopts != NULL + && (argv[optind][1] == '-' + || (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1]))))) + { + char *nameend; + const struct option *p; + const struct option *pfound = NULL; + int exact = 0; + int ambig = 0; + int indfound = 0; /* set to zero by Anton */ + int option_index; + + for (nameend = nextchar; *nameend && *nameend != '='; nameend++) + /* Do nothing. */ ; + + /* Test all long options for either exact match + or abbreviated matches. */ + for (p = longopts, option_index = 0; p->name; p++, option_index++) + if (!strncmp(p->name, nextchar, nameend - nextchar)) + { + if ((unsigned int)(nameend - nextchar) == (unsigned int)strlen (p->name)) + { + /* Exact match found. */ + pfound = p; + indfound = option_index; + exact = 1; + break; + } + else if (pfound == NULL) + { + /* First nonexact match found. */ + pfound = p; + indfound = option_index; + } + else + /* Second or later nonexact match found. */ + ambig = 1; + } + + if (ambig && !exact) + { + if (opterr) + fprintf (stderr, "%s: option `%s' is ambiguous\n", + argv[0], argv[optind]); + nextchar += strlen (nextchar); + optind++; + return '?'; + } + + if (pfound != NULL) + { + option_index = indfound; + optind++; + if (*nameend) + { + /* Don't test has_arg with >, because some C compilers don't + allow it to be used on enums. */ + if (pfound->has_arg) + optarg = nameend + 1; + else + { + if (opterr) + { + if (argv[optind - 1][1] == '-') + /* --option */ + fprintf (stderr, + "%s: option `--%s' doesn't allow an argument\n", + argv[0], pfound->name); + else + /* +option or -option */ + fprintf (stderr, + "%s: option `%c%s' doesn't allow an argument\n", + argv[0], argv[optind - 1][0], pfound->name); + } + nextchar += strlen (nextchar); + return '?'; + } + } + else if (pfound->has_arg == 1) + { + if (optind < argc) + optarg = argv[optind++]; + else + { + if (opterr) + fprintf (stderr, "%s: option `%s' requires an argument\n", + argv[0], argv[optind - 1]); + nextchar += strlen (nextchar); + return optstring[0] == ':' ? ':' : '?'; + } + } + nextchar += strlen (nextchar); + if (longind != NULL) + *longind = option_index; + if (pfound->flag) + { + *(pfound->flag) = pfound->val; + return 0; + } + return pfound->val; + } + + /* Can't find it as a long option. If this is not getopt_long_only, + or the option starts with '--' or is not a valid short + option, then it's an error. + Otherwise interpret it as a short option. */ + if (!long_only || argv[optind][1] == '-' + || my_index (optstring, *nextchar) == NULL) + { + if (opterr) + { + if (argv[optind][1] == '-') + /* --option */ + fprintf (stderr, "%s: unrecognized option `--%s'\n", + argv[0], nextchar); + else + /* +option or -option */ + fprintf (stderr, "%s: unrecognized option `%c%s'\n", + argv[0], argv[optind][0], nextchar); + } + nextchar = (char *) ""; + optind++; + return '?'; + } + } + + /* Look at and handle the next short option-character. */ + + { + char c = *nextchar++; + char *temp = my_index (optstring, c); + + /* Increment `optind' when we start to process its last character. */ + if (*nextchar == '\0') + ++optind; + + if (temp == NULL || c == ':') + { + if (opterr) + { + if (posixly_correct) + /* 1003.2 specifies the format of this message. */ + fprintf (stderr, "%s: illegal option -- %c\n", argv[0], c); + else + fprintf (stderr, "%s: invalid option -- %c\n", argv[0], c); + } + optopt = c; + return '?'; + } + if (temp[1] == ':') + { + if (temp[2] == ':') + { + /* This is an option that accepts an argument optionally. */ + if (*nextchar != '\0') + { + optarg = nextchar; + optind++; + } + else + optarg = NULL; + nextchar = NULL; + } + else + { + /* This is an option that requires an argument. */ + if (*nextchar != '\0') + { + optarg = nextchar; + /* If we end this ARGV-element by taking the rest as an arg, + we must advance to the next element now. */ + optind++; + } + else if (optind == argc) + { + if (opterr) + { + /* 1003.2 specifies the format of this message. */ + fprintf (stderr, "%s: option requires an argument -- %c\n", + argv[0], c); + } + optopt = c; + if (optstring[0] == ':') + c = ':'; + else + c = '?'; + } + else + /* We already incremented `optind' once; + increment it again when taking next ARGV-elt as argument. */ + optarg = argv[optind++]; + nextchar = NULL; + } + } + return c; + } +} + +int +getopt (argc, argv, optstring) + int argc; + char *const *argv; + const char *optstring; +{ + return _getopt_internal (argc, argv, optstring, + (const struct option *) 0, + (int *) 0, + 0); +} + +#endif /* _LIBC or not __GNU_LIBRARY__. */ + +#ifdef TEST + +/* Compile with -DTEST to make an executable for use in testing + the above definition of `getopt'. */ + +int +main (argc, argv) + int argc; + char **argv; +{ + int c; + int digit_optind = 0; + + while (1) + { + int this_option_optind = optind ? optind : 1; + + c = getopt (argc, argv, "abc:d:0123456789"); + if (c == EOF) + break; + + switch (c) + { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + if (digit_optind != 0 && digit_optind != this_option_optind) + printf ("digits occur in two different argv-elements.\n"); + digit_optind = this_option_optind; + printf ("option %c\n", c); + break; + + case 'a': + printf ("option a\n"); + break; + + case 'b': + printf ("option b\n"); + break; + + case 'c': + printf ("option c with value `%s'\n", optarg); + break; + + case '?': + break; + + default: + printf ("?? getopt returned character code 0%o ??\n", c); + } + } + + if (optind < argc) + { + printf ("non-option ARGV-elements: "); + while (optind < argc) + printf ("%s ", argv[optind++]); + printf ("\n"); + } + + exit (0); +} + +#endif /* TEST */ diff --git a/examples/LDAP/smbldap-tools/mkntpwd/getopt.h b/examples/LDAP/smbldap-tools/mkntpwd/getopt.h new file mode 100644 index 00000000000..f3696d955dc --- /dev/null +++ b/examples/LDAP/smbldap-tools/mkntpwd/getopt.h @@ -0,0 +1,133 @@ +/* Declarations for getopt. + Copyright (C) 1989, 90, 91, 92, 93, 94 Free Software Foundation, Inc. + +This file is part of the GNU C Library. Its master source is NOT part of +the C library, however. The master source lives in /gd/gnu/lib. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifndef _GETOPT_H +#define _GETOPT_H 1 + +#ifdef __cplusplus +extern "C" { +#endif + +/* For communication from `getopt' to the caller. + When `getopt' finds an option that takes an argument, + the argument value is returned here. + Also, when `ordering' is RETURN_IN_ORDER, + each non-option ARGV-element is returned here. */ + +extern char *optarg; + +/* Index in ARGV of the next element to be scanned. + This is used for communication to and from the caller + and for communication between successive calls to `getopt'. + + On entry to `getopt', zero means this is the first call; initialize. + + When `getopt' returns EOF, this is the index of the first of the + non-option elements that the caller should itself scan. + + Otherwise, `optind' communicates from one call to the next + how much of ARGV has been scanned so far. */ + +extern int optind; + +/* Callers store zero here to inhibit the error message `getopt' prints + for unrecognized options. */ + +extern int opterr; + +/* Set to an option character which was unrecognized. */ + +extern int optopt; + +/* Describe the long-named options requested by the application. + The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector + of `struct option' terminated by an element containing a name which is + zero. + + The field `has_arg' is: + no_argument (or 0) if the option does not take an argument, + required_argument (or 1) if the option requires an argument, + optional_argument (or 2) if the option takes an optional argument. + + If the field `flag' is not NULL, it points to a variable that is set + to the value given in the field `val' when the option is found, but + left unchanged if the option is not found. + + To have a long-named option do something other than set an `int' to + a compiled-in constant, such as set a value from `optarg', set the + option's `flag' field to zero and its `val' field to a nonzero + value (the equivalent single-letter option character, if there is + one). For long options that have a zero `flag' field, `getopt' + returns the contents of the `val' field. */ + +struct option +{ +#if defined (__STDC__) && __STDC__ + const char *name; +#else + char *name; +#endif + /* has_arg can't be an enum because some compilers complain about + type mismatches in all the code that assumes it is an int. */ + int has_arg; + int *flag; + int val; +}; + +/* Names for the values of the `has_arg' field of `struct option'. */ + +#define no_argument 0 +#define required_argument 1 +#define optional_argument 2 + +#if defined (__STDC__) && __STDC__ +#ifdef __GNU_LIBRARY__ +/* Many other libraries have conflicting prototypes for getopt, with + differences in the consts, in stdlib.h. To avoid compilation + errors, only prototype getopt for the GNU C library. */ +extern int getopt (int argc, char *const *argv, const char *shortopts); +#else /* not __GNU_LIBRARY__ */ +extern int getopt (); +#endif /* __GNU_LIBRARY__ */ +extern int getopt_long (int argc, char *const *argv, const char *shortopts, + const struct option *longopts, int *longind); +extern int getopt_long_only (int argc, char *const *argv, + const char *shortopts, + const struct option *longopts, int *longind); + +/* Internal only. Users should not call this directly. */ +extern int _getopt_internal (int argc, char *const *argv, + const char *shortopts, + const struct option *longopts, int *longind, + int long_only); +#else /* not __STDC__ */ +extern int getopt (); +extern int getopt_long (); +extern int getopt_long_only (); + +extern int _getopt_internal (); +#endif /* __STDC__ */ + +#ifdef __cplusplus +} +#endif + +#endif /* _GETOPT_H */ diff --git a/examples/LDAP/smbldap-tools/mkntpwd/md4.c b/examples/LDAP/smbldap-tools/mkntpwd/md4.c new file mode 100644 index 00000000000..1c9c2e6ecd5 --- /dev/null +++ b/examples/LDAP/smbldap-tools/mkntpwd/md4.c @@ -0,0 +1,171 @@ +/* + Unix SMB/Netbios implementation. + Version 1.9. + a implementation of MD4 designed for use in the SMB authentication protocol + Copyright (C) Andrew Tridgell 1997 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +/* NOTE: This code makes no attempt to be fast! + + It assumes that a int is at least 32 bits long +*/ + +typedef unsigned int uint32; + +static uint32 A, B, C, D; + +static uint32 F(uint32 X, uint32 Y, uint32 Z) +{ + return (X&Y) | ((~X)&Z); +} + +static uint32 G(uint32 X, uint32 Y, uint32 Z) +{ + return (X&Y) | (X&Z) | (Y&Z); +} + +static uint32 H(uint32 X, uint32 Y, uint32 Z) +{ + return X^Y^Z; +} + +static uint32 lshift(uint32 x, int s) +{ + x &= 0xFFFFFFFF; + return ((x<>(32-s)); +} + +#define ROUND1(a,b,c,d,k,s) a = lshift(a + F(b,c,d) + X[k], s) +#define ROUND2(a,b,c,d,k,s) a = lshift(a + G(b,c,d) + X[k] + (uint32)0x5A827999,s) +#define ROUND3(a,b,c,d,k,s) a = lshift(a + H(b,c,d) + X[k] + (uint32)0x6ED9EBA1,s) + +/* this applies md4 to 64 byte chunks */ +static void mdfour64(uint32 *M) +{ + int j; + uint32 AA, BB, CC, DD; + uint32 X[16]; + + for (j=0;j<16;j++) + X[j] = M[j]; + + AA = A; BB = B; CC = C; DD = D; + + ROUND1(A,B,C,D, 0, 3); ROUND1(D,A,B,C, 1, 7); + ROUND1(C,D,A,B, 2, 11); ROUND1(B,C,D,A, 3, 19); + ROUND1(A,B,C,D, 4, 3); ROUND1(D,A,B,C, 5, 7); + ROUND1(C,D,A,B, 6, 11); ROUND1(B,C,D,A, 7, 19); + ROUND1(A,B,C,D, 8, 3); ROUND1(D,A,B,C, 9, 7); + ROUND1(C,D,A,B, 10, 11); ROUND1(B,C,D,A, 11, 19); + ROUND1(A,B,C,D, 12, 3); ROUND1(D,A,B,C, 13, 7); + ROUND1(C,D,A,B, 14, 11); ROUND1(B,C,D,A, 15, 19); + + ROUND2(A,B,C,D, 0, 3); ROUND2(D,A,B,C, 4, 5); + ROUND2(C,D,A,B, 8, 9); ROUND2(B,C,D,A, 12, 13); + ROUND2(A,B,C,D, 1, 3); ROUND2(D,A,B,C, 5, 5); + ROUND2(C,D,A,B, 9, 9); ROUND2(B,C,D,A, 13, 13); + ROUND2(A,B,C,D, 2, 3); ROUND2(D,A,B,C, 6, 5); + ROUND2(C,D,A,B, 10, 9); ROUND2(B,C,D,A, 14, 13); + ROUND2(A,B,C,D, 3, 3); ROUND2(D,A,B,C, 7, 5); + ROUND2(C,D,A,B, 11, 9); ROUND2(B,C,D,A, 15, 13); + + ROUND3(A,B,C,D, 0, 3); ROUND3(D,A,B,C, 8, 9); + ROUND3(C,D,A,B, 4, 11); ROUND3(B,C,D,A, 12, 15); + ROUND3(A,B,C,D, 2, 3); ROUND3(D,A,B,C, 10, 9); + ROUND3(C,D,A,B, 6, 11); ROUND3(B,C,D,A, 14, 15); + ROUND3(A,B,C,D, 1, 3); ROUND3(D,A,B,C, 9, 9); + ROUND3(C,D,A,B, 5, 11); ROUND3(B,C,D,A, 13, 15); + ROUND3(A,B,C,D, 3, 3); ROUND3(D,A,B,C, 11, 9); + ROUND3(C,D,A,B, 7, 11); ROUND3(B,C,D,A, 15, 15); + + A += AA; B += BB; C += CC; D += DD; + + A &= 0xFFFFFFFF; B &= 0xFFFFFFFF; + C &= 0xFFFFFFFF; D &= 0xFFFFFFFF; + + for (j=0;j<16;j++) + X[j] = 0; +} + +static void copy64(uint32 *M, unsigned char *in) +{ + int i; + + for (i=0;i<16;i++) + M[i] = (in[i*4+3]<<24) | (in[i*4+2]<<16) | + (in[i*4+1]<<8) | (in[i*4+0]<<0); +} + +static void copy4(unsigned char *out,uint32 x) +{ + out[0] = x&0xFF; + out[1] = (x>>8)&0xFF; + out[2] = (x>>16)&0xFF; + out[3] = (x>>24)&0xFF; +} + +/* produce a md4 message digest from data of length n bytes */ +void mdfour(unsigned char *out, unsigned char *in, int n) +{ + unsigned char buf[128]; + uint32 M[16]; + uint32 b = n * 8; + int i; + + A = 0x67452301; + B = 0xefcdab89; + C = 0x98badcfe; + D = 0x10325476; + + while (n > 64) { + copy64(M, in); + mdfour64(M); + in += 64; + n -= 64; + } + + for (i=0;i<128;i++) + buf[i] = 0; + memcpy(buf, in, n); + buf[n] = 0x80; + + if (n <= 55) { + copy4(buf+56, b); + copy64(M, buf); + mdfour64(M); + } else { + copy4(buf+120, b); + copy64(M, buf); + mdfour64(M); + copy64(M, buf+64); + mdfour64(M); + } + + for (i=0;i<128;i++) + buf[i] = 0; + copy64(M, buf); + + copy4(out, A); + copy4(out+4, B); + copy4(out+8, C); + copy4(out+12, D); + + A = B = C = D = 0; +} + + diff --git a/examples/LDAP/smbldap-tools/mkntpwd/mkntpwd.c b/examples/LDAP/smbldap-tools/mkntpwd/mkntpwd.c new file mode 100644 index 00000000000..0c7d61e1341 --- /dev/null +++ b/examples/LDAP/smbldap-tools/mkntpwd/mkntpwd.c @@ -0,0 +1,253 @@ +/* + This code is based on work from + L0phtcrack 1.5 06.02.97 mudge@l0pht.com + + The code also contains sources from: + . routines from the samba code source + md4.c smbdes.c + + Anton Roeckseisen (anton@genua.de) + +*/ + +/* + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "mkntpwd.h" + +void str_to_key(unsigned char *,unsigned char *); +void usage(char *); +int PutUniCode(char *dst,char *src); +void printlanhash(char *tmp); +void mdfour(unsigned char *out, unsigned char *in, int n); +void E_P16(unsigned char *p14,unsigned char *p16); + + +void main(int argc, char **argv) { + extern char *optarg; + int c; + + int printlan = 0; + char lanpwd[LMPASSWDLEN+1]; + int printnt = 0; + char inputfile[FILENAMEBUFFER+1] = ""; + FILE* InputFilePtr; + int just_pwd = 0; + int i; + char hashout[17]; + + char ntpasswd[NTPASSWDLEN+1]; + char *hold; + unsigned char *p16; + int uni_len; + char passwd[NTPASSWDLEN+1]; + + if (argc==1) + usage(argv[0]); + + if (argc==2) + just_pwd=1; + else + just_pwd=0; + + lanpwd[0] = '\0'; + ntpasswd[0] = '\0'; + + while ( (c = getopt(argc, argv, "L:N:f:")) != EOF){ + switch(c) { + case 'L': + printlan++; + strncpy(lanpwd,optarg,LMPASSWDLEN); + lanpwd[LMPASSWDLEN]='\0'; + for (i=0;i0 && passwd[strlen(passwd)-1]=='\n') + passwd[strlen(passwd)-1]='\0'; + + /* create LANMAN-password (shorter) */ + strncpy(lanpwd,passwd,LMPASSWDLEN); + lanpwd[LMPASSWDLEN]='\0'; + for (i=0;i1 && just_pwd==1) { + strncpy(lanpwd,argv[1],LMPASSWDLEN); + lanpwd[LMPASSWDLEN]='\0'; + for (i=0;i0) { + memset(hashout,'\0',17); + E_P16((uchar *)lanpwd,hashout); + printlanhash(hashout); + } + + if (printnt >0) { + + if (printlan>0) printf(":"); + + memset(ntpasswd, '\0', sizeof(ntpasswd)); + + if (passwd[strlen(passwd)-1] == '\n') /* strip the \n - this + is done in LowerString for the case sensitive + check */ + passwd[strlen(passwd)-1] = '\0'; + + hold = (char *)malloc(NTPASSWDLEN * 2); /* grab space for + unicode */ + if (hold == NULL){ + fprintf(stderr, "out of memory...crackntdialog hold\n"); + exit(1); + } + + uni_len = PutUniCode(hold, passwd); /* convert to + unicode and return correct + unicode length for md4 */ + + p16 = (unsigned char*)malloc(17); /* grab space for md4 hash */ + if (p16 == NULL){ + fprintf(stderr, "out of memory...crackntdialect p16\n"); + exit(1); + } + + memset(p16,'\0',17); + mdfour(p16,hold, uni_len); + + printlanhash(p16); + + free(p16); + free(hold); + } + + printf("\n"); + + exit(0); + +} + +/*****************************************************************************/ +/*****************************************************************************/ +/*****************************************************************************/ + +void usage(char *progname){ + char *p; + + p = strrchr(progname, '\\'); + if (p == NULL) + p = progname; + else + p++; + + fprintf(stderr, "Usage: %s [-L lanmgrpwd] [-N ntpasswd]\n",p); + fprintf(stderr, " %s password\n",p); + fprintf(stderr, " %s -f [-] [filename]\n\n",p); + fprintf(stderr, " -L lanmgrpasswd LanManager cleartextpwd <= 14 chars\n"); + fprintf(stderr, " -N ntpasswd NT cleartextpwd <=128 chars (usually <=14)\n\n"); + fprintf(stderr, " with both options present the encrypted LanManager-Pwd is \n"); + fprintf(stderr, " printed first, followed by a ':' and the encrypted NT-Pwd.\n\n"); + fprintf(stderr, " The second usage behaves like %s -L pwd -N pwd\n\n",p); + fprintf(stderr, " The third usage reads the password from STDIN or a File. Printout\n"); + fprintf(stderr, " is the same as second.\n\n"); + fprintf(stderr, "anton@genua.de\n\n"); + exit(1); +} + + +/******************************************************************* +write a string in unicoode format +********************************************************************/ +int PutUniCode(char *dst,char *src) +{ + int ret = 0; + while (*src) { + dst[ret++] = src[0]; + dst[ret++] = 0; + src++; + } + dst[ret++]=0; + dst[ret++]=0; + return(ret-2); /* the way they do the md4 hash they don't represent + the last null. ie 'A' becomes just 0x41 0x00 - not + 0x41 0x00 0x00 0x00 */ +} + +/* + print binary buffer as hex-string +*/ +void printlanhash(char *tmp) { + + int i; + unsigned char c; + char outbuffer[33]; + + + /* build string from binary hash */ + for(i=0;i<16;i++) { + c=tmp[i]; + sprintf(outbuffer+2*i,"%x",(c>>4) & 0x0f); + sprintf(outbuffer+2*i+1,"%x",c & 0x0f); + } + + /* convert to uppercase */ + for(i=0;i<32;i++) + outbuffer[i] = toupper(outbuffer[i]); + outbuffer[32]='\0'; + + /* print out hex-string */ + printf("%s",outbuffer); +} + + diff --git a/examples/LDAP/smbldap-tools/mkntpwd/mkntpwd.h b/examples/LDAP/smbldap-tools/mkntpwd/mkntpwd.h new file mode 100644 index 00000000000..9a020b8d286 --- /dev/null +++ b/examples/LDAP/smbldap-tools/mkntpwd/mkntpwd.h @@ -0,0 +1,17 @@ +#include +#include +#include +#include +#include + +typedef short int16; +typedef int int32; +typedef unsigned short uint16; +typedef unsigned int uint32; +typedef unsigned char uchar; + +#define MAX_STRING 255 +#define MAX_WORD 128 +#define LMPASSWDLEN 14 +#define NTPASSWDLEN 128 +#define FILENAMEBUFFER 128 diff --git a/examples/LDAP/smbldap-tools/mkntpwd/smbdes.c b/examples/LDAP/smbldap-tools/mkntpwd/smbdes.c new file mode 100644 index 00000000000..e4f8280f9bc --- /dev/null +++ b/examples/LDAP/smbldap-tools/mkntpwd/smbdes.c @@ -0,0 +1,337 @@ +/* + Unix SMB/Netbios implementation. + Version 1.9. + + a partial implementation of DES designed for use in the + SMB authentication protocol + + Copyright (C) Andrew Tridgell 1997 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +/* NOTES: + + This code makes no attempt to be fast! In fact, it is a very + slow implementation + + This code is NOT a complete DES implementation. It implements only + the minimum necessary for SMB authentication, as used by all SMB + products (including every copy of Microsoft Windows95 ever sold) + + In particular, it can only do a unchained forward DES pass. This + means it is not possible to use this code for encryption/decryption + of data, instead it is only useful as a "hash" algorithm. + + There is no entry point into this code that allows normal DES operation. + + I believe this means that this code does not come under ITAR + regulations but this is NOT a legal opinion. If you are concerned + about the applicability of ITAR regulations to this code then you + should confirm it for yourself (and maybe let me know if you come + up with a different answer to the one above) +*/ + + + +static int perm1[56] = {57, 49, 41, 33, 25, 17, 9, + 1, 58, 50, 42, 34, 26, 18, + 10, 2, 59, 51, 43, 35, 27, + 19, 11, 3, 60, 52, 44, 36, + 63, 55, 47, 39, 31, 23, 15, + 7, 62, 54, 46, 38, 30, 22, + 14, 6, 61, 53, 45, 37, 29, + 21, 13, 5, 28, 20, 12, 4}; + +static int perm2[48] = {14, 17, 11, 24, 1, 5, + 3, 28, 15, 6, 21, 10, + 23, 19, 12, 4, 26, 8, + 16, 7, 27, 20, 13, 2, + 41, 52, 31, 37, 47, 55, + 30, 40, 51, 45, 33, 48, + 44, 49, 39, 56, 34, 53, + 46, 42, 50, 36, 29, 32}; + +static int perm3[64] = {58, 50, 42, 34, 26, 18, 10, 2, + 60, 52, 44, 36, 28, 20, 12, 4, + 62, 54, 46, 38, 30, 22, 14, 6, + 64, 56, 48, 40, 32, 24, 16, 8, + 57, 49, 41, 33, 25, 17, 9, 1, + 59, 51, 43, 35, 27, 19, 11, 3, + 61, 53, 45, 37, 29, 21, 13, 5, + 63, 55, 47, 39, 31, 23, 15, 7}; + +static int perm4[48] = { 32, 1, 2, 3, 4, 5, + 4, 5, 6, 7, 8, 9, + 8, 9, 10, 11, 12, 13, + 12, 13, 14, 15, 16, 17, + 16, 17, 18, 19, 20, 21, + 20, 21, 22, 23, 24, 25, + 24, 25, 26, 27, 28, 29, + 28, 29, 30, 31, 32, 1}; + +static int perm5[32] = { 16, 7, 20, 21, + 29, 12, 28, 17, + 1, 15, 23, 26, + 5, 18, 31, 10, + 2, 8, 24, 14, + 32, 27, 3, 9, + 19, 13, 30, 6, + 22, 11, 4, 25}; + + +static int perm6[64] ={ 40, 8, 48, 16, 56, 24, 64, 32, + 39, 7, 47, 15, 55, 23, 63, 31, + 38, 6, 46, 14, 54, 22, 62, 30, + 37, 5, 45, 13, 53, 21, 61, 29, + 36, 4, 44, 12, 52, 20, 60, 28, + 35, 3, 43, 11, 51, 19, 59, 27, + 34, 2, 42, 10, 50, 18, 58, 26, + 33, 1, 41, 9, 49, 17, 57, 25}; + + +static int sc[16] = {1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1}; + +static int sbox[8][4][16] = { + {{14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7}, + {0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8}, + {4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0}, + {15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13}}, + + {{15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10}, + {3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5}, + {0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15}, + {13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9}}, + + {{10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8}, + {13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1}, + {13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7}, + {1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12}}, + + {{7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15}, + {13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9}, + {10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4}, + {3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14}}, + + {{2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9}, + {14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6}, + {4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14}, + {11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3}}, + + {{12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11}, + {10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8}, + {9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6}, + {4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13}}, + + {{4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1}, + {13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6}, + {1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2}, + {6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12}}, + + {{13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7}, + {1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2}, + {7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8}, + {2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11}}}; + +static void permute(char *out, char *in, int *p, int n) +{ + int i; + for (i=0;i>1; + key[1] = ((str[0]&0x01)<<6) | (str[1]>>2); + key[2] = ((str[1]&0x03)<<5) | (str[2]>>3); + key[3] = ((str[2]&0x07)<<4) | (str[3]>>4); + key[4] = ((str[3]&0x0F)<<3) | (str[4]>>5); + key[5] = ((str[4]&0x1F)<<2) | (str[5]>>6); + key[6] = ((str[5]&0x3F)<<1) | (str[6]>>7); + key[7] = str[6]&0x7F; + for (i=0;i<8;i++) { + key[i] = (key[i]<<1); + } +} + + +static void smbhash(unsigned char *out, unsigned char *in, unsigned char *key) +{ + int i; + char outb[64]; + char inb[64]; + char keyb[64]; + unsigned char key2[8]; + + str_to_key(key, key2); + + for (i=0;i<64;i++) { + inb[i] = (in[i/8] & (1<<(7-(i%8)))) ? 1 : 0; + keyb[i] = (key2[i/8] & (1<<(7-(i%8)))) ? 1 : 0; + outb[i] = 0; + } + + dohash(outb, inb, keyb); + + for (i=0;i<8;i++) { + out[i] = 0; + } + + for (i=0;i<64;i++) { + if (outb[i]) + out[i/8] |= (1<<(7-(i%8))); + } +} + +void E_P16(unsigned char *p14,unsigned char *p16) +{ + unsigned char sp8[8] = {0x4b, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25}; + smbhash(p16, sp8, p14); + smbhash(p16+8, sp8, p14+7); +} + +void E_P24(unsigned char *p21, unsigned char *c8, unsigned char *p24) +{ + smbhash(p24, c8, p21); + smbhash(p24+8, c8, p21+7); + smbhash(p24+16, c8, p21+14); +} + +void cred_hash1(unsigned char *out,unsigned char *in,unsigned char *key) +{ + unsigned char buf[8]; + + smbhash(buf, in, key); + smbhash(out, buf, key+9); +} + +void cred_hash2(unsigned char *out,unsigned char *in,unsigned char *key) +{ + unsigned char buf[8]; + static unsigned char key2[8]; + + smbhash(buf, in, key); + key2[0] = key[7]; + smbhash(out, buf, key2); +} + diff --git a/examples/LDAP/smbldap-tools/smbldap-groupadd.pl b/examples/LDAP/smbldap-tools/smbldap-groupadd.pl new file mode 100755 index 00000000000..6ced1eed2d0 --- /dev/null +++ b/examples/LDAP/smbldap-tools/smbldap-groupadd.pl @@ -0,0 +1,86 @@ +#!/usr/bin/perl + +# $Id: smbldap-groupadd.pl,v 1.1.4.1 2002/06/17 18:35:08 jerry Exp $ +# +# This code was developped by IDEALX (http://IDEALX.org/) and +# contributors (their names can be found in the CONTRIBUTORS file). +# +# Copyright (C) 2001-2002 IDEALX +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +# USA. + +# Purpose of smbldap-groupadd : group (posix) add + +use strict; +use smbldap_tools; + +use Getopt::Std; +my %Options; + +my $ok = getopts('og:?', \%Options); +if ( (!$ok) || (@ARGV < 1) || ($Options{'?'}) ) { + print "Usage: $0 [-go?] groupname\n"; + print " -g gid\n"; + print " -o gid is not unique\n"; + print " -? show this help message\n"; + exit (1); +} + +my $_groupName = $ARGV[0]; + +if (defined(get_group_dn($_groupName))) { + print "$0: group $_groupName exists\n"; + exit (6); +} + +my $_groupGidNumber = $Options{'g'}; + +if (!group_add($_groupName, $_groupGidNumber, $Options{'o'})) { + print "$0: error adding group $_groupName\n"; + exit (6); +} + +exit(0); + +######################################## + +=head1 NAME + + smbldap-groupadd.pl - Create a new group + +=head1 SYNOPSIS + + smbldap-groupadd.pl [-g gid [-o]] group + +=head1 DESCRIPTION + The smbldap-groupadd.pl command creates a new group account using + the values specified on the command line and the default values + from the system. The new group will be entered into the system + files as needed. The options which apply to the groupadd command are + + -g gid The numerical value of the group's ID. This value must be + unique, unless the -o option is used. The value must be non- + negative. The default is to use the smallest ID value greater + than 1000 and greater than every other group. + +=head1 SEE ALSO + + groupadd(1) + +=cut + +#' + diff --git a/examples/LDAP/smbldap-tools/smbldap-groupdel.pl b/examples/LDAP/smbldap-tools/smbldap-groupdel.pl new file mode 100755 index 00000000000..c5b64c3d4ef --- /dev/null +++ b/examples/LDAP/smbldap-tools/smbldap-groupdel.pl @@ -0,0 +1,95 @@ +#!/usr/bin/perl + +# $Id: smbldap-groupdel.pl,v 1.1.4.1 2002/06/17 18:35:08 jerry Exp $ +# +# This code was developped by IDEALX (http://IDEALX.org/) and +# contributors (their names can be found in the CONTRIBUTORS file). +# +# Copyright (C) 2001-2002 IDEALX +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +# USA. + +# Purpose of smbldap-groupdel : group (posix) deletion + +use strict; +use smbldap_tools; +use smbldap_conf; + +##################### + +use Getopt::Std; +my %Options; + +my $ok = getopts('?', \%Options); +if ( (!$ok) || (@ARGV < 1) || ($Options{'?'}) ) { + print "Usage: $0 groupname\n"; + print " -? show this help message\n"; + exit (1); +} + +my $_groupName = $ARGV[0]; + +my $dn_line; +if (!defined($dn_line = get_group_dn($_groupName))) { + print "$0: group $_groupName doesn't exist\n"; + exit (6); +} + +my $dn = get_dn_from_line($dn_line); + +my $rc = system "$ldapdelete $dn >/dev/null"; +die "$0: error while deleting group $_groupName\n" + unless ($rc == 0); + +my $nscd_status = system "/etc/init.d/nscd status >/dev/null 2>&1"; + +if ($nscd_status == 0) { + system "/etc/init.d/nscd restart > /dev/null 2>&1"; +} + +#if (defined($dn_line = get_group_dn($_groupName))) { +# print "$0: failed to delete group\n"; +# exit (7); +#} + + +exit (0); + +############################################################ + +=head1 NAME + + smbldap-groupdel.pl - Delete a group + +=head1 SYNOPSIS + + smbldap-groupdel.pl group + +=head1 DESCRIPTION + + The smbldap-groupdel.pl command modifies the system account files, + deleting all entries that refer to group. The named group must exist. + + You must manually check all filesystems to insure that no files remain + with the named group as the file group ID. + +=head1 SEE ALSO + + groupdel(1) + +=cut + +#' diff --git a/examples/LDAP/smbldap-tools/smbldap-groupmod.pl b/examples/LDAP/smbldap-tools/smbldap-groupmod.pl new file mode 100755 index 00000000000..a35e7ea898d --- /dev/null +++ b/examples/LDAP/smbldap-tools/smbldap-groupmod.pl @@ -0,0 +1,213 @@ +#!/usr/bin/perl + +# $Id: smbldap-groupmod.pl,v 1.1.4.1 2002/06/17 18:35:08 jerry Exp $ +# +# This code was developped by IDEALX (http://IDEALX.org/) and +# contributors (their names can be found in the CONTRIBUTORS file). +# +# Copyright (C) 2001-2002 IDEALX +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +# USA. + +# Purpose of smbldap-groupmod : group (posix) modification + + +use strict; +use smbldap_tools; +use smbldap_conf; + + +##################### + +use Getopt::Std; +my %Options; + +my $ok = getopts('og:n:m:x:?', \%Options); +if ( (!$ok) || (@ARGV < 1) || ($Options{'?'}) ) { + print "Usage: $0 [-g gid [-o]] [-n name] [-m members(,)] [-x members (,)] groupname\n"; + print " -g new gid\n"; + print " -o gid is not unique\n"; + print " -n new group name\n"; + print " -m add members (comma delimited)\n"; + print " -x delete members (comma delimted)\n"; + print " -? show this help message\n"; + exit (1); +} + +my $groupName = $ARGV[0]; + +if (!defined(get_group_dn($groupName))) { + print "$0: group $groupName doesn't exist\n"; + exit (6); +} + +my $newname = $Options{'n'}; + +my $nscd_status = system "/etc/init.d/nscd status >/dev/null 2>&1"; + +if ($nscd_status == 0) { + system "/etc/init.d/nscd restart > /dev/null 2>&1"; +} + +my $gid = getgrnam($groupName); + +my $tmp; +if (defined($tmp = $Options{'g'}) and $tmp =~ /\d+/) { + if (!defined($Options{'o'})) { + if (defined(getgrgid($tmp))) { + print "$0: gid $tmp exists\n"; + exit (6); + } + } + if (!($gid == $tmp)) { + my $tmpldif = +"dn: cn=$groupName,$groupsdn +changetype: modify +replace: gidNumber +gidNumber: $tmp + +"; + die "$0: error while modifying group $groupName\n" + unless (do_ldapmodify($tmpldif) == 0); + undef $tmpldif; + + } +} + +if (defined($newname)) { + my $FILE="|$ldapmodrdn >/dev/null"; + open (FILE, $FILE) || die "$!\n"; + print FILE </dev/null 2>&1"; + +if ($nscd_status == 0) { + system "/etc/init.d/nscd restart > /dev/null 2>&1"; +} + +exit (0); + +############################################################ + +=head1 NAME + + smbldap-groupmod.pl - Modify a group + +=head1 SYNOPSIS + + smbldap-groupmod.pl [-g gid [-o]] [-n group_name ] group + +=head1 DESCRIPTION + + The smbldap-groupmod.pl command modifies the system account files to + reflect the changes that are specified on the command line. + The options which apply to the smbldap-groupmod command are + + -g gid The numerical value of the group's ID. This value must be + unique, unless the -o option is used. The value must be non- + negative. Any files which the old group ID is the file + group ID must have the file group ID changed manually. + + -n group_name + The name of the group will be changed from group to group_name. + + -m members + The members to be added to the group in comma-delimeted form. + + -x members + The members to be removed from the group in comma-delimted form. + +=head1 EXAMPLES + + smbldap-groupmod.pl -g 253 development + This will change the GID of the 'development' group to '253'. + + smbldap-groupmod.pl -n Idiots Managers + This will change the name of the 'Managers' group to 'Idiots'. + + smbldap-groupmod.pl -m "jdoe,jsmith" "Domain Admins" + This will add 'jdoe' and 'jsmith' to the 'Domain Admins' group. + + smbldap-groupmod.pl -x "jdoe,jsmith" "Domain Admins" + This will remove 'jdoe' and 'jsmith' from the 'Domain Admins' group. + +=head1 SEE ALSO + + groupmod(1) + +=cut + +#' diff --git a/examples/LDAP/smbldap-tools/smbldap-groupshow.pl b/examples/LDAP/smbldap-tools/smbldap-groupshow.pl new file mode 100755 index 00000000000..2426b85fa83 --- /dev/null +++ b/examples/LDAP/smbldap-tools/smbldap-groupshow.pl @@ -0,0 +1,74 @@ +#!/usr/bin/perl + +# $Id: smbldap-groupshow.pl,v 1.1.4.1 2002/06/17 18:35:08 jerry Exp $ +# +# This code was developped by IDEALX (http://IDEALX.org/) and +# contributors (their names can be found in the CONTRIBUTORS file). +# +# Copyright (C) 2001-2002 IDEALX +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +# USA. + +# Purpose of smbldap-groupshow : user (posix,shadow,samba) display +# +# History : +# . originally by David Le Corfec + +use strict; +use smbldap_tools; + +use Getopt::Std; +my %Options; + +my $ok = getopts('?', \%Options); + +if ( (!$ok) || (@ARGV < 1) || ($Options{'?'}) ) { + print "Usage: $0 [-?] group\n"; + print " -? show this help message\n"; + exit (1); +} + +# Read only first @ARGV +my $group = $ARGV[0]; + +my $lines = read_group($group); +if (!defined($lines)) { + print "$0: group $group doesn't exist\n"; + exit (1); +} + +print "$lines\n"; + +exit(0); + +############################################################ + +=head1 NAME + + smbldap-groupshow.pl - Display group informations + +=head1 SYNOPSIS + + smbldap-groupshow.pl groupname + +=head1 DESCRIPTION + + The smbldap-groupshow.pl command displays informations + associated with the given group. + +=cut + +#' diff --git a/examples/LDAP/smbldap-tools/smbldap-migrate-accounts.pl b/examples/LDAP/smbldap-tools/smbldap-migrate-accounts.pl new file mode 100755 index 00000000000..dd66954c41b --- /dev/null +++ b/examples/LDAP/smbldap-tools/smbldap-migrate-accounts.pl @@ -0,0 +1,236 @@ +#!/usr/bin/perl + +# $Id: smbldap-migrate-accounts.pl,v 1.1.4.1 2002/06/17 18:35:08 jerry Exp $ +# +# This code was developped by IDEALX (http://IDEALX.org/) and +# contributors (their names can be found in the CONTRIBUTORS file). +# +# Copyright (C) 2002 IDEALX +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +# USA. + +# Purpose of smbldap-migrate-accounts : add NT sam entries from pwdump +# to ldap + +use strict; +use Getopt::Std; +use smbldap_tools; +use smbldap_conf; + +# smbldap-migrate.pl (-? for help) +# +# Read pwdump entries on stdin, and add them to the ldap server. +# Output uncreated/unmodified entries (see parameters -C -U) +# in pwdump format to stdout. +# Errors, debug and stats are output to stderr. + +sub modify_account +{ + my ($login, $basedn, $lmpwd, $ntpwd, $gecos, $homedir) = @_; + + my $tmpldif = +"dn: uid=$login,$basedn +changetype: modify +lmpassword: $lmpwd +ntpassword: $ntpwd +gecos: $gecos +smbHome: $homedir + +"; + + die "$0: error while modifying user $login\n" + unless (do_ldapmodify($tmpldif) == 0); + undef $tmpldif; +} + +##################### + + +my %Options; + +my $ok = getopts('awA:CUW:?', \%Options); + +if ( (!$ok) || ($Options{'?'}) ) { + print "Usage: $0 [-awAWCU?]\n"; + print " -a process only people, ignore computers\n"; + print " -w process only computers, ignore persons\n"; + print " -A option string passed verbatim to smbldap-useradd for persons\n"; + print " -W option string passed verbatim to smbldap-useradd for computers\n"; + print " -C if entry not found, don't create it and log it to stdout (default: create it)\n"; + print " -U if entry found, don't update it and log it to stdout (default: update it)\n"; + print " -? show this help message\n"; + exit (1); +} + +my %processed = ( 'user' => 0, 'machine' => 0); +my %created = ( 'user' => 0, 'machine' => 0); +my %updated = ( 'user' => 0, 'machine' => 0); +my %logged = ( 'user' => 0, 'machine' => 0); +my %errors = ( 'user' => 0, 'machine' => 0); +my %existing = ( 'user' => 0, 'machine' => 0); +my $specialskipped = 0; + +while (<>) +{ + my ($login, $rid, $lmpwd, $ntpwd, $gecos, $homedir, $b) = split(/:/, $_); + my $usertype; + my $userbasedn; + + my $entry_type = 'user'; + + if ($login =~ m/.*\$$/ ) { # computer + $processed{'machine'}++; + $entry_type = 'machine'; + if (defined($Options{'a'})) { + print STDERR "ignoring $login\n"; + next; + } + + $usertype = "-w $Options{'W'}"; + $userbasedn = $computersdn; + } + else { # people + $processed{'user'}++; + if (defined($Options{'w'})) { + print STDERR "ignoring $login\n"; + next; + } + if ($rid < 1000) { + $specialskipped++; + print STDERR "$login seems to be a special Win account (rid=$rid), skipping\n"; + next; + } + + $usertype = "-a $Options{'A'}"; + $userbasedn = $usersdn; + } + + # normalize homedir +# uncomment to replace configured share with share from pwdump +# if ($homedir eq "") { + $homedir = $_userSmbHome; +# } + + # normalize gecos + if (!($gecos eq "")) { + $gecos =~ tr/ÁÀÂÄáàâäÇçÉÈÊËÆéèêëæÍÌÏÎíìîÏÑñÓÒÔÖóòôöÚÙÜÛúùüûÝýÿ/AAAAaaaaCcEEEEEeeeeeIIIIiiiiNnOOOOooooUUUUuuuuYyy/; + } else { + $gecos = $_userGecos; + } + + my $user_exists = is_samba_user($login); + + if (!$user_exists) { + if (!defined($Options{'C'})) { + # uid doesn't exist and we want to create it + my $addcmd = "/usr/local/sbin/smbldap-useradd.pl $usertype $login > /dev/null"; + print STDERR "$addcmd\n"; + my $r = system "$addcmd"; + if ($r != 0) { + print STDERR "error adding $login, skipping\n"; + next; + } + # lem modif... a retirer si pb + if ($entry_type eq "user") + { + modify_account($login, $userbasedn, $lmpwd, $ntpwd, $gecos, $homedir); + } + + $created{$entry_type}++; + } + else { # uid doesn't exist and no create => log + print "$_"; + $logged{$entry_type}++; + } + } + else { # account exists + $existing{$entry_type}++; + if (!defined($Options{'U'})) { # exists and modify + modify_account($login, $userbasedn, $lmpwd, $ntpwd, $gecos, $homedir); + $updated{$entry_type}++; + } + else { # exists and log + print "$_"; + $logged{$entry_type}++; + } + } +} + +my $sum; + +$sum = $processed{'user'} + $processed{'machine'}; +print STDERR "processed: all=$sum user=$processed{'user'} machine=$processed{'machine'}\n"; + +$sum = $existing{'user'} + $existing{'machine'}; +print STDERR "existing: all=$sum user=$existing{'user'} machine=$existing{'machine'}\n"; + +$sum = $created{'user'} + $created{'machine'}; +print STDERR "created: all=$sum user=$created{'user'} machine=$created{'machine'}\n"; + +$sum = $updated{'user'} + $updated{'machine'}; +print STDERR "updated: all=$sum user=$updated{'user'} machine=$updated{'machine'}\n"; + +$sum = $logged{'user'} + $logged{'machine'}; +print STDERR "logged: all=$sum user=$logged{'user'} machine=$logged{'machine'}\n"; + +print STDERR "special users skipped: $specialskipped\n"; + + +######################################## + +=head1 NAME + + smbldap-migrate.pl - Migrate NT accounts to LDAP + +=head1 SYNOPSIS + + smbldap-migrate.pl [-a] [-w] [-A opts] [-W opts] [-C] [-U] [-?] + +=head1 DESCRIPTION + + This command reads from stdin account entries as created by pwdump, + a tool to dump an user database on NT. + Depending of the options, some account entries may be output on + stdout. All errors and informations are sent to stderr. + + -a process only people, ignore computers + + -w process only computers, ignore persons + + -A opts + a string containing arguments to pass verbatim to + smbldap-useradd when adding users, eg "-m -x". + You don't have to specify -a in this string. + + -W opts + a string containing arguments to pass verbatim to + smbldap-useradd when adding computers, eg "-m -x". + You don't have to specify -w in this string. + + -C if NT account not found in LDAP, don't create it and log it to stdout + (default: create it) + + -U if NT account found in LDAP, don't update it and log it to stdout + (default: update it) + + -? show the help message + +=cut + +#' + +# The End + diff --git a/examples/LDAP/smbldap-tools/smbldap-migrate-groups.pl b/examples/LDAP/smbldap-tools/smbldap-migrate-groups.pl new file mode 100644 index 00000000000..8be0c1b72be --- /dev/null +++ b/examples/LDAP/smbldap-tools/smbldap-migrate-groups.pl @@ -0,0 +1,227 @@ +#!/usr/bin/perl + +# $Id: smbldap-migrate-groups.pl,v 1.1.4.1 2002/06/17 18:35:08 jerry Exp $ +# +# This code was developped by IDEALX (http://IDEALX.org/) and +# contributors (their names can be found in the CONTRIBUTORS file). +# +# Copyright (C) 2002 IDEALX +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +# USA. + +# Purpose of smbldap-migrate-groups : to parse a Windows +# group dump and populate Unix groups +# Reads group dump on stdin + + +use strict; +use smbldap_tools; +use smbldap_conf; +use Getopt::Std; + + + +sub process_rec_group +{ + my ($group, $mb) = @_; + my @members; + + if (!(@members = group_get_members($group))) { + return 0; + } + + foreach my $m (@members) { + if ( !($m =~ m/^\*/) ) { + push @{$mb}, $m; + } else { + my $gname = $m; + $gname =~ s/^.//; + if (!process_rec_group($gname, $mb)) { + print "recursive group not added : $gname\n"; + } + } + } +} + + +# given a group dn and a list of members, update the group +sub modify_group +{ + my ($group, $dn_line, @members, $recgroup) = @_; + my $m; + my @new_mb; + + foreach $m (@members) { + if ( ($m =~ m/^\*/) ) { + my $gname = $m; + $gname =~ s/^.//; + if (!$recgroup) { + print "recursive group not added : $gname\n"; + } else { + if (!process_rec_group($gname, \@new_mb)) { + print "recursive group not added : $gname\n"; + } + } + } else { + push @new_mb, $m; + } + } + + # new_mb contains flat members from group dump + # now append them to existing members + push @new_mb, group_get_members($group); + # uniq them + my %saw; + @saw{@new_mb} = (); + @new_mb = keys %saw; + + my $nmb = $#new_mb + 1; + print STDERR "Group $group now has $nmb member(s)\n"; + + my $mbs; + foreach $m (@new_mb) { + $mbs .= "memberUid: $m\n"; + } + + my $mods="$dn_line +changetype: modify +replace: memberUid +$mbs +"; + + #print "$mods\n"; + my $tmpldif = +"$mods +"; + + die "$0: error while modifying group $group\n" + unless (do_ldapmodify($tmpldif) == 0); + undef $tmpldif; +} + +sub display_group +{ + my ($group, @members) = @_; + + print "Group name $group\n"; + print "Members\n"; + my $m; + my $i = 0; + foreach $m (@members) { + print "$m "; + if ($i % 5 == 0) { + print "\n"; + } + $i++; + } +} + +sub process_group +{ + my ($group, @members, $nocreate, $noupdate, $recgroup) = @_; + + my $dn_line; + if (!defined($dn_line = get_group_dn($group))) { + # group not found, create it ? + if (!$nocreate) { + system "/usr/local/sbin/smbldap-groupadd.pl \"$group\"; sleep 5"; + if (!defined($dn_line = get_group_dn($group))) { + return 1; + } + modify_group($group, $dn_line, @members, $recgroup); + } else { + # don't create + print "not created:\n"; + display_group($group, @members); + } + } else { + # group found, update it ? + if (!$noupdate) { + modify_group($group, $dn_line, @members, $recgroup); + } else { + # don't update + print "not updated:\n"; + display_group($group, @members); + } + } +} + +################################################### + +my %Options; + +my $ok = getopts('CUr?', \%Options); +if ( (!$ok) || ($Options{'?'}) ) { + print "Usage: $0 [-CUr?] < group_dump\n"; + print " -C don't create group if it doesn't exist\n"; + print " -U don't update group if it exists\n"; + print " -r recursively process groups\n"; + exit(1); +} + +my $group_name; +my $group_desc; +my $has_members = 0; +my @members = (); + +while (<>) +{ + my $line = $_; + chomp($line); + next if ( $line =~ m/^\s*$/ ); + + if ($group_name eq "") { + if ( $line =~ m/^Group name\s+(.+).$/ ) { + $group_name = $1; + next; + } + } + if ($group_desc eq "") { + if ( $line =~ m/^Comment\s+(.*)$/ ) { + $group_desc = $1; + next; + } + } + next if ( $line =~ m/^-+.$/ ); + if (!$has_members) { + if ( $line =~ m/^Members/ ) { + $has_members = 1; + next; + } + } else { + if ( $line =~ m/^The command completed successfully/ ) { + last; + } else { + push(@members, split(/\s+/, $line)); + next; + } + } + + #print; +} + +if ( $#members > -1) { + process_group($group_name, @members, $Options{'C'}, $Options{'U'}, $Options{'r'}); +} + +#print "gn=$group_name\n"; +#print "gd=$group_desc\n"; +#my $m; +#foreach $m (@members) +#{ +# print "$m "; +#} +#print "\n"; diff --git a/examples/LDAP/smbldap-tools/smbldap-passwd.pl b/examples/LDAP/smbldap-tools/smbldap-passwd.pl new file mode 100755 index 00000000000..325c7718328 --- /dev/null +++ b/examples/LDAP/smbldap-tools/smbldap-passwd.pl @@ -0,0 +1,217 @@ +#!/usr/bin/perl + +# LDAP to unix password sync script for samba +# $Id: smbldap-passwd.pl,v 1.1.4.1 2002/06/17 18:35:08 jerry Exp $ + +# This code was developped by IDEALX (http://IDEALX.org/) and +# contributors (their names can be found in the CONTRIBUTORS file). +# +# Copyright (C) 2001-2002 IDEALX +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +# USA. + +# Purpose : +# . ldap-unix passwd sync for SAMBA-2.2.2 + LDAP +# . may also replace /bin/passwd + +use strict; +use smbldap_tools; +use smbldap_conf; + +my $user; +my $oldpass; +my $ret; + +my $arg; + +foreach $arg (@ARGV) { + if ($< != 0) { + die "Only root can specify parameters\n"; + } else { + if ( ($arg eq '-?') || ($arg eq '--help') ) { + print "Usage: $0 [username]\n"; + print " -?, --help show this help message\n"; + exit (6); + } elsif (substr($arg,0) ne '-') { + $user = $arg; + } + $oldpass = 1; + } +} + +if (!defined($user)) { + $user=$ENV{"USER"}; +} + +# test existence of user in LDAP +my $dn_line; +if (!defined($dn_line = get_user_dn($user))) { + print "$0: user $user doesn't exist\n"; + exit (10); +} + +my $dn = get_dn_from_line($dn_line); + +my $samba = is_samba_user($user); + +print "Changing password for $user\n"; + +# non-root user +if (!defined($oldpass)) { + # prompt for current password + system "stty -echo"; + print "(current) UNIX password: "; + chomp($oldpass=); + print "\n"; + system "stty echo"; + + if (!is_user_valid($user, $dn, $oldpass)) { + print "Authentication failure\n"; + exit (10); + } +} + +# prompt for new password + +my $pass; +my $pass2; + +system "stty -echo"; +print "New password : "; +chomp($pass=); +print "\n"; +system "stty echo"; + +system "stty -echo"; +print "Retype new password : "; +chomp($pass2=); +print "\n"; +system "stty echo"; + +if ($pass ne $pass2) { + print "New passwords don't match!\n"; + exit (10); +} + +# only modify smb passwords if smb user +if ($samba == 1) { + if (!$with_smbpasswd) { +# generate LanManager and NT clear text passwords + if ($mk_ntpasswd eq '') { + print "Either set \$with_smbpasswd = 1 or specify \$mk_ntpasswd\n"; + exit(1); + } + my $ntpwd = `$mk_ntpasswd '$pass'`; + chomp(my $lmpassword = substr($ntpwd, 0, index($ntpwd, ':'))); + chomp(my $ntpassword = substr($ntpwd, index($ntpwd, ':')+1)); + +# change nt/lm passwords + my $tmpldif = +"$dn_line +changetype: modify +replace: lmpassword +lmpassword: $lmpassword +- +changetype: modify +replace: ntpassword +ntpassword: $ntpassword +- + +"; + die "$0: error while modifying password for $user\n" + unless (do_ldapmodify($tmpldif) == 0); + undef $tmpldif; + } + else { + if ($< != 0) { + my $FILE="|$smbpasswd -s >/dev/null"; + open (FILE, $FILE) || die "$!\n"; + print FILE < /dev/null"; +if ($ret == 0) { + print "all authentication tokens updated successfully\n"; +} else { + return $ret; +} + +exit 0; + + +# - The End + +=head1 NAME + +smbldap-passwd.pl - change user password + +=head1 SYNOPSIS + + smbldap-passwd.pl [name] + +=head1 DESCRIPTION + + smbldap-passwd.pl changes passwords for user accounts. A normal user + may only change the password for their own account, the super user may + change the password for any account. + + Password Changes + The user is first prompted for their old password, if one is present. + This password is then tested against the stored password by binding + to the server. The user has only one chance to enter the correct pass- + word. The super user is permitted to bypass this step so that forgot- + ten passwords may be changed. + + The user is then prompted for a replacement password. As a general + guideline, passwords should consist of 6 to 8 characters including + one or more from each of following sets: + + Lower case alphabetics + + Upper case alphabetics + + Digits 0 thru 9 + + Punctuation marks + + passwd will prompt again and compare the second entry against the first. + Both entries are require to match in order for the password to be + changed. + +=head1 SEE ALSO + + passwd(1) + +=cut + +#' diff --git a/examples/LDAP/smbldap-tools/smbldap-populate.pl b/examples/LDAP/smbldap-tools/smbldap-populate.pl new file mode 100755 index 00000000000..11bc599d865 --- /dev/null +++ b/examples/LDAP/smbldap-tools/smbldap-populate.pl @@ -0,0 +1,296 @@ +#!/usr/bin/perl + +# Populate a LDAP base for Samba-LDAP usage +# +# $Id: smbldap-populate.pl,v 1.1.4.1 2002/06/17 18:35:08 jerry Exp $ + +# This code was developped by IDEALX (http://IDEALX.org/) and +# contributors (their names can be found in the CONTRIBUTORS file). +# +# Copyright (C) 2001-2002 IDEALX +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +# USA. + +# Purpose : +# . Create an initial LDAP database suitable for Samba 2.2 +# . For lazy people, replace ldapadd (with only an ldif parameter) + +use strict; +use smbldap_tools; +use smbldap_conf; + +use Getopt::Std; + +use vars qw(%oc); + +# objectclass of the suffix +%oc = ( + "ou" => "organizationalUnit", + "o" => "organization", + "dc" => "dcObject", +); + + +my %Options; + +my $ok = getopts('a:b:?', \%Options); +if ( (!$ok) || ($Options{'?'}) ) { + print "Usage: $0 [-ab?] [ldif]\n"; + print " -a administrator login name (default: Administrator)\n"; + print " -b guest login name (default: nobody)\n"; + print " -? show this help message\n"; + print " ldif file to add to ldap (default: suffix, Groups,"; + print " Users, Computers and builtin users )\n"; + exit (1); +} + +my $_ldifName; + +if (@ARGV >= 1) { + $_ldifName = $ARGV[0]; +} + +my $adminName = $Options{'a'}; +if (!defined($adminName)) { + $adminName = "Administrator"; +} + +my $guestName = $Options{'b'}; +if (!defined($guestName)) { + $guestName = "nobody"; +} + +if (!defined($_ldifName)) { + my $attr; + my $val; + my $objcl; + + if ($suffix =~ m/([^=]+)=([^,]+)/) { + $attr = $1; + $val = $2; + $objcl = $oc{$attr} if (exists $oc{$attr}); + if (!defined($objcl)) { + $objcl = "myhardcodedobjectclass"; + } + } else { + die "can't extract first attr and value from suffix $suffix"; + } + #print "$attr=$val\n"; + + #my $FILE="|cat"; + my $FILE="|$ldapadd -c"; + open (FILE, $FILE) || die "$!\n"; + + print FILE < +Source0: smbldap-groupadd.pl +Source1: smbldap-groupdel.pl +Source2: smbldap-groupmod.pl +Source3: smbldap-groupshow.pl +Source4: smbldap-passwd.pl +Source5: smbldap-useradd.pl +Source6: smbldap-userdel.pl +Source7: smbldap-usermod.pl +Source8: smbldap-usershow.pl +Source9: smbldap_conf.pm +Source10: smbldap_tools.pm +Source11: CONTRIBUTORS +Source12: COPYING +Source13: ChangeLog +Source14: FILES +Source15: README +Source16: TODO +Source17: mkntpwd.tar.gz +Source18: smbldap-populate.pl +Source19: smbldap-migrate-accounts.pl +Source20: smbldap-migrate-groups.pl +Source21: INFRA +BuildRoot: /%{_tmppath}/%{name} +Prefix: /usr/local +BuildRequires: perl >= 5.6 +Requires: perl >= 5.6, openldap, openldap-clients, samba + +%description +In settings with OpenLDAP and Samba-LDAP servers, this collection is +useful to add, modify and delete users and groups, and to change +Unix and Samba passwords. In those context they replace the system +tools to manage users, groups and passwords. + +%prep + +%setup -c -T + +%build +tar zxvf %{SOURCE17} +cd mkntpwd +make + +%install +rm -rf $RPM_BUILD_ROOT +mkdir -p $RPM_BUILD_ROOT/%{prefix}/sbin +mkdir -p $RPM_BUILD_ROOT/%{prefix}/share +mkdir -p $RPM_BUILD_ROOT/%{prefix}/share/doc +mkdir -p $RPM_BUILD_ROOT/%{prefix}/share/doc/smbldap-tools + +cd mkntpwd ; make PREFIX=$RPM_BUILD_ROOT/%{prefix} install + +install -m 550 %{SOURCE0} $RPM_BUILD_ROOT/%{prefix}/sbin/smbldap-groupadd.pl +install -m 550 %{SOURCE1} $RPM_BUILD_ROOT/%{prefix}/sbin/smbldap-groupdel.pl +install -m 550 %{SOURCE2} $RPM_BUILD_ROOT/%{prefix}/sbin/smbldap-groupmod.pl +install -m 555 %{SOURCE3} $RPM_BUILD_ROOT/%{prefix}/sbin/smbldap-groupshow.pl +install -m 555 %{SOURCE4} $RPM_BUILD_ROOT/%{prefix}/sbin/smbldap-passwd.pl +install -m 550 %{SOURCE5} $RPM_BUILD_ROOT/%{prefix}/sbin/smbldap-useradd.pl +install -m 550 %{SOURCE6} $RPM_BUILD_ROOT/%{prefix}/sbin/smbldap-userdel.pl +install -m 550 %{SOURCE7} $RPM_BUILD_ROOT/%{prefix}/sbin/smbldap-usermod.pl +install -m 555 %{SOURCE8} $RPM_BUILD_ROOT/%{prefix}/sbin/smbldap-usershow.pl +install -m 550 %{SOURCE18} $RPM_BUILD_ROOT/%{prefix}/sbin/smbldap-populate.pl +install -m 751 %{SOURCE9} $RPM_BUILD_ROOT/%{prefix}/sbin/smbldap_conf.pm +install -m 555 %{SOURCE10} $RPM_BUILD_ROOT/%{prefix}/sbin/smbldap_tools.pm +install -m 550 %{SOURCE19} $RPM_BUILD_ROOT/%{prefix}/sbin/smbldap-migrate-accounts.pl +install -m 550 %{SOURCE20} $RPM_BUILD_ROOT/%{prefix}/sbin/smbldap-migrate-groups.pl + +install -m 644 %{SOURCE11} $RPM_BUILD_ROOT/%{prefix}/share/doc/smbldap-tools/CONTRIBUTORS +install -m 644 %{SOURCE12} $RPM_BUILD_ROOT/%{prefix}/share/doc/smbldap-tools/COPYING +install -m 644 %{SOURCE13} $RPM_BUILD_ROOT/%{prefix}/share/doc/smbldap-tools/ChangeLog +install -m 644 %{SOURCE14} $RPM_BUILD_ROOT/%{prefix}/share/doc/smbldap-tools/FILES +install -m 644 %{SOURCE15} $RPM_BUILD_ROOT/%{prefix}/share/doc/smbldap-tools/README +install -m 644 %{SOURCE16} $RPM_BUILD_ROOT/%{prefix}/share/doc/smbldap-tools/TODO +install -m 644 %{SOURCE21} $RPM_BUILD_ROOT/%{prefix}/share/doc/smbldap-tools/INFRA + +%clean +rm -rf $RPM_BUILD_ROOT + +%post +ln -sf %{prefix}/sbin/smbldap_tools.pm /usr/lib/perl5/site_perl/smbldap_tools.pm +ln -sf %{prefix}/sbin/smbldap_conf.pm /usr/lib/perl5/site_perl/smbldap_conf.pm +chgrp 512 %{prefix}/sbin/smbldap-useradd.pl %{prefix}/sbin/smbldap_conf.pm || echo "An error occured while changing groups of smbldap-useradd.pl and smbldap_conf.pm in /usr/local/sbin. For proper operations, please ensure that they have the same posix group as the Samba domain administrator if there's a local Samba PDC." +perl -i -pe 's/_SLAVELDAP_/localhost/' %{prefix}/sbin/smbldap_conf.pm +perl -i -pe 's/_MASTERLDAP_/localhost/' %{prefix}/sbin/smbldap_conf.pm +perl -i -pe 's/_SUFFIX_/dc=IDEALX,dc=org/' %{prefix}/sbin/smbldap_conf.pm +perl -i -pe 's/_USERS_/Users/' %{prefix}/sbin/smbldap_conf.pm +perl -i -pe 's/_COMPUTERS_/Computers/' %{prefix}/sbin/smbldap_conf.pm +perl -i -pe 's/_GROUPS_/Groups/' %{prefix}/sbin/smbldap_conf.pm +perl -i -pe 's/_LOGINSHELL_/\/bin\/bash/' %{prefix}/sbin/smbldap_conf.pm +perl -i -pe 's/_USERHOMEPREFIX_/\/home\//' %{prefix}/sbin/smbldap_conf.pm +perl -i -pe 's/_BINDDN_/cn=Manager,\$suffix/' %{prefix}/sbin/smbldap_conf.pm +perl -i -pe 's/_BINDPW_/secret/' %{prefix}/sbin/smbldap_conf.pm +perl -i -pe 's/_PDCNAME_/PDC-SRV/' %{prefix}/sbin/smbldap_conf.pm +perl -i -pe 's/_HOMEDRIVE_/D/' %{prefix}/sbin/smbldap_conf.pm + +# FIXME: links should not be removed on upgrade +#%postun +#if [ $1 = 0 ] ; then +# rm -f /usr/lib/perl5/site_perl/smbldap_tools.pm +# rm -f /usr/lib/perl5/site_perl/smbldap_conf.pm +#fi + +%files +%defattr(-,root,root) +%{prefix}/sbin/*.pl +%{prefix}/sbin/smbldap_tools.pm +%config %{prefix}/sbin/smbldap_conf.pm +%{prefix}/sbin/mkntpwd +%doc %{prefix}/share/doc/%{name}/TODO +%doc %{prefix}/share/doc/%{name}/README +%doc %{prefix}/share/doc/%{name}/CONTRIBUTORS +%doc %{prefix}/share/doc/%{name}/FILES +%doc %{prefix}/share/doc/%{name}/COPYING + + +%changelog +* Sat Jun 1 2002 Olivier Lemaire 0.7-1 +- some bugfixes about smbldap-populate +- bugfixed the smbpasswd call in smbldap-useradd +- cleaned up the smbldap_conf +- more documentation + +* Tue Apr 30 2002 Brad Langhorst 0.6-2 +- changed requires samba-common to samba +- replaced /usr/local with %{prefix} to allow relocation + +* Tue Feb 5 2002 David Le Corfec 0.6-1 +- v0.6 + +* Mon Feb 4 2002 David Le Corfec 0.5-1 +- v0.5 + +* Mon Jan 14 2002 David Le Corfec 0.3-4 +- internal changes +- should upgrade smoothly from now on + +* Mon Jan 14 2002 David Le Corfec 0.2-1 +- added migration scripts + +* Fri Dec 28 2001 David Le Corfec 0.1-5 +- numeric group for chmod + +* Thu Dec 27 2001 David Le Corfec 0.1-4 +- misc bugfixes + +* Mon Dec 18 2001 David Le Corfec 0.1-3 +- changed files attrs for domain admins to add users +- added smbldap-populate.pl + +* Fri Dec 14 2001 David Le Corfec +- added mkntpwd + +* Wed Dec 12 2001 Olivier Lemaire +- Spec file was generated, and tested atomically. diff --git a/examples/LDAP/smbldap-tools/smbldap-useradd.pl b/examples/LDAP/smbldap-tools/smbldap-useradd.pl new file mode 100755 index 00000000000..9d2ca90bd29 --- /dev/null +++ b/examples/LDAP/smbldap-tools/smbldap-useradd.pl @@ -0,0 +1,462 @@ +#!/usr/bin/perl + +# $Id: smbldap-useradd.pl,v 1.1.4.1 2002/06/17 18:35:08 jerry Exp $ +# +# This code was developped by IDEALX (http://IDEALX.org/) and +# contributors (their names can be found in the CONTRIBUTORS file). +# +# Copyright (C) 2002 IDEALX +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +# USA. + +# Purpose of smbldap-useradd : user (posix,shadow,samba) add + +use strict; +use smbldap_tools; +use smbldap_conf; + + +##################### + +use Getopt::Std; +my %Options; + +my $ok = getopts('axnmwPG:u:g:d:s:c:k:A:B:C:D:E:F:H:?', \%Options); + +if ( (!$ok) || (@ARGV < 1) || ($Options{'?'}) ) { + print "Usage: $0 [-awmugdsckGPABCDEFH?] username\n"; + print " -a is a Windows User (otherwise, Posix stuff only)\n"; + print " -w is a Windows Workstation (otherwise, Posix stuff only)\n"; + print " -x creates rid and primaryGroupID in hex instead of decimal\n"; + print " -u uid\n"; + print " -g gid\n"; + print " -G supplementary comma-separated groups\n"; + print " -n do not create a group\n"; + print " -d home\n"; + print " -s shell\n"; + print " -c gecos\n"; + print " -m creates home directory and copies /etc/skel\n"; + print " -k skeleton dir (with -m)\n"; + print " -P ends by invoking smbldap-passwd.pl\n"; + print " -A can change password ? 0 if no, 1 if yes\n"; + print " -B must change password ? 0 if no, 1 if yes\n"; + print " -C smbHome (SMB home share, like '\\\\PDC-SRV\\homes')\n"; + print " -D homeDrive (letter associated with home share, like 'H:')\n"; + print " -E scriptPath (DOS script to execute on login)\n"; + print " -F profilePath (profile directory, like '\\\\PDC-SRV\\profiles\\foo')\n"; + print " -H acctFlags (samba account control bits like '[NDHTUMWSLKI]')\n"; + print " -? show this help message\n"; + exit (1); +} + +# cause problems when dealing with getpwuid because of the +# negative ttl and ldap modification +my $nscd_status = system "/etc/init.d/nscd status >/dev/null 2>&1"; + +if ($nscd_status == 0) { + system "/etc/init.d/nscd stop > /dev/null 2>&1"; +} + +# Read options +my $userUidNumber = $Options{'u'}; +if (!defined($userUidNumber)) { + # find first unused uid starting from $UID_START + while (defined(getpwuid($UID_START))) { + $UID_START++; + } + $userUidNumber = $UID_START; +} elsif (getpwuid($userUidNumber)) { die "Uid already exists.\n"; } + +if ($nscd_status == 0) { + system "/etc/init.d/nscd start > /dev/null 2>&1"; +} + + +# as rid we use 2 * uid + 1000 +my $userRid = 2 * $userUidNumber + 1000; +if (defined($Options{'x'})) { + $userRid= sprint("%x", $userRid); +} + +my $createGroup = 0; +my $userGidNumber = $Options{'g'}; +# gid not specified ? +if (!defined($userGidNumber)) { + # windows machine => $_defaultComputerGid + if (defined($Options{'w'})) { + $userGidNumber = $_defaultComputerGid; +# } elsif (!defined($Options{'n'})) { + # create new group (redhat style) + # find first unused gid starting from $GID_START +# while (defined(getgrgid($GID_START))) { +# $GID_START++; +# } +# $userGidNumber = $GID_START; + +# $createGroup = 1; + + } else { + # user will have gid = $_defaultUserGid + $userGidNumber = $_defaultUserGid; + } +} else { + my $gid; + if (($gid = parse_group($userGidNumber)) < 0) { + print "$0: unknown group $userGidNumber\n"; + exit (6); + } + $userGidNumber = $gid; +} + +# as grouprid we use 2 * gid + 1001 +my $userGroupRid = 2 * $userGidNumber + 1001; +if (defined($Options{'x'})) { + $userGroupRid = sprint("%x", $userGroupRid); +} +# Read only first @ARGV +my $userName = $ARGV[0]; + +# user must not exist in LDAP (should it be nss-wide ?) +my ($rc, $dn) = get_user_dn2($userName); +if ($rc and defined($dn)) { + print "$0: user $userName exists\n"; + exit (9); +} elsif (!$rc) { + print "$0: error in get_user_dn2\n"; + exit(10); +} + +my $userHomeDirectory; +my $tmp; +if (!defined($userHomeDirectory = $Options{'d'})) +{ + $userHomeDirectory = $_userHomePrefix.$userName; +} +$_userLoginShell = $tmp if (defined($tmp = $Options{'s'})); +$_userGecos = $tmp if (defined($tmp = $Options{'c'})); +$_skeletonDir = $tmp if (defined($tmp = $Options{'k'})); + +######################## + +# MACHINE ACCOUNT +if (defined($tmp = $Options{'w'})) { + + # add a trailing dollar if missing + if ($userName =~ /[^\$]$/s) { + $userName .= "\$"; + } + + #print "About to create machine $userName:\n"; + + if (!add_posix_machine ($userName, $userUidNumber, $userGidNumber)) { + die "$0: error while adding posix account\n"; + } + + if (!$with_smbpasswd) { + if (!add_samba_machine_mkntpwd($userName, $userUidNumber)) { + die "$0: error while adding samba account\n"; + } + } else { + if (!add_samba_machine($userName)) { + die "$0: error while adding samba account\n"; + } + + my $tmpldif = +"dn: uid=$userName,$computersdn +changetype: modify +acctFlags: [W ] + +"; + die "$0: error while modifying accountflags of $userName\n" + unless (do_ldapmodify($tmpldif) == 0); + undef $tmpldif; + } + + exit 0; +} + +####################### + +# USER ACCOUNT + +# add posix account first + +my $tmpldif = +"dn: uid=$userName,$usersdn +objectclass: top +objectclass: account +objectclass: posixAccount +cn: $userName +uid: $userName +uidNumber: $userUidNumber +gidNumber: $userGidNumber +homeDirectory: $userHomeDirectory +loginShell: $_userLoginShell +gecos: $_userGecos +description: $_userGecos +userPassword: {crypt}x + +"; + +die "$0: error while adding posix user $userName\n" + unless (do_ldapadd($tmpldif) == 0); + +undef $tmpldif; + +#if ($createGroup) { +# group_add($userName, $userGidNumber); +#} + +group_add_user($userGidNumber, $userName); + +my $grouplist; +# adds to supplementary groups +if (defined($grouplist = $Options{'G'})) { + add_grouplist_user($grouplist, $userName); +} + +# If user was created successfully then we should create his/her home dir +if (defined($tmp = $Options{'m'})) { + if ( !(-e $userHomeDirectory) ) { + system "mkdir $userHomeDirectory 2>/dev/null"; + system "cp -a $_skeletonDir/.[a-z,A-Z]* $_skeletonDir/* $userHomeDirectory 2>/dev/null"; + system "chown -R $userUidNumber:$userGidNumber $userHomeDirectory 2>/dev/null"; + system "chmod 700 $userHomeDirectory 2>/dev/null"; + } +} + + +# Add Samba user infos +if (defined($Options{'a'})) { + if (!$with_smbpasswd) { + + my $winmagic = 2147483647; + my $valpwdcanchange = 0; + my $valpwdmustchange = $winmagic; + my $valacctflags = "[UX]"; + + if (defined($tmp = $Options{'A'})) { + if ($tmp != 0) { + $valpwdcanchange = "0"; + } else { + $valpwdcanchange = "$winmagic"; + } + } + + if (defined($tmp = $Options{'B'})) { + if ($tmp != 0) { + $valpwdmustchange = "0"; + } else { + $valpwdmustchange = "$winmagic"; + } + } + + if (defined($tmp = $Options{'H'})) { + $valacctflags = "$tmp"; + } + + my $tmpldif = +"dn: uid=$userName,$usersdn +changetype: modify +objectclass: top +objectclass: account +objectclass: posixAccount +objectClass: sambaAccount +pwdLastSet: 0 +logonTime: 0 +logoffTime: 2147483647 +kickoffTime: 2147483647 +pwdCanChange: $valpwdcanchange +pwdMustChange: $valpwdmustchange +displayName: $_userGecos +acctFlags: $valacctflags +rid: $userRid + +"; + + die "$0: error while adding samba account to posix user $userName\n" + unless (do_ldapmodify($tmpldif) == 0); + + undef $tmpldif; + } else { + my $FILE="|smbpasswd -s -a $userName >/dev/null" ; + open (FILE, $FILE) || die "$!\n"; + print FILE < 2) + + -c comment + The new user's comment field (gecos). + + -d home_dir + The new user will be created using home_dir as the value for the + user's login directory. The default is to append the login name + to default_home and use that as the login directory name. + + -g initial_group + The group name or number of the user's initial login group. The + group name must exist. A group number must refer to an already + existing group. The default group number is 1. + + -G group,[...] + A list of supplementary groups which the user is also a member + of. Each group is separated from the next by a comma, with no + intervening whitespace. The groups are subject to the same + restrictions as the group given with the -g option. The default + is for the user to belong only to the initial group. + + -m The user's home directory will be created if it does not exist. + The files contained in skeleton_dir will be copied to the home + directory if the -k option is used, otherwise the files con­ + tained in /etc/skel will be used instead. Any directories con­ + tained in skeleton_dir or /etc/skel will be created in the + user's home directory as well. The -k option is only valid in + conjunction with the -m option. The default is to not create + the directory and to not copy any files. + + -s shell + The name of the user's login shell. The default is to leave + this field blank, which causes the system to select the default + login shell. + + -u uid The numerical value of the user's ID. This value must be + unique, unless the -o option is used. The value must be non- + negative. The default is to use the smallest ID value greater + than 1000 and greater than every other user. + + -P ends by invoking smbldap-passwd.pl + + -A can change password ? 0 if no, 1 if yes + + -B must change password ? 0 if no, 1 if yes + + -C smbHome (SMB home share, like '\\\\PDC-SRV\\homes') + + -D homeDrive (letter associated with home share, like 'H:') + + -E scriptPath, relative to the [netlogon] share (DOS script to execute on login, like 'foo.bat') + + -F profilePath (profile directory, like '\\\\PDC-SRV\\profiles\\foo') + + -H acctFlags, spaces and trailing bracket are ignored (samba account control bits like '[NDHTUMWSLKI]') + +=head1 SEE ALSO + + useradd(1) + +=cut + +#' diff --git a/examples/LDAP/smbldap-tools/smbldap-userdel.pl b/examples/LDAP/smbldap-tools/smbldap-userdel.pl new file mode 100755 index 00000000000..e2ad403b6d5 --- /dev/null +++ b/examples/LDAP/smbldap-tools/smbldap-userdel.pl @@ -0,0 +1,124 @@ +#!/usr/bin/perl + +# $Id: smbldap-userdel.pl,v 1.1.4.1 2002/06/17 18:35:08 jerry Exp $ +# +# This code was developped by IDEALX (http://IDEALX.org/) and +# contributors (their names can be found in the CONTRIBUTORS file). +# +# Copyright (C) 2001-2002 IDEALX +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +# USA. + +# Purpose of smbldap-userdel : user (posix,shadow,samba) deletion + +use strict; +use smbldap_tools; + + +##################### + +use Getopt::Std; +my %Options; + +my $ok = getopts('r?', \%Options); + +if ( (!$ok) || (@ARGV < 1) || ($Options{'?'}) ) { + print "Usage: $0 [-r?] username\n"; + print " -r remove home directory\n"; + exit (1); +} + +# Read only first @ARGV +my $user = $ARGV[0]; + +my $dn; +# user must not exist in LDAP +if (!defined($dn=get_user_dn($user))) { + print "$0: user $user does not exist\n"; + exit (6); +} + +if ($< != 0) { + print "You must be root to delete an user\n"; + exit (1); +} + +my $homedir; +if (defined($Options{'r'})) { + $homedir=get_homedir($user); +} + +# remove user from groups +my $groups = find_groups_of $user; +my @grplines = split(/\n/, $groups); + +my $grp; +foreach $grp (@grplines) { + my $gname = ""; + if ( $grp =~ /dn: cn=([^,]+),/) { + $gname = $1; + #print "xx $gname\n"; + } + if ($gname ne "") { + group_remove_member($gname, $user); + } +} + +# XXX +delete_user($user); + +# delete dir -- be sure that homeDir is not a strange value +if (defined($Options{'r'})) { + if ($homedir !~ /^\/dev/ and $homedir !~ /^\/$/) { + system "rm -rf $homedir"; + } +} + +my $nscd_status = system "/etc/init.d/nscd status >/dev/null 2>&1"; + +if ($nscd_status == 0) { + system "/etc/init.d/nscd restart > /dev/null 2>&1"; +} + +exit (0); + +############################################################ + +=head1 NAME + + smbldap-userdel.pl - Delete a user account and related files + +=head1 SYNOPSIS + + smbldap-userdel.pl [-r] login + +=head1 DESCRIPTION + + The smbldap-userdel.pl command modifies the system + account files, deleting all entries that refer to login. + The named user must exist. + + -r Files in the user's home directory will be removed along with + the home directory itself. Files located in other file + systems will have to be searched for and deleted manually. + +=head1 SEE ALSO + + userdel(1) + +=cut + +#' diff --git a/examples/LDAP/smbldap-tools/smbldap-usermod.pl b/examples/LDAP/smbldap-tools/smbldap-usermod.pl new file mode 100755 index 00000000000..dd5fcab74fd --- /dev/null +++ b/examples/LDAP/smbldap-tools/smbldap-usermod.pl @@ -0,0 +1,405 @@ +#!/usr/bin/perl + +# $Id: smbldap-usermod.pl,v 1.1.4.1 2002/06/17 18:35:08 jerry Exp $ +# +# This code was developped by IDEALX (http://IDEALX.org/) and +# contributors (their names can be found in the CONTRIBUTORS file). +# +# Copyright (C) 2001-2002 IDEALX +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +# USA. + +# Purpose of smbldap-usermod : user (posix,shadow,samba) modification + +use strict; +use smbldap_tools; +use smbldap_conf; + + +##################### + +use Getopt::Std; +my %Options; +my $nscd_status; + +my $ok = getopts('A:B:C:D:E:F:H:IJxme:f:u:g:G:d:l:s:c:ok:?', \%Options); +if ( (!$ok) || (@ARGV < 1) || ($Options{'?'}) ) { + print "Usage: $0 [-awmugdsckxABCDEFGHI?] username\n"; + print " -c gecos\n"; + print " -d home directory\n"; + #print " -m move home directory\n"; + #print " -e expire date (YYYY-MM-DD)\n"; + #print " -f inactive days\n"; + print " -u uid\n"; + print " -o uid can be non unique\n"; + print " -g gid\n"; + print " -G supplementary groups (comma separated)\n"; + print " -l login name\n"; + print " -s shell\n"; + print " -x creates rid and primaryGroupID in hex instead of decimal (for Samba 2.2.2 unpatched only)\n"; + print " -A can change password ? 0 if no, 1 if yes\n"; + print " -B must change password ? 0 if no, 1 if yes\n"; + print " -C smbHome (SMB home share, like '\\\\PDC-SRV\\homes')\n"; + print " -D homeDrive (letter associated with home share, like 'H:')\n"; + print " -E scriptPath (DOS script to execute on login)\n"; + print " -F profilePath (profile directory, like '\\\\PDC-SRV\\profiles\\foo')\n"; + print " -H acctFlags (samba account control bits like '[NDHTUMWSLKI]')\n"; + print " -I disable an user. Can't be used with -H or -J\n"; + print " -J enable an user. Can't be used with -H or -I\n"; + print " -? show this help message\n"; + exit (1); +} + +if ($< != 0) { + print "You must be root to modify an user\n"; + exit (1); +} + +# Read only first @ARGV +my $user = $ARGV[0]; + +# Read user datas +my $lines = read_user($user); +if (!defined($lines)) { + print "$0: user $user doesn't exist\n"; + exit (1); +} + +#print "$lines\n"; +my $dn_line; +if ( $lines =~ /(^dn: .*)/ ) { + $dn_line = $1; +} + +chomp($dn_line); + +my $samba = 0; +if ($lines =~ m/objectClass: sambaAccount/) { + $samba = 1; +} + +############ + +my $tmp; +my $mods; + +# Process options +my $changed_uid; +my $_userUidNumber; +my $_userRid; +if (defined($tmp = $Options{'u'})) { + if (defined($Options{'o'})) { + $nscd_status = system "/etc/init.d/nscd status >/dev/null 2>&1"; + + if ($nscd_status == 0) { + system "/etc/init.d/nscd stop > /dev/null 2>&1"; + } + + if (getpwuid($tmp)) { + if ($nscd_status == 0) { + system "/etc/init.d/nscd start > /dev/null 2>&1"; + } + + print "$0: uid number $tmp exists\n"; + exit (6); + } + if ($nscd_status == 0) { + system "/etc/init.d/nscd start > /dev/null 2>&1"; + } + + } + $_userUidNumber = $tmp; + # as rid we use 2 * uid + 1000 + my $_userRid = 2 * $_userUidNumber + 1000; + if (defined($Options{'x'})) { + $_userRid= sprint("%x", $_userRid); + } + $mods .= "uidNumber: $_userUidNumber\n"; + if ($samba) { + $mods .= "rid: $_userRid\n"; + } + $changed_uid = 1; +} + +my $changed_gid; +my $_userGidNumber; +my $_userGroupRid; +if (defined($tmp = $Options{'g'})) { + $_userGidNumber = parse_group($tmp); + if ($_userGidNumber < 0) { + print "$0: group $tmp doesn't exist\n"; + exit (6); + } +# as grouprid we use 2 * gid + 1001 + my $_userGroupRid = 2 * $_userGidNumber + 1001; + if (defined($Options{'x'})) { + $_userGroupRid = sprint("%x", $_userGroupRid); + } + $mods .= "gidNumber: $_userGidNumber\n"; + if ($samba) { + $mods .= "primaryGroupID: $_userGroupRid\n"; + } + $changed_gid = 1; +} + +my $changed_shell; +my $_userLoginShell; +if (defined($tmp = $Options{'s'})) { + $_userLoginShell = $tmp; + $mods .= "loginShell: $_userLoginShell\n"; + $changed_shell = 1; +} + +my $changed_gecos; +my $_userGecos; +if (defined($tmp = $Options{'c'})) { + $_userGecos = $tmp; + $mods .= "gecos: $_userGecos\n"; + $changed_gecos = 1; +} + +my $changed_homedir; +my $newhomedir; +if (defined($tmp = $Options{'d'})) { + $newhomedir = $tmp; + $mods .= "homeDirectory: $newhomedir\n"; + $changed_homedir = 1; +} + + +if (defined($tmp = $Options{'G'})) { + + # remove user from old groups + my $groups = find_groups_of $user; + my @grplines = split(/\n/, $groups); + + my $grp; + foreach $grp (@grplines) { + my $gname = ""; + if ( $grp =~ /dn: cn=([^,]+),/) { + $gname = $1; + #print "xx $gname\n"; + } + if ($gname ne "") { + group_remove_member($gname, $user); + } + } + + # add user to new groups + add_grouplist_user($tmp, $user); +} + +# +# A : pwdCanChange +# B : pwdMustChange +# C : smbHome +# D : homeDrive +# E : scriptPath +# F : profilePath +# H : acctFlags + +my $attr; +my $winmagic = 2147483647; + +if (defined($tmp = $Options{'A'})) { + $attr = "pwdCanChange"; + if ($tmp != 0) { + $mods .= "$attr: 0\n"; + } else { + $mods .= "$attr: $winmagic\n"; + } +} + +if (defined($tmp = $Options{'B'})) { + $attr = "pwdMustChange"; + if ($tmp != 0) { + $mods .= "$attr: 0\n"; + } else { + $mods .= "$attr: $winmagic\n"; + } +} + +if (defined($tmp = $Options{'C'})) { + $attr = "smbHome"; + #$tmp =~ s/\\/\\\\/g; + $mods .= "$attr: $tmp\n"; +} + +if (defined($tmp = $Options{'D'})) { + $attr = "homeDrive"; + $tmp = $tmp.":" unless ($tmp =~ /:/); + $mods .= "$attr: $tmp\n"; +} + +if (defined($tmp = $Options{'E'})) { + $attr = "scriptPath"; + #$tmp =~ s/\\/\\\\/g; + $mods .= "$attr: $tmp\n"; +} + +if (defined($tmp = $Options{'F'})) { + $attr = "profilePath"; + #$tmp =~ s/\\/\\\\/g; + $mods .= "$attr: $tmp\n"; +} + +if (defined($tmp = $Options{'H'})) { + $attr = "acctFlags"; + #$tmp =~ s/\\/\\\\/g; + $mods .= "$attr: $tmp\n"; +} elsif (defined($tmp = $Options{'I'})) { + my $flags; + + if ( $lines =~ /^acctFlags: (.*)/m ) { + $flags = $1; + } + + chomp($flags); + + if ( !($flags =~ /D/) ) { + my $letters; + if ($flags =~ /(\w+)/) { + $letters = $1; + } + $mods .= "acctFlags: \[D$letters\]\n"; + } +} elsif (defined($tmp = $Options{'J'})) { + my $flags; + + if ( $lines =~ /^acctFlags: (.*)/m ) { + $flags = $1; + } + + chomp($flags); + + if ( $flags =~ /D/ ) { + my $letters; + if ($flags =~ /(\w+)/) { + $letters = $1; + } + $letters =~ s/D//; + $mods .= "acctFlags: \[$letters\]\n"; + } +} + +if ($mods ne '') { + #print "----\n$dn_line\n$mods\n----\n"; + + my $tmpldif = +"$dn_line +changetype: modify +$mods +"; + + die "$0: error while modifying user $user\n" + unless (do_ldapmodify($tmpldif) == 0); + + undef $tmpldif; +} + +$nscd_status = system "/etc/init.d/nscd status >/dev/null 2>&1"; + +if ($nscd_status == 0) { + system "/etc/init.d/nscd restart > /dev/null 2>&1"; +} + + +############################################################ + +=head1 NAME + + smbldap-usermod.pl - Modify a user account + +=head1 SYNOPSIS + + smbldap-usermod.pl [-c comment] [-d home_dir] + [-g initial_group] [-G group[,...]] + [-l login_name] [-p passwd] + [-s shell] [-u uid [ -o]] [-x] + [-A canchange] [-B mustchange] [-C smbhome] + [-D homedrive] [-E scriptpath] [-F profilepath] + [-H acctflags] login + +=head1 DESCRIPTION + + The smbldap-usermod.pl command modifies the system account files + to reflect the changes that are specified on the command line. + The options which apply to the usermod command are + + -c comment + The new value of the user's comment field (gecos). + + -d home_dir + The user's new login directory. + + -g initial_group + The group name or number of the user's new initial login group. + The group name must exist. A group number must refer to an + already existing group. The default group number is 1. + + -G group,[...] + A list of supplementary groups which the user is also a member + of. Each group is separated from the next by a comma, with no + intervening whitespace. The groups are subject to the same + restrictions as the group given with the -g option. If the user + is currently a member of a group which is not listed, the user + will be removed from the group + + -l login_name + The name of the user will be changed from login to login_name. + Nothing else is changed. In particular, the user's home direc­ + tory name should probably be changed to reflect the new login + name. + + -s shell + The name of the user's new login shell. Setting this field to + blank causes the system to select the default login shell. + + -u uid The numerical value of the user's ID. This value must be + unique, unless the -o option is used. The value must be non- + negative. Any files which the user owns and which are + located in the directory tree rooted at the user's home direc­ + tory will have the file user ID changed automatically. Files + outside of the user's home directory must be altered manually. + + -x Creates rid and primaryGroupID in hex instead of decimal (for + Samba 2.2.2 unpatched only - higher versions always use decimal) + + -A can change password ? 0 if no, 1 if yes + + -B must change password ? 0 if no, 1 if yes + + -C smbHome (SMB home share, like '\\\\PDC-SRV\\homes') + + -D homeDrive (letter associated with home share, like 'H:') + + -E scriptPath, relative to the [netlogon] share (DOS script to execute on login, like 'foo.bat') + + -F profilePath (profile directory, like '\\\\PDC-SRV\\profiles\\foo') + + -H acctFlags, spaces and trailing bracket are ignored (samba account control bits like '[NDHTUMWSLKI]') + + -I disable user. Can't be used with -H or -J + + -J enable user. Can't be used with -H or -I + +=head1 SEE ALSO + + usermod(1) + +=cut + +#' diff --git a/examples/LDAP/smbldap-tools/smbldap-usershow.pl b/examples/LDAP/smbldap-tools/smbldap-usershow.pl new file mode 100755 index 00000000000..41391a91969 --- /dev/null +++ b/examples/LDAP/smbldap-tools/smbldap-usershow.pl @@ -0,0 +1,71 @@ +#!/usr/bin/perl + +# $Id: smbldap-usershow.pl,v 1.1.4.1 2002/06/17 18:35:08 jerry Exp $ +# +# This code was developped by IDEALX (http://IDEALX.org/) and +# contributors (their names can be found in the CONTRIBUTORS file). +# +# Copyright (C) 2001-2002 IDEALX +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +# USA. + +# Purpose of smbldap-userdisplay : user (posix,shadow,samba) display + +use strict; +use smbldap_tools; + +use Getopt::Std; +my %Options; + +my $ok = getopts('?', \%Options); + +if ( (!$ok) || (@ARGV < 1) || ($Options{'?'}) ) { + print "Usage: $0 [-?] username\n"; + print " -? show this help message\n"; + exit (1); +} + +# Read only first @ARGV +my $user = $ARGV[0]; + +my $lines = read_user($user); +if (!defined($lines)) { + print "$0: user $user doesn't exist\n"; + exit (1); +} + +print "$lines\n"; + +exit(0); + +############################################################ + +=head1 NAME + + smbldap-usershow.pl - Show a user account informations + +=head1 SYNOPSIS + + smbldap-usershow.pl login + +=head1 DESCRIPTION + + The smbldap-usershow.pl command displays the informations + associated with the login. The named user must exist. + +=cut + +#' diff --git a/examples/LDAP/smbldap-tools/smbldap_conf.pm b/examples/LDAP/smbldap-tools/smbldap_conf.pm new file mode 100644 index 00000000000..158f2c1460e --- /dev/null +++ b/examples/LDAP/smbldap-tools/smbldap_conf.pm @@ -0,0 +1,251 @@ +#!/usr/bin/perl +use strict; +package smbldap_conf; + +# $Id: smbldap_conf.pm,v 1.1.4.1 2002/06/17 18:35:08 jerry Exp $ +# +# smbldap-tools.conf : Q & D configuration file for smbldap-tools + +# This code was developped by IDEALX (http://IDEALX.org/) and +# contributors (their names can be found in the CONTRIBUTORS file). +# +# Copyright (C) 2001-2002 IDEALX +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +# USA. + +# Purpose : +# . be the configuration file for all smbldap-tools scripts + +use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS +$UID_START $GID_START $smbpasswd $slaveLDAP $masterLDAP +$with_smbpasswd $mk_ntpasswd +$ldap_path $ldap_opts $ldapsearch $ldapsearchnobind +$ldapmodify $ldappasswd $ldapadd $ldapdelete $ldapmodrdn +$suffix $usersdn $computersdn +$groupsdn $scope $binddn $bindpasswd +$slaveDN $slavePw $masterDN $masterPw +$_userLoginShell $_userHomePrefix $_userGecos +$_defaultUserGid $_defaultComputerGid +$_skeletonDir $_userSmbHome +$_userProfile $_userHomeDrive +$_userScript $usersou $computersou $groupsou +); + +use Exporter; +$VERSION = 1.00; +@ISA = qw(Exporter); + +@EXPORT = qw( +$UID_START $GID_START $smbpasswd $slaveLDAP $masterLDAP +$with_smbpasswd $mk_ntpasswd +$ldap_path $ldap_opts $ldapsearch $ldapsearchnobind $ldapmodify $ldappasswd +$ldapadd $ldapdelete $ldapmodrdn $suffix $usersdn +$computersdn $groupsdn $scope $binddn $bindpasswd +$slaveDN $slavePw $masterDN $masterPw +$_userLoginShell $_userHomePrefix $_userGecos +$_defaultUserGid $_defaultComputerGid $_skeletonDir +$_userSmbHome $_userProfile $_userHomeDrive $_userScript +$usersou $computersou $groupsou +); + + +############################################################################## +# +# General Configuration +# +############################################################################## + +# +# UID and GID starting at... +# + +$UID_START = 1000; +$GID_START = 1000; + +############################################################################## +# +# LDAP Configuration +# +############################################################################## + +# Notes: to use to dual ldap servers backend for Samba, you must patch +# Samba with the dual-head patch from IDEALX. If not using this patch +# just use the same server for slaveLDAP and masterLDAP. +# +# Slave LDAP : needed for read operations +# +# Ex: $slaveLDAP = "127.0.0.1"; +$slaveLDAP = "_SLAVELDAP_"; + +# +# Master LDAP : needed for write operations +# +# Ex: $masterLDAP = "127.0.0.1"; +$masterLDAP = "_MASTERLDAP_"; + +# +# LDAP Suffix +# +# Ex: $suffix = "dc=IDEALX,dc=ORG"; +$suffix = "_SUFFIX_"; + +# +# Where are stored Users +# +# Ex: $usersdn = "ou=Users,$suffix"; for ou=Users,dc=IDEALX,dc=ORG +$usersou = q(_USERS_); + +$usersdn = "ou=$usersou,$suffix"; + +# +# Where are stored Computers +# +# Ex: $computersdn = "ou=Computers,$suffix"; for ou=Computers,dc=IDEALX,dc=ORG +$computersou = q(_COMPUTERS_); + +$computersdn = "ou=$computersou,$suffix"; + +# +# Where are stored Groups +# +# Ex $groupsdn = "ou=Groups,$suffix"; for ou=Groups,dc=IDEALX,dc=ORG +$groupsou = q(_GROUPS_); + +$groupsdn = "ou=$groupsou,$suffix"; + +# +# Default scope Used +# +$scope = "sub"; + +# +# Credential Configuration +# +# Bind DN used +# Ex: $binddn = "cn=Manager,$suffix"; for cn=Manager,dc=IDEALX,dc=org +$binddn = "_BINDDN_"; +# +# Bind DN passwd used +# Ex: $bindpasswd = 'secret'; for 'secret' +$bindpasswd = "_BINDPW_"; + +# +# Notes: if using dual ldap patch, you can specify to different configuration +# By default, we will use the same DN (so it will work for standard Samba +# release) +# +$slaveDN = $binddn; +$slavePw = $bindpasswd; +$masterDN = $binddn; +$masterPw = $bindpasswd; + +############################################################################## +# +# Unix Accounts Configuration +# +############################################################################## + +# Login defs +# +# Default Login Shell +# +# Ex: $_userLoginShell = q(/bin/bash); +$_userLoginShell = q(_LOGINSHELL_); + +# +# Home directory prefix (without username) +# +#Ex: $_userHomePrefix = q(/home/); +$_userHomePrefix = q(_USERHOMEPREFIX_); + +# +# Gecos +# +$_userGecos = q(System User); + +# +# Default User (POSIX and Samba) GID +# +$_defaultUserGid = 100; + +# +# Default Computer (Samba) GID +# +$_defaultComputerGid = 553; + +# +# Skel dir +# +$_skeletonDir = q(/etc/skel); + +############################################################################## +# +# SAMBA Configuration +# +############################################################################## + +# +# The UNC path to home drives location without the username last extension +# (will be dynamically prepended) +# Ex: q(\\\\My-PDC-netbios-name\\homes) for \\My-PDC-netbios-name\homes +$_userSmbHome = q(\\\\_PDCNAME_\\homes); + +# +# The UNC path to profiles locations without the username last extension +# (will be dynamically prepended) +# Ex: q(\\\\My-PDC-netbios-name\\profiles) for \\My-PDC-netbios-name\profiles +$_userProfile = q(\\\\_PDCNAME_\\profiles\\); + +# +# The default Home Drive Letter mapping +# (will be automatically mapped at logon time if home directory exist) +# Ex: q(U:) for U: +$_userHomeDrive = q(_HOMEDRIVE_:); + +# +# The default user netlogon script name +# if not used, will be automatically username.cmd +# +#$_userScript = q(startup.cmd); # make sure script file is edited under dos + + +############################################################################## +# +# SMBLDAP-TOOLS Configuration (default are ok for a RedHat) +# +############################################################################## + +# Allows not to use smbpasswd (if $with_smbpasswd == 0 in smbldap_conf.pm) but +# prefer mkntpwd... most of the time, it's a wise choice :-) +$with_smbpasswd = 0; +$smbpasswd = "/usr/bin/smbpasswd"; +$mk_ntpasswd = "/usr/local/sbin/mkntpwd"; + +$ldap_path = "/usr/bin"; +$ldap_opts = "-x"; +$ldapsearch = "$ldap_path/ldapsearch $ldap_opts -h $slaveLDAP -D '$slaveDN' -w '$slavePw'"; +$ldapsearchnobind = "$ldap_path/ldapsearch $ldap_opts -h $slaveLDAP"; +$ldapmodify = "$ldap_path/ldapmodify $ldap_opts -h $masterLDAP -D '$masterDN' -w '$masterPw'"; +$ldappasswd = "$ldap_path/ldappasswd $ldap_opts -h $masterLDAP -D '$masterDN' -w '$masterPw'"; +$ldapadd = "$ldap_path/ldapadd $ldap_opts -h $masterLDAP -D '$masterDN' -w '$masterPw'"; +$ldapdelete = "$ldap_path/ldapdelete $ldap_opts -h $masterLDAP -D '$masterDN' -w '$masterPw'"; +$ldapmodrdn = "$ldap_path/ldapmodrdn $ldap_opts -h $masterLDAP -D '$masterDN' -w '$masterPw'"; + + + +1; + +# - The End diff --git a/examples/LDAP/smbldap-tools/smbldap_tools.pm b/examples/LDAP/smbldap-tools/smbldap_tools.pm new file mode 100755 index 00000000000..1f0d4d1c43b --- /dev/null +++ b/examples/LDAP/smbldap-tools/smbldap_tools.pm @@ -0,0 +1,585 @@ +#! /usr/bin/perl +use strict; +package smbldap_tools; +use smbldap_conf; + +# $Id: smbldap_tools.pm,v 1.1.4.1 2002/06/17 18:35:08 jerry Exp $ +# +# This code was developped by IDEALX (http://IDEALX.org/) and +# contributors (their names can be found in the CONTRIBUTORS file). +# +# Copyright (C) 2001-2002 IDEALX +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +# USA. + + +# ugly funcs using global variables and spawning openldap clients + +use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS); +use Exporter; +$VERSION = 1.00; +@ISA = qw(Exporter); + +@EXPORT = qw( +get_user_dn +get_group_dn +is_samba_user +is_user_valid +get_dn_from_line +add_posix_machine +add_samba_machine +add_samba_machine_mkntpwd +group_add_user +add_grouplist_user +disable_user +delete_user +group_add +get_homedir +read_user +read_group +find_groups_of +parse_group +group_remove_member +group_get_members +do_ldapadd +do_ldapmodify +get_user_dn2 +); + +# dn_line = get_user_dn($username) +# where dn_line is like "dn: a=b,c=d" +sub get_user_dn +{ + my $user = shift; + my $dn=`$ldapsearch -b '$suffix' -s '$scope' '(&(objectclass=posixAccount)(uid=$user))' | grep "^dn:"`; + chomp $dn; + if ($dn eq '') { + return undef; + } + + return $dn; +} + +# return (success, dn) +sub get_user_dn2 +{ + my $user = shift; + + my $sr = `$ldapsearch -b '$suffix' -s '$scope' '(&(objectclass=posixAccount)(uid=$user))'`; + if ($sr eq "") { + print "get_user_dn2: error in ldapsearch : +$ldapsearch -b '$suffix' -s '$scope' '(&(objectclass=posixAccount)(uid=$user))'\n"; + return (0, undef); + } + + my @lines = split(/\n/, $sr); + + my @matches = grep(/^dn:/, @lines); + + my $dn = $matches[0]; + chomp $dn; + if ($dn eq '') { + return (1, undef); + } + + return (1, $dn); +} + +# dn_line = get_group_dn($groupname) +# where dn_line is like "dn: a=b,c=d" +sub get_group_dn +{ + my $group = shift; + my $dn=`$ldapsearch -b '$groupsdn' -s '$scope' '(&(objectclass=posixGroup)(|(cn=$group)(gidNumber=$group)))' | grep "^dn:"`; + chomp $dn; + if ($dn eq '') { + return undef; + } + + return $dn; +} + +# bool = is_samba_user($username) +sub is_samba_user +{ + my $user = shift; + my $cmd = "$ldapsearch -b '$suffix' -s '$scope' '(&(objectClass=sambaAccount)(uid=$user))' | grep '^dn:\'"; + my $res=`$cmd`; + chomp $res; + if ($res ne '') { + return 1; + } + return 0; +} + +# bool = is_user_valid($username) +# try to bind with user dn and password to validate current password +sub is_user_valid +{ + my ($user, $dn, $pass) = @_; + my $res=`$ldapsearchnobind -b '$usersdn' -s '$scope' -D '$dn' -w '$pass' '(&(objectclass=posixAccount)(uid=$user))' 2>/dev/null | grep "^dn:"`; + chomp $res; + if ($res eq '') { + return 0; + } + return 1; +} + +# dn = get_dn_from_line ($dn_line) +# helper to get "a=b,c=d" from "dn: a=b,c=d" +sub get_dn_from_line +{ + my $dn = shift; + $dn =~ s/^dn: //; + return $dn; +} + +# success = add_posix_machine($user, $uid, $gid) +sub add_posix_machine +{ + my ($user, $uid, $gid) = @_; + +my $tmpldif = +"dn: uid=$user,$computersdn +objectclass: top +objectclass: posixAccount +cn: $user +uid: $user +uidNumber: $uid +gidNumber: $gid +homeDirectory: /dev/null +loginShell: /bin/false +description: Computer + +"; + + die "$0: error while adding posix account to machine $user\n" + unless (do_ldapadd($tmpldif) == 0); + + undef $tmpldif; + + return 1; +} + +# success = add_samba_machine($computername) +sub add_samba_machine +{ + my $user = shift; + system "smbpasswd -a -m $user"; + + return 1; +} + +sub add_samba_machine_mkntpwd +{ + my ($user, $uid) = @_; + my $rid = 2 * $uid + 1000; # Samba 2.2.2 stuff + + my $name = $user; + $name =~ s/.$//s; + + if ($mk_ntpasswd eq '') { + print "Either set \$with_smbpasswd = 1 or specify \$mk_ntpasswd\n"; + return 0; + } + + my $ntpwd = `$mk_ntpasswd '$name'`; + chomp(my $lmpassword = substr($ntpwd, 0, index($ntpwd, ':'))); + chomp(my $ntpassword = substr($ntpwd, index($ntpwd, ':')+1)); + + my $tmpldif = +"dn: uid=$user,$computersdn +changetype: modify +objectclass: top +objectclass: posixAccount +objectClass: sambaAccount +pwdLastSet: 0 +logonTime: 0 +logoffTime: 2147483647 +kickoffTime: 2147483647 +pwdCanChange: 0 +pwdMustChange: 2147483647 +acctFlags: [W ] +lmpassword: $lmpassword +ntpassword: $ntpassword +rid: $rid +primaryGroupID: 0 + +"; + + die "$0: error while adding samba account to $user\n" + unless (do_ldapmodify($tmpldif) == 0); + undef $tmpldif; + + return 1; +} + + + +sub group_add_user +{ + my ($group, $userid) = @_; + my $dn_line; + + if (!defined($dn_line = get_group_dn($group))) { + return 1; + } + my $dn = get_dn_from_line($dn_line); + my $members = `$ldapsearch -b '$dn' -s base | grep -i "^memberUid:"`; + chomp($members); + # user already member ? + if ($members =~ m/^memberUid: $userid/) { + return 2; + } + my $mods = ""; + if ($members ne '') { + $mods="$dn_line +changetype: modify +replace: memberUid +$members +memberUid: $userid +"; + } else { + $mods="$dn_line +changetype: modify +add: memberUid +memberUid: $userid +"; + } + + #print "$mods\n"; + + my $tmpldif = +"$mods +"; + + die "$0: error while modifying group $group\n" + unless (do_ldapmodify($tmpldif) == 0); + undef $tmpldif; + return 0; +} + +sub add_grouplist_user +{ + my ($grouplist, $user) = @_; + my @array = split(/,/, $grouplist); + foreach my $group (@array) { + group_add_user($group, $user); + } +} + +# XXX FIXME : acctFlags |= D, and not acctFlags = D +sub disable_user +{ + my $user = shift; + my $dn_line; + + if (!defined($dn_line = get_user_dn($user))) { + print "$0: user $user doesn't exist\n"; + exit (10); + } + + my $tmpldif = +"dn: $dn_line +changetype: modify +replace: userPassword +userPassword: {crypt}!x + +"; + + die "$0: error while modifying user $user\n" + unless (do_ldapmodify($tmpldif) == 0); + undef $tmpldif; + + if (is_samba_user($user)) { + + my $tmpldif = +"dn: $dn_line +changetype: modify +replace: acctFlags +acctFlags: [D ] + +"; + + die "$0: error while modifying user $user\n" + unless (do_ldapmodify($tmpldif) == 0); + undef $tmpldif; + + } + +} + +# delete_user($user) +sub delete_user +{ + my $user = shift; + my $dn_line; + + if (!defined($dn_line = get_user_dn($user))) { + print "$0: user $user doesn't exist\n"; + exit (10); + } + + my $dn = get_dn_from_line($dn_line); + system "$ldapdelete $dn >/dev/null"; +} + +# $success = group_add($groupname, $group_gid, $force_using_existing_gid) +sub group_add +{ + my ($gname, $gid, $force) = @_; + + my $nscd_status = system "/etc/init.d/nscd status >/dev/null 2>&1"; + + if ($nscd_status == 0) { + system "/etc/init.d/nscd stop > /dev/null 2>&1"; + } + + if (!defined($gid)) { + while (defined(getgrgid($GID_START))) { + $GID_START++; + } + $gid = $GID_START; + } else { + if (!defined($force)) { + if (defined(getgrgid($gid))) { + return 0; + } + } + } + + if ($nscd_status == 0) { + system "/etc/init.d/nscd start > /dev/null 2>&1"; + } + + my $tmpldif = +"dn: cn=$gname,$groupsdn +objectclass: posixGroup +cn: $gname +gidNumber: $gid + +"; + + die "$0: error while adding posix group $gname\n" + unless (do_ldapadd($tmpldif) == 0); + + undef $tmpldif; + + return 1; +} + +# $homedir = get_homedir ($user) +sub get_homedir +{ + my $user = shift; + my $homeDir=`$ldapsearch -b '$suffix' -s '$scope' '(&(objectclass=posixAccount)(uid=$user))' | grep "^homeDirectory:"`; + chomp $homeDir; + if ($homeDir eq '') { + return undef; + } + $homeDir =~ s/^homeDirectory: //; + + return $homeDir; +} + +# search for an user +sub read_user +{ + my $user = shift; + my $lines=`$ldapsearch -b '$suffix' -s '$scope' '(&(objectclass=posixAccount)(uid=$user))' -LLL`; + chomp $lines; + if ($lines eq '') { + return undef; + } + + return $lines; +} + +# search for a group +sub read_group +{ + my $user = shift; + my $lines=`$ldapsearch -b '$groupsdn' -s '$scope' '(&(objectclass=posixGroup)(cn=$user))' -LLL`; + chomp $lines; + if ($lines eq '') { + return undef; + } + + return $lines; +} + +# find groups of a given user +sub find_groups_of +{ + my $user = shift; + my $lines=`$ldapsearch -b '$groupsdn' -s '$scope' '(&(objectclass=posixGroup)(memberuid=$user))' -LLL | grep "^dn: "`; + chomp $lines; + if ($lines eq '') { + return undef; + } + + return $lines; +} + +# return the gidnumber for a group given as name or gid +# -1 : bad group name +# -2 : bad gidnumber +sub parse_group +{ + my $userGidNumber = shift; + + if ($userGidNumber =~ /[^\d]/ ) { + my $gname = $userGidNumber; + my $gidnum = getgrnam($gname); + if ($gidnum !~ /\d+/) { + return -1; + } else { + $userGidNumber = $gidnum; + } + } elsif (!defined(getgrgid($userGidNumber))) { + return -2; + } + return $userGidNumber; +} + +# remove $user from $group +sub group_remove_member +{ + my ($group, $user) = @_; + + my $grp_line = get_group_dn($group); + if (!defined($grp_line)) { + return 0; + } + my $members = `$ldapsearch -b '$groupsdn' -s '$scope' '(&(objectclass=posixgroup)(cn=$group))' | grep -i "^memberUid:"`; + + #print "avant ---\n$members\n"; + $members =~ s/memberUid: $user\n//; + #print "----\n$members\n---\n"; + + chomp($members); + + my $header; + if ($members eq '') { + $header = "changetype: modify\n"; + $header .= "delete: memberUid"; + } else { + $header = "changetype: modify\n"; + $header .= "replace: memberUid"; + } + + my $tmpldif = +"$grp_line +$header +$members +"; + die "$0: error while modifying group $group\n" + unless (do_ldapmodify($tmpldif) == 0); + undef $tmpldif; + + return 1; +} + +sub group_get_members +{ + my ($group) = @_; + my @members; + + my $grp_line = get_group_dn($group); + if (!defined($grp_line)) { + return 0; + } + my $members = `$ldapsearch -b '$groupsdn' -s '$scope' '(&(objectclass=posixgroup)(cn=$group))' memberUid | grep -i "^memberUid:"`; + + my @lines = split (/\n/, $members); + foreach my $line (@lines) { + $line =~ s/^memberUid: //; + push(@members, $line); + } + + return @members; +} + +sub file_write { + my ($filename, $filecontent) = @_; + local *FILE; + open (FILE, "> $filename") || + die "Cannot open «$filename» for writing: $!\n"; + print FILE $filecontent; + close FILE; +} + +# wrapper for ldapadd +sub do_ldapadd2 +{ + my $ldif = shift; + + my $tempfile = "/tmp/smbldapadd.$$"; + file_write($tempfile, $ldif); + + my $rc = system "$ldapadd < $tempfile >/dev/null"; + unlink($tempfile); + return $rc; +} + +sub do_ldapadd +{ + my $ldif = shift; + + my $FILE = "|$ldapadd >/dev/null"; + open (FILE, $FILE) || die "$!\n"; + print FILE </dev/null"; + unlink($tempfile); + return $rc; +} + +sub do_ldapmodify +{ + my $ldif = shift; + + my $FILE = "|$ldapmodify -r >/dev/null"; + open (FILE, $FILE) || die "$!\n"; + print FILE <&2; exit 1; } + fi + ac_feature=`echo $ac_feature| sed 's/-/_/g'` + eval "enable_${ac_feature}=no" ;; + + -enable-* | --enable-*) + ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then + { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } + fi + ac_feature=`echo $ac_feature| sed 's/-/_/g'` + case "$ac_option" in + *=*) ;; + *) ac_optarg=yes ;; + esac + eval "enable_${ac_feature}='$ac_optarg'" ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix="$ac_optarg" ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he) + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat << EOF +Usage: configure [options] [host] +Options: [defaults in brackets after descriptions] +Configuration: + --cache-file=FILE cache test results in FILE + --help print this message + --no-create do not create output files + --quiet, --silent do not print \`checking...' messages + --version print the version of autoconf that created configure +Directory and file names: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [same as prefix] + --bindir=DIR user executables in DIR [EPREFIX/bin] + --sbindir=DIR system admin executables in DIR [EPREFIX/sbin] + --libexecdir=DIR program executables in DIR [EPREFIX/libexec] + --datadir=DIR read-only architecture-independent data in DIR + [PREFIX/share] + --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data in DIR + [PREFIX/com] + --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var] + --libdir=DIR object code libraries in DIR [EPREFIX/lib] + --includedir=DIR C header files in DIR [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include] + --infodir=DIR info documentation in DIR [PREFIX/info] + --mandir=DIR man documentation in DIR [PREFIX/man] + --srcdir=DIR find the sources in DIR [configure dir or ..] + --program-prefix=PREFIX prepend PREFIX to installed program names + --program-suffix=SUFFIX append SUFFIX to installed program names + --program-transform-name=PROGRAM + run sed PROGRAM on installed program names +EOF + cat << EOF +Host type: + --build=BUILD configure for building on BUILD [BUILD=HOST] + --host=HOST configure for HOST [guessed] + --target=TARGET configure for TARGET [TARGET=HOST] +Features and packages: + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --x-includes=DIR X include files are in DIR + --x-libraries=DIR X library files are in DIR +EOF + if test -n "$ac_help"; then + echo "--enable and --with options recognized:$ac_help" + fi + exit 0 ;; + + -host | --host | --hos | --ho) + ac_prev=host ;; + -host=* | --host=* | --hos=* | --ho=*) + host="$ac_optarg" ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir="$ac_optarg" ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir="$ac_optarg" ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir="$ac_optarg" ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir="$ac_optarg" ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst \ + | --locals | --local | --loca | --loc | --lo) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* \ + | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) + localstatedir="$ac_optarg" ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir="$ac_optarg" ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir="$ac_optarg" ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix="$ac_optarg" ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix="$ac_optarg" ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix="$ac_optarg" ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name="$ac_optarg" ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir="$ac_optarg" ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir="$ac_optarg" ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site="$ac_optarg" ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir="$ac_optarg" ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir="$ac_optarg" ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target="$ac_optarg" ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers) + echo "configure generated by autoconf version 2.13" + exit 0 ;; + + -with-* | --with-*) + ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then + { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } + fi + ac_package=`echo $ac_package| sed 's/-/_/g'` + case "$ac_option" in + *=*) ;; + *) ac_optarg=yes ;; + esac + eval "with_${ac_package}='$ac_optarg'" ;; + + -without-* | --without-*) + ac_package=`echo $ac_option|sed -e 's/-*without-//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then + { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } + fi + ac_package=`echo $ac_package| sed 's/-/_/g'` + eval "with_${ac_package}=no" ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes="$ac_optarg" ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries="$ac_optarg" ;; + + -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; } + ;; + + *) + if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then + echo "configure: warning: $ac_option: invalid host type" 1>&2 + fi + if test "x$nonopt" != xNONE; then + { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } + fi + nonopt="$ac_option" + ;; + + esac +done + +if test -n "$ac_prev"; then + { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; } +fi + +trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 + +# File descriptor usage: +# 0 standard input +# 1 file creation +# 2 errors and warnings +# 3 some systems may open it to /dev/tty +# 4 used on the Kubota Titan +# 6 checking for... messages and results +# 5 compiler messages saved in config.log +if test "$silent" = yes; then + exec 6>/dev/null +else + exec 6>&1 +fi +exec 5>./config.log + +echo "\ +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. +" 1>&5 + +# Strip out --no-create and --no-recursion so they do not pile up. +# Also quote any args containing shell metacharacters. +ac_configure_args= +for ac_arg +do + case "$ac_arg" in + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c) ;; + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;; + *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*) + ac_configure_args="$ac_configure_args '$ac_arg'" ;; + *) ac_configure_args="$ac_configure_args $ac_arg" ;; + esac +done + +# NLS nuisances. +# Only set these to C if already set. These must not be set unconditionally +# because not all systems understand e.g. LANG=C (notably SCO). +# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'! +# Non-C LC_CTYPE values break the ctype check. +if test "${LANG+set}" = set; then LANG=C; export LANG; fi +if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi +if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi +if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -rf conftest* confdefs.h +# AIX cpp loses on an empty file, so make sure it contains at least a newline. +echo > confdefs.h + +# A filename unique to this package, relative to the directory that +# configure is in, which we can look for to find out if srcdir is correct. +ac_unique_file= + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then its parent. + ac_prog=$0 + ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'` + test "x$ac_confdir" = "x$ac_prog" && ac_confdir=. + srcdir=$ac_confdir + if test ! -r $srcdir/$ac_unique_file; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r $srcdir/$ac_unique_file; then + if test "$ac_srcdir_defaulted" = yes; then + { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; } + else + { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; } + fi +fi +srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'` + +# Prefer explicitly selected file to automatically selected ones. +if test -z "$CONFIG_SITE"; then + if test "x$prefix" != xNONE; then + CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" + else + CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" + fi +fi +for ac_site_file in $CONFIG_SITE; do + if test -r "$ac_site_file"; then + echo "loading site script $ac_site_file" + . "$ac_site_file" + fi +done + +if test -r "$cache_file"; then + echo "loading cache $cache_file" + . $cache_file +else + echo "creating cache $cache_file" + > $cache_file +fi + +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +ac_exeext= +ac_objext=o +if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then + # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu. + if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then + ac_n= ac_c=' +' ac_t=' ' + else + ac_n=-n ac_c= ac_t= + fi +else + ac_n= ac_c='\c' ac_t= +fi + + + +uname=`uname` + +# Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:533: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_CC="gcc" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:563: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_prog_rejected=no + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + break + fi + done + IFS="$ac_save_ifs" +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# -gt 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + set dummy "$ac_dir/$ac_word" "$@" + shift + ac_cv_prog_CC="$@" + fi +fi +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + if test -z "$CC"; then + case "`uname -s`" in + *win32* | *WIN32*) + # Extract the first word of "cl", so it can be a program name with args. +set dummy cl; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:614: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_CC="cl" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + ;; + esac + fi + test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; } +fi + +echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6 +echo "configure:646: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 + +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +cat > conftest.$ac_ext << EOF + +#line 657 "configure" +#include "confdefs.h" + +main(){return(0);} +EOF +if { (eval echo configure:662: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + ac_cv_prog_cc_works=yes + # If we can't run a trivial program, we are probably using a cross compiler. + if (./conftest; exit) 2>/dev/null; then + ac_cv_prog_cc_cross=no + else + ac_cv_prog_cc_cross=yes + fi +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + ac_cv_prog_cc_works=no +fi +rm -fr conftest* +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +echo "$ac_t""$ac_cv_prog_cc_works" 1>&6 +if test $ac_cv_prog_cc_works = no; then + { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; } +fi +echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 +echo "configure:688: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 +echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6 +cross_compiling=$ac_cv_prog_cc_cross + +echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 +echo "configure:693: checking whether we are using GNU C" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.c <&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then + ac_cv_prog_gcc=yes +else + ac_cv_prog_gcc=no +fi +fi + +echo "$ac_t""$ac_cv_prog_gcc" 1>&6 + +if test $ac_cv_prog_gcc = yes; then + GCC=yes +else + GCC= +fi + +ac_test_CFLAGS="${CFLAGS+set}" +ac_save_CFLAGS="$CFLAGS" +CFLAGS= +echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 +echo "configure:721: checking whether ${CC-cc} accepts -g" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + echo 'void f(){}' > conftest.c +if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then + ac_cv_prog_cc_g=yes +else + ac_cv_prog_cc_g=no +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_prog_cc_g" 1>&6 +if test "$ac_test_CFLAGS" = set; then + CFLAGS="$ac_save_CFLAGS" +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi + + +# Extract the first word of "libtool", so it can be a program name with args. +set dummy libtool; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:756: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_path_LIBTOOL'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case "$LIBTOOL" in + /*) + ac_cv_path_LIBTOOL="$LIBTOOL" # Let the user override the test with a path. + ;; + ?:/*) + ac_cv_path_LIBTOOL="$LIBTOOL" # Let the user override the test with a dos path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_path_LIBTOOL="$ac_dir/$ac_word" + break + fi + done + IFS="$ac_save_ifs" + ;; +esac +fi +LIBTOOL="$ac_cv_path_LIBTOOL" +if test -n "$LIBTOOL"; then + echo "$ac_t""$LIBTOOL" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +if test "$LIBTOOL" = ""; then + echo + echo 'FATAL ERROR: libtool does not seem to be installed.' + echo $pkg_name cannot be built without a working libtool installation. + exit 1 +fi + +# +# Config CFLAGS settings +# +CFLAGS="-Wall" + +case "$uname" in + AIX) + if test "${GCC}" = "yes"; then + CFLAGS="$CFLAGS -I/usr/include -D_LINUX_SOURCE_COMPAT" + else + CFLAGS="-D_LINUX_SOURCE_COMPAT" + fi + ;; + SunOS) + if test "${GCC}" = "yes"; then + CFLAGS="$CFLAGS" + else + CFLAGS="" + fi + ;; +# Linux) +# CFLAGS="-Wall" +# ;; +esac + +# +# Config LDLAGS settings +# +LDFLAGS="-shared" + +case "$uname" in + AIX) + LDFLAGS="-Wl,-G,-bexpall,-bnoentry" + ;; + SunOS) + LDFLAGS="-G" + ;; +# Linux) +# echo "Linux found" +# LDFLAGS="-shared" +# ;; +esac + +################################################# +# Check to see if we should use the included popt + +# Check whether --with-included-popt or --without-included-popt was given. +if test "${with_included_popt+set}" = set; then + withval="$with_included_popt" + + case "$withval" in + yes) + INCLUDED_POPT=yes + ;; + no) + INCLUDED_POPT=no + ;; + esac +fi + +if test x"$INCLUDED_POPT" != x"yes"; then + echo $ac_n "checking for poptGetContext in -lpopt""... $ac_c" 1>&6 +echo "configure:857: checking for poptGetContext in -lpopt" >&5 +ac_lib_var=`echo popt'_'poptGetContext | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lpopt $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + INCLUDED_POPT=no +else + echo "$ac_t""no" 1>&6 +INCLUDED_POPT=yes +fi + +fi + +echo $ac_n "checking whether to use included popt""... $ac_c" 1>&6 +echo "configure:900: checking whether to use included popt" >&5 +if test x"$INCLUDED_POPT" = x"yes"; then + echo "$ac_t""$srcdir/popt" 1>&6 + CFLAGS="$CFLAGS -I../../source/popt" +else + echo "$ac_t""no" 1>&6 +fi + +CFLAGS="$CFLAGS -I../../source -I../../source/include -I../../source/ubiqx -I../../source/smbwrapper" + +trap '' 1 2 15 +cat > confcache <<\EOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs. It is not useful on other systems. +# If it contains results you don't want to keep, you may remove or edit it. +# +# By default, configure uses ./config.cache as the cache file, +# creating it if it does not exist already. You can give configure +# the --cache-file=FILE option to use a different cache file; that is +# what configure does when it calls configure scripts in +# subdirectories, so they share the cache. +# Giving --cache-file=/dev/null disables caching, for debugging configure. +# config.status only pays attention to the cache file if you give it the +# --recheck option to rerun configure. +# +EOF +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, don't put newlines in cache variables' values. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +(set) 2>&1 | + case `(ac_space=' '; set | grep ac_space) 2>&1` in + *ac_space=\ *) + # `set' does not quote correctly, so add quotes (double-quote substitution + # turns \\\\ into \\, and sed turns \\ into \). + sed -n \ + -e "s/'/'\\\\''/g" \ + -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p" + ;; + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p' + ;; + esac >> confcache +if cmp -s $cache_file confcache; then + : +else + if test -w $cache_file; then + echo "updating cache $cache_file" + cat confcache > $cache_file + else + echo "not updating unwritable cache $cache_file" + fi +fi +rm -f confcache + +trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +# Any assignment to VPATH causes Sun make to only execute +# the first set of double-colon rules, so remove it if not needed. +# If there is a colon in the path, we need to keep it. +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d' +fi + +trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15 + +# Transform confdefs.h into DEFS. +# Protect against shell expansion while executing Makefile rules. +# Protect against Makefile macro expansion. +cat > conftest.defs <<\EOF +s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%-D\1=\2%g +s%[ `~#$^&*(){}\\|;'"<>?]%\\&%g +s%\[%\\&%g +s%\]%\\&%g +s%\$%$$%g +EOF +DEFS=`sed -f conftest.defs confdefs.h | tr '\012' ' '` +rm -f conftest.defs + + +# Without the "./", some shells look in PATH for config.status. +: ${CONFIG_STATUS=./config.status} + +echo creating $CONFIG_STATUS +rm -f $CONFIG_STATUS +cat > $CONFIG_STATUS </dev/null | sed 1q`: +# +# $0 $ac_configure_args +# +# Compiler output produced by configure, useful for debugging +# configure, is in ./config.log if it exists. + +ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]" +for ac_option +do + case "\$ac_option" in + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion" + exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;; + -version | --version | --versio | --versi | --vers | --ver | --ve | --v) + echo "$CONFIG_STATUS generated by autoconf version 2.13" + exit 0 ;; + -help | --help | --hel | --he | --h) + echo "\$ac_cs_usage"; exit 0 ;; + *) echo "\$ac_cs_usage"; exit 1 ;; + esac +done + +ac_given_srcdir=$srcdir + +trap 'rm -fr `echo "Makefile" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15 +EOF +cat >> $CONFIG_STATUS < conftest.subs <<\\CEOF +$ac_vpsub +$extrasub +s%@SHELL@%$SHELL%g +s%@CFLAGS@%$CFLAGS%g +s%@CPPFLAGS@%$CPPFLAGS%g +s%@CXXFLAGS@%$CXXFLAGS%g +s%@FFLAGS@%$FFLAGS%g +s%@DEFS@%$DEFS%g +s%@LDFLAGS@%$LDFLAGS%g +s%@LIBS@%$LIBS%g +s%@exec_prefix@%$exec_prefix%g +s%@prefix@%$prefix%g +s%@program_transform_name@%$program_transform_name%g +s%@bindir@%$bindir%g +s%@sbindir@%$sbindir%g +s%@libexecdir@%$libexecdir%g +s%@datadir@%$datadir%g +s%@sysconfdir@%$sysconfdir%g +s%@sharedstatedir@%$sharedstatedir%g +s%@localstatedir@%$localstatedir%g +s%@libdir@%$libdir%g +s%@includedir@%$includedir%g +s%@oldincludedir@%$oldincludedir%g +s%@infodir@%$infodir%g +s%@mandir@%$mandir%g +s%@CC@%$CC%g +s%@LIBTOOL@%$LIBTOOL%g + +CEOF +EOF + +cat >> $CONFIG_STATUS <<\EOF + +# Split the substitutions into bite-sized pieces for seds with +# small command number limits, like on Digital OSF/1 and HP-UX. +ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script. +ac_file=1 # Number of current file. +ac_beg=1 # First line for current file. +ac_end=$ac_max_sed_cmds # Line after last line for current file. +ac_more_lines=: +ac_sed_cmds="" +while $ac_more_lines; do + if test $ac_beg -gt 1; then + sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file + else + sed "${ac_end}q" conftest.subs > conftest.s$ac_file + fi + if test ! -s conftest.s$ac_file; then + ac_more_lines=false + rm -f conftest.s$ac_file + else + if test -z "$ac_sed_cmds"; then + ac_sed_cmds="sed -f conftest.s$ac_file" + else + ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file" + fi + ac_file=`expr $ac_file + 1` + ac_beg=$ac_end + ac_end=`expr $ac_end + $ac_max_sed_cmds` + fi +done +if test -z "$ac_sed_cmds"; then + ac_sed_cmds=cat +fi +EOF + +cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF +for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case "$ac_file" in + *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` + ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; + *) ac_file_in="${ac_file}.in" ;; + esac + + # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories. + + # Remove last slash and all that follows it. Not all systems have dirname. + ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` + if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then + # The file is in a subdirectory. + test ! -d "$ac_dir" && mkdir "$ac_dir" + ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`" + # A "../" for each directory in $ac_dir_suffix. + ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'` + else + ac_dir_suffix= ac_dots= + fi + + case "$ac_given_srcdir" in + .) srcdir=. + if test -z "$ac_dots"; then top_srcdir=. + else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;; + /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;; + *) # Relative path. + srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix" + top_srcdir="$ac_dots$ac_given_srcdir" ;; + esac + + + echo creating "$ac_file" + rm -f "$ac_file" + configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure." + case "$ac_file" in + *Makefile*) ac_comsub="1i\\ +# $configure_input" ;; + *) ac_comsub= ;; + esac + + ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"` + sed -e "$ac_comsub +s%@configure_input@%$configure_input%g +s%@srcdir@%$srcdir%g +s%@top_srcdir@%$top_srcdir%g +" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file +fi; done +rm -f conftest.s* + +EOF +cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF + +exit 0 +EOF +chmod +x $CONFIG_STATUS +rm -fr confdefs* $ac_clean_files +test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1 + diff --git a/examples/VFS/configure.in b/examples/VFS/configure.in new file mode 100644 index 00000000000..2afa2e1a044 --- /dev/null +++ b/examples/VFS/configure.in @@ -0,0 +1,92 @@ +dnl Samba VFS Modules + +AC_INIT + +uname=`uname` + +dnl Check programs needed +AC_PROG_CC + +dnl ensure libtool is installed +AC_PATH_PROG(LIBTOOL, libtool,,) +if test "$LIBTOOL" = ""; then + echo + echo 'FATAL ERROR: libtool does not seem to be installed.' + echo $pkg_name cannot be built without a working libtool installation. + exit 1 +fi + +# +# Config CFLAGS settings +# +CFLAGS="-Wall" + +case "$uname" in + AIX) + if test "${GCC}" = "yes"; then + CFLAGS="$CFLAGS -I/usr/include -D_LINUX_SOURCE_COMPAT" + else + CFLAGS="-D_LINUX_SOURCE_COMPAT" + fi + ;; + SunOS) + if test "${GCC}" = "yes"; then + CFLAGS="$CFLAGS" + else + CFLAGS="" + fi + ;; +# Linux) +# CFLAGS="-Wall" +# ;; +esac + +# +# Config LDLAGS settings +# +LDFLAGS="-shared" + +case "$uname" in + AIX) + LDFLAGS="-Wl,-G,-bexpall,-bnoentry" + ;; + SunOS) + LDFLAGS="-G" + ;; +# Linux) +# echo "Linux found" +# LDFLAGS="-shared" +# ;; +esac + +################################################# +# Check to see if we should use the included popt + +AC_ARG_WITH(included-popt, +[ --with-included-popt use bundled popt library, not from system], +[ + case "$withval" in + yes) + INCLUDED_POPT=yes + ;; + no) + INCLUDED_POPT=no + ;; + esac ], +) +if test x"$INCLUDED_POPT" != x"yes"; then + AC_CHECK_LIB(popt, poptGetContext, + INCLUDED_POPT=no, INCLUDED_POPT=yes) +fi + +AC_MSG_CHECKING(whether to use included popt) +if test x"$INCLUDED_POPT" = x"yes"; then + AC_MSG_RESULT($srcdir/popt) + CFLAGS="$CFLAGS -I../../source/popt" +else + AC_MSG_RESULT(no) +fi + +CFLAGS="$CFLAGS -I../../source -I../../source/include -I../../source/ubiqx -I../../source/smbwrapper" + +AC_OUTPUT([Makefile]) diff --git a/examples/VFS/recycle.c b/examples/VFS/recycle.c deleted file mode 100644 index 74d3657895a..00000000000 --- a/examples/VFS/recycle.c +++ /dev/null @@ -1,287 +0,0 @@ -/* - * Auditing VFS module for samba. Log selected file operations to syslog - * facility. - * - * Copyright (C) 2001, Brandon Stone, Amherst College, . - * Copyright (C) 2002, Jeremy Allison - modified to make a VFS module. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include "config.h" -#include -#include -#ifdef HAVE_UTIME_H -#include -#endif -#ifdef HAVE_DIRENT_H -#include -#endif -#include -#ifdef HAVE_FCNTL_H -#include -#endif -#include -#include -#include -#include - -/* VFS operations */ - -extern struct vfs_ops default_vfs_ops; /* For passthrough operation */ - -static int recycle_unlink(connection_struct *, const char *); -static int recycle_connect(struct connection_struct *conn, const char *service, const char *user); -static void recycle_disconnect(struct connection_struct *conn); - -struct vfs_ops recycle_ops = { - - /* Disk operations */ - - recycle_connect, /* connect */ - recycle_disconnect, /* disconnect */ - NULL, /* disk free */ - - /* Directory operations */ - - NULL, /* opendir */ - NULL, /* readdir */ - NULL, /* mkdir */ - NULL, /* rmdir */ - NULL, /* closedir */ - - /* File operations */ - - NULL, /* open */ - NULL, /* close */ - NULL, /* read */ - NULL, /* write */ - NULL, /* lseek */ - NULL, /* rename */ - NULL, /* fsync */ - NULL, /* stat */ - NULL, /* fstat */ - NULL, /* lstat */ - recycle_unlink, - NULL, /* chmod */ - NULL, /* fchmod */ - NULL, /* chown */ - NULL, /* fchown */ - NULL, /* chdir */ - NULL, /* getwd */ - NULL, /* utime */ - NULL, /* ftruncate */ - NULL, /* lock */ - NULL, /* symlink */ - NULL, /* readlink */ - NULL, /* link */ - NULL, /* mknod */ - NULL, /* realpath */ - NULL, /* fget_nt_acl */ - NULL, /* get_nt_acl */ - NULL, /* fset_nt_acl */ - NULL, /* set_nt_acl */ - - NULL, /* chmod_acl */ - NULL, /* fchmod_acl */ - - NULL, /* sys_acl_get_entry */ - NULL, /* sys_acl_get_tag_type */ - NULL, /* sys_acl_get_permset */ - NULL, /* sys_acl_get_qualifier */ - NULL, /* sys_acl_get_file */ - NULL, /* sys_acl_get_fd */ - NULL, /* sys_acl_clear_perms */ - NULL, /* sys_acl_add_perm */ - NULL, /* sys_acl_to_text */ - NULL, /* sys_acl_init */ - NULL, /* sys_acl_create_entry */ - NULL, /* sys_acl_set_tag_type */ - NULL, /* sys_acl_set_qualifier */ - NULL, /* sys_acl_set_permset */ - NULL, /* sys_acl_valid */ - NULL, /* sys_acl_set_file */ - NULL, /* sys_acl_set_fd */ - NULL, /* sys_acl_delete_def_file */ - NULL, /* sys_acl_get_perm */ - NULL, /* sys_acl_free_text */ - NULL, /* sys_acl_free_acl */ - NULL /* sys_acl_free_qualifier */ -}; - -/* VFS initialisation function. Return initialised vfs_ops structure - back to SAMBA. */ - -struct vfs_ops *vfs_init(int *vfs_version, struct vfs_ops *def_vfs_ops) -{ - struct vfs_ops tmp_ops; - - *vfs_version = SMB_VFS_INTERFACE_VERSION; - memcpy(&tmp_ops, def_vfs_ops, sizeof(struct vfs_ops)); - tmp_ops.unlink = recycle_unlink; - tmp_ops.connect = recycle_connect; - tmp_ops.disconnect = recycle_disconnect; - memcpy(&recycle_ops, &tmp_ops, sizeof(struct vfs_ops)); - return &recycle_ops; -} - -static int recycle_connect(struct connection_struct *conn, const char *service, const char *user) -{ - pstring opts_str; - fstring recycle_bin; - char *p; - - DEBUG(3,("recycle_connect: called for service %s as user %s\n", service, user)); - - pstrcpy(opts_str, (const char *)lp_vfs_options(SNUM(conn))); - if (!*opts_str) { - DEBUG(3,("recycle_connect: No options listed (%s).\n", lp_vfs_options(SNUM(conn)) )); - return 0; /* No options. */ - } - - p = opts_str; - if (next_token(&p,recycle_bin,"=",sizeof(recycle_bin))) { - if (!strequal("recycle", recycle_bin)) { - DEBUG(3,("recycle_connect: option %s is not recycle\n", recycle_bin )); - return -1; - } - } - - if (!next_token(&p,recycle_bin," \n",sizeof(recycle_bin))) { - DEBUG(3,("recycle_connect: no option after recycle=\n")); - return -1; - } - - DEBUG(10,("recycle_connect: recycle name is %s\n", recycle_bin )); - - conn->vfs_private = (void *)strdup(recycle_bin); - return 0; -} - -static void recycle_disconnect(struct connection_struct *conn) -{ - SAFE_FREE(conn->vfs_private); -} - -static BOOL recycle_XXX_exist(connection_struct *conn, const char *dname, BOOL isdir) -{ - SMB_STRUCT_STAT st; - - if (default_vfs_ops.stat(conn,dname,&st) != 0) - return(False); - - if (isdir) - return S_ISDIR(st.st_mode) ? True : False; - else - return S_ISREG(st.st_mode) ? True : False; -} - -static BOOL recycle_directory_exist(connection_struct *conn, const char *dname) -{ - return recycle_XXX_exist(conn, dname, True); -} - -static BOOL recycle_file_exist(connection_struct *conn, const char *fname) -{ - return recycle_XXX_exist(conn, fname, False); -} - -static SMB_OFF_T recycle_get_file_size(connection_struct *conn, const char *fname) -{ - SMB_STRUCT_STAT st; - - if (default_vfs_ops.stat(conn,fname,&st) != 0) - return (SMB_OFF_T)-1; - - return(st.st_size); -} - -/******************************************************************** - Check if file should be recycled -*********************************************************************/ - -static int recycle_unlink(connection_struct *conn, const char *inname) -{ - fstring recycle_bin; - pstring fname; - char *base, *ext; - pstring bin; - int i=1, len, addlen; - int dir_mask=0770; - SMB_BIG_UINT dfree,dsize,bsize; - - *recycle_bin = '\0'; - pstrcpy(fname, inname); - - if (conn->vfs_private) - fstrcpy(recycle_bin, (const char *)conn->vfs_private); - - if(!*recycle_bin) { - DEBUG(3, ("recycle bin: share parameter not set, purging %s...\n", fname)); - return default_vfs_ops.unlink(conn,fname); - } - - if(recycle_get_file_size(conn, fname) == 0) { - DEBUG(3, ("recycle bin: file %s is empty, purging...\n", fname)); - return default_vfs_ops.unlink(conn,fname); - } - - base = strrchr(fname, '/') + 1; - if(base == (char*)1) - ext = strrchr(fname, '.'); - else - ext = strrchr(base, '.'); - - pstrcpy(bin, recycle_bin); - pstrcat(bin, "/"); - pstrcat(bin, base); - - if(strcmp(fname,bin) == 0) { - DEBUG(3, ("recycle bin: file %s exists, purging...\n", fname)); - return default_vfs_ops.unlink(conn,fname); - } - - len = strlen(bin); - addlen = sizeof(pstring)-len-1; - while(recycle_file_exist(conn,bin)) { - slprintf(bin+len, addlen, " (Copy #%d)", i++); - pstrcat(bin, ext); - } - - DEBUG(3, ("recycle bin: moving source=%s to dest=%s\n", fname, bin)); - default_vfs_ops.disk_free(conn,".",True,&bsize,&dfree,&dsize); - if((unsigned int)dfree > 0) { - int ret; - if(!recycle_directory_exist(conn,recycle_bin)) { - DEBUG(3, ("recycle bin: directory %s nonexistant, creating...\n", recycle_bin)); - if (default_vfs_ops.mkdir(conn,recycle_bin,dir_mask) == -1) { - DEBUG(3, ("recycle bin: unable to create directory %s. Error was %s\n", - recycle_bin, strerror(errno) )); - } - } - DEBUG(3, ("recycle bin: move %s -> %s\n", fname, bin)); - - ret = default_vfs_ops.rename(conn, fname, bin); - if (ret == -1) { - DEBUG(3, ("recycle bin: move error %d (%s)\n", errno, strerror(errno) )); - DEBUG(3, ("recycle bin: move failed, purging...\n")); - return default_vfs_ops.unlink(conn,fname); - } - return ret; - } else { - DEBUG(3, ("recycle bin: move failed, purging...\n")); - return default_vfs_ops.unlink(conn,fname); - } -} diff --git a/examples/VFS/recycle/README b/examples/VFS/recycle/README new file mode 100644 index 00000000000..2b85a65925e --- /dev/null +++ b/examples/VFS/recycle/README @@ -0,0 +1,83 @@ +The recycle VFS module implements a recycle bin for Samba. +Deleted files will be moved to a special directory and +not be deleted unless specified in the configuration file. +It is up to the administrator/user to clean up the files +in the recycle bin. + +Installation: + +1. Build VFS module using the GNU autoconf script and Makefile + in the parent directory (cd .. && ./configure && make) +2. Install module by copying to /usr/lib/samba/vfs (or any other place you like) +3. Install/modify recycle.conf. See below for the description +4. Modify smb.conf to use the recycle module + Add the lines "vfs object = /usr/lib/samba/recycle.so" + and "vfs options = /etc/samba/recycle.conf". +5. Start Samba + + +Options for recycle.conf: +name + name of the recycle bin at root level of the share + allows smb.conf substutitions like %U. + Example: + name = .recycle/%U + +mode + KEEP_DIRECTORIES : retain directory hierarchy of deleted file, + VERSIONS : create several versions of a file in recycle bin if + the file already exists in the recycle bin + e.g. mytext.doc + Copy #1 of mytext.doc + Copy #2 of mytext.doc + + TOUCH : touch access date when moving files to the recycle bin. + This is useful for automatic cleanup scripts. + Attn: This doesn't work if you have no write permissions + to the file being deleted. Deletion works if you + have write permissions to the parent directory. + Example: + mode = KEEP_DIRECTORIES|VERSIONS|TOUCH + +maxsize + maximum size of files to be moved to recycle bin. Setting this zo + zero (default) moves files of any size to the recycle bin. + Example: + maxsize = 0 + +exclude + exclude files from moving to recycle bin. Delete them immediately + Useful for temporary files. You can use the wildcards * and ? + Example: + exclude = *.tmp|*.temp|*.obj|~$*|*.$$$ + +excludedir + exclude directories from the recycle bin, useful for temporary + directories. + Example + excludedir = /tmp|/temp|/trash + +noversions + don't create versions of files in the recycle bin. Only usefull if + mode = VERSIONS is set. + Examples: + noversions = *.doc|*.xls|*.ppt + +Example smb.conf: + +[homes] + comment = Home-directory + path = /home/%u + read only = No + create mask = 0750 + vfs object = /usr/lib/samba/recycle.so + vfs options = /etc/samba/recycle.conf + +Example recycle.conf: + +name = .recycle/%U +mode = KEEP_DIRECTORIES|NOVERSIONS|TOUCH +maxsize = 0 +exclude = *.tmp|*.temp|*.o|*.obj|~$* +excludedir = /tmp|/temp|/cache +noversions = *.doc|*.xls|*.ppt diff --git a/examples/VFS/recycle/cleanup_recycle.pl b/examples/VFS/recycle/cleanup_recycle.pl new file mode 100644 index 00000000000..f614cf78708 --- /dev/null +++ b/examples/VFS/recycle/cleanup_recycle.pl @@ -0,0 +1,25 @@ +# !/usr/bin/perl -w +# +# this script looks for all files with an access date older than +# $maxage days and deletes them. +# Empty directories will be deleted afterwards +# + +$dirpath = "/data/.recycle"; +$maxage = 2; + +# delete all old files +@a=`find $dirpath -atime +$maxage`; +foreach (@a) + { + print "deleting file: $_"; + $r = `rm -f $_ 2> /dev/zero`; + } + +# delete all empty directories +@a=`find $dirpath -type d | sort -r`; +foreach (@a) + { + print "deleting directory: $_"; + $r = `rmdir $_ 2> /dev/zero`; + } diff --git a/examples/VFS/recycle/recycle.c b/examples/VFS/recycle/recycle.c new file mode 100644 index 00000000000..3d2d5d79697 --- /dev/null +++ b/examples/VFS/recycle/recycle.c @@ -0,0 +1,556 @@ +/* + * Recycle bin VFS module for Samba. + * + * Copyright (C) 2001, Brandon Stone, Amherst College, . + * Copyright (C) 2002, Jeremy Allison - modified to make a VFS module. + * Copyright (C) 2002, Juergen Hasch - added some options. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "config.h" +#include +#include +#ifdef HAVE_UTIME_H +#include +#endif +#ifdef HAVE_DIRENT_H +#include +#endif +#ifdef HAVE_FCNTL_H +#include +#endif +#include +#include +#include +#include + +const char delimiter = '|'; /* delimiter for options */ + +/* One per connection */ + +typedef struct recycle_bin_struct +{ + TALLOC_CTX *ctx; + char *recycle_bin; /* name of the recycle bin directory */ + BOOL keep_directories; /* keep directory structure of deleted file in recycle bin */ + BOOL versions; /* create versions of deleted files with identical name */ + BOOL touch; /* touch access date of deleted file */ + char *exclude; /* which files to exclude */ + char *exclude_dir; /* which directories to exclude */ + char *noversions; /* which files to exclude from versioning */ + SMB_OFF_T max_size; /* maximum file size to be saved */ +} recycle_bin_struct; + +/* Global Variables */ +static recycle_bin_struct *current; + +/* VFS operations */ + +extern struct vfs_ops default_vfs_ops; /* For passthrough operation */ + +static int recycle_unlink(connection_struct *, const char *); +static int recycle_connect(struct connection_struct *conn, const char *service, const char *user); +static void recycle_disconnect(struct connection_struct *conn); + +BOOL checkparam(char *haystack,char *needle); + +struct vfs_ops recycle_ops = { + + /* Disk operations */ + + recycle_connect, /* connect */ + recycle_disconnect, /* disconnect */ + NULL, /* disk free */ + + /* Directory operations */ + + NULL, /* opendir */ + NULL, /* readdir */ + NULL, /* mkdir */ + NULL, /* rmdir */ + NULL, /* closedir */ + + /* File operations */ + + NULL, /* open */ + NULL, /* close */ + NULL, /* read */ + NULL, /* write */ + NULL, /* lseek */ + NULL, /* rename */ + NULL, /* fsync */ + NULL, /* stat */ + NULL, /* fstat */ + NULL, /* lstat */ + recycle_unlink, + NULL, /* chmod */ + NULL, /* fchmod */ + NULL, /* chown */ + NULL, /* fchown */ + NULL, /* chdir */ + NULL, /* getwd */ + NULL, /* utime */ + NULL, /* ftruncate */ + NULL, /* lock */ + NULL, /* symlink */ + NULL, /* readlink */ + NULL, /* link */ + NULL, /* mknod */ + NULL, /* realpath */ + NULL, /* fget_nt_acl */ + NULL, /* get_nt_acl */ + NULL, /* fset_nt_acl */ + NULL, /* set_nt_acl */ + + NULL, /* chmod_acl */ + NULL, /* fchmod_acl */ + + NULL, /* sys_acl_get_entry */ + NULL, /* sys_acl_get_tag_type */ + NULL, /* sys_acl_get_permset */ + NULL, /* sys_acl_get_qualifier */ + NULL, /* sys_acl_get_file */ + NULL, /* sys_acl_get_fd */ + NULL, /* sys_acl_clear_perms */ + NULL, /* sys_acl_add_perm */ + NULL, /* sys_acl_to_text */ + NULL, /* sys_acl_init */ + NULL, /* sys_acl_create_entry */ + NULL, /* sys_acl_set_tag_type */ + NULL, /* sys_acl_set_qualifier */ + NULL, /* sys_acl_set_permset */ + NULL, /* sys_acl_valid */ + NULL, /* sys_acl_set_file */ + NULL, /* sys_acl_set_fd */ + NULL, /* sys_acl_delete_def_file */ + NULL, /* sys_acl_get_perm */ + NULL, /* sys_acl_free_text */ + NULL, /* sys_acl_free_acl */ + NULL /* sys_acl_free_qualifier */ +}; + +/** + * Parse recycle bin configuration parameters + * + * @retval False if out of memory + **/ +static BOOL do_parameter(char *pszParmName, char *pszParmValue) +{ + if (StrCaseCmp("name",pszParmName)==0) { + current->recycle_bin = (char *)talloc(current->ctx,sizeof(pstring)); + if (current->recycle_bin == NULL) + return False; + current->recycle_bin = safe_strcpy(current->recycle_bin,pszParmValue,sizeof(pstring)); + standard_sub_basic(current->recycle_bin); + trim_string(current->recycle_bin,"/","/"); + DEBUG(10, ("name=%s\n", current->recycle_bin)); + } else if (StrCaseCmp("mode",pszParmName)==0) { + if (checkparam(pszParmValue,"KEEP_DIRECTORIES") == True) + current->keep_directories = True; + if (checkparam(pszParmValue,"VERSIONS") == True) + current->versions = True; + if (checkparam(pszParmValue,"TOUCH") == True) + current->touch = True; + DEBUG(10, ("mode=%s\n", pszParmValue)); + } else if (StrCaseCmp("maxsize",pszParmName)==0) { + current->max_size = strtoul(pszParmValue,NULL,10); + DEBUG(10, ("max_size=%ld\n", (long int)current->max_size)); + } else if (StrCaseCmp("exclude",pszParmName)==0) { + current->exclude = talloc_strdup(current->ctx, pszParmValue); + if (current->exclude == NULL) + return False; + DEBUG(10, ("exclude=%s\n", current->exclude)); + } else if (StrCaseCmp("excludedir",pszParmName)==0) { + current->exclude_dir = talloc_strdup(current->ctx, pszParmValue); + if (current->exclude_dir == NULL) + return False; + DEBUG(10, ("exclude_dir=%s\n", current->exclude_dir)); + } else if (StrCaseCmp("noversions",pszParmName)==0) { + current->noversions = talloc_strdup(current->ctx, pszParmValue); + if (current->noversions == NULL) + return False; + DEBUG(10, ("noversions=%s\n", current->noversions)); + } + return True; +} + +/** + * We don't care for sections in configuration file + * + **/ +static BOOL do_section(char *pszSectionName) +{ + return True; +} + +/** + * VFS initialisation function. + * + * @retval initialised vfs_ops structure + **/ +struct vfs_ops *vfs_init(int *vfs_version, struct vfs_ops *def_vfs_ops) +{ + struct vfs_ops tmp_ops; + DEBUG(3, ("Initializing VFS module recycle\n")); + + *vfs_version = SMB_VFS_INTERFACE_VERSION; + memcpy(&tmp_ops, def_vfs_ops, sizeof(struct vfs_ops)); + tmp_ops.unlink = recycle_unlink; + tmp_ops.connect = recycle_connect; + tmp_ops.disconnect = recycle_disconnect; + memcpy(&recycle_ops, &tmp_ops, sizeof(struct vfs_ops)); + return &recycle_ops; +} + +static int recycle_connect(struct connection_struct *conn, const char *service, const char *user) +{ + const char *p; + pstring conf_file; + int rc; + TALLOC_CTX *ctx=NULL; + + DEBUG(3,("Called for service %s (%d) as user %s\n", service, SNUM(conn), user)); + + if (!(ctx = talloc_init_named("recycle bin"))) { + DEBUG(0, ("Failed to allocate memory in VFS module recycle_bin\n")); + return 0; + } + + /* read configuration file */ + *conf_file='\0'; + p = (const char *)lp_vfs_options(SNUM(conn)); + if (p != NULL && strlen(p) > 0) { + pstrcpy(conf_file,p); + DEBUG(10,("Using configuration file %s\n",conf_file)); + } + + current = talloc(ctx,sizeof(recycle_bin_struct)); + if ( current == NULL) { + DEBUG(0, ("Failed to allocate memory in VFS module recycle_bin\n")); + return -1; + } + current->ctx = ctx; + /* Set defaults */ + current->recycle_bin = talloc_strdup(ctx,".recycle"); + current->keep_directories = False; + current->versions = False; + current->touch = False; + current->exclude = ""; + current->exclude_dir = ""; + current->noversions = ""; + current->max_size = 0; + if (strlen(conf_file) > 0) { + rc=pm_process( conf_file, do_section, do_parameter); + DEBUG(10, ("pm_process returned %d\n", rc)); + } + conn->vfs_private= (void *)current; + return 0; +} + +static void recycle_disconnect(struct connection_struct *conn) +{ + DEBUG(3, ("Disconnecting VFS module recycle_bin\n")); + talloc_destroy(((recycle_bin_struct*)conn->vfs_private)->ctx); + default_vfs_ops.disconnect(conn); +} + +static BOOL recycle_XXX_exist(connection_struct *conn, const char *dname, BOOL isdir) +{ + SMB_STRUCT_STAT st; + + if (default_vfs_ops.stat(conn,dname,&st) != 0) + return(False); + + if (isdir) + return S_ISDIR(st.st_mode) ? True : False; + else + return S_ISREG(st.st_mode) ? True : False; +} + +static BOOL recycle_directory_exist(connection_struct *conn, const char *dname) +{ + return recycle_XXX_exist(conn, dname, True); +} + +static BOOL recycle_file_exist(connection_struct *conn, const char *fname) +{ + return recycle_XXX_exist(conn, fname, False); +} + +/** + * Return file size + * @param conn connection + * @param fname file name + * @return size in bytes + **/ +static SMB_OFF_T recycle_get_file_size(connection_struct *conn, const char *fname) +{ + SMB_STRUCT_STAT st; + if (default_vfs_ops.stat(conn,fname,&st) != 0) { + DEBUG(0,("stat for %s returned %s\n",fname,strerror(errno))); + return (SMB_OFF_T)0; + } + return(st.st_size); +} + +/** + * Create directory tree + * @param conn connection + * @param dname Directory tree to be created + * @return Returns True for success + **/ +static BOOL recycle_create_dir(connection_struct *conn, const char *dname) +{ + char *c,*y; + int i; + + mode_t mode; + pstring tempstr; + pstring newdir; + + *newdir='\0'; + mode=S_IREAD|S_IWRITE|S_IEXEC; + pstrcpy(tempstr,dname); + y=tempstr; + /* Create directory tree if neccessary */ + while((c=strsep(&y,"/"))) { + pstrcat(newdir,c); + if (recycle_directory_exist(conn,newdir)) + DEBUG(3, ("dir %s already exists\n",newdir)); + else { + DEBUG(3, ("creating new dir %s\n",newdir)); + i=default_vfs_ops.mkdir(conn,newdir,mode); + if (i) { + DEBUG(3,("mkdir failed for %s with error %s\n",newdir,strerror(errno))); + return False; + } + } + pstrcat(newdir,"/"); + } + return True; +} + +/** + * Check if needle is contained exactly in haystack + * @param haystack list of parameters separated by delimimiter character + * @param needle string to be matched exactly to haystack + * @return True if found + **/ +BOOL checkparam(char *haystack,char *needle) +{ + char *p,*c; + pstring str; + int i,len; + + if (haystack==NULL || strlen(haystack)==0 || needle == NULL || strlen(needle)== 0) + return False; + + pstrcpy(str,haystack); + len=strlen(str)+1; + p=c=str; + + for (i=0; i < len; i++, p++) { + if (*p == delimiter || *p == '\0') { + *p='\0'; + if(strncmp(c,needle,c-p) == 0) + return True; + c=p+1; + } + } + return False; +} + +/** + * Check if needle is contained in haystack, * and ? patterns are resolved + * @param haystack list of parameters separated by delimimiter character + * @param needle string to be matched exectly to haystack including pattern matching + * @return True if found + **/ +BOOL matchparam(char *haystack,char *needle) +{ + char *p,*c; + pstring str; + int i,len; + + if (haystack==NULL || strlen(haystack)==0 || needle == NULL || strlen(needle)== 0) + return False; + + pstrcpy(str,haystack); + len=strlen(str)+1; + p=c=str; + + for (i=0; i < len; i++, p++) { + if (*p == delimiter || *p == '\0') { + *p='\0'; + if (!unix_wild_match(c,needle)) + return True; + c=p+1; + } + } + return False; +} + +/** + * Touch access date + **/ +void recycle_touch(connection_struct *conn, const char *fname) +{ + SMB_STRUCT_STAT st; + struct utimbuf tb; + time_t current; + + if (default_vfs_ops.stat(conn,fname,&st) != 0) { + DEBUG(0,("stat for %s returned %s\n",fname,strerror(errno))); + return; + } + current = time(¤t); + tb.actime = current; + tb.modtime = st.st_mtime; + + if (default_vfs_ops.utime(conn, fname, &tb) == -1 ) + DEBUG(0, ("Touching %s failed, reason = %s\n",fname,strerror(errno))); + } + +/** + * Check if file should be recycled + **/ +static int recycle_unlink(connection_struct *conn, const char *inname) +{ + pstring fname,fpath, bin; + char *base, *ext; + int i=1, len, addlen; + SMB_BIG_UINT dfree,dsize,bsize; + SMB_OFF_T fsize,space_avail; + BOOL exist; + int rc; + + pstrcpy(fname,inname); + if (conn->vfs_private) + current = (recycle_bin_struct *)conn->vfs_private; + else { + DEBUG(0,("Recycle bin not initialized!\n")); + return default_vfs_ops.unlink(conn,fname); + } + + if(!current->recycle_bin || !*(current->recycle_bin)) { + DEBUG(3, ("Recycle path not set, purging %s...\n", fname)); + return default_vfs_ops.unlink(conn,fname); + } + + /* we don't recycle the recycle bin... */ + if (strstr(fname,current->recycle_bin)==fname) { + DEBUG(3, ("File is within recycling bin\n")); + return default_vfs_ops.unlink(conn,fname); + } + + fsize = recycle_get_file_size(conn,fname); + if(fsize == 0) { + DEBUG(3, ("File %s is empty, purging...\n", fname)); + return default_vfs_ops.unlink(conn,fname); + } + + if(current->max_size > 0 && fsize > current->max_size) { + DEBUG(3, ("File %s exceeds maximum recycle size, purging... \n", fname)); + return default_vfs_ops.unlink(conn,fname); + } + + space_avail = default_vfs_ops.disk_free(conn,".",True,&bsize,&dfree,&dsize)*1024L; + DEBUG(10,("space_avail = %Lu, fsize = %Lu\n",space_avail,fsize)); + if(space_avail < fsize) { + DEBUG(3, ("Not enough diskspace, purging file %s\n",fname)); + return default_vfs_ops.unlink(conn,fname); + } + + /* extract filename and path */ + pstrcpy(fpath,"/"); + pstrcat(fpath, fname); + base = strrchr(fpath, '/'); + if (base == NULL) { + ext = strrchr(fname, '.'); + base = (char *)fname; + pstrcpy(fpath,"/"); + } + else { + ext = strrchr(base, '.'); + *(base++) = '\0'; + } + + DEBUG(10, ("fname:%s\n", fname)); /* original filename with path */ + DEBUG(10, ("fpath:%s\n", fpath)); /* original path */ + DEBUG(10, ("base:%s\n", base)); /* filename without path */ + DEBUG(10, ("ext:%s\n", ext)); /* filename extension */ + + if (matchparam(current->exclude,base)) { + DEBUG(3, ("file %s is excluded \n",base)); + return default_vfs_ops.unlink(conn,fname); + } + + if (checkparam(current->exclude_dir,fpath)) { + DEBUG(3, ("directory %s is excluded \n",fpath)); + return default_vfs_ops.unlink(conn,fname); + } + + pstrcpy(bin, current->recycle_bin); + + /* see if we need to recreate the original directory structure in the recycle bin */ + if (current->keep_directories == True) + pstrcat(bin, fpath); + + exist=recycle_directory_exist(conn,bin); + if (exist) + DEBUG(10, ("Directory already exists\n")); + else { + DEBUG(10, ("Creating directory %s\n",bin)); + rc=recycle_create_dir(conn,bin); + if (rc == False) + { + DEBUG(3, ("Could not create directory, purging %s...\n", fname)); + return default_vfs_ops.unlink(conn,fname); + } + } + + pstrcat(bin, "/"); + pstrcat(bin,base); + DEBUG(10, ("bin:%s\n", bin)); /* new filename with path */ + + /* check if we should delete file from recycle bin */ + if (recycle_file_exist(conn,bin)) { + if (current->versions == False || matchparam(current->noversions,base) == True) { + DEBUG(3, ("Removing old file %s from recycle bin\n",bin)); + default_vfs_ops.unlink(conn,bin); + } + } + + /* rename file we move to recycle bin */ + len = strlen(bin); + addlen = sizeof(pstring)-len-1; + while(recycle_file_exist(conn,bin)) { + slprintf(bin+len, addlen, " (Copy #%d)", i++); + pstrcat(bin, ext); + } + + DEBUG(10, ("Moving source=%s to dest=%s\n", fname, bin)); + rc = default_vfs_ops.rename(conn, fname, bin); + if (rc == -1) { + DEBUG(3, ("Move error %d (%s), purging file %s (%s)\n", errno, strerror(errno),fname,bin)); + return default_vfs_ops.unlink(conn,fname); + } + + /* touch access date of moved file */ + if (current->touch == True ) + recycle_touch(conn,bin); + return rc; +} diff --git a/examples/VFS/recycle/recycle.conf b/examples/VFS/recycle/recycle.conf new file mode 100644 index 00000000000..00cc7982124 --- /dev/null +++ b/examples/VFS/recycle/recycle.conf @@ -0,0 +1,17 @@ +# name of the recycle bin at root level of share +name = .recycle +# mode : +# KEEP_DIRECTORIES = retain directory hierarchy of deleted file, +# i.e. recreate all directories in recycle bin +# VERSIONS = create copies in case of identical file names in recycle bin +# TOUCH = touch access date of files moved into the recycle bin +mode = KEEP_DIRECTORIES|VERSIONS|TOUCH +# maximum file size to be moved to the recycle bin (0 means any size) +maxsize = 0 +# exclude file names with the following extensions: +exclude = *.tmp|*.temp|*.o|*.obj|~$* +# exclude directories: +excludedir = /tmp|/temp|/cache +# Add file extensions of files where no versioning is wanted (i.e. copy # 1...) +# only valid when mode=VERSIONS is set +noversions = *.doc|*.xls|*.ppt diff --git a/examples/libsmbclient/testsmbc.c b/examples/libsmbclient/testsmbc.c index f67c91073c6..7aae9d85616 100644 --- a/examples/libsmbclient/testsmbc.c +++ b/examples/libsmbclient/testsmbc.c @@ -95,10 +95,74 @@ int main(int argc, char *argv[]) if (argc > 1) { - if ((dh1 = smbc_opendir(argv[1]))<1) { + /* Try to list the print jobs ... */ - fprintf(stderr, "Could not open directory: %s: %s\n", - argv[1], strerror(errno)); + if (smbc_list_print_jobs("smb://samba/pclp", print_list_fn) < 0) { + + fprintf(stderr, "Could not list print jobs: %s, %d\n", strerror(errno), errno); + exit(1); + + } + + /* Try to delete the last job listed */ + + if (global_id > 0) { + + fprintf(stdout, "Trying to delete print job %u\n", global_id); + + if (smbc_unlink_print_job("smb://samba/pclp", global_id) < 0) { + + fprintf(stderr, "Failed to unlink job id %u, %s, %u\n", global_id, + strerror(errno), errno); + + exit(1); + + } + + } + + /* Try to print a file ... */ + + if (smbc_print_file("smb://samba/public/testfile2.txt", "smb://samba/pclp") < 0) { + + fprintf(stderr, "Failed to print job: %s %u\n", strerror(errno), errno); + exit(1); + + } + + /* Try to delete argv[1] as a file ... */ + + if (smbc_unlink(argv[1]) < 0) { + + fprintf(stderr, "Could not unlink: %s, %s, %d\n", + argv[1], strerror(errno), errno); + + exit(0); + + } + + if ((dh1 = smbc_opendir("smb://"))<1) { + + fprintf(stderr, "Could not open directory: smb://: %s\n", + strerror(errno)); + + exit(1); + + } + + if ((dh2 = smbc_opendir("smb://sambanet")) < 0) { + + fprintf(stderr, "Could not open directory: smb://sambanet: %s\n", + strerror(errno)); + + exit(1); + + } + + if ((dh3 = smbc_opendir("smb://samba")) < 0) { + + fprintf(stderr, "Could not open directory: smb://samba: %s\n", + strerror(errno)); exit(1); @@ -139,6 +203,62 @@ int main(int argc, char *argv[]) dirp = (char *)dirbuf; + if ((dirc = smbc_getdents(dh2, (struct smbc_dirent *)dirp, + sizeof(dirbuf))) < 0) { + + fprintf(stderr, "Problems getting directory entries: %s\n", + strerror(errno)); + + exit(1); + + } + + /* Now, process the list of names ... */ + + fprintf(stdout, "\nDirectory listing, size = %u\n", dirc); + + while (dirc > 0) { + + dsize = ((struct smbc_dirent *)dirp)->dirlen; + fprintf(stdout, "Dir Ent, Type: %u, Name: %s, Comment: %s\n", + ((struct smbc_dirent *)dirp)->smbc_type, + ((struct smbc_dirent *)dirp)->name, + ((struct smbc_dirent *)dirp)->comment); + + dirp += dsize; + (char *)dirc -= dsize; + + } + + dirp = (char *)dirbuf; + + if ((dirc = smbc_getdents(dh3, (struct smbc_dirent *)dirp, + sizeof(dirbuf))) < 0) { + + fprintf(stderr, "Problems getting directory entries: %s\n", + strerror(errno)); + + exit(1); + + } + + /* Now, process the list of names ... */ + + fprintf(stdout, "Directory listing, size = %u\n", dirc); + + while (dirc > 0) { + + dsize = ((struct smbc_dirent *)dirp)->dirlen; + fprintf(stdout, "\nDir Ent, Type: %u, Name: %s, Comment: %s\n", + ((struct smbc_dirent *)dirp)->smbc_type, + ((struct smbc_dirent *)dirp)->name, + ((struct smbc_dirent *)dirp)->comment); + + (char *)dirp += dsize; + (char *)dirc -= dsize; + + } + exit(1); } diff --git a/examples/smb.conf.default b/examples/smb.conf.default index 72925cdcb92..90737b37b51 100644 --- a/examples/smb.conf.default +++ b/examples/smb.conf.default @@ -3,158 +3,247 @@ # here. Samba has a huge number of configurable options (perhaps too # many!) most of which are not shown in this example # -# Any line which starts with a ; (semi-colon) or a # (hash) +# Any line which starts with a ; (semi-colon) or a # (hash) # is a comment and is ignored. In this example we will use a # # for commentry and a ; for parts of the config file that you # may wish to enable # # NOTE: Whenever you modify this file you should run the command "testparm" -# to check that you have not many any basic syntactic errors. +# to check that you have not many any basic syntactic errors. # #======================= Global Settings ===================================== [global] -# workgroup = NT-Domain-Name or Workgroup-Name, eg: REDHAT4 - workgroup = MYGROUP - -# server string is the equivalent of the NT Description field - server string = Samba Server - -# This option is important for security. It allows you to restrict -# connections to machines which are on your local network. The -# following example restricts access to two C class networks and -# the "loopback" interface. For more examples of the syntax see -# the smb.conf man page -; hosts allow = 192.168.1. 192.168.2. 127. - -# If you want to automatically load your printer list rather -# than setting them up individually then you'll need this - load printers = yes - -# you may wish to override the location of the printcap file -; printcap name = /etc/printcap - -# on SystemV system setting printcap name to lpstat should allow -# you to automatically obtain a printer list from the SystemV spool -# system -; printcap name = lpstat - -# It should not be necessary to specify the print system type unless -# it is non-standard. Currently supported print systems include: -# bsd, sysv, plp, lprng, aix, hpux, qnx -; printing = bsd - -# Uncomment this if you want a guest account, you must add this to /etc/passwd -# otherwise the user "nobody" is used -; guest account = pcguest - -# this tells Samba to use a separate log file for each machine -# that connects - log file = /usr/local/samba/var/log.%m - -# Put a capping on the size of the log files (in Kb). - max log size = 50 - -# Security mode. Most people will want user level security. See -# security_level.txt for details. - security = user - -# Use password server option only with security = server -# The argument list may include: -# password server = My_PDC_Name [My_BDC_Name] [My_Next_BDC_Name] -# or to auto-locate the domain controller/s -# password server = * -; password server = - -# Note: Do NOT use the now deprecated option of "domain controller" -# This option is no longer implemented. - -# You may wish to use password encryption. Please read -# ENCRYPTION.txt, Win95.txt and WinNT.txt in the Samba documentation. -# Do not enable this option unless you have read those documents -; encrypt passwords = yes - -# Using the following line enables you to customise your configuration -# on a per machine basis. The %m gets replaced with the netbios name -# of the machine that is connecting -; include = /usr/local/samba/lib/smb.conf.%m - -# Most people will find that this option gives better performance. -# See speed.txt and the manual pages for details -# You may want to add the following on a Linux system: -# SO_RCVBUF=8192 SO_SNDBUF=8192 - socket options = TCP_NODELAY - -# Configure Samba to use multiple interfaces -# If you have multiple network interfaces then you must list them -# here. See the man page for details. -; interfaces = 192.168.12.2/24 192.168.13.2/24 - -# Browser Control Options: -# set local master to no if you don't want Samba to become a master -# browser on your network. Otherwise the normal election rules apply -; local master = no - -# OS Level determines the precedence of this server in master browser -# elections. The default value should be reasonable -; os level = 33 - -# Domain Master specifies Samba to be the Domain Master Browser. This -# allows Samba to collate browse lists between subnets. Don't use this -# if you already have a Windows NT domain controller doing this job -; domain master = yes - -# Preferred Master causes Samba to force a local browser election on startup -# and gives it a slightly higher chance of winning the election -; preferred master = yes - -# Enable this if you want Samba to be a domain logon server for -# Windows95 workstations. -; domain logons = yes - -# if you enable domain logons then you may want a per-machine or -# per user logon script -# run a specific logon batch file per workstation (machine) -; logon script = %m.bat -# run a specific logon batch file per username -; logon script = %U.bat - -# Where to store roving profiles (only for Win95 and WinNT) -# %L substitutes for this servers netbios name, %U is username -# You must uncomment the [Profiles] share below -; logon path = \\%L\Profiles\%U - -# Windows Internet Name Serving Support Section: -# WINS Support - Tells the NMBD component of Samba to enable it's WINS Server -; wins support = yes - -# WINS Server - Tells the NMBD components of Samba to be a WINS Client -# Note: Samba can be either a WINS Server, or a WINS Client, but NOT both -; wins server = w.x.y.z - -# WINS Proxy - Tells Samba to answer name resolution queries on -# behalf of a non WINS capable client, for this to work there must be -# at least one WINS Server on the network. The default is NO. -; wins proxy = yes - -# DNS Proxy - tells Samba whether or not to try to resolve NetBIOS names -# via DNS nslookups. The built-in default for versions 1.9.17 is yes, -# this has been changed in version 1.9.18 to no. - dns proxy = no +## +## Basic Server Settings +## + + # workgroup = NT-Domain-Name or Workgroup-Name, eg: REDHAT4 + workgroup = MYGROUP + + # server string is the equivalent of the NT Description field + server string = Samba Server + + # This option is important for security. It allows you to restrict + # connections to machines which are on your local network. The + # following example restricts access to two C class networks and + # the "loopback" interface. For more examples of the syntax see + # the smb.conf man page + ; hosts allow = 192.168.1. 192.168.2.0./24 192.168.3.0/255.255.255.0 127.0.0.1 + + # Uncomment this if you want a guest account, you must add this to /etc/passwd + # otherwise the user "nobody" is used + ; guest account = pcguest + + # this tells Samba to use a separate log file for each machine + # that connects + log file = /usr/local/samba/var/log.%m + + # How much information do you want to see in the logs? + # default is only to log critical messages + ; log level = 1 + + # Put a capping on the size of the log files (in Kb). + max log size = 50 + + # Security mode. Most people will want user level security. See + # security_level.txt for details. + security = user + + # Using the following line enables you to customise your configuration + # on a per machine basis. The %m gets replaced with the netbios name + # of the machine that is connecting. + # Note: Consider carefully the location in the configuration file of + # this line. The included file is read at that point. + ; include = /usr/local/samba/lib/smb.conf.%m + + # Most people will find that this option gives better performance. + # See speed.txt and the manual pages for details + # You may want to add the following on a Linux system: + # SO_RCVBUF=8192 SO_SNDBUF=8192 + ; socket options = TCP_NODELAY + + # Configure Samba to use multiple interfaces + # If you have multiple network interfaces and want to limit smbd will + # use, list the ones desired here. Otherwise smbd & nmbd will bind to all + # active interfaces on the system. See the man page for details. + ; interfaces = 192.168.12.2/24 192.168.13.2/24 + + # Should smbd report that it has MS-DFS Capabilities? Only available + # if --with-msdfs was passed to ./configure + ; host msdfs = yes + +## +## Network Browsing +## + # set local master to no if you don't want Samba to become a master + # browser on your network. Otherwise the normal election rules apply + ; local master = no + + # OS Level determines the precedence of this server in master browser + # elections. The default value (20) should be reasonable + ; os level = 20 + + # Domain Master specifies Samba to be the Domain Master Browser. This + # allows Samba to collate browse lists between subnets. Don't use this + # if you already have a Windows NT domain controller doing this job + ; domain master = yes + + # Preferred Master causes Samba to force a local browser election on startup + # and gives it a slightly higher chance of winning the election + ; preferred master = yes + + +## +## WINS & Name Resolution +## + # Windows Internet Name Serving Support Section: + # WINS Support - Tells the NMBD component of Samba to enable it's WINS Server + ; wins support = yes + + # WINS Server - Tells the NMBD components of Samba to be a WINS Client + # Note: Samba can be either a WINS Server, or a WINS Client, but NOT both + ; wins server = w.x.y.z + + # WINS Proxy - Tells Samba to answer name resolution queries on + # behalf of a non WINS capable client, for this to work there must be + # at least one WINS Server on the network. The default is NO. + ; wins proxy = yes + + # DNS Proxy - tells Samba whether or not to try to resolve NetBIOS names + # via DNS nslookups. + dns proxy = no + + +## +## Passwords & Authentication +## + # Use password server option only with security = server + # The argument list may include: + # password server = My_PDC_Name [My_BDC_Name] [My_Next_BDC_Name] + # or to auto-locate the domain controller/s + ; password server = * + ; password server = + + # You may wish to use password encryption. Please read + # ENCRYPTION.txt, Win95.txt and WinNT.txt in the Samba documentation. + # Do not enable this option unless you have read those documents + ; encrypt passwords = yes + + # Should smbd obey the session and account lines in /etc/pam.d/samba ? + # only available if --with-pam was used at compile time + ; obey pam restrictions = yes + + # When using encrypted passwords, Samba can synchronize the local + # UNIX password as well. You will also need the "passwd chat" parameters + ; unix passwword sync = yes + + # how should smbd talk to the local system when changing a UNIX + # password? See smb.conf(5) for details + ; passwd chat = + + # This is only available if you compiled Samba to include --with-pam + # Use PAM for changing the password + ; pam password change = yes + +## +## Domain Control +## + # Enable this if you want Samba act as a domain controller. + # make sure you have read the Samba-PDC-HOWTO included in the documentation + # before enabling this parameter + ; domain logons = yes + + # if you enable domain logons then you may want a per-machine or + # per user logon script + # run a specific logon batch file per workstation (machine) + ; logon script = %m.bat + # run a specific logon batch file per username + ; logon script = %U.bat + + # Where to store roving profiles (only for Win95 and WinNT) + # %L substitutes for this servers netbios name, %U is username + # You must uncomment the [Profiles] share below + ; logon path = \\%L\Profiles\%U + + # UNC path specifying the network location of the user's home directory + # only used when acting as a DC for WinNT/2k/XP. Ignored by Win9x clients + ; logon home = \\%L\%U + + # What drive should the "logon home" be mounted at upon login ? + # only used when acting as a DC for WinNT/2k/XP. Ignored by Win9x clients + ; logon drive = H: + +## +## Printing +## + + # If you want to automatically load your printer list rather + # than setting them up individually then you'll need this + load printers = yes + + # you may wish to override the location of the printcap file + ; printcap name = /etc/printcap + + # on SystemV system setting printcap name to lpstat should allow + # you to automatically obtain a printer list from the SystemV spool + # system + ; printcap name = lpstat + + # It should not be necessary to specify the print system type unless + # it is non-standard. Currently supported print systems include: + # bsd, sysv, plp, lprng, aix, hpux, qnx + ; printing = bsd + + # Enable this to make Samba 2.2 behavior just like Samba 2.0 + # not recommended nuless you are sure of what you are doing + ; disable spoolss = yes + + # list of users and groups which should be able to remotely manage + # printer drivers installed on the server + ; printer admin = root, +ntadmin + + +## +## Winbind +## + + # specify the uid range which can be used by winbindd + # to allocate uids for Windows users as necessary + ; winbind uid = 10000-65000 + + # specify the uid range which can be used by winbindd + # to allocate uids for Windows users as necessary + ; winbind gid = 10000-65000 + + # Define a home directory to be given to passwd(5) style entries + # generated by libnss_winbind.so. You can use variables here + ; winbind template homedir = /home/%D/%U + + # Specify a shell for all winbind user entries return by the + # libnss_winbind.so library. + ; winbind template shell = /bin/sh + + # What character should be used to separate the DOMAIN and Username + # for a Windows user. The default is DOMAIN\user, but many people + # prefer DOMAIN+user + ; winbind separator = + + #============================ Share Definitions ============================== [homes] - comment = Home Directories - browseable = no - writable = yes + comment = Home Directories + browseable = no + writable = yes + valid users = %S # Un-comment the following and create the netlogon directory for Domain Logons ; [netlogon] -; comment = Network Logon Service -; path = /usr/local/samba/lib/netlogon -; guest ok = yes -; writable = no -; share modes = no +; comment = Network Logon Service +; path = /usr/local/samba/lib/netlogon +; guest ok = yes +; writable = no +; share modes = no # Un-comment the following to provide a specific roving profile share @@ -165,23 +254,30 @@ ; guest ok = yes -# NOTE: If you have a BSD-style print system there is no need to +# NOTE: If you have a BSD-style print system there is no need to # specifically define each individual printer [printers] comment = All Printers path = /usr/spool/samba browseable = no -# Set public = yes to allow user 'guest account' to print + # Set public = yes to allow user 'guest account' to print guest ok = no writable = no printable = yes # This one is useful for people to share files -;[tmp] -; comment = Temporary file space -; path = /tmp -; read only = no -; public = yes +#[tmp] +# comment = Temporary file space +# path = /tmp +# read only = no +# public = yes + + +# MS-DFS support is only available if Samba was compiled to +# include --with-msdfs +;[dfsroot] +; dfs root = yes + # A publicly accessible directory, but read only, except for people in # the "staff" group @@ -193,64 +289,67 @@ ; printable = no ; write list = @staff -# Other examples. -# + +## +## Other examples. +## + # A private printer, usable only by fred. Spool data will be placed in fred's # home directory. Note that fred must have write access to the spool directory, # wherever it is. -;[fredsprn] -; comment = Fred's Printer -; valid users = fred -; path = /homes/fred -; printer = freds_printer -; public = no -; writable = no -; printable = yes +#[fredsprn] +# comment = Fred's Printer +# valid users = fred +# path = /homes/fred +# printer = freds_printer +# public = no +# writable = no +# printable = yes # A private directory, usable only by fred. Note that fred requires write # access to the directory. -;[fredsdir] -; comment = Fred's Service -; path = /usr/somewhere/private -; valid users = fred -; public = no -; writable = yes -; printable = no +#[fredsdir] +# comment = Fred's Service +# path = /usr/somewhere/private +# valid users = fred +# public = no +# writable = yes +# printable = no # a service which has a different directory for each machine that connects # this allows you to tailor configurations to incoming machines. You could # also use the %U option to tailor it by user name. # The %m gets replaced with the machine name that is connecting. -;[pchome] -; comment = PC Directories -; path = /usr/pc/%m -; public = no -; writable = yes +#[pchome] +# comment = PC Directories +# path = /usr/pc/%m +# public = no +# writable = yes # A publicly accessible directory, read/write to all users. Note that all files # created in the directory by users will be owned by the default user, so # any user with access can delete any other user's files. Obviously this # directory must be writable by the default user. Another user could of course # be specified, in which case all files would be owned by that user instead. -;[public] -; path = /usr/somewhere/else/public -; public = yes -; only guest = yes -; writable = yes -; printable = no +#[public] +# path = /usr/somewhere/else/public +# public = yes +# only guest = yes +# writable = yes +# printable = no # The following two entries demonstrate how to share a directory so that two # users can place files there that will be owned by the specific users. In this # setup, the directory should be writable by both users and should have the # sticky bit set on it to prevent abuse. Obviously this could be extended to # as many users as required. -;[myshare] -; comment = Mary's and Fred's stuff -; path = /usr/somewhere/shared -; valid users = mary fred -; public = no -; writable = yes -; printable = no -; create mask = 0765 +#[myshare] +# comment = Mary's and Fred's stuff +# path = /usr/somewhere/shared +# valid users = mary fred +# public = no +# writable = yes +# printable = no +# create mask = 0765 -- cgit