예제 #1
0
static void nfs_Init(const nfs_start_info_t *p_start_info)
{
	cache_inode_status_t cache_status;
	state_status_t state_status;
	int rc = 0;
#ifdef _HAVE_GSSAPI
	gss_buffer_desc gss_service_buf;
	OM_uint32 maj_stat, min_stat;
	char GssError[MAXNAMLEN + 1];
#endif

#ifdef USE_DBUS
	/* DBUS init */
	gsh_dbus_pkginit();
#ifdef USE_DBUS_STATS
	dbus_export_init();
	dbus_client_init();
#endif
#endif

	/* Cache Inode Initialisation */
	cache_status = cache_inode_init();
	if (cache_status != CACHE_INODE_SUCCESS) {
		LogFatal(COMPONENT_INIT,
			 "Cache Inode Layer could not be initialized, status=%s",
			 cache_inode_err_str(cache_status));
	}

	state_status = state_lock_init(nfs_param.cache_param.cookie_param);
	if (state_status != STATE_SUCCESS) {
		LogFatal(COMPONENT_INIT,
			 "State Lock Layer could not be initialized, status=%s",
			 state_err_str(state_status));
	}
	LogInfo(COMPONENT_INIT, "Cache Inode library successfully initialized");

	/* Cache Inode LRU (call this here, rather than as part of
	   cache_inode_init() so the GC policy has been set */
	rc = cache_inode_lru_pkginit();
	if (rc != 0) {
		LogFatal(COMPONENT_INIT,
			 "Unable to initialize LRU subsystem: %d.", rc);
	}

	/* finish the job with exports by caching the root entries
	 */
	exports_pkginit();

	nfs41_session_pool =
	    pool_init("NFSv4.1 session pool", sizeof(nfs41_session_t),
		      pool_basic_substrate, NULL, NULL, NULL);

	request_pool =
	    pool_init("Request pool", sizeof(request_data_t),
		      pool_basic_substrate, NULL,
		      NULL /* FASTER constructor_request_data_t */ ,
		      NULL);
	if (!request_pool) {
		LogCrit(COMPONENT_INIT, "Error while allocating request pool");
		LogError(COMPONENT_INIT, ERR_SYS, ERR_MALLOC, errno);
		Fatal();
	}

	request_data_pool =
	    pool_init("Request Data Pool", sizeof(nfs_request_data_t),
		      pool_basic_substrate, NULL,
		      NULL /* FASTER constructor_nfs_request_data_t */ ,
		      NULL);
	if (!request_data_pool) {
		LogCrit(COMPONENT_INIT,
			"Error while allocating request data pool");
		LogError(COMPONENT_INIT, ERR_SYS, ERR_MALLOC, errno);
		Fatal();
	}

	dupreq_pool =
	    pool_init("Duplicate Request Pool", sizeof(dupreq_entry_t),
		      pool_basic_substrate, NULL, NULL, NULL);
	if (!(dupreq_pool)) {
		LogCrit(COMPONENT_INIT,
			"Error while allocating duplicate request pool");
		LogError(COMPONENT_INIT, ERR_SYS, ERR_MALLOC, errno);
		Fatal();
	}
#ifdef _USE_ASYNC_CACHE_INODE
	/* Start the TAD and synclets for writeback cache inode */
	cache_inode_async_init(nfs_param.cache_layers_param.
			       cache_inode_client_param);
#endif

	/* If rpcsec_gss is used, set the path to the keytab */
#ifdef _HAVE_GSSAPI
#ifdef HAVE_KRB5
	if (nfs_param.krb5_param.active_krb5) {
		OM_uint32 gss_status = GSS_S_COMPLETE;

		if (nfs_param.krb5_param.keytab[0] != '\0')
			gss_status =
			    krb5_gss_register_acceptor_identity(nfs_param.
								krb5_param.
								keytab);

		if (gss_status != GSS_S_COMPLETE) {
			log_sperror_gss(GssError, gss_status, 0);
			LogFatal(COMPONENT_INIT,
				 "Error setting krb5 keytab to value %s is %s",
				 nfs_param.krb5_param.keytab, GssError);
		}
		LogInfo(COMPONENT_INIT,
			"krb5 keytab path successfully set to %s",
			nfs_param.krb5_param.keytab);
#endif				/* HAVE_KRB5 */

		/* Set up principal to be use for GSSAPPI within GSSRPC/KRB5 */
		gss_service_buf.value = nfs_param.krb5_param.svc.principal;
		gss_service_buf.length =
			strlen(nfs_param.krb5_param.svc.principal) + 1;
		/* The '+1' is not to be forgotten, for the '\0' at the end */

		maj_stat = gss_import_name(&min_stat, &gss_service_buf,
					   (gss_OID) GSS_C_NT_HOSTBASED_SERVICE,
					   &nfs_param.krb5_param.svc.gss_name);
		if (maj_stat != GSS_S_COMPLETE) {
			log_sperror_gss(GssError, maj_stat, min_stat);
			LogFatal(COMPONENT_INIT,
				 "Error importing gss principal %s is %s",
				 nfs_param.krb5_param.svc.principal, GssError);
		}

		if (nfs_param.krb5_param.svc.gss_name == GSS_C_NO_NAME)
			LogInfo(COMPONENT_INIT,
				"Regression:  svc.gss_name == GSS_C_NO_NAME");

		LogInfo(COMPONENT_INIT, "gss principal \"%s\" successfully set",
			nfs_param.krb5_param.svc.principal);

		/* Set the principal to GSSRPC */
		if (!svcauth_gss_set_svc_name
		    (nfs_param.krb5_param.svc.gss_name)) {
			LogFatal(COMPONENT_INIT,
				 "Impossible to set gss principal to GSSRPC");
		}

		/* Don't release name until shutdown, it will be used by the
		 * backchannel. */

#ifdef HAVE_KRB5
	}			/*  if( nfs_param.krb5_param.active_krb5 ) */
#endif				/* HAVE_KRB5 */
#endif				/* _HAVE_GSSAPI */

	/* RPC Initialisation - exits on failure */
	nfs_Init_svc();
	LogInfo(COMPONENT_INIT, "RPC ressources successfully initialized");

	/* Admin initialisation */
	nfs_Init_admin_thread();

	LogEvent(COMPONENT_INIT, "Initializing ID Mapper.");
	if (!idmapper_init())
		LogFatal(COMPONENT_INIT, "Failed initializing ID Mapper.");
	else
		LogEvent(COMPONENT_INIT, "ID Mapper successfully initialized.");

	/* Init the NFSv4 Clientid cache */
	LogDebug(COMPONENT_INIT, "Now building NFSv4 clientid cache");
	if (nfs_Init_client_id(&nfs_param.client_id_param) !=
	    CLIENT_ID_SUCCESS) {
		LogFatal(COMPONENT_INIT,
			 "Error while initializing NFSv4 clientid cache");
	}
	LogInfo(COMPONENT_INIT,
		"NFSv4 clientid cache successfully initialized");

	/* Init duplicate request cache */
	dupreq2_pkginit();
	LogInfo(COMPONENT_INIT,
		"duplicate request hash table cache successfully initialized");

	/* Init the IP/name cache */
	LogDebug(COMPONENT_INIT, "Now building IP/name cache");
	if (nfs_Init_ip_name(nfs_param.ip_name_param) != IP_NAME_SUCCESS) {
		LogFatal(COMPONENT_INIT,
			 "Error while initializing IP/name cache");
	}
	LogInfo(COMPONENT_INIT, "IP/name cache successfully initialized");

	/* Init The NFSv4 State id cache */
	LogDebug(COMPONENT_INIT, "Now building NFSv4 State Id cache");
	if (nfs4_Init_state_id(&nfs_param.state_id_param) != 0) {
		LogFatal(COMPONENT_INIT,
			 "Error while initializing NFSv4 State Id cache");
	}
	LogInfo(COMPONENT_INIT,
		"NFSv4 State Id cache successfully initialized");

	/* Init The NFSv4 Open Owner cache */
	LogDebug(COMPONENT_INIT, "Now building NFSv4 Owner cache");
	if (Init_nfs4_owner(&nfs_param.nfs4_owner_param) != 0) {
		LogFatal(COMPONENT_INIT,
			 "Error while initializing NFSv4 Owner cache");
	}
	LogInfo(COMPONENT_INIT,
		"NFSv4 Open Owner cache successfully initialized");

	if (nfs_param.core_param.enable_NLM) {
		/* Init The NLM Owner cache */
		LogDebug(COMPONENT_INIT, "Now building NLM Owner cache");
		if (Init_nlm_hash() != 0) {
			LogFatal(COMPONENT_INIT,
				 "Error while initializing NLM Owner cache");
		}
		LogInfo(COMPONENT_INIT,
			"NLM Owner cache successfully initialized");
		nlm_init();
	}
#ifdef _USE_9P
	/* Init the 9P lock owner cache */
	LogDebug(COMPONENT_INIT, "Now building 9P Owner cache");
	if (Init_9p_hash() != 0) {
		LogFatal(COMPONENT_INIT,
			 "Error while initializing 9P Owner cache");
	}
	LogInfo(COMPONENT_INIT, "9P Owner cache successfully initialized");
#endif

	LogDebug(COMPONENT_INIT, "Now building NFSv4 Session Id cache");
	if (nfs41_Init_session_id(&nfs_param.session_id_param) != 0) {
		LogFatal(COMPONENT_INIT,
			 "Error while initializing NFSv4 Session Id cache");
	}
	LogInfo(COMPONENT_INIT,
		"NFSv4 Session Id cache successfully initialized");

	LogDebug(COMPONENT_INIT, "Now building NFSv4 ACL cache");
	if (nfs4_acls_init() != 0) {
		LogCrit(COMPONENT_INIT, "Error while initializing NFSv4 ACLs");
		exit(1);
	}
	LogInfo(COMPONENT_INIT, "NFSv4 ACL cache successfully initialized");

#ifdef _USE_9P
	LogDebug(COMPONENT_INIT, "Now building 9P resources");
	if (_9p_init(&nfs_param._9p_param)) {
		LogCrit(COMPONENT_INIT,
			"Error while initializing 9P Resources");
		exit(1);
	}
	LogInfo(COMPONENT_INIT, "9P resources successfully initialized");
#endif				/* _USE_9P */

	/* Creates the pseudo fs */
	LogDebug(COMPONENT_INIT, "Now building pseudo fs");
	rc = nfs4_ExportToPseudoFS();
	if (rc != 0)
		LogFatal(COMPONENT_INIT,
			 "Error %d while initializing NFSv4 pseudo file system",
			 rc);

	LogInfo(COMPONENT_INIT,
		"NFSv4 pseudo file system successfully initialized");

	/* Save Ganesha thread credentials with Frank's routine for later use */
	fsal_save_ganesha_credentials();

	/* Create stable storage directory, this needs to be done before
	 * starting the recovery thread.
	 */
	nfs4_create_recov_dir();

	/* initialize grace and read in the client IDs */
	nfs4_init_grace();
	nfs4_load_recov_clids(NULL);

	/* Start grace period */
	nfs4_start_grace(NULL);

	/* callback dispatch */
	nfs_rpc_cb_pkginit();
#ifdef _USE_CB_SIMULATOR
	nfs_rpc_cbsim_pkginit();
#endif				/*  _USE_CB_SIMULATOR */

}				/* nfs_Init */
예제 #2
0
int nfs_rpc_req2client_cred(struct svc_req *reqp, nfs_client_cred_t * pcred)
{
  /* Structure for managing basic AUTH_UNIX authentication */
  struct authunix_parms *aup = NULL;

  /* Stuff needed for managing RPCSEC_GSS */
#ifdef _HAVE_GSSAPI
  OM_uint32 maj_stat = 0;
  OM_uint32 min_stat = 0;
  struct svc_rpc_gss_data *gd = NULL;
  gss_buffer_desc oidbuff;
#endif

  if(reqp == NULL || pcred == NULL)
    return -1;

  pcred->flavor = reqp->rq_cred.oa_flavor;
  pcred->length = reqp->rq_cred.oa_length;

  switch (reqp->rq_cred.oa_flavor)
    {
    case AUTH_NONE:
      /* Do nothing... because there seems like nothing is to be done... */
      break;

    case AUTH_UNIX:
      aup = (struct authunix_parms *)(reqp->rq_clntcred);

      pcred->auth_union.auth_unix.aup_uid = aup->aup_uid;
      pcred->auth_union.auth_unix.aup_gid = aup->aup_gid;
      pcred->auth_union.auth_unix.aup_time = aup->aup_time;

      break;

#ifdef _HAVE_GSSAPI
    case RPCSEC_GSS:
      /* Extract the information from the RPCSEC_GSS opaque structure */
      gd = SVCAUTH_PRIVATE(reqp->rq_xprt->xp_auth);

      pcred->auth_union.auth_gss.svc = (unsigned int)(gd->sec.svc);
      pcred->auth_union.auth_gss.qop = (unsigned int)(gd->sec.qop);
      pcred->auth_union.auth_gss.gss_context_id = gd->ctx;
      strncpy(pcred->auth_union.auth_gss.cname, gd->cname.value, NFS_CLIENT_NAME_LEN);

      if((maj_stat = gss_oid_to_str(&min_stat, gd->sec.mech, &oidbuff)) != GSS_S_COMPLETE)
        {
          char errbuff[1024];
          log_sperror_gss(errbuff, maj_stat, min_stat);
          LogCrit(COMPONENT_DISPATCH,
                  "GSSAPI ERROR: %u|%u = %s",
                  maj_stat, min_stat, errbuff);
          return -1;
        }
      strncpy(pcred->auth_union.auth_gss.stroid, oidbuff.value, NFS_CLIENT_NAME_LEN);

      /* Je fais le menage derriere moi */
      (void)gss_release_buffer(&min_stat, &oidbuff);
      break;
#endif

    default:
      /* Unsupported authentication flavour */
      return -1;
      break;
    }

  return 1;
}                               /* nfs_rpc_req2client_cred */
예제 #3
0
static bool_t
Svcauth_gss_validate(struct svc_req *rqst, struct svc_rpc_gss_data *gd,
                     struct rpc_msg *msg)
{
  struct opaque_auth *oa;
  gss_buffer_desc rpcbuf, checksum;
  OM_uint32 maj_stat, min_stat, qop_state;
  u_char rpchdr[128];
  int32_t *buf;
  char GssError[256];

