sort.c

Go to the documentation of this file.
00001 /**
00002  *  @file
00003  *  Implementation of seaudit sort routines.
00004  *
00005  *  @author Jeremy A. Mowery jmowery@tresys.com
00006  *  @author Jason Tang jtang@tresys.com
00007  *
00008  *  Copyright (C) 2003-2007 Tresys Technology, LLC
00009  *
00010  *  This library is free software; you can redistribute it and/or
00011  *  modify it under the terms of the GNU Lesser General Public
00012  *  License as published by the Free Software Foundation; either
00013  *  version 2.1 of the License, or (at your option) any later version.
00014  *
00015  *  This library is distributed in the hope that it will be useful,
00016  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00018  *  Lesser General Public License for more details.
00019  *
00020  *  You should have received a copy of the GNU Lesser General Public
00021  *  License along with this library; if not, write to the Free Software
00022  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00023  */
00024 
00025 #include "seaudit_internal.h"
00026 
00027 #include <apol/util.h>
00028 
00029 #include <errno.h>
00030 #include <string.h>
00031 
00032 /**
00033  * Callback that compares two messages.
00034  */
00035 typedef int (sort_comp_func) (const seaudit_sort_t * sort, const seaudit_message_t * a, const seaudit_message_t * b);
00036 
00037 /**
00038  * Callback that returns non-zero if the sort routine can handle the
00039  * given message, 0 if not supported.
00040  */
00041 typedef int (sort_supported_func) (const seaudit_sort_t * sort, const seaudit_message_t * m);
00042 
00043 struct seaudit_sort
00044 {
00045         const char *name;
00046         sort_comp_func *comp;
00047         sort_supported_func *support;
00048         int direction;
00049 };
00050 
00051 seaudit_sort_t *seaudit_sort_create_from_sort(const seaudit_sort_t * sort)
00052 {
00053         seaudit_sort_t *s;
00054         if (sort == NULL) {
00055                 errno = EINVAL;
00056                 return NULL;
00057         }
00058         if ((s = calloc(1, sizeof(*s))) == NULL) {
00059                 return NULL;
00060         }
00061         s->name = sort->name;
00062         s->comp = sort->comp;
00063         s->support = sort->support;
00064         s->direction = sort->direction;
00065         return s;
00066 }
00067 
00068 void seaudit_sort_destroy(seaudit_sort_t ** sort)
00069 {
00070         if (sort != NULL && *sort != NULL) {
00071                 free(*sort);
00072                 *sort = NULL;
00073         }
00074 }
00075 
00076 static seaudit_sort_t *sort_create(const char *name, sort_comp_func * comp, sort_supported_func support, const int direction)
00077 {
00078         seaudit_sort_t *s = calloc(1, sizeof(*s));
00079         if (s == NULL) {
00080                 return NULL;
00081         }
00082         s->name = name;
00083         s->comp = comp;
00084         s->support = support;
00085         s->direction = direction;
00086         return s;
00087 }
00088 
00089 seaudit_sort_t *sort_create_from_sort(const seaudit_sort_t * sort)
00090 {
00091         if (sort == NULL) {
00092                 errno = EINVAL;
00093                 return NULL;
00094         }
00095         return sort_create(sort->name, sort->comp, sort->support, sort->direction);
00096 }
00097 
00098 static int sort_message_type_comp(const seaudit_sort_t * sort
00099                                   __attribute__ ((unused)), const seaudit_message_t * a, const seaudit_message_t * b)
00100 {
00101         if (a->type != b->type) {
00102                 return a->type - b->type;
00103         }
00104         if (a->type == SEAUDIT_MESSAGE_TYPE_AVC) {
00105                 return a->data.avc->msg - b->data.avc->msg;
00106         }
00107         return 0;
00108 }
00109 
00110 static int sort_message_type_support(const seaudit_sort_t * sort __attribute__ ((unused)), const seaudit_message_t * msg)
00111 {
00112         return msg->type != SEAUDIT_MESSAGE_TYPE_INVALID;
00113 }
00114 
00115 seaudit_sort_t *seaudit_sort_by_message_type(const int direction)
00116 {
00117         return sort_create("message_type", sort_message_type_comp, sort_message_type_support, direction);
00118 }
00119 
00120 /**
00121  * Given two dates compare them, checking to see if the dates passed
00122  * in have valid years and correcting if not before comparing.
00123  */
00124 static int sort_date_comp(const seaudit_sort_t * sort
00125                           __attribute__ ((unused)), const seaudit_message_t * a, const seaudit_message_t * b)
00126 {
00127         /* tm has year, month, day, hour, min, sec */
00128         /* if we should compare the years */
00129         struct tm *t1 = a->date_stamp;
00130         struct tm *t2 = b->date_stamp;
00131         int retval;
00132         if (t1->tm_year != 0 && t2->tm_year != 0 && (retval = t1->tm_year - t2->tm_year) != 0) {
00133                 return retval;
00134         }
00135         if ((retval = t1->tm_mon - t2->tm_mon) != 0) {
00136                 return retval;
00137         }
00138         if ((retval = t1->tm_mday - t2->tm_mday) != 0) {
00139                 return retval;
00140         }
00141         if ((retval = t1->tm_hour - t2->tm_hour) != 0) {
00142                 return retval;
00143         }
00144         if ((retval = t1->tm_min - t2->tm_min) != 0) {
00145                 return retval;
00146         }
00147         if ((retval = t1->tm_sec - t2->tm_sec) != 0) {
00148                 return retval;
00149         }
00150         return 0;
00151 }
00152 
00153 static int sort_date_support(const seaudit_sort_t * sort __attribute__ ((unused)), const seaudit_message_t * msg)
00154 {
00155         return msg->date_stamp != NULL;
00156 }
00157 
00158 seaudit_sort_t *seaudit_sort_by_date(const int direction)
00159 {
00160         return sort_create("date", sort_date_comp, sort_date_support, direction);
00161 }
00162 
00163 static int sort_host_comp(const seaudit_sort_t * sort
00164                           __attribute__ ((unused)), const seaudit_message_t * a, const seaudit_message_t * b)
00165 {
00166         return strcmp(a->host, b->host);
00167 }
00168 
00169 static int sort_host_support(const seaudit_sort_t * sort __attribute__ ((unused)), const seaudit_message_t * msg)
00170 {
00171         return msg->host != NULL;
00172 }
00173 
00174 seaudit_sort_t *seaudit_sort_by_host(const int direction)
00175 {
00176         return sort_create("host", sort_host_comp, sort_host_support, direction);
00177 }
00178 
00179 static int sort_perm_comp(const seaudit_sort_t * sort
00180                           __attribute__ ((unused)), const seaudit_message_t * a, const seaudit_message_t * b)
00181 {
00182         size_t i;
00183         return apol_vector_compare(a->data.avc->perms, b->data.avc->perms, apol_str_strcmp, NULL, &i);
00184 }
00185 
00186 static int sort_perm_support(const seaudit_sort_t * sort __attribute__ ((unused)), const seaudit_message_t * msg)
00187 {
00188         return msg->type == SEAUDIT_MESSAGE_TYPE_AVC &&
00189                 msg->data.avc->perms != NULL && apol_vector_get_size(msg->data.avc->perms) >= 1;
00190 }
00191 
00192 seaudit_sort_t *seaudit_sort_by_permission(const int direction)
00193 {
00194         return sort_create("permission", sort_perm_comp, sort_perm_support, direction);
00195 }
00196 
00197 static int sort_source_user_comp(const seaudit_sort_t * sort
00198                                  __attribute__ ((unused)), const seaudit_message_t * a, const seaudit_message_t * b)
00199 {
00200         return strcmp(a->data.avc->suser, b->data.avc->suser);
00201 }
00202 
00203 static int sort_source_user_support(const seaudit_sort_t * sort __attribute__ ((unused)), const seaudit_message_t * msg)
00204 {
00205         return msg->type == SEAUDIT_MESSAGE_TYPE_AVC && msg->data.avc->suser != NULL;
00206 }
00207 
00208 seaudit_sort_t *seaudit_sort_by_source_user(const int direction)
00209 {
00210         return sort_create("source_user", sort_source_user_comp, sort_source_user_support, direction);
00211 }
00212 
00213 static int sort_source_role_comp(const seaudit_sort_t * sort __attribute((unused)), const seaudit_message_t * a,
00214                                  const seaudit_message_t * b)
00215 {
00216         return strcmp(a->data.avc->srole, b->data.avc->srole);
00217 }
00218 
00219 static int sort_source_role_support(const seaudit_sort_t * sort __attribute__ ((unused)), const seaudit_message_t * msg)
00220 {
00221         return msg->type == SEAUDIT_MESSAGE_TYPE_AVC && msg->data.avc->srole != NULL;
00222 }
00223 
00224 seaudit_sort_t *seaudit_sort_by_source_role(const int direction)
00225 {
00226         return sort_create("source_role", sort_source_role_comp, sort_source_role_support, direction);
00227 }
00228 
00229 static int sort_source_type_comp(const seaudit_sort_t * sort
00230                                  __attribute__ ((unused)), const seaudit_message_t * a, const seaudit_message_t * b)
00231 {
00232         return strcmp(a->data.avc->stype, b->data.avc->stype);
00233 }
00234 
00235 static int sort_source_type_support(const seaudit_sort_t * sort __attribute__ ((unused)), const seaudit_message_t * msg)
00236 {
00237         return msg->type == SEAUDIT_MESSAGE_TYPE_AVC && msg->data.avc->stype != NULL;
00238 }
00239 
00240 seaudit_sort_t *seaudit_sort_by_source_type(const int direction)
00241 {
00242         return sort_create("source_type", sort_source_type_comp, sort_source_type_support, direction);
00243 }
00244 
00245 static int sort_target_user_comp(const seaudit_sort_t * sort
00246                                  __attribute__ ((unused)), const seaudit_message_t * a, const seaudit_message_t * b)
00247 {
00248         return strcmp(a->data.avc->tuser, b->data.avc->tuser);
00249 }
00250 
00251 static int sort_target_user_support(const seaudit_sort_t * sort __attribute__ ((unused)), const seaudit_message_t * msg)
00252 {
00253         return msg->type == SEAUDIT_MESSAGE_TYPE_AVC && msg->data.avc->tuser != NULL;
00254 }
00255 
00256 seaudit_sort_t *seaudit_sort_by_target_user(const int direction)
00257 {
00258         return sort_create("target_user", sort_target_user_comp, sort_target_user_support, direction);
00259 }
00260 
00261 static int sort_target_role_comp(const seaudit_sort_t * sort
00262                                  __attribute__ ((unused)), const seaudit_message_t * a, const seaudit_message_t * b)
00263 {
00264         return strcmp(a->data.avc->trole, b->data.avc->trole);
00265 }
00266 
00267 static int sort_target_role_support(const seaudit_sort_t * sort __attribute__ ((unused)), const seaudit_message_t * msg)
00268 {
00269         return msg->type == SEAUDIT_MESSAGE_TYPE_AVC && msg->data.avc->trole != NULL;
00270 }
00271 
00272 seaudit_sort_t *seaudit_sort_by_target_role(const int direction)
00273 {
00274         return sort_create("target_role", sort_target_role_comp, sort_target_role_support, direction);
00275 }
00276 
00277 static int sort_target_type_comp(const seaudit_sort_t * sort
00278                                  __attribute__ ((unused)), const seaudit_message_t * a, const seaudit_message_t * b)
00279 {
00280         return strcmp(a->data.avc->ttype, b->data.avc->ttype);
00281 }
00282 
00283 static int sort_target_type_support(const seaudit_sort_t * sort __attribute__ ((unused)), const seaudit_message_t * msg)
00284 {
00285         return msg->type == SEAUDIT_MESSAGE_TYPE_AVC && msg->data.avc->ttype != NULL;
00286 }
00287 
00288 seaudit_sort_t *seaudit_sort_by_target_type(const int direction)
00289 {
00290         return sort_create("target_type", sort_target_type_comp, sort_target_type_support, direction);
00291 }
00292 
00293 static int sort_object_class_comp(const seaudit_sort_t * sort
00294                                   __attribute__ ((unused)), const seaudit_message_t * a, const seaudit_message_t * b)
00295 {
00296         return strcmp(a->data.avc->tclass, b->data.avc->tclass);
00297 }
00298 
00299 static int sort_object_class_support(const seaudit_sort_t * sort __attribute__ ((unused)), const seaudit_message_t * msg)
00300 {
00301         return msg->type == SEAUDIT_MESSAGE_TYPE_AVC && msg->data.avc->tclass != NULL;
00302 }
00303 
00304 seaudit_sort_t *seaudit_sort_by_object_class(const int direction)
00305 {
00306         return sort_create("object_class", sort_object_class_comp, sort_object_class_support, direction);
00307 }
00308 
00309 static int sort_executable_comp(const seaudit_sort_t * sort
00310                                 __attribute__ ((unused)), const seaudit_message_t * a, const seaudit_message_t * b)
00311 {
00312         return strcmp(a->data.avc->exe, b->data.avc->exe);
00313 }
00314 
00315 static int sort_executable_support(const seaudit_sort_t * sort __attribute__ ((unused)), const seaudit_message_t * msg)
00316 {
00317         return msg->type == SEAUDIT_MESSAGE_TYPE_AVC && msg->data.avc->exe != NULL;
00318 }
00319 
00320 seaudit_sort_t *seaudit_sort_by_executable(const int direction)
00321 {
00322         return sort_create("executable", sort_executable_comp, sort_executable_support, direction);
00323 }
00324 
00325 static int sort_command_comp(const seaudit_sort_t * sort
00326                              __attribute__ ((unused)), const seaudit_message_t * a, const seaudit_message_t * b)
00327 {
00328         return strcmp(a->data.avc->comm, b->data.avc->comm);
00329 }
00330 
00331 static int sort_command_support(const seaudit_sort_t * sort __attribute__ ((unused)), const seaudit_message_t * msg)
00332 {
00333         return msg->type == SEAUDIT_MESSAGE_TYPE_AVC && msg->data.avc->comm != NULL;
00334 }
00335 
00336 seaudit_sort_t *seaudit_sort_by_command(const int direction)
00337 {
00338         return sort_create("command", sort_command_comp, sort_command_support, direction);
00339 }
00340 
00341 static int sort_name_comp(const seaudit_sort_t * sort
00342                           __attribute__ ((unused)), const seaudit_message_t * a, const seaudit_message_t * b)
00343 {
00344         return strcmp(a->data.avc->name, b->data.avc->name);
00345 }
00346 
00347 static int sort_name_support(const seaudit_sort_t * sort __attribute__ ((unused)), const seaudit_message_t * msg)
00348 {
00349         return msg->type == SEAUDIT_MESSAGE_TYPE_AVC && msg->data.avc->name != NULL;
00350 }
00351 
00352 seaudit_sort_t *seaudit_sort_by_name(const int direction)
00353 {
00354         return sort_create("name", sort_name_comp, sort_name_support, direction);
00355 }
00356 
00357 static int sort_path_comp(const seaudit_sort_t * sort
00358                           __attribute__ ((unused)), const seaudit_message_t * a, const seaudit_message_t * b)
00359 {
00360         return strcmp(a->data.avc->path, b->data.avc->path);
00361 }
00362 
00363 static int sort_path_support(const seaudit_sort_t * sort __attribute__ ((unused)), const seaudit_message_t * msg)
00364 {
00365         return msg->type == SEAUDIT_MESSAGE_TYPE_AVC && msg->data.avc->path != NULL;
00366 }
00367 
00368 seaudit_sort_t *seaudit_sort_by_path(const int direction)
00369 {
00370         return sort_create("path", sort_path_comp, sort_path_support, direction);
00371 }
00372 
00373 static int sort_device_comp(const seaudit_sort_t * sort
00374                             __attribute__ ((unused)), const seaudit_message_t * a, const seaudit_message_t * b)
00375 {
00376         return strcmp(a->data.avc->dev, b->data.avc->dev);
00377 }
00378 
00379 static int sort_device_support(const seaudit_sort_t * sort __attribute__ ((unused)), const seaudit_message_t * msg)
00380 {
00381         return msg->type == SEAUDIT_MESSAGE_TYPE_AVC && msg->data.avc->dev != NULL;
00382 }
00383 
00384 seaudit_sort_t *seaudit_sort_by_device(const int direction)
00385 {
00386         return sort_create("device", sort_device_comp, sort_device_support, direction);
00387 }
00388 
00389 static int sort_inode_comp(const seaudit_sort_t * sort
00390                            __attribute__ ((unused)), const seaudit_message_t * a, const seaudit_message_t * b)
00391 {
00392         /* need this logic because inodes are unsigned, so subtraction
00393          * could overflow */
00394         if (a->data.avc->inode < b->data.avc->inode) {
00395                 return -1;
00396         }
00397         return a->data.avc->inode - b->data.avc->inode;
00398 }
00399 
00400 static int sort_inode_support(const seaudit_sort_t * sort __attribute__ ((unused)), const seaudit_message_t * msg)
00401 {
00402         return msg->type == SEAUDIT_MESSAGE_TYPE_AVC && msg->data.avc->inode > 0;
00403 }
00404 
00405 seaudit_sort_t *seaudit_sort_by_inode(const int direction)
00406 {
00407         return sort_create("inode", sort_inode_comp, sort_inode_support, direction);
00408 }
00409 
00410 static int sort_pid_comp(const seaudit_sort_t * sort
00411                          __attribute__ ((unused)), const seaudit_message_t * a, const seaudit_message_t * b)
00412 {
00413         /* need this logic because pids are unsigned, so subtraction
00414          * could overflow */
00415         if (a->data.avc->pid < b->data.avc->pid) {
00416                 return -1;
00417         }
00418         return a->data.avc->pid - b->data.avc->pid;
00419 }
00420 
00421 static int sort_pid_support(const seaudit_sort_t * sort __attribute__ ((unused)), const seaudit_message_t * msg)
00422 {
00423         return msg->type == SEAUDIT_MESSAGE_TYPE_AVC && msg->data.avc->pid > 0;
00424 }
00425 
00426 seaudit_sort_t *seaudit_sort_by_pid(const int direction)
00427 {
00428         return sort_create("pid", sort_pid_comp, sort_pid_support, direction);
00429 }
00430 
00431 static int sort_port_comp(const seaudit_sort_t * sort
00432                           __attribute__ ((unused)), const seaudit_message_t * a, const seaudit_message_t * b)
00433 {
00434         return a->data.avc->port - b->data.avc->port;
00435 }
00436 
00437 static int sort_port_support(const seaudit_sort_t * sort __attribute__ ((unused)), const seaudit_message_t * msg)
00438 {
00439         return msg->type == SEAUDIT_MESSAGE_TYPE_AVC && msg->data.avc->port > 0;
00440 }
00441 
00442 seaudit_sort_t *seaudit_sort_by_port(const int direction)
00443 {
00444         return sort_create("port", sort_port_comp, sort_port_support, direction);
00445 }
00446 
00447 static int sort_laddr_comp(const seaudit_sort_t * sort
00448                            __attribute__ ((unused)), const seaudit_message_t * a, const seaudit_message_t * b)
00449 {
00450         return strcmp(a->data.avc->laddr, b->data.avc->laddr);
00451 }
00452 
00453 static int sort_laddr_support(const seaudit_sort_t * sort __attribute__ ((unused)), const seaudit_message_t * msg)
00454 {
00455         return msg->type == SEAUDIT_MESSAGE_TYPE_AVC && msg->data.avc->laddr != NULL;
00456 }
00457 
00458 seaudit_sort_t *seaudit_sort_by_laddr(const int direction)
00459 {
00460         return sort_create("laddr", sort_laddr_comp, sort_laddr_support, direction);
00461 }
00462 
00463 static int sort_lport_comp(const seaudit_sort_t * sort
00464                            __attribute__ ((unused)), const seaudit_message_t * a, const seaudit_message_t * b)
00465 {
00466         return a->data.avc->lport - b->data.avc->lport;
00467 }
00468 
00469 static int sort_lport_support(const seaudit_sort_t * sort __attribute__ ((unused)), const seaudit_message_t * msg)
00470 {
00471         return msg->type == SEAUDIT_MESSAGE_TYPE_AVC && msg->data.avc->lport > 0;
00472 }
00473 
00474 seaudit_sort_t *seaudit_sort_by_lport(const int direction)
00475 {
00476         return sort_create("lport", sort_lport_comp, sort_lport_support, direction);
00477 }
00478 
00479 static int sort_faddr_comp(const seaudit_sort_t * sort
00480                            __attribute__ ((unused)), const seaudit_message_t * a, const seaudit_message_t * b)
00481 {
00482         return strcmp(a->data.avc->faddr, b->data.avc->faddr);
00483 }
00484 
00485 static int sort_faddr_support(const seaudit_sort_t * sort __attribute__ ((unused)), const seaudit_message_t * msg)
00486 {
00487         return msg->type == SEAUDIT_MESSAGE_TYPE_AVC && msg->data.avc->faddr != NULL;
00488 }
00489 
00490 seaudit_sort_t *seaudit_sort_by_faddr(const int direction)
00491 {
00492         return sort_create("faddr", sort_faddr_comp, sort_faddr_support, direction);
00493 }
00494 
00495 static int sort_fport_comp(const seaudit_sort_t * sort
00496                            __attribute__ ((unused)), const seaudit_message_t * a, const seaudit_message_t * b)
00497 {
00498         return a->data.avc->fport - b->data.avc->fport;
00499 }
00500 
00501 static int sort_fport_support(const seaudit_sort_t * sort __attribute__ ((unused)), const seaudit_message_t * msg)
00502 {
00503         return msg->type == SEAUDIT_MESSAGE_TYPE_AVC && msg->data.avc->fport > 0;
00504 }
00505 
00506 seaudit_sort_t *seaudit_sort_by_fport(const int direction)
00507 {
00508         return sort_create("fport", sort_fport_comp, sort_fport_support, direction);
00509 }
00510 
00511 static int sort_saddr_comp(const seaudit_sort_t * sort
00512                            __attribute__ ((unused)), const seaudit_message_t * a, const seaudit_message_t * b)
00513 {
00514         return strcmp(a->data.avc->saddr, b->data.avc->saddr);
00515 }
00516 
00517 static int sort_saddr_support(const seaudit_sort_t * sort __attribute__ ((unused)), const seaudit_message_t * msg)
00518 {
00519         return msg->type == SEAUDIT_MESSAGE_TYPE_AVC && msg->data.avc->saddr != NULL;
00520 }
00521 
00522 seaudit_sort_t *seaudit_sort_by_saddr(const int direction)
00523 {
00524         return sort_create("saddr", sort_saddr_comp, sort_saddr_support, direction);
00525 }
00526 
00527 static int sort_sport_comp(const seaudit_sort_t * sort
00528                            __attribute__ ((unused)), const seaudit_message_t * a, const seaudit_message_t * b)
00529 {
00530         return a->data.avc->source - b->data.avc->source;
00531 }
00532 
00533 static int sort_sport_support(const seaudit_sort_t * sort __attribute__ ((unused)), const seaudit_message_t * msg)
00534 {
00535         return msg->type == SEAUDIT_MESSAGE_TYPE_AVC && msg->data.avc->source > 0;
00536 }
00537 
00538 seaudit_sort_t *seaudit_sort_by_sport(const int direction)
00539 {
00540         return sort_create("sport", sort_sport_comp, sort_sport_support, direction);
00541 }
00542 
00543 static int sort_daddr_comp(const seaudit_sort_t * sort
00544                            __attribute__ ((unused)), const seaudit_message_t * a, const seaudit_message_t * b)
00545 {
00546         return strcmp(a->data.avc->daddr, b->data.avc->daddr);
00547 }
00548 
00549 static int sort_daddr_support(const seaudit_sort_t * sort __attribute__ ((unused)), const seaudit_message_t * msg)
00550 {
00551         return msg->type == SEAUDIT_MESSAGE_TYPE_AVC && msg->data.avc->daddr != NULL;
00552 }
00553 
00554 seaudit_sort_t *seaudit_sort_by_daddr(const int direction)
00555 {
00556         return sort_create("daddr", sort_daddr_comp, sort_daddr_support, direction);
00557 }
00558 
00559 static int sort_dport_comp(const seaudit_sort_t * sort
00560                            __attribute__ ((unused)), const seaudit_message_t * a, const seaudit_message_t * b)
00561 {
00562         return a->data.avc->dest - b->data.avc->dest;
00563 }
00564 
00565 static int sort_dport_support(const seaudit_sort_t * sort __attribute__ ((unused)), const seaudit_message_t * msg)
00566 {
00567         return msg->type == SEAUDIT_MESSAGE_TYPE_AVC && msg->data.avc->dest > 0;
00568 }
00569 
00570 seaudit_sort_t *seaudit_sort_by_dport(const int direction)
00571 {
00572         return sort_create("dport", sort_dport_comp, sort_dport_support, direction);
00573 }
00574 
00575 static int sort_key_comp(const seaudit_sort_t * sort
00576                          __attribute__ ((unused)), const seaudit_message_t * a, const seaudit_message_t * b)
00577 {
00578         return a->data.avc->key - b->data.avc->key;
00579 }
00580 
00581 static int sort_key_support(const seaudit_sort_t * sort __attribute__ ((unused)), const seaudit_message_t * msg)
00582 {
00583         return msg->type == SEAUDIT_MESSAGE_TYPE_AVC && msg->data.avc->is_key;
00584 }
00585 
00586 seaudit_sort_t *seaudit_sort_by_key(const int direction)
00587 {
00588         return sort_create("key", sort_key_comp, sort_key_support, direction);
00589 }
00590 
00591 static int sort_cap_comp(const seaudit_sort_t * sort
00592                          __attribute__ ((unused)), const seaudit_message_t * a, const seaudit_message_t * b)
00593 {
00594         return a->data.avc->capability - b->data.avc->capability;
00595 }
00596 
00597 static int sort_cap_support(const seaudit_sort_t * sort __attribute__ ((unused)), const seaudit_message_t * msg)
00598 {
00599         return msg->type == SEAUDIT_MESSAGE_TYPE_AVC && msg->data.avc->is_capability;
00600 }
00601 
00602 seaudit_sort_t *seaudit_sort_by_cap(const int direction)
00603 {
00604         return sort_create("cap", sort_cap_comp, sort_cap_support, direction);
00605 }
00606 
00607 /******************** protected functions below ********************/
00608 
00609 struct sort_name_map
00610 {
00611         const char *name;
00612         seaudit_sort_t *(*create_fn) (int);
00613 };
00614 
00615 static const struct sort_name_map create_map[] = {
00616         {"message_type", seaudit_sort_by_message_type},
00617         {"date", seaudit_sort_by_date},
00618         {"host", seaudit_sort_by_host},
00619         {"permission", seaudit_sort_by_permission},
00620         {"source_user", seaudit_sort_by_source_user},
00621         {"source_role", seaudit_sort_by_source_role},
00622         {"source_type", seaudit_sort_by_source_type},
00623         {"target_user", seaudit_sort_by_target_user},
00624         {"target_role", seaudit_sort_by_target_role},
00625         {"target_type", seaudit_sort_by_target_type},
00626         {"object_class", seaudit_sort_by_object_class},
00627         {"executable", seaudit_sort_by_executable},
00628         {"name", seaudit_sort_by_name},
00629         {"command", seaudit_sort_by_command},
00630         {"path", seaudit_sort_by_path},
00631         {"device", seaudit_sort_by_device},
00632         {"inode", seaudit_sort_by_inode},
00633         {"pid", seaudit_sort_by_pid},
00634         {"port", seaudit_sort_by_port},
00635         {"laddr", seaudit_sort_by_laddr},
00636         {"lport", seaudit_sort_by_lport},
00637         {"faddr", seaudit_sort_by_faddr},
00638         {"fport", seaudit_sort_by_fport},
00639         {"saddr", seaudit_sort_by_saddr},
00640         {"sport", seaudit_sort_by_sport},
00641         {"daddr", seaudit_sort_by_daddr},
00642         {"dport", seaudit_sort_by_dport},
00643         {"key", seaudit_sort_by_key},
00644         {"cap", seaudit_sort_by_cap},
00645         {NULL, NULL}
00646 };
00647 
00648 seaudit_sort_t *sort_create_from_name(const char *name, int direction)
00649 {
00650         size_t i;
00651         for (i = 0; create_map[i].name != NULL; i++) {
00652                 if (strcmp(create_map[i].name, name) == 0) {
00653                         return create_map[i].create_fn(direction);
00654                 }
00655         }
00656         errno = EINVAL;
00657         return NULL;
00658 }
00659 
00660 int sort_is_supported(const seaudit_sort_t * sort, const seaudit_message_t * msg)
00661 {
00662         return sort->support(sort, msg);
00663 }
00664 
00665 int sort_comp(const seaudit_sort_t * sort, const seaudit_message_t * a, const seaudit_message_t * b)
00666 {
00667         int retval = sort->comp(sort, a, b);
00668         return (sort->direction >= 0 ? retval : -1 * retval);
00669 }
00670 
00671 const char *sort_get_name(const seaudit_sort_t * sort)
00672 {
00673         return sort->name;
00674 }
00675 
00676 int sort_get_direction(const seaudit_sort_t * sort)
00677 {
00678         return sort->direction;
00679 }