3 # dump_database.pl - script to dump data from the database to flat files so the ofher perl
4 # scripts can process it without needing to access the database.
7 require("/usr/share/gforge/lib/include.pl"); # Include all the predefined functions
10 my($name,$passwd,$uid,$gid,$quota,$comment,$gcos,$dir,$shell) = getpwnam("gforge");
19 # Dump the users Table information
20 my $query = "select unix_uid, unix_gid, unix_status, user_name, shell, unix_pw, realname from users where unix_status != 'N'";
21 my $c = $dbh->prepare($query);
24 while(my ($uid, $gid, $status, $username, $shell, $passwd, $realname) = $c->fetchrow()) {
25 $home_dir = $homedir_prefix.$username;
27 $userlist = "$uid:$gid:$status:$username:$shell:$passwd:$realname\n";
29 push @user_array, $userlist;
35 # Now write out the files
36 write_array_file($file_dir."/dumps/user_dump", @user_array);
37 system("chmod o-r,g-r $file_dir/dumps/user_dump");
39 my $user_file = $file_dir . "/dumps/user_dump";
40 my ($uid, $gid, $status, $username, $shell, $passwd, $realname);
42 # Open up all the files that we need.
43 @userdump_array = open_array_file($user_file);
46 # Loop through @userdump_array and deal w/ users.
48 if($verbose){print ("\n\n Processing Users\n\n")};
49 while ($ln = pop(@userdump_array)) {
51 ($uid, $gid, $status, $username, $shell, $passwd, $realname) = split(":", $ln);
52 $username =~ tr/A-Z/a-z/;
53 $user_exists = (-d $homedir_prefix .'/'. $username || -f "/var/lib/gforge/tmp/$username.tar.gz");
55 if ($status eq 'A' && $user_exists) {
56 update_user($uid, $gid, $username, $realname, $shell, $passwd);
58 } elsif ($status eq 'A' && !$user_exists) {
59 add_user($uid, $gid, $username, $realname, $shell, $passwd);
61 } elsif ($status eq 'D' && $user_exists) {
62 delete_user($username);
64 } elsif ($status eq 'D' && !$user_exists) {
65 if($verbose){print("Error trying to delete user: $username\n")};
67 } elsif ($status eq 'S' && $user_exists) {
68 suspend_user($username);
70 } elsif ($status eq 'S' && !$user_exists) {
71 if($verbose){print("Error trying to suspend user: $username\n")};
74 if($verbose){print("Unknown Status Flag: $username\n")};
78 ###############################################
80 ###############################################
82 ## Become this effective user (EUID/EGID) and perform this action.
84 ## This protect against symlink attacks; they are inevitable when
85 ## working in a directory owned by a local user. We could naively
86 ## check for the presence of symlinks, but then we'd still be
87 ## vulnerable to a symlink race attack.
89 ## We'll use set_e_uid/set_e_gid for efficiency and simplicity
90 ## (e.g. we can get the return value directly), which is enough for
91 ## opening files and similar basic operations. When calling external
92 ## programs, you should use fork&exec&setuid/setgid.
96 sub SudoEffectiveUser {
98 my $sub_unprivileged = $_[1];
100 my ($uid,$gid) = GetUserUidGid($user);
101 if ($uid eq "" or $gid eq "") {
102 print "Unknown user: $user";
106 my $old_GID = $GID; # save additional groups
108 $EGID = "$gid $gid"; # set egid and additional groups
110 warn "Cannot setegid($gid $gid): $!";
115 warn "Cannot seteuid($uid): $!";
119 # Perform the action under this effective user:
120 my $ret = &$sub_unprivileged();
123 undef($EUID); # restore euid==uid
124 $EGID = $old_GID; # restore egid==gid + additional groups
129 ## Get system uid/gid
132 my ($name,$passwd,$uid,$gid,
133 $quota,$comment,$gcos,$dir,$shell,$expire) = getpwnam($user);
137 #############################
139 #############################
141 my $thecmd = shift(@_);
146 return system($thecmd);
149 #############################
151 #############################
153 my ($uid, $gid, $username, $realname, $shell, $passwd) = @_;
156 $home_dir = $homedir_prefix."/".$username;
158 if($verbose){print("Making a User Account for : $username\n")};
160 # Now lets create the homedir and copy the contents of /etc/skel into it.
161 mkdir $home_dir, 0755;
162 chown $uid, $gid, $home_dir;
164 SudoEffectiveUser($username, sub {
165 mkdir $home_dir.'/incoming', 0755;
169 #############################
170 # User Update Function
171 #############################
173 my ($uid, $gid, $username, $realname, $shell, $passwd) = @_;
174 my ($realuid, $realgid);
176 if($verbose){print("Updating Account for: $username\n")};
178 SudoEffectiveUser($username, sub {
179 $home_dir = $homedir_prefix.'/'.$username;
180 if (-d $home_dir.'/incoming') {
181 chmod 0755, $home_dir.'/incoming';
183 mkdir $home_dir.'/incoming', 0755;
188 #############################
189 # User Deletion Function
190 #############################
192 my $username = shift(@_);
194 my $alreadydone=(-f "/var/lib/gforge/tmp/$username.tar.gz");
196 my $oldmask = umask(077);
198 print("Deleting User : $username\n");
200 run_verbose("/bin/mv /var/lib/gforge/chroot/home/users/$username /var/lib/gforge/chroot/home/users/deleted_$username");
201 run_verbose("cd / && /bin/tar -cf - /var/lib/gforge/chroot/home/users/deleted_$username | /bin/gzip -n9 >/var/lib/gforge/tmp/$username.tar.gz && /bin/rm -rf /var/lib/gforge/chroot/home/users/deleted_$username");
206 #############################
207 # User Suspension Function
208 #############################
210 my $this_user = shift(@_);
211 my ($s_username, $s_passwd, $s_date, $s_min, $s_max, $s_inact, $s_expire, $s_flag, $s_resv, $counter);
213 my $new_pass = "!!" . $s_passwd;
216 #############################
218 #############################
219 sub get_file_owner_uid {
220 my $filename = shift(@_);
221 my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,$ctime,$blksize,$blocks) = stat($filename);
224 #############################
226 #############################
227 sub get_file_owner_gid {
228 my $filename = shift(@_);
229 my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,$ctime,$blksize,$blocks) = stat($filename);