/*
 * GPL HEADER START
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 only,
 * as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License version 2 for more details (a copy is included
 * in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU General Public License
 * version 2 along with this program; If not, see
 * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
 *
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 *
 * GPL HEADER END
 */
/*
 * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
 * Use is subject to license terms.
 *
 * Copyright (c) 2012, Intel Corporation.
 */
/*
 * This file is part of Lustre, http://www.lustre.org/
 * Lustre is a trademark of Sun Microsystems, Inc.
 *
 * lustre/obdclass/idmap.c
 *
 * Lustre user identity mapping.
 *
 * Author: Fan Yong <fanyong@clusterfs.com>
 */

#define DEBUG_SUBSYSTEM S_SEC

#include <lustre_idmap.h>
#include <md_object.h>
#include <obd_support.h>

#define lustre_get_group_info(group_info) do {	     \
	atomic_inc(&(group_info)->usage);	      \
} while (0)

#define lustre_put_group_info(group_info) do {	     \
	if (atomic_dec_and_test(&(group_info)->usage)) \
		groups_free(group_info);	       \
} while (0)

/*
 * groups_search() is copied from linux kernel!
 * A simple bsearch.
 */
static int lustre_groups_search(const struct group_info *group_info, gid_t grp)
{
	int left, right;

	if (!group_info)
		return 0;

	left = 0;
	right = group_info->ngroups;
	while (left < right) {
		int mid = (left + right) / 2;
		int cmp = grp -
			from_kgid(&init_user_ns, CFS_GROUP_AT(group_info, mid));

		if (cmp > 0)
			left = mid + 1;
		else if (cmp < 0)
			right = mid;
		else
			return 1;
	}
	return 0;
}

void lustre_groups_from_list(struct group_info *ginfo, gid_t *glist)
{
	int i;
	int count = ginfo->ngroups;

	/* fill group_info from gid array */
	for (i = 0; i < ginfo->nblocks && count > 0; i++) {
		int cp_count = min(CFS_NGROUPS_PER_BLOCK, count);
		int off = i * CFS_NGROUPS_PER_BLOCK;
		int len = cp_count * sizeof(*glist);

		memcpy(ginfo->blocks[i], glist + off, len);
		count -= cp_count;
	}
}
EXPORT_SYMBOL(lustre_groups_from_list);

/* groups_sort() is copied from linux kernel! */
/* a simple shell-metzner sort */
void lustre_groups_sort(struct group_info *group_info)
{
	int base, max, stride;
	int gidsetsize = group_info->ngroups;

	for (stride = 1; stride < gidsetsize; stride = 3 * stride + 1)
		; /* nothing */
	stride /= 3;

	while (stride) {
		max = gidsetsize - stride;
		for (base = 0; base < max; base++) {
			int left = base;
			int right = left + stride;
			gid_t tmp = from_kgid(&init_user_ns,
					      CFS_GROUP_AT(group_info, right));

			while (left >= 0 &&
			       tmp < from_kgid(&init_user_ns,
					       CFS_GROUP_AT(group_info, left))) {
				CFS_GROUP_AT(group_info, right) =
				    CFS_GROUP_AT(group_info, left);
				right = left;
				left -= stride;
			}
			CFS_GROUP_AT(group_info, right) =
						make_kgid(&init_user_ns, tmp);
		}
		stride /= 3;
	}
}
EXPORT_SYMBOL(lustre_groups_sort);

int lustre_in_group_p(struct lu_ucred *mu, gid_t grp)
{
	int rc = 1;

	if (grp != mu->uc_fsgid) {
		struct group_info *group_info = NULL;

		if (mu->uc_ginfo || !mu->uc_identity ||
		    mu->uc_valid == UCRED_OLD)
			if (grp == mu->uc_suppgids[0] ||
			    grp == mu->uc_suppgids[1])
				return 1;

		if (mu->uc_ginfo)
			group_info = mu->uc_ginfo;
		else if (mu->uc_identity)
			group_info = mu->uc_identity->mi_ginfo;

		if (!group_info)
			return 0;

		lustre_get_group_info(group_info);
		rc = lustre_groups_search(group_info, grp);
		lustre_put_group_info(group_info);
	}
	return rc;
}
EXPORT_SYMBOL(lustre_in_group_p);

