Ticket #50421: patch-rename-server-keytab-backend.diff
File patch-rename-server-keytab-backend.diff, 17.1 KB (added by akkornel (A. Karl Kornel), 8 years ago) |
---|
-
deleted file server/keytab-backend
+ - 1 #!/usr/bin/perl2 #3 # Extract keytabs from the KDC without changing the key.4 #5 # This is a remctl backend that extracts existing keys from a KDC database6 # using kadmin.local. It requires a patched version of kadmin.local that7 # supports the -norandkey option. It expects a configuration file in8 # /etc/krb5kdc/allow-extract that contains a list of regexes, one per line,9 # matching principals that may be extracted in this fashion. (Generally you10 # do not want to list user principals here.) It also expects to be able to11 # write to a directory named /var/lib/keytabs; that's where it puts the12 # keytabs temporarily before sending them back to via remctl.13 #14 # remctl should handle authorization restrictions on this script. It doesn't15 # do any additional authorization checks itself.16 #17 # The keytab for the extracted principal will be printed to standard output.18 19 use 5.008;20 use strict;21 use warnings;22 23 use Sys::Syslog qw(openlog syslog);24 25 # Path to configuration file listing principals that may be extracted.26 our $CONFIG = '/etc/krb5kdc/allow-extract';27 28 # The full path to a kadmin.local that supports -norandkey.29 our $KADMIN = '/usr/sbin/kadmin.local';30 31 # A temporary area into which keytabs should be written.32 our $TMP = '/var/lib/keytabs';33 34 # Set to zero to suppress syslog logging, which is used only for testing. Set35 # to a reference to a string to append messages to that string instead.36 our $SYSLOG;37 $SYSLOG = 1 unless defined $SYSLOG;38 39 ##############################################################################40 # Logging41 ##############################################################################42 43 # Initialize logging.44 sub log_init {45 if (ref $SYSLOG) {46 $$SYSLOG = '';47 } elsif ($SYSLOG) {48 openlog ('keytab-backend', 'pid', 'auth');49 }50 }51 52 # Log a failure message to both syslog and to stderr and exit with a non-zero53 # status.54 sub error {55 my $message = join ('', @_);56 if (ref $SYSLOG) {57 $$SYSLOG .= $message . "\n";58 } elsif ($SYSLOG) {59 syslog ('err', '%s', $message);60 }61 die "keytab-backend: $message\n";62 }63 64 # Log a regular message, generally for success.65 sub info {66 my $message = join ('', @_);67 if (ref $SYSLOG) {68 $$SYSLOG .= $message . "\n";69 } elsif ($SYSLOG) {70 syslog ('info', '%s', $message);71 }72 }73 74 ##############################################################################75 # Implementation76 ##############################################################################77 78 # Check and download the keytab. This is in a subroutine call for easier79 # testing. We separately log actions unless $SYSLOG is set to 0. remctld80 # keeps some logs, but it won't tell us whether the download is successful or81 # not.82 sub download {83 my (@args) = @_;84 log_init;85 86 # Set up a default identity if run from the command line.87 $ENV{REMOTE_USER} = getpwnam ($<) || 'UNKNOWN' unless $ENV{REMOTE_USER};88 89 # Read the regexes of valid principals into memory.90 open (CONFIG, '<', $CONFIG) or error "cannot open $CONFIG: $!";91 my @valid;92 while (<CONFIG>) {93 next if /^\s*\#/;94 next if /^\s*$/;95 s/^\s+//;96 s/\s+$//;97 s/\s*\#.*//;98 push (@valid, qr/$_/);99 }100 close CONFIG;101 102 # The first argument will be the remctl service, so skip it.103 if (@args == 2) {104 shift @args;105 }106 if (@args != 1) {107 error "invalid arguments: @args";108 }109 my $principal = $args[0];110 111 # Ensure that we're allowed to retrieve this principal.112 unless ($principal =~ m%^[\w-]+(?:/[\w.-]+)?\@[\w.-]+\z%) {113 error "bad principal name $principal";114 }115 my $okay;116 for my $regex (@valid) {117 if ($principal =~ /$regex/) {118 $okay = 1;119 last;120 }121 }122 unless ($okay) {123 error "permission denied: $ENV{REMOTE_USER} may not retrieve"124 . " $principal";125 }126 127 # Do the actual work.128 my $filename = "$TMP/keytab$$";129 my $command = "ktadd -k $filename -q -norandkey $principal";130 my $output = `$KADMIN -q '$command' 2>&1`;131 if ($? != 0) {132 my $status = ($? >> 8);133 warn $output;134 error "retrieve of $principal failed for $ENV{REMOTE_USER}:"135 . " kadmin.local exited with status $status";136 }137 open (KEYTAB, '<', $filename)138 or error "cannot open temporary keytab $filename: $!";139 print while <KEYTAB>;140 close KEYTAB;141 unlink $filename;142 info ("keytab $principal retrieved by $ENV{REMOTE_USER}");143 }144 download (@ARGV);145 __END__146 147 ##############################################################################148 # Documentation149 ##############################################################################150 151 =for stopwords152 keytab-backend keytabs KDC keytab kadmin.local -norandkey ktadd remctld153 auth Allbery rekeying MERCHANTABILITY NONINFRINGEMENT sublicense154 kadmin.local.155 156 =head1 NAME157 158 keytab-backend - Extract keytabs from the KDC without changing the key159 160 =head1 SYNOPSIS161 162 B<keytab-backend> retrieve I<principal>163 164 =head1 DESCRIPTION165 166 B<keytab-backend> retrieves a keytab for an existing principal from the167 KDC database without changing the current key. It allows generation of a168 keytab for a service without rekeying that service. It requires a169 B<kadmin.local> patched to support the B<-norandkey> option to B<ktadd>.170 171 This script is intended to run under B<remctld>. On success, it prints172 the keytab to standard output, logs a success message to syslog (facility173 auth, priority info), and exits with status 0. On failure, it prints out174 an error message, logs an error to syslog (facility auth, priority err),175 and exits with a non-zero status.176 177 The principal is checked for basic sanity (only accepting alphanumerics,178 C<_>, and C<-> with an optional instance and then only alphanumerics,179 C<_>, C<->, and C<.> in the realm) and then checked against a180 configuration file that lists regexes of principals that can be retrieved.181 When deploying this software, limit as tightly as possible which182 principals can be downloaded in this fashion. Generally only shared183 service principals used on multiple systems should be made available in184 this way.185 186 B<keytab-backend> does not do any authorization checks. Those should be187 done by B<remctld> before it is called.188 189 =head1 FILES190 191 =over 4192 193 =item F</etc/krb5kdc/allow-extract>194 195 The configuration file that controls which principals can have their196 keytabs retrieved. Blank lines and lines starting with C<#>, as well as197 anything after C<#> on a line, are ignored. All other lines should be198 Perl regular expressions, one per line, that match principals whose199 keytabs can be retrieved by B<keytab-backend>. Any principal that does200 not match one of those regular expressions cannot be retrieved.201 202 =item F</var/lib/keytabs>203 204 The temporary directory used for creating keytabs. B<keytab-backend> will205 create the keytab in this directory, make sure that was successful, and206 then delete the temporary file after the results have been sent to207 standard output.208 209 =back210 211 =head1 AUTHOR212 213 Russ Allbery <eagle@eyrie.org>214 215 =head1 COPYRIGHT AND LICENSE216 217 Copyright 2006, 2007, 2008, 2010, 2013 The Board of Trustees of the Leland218 Stanford Junior University219 220 Permission is hereby granted, free of charge, to any person obtaining a221 copy of this software and associated documentation files (the "Software"),222 to deal in the Software without restriction, including without limitation223 the rights to use, copy, modify, merge, publish, distribute, sublicense,224 and/or sell copies of the Software, and to permit persons to whom the225 Software is furnished to do so, subject to the following conditions:226 227 The above copyright notice and this permission notice shall be included in228 all copies or substantial portions of the Software.229 230 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR231 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,232 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL233 THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER234 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING235 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER236 DEALINGS IN THE SOFTWARE.237 238 =head1 SEE ALSO239 240 kadmin.local(8), remctld(8)241 242 This program is part of the wallet system. The current version is243 available from L<http://www.eyrie.org/~eagle/software/wallet/>.244 245 =cut -
new file server/keytab-backend.in
- + 1 #!@PERL@ 2 # 3 # Extract keytabs from the KDC without changing the key. 4 # 5 # This is a remctl backend that extracts existing keys from a KDC database 6 # using kadmin.local. It requires a patched version of kadmin.local that 7 # supports the -norandkey option. It expects a configuration file in 8 # /etc/krb5kdc/allow-extract that contains a list of regexes, one per line, 9 # matching principals that may be extracted in this fashion. (Generally you 10 # do not want to list user principals here.) It also expects to be able to 11 # write to a directory named /var/lib/keytabs; that's where it puts the 12 # keytabs temporarily before sending them back to via remctl. 13 # 14 # remctl should handle authorization restrictions on this script. It doesn't 15 # do any additional authorization checks itself. 16 # 17 # The keytab for the extracted principal will be printed to standard output. 18 19 use 5.008; 20 use strict; 21 use warnings; 22 23 use Sys::Syslog qw(openlog syslog); 24 25 # Path to configuration file listing principals that may be extracted. 26 our $CONFIG = '/etc/krb5kdc/allow-extract'; 27 28 # The full path to a kadmin.local that supports -norandkey. 29 our $KADMIN = '/usr/sbin/kadmin.local'; 30 31 # A temporary area into which keytabs should be written. 32 our $TMP = '/var/lib/keytabs'; 33 34 # Set to zero to suppress syslog logging, which is used only for testing. Set 35 # to a reference to a string to append messages to that string instead. 36 our $SYSLOG; 37 $SYSLOG = 1 unless defined $SYSLOG; 38 39 ############################################################################## 40 # Logging 41 ############################################################################## 42 43 # Initialize logging. 44 sub log_init { 45 if (ref $SYSLOG) { 46 $$SYSLOG = ''; 47 } elsif ($SYSLOG) { 48 openlog ('keytab-backend', 'pid', 'auth'); 49 } 50 } 51 52 # Log a failure message to both syslog and to stderr and exit with a non-zero 53 # status. 54 sub error { 55 my $message = join ('', @_); 56 if (ref $SYSLOG) { 57 $$SYSLOG .= $message . "\n"; 58 } elsif ($SYSLOG) { 59 syslog ('err', '%s', $message); 60 } 61 die "keytab-backend: $message\n"; 62 } 63 64 # Log a regular message, generally for success. 65 sub info { 66 my $message = join ('', @_); 67 if (ref $SYSLOG) { 68 $$SYSLOG .= $message . "\n"; 69 } elsif ($SYSLOG) { 70 syslog ('info', '%s', $message); 71 } 72 } 73 74 ############################################################################## 75 # Implementation 76 ############################################################################## 77 78 # Check and download the keytab. This is in a subroutine call for easier 79 # testing. We separately log actions unless $SYSLOG is set to 0. remctld 80 # keeps some logs, but it won't tell us whether the download is successful or 81 # not. 82 sub download { 83 my (@args) = @_; 84 log_init; 85 86 # Set up a default identity if run from the command line. 87 $ENV{REMOTE_USER} = getpwnam ($<) || 'UNKNOWN' unless $ENV{REMOTE_USER}; 88 89 # Read the regexes of valid principals into memory. 90 open (CONFIG, '<', $CONFIG) or error "cannot open $CONFIG: $!"; 91 my @valid; 92 while (<CONFIG>) { 93 next if /^\s*\#/; 94 next if /^\s*$/; 95 s/^\s+//; 96 s/\s+$//; 97 s/\s*\#.*//; 98 push (@valid, qr/$_/); 99 } 100 close CONFIG; 101 102 # The first argument will be the remctl service, so skip it. 103 if (@args == 2) { 104 shift @args; 105 } 106 if (@args != 1) { 107 error "invalid arguments: @args"; 108 } 109 my $principal = $args[0]; 110 111 # Ensure that we're allowed to retrieve this principal. 112 unless ($principal =~ m%^[\w-]+(?:/[\w.-]+)?\@[\w.-]+\z%) { 113 error "bad principal name $principal"; 114 } 115 my $okay; 116 for my $regex (@valid) { 117 if ($principal =~ /$regex/) { 118 $okay = 1; 119 last; 120 } 121 } 122 unless ($okay) { 123 error "permission denied: $ENV{REMOTE_USER} may not retrieve" 124 . " $principal"; 125 } 126 127 # Do the actual work. 128 my $filename = "$TMP/keytab$$"; 129 my $command = "ktadd -k $filename -q -norandkey $principal"; 130 my $output = `$KADMIN -q '$command' 2>&1`; 131 if ($? != 0) { 132 my $status = ($? >> 8); 133 warn $output; 134 error "retrieve of $principal failed for $ENV{REMOTE_USER}:" 135 . " kadmin.local exited with status $status"; 136 } 137 open (KEYTAB, '<', $filename) 138 or error "cannot open temporary keytab $filename: $!"; 139 print while <KEYTAB>; 140 close KEYTAB; 141 unlink $filename; 142 info ("keytab $principal retrieved by $ENV{REMOTE_USER}"); 143 } 144 download (@ARGV); 145 __END__ 146 147 ############################################################################## 148 # Documentation 149 ############################################################################## 150 151 =for stopwords 152 keytab-backend keytabs KDC keytab kadmin.local -norandkey ktadd remctld 153 auth Allbery rekeying MERCHANTABILITY NONINFRINGEMENT sublicense 154 kadmin.local. 155 156 =head1 NAME 157 158 keytab-backend - Extract keytabs from the KDC without changing the key 159 160 =head1 SYNOPSIS 161 162 B<keytab-backend> retrieve I<principal> 163 164 =head1 DESCRIPTION 165 166 B<keytab-backend> retrieves a keytab for an existing principal from the 167 KDC database without changing the current key. It allows generation of a 168 keytab for a service without rekeying that service. It requires a 169 B<kadmin.local> patched to support the B<-norandkey> option to B<ktadd>. 170 171 This script is intended to run under B<remctld>. On success, it prints 172 the keytab to standard output, logs a success message to syslog (facility 173 auth, priority info), and exits with status 0. On failure, it prints out 174 an error message, logs an error to syslog (facility auth, priority err), 175 and exits with a non-zero status. 176 177 The principal is checked for basic sanity (only accepting alphanumerics, 178 C<_>, and C<-> with an optional instance and then only alphanumerics, 179 C<_>, C<->, and C<.> in the realm) and then checked against a 180 configuration file that lists regexes of principals that can be retrieved. 181 When deploying this software, limit as tightly as possible which 182 principals can be downloaded in this fashion. Generally only shared 183 service principals used on multiple systems should be made available in 184 this way. 185 186 B<keytab-backend> does not do any authorization checks. Those should be 187 done by B<remctld> before it is called. 188 189 =head1 FILES 190 191 =over 4 192 193 =item F</etc/krb5kdc/allow-extract> 194 195 The configuration file that controls which principals can have their 196 keytabs retrieved. Blank lines and lines starting with C<#>, as well as 197 anything after C<#> on a line, are ignored. All other lines should be 198 Perl regular expressions, one per line, that match principals whose 199 keytabs can be retrieved by B<keytab-backend>. Any principal that does 200 not match one of those regular expressions cannot be retrieved. 201 202 =item F</var/lib/keytabs> 203 204 The temporary directory used for creating keytabs. B<keytab-backend> will 205 create the keytab in this directory, make sure that was successful, and 206 then delete the temporary file after the results have been sent to 207 standard output. 208 209 =back 210 211 =head1 AUTHOR 212 213 Russ Allbery <eagle@eyrie.org> 214 215 =head1 COPYRIGHT AND LICENSE 216 217 Copyright 2006, 2007, 2008, 2010, 2013 The Board of Trustees of the Leland 218 Stanford Junior University 219 220 Permission is hereby granted, free of charge, to any person obtaining a 221 copy of this software and associated documentation files (the "Software"), 222 to deal in the Software without restriction, including without limitation 223 the rights to use, copy, modify, merge, publish, distribute, sublicense, 224 and/or sell copies of the Software, and to permit persons to whom the 225 Software is furnished to do so, subject to the following conditions: 226 227 The above copyright notice and this permission notice shall be included in 228 all copies or substantial portions of the Software. 229 230 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 231 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 232 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 233 THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 234 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 235 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 236 DEALINGS IN THE SOFTWARE. 237 238 =head1 SEE ALSO 239 240 kadmin.local(8), remctld(8) 241 242 This program is part of the wallet system. The current version is 243 available from L<http://www.eyrie.org/~eagle/software/wallet/>. 244 245 =cut