3 # mailfwd_update.pl - Script to create ~/.forward for each user
4 # based on ssh_dump_update.pl
5 # changes Copyright © 2010
6 # Thorsten Glaser <t.glaser@tarent.de>
7 # Licence: GPLv2+ (FusionForge)
12 ## Become this effective user (EUID/EGID) and perform this action.
14 ## This protect against symlink attacks; they are inevitable when
15 ## working in a directory owned by a local user. We could naively
16 ## check for the presence of symlinks, but then we'd still be
17 ## vulnerable to a symlink race attack.
19 ## We'll use set_e_uid/set_e_gid for efficiency and simplicity
20 ## (e.g. we can get the return value directly), which is enough for
21 ## opening files and similar basic operations. When calling external
22 ## programs, you should use fork&exec&setuid/setgid.
26 sub SudoEffectiveUser {
28 my $sub_unprivileged = $_[1];
30 my ($uid,$gid) = GetUserUidGid($user);
31 if ($uid eq "" or $gid eq "") {
32 print "Unknown user: $user";
36 my $old_GID = $GID; # save additional groups
38 $EGID = "$gid $gid"; # set egid and additional groups
40 warn "Cannot setegid($gid $gid): $!";
45 warn "Cannot seteuid($uid): $!";
49 # Perform the action under this effective user:
50 my $ret = &$sub_unprivileged();
53 undef($EUID); # restore euid==uid
54 $EGID = $old_GID; # restore egid==gid + additional groups
62 my ($name,$passwd,$uid,$gid,
63 $quota,$comment,$gcos,$dir,$shell,$expire) = getpwnam($user);
67 require("/usr/share/gforge/lib/include.pl"); # Include all the predefined functions
69 my($name,$passwd,$uid,$gid,$quota,$comment,$gcos,$dir,$shell) = getpwnam("gforge");
78 $dbh->{AutoCommit} = 0;
80 # Dump the Table information
81 $query = "SELECT user_name,unix_uid,email FROM users WHERE email != '' AND status !='D'";
82 $c = $dbh->prepare($query);
84 while(my ($username, $unix_uid, $mailadr) = $c->fetchrow()) {
85 $new_list = "$username:$unix_uid:$mailadr\n";
86 push @fwd_array, $new_list;
94 if($verbose){print("\n\n Processing Users fwd creation\n\n")};
95 while ($ln = pop(@fwd_array)) {
96 ($username, $uid, $mailadr) = split(":", $ln);
98 $username =~ tr/[A-Z]/[a-z]/;
101 push @user_authorized_keys, $mailadr . "\n";
103 if($verbose){print ("Processing $username\n")};
105 if (-d "$homedir_prefix/$username"){
106 if($verbose){print("Writing fwd for $username: ")};
108 SudoEffectiveUser($username, sub {
109 if (write_array_file("$homedir_prefix/$username/.forward", @user_authorized_keys)) {
110 warn "Problem writing fwd for $username\n";
115 chown $uid, $uid, ("$homedir_prefix/$username/.forward");
116 chmod 0644, "$homedir_prefix/$username/.forward";
118 if($verbose){print ("Done\n")};
120 if($verbose){print ("Not yet done, waiting for home creation\n")};
123 undef @user_authorized_keys;
127 ### Phase 2: remove the files when needed
129 # Dump the Table information
130 $query = "SELECT user_name,unix_uid FROM users WHERE email = '' OR email IS NULL OR status = 'D'";
131 $c = $dbh->prepare($query);
133 while(my ($username, $unix_uid) = $c->fetchrow()) {
134 $new_list = "$username:$unix_uid\n";
135 push @fwd_array, $new_list;
138 if($verbose){print("\n\n Processing Users fwd deletion\n\n")};
139 while ($ln = pop(@fwd_array)) {
140 ($username, $uid) = split(":", $ln);
142 $username =~ tr/[A-Z]/[a-z]/;
145 if($verbose){print ("Processing $username\n")};
147 unlink("$homedir_prefix/$username/.forward");
149 if($verbose){print ("Done\n")};