Example #1
0
/**
 * Retrieves the resource id of a version of a VCR
 * 
 * @param db handle to the database
 * @param db_r VCR with @serialno set
 * @param version_num number of specific version of the VCR
 * @param version_id will be set to resource id of the version
 * 
 * @return NULL on success, error otherwise.
 */
dav_error *dbms_get_version_id(const dav_repos_db *db, dav_repos_resource *db_r,
                               int version_num, int *version_id)
{
    apr_pool_t *pool = db_r->p;
    dav_repos_query *q = NULL;
    int ierrno = 0;

    TRACE();

    q = dbms_prepare(pool, db->db, 
                     "SELECT resource_id FROM versions "
		     "WHERE number=? AND vcr_id=?");
    dbms_set_int(q, 1, version_num);
    dbms_set_int(q, 2, db_r->serialno);

    if (dbms_execute(q)) {
	dbms_query_destroy(q);
	db_error_message(pool, db->db, "dbms_execute error");
	return dav_new_error(pool, HTTP_INTERNAL_SERVER_ERROR, 0,
			     "DBMS Error");
    }

    if ((ierrno = dbms_next(q)) <= 0) {
	dbms_query_destroy(q);
	db_error_message(pool, db->db, "dbms_next error");
	return dav_new_error(pool, HTTP_INTERNAL_SERVER_ERROR, 0,
			     "DBMS Error");
    }

    *version_id = dbms_get_int(q, 1);
    dbms_query_destroy(q);

    return NULL;
}
/*
** dav_fs_parse_locktoken
**
** Parse an opaquelocktoken URI into a locktoken.
*/
static dav_error * dav_fs_parse_locktoken(
    apr_pool_t *p,
    const char *char_token,
    dav_locktoken **locktoken_p)
{
    dav_locktoken *locktoken;

    if (ap_strstr_c(char_token, "opaquelocktoken:") != char_token) {
        return dav_new_error(p,
                             HTTP_BAD_REQUEST, DAV_ERR_LOCK_UNK_STATE_TOKEN, 0,
                             "The lock token uses an unknown State-token "
                             "format and could not be parsed.");
    }
    char_token += 16;

    locktoken = apr_pcalloc(p, sizeof(*locktoken));
    if (apr_uuid_parse(&locktoken->uuid, char_token)) {
        return dav_new_error(p, HTTP_BAD_REQUEST, DAV_ERR_LOCK_PARSE_TOKEN, 0,
                             "The opaquelocktoken has an incorrect format "
                             "and could not be parsed.");
    }

    *locktoken_p = locktoken;
    return NULL;
}
Example #3
0
static dav_error *dav_deltav_patch_validate(const dav_resource * resource,
                                            const apr_xml_elem * elem,
                                            int operation,
                                            void **context,
                                            int *defer_to_dead)
{
    dav_elem_private *priv = elem->priv;

    TRACE();

    *context = (void *)get_livepropspec_from_id(dav_deltav_props, priv->propid);
    if (priv->propid == DAV_PROPID_auto_version) {
	*defer_to_dead = 0;
	if (resource->versioned && operation == DAV_PROP_OP_SET) {
	    char *av_value = elem->first_child ?
		apr_pstrdup(resource->pool, elem->first_child->name) : "";
	    if (!(strcmp(av_value, "checkout-checkin")))
                ;
            else if(!(strcmp(av_value, "checkout-unlocked-checkin") &&
                      strcmp(av_value, "checkout") &&
                      strcmp(av_value, "locked-checkout")))
                return dav_new_error
                  (resource->pool, HTTP_FORBIDDEN, 0, apr_psprintf
                   (resource->pool, "%s supported currently", av_value));
            else
		return dav_new_error(resource->pool, HTTP_BAD_REQUEST, 0,
				     "Undefined value given for DAV:auto-version ");
	} else
	    return dav_new_error(resource->pool, HTTP_FORBIDDEN, 0,
				 "Not a set operation on a VCR");
    }
    return NULL;
}
Example #4
0
/** 
 * Get the version number of a version resource using its resource id
 * @param d handle to the database
 * @param r a resource whose checked_id is set to the resource_id of the version
            the version number is assigned to the vr_num field
 * @return NULL on success, dav_error otherwise
 */
dav_error *dbms_get_version_number(const dav_repos_db *d, dav_repos_resource *r)
{
    apr_pool_t *pool = r->p;
    dav_repos_query *q = NULL;
    int ierrno = 0;
    dav_error *err = NULL;

    TRACE();

    q = dbms_prepare(pool, d->db, 
                     "SELECT number FROM versions "
                     "WHERE resource_id=?");
    dbms_set_int(q, 1, r->checked_id);
    if (dbms_execute(q)) {
        dbms_query_destroy(q);
        return dav_new_error(pool, HTTP_INTERNAL_SERVER_ERROR, 0,
                "DBMS Error");
    }

    if ((ierrno = dbms_next(q)) <= 0) {
        dbms_query_destroy(q);
        return dav_new_error(pool, HTTP_INTERNAL_SERVER_ERROR, 0,
                "Could not lookup version number");
    }

    r->vr_num = dbms_get_int(q, 1);

    dbms_query_destroy(q);
     
    return err;
}
Example #5
0
dav_error *
dav_svn__new_error(apr_pool_t *pool,
                   int status,
                   int error_id,
                   const char *desc)
{
  if (error_id == 0)
    error_id = SVN_ERR_RA_DAV_REQUEST_FAILED;

/*
 * Note: dav_new_error() in httpd 2.0/2.2 always treated
 * the errno field in dav_error as an apr_status_t when
 * logging; on some platforms errno and apr_status_t
 * aren't directly interchangeable.  The code for httpd
 * > 2.2 below perpetuates this.
 */
#if AP_MODULE_MAGIC_AT_LEAST(20091119,0)
  return dav_new_error(pool, status, error_id, 0, desc);
#else

  errno = 0; /* For the same reason as in dav_svn__new_error_tag */

  return dav_new_error(pool, status, error_id, desc);
#endif
}
Example #6
0
/**
 * Change the parent acl of a resource
 * @param d database handle
 * @param db_r the resource
 * @param new_parent_id serialno of the new parent
 * @return NULL for success, dav_error otherwise
 */
