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,¤t_authdata)==TRUE) + if(is_authorized_for_hostgroup_commands(temp_hostgroup,¤t_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,¤t_authdata)==TRUE) + if(is_authorized_for_servicegroup_commands(temp_servicegroup,¤t_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);