summaryrefslogtreecommitdiff
path: root/scripts/system/vyatta_update_login.pl
blob: d482c2975ba3fc4e2328d546e0fd596f792ed1e3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#!/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) 2007 Vyatta, Inc.
# All Rights Reserved.
#
# **** End License ****

use strict;
use lib "/opt/vyatta/share/perl5";
use Vyatta::Config;

# handle "user"
my $uconfig = new Vyatta::Config;
$uconfig->setLevel("system login user");

my %users     = $uconfig->listNodeStatus();
my @user_keys = sort keys %users;

if (   ( scalar(@user_keys) <= 0 )
    || !( grep /^root$/, @user_keys )
    || ( $users{'root'} eq 'deleted' ) )
{
    # root is deleted
    die "User \"root\" cannot be deleted\n";
}

# Exit codes form useradd.8 man page
my %reasons = (
    0  => 'success',
    1  => 'can´t update password file',
    2  => 'invalid command syntax',
    3  => 'invalid argument to option',
    4  => 'UID already in use (and no -o)',
    6  => 'specified group doesn´t exist',
    9  => 'username already in use',
    10 => 'can´t update group file',
    12 => 'can´t create home directory',
    13 => 'can´t create mail spool',
);

# Map of level to additional groups
my %level_map = (
    'admin'    => [ 'quaggavty', 'vyattacfg', 'sudo', 'adm', 'dip', 'disk'],
    'operator' => [ 'quaggavty', 'operator',  'adm', 'dip', ],
);

# Construct a map from existing users to group membership
# Use space seperated format
my %group_map;
while (my ($name, undef, undef, $members) = getgrent()) {
    foreach my $user (split / /,$members) {
	my $g = $group_map{$user};
	if ($g) {
	    my @l = split / /, $g;
	    push @l, $name;
	    $group_map{$user} = join(' ', sort @l);
	} else {
	    $group_map{$user} = $name;
	}

    }
}

# we have some users
for my $user (@user_keys) {
    if ( $users{$user} eq 'deleted' ) {
        system("sudo userdel -r '$user'") == 0
	    or die "userdel failed: $?\n"
    }
    elsif ( $users{$user} eq 'added' || $users{$user} eq 'changed' ) {
        $uconfig->setLevel("system login user $user");
        my $pwd  = $uconfig->returnValue('authentication encrypted-password');
	$pwd or die "Encrypted password not in configuration for $user";

        my $level  = $uconfig->returnValue('level');
	$level or die "Level not defined for $user";

	# map level to group membership
        my @groups = @{$level_map{$level}};
	# add any additional groups from configuration
        push( @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 $cmd;
	# not found in existing passwd, must be new
        if ( !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 no part of password or group file changed
	    # then there is nothing to do here.
	    next if ( $opwd eq $pwd &&
		      (!$fname || $fname eq $comment) &&
		      (!$home  || $home eq $dir)  &&
		      join(' ',  sort @groups) eq $group_map{$user} );

            $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") == 0
	    or die "sudo $cmd $user failed: $?";
    }
}

exit 0;