Diff for /embedaddon/sudo/src/hooks.c between versions 1.1.1.3 and 1.1.1.4

version 1.1.1.3, 2013/07/22 10:46:13 version 1.1.1.4, 2014/06/15 16:12:55
Line 1 Line 1
 /*  /*
 * Copyright (c) 2012 Todd C. Miller <Todd.Miller@courtesan.com> * Copyright (c) 2012-2013 Todd C. Miller <Todd.Miller@courtesan.com>
  *   *
  * Permission to use, copy, modify, and distribute this software for any   * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above   * purpose with or without fee is hereby granted, provided that the above
Line 40 Line 40
 #include "sudo_plugin.h"  #include "sudo_plugin.h"
 #include "sudo_plugin_int.h"  #include "sudo_plugin_int.h"
 #include "sudo_debug.h"  #include "sudo_debug.h"
   #include "queue.h"
   
 /* Singly linked hook list. */  /* Singly linked hook list. */
struct sudo_hook_list {struct sudo_hook_entry {
    struct sudo_hook_list *next;    SLIST_ENTRY(sudo_hook_entry) entries;
     union {      union {
         sudo_hook_fn_t generic_fn;          sudo_hook_fn_t generic_fn;
         sudo_hook_fn_setenv_t setenv_fn;          sudo_hook_fn_setenv_t setenv_fn;
Line 53  struct sudo_hook_list { Line 54  struct sudo_hook_list {
     } u;      } u;
     void *closure;      void *closure;
 };  };
   SLIST_HEAD(sudo_hook_list, sudo_hook_entry);
   
 /* Each hook type gets own hook list. */  /* Each hook type gets own hook list. */
static struct sudo_hook_list *sudo_hook_setenv_list;static struct sudo_hook_list sudo_hook_setenv_list =
static struct sudo_hook_list *sudo_hook_unsetenv_list;    SLIST_HEAD_INITIALIZER(sudo_hook_setenv_list);
static struct sudo_hook_list *sudo_hook_getenv_list;static struct sudo_hook_list sudo_hook_unsetenv_list =
static struct sudo_hook_list *sudo_hook_putenv_list;    SLIST_HEAD_INITIALIZER(sudo_hook_unsetenv_list);
 static struct sudo_hook_list sudo_hook_getenv_list =
     SLIST_HEAD_INITIALIZER(sudo_hook_getenv_list);
 static struct sudo_hook_list sudo_hook_putenv_list =
     SLIST_HEAD_INITIALIZER(sudo_hook_putenv_list);
   
