diff -ur nagios-2.5.org/base/notifications.c nagios-2.5/base/notifications.c
--- nagios-2.5.org/base/notifications.c	2006-04-07 18:24:13.000000000 -0400
+++ nagios-2.5/base/notifications.c	2006-11-05 22:23:57.000000000 -0500
@@ -832,7 +832,7 @@
 		/* find all contacts for this service */
 		for(temp_contact=contact_list;temp_contact!=NULL;temp_contact=temp_contact->next){
 		
-			if(is_contact_for_service(svc,temp_contact)==TRUE)
+			if(is_contact_for_service_perm(svc,temp_contact,'n')==TRUE)
 				add_notification(temp_contact);
 	                }
 	        }
@@ -1572,7 +1572,7 @@
 		/* get all contacts for this host */
 		for(temp_contact=contact_list;temp_contact!=NULL;temp_contact=temp_contact->next){
 
-			if(is_contact_for_host(hst,temp_contact)==TRUE)
+			if(is_contact_for_host_perm(hst,temp_contact,'n')==TRUE)
 				add_notification(temp_contact);
 		        }
 	        }
diff -ur nagios-2.5.org/cgi/cgiauth.c nagios-2.5/cgi/cgiauth.c
--- nagios-2.5.org/cgi/cgiauth.c	2006-10-08 19:35:18.000000000 -0400
+++ nagios-2.5/cgi/cgiauth.c	2006-11-05 22:55:28.000000000 -0500
@@ -218,7 +218,7 @@
 	temp_contact=find_contact(authinfo->username);
 
 	/* see if this user is a contact for the host */
-	if(is_contact_for_host(hst,temp_contact)==TRUE)
+	if(is_contact_for_host_perm(hst,temp_contact,'r')==TRUE)
 		return TRUE;
 
 	/* see if this user is an escalated contact for the host */
@@ -295,14 +295,14 @@
 		return FALSE;
 
 	/* if this user is authorized for this host, they are for all services on it as well... */
-	if(is_authorized_for_host(temp_host,authinfo)==TRUE)
-		return TRUE;
+	/* if(is_authorized_for_host(temp_host,authinfo)==TRUE)
+		return TRUE;*/
 
 	/* find the contact */
 	temp_contact=find_contact(authinfo->username);
 
 	/* see if this user is a contact for the service */
-	if(is_contact_for_service(svc,temp_contact)==TRUE)
+	if(is_contact_for_service_perm(svc,temp_contact,'r')==TRUE)
 		return TRUE;
 
 	/* see if this user is an escalated contact for the service */
@@ -419,16 +419,16 @@
 		if(temp_contact && temp_contact->can_submit_commands==FALSE)
 			return FALSE;
 
-		/* see if this user is a contact for the host */
-		if(is_contact_for_host(temp_host,temp_contact)==TRUE)
+		/* see if this user is a contact for the host with permissions */
+		if(is_contact_for_host_perm(temp_host,temp_contact,'x')==TRUE)
 			return TRUE;
 
 		/* see if this user is an escalated contact for the host */
 		if(is_escalated_contact_for_host(temp_host,temp_contact)==TRUE)
 			return TRUE;
 
-		/* this user is a contact for the service, so they have permission... */
-		if(is_contact_for_service(svc,temp_contact)==TRUE)
+		/* see if this user is a contact for the service with permissions */
+		if(is_contact_for_service_perm(svc,temp_contact,'x')==TRUE)
 			return TRUE;
 
 		/* this user is an escalated contact for the service, so they have permission... */
@@ -469,8 +469,8 @@
 		if(temp_contact && temp_contact->can_submit_commands==FALSE)
 			return FALSE;
 
-		/* this user is a contact for the host, so they have permission... */
-		if(is_contact_for_host(hst,temp_contact)==TRUE)
+		/* see if this user is a contact for the host with permissions */
+		if(is_contact_for_host_perm(hst,temp_contact,'x')==TRUE)
 			return TRUE;
 
 		/* this user is an escalated contact for the host, so they have permission... */