dav_error *dbms_change_acl_parent(dav_repos_db *d,
                                  dav_repos_resource *db_r,
                                  int new_parent_id)
{
    dav_repos_query *q = NULL;
    apr_pool_t *pool = db_r->p;
    char *orig_path, *new_parent_path, *new_path; 
    dav_error *err = NULL;

    TRACE();

    /* Get current path */
    q = dbms_prepare(pool, d->db, "SELECT path FROM acl_inheritance"
                                  " WHERE resource_id = ?");
    dbms_set_int(q, 1, db_r->serialno);
    dbms_execute(q);
    if(dbms_next(q) <= 0) {
        dbms_query_destroy(q);
        /* Not currently part of acl_inheritance, just add it */
        return dbms_inherit_parent_aces(d, db_r, new_parent_id);
    } else {
        orig_path = dbms_get_string(q, 1);
        dbms_query_destroy(q);
    }

    /* Get new_parent_path */
    q = dbms_prepare(pool, d->db, "SELECT path FROM acl_inheritance"
                                  " WHERE resource_id = ?");
    dbms_set_int(q, 1, new_parent_id);
    dbms_execute(q);
    if(dbms_next(q) <= 0) {
        dbms_query_destroy(q);
        return dav_new_error(pool, HTTP_INTERNAL_SERVER_ERROR, 0,
                             "invalid parent specified in change_acl_parent");
    } else {
        new_parent_path = dbms_get_string(q, 1);
        dbms_query_destroy(q);
    }

    new_path = apr_psprintf(pool, "%s,%ld", new_parent_path, db_r->serialno);

    /* Update path(s) */
    q = dbms_prepare(pool, d->db, "UPDATE acl_inheritance"
                                  " SET path = replace(path, ?, ?)"
                                  " WHERE path LIKE ?"
                                  " OR path = ?");
    dbms_set_string(q, 1, orig_path);
    dbms_set_string(q, 2, new_path);
    dbms_set_string(q, 3, apr_pstrcat(pool, orig_path, ",%", NULL));
    dbms_set_string(q, 4, orig_path);

    if (dbms_execute(q))
        err = dav_new_error(pool, HTTP_INTERNAL_SERVER_ERROR, 0,
                            "DBMS Error during update to acl_inheritance "
                            "(moving subtree)");
    dbms_query_destroy(q);

    return err;
}
/*
** dav_fs_load_locknull_list:  Returns a dav_buffer dump of the locknull file
**    for the given directory.
*/
static dav_error * dav_fs_load_locknull_list(apr_pool_t *p, const char *dirpath,
                                             dav_buffer *pbuf)
{
    apr_finfo_t finfo;
    apr_file_t *file = NULL;
    dav_error *err = NULL;
    apr_size_t amt;
    apr_status_t rv;

    dav_buffer_init(p, pbuf, dirpath);

    if (pbuf->buf[pbuf->cur_len - 1] == '/')
        pbuf->buf[--pbuf->cur_len] = '\0';

    dav_buffer_place(p, pbuf, "/" DAV_FS_STATE_DIR "/" DAV_FS_LOCK_NULL_FILE);

    /* reset this in case we leave w/o reading into the buffer */
    pbuf->cur_len = 0;

    if (apr_file_open(&file, pbuf->buf, APR_READ | APR_BINARY, APR_OS_DEFAULT,
                p) != APR_SUCCESS) {
        return NULL;
    }

    rv = apr_file_info_get(&finfo, APR_FINFO_SIZE, file);
    if (rv != APR_SUCCESS) {
        err = dav_new_error(p, HTTP_INTERNAL_SERVER_ERROR, 0, rv,
                            apr_psprintf(p,
                                        "Opened but could not stat file %s",
                                        pbuf->buf));
        goto loaderror;
    }

    if (finfo.size != (apr_size_t)finfo.size) {
        err = dav_new_error(p, HTTP_INTERNAL_SERVER_ERROR, 0, 0,
                            apr_psprintf(p,
                                        "Opened but rejected huge file %s",
                                        pbuf->buf));
        goto loaderror;
    }

    amt = (apr_size_t)finfo.size;
    dav_set_bufsize(p, pbuf, amt);
    if ((rv = apr_file_read(file, pbuf->buf, &amt)) != APR_SUCCESS
        || amt != finfo.size) {
        err = dav_new_error(p, HTTP_INTERNAL_SERVER_ERROR, 0, rv,
                            apr_psprintf(p,
                                        "Failure reading locknull file "
                                        "for %s", dirpath));

        /* just in case the caller disregards the returned error */
        pbuf->cur_len = 0;
        goto loaderror;
    }

  loaderror:
    apr_file_close(file);
    return err;
}
Example #8
0
dav_error *dbms_restore_vcc(const dav_repos_db *db,
                            dav_repos_resource *vcc,
                            dav_repos_resource *cvr)
{
    apr_pool_t *pool = vcc->p;
    dav_repos_query *q = NULL;

    /* delete all version controlled binds of the vcc */
    q = dbms_prepare(pool, db->db,
                     "DELETE FROM binds "
                     "WHERE collection_id=? AND resource_id IN "
                     "(SELECT resource_id FROM binds INNER JOIN vcrs USING resource_id WHERE collection_id=?)");
    dbms_set_int(q, 1, vcc->serialno);
    dbms_set_int(q, 2, vcc->serialno);
    
    if (dbms_execute(q)) {
        dbms_query_destroy(q);
        return dav_new_error(pool, HTTP_INTERNAL_SERVER_ERROR, 0,
                             "DBMS Error");
    }
    dbms_query_destroy(q);
    
    /* delete any conflicting non-version controlled binds to the VCC that
       may have been introduced after checking out */
    q = dbms_prepare(pool, db->db,
                     "DELETE FROM binds "
                     "WHERE collection_id=? AND name IN (SELECT name FROM binds WHERE collection_id=?");
    dbms_set_int(q, 1, vcc->serialno);
    dbms_set_int(q, 2, cvr->serialno);
    
    if (dbms_execute(q)) {
        dbms_query_destroy(q);
        return dav_new_error(pool, HTTP_INTERNAL_SERVER_ERROR, 0,
                             "DBMS Error");
    }
    dbms_query_destroy(q);
    
    /* copy and restore all the binds from the collection version */
    q = dbms_prepare(pool, db->db,
                     "INSERT INTO binds "
                     " (SELECT (NULL, name, ?, vcrs.resource_id, updated_at) "
                     "  FROM binds JOIN vcrs ON binds.resource_id=vcrs.vhr_id "
                     "  WHERE collection_id=?) ");
    dbms_set_int(q, 1, vcc->serialno);
    dbms_set_int(q, 2, cvr->serialno);

    if (dbms_execute(q)) {
        dbms_query_destroy(q);
        return dav_new_error(pool, HTTP_INTERNAL_SERVER_ERROR, 0,
                             "DBMS Error");
    }
    dbms_query_destroy(q);

    return NULL;
}
Example #9
0
/**
 * Add a (resource, parent) entry into acl_inheritance table,
 * if not already done.
 * @param d DBMS connection struct
 * @param db_r The child resource
 * @param parent Resource_id of the parent
 */
