Exemplo n.º 1
0
static gfarm_error_t
create_hostlist_by_domain_and_hash(struct file_info *finfo, char *domain,
	struct gfarm_hash_table *hosthash,
	int *nhostsp, char ***hostsp, int **portsp)
{
	int ninfo, i, j, *ports, nhosts;
	struct gfarm_host_sched_info *infos;
	char **hosts;
	gfarm_error_t e;

	e = schedule_host_domain(finfo->pathname, domain, &ninfo, &infos);
	if (e != GFARM_ERR_NO_ERROR)
		return (e);
	/* sort 'infos' in descending order wrt available capacity */
	qsort(infos, ninfo, sizeof(*infos), compare_available_capacity_r);

	/* eliminate file system nodes that do not have enough space */
	for (i = 0; i < ninfo; ++i)
		/* note that disk_avail is the number of 1K blocks */
		if (infos[i].disk_avail * 1024
		    < gfarm_get_minimum_free_disk_space())
			break;
	nhosts = i;

	/* XXX - abandon CPU load and available capacity */
	GFARM_MALLOC_ARRAY(hosts, nhosts);
	if (hosts == NULL) {
		gfarm_host_sched_info_free(ninfo, infos);
		return (GFARM_ERR_NO_MEMORY);
	}
	GFARM_MALLOC_ARRAY(ports, nhosts);
	if (ports == NULL) {
		free(hosts);
		gfarm_host_sched_info_free(ninfo, infos);
		return (GFARM_ERR_NO_MEMORY);
	}
	for (i = 0, j = 0; i < nhosts; ++i) {
		char *host = infos[i].host;

		if (hosthash == NULL ||
		    gfarm_hash_lookup(hosthash, host, strlen(host) + 1)) {
			hosts[j] = strdup(host);
			ports[j] = infos[i].port;
			if (hosts[j] == NULL) {
				gfarm_strings_free_deeply(j, hosts);
				return (GFARM_ERR_NO_MEMORY);
			}
			++j;
		}
	}
	gfarm_host_sched_info_free(ninfo, infos);
	*hostsp = hosts;
	*portsp = ports;
	*nhostsp = j;

	return (e);
}
Exemplo n.º 2
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);
}
Exemplo n.º 3
0
Arquivo: gsi.c Projeto: ddk50/gfarm_v2
int
gfarmGssImportNameOfHostBasedService(gss_name_t *namePtr, char *service,
    char *hostname, OM_uint32 *majStatPtr, OM_uint32 *minStatPtr)
{
    OM_uint32 majStat;
    OM_uint32 minStat;
    int ret = -1;
    size_t nameLength = strlen(service) + 1 + strlen(hostname);
    char *nameString;

    GFARM_MALLOC_ARRAY(nameString, nameLength + 1);
    if (nameString == NULL) {
	gflog_auth_error(GFARM_MSG_1000613,
	    "gfarmGssImportNameOfHostBasedService(): "
			 "no memory");
	majStat = GSS_S_FAILURE;
	minStat = GFSL_DEFAULT_MINOR_ERROR;
    } else {
	sprintf(nameString, "%s@%s", service, hostname);
	if (gfarmGssImportName(namePtr, nameString, nameLength,
			       GSS_C_NT_HOSTBASED_SERVICE,
			       &majStat, &minStat) > 0) {
	    ret = 1;
	}
	free(nameString);
    }
    if (majStatPtr != NULL) {
	*majStatPtr = majStat;
    }
    if (minStatPtr != NULL) {
	*minStatPtr = minStat;
    }
    return ret;
}
Exemplo n.º 4
0
struct gfarm_iobuffer *
gfarm_iobuffer_alloc(int bufsize)
{
	struct gfarm_iobuffer *b;

	GFARM_MALLOC(b);
	if (b == NULL)
		return (NULL);
	GFARM_MALLOC_ARRAY(b->buffer, bufsize);
	if (b->buffer == NULL) {
		free(b);
		return (NULL);
	}
	b->bufsize = bufsize;
	b->head = b->tail = 0;

	b->read_func = NULL;
	b->read_cookie = NULL;
	b->read_fd = -1;

	b->write_func = NULL;
	b->write_cookie = NULL;
	b->write_fd = -1;

	b->write_close_func = gfarm_iobuffer_write_close_nop;

	b->read_eof = 0;
	b->write_eof = 0;
	b->error = 0;

	return (b);
}
Exemplo n.º 5
0
Arquivo: gsi.c Projeto: ddk50/gfarm_v2
int
gfarmGssReceiveToken(int fd, gss_buffer_t gsBuf, int timeoutMsec)
{
    gfarm_int32_t iLen;
    gfarm_int8_t *buf;

    gsBuf->length = 0;
    gsBuf->value = NULL;

    if (gfarmReadInt32(fd, &iLen, 1, timeoutMsec) != 1) {
	gflog_debug(GFARM_MSG_1000794, "gfarmReadInt32() failed");
	return -1;
    }

    /*
     * XXXXX FIXME:
     * 	GSSAPI has no API for allocating a gss_buffer_t. It is not
     *	recommended to allocate it with malloc().
     */
    GFARM_MALLOC_ARRAY(buf, iLen);
    if (buf == NULL) {
	gflog_debug(GFARM_MSG_1000795, "allocation of buffer failed");
	return -1;
    }
    if (gfarmReadInt8(fd, buf, iLen, timeoutMsec) != iLen) {
	free(buf);
	gflog_debug(GFARM_MSG_1000796, "gfarmReadInt8() failed");
	return -1;
    }

    gsBuf->length = iLen;
    gsBuf->value = buf;
    return iLen;
}
Exemplo n.º 6
0
Arquivo: gsi.c Projeto: ddk50/gfarm_v2
int
gfarmGssImportName(gss_name_t *namePtr, void *nameValue, size_t nameLength,
    gss_OID nameType, OM_uint32 *majStatPtr, OM_uint32 *minStatPtr)
{
    OM_uint32 majStat = 0;
    OM_uint32 minStat = 0;
    int ret = -1;
    gss_buffer_desc buf;

#if GFARM_FAKE_GSS_C_NT_USER_NAME_FOR_GLOBUS
    if (nameType == GSS_C_NT_USER_NAME) {
	char *user;
	gfarmAuthEntry *aePtr;

	GFARM_MALLOC_ARRAY(user, nameLength + 1);
	if (user == NULL) {
	    gflog_auth_error(GFARM_MSG_1000611,
		"gfarmGssImportName(): no memory");
	    majStat = GSS_S_FAILURE;
	    minStat = GFSL_DEFAULT_MINOR_ERROR;
	    goto Done;
	}
	memcpy(user, nameValue, nameLength);
	user[nameLength] = '\0';
	aePtr = gfarmAuthGetLocalUserEntry(user);
	if (aePtr == NULL) {
	    gflog_auth_error(GFARM_MSG_1000612, "%s: ERROR: cannot convert "
			     "this user name to X.509 Distinguish name", user);
	    free(user);
	    majStat = GSS_S_FAILURE;
	    minStat = GFSL_DEFAULT_MINOR_ERROR;
	    goto Done;
	}
	free(user);
	assert(aePtr->authType == GFARM_AUTH_USER);
	nameValue = aePtr->distName;
	nameLength = strlen(aePtr->distName);
	nameType = GSS_C_NO_OID; /* mechanism specific */
    }
#endif /* GFARM_FAKE_GSS_C_NT_USER_NAME_FOR_GLOBUS */
    buf.length = nameLength;
    buf.value = nameValue;
    majStat = gss_import_name(&minStat, &buf, nameType, namePtr);
    if (majStat == GSS_S_COMPLETE) {
	ret = 1; /* OK */
    }

#if GFARM_FAKE_GSS_C_NT_USER_NAME_FOR_GLOBUS
    Done:
#endif /* GFARM_FAKE_GSS_C_NT_USER_NAME_FOR_GLOBUS */
    if (majStatPtr != NULL) {
	*majStatPtr = majStat;
    }
    if (minStatPtr != NULL) {
	*minStatPtr = minStat;
    }
    return ret;
}
Exemplo n.º 7
0
static int
unlink_dir(const char *src)
{
	struct stat sb;

	if (lstat(src, &sb)) {
		perror(src);
		return (1);
	}
	if (S_ISDIR(sb.st_mode)) {
		DIR *dirp;
		struct dirent *dp;

		/* allow read and write access always */
		chmod(src, (sb.st_mode | S_IRUSR | S_IWUSR) & 07777);

		dirp = opendir(src);
		if (dirp == NULL) {
			perror(src);
			return (1);
		}
		while ((dp = readdir(dirp)) != NULL) {
			char *f;

			if (strcmp(dp->d_name, ".") == 0
			    || strcmp(dp->d_name, "..") == 0 || dp->d_ino == 0)
				continue;

			GFARM_MALLOC_ARRAY(f, 
				strlen(src) + 1 + strlen(dp->d_name) + 1);
			if (f == NULL) {
				print_errmsg(dp->d_name, NULL,
					"not enough memory");
				return (1);
			}
			strcpy(f, src);
			strcat(f, "/");
			strcat(f, dp->d_name);

			(void)unlink_dir(f);

			free(f);
		}
		closedir(dirp);
		if (rmdir(src)) {
			perror(src);
			return (1);
		}
	}
	else if (unlink(src)) {
		/* if 'src' is not a directory, try to unlink. */
		perror(src);
		return (1);
	}
	return (0);
}
Exemplo n.º 8
0
gfarm_error_t
gfs_opendir_caching_internal(const char *path, GFS_Dir *dirp)
{
	gfarm_error_t e;
	GFS_DirPlus dp;
	struct gfs_dir_caching *dir;
	char *p;
	static struct gfs_dir_ops ops = {
		gfs_closedir_caching_internal,
		gfs_readdir_caching_internal,
		gfs_seekdir_unimpl,
		gfs_telldir_unimpl
	};

	if ((e = gfs_opendirplus(path, &dp)) != GFARM_ERR_NO_ERROR)
		return (e);

	GFARM_MALLOC(dir);
	if (*gfarm_path_dir_skip(path) != '\0') {
		GFARM_MALLOC_ARRAY(p, strlen(path) + 1 + 1);
		if (p != NULL)
			sprintf(p, "%s/", path);
	} else {
		GFARM_MALLOC_ARRAY(p, strlen(path) + 1);
		if (p != NULL)
			strcpy(p, path);
	}

	if (dir == NULL || p == NULL) {
		gfs_closedirplus(dp);
		if (dir != NULL)
			free(dir);
		if (p != NULL)
			free(p);
		return (GFARM_ERR_NO_MEMORY);
	}

	dir->super.ops = &ops;
	dir->dp = dp;
	dir->path = p;
	*dirp = &dir->super;
	return (GFARM_ERR_NO_ERROR);
}
Exemplo n.º 9
0
gfarm_error_t
list(int op, int n, char *names[])
{
	struct gfarm_group_info *groups;
	gfarm_error_t e, *errs;

	GFARM_MALLOC_ARRAY(groups, n);
	GFARM_MALLOC_ARRAY(errs, n);
	if (groups == NULL || errs == NULL) {
		e = GFARM_ERR_NO_MEMORY;
	} else if ((e = gfm_client_group_info_get_by_names(
	    gfm_server, n, (const char **)names, errs, groups)) !=
	    GFARM_ERR_NO_ERROR) {
		/* nothing to do */
	} else {
		e = display_group(op, n, names, errs, groups);
	}
	free(groups);
	free(errs);
	return (e);
}
Exemplo n.º 10
0
static gfarm_error_t
gfs_readdir_caching_internal(GFS_Dir super, struct gfs_dirent **entryp)
{
	struct gfs_dir_caching *dir = (struct gfs_dir_caching *)super;
	struct gfs_dirent *ep;
	struct gfs_stat *stp;
	char *path;
	gfarm_error_t e = gfs_readdirplus(dir->dp, &ep, &stp);

	if (e != GFARM_ERR_NO_ERROR)
		return (e);

	if (ep != NULL) { /* i.e. not EOF */
		GFARM_MALLOC_ARRAY(path,
		    strlen(dir->path) + strlen(ep->d_name) + 1);
		if (path == NULL) {
			/*
			 * It's ok to fail in entering the cache,
			 * since it's merely cache.
			 */
			gflog_warning(GFARM_MSG_UNUSED,
			    "dircache: failed to cache %s%s due to no memory",
			    dir->path, ep->d_name);
		} else {
			struct timeval now;

			gettimeofday(&now, NULL);
			sprintf(path, "%s%s", dir->path, ep->d_name);
#ifdef DIRCACHE_DEBUG
			gflog_debug(GFARM_MSG_1000094,
			    "%ld.%06ld: gfs_readdir_caching()->"
			    "\"%s\" (%d)",
			    (long)now.tv_sec, (long)now.tv_usec,
			    path, stat_cache_count);
#endif
			/*
			 * It's ok to fail in entering the cache,
			 * since it's merely cache.
			 */
			if ((e = gfs_stat_cache_enter_internal(path, stp, &now))
			    != GFARM_ERR_NO_ERROR) {
				gflog_warning(GFARM_MSG_UNUSED,
				    "dircache: failed to cache %s: %s",
				    path, gfarm_error_string(e));
			}
			free(path);
		}
	}

	*entryp = ep;
	return (GFARM_ERR_NO_ERROR);
}
Exemplo n.º 11
0
void
job_table_init(int table_size)
{
	int i;

	GFARM_MALLOC_ARRAY(job_table, table_size);
	if (job_table == NULL) {
		errno = ENOMEM; gflog_fatal_errno("job table");
	}
	for (i = 0; i < table_size; i++)
		job_table[i] = NULL;
	job_table_size = table_size;
}
Exemplo n.º 12
0
gfarm_error_t
process_alloc(struct user *user,
	gfarm_int32_t keytype, size_t keylen, char *sharedkey,
	struct process **processp, gfarm_pid_t *pidp)
{
	struct process *process;
	struct file_opening **filetab;
	int fd;
	gfarm_int32_t pid32;

