Handle hostnames with upper-case letters
[webmin.git] / useradmin / macos-lib.pl
1 # freebsd-lib.pl
2 # Functions for freebsd format last output
3
4 $netinfo_domain = $config{'netinfo_domain'} || ".";
5
6 # Mapping from OSX user properties to Webmin user hash keys
7 %user_properties_map = (
8         'RecordName' => 'user',
9         'UniqueID' => 'uid',
10         'PrimaryGroupID' => 'gid',
11         'RealName' => 'real',
12         'NFSHomeDirectory' => 'home',
13         'UserShell' => 'shell',
14         );
15
16 # And to group hash keys
17 %group_properties_map = (
18         'RecordName' => 'group',
19         'PrimaryGroupID' => 'gid',
20         'GroupMembership' => 'members',
21         );
22
23 # passfiles_type()
24 # Returns 6 for macos netinfo user storage, 7 for new directory service
25 sub passfiles_type
26 {
27 if (-x "/usr/bin/nidump") {
28         # Old netinfo format users DB
29         return 6;
30         }
31 elsif (-x "/usr/bin/dscl") {
32         # New directory service DB
33         return 7;
34         }
35 else {
36         return 0;
37         }
38 }
39
40 # groupfiles_type()
41 # Returns 5 for macos netinfo group storage, 7 for new directory service
42 sub groupfiles_type
43 {
44 if (-x "/usr/bin/nidump") {
45         # Old netinfo format groups DB
46         return 5;
47         }
48 elsif (-x "/usr/bin/dscl") {
49         # New directory service DB
50         return 7;
51         }
52 else {
53         return 0;
54         }
55 }
56
57 # open_last_command(handle, user)
58 sub open_last_command
59 {
60 local ($fh, $user) = @_;
61 open($fh, "last $user |");
62 }
63
64 # read_last_line(handle)
65 # Parses a line of output from last into an array of
66 #  user, tty, host, login, logout, period
67 sub read_last_line
68 {
69 $fh = $_[0];
70 while(1) {
71         chop($line = <$fh>);
72         if (!$line) { return (); }
73         if ($line =~ /^(reboot|shutdown)/) { next; }
74         if ($line =~ /^(\S+)\s+(\S+)\s+(\S+)?\s+(\S+\s+\S+\s+\d+\s+\d+:\d+)\s+\-\s+(\S+)\s+\((\d+:\d+)\)/) {
75                 return ($1, $2, $3, $4, $5 eq "shutdown" ? "Shutdown" :
76                                         $5 eq "crash" ? "Crash" : $5, $6);
77                 }
78         elsif ($line =~ /^(\S+)\s+(\S+)\s+(\S+)?\s+(\S+\s+\S+\s+\d+\s+\d+:\d+)\s+still/) {
79                 return ($1, $2, $3, $4);
80                 }
81         }
82 }
83
84 # execute_dscl_command(command, arg, ...)
85 # Executes some batch command with dscl, and calls error on failure
86 sub execute_dscl_command
87 {
88 local ($cmd, @args) = @_;
89 local $fullcmd = "dscl '$netinfo_domain' ".quotemeta($cmd);
90 foreach my $a (@args) {
91         $fullcmd .= " ".($a eq '' ? "''" : quotemeta($a));
92         }
93 local $out = &backquote_command("$fullcmd 2>&1 </dev/null");
94 if ($?) {
95         &error("<tt>".&html_escape($fullcmd)."</tt> failed : ".
96                "<tt>".&html_escape($out)."</tt>");
97         }
98 return $out;
99 }
100
101 # get_macos_password_hash(uid)
102 # Given a user's ID, return the password hash. This is in SHA1 format, and the
103 # first 4 bytes are the salt
104 sub get_macos_password_hash
105 {
106 local ($uuid) = @_;
107 return undef if (!$uuid);
108 local $hashfile = &read_file_contents("/var/db/shadow/hash/$uuid");
109 if ($hashfile) {
110         return substr($hashfile, 169, 48);
111         }
112 return undef;
113 }
114
115 # set_macos_password_hash(uuid, hash)
116 # Updates the password hash for some OSX user
117 sub set_macos_password_hash
118 {
119 local ($uuid, $pass) = @_;
120 print STDERR "uuid=$uuid hash=$pass\n";
121 return 0 if (!$uuid);
122 local $hashfile = &read_file_contents("/var/db/shadow/hash/$uuid");
123 if ($hashfile) {
124         if (length($pass) > 48) {
125                 $pass = substr($pass, 0, 48);
126                 }
127         elsif (length($pass) < 48) {
128                 $pass .= ("0" x (48-length($pass)));
129                 }
130         substr($hashfile, 169, 48) = $pass;
131         &open_tempfile(HASHFILE, ">/var/db/shadow/hash/$uuid");
132         &print_tempfile(HASHFILE, $hashfile);
133         &close_tempfile(HASHFILE);
134         return 1;
135         }
136 return 0;
137 }
138
139 1;
140