/*
 * User authentication & authorization
 *
 * Copyright 2010 Krzysztof Piotr Oledzki <ole@ans.pl>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version
 * 2 of the License, or (at your option) any later version.
 *
 */

#ifdef CONFIG_HAP_CRYPT
/* This is to have crypt() defined on Linux */
#define _GNU_SOURCE

#ifdef NEED_CRYPT_H
/* some platforms such as Solaris need this */
#include <crypt.h>
#endif
#endif /* CONFIG_HAP_CRYPT */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include <types/global.h>
#include <common/config.h>
#include <common/errors.h>
#include <common/hathreads.h>

#include <proto/acl.h>
#include <proto/log.h>

#include <types/auth.h>
#include <types/pattern.h>

struct userlist *userlist = NULL;    /* list of all existing userlists */

#ifdef CONFIG_HAP_CRYPT
#ifdef HA_HAVE_CRYPT_R
/* context for crypt_r() */
static THREAD_LOCAL struct crypt_data crypt_data = { .initialized = 0 };
#else
/* lock for crypt() */
__decl_hathreads(static HA_SPINLOCK_T auth_lock);
#endif
#endif

/* find targets for selected gropus. The function returns pointer to
 * the userlist struct ot NULL if name is NULL/empty or unresolvable.
 */

struct userlist *
auth_find_userlist(char *name)
{
	struct userlist *l;

	if (!name || !*name)
		return NULL;

	for (l = userlist; l; l = l->next)
		if (!strcmp(l->name, name))
			return l;

	return NULL;
}

int check_group(struct userlist *ul, char *name)
{
	struct auth_groups *ag;

	for (ag = ul->groups; ag; ag = ag->next)
		if (strcmp(name, ag->name) == 0)
			return 1;
	return 0;
}

void
userlist_free(struct userlist *ul)
{
	struct userlist *tul;
	struct auth_users *au, *tau;
	struct auth_groups_list *agl, *tagl;
	struct auth_groups *ag, *tag;

	while (ul) {
		/* Free users. */
		au = ul->users;
		while (au) {
			/* Free groups that own current user. */
			agl = au->u.groups;
			while (agl) {
				tagl = agl;
				agl = agl->next;
				free(tagl);
			}

			tau = au;
			au = au->next;
			free(tau->user);
			free(tau->pass);
			free(tau);
		}

		/* Free grouplist. */
		ag = ul->groups;
		while (ag) {
			tag = ag;
			ag = ag->next;
			free(tag->name);
			free(tag);
		}

		tul = ul;
		ul = ul->next;
		free(tul->name);
		free(tul);
	};
}

int userlist_postinit()
{
	struct userlist *curuserlist = NULL;

	/* Resolve usernames and groupnames. */
	for (curuserlist = userlist; curuserlist; curuserlist = curuserlist->next) {
		struct auth_groups *ag;
		struct auth_users *curuser;
		struct auth_groups_list *grl;

		for (curuser = curuserlist->users; curuser; curuser = curuser->next) {
			char *group = NULL;
			struct auth_groups_list *groups = NULL;

			if (!curuser->u.groups_names)
				continue;

			while ((group = strtok(group?NULL:curuser->u.groups_names, ","))) {
				for (ag = curuserlist->groups; ag; ag = ag->next) {
					if (!strcmp(ag->name, group))
						break;
				}

				if (!ag) {
					ha_alert("userlist '%s': no such group '%s' specified in user '%s'\n",
						 curuserlist->name, group, curuser->user);
					free(groups);
					return ERR_ALERT | ERR_FATAL;
				}

				/* Add this group at the group userlist. */
				grl = calloc(1, sizeof(*grl));
				if (!grl) {
					ha_alert("userlist '%s': no more memory when trying to allocate the user groups.\n",
						 curuserlist->name);
					free(groups);
					return ERR_ALERT | ERR_FATAL;
				}

				grl->group = ag;
				grl->next = groups;
				groups = grl;
			}

			free(curuser->u.groups);
			curuser->u.groups = groups;
		}

		for (ag = curuserlist->groups; ag; ag = ag->next) {
			char *user = NULL;

			if (!ag->groupusers)
				continue;

			while ((user = strtok(user?NULL:ag->groupusers, ","))) {
				for (curuser = curuserlist->users; curuser; curuser = curuser->next) {
					if (!strcmp(curuser->user, user))
						break;
				}

				if (!curuser) {
					ha_alert("userlist '%s': no such user '%s' specified in group '%s'\n",
						 curuserlist->name, user, ag->name);
					return ERR_ALERT | ERR_FATAL;
				}

				/* Add this group at the group userlist. */
				grl = calloc(1, sizeof(*grl));
				if (!grl) {
					ha_alert("userlist '%s': no more memory when trying to allocate the user groups.\n",
						 curuserlist->name);
					return  ERR_ALERT | ERR_FATAL;
				}

				grl->group = ag;
				grl->next = curuser->u.groups;
				curuser->u.groups = grl;
			}

			free(ag->groupusers);
			ag->groupusers = NULL;
		}

#ifdef DEBUG_AUTH
		for (ag = curuserlist->groups; ag; ag = ag->next) {
			struct auth_groups_list *agl;

			fprintf(stderr, "group %s, id %p, users:", ag->name, ag);
			for (curuser = curuserlist->users; curuser; curuser = curuser->next) {
				for (agl = curuser->u.groups; agl; agl = agl->next) {
					if (agl->group == ag)
						fprintf(stderr, " %s", curuser->user);
				}
			}
			fprintf(stderr, "\n");
		}
#endif
	}

	return ERR_NONE;
}

