diff options
author | Stephen Hemminger <stephen.hemminger@vyatta.com> | 2010-01-26 17:53:07 -0800 |
---|---|---|
committer | Stephen Hemminger <stephen.hemminger@vyatta.com> | 2010-01-26 17:53:07 -0800 |
commit | 9b212208f79329273e84b28560604011662fed75 (patch) | |
tree | 88f2f13dd8778e1e05e9f928730d4bf8f912848e | |
parent | bc572039bdf355c1d0dfdcde974a55ea392092f1 (diff) | |
parent | b5bb8c35539d1b108e988d39153abc813c326b0f (diff) | |
download | vyatta-cfg-system-9b212208f79329273e84b28560604011662fed75.tar.gz vyatta-cfg-system-9b212208f79329273e84b28560604011662fed75.zip |
Merge branch 'kenwood' of 192.168.100.1:git/vyatta-cfg-system into kenwood
-rw-r--r-- | Makefile.am | 1 | ||||
-rwxr-xr-x | lib/Vyatta/Login/User.pm | 261 | ||||
-rw-r--r-- | scripts/system/vyatta_check_username.pl | 66 | ||||
-rw-r--r-- | templates/system/login/user/node.def | 8 |
4 files changed, 193 insertions, 143 deletions
diff --git a/Makefile.am b/Makefile.am index d284bfd4..8d738067 100644 --- a/Makefile.am +++ b/Makefile.am @@ -23,6 +23,7 @@ sbin_SCRIPTS += scripts/install-system sbin_SCRIPTS += scripts/vyatta-grub-setup sbin_SCRIPTS += scripts/standalone_root_pw_reset sbin_SCRIPTS += scripts/vyatta-passwd-sync +sbin_SCRIPTS += scripts/system/vyatta_check_username.pl sbin_SCRIPTS += scripts/system/vyatta_update_login.pl sbin_SCRIPTS += scripts/system/vyatta_update_logrotate.pl sbin_SCRIPTS += scripts/system/vyatta_update_resolv.pl diff --git a/lib/Vyatta/Login/User.pm b/lib/Vyatta/Login/User.pm index b0c0381c..383978e4 100755 --- a/lib/Vyatta/Login/User.pm +++ b/lib/Vyatta/Login/User.pm @@ -35,42 +35,25 @@ my %reasons = ( 13 => 'canĀ“t create mail spool', ); -# Construct a map from existing users to group membership -sub get_groups { - my %group_map; - - setgrent(); - while ( my ( $name, undef, undef, $members ) = getgrent() ) { - foreach my $user ( split / /, $members ) { - $group_map{$user} = [] unless ( $group_map{$user} ); - my $g = $group_map{$user}; - push @$g, $name; - } - } - endgrent(); - - return \%group_map; -} - my $levelFile = "/opt/vyatta/etc/level"; # Convert level to additional groups -sub _level2groups { +sub _level_groups { my $level = shift; my @groups; - open (my $f, '<', $levelFile) - or return; + open( my $f, '<', $levelFile ) + or return; while (<$f>) { - chomp; - next unless $_; - - my ($l, $g) = split /:/; - if ($l eq $level) { - @groups = split(/,/, $g); - last; - } + chomp; + next unless $_; + + my ( $l, $g ) = split /:/; + if ( $l eq $level ) { + @groups = split( /,/, $g ); + last; + } } close $f; return @groups; @@ -83,14 +66,14 @@ my $protected_users = '/opt/vyatta/etc/protected-user'; sub _protected_users { my @protected; - open my $pfd, '<', $protected_users - or return; + open my $pfd, '<', $protected_users + or return; while (<$pfd>) { - chomp; - next unless $_; + chomp; + next unless $_; - push @protected, $_; + push @protected, $_; } close($pfd); return @protected; @@ -101,19 +84,20 @@ sub _vyatta_users { my @vusers; setpwent(); + # ($name,$passwd,$uid,$gid,$quota,$comment,$gcos,$dir,$shell,$expire) # = getpw* while ( my ($name, undef, undef, undef, undef, undef, undef, undef, $shell) = getpwent() ) { - push @vusers, $name if ($shell eq '/bin/vbash'); + push @vusers, $name if ( $shell eq '/bin/vbash' ); } endpwent(); return @vusers; } -sub set_authorized_keys { - my $user = shift; +sub _authorized_keys { + my $user = shift; my $config = new Vyatta::Config; $config->setLevel("system login user $user authentication public-keys"); @@ -122,143 +106,138 @@ sub set_authorized_keys { # ($name,$passwd,$uid,$gid,$quota,$comment,$gcos,$dir,$shell,$expire) # = getpw* - my (undef, undef, $uid, $gid, undef, undef, undef, $home) - = getpwnam($user); + my ( undef, undef, $uid, $gid, undef, undef, undef, $home ) = + getpwnam($user); return unless $home; return unless -d $home; my $sshdir = "$home/.ssh"; - unless (-d $sshdir) { - mkdir $sshdir; - chown ($uid, $gid, $sshdir); - chmod (0750, $sshdir); + unless ( -d $sshdir ) { + mkdir $sshdir; + chown( $uid, $gid, $sshdir ); + chmod( 0750, $sshdir ); } - open (my $auth, '>', "$sshdir/authorized_keys"); + open( my $auth, '>', "$sshdir/authorized_keys" ); unless ($auth) { - warn "open $sshdir/authorized_keys failed: $!"; - return; + warn "open $sshdir/authorized_keys failed: $!"; + return; } print {$auth} "# Automatically generated by Vyatta configuration\n"; print {$auth} "# Do not edit, all changes will be lost\n"; foreach my $name (@keys) { - my $type = $config->returnValue("$name type"); - my $key = $config->returnValue("$name key"); - print {$auth} "$type $key $name\n"; + my $type = $config->returnValue("$name type"); + my $key = $config->returnValue("$name key"); + print {$auth} "$type $key $name\n"; } close $auth; - chmod (0640, "$sshdir/authorized_keys"); + chmod( 0640, "$sshdir/authorized_keys" ); +} + +sub _delete_user { + my $user = shift; + + if ( $user eq 'root' ) { + warn "Disabling root account, instead of deleting\n"; + system('sudo usermod -p ! root') == 0 + or die "usermod of root failed: $?\n"; + } elsif ( getlogin() eq $user ) { + die "Attempting to delete current user: $user\n"; + } else { + # This logs out user (so we can delete it) + system("sudo pkill -u $user"); + + system("sudo userdel -r '$user'") == 0 + or die "userdel of $user failed: $?\n"; + } +} + +sub _update_user { + my $user = shift; + my $cfg = new Vyatta::Config; + + $cfg->setLevel("system login user $user"); + my $pwd = $cfg->returnValue('authentication encrypted-password'); + my $level = $cfg->returnValue('level'); + my $fname = $cfg->returnValue('full-name'); + my $home = $cfg->returnValue('home-directory'); + + unless ($pwd) { + warn "Encrypted password not in configuration for $user"; + return; + } + + unless ($level) { + warn "Level not defined for $user"; + return; + } + + # map level to group membership + my @groups = _level_groups($level); + + # add any additional groups from configuration + push( @groups, $cfg->returnValues('group') ); + + # Read existing settings + my $uid = getpwnam($user); + + # not found in existing passwd, must be new + my $cmd; + unless ( defined($uid) ) { + # make new user using vyatta shell + # and make home directory (-m) + # and with default group of 100 (users) + $cmd = 'useradd -s /bin/vbash -m -N'; + } else { + # update existing account + # NB: can't skip because can't read original password + $cmd = "usermod"; + } + + $cmd .= " -p '$pwd'"; + $cmd .= " -c \"$fname\"" if ( defined $fname ); + $cmd .= " -d \"$home\"" if ( defined $home ); + $cmd .= ' -G ' . join( ',', @groups ); + system("sudo $cmd $user"); + + unless ( $? == 0 ) { + my $reason = $reasons{ ( $? >> 8 ) }; + die "Attempt to change user $user failed: $reason\n"; + } } sub update { - my $membership = get_groups(); - my $uconfig = new Vyatta::Config; + my $uconfig = new Vyatta::Config; $uconfig->setLevel("system login user"); - my %users = $uconfig->listNodeStatus(); + my %users = $uconfig->listNodeStatus(); die "All users deleted!\n" unless %users; foreach my $user ( keys %users ) { - my $state = $users{$user}; + my $state = $users{$user}; if ( $state eq 'deleted' ) { - if ($user eq 'root') { - warn "Disabling root account, instead of deleting\n"; - system ('sudo usermod -p ! root') == 0 - or die "usermod of root failed: $?\n"; - } elsif (getlogin() eq $user) { - die "Attempting to delete current user: $user\n"; - } else { - # This logs out user - system("sudo pkill -u $user"); - - system("sudo userdel -r '$user'") == 0 - or die "userdel of $user failed: $?\n"; - } - next; + _delete_user($user); + next; } - next unless ($state eq 'added' || $state eq 'changed'); - - $uconfig->setLevel("system login user $user"); - my $pwd = $uconfig->returnValue('authentication encrypted-password'); - - unless ($pwd) { - warn "Encrypted password not in configuration for $user"; - next; - } - - my $level = $uconfig->returnValue('level'); - unless ($level) { - warn "Level not defined for $user"; - next; - } - - # map level to group membership - my @new_groups = _level2groups($level); - - # add any additional groups from configuration - push( @new_groups, $uconfig->returnValues('group') ); - - my $fname = $uconfig->returnValue('full-name'); - my $home = $uconfig->returnValue('home-directory'); - - # Read existing settings - my (undef, $opwd, $uid, $gid, undef, $comment, - undef, $dir, $shell, undef) = getpwnam($user); - - my $old_groups = $membership->{$user}; - - my $og_str = (defined($old_groups)) - ? (join(' ', sort @$old_groups)) : ''; - my $ng_str = join(' ', sort @new_groups); - - # not found in existing passwd, must be new - my $cmd; - unless ( defined($uid) ) { - # make new user using vyatta shell - # and make home directory (-m) - # and with default group of 100 (users) - $cmd = 'useradd -s /bin/vbash -m -N'; - } else { - if ($opwd eq $pwd - && ( !$fname || $fname eq $comment ) - && ( !$home || $home eq $dir ) - && $og_str eq $ng_str) { - # If no part of password or group file changed - # then there is nothing to do here. - } else { - $cmd = "usermod"; - } - } - - if ($cmd) { - $cmd .= " -p '$pwd'"; - $cmd .= " -c \"$fname\"" if ( defined $fname ); - $cmd .= " -d \"$home\"" if ( defined $home ); - $cmd .= ' -G ' . join( ',', @new_groups ); - system("sudo $cmd $user"); - - unless ( $? == 0 ) { - my $reason = $reasons{ ( $? >> 8 ) }; - die "Attempt to change user $user failed: $reason\n"; - } - } - - set_authorized_keys($user); + next unless ( $state eq 'added' || $state eq 'changed' ); + + _update_user($user); + _authorized_keys($user); } # Remove any vyatta users that do not exist in current configuration # This can happen if user added but configuration not saved my %protected = map { $_ => 1 } _protected_users(); - foreach my $user (_vyatta_users()) { - next if $protected{$user}; - next if defined $users{$user}; + foreach my $user ( _vyatta_users() ) { + next if $protected{$user}; + next if defined $users{$user}; - warn "User $user not listed in current configuration\n"; - system ("sudo userdel --remove $user") == 0 - or die "Attempt to delete user $user failed: $!"; + warn "User $user not listed in current configuration\n"; + system("sudo userdel --remove $user") == 0 + or die "Attempt to delete user $user failed: $!"; } } diff --git a/scripts/system/vyatta_check_username.pl b/scripts/system/vyatta_check_username.pl new file mode 100644 index 00000000..254b3417 --- /dev/null +++ b/scripts/system/vyatta_check_username.pl @@ -0,0 +1,66 @@ +#!/usr/bin/perl + +# **** License **** +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# This code was originally developed by Vyatta, Inc. +# Portions created by Vyatta are Copyright (C) 2010 Vyatta, Inc. +# All Rights Reserved. +# +# **** End License **** + +use strict; +use warnings; + +my $passwdFile = '/etc/passwd'; + +# Lookup user in password file which may not give same +# result as getpw* which uses NSS +sub finduser { + my $user = shift; + my $uid; + + open( my $f, '<', $passwdFile ) + or die "Can't open $passwdFile: $!"; + + while (<$f>) { + chomp; + my ( $name, undef, $id ) = split /:/; + + next unless ( $name eq $user ); + $uid = $id; + last; + } + close $f; + + return $uid; +} + +foreach my $user (@ARGV) { + my $uid = getpwnam($user); + + # User does not exist in system, its okay + next unless defined($uid); + + # System accounts should not be listed in vyatta configuration + # 1000 is SYS_UID_MIN + die "$user : account is already reserved for system use\n" + if ($uid > 0 && $uid < 1000); + + my $pwuid = finduser($user); + + die "$user : account exists but is not local (change on server)\n" + unless defined ($pwuid); + + die "$user : exists but has different uid on local versus remote\n" + unless ($pwuid eq $uid); +} + +exit 0; diff --git a/templates/system/login/user/node.def b/templates/system/login/user/node.def index d23a397f..751767d6 100644 --- a/templates/system/login/user/node.def +++ b/templates/system/login/user/node.def @@ -1,9 +1,13 @@ tag: type: txt help: Set user account information + +syntax:expression: pattern $VAR(@) "^[a-zA-Z_][a-zA-Z0-9_-]*\\$?$" + ; "invalid user name $VAR(@)" + +syntax:expression: exec "/opt/vyatta/sbin/vyatta_check_username.pl $VAR(@)" + commit:expression: $VAR(authentication/encrypted-password) != "" || ($VAR(authentication/plaintext-password) != "" && $VAR(authentication/plaintext-password/@) != "") ; "user password must be specified" -syntax:expression: pattern $VAR(@) "^[a-zA-Z_][a-zA-Z0-9_-]*\\$?$" - ; "invalid user name $VAR(@)" |