File Coverage

blib/lib/Win32/pwent.pm
Criterion Covered Total %
statement 16 18 88.8
branch n/a
condition n/a
subroutine 6 6 100.0
pod n/a
total 22 24 91.6


line stmt bran cond sub pod time code
1             package Win32::pwent;
2            
3 1     1   21466 use warnings;
  1         1  
  1         29  
4 1     1   4 use strict;
  1         2  
  1         30  
5 1     1   5 use vars qw(@ISA @EXPORT @EXPORT_OK);
  1         6  
  1         49  
6            
7 1     1   4 use Exporter;
  1         1  
  1         75  
8             @ISA = qw(Exporter);
9             @EXPORT = qw();
10             @EXPORT_OK = qw(getpwent endpwent setpwent getpwnam getpwuid getgrent entgrent setgrent getgrnam getgrgid);
11            
12 1     1   5 use File::Spec;
  1         2  
  1         22  
13            
14 1     1   473 use Win32;
  0            
  0            
15             use Win32::NetAdmin;
16             use Win32::TieRegistry Delimiter => "/";
17             use Win32API::Net 0.13; # for USER_INFO_4 structure
18            
19             =head1 NAME
20            
21             Win32::pwent - pwent and grent support for Win32
22            
23             =cut
24            
25             our $VERSION = '0.100';
26            
27             =head1 SYNOPSIS
28            
29             use Win32;
30             use Win32::pwent qw(getpwnam getpwent endpwent);
31            
32             my $uid = getpwnam(getlogin);
33             my $win32login = Win32::LoginName();
34             while( my @pwent = getpwent )
35             {
36             if( $pwent[0] eq $win32login and $pwent[2] == $uid )
37             {
38             print( "It's me \\o/\n" );
39             endpwent();
40             last;
41             }
42             }
43            
44             =head1 DESCRIPTION
45            
46             Win32::pwent should help building a bridge for Perl scripts running on
47             Unix like systems to Win32.
48            
49             It supports reading access to LanManager User-Info structures via the
50             well known pwent and grent functions.
51            
52             =head1 EXPORT
53            
54             Win32::pwent doesn't export anything by default. Following function can
55             be imported explicitely: C, C, C, C,
56             C, C, C, C
57            
58             =head1 SUBROUTINES/METHODS
59            
60             All exported subroutines behaves as the same ones for Unix-like systems
61             provided by Perl itself. See L.
62            
63             =head2 getpwent
64            
65             Returns the next entry from user list got from LANMAN user database.
66             If this is the first call to C (or the first call after an
67             C call), a user cache based on the LANMAN database using the
68             functions C and C from the module L
69             is created.
70            
71             see L
72            
73             =head2 endpwent
74            
75             Free the user list cache and rewind the pointer for the next user entry.
76            
77             see L
78            
79             =head2 setpwent
80            
81             Rewind the pointer for the next user entry.
82            
83             see L
84            
85             =head2 getpwnam
86            
87             Fetches the user (by name) entry from LANMAN user database and return it
88            
89             see L
90            
91             =head2 getpwuid
92            
93             fetches the user (by user id) entry from LANMAN user database and return it
94            
95             see L
96            
97             =head2 getgrent
98            
99             Return the next group entry from LANMAN group database. If this is the first
100             call to C (or the first call after an C call), a group
101             cache based on the LANMAN database using the functions C and
102             C from the module L is created.
103            
104             see L
105            
106             =head2 endgrent
107            
108             Free the group list cache and rewind the pointer for the next group entry.
109            
110             see L
111            
112             =head2 setgrent
113            
114             Rewind the pointer for the next group entry.
115            
116             see L
117            
118             =head2 getgrnam
119            
120             Fetches the group (by name) entry from LANMAN user database and return
121             it. This function doesn't uses the groups cache from getgrent.
122            
123             see L
124            
125             =head2 getgrgid
126            
127             Fetches the group (by group id) entry from LANMAN user database and return
128             it. This function doesn't uses the groups cache from getgrent.
129            
130             see L
131            
132             =cut
133            
134             sub _fillpwent
135             {
136             my $userName = $_[0];
137            
138             my %userInfo;
139             if( Win32API::Net::UserGetInfo( "", $userName, 4, \%userInfo ) )
140             {
141             $userInfo{userId} = $1 if( $userInfo{userSid} =~ m/-(\d+)$/ );
142             }
143             else
144             {
145             Win32API::Net::UserGetInfo( "", $userName, 3, \%userInfo )
146             or die "UserGetInfo() failed: $^E";
147             }
148            
149             if( defined( $userInfo{userSid} ) )
150             {
151             unless( defined( $userInfo{homeDir} ) && ( $userInfo{homeDir} ne '' ) )
152             {
153             my $regPath = "LMachine/SOFTWARE/Microsoft/Windows NT/CurrentVersion/ProfileList/" . $userInfo{userSid} . "/ProfileImagePath";
154             $userInfo{homeDir} = $Registry->{$regPath};
155             }
156            
157             #my $console;
158             #$::HKEY_USERS->Open( $userInfo{userSid} . "\\Console", $console );
159             # find tree item - e.g. %SystemRoot%_system32_cmd.exe
160             $userInfo{shell} = File::Spec->catfile( $ENV{SystemRoot}, 'system32', 'cmd.exe' );
161            
162             }
163             else
164             {
165             $userInfo{shell} = File::Spec->catfile( $ENV{SystemRoot}, 'system32', 'cmd.exe' );
166             }
167             my @pwent = ( @userInfo{'name', 'password', 'userId', 'primaryGroupId', 'maxStorage', 'comment', 'fullName', 'homeDir', 'shell', 'acctExpires'} );
168            
169             return \@pwent;
170             }
171            
172             sub _fillpwents
173             {
174             my @pwents;
175             my %users;
176             Win32::NetAdmin::GetUsers( "", 0, \%users )
177             or die "GetUsers() failed: $^E";
178             foreach my $userName (keys %users)
179             {
180             push( @pwents, _fillpwent( $userName ) );
181             }
182            
183             return \@pwents;
184             }
185            
186             my $pwents;
187             my $pwents_pos;
188            
189             sub getpwent
190             {
191             unless( "ARRAY" eq ref($pwents) )
192             {
193             $pwents = _fillpwents();
194             }
195             defined $pwents_pos or $pwents_pos = 0;
196             my @pwent = @{$pwents->[$pwents_pos++]} if( $pwents_pos < scalar(@$pwents) );
197             return wantarray ? @pwent : $pwent[2];
198             }
199            
200             sub setpwent { $pwents_pos = undef; }
201            
202             sub endpwent { $pwents = $pwents_pos = undef; }
203            
204             sub getpwnam
205             {
206             my $userName = $_[0];
207             my $pwent = _fillpwent( $userName );
208             return wantarray ? @$pwent : $pwent->[2];
209             }
210            
211             sub getpwuid
212             {
213             my $uid = $_[0];
214             my $pwents = _fillpwents();
215             my @uid_pwents = grep { $uid == $_->[2] } @$pwents;
216             my @pwent = @{$uid_pwents[0]} if( 1 <= scalar(@uid_pwents) );
217             return wantarray ? @pwent : $pwent[0];
218             }
219            
220             sub _fillgrent
221             {
222             my $grNam = $_[0];
223             my %grInfo;
224             unless( Win32API::Net::GroupGetInfo( "", $grNam, 2, \%grInfo ) )
225             {
226             Win32API::Net::GroupGetInfo( "", $grNam, 3, \%grInfo )
227             or die "GroupGetInfo failed $^E";
228             $grInfo{groupId} = $1 if( $grInfo{groupSid} =~ m/-(\d+)$/ );
229             }
230             my @grent = ( $grInfo{name}, undef, $grInfo{groupId} );
231             my @grusers;
232             Win32API::Net::GroupGetUsers( "", $grNam, \@grusers )
233             or die "GroupGetUsers failed $^E";
234             push( @grent, join( ' ', @grusers ) );
235             return \@grent;
236             }
237            
238             sub _fillgrents
239             {
240             my @groupNames;
241             Win32API::Net::GroupEnum( "", \@groupNames )
242             or die "GroupEnum failed: $^E";
243             my @grents;
244             foreach my $groupName (@groupNames)
245             {
246             my $grent = _fillgrent($groupName);
247             push( @grents, $grent );
248             }
249             return \@grents;
250             }
251            
252             my $grents;
253             my $grents_pos;
254            
255             sub getgrent
256             {
257             unless( "ARRAY" eq ref($grents) )
258             {
259             $grents = _fillgrents();
260             }
261             defined $grents_pos or $grents_pos = 0;
262             my @grent = @{$grents->[$grents_pos++]} if( $grents_pos < scalar(@$grents) );
263             return wantarray ? @grent : $grent[2];
264             }
265            
266             sub setgrent { $grents_pos = undef; }
267            
268             sub endgrent { $grents = $grents_pos = undef; }
269            
270             sub getgrnam
271             {
272             my $groupName = $_[0];
273             my $grent = _fillgrent( $groupName );
274             return wantarray ? @$grent : $grent->[2];
275             }
276            
277             sub getgrgid
278             {
279             my $gid = $_[0];
280             my $grents = _fillgrents();
281             my @gid_grents = grep { $gid == $_->[2] } @$grents;
282             my @grent = @{$gid_grents[0]} if( 1 <= scalar(@gid_grents) );
283             return wantarray ? @grent : $grent[0];
284             }
285            
286             =head1 AUTHOR
287            
288             Jens Rehsack, C<< >>
289            
290             =head1 BUGS AND LIMITATIONS
291            
292             Win32::pwent uses the LAN manager interface, so it might be possible that
293             users and groups from Active Directory are not recognized.
294            
295             All functions provided by Win32::pwent are pure perl functions, so they
296             don't provide the additional features the core functions provide, because
297             the core implementation handles them as operators.
298            
299             If you think you've found a bug then please also read "How to Report Bugs
300             Effectively" by Simon Tatham:
301             L.
302            
303             Please report any bugs or feature requests to
304             C, or through the web interface at
305             L. I will be
306             notified, and then you'll automatically be notified of progress on your
307             bug as I make changes.
308            
309             =head1 SUPPORT
310            
311             You can find documentation for this module with the perldoc command.
312            
313             perldoc Win32::pwent
314            
315             You can also look for information at:
316            
317             =over 4
318            
319             =item * RT: CPAN's request tracker
320            
321             L
322            
323             =item * AnnoCPAN: Annotated CPAN documentation
324            
325             L
326            
327             =item * CPAN Ratings
328            
329             L
330            
331             =item * Search CPAN
332            
333             L
334            
335             =back
336            
337             Please recognize that the development of Open Source is done in free time of
338             volunteers.
339            
340             =head1 ACKNOWLEDGEMENTS
341            
342             Jan Dubios from ActiveState who helped me through the required patches for
343             L and give a lot feedback regarding compatibility.
344            
345             =head1 LICENSE AND COPYRIGHT
346            
347             Copyright (c) 2010 Jens Rehsack.
348            
349             This program is free software; you can redistribute it and/or modify it
350             under the terms of either: the GNU General Public License as published
351             by the Free Software Foundation; or the Artistic License.
352            
353             See http://dev.perl.org/licenses/ for more information.
354            
355             =cut
356            
357             1; # End of Win32::pwent