  memset(rpchdr, 0, sizeof(rpchdr));

  /* XXX - Reconstruct RPC header for signing (from xdr_callmsg). */
  oa = &msg->rm_call.cb_cred;

  LogFullDebug(COMPONENT_RPCSEC_GSS,
               "Call to Svcauth_gss_validate --> xid=%u dir=%u rpcvers=%u prog=%u vers=%u proc=%u flavor=%u len=%u base=%p ckeck.len=%u check.val=%p",
               msg->rm_xid,
               msg->rm_direction,
               msg->rm_call.cb_rpcvers,
               msg->rm_call.cb_prog,
               msg->rm_call.cb_vers,
               msg->rm_call.cb_proc,
               oa->oa_flavor,
               oa->oa_length,
               oa->oa_base,
               msg->rm_call.cb_verf.oa_length,
               msg->rm_call.cb_verf.oa_base);

  if(oa->oa_length > MAX_AUTH_BYTES)
    {
      LogCrit(COMPONENT_RPCSEC_GSS,
              "Svcauth_gss_validate oa->oa_length (%u) > MAX_AUTH_BYTES (%u)",
              oa->oa_length, MAX_AUTH_BYTES);
      return (FALSE);
    }
  
  /* 8 XDR units from the IXDR macro calls. */
  if(sizeof(rpchdr) < (8 * BYTES_PER_XDR_UNIT +
     RNDUP(oa->oa_length)))
    {
      LogCrit(COMPONENT_RPCSEC_GSS,
              "Svcauth_gss_validate sizeof(rpchdr) (%d) < (8 * BYTES_PER_XDR_UNIT (%d) + RNDUP(oa->oa_length (%u))) (%d)",
              (int) sizeof(rpchdr),
              (int) (8 * BYTES_PER_XDR_UNIT),
              oa->oa_length,
              (int) (8 * BYTES_PER_XDR_UNIT + RNDUP(oa->oa_length)));
      return (FALSE);
    }