dav_error *dbms_inherit_parent_aces(const dav_repos_db *d, 
                                    const dav_repos_resource *db_r, 
                                    int parent)
{
    dav_error *err = NULL;
    dav_repos_query *q = NULL;
    apr_pool_t *pool = db_r->p;

    TRACE();

    /* check if the resource is already in acl_inheritance */
    q = dbms_prepare(pool, d->db, "SELECT path FROM acl_inheritance"
                                  " WHERE resource_id = ?");
    dbms_set_int(q, 1, db_r->serialno);
    if(dbms_execute(q)) {
        dbms_query_destroy(q);
        return dav_new_error(pool, HTTP_INTERNAL_SERVER_ERROR, 0,
                             "DBMS Error during select "
                             "on acl_inheritance");
    }

    if(dbms_next(q) > 0) {
        /* resource already a part of acl_inheritance, nothing to do */
        dbms_query_destroy(q);
        return err;
    }
    dbms_query_destroy(q);

    /* Insert the new entry (resource, parent) with proper lft & rgt values */
    q = dbms_prepare(pool, d->db,
                     "INSERT INTO acl_inheritance (resource_id, path)"
                     " SELECT ?, a.path || ',' || ?"
                     " FROM acl_inheritance a WHERE a.resource_id = ?");
    dbms_set_int(q, 1, db_r->serialno);
    dbms_set_int(q, 2, db_r->serialno);
    dbms_set_int(q, 3, parent);

    if(dbms_execute(q))
        err =  dav_new_error(pool, HTTP_INTERNAL_SERVER_ERROR, 0,
                             "DBMS Error during update "
                             "on acl_inheritance");

    dbms_query_destroy(q);

    /* Set the private members of dav_acl */
    if(db_r->acl) {
        dav_acl_private *priv = apr_pcalloc(pool, sizeof(*priv));
        priv->parent_id = parent;
        db_r->acl->info = priv;
    }

    return err;
}
Example #10
0
/*
** Find a particular lock on a resource (specified by its locktoken).
**
** *lock will be set to NULL if the lock is not found.
**
** Note that the provider can optimize the unmarshalling -- only one
** lock (or none) must be constructed and returned.
**
** If partial_ok is true (non-zero), then an indirect lock can be
** partially filled in. Otherwise, another lookup is done and the
** lock structure will be filled out as a DAV_LOCKREC_INDIRECT.
*/
static dav_error *
find_lock(dav_lockdb *lockdb,
          const dav_resource *resource,
          const dav_locktoken *locktoken,
          int partial_ok,
          dav_lock **lock)
{
  dav_lockdb_private *info = lockdb->info;
  svn_error_t *serr;
  svn_lock_t *slock;
  dav_lock *dlock = NULL;

  /* If the resource's fs path is unreadable, we don't want to say
     anything about locks attached to it.*/
  if (! dav_svn__allow_read(resource, SVN_INVALID_REVNUM, resource->pool))
    return dav_new_error(resource->pool, HTTP_FORBIDDEN,
                         DAV_ERR_LOCK_SAVE_LOCK,
                         "Path is not accessible.");

  serr = svn_fs_get_lock(&slock,
                         resource->info->repos->fs,
                         resource->info->repos_path,
                         resource->pool);
  if (serr)
    return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
                                "Failed to look up lock by path.",
                                resource->pool);

  if (slock != NULL)
    {
      /* Sanity check. */
      if (strcmp(locktoken->uuid_str, slock->token) != 0)
        return dav_new_error(resource->pool, HTTP_BAD_REQUEST,
                             DAV_ERR_LOCK_SAVE_LOCK,
                             "Incoming token doesn't match existing lock.");

      svn_lock_to_dav_lock(&dlock, slock, FALSE,
                           resource->exists, resource->pool);

      /* Let svn clients know the creationdate of the slock. */
      apr_table_setn(info->r->headers_out, SVN_DAV_CREATIONDATE_HEADER,
                     svn_time_to_cstring(slock->creation_date,
                                         resource->pool));

      /* Let svn clients know the 'owner' of the slock. */
      apr_table_setn(info->r->headers_out, SVN_DAV_LOCK_OWNER_HEADER,
                     slock->owner);
    }

  *lock = dlock;
  return 0;
}
/*
** dav_fs_save_locknull_list:  Saves contents of pbuf into the
**    locknull file for dirpath.
*/
static dav_error * dav_fs_save_locknull_list(apr_pool_t *p, const char *dirpath,
                                             dav_buffer *pbuf)
{
    const char *pathname;
    apr_file_t *file = NULL;
    dav_error *err = NULL;
    apr_size_t amt;
    apr_status_t rv;

    if (pbuf->buf == NULL)
        return NULL;

    dav_fs_ensure_state_dir(p, dirpath);
    pathname = apr_pstrcat(p,
                          dirpath,
                          dirpath[strlen(dirpath) - 1] == '/' ? "" : "/",
                          DAV_FS_STATE_DIR "/" DAV_FS_LOCK_NULL_FILE,
                          NULL);

    if (pbuf->cur_len == 0) {
        /* delete the file if cur_len == 0 */
        if ((rv = apr_file_remove(pathname, p)) != APR_SUCCESS) {
            return dav_new_error(p, HTTP_INTERNAL_SERVER_ERROR, 0, rv,
                                 apr_psprintf(p,
                                             "Error removing %s", pathname));
        }
        return NULL;
    }

    if ((rv = apr_file_open(&file, pathname,
                            APR_WRITE | APR_CREATE | APR_TRUNCATE | APR_BINARY,
                            APR_OS_DEFAULT, p)) != APR_SUCCESS) {
        return dav_new_error(p, HTTP_INTERNAL_SERVER_ERROR, 0, rv,
                             apr_psprintf(p,
                                         "Error opening %s for writing",
                                         pathname));
    }

    amt = pbuf->cur_len;
    if ((rv = apr_file_write_full(file, pbuf->buf, amt, &amt)) != APR_SUCCESS
        || amt != pbuf->cur_len) {
        err = dav_new_error(p, HTTP_INTERNAL_SERVER_ERROR, 0, rv,
                            apr_psprintf(p,
                                        "Error writing %" APR_SIZE_T_FMT
                                        " bytes to %s",
                                        pbuf->cur_len, pathname));
    }

    apr_file_close(file);
    return err;
}
Example #12
0
static dav_error * dav_repos_patch_validate(const dav_resource * resource,
                                            const apr_xml_elem * elem,
                                            int operation,
                                            void **context,
                                            int *defer_to_dead)
{
    apr_pool_t *pool = resource->pool;
    dav_elem_private *priv = elem->priv;
    dav_repos_resource *db_r = resource->info->db_r;
    dav_repos_db *db = resource->info->db;
    char *path;
    const char *data;
    apr_size_t size;


    if (operation == DAV_PROP_OP_DELETE)
        return dav_new_error(pool, HTTP_CONFLICT, 0,
                             "This property cannot be removed");

    *context = (void *)get_livepropspec_from_id(dav_repos_props, priv->propid);
    switch(priv->propid) {
    case DAV_PROPID_displayname:
        if (elem->first_cdata.first &&
            (elem->first_cdata.first->text == NULL ||
            strlen(elem->first_cdata.first->text) > DAV_DISPLAYNAME_LIMIT))
            return dav_new_error(pool, HTTP_CONFLICT, 0,
                                 "Invalid value specified");
        break;
    case DAV_PROPID_getcontentlanguage:
        if (validate_language_tag(pool, elem->first_cdata.first->text))
            return dav_new_error(pool, HTTP_CONFLICT, 0,
                                 "Invalid value specified");
        break;
    case DAV_PROPID_getcontenttype:
        apr_xml_to_text(pool, elem, APR_XML_X2T_INNER, NULL, NULL, &data, &size);
        data = strip_whitespace((char*)data);
        sabridge_get_resource_file(db, db_r, &path);
        if (!is_content_type_good(path, data))
            return dav_new_error(pool, HTTP_CONFLICT, 0,
                                 "Couldn't pass filter");
        break;
    default:
        return dav_new_error(pool, HTTP_FORBIDDEN, 0,
                             "Cannot be modified");
    }

    return NULL;
}
Example #13
0
/**
 * Set the DAV:auto-version property
 * @param
 * @param d DB connection struct containing the user, password, and DB name
 * @param db_r Identifies the resource to set the set the property on. 
 *             Should have db_r->serialno and db_r->autoversion_type set
 * @return NULL, for success; Error, otherwise.
 *
 */
