diff -r b774480aa8c8 doc/example.conf
--- a/doc/example.conf	Sat Aug 25 18:19:06 2012 +0300
+++ b/doc/example.conf	Tue Oct 02 15:14:37 2012 +0200
@@ -161,10 +161,12 @@
  * Syntax:
  * allow channel {
  *   channel "channel name";
+ *   class "clients"; (optional)
  * };
  */
-allow           channel {
+allow channel {
 	channel "#WarezSucks";
+	class "clients";
 };
 
 /*
@@ -710,11 +712,13 @@
  * deny channel {
  * 	channel "(channel)";
  * 	reason "reason";
+ *      class "clients"; (optional)
  * };
 */
 deny channel {
 	channel "*warez*";
 	reason "Warez is illegal";
+	class "clients";
 };
 
 /*
diff -r b774480aa8c8 include/h.h
--- a/include/h.h	Sat Aug 25 18:19:06 2012 +0300
+++ b/include/h.h	Tue Oct 02 15:14:37 2012 +0200
@@ -130,7 +130,7 @@
 ConfigItem_ban 		*Find_ban(aClient *, char *host, short type);
 ConfigItem_ban 		*Find_banEx(aClient *,char *host, short type, short type2);
 ConfigItem_vhost	*Find_vhost(char *name);
-ConfigItem_deny_channel *Find_channel_allowed(char *name);
+ConfigItem_deny_channel *Find_channel_allowed(aClient *cptr, char *name);
 ConfigItem_alias	*Find_alias(char *name);
 ConfigItem_help 	*Find_Help(char *command);
 int			AllowClient(aClient *cptr, struct hostent *hp, char *sockhost, char *username);
diff -r b774480aa8c8 include/struct.h
--- a/include/struct.h	Sat Aug 25 18:19:06 2012 +0300
+++ b/include/struct.h	Tue Oct 02 15:14:37 2012 +0200
@@ -1380,14 +1380,14 @@
 struct _configitem_deny_channel {
 	ConfigItem		*prev, *next;
 	ConfigFlag		flag;
-	char			*channel, *reason, *redirect;
+	char			*channel, *reason, *redirect, *class;
 	unsigned char	warn;
 };
 
 struct _configitem_allow_channel {
 	ConfigItem		*prev, *next;
 	ConfigFlag		flag;
-	char			*channel;
+	char			*channel, *class;
 };
 
 struct _configitem_allow_dcc {
diff -r b774480aa8c8 src/modules/m_join.c
--- a/src/modules/m_join.c	Sat Aug 25 18:19:06 2012 +0300
+++ b/src/modules/m_join.c	Tue Oct 02 15:14:37 2012 +0200
@@ -649,7 +649,7 @@
 				if (!IsOper(sptr) && !IsULine(sptr))
 				{
 					ConfigItem_deny_channel *d;
-					if ((d = Find_channel_allowed(name)))
+					if ((d = Find_channel_allowed(cptr, name)))
 					{
 						if (d->warn)
 						{
@@ -669,6 +669,11 @@
 							parv[1] = d->redirect;
 							do_join(cptr, sptr, 2, parv);
 						}
+						if (d->class) {
+							sendto_one(sptr,
+							":%s %s %s :*** Can not join %s: Your class is not allowed",
+							me.name, IsWebTV(sptr) ? "PRIVMSG" : "NOTICE", sptr->name, name);
+						}
 						continue;
 					}
 				}
diff -r b774480aa8c8 src/s_conf.c
--- a/src/s_conf.c	Sat Aug 25 18:19:06 2012 +0300
+++ b/src/s_conf.c	Tue Oct 02 15:14:37 2012 +0200
@@ -2278,6 +2278,7 @@
 		ircfree(deny_channel_ptr->redirect);
 		ircfree(deny_channel_ptr->channel);
 		ircfree(deny_channel_ptr->reason);
+		ircfree(deny_channel_ptr->class);
 		DelListItem(deny_channel_ptr, conf_deny_channel);
 		MyFree(deny_channel_ptr);
 	}
@@ -2286,6 +2287,7 @@
 	{
 		next = (ListStruct *)allow_channel_ptr->next;
 		ircfree(allow_channel_ptr->channel);
+		ircfree(allow_channel_ptr->class);
 		DelListItem(allow_channel_ptr, conf_allow_channel);
 		MyFree(allow_channel_ptr);
 	}
@@ -3050,21 +3052,21 @@
 
 
 /** returns NULL if allowed and struct if denied */
-ConfigItem_deny_channel *Find_channel_allowed(char *name)
+ConfigItem_deny_channel *Find_channel_allowed(aClient *cptr, char *name)
 {
 	ConfigItem_deny_channel *dchannel;
 	ConfigItem_allow_channel *achannel;
 
 	for (dchannel = conf_deny_channel; dchannel; dchannel = (ConfigItem_deny_channel *)dchannel->next)
 	{
-		if (!match(dchannel->channel, name))
+		if (!match(dchannel->channel, name) && (dchannel->class ? !strcmp(cptr->class->name, dchannel->class) : 1))
 			break;
 	}
 	if (dchannel)
 	{
 		for (achannel = conf_allow_channel; achannel; achannel = (ConfigItem_allow_channel *)achannel->next)
 		{
-			if (!match(achannel->channel, name))
+			if (!match(achannel->channel, name) && (achannel->class ? !strcmp(cptr->class->name, achannel->class) : 1))
 				break;
 		}
 		if (achannel)
@@ -5089,15 +5091,19 @@
 	ConfigItem_allow_channel 	*allow = NULL;
 	ConfigEntry 	    	*cep;
 
+	allow = MyMallocEx(sizeof(ConfigItem_allow_channel));
 	for (cep = ce->ce_entries; cep; cep = cep->ce_next)
 	{
 		if (!strcmp(cep->ce_varname, "channel"))
 		{
-			allow = MyMallocEx(sizeof(ConfigItem_allow_channel));
 			ircstrdup(allow->channel, cep->ce_vardata);
-			AddListItem(allow, conf_allow_channel);
-		}
-	}
+		}
+		else if (!strcmp(cep->ce_varname, "class"))
+		{
+			ircstrdup(allow->class, cep->ce_vardata);
+		}
+	}
+	AddListItem(allow, conf_allow_channel);
 	return 1;
 }
 
