Exemple #1
0
int
split (vec<str> *out, rxx pat, str expr, size_t lim, bool emptylast)
{
  const char *p = expr;
  const char *const e = p + expr.len ();
  size_t n;
  if (out)
    out->clear ();

  // check p < e to see that we're not dealing with an empty
  // string (especially since x? matches "").
  for (n = 0; p < e && n + 1 < lim; n++) {
    if (!pat._exec (p, e - p, 0)) {
      return 0;
    }
    if (!pat.success ())
      break;
    if (out)
      out->push_back (str (p, pat.start (0)));
    p += max (pat.end (0), 1);
  }

  if (lim && (p < e || emptylast)) {
    n++;
    if (out) {
      out->push_back (str (p, e - p));
    }
  }
  return n;
}
Exemple #2
0
str
rxx_replace_2 (str input, rxx pat, str repl_str)
{
  repl_t repl;
  str ret;
  if (!repl.parse (repl_str)) {
    warn << "XX cannot parse replacement string: " << repl_str << "\n";
  } else {
    const char *p = input;
    const char *const e = p + input.len ();
    strbuf b;
    bool go = true;
    bool err = false;

    // check p < e to see that we're not dealing with an empty
    // string (especially since x? matches "").
    while (go && !err && p < e) {

      if (!pat._exec (p, e - p, 0)) { 
	warn << "XX regex execution failed\n";
	err = true; 
      }
      
      else if (!pat.success ()) { go = false; }

      else {
	str pre = str (p, pat.start (0));
	strbuf_output (b, pre);
	repl.output (b, p, pat);
	p += max (pat.end (0), 1);
      }

    }

    if (p < e && !err) {
      str post = str (p, e - p);
      strbuf_output (b, post);
    }

    if (!err) { ret = b; }

  }
  return ret;
}
Exemple #3
0
// Call the replace function for each matched pattern.
str 
rxx_replace (str input, rxx pat, rxx_replace_cb_t cb)
{
  const char *p = input;
  const char *const e = p + input.len ();
  strbuf b;
  bool go = true;
  bool err = false;
  str ret;

  // check p < e to see that we're not dealing with an empty
  // string (especially since x? matches "").
  while (go && !err && p < e) {
    
    if (!pat._exec (p, e - p, 0)) { 
      warn << "XX regex execution failed\n";
      err = true; 
    }
    
    else if (!pat.success ()) { go = false; }
    
    else {
      str pre = str (p, pat.start (0));
      strbuf_output (b, pre);
      vec<str> v;
      extract_matches (&v, p, pat);
      str repl = (*cb) (&v);
      if (repl) {
	strbuf_output (b, repl);
      }
      p += max (pat.end (0), 1);
    }
    
  }
  
  if (p < e && !err) {
    str post = str (p, e - p);
    strbuf_output (b, post);
  }
  
  if (!err) { ret = b; }
  return ret;
}
void
authclnt::update_group (svccb *sbp, update_info &i)
{
  dbfile *udbp;
  ptr<authcursor> uac;
  sfsauth_dbrec udbr;

  *i.kname.name = i.argp->req.rec.groupinfo->name;
  bool create = i.argp->req.rec.groupinfo->id == 0
    && i.argp->req.rec.groupinfo->vers == 1;
  bool exists = get_group_cursor (&udbp, &uac, &udbr, i.kname, true, create);

  if (exists && create && udbr.groupinfo->id > udbp->grprange->id_max) {
    *i.res.errmsg = strbuf () << "all group IDs in the allowed range ("
                              << udbp->grprange->id_min << "-"
                              << udbp->grprange->id_max << ") are in use";
    return;
  }

  if (!exists) {
    if (!create) {
      *i.res.errmsg = "perhaps record is read-only "
                      "or database doesn't accept group updates";
      return;
    }
    else {
      *i.res.errmsg = "no writable databases that accept group updates";
      return;
    }
  }
  if (create && udbr.groupinfo->vers != 0) {
    *i.res.errmsg = strbuf () << "group `" << udbr.groupinfo->name
                              << "'already exists";
    return;
  }

  if (!i.admin) {
    if (create) {
      str gname;
      if (!(gname = group_prefix (udbr.groupinfo->name, i.cdbr.userinfo->name))
          || gname.len () < 1) {
        *i.res.errmsg = strbuf () << "group name must be of the form `"
                                << i.cdbr.userinfo->name << ".groupname'";
        return;
      }
      static rxx groupquotarx ("(\\A|,)groupquota=([0-9]+)(\\Z|,)");
      if (groupquotarx.search (i.cdbr.userinfo->privs)
          || udbp->default_groupquota >= 0) {
        u_int32_t max_groups;
        u_int32_t cur_groups;
        
        if (groupquotarx.success ())
          convertint (groupquotarx[2], &max_groups);
        else
          max_groups = udbp->default_groupquota;

        // XXX - open could fail
        ptr<authcursor> gac = udbp->db->open (udbp->dbflags);
        cur_groups = gac->count_group_prefix (strbuf ()
                                              << i.cdbr.userinfo->name << ".");
        if (cur_groups + 1 > max_groups) {
          *i.res.errmsg = strbuf () << "group quota exceeded (current="
                                    << cur_groups << "/quota=" << max_groups << ")";
          return;
        }
      }
    }
    else {
      ptr<sfspub> pk = sfscrypt.alloc (i.cdbr.userinfo->pubkey);
      str h = armor32 (pk->get_pubkey_hash ());
      sfs_groupmembers list;
      unsigned int n = udbr.groupinfo->owners.size ();
      for (unsigned int j = 0; j < n; j++)
        list.push_back (udbr.groupinfo->owners[j]);
      
      if (!group_prefix (udbr.groupinfo->name, i.cdbr.userinfo->name)
          && !is_a_member (i.cdbr.userinfo->name, h, list)) {
        *i.res.errmsg = "access denied";
        return;
      }
    }
  }
  if (i.argp->req.rec.groupinfo->vers < 1) {
    *i.res.errmsg = "version number of record must be greater than 0";
    return;
  }
  if (i.argp->req.rec.groupinfo->vers != udbr.groupinfo->vers + 1) {
    *i.res.errmsg = "version mismatch";
    return;
  }
  uac->ae.groupinfo->vers = i.argp->req.rec.groupinfo->vers;

  strbuf sb;
  sb << "Last modified " << timestr () << " by " ;
  if (uid && !*uid)
    sb << "*superuser*";
  else
    sb << i.cp->unixcred->username;
  sb << "@" << client_name;
  uac->ae.groupinfo->audit = sb;

  // XXX: checking to make sure that the owners/groups are well-formed happens in update
  process_group_updates (udbr.groupinfo->owners, i.argp->req.rec.groupinfo->owners);
  process_group_updates (udbr.groupinfo->members, i.argp->req.rec.groupinfo->members);
  uac->ae.groupinfo->owners = udbr.groupinfo->owners;
  uac->ae.groupinfo->members = udbr.groupinfo->members;

  bool chlogok = write_group_changelog (i.argp->req.rec.groupinfo->name,
                                        i.argp->req.rec.groupinfo->vers,
                                        i.argp->req.rec.groupinfo->members,
                                        sb);
  if (!chlogok) {
    *i.res.errmsg = "could not write changelog; database unmodified";
    return;
  }

  if (!uac->update ()) {
    // XXX: remove changelog entry
    *i.res.errmsg = "database refused update; see SFS documentation for correct syntax";
    return;
  }
  i.res.set_ok (true);
  udbp->mkpub ();
  uac->find_group_name (udbr.groupinfo->name);
  if (global_dbcache)
    update_dbcache (uac);
}