struct lustre_idmap_entry {
	struct list_head       lie_rmt_uid_hash; /* hashed as lie_rmt_uid; */
	struct list_head       lie_lcl_uid_hash; /* hashed as lie_lcl_uid; */
	struct list_head       lie_rmt_gid_hash; /* hashed as lie_rmt_gid; */
	struct list_head       lie_lcl_gid_hash; /* hashed as lie_lcl_gid; */
	uid_t	    lie_rmt_uid;      /* remote uid */
	uid_t	    lie_lcl_uid;      /* local uid */
	gid_t	    lie_rmt_gid;      /* remote gid */
	gid_t	    lie_lcl_gid;      /* local gid */
};

static inline __u32 lustre_idmap_hashfunc(__u32 id)
{
	return id & (CFS_IDMAP_HASHSIZE - 1);
}

static
struct lustre_idmap_entry *idmap_entry_alloc(uid_t rmt_uid, uid_t lcl_uid,
					     gid_t rmt_gid, gid_t lcl_gid)
{
	struct lustre_idmap_entry *e;

	OBD_ALLOC_PTR(e);
	if (e == NULL)
		return NULL;

	INIT_LIST_HEAD(&e->lie_rmt_uid_hash);
	INIT_LIST_HEAD(&e->lie_lcl_uid_hash);
	INIT_LIST_HEAD(&e->lie_rmt_gid_hash);
	INIT_LIST_HEAD(&e->lie_lcl_gid_hash);
	e->lie_rmt_uid = rmt_uid;
	e->lie_lcl_uid = lcl_uid;
	e->lie_rmt_gid = rmt_gid;
	e->lie_lcl_gid = lcl_gid;

	return e;
}

static void idmap_entry_free(struct lustre_idmap_entry *e)
{
	if (!list_empty(&e->lie_rmt_uid_hash))
		list_del(&e->lie_rmt_uid_hash);
	if (!list_empty(&e->lie_lcl_uid_hash))
		list_del(&e->lie_lcl_uid_hash);
	if (!list_empty(&e->lie_rmt_gid_hash))
		list_del(&e->lie_rmt_gid_hash);
	if (!list_empty(&e->lie_lcl_gid_hash))
		list_del(&e->lie_lcl_gid_hash);
	OBD_FREE_PTR(e);
}

/*
 * return value
 * NULL: not found entry
 * ERR_PTR(-EACCES): found 1(remote):N(local) mapped entry
 * others: found normal entry
 */
static
struct lustre_idmap_entry *idmap_search_entry(struct lustre_idmap_table *t,
					      uid_t rmt_uid, uid_t lcl_uid,
					      gid_t rmt_gid, gid_t lcl_gid)
{
	struct list_head *head;
	struct lustre_idmap_entry *e;

	head = &t->lit_idmaps[RMT_UIDMAP_IDX][lustre_idmap_hashfunc(rmt_uid)];
	list_for_each_entry(e, head, lie_rmt_uid_hash)
		if (e->lie_rmt_uid == rmt_uid) {
			if (e->lie_lcl_uid == lcl_uid) {
				if (e->lie_rmt_gid == rmt_gid &&
				    e->lie_lcl_gid == lcl_gid)
					/* must be quaternion match */
					return e;
			} else {
				/* 1:N uid mapping */
				CERROR("rmt uid %u already be mapped to %u"
				       " (new %u)\n", e->lie_rmt_uid,
				       e->lie_lcl_uid, lcl_uid);
				return ERR_PTR(-EACCES);
			}
		}

	head = &t->lit_idmaps[RMT_GIDMAP_IDX][lustre_idmap_hashfunc(rmt_gid)];
	list_for_each_entry(e, head, lie_rmt_gid_hash)
		if (e->lie_rmt_gid == rmt_gid) {
			if (e->lie_lcl_gid == lcl_gid) {
				if (unlikely(e->lie_rmt_uid == rmt_uid &&
				    e->lie_lcl_uid == lcl_uid))
					/* after uid mapping search above,
					 * we should never come here */
					LBUG();
			} else {
				/* 1:N gid mapping */
				CERROR("rmt gid %u already be mapped to %u"
				       " (new %u)\n", e->lie_rmt_gid,
				       e->lie_lcl_gid, lcl_gid);
				return ERR_PTR(-EACCES);
			}
		}

	return NULL;
}

