Exemple #1
0
/**
 * Function called for the configuration parameter NSHost
 * @param cmd    Lots of information about the configuration contexts (as pool)
 * @param config Unused pointer
 * @param arg    The value of the parameter
 * @return       NULL on success. An error string otherwise
 */
static const char *dav_ns_cmd_dmlite(cmd_parms *cmd, void *config,
                                     const char *arg)
{
  dav_ns_server_conf *conf;
  conf = ap_get_module_config(cmd->server->module_config, &lcgdm_ns_module);

  if (dmlite_manager_load_configuration(conf->manager, arg) != 0)
    return apr_psprintf(cmd->pool, "Could not load %s (%s)",
                        arg, dmlite_manager_error(conf->manager));

  return NULL;
}
Exemple #2
0
/**
 * This function is used internally to create new resources.
 * @param r          The request to associate.
 * @param sfn        The SFN to link to the resource.
 * @param uri        The URI (without the query!)
 * @param user       The associated user. If NULL, will be queried and initialized.
 * @param resource   Where to put it.
 * @return           NULL on success.
 */
static dav_error *dav_ns_internal_get_resource(request_rec          *r,
                                               const char           *sfn,
                                               dmlite_credentials   *user,
                                               dav_resource        **resource)
{
  dav_resource_private *info;
  int                   exists, i;
  const char           *p;
  apr_table_t          *query;
  char                  replica_key[10];
  unsigned              nargs;

  /* Initialize info */
  info = apr_pcalloc(r->pool, sizeof(dav_resource_private));
  info->stat.extra = dmlite_any_dict_new();
  apr_pool_pre_cleanup_register(r->pool, info->stat.extra,
                                (apr_status_t(*)(void*))dmlite_any_dict_free);

  info->request  = r;
  info->sfn = sfn;

  info->s_conf = ap_get_module_config(r->server->module_config,  &lcgdm_ns_module);
  info->d_conf = ap_get_module_config(r->per_dir_config,         &lcgdm_ns_module);
  
  /* User info */
  if (user) {
    info->user = user;
  }
  else {
    if (!(info->user = dav_shared_get_user_credentials(r, info->ctx,
                                                       info->d_conf->anon_user,
                                                       info->d_conf->trusted_dns)))
      return dav_shared_new_error(r, NULL, HTTP_FORBIDDEN,
                                  "Can not authenticate the user");
  }

  /* Instantiate the catalog, if not in the connection notes */
  info->ctx = (dmlite_context*)apr_table_get(r->connection->notes, "dav_ns_ctx");
  if (info->ctx == NULL) {
    info->ctx = dmlite_context_new(info->s_conf->manager);
    if (info->ctx == NULL) {
      return dav_shared_new_error(r, NULL, HTTP_INTERNAL_SERVER_ERROR,
                                  "Could not instantiate a context: %s",
                                  dmlite_manager_error(info->s_conf->manager));
    }

    apr_pool_pre_cleanup_register(r->connection->pool, info->ctx,
                                  (apr_status_t(*)(void*))dmlite_context_free);
    
    apr_table_setn(r->connection->notes, "dav_ns_ctx", (char*)info->ctx);
    
    if (dmlite_setcredentials(info->ctx, info->user) != 0)
      return dav_shared_new_error(r, info->ctx, HTTP_FORBIDDEN,
                                  "Could not set credentials");
  }

  /* Extract parameters from the query */
  query = dav_shared_parse_query(r->pool, r->parsed_uri.query, &nargs);

#ifdef WITH_METALINK
  /* Explicit */
  info->metalink      = (apr_table_get(query, "metalink") != NULL);
  /* Through headers maybe? (i.e. aria2c) */
  if (!info->metalink && dav_shared_request_accepts(r, "application/metalink+xml")) {
    info->metalink = 1;
  }
#else
  info->metalink      = 0;
#endif
  info->space_token   = apr_table_get(query, "spacetoken");
  info->forbidden_str = apr_table_get(query, "forbidden");
  info->notfound_str  = apr_table_get(query, "notfound");
  if ((p = apr_table_get(query, "rid")))
    info->r_id = atol(p);
  else
    info->r_id = -1;

  /* Count in advance how many replicas */
  info->n_replicas = 0;
  snprintf(replica_key, sizeof(replica_key), "r%d", info->n_replicas + 1);
  while(apr_table_get(query, replica_key) != NULL) {
    ++info->n_replicas;
    snprintf(replica_key, sizeof(replica_key), "r%d", info->n_replicas + 1);
  }

  /* Allocate space */
  info->replicas     = apr_pcalloc(r->pool, sizeof(char*)   * info->n_replicas);
  info->replicas_ids = apr_pcalloc(r->pool, sizeof(int64_t) * info->n_replicas);

  /* Go through again :/ */
  for (i = 0; i < info->n_replicas; ++i) {
    const char *field_value;

    snprintf(replica_key, sizeof(replica_key), "r%d", i + 1);
    field_value = apr_table_get(query, replica_key);

    info->replicas[i] = apr_pcalloc(r->pool, sizeof(char) * PATH_MAX);

    if (sscanf(field_value, "%"PRId64",%s",
                            &info->replicas_ids[i], info->replicas[i]) != 2) {
      return dav_shared_new_error(r, NULL, HTTP_BAD_REQUEST, "Replica parameters malformed");
    }
  }

  /* Stat */
  switch (dmlite_statx(info->ctx, info->sfn, &(info->stat))) {
    /* We are good */
    case 0:
      exists = 1;
      break;
    /* Access denied */
    case DM_FORBIDDEN:
      /* If this is not a HEAD or a GET (both are M_GET), just fail,
       * but keep going otherwise */
      if (r->method_number != M_GET)
        return dav_shared_new_error(r, info->ctx, 0,
                                    "Access forbidden for %s on %s", info->sfn, r->method);
    case DM_NO_SUCH_FILE:
      exists = 0;
      /* When creating a file, break here */
      if (r->method_number == M_PUT || r->method_number == M_MKCOL ||
          r->method_number == M_MOVE)
        break;
      /* Now, fall-back to the next replica in the list, if any */
      info->redirect = dav_shared_build_aggregation_url(info->request->pool,
                                                        info->n_replicas,
                                                        (const char**)info->replicas,
                                                        info->replicas_ids,
                                                        info->forbidden_str,
                                                        info->notfound_str,
                                                        -1, info->r_id);
      if (info->redirect != NULL) {
        apr_table_set(r->headers_out, "Location", info->redirect);
        return dav_new_error(r->pool, HTTP_MOVED_TEMPORARILY, 0,
                             info->redirect);
      }
      /* We can't :(, so go to default */
    default:
      return dav_shared_new_error(r, info->ctx, 0, "Can not stat %s", info->sfn);
  }
  
  /* Create and return resource */
  *resource = apr_pcalloc(r->pool, sizeof(dav_resource));
  (*resource)->type   = DAV_RESOURCE_TYPE_REGULAR;
  (*resource)->exists = exists;
  (*resource)->collection = ((info->stat.stat.st_mode & S_IFDIR) != 0);
  (*resource)->uri    = sfn;
  (*resource)->info   = info;
  (*resource)->hooks  = &dav_ns_hooks_repository;
  (*resource)->pool   = r->pool;

  if (exists)
    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
                  "Resource for %s (%s) found (dir=%d)",
                  (*resource)->uri, (*resource)->info->sfn,
                  (*resource)->collection);
  else
    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
                  "NULL resource for %s (%s) created",
                  (*resource)->uri, (*resource)->info->sfn);

  return NULL;
}