	if (process_id_table == NULL) {
		process_id_table = gfarm_id_table_alloc(&process_id_table_ops);
		if (process_id_table == NULL)
			gflog_fatal("allocating pid table: no memory");
	}

	if (keytype != GFM_PROTO_PROCESS_KEY_TYPE_SHAREDSECRET ||
	    keylen != GFM_PROTO_PROCESS_KEY_LEN_SHAREDSECRET)
		return (GFARM_ERR_INVALID_ARGUMENT);
	GFARM_MALLOC_ARRAY(filetab, FILETAB_INITIAL);
	if (filetab == NULL)
		return (GFARM_ERR_NO_MEMORY);
	process = gfarm_id_alloc(process_id_table, &pid32);
	if (process == NULL) {
		free(filetab);
		return (GFARM_ERR_NO_MEMORY);
	}
	process->siblings.next = process->siblings.prev = &process->siblings;
	process->children.next = process->children.prev = &process->children;
	process->parent = NULL;
	memcpy(process->sharedkey, sharedkey, keylen);
	process->pid = pid32;
	process->user = user;
	process->refcount = 0;
	process->nfiles = FILETAB_INITIAL;
	process->filetab = filetab;
	for (fd = 0; fd < FILETAB_INITIAL; fd++)
		filetab[fd] = NULL;

	*processp = process;
	*pidp = pid32;
	return (GFARM_ERR_NO_ERROR);
}
Exemplo n.º 13
0
Arquivo: gsi.c Projeto: ddk50/gfarm_v2
char *
gfarmGssNewDisplayName(const gss_name_t inputName, OM_uint32 *majStatPtr,
    OM_uint32 *minStatPtr, gss_OID *outputNameTypePtr)
{
    OM_uint32 majStat;
    OM_uint32 minStat, minStat2;
    char *ret = NULL;
    gss_buffer_desc buf;
    gss_OID outputNameType;

    if (inputName == GSS_C_NO_NAME) {
	gflog_auth_error(GFARM_MSG_1000614,
	    "gfarmGssNewDisplayName(): GSS_C_NO_NAME is passed");
	majStat = GSS_S_FAILURE;
	minStat = GFSL_DEFAULT_MINOR_ERROR;
    } else if ((majStat = gss_display_name(&minStat, inputName,
					   &buf, &outputNameType))
	       == GSS_S_COMPLETE) {
	GFARM_MALLOC_ARRAY(ret, buf.length + 1);
	if (ret == NULL) {
	    gflog_auth_error(GFARM_MSG_1000615,
		"gfarmGssNewDisplayName(): no memory");
	    majStat = GSS_S_FAILURE;
	    minStat = GFSL_DEFAULT_MINOR_ERROR;
	} else {
	    ret[buf.length] = '\0';
	    memcpy(ret, buf.value, buf.length);
	    gss_release_buffer(&minStat2, &buf);
	    if (outputNameTypePtr != NULL) {
		*outputNameTypePtr = outputNameType;
	    }
	}
    }
    if (majStatPtr != NULL) {
	*majStatPtr = majStat;
    }
    if (minStatPtr != NULL) {
	*minStatPtr = minStat;
    }
    return ret;
}
Exemplo n.º 14
0
static char *
append_prefix_pathname(const char *prefix, const char *path)
{
	char *url;

	GFARM_MALLOC_ARRAY(url, strlen(prefix) + strlen(path) + 2);
	if (url == NULL)
		return (url);

	strcpy(url, prefix);
	switch (url[strlen(url) - 1]) {
	case '/':
	case ':':
		break;
	default:
		strcat(url, "/");
	}
	strcat(url, path);

	return (url);
}
Exemplo n.º 15
0
static gfarm_error_t
gfarm_list_add_file_info(char *pathname, gfarm_off_t filesize,
	int ncopy, char **copy, int surplus, gfarm_list *list)
{
	struct file_info *info;
	gfarm_error_t e;
	int i;

	info = file_info_alloc();
	if (info == NULL)
		return (GFARM_ERR_NO_MEMORY);

	info->pathname = strdup(pathname);
	if (info->pathname == NULL) {
		file_info_free(info);
		return (GFARM_ERR_NO_MEMORY);
	}
	GFARM_MALLOC_ARRAY(info->copy, ncopy);
	if (info->copy == NULL) {
		file_info_free(info);
		return (GFARM_ERR_NO_MEMORY);
	}
	for (i = 0; i < ncopy; ++i) {
		info->copy[i] = strdup(copy[i]);
		if (info->copy[i] == NULL) {
			gfarm_strings_free_deeply(i, info->copy);
			info->copy = NULL;
			file_info_free(info);
			return (GFARM_ERR_NO_ERROR);
		}
	}
	info->ncopy = ncopy;
	info->filesize = filesize;
	info->surplus_ncopy = surplus;
	e = gfarm_list_add(list, info);
	if (e != GFARM_ERR_NO_ERROR)
		file_info_free(info);
	return (e);
}
Exemplo n.º 16
0
gfarm_error_t
gfarm_paraccess_alloc(
	int concurrency, int try_auth,
	struct gfarm_paraccess **pap)
{
	int syserr;
	struct gfarm_paraccess *pa;
	int i;