  buf = (int32_t *) (void *)rpchdr;
  IXDR_PUT_LONG(buf, msg->rm_xid);
  IXDR_PUT_ENUM(buf, msg->rm_direction);
  IXDR_PUT_LONG(buf, msg->rm_call.cb_rpcvers);
  IXDR_PUT_LONG(buf, msg->rm_call.cb_prog);
  IXDR_PUT_LONG(buf, msg->rm_call.cb_vers);
  IXDR_PUT_LONG(buf, msg->rm_call.cb_proc);
  IXDR_PUT_ENUM(buf, oa->oa_flavor);
  IXDR_PUT_LONG(buf, oa->oa_length);
  if(oa->oa_length)
    {
      memcpy((caddr_t) buf, oa->oa_base, oa->oa_length);
      buf += RNDUP(oa->oa_length) / sizeof(int32_t);
    }
  rpcbuf.value = rpchdr;
  rpcbuf.length = (u_char *) buf - rpchdr;

  checksum.value = msg->rm_call.cb_verf.oa_base;
  checksum.length = msg->rm_call.cb_verf.oa_length;

  if(isFullDebug(COMPONENT_RPCSEC_GSS))
    {
      char ctx_str[64];
      sprint_ctx(ctx_str, (unsigned char *)gd->ctx, sizeof(gss_union_ctx_id_desc));
      LogFullDebug(COMPONENT_RPCSEC_GSS,
                   "Svcauth_gss_validate context %s rpcbuf=%p:%u checksum=%p:$%u)",
                   ctx_str, rpcbuf.value, (unsigned int) rpcbuf.length,
                   checksum.value, (unsigned int) checksum.length);
    }

  maj_stat = gss_verify_mic(&min_stat, gd->ctx, &rpcbuf, &checksum, &qop_state);

  if(maj_stat != GSS_S_COMPLETE)
    {
      log_sperror_gss(GssError, maj_stat, min_stat);
      LogCrit(COMPONENT_RPCSEC_GSS, "Error in gss_verify_mic: %s", GssError);
      return (FALSE);
    }
  return (TRUE);
}