Ejemplo n.º 1
0
/*
 * XDR an opaque authentication struct
 * (see auth.h)
 */
bool
xdr_opaque_auth(XDR *xdrs, struct opaque_auth *ap)
{
	assert(xdrs != NULL);
	assert(ap != NULL);

	if (inline_xdr_enum(xdrs, &(ap->oa_flavor)))
		return (inline_xdr_bytes
			(xdrs, &ap->oa_base, &ap->oa_length, MAX_AUTH_BYTES));
	return (false);
}
Ejemplo n.º 2
0
static bool xdr_encode_nfs4_princ(XDR *xdrs, uint32_t id, bool group)
{
	const struct gsh_buffdesc *found;
	uint32_t not_a_size_t;
	bool success = false;

	PTHREAD_RWLOCK_rdlock(group ? &idmapper_group_lock :
			      &idmapper_user_lock);
	if (group)
		success = idmapper_lookup_by_gid(id, &found);
	else
		success = idmapper_lookup_by_uid(id, &found, NULL);

	if (likely(success)) {
		not_a_size_t = found->len;

		/* Fully qualified owners are always stored in the
		   hash table, no matter what our lookup method. */
		success =
		    inline_xdr_bytes(xdrs, (char **)&found->addr, &not_a_size_t,
				     UINT32_MAX);
		PTHREAD_RWLOCK_unlock(group ? &idmapper_group_lock :
				      &idmapper_user_lock);
		return success;
	} else {
		PTHREAD_RWLOCK_unlock(group ? &idmapper_group_lock :
				      &idmapper_user_lock);
		int rc;
		int size;
		bool looked_up = false;
		char *namebuff = NULL;
		struct gsh_buffdesc new_name;

		if (nfs_param.nfsv4_param.use_getpwnam) {
			if (group)
				size = sysconf(_SC_GETGR_R_SIZE_MAX);
			else
				size = sysconf(_SC_GETPW_R_SIZE_MAX);
			if (size == -1)
				size = PWENT_BEST_GUESS_LEN;
			new_name.len = size;
			size += owner_domain.len + 2;
		} else {
			size = NFS4_MAX_DOMAIN_LEN + 2;
		}

		namebuff = alloca(size);

		new_name.addr = namebuff;

		if (nfs_param.nfsv4_param.use_getpwnam) {
			char *cursor;
			bool nulled;

			if (group) {
				struct group g;
				struct group *gres;

				rc = getgrgid_r(id, &g, namebuff, new_name.len,
						&gres);
				nulled = (gres == NULL);
			} else {
				struct passwd p;
				struct passwd *pres;

				rc = getpwuid_r(id, &p, namebuff, new_name.len,
						&pres);
				nulled = (pres == NULL);
			}

			if ((rc == 0) && !nulled) {
				new_name.len = strlen(namebuff);
				cursor = namebuff + new_name.len;
				*(cursor++) = '@';
				++new_name.len;
				memcpy(cursor, owner_domain.addr,
				       owner_domain.len);
				new_name.len += owner_domain.len;
				looked_up = true;
			} else {
				LogInfo(COMPONENT_IDMAPPER,
					"%s failed with code %d.",
					(group ? "getgrgid_r" : "getpwuid_r"),
					rc);
			}
		} else {
#ifdef USE_NFSIDMAP
			if (group) {
				rc = nfs4_gid_to_name(id, owner_domain.addr,
						      namebuff,
						      NFS4_MAX_DOMAIN_LEN + 1);
			} else {
				rc = nfs4_uid_to_name(id, owner_domain.addr,
						      namebuff,
						      NFS4_MAX_DOMAIN_LEN + 1);
			}
			if (rc == 0) {
				new_name.len = strlen(namebuff);
				looked_up = true;
			} else {
				LogInfo(COMPONENT_IDMAPPER,
					"%s failed with code %d.",
					(group ? "nfs4_gid_to_name" :
					"nfs4_uid_to_name"), rc);
			}
#else				/* USE_NFSIDMAP */
			looked_up = false;
#endif				/* !USE_NFSIDMAP */
		}

		if (!looked_up) {
			if (nfs_param.nfsv4_param.allow_numeric_owners) {
				LogInfo(COMPONENT_IDMAPPER,
					"Lookup for %d failed, using numeric %s",
					id, (group ? "group" : "owner"));
				/* 2**32 is 10 digits long in decimal */
				sprintf(namebuff, "%u", id);
				new_name.len = strlen(namebuff);
			} else {
				LogInfo(COMPONENT_IDMAPPER,
					"Lookup for %d failed, using nobody.",
					id);
				memcpy(new_name.addr, "nobody", 6);
				new_name.len = 6;
			}
		}

		/* Add to the cache and encode the result. */
		PTHREAD_RWLOCK_wrlock(group ? &idmapper_group_lock :
				      &idmapper_user_lock);
		if (group)
			success = idmapper_add_group(&new_name, id);
		else
			success = idmapper_add_user(&new_name, id, NULL, false);

		PTHREAD_RWLOCK_unlock(group ? &idmapper_group_lock :
				      &idmapper_user_lock);
		if (unlikely(!success)) {
			LogMajor(COMPONENT_IDMAPPER, "%s failed.",
				 group ? "idmapper_add_group" :
				 "idmaper_add_user");
		}
		not_a_size_t = new_name.len;
		return inline_xdr_bytes(xdrs, (char **)&new_name.addr,
					&not_a_size_t, UINT32_MAX);
	}
}