dav_error *dbms_set_autoversion_type(const dav_repos_db * db,
				     dav_repos_resource * db_r,
                                     dav_repos_autoversion_t av_type)
{
    apr_pool_t *pool = db_r->p;
    dav_repos_query *q = NULL;

    TRACE();

    q = dbms_prepare(pool, db->db, 
                     "UPDATE vcrs "
                     "SET version_type=? "
		     "WHERE resource_id=?");
    dbms_set_int(q, 1, av_type);
    dbms_set_int(q, 2, db_r->serialno);

    if (dbms_execute(q)) {
	db_error_message(pool, db->db,
			 "Could not set auto-version property");
	dbms_query_destroy(q);
	return dav_new_error(pool, HTTP_INTERNAL_SERVER_ERROR, 0,
			     "DBMS Error");
    }
    dbms_query_destroy(q);

    db_r->autoversion_type = av_type;

    return NULL;
}
Example #14
0
/* Copies VCBs
 * @param r_src the source collection
 * @param r_dest the collection version
 */
dav_error *dbms_copy_resource_collection_version(const dav_repos_db * db,
					  dav_repos_resource * r_src,
					  dav_repos_resource * r_dst,
					  request_rec * rec)
{
    apr_pool_t *pool = r_src->p;
    dav_repos_query *q = NULL;
    dav_error *err = NULL;

    TRACE();

    if ((r_src->resourcetype == dav_repos_COLLECTION
	 || r_src->resourcetype == dav_repos_VERSIONED_COLLECTION)
	&& r_dst->resourcetype == dav_repos_COLLECTION_VERSION) {
	/* copying from a collection to collection version */
	q = dbms_prepare(pool, db->db,
			 "INSERT INTO binds(name, collection_id, resource_id, updated_at) "
			 " (SELECT name, ?, vhr_id, updated_at "
			 "  FROM binds INNER JOIN vcrs ON binds.resource_id=vcrs.resource_id "
			 "  WHERE collection_id=?) ");

	dbms_set_int(q, 1, r_dst->serialno);
	dbms_set_int(q, 2, r_src->serialno);

	if (dbms_execute(q)) {
	    dbms_query_destroy(q);
	    err = dav_new_error(pool, HTTP_INTERNAL_SERVER_ERROR, 0,
                                "DBMS Error while intersting into 'binds'");
	}
	dbms_query_destroy(q);
    }
    return err;
}
Example #15
0
/**
 * Set the checkin and checkout version for a resource
 * @param d DB connection struct containing the user, password, and DB name
 * @param db_r Identifies the resource to set the property on r->uri. 
 *          Contains the live property and value to set.
 * @author: The author who changed the resource
 * @return NULL, for success; Error, otherwise.
 */
