File Coverage

lib/HTTPD/UserAdmin.pm
Criterion Covered Total %
statement 42 95 44.2
branch 8 38 21.0
condition 2 5 40.0
subroutine 10 18 55.5
pod 10 13 76.9
total 72 169 42.6


line stmt bran cond sub pod time code
1             # $Id: UserAdmin.pm,v 1.2 2003/01/16 19:41:31 lstein Exp $
2             package HTTPD::UserAdmin;
3 2     2   987 use HTTPD::AdminBase ();
  2         7  
  2         52  
4 2     2   25 use Carp ();
  2         54  
  2         32  
5 2     2   11 use strict;
  2         3  
  2         89  
6 2     2   10 use vars qw($VERSION @ISA);
  2         4  
  2         2891  
7             @ISA = qw(HTTPD::AdminBase);
8             $VERSION = 1.51;
9              
10             sub delete {
11 0     0 1 0 my($self, $user) = @_;
12 0         0 my $rc = 1;
13 0         0 delete($self->{'_HASH'}{$user});
14 0 0       0 $self->{'_HASH'}{$user} and $rc = 0;
15 0         0 $rc;
16             }
17              
18             sub suspend {
19 0     0 1 0 my($self, $user) = @_;
20 0 0       0 $self->{'_HASH'}->{$user} = "!".$self->{'_HASH'}->{$user}
21             if $self->{'_HASH'}->{$user} !~ m/^!/;
22 0 0       0 return 0 unless $self->{'_HASH'}->{$user} =~ m/^!/;
23 0         0 return 1;
24             }
25              
26             sub unsuspend {
27 0     0 1 0 my($self, $user) = @_;
28 0         0 $self->{'_HASH'}->{$user} =~ s/^!//;
29 0 0       0 return 0 unless $self->{'_HASH'}->{$user} !~ m/^!/;
30 0         0 return 1;
31             }
32              
33             sub list {
34 0     0 1 0 keys %{$_[0]->{'_HASH'}};
  0         0  
35             }
36              
37             sub exists {
38 13     13 1 21 my($self, $name) = @_;
39 13 100       51 return 0 unless defined $self->{'_HASH'}{$name};
40 7         23 return $self->{'_HASH'}{$name};
41             }
42              
43             sub db {
44 4     4 1 14 my($self, $file) = @_;
45 4         10 my $old = $self->{'DB'};
46 4 50       21 return $old unless $file;
47 4 50       15 if($self->{'_HASH'}) {
48 0         0 $self->DESTROY;
49             }
50              
51 4         20 $self->{'DB'} = $file;
52              
53             #return unless $self->{NAME};
54 4 50       28 $self->lock || Carp::croak();
55 4         27 $self->_tie('_HASH', $self->{DB});
56 4         10 $old;
57             }
58              
59             sub group {
60 0     0 1 0 my($self) = shift;
61 0         0 $self->load('HTTPD::GroupAdmin');
62 0         0 my %attr = %{$self};
  0         0  
63 0         0 foreach(qw(DB _HASH)) {
64 0         0 delete $attr{$_}; #just incase, everything else should be OK
65             }
66 0         0 return new HTTPD::GroupAdmin (%attr, @_);
67             }
68              
69             sub update {
70 0     0 1 0 my($self, $username, $passwd, @fields) = @_;
71 0 0       0 return (0, "User '$username' does not exist") unless $self->exists($username);
72 0         0 my ($old_encr, $bool);
73 0 0       0 if (!defined $passwd) {
74 0         0 $bool = 1;
75 0         0 $passwd = $self->password($username);
76 0         0 $old_encr = $self->{ENCRYPT};
77 0         0 $self->{ENCRYPT} = 'none';
78             }
79 0         0 $self->delete($username);
80 0         0 $self->add($username, $passwd, @fields);
81 0 0       0 $self->{ENCRYPT} = $old_encr if $bool;
82 0         0 1;
83             }
84              
85             sub convert {
86 0     0 1 0 my($self) = shift;
87 0         0 my $class = $self->baseclass(2); #hmm
88 0         0 my $new = $class->new(@_);
89 0         0 foreach($self->list) {
90 0         0 $new->add($_, $self->password($_), 1);
91             }
92 0         0 $new;
93             }
94              
95             sub password {
96 3     3 1 5 my $self = shift;
97 3         7 my $val = $self->exists(@_);
98 3         14 my($x,$y,$z) = split(':',$val);
99 3 0       10 return defined($z) ? join(':',$x,$y,$z) : join(':',$x,$y)
    50          
100             if $self->{ENCRYPT} eq 'MD5';
101 3         9 return $x;
102             }
103              
104             # from Apache's dbmmanage:
105             # if $newstyle is 1, then use new style salt (starts with '_' and contains
106             # four bytes of iteration count and four bytes of salt). Otherwise, just use
107             # the traditional two-byte salt.
108             # see the man page on your system to decide if you have a newer crypt() lib.
109             # I believe that 4.4BSD derived systems do (at least BSD/OS 2.0 does).
110             # The new style crypt() allows up to 20 characters of the password to be
111             # significant rather than only 8.
112              
113             #my %NewStyle = map $_,1, qw(bsd/os-2.0);
114              
115             sub encrypt {
116 3     3 0 4 my($self) = shift;
117 3         4 my $newstyle = defined $_[1]; # || defined $NewStyle{ join("-",@Config{qw(osname osvers)}) };
118 3         3 my($passwd) = "";
119 3   50     9 my($scheme) = $self->{ENCRYPT} || "crypt";
120             # not quite sure where we're at risk here...
121             # $_[0] =~ /^[^<>;|]+$/ or Carp::croak("Bad password name"); $_[0] = $&;
122 3 50       7 if($scheme eq "crypt") {
    0          
    0          
    0          
123 3         6 $passwd = crypt($_[0], salt($newstyle));
124             }
125             elsif ($scheme eq "MD5") {
126             #I know, this isn't really "encryption",
127             #since you can't decrypt it, oh well...
128 0 0       0 unless (defined $self->{'_MD5'}) {
129 0         0 require MD5;
130 0         0 $self->{'_MD5'} = new MD5;
131             }
132 0         0 my($username,$realm,$pass) = split(":", $_[0]);
133              
134 0         0 $self->{'_MD5'}->add(join(":", $username, $realm, $pass));
135 0         0 $passwd = join(":", $realm, $self->{'_MD5'}->hexdigest());
136 0         0 $self->{'_MD5'}->reset;
137             } elsif ($scheme eq "SHA") {
138 0         0 require Digest::SHA1;
139 0         0 $passwd = '{SHA}' . Digest::SHA1::sha1_base64(shift) .'=';
140             } elsif ($scheme eq 'none') {
141 0         0 return $_[0];
142             } else {
143 0         0 Carp::croak("unknown encryption method '$_'");
144             }
145 3         11 return $passwd;
146             }
147              
148             sub salt {
149 3     3 0 5 my($newstyle) = @_;
150 3 50 33     17 return defined($newstyle) && $newstyle ?
151             join('', "_", randchar(1), "a..", randchar(4)) : randchar(2);
152             }
153              
154             my(@saltset) = (qw(. /), 0..9, "A".."Z", "a".."z");
155              
156             sub randchar {
157 3     3 0 5 local($^W) = 0; #we get a bogus warning here
158 3         4 my($count) = @_;
159 3         4 my $str = "";
160 3         65 $str .= $saltset[rand(@saltset)] while $count--;
161 3         694 $str;
162             }
163              
164 0     0     sub DESTROY {
165             }
166              
167             #These should work fine with the _generic classes
168             my %Support = (apache => [qw(DBM Text SQL)],
169             ncsa => [qw(DBM Text)],
170             );
171              
172             HTTPD::UserAdmin->support(%Support);
173              
174             1;
175              
176             __END__