#!/usr/bin/perl # # Copyright 1998 Linux-Consulting.com All Rights Reserved # http://www.Linux-Consulting.com/Majordomo # # You may Freely Distribute for NON-Commercial use under the GPL License # # Any comments and feedback will be appreciated and will be incorporated # and acknowledged/credited in due course # # ------------------------------------------------------ # The lastest version of Majordomo is available at: # http://www.GreatCircles.com/majordomo # ftp:/pub/majordomo # # Check the Majordomo Setup # ------------------------- # ### # ### Make sure that #!/usr/bin/perl on line 1 of this script is the right path # ### Make sure after downloading that it is executable: chmod 754 mj_check.pl # ### # - # - check for permission problems on mailing lists # - check ownerships of mail list files # - create "entries" to be appended to /etc/aliases # - # ------------------------------------------------------- # # 16-Sep-98 amo Date-of-Birth # 21-Sep-98 amo Minor Patches for initial values for testing # 15-oct-98 amo nomad@orci.com - Fixed Path to binaries if MJ_HOME is user defined # 12-Sep-00 amo v1.0.2 = Modified for 1.94.5 # # my ( $NM ) = "mj_check.pl"; my ( $MJ_Version ) = "1.0.2"; # my ( $MJ_HOME ) = "/usr/local/majordomo"; # my ( $MJ_WRAP ) = "$MJ_HOME/wrapper"; my ( $MJ_ARCHIVE ) = "$MJ_HOME/archive2.pl"; my ( $MJ_DIGEST ) = "$MJ_HOME/digest"; my ( $MJ_RESEND ) = "$MJ_HOME/resend"; # my ( $MJ_CF ) = "$MJ_HOME/majordomo.cf"; my ( $MJ_SRC ) = "/usr/src/majordomo-1.94.5"; # my ( @MJ_LIST ) = (); # use () instead of "" so initial counter == -1 my ( $MJ_CREATE ) = (); # Create a mailing list my ( $MJ_TEST ) = (); # Test this mailing list # my ( $DEBUG ) = 0; my ( $MY_MAILER ) = "/bin/mailx" if ( -x "/bin/mailx" ); $MY_MAILER = "/usr/bin/elm" if ( -x "/usr/bin/elm" ); # local ( %MJ_Var ) = (); # all the majordomo variables of interest local ( $Home_Dir ) = ""; local ( $MJ_UID ) = 99999; # pick a silly number local ( $MJ_GID ) = 99999; # # &read_arg; # Read command line arguments # &read_make; # Read the majordomo/Makefile # &read_cf; # Read the majordomo.cf file # &err_chk ; # Check for Errors # &chk_lists ; # Check the mailing lists # &pr_msg ( "\nDone..\n" ); # exit ( 0 ); # ==================================================================================== # # Subroutines # sub usage { # printf "\n"; printf "Usage: ${NM}-$MJ_Version [ options ]\n"; printf "\t -h this help file\n"; printf "\t -v Version\n"; printf "\t -home mj_dir Home directory, eg: /home/majorodomo\n"; printf "\t -cf cf_dir Directory of majordomo.cf, eg: /usr/local/majordomo.cf\n"; printf "\t -src mj_src Majordomo source tree, eg: /usr/src/majordomo-1.94.5\n"; printf "\t -l listname Mailing List name to check, eg: -l test -l test2 -l test3\n"; printf "\t -create listname Create a mail list, eg: -create test \n"; printf "\t -t listname Test the functionality of the mailing list, eg: -t test\n"; printf "\n"; # } # usage # # # Read command line arguments # --------------------------- # sub read_arg { # my ( $argv ) = ""; my ( $id ) = 0; my ( $jd ) = 0; my ( $kd ) = 0; # # foreach $argv ( @ARGV ) { # while ( $id <= @ARGV ) { # $argv = $ARGV[$id]; # printf "arg=$argv..\n"; # if ( $argv eq "-debug" ) { $DEBUG = 1; # } elsif ( $argv eq "-v" ) { printf "${NM}-$MJ_Version 1998 Copyright 1998 Linux-Consulting. All Rights Reserved.\n"; exit ( 1 ); # } elsif ( $argv eq "-h" ) { &usage ; # print usage exit ( 1 ); # } elsif ( $argv eq "-l" ) { $MJ_LIST[$jd++] = $ARGV[++$id]; # List to check # } elsif ( $argv eq "-home" ) { $MJ_HOME = $ARGV[++$id]; # /home/majordomo # # } elsif ( $argv eq "-cf" ) { # $MJ_CF = $ARGV[++$id]; # /usr/local/etc/majordomo # # } elsif ( $argv eq "-src" ) { $MJ_SRC = $ARGV[++$id]; # /usr/src/majordomo-1.94.4 # } elsif ( $argv eq "-create" ) { $MJ_CREATE[$jd++] = $ARGV[++$id]; # Mailing List to create # } elsif ( $argv eq "-t" ) { $id += 1; $MJ_LIST[$jd++] = $ARGV[$id]; # List to check $MJ_TEST[$kd++] = $ARGV[$id]; # Test this Mailing List } # $id += 1; # } # cycle thru command line args # # printf "LIST=$LIST..Home=$MJ_HOME..CF=$MJ_CF..\n" if ( $DEBUG ); # } # read_arg # # # Read the Majordomo Makefile # --------------------------- # sub read_make { # my ( $mj_make ) = "$MJ_SRC/Makefile"; # if ( ! -f $mj_make ) { # &pr_msg ( "\n" ); &pr_msg ( "ERROR: Cannot find file=$MJ_SRC/Makefile\n" ); &pr_msg ( "..Please use -src /usr/src/where_you_put_majordomo-1.94.5 \n" ); &pr_msg ( "\n" ); exit 1; } # error # my ( $mj_perl ) = `grep ^PERL $mj_make`; my ( $mj_home ) = `grep ^W_HOME $mj_make`; my ( $mj_own ) = `grep ^W_USER $mj_make`; my ( $mj_grp ) = `grep ^W_GROUP $mj_make`; # my ( $mj_perl_key, $eq, $mj_PERL ) = split ( /\s+/, $mj_perl ); # read the make file my ( $mj_home_key, $eq, $mj_HOME ) = split ( /\s+/, $mj_home ); my ( $mj_own_key, $eq, $mj_UID ) = split ( /\s+/, $mj_own ); my ( $mj_grp_key, $eq, $mj_GID ) = split ( /\s+/, $mj_grp ); # #MJ_PERL = $mj_PERL; # $MJ_HOME = $mj_HOME; $MJ_UID = $mj_UID; $MJ_GID = $mj_GID; # # Check for perl binary # if ( ! -x $mj_PERL ) { # &pr_msg ( "\n" ); &pr_msg ( "..ERROR: Missing Perl binary=$mj_PERL\n" ); &pr_msg ( "....Recommendation: /usr/bin/perl or change PERL variable in $mj_make\n" ); # if ( -x "/usr/bin/perl" ); &pr_msg ( "\n" ); # } # missing perl binary # # majordom:*:504:2:Majordomo Master,,,:/usr/local/majordomo:/bin/bash # my ( $mj_pwd_str ) = `grep ":$MJ_UID:" /etc/passwd | grep ":$MJ_GID": `; my ( $mj_acct, $mj_pwd, $mj_uid, $mj_gid, $mj_name, $mj_home, $mj_shell ) = split ( /:/, $mj_pwd_str ); # # daemon::2:root,bin,daemon # my ( $mj_grp_str ) = `grep ":$MJ_GID:" /etc/group `; my ( $mj_grp, $mj_grp_x, $mj_grp_gid, $mj_grp_users ) = split ( /:/, $mj_grp_str ); # my ( $err ) = 0; # # &pr_msg ( "Checking MJ_own=$MJ_UID..MJ_grp=$MJ_GID...$mj_make..\n" ); # $err += &pr_msg ( "..ERROR: Undefined Majordomo User=$MJ_UID..\n" ) if ( length $mj_uid == 0 ); $err += &pr_msg ( "..ERROR: Undefined Majordomo Group=$MJ_GID..\n" ) if ( length $mj_gid == 0 ); # if ( $err ) { &pr_msg ( "----Recommendation: Add the following to your /etc/passwd file\n" ); &pr_msg ( "------majordom:*:$mj_UID:$mj_GID:Majordomo Master,,,:$MJ_HOME:/bin/bash\n" ); } # error # $err = 0; $err += &pr_msg ( "..ERROR: Undefined Majordomo Group=$MJ_GID..\n" ) if ( length $mj_grp_gid == 0 ); if ( $err ) { &pr_msg ( "----Recommendation: Add the following to your /etc/group file\n" ); &pr_msg ( "------daemon::$mj_GID:root,bin,daemon\n" ); } # error # # # Cannot continue # if ( ( $MJ_UID == 0 ) || ( $MJ_GID == 0 ) ) { # &pr_msg ( "\n" ); &pr_msg ( "..Please be sure to specify the path to /usr/src/majordomo-*/Makefile\n" ); &pr_msg ( "....$NM -src /usr/src/majordomo-1.94.4\n" ); &pr_msg ( "\n" ); &pr_msg ( "\n" ); &pr_msg ( "..ERROR: You really should NOT run majordomo as root.root\n" ); &pr_msg ( "....Please define W_USER and G_USR in $mj_make\n" ); &pr_msg ( "\n" ); # exit 1; } # abort # &pr_msg ( "\n" ); # } # read_make # # # Get some of the Variables from majordomo.cf # ------------------------------------------- # sub read_cf { # my ( $line ) = ""; my ( $len ) = 0; my ( $key ) = ""; my ( @val ) = ""; # $MJ_CF = "$MJ_HOME/majordomo.cf"; # # 15-Oct-98 Fix bug if $MJ_HOME is different # $MJ_WRAP = "$MJ_HOME/wrapper"; $MJ_ARCHIVE = "$MJ_HOME/archive2.pl"; $MJ_DIGEST = "$MJ_HOME/digest"; $MJ_RESEND = "$MJ_HOME/resend"; # # $stat = open ( FRD, "< $MJ_CF" ); # Read the config file # printf "mj_cf=$MJ_CF..\n"; if ( $stat == 0 ) { &pr_msg ( "ERROR: Could not find $MJ_CF\n" ); &pr_msg ( "..Please use -home /home/majordomo or wherever-you_put_majordomo \n" ); exit 1; } else { &pr_msg ( "Reading $MJ_CF\n" ); } # while ( ) { # $line = $_; chomp ( $line ); # $line =~ s/^\s+//; # take out leading spaces for things like $homedir $line =~ s/ =/=/; # for homedir # # Remember the parameters that begins with "$parameter=...value..." # $_ = $line; if ( /^\$/ ) { ( $key, @val ) = split ( /\s+/, $line ); # $key =~ s/^\$//; # Take out $ in $variable name $key =~ s/=$//; # Take out = in $key= # # $val =~ s/^"//; # clean up "/usr/test/majordomo"; # $val =~ s/";$//; # $MJ_Var{ $key } = "@val"; # } # collected all the mj variables # } # read the cf file # close ( FRD ); # # Add some majordomo binaries to look for too # $MJ_Var { "wrapper_bin" } = "$MJ_WRAP"; $MJ_Var { "archive_bin" } = "$MJ_ARCHIVE"; $MJ_Var { "digest_bin" } = "$MJ_DIGEST"; $MJ_Var { "resend_bin" } = "$MJ_RESEND"; # &pr_var if ( $DEBUG > 2 ); # print the variables # } # read_cf # # # Print the Variables # ------------------- # sub pr_var { # my ( $key ) = ""; my ( $val ) = ""; # foreach $key ( keys %MJ_Var ) { # $val = $MJ_Var{ $key }; # printf "..key: $key=$val..\n" if ( DEBUG ); # } # cycle thru all the variables # } # pr_var # # # Check the variables in some sane order # ------------------------------------- # sub err_chk { # &pr_var if ( $DEBUG ); # # # Check for the majordomo binaries # &chk_dirfile ( "-f", "wrapper_bin" ); # check for setuid bit later &chk_dirfile ( "-f", "archive_bin" ); &chk_dirfile ( "-f", "digest_bin" ); &chk_dirfile ( "-f", "resend_bin" ); # $WhereAmI = &chk_value ( "whereami", "foo.NOWHERE.COM" ); # $Home_Dir = &chk_dirfile ( "-d", "homedir" ); # watch out for /usr/test/majordomo &chk_dirfile ( "-f", "log" ); $List_Dir = &chk_dirfile ( "-d", "listdir" ); $Archive_Dir = &chk_dirfile ( "-d", "filedir" ); # check filedir.filedir_suffix too $Digest_Dir = &chk_dirfile ( "-d", "digest_work_dir" ); # $Sendmail_Cmd = &chk_dirfile ( "-f", "sendmail_command" ); # check for file # &pr_msg ( "\n" ); # done # # The way I like it... # $My_Archive_Dir = "$Home_Dir/Archive"; $My_Digest_Dir = "$Home_Dir/Digest"; # } # err_chk # # # Check that the default value is changed # --------------------------------------- # sub chk_value { # my ( $key ) = @_[0]; my ( $def ) = @_[1]; # my ( $val ) = $MJ_Var{ $key }; # Get the variable read from the cf file # $val =~ s/;$//; # get rid of trailing ; $val =~ s/^"//; # get rid of quotes $val =~ s/"$//; # &pr_msg ( "..Checking \$$key.. ( $val ).." ); # if ( $val eq $def ) { &pr_msg ( "ERROR: You need to define $key, you CANNOT use the default value=$val\n" ); } else { &pr_msg ( "ok\n" ); } # return ( $val ) ; # } # chk_value # # # Check that the directory and files exists # ----------------------------------------- # sub chk_dirfile { # my ( $df ) = @_[0]; my ( $key ) = @_[1]; # my ( $val ) = $MJ_Var{ "$key" }; # Get the variable read from the cf file $val =~ s/;$//; # get rid of trailing ; # my ( $aka ) = $val ; # # Convert variables into real values # $aka =~ s/\$homedir/$Home_Dir/; # for $listdir="$homedir/Lists" $aka =~ s/\$listdir/$List_Dir/; # for $filedir="$listdir" --> better to use $homedir/Archive # $aka =~ s/^"//; # get rid of quotes $aka =~ s/"$//; # &pr_msg ( "..Checking \$$key=$val..( $aka ).." ); # if ( ( -d "$aka" && $df eq "-d" ) || ( $df eq "-f" && -f "$aka" ) || -l "$aka" ) { # &pr_msg ( "..OK..\n" ); # } else { &pr_msg ( "ERROR: No such directory..\n" ); &pr_msg ( "\tRecommendation: `mkdir -p $aka' or change the \$$key variable in $MJ_CF file\n\n" ) if ( $df eq "-d" ); } # return ( $aka ); # } # chk_dirfile # # # Check that the Lists exits # -------------------------- # sub chk_lists { # # my ( @List ) = (); # so that initial value is -1 my ( $lst ) = ""; my ( $id ) = 0; my ( $err ) = 0; # # # Extract only the Mailing lists # ------------------------------ # @MJ_LIST = `cd $List_Dir ; find . -print` if ( $#MJ_LIST == -1 ); # Read the directory # foreach $lst ( @MJ_LIST ) { # chomp ( $lst ); # $lst =~ s-^./--; # snip off leading ./list_name $_ = $lst; # if ( /.config/ ) { $Config{$id} = $lst; # } elsif ( /.info/ ) { $Info{$lst} = $lst; # } elsif ( /.closed/ ) { $Closed{$lst} = $lst; # } elsif ( /.passwd/ ) { $Passwd{$lst} = $lst; # } elsif ( $lst ne "." ) { $List[$id] = $lst; $id += 1; } # } # lists # # # Create a Mailing List # --------------------- # foreach $lst ( @MJ_CREATE ) { # printf "Creating Mailing List=$lst\n"; # &create_list ( "-f", "$List_Dir/$lst" ); &create_list ( "-f", "$List_Dir/$lst.info" ); &create_list ( "-f", "$List_Dir/$lst.config" ); # &create_list ( "-f", "$List_Dir/$lst-digest" ); &create_list ( "-f", "$List_Dir/$lst-digest.info" ); &create_list ( "-f", "$List_Dir/$lst-digest.config" ); # &create_list ( "-d", "$Archive_Dir/$lst.archive" ); &create_list ( "-d", "$Archive_Dir/$lst-digest.archive" ); &create_list ( "-d", "$Digest_Dir/$lst-digest" ); # &create_list_alias ( $lst ); # } # Create a mailing list # # return ( 0 ) if ( $#MJ_CREATE >= 0 ); # Only need to create it # # # Check for MailingList{.info,,config,-digest,-digest.info,-digest.info} # ---------------------------------------------------------------------- # # Check owner/group permissions later # foreach $lst ( @List ) { # printf "Checking Mailing List=$lst..\n"; # $err = 0; $err += &chk_list_dirfile ( "-f", "$List_Dir/$lst", "MailingList" ); $err += &chk_list_dirfile ( "-f", "$List_Dir/$lst.info", "info" ); $err += &chk_list_dirfile ( "-f", "$List_Dir/$lst.config", "config" ); # # optional files #err += &chk_list_dirfile ( "-f", "$List_Dir/$lst.closed", "closed" ); #err += &chk_list_dirfile ( "-f", "$List_Dir/$lst.passwd", "passwd" ); # $err += &chk_list_dirfile ( "-d", "$Archive_Dir/$lst.archive", "Archive" ); $err += &chk_list_dirfile ( "-d", "$Digest_Dir/$lst-digest", "Digest" ); # } # Check the Lists # # # Test the List # ------------- # foreach $lst ( @MJ_TEST ) { # &test_list ( $lst ); # } # test the List # } # chk_lists # # # Create a Mailing List # --------------------- # sub create_list { # my ( $df ) = @_[0]; my ( $lst ) = @_[1]; # my ( $cmd1 ) = ""; my ( $cmd2 ) = ""; my ( $cmd3 ) = "chown $MJ_UID.$MJ_GID $lst"; # if ( $df eq "-d" ) { $cmd1 = "mkdir $lst"; $cmd2 = "chmod 750 $lst"; } else { $cmd1 = "touch $lst"; $cmd2 = "chmod 640 $lst"; } # &pr_msg ( "..$cmd1\n" ); &pr_msg ( "..$cmd2\n" ); &pr_msg ( "..$cmd3\n" ); &pr_msg ( "..\n" ); # } # create_list # # # Create a Mailing List # --------------------- # sub create_list_alias { # my ( $lst ) = @_[0]; # my ( %New_List ) = () ; my ( $key ) = ""; my ( $str ) = ""; # $New_List { "New_00" } = "#" ; $New_List { "New_02" } = "# Append these lines to /etc/aliases.$lst"; $New_List { "New_03" } = "# ---------------------------------------"; $New_List { "New_04" } = "# please run: newaliases or sendmail -bi "; $New_List { "New_05" } = "#" ; $New_List { "New_06" } = "# Create $lst Mailing List"; $New_List { "New_07" } = "#" ; $New_List { "New_08" } = "DomoMaster: root,You,SomebodyElse # You need to change to the right real people"; $New_List { "New_09" } = "#" ; # $New_List { "New_11" } = "owner-majordomo: majordom # The majordomo user defined in /etc/passwd"; $New_List { "New_12" } = "majordomo-owner: owner-majordomo"; $New_List { "New_13" } = "#"; $New_List { "New_14" } = "Majordomo: \"|$MJ_HOME/wrapper majordomo\" "; $New_List { "New_15" } = "#"; # $New_List { "New_20" } = "$lst-owner: DomoMaster"; $New_List { "New_21" } = "$lst-approval: DomoMaster"; $New_List { "New_22" } = "$lst-digest-approval: $lst-approval"; $New_List { "New_23" } = "#" ; $New_List { "New_24" } = "owner-$lst: DomoMaster" ; $New_List { "New_25" } = "owner-$lst-owner: DomoMaster" ; $New_List { "New_26" } = "#" ; $New_List { "New_31" } = "owner-$lst-archive: owner-$lst" ; $New_List { "New_32" } = "owner-$lst-outgoing: owner-$lst" ; $New_List { "New_33" } = "owner-$lst-request: owner-$lst" ; $New_List { "New_34" } = "#" ; $New_List { "New_35" } = "owner-$lst-digest: owner-$lst" ; $New_List { "New_36" } = "owner-$lst-digest-outgoing: owner-$lst" ; $New_List { "New_37" } = "owner-$lst-digest-request: owner-$lst" ; $New_List { "New_38" } = "#" ; $New_List { "New_39" } = "#" ; # $New_List { "New_41" } = "$lst: \"|$MJ_WRAP resend -l $lst -r $lst $lst-outgoing\" "; $New_List { "New_42" rc/majordomo-1.94.4\n" ); &pr_msg ( "\n" ); &pr_msg ( "\n" ); &pr_msg ( "..ERROR: You really should NOT run majordomo as root.root\n" ); &pr_msg ( "....Please define W_USER and G_USR in $mj_make\n" ); &pr_msg ( "\n" ); # exit 1; } # abort # &pr_msg ( "\n" ); # } # read_make # # # Get some of the Variables from majordomo.cf # ------------------------------------------- # sub read_cf { # my ( $line ) = ""; my ( $len ) = 0; my ( $key ) = ""; my ( @val ) = "";