Пример #1
0
GList *find_dangling_aliases(const char * const name)
{
	int result;
	char *username;
	GList *uids = NULL;
	GList *fwds = NULL;
	GList *dangling = NULL;

	/* For each alias, figure out if it resolves to a valid user
	 * or some forwarding address. If neither, remove it. */

	result = auth_check_user_ext(name,&uids,&fwds,0);
	
	if (!result) {
		qerrorf("Nothing found searching for [%s].\n", name);
		serious_errors = 1;
		return dangling;
	}

	uids = g_list_first(uids);
	while (uids) {
		username = auth_get_userid(*(u64_t *)uids->data);
		if (!username)
			dangling = g_list_prepend(dangling, uids->data);

		g_free(username);
		if (! g_list_next(uids))
			break;
		uids = g_list_next(uids);
	}

	return dangling;
}
Пример #2
0
int auth_check_user_ext(const char *username, GList **userids, GList **fwds, int checks)
{
	int occurences = 0;
	GList *d = NULL;
	char *endptr;
	uint64_t id, *uid;

	if (checks > 20) {
		TRACE(TRACE_ERR,"too many checks. Possible loop detected.");
		return 0;
	}

	TRACE(TRACE_DEBUG, "[%d] checking user [%s] in alias table", checks, username);

	d = user_get_deliver_to(username);

	if (! d) {
		if (checks == 0) {
			TRACE(TRACE_DEBUG, "user %s not in aliases table", username);
			return 0;
		}
		/* found the last one, this is the deliver to
		 * but checks needs to be bigger then 0 because
		 * else it could be the first query failure */
		id = strtoull(username, &endptr, 10);
		if (*endptr == 0) {
			/* numeric deliver-to --> this is a userid */
			uid = g_new0(uint64_t,1);
			*uid = id;
			*(GList **)userids = g_list_prepend(*(GList **)userids, uid);

		} else {
			*(GList **)fwds = g_list_prepend(*(GList **)fwds, g_strdup(username));
		}
		TRACE(TRACE_DEBUG, "adding [%s] to deliver_to address", username);
		return 1;
	} 

	while (d) {
		/* do a recursive search for deliver_to */
		char *deliver_to = (char *)d->data;
		TRACE(TRACE_DEBUG, "checking user %s to %s", username, deliver_to);

		occurences += auth_check_user_ext(deliver_to, userids, fwds, checks+1);

		if (! g_list_next(d)) break;
		d = g_list_next(d);
	}

	g_list_destroy(d);

	return occurences;
}
Пример #3
0
int auth_check_user_ext(const char *address, GList **userids, GList **fwds, int checks)
{
	int occurences = 0;
	u64_t id, *uid;
	char *endptr = NULL;
	char *query;
	const char *fields[] = { 
		_ldap_cfg.field_nid, 
		_ldap_cfg.field_fwdtarget[0] ? _ldap_cfg.field_fwdtarget : NULL, 
		NULL 
	};
	char *attrvalue;
	GList *entlist, *fldlist, *attlist, *searchlist;

	if (checks > 20) {
		TRACE(TRACE_ERR, "too many checks. Possible loop detected.");
		return 0;
	}

	TRACE(TRACE_DEBUG, "checking user [%s] in alias table", address);
 	if (strlen(_ldap_cfg.query_string)==0) {
 		/* build a mail filter, with multiple attributes, if needed */
 		GString *f = g_string_new(_ldap_cfg.field_mail);
 		searchlist = g_string_split(f,",");
 		g_string_free(f,TRUE);
 	
 		GString *t = g_string_new("");
 		GString *q = g_string_new("");
 		GList *l = NULL;
 		searchlist = g_list_first(searchlist);
 		while(searchlist) {
 			g_string_printf(t,"%s=%s",(char *)searchlist->data,address);
 			l = g_list_append(l,g_strdup(t->str));
 			if(!g_list_next(searchlist))
 				break;
 			searchlist = g_list_next(searchlist);	
 		}
  
 		t = g_list_join(l,")(");
 		g_string_printf(q,"(|(%s))", t->str);
 		query = q->str;
 		g_string_free(t,TRUE);
 		g_string_free(q,FALSE);
 		g_list_foreach(l,(GFunc)g_free,NULL);
 		g_list_free(l);	
 	} else {
 		int i;
 		GString *q = g_string_new("");
 		for (i = 0; _ldap_cfg.query_string[i] != '\0'; i++) {
 			if (_ldap_cfg.query_string[i]=='%' && _ldap_cfg.query_string[i+1] && _ldap_cfg.query_string[i+1]=='s') {
 				g_string_append(q,address);
 				i++;
 			} else {
 				g_string_append_c(q,_ldap_cfg.query_string[i]);
 			}
 		}	
 		query = q->str;
 		g_string_free(q,FALSE);
 	}
 
	TRACE(TRACE_DEBUG, "searching with query [%s], checks [%d]", query, checks);

	entlist = __auth_get_every_match(query, fields);
	g_free(query);

	if (g_list_length(entlist) < 1) {
		if (checks > 0) {
			/* found the last one, this is the deliver to
			 * but checks needs to be bigger then 0 because
			 * else it could be the first query failure */

			id = strtoull(address, &endptr, 10);
			if (*endptr == 0) { /* numeric deliver-to --> this is a userid */
				TRACE(TRACE_DEBUG, "adding [%llu] to userids", id);
				uid = g_new0(u64_t,1);
				*uid = id;
				*(GList **)userids = g_list_prepend(*(GList **)userids, uid);
			} else {
				TRACE(TRACE_DEBUG, "adding [%s] to forwards", address);
				*(GList **)fwds = g_list_prepend(*(GList **)fwds, g_strdup(address));
			}
			return 1;
		} else {
			TRACE(TRACE_DEBUG, "user [%s] not in aliases table", address);
			dm_ldap_freeresult(entlist);
			return 0;
		}
	}

	TRACE(TRACE_DEBUG, "into checking loop");
	entlist = g_list_first(entlist);
	while (entlist) {
		fldlist = g_list_first(entlist->data);
		while(fldlist) {
			attlist = g_list_first(fldlist->data);
			while(attlist) {
				attrvalue = (char *)attlist->data;
				occurences += auth_check_user_ext(attrvalue, userids, fwds, checks+1);
				
				if (! g_list_next(attlist))
					break;
				attlist = g_list_next(attlist);
			}
			if (! g_list_next(fldlist))
				break;
			fldlist = g_list_next(fldlist);
		}
		if (! g_list_next(entlist))
			break;
		entlist = g_list_next(entlist);
	}
	dm_ldap_freeresult(entlist);
	return occurences;
}