diff -ur nagios-3.0.6.org/base/config.c nagios-3.0.6/base/config.c
--- nagios-3.0.6.org/base/config.c	2008-11-30 12:22:58.000000000 -0500
+++ nagios-3.0.6/base/config.c	2009-05-16 11:31:53.000000000 -0400
@@ -201,6 +201,8 @@
 extern host		**host_hashlist;
 extern service		**service_hashlist;
 
+extern char             *default_permissions;
+
 extern int              external_command_buffer_slots;
 
 extern unsigned long    max_check_result_file_age;
@@ -1295,6 +1297,22 @@
 			auth_file=(char *)strdup(value);
 		        }
 
+		else if(!strcmp(variable,"default_permissions")){
+			if(default_permissions!=NULL)
+				free(default_permissions);
+			default_permissions=(char *)strdup(value);
+			if(default_permissions==NULL){
+				strcpy(error_message,"Could not allocate memory for default permissions string");
+				error=TRUE;
+				break;
+			        }
+			strip(default_permissions);
+
+#ifdef DEBUG1
+			printf("\t\tdefault_permissions set to '%s'\n",default_permissions);
+#endif
+		        }
+
 		/* warn about old variables */
 		else if(!strcmp(variable,"comment_file") || !strcmp(variable,"xcddefault_comment_file")){
 			logit(NSLOG_CONFIG_WARNING,TRUE,"Warning: comment_file variable ignored.  Comments are now stored in the status and retention files.");
diff -ur nagios-3.0.6.org/base/nagios.c nagios-3.0.6/base/nagios.c
--- nagios-3.0.6.org/base/nagios.c	2008-12-01 22:48:17.000000000 -0500
+++ nagios-3.0.6/base/nagios.c	2009-05-16 11:31:53.000000000 -0400
@@ -255,6 +255,8 @@
 pthread_t       worker_threads[TOTAL_WORKER_THREADS];
 int             external_command_buffer_slots=DEFAULT_EXTERNAL_COMMAND_BUFFER_SLOTS;
 
+char            *default_permissions;
+
 check_stats     check_statistics[MAX_CHECK_STATS_TYPES];
 
 char            *debug_file;
diff -ur nagios-3.0.6.org/base/notifications.c nagios-3.0.6/base/notifications.c
--- nagios-3.0.6.org/base/notifications.c	2008-11-30 12:22:58.000000000 -0500
+++ nagios-3.0.6/base/notifications.c	2009-05-16 16:20:23.000000000 -0400
@@ -50,7 +50,7 @@
 
 extern char            *generic_summary;
 
-
+extern char            *default_permissions;
 
 /******************************************************************/
 /***************** SERVICE NOTIFICATION FUNCTIONS *****************/
@@ -110,7 +110,7 @@
 	log_debug_info(DEBUGL_NOTIFICATIONS,2,"Creating list of contacts to be notified.\n");
 
 	/* create the contact notification list for this service */
-	create_notification_list_from_service(svc,options,&escalated);
+	create_notification_list_from_service(svc,options,&escalated, default_permissions, 'n');
 
 #ifdef USE_EVENT_BROKER
 	/* send data to event broker */
@@ -860,10 +860,13 @@
 
 
 /* given a service, create a list of contacts to be notified, removing duplicates */
-int create_notification_list_from_service(service *svc, int options, int *escalated){
+int create_notification_list_from_service(service *svc, int options, int *escalated, char *default_perm, char perm){
 	serviceescalation *temp_se=NULL;
 	contactsmember *temp_contactsmember=NULL;
 	contact *temp_contact=NULL;
+        char *temp_contact_name;
+        char *temp_contactgroup_name;
+	char *perms;
 	contactgroupsmember *temp_contactgroupsmember=NULL;
 	contactgroup *temp_contactgroup=NULL;
 	int escalate_notification=FALSE;
@@ -902,7 +905,13 @@
 			for(temp_contactsmember=temp_se->contacts;temp_contactsmember!=NULL;temp_contactsmember=temp_contactsmember->next){
 				if((temp_contact=temp_contactsmember->contact_ptr)==NULL)
 					continue;
-				add_notification(temp_contact);
+
+                                /* Check for permissions */       
+                                temp_contact_name = strdup(temp_contactsmember->contact_name);
+                                if (permission_check(temp_contact_name, default_perm, perm))
+                                  continue;
+         
+                                add_notification(temp_contactsmember->contact_ptr);
 				}
 
 			log_debug_info(DEBUGL_NOTIFICATIONS,2,"Adding members of contact groups from service escalation(s) to notification list.\n");
@@ -912,7 +921,13 @@
 				log_debug_info(DEBUGL_NOTIFICATIONS,2,"Adding members of contact group '%s' for service escalation to notification list.\n",temp_contactgroupsmember->group_name);
 				if((temp_contactgroup=temp_contactgroupsmember->group_ptr)==NULL)
 					continue;
-				for(temp_contactsmember=temp_contactgroup->members;temp_contactsmember!=NULL;temp_contactsmember=temp_contactsmember->next){
+
+                                /* Check for permissions */
+                                temp_contactgroup_name = strdup(temp_contactgroupsmember->group_name);
+                                if (permission_check(temp_contactgroup_name, default_perm, perm))
+                                  continue;
+
+                                for(temp_contactsmember=temp_contactgroup->members;temp_contactsmember!=NULL;temp_contactsmember=temp_contactsmember->next){
 					if((temp_contact=temp_contactsmember->contact_ptr)==NULL)
 						continue;
 					add_notification(temp_contact);
@@ -930,7 +945,13 @@
 		for(temp_contactsmember=svc->contacts;temp_contactsmember!=NULL;temp_contactsmember=temp_contactsmember->next){
 			if((temp_contact=temp_contactsmember->contact_ptr)==NULL)
 				continue;
-			add_notification(temp_contact);
+
+                        /* Check for permissions */
+                       temp_contact_name = strdup(temp_contactsmember->contact_name);
+                       if (permission_check(temp_contact_name, default_perm, perm))
+                         continue;
+
+                        add_notification(temp_contact);
 			}
 
 		/* add all contacts that belong to contactgroups for this service */
@@ -941,7 +962,13 @@
 			for(temp_contactsmember=temp_contactgroup->members;temp_contactsmember!=NULL;temp_contactsmember=temp_contactsmember->next){
 				if((temp_contact=temp_contactsmember->contact_ptr)==NULL)
 					continue;
-				add_notification(temp_contact);
+
+                                /* Check for permissions */
+                                temp_contactgroup_name = strdup(temp_contactgroupsmember->group_name);
+                                if (permission_check(temp_contactgroup_name, default_perm, perm))
+                                  continue;
+
+                                add_notification(temp_contact);
 				}
 			}
 	        }
@@ -950,8 +977,6 @@
         }
 
 
-
-
 /******************************************************************/
 /******************* HOST NOTIFICATION FUNCTIONS ******************/
 /******************************************************************/
@@ -1003,7 +1028,7 @@
 	log_debug_info(DEBUGL_NOTIFICATIONS,2,"Creating list of contacts to be notified.\n");
 
 	/* create the contact notification list for this host */
-	create_notification_list_from_host(hst,options,&escalated);
+	create_notification_list_from_host(hst,options,&escalated, default_permissions, 'n');
 
 #ifdef USE_EVENT_BROKER
 	/* send data to event broker */
@@ -1719,10 +1744,13 @@
 
 
 /* given a host, create a list of contacts to be notified, removing duplicates */
-int create_notification_list_from_host(host *hst, int options, int *escalated){
+int create_notification_list_from_host(host *hst, int options, int *escalated, char *default_perm, char perm){
 	hostescalation *temp_he=NULL;
 	contactsmember *temp_contactsmember=NULL;
 	contact *temp_contact=NULL;
+        char *temp_contact_name;
+        char *temp_contactgroup_name;
+        char *perms;
 	contactgroupsmember *temp_contactgroupsmember=NULL;
 	contactgroup *temp_contactgroup=NULL;
 	int escalate_notification=FALSE;
@@ -1761,7 +1789,13 @@
 			for(temp_contactsmember=temp_he->contacts;temp_contactsmember!=NULL;temp_contactsmember=temp_contactsmember->next){
 				if((temp_contact=temp_contactsmember->contact_ptr)==NULL)
 					continue;
-				add_notification(temp_contact);
+
+                                /* Check for permissions */       
+                                temp_contact_name = strdup(temp_contactsmember->contact_name);
+                                if (permission_check(temp_contact_name, default_perm, perm))
+                                  continue;
+
+                                add_notification(temp_contact);
 			        }
 
 			log_debug_info(DEBUGL_NOTIFICATIONS,2,"Adding members of contact groups from host escalation(s) to notification list.\n");
@@ -1771,7 +1805,13 @@
 				log_debug_info(DEBUGL_NOTIFICATIONS,2,"Adding members of contact group '%s' for host escalation to notification list.\n",temp_contactgroupsmember->group_name);
 				if((temp_contactgroup=temp_contactgroupsmember->group_ptr)==NULL)
 					continue;
-				for(temp_contactsmember=temp_contactgroup->members;temp_contactsmember!=NULL;temp_contactsmember=temp_contactsmember->next){
+
+                                /* Check for permissions */
+                                temp_contactgroup_name = strdup(temp_contactgroupsmember->group_name);
+                                if (permission_check(temp_contactgroup_name, default_perm, perm))
+                                  continue;
+                                
+                                for(temp_contactsmember=temp_contactgroup->members;temp_contactsmember!=NULL;temp_contactsmember=temp_contactsmember->next){
 					if((temp_contact=temp_contactsmember->contact_ptr)==NULL)
 						continue;
 					add_notification(temp_contact);
@@ -1789,10 +1829,13 @@
 
 		/* add all individual contacts for this host */
 		for(temp_contactsmember=hst->contacts;temp_contactsmember!=NULL;temp_contactsmember=temp_contactsmember->next){
-			if((temp_contact=temp_contactsmember->contact_ptr)==NULL)
-				continue;
-			add_notification(temp_contact);
-			}
+                        /* Check for permissions */
+                       temp_contact_name = strdup(temp_contactsmember->contact_name);
+                       if (permission_check(temp_contact_name, default_perm, perm))
+                         continue;
+
+                       add_notification(temp_contactsmember->contact_ptr);
+       	        }
 
 		log_debug_info(DEBUGL_NOTIFICATIONS,2,"Adding members of contact groups for host to notification list.\n");
 
@@ -1802,7 +1845,13 @@
 
 			if((temp_contactgroup=temp_contactgroupsmember->group_ptr)==NULL)
 				continue;
-			for(temp_contactsmember=temp_contactgroup->members;temp_contactsmember!=NULL;temp_contactsmember=temp_contactsmember->next){
+
+                        /* Check for permissions */
+                        temp_contactgroup_name = strdup(temp_contactgroupsmember->group_name);
+                        if (permission_check(temp_contactgroup_name, default_perm, perm))
+                          continue;
+
+                        for(temp_contactsmember=temp_contactgroup->members;temp_contactsmember!=NULL;temp_contactsmember=temp_contactsmember->next){
 				if((temp_contact=temp_contactsmember->contact_ptr)==NULL)
 					continue;
 				add_notification(temp_contact);
@@ -1814,8 +1863,6 @@
         }
 
 
-
-
 /******************************************************************/
 /***************** NOTIFICATION TIMING FUNCTIONS ******************/
 /******************************************************************/
diff -ur nagios-3.0.6.org/cgi/cgiauth.c nagios-3.0.6/cgi/cgiauth.c
--- nagios-3.0.6.org/cgi/cgiauth.c	2008-11-30 13:13:11.000000000 -0500
+++ nagios-3.0.6/cgi/cgiauth.c	2009-05-16 16:08:27.000000000 -0400
@@ -37,7 +37,7 @@
 extern int             use_authentication;
 extern int             use_ssl_authentication;
 
-
+extern char            *default_permissions;
 
 /* get current authentication information */
 int get_authentication_information(authdata *authinfo){
@@ -198,11 +198,11 @@
 	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(hst,temp_contact,default_permissions,'r')==TRUE)
 		return TRUE;
 
 	/* see if this user is an escalated contact for the host */
-	if(is_escalated_contact_for_host(hst,temp_contact)==TRUE)
+	if(is_escalated_contact_for_host(hst,temp_contact,default_permissions,'r')==TRUE)
 		return TRUE;
 
 	return FALSE;
@@ -228,6 +228,25 @@
 	return TRUE;
         }
 
+/* check if user is authorized to view information about all hosts in a particular hostgroup */
+int is_authorized_for_hostgroup_commands(hostgroup *hg, authdata *authinfo){
+	hostsmember *temp_hostsmember;
+	host *temp_host;
+
+	if(hg==NULL)
+		return FALSE;
+
+	/* CHANGED in 2.0 - user must be authorized for ALL hosts in a hostgroup, not just one */
+	/* see if user is authorized for all hosts in the hostgroup */
+	for(temp_hostsmember=hg->members;temp_hostsmember!=NULL;temp_hostsmember=temp_hostsmember->next){
+		temp_host=find_host(temp_hostsmember->host_name);
+		if(is_authorized_for_host_commands(temp_host,authinfo)==FALSE)
+			return FALSE;
+	        }
+
+	return TRUE;
+        }
+
 
 
 /* check if user is authorized to view information about all services in a particular servicegroup */
@@ -248,6 +267,23 @@
 	return TRUE;
         }
 
+/* check if user is authorized to view information about all services in a particular servicegroup */
+int is_authorized_for_servicegroup_commands(servicegroup *sg, authdata *authinfo){
+	servicesmember *temp_servicesmember;
+	service *temp_service;
+
+	if(sg==NULL)
+		return FALSE;
+
+	/* see if user is authorized for all services in the servicegroup */
+	for(temp_servicesmember=sg->members;temp_servicesmember!=NULL;temp_servicesmember=temp_servicesmember->next){
+		temp_service=find_service(temp_servicesmember->host_name,temp_servicesmember->service_description);
+		if(is_authorized_for_service_commands(temp_service,authinfo)==FALSE)
+			return FALSE;
+	        }
+
+	return TRUE;
+        }
 
 /* check if user is authorized to view information about a particular service */
 int is_authorized_for_service(service *svc, authdata *authinfo){
@@ -282,11 +318,10 @@
 	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(svc,temp_contact,default_permissions,'r')==TRUE)
 		return TRUE;
-
 	/* see if this user is an escalated contact for the service */
-	if(is_escalated_contact_for_service(svc,temp_contact)==TRUE)
+	if(is_escalated_contact_for_service(svc,temp_contact,default_permissions,'r')==TRUE)
 		return TRUE;
 
 	return FALSE;
@@ -379,7 +414,6 @@
 	/* if we're not using authentication, fake it */
 	if(use_authentication==FALSE)
 		return TRUE;
-
 	/* if this user has not authenticated return error */
 	if(authinfo->authenticated==FALSE)
 		return FALSE;
@@ -400,19 +434,19 @@
 			return FALSE;
 
 		/* see if this user is a contact for the host */
-		if(is_contact_for_host(temp_host,temp_contact)==TRUE)
+		if(is_contact_for_host(temp_host,temp_contact,default_permissions,'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)
+		if(is_escalated_contact_for_host(temp_host,temp_contact,default_permissions,'x')==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(svc,temp_contact,default_permissions,'x')==TRUE)
 			return TRUE;
 
 		/* this user is an escalated contact for the service, so they have permission... */
-		if(is_escalated_contact_for_service(svc,temp_contact)==TRUE)
+		if(is_escalated_contact_for_service(svc,temp_contact,default_permissions,'x')==TRUE)
 			return TRUE;
 
 		/* this user is not a contact for the host, so they must have been given explicit permissions to all service commands */
@@ -450,11 +484,11 @@
 			return FALSE;
 
 		/* this user is a contact for the host, so they have permission... */
-		if(is_contact_for_host(hst,temp_contact)==TRUE)
+		if(is_contact_for_host(hst,temp_contact,default_permissions,'x')==TRUE)
 			return TRUE;
 
 		/* this user is an escalated contact for the host, so they have permission... */
-		if(is_escalated_contact_for_host(hst,temp_contact)==TRUE)
+		if(is_escalated_contact_for_host(hst,temp_contact,default_permissions,'x')==TRUE)
 			return TRUE;
 
 		/* this user is not a contact for the host, so they must have been given explicit permissions to all host commands */
diff -ur nagios-3.0.6.org/cgi/cgiutils.c nagios-3.0.6/cgi/cgiutils.c
--- nagios-3.0.6.org/cgi/cgiutils.c	2008-11-30 13:13:11.000000000 -0500
+++ nagios-3.0.6/cgi/cgiutils.c	2009-05-16 11:31:53.000000000 -0400
@@ -113,6 +113,8 @@
 int             default_statusmap_layout_method=0;
 int             default_statuswrl_layout_method=0;
 
+char           *default_permissions=NULL;
+
 extern hostgroup       *hostgroup_list;
 extern contactgroup    *contactgroup_list;
 extern command         *command_list;
@@ -266,6 +268,7 @@
 	mmapfile *thefile;
 	char *var=NULL;
 	char *val=NULL;
+	char *temp_buffer=NULL;
 
 
 	if((thefile=mmap_fopen(filename))==NULL)
@@ -408,6 +411,15 @@
 		else if(!strcmp(var,"lock_author_names"))
 			lock_author_names=(atoi(val)>0)?TRUE:FALSE;
 
+                else if(strstr(var,"default_permissions=")==var){
+                        temp_buffer=strtok(var,"=");
+
+                        temp_buffer=strtok(NULL,"\n");
+                        if(temp_buffer==NULL)
+                                continue;
+                        default_permissions=strdup(temp_buffer);
+                }
+
 		else if(!strcmp(var,"use_ssl_authentication"))
 			use_ssl_authentication=(atoi(val)>0)?TRUE:FALSE;
  	        }
diff -ur nagios-3.0.6.org/cgi/cmd.c nagios-3.0.6/cgi/cmd.c
--- nagios-3.0.6.org/cgi/cmd.c	2008-11-30 12:22:58.000000000 -0500
+++ nagios-3.0.6/cgi/cmd.c	2009-05-16 13:08:32.000000000 -0400
@@ -1729,7 +1729,7 @@
 
 		/* see if the user is authorized to issue a command... */
 		temp_hostgroup=find_hostgroup(hostgroup_name);
-		if(is_authorized_for_hostgroup(temp_hostgroup,&current_authdata)==TRUE)
+		if(is_authorized_for_hostgroup_commands(temp_hostgroup,&current_authdata)==TRUE)
 			authorized=TRUE;
 
 		/* clean up the comment data if scheduling downtime */
@@ -1770,7 +1770,7 @@
 		/* see if the user is authorized to issue a command... */
 
 		temp_servicegroup=find_servicegroup(servicegroup_name);
-		if(is_authorized_for_servicegroup(temp_servicegroup,&current_authdata)==TRUE)
+		if(is_authorized_for_servicegroup_commands(temp_servicegroup,&current_authdata)==TRUE)
 			authorized=TRUE;
 
 		break;
diff -ur nagios-3.0.6.org/common/macros.c nagios-3.0.6/common/macros.c
--- nagios-3.0.6.org/common/macros.c	2008-11-30 12:22:58.000000000 -0500
+++ nagios-3.0.6/common/macros.c	2009-05-16 18:10:59.000000000 -0400
@@ -1133,7 +1133,7 @@
 
 				/* filter totals based on contact if necessary */
 				if(macro_contact_ptr!=NULL)
-					authorized=is_contact_for_host(temp_host,macro_contact_ptr);
+					authorized=is_contact_for_host(temp_host,macro_contact_ptr, NULL, NULL);
 
 				if(authorized==TRUE){
 					problem=TRUE;
@@ -1173,7 +1173,7 @@
 
 				/* filter totals based on contact if necessary */
 				if(macro_contact_ptr!=NULL)
-					authorized=is_contact_for_service(temp_service,macro_contact_ptr);
+					authorized=is_contact_for_service(temp_service,macro_contact_ptr, NULL, NULL);
 
 				if(authorized==TRUE){
 					problem=TRUE;
diff -ur nagios-3.0.6.org/common/objects.c nagios-3.0.6/common/objects.c
--- nagios-3.0.6.org/common/objects.c	2008-11-30 12:22:59.000000000 -0500
+++ nagios-3.0.6/common/objects.c	2009-05-16 16:22:25.000000000 -0400
@@ -89,6 +89,40 @@
         }
 
 
+/******************************************************************/
+/******* ADVANCED PERMISSIONS CHECK FUNCTION              *********/
+/******************************************************************/
+
+int permission_check(char *temp_contact_or_group_name, char *default_perm, char perm) {
+        char *perms;
+
+        /* Check for permissions */
+        perms = strchr(temp_contact_or_group_name, ':');
+        if (perms) {
+          perms = strchr(perms, perm);
+          if (! (perms)) {      /* permission not found so deny */
+            if (temp_contact_or_group_name)
+              free(temp_contact_or_group_name);
+            return 1;   /* continue; */
+          }
+        }
+
+        else if (default_perm) {
+          /* No permissions defined for service, but default permissions found */
+          perms = strchr(default_perm, perm);
+          if (! (perms)) {      /* permission not found so deny */
+            if (temp_contact_or_group_name)
+              free(temp_contact_or_group_name);
+            return 1;   /* continue; */
+          }
+        }
+
+        /* No permissions set so defaulting to full access, or user has permission */
+        perms = strchr(temp_contact_or_group_name, ':');
+        if (perms)
+          *perms = '\0';        /* Remove perms from temp_contact_or_group_name */
+        return 0;
+}
 
 /******************************************************************/
 /******************** SKIPLIST FUNCTIONS **************************/
@@ -2784,11 +2818,19 @@
 /* find a contact from the list in memory */
 contact * find_contact(char *name){
 	contact temp_contact;
+        char *temp_contact_name;
+        char *perms;
 
 	if(name==NULL)
 		return NULL;
 
-	temp_contact.name=name;
+        /* Ignore permissions */
+        temp_contact_name = strdup(name);
+        perms = strchr(temp_contact_name, ':');
+        if (perms)
+          *perms = '\0';      
+
+	temp_contact.name=temp_contact_name;
 
 	return skiplist_find_first(object_skiplists[CONTACT_SKIPLIST],&temp_contact,NULL);
 	}
@@ -2797,11 +2839,19 @@
 /* find a contact group from the list in memory */
 contactgroup * find_contactgroup(char *name){
 	contactgroup temp_contactgroup;
+        char *temp_contactgroup_name;
+        char *perms;
 
 	if(name==NULL)
 		return NULL;
 
-	temp_contactgroup.group_name=name;
+        /* Ignore permissions */
+        temp_contactgroup_name = strdup(name);
+        perms = strchr(temp_contactgroup_name, ':');
+        if (perms)
+          *perms = '\0';      
+
+	temp_contactgroup.group_name=temp_contactgroup_name;
 
 	return skiplist_find_first(object_skiplists[CONTACTGROUP_SKIPLIST],&temp_contactgroup,NULL);
 	}
@@ -3196,7 +3246,7 @@
 
 
 /*  tests whether a contact is a member of a particular hostgroup - used only by the CGIs */
-int is_contact_for_hostgroup(hostgroup *group, contact *cntct){
+int is_contact_for_hostgroup(hostgroup *group, contact *cntct, char *default_perm, char perm){
 	hostsmember *temp_hostsmember=NULL;
 	host *temp_host=NULL;
 
@@ -3211,7 +3261,7 @@
 #endif
 		if(temp_host==NULL)
 			continue;
-		if(is_contact_for_host(temp_host,cntct)==TRUE)
+		if(is_contact_for_host(temp_host,cntct,default_perm,'r')==TRUE)
 			return TRUE;
 	        }
 
@@ -3221,7 +3271,7 @@
 
 
 /*  tests whether a contact is a member of a particular servicegroup - used only by the CGIs */
-int is_contact_for_servicegroup(servicegroup *group, contact *cntct){
+int is_contact_for_servicegroup(servicegroup *group, contact *cntct, char *default_perm, char perm){
 	servicesmember *temp_servicesmember=NULL;
 	service *temp_service=NULL;
 
@@ -3236,7 +3286,7 @@
 #endif
 		if(temp_service==NULL)
 			continue;
-		if(is_contact_for_service(temp_service,cntct)==TRUE)
+		if(is_contact_for_service(temp_service,cntct,default_perm,'r')==TRUE)
 			return TRUE;
 	        }
 
@@ -3245,10 +3295,14 @@
 
 
 
-/*  tests whether a contact is a contact for a particular host */
-int is_contact_for_host(host *hst, contact *cntct){
+
+/*  tests whether a contact is a contact for a particular host with permissions */
+int is_contact_for_host(host *hst, contact *cntct, char *default_perm, char perm){
 	contactsmember *temp_contactsmember=NULL;
 	contact *temp_contact=NULL;
+        char *temp_contact_name=NULL;
+        char *temp_contactgroup_name;
+        char *perms;
 	contactgroupsmember *temp_contactgroupsmember=NULL;
 	contactgroup *temp_contactgroup=NULL;
 	
@@ -3261,7 +3315,12 @@
 #ifdef NSCORE
 		temp_contact=temp_contactsmember->contact_ptr;
 #else
-		temp_contact=find_contact(temp_contactsmember->contact_name);
+                /* Check for permissions */
+                temp_contact_name = strdup(temp_contactsmember->contact_name);
+                if (permission_check(temp_contact_name, default_perm, perm))
+                  continue;
+
+                temp_contact=find_contact(temp_contact_name);
 #endif
 		if(temp_contact==NULL)
 			continue;
@@ -3274,12 +3333,18 @@
 #ifdef NSCORE
 		temp_contactgroup=temp_contactgroupsmember->group_ptr;
 #else
-		temp_contactgroup=find_contactgroup(temp_contactgroupsmember->group_name);
+                /* Check for permissions */
+                temp_contactgroup_name = strdup(temp_contactgroupsmember->group_name);
+                if (permission_check(temp_contactgroup_name, default_perm, perm))
+                  continue;
+
+                temp_contactgroup=find_contactgroup(temp_contactgroup_name);
+
 #endif
-		if(temp_contactgroup==NULL)
+		if(temp_contactgroup==NULL) 
 			continue;
 
-		for(temp_contactsmember=temp_contactgroup->members;temp_contactsmember!=NULL;temp_contactsmember=temp_contactsmember->next){
+                for(temp_contactsmember=temp_contactgroup->members;temp_contactsmember!=NULL;temp_contactsmember=temp_contactsmember->next){
 #ifdef NSCORE
 			temp_contact=temp_contactsmember->contact_ptr;
 #else
@@ -3287,7 +3352,7 @@
 #endif
 			if(temp_contact==NULL)
 				continue;
-			if(temp_contact==cntct)
+			if(temp_contact==cntct) 
 				return TRUE;
 			}
 		}
@@ -3296,12 +3361,14 @@
         }
 
 
-
-/* tests whether or not a contact is an escalated contact for a particular host */
-int is_escalated_contact_for_host(host *hst, contact *cntct){
+/* tests whether or not a contact is an escalated contact for a particular host with perms */
+int is_escalated_contact_for_host(host *hst, contact *cntct, char *default_perm, char perm){
 	contactsmember *temp_contactsmember=NULL;
 	contact *temp_contact=NULL;
 	hostescalation *temp_hostescalation=NULL;
+        char *temp_contact_name;
+        char *temp_contactgroup_name;
+        char *perms;
 	contactgroupsmember *temp_contactgroupsmember=NULL;
 	contactgroup *temp_contactgroup=NULL;
 	void *ptr=NULL;
@@ -3315,7 +3382,12 @@
 #ifdef NSCORE
 			temp_contact=temp_contactsmember->contact_ptr;
 #else
-			temp_contact=find_contact(temp_contactsmember->contact_name);
+                        /* Check for permissions */
+                        temp_contact_name = strdup(temp_contactsmember->contact_name);
+                        if (permission_check(temp_contact_name, default_perm, perm))
+                          continue;
+
+                        temp_contact=find_contact(temp_contact_name);
 #endif
 			if(temp_contact==NULL)
 				continue;
@@ -3328,7 +3400,13 @@
 #ifdef NSCORE
 			temp_contactgroup=temp_contactgroupsmember->group_ptr;
 #else
-			temp_contactgroup=find_contactgroup(temp_contactgroupsmember->group_name);
+                        /* Check for permissions */
+                        temp_contactgroup_name = strdup(temp_contactgroupsmember->group_name);
+                        if (permission_check(temp_contactgroup_name, default_perm, perm))
+                          continue;
+        
+                        temp_contactgroup=find_contactgroup(temp_contactgroup_name);
+                        /* temp_contactgroup=find_contactgroup(temp_contactgroupsmember->group_name); */
 #endif
 			if(temp_contactgroup==NULL)
 				continue;
@@ -3351,10 +3429,13 @@
         }
 
 
-/*  tests whether a contact is a contact for a particular service */
-int is_contact_for_service(service *svc, contact *cntct){
+/*  tests whether a contact is a contact for a particular service with perms */
+int is_contact_for_service(service *svc, contact *cntct, char *default_perm, char perm){
 	contactsmember *temp_contactsmember=NULL;
 	contact *temp_contact=NULL;
+        char *temp_contact_name;
+        char *temp_contactgroup_name;
+        char *perms;
 	contactgroupsmember *temp_contactgroupsmember=NULL;
 	contactgroup *temp_contactgroup=NULL;
 
@@ -3363,11 +3444,16 @@
 
 	/* search all individual contacts of this service */
 	for(temp_contactsmember=svc->contacts;temp_contactsmember!=NULL;temp_contactsmember=temp_contactsmember->next){
-#ifdef NSCORE
-		temp_contact=temp_contactsmember->contact_ptr;
-#else
-		temp_contact=find_contact(temp_contactsmember->contact_name);
-#endif
+//#ifdef NSCORE
+//		temp_contact=temp_contactsmember->contact_ptr;
+//#else
+                /* Check for permissions */
+                temp_contact_name = strdup(temp_contactsmember->contact_name);
+                if (permission_check(temp_contact_name, default_perm, perm))
+                  continue;
+
+                temp_contact=find_contact(temp_contact_name);
+//#endif
 		
 		if(temp_contact==cntct)
 			return TRUE;
@@ -3378,7 +3464,13 @@
 #ifdef NSCORE
 		temp_contactgroup=temp_contactgroupsmember->group_ptr;
 #else
-		temp_contactgroup=find_contactgroup(temp_contactgroupsmember->group_name);
+                /* Check for permissions */
+                temp_contactgroup_name = strdup(temp_contactgroupsmember->group_name);
+                if (permission_check(temp_contactgroup_name, default_perm, perm))
+                  continue;
+
+                temp_contactgroup=find_contactgroup(temp_contactgroup_name);
+//		temp_contactgroup=find_contactgroup(temp_contactgroupsmember->group_name);
 #endif
 		if(temp_contactgroup==NULL)
 			continue;
@@ -3400,13 +3492,15 @@
         }
 
 
-
-/* tests whether or not a contact is an escalated contact for a particular service */
-int is_escalated_contact_for_service(service *svc, contact *cntct){
+/* tests whether or not a contact is an escalated contact for a particular service with perms */
+int is_escalated_contact_for_service(service *svc, contact *cntct, char *default_perm, char perm){
 	serviceescalation *temp_serviceescalation=NULL;
 	contactsmember *temp_contactsmember=NULL;
 	contact *temp_contact=NULL;
-	contactgroupsmember *temp_contactgroupsmember=NULL;
+        char *temp_contact_name;
+        char *temp_contactgroup_name;
+        char *perms;
+	contactgroupsmember *temp_contactgroupsmember=NULL;	// fixme Alex - add support for contactgroup
 	contactgroup *temp_contactgroup=NULL;
 	void *ptr=NULL;
 
@@ -3415,11 +3509,16 @@
 
 		/* search all contacts of this service escalation */
 		for(temp_contactsmember=temp_serviceescalation->contacts;temp_contactsmember!=NULL;temp_contactsmember=temp_contactsmember->next){
-#ifdef NSCORE
-			temp_contact=temp_contactsmember->contact_ptr;
-#else
-			temp_contact=find_contact(temp_contactsmember->contact_name);
-#endif
+//#ifdef NSCORE
+//			temp_contact=temp_contactsmember->contact_ptr;
+//#else
+                        /* Check for permissions */
+                        temp_contact_name = strdup(temp_contactsmember->contact_name);
+                        if (permission_check(temp_contact_name, default_perm, perm))
+                          continue;
+        
+                        temp_contact=find_contact(temp_contact_name);
+//#endif
 			if(temp_contact==NULL)
 				continue;
 			if(temp_contact==cntct)
@@ -3431,7 +3530,13 @@
 #ifdef NSCORE
 			temp_contactgroup=temp_contactgroupsmember->group_ptr;
 #else
-			temp_contactgroup=find_contactgroup(temp_contactgroupsmember->group_name);
+                        /* Check for permissions */
+                        temp_contactgroup_name = strdup(temp_contactgroupsmember->group_name);
+                        if (permission_check(temp_contactgroup_name, default_perm, perm))
+                          continue;
+
+                        temp_contactgroup=find_contactgroup(temp_contactgroup_name);
+                        /* temp_contactgroup=find_contactgroup(temp_contactgroupsmember->group_name); */
 #endif
 			if(temp_contactgroup==NULL)
 				continue;
diff -ur nagios-3.0.6.org/include/cgiauth.h nagios-3.0.6/include/cgiauth.h
--- nagios-3.0.6.org/include/cgiauth.h	2005-11-25 22:52:07.000000000 -0500
+++ nagios-3.0.6/include/cgiauth.h	2009-05-16 13:05:48.000000000 -0400
@@ -60,7 +60,10 @@
 int is_authorized_for_service_commands(service *,authdata *);
 
 int is_authorized_for_hostgroup(hostgroup *,authdata *);
+int is_authorized_for_hostgroup_commands(hostgroup *,authdata *);
+
 int is_authorized_for_servicegroup(servicegroup *,authdata *);
+int is_authorized_for_servicegroup_commands(servicegroup *,authdata *);
 
 int is_authorized_for_configuration_information(authdata *);
 
diff -ur nagios-3.0.6.org/include/nagios.h nagios-3.0.6/include/nagios.h
--- nagios-3.0.6.org/include/nagios.h	2008-11-30 12:22:59.000000000 -0500
+++ nagios-3.0.6/include/nagios.h	2009-05-16 15:53:07.000000000 -0400
@@ -606,8 +606,8 @@
 int host_notification(host *,int,char *,char *,int);                           	/* notify all contacts about a host (problem or recovery) */
 int check_contact_host_notification_viability(contact *,host *,int,int);	/* checks viability of notifying a contact about a host */ 
 int notify_contact_of_host(contact *,host *,int,char *,char *,int,int);        	/* notify a single contact about a host */
-int create_notification_list_from_host(host *,int,int *);         		/* given a host, create list of contacts to be notified (remove duplicates) */
-int create_notification_list_from_service(service *,int,int *);    		/* given a service, create list of contacts to be notified (remove duplicates) */
+int create_notification_list_from_host(host *,int,int *, char *, char);         		/* given a host, create list of contacts to be notified (remove duplicates) */
+int create_notification_list_from_service(service *,int,int *, char *, char);    		/* given a service, create list of contacts to be notified (remove duplicates) */
 int add_notification(contact *);						/* adds a notification instance */
 notification *find_notification(contact *);					/* finds a notification object */
 time_t get_next_host_notification_time(host *,time_t);				/* calculates nex acceptable re-notification time for a host */
diff -ur nagios-3.0.6.org/include/objects.h nagios-3.0.6/include/objects.h
--- nagios-3.0.6.org/include/objects.h	2008-11-30 12:22:59.000000000 -0500
+++ nagios-3.0.6/include/objects.h	2009-05-16 16:03:35.000000000 -0400
@@ -738,12 +738,16 @@
 int is_host_member_of_servicegroup(servicegroup *,host *);	        /* tests whether or not a service is a member of a specific servicegroup */
 int is_service_member_of_servicegroup(servicegroup *,service *);	/* tests whether or not a service is a member of a specific servicegroup */
 int is_contact_member_of_contactgroup(contactgroup *, contact *);	/* tests whether or not a contact is a member of a specific contact group */
-int is_contact_for_hostgroup(hostgroup *,contact *);	                /* tests whether or not a contact is a member of a specific hostgroup */
-int is_contact_for_servicegroup(servicegroup *,contact *);	        /* tests whether or not a contact is a member of a specific servicegroup */
-int is_contact_for_host(host *,contact *);			        /* tests whether or not a contact is a contact member for a specific host */
-int is_escalated_contact_for_host(host *,contact *);                    /* checks whether or not a contact is an escalated contact for a specific host */
-int is_contact_for_service(service *,contact *);		        /* tests whether or not a contact is a contact member for a specific service */
-int is_escalated_contact_for_service(service *,contact *);              /* checks whether or not a contact is an escalated contact for a specific service */
+int is_contact_for_hostgroup(hostgroup *,contact *, char *, char);	/* tests whether or not a contact is a member of a specific hostgroup */
+int is_contact_for_servicegroup(servicegroup *,contact *, char *, char);/* tests whether or not a contact is a member of a specific servicegroup */
+int is_contact_for_host(host *,contact *, char *, char);
+                                        			        /* tests whether or not a contact is a contact member for a specific host */
+int is_escalated_contact_for_host(host *,contact *, char *, char);
+                                                                        /* checks whether or not a contact is an escalated contact for a specific host */
+int is_contact_for_service(service *,contact *, char *, char);
+                                                		        /* tests whether or not a contact is a contact member for a specific service */
+int is_escalated_contact_for_service(service *,contact *, char *, char);
+                                                                        /* checks whether or not a contact is an escalated contact for a specific service */
 int is_host_immediate_parent_of_host(host *,host *);		        /* tests whether or not a host is an immediate parent of another host */
 
 int number_of_immediate_child_hosts(host *);		                /* counts the number of immediate child hosts for a particular host */
diff -ur nagios-3.0.6.org/sample-config/cgi.cfg.in nagios-3.0.6/sample-config/cgi.cfg.in
--- nagios-3.0.6.org/sample-config/cgi.cfg.in	2008-11-30 13:13:11.000000000 -0500
+++ nagios-3.0.6/sample-config/cgi.cfg.in	2009-05-16 11:32:07.000000000 -0400
@@ -329,4 +329,13 @@
 
 #splunk_url=http://127.0.0.1:8000/
 
+# DEFAULT HOST/SERVICE PERMISSIONS
+# This option contains a list of default permissions for hosts and
+# services that will be used when permissions are not explicitly
+# set on a host or service.  When not defined, the default is all
+# permissions (rwxn).  Note:  This option must be set the same in
+# both cgi.cfg and nagios.cfg.
+
+#default_permissions=rwxn
+
 
diff -ur nagios-3.0.6.org/sample-config/nagios.cfg.in nagios-3.0.6/sample-config/nagios.cfg.in
--- nagios-3.0.6.org/sample-config/nagios.cfg.in	2008-11-02 13:51:30.000000000 -0500
+++ nagios-3.0.6/sample-config/nagios.cfg.in	2009-05-16 11:32:07.000000000 -0400
@@ -1294,4 +1294,13 @@
 
 max_debug_file_size=1000000
 
+# DEFAULT HOST/SERVICE PERMISSIONS
+# This option contains a list of default permissions for hosts and
+# services that will be used when permissions are not explicitly
+# set on a host or service.  When not defined, the default is all
+# permissions (rwxn).  Note:  This option must be set the same in
+# both cgi.cfg and nagios.cfg.
+
+#default_permissions=rwxn
+
 
diff -ur nagios-3.0.6.org/xdata/xodtemplate.c nagios-3.0.6/xdata/xodtemplate.c
--- nagios-3.0.6.org/xdata/xodtemplate.c	2008-11-30 12:22:59.000000000 -0500
+++ nagios-3.0.6/xdata/xodtemplate.c	2009-05-16 16:11:25.000000000 -0400
@@ -9468,16 +9468,33 @@
 /* finds a specific contactgroup object by its REAL name, not its TEMPLATE name */
 xodtemplate_contactgroup *xodtemplate_find_real_contactgroup(char *name){
 	xodtemplate_contactgroup temp_contactgroup;
+        char *temp_contactgroup_name;
+        char *perms;
+        void *skiplist_temp;
 
 	if(name==NULL)
 		return NULL;
 
-	temp_contactgroup.contactgroup_name=name;
+        /* Ignore permissions */
+        temp_contactgroup_name = strdup(name);
+         perms = strchr(temp_contactgroup_name, ':');
+        if (perms)
+          *perms = '\0';
 
-	return skiplist_find_first(xobject_skiplists[X_CONTACTGROUP_SKIPLIST],&temp_contactgroup,NULL);
+	temp_contactgroup.contactgroup_name=temp_contactgroup_name;
+
+	skiplist_temp = skiplist_find_first(xobject_skiplists[X_CONTACTGROUP_SKIPLIST],&temp_contactgroup,NULL);
+
+        if (temp_contactgroup_name)
+          free (temp_contactgroup_name);
+
+        return skiplist_temp;
         }
 
 
+
+
+
 /* finds a specific hostgroup object */
 xodtemplate_hostgroup *xodtemplate_find_hostgroup(char *name){
 	xodtemplate_hostgroup temp_hostgroup;
@@ -9572,13 +9589,27 @@
 /* finds a specific contact object by its REAL name, not its TEMPLATE name */
 xodtemplate_contact *xodtemplate_find_real_contact(char *name){
 	xodtemplate_contact temp_contact;
+        char *temp_contact_name;
+        char *perms;
+        void *skiplist_temp;
 
 	if(name==NULL)
 		return NULL;
 
-	temp_contact.contact_name=name;
+        /* Ignore permissions */
+        temp_contact_name = strdup(name);
+        perms = strchr(temp_contact_name, ':');
+        if (perms)
+          *perms = '\0';
+
+	temp_contact.contact_name=temp_contact_name;
 
-	return skiplist_find_first(xobject_skiplists[X_CONTACT_SKIPLIST],&temp_contact,NULL);
+	skiplist_temp = skiplist_find_first(xobject_skiplists[X_CONTACT_SKIPLIST],&temp_contact,NULL);
+	
+        if (temp_contact_name)
+          free (temp_contact_name);
+
+        return skiplist_temp;
 	}
 
 
@@ -13161,6 +13192,14 @@
 int xodtemplate_add_member_to_memberlist(xodtemplate_memberlist **list, char *name1, char *name2){
 	xodtemplate_memberlist *temp_item=NULL;
 	xodtemplate_memberlist *new_item=NULL;
+        char *temp_contact_name_in_list=NULL;
+        char *temp_contact_name_in_list_perms=NULL;
+        char *temp_contact_name=NULL;
+        char *temp_contact_name_perms=NULL;
+        char *temp_new_contact_name=NULL;
+        char *perms=NULL;
+        char *new_perms=NULL;
+        int found = 0;
 	int error=FALSE;
 
 	if(list==NULL)
@@ -13169,7 +13208,7 @@
 		return ERROR;
 
 	/* skip this member if its already in the list */
-	for(temp_item=*list;temp_item;temp_item=temp_item->next){
+/*	for(temp_item=*list;temp_item;temp_item=temp_item->next){
 		if(!strcmp(temp_item->name1,name1)){
 			if(temp_item->name2==NULL){
 				if(name2==NULL)
@@ -13180,8 +13219,92 @@
 			}
 		}
 	if(temp_item)
-		return OK;
+		return OK; */
+
+        /* merge / replace this contact if its already in the list */
+	for(temp_item=*list;temp_item;temp_item=temp_item->next) {
+
+                /* Ignore permissions */
+                temp_contact_name_in_list = strdup(temp_item->name1);
+                perms = strchr(temp_contact_name_in_list, ':');
+                if (perms) {
+                  temp_contact_name_in_list_perms = strdup(perms);
+                  *perms = '\0';
+                }
+
+                temp_contact_name = strdup(name1);
+                perms = strchr(temp_contact_name, ':');
+                if (perms) {
+                  temp_contact_name_perms = strdup(perms);
+                  *perms = '\0';
+                }
+
+                /* Check for match (ignoring permissions) */
+		if(!strcmp(temp_contact_name_in_list,temp_contact_name))
+                  found=1;
+                
+                if (found) {
+                  /* Found match (duplicate) */
+
+                  /* Create new contact name that includes all perm */
+                  if (temp_contact_name_in_list_perms && temp_contact_name_perms)
+                    asprintf(&temp_new_contact_name,"%s%s%s",temp_contact_name,temp_contact_name_in_list_perms,temp_contact_name_perms);
+                  else if (temp_contact_name_in_list_perms)
+                    asprintf(&temp_new_contact_name,"%s%s",temp_contact_name,temp_contact_name_in_list_perms);
+                  else if (temp_contact_name_perms)
+                    asprintf(&temp_new_contact_name,"%s%s",temp_contact_name,temp_contact_name_perms);
+                  else
+                    temp_new_contact_name = strdup(name1);
+
+                  if (temp_contact_name_in_list_perms)
+                    free (temp_contact_name_in_list_perms);
+                  if (temp_contact_name_perms)
+                    free (temp_contact_name_perms);
+
+                  /* Remove contact from the list */
+                  xodtemplate_remove_memberlist_item(temp_item,list);
+
+                  /* allocate memory for a new list item */
+                  if((new_item=(xodtemplate_memberlist *)malloc(sizeof(xodtemplate_memberlist)))==NULL)
+                    return ERROR;
+
+	/* save the member name(s) */
+	new_item->name1=NULL;
+	new_item->name2=NULL;
+	if(name1){
+		if((new_item->name1=(char *)strdup(temp_new_contact_name))==NULL)
+			error=TRUE;
+		}
+	if(name2){
+		if((new_item->name2=(char *)strdup(name2))==NULL)
+			error=TRUE;
+		}
+
+	if(error==TRUE){
+		my_free(new_item->name1);
+		my_free(new_item->name2);
+		my_free(new_item);
+		return ERROR;
+	        }
 
+	/* add new item to head of list */
+	new_item->next=*list;
+	*list=new_item;
+                                
+                  if (temp_contact_name_in_list)
+                    free (temp_contact_name_in_list);
+                  if (temp_contact_name)
+                    free (temp_contact_name);
+                  if (new_perms)
+                    free (new_perms);
+
+                  break;
+                }
+        }
+
+	if(found)
+          return OK;
+     		
 	/* allocate memory for a new list item */
 	if((new_item=(xodtemplate_memberlist *)malloc(sizeof(xodtemplate_memberlist)))==NULL)
 		return ERROR;
@@ -13329,6 +13452,8 @@
 	int found_match=TRUE;
 	int reject_item=FALSE;
 	int use_regexp=FALSE;
+        char *temp_group_name;
+        char *perms;
 
 	if(list==NULL || contactgroups==NULL)
 		return ERROR;
@@ -13345,6 +13470,12 @@
 		/* strip trailing spaces */
 		strip(temp_ptr);
 
+                /* Check for permissions on the group.  These will be added to each contact */
+                temp_group_name = strdup(temp_ptr);
+                perms = strchr(temp_group_name, ':');
+
+// fixme Alex - regex should use temp_group_name?
+
 		/* should we use regular expression matching? */
 		if(use_regexp_matches==TRUE && (use_true_regexp_matching==TRUE || strstr(temp_ptr,"*") || strstr(temp_ptr,"?") || strstr(temp_ptr,"+") || strstr(temp_ptr,"\\.")))
 			use_regexp=TRUE;
@@ -13377,7 +13508,8 @@
 					continue;
 
 				/* add contactgroup members to list */
-				xodtemplate_add_contactgroup_members_to_memberlist(list,temp_contactgroup,_config_file,_start_line);
+				xodtemplate_add_contactgroup_members_to_memberlist(list,temp_contactgroup,_config_file,_start_line,perms);
+
 		                } 
 
 			/* free memory allocated to compiled regexp */
@@ -13399,7 +13531,7 @@
 						continue;
 
 					/* add contactgroup to list */
-					xodtemplate_add_contactgroup_members_to_memberlist(list,temp_contactgroup,_config_file,_start_line);
+					xodtemplate_add_contactgroup_members_to_memberlist(list,temp_contactgroup,_config_file,_start_line,perms);
 				        }
 			        }
 
@@ -13419,7 +13551,7 @@
 					found_match=TRUE;
 
 					/* add contactgroup members to proper list */
-					xodtemplate_add_contactgroup_members_to_memberlist((reject_item==TRUE)?reject_list:list,temp_contactgroup,_config_file,_start_line);
+					xodtemplate_add_contactgroup_members_to_memberlist((reject_item==TRUE)?reject_list:list,temp_contactgroup,_config_file,_start_line,perms);
 				        }
 			        }
 		        }
@@ -13430,6 +13562,8 @@
 #endif
 			break;
 	                }
+                if(temp_group_name)
+                  free (temp_group_name);
 	        }
 
 	/* free memory */
@@ -13568,9 +13702,10 @@
 
 
 /* adds members of a contactgroups to the list of expanded (accepted) or rejected contacts */
-int xodtemplate_add_contactgroup_members_to_memberlist(xodtemplate_memberlist **list, xodtemplate_contactgroup *temp_contactgroup,int _config_file, int _start_line){
+int xodtemplate_add_contactgroup_members_to_memberlist(xodtemplate_memberlist **list, xodtemplate_contactgroup *temp_contactgroup,int _config_file, int _start_line, char *perms){
 	char *group_members=NULL;
 	char *member_name=NULL;
+        char *member_name_with_perms=NULL;
 	char *member_ptr=NULL;
 
 	if(list==NULL || temp_contactgroup==NULL)
@@ -13598,8 +13733,14 @@
 		/* strip trailing spaces from member name */
 		strip(member_name);
 
+                /* add perms to member */
+                if (perms)
+                  asprintf(&member_name_with_perms,"%s%s",member_name,perms);
+                else
+                  member_name_with_perms = strdup(member_name);
+
 		/* add contact to the list */
-		xodtemplate_add_member_to_memberlist(list,member_name,NULL);
+		xodtemplate_add_member_to_memberlist(list,member_name_with_perms,NULL);
 	        }
 
 	my_free(group_members);
diff -ur nagios-3.0.6.org/xdata/xodtemplate.h nagios-3.0.6/xdata/xodtemplate.h
--- nagios-3.0.6.org/xdata/xodtemplate.h	2008-11-30 12:22:59.000000000 -0500
+++ nagios-3.0.6/xdata/xodtemplate.h	2009-05-16 11:32:07.000000000 -0400
@@ -787,7 +787,7 @@
 xodtemplate_memberlist *xodtemplate_expand_contactgroups_and_contacts(char *,char *,int,int);
 int xodtemplate_expand_contactgroups(xodtemplate_memberlist **,xodtemplate_memberlist **,char *,int,int);
 int xodtemplate_expand_contacts(xodtemplate_memberlist **,xodtemplate_memberlist **,char *,int,int);
-int xodtemplate_add_contactgroup_members_to_memberlist(xodtemplate_memberlist **,xodtemplate_contactgroup *,int,int);
+int xodtemplate_add_contactgroup_members_to_memberlist(xodtemplate_memberlist **,xodtemplate_contactgroup *,int,int, char *);
 
 xodtemplate_memberlist *xodtemplate_expand_hostgroups_and_hosts(char *,char *,int,int);
 int xodtemplate_expand_hostgroups(xodtemplate_memberlist **,xodtemplate_memberlist **,char *,int,int);