File Coverage

blib/lib/Passwd/Samba.pm
Criterion Covered Total %
statement 20 97 20.6
branch 1 38 2.6
condition 0 21 0.0
subroutine 7 14 50.0
pod 8 8 100.0
total 36 178 20.2


line stmt bran cond sub pod time code
1             package Passwd::Samba;
2              
3 1     1   608 use vars qw($VERSION @ISA @EXPORT @EXPORT_OK);
  1         2  
  1         82  
4              
5 1     1   5 use warnings;
  1         2  
  1         29  
6 1     1   4 use strict;
  1         4  
  1         37  
7              
8 1     1   872 use Crypt::SmbHash;
  1         36088  
  1         77  
9 1     1   11 use File::Spec;
  1         2  
  1         48  
10             #======================================================================
11             $VERSION = '0.142';
12             @ISA = qw(Exporter);
13             @EXPORT_OK = qw(del uid maxuid passwd rename user users smbpasswd_file);
14             #======================================================================
15 1     1   5 use constant PASSWD => '/etc/samba/smbpasswd';
  1         2  
  1         1468  
16             #======================================================================
17             my $Self = __PACKAGE__->new();
18             #======================================================================
19             sub new {
20 1     1 1 4 my ($class, %params) = @_;
21              
22 1 50       8 return bless {
23             smbpasswd => (defined $params{smbpasswd} ? $params{smbpasswd} : PASSWD),
24             }, $class;
25             }
26             #======================================================================
27             sub smbpasswd_file {
28 0 0 0 0 1   my $self = scalar @_ && ref $_[0] eq __PACKAGE__ ? shift : $Self;
29 0           my ($val) = @_;
30 0 0         return $self->{smbpasswd} unless defined $val;
31 0           $self->{smbpasswd} = File::Spec->canonpath($val);
32 0           return $self->{smbpasswd};
33             }
34             #======================================================================
35             sub del {
36 0 0 0 0 1   my $self = scalar @_ && ref $_[0] eq __PACKAGE__ ? shift : $Self;
37            
38 0           open(my $fh, '<', $self->smbpasswd_file);
39 0           my @a;
40 0           while(<$fh>){
41 0 0         push @a,$_ if /^[^:]+:/o;
42             }
43 0           close($fh);
44            
45 0           my $re = '^'.join('$|^', @_).'$';
46 0           $re = qr/$re/;
47            
48 0           open($fh, '>', $self->smbpasswd_file);
49 0           print $fh grep { (split(/:/,$_))[0] !~ $re } @a;
  0            
50 0           close($fh);
51            
52 0           return;
53             }
54             #======================================================================
55             sub rename {
56 0 0 0 0 1   my $self = scalar @_ && ref $_[0] eq __PACKAGE__ ? shift : $Self;
57 0 0         return unless defined $_[1];
58            
59 0           open(my $fh, '<', $self->smbpasswd_file);
60 0           my @a;
61 0           while(<$fh>){
62 0 0         push @a,$_ if /^[^:]+:/o;
63             }
64 0           close($fh);
65             # jesli taki uzytkownik juz istnieje
66 0 0         return if grep { /^$_[1]:/ } @a;
  0            
67            
68 0           @a = map { s/^$_[0]:/$_[1]:/;$_ } @a;
  0            
  0            
69            
70 0           open($fh, '>', $self->smbpasswd_file);
71 0           print $fh @a;
72 0           close($fh);
73            
74 0           return 1;
75             }
76             #======================================================================
77             sub uid {
78 0 0 0 0 1   my $self = scalar @_ && ref $_[0] eq __PACKAGE__ ? shift : $Self;
79            
80 0           open(my $fh, '<', $self->smbpasswd_file);
81 0 0         if(not defined $_[1]){
82 0           while(<$fh>){
83 0 0         return (split(/:/,$_))[1] if /^$_[0]:/;
84             }
85             }else{
86 0           my @a;
87 0           while(<$fh>){
88 0 0         if(/^[^:]+:/o){
89 0 0         if(/^$_[0]:/){
90 0           my @tmp = split(/:/,$_);
91 0           $tmp[1] = $_[1];
92 0           push @a, join(':', @tmp);
93 0           }else{ push @a, $_; }
94             }
95             }
96 0           close($fh);
97 0           open($fh, '>', $self->smbpasswd_file);
98 0           print $fh @a;
99             }
100 0           close($fh);
101              
102 0           return 1;
103             }
104             #======================================================================
105             sub maxuid {
106 0 0 0 0 1   my $self = scalar @_ && ref $_[0] eq __PACKAGE__ ? shift : $Self;
107              
108 0           my $max = 0;
109 0           open(my $fh, '<', $self->smbpasswd_file);
110 0           while(<$fh>){
111 0           my $tmp = (split(/:/,$_))[1];
112 0 0         $max = $tmp > $max ? $tmp : $max;
113             }
114 0           close($fh);
115 0           return $max;
116             }
117             #======================================================================
118             *user = \&passwd;
119             #======================================================================
120             sub passwd {
121 0 0 0 0 1   my $self = scalar @_ && ref $_[0] eq __PACKAGE__ ? shift : $Self;
122            
123 0           my ($name, $passwd) = @_;
124 0 0         return unless defined $passwd;
125 0           my $uid = (getpwnam($name))[2];
126 0           my ($lm, $nt);
127 0           ntlmgen $passwd, $lm, $nt;
128 0           __PACKAGE__->del($name);
129              
130 0           open(my $fh, '>>', $self->smbpasswd_file);
131 0           printf $fh "%s:%d:%s:%s:[%-11s]:LCT-%08X\n", $name, $uid, $lm, $nt, "U", time;
132 0           close($fh);
133              
134 0           return 1;
135             }
136             #======================================================================
137             sub users {
138 0 0 0 0 1   my $self = scalar @_ && ref $_[0] eq __PACKAGE__ ? shift : $Self;
139              
140 0           my @a;
141 0           open(my $fh, '<', $self->smbpasswd_file);
142 0           push @a, (split(/:/,$_))[0] while <$fh>;
143 0           close($fh);
144 0           return @a;
145             }
146             #======================================================================
147             1;
148              
149              
150             =head1 NAME
151              
152             Passwd::Samba
153              
154              
155             =head1 SYNOPSIS
156              
157             use Passwd::Samba;
158            
159             my $ps = Passwd::Samba->new();
160             my $err = $ps->passwd("example", "_plain_text_secret_" );
161             foreach my $user ($ps->users) {
162             print "Username: $user\nUID: ", $ps->uid($user), "\n\n";
163             }
164             my $uid = $ps->uid('example');
165             $ps->rename('example', 'new_example');
166             $pu->del('new_example');
167              
168             # or
169              
170             use Passwd::Samba qw(del uid maxuid passwd rename users);
171              
172             my $err = passwd("example", "_plain_text_secret_" );
173             foreach my $user (users()) {
174             print "Username: $user\nUID: ", uid($user), "\n\n";
175             }
176             my $uid = uid('example');
177             rename('example', 'new_example');
178             del('new_example');
179              
180             =head1 DESCRIPTION
181              
182             The Passwd::Samba module provides an abstract interface to /etc/samba/smbpasswd format files. It is inspired by Unix::PasswdFile module.
183              
184             =head1 SUBROUTINES/METHODS
185              
186             =over 4
187              
188             =item B
189              
190             Constructor. Possible parameters are:
191              
192             =over 8
193              
194             =item B - path to smbpasswd file; default C
195              
196             =back
197              
198             =item B
199              
200             This method will delete the list of users. It has no effect if the supplied user does not exist.
201              
202             =item B
203              
204             This method returns the maximum UID in use by all users.
205              
206             =item B
207              
208             Modify a user's password. Returns the result of operation (TRUE or FALSE).
209              
210             =item B
211              
212             This method changes the username for a user. If NEWNAME corresponds to an existing user, that user will be overwritten. It returns FALSE on failure and TRUE on success.
213              
214             =item B
215              
216             Read or modify a user's UID. Returns the result of operation (TRUE or FALSE) if UID was specified otherwhise returns the UID.
217              
218             =item B
219              
220             This alias for passwd. User is created if doesn't exists.
221              
222             =item B
223              
224             This method returns a list of all existing usernames.
225              
226             =item B
227              
228             This method, if called with an argument, sets path to the I file.
229             Otherwise returns the current PATH.
230              
231             =back
232              
233             =head1 DEPENDENCIES
234              
235             =over 4
236              
237             =item Crypt::SmbHash
238              
239             =item Exporter
240              
241             =back
242              
243             =head1 INCOMPATIBILITIES
244              
245             None known.
246              
247             =head1 BUGS AND LIMITATIONS
248              
249             None known.
250              
251             =head1 THANKS
252              
253             =over 4
254              
255             =item Thanks to Andy Gorman for suggestions as well as supplying relevant patch!
256              
257             =back
258              
259             =head1 AUTHOR
260              
261             Strzelecki Ɓukasz
262              
263             =head1 LICENCE AND COPYRIGHT
264              
265             This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
266              
267             See http://www.perl.com/perl/misc/Artistic.html
268