grantnodetype.in 6.27 KB
Newer Older
Leigh Stoller's avatar
Leigh Stoller committed
1 2 3
#!/usr/bin/perl -wT

#
4
# Copyright (c) 2003-2012, 2014 University of Utah and the Flux Group.
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
# 
# {{{EMULAB-LICENSE
# 
# This file is part of the Emulab network testbed software.
# 
# This file is free software: you can redistribute it and/or modify it
# under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or (at
# your option) any later version.
# 
# This file 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 Affero General Public
# License for more details.
# 
# You should have received a copy of the GNU Affero General Public License
# along with this file.  If not, see <http://www.gnu.org/licenses/>.
# 
# }}}
Leigh Stoller's avatar
Leigh Stoller committed
24 25 26 27 28 29 30 31 32 33 34 35 36
#

use English;
use Getopt::Std;

#
# Grant permission to use types/class of nodes. If given a specific
# "type", then grant permission to use just that type. If its a class, then
# permission to use all of the types in that class, the class itself, and any
# aux nodetypes for the type/class (node_types_auxtypes table). 
#
sub usage()
{
37
    print STDERR "Usage: grantnodetype [-h] [-r] [-m] -p <pid> <type> [count]\n";
38
    print STDERR "       grantnodetype [-h] -R <type>\n";
Leigh Stoller's avatar
Leigh Stoller committed
39
    print STDERR "	-h   This message\n";
40
    print STDERR "	-r   Revoke access instead of grant\n";
41
    print STDERR "	-m   Force insert of missing minus policy\n";
42
    print STDERR "      -R   Remove all projects for type, and minus policy\n";
43
    print STDERR "   count   Overdide default count of 999999\n";
Leigh Stoller's avatar
Leigh Stoller committed
44 45
    exit(-1);
}
46
my $optlist  = "hp:dnrmR";
Leigh Stoller's avatar
Leigh Stoller committed
47 48
my $impotent = 0;
my $debug    = 0;
49
my $revoke   = 0;
50
my $revokeall= 0;
51
my $addminus = 0;
Leigh Stoller's avatar
Leigh Stoller committed
52 53
my %newtypes = ();
my $pid;
54
my $count    = 999999;
Leigh Stoller's avatar
Leigh Stoller committed
55 56 57 58 59 60

#
# Please do not run as root. Hard to track what has happened.
#
if ($UID == 0) {
    die("*** $0:\n".
61
	"    Please do not run this as root!\n");
Leigh Stoller's avatar
Leigh Stoller committed
62 63 64 65 66
}

#
# Configure variables
#
67 68
my $TB		 = "@prefix@";
my $update_perms = "$TB/sbin/update_permissions";
Leigh Stoller's avatar
Leigh Stoller committed
69 70 71 72 73 74 75

#
# Testbed Support libraries
#
use lib "@prefix@/lib";
use libdb;
use libtestbed;
76 77
use Project;
use Group;
Leigh Stoller's avatar
Leigh Stoller committed
78

79 80 81
# Be careful not to exit on transient error
$libdb::DBQUERY_MAXTRIES = 30;

Leigh Stoller's avatar
Leigh Stoller committed
82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102
#
# Turn off line buffering on output
#
$| = 1;

#
# Untaint the path
# 
$ENV{'PATH'} = "/bin:/sbin:/usr/bin:";

#
# Parse command arguments. Once we return from getopts, all that should be
# left are the required arguments.
#
%options = ();
if (! getopts($optlist, \%options)) {
    usage();
}
if (defined($options{h})) {
    usage();
}
103 104 105
if (defined($options{m})) {
    $addminus = 1;
}
Leigh Stoller's avatar
Leigh Stoller committed
106 107 108
if (defined($options{n})) {
    $impotent = 1;
}
109 110 111
if (defined($options{r})) {
    $revoke = 1;
}
112 113 114
if (defined($options{R})) {
    $revokeall = 1;
}
Leigh Stoller's avatar
Leigh Stoller committed
115 116 117 118 119 120
if (defined($options{d})) {
    $debug = 1;
}
if (defined($options{p})) {
    $pid = $options{p};
}
121 122
if (!$revokeall &&
    (scalar(@ARGV) < 1 || scalar(@ARGV) > 2 || !defined($pid))) {
Leigh Stoller's avatar
Leigh Stoller committed
123 124 125
    usage();
}
my $type = $ARGV[0];
126
$count   = $ARGV[1] if (@ARGV == 2);
Leigh Stoller's avatar
Leigh Stoller committed
127 128 129 130 131 132 133 134 135 136 137

