Esempio n. 1
0
/** Check for CHARGES on thing and, if present, lower.
 * \param thing object being used.
 * \retval 0 charges was set to 0
 * \retval 1 charges not set, or was > 0
 */
int
charge_action(dbref thing)
{
  ATTR *b;
  char tbuf2[BUFFER_LEN];
  int num;

  /* check if object has # of charges */
  b = atr_get_noparent(thing, "CHARGES");

  if (!b) {
    return 1;                   /* no CHARGES */
  } else {
    strcpy(tbuf2, atr_value(b));
    num = atoi(tbuf2);
    if (num > 0) {
      /* charges left, decrement and execute */
      (void) atr_add(thing, "CHARGES", tprintf("%d", num - 1),
                     Owner(b->creator), 0);
      return 1;
    } else {
      /* no charges left, try to execute runout */
      return 0;
    }
  }
}
Esempio n. 2
0
/** Retrieve the amount of quote remaining to a player.
 * Figure out a player's quota. Add the RQUOTA attribute if he doesn't
 * have one already. This function returns the REMAINING quota, not
 * the TOTAL limit.
 * \param who player to check.
 * \return player's remaining quota.
 */
int
get_current_quota(dbref who)
{
  ATTR *a;
  int i;
  int limit;
  int owned = 0;

  /* if he's got an RQUOTA attribute, his remaining quota is that */
  a = atr_get_noparent(Owner(who), "RQUOTA");
  if (a)
    return parse_integer(atr_value(a));

  /* else, count up his objects. If he has less than the START_QUOTA,
   * then his remaining quota is that minus his number of current objects.
   * Otherwise, it's his current number of objects. Add the attribute
   * if he doesn't have it.
   */

  for (i = 0; i < db_top; i++)
    if (Owner(i) == Owner(who))
      owned++;
  owned--;                      /* don't count the player himself */

  if (owned <= START_QUOTA)
    limit = START_QUOTA - owned;
  else
    limit = owned;

  (void) atr_add(Owner(who), "RQUOTA", tprintf("%d", limit), GOD, 0);

  return limit;
}
Esempio n. 3
0
/** Processing related to players' last connections.
 * Here we check to see if a player gets a paycheck, tell them their
 * last connection site, and update all their LAST* attributes.
 * \param player dbref of player.
 * \param host hostname of player's current connection.
 * \param ip ip address of player's current connection.
 */
void
check_last(dbref player, const char *host, const char *ip)
{
  char *s;
  ATTR *a;
  ATTR *h;
  char last_time[MAX_COMMAND_LEN / 8];
  char last_place[MAX_COMMAND_LEN];

  /* compare to last connect see if player gets salary */
  s = show_time(mudtime, 0);
  a = atr_get_noparent(player, "LAST");
  if (a && (strncmp(atr_value(a), s, 10) != 0))
    giveto(player, Paycheck(player));
  /* tell the player where he last connected from */
  if (!Guest(player)) {
    h = atr_get_noparent(player, "LASTSITE");
    if (h && a) {
      strcpy(last_place, atr_value(h));
      strcpy(last_time, atr_value(a));
      notify_format(player, T("Last connect was from %s on %s."), last_place,
                    last_time);
    }
    /* How about last failed connection */
    h = atr_get_noparent(player, "LASTFAILED");
    if (h && a) {
      strcpy(last_place, atr_value(h));
      if (strlen(last_place) > 2)
        notify_format(player, T("Last FAILED connect was from %s."),
                      last_place);
    }
  }
  /* if there is no Lastsite, then the player is newly created.
   * the extra variables are a kludge to work around some weird
   * behavior involving uncompress.
   */

  /* set the new attributes */
  (void) atr_add(player, "LAST", s, GOD, 0);
  (void) atr_add(player, "LASTSITE", host, GOD, 0);
  (void) atr_add(player, "LASTIP", ip, GOD, 0);
  (void) atr_add(player, "LASTFAILED", " ", GOD, 0);
}
Esempio n. 4
0
/** Check a player's password against a given string.
 *
 *  First checks new-style formatted password strings
 *  If that doesn't match, tries old-style SHA0 password
 *  strings, and upgrades the stored password.
 *  If that doesn't match, tries really-old-style crypt(3)
 *  password strings, and upgrades the stored password.
 *  If that doesn't work, you lose.
 *
 * \param player dbref of player.
 * \param password plaintext password string to check.
 * \retval 1 password matches (or player has no password).
 * \retval 0 password fails to match.
 */
bool
password_check(dbref player, const char *password)
{
  ATTR *a;
  char *saved;

  /* read the password and compare it */
  if (!(a = atr_get_noparent(player, pword_attr)))
    return 1; /* No password attribute */

  saved = strdup(atr_value(a));

  if (!saved)
    return 0;

  if (!password_comp(saved, password)) {
    /* Nope. Try SHA0. */
    char *passwd = mush_crypt_sha0(password);
    if (strcmp(saved, passwd) != 0) {
/* Not SHA0 either. Try old-school crypt(); */
#ifdef HAVE_CRYPT
      if (strcmp(crypt(password, "XX"), saved) != 0) {
/* Nope */
#endif /* HAVE_CRYPT */
        /* See if it's a MUX password */
        if (!check_mux_password(saved, password)) {
          /* As long as it's not obviously encrypted, check for a
           * plaintext password. */
          if (strlen(password) < 4 || *password == '$' ||
              (password[0] == 'X' && password[1] == 'X') ||
              strcmp(saved, password)) {
            free(saved);
            return 0;
          }
        }
#ifdef HAVE_CRYPT
      }
#endif
    }
    /* Something worked. Change password to SHS-encrypted */
    do_rawlog(LT_CONN, "Updating password format for player #%d", player);
    (void) atr_add(player, pword_attr, password_hash(password, NULL), GOD, 0);
  }
  /* Success! */
  free(saved);
  return 1;
}
Esempio n. 5
0
/** Reset all of a player's player list entries (names/aliases).
 * This is called when a player changes name or alias.
 * We remove all their old entries, and add back their new ones.
 * \param player dbref of player
 * \param oldname player's former name (NULL if not changing)
 * \param oldalias player's former aliases (NULL if not changing)
 * \param name player's new name
 * \param alias player's new aliases
 */
void
reset_player_list(dbref player, const char *oldname, const char *oldalias,
                  const char *name, const char *alias)
{
  char tbuf1[BUFFER_LEN];
  char tbuf2[BUFFER_LEN];
  if (!oldname)
    name = Name(player);
  if (oldalias) {
    mush_strncpy(tbuf1, oldalias, BUFFER_LEN);
    if (alias) {
      strncpy(tbuf2, alias, BUFFER_LEN - 1);
      tbuf2[BUFFER_LEN - 1] = '\0';
    } else {
      tbuf2[0] = '\0';
    }
  } else {
    /* We are not changing aliases, just name, but we need to get the
     * aliases anyway, since we may change name to something that's
     * in the alias, and thus must not be deleted.
     */
    ATTR *a = atr_get_noparent(player, "ALIAS");
    if (a) {
      mush_strncpy(tbuf1, atr_value(a), BUFFER_LEN);
    } else {
      tbuf1[0] = '\0';
    }
    strcpy(tbuf2, tbuf1);
  }
  /* Delete all the old stuff */
  delete_player(player, tbuf1);
  delete_player(player, NULL);
  /* Add in the new stuff */
  add_player_alias(player, name);
  add_player_alias(player, tbuf2);
}
Esempio n. 6
0
/** Clone an object.
 * \verbatim
 * This is the top-level function for @clone, which creates a duplicate
 * of a (non-player) object.
 * \endverbatim
 * \param player the enactor.
 * \param name the name of the object to clone.
 * \param newname the name to give the duplicate.
 * \param preserve if 1, preserve ownership and privileges on duplicate.
 * \param newdbref the (unparsed) dbref to give the object, or NULL to use the next free
 * \param pe_info The pe_info to use for lock and \@command priv checks
 * \return dbref of the duplicate, or NOTHING.
 */
dbref
do_clone(dbref player, char *name, char *newname, int preserve, char *newdbref,
         NEW_PE_INFO *pe_info)
{
  dbref clone, thing;
  char dbnum[BUFFER_LEN];

  thing = noisy_match_result(player, name, NOTYPE, MAT_EVERYTHING);
  if (thing == NOTHING)
    return NOTHING;

  if (newname && *newname && !ok_name(newname, IsExit(thing))) {
    notify(player, T("That is not a reasonable name."));
    return NOTHING;
  }

  if (!controls(player, thing) || IsPlayer(thing) ||
      (IsRoom(thing) && !command_check_byname(player, "@dig", pe_info)) ||
      (IsExit(thing) && !command_check_byname(player, "@open", pe_info)) ||
      (IsThing(thing) && !command_check_byname(player, "@create", pe_info))) {
    notify(player, T("Permission denied."));
    return NOTHING;
  }
  /* don't allow cloning of destructed things */
  if (IsGarbage(thing)) {
    notify(player, T("There's nothing left of it to clone!"));
    return NOTHING;
  }
  if (preserve && !Wizard(player)) {
    notify(player, T("You cannot @CLONE/PRESERVE. Use normal @CLONE instead."));
    return NOTHING;
  }

  if (!make_first_free_wrapper(player, newdbref)) {
    return NOTHING;
  }

  /* make sure owner can afford it */
  switch (Typeof(thing)) {
  case TYPE_THING:
    if (can_pay_fees(player, Pennies(thing))) {
      clone = clone_object(player, thing, newname, preserve);
      notify_format(player, T("Cloned: Object %s."), unparse_dbref(clone));
      if (IsRoom(player))
        moveto(clone, player, player, "cloned");
      else
        moveto(clone, Location(player), player, "cloned");
      current_state.things++;
      local_data_clone(clone, thing, preserve);
      real_did_it(player, clone, NULL, NULL, NULL, NULL, "ACLONE", NOTHING,
                  NULL, 0, 0);
      return clone;
    }
    return NOTHING;
    break;
  case TYPE_ROOM:
    if (can_pay_fees(player, ROOM_COST)) {
      clone = clone_object(player, thing, newname, preserve);
      Exits(clone) = NOTHING;
      notify_format(player, T("Cloned: Room #%d."), clone);
      current_state.rooms++;
      local_data_clone(clone, thing, preserve);
      real_did_it(player, clone, NULL, NULL, NULL, NULL, "ACLONE", NOTHING,
                  NULL, 0, 0);
      return clone;
    }
    return NOTHING;
    break;
  case TYPE_EXIT:
    /* For exits, we don't want people to be able to link it to
       a location they can't with @open. So, all this stuff.
     */
    switch (Location(thing)) {
    case NOTHING:
      strcpy(dbnum, "#-1");
      break;
    case HOME:
      strcpy(dbnum, "home");
      break;
    case AMBIGUOUS:
      strcpy(dbnum, "variable");
      break;
    default:
      strcpy(dbnum, unparse_dbref(Location(thing)));
    }
    if (newname && *newname)
      clone = do_real_open(player, newname, dbnum, NOTHING, pe_info);
    else
      clone = do_real_open(player, Name(thing), dbnum, NOTHING, pe_info);
    if (!GoodObject(clone)) {
      return NOTHING;
    } else {
      char *alias_val = NULL;
      ATTR *alias_attr = NULL;
      alias_attr = atr_get_noparent(clone, "ALIAS");
      if (alias_attr) {
        alias_val = safe_atr_value(alias_attr, "atrval.do_clone");
        atr_clr(clone, "ALIAS", GOD);
      }
      atr_cpy(clone, thing);
      if (alias_val) {
        atr_add(clone, "ALIAS", alias_val, player, 0);
        mush_free(alias_val, "atrval.do_clone");
      }
      clone_locks(player, thing, clone);
      Zone(clone) = Zone(thing);
      Parent(clone) = Parent(thing);
      Flags(clone) = clone_flag_bitmask("FLAG", Flags(thing));
      if (!preserve) {
        clear_flag_internal(clone, "WIZARD");
        clear_flag_internal(clone, "ROYALTY");
        Warnings(clone) = 0;    /* zap warnings */
        Powers(clone) = new_flag_bitmask("POWER");      /* zap powers */
      } else {
        Warnings(clone) = Warnings(thing);
        Powers(clone) = clone_flag_bitmask("POWER", Powers(thing));
      }
      if (Wizard(clone) || Royalty(clone) || Warnings(clone) ||
          !null_flagmask("POWER", Powers(clone)))
        notify(player,
               T
               ("Warning: @CLONE/PRESERVE on an object with WIZ, ROY, @powers, or @warnings."));
      notify_format(player, T("Cloned: Exit #%d."), clone);
      local_data_clone(clone, thing, preserve);
      return clone;
    }
  }
  return NOTHING;

}
Esempio n. 7
0
/** Add new standard attributes, or change permissions on them.
 * \verbatim
 * Given the name and permission string for an attribute, add it to
 * the attribute table (or modify the permissions if it's already
 * there). Permissions may be changed retroactively, which modifies
 * permissions on any copies of that attribute set on objects in the
 * database. This is the top-level code for @attribute/access.
 * \endverbatim
 * \param player the enactor.
 * \param name the attribute name.
 * \param perms a string of attribute permissions, space-separated.
 * \param retroactive if true, apply the permissions retroactively.
 */
void
do_attribute_access(dbref player, char *name, char *perms, int retroactive)
{
  ATTR *ap, *ap2;
  privbits flags = 0;
  int i;
  int insert = 0;

  /* Parse name and perms */
  if (!name || !*name) {
    notify(player, T("Which attribute do you mean?"));
    return;
  }
  if (strcasecmp(perms, "none")) {
    flags = list_to_privs(attr_privs_set, perms, 0);
    if (!flags) {
      notify(player, T("I don't understand those permissions."));
      return;
    }
  }
  upcasestr(name);
  /* Is this attribute already in the table? */
  ap = (ATTR *) ptab_find_exact(&ptab_attrib, name);
  if (ap) {
    if (AF_Internal(ap)) {
      /* Don't muck with internal attributes */
      notify(player, T("That attribute's permissions can not be changed."));
      return;
    }
  } else {
    /* Create fresh if the name is ok */
    if (!good_atr_name(name)) {
      notify(player, T("Invalid attribute name."));
      return;
    }
    insert = 1;
    ap = (ATTR *) mush_malloc(sizeof(ATTR), "ATTR");
    if (!ap) {
      notify(player, T("Critical memory failure - Alert God!"));
      do_log(LT_ERR, 0, 0, "do_attribute_access: unable to malloc ATTR");
      return;
    }
    AL_NAME(ap) = strdup(name);
    ap->data = NULL_CHUNK_REFERENCE;
  }
  AL_FLAGS(ap) = flags;
  AL_CREATOR(ap) = player;

  /* Only insert when it's not already in the table */
  if (insert) {
    ptab_insert_one(&ptab_attrib, name, ap);
  }

  /* Ok, now we need to see if there are any attributes of this name
   * set on objects in the db. If so, and if we're retroactive, set
   * perms/creator
   */
  if (retroactive) {
    for (i = 0; i < db_top; i++) {
      if ((ap2 = atr_get_noparent(i, name))) {
        if (AL_FLAGS(ap2) & AF_ROOT)
          AL_FLAGS(ap2) = flags | AF_ROOT;
        else
          AL_FLAGS(ap2) = flags;
        AL_CREATOR(ap2) = player;
      }
    }
  }

  notify_format(player, T("%s -- Attribute permissions now: %s"), name,
                privs_to_string(attr_privs_view, flags));
}