 /* NOTE: must not anything that might call setenv() */  /* NOTE: must not anything that might call setenv() */
 int  int
 process_hooks_setenv(const char *name, const char *value, int overwrite)  process_hooks_setenv(const char *name, const char *value, int overwrite)
 {  {
    struct sudo_hook_list *hook;    struct sudo_hook_entry *hook;
     int rc = SUDO_HOOK_RET_NEXT;      int rc = SUDO_HOOK_RET_NEXT;
   
     /* First process the hooks. */      /* First process the hooks. */
    for (hook = sudo_hook_setenv_list; hook != NULL; hook = hook->next) {    SLIST_FOREACH(hook, &sudo_hook_setenv_list, entries) {
         rc = hook->u.setenv_fn(name, value, overwrite, hook->closure);          rc = hook->u.setenv_fn(name, value, overwrite, hook->closure);
         switch (rc) {          switch (rc) {
             case SUDO_HOOK_RET_NEXT:              case SUDO_HOOK_RET_NEXT:
Line 89  done: Line 95  done:
 int  int
 process_hooks_putenv(char *string)  process_hooks_putenv(char *string)
 {  {
    struct sudo_hook_list *hook;    struct sudo_hook_entry *hook;
     int rc = SUDO_HOOK_RET_NEXT;      int rc = SUDO_HOOK_RET_NEXT;
   
     /* First process the hooks. */      /* First process the hooks. */
    for (hook = sudo_hook_putenv_list; hook != NULL; hook = hook->next) {    SLIST_FOREACH(hook, &sudo_hook_putenv_list, entries) {
         rc = hook->u.putenv_fn(string, hook->closure);          rc = hook->u.putenv_fn(string, hook->closure);
         switch (rc) {          switch (rc) {
             case SUDO_HOOK_RET_NEXT:              case SUDO_HOOK_RET_NEXT:
Line 114  done: Line 120  done:
 int  int
 process_hooks_getenv(const char *name, char **value)  process_hooks_getenv(const char *name, char **value)
 {  {
    struct sudo_hook_list *hook;    struct sudo_hook_entry *hook;
     char *val = NULL;      char *val = NULL;
     int rc = SUDO_HOOK_RET_NEXT;      int rc = SUDO_HOOK_RET_NEXT;
   
     /* First process the hooks. */      /* First process the hooks. */
    for (hook = sudo_hook_getenv_list; hook != NULL; hook = hook->next) {    SLIST_FOREACH(hook, &sudo_hook_getenv_list, entries) {
         rc = hook->u.getenv_fn(name, &val, hook->closure);          rc = hook->u.getenv_fn(name, &val, hook->closure);
         switch (rc) {          switch (rc) {
             case SUDO_HOOK_RET_NEXT:              case SUDO_HOOK_RET_NEXT:
Line 142  done: Line 148  done:
 int  int
 process_hooks_unsetenv(const char *name)  process_hooks_unsetenv(const char *name)
 {  {
    struct sudo_hook_list *hook;    struct sudo_hook_entry *hook;
     int rc = SUDO_HOOK_RET_NEXT;      int rc = SUDO_HOOK_RET_NEXT;
   
     /* First process the hooks. */      /* First process the hooks. */
    for (hook = sudo_hook_unsetenv_list; hook != NULL; hook = hook->next) {    SLIST_FOREACH(hook, &sudo_hook_unsetenv_list, entries) {
         rc = hook->u.unsetenv_fn(name, hook->closure);          rc = hook->u.unsetenv_fn(name, hook->closure);
         switch (rc) {          switch (rc) {
             case SUDO_HOOK_RET_NEXT:              case SUDO_HOOK_RET_NEXT:
Line 165  done: Line 171  done:
   
 /* Hook registration internals. */  /* Hook registration internals. */
 static void  static void
register_hook_internal(struct sudo_hook_list **head,register_hook_internal(struct sudo_hook_list *head,
     int (*hook_fn)(), void *closure)      int (*hook_fn)(), void *closure)
 {  {
    struct sudo_hook_list *hook;    struct sudo_hook_entry *hook;
     debug_decl(register_hook_internal, SUDO_DEBUG_HOOKS)      debug_decl(register_hook_internal, SUDO_DEBUG_HOOKS)
   
     hook = ecalloc(1, sizeof(*hook));      hook = ecalloc(1, sizeof(*hook));
     hook->u.generic_fn = hook_fn;      hook->u.generic_fn = hook_fn;
     hook->closure = closure;      hook->closure = closure;
    hook->next = *head;    SLIST_INSERT_HEAD(head, hook, entries);
    *head = hook; 
   
     debug_return;      debug_return;
 }  }
Line 220  register_hook(struct sudo_hook *hook) Line 225  register_hook(struct sudo_hook *hook)
   
 /* Hook deregistration internals. */  /* Hook deregistration internals. */
 static void  static void
deregister_hook_internal(struct sudo_hook_list **head,deregister_hook_internal(struct sudo_hook_list *head,
     int (*hook_fn)(), void *closure)      int (*hook_fn)(), void *closure)
 {  {
    struct sudo_hook_list *hook, *prev = NULL;    struct sudo_hook_entry *hook, *prev = NULL;
     debug_decl(deregister_hook_internal, SUDO_DEBUG_HOOKS)      debug_decl(deregister_hook_internal, SUDO_DEBUG_HOOKS)
   
    for (hook = *head, prev = NULL; hook != NULL; prev = hook, hook = hook->next) {    SLIST_FOREACH(hook, head, entries) {
         if (hook->u.generic_fn == hook_fn && hook->closure == closure) {          if (hook->u.generic_fn == hook_fn && hook->closure == closure) {
             /* Remove from list and free. */              /* Remove from list and free. */
             if (prev == NULL)              if (prev == NULL)
                *head = hook->next;                SLIST_REMOVE_HEAD(head, entries);
             else              else
                prev->next = hook->next;                SLIST_REMOVE_AFTER(prev, entries);
             efree(hook);              efree(hook);
             break;              break;
         }          }
           prev = hook;
     }      }
   
     debug_return;      debug_return;

Removed from v.1.1.1.3  
changed lines
  Added in v.1.1.1.4


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>