#!/usr/bin/perl # # Name: add-popa3d-user # Author: Tim van Erven # Version: 1.3.1 # Website: http://gene.science.uva.nl/~talerven/software/ # # Copyright (c) 2002,2003 Tim van Erven # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the # "Software"), to deal in the Software without restriction, including # without limitation the rights to use, copy, modify, merge, publish, # distribute, sublicense, and/or sell copies of the Software, and to # permit persons to whom the Software is furnished to do so, subject to # the following conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. # IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. use strict; use warnings; use Crypt::PasswdMD5; use Fcntl; # Options # auth and mail subdirectories will be created in the # virtual_domain_root_directory. They will contain authentication # information and mail respectively for your (virtual) users. my $virtual_domain_root_directory = "/home/virtual/popa3d/127.0.0.1"; # Auth file creation properties my $auth_mask = 0600; my $auth_owner = "root"; my $auth_group = "root"; # Mail file creation properties my $mail_mask = 0660; # Mail for real users is owned by the respective user; other mail is # owned by the virtual mail owner. You should make this a dedicated # pseudo-user (a system user that can't actually log in). Better yet, # use a separate pseudo-user for each domain. my $virtual_mail_owner = "vmail"; my $mail_group = "mail"; # End of options. No need to change anything below this line. ####################################################################### my $user; my $is_real_user; my $passwd; my $undo_auth_file; my $undo_mail_file; # Sanitize environment delete @ENV{keys %ENV}; $ENV{'PATH'} = '/bin:/usr/bin'; # Handle interrupts gracefully $SIG{'INT'} = $SIG{'QUIT'} = $SIG{'HUP'} = 'sighandler'; # Select username if ($#ARGV == 0) { $user = $ARGV[0]; } else { print "Enter a username to add: "; chomp($user = ); } $user =~ /^[[:print:]]{1,40}$/ or &cleanup("Invalid username\n"); $user =~ /^[^\.\/]*$/ or &cleanup("Dangerous username unsupported\n"); # Does the user exist in /etc/passwd? $is_real_user = getpwnam($user); # Create auth file for user print "Creating auth file for ", defined($is_real_user) ? "real" : "virtual", " user $user...\n"; sysopen(AUTH, "$virtual_domain_root_directory/auth/$user", O_WRONLY | O_CREAT | O_EXCL, $auth_mask) or &cleanup("Can't create ", "$virtual_domain_root_directory/auth/$user: $!\n"); $undo_auth_file = "$virtual_domain_root_directory/auth/$user"; # Set auth file ownership and permissions my $auth_uid; my $auth_gid; $auth_uid = getpwnam($auth_owner); defined($auth_uid) or &cleanup("Can't get uid for user $auth_owner: $!\n"); $auth_gid = getgrnam($auth_group); defined($auth_gid) or &cleanup("Can't get gid for group $auth_group: $!\n"); chown $auth_uid, $auth_gid, "$virtual_domain_root_directory/auth/$user" or &cleanup("Can't change ownership for ", "$virtual_domain_root_directory/auth/$user: $!\n"); chmod $auth_mask, "$virtual_domain_root_directory/auth/$user" or &cleanup("Can't change permissions for ", "$virtual_domain_root_directory/auth/$user: $!\n"); # Get password my $passwd_retyped; system "stty", "-echo"; print "Enter new password for $user: "; chomp($passwd = ); print "\nRetype new password for $user: "; chomp($passwd_retyped = ); print "\n"; system "stty", "echo"; $passwd eq $passwd_retyped or &cleanup("Sorry, passwords do not match\n"); # Write auth file my $enc_passwd; print "Writing auth file contents for $user...\n"; $enc_passwd = Crypt::PasswdMD5::unix_md5_crypt( $passwd, substr(time(), -8) ); print AUTH defined($is_real_user) ? $user : $virtual_mail_owner, ":", $enc_passwd, "::\n"; # Close auth file close(AUTH); # Create mail file for user print "Creating mail file for $user...\n"; sysopen(MAIL, "$virtual_domain_root_directory/mail/$user", O_RDONLY | O_CREAT | O_EXCL, $mail_mask) or &cleanup("Can't create ", "$virtual_domain_root_directory/mail/$user: $!\n"); $undo_mail_file = "$virtual_domain_root_directory/mail/$user"; close(MAIL); # Set mail file ownership and permissions my $mail_owner; my $mail_uid; my $mail_gid; $mail_owner = defined($is_real_user) ? $user : $virtual_mail_owner; $mail_uid = getpwnam($mail_owner); defined($mail_uid) or &cleanup("Can't get uid for user $mail_owner: $!\n"); $mail_gid = getgrnam($mail_group); defined($mail_gid) or &cleanup("Can't get gid for group $mail_group: $!\n"); chown $mail_uid, $mail_gid, "$virtual_domain_root_directory/mail/$user" or &cleanup("Can't change ownership for ", "$virtual_domain_root_directory/mail/$user: $!\n"); chmod $mail_mask, "$virtual_domain_root_directory/mail/$user" or &cleanup("Can't change permissions for ", "$virtual_domain_root_directory/mail/$user: $!\n"); sub cleanup { print STDERR "@{_}Cleaning up...\n"; print STDERR "Echo input characters...\n"; system "stty", "echo"; if ($undo_auth_file) { print STDERR "Removing auth file...\n"; unlink $undo_auth_file or print STDERR "Can't delete $undo_auth_file: $!\n"; } if ($undo_mail_file) { print STDERR "Removing mail file...\n"; unlink $undo_mail_file or print STDERR "Can't delete $undo_mail_file: $!\n"; } exit 1; } sub sighandler { &cleanup("Caught a SIG@_.\n"); }