summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStephen Hemminger <stephen.hemminger@vyatta.com>2010-01-26 17:53:07 -0800
committerStephen Hemminger <stephen.hemminger@vyatta.com>2010-01-26 17:53:07 -0800
commit9b212208f79329273e84b28560604011662fed75 (patch)
tree88f2f13dd8778e1e05e9f928730d4bf8f912848e
parentbc572039bdf355c1d0dfdcde974a55ea392092f1 (diff)
parentb5bb8c35539d1b108e988d39153abc813c326b0f (diff)
downloadvyatta-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.am1
-rwxr-xr-xlib/Vyatta/Login/User.pm261
-rw-r--r--scripts/system/vyatta_check_username.pl66
-rw-r--r--templates/system/login/user/node.def8
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(@)"