dav_error *dbms_insert_version(const dav_repos_db * db,
                               dav_repos_resource *new_version)
{
    apr_pool_t *pool = new_version->p;
    dav_repos_query *q = NULL;

    TRACE();

    /* Make an entry into the versions table */
    q = dbms_prepare(pool, db->db,
		     "INSERT INTO versions(resource_id, number,vcr_id, vhr_id) "
		     "VALUES(?, ?, ?, ?)");
    dbms_set_int(q, 1, new_version->serialno);
    dbms_set_int(q, 2, new_version->version);
    dbms_set_int(q, 3, new_version->vcr_id);
    dbms_set_int(q, 4, new_version->vhr_id);

    if (dbms_execute(q)) {
	dbms_query_destroy(q);
	db_error_message(pool, db->db, "dbms_execute error");
	return dav_new_error(pool,
			     HTTP_INTERNAL_SERVER_ERROR, 0, "DBMS Error");
    }
    dbms_query_destroy(q);

    return NULL;
}
Example #16
0
/** 
 * Make an entry into the vcrs table for an existing resource.
 * Also changes the type of the resource
 * 
 * @param db handle to the database
 * @param db_r resource which is being converted to a VCR
 * 
 * @return 
 */
dav_error *dbms_insert_vcr(const dav_repos_db *db,
                           dav_repos_resource *db_r)
{
    apr_pool_t *pool = db_r->p;
    dav_repos_query *q = NULL;

    TRACE();

    /* Create the vcrs entry */
    q = dbms_prepare(pool, db->db,
                     "INSERT INTO vcrs(resource_id, checked_id, vhr_id, "
                     "    checked_state, version_type, checkin_on_unlock)"
                     " VALUES ( ?, ?, ?, 'I', ?, 0)");
    dbms_set_int(q, 1, db_r->serialno);
    dbms_set_int(q, 2, db_r->checked_id);
    dbms_set_int(q, 3, db_r->vhr_id);

    db_r->checked_state = DAV_RESOURCE_CHECKED_IN;
    dbms_set_int(q, 4, db_r->autoversion_type);
    db_r->checkin_on_unlock = 1;

    if (dbms_execute(q)) {
        dbms_query_destroy(q);
        db_error_message(pool, db->db, "dbms_execute error");
        return dav_new_error(pool,
                             HTTP_INTERNAL_SERVER_ERROR, 0,
                             "DBMS Error");
    }
    dbms_query_destroy(q);

    return NULL;
}
static dav_error * dav_fs_dbm_error(dav_db *db, apr_pool_t *p,
                                    apr_status_t status)
{
    int errcode;
    const char *errstr;
    dav_error *err;
    char errbuf[200];

    if (status == APR_SUCCESS)
        return NULL;

    p = db ? db->pool : p;

    /* There might not be a <db> if we had problems creating it. */
    if (db == NULL) {
        errcode = 1;
        errstr = "Could not open property database.";
        if (APR_STATUS_IS_EDSOOPEN(status))
            ap_log_error(APLOG_MARK, APLOG_CRIT, status, ap_server_conf, APLOGNO(00576)
            "The DBM driver could not be loaded");
    }
    else {
        (void) apr_dbm_geterror(db->file, &errcode, errbuf, sizeof(errbuf));
        errstr = apr_pstrdup(p, errbuf);
    }

    err = dav_new_error(p, HTTP_INTERNAL_SERVER_ERROR, errcode, status, errstr);
    return err;
}
Example #18
0
/* Helper func for dav_lock_to_svn_lock:  take an incoming
   "<D:owner>&lt;foo&gt;</D:owner>" tag and convert it to
   "<foo>". */
