[OpenAFS] uss command deprecated
Dan Scott
danieljamesscott@gmail.com
Thu, 26 Jan 2012 21:22:46 -0500
On Thu, Jan 26, 2012 at 20:26, Russ Allbery <rra@stanford.edu> wrote:
> Dan Scott <danieljamesscott@gmail.com> writes:
>
>> We use uss with a template file during account creation, to create a
>> volume and mountpoint, and to configure a skeleton directory and to set
>> permissions.
>
>> Is the uss command going to be removed? If so, is there an alternative
>> method of using similar templates? I couldn't find anything in the
>> manual.
>
> There are no immediate plans to remove it. =A0However, I'd like to
> understand your use case better, since I've not seen a use of uss that
> couldn't be replaced by a fairly simple shell script. =A0For example, her=
e
> is the script we use to create user home directories.
Thanks for your script. It looks like it does all that we require. It
just seems a lot more complicated than a couple of lines in a template
file.
It's not a big problem if it's removed, but doesn't uss remain useful
as a migration/setup tool? Maybe the useful parts could be
moved/merged with another utility?
Thanks,
Dan
> This is not exactly trivial, and it does rely on some internal tools like
> volcreate, but it's also not complex and could be made substantially
> simpler if one didn't mind editing it whenever policy changed. =A0Most of=
it
> is error checking.
>
> #!/usr/bin/perl -w
> $ID =3D q$Id: create-user,v 1.15 2010-06-14 15:15:37 hallk Exp $;
> #
> # create-user -- Create a user AFS volume and populate it.
> #
> # Written by Russ Allbery <rra@stanford.edu>
> # Copyright 2003, 2004, 2006 Board of Trustees, Leland Stanford Jr. Unive=
rsity
> #
> # Creates a user volume and populates it with the appropriate skel files =
and
> # the like. =A0Sets up initial AFS permissions in various portions of the
> # account. =A0Uses volcreate to do the actual volume creation. =A0Note th=
at unlike
> # the other create-* scripts, this script is not interactive. =A0It takes=
the
> # user name as a command-line argument.
>
> #########################################################################=
#####
> # Site configuration
> #########################################################################=
#####
>
> # The path to the file that contains the default quota amounts.
> $DEFAULTQUOTA =A0 =3D '/afs/ir/service/afs/data/default-quota';
>
> # The full path to fs. =A0Allow for Linux where the preferred location ma=
y be on
> # local disk, and normally avoid the pubsw wrapper.
> ($FS) =A0=3D grep { -x $_ } qw(/usr/bin/fs /usr/afsws/bin/fs /usr/pubsw/b=
in/fs);
> $FS ||=3D '/usr/afsws/bin/fs';
>
> # The full path to pts. =A0Allow for Linux where the preferred location m=
ay be
> # on local disk.
> ($PTS) =A0=3D grep { -x $_ } qw(/usr/bin/pts /usr/pubsw/bin/pts);
> $PTS ||=3D '/usr/pubsw/bin/pts';
>
> # The path to the skeleton files that are installed in a new account.
> #($SKEL) =A0=3D grep { -x $_ } qw(/etc/lsdb/skel /usr/pubsw/etc/skel);
> #$SKEL ||=3D '/usr/pubsw/etc/skel';
> $SKEL =A0 =A0 =A0 =A0 =A0 =3D '/usr/pubsw/etc/skel';
>
> # The path to the volcreate script.
> $VOLCREATE =A0 =A0 =A0=3D '/afs/ir/service/afs/scripts/volcreate';
>
> # The path to the volume release script.
> $VOLRELEASE =A0 =A0 =3D '/afs/ir/service/afs/scripts/volrelease';
>
> #########################################################################=
#####
> # Modules and declarations
> #########################################################################=
#####
>
> require 5.004;
>
> use strict;
> use subs qw(chmod chown mkdir system);
> use vars qw($DEFAULTQUOTA $FS $ID $PTS $SKEL $VOLCREATE $VOLRELEASE);
>
> use File::Copy qw(copy);
>
> #########################################################################=
#####
> # Overrides for error checking
> #########################################################################=
#####
>
> sub chmod {
> =A0 =A0my $status =3D CORE::chmod ($_[0], $_[1]);
> =A0 =A0unless ($status) {
> =A0 =A0 =A0 =A0warn "$0: chmod $_[1] failed: $!\n";
> =A0 =A0}
> =A0 =A0return $status;
> }
>
> sub chown {
> =A0 =A0my $status =3D CORE::chown ($_[0], $_[1], $_[2]);
> =A0 =A0unless ($status) {
> =A0 =A0 =A0 =A0warn "$0: chown $_[2] failed: $!\n";
> =A0 =A0}
> =A0 =A0return $status;
> }
>
> sub mkdir {
> =A0 =A0my $status =3D CORE::mkdir ($_[0], $_[1]);
> =A0 =A0unless ($status) {
> =A0 =A0 =A0 =A0warn "$0: mkdir $_[0] failed: $!\n";
> =A0 =A0}
> =A0 =A0return $status;
> }
>
> sub system {
> =A0 =A0my $status =3D CORE::system (@_);
> =A0 =A0if ($status !=3D 0) {
> =A0 =A0 =A0 =A0die "$0: @_ exited with status ", ($status >> 8), "\n";
> =A0 =A0}
> =A0 =A0return $status;
> }
>
> #########################################################################=
#####
> # Implementation
> #########################################################################=
#####
>
> # Get the default quota for user volumes.
> sub default_quota {
> =A0 =A0open (QUOTA, $DEFAULTQUOTA) or die "$0: can't open $DEFAULTQUOTA: =
$!\n";
> =A0 =A0local $_;
> =A0 =A0my $quota;
> =A0 =A0while (<QUOTA>) {
> =A0 =A0 =A0 =A0next if /^\s*$/;
> =A0 =A0 =A0 =A0next if /^\s*\#/;
> =A0 =A0 =A0 =A0if (/^\s*user:\s*(\d+)\s*$/) {
> =A0 =A0 =A0 =A0 =A0 =A0$quota =3D $1;
> =A0 =A0 =A0 =A0}
> =A0 =A0}
> =A0 =A0close QUOTA;
> =A0 =A0die "$0: no user quota default found in $DEFAULTQUOTA\n" unless $q=
uota;
> =A0 =A0return $quota;
> }
>
> # Look for a user in PTS. =A0If the user is found, returns their UID; oth=
erwise,
> # abort.
> sub pts_examine {
> =A0 =A0my ($user) =3D @_;
> =A0 =A0die "$0: bad characters in SUNet ID $user\n" if ($user =3D~ /[\s\'=
\\]/);
> =A0 =A0my $output =3D `$PTS examine '$user' 2>&1`;
> =A0 =A0my $status =3D $?;
> =A0 =A0$output =3D~ s/^libprot: no such entry Could not get afs tokens.*\=
n//;
>
> =A0 =A0# For some reason, a regex anchored with ^ still doesn't match the=
output,
> =A0 =A0# even though we've removed the libprot line. =A0I don't understan=
d at all,
> =A0 =A0# but not anchoring the regex does work. =A0Perl bug?
> =A0 =A0if ($status =3D=3D 0 && $output =3D~ /Name: \Q$user\E, id: (\d+),/=
) {
> =A0 =A0 =A0 =A0return $1;
> =A0 =A0} else {
> =A0 =A0 =A0 =A0warn $output;
> =A0 =A0 =A0 =A0if ($status !=3D 0) {
> =A0 =A0 =A0 =A0 =A0 =A0die "$0: PTS examine for $user failed with status =
",
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0($status >> 8), "\n";
> =A0 =A0 =A0 =A0}
> =A0 =A0 =A0 =A0exit 1;
> =A0 =A0}
> }
>
> # Create the user's volume. =A0Assumes that we're already authenticated a=
s a
> # user who can create volumes.
> sub create_volume {
> =A0 =A0my ($user) =3D @_;
> =A0 =A0my $quota =3D default_quota;
> =A0 =A0unless (length ($user) > 1) {
> =A0 =A0 =A0 =A0die "$0: user $user must be at least two characters\n";
> =A0 =A0}
> =A0 =A0unless ($user =3D~ /^[a-z0-9]+$/) {
> =A0 =A0 =A0 =A0die "$0: invalid characters in user $user\n";
> =A0 =A0}
> =A0 =A0my ($f, $s) =3D ($user =3D~ /^(\w)(\w)/);
> =A0 =A0my $path =3D "/afs/.ir/users/$f/$s/$user";
> =A0 =A0system ($VOLCREATE, '-t', 'user', "user.$user", $quota, $path,
> =A0 =A0 =A0 =A0 =A0 =A0$user, 'all');
> =A0 =A0system ($VOLRELEASE, "users.$f.$s");
> }
>
> # Set up the user directory.
> sub setup_directory {
> =A0 =A0my ($user) =3D @_;
> =A0 =A0umask 022;
>
> =A0 =A0unless (length ($user) > 1) {
> =A0 =A0 =A0 =A0die "$0: user $user must be at least two characters\n";
> =A0 =A0}
> =A0 =A0unless ($user =3D~ /^[a-z0-9]+$/) {
> =A0 =A0 =A0 =A0die "$0: invalid characters in user $user\n";
> =A0 =A0}
> =A0 =A0my ($f, $s) =3D ($user =3D~ /^(\w)(\w)/);
> =A0 =A0my $path =3D "/afs/.ir/users/$f/$s/$user";
> =A0 =A0my $uid =3D pts_examine ($user);
> =A0 =A0my $gid =3D 37;
> =A0 =A0unless (-d $path) {
> =A0 =A0 =A0 =A0die "$0: home directory $path invalid: $!\n";
> =A0 =A0}
>
> =A0 =A0system ($FS, 'mkmount', "$path/.backup", "user.$user.backup");
> =A0 =A0mkdir ("$path/private", 0700);
> =A0 =A0mkdir ("$path/public", =A00755);
> =A0 =A0mkdir ("$path/Mail", =A0 =A00700);
> =A0 =A0mkdir ("$path/News", =A0 =A00700);
> =A0 =A0mkdir ("$path/WWW", =A0 =A0 0755);
> =A0 =A0chown ($uid, $gid, $path);
> =A0 =A0chown ($uid, $gid, "$path/private");
> =A0 =A0chown ($uid, $gid, "$path/public");
> =A0 =A0chown ($uid, $gid, "$path/Mail");
> =A0 =A0chown ($uid, $gid, "$path/News");
> =A0 =A0chown ($uid, $gid, "$path/WWW");
> =A0 =A0system ($FS, 'setacl', $path, =A0 =A0 =A0 =A0 =A0'system:campushos=
ts', 'l');
> =A0 =A0system ($FS, 'setacl', $path, =A0 =A0 =A0 =A0 =A0'system:www-serve=
rs', 'l');
> =A0 =A0system ($FS, 'setacl', "$path/public", 'system:campushosts', 'rl')=
;
> =A0 =A0system ($FS, 'setacl', "$path/WWW", =A0 =A0'system:www-servers', '=
rl');
> =A0 =A0opendir (SKEL, $SKEL) or die "$0: can't open $SKEL: $!\n";
> =A0 =A0for my $file (grep { !/^\.\.?$/ } readdir SKEL) {
> =A0 =A0 =A0 =A0copy ("$SKEL/$file", "$path/$file")
> =A0 =A0 =A0 =A0 =A0 =A0or die "$0: can't copy $SKEL/$file to $path/$file:=
$!\n";
> =A0 =A0 =A0 =A0chown ($uid, $gid, "$path/$file");
> =A0 =A0}
> =A0 =A0closedir SKEL;
>
> =A0 =A0open (KLOGIN, "> $path/public/.klogin")
> =A0 =A0 =A0 =A0or die "$0: can't create $path/public/.klogin: $!\n";
> =A0 =A0print KLOGIN "$user\@IR.STANFORD.EDU\n";
> =A0 =A0close KLOGIN or die "$0: can't flush $path/public/.klogin: $!\n";
> =A0 =A0open (K5LOGIN, "> $path/public/.k5login")
> =A0 =A0 =A0 =A0or die "$0: can't create $path/public/.k5login: $!\n";
> =A0 =A0print K5LOGIN "$user\@stanford.edu\n";
> =A0 =A0close K5LOGIN or die "$0: can't flush $path/public/.k5login: $!\n"=
;
> =A0 =A0chown ($uid, $gid, "$path/public/.klogin");
> =A0 =A0chown ($uid, $gid, "$path/public/.k5login");
> =A0 =A0symlink ("public/.klogin", "$path/.klogin")
> =A0 =A0 =A0 =A0or die "$0: can't symlink $path/.klogin: $!\n";
> =A0 =A0symlink ("public/.k5login", "$path/.k5login")
> =A0 =A0 =A0 =A0or die "$0: can't symlink $path/.k5login: $!\n";
> }
>
> #########################################################################=
#####
> # Main routine
> #########################################################################=
#####
>
> # Clean up for error messages.
> $0 =3D~ s%.*/%%;
>
> my $user =3D shift or die "$0: no user specified\n";
> create_volume ($user);
> setup_directory ($user);
>
> --
> Russ Allbery (rra@stanford.edu) =A0 =A0 =A0 =A0 =A0 =A0 <http://www.eyrie=
.org/~eagle/>