static __u32 idmap_lookup_uid(struct list_head *hash, int reverse,
			      __u32 uid)
{
	struct list_head *head = &hash[lustre_idmap_hashfunc(uid)];
	struct lustre_idmap_entry *e;

	if (!reverse) {
		list_for_each_entry(e, head, lie_rmt_uid_hash)
			if (e->lie_rmt_uid == uid)
				return e->lie_lcl_uid;
	} else {
		list_for_each_entry(e, head, lie_lcl_uid_hash)
			if (e->lie_lcl_uid == uid)
				return e->lie_rmt_uid;
	}

	return CFS_IDMAP_NOTFOUND;
}

static __u32 idmap_lookup_gid(struct list_head *hash, int reverse, __u32 gid)
{
	struct list_head *head = &hash[lustre_idmap_hashfunc(gid)];
	struct lustre_idmap_entry *e;

	if (!reverse) {
		list_for_each_entry(e, head, lie_rmt_gid_hash)
			if (e->lie_rmt_gid == gid)
				return e->lie_lcl_gid;
	} else {
		list_for_each_entry(e, head, lie_lcl_gid_hash)
			if (e->lie_lcl_gid == gid)
				return e->lie_rmt_gid;
	}

	return CFS_IDMAP_NOTFOUND;
}

int lustre_idmap_add(struct lustre_idmap_table *t,
		     uid_t ruid, uid_t luid,
		     gid_t rgid, gid_t lgid)
{
	struct lustre_idmap_entry *e0, *e1;

	LASSERT(t);

	spin_lock(&t->lit_lock);
	e0 = idmap_search_entry(t, ruid, luid, rgid, lgid);
	spin_unlock(&t->lit_lock);
	if (!e0) {
		e0 = idmap_entry_alloc(ruid, luid, rgid, lgid);
		if (!e0)
			return -ENOMEM;

		spin_lock(&t->lit_lock);
		e1 = idmap_search_entry(t, ruid, luid, rgid, lgid);
		if (e1 == NULL) {
			list_add_tail(&e0->lie_rmt_uid_hash,
					  &t->lit_idmaps[RMT_UIDMAP_IDX]
					  [lustre_idmap_hashfunc(ruid)]);
			list_add_tail(&e0->lie_lcl_uid_hash,
					  &t->lit_idmaps[LCL_UIDMAP_IDX]
					  [lustre_idmap_hashfunc(luid)]);
			list_add_tail(&e0->lie_rmt_gid_hash,
					  &t->lit_idmaps[RMT_GIDMAP_IDX]
					  [lustre_idmap_hashfunc(rgid)]);
			list_add_tail(&e0->lie_lcl_gid_hash,
					  &t->lit_idmaps[LCL_GIDMAP_IDX]
					  [lustre_idmap_hashfunc(lgid)]);
		}
		spin_unlock(&t->lit_lock);
		if (e1 != NULL) {
			idmap_entry_free(e0);
			if (IS_ERR(e1))
				return PTR_ERR(e1);
		}
	} else if (IS_ERR(e0)) {
		return PTR_ERR(e0);
	}

	return 0;
}
EXPORT_SYMBOL(lustre_idmap_add);