#
# Untaint the arguments.
#
if ($type =~ /^([-\w]+)$/) {
    $type = $1;
}
else {
    die("Tainted type name: $type");
}

138 139 140 141 142 143 144 145 146 147 148 149 150
#
# Clear the type from the group_policies table, including the minus policy,
# which allows the type to be used by everyone.
#
if ($revokeall) {
    DBQueryFatal("delete from group_policies ".
		 "where policy='type' and auxdata='$type'")
	if (!$impotent);

    system($update_perms);
    exit($? >> 8);
}

Leigh Stoller's avatar
Leigh Stoller committed
151 152 153 154 155 156 157 158 159 160 161 162 163
if ($pid =~ /^([-\w]+)$/) {
    $pid = $1;
}
else {
    die("Tainted pid name: $pid");
}

# Only admin types can do this.
if (!TBAdmin($UID)) {
    die("*** $0:\n".
	"    You are not allowed to grant permission to use node types!\n");
}

164 165 166 167 168 169 170 171
my $project = Project->Lookup($pid);
if (!defined($project)) {
    die("*** $0:\n".
	"    Cannot map project $pid to its object\n");
}
# Need this below.
my $pid_idx = $project->pid_idx();

Leigh Stoller's avatar
Leigh Stoller committed
172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195
#
# Check to make sure a valid type in the node_types table.
#
my $query_result =
    DBQueryFatal("select distinct type,class from node_types ".
		 "where type='$type' or class='$type'");

if (! $query_result->num_rows) {
    die("*** $0:\n".
	"    No such type/class $type in the types table!\n");
}

while (my ($nodetype,$nodeclass) = $query_result->fetchrow_array()) {
    if ($nodeclass eq $type) {
	#
	# Grant permission to this class/type, and all of the aux types for it.
	#
	$newtypes{$nodetype} = 1
	    if (!defined($newtypes{$nodetype}));
	$newtypes{$nodeclass} = 1
	    if ($nodeclass ne $nodetype && !defined($newtypes{$nodeclass}));

	my $aux_result =
	    DBQueryFatal("select auxtype from node_types_auxtypes ".
196
			 "where type='$nodetype' or type='$nodeclass'");
Leigh Stoller's avatar
Leigh Stoller committed
197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215

	while (my ($auxtype) = $aux_result->fetchrow_array()) {
	    $newtypes{$auxtype} = 1
		if (!defined($newtypes{$auxtype}));
	}
    }
    else {
	#
	# A single type. Just grant permission to the type itself.
	#
	$newtypes{$type} = 1
	    if (!defined($newtypes{$type}));
    }
}

#
# Run the queries.
# 
foreach my $newtype (keys(%newtypes)) {
216 217 218
    print STDERR
	($revoke ? "Revoking" : "Granting") . " " .
	"permission to use type $newtype\n"
Leigh Stoller's avatar
Leigh Stoller committed
219
	if ($debug);
220 221 222 223 224 225 226 227 228 229 230 231 232 233

    #
    # Make sure there is a minus policy in the group_policies table;
    # If not, then granting permission to use this type is silly, and
    # probably means that the group_policies table needs updating.
    #
    $query_result =
	DBQueryFatal("select * from group_policies ".
		     "where pid='-' and policy='type' and auxdata='$newtype'");
    
    exit(0)
	if (!$query_result);

    if (!$query_result->num_rows) {
234 235 236 237 238 239 240 241 242 243 244
	if ($addminus) {
	    DBQueryFatal("replace into group_policies ".
			 "(pid_idx,gid_idx,pid,gid,policy,auxdata,count) ".
			 "values (0, 0, '-', '-','type','$newtype', 0)")
		if (!$impotent);
	}
	else {
	    die("*** $0:\n".
		"    There is no '-' policy for node type $newtype!\n".
		"    Use the -m option if you want to add the minux policy.\n");
	}
245 246 247 248 249
    }

    #
    # Add generic rules that say the project is allowed to use "infinite"
    # number of nodes of each type. 
250
    #
251
    my $count = ($revoke ? 0 : $count);
252
    
253
    DBQueryFatal("replace into group_policies ".
254 255
		 "(pid_idx, gid_idx, pid, gid, policy, auxdata, count) ".
		 "values ($pid_idx, $pid_idx, '$pid', '$pid', ".
256
		 "        'type', '$newtype', $count)")
Leigh Stoller's avatar
Leigh Stoller committed
257 258 259
	if (!$impotent);
}

260 261 262 263 264 265
#
# Now update the permissions table. 
#
system($update_perms);
exit($? >> 8)
    if ($?);
Leigh Stoller's avatar
Leigh Stoller committed
266
exit(0);