コード例 #1
0
ファイル: authldaplib.c プロジェクト: zixia/wmail
static int auth_ldap_do3(const char *attrname,
			 const char *user, const char *pass,
			 int (*callback)(struct authinfo *, void *),
			 void *arg, const char *newpass,
			 const char *authaddr)
{
	char *newpass_crypt=0;
	const char *attributes[10], *ldap_attributes[10];
  
	struct timeval timeout;

	LDAPMessage *result;
	LDAPMessage *entry;
	char *filter, *dn;
	int i, j;

	struct authinfo auth;
	char *homeDir=0;
	char *mailDir=0;
	char *userPassword=0;
	char *cryptPassword=0;
	char *cn=0;
	uid_t au;
	gid_t ag;
	int rc;
	char *quota=0;
        int additionalFilter = 0;
        int hasAdditionalFilter = 0;

        hasAdditionalFilter = my_ldap.filter != 0;

	memset(&auth, 0, sizeof(auth));

        if (hasAdditionalFilter)
        {
            /* To add the additional filter, we need to add on the
             * additional size for "(&)" and the other filter.  So
             * filter+3
             */
            additionalFilter = strlen(my_ldap.filter) + 3;
        }

	if ((filter=malloc(additionalFilter+strlen(attrname)+strlen(user)+
			   (my_ldap.domain ? strlen(my_ldap.domain):0)+
			   sizeof ("(=@)"))) == 0)
	{
		perror("malloc");
		return 1;
	}
        strcpy(filter, "\0");

        if (hasAdditionalFilter)
        {
            strcat(filter, "(&");
            strcat(filter, my_ldap.filter);
        }

        strcat(strcat(strcat(strcat(filter, "("), attrname), "="), user);
	if ( my_ldap.domain && my_ldap.domain[0] && strchr(user, '@') == 0 )
		strcat(strcat(filter, "@"), my_ldap.domain);
	strcat(filter, ")");
        
        if (hasAdditionalFilter)
        {
            strcat(filter, ")");
        }

	timeout.tv_sec=my_ldap.timeout;
	timeout.tv_usec=0;

	read_env("LDAP_HOMEDIR", &attributes[0], "", 0, "homeDir");
	read_env("LDAP_MAILDIR", &attributes[1], "", 0, 0);
	read_env("LDAP_FULLNAME", &attributes[2], "", 0, "cn");
	read_env("LDAP_CLEARPW", &attributes[3], "", 0, 0);
	read_env("LDAP_CRYPTPW", &attributes[4], "", 0, 0);
	read_env("LDAP_UID", &attributes[5], "", 0, 0);
	read_env("LDAP_GID", &attributes[6], "", 0, 0);
	attributes[7]=my_ldap.mail;
	read_env("LDAP_MAILDIRQUOTA", &attributes[8], "", 0, 0);

	j=0;
	for (i=0; i<9; i++)
	{
		if (attributes[i])
			ldap_attributes[j++]=attributes[i];
	}

	ldap_attributes[j]=0;

	if (ldaperror(ldap_search_st(my_ldap_fp,
				     (char *)my_ldap.basedn,LDAP_SCOPE_SUBTREE,
				     filter, (char **)ldap_attributes, 0,
				     &timeout, &result)
		      != LDAP_SUCCESS))
	{
		free(filter);

		if (my_ldap_fp)	return (-1);
		return (1);
	}

	free(filter);

	/* If we are more than one result, reject */
	if (ldap_count_entries(my_ldap_fp,result)!=1)
	{
		ldap_msgfree(result);
		return -1;
	}
#if DEBUG_LDAP
	syslog(LOG_DAEMON|LOG_CRIT,"Nombre de résulat:    %d\n",ldap_count_entries(my_ldap_fp,result));
#endif

	dn = ldap_get_dn(my_ldap_fp, result);

#if DEBUG_LDAP
	syslog(LOG_DAEMON|LOG_CRIT,"DN:    %s\n",dn);
#endif

	if (dn == NULL) 
	{
		ldap_perror(my_ldap_fp, "ldap_get_dn");
		return -1;
	}

	/* Get the pointer on this result */
	entry=ldap_first_entry(my_ldap_fp,result);
	if (entry==NULL)
	{
		ldap_perror(my_ldap_fp,"ldap_first_entry");
		free(dn);
		return -1;
	}

#if DEBUG_LDAP
	syslog(LOG_DAEMON|LOG_CRIT,"after ldap_first_entry\n");
#endif
	/* Copy the directory and the password into struct */
	copy_value(my_ldap_fp,entry,attributes[0],&homeDir, user);
	if (attributes[1])
		copy_value(my_ldap_fp,entry,attributes[1],&mailDir, user);
	copy_value(my_ldap_fp,entry,attributes[2],&cn, user);
	if (attributes[3])
		copy_value(my_ldap_fp,entry,attributes[3],&userPassword, user);
	if (attributes[4])
		copy_value(my_ldap_fp,entry,attributes[4],&cryptPassword, user);

	au=my_ldap.uid;
	ag=my_ldap.gid;
	if (attributes[5])
	{
		char *p=0;
		unsigned long n;

		copy_value(my_ldap_fp, entry, attributes[5], &p, user);
		if (p) {
			if (sscanf(p, "%lu", &n) > 0)
				au= (uid_t)n;
			free(p);
		}
#if DEBUG_LDAP
		syslog(LOG_DAEMON|LOG_CRIT,"au= %d\n",au);
#endif
	}

	if (attributes[6])
	{
		char *p=0;
		unsigned long n;

		copy_value(my_ldap_fp, entry, attributes[6], &p, user);
		if (p) {
			if (sscanf(p, "%lu", &n) > 0)
				ag= (gid_t)n;
			free(p);
		}
#if DEBUG_LDAP
		syslog(LOG_DAEMON|LOG_CRIT,"ag= %d\n",ag);
#endif
	}

	if (attributes[8])
		copy_value(my_ldap_fp,entry,attributes[8],&quota, user);

	if (homeDir != 0 && my_ldap.mailroot != 0 && *my_ldap.mailroot)
	{
		char *new_mailroot=malloc(strlen(homeDir)+
					  strlen(my_ldap.mailroot)+2);

		if (!new_mailroot)
		{
			syslog(LOG_DAEMON|LOG_CRIT, "authldap: malloc failed");
			rc= -1;
		}
		else
		{
			strcat(strcat(strcpy(new_mailroot, my_ldap.mailroot),
				      "/"), homeDir);
			free(homeDir);
			homeDir=new_mailroot;
		}
	}

	auth.sysusername=user;
	auth.sysuserid= &au;
	auth.sysgroupid= ag;
	auth.homedir=homeDir;
	auth.address=authaddr;
	auth.fullname=cn;
	auth.maildir=mailDir;
	auth.clearpasswd=userPassword;
	auth.passwd=cryptPassword;
	auth.quota=quota;

	if (auth.sysusername == 0)
		auth.sysusername=auth.address="";

	if (homeDir == 0)
		auth.homedir="";

	rc=0;

	if (au == 0 || ag == 0)
	{
		syslog(LOG_DAEMON|LOG_CRIT,
		       "authlib: refuse to authenticate %s: uid=%d, gid=%d\n",
		       user, au, ag);
		rc= 1;
	}

	if (pass)
	{
		if (my_ldap.authbind) 
		{
			LDAP *bindp=ldapconnect();

			if (!bindp)
				rc=1;
			else
			{
#if HAVE_LDAP_TLS
				if(my_ldap.tls && enable_tls_on(bindp)) {
#if HAVE_SYSLOG_H
					syslog(LOG_DAEMON|LOG_CRIT, "authlib: LDAP_TLS enabled but I'm unable to start tls, check your config\n");
#endif
					rc = 1;
				} else {
#endif
					switch (ldap_simple_bind_s(bindp, dn, (char *)pass))
					{
					case LDAP_SUCCESS:
						break;
					case LDAP_INVALID_CREDENTIALS:
						rc = -1;
						break;
					default:
						rc = 1;
						break;
					}
#if HAVE_LDAP_TLS
				}
#endif
				ldap_unbind(bindp);
			}
			if (rc == 0 && newpass)
			{
				if ((newpass_crypt=authcryptpasswd(newpass,
								   NULL))
				    == 0)
					rc= -1;
			}
		}
		else
		{
			if (auth.clearpasswd)
			{
				if (strcmp(pass,auth.clearpasswd))
					rc= -1;
			}
			else
			{
			const char *p=auth.passwd;

				if (p && strncasecmp(p, "{crypt}", 7) == 0)
					p += 7; /* For authcheckpassword */

				if (!p || authcheckpassword(pass, p))
					rc= -1;
			}

			if (rc == 0 && newpass && auth.passwd)
			{
				if ((newpass_crypt=authcryptpasswd(newpass,
								   auth.passwd)
				     ) == 0)
					rc= -1;
			}
		}
        }

	if (rc == 0 && newpass)
	{
		LDAPMod *mods[3];
		int mod_index=0;

		LDAPMod mod_clear, mod_crypt;
		char *mod_clear_vals[2], *mod_crypt_vals[2];

		if (attributes[3])
		{
			mods[mod_index]= &mod_clear;
			mod_clear.mod_op=LDAP_MOD_REPLACE;
			mod_clear.mod_type=(char *)attributes[3];
			mod_clear.mod_values=mod_clear_vals;

			mod_clear_vals[0]=(char *)newpass;
			mod_clear_vals[1]=NULL;
			++mod_index;
		}

		if (attributes[4] && newpass_crypt)
		{
			mods[mod_index]= &mod_crypt;
			mod_crypt.mod_op=LDAP_MOD_REPLACE;
			mod_crypt.mod_type=(char *)attributes[4];
			mod_crypt.mod_values=mod_crypt_vals;

			mod_crypt_vals[0]=newpass_crypt;
			mod_crypt_vals[1]=NULL;
			++mod_index;
		}
		if (mod_index == 0)
			rc= -1;
		else
		{
			mods[mod_index]=0;

			if (ldap_modify_s(my_ldap_fp, dn, mods))
			{
				rc= -1;
			}
		}
	}

	if (newpass_crypt)
		free(newpass_crypt);
	free (dn);
#if DEBUG_LDAP
	syslog(LOG_DAEMON|LOG_CRIT,"before callback rc=%d\n",rc);
#endif

	if (rc == 0 && callback)
		rc= (*callback)(&auth, arg);
#if DEBUG_LDAP
	syslog(LOG_DAEMON|LOG_CRIT,"after callback rc=%d\n",rc);
#endif

	ldap_msgfree(result);

	if (homeDir)	free(homeDir);
	if (mailDir)	free(mailDir);
	if (userPassword)	free(userPassword);
	if (cryptPassword)	free(cryptPassword);
	if (cn)		free(cn);
	if (quota)	free(quota);
	return (rc);
}
コード例 #2
0
ファイル: authpgsqllib.c プロジェクト: zixia/nospam
int auth_pgsql_setpass(const char *user, const char *pass)
{
	char *newpass_crypt;
	const char *newpass_crypt_ptr;
	const char *p;
	int l;
	char *sql_buf;
	const char *comma;
	int rc=0;

	const char *clear_field=NULL;
	const char *crypt_field=NULL;
	const char *defdomain=NULL;
	const char *where_clause=NULL;
	const char *user_table=NULL;
	const char *login_field=NULL;
	const char *chpass_clause=NULL; /* [email protected] */

	if (!pgconn)
		return (-1);


	if (!(newpass_crypt=authcryptpasswd(pass, "{crypt}")))
		return (-1);

	if (!(newpass_crypt_ptr=strchr(newpass_crypt, '}')))
	{
		free(newpass_crypt);	/* WTF???? */
		return (-1);
	}
	++newpass_crypt_ptr;

	for (l=0, p=pass; *p; p++)
	{
		if ((int)(unsigned char)*p < ' ')
		{
			free(newpass_crypt);
			return (-1);
		}
		if (*p == '"' || *p == '\\')
			++l;
		++l;
	}

	/* [email protected] */
	chpass_clause=read_env("PGSQL_CHPASS_CLAUSE");
	defdomain=read_env("DEFAULT_DOMAIN");
	user_table=read_env("PGSQL_USER_TABLE");
	if (!chpass_clause)
	{
		login_field = read_env("PGSQL_LOGIN_FIELD");
		if (!login_field) login_field = "id";
		crypt_field=read_env("PGSQL_CRYPT_PWFIELD");
		clear_field=read_env("PGSQL_CLEAR_PWFIELD");
		where_clause=read_env("PGSQL_WHERE_CLAUSE");
		sql_buf=malloc(strlen(crypt_field ? crypt_field:"")
			       + strlen(clear_field ? clear_field:"")
			       + strlen(defdomain ? defdomain:"")
			       + strlen(login_field) + l + strlen(newpass_crypt)
			       + strlen(user_table)
			       + strlen(where_clause ? where_clause:"")
			       + 200);
	}
	else
	{
		sql_buf=parse_chpass_clause(chpass_clause,
					    user,
					    defdomain,
					    pass,
					    newpass_crypt_ptr);
	}

	if (!sql_buf)
	{
		free(newpass_crypt);
		return (-1);
	}

	if (!chpass_clause) /* [email protected] */
	{
		sprintf(sql_buf, "UPDATE %s SET", user_table);

		comma="";

		if (clear_field && *clear_field)
		{
			char *q;

			strcat(strcat(strcat(sql_buf, " "), clear_field),
			       "='");

			q=sql_buf+strlen(sql_buf);
			while (*pass)
			{
				if (*pass == '"' || *pass == '\\')
					*q++= '\\';
				*q++ = *pass++;
			}
			strcpy(q, "'");
			comma=", ";
		}

		if (crypt_field && *crypt_field)
		{
			strcat(strcat(strcat(strcat(strcat(strcat(sql_buf, comma),
							   " "),
						    crypt_field),
					     "='"),
				      newpass_crypt_ptr),
			       "'");
		}
		free(newpass_crypt);

		strcat(strcat(strcat(sql_buf, " WHERE "),
			      login_field),
		       "='");

		append_username(sql_buf+strlen(sql_buf), user, defdomain);

		strcat(sql_buf, "'");

		if (where_clause && *where_clause)
		{
			strcat(sql_buf, " AND (");
			strcat(sql_buf, where_clause);
			strcat(sql_buf, ")");
		}

	} /* end of: if (!chpass_clause) */

	pgresult=PQexec (pgconn, sql_buf);
	if (!pgresult || PQresultStatus(pgresult) != PGRES_COMMAND_OK)
	{
		rc= -1;
		auth_pgsql_cleanup();
	}
	PQclear(pgresult);
	free(sql_buf);
	return (rc);
}
コード例 #3
0
ファイル: authmysqllib.c プロジェクト: MhdAlyan/courier
int auth_mysql_setpass(const char *user, const char *pass,
		       const char *oldpass)
{
	char *newpass_crypt;
	char *sql_buf;
	int rc=0;

	char *clear_escaped;
	char *crypt_escaped;

	const char  *clear_field	=NULL,
		    *crypt_field	=NULL,
		    *defdomain		=NULL,
		    *where_clause	=NULL,
		    *user_table		=NULL,
		    *login_field	=NULL,
		    *chpass_clause	=NULL; /* [email protected] */

	if (do_connect())	return (-1);

	if (!(newpass_crypt=authcryptpasswd(pass, oldpass)))
		return (-1);

	clear_escaped=malloc(strlen(pass)*2+1);

	if (!clear_escaped)
	{
		perror("malloc");
		free(newpass_crypt);
		return -1;
	}

	crypt_escaped=malloc(strlen(newpass_crypt)*2+1);

	if (!crypt_escaped)
	{
		perror("malloc");
		free(clear_escaped);
		free(newpass_crypt);
		return -1;
	}

	mysql_real_escape_string(mysql, clear_escaped, pass, strlen(pass));
	mysql_real_escape_string(mysql, crypt_escaped,
				 newpass_crypt, strlen(newpass_crypt));

	/* [email protected] */
	chpass_clause=read_env("MYSQL_CHPASS_CLAUSE");
	defdomain=read_env("DEFAULT_DOMAIN");
	user_table=read_env("MYSQL_USER_TABLE");
	if (!chpass_clause)
	{
		int has_domain=strchr(user, '@') != NULL;
		char *username_escaped;
		char dummy_buf[1];
		size_t sql_buf_size;

		username_escaped=malloc(strlen(user)*2+1);

		if (!username_escaped)
		{
			perror("malloc");
			free(clear_escaped);
			free(crypt_escaped);
			free(newpass_crypt);
			return -1;
		}

		mysql_real_escape_string(mysql, username_escaped,
					 user, strlen(user));

		login_field = read_env("MYSQL_LOGIN_FIELD");
		if (!login_field) login_field = "id";
		crypt_field=read_env("MYSQL_CRYPT_PWFIELD");
		clear_field=read_env("MYSQL_CLEAR_PWFIELD");
		where_clause=read_env("MYSQL_WHERE_CLAUSE");

		if (!where_clause)
			where_clause="";

		if (!crypt_field)
			crypt_field="";

		if (!clear_field)
			clear_field="";

		if (!defdomain)
			defdomain="";

#define DEFAULT_SETPASS_UPDATE \
		"UPDATE %s SET %s%s%s%s %s %s%s%s%s WHERE %s='%s%s%s' %s%s%s", \
			user_table,					\
			*clear_field ? clear_field:"",			\
			*clear_field ? "='":"",				\
			*clear_field ? clear_escaped:"",		\
			*clear_field ? "'":"",				\
									\
			*clear_field && *crypt_field ? ",":"",		\
									\
			*crypt_field ? crypt_field:"",			\
			*crypt_field ? "='":"",				\
			*crypt_field ? crypt_escaped:"",		\
			*crypt_field ? "'":"",				\
			login_field,					\
			username_escaped,				\
			has_domain || !*defdomain ? "":"@",		\
			has_domain ? "":defdomain,			\
			*where_clause ? " AND (":"", where_clause,	\
			*where_clause ? ")":""


		sql_buf_size=snprintf(dummy_buf, 1, DEFAULT_SETPASS_UPDATE);

		sql_buf=malloc(sql_buf_size+1);

		if (sql_buf)
			snprintf(sql_buf, sql_buf_size+1,
				 DEFAULT_SETPASS_UPDATE);

		free(username_escaped);
	}
	else
	{
		sql_buf=parse_chpass_clause(chpass_clause,
					    user,
					    defdomain,
					    clear_escaped,
					    crypt_escaped);
	}
	
	free(clear_escaped);
	free(crypt_escaped);
	free(newpass_crypt);

	if (courier_authdebug_login_level >= 2)
	{
		DPRINTF("setpass SQL: %s", sql_buf);
	}
	if (mysql_query (mysql, sql_buf))
	{
		DPRINTF("setpass SQL failed");
		rc= -1;
		auth_mysql_cleanup();
	}
	free(sql_buf);
	return (rc);
}