Beispiel #1
0
/*
 * the following function is for client,
 * server/daemon process shouldn't call it.
 * Because this function may read incorrect setting from user specified
 * $USER or $HOME.
 */
gfarm_error_t
gfarm_config_read(void)
{
	gfarm_error_t e;
	char *home;
	FILE *config;
	int lineno, user_config_errno, rc_need_free;;
	static char gfarm_client_rc[] = GFARM_CLIENT_RC;
	char *rc;

	rc_need_free = 0;
	rc = getenv("GFARM_CONFIG_FILE");
	if (rc == NULL) {
		/*
		 * result of gfarm_get_local_homedir() should not be trusted.
		 * (maybe forged)
		 */
		home = gfarm_get_local_homedir();

		GFARM_MALLOC_ARRAY(rc,
		    strlen(home) + 1 + sizeof(gfarm_client_rc));
		if (rc == NULL)
			return (GFARM_ERR_NO_MEMORY);
		sprintf(rc, "%s/%s", home, gfarm_client_rc);
		rc_need_free = 1;
	}
	gfarm_init_user_map();
	if ((config = fopen(rc, "r")) == NULL) {
		user_config_errno = errno;
	} else {
		user_config_errno = 0;
		e = gfarm_config_read_file(config, &lineno);
		if (e != GFARM_ERR_NO_ERROR) {
			gflog_error("%s: %d: %s",
			    rc, lineno, gfarm_error_string(e));
			if (rc_need_free)
				free(rc);
			return (e);
		}
	}
	if (rc_need_free)
		free(rc);

	if ((config = fopen(gfarm_config_file, "r")) == NULL) {
		if (user_config_errno != 0)
			return (GFARM_ERRMSG_CANNOT_OPEN_CONFIG);
	} else {
		e = gfarm_config_read_file(config, &lineno);
		if (e != GFARM_ERR_NO_ERROR) {
			gflog_error("%s: %d: %s",
			    gfarm_config_file, lineno, gfarm_error_string(e));
			return (e);
		}
	}

	gfarm_config_set_default_ports();
	gfarm_config_set_default_misc();

	return (GFARM_ERR_NO_ERROR);
}
Beispiel #2
0
int
gfsk_gfarm_init(uid_t uid)
{
	gfarm_error_t e;

	e = gfarm_context_init();
	if (e != GFARM_ERR_NO_ERROR) {
		gflog_error(GFARM_MSG_UNFIXED,
			"gfarm_context_init failed: %s",
			gfarm_error_string(e));
		goto out;
	}
	e = gfarm_set_local_user_for_this_uid(uid);
	if (e != GFARM_ERR_NO_ERROR) {
		gflog_error(GFARM_MSG_UNFIXED,
			"gfarm_set_local_user_for_this_uid failed: %s",
			gfarm_error_string(e));
		goto out;
	}
	gflog_initialize();
	e = gfarm_config_read();
	if (e != GFARM_ERR_NO_ERROR) {
		gflog_error(GFARM_MSG_UNFIXED,
		    "gfarm_config_read() failed: %s", gfarm_error_string(e));
		goto out;
	}
out:
	return (-gfarm_error_to_errno(e));
}
Beispiel #3
0
/* FIXME: should support return values other than gfarm_error_t too */
void
gfm_async_server_reply_to_gfsd_schedule(struct host *host,
	struct peer *peer, gfp_xdr_xid_t xid,
	gfarm_error_t errcode, int flags, const char *diag)
{
	gfarm_error_t e;
	struct gfm_async_server_reply_to_gfsd_entry *qe;

	GFARM_MALLOC(qe);
	if (qe == NULL) {
		gflog_error(GFARM_MSG_1004031,
		    "%s: %s: no memory for queue entry",
		    host_name(host), diag);
	} else {
		netsendq_entry_init(&qe->qentry,
		    &gfm_async_server_reply_to_gfsd_queue);
		qe->qentry.abhost = host_to_abstract_host(host);
		qe->peer = peer;
		qe->xid = xid;
		qe->errcode = errcode;
		qe->diag = diag;
		e = netsendq_add_entry(host_sendq(host), &qe->qentry, flags);
		if (e != GFARM_ERR_NO_ERROR) {
			gflog_info(GFARM_MSG_1004032,
			    "%s: %s queueing: %s",
			    host_name(host), diag, gfarm_error_string(e));
			if ((flags & NETSENDQ_ADD_FLAG_DETACH_ERROR_HANDLING)
			    == 0)
				free(qe);
		}
	}
}
Beispiel #4
0
char *
gfarm_gsi_server_initialize(void)
{
	OM_uint32 e_major;
	OM_uint32 e_minor;
	int rv;

	if (gsi_initialized) {
		if (gsi_server_initialized)
			return (NULL);
		gfarmSecSessionFinalizeInitiator();
		gsi_initialized = 0;
	}

	rv = gfarmSecSessionInitializeBoth(NULL, NULL, GRID_MAPFILE,
	    &e_major, &e_minor);
	if (rv <= 0) {
		if (gflog_auth_get_verbose()) {
			gflog_error(
			    "can't initialize GSI as both because of:");
			gfarmGssPrintMajorStatus(e_major);
			gfarmGssPrintMinorStatus(e_minor);
		}
		gfarmSecSessionFinalizeBoth();
		return ("GSI initialization failed"); /* XXX */
	}
	gsi_initialized = 1;
	gsi_server_initialized = 1;
	return (NULL);
}
Beispiel #5
0
/* the following function is for server. */
gfarm_error_t
gfarm_server_config_read(void)
{
	gfarm_error_t e;
	int lineno;
	FILE *config;
	char *config_file = gfarm_config_get_filename();

	gfarm_init_config();
	if ((config = fopen(config_file, "r")) == NULL) {
		gflog_debug(GFARM_MSG_1000976,
			"open operation on server config file (%s) failed",
			config_file);
		return (GFARM_ERRMSG_CANNOT_OPEN_CONFIG);
	}
	e = gfarm_config_read_file(config, &lineno);
	if (e != GFARM_ERR_NO_ERROR) {
		gflog_error(GFARM_MSG_1000014, "%s: line %d: %s",
		    config_file, lineno, gfarm_error_string(e));
		return (e);
	}

	gfarm_config_set_default_ports();
	gfarm_config_set_default_misc();

	return (GFARM_ERR_NO_ERROR);
}
Beispiel #6
0
int
gfsk_evfd_create(unsigned int count)
{
	int fd;

	struct file *file;
	file = gfsk_evfd_file_create(count);
	if (IS_ERR(file)) {
		fd = PTR_ERR(file);
		gflog_error(GFARM_MSG_UNFIXED, "fail gfsk_evfd_file_create %d"
			, fd);
	} else {
		if ((fd = gfsk_fd_file_set(file)) < 0)
			gflog_error(GFARM_MSG_UNFIXED,
				"fail gfsk_fd_file_set %d", fd);
		fput(file);
	}
	return (fd);
}
Beispiel #7
0
char *
gfarm_gsi_client_cred_name(void)
{
	gss_cred_id_t cred;
	gss_name_t name;
	OM_uint32 e_major, e_minor;
	static int initialized = 0;
	static char *dn;

	if (initialized)
		return (dn);
	
	if (gfarmSecSessionGetInitiatorInitialCredential(&cred) < 0) {
		dn = NULL;
		gflog_auth_error("gfarm_gsi_client_cred_name(): "
		    "not initialized as an initiator");
	} else if (gfarmGssNewCredentialName(&name, cred, &e_major, &e_minor)
	    < 0) {
		dn = NULL;
		if (gflog_auth_get_verbose()) {
			gflog_error("cannot convert initiator credential "
			    "to name");
			gfarmGssPrintMajorStatus(e_major);
			gfarmGssPrintMinorStatus(e_minor);
		}
	} else {
		dn = gfarmGssNewDisplayName(name, &e_major, &e_minor, NULL);
		if (dn == NULL && gflog_auth_get_verbose()) {
			gflog_error("cannot convert initiator credential "
			    "to string");
			gfarmGssPrintMajorStatus(e_major);
			gfarmGssPrintMinorStatus(e_minor);
		}
		gfarmGssDeleteName(&name, NULL, NULL);
	}
	initialized = 1;
	return (dn);
}
Beispiel #8
0
static gfarm_error_t
sync_back_channel_service(struct abstract_host *h, struct peer *peer)
{
	struct host *host = abstract_host_to_host(h);
	gfarm_int32_t (*result_callback)(void *, void *, size_t);
	void *arg;

	if (!host_get_result_callback(host, peer, &result_callback, &arg)) {
		gflog_error(GFARM_MSG_1002285,
		    "extra data from back channel");
		return (GFARM_ERR_PROTOCOL);
	}
	/*
	 * the 3rd argument of (*callback)() (i.e. 0) is dummy,
	 * but it must be a value except GFP_XDR_ASYNC_SIZE_FREED.
	 */
	return ((*result_callback)(peer, arg, 0));
}
Beispiel #9
0
static void
free_secsession(struct io_gfsl *io)
{
	OM_uint32 e_major, e_minor;

	gfarmSecSessionTerminate(io->session);

	if (io->cred_to_be_freed != GSS_C_NO_CREDENTIAL &&
	    gfarmGssDeleteCredential(&io->cred_to_be_freed,
	    &e_major, &e_minor) < 0 &&
	    gflog_auth_get_verbose()) {
		gflog_error("Can't free my credential because of:");
		gfarmGssPrintMajorStatus(e_major);
		gfarmGssPrintMinorStatus(e_minor);
	}
		
	if (io->buffer != NULL)
		free(io->buffer);
	free(io);
}
Beispiel #10
0
static gfarm_error_t
gfm_server_switch_back_channel_common(
	struct peer *peer, gfp_xdr_xid_t xid, size_t *sizep,
	int from_client,
	int version, const char *diag, struct relayed_request *relay)
{
	gfarm_error_t e = GFARM_ERR_NO_ERROR, e2;
	struct host *host;
	gfp_xdr_async_peer_t async = NULL;
	struct local_peer *local_peer = NULL;
	int is_direct_connection;
	int i = 0;

#ifdef __GNUC__ /* workaround gcc warning: might be used uninitialized */
	host = NULL;
#endif
	is_direct_connection = (peer_get_parent(peer) == NULL);

	giant_lock();

	if (from_client) {
		gflog_debug(GFARM_MSG_1001995,
		    "Operation not permitted: from_client");
		e = GFARM_ERR_OPERATION_NOT_PERMITTED;
	} else if ((host = peer_get_host(peer)) == NULL) {
		gflog_debug(GFARM_MSG_1001996,
		    "Operation not permitted: peer_get_host() failed");
		e = GFARM_ERR_OPERATION_NOT_PERMITTED;
	} else if (is_direct_connection &&
	    (e = gfp_xdr_async_peer_new(&async)) != GFARM_ERR_NO_ERROR) {
		gflog_error(GFARM_MSG_1002288,
		    "%s: gfp_xdr_async_peer_new(): %s",
		    diag, gfarm_error_string(e));
	}
	giant_unlock();

	e2 = gfm_server_relay_put_reply(peer, xid, sizep, relay,
	    diag, &e,  "i", &i/*XXX FIXME*/);
	if (e2 != GFARM_ERR_NO_ERROR)
		return (e2);
	if (debug_mode)
		gflog_debug(GFARM_MSG_1000404, "gfp_xdr_flush");
	e2 = gfp_xdr_flush(peer_get_conn(peer));
	if (e2 != GFARM_ERR_NO_ERROR) {
		gflog_warning(GFARM_MSG_1000405,
		    "%s: protocol flush: %s",
		    diag, gfarm_error_string(e2));
		return (e2);
	} else if (e != GFARM_ERR_NO_ERROR)
		return (e2);

	if (is_direct_connection) {
		local_peer = peer_to_local_peer(peer);
		local_peer_set_async(local_peer, async); /* XXXRELAY */
		local_peer_set_readable_watcher(local_peer,
		    back_channel_recv_watcher);
	}

	if (host_is_up(host)) /* throw away old connetion */ {
		gflog_warning(GFARM_MSG_1002440,
		    "back_channel(%s): switching to new connection",
		    host_name(host));
		host_disconnect_request(host, NULL);
	}

	giant_lock();
	peer_set_peer_type(peer, peer_type_back_channel);
	abstract_host_set_peer(host_to_abstract_host(host), peer, version);
	giant_unlock();

	if (is_direct_connection) {
		local_peer_watch_readable(local_peer);
		gfarm_thr_statewait_signal(
		    local_peer_get_statewait(local_peer), e2, diag);
	}

	callout_setfunc(host_status_callout(host),
	    NULL /* or, use back_channel_send_manager thread pool? */,
	    gfs_client_status_callout, host);
	gfs_client_status_schedule(host, 1);
	gflog_info(GFARM_MSG_1004035,
	    "back_channel(%s): started", host_name(host));

	return (e2);
}
Beispiel #11
0
static void
gfs_client_status_schedule(struct host *host, int first_attempt)
{
	gfarm_error_t e;
	struct gfs_client_status_entry *qe;
	enum { stop_callout, do_next, do_retry } callout_next = do_next;
	const char diag[] = "GFS_PROTO_STATUS";

	GFARM_MALLOC(qe);
	if (qe == NULL) {
		callout_next = do_retry;
		gflog_error(GFARM_MSG_1004026,
		    "%s: %s: no memory for queue entry",
		    host_name(host), diag);
	} else {
		netsendq_entry_init(&qe->qentry, &gfs_proto_status_queue);
		qe->qentry.abhost = host_to_abstract_host(host);
		e = netsendq_add_entry(host_sendq(host), &qe->qentry,
		    NETSENDQ_ADD_FLAG_DETACH_ERROR_HANDLING);
		if (e == GFARM_ERR_NO_ERROR) {
			/* OK */
		} else if (first_attempt && e == GFARM_ERR_DEVICE_BUSY) {
			/*
			 * if this is first attempt just after
			 * the back channel connection is made,
			 * it's possible previous callout remains
			 * with the following scenario:
			 * 1. gfs_client_status_callout() thread begins to run
			 * 2. host_unset_peer() calls callout_stop()
			 * 3. netsendq_host_becomes_down() clears readyq
			 * 4. the gfs_client_status_callout() thread in 1
			 *    adds an entry to workq and readyq
			 */
			gflog_info(GFARM_MSG_1004027,
			    "%s: %s queueing conflict", host_name(host), diag);
		} else {
			/* increment refcount */
			struct peer *peer = host_get_peer(host);

			callout_next = stop_callout;
			gflog_info(GFARM_MSG_1004028,
			    "%s: %s queueing: %s",
			    host_name(host), diag, gfarm_error_string(e));
			/* `qe' is be freed by gfs_client_status_finalize() */
			if (peer == NULL) {
				gflog_info(GFARM_MSG_1004029,
				    "%s: %s: already disconnected",
				    host_name(host), diag);
			} else {
				gfs_client_status_disconnect_or_message(host,
				    peer, diag, "queueing",
				    gfarm_error_string(e));
				 /* decrement refcount */
				host_put_peer(host, peer);
			}
		}
	}
	switch (callout_next) {
	case stop_callout:
		/* do nothing */
		break;
	case do_next:
		callout_schedule(host_status_callout(host),
		    gfarm_metadb_heartbeat_interval * 1000000);
		break;
	case do_retry:
		callout_schedule(host_status_callout(host),
		    gfarm_metadb_heartbeat_interval * 1000000 / 10);
		break;
	}
}
Beispiel #12
0
char *
gfarm_gsi_cred_config_convert_to_name(
	enum gfarm_auth_cred_type type, char *service, char *name,
	char *hostname,
	gss_name_t *namep)
{
	int rv;
	OM_uint32 e_major;
	OM_uint32 e_minor;
	gss_cred_id_t cred;

	switch (type) {
	case GFARM_AUTH_CRED_TYPE_DEFAULT:
		/* special. equivalent to GSS_C_NO_CREDENTIAL */
		if (name != NULL)
			return ("cred_type is not set, but cred_name is set");
		if (service != NULL)
			return ("cred_type is not set, but cred_service is set"
			    );
		return ("internal error: missing GSS_C_NO_CREDENTIAL check");
	case GFARM_AUTH_CRED_TYPE_NO_NAME:
		if (name != NULL)
			return ("cred_type is \"no-name\", "
			    "but cred_name is set");
		if (service != NULL)
			return ("cred_type is \"no-name\", "
			    "but cred_service is set");
		*namep = GSS_C_NO_NAME;
		return (NULL);
	case GFARM_AUTH_CRED_TYPE_MECHANISM_SPECIFIC:
		if (name == NULL)
			return ("cred_type is \"mechanism-specific\", "
			    "but cred_name is not set");
		if (service != NULL)
			return ("cred_type is \"mechanism-specific\", "
			    "but cred_service is set");
		rv = gfarmGssImportName(namep, name, strlen(name),
		    GSS_C_NO_OID, &e_major, &e_minor);
		break;
	case GFARM_AUTH_CRED_TYPE_HOST:
		if (name == NULL)
			name = hostname;
		if (service == NULL) {
			rv = gfarmGssImportNameOfHost(namep, name,
			    &e_major, &e_minor);
		} else {
			rv = gfarmGssImportNameOfHostBasedService(namep,
			    service, name, &e_major, &e_minor);
		}
		break;
	case GFARM_AUTH_CRED_TYPE_USER:
		if (service != NULL)
			return ("cred_type is \"user\", "
			    "but cred_service is set");
		/*
		 * XXX FIXME: `name' must be converted from global_username
		 * to local_username, but there is no such function for now.
		 */
		if (name == NULL)
			name = gfarm_get_local_username();
		rv = gfarmGssImportName(namep, name, strlen(name),
		    GSS_C_NT_USER_NAME, &e_major, &e_minor);
		break;
	case GFARM_AUTH_CRED_TYPE_SELF:
		/* special. there is no corresponding name_type in GSSAPI */
		if (name != NULL)
			return ("cred_type is \"self\", but cred_name is set");
		if (service != NULL)
			return ("cred_type is \"self\", "
			    "but cred_service is set");
		if (gfarmSecSessionGetInitiatorInitialCredential(&cred) < 0 ||
		    cred == GSS_C_NO_CREDENTIAL)
			return ("cred_type is \"self\", "
			    "but not initialized as an initiator");
		rv = gfarmGssNewCredentialName(namep, cred, &e_major,&e_minor);
		break;
	default:
		return ("internal error - invalid cred_type");
	}
	if (rv < 0) {
		if (gflog_auth_get_verbose()) {
			gflog_error("gfarmGssImportName(): "
			    "invalid credential configuration:");
			gfarmGssPrintMajorStatus(e_major);
			gfarmGssPrintMinorStatus(e_minor);
		}
		return ("invalid credential configuration");
	}
	return (NULL);
}