Handle hostnames with upper-case letters
[webmin.git] / passwd / passwd-lib.pl
1 =head1 passwd-lib.pl
2
3 Functions to support the change passwords module. Some example code :
4
5  foreign_require('passwd', 'passwd-lib.pl');
6  $user = passwd::find_user('joe');
7  if ($user) {
8    passwd::change_password($user, 'smeg', 0);
9  }
10
11 =cut
12
13 BEGIN { push(@INC, ".."); };
14 use WebminCore;
15 &init_config();
16 %access = &get_module_acl();
17
18 =head2 can_edit_passwd(&user)
19
20 Returns 1 if the current Webmin user can change the password for the Unix
21 user whose details are in the given hash ref, which is in the format returned
22 by useradmin::list_users.
23
24 =cut
25 sub can_edit_passwd
26 {
27 if ($access{'mode'} == 0) {
28         # Can change any
29         return 1;
30         }
31 elsif ($access{'mode'} == 3) {
32         # Only own password
33         return $_[0]->[0] eq $remote_user;
34         }
35 elsif ($access{'mode'} == 4) {
36         # UID within range
37         return (!$access{'low'} || $_[0]->[2] >= $access{'low'}) &&
38                (!$access{'high'} || $_[0]->[2] <= $access{'high'});
39         }
40 elsif ($access{'mode'} == 5) {
41         # Member of some group (except for exclusion list)
42         return 0 if (&indexof($_[0]->[0],
43                               split(/\s+/, $access{'notusers'})) >= 0);
44         local $g = getgrgid($_[0]->[3]);
45         return 1 if (&indexof($g, split(/\s+/, $access{'users'})) >= 0);
46         if ($access{'sec'}) {
47                 local $gname;
48                 foreach $gname (split(/\s+/, $access{'users'})) {
49                         local @g = getgrnam($gname);
50                         return 1 if (&indexof($_[0]->[0],
51                                               split(/\s+/, $g[3])) >= 0);
52                         }
53                 }
54         return 0;
55         }
56 elsif ($access{'mode'} == 6) {
57         # Users matching regexp
58         return $_[0]->[0] =~ /$access{'users'}/;
59         }
60 else {
61         # Users on / not on some list
62         local $idx = &indexof($_[0]->[0], split(/\s+/, $access{'users'}));
63         return $access{'mode'} == 1 && $idx >= 0 ||
64                $access{'mode'} == 2 && $idx < 0;
65         }
66 }
67
68 =head2 find_user(name)
69
70 Looks up the user structure for some name, in the useradmin, ldap-useradmin
71 and nis modules, and returns it.
72
73 =cut
74 sub find_user
75 {
76 local $mod;
77 foreach $mod ([ "useradmin", "user-lib.pl" ],
78               [ "ldap-useradmin", "ldap-useradmin-lib.pl" ],
79 #             [ "nis", "nis-lib.pl" ],
80              ) {
81         next if (!&foreign_installed($mod->[0], 1));
82         &foreign_require($mod->[0], $mod->[1]);
83         local @ulist = &foreign_call($mod->[0], "list_users");
84         local ($user) = grep { $_->{'user'} eq $_[0] } @ulist;
85         if ($user) {
86                 $user->{'mod'} = $mod->[0];
87                 return $user;
88                 }
89         }
90 return undef;
91 }
92
93 =head2 change_password(&user, pass, do-others)
94
95 Updates a user's password. The required parameters are :
96
97 =item user - A hash ref of user details, in the format supplied by find_user.
98
99 =item pass - The new password, in plain text.
100
101 =item do-others - If set to 1, the password is changed in other Webmin modules too.
102
103 =cut
104 sub change_password
105 {
106 local ($user, $pass, $others) = @_;
107 local $mod = $user->{'mod'} || "useradmin";
108 local $pft = $mod eq "useradmin" ? &useradmin::passfiles_type() :
109              $mod eq "ldap-useradmin" ? 1 : 0;
110
111 # Do the change!
112 $user->{'olduser'} = $user->{'user'};
113 $user->{'pass'} = &foreign_call($mod, "encrypt_password", $pass);
114 $user->{'passmode'} = 3;
115
116 # Modification ALain De Witte - on change of the password set
117 # ADMCHG flag for AIX
118 $user->{'admchg'} = 1;
119
120 $user->{'plainpass'} = $pass;
121 if ($pft == 2 || $pft == 5) {
122         if ($in{'expire'}) {
123                 $user->{'change'} = 0;
124                 }
125         else {
126                 $user->{'change'} = int(time() / (60*60*24));
127                 }
128         }
129 elsif ($pft == 4) {
130         $user->{'change'} = time();
131         }
132 &foreign_call($mod, "lock_user_files");
133 &foreign_call($mod, "set_user_envs", $user, 'MODIFY_USER',
134               $in{'new'});
135 &foreign_call($mod, "making_changes");
136 &foreign_call($mod, "modify_user", $user, $user);
137 &foreign_call($mod, "made_changes");
138 &foreign_call($mod, "unlock_user_files");
139 if ($others) {
140         &foreign_call($mod, "other_modules",
141                       "useradmin_modify_user", $user);
142         }
143 }
144
145 1;
146