Beispiel #1
0
/**
 * @brief Validate export permissions
 *
 * @param[in]  req              Incoming request.
 *
 * @return NFS4_OK if successful, NFS4ERR_ACCESS or NFS4ERR_WRONGSEC otherwise.
 *
 */
nfsstat4 nfs4_export_check_access(struct svc_req *req)
{
    xprt_type_t xprt_type = svc_get_xprt_type(req->rq_xprt);
    int port = get_port(op_ctx->caller_addr);

    LogMidDebugAlt(COMPONENT_NFS_V4, COMPONENT_EXPORT,
                   "nfs4_export_check_access about to call export_check_access");
    export_check_access();

    /* Check if any access at all */
    if ((op_ctx->export_perms->options &
            EXPORT_OPTION_ACCESS_TYPE) == 0) {
        LogInfoAlt(COMPONENT_NFS_V4, COMPONENT_EXPORT,
                   "Access not allowed on Export_Id %d %s for client %s",
                   op_ctx->export->export_id,
                   op_ctx->export->fullpath,
                   op_ctx->client
                   ? op_ctx->client->hostaddr_str
                   : "unknown client");
        return NFS4ERR_ACCESS;
    }
Beispiel #2
0
/**
 * @brief Validate export permissions
 *
 * @param[in]  req              Incoming request.
 *
 * @return NFS4_OK if successful, NFS4ERR_ACCESS or NFS4ERR_WRONGSEC otherwise.
 *
 */
nfsstat4 nfs4_export_check_access(struct svc_req *req)
{
	xprt_type_t xprt_type = svc_get_xprt_type(req->rq_xprt);
	int port = get_port(op_ctx->caller_addr);

	LogMidDebugAlt(COMPONENT_NFS_V4, COMPONENT_EXPORT,
		    "nfs4_export_check_access about to call export_check_access");
	export_check_access();

	/* Check if any access at all */
	if ((op_ctx->export_perms->options &
	     EXPORT_OPTION_ACCESS_MASK) == 0) {
		LogInfoAlt(COMPONENT_NFS_V4, COMPONENT_EXPORT,
			"Access not allowed on Export_Id %d %s for client %s",
			op_ctx->ctx_export->export_id,
			op_ctx->ctx_export->fullpath,
			op_ctx->client
				? op_ctx->client->hostaddr_str
				: "unknown client");
		return NFS4ERR_ACCESS;
	}

	/* Check protocol version */
	if ((op_ctx->export_perms->options & EXPORT_OPTION_NFSV4) == 0) {
		LogInfoAlt(COMPONENT_NFS_V4, COMPONENT_EXPORT,
			"NFS4 not allowed on Export_Id %d %s for client %s",
			op_ctx->ctx_export->export_id,
			op_ctx->ctx_export->fullpath,
			op_ctx->client
				? op_ctx->client->hostaddr_str
				: "unknown client");
		return NFS4ERR_ACCESS;
	}

	/* Check transport type */
	if (((xprt_type == XPRT_UDP) &&
	    ((op_ctx->export_perms->options &
	      EXPORT_OPTION_UDP) == 0))
	    ||
	    ((xprt_type == XPRT_TCP) &&
	    ((op_ctx->export_perms->options &
	      EXPORT_OPTION_TCP) == 0))) {
		LogInfoAlt(COMPONENT_NFS_V4, COMPONENT_EXPORT,
			"NFS4 over %s not allowed on Export_Id %d %s for client %s",
			xprt_type_to_str(xprt_type),
			op_ctx->ctx_export->export_id,
			op_ctx->ctx_export->fullpath,
			op_ctx->client
				? op_ctx->client->hostaddr_str
				: "unknown client");
		return NFS4ERR_ACCESS;
	}

	/* Check if client is using a privileged port. */
	if (((op_ctx->export_perms->options &
	      EXPORT_OPTION_PRIVILEGED_PORT) != 0)
	    && (port >= IPPORT_RESERVED)) {
		LogInfoAlt(COMPONENT_NFS_V4, COMPONENT_EXPORT,
			"Non-reserved Port %d is not allowed on Export_Id %d %s for client %s",
			port, op_ctx->ctx_export->export_id,
			op_ctx->ctx_export->fullpath,
			op_ctx->client
				? op_ctx->client->hostaddr_str
				: "unknown client");
		return NFS4ERR_ACCESS;
	}

	/* Test if export allows the authentication provided */
	if (export_check_security(req) == false) {
		LogInfoAlt(COMPONENT_NFS_V4, COMPONENT_EXPORT,
			"NFS4 auth not allowed on Export_Id %d %s for client %s",
			op_ctx->ctx_export->export_id,
			op_ctx->ctx_export->fullpath,
			op_ctx->client
				? op_ctx->client->hostaddr_str
				: "unknown client");
		return NFS4ERR_WRONGSEC;
	}

	/* Get creds */
	return nfs_req_creds(req);
}
Beispiel #3
0
state_nlm_client_t *get_nlm_client(care_t               care,
                                   SVCXPRT            * xprt,
                                   state_nsm_client_t * pnsm_client,
                                   char               * caller_name)
{
  state_nlm_client_t   key;
  state_nlm_client_t * pclient;
  char                 str[HASHTABLE_DISPLAY_STRLEN];
  struct hash_latch    latch;
  hash_error_t         rc;
  hash_buffer_t        buffkey;
  hash_buffer_t        buffval;

  if(caller_name == NULL)
    return NULL;

  memset(&key, 0, sizeof(key));

  key.slc_nsm_client          = pnsm_client;
  key.slc_nlm_caller_name_len = strlen(caller_name);
  key.slc_client_type         = svc_get_xprt_type(xprt);

  if(key.slc_nlm_caller_name_len > LM_MAXSTRLEN)
    return NULL;

  key.slc_nlm_caller_name = caller_name;
  
  if(isFullDebug(COMPONENT_STATE))
    {
      display_nlm_client(&key, str);
      LogFullDebug(COMPONENT_STATE,
                   "Find {%s}", str);
    }

  buffkey.pdata = &key;
  buffkey.len   = sizeof(key);

  rc = HashTable_GetLatch(ht_nlm_client,
                          &buffkey,
                          &buffval,
                          TRUE,
                          &latch);

  /* If we found it, return it */
  if(rc == HASHTABLE_SUCCESS)
    {
      pclient = buffval.pdata;

      /* Return the found NLM Client */
      if(isFullDebug(COMPONENT_STATE))
        {
          display_nlm_client(pclient, str);
          LogFullDebug(COMPONENT_STATE,
                       "Found {%s}",
                       str);
        }

      /* Increment refcount under hash latch.
       * This prevents dec ref from removing this entry from hash if a race
       * occurs.
       */
      inc_nlm_client_ref(pclient);

      HashTable_ReleaseLatched(ht_nlm_client, &latch);

      if(care == CARE_MONITOR && !nsm_monitor(pnsm_client))
          {
            dec_nlm_client_ref(pclient);
            pclient = NULL;
          }

      return pclient;
    }

  /* An error occurred, return NULL */
  if(rc != HASHTABLE_ERROR_NO_SUCH_KEY)
    {
      display_nlm_client(&key, str);

      LogCrit(COMPONENT_STATE,
              "Error %s, could not find {%s}",
              hash_table_err_to_str(rc), str);

      return NULL;
    }

  /* Not found, but we don't care, return NULL */
  if(care == CARE_NOT)
    {
      /* Return the found NLM Client */
      if(isFullDebug(COMPONENT_STATE))
        {
          display_nlm_client(&key, str);
          LogFullDebug(COMPONENT_STATE,
                       "Ignoring {%s}",
                       str);
        }

      HashTable_ReleaseLatched(ht_nlm_client, &latch);

      return NULL;
    }

  pclient = gsh_malloc(sizeof(*pclient));

  if(pclient == NULL)
    {
      display_nlm_client(&key, str);
      LogCrit(COMPONENT_STATE,
              "No memory for {%s}",
              str);

      return NULL;
    }

  /* Copy everything over */
  memcpy(pclient, &key, sizeof(key));

  pclient->slc_nlm_caller_name = gsh_strdup(key.slc_nlm_caller_name);

  /* Take a reference to the NSM Client */
  inc_nsm_client_ref(pnsm_client);

  if(pclient->slc_nlm_caller_name == NULL)
    {
      /* Discard the created client */
      free_nlm_client(pclient);
      return NULL;
    }

  pclient->slc_refcount = 1;

  if(isFullDebug(COMPONENT_STATE))
    {
      display_nlm_client(pclient, str);
      LogFullDebug(COMPONENT_STATE,
                   "New {%s}", str);
    }

  buffkey.pdata = pclient;
  buffkey.len   = sizeof(*pclient);
  buffval.pdata = pclient;
  buffval.len   = sizeof(*pclient);

  rc = HashTable_SetLatched(ht_nlm_client,
                            &buffval,
                            &buffval,
                            &latch,
                            FALSE,
                            NULL,
                            NULL);

  /* An error occurred, return NULL */
  if(rc != HASHTABLE_SUCCESS)
    {
      display_nlm_client(pclient, str);

      LogCrit(COMPONENT_STATE,
              "Error %s, inserting {%s}",
              hash_table_err_to_str(rc), str);

      free_nlm_client(pclient);

      return NULL;
    }

  if(care != CARE_MONITOR || nsm_monitor(pnsm_client))
    return pclient;

  /* Failed to monitor, release client reference
   * and almost certainly remove it from the hash table.
   */
  dec_nlm_client_ref(pclient);

  return NULL;
}
Beispiel #4
0
/**
 * @brief Get an NLM client
 *
 * @param[in] care        Care status
 * @param[in] xprt        RPC transport
 * @param[in] nsm_client  Related NSM client
 * @param[in] caller_name Caller name
 *
 * @return NLM client or NULL.
 */
state_nlm_client_t *get_nlm_client(care_t care, SVCXPRT *xprt,
				   state_nsm_client_t *nsm_client,
				   char *caller_name)
{
	state_nlm_client_t key;
	state_nlm_client_t *pclient;
	char str[LOG_BUFF_LEN];
	struct display_buffer dspbuf = {sizeof(str), str, str};
	struct hash_latch latch;
	hash_error_t rc;
	struct gsh_buffdesc buffkey;
	struct gsh_buffdesc buffval;
	struct sockaddr_storage local_addr;
	socklen_t addr_len;

	if (caller_name == NULL)
		return NULL;

	memset(&key, 0, sizeof(key));

	key.slc_nsm_client = nsm_client;
	key.slc_nlm_caller_name_len = strlen(caller_name);
	key.slc_client_type = svc_get_xprt_type(xprt);

	addr_len = sizeof(local_addr);
	if (getsockname(xprt->xp_fd, (struct sockaddr *)&local_addr, &addr_len)
	    == -1) {
		LogEvent(COMPONENT_CLIENTID, "Failed to get local addr.");
	} else {
		memcpy(&(key.slc_server_addr), &local_addr,
		       sizeof(struct sockaddr_storage));
	}

	if (key.slc_nlm_caller_name_len > LM_MAXSTRLEN)
		return NULL;

	key.slc_nlm_caller_name = caller_name;

	if (isFullDebug(COMPONENT_STATE)) {
		display_nlm_client(&dspbuf, &key);
		LogFullDebug(COMPONENT_STATE, "Find {%s}", str);
	}

	buffkey.addr = &key;
	buffkey.len = sizeof(key);

	rc = hashtable_getlatch(ht_nlm_client, &buffkey, &buffval, true,
				&latch);

	/* If we found it, return it */
	if (rc == HASHTABLE_SUCCESS) {
		pclient = buffval.addr;

		/* Return the found NLM Client */
		if (isFullDebug(COMPONENT_STATE)) {
			display_nlm_client(&dspbuf, pclient);
			LogFullDebug(COMPONENT_STATE, "Found {%s}", str);
		}

		/* Increment refcount under hash latch.
		 * This prevents dec ref from removing this entry from hash
		 * if a race occurs.
		 */
		inc_nlm_client_ref(pclient);

		hashtable_releaselatched(ht_nlm_client, &latch);

		if (care == CARE_MONITOR && !nsm_monitor(nsm_client)) {
			dec_nlm_client_ref(pclient);
			pclient = NULL;
		}

		return pclient;
	}

	/* An error occurred, return NULL */
	if (rc != HASHTABLE_ERROR_NO_SUCH_KEY) {
		display_nlm_client(&dspbuf, &key);

		LogCrit(COMPONENT_STATE, "Error %s, could not find {%s}",
			hash_table_err_to_str(rc), str);

		return NULL;
	}

	/* Not found, but we don't care, return NULL */
	if (care == CARE_NOT) {
		/* Return the found NLM Client */
		if (isFullDebug(COMPONENT_STATE)) {
			display_nlm_client(&dspbuf, &key);
			LogFullDebug(COMPONENT_STATE, "Ignoring {%s}", str);
		}

		hashtable_releaselatched(ht_nlm_client, &latch);

		return NULL;
	}

	pclient = gsh_malloc(sizeof(*pclient));

	if (pclient == NULL) {
		display_nlm_client(&dspbuf, &key);
		LogCrit(COMPONENT_STATE, "No memory for {%s}", str);

		return NULL;
	}

	/* Copy everything over */
	memcpy(pclient, &key, sizeof(key));

	pclient->slc_nlm_caller_name = gsh_strdup(key.slc_nlm_caller_name);

	/* Take a reference to the NSM Client */
	inc_nsm_client_ref(nsm_client);

	if (pclient->slc_nlm_caller_name == NULL) {
		/* Discard the created client */
		free_nlm_client(pclient);
		return NULL;
	}

	pclient->slc_refcount = 1;

	if (isFullDebug(COMPONENT_STATE)) {
		display_nlm_client(&dspbuf, pclient);
		LogFullDebug(COMPONENT_STATE, "New {%s}", str);
	}

	buffkey.addr = pclient;
	buffkey.len = sizeof(*pclient);
	buffval.addr = pclient;
	buffval.len = sizeof(*pclient);

	rc = hashtable_setlatched(ht_nlm_client, &buffval, &buffval, &latch,
				  false, NULL, NULL);

	/* An error occurred, return NULL */
	if (rc != HASHTABLE_SUCCESS) {
		display_nlm_client(&dspbuf, pclient);

		LogCrit(COMPONENT_STATE, "Error %s, inserting {%s}",
			hash_table_err_to_str(rc), str);

		free_nlm_client(pclient);

		return NULL;
	}

	if (care != CARE_MONITOR || nsm_monitor(nsm_client))
		return pclient;

	/* Failed to monitor, release client reference
	 * and almost certainly remove it from the hash table.
	 */
	dec_nlm_client_ref(pclient);

	return NULL;
}