...
 
Commits (115)
......@@ -2257,13 +2257,13 @@ sub UpdateSliverStatusAll($$)
# Helper functions for below.
sub ContextError()
{
return GeniResponse->Create(GENIRESPONSE_ERROR(), undef,
"Could not generate context for RPC");
return GeniResponse->new(GENIRESPONSE_ERROR(), -1,
"Could not generate context for RPC");
}
sub CredentialError()
{
return GeniResponse->Create(GENIRESPONSE_ERROR(), undef,
"Could not generate credentials for RPC");
return GeniResponse->new(GENIRESPONSE_ERROR(), -1,
"Could not generate credentials for RPC");
}
#
......@@ -2776,10 +2776,11 @@ sub ConsoleURL($$)
#
# Create an Image,
#
sub CreateImage($$$$;$$$$$)
sub CreateImage($$$$;$$$$$$)
{
my ($self, $sliver_urn, $imagename, $update_prepare,
$copyback_uuid, $bsname, $nosnapshot, $mustnotexist, $wholedisk) = @_;
$copyback_uuid, $bsname, $nosnapshot,
$mustnotexist, $wholedisk, $description) = @_;
my $authority = $self->GetGeniAuthority();
my $geniuser = $self->instance()->GetGeniUser();
my $slice = $self->instance()->GetGeniSlice();
......@@ -2818,6 +2819,8 @@ sub CreateImage($$$$;$$$$$)
if ($mustnotexist);
$args->{'wholedisk'} = 1
if ($wholedisk);
$args->{'description'} = $description
if (defined($description));
my $cmurl = $authority->url();
$cmurl = devurl($cmurl) if ($usemydevtree);
......
......@@ -1533,16 +1533,16 @@ sub EncryptBlocks($$$)
#
# Add a portal element.
#
sub AddPortalTag($$$)
sub AddPortalTag($$$$)
{
my ($pxml, $tag, $pmsg) = @_;
my ($pxml, $tag, $url, $pmsg) = @_;
my $rspec = GeniXML::Parse($$pxml);
if (! defined($rspec)) {
$$pmsg = "AddPortalTag: Could not parse rspec";
return -1;
}
GeniXML::SetPortal($rspec, $tag);
GeniXML::SetPortal($rspec, $tag, $url);
$$pxml = GeniXML::Serialize($rspec);
return 0;
}
......
......@@ -36,7 +36,7 @@ use POSIX qw(ceil);
use vars qw(@ISA @EXPORT);
@ISA = "Exporter";
@EXPORT = qw (MapUserURN MapProjectURN);
@EXPORT = qw (MapUserURN MapProjectURN ReadFile);
# Must come after package declaration!
use emdb;
......@@ -130,6 +130,18 @@ sub MapUserURN($)
return undef;
}
#
# Convenience
#
sub ReadFile($) {
local $/ = undef;
my ($filename) = @_;
open(FILE, $filename) or fatal("Could not open $filename: $!");
my $contents = <FILE>;
close(FILE);
return $contents;
}
#
# Given a reservation details hash, calculate a utilization number
# from the history array.
......
......@@ -664,7 +664,7 @@ if ($localuser) {
$emulab_user, $project));
# Hack for Kobus' class, generalize someday.
if ($pid eq "CS4480-2018") {
if (0 && $pid eq "CS4480-2018") {
my $termination = str2time("2018-05-02");
# convert to hours till then
$duration = int(($termination - time()) / 3600);
......@@ -825,20 +825,6 @@ $tmp = APT_Profile::EncryptBlocks(\$rspecstr, $alt_certificate, \$errmsg);
if ($tmp) {
($tmp < 0 ? fatal($errmsg) : UserError($errmsg));
}
#
# Tell the CM to do normal NFS mounts if this is the "Emulab" portal
# making the request. The CM is of course free to ignore this.
#
# XXX Need to handle this differently if we use the stitcher.
#
if ($portal ne "emulab") {
if (APT_Profile::ClearPortalTag(\$rspecstr, $errmsg)) {
fatal($errmsg);
}
}
elsif (APT_Profile::AddPortalTag(\$rspecstr, $portal, $errmsg)) {
fatal($errmsg);
}
#
# Generate credentials we need.
......@@ -897,6 +883,22 @@ if ($instance->ApplyExtensionPolicies()) {
fatal("Error applying policies");
}
#
# Tell the CM the portal information, which is used by Emulab based
# CMs to send email links.
#
# Special: This also tells the CM to do normal NFS mounts if this is
# the "Emulab" portal making the request.
#
# XXX The local instance will not have these tags, but no big deal.
# XXX Need to handle this differently if we use the stitcher?
#
if (APT_Profile::AddPortalTag(\$rspecstr,
$portal, $instance->webURL(), \$errmsg)) {
$instance->Delete();
fatal($errmsg);
}
#
# Get the set of keys (accounts) that need to be sent along. We build
# them in CM format, but convert to AM format later if needed.
......
......@@ -221,6 +221,8 @@ sub DoListImages()
if (!defined($authority));
# URN without the version.
$urn = GeniHRN::GenerateImage($auth,$ospid,$os,undef);
# Put it into the object so that PHP/JS code can find it easy.
$image->{'imagename'} = $os;
# Default to version zero, for old sites not reporting version.
my $vers = (defined($osvers) ? $osvers : 0);
......@@ -258,9 +260,16 @@ sub DoListImages()
#
if (exists($image0->{'project_urn'})) {
my $projhrn = GeniHRN->new($image0->{'project_urn'});
if ($projhrn->domain() eq $OURDOMAIN &&
defined($projhrn->project())) {
my $project = Project->Lookup($projhrn->project());
if ($projhrn->domain() eq $OURDOMAIN) {
my $project;
if (defined($projhrn->project())) {
$project = Project->Lookup($projhrn->project());
}
else {
# Backwards compat; we did not always send project urns.
$project = Project->Lookup($image0->{'pid'});
}
if (defined($project)) {
$ref->{'pid'} = $project->pid();
$ref->{'pid_idx'} = $project->pid_idx();
......@@ -271,6 +280,7 @@ sub DoListImages()
# Remote pid, set above
$ref->{'pid'} = $image0->{'pid'};
}
$ref->{'imagename'} = $image0->{'imagename'};
#
# Find profiles using the named image
......@@ -322,11 +332,18 @@ sub DoListImages()
while (@versions) {
my $image = shift(@versions);
my $urn = $image->{'urn'};
my $hrn = GeniHRN->new($urn);
my @using = ();
$image->{'using'} = [];
$image->{'candelete'} = 0;
$image->{'deleted'} = 0;
my (undef, undef, undef, $osvers) = $hrn->ParseImage();
# Default to version zero, for old sites not reporting version.
my $vers = (defined($osvers) ? $osvers : 0);
# Put it into the object so that PHP/JS code can find it easy.
$image->{'version'} = int($vers);
next
if (APT_Profile::ImageInfo::FindProfilesUsing($urn, \@using));
......@@ -395,7 +412,7 @@ sub DoDeleteImage()
print STDERR "Usage: manage_images delete [-a am_urn] <image_urn>\n";
exit(-1);
};
my $optlist = "a:d:n";
my $optlist = "a:d:v:n";
my $aggregate_urn = $MYURN;
my $impotent = 0;
my $profile;
......@@ -422,64 +439,24 @@ sub DoDeleteImage()
if ($profile->isLocked()) {
fatal("Profile is locked down, cannot be deleted");
}
#
# This argument says; delete any version of the specified
# profile, that reference the image being deleted. So we
# have to go through every version of the profile and check
# to see if its using this image. For any of those versions,
# we try to delete it.
# The caller tells us what versions of the image to delete,
#
if (!exists($options{"v"})) {
fatal("Missing version number list");
}
if ($options{"v"} !~ /^[\d,]+$/) {
fatal("Version number list should be comma separated integers");
}
my @todelete = ();
foreach my $version ($profile->AllVersions()) {
my $usingimage = 0;
my $conflict;
#
# Check image references for this version. We want to
# know if there are any other images associated with this
# version beside the one we are trying to delete. If so,
# we cannot delete the profile version since that will
# result in another image getting deleted.
#
my %irefs = %{ $version->images() };
foreach my $client_id (keys(%irefs)) {
my $imageinfo = $irefs{$client_id};
# We do not ever care about system images.
next
if ($imageinfo->ospid() eq "emulab-ops");
# The image we are trying to delete is okay
if ($imageinfo->image() eq $image_urn) {
$usingimage = 1;
next;
}
my $snapname = $profile->name() . "." . $client_id;
if ($imageinfo->os() eq $profile->name() ||
$imageinfo->os() eq $snapname) {
$conflict = $imageinfo;
}
}
if ($usingimage && $conflict) {
my $mesg =
"Version " . $version->version() . " of the " .
$version->name() . " profile has another ".
"image that would be deleted as well: ".
$conflict->image() . ". ".
"You will need to go to the profile page and delete ".
"that profile version before you can delete this image.";
foreach my $versnum (split(",", $options{"v"})) {
my $version = APT_Profile->Lookup($profile->profileid(), $versnum);
next
if (!defined($version));
if ($webtask) {
$webtask->reason("conflict");
$webtask->profile($version->uuid());
$webtask->image($conflict->image());
}
UserError($mesg);
}
if ($usingimage && $version->isLocked()) {
if ($version->isLocked()) {
my $mesg =
"Version " . $version->version() . " of the " .
$version->name() . " profile is locked down, ".
......@@ -491,11 +468,42 @@ sub DoDeleteImage()
}
UserError($mesg);
}
if ($usingimage) {
push(@todelete, $version);
print "Would delete version " . $version->version() .
" of profile " . $profile->name() . "\n";
#
# Check image references for this version. We want to
# know if there are any other images associated with this
# version beside the one we are trying to delete. If so,
# we cannot delete the profile version since that will
# result in another image getting deleted.
#
my %irefs = %{ $version->images() };
if (keys(%irefs) > 1) {
foreach my $client_id (keys(%irefs)) {
my $imageinfo = $irefs{$client_id};
# We do not ever care about system images.
next
if ($imageinfo->ospid() eq "emulab-ops");
my $mesg =
"Version " . $version->version() . " of the " .
$version->name() . " profile is using multiple ".
"images. As a safety measure, we require that you ".
"delete or edit that profile before you can delete ".
"this image.";
if ($webtask) {
$webtask->reason("conflict");
$webtask->profile($version->uuid());
$webtask->image($imageinfo->image());
}
UserError($mesg);
}
}
print "Would delete version " . $version->version() .
" of profile " . $profile->name() . "\n";
push(@todelete, $version);
}
foreach my $version (@todelete) {
my $vers = $version->version();
......
......@@ -299,6 +299,7 @@ sub DoSnapshot()
my $old_status = $instance->status();
my $node_id;
my $imagename;
my $description;
my $cloneprofile;
my $update_profile;
my $copyback_uuid;
......@@ -312,7 +313,7 @@ sub DoSnapshot()
my $usetracker = 0;
my $operation = "image-only"; # Default to just snapshot.
my $optlist = "n:i:u:Uc:O:Sse";
my $optlist = "n:i:u:Uc:O:SseD:";
my %options = ();
if (! getopts($optlist, \%options)) {
usage();
......@@ -335,6 +336,9 @@ sub DoSnapshot()
if (defined($options{"U"})) {
$update_prepare = 1;
}
if (defined($options{"D"})) {
$description = ReadFile($options{"D"});
}
if (defined($options{"s"})) {
$nosnapshot = 1;
}
......@@ -604,12 +608,14 @@ sub DoSnapshot()
my $response =
$aggregate->CreateImage($sliver_urn, $imagename,
$update_prepare, $copyback_uuid,
undef, $nosnapshot, $mustnotexist, $wholedisk);
undef, $nosnapshot, $mustnotexist, $wholedisk,
$description);
if ($response->code() != GENIRESPONSE_SUCCESS) {
$errcode = $response->code();
($exitcode,$errmsg) = ResponseErrorMessage($aggregate, $response);
# Important to tell web user about these.
if ($response->code() == GENIRESPONSE_NOSPACE ||
$response->code() == GENIRESPONSE_FORBIDDEN ||
$response->code() == GENIRESPONSE_ALREADYEXISTS) {
$exitcode = 1;
}
......@@ -933,7 +939,7 @@ sub DoSnapshot()
$slice->UnLock()
if ($needunlock);
exit($errcode);
exit($exitcode);
}
sub DoImageTrackerStuff($$$$$$$)
......@@ -2015,6 +2021,9 @@ sub DoMaxExtension()
$webtask->output($errmsg) if (defined($errmsg));
$webtask->Exited($errcode);
}
if ($errcode < 0) {
print STDERR "\n\n" . $instance->webURL() . "\n";
}
exit($errcode);
}
......@@ -4301,6 +4310,11 @@ sub fatal($)
}
print STDERR "*** $0:\n".
" $mesg\n";
# Helpful.
if (defined($instance)) {
print STDERR "\n\n" . $instance->webURL() . "\n";
}
# Exit with negative status so web interface treats it as system error.
exit(-1);
}
......
......@@ -77,12 +77,12 @@ int parse_ptop(tb_pgraph &pg, tb_sgraph &sg, istream& input)
{
int num_nodes = 0;
int line=0,errors=0;
char inbuf[32768];
char inbuf[65536];
string_vector parsed_line;
while (!input.eof()) {
line++;
input.getline(inbuf,32768);
input.getline(inbuf,65536);
parsed_line = split_line(inbuf,' ');
if (parsed_line.size() == 0) {continue;}
......
......@@ -4602,6 +4602,7 @@ outfiles="Makeconf GNUmakefile setversion \
tmcc/freebsd/init/10.3/GNUmakefile \
tmcc/freebsd/init/10.4/GNUmakefile \
tmcc/freebsd/init/11/GNUmakefile \
tmcc/freebsd/init/11.2/GNUmakefile \
tmcc/freebsd/init/12/GNUmakefile \
tmcc/freebsd/supfile tmcc/freebsd/sethostname \
tmcc/linux/GNUmakefile tmcc/linux/supfile \
......@@ -4617,6 +4618,7 @@ outfiles="Makeconf GNUmakefile setversion \
tmcc/ubuntu16/GNUmakefile \
tmcc/ubuntu16-ms/GNUmakefile \
tmcc/ubuntu18/GNUmakefile \
tmcc/ubuntu18-ms/GNUmakefile \
tmcc/linux-ms/GNUmakefile \
tmcc/archlinux/GNUmakefile \
tmcc/alpine/GNUmakefile \
......
......@@ -290,6 +290,7 @@ outfiles="Makeconf GNUmakefile setversion \
tmcc/freebsd/init/10.3/GNUmakefile \
tmcc/freebsd/init/10.4/GNUmakefile \
tmcc/freebsd/init/11/GNUmakefile \
tmcc/freebsd/init/11.2/GNUmakefile \
tmcc/freebsd/init/12/GNUmakefile \
tmcc/freebsd/supfile tmcc/freebsd/sethostname \
tmcc/linux/GNUmakefile tmcc/linux/supfile \
......@@ -305,6 +306,7 @@ outfiles="Makeconf GNUmakefile setversion \
tmcc/ubuntu16/GNUmakefile \
tmcc/ubuntu16-ms/GNUmakefile \
tmcc/ubuntu18/GNUmakefile \
tmcc/ubuntu18-ms/GNUmakefile \
tmcc/linux-ms/GNUmakefile \
tmcc/archlinux/GNUmakefile \
tmcc/alpine/GNUmakefile \
......
......@@ -29,7 +29,10 @@ SYSTEM := $(shell $(SRCDIR)/../../../tmcc/osstuff.sh -o)
IPERFVERSION = 2.0.2
ifeq ($(SYSTEM),Linux)
OSTAG=$(shell $(SRCDIR)/../../../tmcc/osstuff.sh -t)
ifneq (,$(filter $(OSTAG),alpine debian9 debianS ubuntu18))
# NB: the 2.0.10 patch is still subtly broken, so we continue to keep
# the 2.0.2 patch alive. Add exceptions in the filter case below if you
# really want to use the 2.0.10 patch.
ifneq (,$(filter $(OSTAG),))
IPERFVERSION = 2.0.10
# If 2.0.10, we have to disable 64-bit seq numbers; they mess up the
# client_hdr size in a backwards-incompat way.
......@@ -43,15 +46,6 @@ include $(OBJDIR)/Makeconf
SYSTEM := $(patsubst CYGWIN%,CYGWIN,$(shell uname -s))
ISBROKEN = 0
ifeq ($(SYSTEM),FreeBSD)
FBSDREL = $(shell uname -r)
ifneq ($(findstring 11.,$(FBSDREL)),)
ISBROKEN = 1
endif
ifneq ($(findstring 12.,$(FBSDREL)),)
ISBROKEN = 1
endif
endif
ifeq ($(host_cpu),arm)
ISBROKEN = 1
endif
......
diff -Nurb include/Settings.hpp include/Settings.hpp
--- include/Settings.hpp 2017-08-08 21:54:14.000000000 -0600
+++ include/Settings.hpp 2018-02-08 11:11:05.297576181 -0700
diff -Nurb iperf-2.0.10.orig/include/Settings.hpp iperf-2.0.10/include/Settings.hpp
--- iperf-2.0.10.orig/include/Settings.hpp 2017-08-08 21:54:14.000000000 -0600
+++ iperf-2.0.10/include/Settings.hpp 2018-02-08 11:11:05.297576181 -0700
@@ -139,6 +139,7 @@
int mBufLen; // -l
int mMSS; // -M
......@@ -35,9 +35,9 @@ diff -Nurb include/Settings.hpp include/Settings.hpp
#endif
} client_hdr_v1;
diff -Nurb src/Client.cpp src/Client.cpp
--- src/Client.cpp 2017-08-08 21:54:14.000000000 -0600
+++ src/Client.cpp 2018-02-08 12:07:00.907572372 -0700
diff -Nurb iperf-2.0.10.orig/src/Client.cpp iperf-2.0.10/src/Client.cpp
--- iperf-2.0.10.orig/src/Client.cpp 2017-08-08 21:54:14.000000000 -0600
+++ iperf-2.0.10/src/Client.cpp 2018-02-08 12:07:00.907572372 -0700
@@ -573,9 +573,11 @@
if (isUDP(mSettings)) {
// store datagram ID into buffer
......@@ -101,9 +101,9 @@ diff -Nurb src/Client.cpp src/Client.cpp
+ fprintf( stderr, warn_no_ack, mSettings->mSock, count, timo );
}
// end write_UDP_FIN
diff -Nurb src/Locale.c src/Locale.c
--- src/Locale.c 2017-08-11 12:41:20.000000000 -0600
+++ src/Locale.c 2018-02-08 11:11:05.297576181 -0700
diff -Nurb iperf-2.0.10.orig/src/Locale.c iperf-2.0.10/src/Locale.c
--- iperf-2.0.10.orig/src/Locale.c 2017-08-11 12:41:20.000000000 -0600
+++ iperf-2.0.10/src/Locale.c 2018-02-08 11:11:05.297576181 -0700
@@ -373,7 +373,7 @@
"WARNING: Path MTU Discovery may not be enabled.\n";
......@@ -113,9 +113,9 @@ diff -Nurb src/Locale.c src/Locale.c
const char warn_ack_failed[]=
"[%3d] WARNING: ack of last datagram failed after %d tries.\n";
diff -Nurb src/Server.cpp src/Server.cpp
--- src/Server.cpp 2017-08-08 21:54:14.000000000 -0600
+++ src/Server.cpp 2018-02-08 10:59:38.116942057 -0700
diff -Nurb iperf-2.0.10.orig/src/Server.cpp iperf-2.0.10/src/Server.cpp
--- iperf-2.0.10.orig/src/Server.cpp 2017-08-08 21:54:14.000000000 -0600
+++ iperf-2.0.10/src/Server.cpp 2018-02-08 10:59:38.116942057 -0700
@@ -313,9 +313,12 @@
if (!reportstruct->emptyreport) {
......@@ -130,9 +130,9 @@ diff -Nurb src/Server.cpp src/Server.cpp
reportstruct->packetID = ntohl(mBuf_UDP->id);
}
reportstruct->sentTime.tv_sec = ntohl( mBuf_UDP->tv_sec );
diff -Nurb src/Settings.cpp src/Settings.cpp
--- src/Settings.cpp 2017-08-11 11:55:44.000000000 -0600
+++ src/Settings.cpp 2018-02-08 12:11:03.680668904 -0700
diff -Nurb iperf-2.0.10.orig/src/Settings.cpp iperf-2.0.10/src/Settings.cpp
--- iperf-2.0.10.orig/src/Settings.cpp 2017-08-11 11:55:44.000000000 -0600
+++ iperf-2.0.10/src/Settings.cpp 2018-02-08 12:11:03.680668904 -0700
@@ -114,6 +114,7 @@
{"realtime", no_argument, NULL, 'z'},
......@@ -222,9 +222,9 @@ diff -Nurb src/Settings.cpp src/Settings.cpp
if ( client->mMode == kTest_DualTest ) {
flags |= RUN_NOW;
}
diff -Nurb src/main.cpp src/main.cpp
--- src/main.cpp 2017-08-08 21:54:14.000000000 -0600
+++ src/main.cpp 2018-02-08 11:11:05.298576198 -0700
diff -Nurb iperf-2.0.10.orig/src/main.cpp iperf-2.0.10/src/main.cpp
--- iperf-2.0.10.orig/src/main.cpp 2017-08-08 21:54:14.000000000 -0600
+++ iperf-2.0.10/src/main.cpp 2018-02-08 11:11:05.298576198 -0700
@@ -166,6 +166,11 @@
// read settings from command-line parameters
Settings_ParseCommandLine( argc, argv, ext_gSettings );
......@@ -237,9 +237,9 @@ diff -Nurb src/main.cpp src/main.cpp
// Check for either having specified client or server
if ( ext_gSettings->mThreadMode == kMode_Client
|| ext_gSettings->mThreadMode == kMode_Listener ) {
diff -Nurb src/stdio.c src/stdio.c
--- src/stdio.c 2017-08-08 21:54:14.000000000 -0600
+++ src/stdio.c 2018-02-08 11:11:05.298576198 -0700
diff -Nurb iperf-2.0.10.orig/src/stdio.c iperf-2.0.10/src/stdio.c
--- iperf-2.0.10.orig/src/stdio.c 2017-08-08 21:54:14.000000000 -0600
+++ iperf-2.0.10/src/stdio.c 2018-02-08 11:11:05.298576198 -0700
@@ -255,8 +255,6 @@
* ------------------------------------------------------------------- */
......
#!/bin/sh
#
# Copyright (c) 2004-2012 University of Utah and the Flux Group.
# Copyright (c) 2004-2018 University of Utah and the Flux Group.
#
# {{{EMULAB-LICENSE
#
......@@ -78,7 +78,7 @@ if [ ! -d $dir/iperf-$version/src ]; then
srcdir="../$srcdir"
;;
esac
cd iperf-$version && patch -p0 < $srcdir/iperf-${version}.patch || {
cd iperf-$version && patch -p1 < $srcdir/iperf-${version}.patch || {
echo "ERROR: iperf-fetch.sh: patch failed"
exit 1
}
......
......@@ -1701,7 +1701,7 @@ int
event_notification_insert_hmac(event_handle_t handle,
event_notification_t notification)
{
HMAC_CTX ctx;
HMAC_CTX *ctxp;
unsigned char mac[EVP_MAX_MD_SIZE];
unsigned int len = EVP_MAX_MD_SIZE;
......@@ -1720,22 +1720,42 @@ event_notification_insert_hmac(event_handle_t handle,
pubsub_notification_remove(notification->pubsub_notification,
"___elvin_ordered___", &handle->status);
memset(&ctx, 0, sizeof(ctx));
#if (OPENSSL_VERSION_NUMBER >= 0x10100000L)
ctxp = HMAC_CTX_new();
if (!ctxp) {
ERROR("HMAC_CTX_new failed to alloc ctx\n");
return 1;
}
HMAC_Init_ex(ctxp, handle->keydata, handle->keylen, EVP_sha1(), NULL);
#else
HMAC_CTX ctx;
ctxp = &ctx;
memset(ctxp, 0, sizeof(ctx));
#if (OPENSSL_VERSION_NUMBER < 0x0090703f)
HMAC_Init(&ctx, handle->keydata, handle->keylen, EVP_sha1());
HMAC_Init(ctxp, handle->keydata, handle->keylen, EVP_sha1());
#else
HMAC_CTX_init(&ctx);
HMAC_Init_ex(&ctx, handle->keydata, handle->keylen, EVP_sha1(), NULL);
HMAC_CTX_init(ctxp);
HMAC_Init_ex(ctxp, handle->keydata, handle->keylen, EVP_sha1(), NULL);
#endif
#endif
if (!pubsub_notification_traverse(notification->pubsub_notification,
hmac_traverse,
&ctx, &handle->status)) {
ctxp, &handle->status)) {
ERROR("event_notification_insert_hmac failed: hmac_traverse\n");
HMAC_cleanup(&ctx);
#if (OPENSSL_VERSION_NUMBER >= 0x10100000L)
HMAC_CTX_free(ctxp);
#else
HMAC_cleanup(ctxp);
#endif
return 1;
}
HMAC_Final(&ctx, mac, &len);
HMAC_cleanup(&ctx);
HMAC_Final(ctxp, mac, &len);
#if (OPENSSL_VERSION_NUMBER >= 0x10100000L)
HMAC_CTX_free(ctxp);
#else
HMAC_cleanup(ctxp);
#endif
ctxp = NULL;
if (0) {
hmac_dump("event_notification_insert_hmac", mac, len);
......@@ -1833,7 +1853,10 @@ static int
event_notification_check_hmac(event_handle_t handle,
event_notification_t notification)
{
HMAC_CTX ctx;
#if (OPENSSL_VERSION_NUMBER < 0x10100000L)
HMAC_CTX ctx;
#endif
HMAC_CTX *ctxp = NULL;
unsigned char srcmac[EVP_MAX_MD_SIZE], mac[EVP_MAX_MD_SIZE];
char *pmac;
unsigned int srclen, len = EVP_MAX_MD_SIZE;
......@@ -1842,6 +1865,11 @@ event_notification_check_hmac(event_handle_t handle,
#ifdef ELVIN_COMPAT
struct elvin_hashtable *hashtable;
#endif
#if (OPENSSL_VERSION_NUMBER < 0x10100000L)
ctxp = &ctx;
#endif
if (0)
INFO("event_notification_check_hmac (key): %s\n",
handle->keydata);
......@@ -1900,18 +1928,32 @@ event_notification_check_hmac(event_handle_t handle,
* order, and uses __hmac__ to compare against.
*/
if (! elvin_ordered) {
memset(&ctx, 0, sizeof(ctx));
#if (OPENSSL_VERSION_NUMBER >= 0x10100000L)
ctxp = HMAC_CTX_new();
if (!ctxp) {
ERROR("HMAC_CTX_new failed to alloc ctx\n");
return 1;
}
HMAC_Init_ex(ctxp, handle->keydata, handle->keylen, EVP_sha1(), NULL);
#else
memset(ctxp, 0, sizeof(ctx));
#if (OPENSSL_VERSION_NUMBER < 0x0090703f)
HMAC_Init(&ctx, handle->keydata, handle->keylen, EVP_sha1());
HMAC_Init(ctxp, handle->keydata, handle->keylen, EVP_sha1());
#else
HMAC_CTX_init(&ctx);
HMAC_Init_ex(&ctx, handle->keydata, handle->keylen,
HMAC_CTX_init(ctxp);
HMAC_Init_ex(ctxp, handle->keydata, handle->keylen,
EVP_sha1(), NULL);
#endif
#endif
hashtable = elvin_hashtable_alloc(0, &handle->status);
if (hashtable == NULL) {
ERROR("event_notification_check_hmac failed: "
"hashtable alloc\n");
#if (OPENSSL_VERSION_NUMBER >= 0x10100000L)
HMAC_CTX_free(ctxp);
#else
HMAC_cleanup(ctxp);
#endif
return -1;
}
if (!pubsub_notification_traverse(pubsub_notification,
......@@ -1921,18 +1963,32 @@ event_notification_check_hmac(event_handle_t handle,
ERROR("event_notification_check_hmac failed: "
"hmac_fill_hash\n");
elvin_hashtable_free(hashtable);
#if (OPENSSL_VERSION_NUMBER >= 0x10100000L)
HMAC_CTX_free(ctxp);
#else
HMAC_cleanup(ctxp);
#endif
return -1;
}
if (!elvin_hashtable_traverse(hashtable, hmac_traverse,
&ctx, &handle->status)) {
ctxp, &handle->status)) {
ERROR("event_notification_check_hmac failed: "
"notify_traverse\n");
elvin_hashtable_free(hashtable);
#if (OPENSSL_VERSION_NUMBER >= 0x10100000L)
HMAC_CTX_free(ctxp);
#else
HMAC_cleanup(ctxp);
#endif
return -1;
}
elvin_hashtable_free(hashtable);
HMAC_Final(&ctx, mac, &len);
HMAC_cleanup(&ctx);
HMAC_Final(ctxp, mac, &len);
#if (OPENSSL_VERSION_NUMBER >= 0x10100000L)
HMAC_reset(ctxp);
#else
HMAC_cleanup(ctxp);
#endif
if (0) {
hmac_dump("event_notification_check_hmac (elvin)",
......@@ -1945,22 +2001,44 @@ event_notification_check_hmac(event_handle_t handle,
/*
* Do a normal HMAC check.
*/
memset(&ctx, 0, sizeof(ctx));
#if (OPENSSL_VERSION_NUMBER >= 0x10100000L)
if (!ctxp) {
ctxp = HMAC_CTX_new();
if (!ctxp) {
ERROR("HMAC_CTX_new failed to alloc ctx\n");
return 1;
}
}
else {
HMAC_CTX_reset(ctxp);
}
HMAC_Init_ex(ctxp, handle->keydata, handle->keylen, EVP_sha1(), NULL);
#else
memset(ctxp, 0, sizeof(ctx));
#if (OPENSSL_VERSION_NUMBER < 0x0090703f)
HMAC_Init(&ctx, handle->keydata, handle->keylen, EVP_sha1());
HMAC_Init(ctxp, handle->keydata, handle->keylen, EVP_sha1());
#else
HMAC_CTX_init(&ctx);
HMAC_Init_ex(&ctx, handle->keydata, handle->keylen, EVP_sha1(), NULL);
HMAC_CTX_init(ctxp);
HMAC_Init_ex(ctxp, handle->keydata, handle->keylen, EVP_sha1(), NULL);
#endif
#endif
if (!pubsub_notification_traverse(pubsub_notification,
hmac_traverse,
&ctx, &handle->status)) {
HMAC_cleanup(&ctx);
ctxp, &handle->status)) {
#if (OPENSSL_VERSION_NUMBER >= 0x10100000L)
HMAC_CTX_free(ctxp);
#else
HMAC_cleanup(ctxp);
#endif
return -1;
}
HMAC_Final(&ctx, mac, &len);
HMAC_cleanup(&ctx);
HMAC_Final(ctxp, mac, &len);
#if (OPENSSL_VERSION_NUMBER >= 0x10100000L)
HMAC_CTX_free(ctxp);
#else
HMAC_cleanup(ctxp);
#endif
if (0) {
hmac_dump("event_notification_check_hmac (plain)", mac, len);
......
......@@ -750,8 +750,12 @@ convpubkey(struct pubkeydata *k)
BN_bin2bn(k->modulus, k->keylength, mod);
BN_bin2bn(k->exponent, k->expsize, exp);
/* set up the RSA public key structure */
#if (OPENSSL_VERSION_NUMBER >= 0x10100000L)
RSA_set0_key(rsa,mod,exp,NULL);
#else
rsa->n = mod;
rsa->e = exp;
#endif
return rsa;
}
......
......@@ -71,6 +71,8 @@ init_checksum(char *keyfile)
{
char str[1024];
FILE *file;
BIGNUM *n, *e, *dmp1, *dmq1, *iqmp;
n = e = dmp1 = dmq1 = iqmp = NULL;
if (keyfile == NULL || (file = fopen(keyfile, "r")) == NULL) {
fprintf(stderr, "%s: cannot open keyfile\n", keyfile);
......@@ -81,22 +83,33 @@ init_checksum(char *keyfile)
return 0;
}
if (fscanf(file, "%1024s", str) != 1)
goto bad;
BN_hex2bn(&signature_key->n, str);
BN_hex2bn(&n, str);
if (fscanf(file, "%1024s", str) != 1)
goto bad;
BN_hex2bn(&signature_key->e, str);
BN_hex2bn(&e, str);
if (fscanf(file, "%1024s", str) != 1)
goto bad;
BN_hex2bn(&signature_key->dmp1, str);
BN_hex2bn(&dmp1, str);
if (fscanf(file, "%1024s", str) != 1)
goto bad;
BN_hex2bn(&signature_key->dmq1, str);
BN_hex2bn(&dmq1, str);
if (fscanf(file, "%1024s", str) != 1)
goto bad;
BN_hex2bn(&signature_key->iqmp, str);
BN_hex2bn(&iqmp, str);
fclose(file);
#if (OPENSSL_VERSION_NUMBER >= 0x10100000L)
RSA_set0_key(signature_key, n, e, NULL);
RSA_set0_crt_params(signature_key, dmp1, dmq1, iqmp);
#else
signature_key->n = n;
signature_key->e = e;
signature_key->dmp1 = dmp1;
signature_key->dmq1 = dmq1;
signature_key->iqmp = iqmp;
#endif
return 1;
bad:
......
......@@ -1396,21 +1396,29 @@ decrypt_buffer(unsigned char *dest, const unsigned char *source,
int update_count = 0;
int final_count = 0;
int error = 0;
#if (OPENSSL_VERSION_NUMBER < 0x10100000L)
EVP_CIPHER_CTX context;
#endif
EVP_CIPHER_CTX *contextp;
EVP_CIPHER const *ecipher;
EVP_CIPHER_CTX_init(&context);
#if (OPENSSL_VERSION_NUMBER >= 0x10100000L)
contextp = EVP_CIPHER_CTX_new();
#else
contextp = &context;
EVP_CIPHER_CTX_init(contextp);
#endif
ecipher = EVP_bf_cbc();
EVP_DecryptInit(&context, ecipher, NULL, header->enc_iv);
EVP_CIPHER_CTX_set_key_length(&context, ENC_MAX_KEYLEN);
EVP_DecryptInit(&context, NULL, encryption_key, NULL);
EVP_DecryptInit(contextp, ecipher, NULL, header->enc_iv);
EVP_CIPHER_CTX_set_key_length(contextp, ENC_MAX_KEYLEN);
EVP_DecryptInit(contextp, NULL, encryption_key, NULL);
/* decrypt */
EVP_DecryptUpdate(&context, dest, &update_count, source, header->size);
EVP_DecryptUpdate(contextp, dest, &update_count, source, header->size);
/* cleanup */
error = EVP_DecryptFinal(&context, dest + update_count, &final_count);
error = EVP_DecryptFinal(contextp, dest + update_count, &final_count);
if (!error) {
char keystr[ENC_MAX_KEYLEN*2 + 1];
fprintf(stderr, "Padding was incorrect.\n");
......
/*
* Copyright (c) 2000-2015 University of Utah and the Flux Group.
* Copyright (c) 2000-2018 University of Utah and the Flux Group.
*
* {{{EMULAB-LICENSE
*
......@@ -734,7 +734,7 @@ main(int argc, char *argv[])
* Generate a random UUID if one was not provided and we are
* not operating in compatibility mode.
*/
if (!compat && !got_imageid) {
if (!info && !compat && !got_imageid) {
int fd = open("/dev/urandom", O_RDONLY, 0);
if (fd < 0 ||
......@@ -3215,6 +3215,21 @@ output_public_key(char *imagename, RSA *key)
fprintf(stderr, "Cannot create keyfile %s\n", fname);
exit(1);
}
#if (OPENSSL_VERSION_NUMBER >= 0x10100000L)
const BIGNUM *n = NULL, *e = NULL;
const BIGNUM *dmp1 = NULL, *dmq1 = NULL, *iqmp = NULL;
RSA_get0_key(key,&n,&e,NULL);
BN_print_fp(file, n);
fprintf(file, "\n");
BN_print_fp(file, e);
fprintf(file, "\n");
BN_print_fp(file, dmp1);
fprintf(file, "\n");
BN_print_fp(file, dmq1);
fprintf(file, "\n");
BN_print_fp(file, iqmp);
fprintf(file, "\n");
#else
BN_print_fp(file, key->n);
fprintf(file, "\n");
BN_print_fp(file, key->e);
......@@ -3225,6 +3240,7 @@ output_public_key(char *imagename, RSA *key)
fprintf(file, "\n");
BN_print_fp(file, key->iqmp);
fprintf(file, "\n");
#endif
fclose(file);
fprintf(stderr, "Signing pubkey written to %s\n", fname);
......@@ -3305,7 +3321,12 @@ checksum_finish(blockhdr_t *hdr)
/*
* Encryption functions
*/
#if (OPENSSL_VERSION_NUMBER >= 0x10100000L)
static EVP_CIPHER_CTX *cipher_ctxp;
#else
static EVP_CIPHER_CTX cipher_ctx;
static EVP_CIPHER_CTX *cipher_ctxp = &cipher_ctx;
#endif
static const EVP_CIPHER *ecipher;
/* XXX: the size of the IV may have to change with different ciphers */
static uint8_t iv[ENC_MAX_KEYLEN];
......@@ -3325,7 +3346,11 @@ encrypt_start(blockhdr_t *hdr)
/*
* Pick our cipher - currently, only Blowfish in CBC mode is supported
*/
EVP_CIPHER_CTX_init(&cipher_ctx);
#if (OPENSSL_VERSION_NUMBER >= 0x10100000L)
cipher_ctxp = EVP_CIPHER_CTX_new();
#else
EVP_CIPHER_CTX_init(cipher_ctxp);
#endif
ecipher = EVP_bf_cbc();
/*
......@@ -3367,13 +3392,13 @@ encrypt_start(blockhdr_t *hdr)
/*
* Set the cipher and IV
*/
EVP_EncryptInit(&cipher_ctx, ecipher, NULL, iv);
EVP_EncryptInit(cipher_ctxp, ecipher, NULL, iv);
/*
* Bump up the key length and set the key
*/
EVP_CIPHER_CTX_set_key_length(&cipher_ctx, ENC_MAX_KEYLEN);
EVP_EncryptInit(&cipher_ctx, NULL, enc_key, NULL);
EVP_CIPHER_CTX_set_key_length(cipher_ctxp, ENC_MAX_KEYLEN);
EVP_EncryptInit(cipher_ctxp, NULL, enc_key, NULL);
/*
* Copy the IV into the header
......@@ -3393,9 +3418,9 @@ encrypt_chunk(uint8_t *buf, off_t size, off_t maxsize)
int encrypted_this_round = 0;
/* man page says encrypted output could be this large */
assert(size + EVP_CIPHER_CTX_block_size(&cipher_ctx) - 1 <= maxsize);
assert(size + EVP_CIPHER_CTX_block_size(cipher_ctxp) - 1 <= maxsize);
EVP_EncryptUpdate(&cipher_ctx, ebuffer_current, &encrypted_this_round,
EVP_EncryptUpdate(cipher_ctxp, ebuffer_current, &encrypted_this_round,
buf, size);
encrypted_bytes += encrypted_this_round;
ebuffer_current = encryption_buffer + encrypted_bytes;
......@@ -3406,7 +3431,7 @@ encrypt_finish(blockhdr_t *hdr, uint8_t *outbuf, uint32_t *out_size)
{
int encrypted_this_round = 0;
EVP_EncryptFinal(&cipher_ctx, ebuffer_current, &encrypted_this_round);
EVP_EncryptFinal(cipher_ctxp, ebuffer_current, &encrypted_this_round);
encrypted_bytes += encrypted_this_round;
/*
......
......@@ -96,6 +96,9 @@ endif
ifeq ($(MDSUBDIR),redhat9)
MDSUBDIR = linux9
endif
ifeq ($(MDSUBDIR),MoonshotUbuntu18)
MDSUBDIR = ubuntu18-ms
endif
ifeq ($(MDSUBDIR),MoonshotUbuntu16)
MDSUBDIR = ubuntu16-ms
endif
......
#
# Insert Copyright Here.
#
SRCDIR = @srcdir@
TESTBED_SRCDIR = @top_srcdir@
OBJDIR = @top_builddir@
SUBDIR = $(subst $(TESTBED_SRCDIR)/,,$(SRCDIR))
include $(OBJDIR)/Makeconf
all:
client: init
include $(TESTBED_SRCDIR)/GNUmakerules
CFLAGS += -DDEBUGSHELL -DSECURE -DLOGIN_CAP -DCOMPAT_SYSV_INIT -DTESTBED
init.c: pathnames.h mntopts.h
getmntopts.c: mntopts.h
init: init.c getmntopts.c
$(CC) $(CFLAGS) -static -o init $^ -lutil -lcrypt
install:
client-install: client
install -s -o root -g wheel -m 555 -b -B.bak -fschg -S init $(DESTDIR)/sbin/init
clean:
rm -f *.o core init
/*-
* Copyright (c) 1994
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#if 0
#ifndef lint
static char sccsid[] = "@(#)getmntopts.c 8.3 (Berkeley) 3/29/95";
#endif /* not lint */
#endif
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: releng/11.2/sbin/mount/getmntopts.c 331722 2018-03-29 02:50:57Z eadler $");
#include <sys/param.h>
#include <sys/mount.h>
#include <sys/stat.h>
#include <sys/uio.h>
#include <err.h>
#include <errno.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "mntopts.h"
int getmnt_silent = 0;
void
getmntopts(const char *options, const struct mntopt *m0, int *flagp,
int *altflagp)
{
const struct mntopt *m;
int negative, len;
char *opt, *optbuf, *p;
int *thisflagp;
/* Copy option string, since it is about to be torn asunder... */
if ((optbuf = strdup(options)) == NULL)
err(1, NULL);
for (opt = optbuf; (opt = strtok(opt, ",")) != NULL; opt = NULL) {
/* Check for "no" prefix. */
if (opt[0] == 'n' && opt[1] == 'o') {
negative = 1;
opt += 2;
} else
negative = 0;
/*
* for options with assignments in them (ie. quotas)
* ignore the assignment as it's handled elsewhere
*/
p = strchr(opt, '=');
if (p != NULL)
*++p = '\0';
/* Scan option table. */
for (m = m0; m->m_option != NULL; ++m) {
len = strlen(m->m_option);
if (strncasecmp(opt, m->m_option, len) == 0)
if (opt[len] == '\0' || opt[len] == '=')
break;
}
/* Save flag, or fail if option is not recognized. */
if (m->m_option) {
thisflagp = m->m_altloc ? altflagp : flagp;
if (negative == m->m_inverse)
*thisflagp |= m->m_flag;
else
*thisflagp &= ~m->m_flag;
} else if (!getmnt_silent) {
errx(1, "-o %s: option not supported", opt);
}
}
free(optbuf);
}
void
rmslashes(char *rrpin, char *rrpout)
{
char *rrpoutstart;
*rrpout = *rrpin;
for (rrpoutstart = rrpout; *rrpin != '\0'; *rrpout++ = *rrpin++) {
/* skip all double slashes */
while (*rrpin == '/' && *(rrpin + 1) == '/')
rrpin++;
}
/* remove trailing slash if necessary */
if (rrpout - rrpoutstart > 1 && *(rrpout - 1) == '/')
*(rrpout - 1) = '\0';
else
*rrpout = '\0';
}
int
checkpath(const char *path, char *resolved)
{
struct stat sb;
if (realpath(path, resolved) == NULL || stat(resolved, &sb) != 0)
return (1);
if (!S_ISDIR(sb.st_mode)) {
errno = ENOTDIR;
return (1);
}
return (0);
}
void
build_iovec(struct iovec **iov, int *iovlen, const char *name, void *val,
size_t len)
{
int i;
if (*iovlen < 0)
return;
i = *iovlen;
*iov = realloc(*iov, sizeof **iov * (i + 2));
if (*iov == NULL) {
*iovlen = -1;
return;
}
(*iov)[i].iov_base = strdup(name);
(*iov)[i].iov_len = strlen(name) + 1;
i++;
(*iov)[i].iov_base = val;
if (len == (size_t)-1) {
if (val != NULL)
len = strlen(val) + 1;
else
len = 0;
}
(*iov)[i].iov_len = (int)len;
*iovlen = ++i;
}
/*
* This function is needed for compatibility with parameters
* which used to use the mount_argf() command for the old mount() syscall.
*/
void
build_iovec_argf(struct iovec **iov, int *iovlen, const char *name,
const char *fmt, ...)
{
va_list ap;
char val[255] = { 0 };
va_start(ap, fmt);
vsnprintf(val, sizeof(val), fmt, ap);
va_end(ap);
build_iovec(iov, iovlen, name, strdup(val), (size_t)-1);
}
/*
* Free the iovec and reset to NULL with zero length. Useful for calling
* nmount in a loop.
*/
void
free_iovec(struct iovec **iov, int *iovlen)
{
int i;
for (i = 0; i < *iovlen; i++)
free((*iov)[i].iov_base);
free(*iov);
}
This diff is collapsed.
/*-
* Copyright (c) 1994
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)mntopts.h 8.7 (Berkeley) 3/29/95
* $FreeBSD: releng/11.2/sbin/mount/mntopts.h 331722 2018-03-29 02:50:57Z eadler $
*/
struct mntopt {
const char *m_option; /* option name */
int m_inverse; /* if a negative option, e.g. "atime" */
long long m_flag; /* bit to set, e.g. MNT_RDONLY */
int m_altloc; /* 1 => set bit in altflags */
};
/* User-visible MNT_ flags. */
#define MOPT_ASYNC { "async", 0, MNT_ASYNC, 0 }
#define MOPT_NOATIME { "atime", 1, MNT_NOATIME, 0 }
#define MOPT_NOEXEC { "exec", 1, MNT_NOEXEC, 0 }
#define MOPT_NOSUID { "suid", 1, MNT_NOSUID, 0 }
#define MOPT_NOSYMFOLLOW { "symfollow", 1, MNT_NOSYMFOLLOW, 0 }
#define MOPT_RDONLY { "rdonly", 0, MNT_RDONLY, 0 }
#define MOPT_SYNC { "sync", 0, MNT_SYNCHRONOUS, 0 }
#define MOPT_UNION { "union", 0, MNT_UNION, 0 }
#define MOPT_USERQUOTA { "userquota", 0, 0, 0 }
#define MOPT_GROUPQUOTA { "groupquota", 0, 0, 0 }
#define MOPT_NOCLUSTERR { "clusterr", 1, MNT_NOCLUSTERR, 0 }
#define MOPT_NOCLUSTERW { "clusterw", 1, MNT_NOCLUSTERW, 0 }
#define MOPT_SUIDDIR { "suiddir", 0, MNT_SUIDDIR, 0 }
#define MOPT_SNAPSHOT { "snapshot", 0, MNT_SNAPSHOT, 0 }
#define MOPT_MULTILABEL { "multilabel", 0, MNT_MULTILABEL, 0 }
#define MOPT_ACLS { "acls", 0, MNT_ACLS, 0 }
#define MOPT_NFS4ACLS { "nfsv4acls", 0, MNT_NFS4ACLS, 0 }
#define MOPT_AUTOMOUNTED { "automounted",0, MNT_AUTOMOUNTED, 0 }
/* Control flags. */
#define MOPT_FORCE { "force", 0, MNT_FORCE, 0 }
#define MOPT_UPDATE { "update", 0, MNT_UPDATE, 0 }
#define MOPT_RO { "ro", 0, MNT_RDONLY, 0 }
#define MOPT_RW { "rw", 1, MNT_RDONLY, 0 }
/* This is parsed by mount(8), but is ignored by specific mount_*(8)s. */
#define MOPT_AUTO { "auto", 0, 0, 0 }
/* A handy macro as terminator of MNT_ array. */
#define MOPT_END { NULL, 0, 0, 0 }
#define MOPT_FSTAB_COMPAT \
MOPT_RO, \
MOPT_RW, \
MOPT_AUTO
/* Standard options which all mounts can understand. */
#define MOPT_STDOPTS \
MOPT_USERQUOTA, \
MOPT_GROUPQUOTA, \
MOPT_FSTAB_COMPAT, \
MOPT_NOATIME, \
MOPT_NOEXEC, \
MOPT_SUIDDIR, /* must be before MOPT_NOSUID */ \
MOPT_NOSUID, \
MOPT_NOSYMFOLLOW, \
MOPT_RDONLY, \
MOPT_UNION, \
MOPT_NOCLUSTERR, \
MOPT_NOCLUSTERW, \
MOPT_MULTILABEL, \
MOPT_ACLS, \
MOPT_NFS4ACLS, \
MOPT_AUTOMOUNTED
void getmntopts(const char *, const struct mntopt *, int *, int *);
void rmslashes(char *, char *);
int checkpath(const char *, char resolved_path[]);
extern int getmnt_silent;
void build_iovec(struct iovec **iov, int *iovlen, const char *name, void *val, size_t len);
void build_iovec_argf(struct iovec **iov, int *iovlen, const char *name, const char *fmt, ...);
void free_iovec(struct iovec **iovec, int *iovlen);
/*-
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Donn Seeley at Berkeley Software Design, Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions