Esempio n. 1
0
static lock_list *
getlockstruct(dbref thing, lock_type type)
{
  lock_list *ll;
  dbref p = thing, ancestor = NOTHING;
  int cmp, count = 0, ancestor_in_chain = 0;

  if (GoodObject(thing))
    ancestor = Ancestor_Parent(thing);
  do {
    for (; GoodObject(p); p = Parent(p)) {
      if (count++ > 100)
        return NULL;
      if (p == ancestor)
        ancestor_in_chain = 1;
      ll = Locks(p);
      while (ll && L_TYPE(ll)) {
        cmp = strcasecmp(L_TYPE(ll), type);
        if (cmp == 0)
          return (p != thing && (ll->flags & LF_PRIVATE)) ? NULL : ll;
        else if (cmp > 0)
          break;
        ll = ll->next;
      }
    }
    p = ancestor;
  } while (!ancestor_in_chain && !Orphan(thing) && GoodObject(ancestor));
  return NULL;
}
Esempio n. 2
0
/** Add a lock to an object (primitive).
 * Set the lock type on thing to boolexp.
 * This is a primitive routine, to be called by other routines.
 * It will go somewhat wonky if given a NULL boolexp.
 * It will allocate memory if called with a string that is not already
 * in the lock table.
 * \param player the enactor, for permission checking.
 * \param thing object on which to set the lock.
 * \param type type of lock to set.
 * \param key lock boolexp pointer (should not be NULL!).
 * \param flags lock flags.
 * \retval 0 failure.
 * \retval 1 success.
 */
int
add_lock(dbref player, dbref thing, lock_type type, boolexp key, int flags)
{
  lock_list *ll, **t;
  lock_type real_type = type;

  if (!GoodObject(thing)) {
    return 0;
  }

  ll = getlockstruct_noparent(thing, type);

  if (ll) {
    if (!can_write_lock(player, thing, ll)) {
      free_boolexp(key);
      return 0;
    }
    /* We're replacing an existing lock. */
    free_boolexp(ll->key);
    ll->key = key;
    ll->creator = player;
    if (flags != -1)
      ll->flags = flags;
  } else {
    ll = next_free_lock();
    if (!ll) {
      /* Oh, this sucks */
      do_log(LT_ERR, 0, 0, "Unable to malloc memory for lock_list!");
    } else {
      real_type = st_insert(type, &lock_names);
      ll->type = real_type;
      ll->key = key;
      ll->creator = player;
      if (flags == -1) {
        const lock_list *l2 = get_lockproto(real_type);
        if (l2)
          ll->flags = l2->flags;
        else
          ll->flags = 0;
      } else {
        ll->flags = flags;
      }
      if (!can_write_lock(player, thing, ll)) {
        st_delete(real_type, &lock_names);
        free_boolexp(key);
        return 0;
      }
      t = &Locks(thing);
      while (*t && strcasecmp(L_TYPE(*t), L_TYPE(ll)) < 0)
        t = &L_NEXT(*t);
      L_NEXT(ll) = *t;
      *t = ll;
    }
  }
  return 1;
}
Esempio n. 3
0
/** Set flags on a lock (user interface).
 * \verbatim
 * This implements @lset.
 * \endverbatim
 * \param player the enactor.
 * \param what string in the form obj/lock.
 * \param flags list of flags to set.
 */
void
do_lset(dbref player, char *what, char *flags)
{
  dbref thing;
  lock_list *l;
  char *lname;
  int flag;
  int unset = 0;

  if ((lname = strchr(what, '/')) == NULL) {
    notify(player, T("No lock name given."));
    return;
  }
  *lname++ = '\0';

  if ((thing = match_controlled(player, what)) == NOTHING)
    return;

  if (*flags == '!') {
    unset = 1;
    flags++;
  }

  if ((flag = string_to_lockflag(flags)) < 0) {
    notify(player, T("Unrecognized lock flag."));
    return;
  }

  l = getlockstruct_noparent(thing, lname);
  if (!l || !Can_Read_Lock(player, thing, L_TYPE(l))) {
    notify(player, T("No such lock."));
    return;
  }

  if (!can_write_lock(player, thing, l)) {
    notify(player, T("Permission denied."));
    return;
  }

  if (unset)
    L_FLAGS(l) &= ~flag;
  else
    L_FLAGS(l) |= flag;

  if (!Quiet(player) && !(Quiet(thing) && (Owner(thing) == player)))
    notify_format(player, "%s/%s - %s.", Name(thing), L_TYPE(l),
                  unset ? T("lock flags unset") : T("lock flags set"));
  if (!IsPlayer(thing)) {
          char lmbuf[1024];
          ModTime(thing) = mudtime;
          snprintf(lmbuf, 1023, "lflags - %s[#%d]", flags, player);
          lmbuf[strlen(lmbuf)+1] = '\0';
          set_lmod(thing, lmbuf);
  }
}
Esempio n. 4
0
/** Set flags on a lock (user interface).
 * \verbatim
 * This implements @lset.
 * \endverbatim
 * \param player the enactor.
 * \param what string in the form obj/lock.
 * \param flags list of flags to set.
 */
void
do_lset(dbref player, char *what, char *flags)
{
  dbref thing;
  lock_list *l;
  char *lname;
  privbits flag;
  bool unset = 0;

  if ((lname = strchr(what, '/')) == NULL) {
    notify(player, T("No lock name given."));
    return;
  }
  *lname++ = '\0';

  if ((thing = match_controlled(player, what)) == NOTHING)
    return;

  if (*flags == '!') {
    unset = 1;
    flags++;
  }

  if (string_to_lockflag(player, flags, &flag) < 0) {
    notify(player, T("Unrecognized lock flag."));
    return;
  }

  l = getlockstruct_noparent(thing, lname);
  if (!l || !Can_Read_Lock(player, thing, L_TYPE(l))) {
    notify(player, T("No such lock."));
    return;
  }

  if (!can_write_lock(player, thing, l)) {
    notify(player, T("Permission denied."));
    return;
  }

  if (unset)
    L_FLAGS(l) &= ~flag;
  else
    L_FLAGS(l) |= flag;

  if (!Quiet(player) && !(Quiet(thing) && (Owner(thing) == player)))
    notify_format(player, "%s/%s - %s.", AName(thing, AN_SYS, NULL), L_TYPE(l),
                  unset ? T("lock flags unset") : T("lock flags set"));
  if (!IsPlayer(thing))
    ModTime(thing) = mudtime;
}
Esempio n. 5
0
static lock_list *
getlockstruct_noparent(dbref thing, lock_type type)
{
  lock_list *ll = Locks(thing);
  int cmp;

  while (ll && L_TYPE(ll)) {
    cmp = strcasecmp(L_TYPE(ll), type);
    if (cmp == 0)
      return ll;
    else if (cmp > 0)
      break;
    ll = ll->next;
  }
  return NULL;
}
Esempio n. 6
0
/** Copy the locks from one object to another.
 * \param player the enactor.
 * \param orig the source object.
 * \param clone the destination object.
 */
void
clone_locks(dbref player, dbref orig, dbref clone)
{
  lock_list *ll;
  for (ll = Locks(orig); ll; ll = ll->next) {
    if (!(L_FLAGS(ll) & LF_NOCLONE))
      add_lock(player, clone, L_TYPE(ll), dup_bool(L_KEY(ll)), L_FLAGS(ll));
  }
}
Esempio n. 7
0
static void
ct_generic(dbref player, dbref i, warn_type flags)
{
    if ((flags & W_LOCK_PROBS)) {
        lock_list *ll;
        for (ll = Locks(i); ll; ll = L_NEXT(ll)) {
            check_lock(player, i, L_TYPE(ll), L_KEY(ll));
        }
    }
}
Esempio n. 8
0
/** Add a lock to an object on db load.
 * Set the lock type on thing to boolexp.
 * Used only on db load, when we can't safely test the player's
 * permissions because they're not loaded yet.
 * This is a primitive routine, to be called by other routines.
 * It will go somewhat wonky if given a NULL boolexp.
 * It will allocate memory if called with a string that is not already
 * in the lock table.
 * \param player lock creator.
 * \param thing object on which to set the lock.
 * \param type type of lock to set.
 * \param key lock boolexp pointer (should not be NULL!).
 * \param flags lock flags.
 * \retval 0 failure.
 */
int
add_lock_raw(dbref player, dbref thing, lock_type type, boolexp key,
             privbits flags)
{
  lock_list *ll, **t;
  lock_type real_type = type;

  if (!GoodObject(thing)) {
    return 0;
  }

  ll = next_free_lock(Locks(thing));
  if (!ll) {
    /* Oh, this sucks */
    do_log(LT_ERR, 0, 0, "Unable to malloc memory for lock_list!");
  } else {
    real_type = st_insert(type, &lock_names);
    ll->type = real_type;
    ll->key = key;
    ll->creator = player;
    if (flags == LF_DEFAULT) {
      const lock_list *l2 = get_lockproto(real_type);
      if (l2)
        ll->flags = l2->flags;
      else
        ll->flags = 0;
    } else {
      ll->flags = flags;
    }
    t = &Locks(thing);
    while (*t && strcasecmp(L_TYPE(*t), L_TYPE(ll)) < 0)
      t = &L_NEXT(*t);
    L_NEXT(ll) = *t;
    *t = ll;
  }
  return 1;
}