@@ -5105,7 +5111,7 @@
 {
 	ConfigEntry		*cep;
 	int			errors = 0;
-	char			has_channel = 0;	
+	char			has_channel = 0, has_class = 0;
 	for (cep = ce->ce_entries; cep; cep = cep->ce_next)
 	{
 		if (config_is_blankorempty(cep, "allow channel"))
@@ -5113,8 +5119,22 @@
 			errors++;
 			continue;
 		}
+
 		if (!strcmp(cep->ce_varname, "channel"))
+		{
 			has_channel = 1;
+		}	
+		else if (!strcmp(cep->ce_varname, "class"))
+		{
+
+			if (has_class)
+			{
+				config_warn_duplicate(cep->ce_fileptr->cf_filename,
+					cep->ce_varlinenum, "allow channel::class");
+				continue;
+			}
+			has_class = 1;
+		}
 		else
 		{
 			config_error_unknown(cep->ce_fileptr->cf_filename, cep->ce_varlinenum,
@@ -9274,6 +9294,10 @@
 		{
 			deny->warn = config_checkval(cep->ce_vardata,CFG_YESNO);
 		}
+		else if (!strcmp(cep->ce_varname, "class"))
+		{
+			ircstrdup(deny->class, cep->ce_vardata);
+		}
 	}
 	AddListItem(deny, conf_deny_channel);
 	return 0;
@@ -9405,7 +9429,7 @@
 	}
 	else if (!strcmp(ce->ce_vardata, "channel"))
 	{
-		char has_channel = 0, has_warn = 0, has_reason = 0, has_redirect = 0;
+		char has_channel = 0, has_warn = 0, has_reason = 0, has_redirect = 0, has_class = 0;
 		for (cep = ce->ce_entries; cep; cep = cep->ce_next)
 		{
 			if (config_is_blankorempty(cep, "deny channel"))
@@ -9453,6 +9477,16 @@
 				}
 				has_warn = 1;
 			}
+			else if (!strcmp(cep->ce_varname, "class"))
+			{
+				if (has_class)
+				{
+					config_warn_duplicate(cep->ce_fileptr->cf_filename,
+						cep->ce_varlinenum, "deny channel::class");
+					continue;
+				}
+				has_class = 1;
+			}
 			else 
 			{
 				config_error_unknown(cep->ce_fileptr->cf_filename, 
diff -r b774480aa8c8 src/s_extra.c
--- a/src/s_extra.c	Sat Aug 25 18:19:06 2012 +0300
+++ b/src/s_extra.c	Tue Oct 02 15:14:37 2012 +0200
@@ -264,7 +264,7 @@
 		return 1;
 	if (!conf_deny_channel)
 		return 1;
-	p = Find_channel_allowed(name);
+	p = Find_channel_allowed(sptr, name);
 	if (p)
 	{
 		sendto_one(sptr, ":%s NOTICE %s :*** %s",