static dav_error *
unescape_xml(const char **output,
             const char *input,
             apr_pool_t *pool)
{
  apr_xml_parser *xml_parser = apr_xml_parser_create(pool);
  apr_xml_doc *xml_doc;
  apr_status_t apr_err;
  const char *xml_input = apr_pstrcat
    (pool, "<?xml version=\"1.0\" encoding=\"utf-8\"?>", input, NULL);

  apr_err = apr_xml_parser_feed(xml_parser, xml_input, strlen(xml_input));
  if (!apr_err)
    apr_err = apr_xml_parser_done(xml_parser, &xml_doc);

  if (apr_err)
    {
      char errbuf[1024];
      (void)apr_xml_parser_geterror(xml_parser, errbuf, sizeof(errbuf));
      return dav_new_error(pool, HTTP_INTERNAL_SERVER_ERROR,
                           DAV_ERR_LOCK_SAVE_LOCK, errbuf);
    }

  apr_xml_to_text(pool, xml_doc->root, APR_XML_X2T_INNER,
                  xml_doc->namespaces, NULL, output, NULL);
  return SVN_NO_ERROR;
}
Example #19
0
/**
 * Update the principal-property ace with the new principal value of 
 * the property
 * @param d database handle
 * @param db_r resource
 * @prop_ns_id the namespace id of the property
 * @prop_name the property name
 * @principal_id serialno of the new principal
 */
dav_error *dbms_update_principal_property_aces(dav_repos_db *d, 
                                               dav_repos_resource *db_r,
                                               int prop_ns_id, 
                                               const char *prop_name, 
                                               int principal_id)
{
    dav_repos_query *q = NULL;
    apr_pool_t *pool = db_r->p;
    dav_error *err = NULL;

    TRACE();

    q = dbms_prepare(pool, d->db, "UPDATE aces SET principal_id = ? "
                     "WHERE resource_id = ? AND property_namespace_id = ? "
                     "AND property_name = ?");
    dbms_set_int(q, 1, principal_id);
    dbms_set_int(q, 2, db_r->serialno);
    dbms_set_int(q, 3, prop_ns_id);
    dbms_set_string(q, 4, prop_name);

    if (dbms_execute(q))
        err =  dav_new_error(pool, HTTP_INTERNAL_SERVER_ERROR, 0,
                             "DBMS Error during update of property aces");

    dbms_query_destroy(q);
    return err;
}
Example #20
0
static dav_error * dav_generic_dbm_new_error(apr_dbm_t *db, apr_pool_t *p,
                                             apr_status_t status)
{
    int errcode;
    const char *errstr;
    dav_error *err;
    char errbuf[200];

    if (status == APR_SUCCESS) {
        return NULL;
    }

    /* There might not be a <db> if we had problems creating it. */
    if (db == NULL) {
        errcode = 1;
        errstr = "Could not open property database.";
    }
    else {
        (void) apr_dbm_geterror(db, &errcode, errbuf, sizeof(errbuf));
        errstr = apr_pstrdup(p, errbuf);
    }

    err = dav_new_error(p, HTTP_INTERNAL_SERVER_ERROR, errcode, status, errstr);
    return err;
}
Example #21
0
static dav_error * dav_fs_dbm_error(dav_db *db, apr_pool_t *p,
                                    apr_status_t status)
{
    int save_errno = errno;
    int errcode;
    const char *errstr;
    dav_error *err;
    char errbuf[200];

    if (status == APR_SUCCESS)
        return NULL;

    p = db ? db->pool : p;

    /* There might not be a <db> if we had problems creating it. */
    if (db == NULL) {
        errcode = 1;
        errstr = "Could not open property database.";
    }
    else {
        (void) apr_dbm_geterror(db->file, &errcode, errbuf, sizeof(errbuf));
        errstr = apr_pstrdup(p, errbuf);
    }

    err = dav_new_error(p, HTTP_INTERNAL_SERVER_ERROR, errcode, errstr);
    err->save_errno = save_errno;
    return err;
}
Example #22
0
/**
 * This is the second most important function, as it delivers the content of the
 * file (or the directory if not DAV)
 * @param resource The resource generated previously
 * @param output   Here is where the output must be written
 * @return         NULL on success
 */
