<commit_before>/* Copyright (C) 2002 <NAME> */

#include "config.h"
#undef HAVE_CONFIG_H

#ifdef USERINFO_PASSWD_FILE

#include "userinfo-passwd.h"

#include "buffer.h"
#include "istream.h"
#include "hash.h"
#include "hex-binary.h"
#include "md5.h"
#include "mycrypt.h"

#include <stdlib.h>
#include <fcntl.h>
#include <sys/stat.h>

struct passwd_file {
	pool_t pool;

	char *path;
	time_t stamp;
	int fd;

	struct hash_table *users;
};

enum password_type {
	PASSWORD_DES,
	PASSWORD_MD5,
	PASSWORD_DIGEST_MD5
};

struct passwd_user {
	char *user_realm; /* user:realm */
	const char *realm; /* NULL or points to user_realm */
	char *password;
	char *home;
	char *mail;

	uid_t uid;
	gid_t gid;

	enum password_type password_type;
	unsigned int chroot:1;
};

static struct passwd_file *passwd_file;

static void passwd_file_sync(void);

static int get_reply_data(struct passwd_user *pu,
			  struct auth_cookie_reply_data *reply)
{
	const char *user;
	struct passwd *pw;

	if (pu->uid == 0 || pu->gid == 0 ||
	    (pu->home == NULL && pu->mail == NULL)) {
		/* all required information was not set in passwd file,
		   check from system's passwd */
		user = pu->realm == NULL ? pu->user_realm :
			t_strndup(pu->user_realm, strlen(pu->user_realm) -
				  strlen(pu->realm) - 1);

		pw = getpwnam(user);
		if (pw == NULL)
			return FALSE;

		passwd_fill_cookie_reply(pw, reply);
	}

	if (pu->uid != 0)
		reply->uid = pu->uid;
	if (pu->gid != 0)
		reply->gid = pu->gid;

	if (pu->home != NULL) {
		if (strocpy(reply->home, pu->home, sizeof(reply->home)) < 0)
			i_panic("home overflow");
	}

	if (pu->mail != NULL) {
		if (strocpy(reply->mail, pu->mail, sizeof(reply->mail)) < 0)
			i_panic("mail overflow");
	}

	if (strocpy(reply->virtual_user, pu->user_realm,
		    sizeof(reply->virtual_user)) < 0)
		i_panic("virtual_user overflow");

	if (pu->realm != NULL) {
		/* @UNSAFE: ':' -> '@' to make it look prettier */
		size_t pos;

		pos = (size_t) (pu->realm - (const char *) pu->user_realm);
		reply->virtual_user[pos-1] = '@';
	}

	reply->chroot = pu->chroot;
	return TRUE;
}

static int passwd_file_verify_plain(const char *user, const char *password,
				    struct auth_cookie_reply_data *reply)
{
	struct passwd_user *pu;
	const char *const *tmp;
	unsigned char digest[16];
	const char *str;

	passwd_file_sync();

	/* find it from all realms */
	pu = hash_lookup(passwd_file->users, user);
	if (pu == NULL) {
		t_push();
		for (tmp = auth_realms; *tmp != NULL; tmp++) {
                        str = t_strconcat(user, ":", *tmp, NULL);
			pu = hash_lookup(passwd_file->users, str);
		}
		t_pop();
	}

	if (pu == NULL)
		return FALSE;

	/* verify that password matches */
	switch (pu->password_type) {
	case PASSWORD_DES:
		if (strcmp(mycrypt(password, pu->password), pu->password) != 0)
			return FALSE;
		break;
	case PASSWORD_MD5:
		md5_get_digest(password, strlen(password), digest);<commit_msg>Don't try looking for plaintext user from all realms. It didn't seem to work before and it's probably not a good idea.<commit_after>/* Copyright (C) 2002 <NAME> */

#include "config.h"
#undef HAVE_CONFIG_H

#ifdef USERINFO_PASSWD_FILE

#include "userinfo-passwd.h"

#include "buffer.h"
#include "istream.h"
#include "hash.h"
#include "hex-binary.h"
#include "md5.h"
#include "mycrypt.h"

#include <stdlib.h>
#include <fcntl.h>
#include <sys/stat.h>

struct passwd_file {
	pool_t pool;

	char *path;
	time_t stamp;
	int fd;

	struct hash_table *users;
};

enum password_type {
	PASSWORD_DES,
	PASSWORD_MD5,
	PASSWORD_DIGEST_MD5
};

struct passwd_user {
	char *user_realm; /* user:realm */
	const char *realm; /* NULL or points to user_realm */
	char *password;
	char *home;
	char *mail;

	uid_t uid;
	gid_t gid;

	enum password_type password_type;
	unsigned int chroot:1;
};

static struct passwd_file *passwd_file;

static void passwd_file_sync(void);

static int get_reply_data(struct passwd_user *pu,
			  struct auth_cookie_reply_data *reply)
{
	const char *user;
	struct passwd *pw;

	if (pu->uid == 0 || pu->gid == 0 ||
	    (pu->home == NULL && pu->mail == NULL)) {
		/* all required information was not set in passwd file,
		   check from system's passwd */
		user = pu->realm == NULL ? pu->user_realm :
			t_strndup(pu->user_realm, strlen(pu->user_realm) -
				  strlen(pu->realm) - 1);

		pw = getpwnam(user);
		if (pw == NULL)
			return FALSE;

		passwd_fill_cookie_reply(pw, reply);
	}

	if (pu->uid != 0)
		reply->uid = pu->uid;
	if (pu->gid != 0)
		reply->gid = pu->gid;

	if (pu->home != NULL) {
		if (strocpy(reply->home, pu->home, sizeof(reply->home)) < 0)
			i_panic("home overflow");
	}

	if (pu->mail != NULL) {
		if (strocpy(reply->mail, pu->mail, sizeof(reply->mail)) < 0)
			i_panic("mail overflow");
	}

	if (strocpy(reply->virtual_user, pu->user_realm,
		    sizeof(reply->virtual_user)) < 0)
		i_panic("virtual_user overflow");

	if (pu->realm != NULL) {
		/* @UNSAFE: ':' -> '@' to make it look prettier */
		size_t pos;

		pos = (size_t) (pu->realm - (const char *) pu->user_realm);
		reply->virtual_user[pos-1] = '@';
	}

	reply->chroot = pu->chroot;
	return TRUE;
}

static int passwd_file_verify_plain(const char *user, const char *password,
				    struct auth_cookie_reply_data *reply)
{
	struct passwd_user *pu;
	unsigned char digest[16];
	const char *str;

	passwd_file_sync();

	/* find it from all realms */
	pu = hash_lookup(passwd_file->users, user);
	if (pu == NULL)
		return FALSE;

	/* verify that password matches */
	switch (pu->password_type) {
	case PASSWORD_DES:
		if (strcmp(mycrypt(password, pu->password), pu->password) != 0)
			return FALSE;
		break;
	case PASSWORD_MD5:
		md5_get_digest(password, strlen(password), digest);
{'fraction_non_alphanumeric': 0.1539003345659447, 'fraction_numerical': 0.007747842930093327, 'mean_word_length': 3.781144781144781, 'pattern_counts': {'":': 1, '<': 17, '<?xml version=': 0, '>': 86, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3080404', 'n_tokens_mistral': 2355, 'n_tokens_neox': 2171, 'n_words': 546}