char * gfarm_auth_shared_key_get(unsigned int *expirep, char *shared_key, char *home, int create, int period) { FILE *fp; static char keyfile_basename[] = "/" GFARM_AUTH_SHARED_KEY_BASENAME; char *keyfilename; unsigned int expire; keyfilename = malloc(strlen(home) + sizeof(keyfile_basename)); if (keyfilename == NULL) return (GFARM_ERR_NO_MEMORY); strcpy(keyfilename, home); strcat(keyfilename, keyfile_basename); if ((fp = fopen(keyfilename, "r+")) != NULL) { if (skip_space(fp) || read_hex(fp, &expire, sizeof(expire))) { fclose(fp); free(keyfilename); return ("~/" GFARM_AUTH_SHARED_KEY_BASENAME ": invalid expire field"); } expire = ntohl(expire); if (skip_space(fp) || read_hex(fp, shared_key, GFARM_AUTH_SHARED_KEY_LEN)) { fclose(fp); free(keyfilename); return ("~/" GFARM_AUTH_SHARED_KEY_BASENAME ": invalid key field"); } } if (fp == NULL) { if (create == GFARM_AUTH_SHARED_KEY_GET) { free(keyfilename); return ("~/" GFARM_AUTH_SHARED_KEY_BASENAME ": not exist"); } fp = fopen(keyfilename, "w+"); if (fp == NULL) { free(keyfilename); return (gfarm_errno_to_error(errno)); } if (chmod(keyfilename, 0600) == -1) { fclose(fp); free(keyfilename); return (gfarm_errno_to_error(errno)); } expire = 0; /* force to regenerate key */ } if (create == GFARM_AUTH_SHARED_KEY_CREATE_FORCE || time(NULL) >= expire) { if (create == GFARM_AUTH_SHARED_KEY_GET) { fclose(fp); free(keyfilename); return (GFARM_ERR_EXPIRED); } if (fseek(fp, 0L, SEEK_SET) == -1) { fclose(fp); free(keyfilename); return (gfarm_errno_to_error(errno)); } gfarm_auth_random(shared_key, GFARM_AUTH_SHARED_KEY_LEN); if (period <= 0) period = GFARM_AUTH_EXPIRE_DEFAULT; expire = time(NULL) + period; expire = htonl(expire); write_hex(fp, &expire, sizeof(expire)); expire = ntohl(expire); fputc(' ', fp); write_hex(fp, shared_key, GFARM_AUTH_SHARED_KEY_LEN); fputc('\n', fp); } fclose(fp); free(keyfilename); *expirep = expire; return (NULL); }
/* * We switch the user's privilege to read ~/.gfarm_shared_key. * * NOTE: reading this file with root privilege may not work, * if home directory is NFS mounted and root access for * the home directory partition is not permitted. * * Do not leave the user privilege switched here, even in the switch_to case, * because it is necessary to switch back to the original user privilege when * gfarm_auth_sharedsecret fails. */ gfarm_error_t gfarm_auth_shared_key_get(unsigned int *expirep, char *shared_key, char *home, struct passwd *pwd, int create, int period) { gfarm_error_t e; FILE *fp; static char keyfile_basename[] = "/" GFARM_AUTH_SHARED_KEY_BASENAME; char *keyfilename; unsigned int expire; static pthread_mutex_t privilege_mutex = PTHREAD_MUTEX_INITIALIZER; uid_t o_uid; gid_t o_gid; #ifdef __GNUC__ /* workaround gcc warning: might be used uninitialized */ o_uid = o_gid = 0; #endif GFARM_MALLOC_ARRAY(keyfilename, strlen(home) + sizeof(keyfile_basename)); if (keyfilename == NULL) return (GFARM_ERR_NO_MEMORY); strcpy(keyfilename, home); strcat(keyfilename, keyfile_basename); if (pwd != NULL) { pthread_mutex_lock(&privilege_mutex); o_gid = getegid(); o_uid = geteuid(); seteuid(0); /* recover root privilege */ initgroups(pwd->pw_name, pwd->pw_gid); setegid(pwd->pw_gid); seteuid(pwd->pw_uid); } if ((fp = fopen(keyfilename, "r+")) != NULL) { if (skip_space(fp) || read_hex(fp, &expire, sizeof(expire))) { fclose(fp); free(keyfilename); e = GFARM_ERRMSG_SHAREDSECRET_INVALID_EXPIRE_FIELD; goto finish; } expire = ntohl(expire); if (skip_space(fp) || read_hex(fp, shared_key, GFARM_AUTH_SHARED_KEY_LEN)) { fclose(fp); free(keyfilename); e = GFARM_ERRMSG_SHAREDSECRET_INVALID_KEY_FIELD; goto finish; } } if (fp == NULL) { if (create == GFARM_AUTH_SHARED_KEY_GET) { free(keyfilename); e = GFARM_ERRMSG_SHAREDSECRET_KEY_FILE_NOT_EXIST; goto finish; } fp = fopen(keyfilename, "w+"); if (fp == NULL) { e = gfarm_errno_to_error(errno); free(keyfilename); goto finish; } if (chmod(keyfilename, 0600) == -1) { e = gfarm_errno_to_error(errno); fclose(fp); free(keyfilename); goto finish; } expire = 0; /* force to regenerate key */ } if (create == GFARM_AUTH_SHARED_KEY_CREATE_FORCE || time(NULL) >= expire) { if (create == GFARM_AUTH_SHARED_KEY_GET) { fclose(fp); free(keyfilename); e = GFARM_ERR_EXPIRED; goto finish; } if (fseek(fp, 0L, SEEK_SET) == -1) { e = gfarm_errno_to_error(errno); fclose(fp); free(keyfilename); goto finish; } gfarm_auth_random(shared_key, GFARM_AUTH_SHARED_KEY_LEN); if (period <= 0) period = GFARM_AUTH_EXPIRE_DEFAULT; expire = time(NULL) + period; expire = htonl(expire); write_hex(fp, &expire, sizeof(expire)); expire = ntohl(expire); fputc(' ', fp); write_hex(fp, shared_key, GFARM_AUTH_SHARED_KEY_LEN); fputc('\n', fp); } fclose(fp); free(keyfilename); *expirep = expire; e = GFARM_ERR_NO_ERROR; finish: if (pwd != NULL) { seteuid(0); /* recover root privilege */ setgroups(1, &o_gid); /* abandon group privileges */ setegid(o_gid); seteuid(o_uid); /* suppress root privilege, if possible */ pthread_mutex_unlock(&privilege_mutex); } return (e); }
/* * 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_initialize(int *argcp, char ***argvp) { gfarm_error_t e; enum gfarm_auth_method auth_method; #ifdef HAVE_GSI int saved_auth_verb; #endif e = gfarm_set_local_user_for_this_local_account(); if (e != GFARM_ERR_NO_ERROR) return (e); e = gfarm_config_read(); if (e != GFARM_ERR_NO_ERROR) return (e); #ifdef HAVE_GSI /* * Suppress verbose error messages. The message will be * displayed later in gfarm_auth_request_gsi(). */ saved_auth_verb = gflog_auth_set_verbose(0); (void)gfarm_gsi_client_initialize(); (void)gflog_auth_set_verbose(saved_auth_verb); #endif /* * In sharedsecret authentication, a global user name is * required to be set to access a metadata server. */ e = gfarm_set_global_user_for_sharedsecret(); if (e != GFARM_ERR_NO_ERROR) return (e); /* * XXX FIXME this shouldn't be necessary here * to support multiple metadata server */ e = gfm_client_connection_acquire(gfarm_metadb_server_name, gfarm_metadb_server_port, &gfarm_metadb_server); if (e != GFARM_ERR_NO_ERROR) { fprintf(stderr, "connecting gfmd: %s\n", gfarm_error_string(e)); exit(1); } gfarm_metadb_set_server(gfarm_metadb_server); /* metadb access is required to obtain a global user name by GSI */ auth_method = gfm_client_connection_auth_method(gfarm_metadb_server); if (GFARM_IS_AUTH_GSI(auth_method)) { e = gfarm_set_global_user_by_gsi(); if (e != GFARM_ERR_NO_ERROR) return (e); } if (argvp != NULL) { #if 0 /* not yet in gfarm v2 */ if (getenv("DISPLAY") != NULL) gfarm_debug_initialize((*argvp)[0]); e = gfarm_parse_argv(argcp, argvp); if (e != GFARM_ERR_NO_ERROR) return (e); #endif /* not yet in gfarm v2 */ } gfarm_auth_random(gfarm_client_pid_key, gfarm_client_pid_key_len); e = gfm_client_process_alloc(gfarm_metadb_server, gfarm_client_pid_key_type, gfarm_client_pid_key, gfarm_client_pid_key_len, &gfarm_client_pid); if (e != GFARM_ERR_NO_ERROR) gflog_fatal("failed to allocate gfarm PID: %s", gfarm_error_string(e)); #if 0 /* not yet in gfarm v2 */ gfarm_initialized = 1; #endif /* not yet in gfarm v2 */ return (GFARM_ERR_NO_ERROR); }