static dav_error *dav_ns_deliver(const dav_resource *resource,
                                 ap_filter_t *output)
{
  apr_bucket_brigade   *bb;
  apr_bucket           *bkt;
  dav_error            *err;

  bb   = apr_brigade_create(resource->pool, output->c->bucket_alloc);
  
  if (resource->collection)
    err = dav_ns_deliver_collection(resource, resource->info->request->output_filters, bb);
  else if (resource->info->metalink) {
    err = dav_ns_deliver_metalink(resource, resource->info->request->output_filters, bb);
  }
  else
    err = dav_new_error(resource->pool, HTTP_INTERNAL_SERVER_ERROR, 0,
                        "NS should not be trying to deliver files!");
  
  if (err != NULL)
    return err;

  /* Close and flush the output */
  bkt = apr_bucket_eos_create(output->c->bucket_alloc);
  APR_BRIGADE_INSERT_TAIL(bb, bkt);
  if (ap_pass_brigade(resource->info->request->output_filters, bb) != APR_SUCCESS)
    return dav_shared_new_error(resource->info->request, NULL, HTTP_INTERNAL_SERVER_ERROR,
                                "Could not write EOS to filter.");

  /* All OK */
  return NULL;
}
Example #23
0
static dav_error *dbms_get_creator_displayname(const dav_repos_db *d, 
                                               dav_repos_resource *r)
{
    int ierrno = 0;
    apr_pool_t *pool = r->p;
    dav_repos_query *q = NULL;

    TRACE();

    q = dbms_prepare(pool, d->db, "SELECT name FROM principals "
                     "WHERE resource_id = ?");

    dbms_set_int(q, 1, r->creator_id);
    if(dbms_execute(q)) {
        dbms_query_destroy(q);
        return dav_new_error(r->p, HTTP_INTERNAL_SERVER_ERROR, 0, 
                             "dbms_execute error");
    }

    if ((ierrno = dbms_next(q)) <= 0) {
        dbms_query_destroy(q);
        r->creator_displayname = NULL;
    }

    r->creator_displayname = dbms_get_string(q, 1);

    dbms_query_destroy(q);

    return NULL;
}
Example #24
0
dav_error *dbms_get_redirect_props(const dav_repos_db *d,
                                   dav_repos_resource *r)
{
    dav_repos_query *q = NULL;
    dav_error *err = NULL;

    TRACE();

    /* do nothing if we have already fetched redirect props */
    if (r->redirect_lifetime && r->reftarget) {
        return NULL;
    }

    q = dbms_prepare(r->p, d->db, "SELECT lifetime, reftarget "
                     "FROM redirectrefs WHERE resource_id = ?");
    dbms_set_int(q, 1, r->serialno);

    if (dbms_execute(q) || (dbms_next(q) <=0)) {
        err = dav_new_error(r->p, HTTP_INTERNAL_SERVER_ERROR, 0,
                            "DBMS error in reftargets lookup.");
        goto error;
    }

    if (0 == apr_strnatcmp(dbms_get_string(q, 1), "p")) 
        r->redirect_lifetime = DAV_REDIRECTREF_PERMANENT;
    else
        r->redirect_lifetime = DAV_REDIRECTREF_TEMPORARY;

    r->reftarget = dbms_get_string(q, 2);

    error:
        dbms_query_destroy(q);
        return err;
}
Example #25
0
dav_error *dbms_insert_redirectref(const dav_repos_db *d, 
                                   dav_repos_resource *r,
                                   const char *reftarget,
                                   dav_redirectref_lifetime t)
{
    dav_repos_query *q = NULL;
    dav_error *err = NULL;
    
    q = dbms_prepare(r->p, d->db, "INSERT INTO redirectrefs "
                     "(resource_id, reftarget, lifetime, updated_at) "
                     "VALUES (?, ?, ?, ?)");

    dbms_set_int(q, 1, r->serialno);
    dbms_set_string(q, 2, reftarget);
    dbms_set_string(q, 3, lifetime_to_s(t));
    dbms_set_string(q, 4, time_apr_to_str(r->p, apr_time_now()));

    if (dbms_execute(q))
        err = dav_new_error(r->p, HTTP_INTERNAL_SERVER_ERROR, 0,
                            "DBMS error while inserting into 'redirectrefs'");

    dbms_query_destroy(q);

    return err;
}
/*
** dav_fs_open_lockdb:
**
** "open" the lock database, as specified in the global server configuration.
** If force is TRUE, then the database is opened now, rather than lazily.
**
** Note that only one can be open read/write.
*/
static dav_error * dav_fs_open_lockdb(request_rec *r, int ro, int force,
                                      dav_lockdb **lockdb)
{
    dav_lockdb_combined *comb;

    comb = apr_pcalloc(r->pool, sizeof(*comb));
    comb->pub.hooks = &dav_hooks_locks_fs;
    comb->pub.ro = ro;
    comb->pub.info = &comb->priv;
    comb->priv.r = r;
    comb->priv.pool = r->pool;

    comb->priv.lockdb_path = dav_get_lockdb_path(r);
    if (comb->priv.lockdb_path == NULL) {
        return dav_new_error(r->pool, HTTP_INTERNAL_SERVER_ERROR,
                             DAV_ERR_LOCK_NO_DB, 0,
                             "A lock database was not specified with the "
                             "DAVLockDB directive. One must be specified "
                             "to use the locking functionality.");
    }

    /* done initializing. return it. */
    *lockdb = &comb->pub;

    if (force) {
        /* ### add a higher-level comment? */
        return dav_fs_really_open_lockdb(*lockdb);
    }

    return NULL;
}
Example #27
0
static dav_error *dav_acl_patch_validate(const dav_resource * resource,
                                         const apr_xml_elem * elem,
                                         int operation,
                                         void **context,
                                         int *defer_to_dead)
{
    apr_pool_t *pool = resource->pool;
    dav_repos_resource *db_r = resource->info->db_r;
    dav_repos_db *db = resource->info->db;
    request_rec *rec = resource->info->rec;
    dav_elem_private *priv = elem->priv;
    dav_error *err = NULL;

    TRACE();

    if (priv->propid == DAV_PROPID_group_member_set) {
	*defer_to_dead = 0;
        if (db_r->resourcetype!=dav_repos_GROUP || operation!=DAV_PROP_OP_SET)
            return dav_new_error(pool, HTTP_FORBIDDEN, 0,
                                 "Not a set operation on a group");
            
        apr_xml_elem *href_elem = dav_find_child(elem, "href");
        apr_hash_t *new_members = apr_hash_make(pool);
        apr_array_header_t *to_remove = NULL;

        while (href_elem && !err) {
            const char *prin_uri = dav_xml_get_cdata(href_elem, pool, 1);
            const char *prin_name = get_name_from_principal_URL(rec, prin_uri);
            if (prin_name == NULL)
                err = dav_new_error
                  (pool, HTTP_CONFLICT, 0, "Not a DAV:principal-URL");
            else
                apr_hash_set(new_members, prin_name, APR_HASH_KEY_STRING, "");
            href_elem = href_elem->next;
        }
        if (err) return err;
        if (apr_hash_count(new_members))
            err = dbms_calculate_group_changes(db, db_r, new_members,&to_remove);
        else
            err = dbms_get_group_members(db, db_r, &to_remove);
        if (err) return err;
        apr_hash_set(new_members, "-to-remove-", APR_HASH_KEY_STRING, to_remove);
        *context = new_members;
    }
    return err;
}
Example #28
0
/** 
 * Retrieves DeltaV properties of a version resource
 * @param d handle to the database
 * @param vr version resource
 * @return NULL on success, dav_error otherwise
 */