diff -ur nagios-2.5.org/common/objects.c nagios-2.5/common/objects.c
--- nagios-2.5.org/common/objects.c	2006-10-08 19:35:18.000000000 -0400
+++ nagios-2.5/common/objects.c	2006-11-05 22:20:44.000000000 -0500
@@ -4926,6 +4926,8 @@
 /* find a contact group from the list in memory */
 contactgroup * find_contactgroup(char *name){
 	contactgroup *temp_contactgroup;
+        char *temp_contactgroup_name;
+        char *perms;
 
 #ifdef DEBUG0
 	printf("find_contactgroup() start\n");
@@ -4934,11 +4936,21 @@
 	if(name==NULL || contactgroup_hashlist==NULL)
 		return NULL;
 
-	for(temp_contactgroup=contactgroup_hashlist[hashfunc1(name,CONTACTGROUP_HASHSLOTS)];temp_contactgroup && compare_hashdata1(temp_contactgroup->group_name,name)<0;temp_contactgroup=temp_contactgroup->nexthash);
+        /* Ignore permissions */
+        temp_contactgroup_name = strdup(name);
+        perms = strchr(temp_contactgroup_name, ':');
+        if (perms)
+          *perms = '\0';
 
-	if(temp_contactgroup && (compare_hashdata1(temp_contactgroup->group_name,name)==0))
+	for(temp_contactgroup=contactgroup_hashlist[hashfunc1(temp_contactgroup_name,CONTACTGROUP_HASHSLOTS)];temp_contactgroup && compare_hashdata1(temp_contactgroup->group_name,temp_contactgroup_name)<0;temp_contactgroup=temp_contactgroup->nexthash);
+
+	if(temp_contactgroup && (compare_hashdata1(temp_contactgroup->group_name,temp_contactgroup_name)==0))
 		return temp_contactgroup;
 
+        if(temp_contactgroup_name)
+          free(temp_contactgroup_name);
+          
+
 #ifdef DEBUG0
 	printf("find_contactgroup() end\n");
 #endif
@@ -5427,7 +5439,9 @@
 int is_contact_for_host(host *hst, contact *cntct){
 	contactgroupsmember *temp_contactgroupsmember;
 	contactgroup *temp_contactgroup;
-	
+        char *temp_contactgroup_name;
+        char *perms;
+        	
 	if(hst==NULL || cntct==NULL){
 		return FALSE;
 	        }
@@ -5435,8 +5449,16 @@
 	/* search all contact groups of this host */
 	for(temp_contactgroupsmember=hst->contact_groups;temp_contactgroupsmember!=NULL;temp_contactgroupsmember=temp_contactgroupsmember->next){
 
+                /* Ignore permissions */
+                temp_contactgroup_name = strdup(temp_contactgroupsmember->group_name);
+                perms = strchr(temp_contactgroup_name, ':');
+                if (perms)
+                  *perms = '\0';
+
 		/* find the contact group */
-		temp_contactgroup=find_contactgroup(temp_contactgroupsmember->group_name);
+		temp_contactgroup=find_contactgroup(temp_contactgroup_name);
+		if (temp_contactgroup_name)
+		  free (temp_contactgroup_name);
 		if(temp_contactgroup==NULL)
 			continue;
 
@@ -5447,6 +5469,47 @@
 	return FALSE;
         }
 
+/*  tests whether a contact is a contact for a particular host with write permissions */
+int is_contact_for_host_perm(host *hst, contact *cntct, char perm){
+	contactgroupsmember *temp_contactgroupsmember;
+	contactgroup *temp_contactgroup;
+        char *temp_contactgroup_name;
+        char *perms;
+        	
+	if(hst==NULL || cntct==NULL){
+		return FALSE;
+	        }
+
+	/* search all contact groups of this host */
+	for(temp_contactgroupsmember=hst->contact_groups;temp_contactgroupsmember!=NULL;temp_contactgroupsmember=temp_contactgroupsmember->next){
+
+                /* Check for permissions */
+                temp_contactgroup_name = strdup(temp_contactgroupsmember->group_name);
+                perms = strchr(temp_contactgroup_name, ':');
+                if (perms) {
+                  perms = strchr(perms, perm);
+                  if (! (perms)) {      /* permission not found so deny */
+                    if (temp_contactgroup_name)
+                      free(temp_contactgroup_name);
+                    continue;
+                  }
+                }
+
+                /* No permissions set so defaulting to full access, or user has permission */
+
+		/* find the contact group */
+		temp_contactgroup=find_contactgroup(temp_contactgroup_name);
+		if (temp_contactgroup_name)
+		  free(temp_contactgroup_name);
+		if(temp_contactgroup==NULL)
+			continue;
+
+		if(is_contact_member_of_contactgroup(temp_contactgroup,cntct)==TRUE)
+			return TRUE;
+	        }
+
+	return FALSE;
+        }
 
 
 /* tests whether or not a contact is an escalated contact for a particular host */
@@ -5481,6 +5544,8 @@
 int is_contact_for_service(service *svc, contact *cntct){
 	contactgroupsmember *temp_contactgroupsmember;
 	contactgroup *temp_contactgroup;
+        char *temp_contactgroup_name;
+        char *perms;
 
 	if(svc==NULL || cntct==NULL)
 		return FALSE;
@@ -5488,8 +5553,16 @@
 	/* search all contact groups of this service */
 	for(temp_contactgroupsmember=svc->contact_groups;temp_contactgroupsmember!=NULL;temp_contactgroupsmember=temp_contactgroupsmember->next){
 
+                /* Ignore permissions */
+                temp_contactgroup_name = strdup(temp_contactgroupsmember->group_name);
+                perms = strchr(temp_contactgroup_name, ':');
+                if (perms)
+                  *perms = '\0';
+
 		/* find the contact group */
-		temp_contactgroup=find_contactgroup(temp_contactgroupsmember->group_name);
+		temp_contactgroup=find_contactgroup(temp_contactgroup_name);
+                if (temp_contactgroup_name)
+                  free (temp_contactgroup_name);
 		if(temp_contactgroup==NULL)
 			continue;
 
@@ -5500,6 +5573,47 @@
 	return FALSE;
         }
 
+/*  tests whether a contact is a contact for a particular service */
+int is_contact_for_service_perm(service *svc, contact *cntct, char perm){
+	contactgroupsmember *temp_contactgroupsmember;
+	contactgroup *temp_contactgroup;
+        char *temp_contactgroup_name;
+        char *perms;
+
+	if(svc==NULL || cntct==NULL)
+		return FALSE;
+
+	/* search all contact groups of this service */
+	for(temp_contactgroupsmember=svc->contact_groups;temp_contactgroupsmember!=NULL;temp_contactgroupsmember=temp_contactgroupsmember->next){
+
+
+                /* Check for permissions */
+                temp_contactgroup_name = strdup(temp_contactgroupsmember->group_name);
+                perms = strchr(temp_contactgroup_name, ':');
+                if (perms) {
+                  perms = strchr(perms, perm);
+                  if (! (perms)) {      /* permission not found so deny */
+                    if (temp_contactgroup_name)
+                      free(temp_contactgroup_name);
+                    continue;
+                  }
+                }
+
+                /* No permissions set so defaulting to full access, or user has permission */
+
+		/* find the contact group */
+		temp_contactgroup=find_contactgroup(temp_contactgroup_name);
+                if (temp_contactgroup_name)
+                  free (temp_contactgroup_name);
+		if(temp_contactgroup==NULL)
+			continue;
+
+		if(is_contact_member_of_contactgroup(temp_contactgroup,cntct)==TRUE)
+			return TRUE;
+	        }
+
+	return FALSE;
+        }
 
 
 /* tests whether or not a contact is an escalated contact for a particular service */

