/* * 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); }
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)); }
/* 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); } } }
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); }
/* 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); }
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); }
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); }
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)); }
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); }
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); }
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; } }
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); }