dav_error *dbms_get_version_resource_props(const dav_repos_db *d,
                                           dav_repos_resource *vr)
{
    apr_pool_t *pool = vr->p;
    dav_repos_query *q = NULL;
    int ierrno = 0;
    dav_error *err = NULL;
    dav_repos_resource *vcr = NULL;
    sabridge_new_dbr_from_dbr(vr, &vcr);

    TRACE();

    q = dbms_prepare(pool, d->db,
                     "SELECT number, vcr_id FROM versions "
                     "WHERE resource_id=?");
    dbms_set_int(q, 1, vr->serialno);

    if (dbms_execute(q)) {
	dbms_query_destroy(q);
	return dav_new_error(pool, HTTP_INTERNAL_SERVER_ERROR, 0, 
                             "dbms_execute error");
    }

    if ((ierrno = dbms_next(q)) < 0) {
	dbms_query_destroy(q);
	return dav_new_error(pool, HTTP_INTERNAL_SERVER_ERROR, 0,
                             "dbms_next error");
    }
    if (ierrno == 0) {
	dbms_query_destroy(q);
	return err;
    }

    vr->version = dbms_get_int(q, 1);
    vr->vcr_id = dbms_get_int(q, 2);

    dbms_query_destroy(q);

    /* check if this is the last version of its VCR */
    vcr->serialno = vr->vcr_id;
    err = dbms_get_vcr_props(d, vcr);
    if(vcr->checked_id == vr->serialno)
        vr->lastversion = 1;

    return err;
}
Example #29
0
/** 
 * Retrieve all DeltaV properties of a version controlled resource
 * @param d handle to the database
 * @param r resource whose properties are retrieved
 * @return NULL on success, dav_error otherwise
 */
dav_error *dbms_get_vcr_props(const dav_repos_db *d, dav_repos_resource *r)
{
    apr_pool_t *pool = r->p;
    dav_repos_query *q = NULL;
    int ierrno = 0;
    dav_error *err = NULL;
    char *checked_state;

    TRACE();

    q = dbms_prepare(pool, d->db,
                     "SELECT checked_state, checked_id, vhr_id, version_type, "
                     "       checkin_on_unlock "
                     "FROM vcrs WHERE resource_id=? ");
    dbms_set_int(q, 1, r->serialno);

    if (dbms_execute(q)) {
	dbms_query_destroy(q);
	return dav_new_error(r->p, HTTP_INTERNAL_SERVER_ERROR, 0, 
                             "dbms_execute error");
    }

    if ((ierrno = dbms_next(q)) < 0) {
	dbms_query_destroy(q);
	return dav_new_error(r->p, HTTP_INTERNAL_SERVER_ERROR, 0,
                             "dbms_next error");
    }
    if (ierrno == 0) {
	dbms_query_destroy(q);
        r->checked_state = DAV_RESOURCE_NOT_VERSIONED;
	return err;
    }

    checked_state = dbms_get_string(q, 1);
    r->checked_state = checked_state[0]=='I'? 
      DAV_RESOURCE_CHECKED_IN : DAV_RESOURCE_CHECKED_OUT;
    r->checked_id = dbms_get_int(q, 2);
    r->vhr_id = dbms_get_int(q, 3);
    r->autoversion_type = dbms_get_int(q, 4);

    dbms_query_destroy(q);

    err = dbms_get_version_number(d, r);

    return err;
}
Example #30
0
/** 
 * Retrieve DeltaV properties of a Version History Resource
 * @param d handle to the database
 * @param vhr version history resource
 * @return NULL on success, dav_error otherwise
 */
dav_error *dbms_get_vhr_props(const dav_repos_db *d, dav_repos_resource *vhr)
{
    apr_pool_t *pool = vhr->p;
    dav_repos_query *q = NULL;
    int ierrno = 0;
    dav_error *err = NULL;
    char *checked_state;

    TRACE();

    q = dbms_prepare(pool, d->db,
                     "SELECT resource_id, checked_state, checked_id "
                     "FROM vcrs WHERE vhr_id=? ");
    dbms_set_int(q, 1, vhr->serialno);

    if (dbms_execute(q)) {
	dbms_query_destroy(q);
	return dav_new_error(pool, HTTP_INTERNAL_SERVER_ERROR, 0, 
                             "dbms_execute error");
    }

    if ((ierrno = dbms_next(q)) < 0) {
	dbms_query_destroy(q);
	return dav_new_error(pool, HTTP_INTERNAL_SERVER_ERROR, 0,
                             "dbms_next error");
    }
    if (ierrno == 0) {
	dbms_query_destroy(q);
	return err;
    }

    vhr->vcr_id = dbms_get_int(q, 1);

    checked_state = dbms_get_string(q, 2);
    vhr->checked_state = checked_state[0]=='I'? 
      DAV_RESOURCE_CHECKED_IN : DAV_RESOURCE_CHECKED_OUT;

    vhr->checked_id = dbms_get_int(q, 3);

    dbms_query_destroy(q);

    err = dbms_get_vhr_root_version_id(d, vhr);
    
    return err;
}