diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..cbb3a13
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,4 @@
+*.rpm
+*.log
+*spec-20*
+*.tar.gz
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..12e4178
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,21 @@
+# Makefile for source rpm: smeserver-dirty-tools
+# $Id: Makefile,v 1.1 2021/06/04 14:01:19 jpp Exp $
+NAME := smeserver-dirty-tools
+SPECFILE = $(firstword $(wildcard *.spec))
+
+define find-makefile-common
+for d in common ../common ../../common ; do if [ -f $$d/Makefile.common ] ; then if [ -f $$d/CVS/Root -a -w $$/Makefile.common ] ; then cd $$d ; cvs -Q update ; fi ; echo "$$d/Makefile.common" ; break ; fi ; done
+endef
+
+MAKEFILE_COMMON := $(shell $(find-makefile-common))
+
+ifeq ($(MAKEFILE_COMMON),)
+# attept a checkout
+define checkout-makefile-common
+test -f CVS/Root && { cvs -Q -d $$(cat CVS/Root) checkout common && echo "common/Makefile.common" ; } || { echo "ERROR: I can't figure out how to checkout the 'common' module." ; exit -1 ; } >&2
+endef
+
+MAKEFILE_COMMON := $(shell $(checkout-makefile-common))
+endif
+
+include $(MAKEFILE_COMMON)
diff --git a/README.md b/README.md
index 48dcea5..d033357 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,15 @@
-# smeserver-dirty-tools
+# smeserver-dirty-tools
-SMEServer Koozali developed git repo for smeserver-dirty-tools smecontribs
\ No newline at end of file
+SMEServer Koozali developed git repo for smeserver-dirty-tools smecontribs
+
+## Wiki
+
https://wiki.koozali.org/
+
+## Bugzilla
+Show list of outstanding bugs: [here](https://bugs.koozali.org/buglist.cgi?component=smeserver-dirty-tools&product=SME%20Contribs&query_format=advanced&limit=0&bug_status=UNCONFIRMED&bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED&bug_status=CONFIRMED)
+
+## Description
+
+
*This description has been generated by an LLM AI system and cannot be relied on to be fully correct.*
+*Once it has been checked, then this comment will be deleted*
+
diff --git a/contriborbase b/contriborbase
new file mode 100644
index 0000000..9b7fd51
--- /dev/null
+++ b/contriborbase
@@ -0,0 +1 @@
+contribs10
diff --git a/root/sbin/e-smith/dt-data-copy b/root/sbin/e-smith/dt-data-copy
new file mode 120000
index 0000000..a3e752a
--- /dev/null
+++ b/root/sbin/e-smith/dt-data-copy
@@ -0,0 +1 @@
+dt-data-sync
\ No newline at end of file
diff --git a/root/sbin/e-smith/dt-data-sync b/root/sbin/e-smith/dt-data-sync
new file mode 100755
index 0000000..08c7baa
--- /dev/null
+++ b/root/sbin/e-smith/dt-data-sync
@@ -0,0 +1,113 @@
+#!/usr/bin/perl
+# (C) 2007 Michael Weinberger
+# See http://wiki.contribs.org/Dirty_Tools for full documentation
+
+use Getopt::Long;
+my %opts;
+my $getRes = GetOptions(
+ "dry-run"=>\$opts{'dry-run'},
+ "ibay"=>\$opts{'ibay'},
+ "compress"=>\$opts{'compress'},
+ "copy"=>\$opts{'copy'},
+);
+
+( my $myself = $0) =~ s/.*\///;
+$opts{'copy'} = ($myself eq 'dt-data-copy' or $opts{'copy'}) ? 1 : 0;
+
+die "Usage: dt-data-sync [--dry-run] [--compress] [--ibay] source_server account|ibay\n dt-data-copy [--dry-run] [--compress] [--ibay] source_server account|ibay\n" if( not $ARGV[1] ) ;
+$server=$ARGV[0];
+$source=$ARGV[1];
+$dryrun= $opts{'dry-run'} ? 1 : 0;
+
+
+$exit=0;
+
+if( $opts{'ibay'} )
+ {
+ $datapath="/home/e-smith/files/ibays/$source";
+ $b=`/sbin/e-smith/db accounts show|grep '=ibay\$'|/bin/sed 's/=.*//'`;
+ chomp($b);
+ @ibays=split( /\n/, $b );
+
+ $b=`/usr/bin/ssh $server /sbin/e-smith/db accounts show|/bin/grep '=ibay\$'|/bin/sed 's/=.*//'`;
+ chomp($b);
+ @remote_ibays=split( /\n/, $b );
+
+ printf "Ibay %s %s\n", $source, $dryrun ? "(dry run)" : "";
+
+ @b= grep( /^$source$/, @ibays);
+ if( not $b[0] )
+ {
+ print "Error: Ibay does not exist local\n";
+ $exit=1;
+ }
+ @b= grep( /^$source$/, @remote_ibays);
+ if( not $b[0] )
+ {
+ print "Error: Ibay does not exist remote\n";
+ $exit=1;
+ }
+
+ if( not -d $datapath )
+ {
+ print "Error: local ibay dir does not exist\n";
+ $exit=1;
+ }
+
+ if( system( "/usr/bin/ssh $server test -d $datapath" ) )
+ {
+ print "Error: remote ibay dir does not exist\n";
+ $exit=1;
+ }
+
+ }
+else
+ {
+ $datapath="/home/e-smith/files/users/$source";
+
+ $u=`/sbin/e-smith/db accounts show|/bin/grep '=user\$'|/bin/sed 's/=.*//'`;
+ chomp($u);
+ @users=split( /\n/, $u );
+
+ $u=`/usr/bin/ssh $server /sbin/e-smith/db accounts show|/bin/grep '=user\$'|/bin/sed 's/=.*//'`;
+ chomp($u);
+ @remote_users=split( /\n/, $u );
+
+ printf "Account %s %s\n", $source, $dryrun ? "(dry run)" : "";
+
+ @u= grep( /^$source$/, @users);
+ if( not $u[0] )
+ {
+ print "Error: Account does not exist local\n";
+ $exit=1;
+ }
+ @u= grep( /^$source$/, @remote_users);
+ if( not $u[0] )
+ {
+ print "Error: Account does not exist remote\n";
+ $exit=1;
+ }
+
+ if( not -d $datapath )
+ {
+ print "Error: local home dir does not exist\n";
+ $exit=1;
+ }
+
+ if( system( "/usr/bin/ssh $server test -d $datapath" ) )
+ {
+ print "Error: remote home dir does not exist\n";
+ $exit=1;
+ }
+ }
+
+
+if( not $exit )
+ {
+ $rync_copy=$opts{'copy'}?"--update":"--delete-during";
+ $rsync_dry=$dryrun ? "--dry-run" : "";
+ $rsync_compress=$opts{'compress'} ? "--compress" : "";
+ system( "/usr/bin/rsync $rsync_dry -av $rync_copy $rsync_compress --rsh='/usr/bin/ssh -o StrictHostKeyChecking=yes' $server:$datapath/ $datapath/" );
+ print "Ok.\n";
+ }
+
diff --git a/root/sbin/e-smith/dt-dovecot-indexfiles-delete b/root/sbin/e-smith/dt-dovecot-indexfiles-delete
new file mode 100755
index 0000000..5cdcab9
--- /dev/null
+++ b/root/sbin/e-smith/dt-dovecot-indexfiles-delete
@@ -0,0 +1,23 @@
+#!/bin/bash
+# (C) 2008 Michael Weinberger
+# See http://wiki.contribs.org/Dirty_Tools for full documentation
+
+# Sometimes Dovecot index files are corrupted after a restore
+# It is save to delete them all. Dovecot will rebuild them when the mailbox is accessed.
+
+echo "Deleting Dovecot's index files";
+
+# Find users - also finds /home/e-smith/files/users
+USERS=`/usr/bin/find /home/e-smith/files/users -maxdepth 1 -type d`
+
+# Add Admin dir
+USERS="/home/e-smith/ $USERS" # admin
+
+for u in $USERS; do
+# Ignore dirs without Maildir
+ ! /usr/bin/test -d $u/Maildir && continue
+ /usr/bin/find $u/Maildir -maxdepth 2 -type f -name "dovecot.index*" -exec /bin/rm -f '{}' \;
+ /usr/bin/find $u/Maildir -maxdepth 2 -type f -name ".imap.index*" -exec /bin/rm -f '{}' \;
+done
+
+echo "Completed";
diff --git a/root/sbin/e-smith/dt-lock-account b/root/sbin/e-smith/dt-lock-account
new file mode 100755
index 0000000..ee286e1
--- /dev/null
+++ b/root/sbin/e-smith/dt-lock-account
@@ -0,0 +1,55 @@
+#!/usr/bin/perl
+# (C) 2007 Michael Weinberger
+# See http://wiki.contribs.org/Dirty_Tools for full documentation
+
+use strict;
+use esmith::AccountsDB;
+use Getopt::Long;
+
+
+my %opts;
+my $getRes = GetOptions(
+ "unlock"=>\$opts{'unlock'},
+);
+
+( my $myself = $0) =~ s/.*\///;
+$opts{'unlock'} = ($myself eq 'dt-unlock-account' or $opts{'unlock'}) ? 1 : 0;
+
+my $account=$ARGV[0];
+
+die "Usage: dt-lock-account account\n dt-unlock-account account\n" if not $account;
+
+if( $account eq 'admin' )
+ {
+ print "not applicable to account 'admin'\n"; exit -1;
+ }
+
+my $accountdb = esmith::AccountsDB->open or die "Could not open account db";
+
+my $acct = $accountdb->get($account);
+
+
+if (not $acct or $acct->prop('type') ne "user")
+ {
+ print "User '$account' does not exist.\n";
+ exit -1;
+ }
+
+if( $opts{'unlock'} )
+ {
+ my $status=system("/usr/bin/passwd", "-u", $account)>>8;
+ if( $status==254 )
+ {
+ print "Account $account has never been assigned a password. Cannot unlock.\n";
+ exit -1;
+ }
+ die "Error running /usr/bin/passwd command to unlock account $account" if $status>0 and $status!=254;
+ system("/usr/bin/smbpasswd", "-e", $account) == 0
+ or die "Error running /usr/bin/smbpasswd command to unlock account $account";
+ $acct->set_prop('PasswordSet', 'yes');
+ }
+else
+ {
+ not system("/sbin/e-smith/signal-event", "user-lock", $account)
+ or die "Error occurred while locking account '$account'";
+ }
diff --git a/root/sbin/e-smith/dt-passwords-sync b/root/sbin/e-smith/dt-passwords-sync
new file mode 100755
index 0000000..1eb1b0b
--- /dev/null
+++ b/root/sbin/e-smith/dt-passwords-sync
@@ -0,0 +1,154 @@
+#!/usr/bin/perl
+# (C) 2007 Michael Weinberger
+# See http://wiki.contribs.org/Dirty_Tools for full documentation
+
+use Getopt::Long;
+my %opts;
+my $getRes = GetOptions(
+ "dry-run"=>\$opts{'dry-run'},
+ "ibays"=>\$opts{'ibays'},
+ "all"=>\$opts{'all'},
+);
+
+
+if( ($opts{'all'} and not $ARGV[0]) or (not $opts{'all'} and not $ARGV[1]) )
+ {
+ die "Usage: dt-passwords-sync [--dry-run] [--ibays] [--all] SOURESERVER [ACCOUNT]\n"
+ }
+$server=$ARGV[0];
+$dryrun= $opts{'dry-run'};
+
+if( $opts{'all'} )
+ {
+ $type=$opts{'ibays'} ? "ibay" : "user";
+ $u=`/sbin/e-smith/db accounts show|grep '=$type\$'|/bin/sed 's/=.*//'`;
+ chomp($u);
+ @users=split( /\n/, $u );
+ }
+else
+ {
+ @users=($ARGV[1]);
+ }
+
+# shadow
+$res = `ssh $server /bin/cat /etc/shadow`;
+@shadow=split(/\n/, $res );
+
+# smbpasswd
+if( not $opts{'ibays'} )
+ {
+ $res = `ssh $server /bin/cat /etc/samba/smbpasswd`;
+ @smbpasswd=split(/\n/, $res );
+ }
+
+
+for( $i=0; $i<@users; $i++ )
+ {
+ $done=0;
+ $account=$users[$i];
+ printf '%-10s: %s', $account, $dryrun ? "(dryrun) " : "";
+
+ # shadow
+ @u= grep( /^$account:/, @shadow);
+ $res=$u[0];
+ chomp($res);
+ if( not $res )
+ {
+ print "does not exist.\n";
+ next;
+ }
+ @pe = split( /:/, $res );
+ $upw=$pe[1];
+ $pwset = $upw =~ /^\!\!/ ? 0 : 1;
+ open( IN, "/etc/shadow" );
+ open( OUT, ">/etc/shadow.pwsync" );
+ while( )
+ {
+ chomp($_);
+ @e=split( /:/, $_ );
+ if( $e[0] eq $account and $e[1] ne $upw)
+ {
+ print "shadow synced. ";
+ $e[1]=$upw;
+ for( $k=0; $k<9; $k++ )
+ {
+ print OUT ':' if $k>0;
+ print OUT $e[$k];
+ }
+ print OUT "\n";
+ $done=1;
+ }
+ else
+ {
+ print OUT "$_\n";;
+ }
+ }
+ close( OUT );
+ close( IN );
+
+ if( not $opts{'ibays'} )
+ {
+ # smbpasswd
+ @u= grep( /^$account:/, @smbpasswd);
+ $res=$u[0];
+ chomp($res);
+ @pe = split( /:/, $res );
+ $lanman_hash=$pe[2];
+ $nt_hash=$pe[3];
+ $flags=$pe[4];
+ $lct=$pe[5];
+ $smb_pwset = $flags =~ /D/ ? 0 : 1;
+ open( IN, "/etc/samba/smbpasswd" );
+ open( OUT, ">/etc/samba/smbpasswd.pwsync" );
+ while( )
+ {
+ chomp($_);
+ @e=split( /:/, $_ );
+ if( $e[0] eq $account and ( $e[2] ne $lanman_hash or $e[3] ne $nt_hash or $flags ne $e[4] or $lct ne $e[5] ) )
+ {
+ print "smbpasswd synced. ";
+ $e[2]=$lanman_hash;
+ $e[3]=$nt_hash;
+ $e[4]=$flags;
+ $e[5]=$lct;
+ for( $k=0; $k<7; $k++ )
+ {
+ print OUT ':' if $k>0;
+ print OUT $e[$k];
+ }
+ print OUT "\n";
+ $done=1;
+ }
+ else
+ {
+ print OUT "$_\n";;
+ }
+ }
+ close( OUT );
+ close( IN );
+ }
+
+ if( not $dryrun )
+ {
+ if( not $opts{'ibays'} )
+ {
+ system( "/bin/chmod --reference /etc/samba/smbpasswd /etc/samba/smbpasswd.pwsync" );
+ system( "/bin/chown --reference /etc/samba/smbpasswd /etc/samba/smbpasswd.pwsync" );
+ system( "/bin/mv -f /etc/samba/smbpasswd.pwsync /etc/samba/smbpasswd" );
+ }
+ system( "/bin/chmod --reference /etc/shadow /etc/shadow.pwsync" );
+ system( "/bin/chown --reference /etc/shadow /etc/shadow.pwsync" );
+ system( "/bin/mv -f /etc/shadow.pwsync /etc/shadow" );
+ system( "/sbin/e-smith/db accounts setprop $account PasswordSet " . ( ($pwset and ($smb_pwset or $opts{'ibays'})) ? 'yes' : 'no' ));
+
+ }
+ if( $done )
+ {
+ print "ok.";
+ }
+ else
+ {
+ print "nothing to be done.";
+ }
+ print "\n";
+ }
diff --git a/root/sbin/e-smith/dt-pw-generate b/root/sbin/e-smith/dt-pw-generate
new file mode 100755
index 0000000..e79c3f3
--- /dev/null
+++ b/root/sbin/e-smith/dt-pw-generate
@@ -0,0 +1,35 @@
+#!/usr/bin/perl
+
+# (C) 2005-2008 Michael Weinberger
+# See http://wiki.contribs.org/Dirty_Tools for full documentation
+
+use strict;
+use esmith::ConfigDB;
+use esmith::FormMagick;
+use esmith::PasswordTools;
+use Getopt::Long;
+
+my %opts;
+my $getRes = GetOptions(
+ "number=s"=>\$opts{'number'},
+ "length=s"=>\$opts{'length'},
+ "mixed-case"=>\$opts{'mixed-case'},
+ "add-consonants"=>\$opts{'add-consonants'},
+ "help"=>\$opts{'help'},
+);
+
+if( $opts{'help'} )
+ {
+ print "Usage: dt-pw-generate [--length=N] [--mixed-case] [--add-consonants]\n";
+ exit 0;
+ }
+
+for(my $i=0; $i<($opts{'number'}?$opts{'number'}:1); $i++)
+ {
+ my $pw=sme_generate_password(
+ $opts{'length'} ? $opts{'length'} : 8,
+ $opts{'add-consonants'} ? 'yes' : 'no',
+ $opts{'mixed-case'} ? 'yes' : 'no',
+ );
+ print "$pw\n";
+ }
diff --git a/root/sbin/e-smith/dt-rename-account b/root/sbin/e-smith/dt-rename-account
new file mode 100755
index 0000000..45bf93c
--- /dev/null
+++ b/root/sbin/e-smith/dt-rename-account
@@ -0,0 +1,140 @@
+#!/usr/bin/perl
+
+# (C) 2007 Michael Weinberger
+# See http://wiki.contribs.org/Dirty_Tools for full documentation
+
+
+# WARNING:
+# In general renaming unix accounts is not a good idea.
+# There may be programs that use the username instead of the uid.
+# However, there are situations where you must do it.
+#
+# The script does the following:
+# 1) checks the new account name for maximum length and bad characters
+# 2) renames the account record key in the accounts database
+# 3) renames all occurrences of account name in pseudonym und group records in the accounts database
+# 4) renames the account in /etc/samba/smbpasswd
+# 5) renames the account in /etc/passwd and /etc/shadow
+# 6) renames the account in /etc/group
+# 7) renames the home directory
+
+# Usage: dt-rename-account account newaccount
+
+
+use Errno;
+use esmith::config;
+use esmith::util;
+use esmith::db;
+tie my %accounts, 'esmith::config', '/home/e-smith/db/accounts';
+tie my %conf, 'esmith::config', '/home/e-smith/db/configuration';
+
+my $release=esmith::util::determineRelease();
+$release =~ s/([0-9]+).*/$1/;
+
+$old=$ARGV[0];
+$new=$ARGV[1];
+
+die "Usage: dt-rename-account account newaccount\n" if( not $ARGV[0] or not $ARGV[1] ) ;
+
+# Länge des Kontennamens
+my $maxAcctNameLength = defined $conf{'maxAcctNameLength'} ? $conf{'maxAcctNameLength'} : 12;
+if ( length $new > $maxAcctNameLength )
+ {
+ print "Error: New account name $new is longer than '$maxAcctNameLength characters'\n";
+ exit 1;
+ }
+
+# bad character test
+if ( $new =~ /^\s*([a-z][a-zA-Z0-9\'\-\s]+?)\s*$/ )
+ {
+ $new = $1;
+ }
+else
+ {
+ print "Error: New account name $new contains bad characters'\n";
+ exit 1;
+ }
+
+($type, %properties) = db_get(\%accounts, $new);
+if( $type )
+ {
+ print "Error: account $new already exists.\n";
+ exit 1;
+ }
+
+
+if( $old ne $new )
+ {
+ ($type, %properties) = db_get(\%accounts, $old);
+ if( $type eq "user" )
+ {
+ # Rename Account Key
+ $raw_value = db_get(\%accounts, $old);
+ $success = db_set(\%accounts, $new, $raw_value);
+ if( $success )
+ {
+ db_delete( \%accounts, $old );
+ print "Account $old renamed to $new.\n";
+ }
+ else
+ {
+ print "Error while creating account $new\n";
+ }
+
+ # Rename Account in pseudonyms
+ @keys = db_get(\%accounts);
+ for( $i=0; $i<@keys; $i++ )
+ {
+ $type = db_get_type(\%accounts, $keys[$i]);
+ if( $type eq "pseudonym" )
+ {
+ %properties = db_get_prop(\%accounts, $keys[$i]);
+ if( $properties{'Account'} eq $old )
+ {
+ $success = db_set_prop(\%accounts, $keys[$i], "Account" => $new)
+ }
+ }
+ elsif( $type eq "group" )
+ {
+ $members = db_get_prop(\%accounts, $keys[$i], "Members");
+ @m = split( /,/, $members );
+ for( $k=0; $k<@m; $k++ )
+ {
+ $m[$k] = $new if( $m[$k] eq $old );
+ }
+ $members = join( ",", @m );
+ $success = db_set_prop(\%accounts, $keys[$i], "Members" => $members );
+ }
+ }
+
+ # Rename account in /etc/samba/smbpasswd
+ system( "/bin/cp /etc/samba/smbpasswd /etc/samba/smbpasswd.$old" );
+ system( "/bin/sed -e 's/^$old:/$new:/' < /etc/samba/smbpasswd > /etc/samba/smbpasswd.$new" );
+ system( "/bin/cp /etc/samba/smbpasswd.$new /etc/samba/smbpasswd" );
+ system( "/bin/chown admin.root /etc/samba/smbpasswd" );
+ system( "/bin/chmod 600 /etc/samba/smbpasswd" );
+
+ # Rename Unix accounts
+ system( "/usr/sbin/usermod", "-l", "$new", "$old" );
+ system( "/usr/sbin/groupmod", "-n", "$new", "$old" );
+
+ # Rename home directory in /etc/passwd
+ system( "/bin/cp /etc/passwd /etc/passwd.$old" );
+ system( "/bin/sed -e 's;:/home/e-smith/files/users/$old:;:/home/e-smith/files/users/$new:;' < /etc/passwd > /etc/passwd.$new" );
+ system( "/bin/cp /etc/passwd.$new /etc/passwd" );
+ system( "/bin/chown admin.root /etc/passwd" );
+ system( "/bin/chmod 644 /etc/passwd" );
+
+ # Update LDAP attributes dn, uid, mail, calFBURL
+ system("/etc/e-smith/events/actions/ldap-delete user-delete $old");
+ system("/etc/e-smith/events/actions/ldap-update user-create $new");
+
+ # Rename Home
+ system( "/bin/mv /home/e-smith/files/users/$old /home/e-smith/files/users/$new" );
+ }
+ else
+ {
+ die "Error: $old is not a valid account.\n";
+ }
+ }
+
diff --git a/root/sbin/e-smith/dt-send-key b/root/sbin/e-smith/dt-send-key
new file mode 100755
index 0000000..3ff4d6c
--- /dev/null
+++ b/root/sbin/e-smith/dt-send-key
@@ -0,0 +1,133 @@
+#!/usr/bin/perl -w
+
+# Michael Weinberger, neddix 2007
+# See http://wiki.contribs.org/Dirty_Tools for full documentation
+
+use strict;
+use Getopt::Long;
+
+my %opts;
+my $getRes = GetOptions(
+ "revoke"=>\$opts{'revoke'},
+ "port=s"=>\$opts{'keys-port'},
+);
+
+die "Usage: dt-send-key [--revoke] [--port=PORT] remotehost\n" if( not $ARGV[0] ) ;
+
+my $ExecCmdOutout='';
+
+my $remotehost=$ARGV[0];
+my $port=$opts{'keys-port'} ? $opts{'keys-port'} : 22;
+
+sub trim($)
+ {
+ my $s=shift;
+ $s=~s/^\s+//;
+ $s=~s/\s+$//;
+ return $s;
+ }
+
+sub ExecCmd( \@$ )
+ {
+ (my $cmdRef, my $forcelog) = @_;
+ my @cmd = @$cmdRef;
+ my $pipestatus='';
+ die "Fork failed: $!\n" unless defined( my $pid=open(RCHILD, "-|"));
+ if( $pid )
+ {
+ $ExecCmdOutout='';
+ while()
+ {
+ chomp( $_ );
+ next if $_ eq '';
+ $ExecCmdOutout.="$_\n";
+ $pipestatus=$_;
+ }
+ close( RCHILD );
+ }
+ else
+ {
+ exec( "@cmd 2>&1; echo \${PIPESTATUS}" ) or die "exec failed: $!\n";
+ }
+ $ExecCmdOutout =~ s/$pipestatus\n$//;
+ $pipestatus = $? if not $pipestatus;
+ return $pipestatus;
+ }
+
+sub sendKeys()
+ {
+ my $kf="/root/.ssh/id_dsa.pub";
+ my $s;
+ my @cmd;
+
+ $remotehost =~ /(.*)/; $remotehost=$1;
+
+ if( not -f $kf or not -f "/root/.ssh/id_dsa" )
+ {
+ $s="Generating DSA keys...";
+ print "$s\n";
+ @cmd=("/usr/bin/ssh-keygen","-q","-t","dsa","-N ''","-f", "/root/.ssh/id_dsa" );
+ not ExecCmd( @cmd, 0 ) or errorExit( 1, "Couldn't generate DSA keys" );
+ $s="Successfully created DSA key pair.";
+ print "$s\n";
+ }
+ open( PUBK, $kf ) or errorExit( 2, "Could not open $kf" );
+ my $pubk=trim();
+ close( PUBK );
+ my $ak="/root/.ssh/authorized_keys2";
+ @cmd=("/bin/cat", $kf,
+ "|/usr/bin/ssh", '-o', "StrictHostKeyChecking=no", '-p', $port, $remotehost,"'/bin/cat - > $ak.\$\$ && /bin/touch $ak && /bin/grep -v \"$pubk\" < $ak >> $ak.\$\$ ; /bin/mv -f $ak.\$\$ $ak'");
+ ExecCmd( @cmd, 0 );
+ if( $ExecCmdOutout )
+ {
+ print "$ExecCmdOutout";
+ errorExit( 3, "$ExecCmdOutout" );
+ }
+ $s="Public DSA key sent to $remotehost";
+ print "$s\n";
+ }
+
+sub revokeKeys()
+ {
+ my $kf="/root/.ssh/id_dsa.pub";
+ return if not -f $kf;
+ my $s;
+ my @cmd;
+
+ open( PUBK, $kf ) or errorExit( 4, "Could not open $kf" );
+ my $pubk=trim();
+ close( PUBK );
+
+ $remotehost =~ /(.*)/; $remotehost=$1;
+ my $ak="/root/.ssh/authorized_keys2";
+ @cmd=("/usr/bin/ssh", '-o', "StrictHostKeyChecking=no", '-p', $port, $remotehost, "'/bin/touch $ak && /bin/grep -v \"$pubk\" < $ak > $ak.\$\$ ; /bin/mv -f $ak.\$\$ $ak'");
+ ExecCmd( @cmd, 0 );
+ if( $ExecCmdOutout )
+ {
+ print "$ExecCmdOutout";
+ errorExit( 5, "$ExecCmdOutout" );
+ }
+ $s="Public DSA key deleted on $remotehost";
+ print "$s\n";
+ }
+
+
+
+sub errorExit( $$ )
+ {
+ (my $err, my $msg) = @_;
+ print( "Error $err: $msg\n" );
+ exit -1;
+ }
+
+
+# main
+if( $opts{'revoke'} )
+ {
+ revokeKeys();
+ }
+else
+ {
+ sendKeys();
+ }
+exit 0;
diff --git a/root/sbin/e-smith/dt-unlock-account b/root/sbin/e-smith/dt-unlock-account
new file mode 120000
index 0000000..fba1e4f
--- /dev/null
+++ b/root/sbin/e-smith/dt-unlock-account
@@ -0,0 +1 @@
+dt-lock-account
\ No newline at end of file
diff --git a/smeserver-dirty-tools.spec b/smeserver-dirty-tools.spec
new file mode 100644
index 0000000..315e03e
--- /dev/null
+++ b/smeserver-dirty-tools.spec
@@ -0,0 +1,94 @@
+# $Id: smeserver-dirty-tools.spec,v 1.8 2009/01/29 13:58:10 mweinber Exp $
+# Authority: mweinber
+# Name: Michael Weinberger
+
+Summary: A collection of "dirty" scripts for the experienced administrator
+%define realname smeserver-dirty-tools
+Name: %{realname}
+%define version 0.1.0
+Version: %{version}
+%define release 6
+Release: %{release}%{?dist}
+License: GNU GPL (GNU General Public License)
+Group: Administration
+Source: %{realname}-%{version}.tar.xz
+BuildRoot: /var/tmp/%{realname}-%{version}-buildroot/
+BuildArch: noarch
+Requires: smeserver-release >= 10
+Requires: perl-esmith-PasswordTools
+AutoReq: no
+
+%description
+See http://wiki.contribs.org/Dirty_Tools for full documentation
+
+
+%changelog
+* Sat Sep 07 2024 cvs2git.sh aka Brian Read 0.1.0-6.sme
+- Roll up patches and move to git repo [SME: 12338]
+
+* Sat Sep 07 2024 BogusDateBot
+- Eliminated rpmbuild "bogus date" warnings due to inconsistent weekday,
+ by assuming the date is correct and changing the weekday.
+
+* Fri Nov 12 2021 John Crisp 0.1.0-5.sme
+- fix dt-dovecot-indexfiles-delete maxdepth [SME: 11621]
+
+* Fri Jun 04 2021 Jean-Philippe Pialasse 0.1.0-4.sme
+- import to SME 10 [SME: 11621]
+
+* Thu Jan 29 2009 Michael Weinberger 0.0.9-3
+ Bug 4962 fix
+* Sat Mar 01 2008 Michael Weinberger 0.0.9-2
+ use perl-esmith-PasswordTools
+* Sat Mar 01 2008 Michael Weinberger 0.0.9-1
+ Bug 4001 fix
+* Tue Sep 11 2007 Michael Weinberger
+ Version 0.0.9
+ dt-data-copy
+* Wed Aug 22 2007 Michael Weinberger
+ Version 0.0.8
+ fixed dt-passowrds-sync: PasswordSet prop for ibays
+* Tue Aug 21 2007 Michael Weinberger
+ Version 0.0.7
+ fixed dt-passowrds-sync: smbpasswd-sync: also sync flags and lct.
+ fixed dt-lock-account: dont unlock (new) account without a password set: Print a error.
+ Set PasswordSet property onyl if both shadow password and smb password are set
+* Sun Aug 19 2007 Michael Weinberger
+ Version 0.0.6
+ dt-lock-account
+* Thu Aug 16 2007 Michael Weinberger
+ Version 0.0.5
+ dt-pw-generate
+* Sun Aug 12 2007 Michael Weinberger
+ Version 0.0.4
+ dt-dovecot-indexfiles-delete added
+ dt-datasync renamed to dt-data-sync
+* Fri Aug 10 2007 Michael Weinberger
+ Schleife in dt-password-sync mit 0 beginnen
+* Wed Aug 01 2007 Michael Weinberger
+- initial release 0.0.1
+
+%prep
+%setup -q -n %{realname}-%{version}
+
+%build
+
+%install
+rm -rf $RPM_BUILD_ROOT
+rm -f %{name}-%{version}-filelist
+(cd root ; find . -depth -print | cpio -dump $RPM_BUILD_ROOT)
+
+rm -f %{name}-%{version}-filelist
+
+find $RPM_BUILD_ROOT -depth -type f -print |\
+ sed -e "s@^$RPM_BUILD_ROOT@@g" \
+ -e "s@^/sbin/e-smith/@%attr(0750,root,root) &@"\
+ >> %{name}-%{version}-filelist
+find $RPM_BUILD_ROOT -depth -type l -print |\
+ sed "s@^$RPM_BUILD_ROOT@@g" >> %{name}-%{version}-filelist
+
+%clean
+rm -rf $RPM_BUILD_ROOT
+
+%files -f %{name}-%{version}-filelist
+%defattr(-,root,root)