diff --git a/db/User.pm.in b/db/User.pm.in index 6426810aa0eba8e29d584850a2abdf94d23e557d..0817f1fd7fd219e4bf46824c8182eeaf08829b4a 100644 --- a/db/User.pm.in +++ b/db/User.pm.in @@ -1037,12 +1037,13 @@ sub SSLCert($$$) } # -# Get user ssh key. This is bogus; I am returning a single key, making sure -# not to return the emulab key. The keys table needs work. +# Get user ssh keys. This is bogus; I am making sure not to return the +# emulab key which is not encrypted. The keys table needs work. # -sub GetSSHKey($$) +sub GetSSHKeys($$) { my ($self, $pref) = @_; + my @result = (); # Must be a real reference. return -1 @@ -1053,18 +1054,15 @@ sub GetSSHKey($$) my $query_result = DBQueryWarn("select pubkey from user_pubkeys ". "where uid_idx='$uid_idx' and ". - " comment not like '%${OURDOMAIN}' limit 1"); + " comment not like '%${OURDOMAIN}'"); return -1 if (!defined($query_result)); - if ($query_result->numrows) { - my ($sshkey) = $query_result->fetchrow_array(); - $$pref = $sshkey; - } - else { - $$pref = undef; - } + while (my ($key) = $query_result->fetchrow_array()) { + push(@result, $key); + } + @$pref = @result; return 0; } @@ -1606,8 +1604,10 @@ sub Lookup($$) return undef if (!$query_result || !$query_result->numrows); - my $self = {}; - $self->{'USER'} = $query_result->fetchrow_hashref(); + my $self = {}; + $self->{'USER'} = $query_result->fetchrow_hashref(); + # Want to know if this is a shadow of a local user. + $self->{'SHADOW'} = User->Lookup($idx); bless($self, $class); @@ -1625,6 +1625,7 @@ sub uid_uuid($) { return field($_[0], "uid_uuid"); } sub created($) { return field($_[0], "created"); } sub name($) { return field($_[0], "name"); } sub email($) { return field($_[0], "email"); } +sub shadow($) { return $_[0]->{'SHADOW'}; } # # Stringify for output. @@ -1644,8 +1645,9 @@ sub Stringify($) # sub Create($$$$$$;$) { - my ($class, $idx, $uid, $uuid, $name, $email, $sshkey) = @_; + my ($class, $idx, $uid, $uuid, $name, $email, $sshkeys) = @_; my @insert_data = (); + my $islocal = 0; # Every user gets a new unique index. if (!defined($idx) || $idx == 0) { @@ -1655,8 +1657,16 @@ sub Create($$$$$$;$) # Sanity check. my $existing = User->Lookup($idx); if (defined($existing)) { - print STDERR "NonLocal user with $idx already exists: $existing\n"; - return undef; + if ($uuid eq $existing->uuid()) { + # + # Shadow a local user, strictly for tmcd. + # + $islocal = 1; + } + else { + print STDERR "NonLocal user with $idx exists: $existing\n"; + return undef; + } } } @@ -1673,19 +1683,22 @@ sub Create($$$$$$;$) push(@insert_data, "email=$safe_email"); push(@insert_data, "uid_uuid=$safe_uuid"); - if (defined($sshkey)) { - my $safe_sshkey = DBQuoteSpecial($sshkey); + if (!$islocal && defined($sshkeys)) { + foreach my $sshkey (@{ $sshkeys }) { + my $safe_sshkey = DBQuoteSpecial($sshkey); - DBQueryWarn("insert into user_pubkeys set ". - " uid=$safe_uid, uid_idx='$idx', ". - " idx=NULL, stamp=now(), pubkey=$safe_sshkey") - or return undef; + DBQueryWarn("insert into user_pubkeys set ". + " uid=$safe_uid, uid_idx='$idx', ". + " idx=NULL, stamp=now(), pubkey=$safe_sshkey") + or return undef; + } } # Insert into DB. if (!DBQueryWarn("insert into nonlocal_users set " . join(",", @insert_data))) { - DBQueryWarn("delete from user_pubkeys where uid_idx='$idx'"); + DBQueryWarn("delete from user_pubkeys where uid_idx='$idx'") + if (!$islocal); return undef; } return User::NonLocal->Lookup($idx); @@ -1703,8 +1716,10 @@ sub Delete($) my $idx = $self->idx(); - DBQueryWarn("delete from user_pubkeys where uid_idx='$idx'") - or return -1; + if (!$self->shadow()) { + DBQueryWarn("delete from user_pubkeys where uid_idx='$idx'") + or return -1; + } DBQueryWarn("delete from nonlocal_user_bindings where uid_idx='$idx'") or return -1; DBQueryWarn("delete from nonlocal_users where uid_idx='$idx'")