/*
 * Authenticate and authorize user; return 1 if OK, 0 if case of error.
 */
int
check_user(struct userlist *ul, const char *user, const char *pass)
{

	struct auth_users *u;
#ifdef DEBUG_AUTH
	struct auth_groups_list *agl;
#endif
	const char *ep;

#ifdef DEBUG_AUTH
	fprintf(stderr, "req: userlist=%s, user=%s, pass=%s\n",
	        ul->name, user, pass);
#endif

	for (u = ul->users; u; u = u->next)
		if (!strcmp(user, u->user))
			break;

	if (!u)
		return 0;

#ifdef DEBUG_AUTH
	fprintf(stderr, "cfg: user=%s, pass=%s, flags=%X, groups=",
		u->user, u->pass, u->flags);
	for (agl = u->u.groups; agl; agl = agl->next)
		fprintf(stderr, " %s", agl->group->name);
#endif

	if (!(u->flags & AU_O_INSECURE)) {
#ifdef CONFIG_HAP_CRYPT
#ifdef HA_HAVE_CRYPT_R
		ep = crypt_r(pass, u->pass, &crypt_data);
#else
		HA_SPIN_LOCK(AUTH_LOCK, &auth_lock);
		ep = crypt(pass, u->pass);
		HA_SPIN_UNLOCK(AUTH_LOCK, &auth_lock);
#endif
#else
		return 0;
#endif
	} else
		ep = pass;

#ifdef DEBUG_AUTH
	fprintf(stderr, ", crypt=%s\n", ep);
#endif

	if (ep && strcmp(ep, u->pass) == 0)
		return 1;
	else
		return 0;
}

struct pattern *
pat_match_auth(struct sample *smp, struct pattern_expr *expr, int fill)
{
	struct userlist *ul = smp->ctx.a[0];
	struct pattern_list *lst;
	struct auth_users *u;
	struct auth_groups_list *agl;
	struct pattern *pattern;

	/* Check if the userlist is present in the context data. */
	if (!ul)
		return NULL;

	/* Browse the userlist for searching user. */
	for (u = ul->users; u; u = u->next) {
		if (strcmp(smp->data.u.str.area, u->user) == 0)
			break;
	}
	if (!u)
		return NULL;

	/* Browse each pattern. */
	list_for_each_entry(lst, &expr->patterns, list) {
		pattern = &lst->pat;

		/* Browse each group for searching group name that match the pattern. */
		for (agl = u->u.groups; agl; agl = agl->next) {
			if (strcmp(agl->group->name, pattern->ptr.str) == 0)
				return pattern;
		}
	}
	return NULL;
}

__attribute__((constructor))
static void __auth_init(void)
{
	hap_register_build_opts("Encrypted password support via crypt(3): yes", 0);
}