	GFARM_MALLOC(pa);
	if (pa == NULL)
		return (GFARM_ERR_NO_MEMORY);

	syserr = gfarm_eventqueue_alloc(concurrency, &pa->q);
	if (syserr !=0) {
		free(pa);
		return (gfarm_errno_to_error(syserr));
	}

	GFARM_MALLOC_ARRAY(pa->access_state, concurrency);
	if (pa->access_state == NULL) {
		gfarm_eventqueue_free(pa->q);
		free(pa);
		return (GFARM_ERR_NO_MEMORY);
        }

	/* construct free slot list */
	i = concurrency - 1;
	pa->access_state[i].next = NULL;
	while (--i >= 0)
		pa->access_state[i].next = &pa->access_state[i + 1];
	pa->free_list = &pa->access_state[0];
	pa->concurrency = pa->nfree = concurrency;

	pa->try_auth = try_auth;
	*pap = pa;
	return (GFARM_ERR_NO_ERROR);
}
Exemplo n.º 17
0
Arquivo: job.c Projeto: ddk50/gfarm_v2
gfarm_error_t
gfj_server_register(struct peer *peer, gfp_xdr_xid_t xid, size_t *sizep,
	int from_client, int skip)
{
	gfarm_error_t e;
	struct gfp_xdr *client = peer_get_conn(peer);
	char *user = peer_get_username(peer);
	int i, eof;
	gfarm_int32_t flags, total_nodes, argc, error, job_id = 0;
	struct gfarm_job_info *info;
	static const char diag[] = "GFJ_PROTO_REGISTER";

	GFARM_MALLOC(info);
	if (info == NULL) {
		gflog_debug(GFARM_MSG_1001685,
			"allocation of gfarm_job_info failed");
		return (GFARM_ERR_NO_MEMORY);
	}
	gfarm_job_info_clear(info, 1);
	e = gfj_server_get_request(peer, sizep, diag, "iisssi",
				   &flags,
				   &total_nodes,
				   &info->job_type,
				   &info->originate_host,
				   &info->gfarm_url_for_scheduling,
				   &argc);
	if (e != GFARM_ERR_NO_ERROR) {
		gflog_debug(GFARM_MSG_1001686,
			"gfj_server_get_request() failed");
		return (e);
	}

	/* XXX - currently `flags' is just igored */
	info->total_nodes = total_nodes;
	info->argc = argc;
	GFARM_MALLOC_ARRAY(info->argv, argc + 1);
	GFARM_MALLOC_ARRAY(info->nodes, total_nodes);
	if (info->argv == NULL || info->nodes == NULL) {
		gflog_debug(GFARM_MSG_1001687,
			"allocation of 'info->argv' or 'info->nodes' failed ");
		free(info->job_type);
		free(info->originate_host);
		free(info->gfarm_url_for_scheduling);
		if (info->argv != NULL)
			free(info->argv);
		if (info->nodes != NULL)
			free(info->nodes);
		free(info);
		return (GFARM_ERR_NO_MEMORY);
	}
	for (i = 0; i < argc; i++) {
		e = gfp_xdr_recv(client, 0, &eof, "s", &info->argv[i]);
		if (e != GFARM_ERR_NO_ERROR || eof) {
			gflog_debug(GFARM_MSG_1001688,
				"gfp_xdr_recv(info->argv[i]) failed");
			if (e == GFARM_ERR_NO_ERROR)
				e = GFARM_ERR_PROTOCOL;
			while (--i >= 0)
				free(info->argv[i]);
			free(info->job_type);
			free(info->originate_host);
			free(info->gfarm_url_for_scheduling);
			free(info->argv);
			free(info->nodes);
			return (e);
		}
	}
	info->argv[i] = NULL;
	info->user = user; /* shared with file_table[].user */
	for (i = 0; i < total_nodes; i++) {
		e = gfp_xdr_recv(client, 0, &eof, "s",
				   &info->nodes[i].hostname);
		if (e != GFARM_ERR_NO_ERROR || eof) {
			gflog_debug(GFARM_MSG_1001689,
				"gfp_xdr_recv(hostname) failed");
			if (e == GFARM_ERR_NO_ERROR)
				e = GFARM_ERR_PROTOCOL;
			while (--i >= 0)
				free(info->nodes[i].hostname);
			for (i = 0; i < argc; i++)
				free(info->argv[i]);
			free(info->job_type);
			free(info->originate_host);
			free(info->gfarm_url_for_scheduling);
			free(info->argv);
			free(info->nodes);
			return (e);
		}
		info->nodes[i].pid = 0;
		info->nodes[i].state = GFJ_NODE_NONE;
	}

	if (skip || !from_client) {
		for (i = 0; i < total_nodes; i++)
			free(info->nodes[i].hostname);
		for (i = 0; i < argc; i++)
			free(info->argv[i]);
		free(info->job_type);
		free(info->originate_host);
		free(info->gfarm_url_for_scheduling);
		free(info->argv);
		free(info->nodes);
		if (skip)
			return (GFARM_ERR_NO_ERROR);
		error = GFARM_ERR_OPERATION_NOT_PERMITTED;
		gflog_debug(GFARM_MSG_1001690,
			"operation is not permitted for from_client");
	} else {
		giant_lock();
		job_id = job_table_add(info, peer_get_jobs_ref(peer));
		giant_unlock();
		if (job_id < JOB_ID_MIN) {
			job_id = 0;
			error = GFARM_ERR_TOO_MANY_JOBS;
			gflog_debug(GFARM_MSG_1001691,
				"too many jobs");
		} else {
			error = GFARM_ERR_NO_ERROR;
		}
	}
	return (gfj_server_put_reply(peer, xid, sizep, diag,
	    error, "i", job_id));
}
Exemplo n.º 18
0
gfarm_error_t
gfj_server_register(struct peer *peer, int from_client, int skip)
{
	gfarm_error_t e;
	struct gfp_xdr *client = peer_get_conn(peer);
	char *user = peer_get_username(peer);
	int i, eof;
	gfarm_int32_t flags, total_nodes, argc, error, job_id = 0;
	struct gfarm_job_info *info;

	GFARM_MALLOC(info);
	if (info == NULL)
		return (GFARM_ERR_NO_MEMORY);
	gfarm_job_info_clear(info, 1);
	e = gfj_server_get_request(peer, "register", "iisssi",
				   &flags,
				   &total_nodes,
				   &info->job_type,
				   &info->originate_host,
				   &info->gfarm_url_for_scheduling,
				   &argc);
	if (e != GFARM_ERR_NO_ERROR)
		return (e);

	/* XXX - currently `flags' is just igored */
	info->total_nodes = total_nodes;
	info->argc = argc;
	GFARM_MALLOC_ARRAY(info->argv, argc + 1);
	GFARM_MALLOC_ARRAY(info->nodes, total_nodes);
	if (info->argv == NULL || info->nodes == NULL) {
		free(info->job_type);
		free(info->originate_host);
		free(info->gfarm_url_for_scheduling);
		if (info->argv != NULL)
			free(info->argv);
		if (info->nodes != NULL)
			free(info->nodes);
		free(info);
		return (GFARM_ERR_NO_MEMORY);
	}
	for (i = 0; i < argc; i++) {
		e = gfp_xdr_recv(client, 0, &eof, "s", &info->argv[i]);
		if (e != GFARM_ERR_NO_ERROR || eof) {
			if (e == GFARM_ERR_NO_ERROR)
				e = GFARM_ERR_PROTOCOL;
			while (--i >= 0)
				free(info->argv[i]);
			free(info->job_type);
			free(info->originate_host);
			free(info->gfarm_url_for_scheduling);
			free(info->argv);
			free(info->nodes);
			return (e);
		}
	}
	info->argv[i] = NULL;
	info->user = user; /* shared with file_table[].user */
	for (i = 0; i < total_nodes; i++) {
		e = gfp_xdr_recv(client, 0, &eof, "s",
				   &info->nodes[i].hostname);
		if (e != GFARM_ERR_NO_ERROR || eof) {
			if (e == GFARM_ERR_NO_ERROR)
				e = GFARM_ERR_PROTOCOL;
			while (--i >= 0)
				free(info->nodes[i].hostname);
			for (i = 0; i < argc; i++)
				free(info->argv[i]);
			free(info->job_type);
			free(info->originate_host);
			free(info->gfarm_url_for_scheduling);
			free(info->argv);
			free(info->nodes);
			return (e);
		}
		info->nodes[i].pid = 0;
		info->nodes[i].state = GFJ_NODE_NONE;
	}

	if (skip || !from_client) {
		for (i = 0; i < total_nodes; i++)
			free(info->nodes[i].hostname);
		for (i = 0; i < argc; i++)
			free(info->argv[i]);
		free(info->job_type);
		free(info->originate_host);
		free(info->gfarm_url_for_scheduling);
		free(info->argv);
		free(info->nodes);
		if (skip)
			return (GFARM_ERR_NO_ERROR);
		error = GFARM_ERR_OPERATION_NOT_PERMITTED;
	} else {
		giant_lock();
		job_id = job_table_add(info, peer_get_jobs_ref(peer));
		giant_unlock();
		if (job_id < JOB_ID_MIN) {
			job_id = 0;
			error = GFARM_ERR_TOO_MANY_JOBS;
		} else {
			error = GFARM_ERR_NO_ERROR;
		}
	}
	return (gfj_server_put_reply(peer, "register",
	    error, "i", job_id));
}
Exemplo n.º 19
0
int
main(int argc, char **argv)
{
	gfarm_error_t e;
	char *opt_domain = "";
	char *opt_mount_point = NULL;
	char *opt_file = NULL;
	int opt_metadata_only = 0;
	int opt_long_format = 0;
	int opt_nhosts = 0;
	int opt_write_mode = 0;
	int opt_create_mode = 0;
	int c, i, available_nhosts, nhosts, *ports;
	struct gfarm_host_sched_info *available_hosts;
	char *path, **hosts, *realpath = NULL;

	if (argc >= 1)
		program_name = basename(argv[0]);

	e = gfarm_initialize(&argc, &argv);
	if (e != GFARM_ERR_NO_ERROR) {
		fprintf(stderr, "%s: %s\n", program_name,
		    gfarm_error_string(e));
		exit(1);
	}

	while ((c = getopt(argc, argv, "D:LMP:cf:ln:w")) != -1) {
		switch (c) {
		case 'D':
			opt_domain = optarg;
			break;
		case 'L':
			gfarm_schedule_search_mode_use_loadavg();
			break;
		case 'M':
			opt_metadata_only = 1;
			break;
		case 'P':
			opt_mount_point = optarg;
			break;
		case 'c':
			opt_create_mode = 1;
			break;
		case 'f':
			opt_file = optarg;
			break;
		case 'l':
			opt_long_format = 1;
			break;
		case 'n':
			opt_nhosts = parse_opt_long(optarg, c, "<nhosts>");
			if (opt_nhosts <= 0) {
				fprintf(stderr, "%s: invalid value: -%c %d\n",
				    program_name, c, opt_nhosts);
				usage();
			}
			break;
		case 'w':
			opt_write_mode = 1;
			break;
		default:
			usage();
		}
	}
	argc -= optind;
	argv += optind;
	if (argc != 0)
		usage();

	if (opt_mount_point != NULL && opt_file != NULL) {
		fprintf(stderr,
		    "%s: -P and -f option cannot be specified at once.\n",
		    program_name);
		usage();
	}

	if (opt_file != NULL) {
		e = gfarm_realpath_by_gfarm2fs(opt_file, &realpath);
		if (e == GFARM_ERR_NO_ERROR)
			path = realpath;
		else
			path = opt_file;
		if (opt_create_mode) {
			GFS_File gf;

			e = gfs_pio_create(path, GFARM_FILE_WRONLY, 0666, &gf);
			if (e != GFARM_ERR_NO_ERROR) {
				fprintf(stderr, "%s: creating \"%s\": %s\n",
				    program_name, path, gfarm_error_string(e));
				exit(1);
			}
			e = gfs_pio_close(gf);
			if (e != GFARM_ERR_NO_ERROR) {
				fprintf(stderr,
				    "%s: gfs_pio_close(\"%s\"): %s\n",
				    program_name, path, gfarm_error_string(e));
				/* exit(1); */
			}
			/* NOTE: this may leave an empty file with ncopy==0 */
		}
		e = gfarm_schedule_hosts_domain_by_file(path,
		    opt_write_mode ? GFARM_FILE_RDWR : GFARM_FILE_RDONLY,
		    opt_domain,
		    &available_nhosts, &available_hosts);
	} else {
		path = opt_mount_point == NULL ? "." : opt_mount_point;
		e = gfarm_realpath_by_gfarm2fs(path, &realpath);
		if (e == GFARM_ERR_NO_ERROR)
			path = realpath;
		e = gfarm_schedule_hosts_domain_all(path, opt_domain,
		    &available_nhosts, &available_hosts);
	}
	if (e != GFARM_ERR_NO_ERROR) {
		fprintf(stderr, "%s: metadata scheduling: %s\n",
		    program_name, gfarm_error_string(e));
		exit(1);
	}

	nhosts = opt_nhosts > 0 ? opt_nhosts : available_nhosts;
	GFARM_MALLOC_ARRAY(hosts, nhosts);
	GFARM_MALLOC_ARRAY(ports, nhosts);
	if (hosts == NULL || ports == NULL) {
		fprintf(stderr, "%s: cannot allocate memory for %d hosts.\n",
		    program_name, nhosts);
		exit(1);
	}

	if (opt_metadata_only) {
		if (nhosts > available_nhosts)
			nhosts = available_nhosts;
		for (i = 0; i < nhosts; i++) {
			hosts[i] = available_hosts[i].host;
			ports[i] = available_hosts[i].port;
		}
	} else if (opt_write_mode) {
		e = gfarm_schedule_hosts_acyclic_to_write(path,
		    available_nhosts, available_hosts,
		    &nhosts, hosts, ports);
	} else {
		e = gfarm_schedule_hosts_acyclic(path,
		    available_nhosts, available_hosts,
		    &nhosts, hosts, ports);
	}
	free(realpath);
	if (e != GFARM_ERR_NO_ERROR) {
		fprintf(stderr, "%s: client side scheduling: %s\n",
		    program_name, gfarm_error_string(e));
		exit(1);
	}

	for (i = 0; i < nhosts; i++) {
		printf("%s", hosts[i]);
		if (opt_long_format)
			printf("\t%d", ports[i]);
		putchar('\n');
	}
	free(hosts);
	free(ports);

	e = gfarm_terminate();
	if (e != GFARM_ERR_NO_ERROR) {
		fprintf(stderr, "%s: %s\n",
		    program_name, gfarm_error_string(e));
		exit(1);
	}

	exit(0);
}
Exemplo n.º 20
0
Arquivo: gsi.c Projeto: ddk50/gfarm_v2
gfarmExportedCredential *
gfarmGssExportCredential(gss_cred_id_t cred, OM_uint32 *statPtr)
{
    gfarmExportedCredential *exportedCred = NULL;
    OM_uint32 majStat = 0;
    OM_uint32 minStat = 0;
    gss_buffer_desc buf = GSS_C_EMPTY_BUFFER;
    char *exported, *filename, *env;
    static char exported_name[] = "X509_USER_DELEG_PROXY=";
    static char env_name[] = "X509_USER_PROXY=";
    static char file_prefix[] = "FILE:";

    majStat = gss_export_cred(&minStat, cred, GSS_C_NO_OID, 1, &buf);
    if (GSS_ERROR(majStat))
	goto Done;

    exported = buf.value;
    for (filename = exported; *filename != '\0'; filename++)
	if (!isalnum(*(unsigned char *)filename) && *filename != '_')
	    break;
    if (*filename != '=') { /* not an environment variable */
	majStat = GSS_S_UNAVAILABLE;
	goto Done;
    }
    filename++;
    if (memcmp(exported, exported_name, sizeof(exported_name) - 1) == 0) {
	GFARM_MALLOC_ARRAY(env, sizeof(env_name) + strlen(filename));
	if (env == NULL) {
	    majStat = GSS_S_FAILURE;
	    goto Done;
	}
	memcpy(env, env_name, sizeof(env_name) - 1);
	strcpy(env + sizeof(env_name) - 1, filename);
	filename = env + sizeof(env_name) - 1;
    } else {
	env = strdup(exported);
	if (env == NULL) {
	    majStat = GSS_S_FAILURE;
	    goto Done;
	}
	filename = env + (filename - exported);
    }
    if (memcmp(filename, file_prefix, sizeof(file_prefix) - 1) == 0)
	filename += sizeof(file_prefix) - 1;

    GFARM_MALLOC(exportedCred);
    if (exportedCred == NULL) {
	free(env);
	majStat = GSS_S_FAILURE;
	goto Done;
    }
    exportedCred->env = env;
    exportedCred->filename = access(filename, R_OK) == 0 ? filename : NULL;

    Done:
    gss_release_buffer(&minStat, &buf);
    if (statPtr != NULL)
	*statPtr = majStat;

    if (GSS_ERROR(majStat)) {
	gflog_debug(GFARM_MSG_1000800,
		"failed to export credential (%u)(%u)",
		 majStat, minStat);
    }

    return exportedCred;
}
Exemplo n.º 21
0
static int
fixdir(char *dir, const char *gfarm_prefix)
{
	DIR* dirp;
	struct dirent *dp;
	struct stat sb;
	char *dir1;
	char *gfarm_url, *e;
	int is_directory;
	struct gfs_stat gs;

	if (lstat(dir, &sb)) {
		perror(dir);
		return (1);
	}
	if (S_ISREG(sb.st_mode))
		return (fixfrag(dir, gfarm_prefix));

	if (!S_ISDIR(sb.st_mode)) {
		print_errmsg(dir, NULL,
			"neither a regular file nor a directory");
		delete_invalid_file_or_directory(dir);
		return (1);
	}

	/* 'dir' is a directory */
	gfarm_url = append_prefix_pathname(gfarm_prefix, dir);
	if (gfarm_url == NULL) {
		print_errmsg(dir, NULL, "not enough memory");
		return (1);
	}

	e = gfs_stat(gfarm_url, &gs);
	if (e != NULL) {
		print_errmsg(gfarm_url, NULL, e);
		delete_invalid_file_or_directory(dir);
		free(gfarm_url);
		return (1);
	}
	is_directory = GFARM_S_ISDIR(gs.st_mode);
	gfs_stat_free(&gs);
	if (!is_directory) {
		print_errmsg(gfarm_url, NULL, "invalid directory");
		delete_invalid_file_or_directory(dir);
		free(gfarm_url);
		return (1);
	}
	free(gfarm_url);

	dirp = opendir(dir);
	if (dirp == NULL) {
		perror(dir);
		return (1);
	}

	if (strcmp(dir, ".") == 0)
		dir = ""; /* just a trick */

	while ((dp = readdir(dirp)) != NULL) {
		if (strcmp(dp->d_name, ".") == 0
		    || strcmp(dp->d_name, "..") == 0)
			continue;

		GFARM_MALLOC_ARRAY(dir1, strlen(dir) + strlen(dp->d_name) + 2);
		if (dir1 == NULL) {
			print_errmsg(dp->d_name, NULL, "not enough memory");
			closedir(dirp);
			return (1);
		}
		strcpy(dir1, dir);
		if (strcmp(dir, ""))
			strcat(dir1, "/");
		strcat(dir1, dp->d_name);

		fixdir(dir1, gfarm_prefix);

		free(dir1);
	}
	return (closedir(dirp));
}
Exemplo n.º 22
0
gfarm_error_t
gfj_server_info(struct peer *peer, int from_client, int skip)
{
	gfarm_error_t e;
	struct gfp_xdr *client = peer_get_conn(peer);
	int i, eof;
	gfarm_int32_t n, *jobs;

	e = gfj_server_get_request(peer, "info", "i", &n);
	if (e != GFARM_ERR_NO_ERROR)
		return (e);

	GFARM_MALLOC_ARRAY(jobs, n);
	if (jobs == NULL)
		return (GFARM_ERR_NO_MEMORY);

	for (i = 0; i < n; i++) {
		e = gfp_xdr_recv(client, 0, &eof, "i", &jobs[i]);
		if (e != GFARM_ERR_NO_ERROR || eof) {
			if (e == GFARM_ERR_NO_ERROR)
				e = GFARM_ERR_PROTOCOL;
			free(jobs);
			return (e);
		}
	}

	if (skip || !from_client) {
		free(jobs);
		if (skip)
			return (GFARM_ERR_NO_ERROR);
		e = gfj_server_put_reply(peer, "info",
		    GFARM_ERR_OPERATION_NOT_PERMITTED, "");
		return (e);
	}

	/* XXX FIXME too long giant lock */
	giant_lock();
	for (i = 0; i < n; i++) {
		if (jobs[i] < 0 || jobs[i] >= job_table_size ||
		    job_table[jobs[i]] == NULL) {
			e = gfj_server_put_reply(peer, "info",
						 GFARM_ERR_NO_SUCH_OBJECT, "");
			if (e != GFARM_ERR_NO_ERROR) {
				giant_unlock();
				free(jobs);
				return (e);
			}
		} else {
			e = gfj_server_put_reply(peer, "info",
						 GFARM_ERR_NO_ERROR, "");
			if (e != GFARM_ERR_NO_ERROR) {
				free(jobs);
				giant_unlock();
				return (e);
			}
			e = gfj_server_put_info_entry(peer_get_conn(peer),
			      job_table[jobs[i]]->info);
			if (e != GFARM_ERR_NO_ERROR) {
				free(jobs);
				giant_unlock();
				return (e);
			}
		}
	}
	free(jobs);
	giant_unlock();
	return (GFARM_ERR_NO_ERROR);
}
Exemplo n.º 23
0
static gfarm_error_t
gfm_realpath_success(struct gfm_connection *gfm_server, void *closure,
	int type, const char *path, gfarm_ino_t ino)
{
	gfarm_error_t e;
	char *buf, *b;
	const char *p, *q;
	const char *hostname;
	size_t len;
	int level = 0;

	len = strlen(path);
	GFARM_MALLOC_ARRAY(buf, len + 2); /* 2 for b[0]='/' + last '\0' */
	if (buf == NULL) {
		gfm_client_connection_free(gfm_server);
		return (GFARM_ERR_NO_MEMORY);
	}
	b = buf;
	p = path;
	e = GFARM_ERR_NO_ERROR;

	while (*p) {
		while (*p == '/')
			p++;
		q = p;
		while (*q != '/' && *q != 0)
			q++;
		len = q - p;
		if (len == 0) {
			if (*q != 0)
				e = GFARM_ERR_INVALID_ARGUMENT;
			break;
		}
		if (len == 1 && p[0] == '.') {
			p = q;
			continue;
		}
		if (len == 2 && p[0] == '.' && p[1] == '.') {
			if (level <= 0) {
				p = q;
				continue;
			}
			--b;
			while (*b != '/' && b > buf)
				b--;
			p = q;
			--level;
			continue;
		}
		*b++ = '/';
		memcpy(b, p, len);
		p = q;
		b += len;
		++level;
	}

	if (level == 0)
		*b++ = '/';
	*b = 0;

	if (e != GFARM_ERR_NO_ERROR) {
		gflog_debug(GFARM_MSG_1002669,
		    "gfm_realpath_success(%s) : %s\n",
		    path, gfarm_error_string(e));
		goto end;
	}

	len = strlen(buf);
	hostname = gfm_client_hostname(gfm_server);
	GFARM_MALLOC_ARRAY(b, len + strlen(hostname) + GFARM_URL_PREFIX_LENGTH +
	    2 + 1 + 5 + 1);
	    /* (gfarm:=PREFIX_LENGTH)(//=2)(:=1)(port=5)(\0=1) */
	if (b == NULL) {
		e = GFARM_ERR_NO_MEMORY;
		goto end;
	}
	sprintf(b, "%s//%s:%d%s", GFARM_URL_PREFIX,
	    hostname, gfm_client_port(gfm_server), buf);
	((struct gfm_realpath_closure *)closure)->path = b;
end:
	free(buf);
	gfm_client_connection_free(gfm_server);
	return (e);
}
Exemplo n.º 24
0
Arquivo: job.c Projeto: ddk50/gfarm_v2
gfarm_error_t
gfj_server_info(struct peer *peer, gfp_xdr_xid_t xid, size_t *sizep,
	int from_client, int skip)
{
	gfarm_error_t e;
	struct gfp_xdr *client = peer_get_conn(peer);
	int i, eof;
	gfarm_int32_t n, *jobs;
	static const char diag[] = "GFJ_PROTO_INFO";

	e = gfj_server_get_request(peer, sizep, diag, "i", &n);
	if (e != GFARM_ERR_NO_ERROR) {
		gflog_debug(GFARM_MSG_1001701,
			"info request failure");
		return (e);
	}

	GFARM_MALLOC_ARRAY(jobs, n);
	if (jobs == NULL) {
		gflog_debug(GFARM_MSG_1001702,
			"allocation of 'jobs' failed");
		return (GFARM_ERR_NO_MEMORY);
	}

	for (i = 0; i < n; i++) {
		e = gfp_xdr_recv(client, 0, &eof, "i", &jobs[i]);
		if (e != GFARM_ERR_NO_ERROR || eof) {
			gflog_debug(GFARM_MSG_1001703,
				"gfp_xdr_recv(jobs[%d]) failed", i);
			if (e == GFARM_ERR_NO_ERROR)
				e = GFARM_ERR_PROTOCOL;
			free(jobs);
			return (e);
		}
	}

	if (skip || !from_client) {
		free(jobs);
		if (skip)
			return (GFARM_ERR_NO_ERROR);
		e = gfj_server_put_reply(peer, xid, sizep, diag,
		    GFARM_ERR_OPERATION_NOT_PERMITTED, "");
		gflog_debug(GFARM_MSG_1001704,
			"operation is not permitted for from_client");
		return (e);
	}

	/* XXX FIXME too long giant lock */
	giant_lock();
	for (i = 0; i < n; i++) {
		if (jobs[i] < 0 || jobs[i] >= job_table_size ||
		    job_table[jobs[i]] == NULL) {
			e = gfj_server_put_reply(peer, xid, sizep, diag,
						 GFARM_ERR_NO_SUCH_OBJECT, "");
			if (e != GFARM_ERR_NO_ERROR) {
				gflog_debug(GFARM_MSG_1001705,
					"gfj_server_put_reply(info) failed");
				giant_unlock();
				free(jobs);
				return (e);
			}
		} else {
			/* XXXRELAY FIXME, reply size is not correct */
			e = gfj_server_put_reply(peer, xid, sizep, diag,
						 GFARM_ERR_NO_ERROR, "");
			if (e != GFARM_ERR_NO_ERROR) {
				gflog_debug(GFARM_MSG_1001706,
					"gfj_server_put_reply(info) failed");
				free(jobs);
				giant_unlock();
				return (e);
			}
			/* XXXRELAY FIXME */
			e = gfj_server_put_info_entry(peer_get_conn(peer),
			      job_table[jobs[i]]->info);
			if (e != GFARM_ERR_NO_ERROR) {
				gflog_debug(GFARM_MSG_1001707,
					"gfj_server_put_info_entry() failed");
				free(jobs);
				giant_unlock();
				return (e);
			}
		}
	}
	free(jobs);
	giant_unlock();
	return (GFARM_ERR_NO_ERROR);
}
Exemplo n.º 25
0
/*
 * 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);
}
Exemplo n.º 26
0
int webgfarm_api_v1_read_file(request_rec *r) {
    // get filepath from request
    char *filepath = webgfarm_api_v1_getfilepath(r);

    if (filepath == NULL || strlen(filepath) == 0) {
        return HTTP_FORBIDDEN;
    }

    webgfarm_config *wconfig = ap_get_module_config(r->server->module_config, &webgfarm_module);

    gfarm_error_t gerr;
    GFS_File gfs_file;

    if (wconfig->read_redirect) {
        //        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "[read] read_redirect is on.");

        char *redirect_url = apr_palloc(r->pool, sizeof (char)*WEBGFARM_BUFFER_SIZE);

        const char *port;

        int available_nhosts;
        struct gfarm_host_sched_info *available_hosts;
        gerr = gfarm_schedule_hosts_domain_by_file(filepath, GFARM_FILE_RDONLY, "", &available_nhosts, &available_hosts);
        if (gerr == GFARM_ERR_NO_ERROR) {
            //            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "[read] gfarm_schedule_hosts_domain_by_file() has no error.");
            int *ports;
            char **hosts;
            int nhosts = available_nhosts;
            int i;
            GFARM_MALLOC_ARRAY(hosts, available_nhosts);
            GFARM_MALLOC_ARRAY(ports, available_nhosts);
            gerr = gfarm_schedule_hosts_acyclic(filepath, available_nhosts, available_hosts, &nhosts, hosts, ports);

            if (nhosts > 0 && gerr == GFARM_ERR_NO_ERROR) {
                //                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "[read] gfarm_schedule_hosts_acyclic() has no error.");
                for (i = 0; i < nhosts; i++) {
                    port = apr_table_get(wconfig->hosts, hosts[i]);
                    if (port != NULL) {
                        if (strcmp(wconfig->localhost, hosts[i]) != 0) {
                            if (wconfig->ssl) {
                                snprintf(redirect_url, WEBGFARM_BUFFER_SIZE, "https://%s:%s%s", hosts[i], port, r->uri);
                            } else {
                                snprintf(redirect_url, WEBGFARM_BUFFER_SIZE, "http://%s:%s%s", hosts[i], port, r->uri);
                            }
                            apr_table_set(r->headers_out, "Location", redirect_url);
                            free(ports);
                            free(hosts);
                            return HTTP_TEMPORARY_REDIRECT;
                        } else {
                            break;
                        }
                    }
                }
            }

            free(ports);
            free(hosts);
        } else if (gerr != GFARM_ERR_NO_SUCH_FILE_OR_DIRECTORY) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "gfarm_schedule_hosts_domain_by_file can not get the hosts of the file(%s) with error: %s", filepath, gfarm_error_string(gerr));
            return HTTP_INTERNAL_SERVER_ERROR;
        }
    }

    // open
    gerr = gfs_pio_open(filepath, GFARM_FILE_RDONLY, &gfs_file);
    if (gerr != GFARM_ERR_NO_ERROR) {
        switch (gerr) {
            case GFARM_ERR_NO_SUCH_FILE_OR_DIRECTORY:
                return HTTP_NOT_FOUND;
                break;
            case GFARM_ERR_PERMISSION_DENIED:
                return HTTP_FORBIDDEN;
                break;
                //FIXEME: Support more error;
            default:
                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "gfs_pio_open can not open the file(%s) with error: %s", filepath, gfarm_error_string(gerr));
                return HTTP_INTERNAL_SERVER_ERROR;
        }
    }

    // get stat
    struct gfs_stat gs;
    gerr = gfs_pio_stat(gfs_file, &gs);
    if (gerr != GFARM_ERR_NO_ERROR) {
        gfs_pio_close(gfs_file);
        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "gfs_pio_stat can not get the stat of the file(%s) with error: %s", filepath, gfarm_error_string(gerr));
        return HTTP_INTERNAL_SERVER_ERROR;
    }
    char *stat_buffer = apr_palloc(r->pool, sizeof (char)*WEBGFARM_BUFFER_SIZE);
    snprintf(stat_buffer, WEBGFARM_BUFFER_SIZE, "%lu", gs.st_ino);
    apr_table_set(r->headers_out, "X-WEBGFARM-STAT-INO", stat_buffer);
    snprintf(stat_buffer, WEBGFARM_BUFFER_SIZE, "%lu", gs.st_gen);
    apr_table_set(r->headers_out, "X-WEBGFARM-STAT-GEN", stat_buffer);
    snprintf(stat_buffer, WEBGFARM_BUFFER_SIZE, "%o", gs.st_mode);
    apr_table_set(r->headers_out, "X-WEBGFARM-STAT-MODE", stat_buffer);
    snprintf(stat_buffer, WEBGFARM_BUFFER_SIZE, "%lu", gs.st_nlink);
    apr_table_set(r->headers_out, "X-WEBGFARM-STAT-NLINK", stat_buffer);
    apr_table_set(r->headers_out, "X-WEBGFARM-STAT-USER", gs.st_user);
    apr_table_set(r->headers_out, "X-WEBGFARM-STAT-GROUP", gs.st_group);
    snprintf(stat_buffer, WEBGFARM_BUFFER_SIZE, "%lu", gs.st_size);
    apr_table_set(r->headers_out, "X-WEBGFARM-STAT-SIZE", stat_buffer);
    snprintf(stat_buffer, WEBGFARM_BUFFER_SIZE, "%lu", gs.st_ncopy);
    apr_table_set(r->headers_out, "X-WEBGFARM-STAT-NCOPY", stat_buffer);

    //    gerr == GFARM_ERR_NO_ERROR
    //read and puts
    if (!r->header_only) {
        char *buf = apr_palloc(r->pool, sizeof (char)*WEBGFARM_BUFFER_SIZE);
        int read_size = 0;
        do {
            gerr = gfs_pio_read(gfs_file, buf, WEBGFARM_BUFFER_SIZE, &read_size);
            if (gerr != GFARM_ERR_NO_ERROR) {
                gerr = gfs_pio_close(gfs_file);
                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "gfs_pio_read can not read the file(%s) with error: %s", filepath, gfarm_error_string(gerr));
                return HTTP_INTERNAL_SERVER_ERROR;
            } else {
                if (read_size != 0) {
                    ap_rwrite(buf, read_size, r);
                }
            }
        } while (gerr == GFARM_ERR_NO_ERROR && read_size != 0);
    }

    // close
    gerr = gfs_pio_close(gfs_file);
    if (gerr != GFARM_ERR_NO_ERROR) {
        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "gfs_pio_close can not close the file(%s) with error: %s", filepath, gfarm_error_string(gerr));

        return HTTP_INTERNAL_SERVER_ERROR;
    } else {
        return OK;
    }
}
Exemplo n.º 27
0
static void
fixurl(const char *gfarm_url)
{
	char *gfarm_file, *local_path, *e;
	struct stat sb;
	int len_path, is_invalid = 0, is_directory = 0;
	glob_t pglob;
	char **pathp, *pat;
	struct gfs_stat gs;

	e = gfarm_canonical_path(gfarm_url_prefix_skip(gfarm_url), &gfarm_file);
	if (e != NULL) {
		/*
		 * no path info, try to delete invalid physical files
		 * or directories
		 */
		e = gfarm_canonical_path_for_creation(
			gfarm_url_prefix_skip(gfarm_url), &gfarm_file);
		if (e != NULL) {
			/* in this case, give up searching invalid files */
			print_errmsg(gfarm_url, NULL, e);
			return;
		}
		is_invalid = 1;
	}
	else {
		/* check it is a directory or not */
		e = gfs_stat(gfarm_url, &gs);
		if (e != NULL) {
			if (e != GFARM_ERR_NO_FRAGMENT_INFORMATION) {
				/* maybe permission denied */
				print_errmsg(gfarm_url, NULL, e);
				goto error_gfarm_file;
			}
			/* no fragment information case */
		}
		else {
			is_directory = GFARM_S_ISDIR(gs.st_mode);
			gfs_stat_free(&gs);
		}
	}
	/*
	 * Check local_path; if it is invalid or not a directory,
	 * delete it.  Otherwise, check it recursively.
	 */
	e = gfarm_path_localize(gfarm_file, &local_path);
	if (e == NULL && stat(local_path, &sb) == 0) {
		if (is_invalid || !is_directory || !S_ISDIR(sb.st_mode)) {
			print_errmsg(local_path, NULL,
				"invalid file or directory");
			delete_invalid_file_or_directory(local_path);
		}
		else if (chdir(local_path) == 0)
			(void)fixdir(".", gfarm_url);
		/* continue */
	}
	if (e != NULL) {
		print_errmsg(gfarm_url, NULL, e);
		goto error_gfarm_file;
	}

	/* investigate file sections */
	len_path = strlen(local_path);
	GFARM_MALLOC_ARRAY(pat, len_path + 3);
	if (pat == NULL) {
		print_errmsg(gfarm_url, NULL, "not enough memory");
		free(local_path);
		goto error_gfarm_file;
	}
	strcpy(pat, local_path);
	strcat(pat, ":*");
	free(local_path);

	pglob.gl_offs = 0;
	glob(pat, GLOB_DOOFFS, NULL, &pglob);
	free(pat);
	
	pathp = pglob.gl_pathv;
	while (*pathp) {
		char *sec = &((*pathp)[len_path + 1]);

		if (is_invalid || is_directory) {
			print_errmsg(gfarm_url, sec, "invalid file");
			delete_invalid_file_or_directory(*pathp);
			++pathp;
			continue;
		}
		(void)fixfrag_i(gfarm_url, *pathp, gfarm_file, sec);

		++pathp;
	}
	globfree(&pglob);

 error_gfarm_file:
	free(gfarm_file);
	return;
}
Exemplo n.º 28
0
int webgfarm_api_v1_write_to_file(request_rec *r) {

    // get filepath from request
    char *filepath = webgfarm_api_v1_getfilepath(r);

    if (filepath == NULL || strlen(filepath) == 0) {
        return HTTP_FORBIDDEN;
    }

    gfarm_error_t gerr;
    GFS_File gfs_file;


    webgfarm_config *wconfig = ap_get_module_config(r->server->module_config, &webgfarm_module);
    if (wconfig->write_redirect) {

        char *redirect_url = apr_palloc(r->pool, sizeof (char)*WEBGFARM_BUFFER_SIZE);
        const char *port;

        int available_nhosts;
        struct gfarm_host_sched_info *available_hosts;
        gerr = gfarm_schedule_hosts_domain_by_file(filepath, GFARM_FILE_RDONLY, "", &available_nhosts, &available_hosts);

        if (available_nhosts > 0) {
            if (gerr == GFARM_ERR_NO_ERROR) {
                int *ports;
                char **hosts;
                int nhosts = available_nhosts;
                int i;
                GFARM_MALLOC_ARRAY(hosts, available_nhosts);
                GFARM_MALLOC_ARRAY(ports, available_nhosts);
                gerr = gfarm_schedule_hosts_acyclic_to_write(filepath, available_nhosts, available_hosts, &nhosts, hosts, ports);

                if (nhosts > 0 && gerr == GFARM_ERR_NO_ERROR) {
                    for (i = 0; i < nhosts; i++) {
                        port = apr_table_get(wconfig->hosts, hosts[i]);
                        if (port != NULL) {
                            if (strcmp(wconfig->localhost, hosts[i]) != 0) {
                                if (wconfig->ssl) {
                                    snprintf(redirect_url, WEBGFARM_BUFFER_SIZE, "https://%s:%s%s", hosts[i], port, r->uri);
                                } else {
                                    snprintf(redirect_url, WEBGFARM_BUFFER_SIZE, "http://%s:%s%s", hosts[i], port, r->uri);
                                }
                                apr_table_set(r->headers_out, "Location", redirect_url);
                                free(ports);
                                free(hosts);
                                return HTTP_TEMPORARY_REDIRECT;
                            } else {
                                break;
                            }
                        }
                    }
                }

                free(ports);
                free(hosts);
            } else if (gerr != GFARM_ERR_NO_SUCH_FILE_OR_DIRECTORY) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "gfarm_schedule_hosts_domain_by_file can not get the hosts of the file(%s) with error: %s", filepath, gfarm_error_string(gerr));
                return HTTP_INTERNAL_SERVER_ERROR;
            }
        }
    }

    // open
    if (r->method_number == M_POST) {
        gerr = gfs_pio_open(filepath, GFARM_FILE_WRONLY | GFARM_FILE_APPEND, &gfs_file);
    } else if (r->method_number == M_PUT) {
        gerr = gfs_pio_open(filepath, GFARM_FILE_WRONLY | GFARM_FILE_TRUNC, &gfs_file);
        if (gerr == GFARM_ERR_NO_SUCH_FILE_OR_DIRECTORY) {
            gerr = gfs_pio_create(filepath, GFARM_FILE_WRONLY, 0644, &gfs_file);
        }
    } else {
        return HTTP_INTERNAL_SERVER_ERROR;
    }

    if (gerr != GFARM_ERR_NO_ERROR) {
        switch (gerr) {
            case GFARM_ERR_NO_SUCH_FILE_OR_DIRECTORY:
                return HTTP_NOT_FOUND;
                break;
            case GFARM_ERR_PERMISSION_DENIED:
                return HTTP_FORBIDDEN;
                break;
                //FIXEME: Support more error;
            default:
                return HTTP_INTERNAL_SERVER_ERROR;
        }
    }

    // get input body size;
    int in_size;
    const char *clen = apr_table_get(r->headers_in, "Content-Length");
    if (clen != NULL) {
        in_size = strtol(clen, NULL, 0);
        if (in_size >= WEBGFFARM_MAX_POST_SIZE) {
            gfs_pio_close(gfs_file);
            return HTTP_BAD_REQUEST;
        }
    } else {
        gfs_pio_close(gfs_file);
        return HTTP_BAD_REQUEST;
    }

    if (in_size != 0) {
        apr_off_t size = 0;
        char *buf;

        if (util_read(r, &buf, &size) != OK) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "[write] failed reading POST body");
            gfs_pio_close(gfs_file);
            return HTTP_INTERNAL_SERVER_ERROR;
        }

        in_size = (int) size;

        if (buf == NULL) {
            return HTTP_BAD_REQUEST;
        }

        // write buffer
        int write_size;
        gerr = gfs_pio_write(gfs_file, buf, in_size, &write_size);
        if (gerr != GFARM_ERR_NO_ERROR) {
            if (in_size != write_size) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "[write] gfs_pio_write failure..(in: %d, out: %d)", (int) in_size, (int) write_size);
            }
            gerr = gfs_pio_close(gfs_file);
            return HTTP_INTERNAL_SERVER_ERROR;
        }
    }

    // close
    gerr = gfs_pio_close(gfs_file);
    if (gerr != GFARM_ERR_NO_ERROR) {
        return HTTP_INTERNAL_SERVER_ERROR;
    } else {
        return OK;
    }

}
Exemplo n.º 29
0
gfarm_error_t
gfs_pio_set_view_global(GFS_File gf, int flags)
{
	struct gfs_file_global_context *gc;
	gfarm_error_t e;
	char *arch;
	int i, n;
	struct gfarm_file_section_info *infos;
	static char gfarm_url_prefix[] = "gfarm:/";

	e = gfs_pio_set_view_default(gf);
	if (e != GFARM_ERR_NO_ERROR)
		return (e);

	if (GFS_FILE_IS_PROGRAM(gf)) {
		e = gfarm_host_get_self_architecture(&arch);
		if (e != GFARM_ERR_NO_ERROR)
			return (gf->error = e);
		e = gfs_pio_set_view_section(gf, arch, NULL, flags);
		if (e == GFARM_ERR_NO_SUCH_OBJECT)
			e = gfs_pio_set_view_section(
				gf, "noarch", NULL, flags);
		return (e);
	}

	if ((gf->mode & GFS_FILE_MODE_FILE_WAS_CREATED) != 0)
		return (gfs_pio_set_view_index(gf, 1, 0, NULL, flags));

	if (gf->open_flags & GFARM_FILE_TRUNC) {
		int nsections;
		struct gfarm_file_section_info *sections;

		/* XXX this may not be OK, if a parallel process does this */
		/* remove all sections except section "0" */
		e = gfarm_file_section_info_get_all_by_file(gf->pi.pathname,
		    &nsections, &sections);
		if (e != GFARM_ERR_NO_ERROR)
			return (e);
		for (i = 0; i < nsections; i++) {
			if (strcmp(sections[i].section, "0") == 0)
				continue;
			(void)gfs_unlink_section_internal(gf->pi.pathname,
			    sections[i].section);
		}
		gfarm_file_section_info_free_all(nsections, sections);

		gf->pi.status.st_nsections = 1;
		return (gfs_pio_set_view_index(gf, 1, 0, NULL, flags));
	}

	/* XXX - GFARM_FILE_APPEND is not supported */
	if (gf->open_flags & GFARM_FILE_APPEND) {
		gf->error = GFARM_ERR_OPERATION_NOT_SUPPORTED;
		return (gf->error);
	}

	GFARM_MALLOC(gc);
	if (gc == NULL) {
		gf->error = GFARM_ERR_NO_MEMORY;
		return (gf->error);
	}

	e = gfarm_file_section_info_get_sorted_all_serial_by_file(
		gf->pi.pathname, &n, &infos);
	if (e != GFARM_ERR_NO_ERROR) {
		free(gc);
		gf->error = e;
		return (e);
	}

	if (n != gf->pi.status.st_nsections) {
		gfarm_file_section_info_free_all(n, infos);
		free(gc);
		gf->error = "metainfo inconsitency, fragment number mismatch";
		return (gf->error);
	}

	GFARM_MALLOC_ARRAY(gc->offsets, n + 1);
	GFARM_MALLOC_ARRAY(gc->url,
	    sizeof(gfarm_url_prefix) + strlen(gf->pi.pathname));
	if (gc->offsets == NULL || gc->url == NULL) {
		if (gc->offsets != NULL)
			free(gc->offsets);
		if (gc->url != NULL)
			free(gc->url);
		gfarm_file_section_info_free_all(n, infos);
		free(gc);
		gf->error = GFARM_ERR_NO_MEMORY;
		return (gf->error);
	}

	gc->offsets[0] = 0;
	for (i = 0; i < n; i++)
		gc->offsets[i + 1] = gc->offsets[i] + infos[i].filesize;
	gfarm_file_section_info_free_all(n, infos);

	sprintf(gc->url, "%s%s", gfarm_url_prefix, gf->pi.pathname);

	gf->view_context = gc;
	gf->view_flags = flags;
	gc->fragment_gf = NULL;
	e = gfs_pio_view_global_move_to(gf, 0);
	if (e != GFARM_ERR_NO_ERROR) {
		free(gc->url);
		free(gc->offsets);
		free(gc);
		gf->view_context = NULL;
		gfs_pio_set_view_default(gf);
		gf->error = e;
		return (e);
	}

	gf->ops = &gfs_pio_view_global_ops;
	gf->p = gf->length = 0;
	gf->io_offset = gf->offset = 0;
	gf->error = GFARM_ERR_NO_ERROR;
	return (GFARM_ERR_NO_ERROR);
}
Exemplo n.º 30
0
Arquivo: gsi.c Projeto: ddk50/gfarm_v2
int
gfarmGssReceive(int fd, gss_ctx_id_t sCtx, gfarm_int8_t **bufPtr,
    int *lenPtr, OM_uint32 *statPtr, int timeoutMsec)
{
    int ret = -1;
    OM_uint32 majStat;
    OM_uint32 minStat;

    gss_buffer_desc inputToken = GSS_C_EMPTY_BUFFER;
    gss_buffer_t itPtr = &inputToken;
    gss_buffer_desc outputToken = GSS_C_EMPTY_BUFFER;
    gss_buffer_t otPtr = &outputToken;

    gfarm_int32_t n;
    int sum = 0;
    int rem;
    int len;
    gfarm_int8_t *buf = NULL;
    int i;

    /*
     * Receive a length of a PLAIN TEXT.
     *	XXXXX FIX ME:
     *		Generally it is wrong idea receiving a plain text
     *		length in plain text communication. Should be
     *		encrypted.
     */

    i = gfarmReadInt32(fd, &n, 1, timeoutMsec);
    if (i == 0) {
	ret = 0;
	n = 0;
	majStat = GSS_S_COMPLETE;
	goto Done;
    } else if (i != 1) {
	majStat = GSS_S_CALL_INACCESSIBLE_READ;
	goto Done;
    }
    GFARM_MALLOC_ARRAY(buf, n);
    if (buf == NULL) {
	majStat = GSS_S_FAILURE;
	goto Done;
    }

    rem = n;
    do {
	if (gfarmGssReceiveToken(fd, itPtr, timeoutMsec) <= 0) {
	    majStat = GSS_S_DEFECTIVE_TOKEN|GSS_S_CALL_INACCESSIBLE_READ;
	    goto Done;
	}
	majStat = gss_unwrap(&minStat, sCtx,
			     (const gss_buffer_t)itPtr,
			     otPtr,
			     NULL, NULL);
	gss_release_buffer(&minStat, itPtr);
	if (majStat == GSS_S_COMPLETE) {
	    if (otPtr->length > 0) {
		memcpy(buf + sum, otPtr->value, otPtr->length);
		len = otPtr->length;
		rem -= len;
		sum += len;
		gss_release_buffer(&minStat, otPtr);
	    } else {
		majStat = GSS_S_DEFECTIVE_TOKEN;
		goto Done;
	    }
	} else {
	    break;
	}
    } while (rem > 0);
    if (rem <= 0) {
	ret = n;
    }

    Done:
    if (statPtr != NULL)
	*statPtr = majStat;

    if (ret == -1) {
	*bufPtr = NULL;
	*lenPtr = -1;
    } else {
	*bufPtr = buf;
	*lenPtr = n;
    }

    if (ret == -1) {
	gflog_debug(GFARM_MSG_1000799,
		"error occurred during gfarmGssReceive (%u)(%u)",
		 majStat, minStat);
    }

    return ret;
}