int lustre_idmap_del(struct lustre_idmap_table *t,
		    uid_t ruid, uid_t luid,
		    gid_t rgid, gid_t lgid)
{
	struct lustre_idmap_entry *e;
	int rc = 0;

	LASSERT(t);

	spin_lock(&t->lit_lock);
	e = idmap_search_entry(t, ruid, luid, rgid, lgid);
	if (IS_ERR(e))
		rc = PTR_ERR(e);
	else if (e)
		idmap_entry_free(e);
	spin_unlock(&t->lit_lock);

	return rc;
}
EXPORT_SYMBOL(lustre_idmap_del);

int lustre_idmap_lookup_uid(struct lu_ucred *mu,
			    struct lustre_idmap_table *t,
			    int reverse, uid_t uid)
{
	struct list_head *hash;

	if (mu && (mu->uc_valid == UCRED_OLD || mu->uc_valid == UCRED_NEW)) {
		if (!reverse) {
			if (uid == mu->uc_o_uid)
				return mu->uc_uid;
			else if (uid == mu->uc_o_fsuid)
				return mu->uc_fsuid;
		} else {
			if (uid == mu->uc_uid)
				return mu->uc_o_uid;
			else if (uid == mu->uc_fsuid)
				return mu->uc_o_fsuid;
		}
	}

	if (t == NULL)
		return CFS_IDMAP_NOTFOUND;

	hash = t->lit_idmaps[reverse ? LCL_UIDMAP_IDX : RMT_UIDMAP_IDX];

	spin_lock(&t->lit_lock);
	uid = idmap_lookup_uid(hash, reverse, uid);
	spin_unlock(&t->lit_lock);

	return uid;
}
EXPORT_SYMBOL(lustre_idmap_lookup_uid);

int lustre_idmap_lookup_gid(struct lu_ucred *mu, struct lustre_idmap_table *t,
			    int reverse, gid_t gid)
{
	struct list_head *hash;

	if (mu && (mu->uc_valid == UCRED_OLD || mu->uc_valid == UCRED_NEW)) {
		if (!reverse) {
			if (gid == mu->uc_o_gid)
				return mu->uc_gid;
			else if (gid == mu->uc_o_fsgid)
				return mu->uc_fsgid;
		} else {
			if (gid == mu->uc_gid)
				return mu->uc_o_gid;
			else if (gid == mu->uc_fsgid)
				return mu->uc_o_fsgid;
		}
	}

	if (t == NULL)
		return CFS_IDMAP_NOTFOUND;

	hash = t->lit_idmaps[reverse ? LCL_GIDMAP_IDX : RMT_GIDMAP_IDX];

	spin_lock(&t->lit_lock);
	gid = idmap_lookup_gid(hash, reverse, gid);
	spin_unlock(&t->lit_lock);

	return gid;
}
EXPORT_SYMBOL(lustre_idmap_lookup_gid);

struct lustre_idmap_table *lustre_idmap_init(void)
{
	struct lustre_idmap_table *t;
	int i, j;

	OBD_ALLOC_PTR(t);
	if(unlikely(t == NULL))
		return (ERR_PTR(-ENOMEM));

	spin_lock_init(&t->lit_lock);
	for (i = 0; i < ARRAY_SIZE(t->lit_idmaps); i++)
		for (j = 0; j < ARRAY_SIZE(t->lit_idmaps[i]); j++)
			INIT_LIST_HEAD(&t->lit_idmaps[i][j]);

	return t;
}
EXPORT_SYMBOL(lustre_idmap_init);

void lustre_idmap_fini(struct lustre_idmap_table *t)
{
	struct list_head *list;
	struct lustre_idmap_entry *e;
	int i;
	LASSERT(t);

	list = t->lit_idmaps[RMT_UIDMAP_IDX];
	spin_lock(&t->lit_lock);
	for (i = 0; i < CFS_IDMAP_HASHSIZE; i++)
		while (!list_empty(&list[i])) {
			e = list_entry(list[i].next,
					   struct lustre_idmap_entry,
					   lie_rmt_uid_hash);
			idmap_entry_free(e);
		}
	spin_unlock(&t->lit_lock);

	OBD_FREE_PTR(t);
}
EXPORT_SYMBOL(lustre_idmap_fini);
