MOO-cows Mailing List Archive


BF proposal: bf_superuser()

Hi folks --

I'm interested in a way of 'superusering' to a wizard character (from a
non-wiz) with a single command.  It turns out it's relatively easy to
write a builtin that looks like

;superuser(#X, #Y)

that turns player #X into player #Y: for instance, ';superuser(#546, #2)'
would make the person connected to player #546 suddenly be connected to
player #2 instead.  (See below for details.) I'd like to see this
incorporated into the server, and I think it would help make wizards get
into the habit of playing non-wiz characters by default, and only
superusering to a wizard when necessary.  (Always playing a wizard is like
always being root, but we all do it.)

My questions are (a) is this in fact a good idea, and (b) if so, how
should such a builtin, and the in-db wrapper around it, work?  The builtin
should probably be wizard-only, with a wrapper (owned by a wizard) that
prompts for a password.  But should @superuser, upon success, allow
players to become any other player they have the password for?  Any wizard
they have the password for? Only one specific wizard (i.e. #2) who then
has the only wizbit on the MOO?  The last seems a little cleaner in some
ways, but would mean only one person could superuser (i.e. be a wizard) at
a time. 

As a further question, should people be able to superuser to a wizard
"invisibly," so that they could su to check on something wizardly without
disrupting a conversation, etc.?  This would involve creating a fake
shandle and nhandle for the programmer character, perhaps buffering data
on the fake nhandle's network buffer, and sending the data to the real
connection upon the superuser exit.  This would be a lot more convenient
than vanishing in a puff of smoke every time one wanted to fix a tiny bug
as a wizard. 

This is a recent idea for me, but I know people have asked about it in 
the past.  Any thoughts/comments?

Tripod, Inc.

P.S. Yes, this is a lot like my bf_connect_player() idea. :)

P.P.S. Here are the technical details: all you have to do to connect
someone is set the value of the "player" member in their connection's
shandle and the "player" member in their tqueue.  So this builtin looks
like what's below, where transfer_tasks() is just a function that takes
care of shuffling tasks around (essentially the same as lines 550-579 of

static package
bf_superuser(Var arglist, Byte next, void *vdata, Objid progr)
{ /* (object, object) */
    Objid       original = arglist.v.list[1].v.obj;
    Objid       target = arglist.v.list[2].v.obj; 

    shandle    *oh = find_shandle(original);
    shandle    *th = find_shandle(target);


    if (!is_wizard(progr))
      return make_error_pack(E_PERM);
    else if (!is_user(original) || !is_user(target))
      return make_error_pack(E_INVARG);
    else if (!oh || th)
      return make_error_pack(E_INVARG);

    /* Now we're convinced that we're dealing with a connected player who 
       is superusering an unconnected player.  The unconnected player
       requirement is just to be polite -- otherwise we'd boot people
       without warning if we were su-ing to them. */

    transfer_tasks(original, target);
    oh->player = target;
    oklog("SUPERUSERED: %s, by %s\n", object_name(target), 

    return no_var_pack();

Home | Subject Index | Thread Index