Annotation of embedaddon/dnsmasq/contrib/lease-access/lease.access.patch, revision 1.1.1.1

1.1       misho       1: Index: src/dnsmasq.c
                      2: ===================================================================
                      3: --- src/dnsmasq.c      (revision 696)
                      4: +++ src/dnsmasq.c      (revision 821)
                      5: @@ -59,7 +59,6 @@
                      6:  static int set_dns_listeners(time_t now, fd_set *set, int *maxfdp);
                      7:  static void check_dns_listeners(fd_set *set, time_t now);
                      8:  static void sig_handler(int sig);
                      9: -static void async_event(int pipe, time_t now);
                     10:  static void fatal_event(struct event_desc *ev);
                     11:  static void poll_resolv(void);
                     12:  
                     13: @@ -275,7 +274,7 @@
                     14:    piperead = pipefd[0];
                     15:    pipewrite = pipefd[1];
                     16:    /* prime the pipe to load stuff first time. */
                     17: -  send_event(pipewrite, EVENT_RELOAD, 0); 
                     18: +  send_event(pipewrite, EVENT_RELOAD, 0, 0); 
                     19:  
                     20:    err_pipe[1] = -1;
                     21:    
                     22: @@ -340,7 +339,7 @@
                     23:            }
                     24:          else if (getuid() == 0)
                     25:            {
                     26: -            send_event(err_pipe[1], EVENT_PIDFILE, errno);
                     27: +            send_event(err_pipe[1], EVENT_PIDFILE, errno, 0);
                     28:              _exit(0);
                     29:            }
                     30:        }
                     31: @@ -372,7 +371,7 @@
                     32:          (setgroups(0, &dummy) == -1 ||
                     33:           setgid(gp->gr_gid) == -1))
                     34:        {
                     35: -        send_event(err_pipe[1], EVENT_GROUP_ERR, errno);
                     36: +        send_event(err_pipe[1], EVENT_GROUP_ERR, errno, 0);
                     37:          _exit(0);
                     38:        }
                     39:    
                     40: @@ -415,14 +414,14 @@
                     41:  
                     42:          if (bad_capabilities != 0)
                     43:            {
                     44: -            send_event(err_pipe[1], EVENT_CAP_ERR, bad_capabilities);
                     45: +            send_event(err_pipe[1], EVENT_CAP_ERR, bad_capabilities, 0);
                     46:              _exit(0);
                     47:            }
                     48:          
                     49:          /* finally drop root */
                     50:          if (setuid(ent_pw->pw_uid) == -1)
                     51:            {
                     52: -            send_event(err_pipe[1], EVENT_USER_ERR, errno);
                     53: +            send_event(err_pipe[1], EVENT_USER_ERR, errno, 0);
                     54:              _exit(0);
                     55:            }     
                     56:  
                     57: @@ -434,7 +433,7 @@
                     58:          /* lose the setuid and setgid capbilities */
                     59:          if (capset(hdr, data) == -1)
                     60:            {
                     61: -            send_event(err_pipe[1], EVENT_CAP_ERR, errno);
                     62: +            send_event(err_pipe[1], EVENT_CAP_ERR, errno, 0);
                     63:              _exit(0);
                     64:            }
                     65:  #endif
                     66: @@ -647,7 +646,7 @@
                     67:        }
                     68:        
                     69:        if (FD_ISSET(piperead, &rset))
                     70: -      async_event(piperead, now);
                     71: +      async_event(piperead, now, NULL, 0);
                     72:        
                     73:  #ifdef HAVE_LINUX_NETWORK
                     74:        if (FD_ISSET(daemon->netlinkfd, &rset))
                     75: @@ -674,7 +673,7 @@
                     76:  #endif      
                     77:  
                     78:        if (daemon->dhcp && FD_ISSET(daemon->dhcpfd, &rset))
                     79: -      dhcp_packet(now);
                     80: +      dhcp_packet(piperead, now);
                     81:  
                     82:  #ifndef NO_FORK
                     83:        if (daemon->helperfd != -1 && FD_ISSET(daemon->helperfd, &wset))
                     84: @@ -719,17 +718,18 @@
                     85:        else
                     86:        return;
                     87:  
                     88: -      send_event(pipewrite, event, 0); 
                     89: +      send_event(pipewrite, event, 0, 0); 
                     90:        errno = errsave;
                     91:      }
                     92:  }
                     93:  
                     94: -void send_event(int fd, int event, int data)
                     95: +void send_event(int fd, int event, int data, int priv)
                     96:  {
                     97:    struct event_desc ev;
                     98:    
                     99:    ev.event = event;
                    100:    ev.data = data;
                    101: +  ev.priv = priv;
                    102:    
                    103:    /* error pipe, debug mode. */
                    104:    if (fd == -1)
                    105: @@ -771,14 +771,17 @@
                    106:        die(_("cannot open %s: %s"), daemon->log_file ? daemon->log_file : "log", EC_FILE);
                    107:      }
                    108:  }     
                    109: -      
                    110: -static void async_event(int pipe, time_t now)
                    111: +
                    112: +/* returns the private data of the event
                    113: + */
                    114: +int async_event(int pipe, time_t now, struct event_desc* event, unsigned int secs)
                    115:  {
                    116:    pid_t p;
                    117:    struct event_desc ev;
                    118:    int i;
                    119:  
                    120: -  if (read_write(pipe, (unsigned char *)&ev, sizeof(ev), 1))
                    121: +  if (read_timeout(pipe, (unsigned char *)&ev, sizeof(ev), now, secs) > 0) 
                    122: +    {
                    123:      switch (ev.event)
                    124:        {
                    125:        case EVENT_RELOAD:
                    126: @@ -872,6 +875,14 @@
                    127:        flush_log();
                    128:        exit(EC_GOOD);
                    129:        }
                    130: +    }
                    131: +  else
                    132: +    return -1; /* timeout */
                    133: +
                    134: +  if (event)
                    135: +    memcpy( event, &ev, sizeof(ev));
                    136: +    
                    137: +  return 0;
                    138:  }
                    139:  
                    140:  static void poll_resolv()
                    141: Index: src/config.h
                    142: ===================================================================
                    143: --- src/config.h       (revision 696)
                    144: +++ src/config.h       (revision 821)
                    145: @@ -51,6 +51,8 @@
                    146:  #define TFTP_MAX_CONNECTIONS 50 /* max simultaneous connections */
                    147:  #define LOG_MAX 5 /* log-queue length */
                    148:  #define RANDFILE "/dev/urandom"
                    149: +#define SCRIPT_TIMEOUT 6
                    150: +#define LEASE_CHECK_TIMEOUT 10
                    151:  
                    152:  /* DBUS interface specifics */
                    153:  #define DNSMASQ_SERVICE "uk.org.thekelleys.dnsmasq"
                    154: Index: src/dnsmasq.h
                    155: ===================================================================
                    156: --- src/dnsmasq.h      (revision 696)
                    157: +++ src/dnsmasq.h      (revision 821)
                    158: @@ -116,6 +116,7 @@
                    159:  /* Async event queue */
                    160:  struct event_desc {
                    161:    int event, data;
                    162: +  unsigned int priv;
                    163:  };
                    164:  
                    165:  #define EVENT_RELOAD    1
                    166: @@ -390,6 +391,7 @@
                    167:  #define ACTION_OLD_HOSTNAME  2
                    168:  #define ACTION_OLD           3
                    169:  #define ACTION_ADD           4
                    170: +#define ACTION_ACCESS        5
                    171:  
                    172:  #define DHCP_CHADDR_MAX 16
                    173:  
                    174: @@ -709,6 +711,7 @@
                    175:  char *print_mac(char *buff, unsigned char *mac, int len);
                    176:  void bump_maxfd(int fd, int *max);
                    177:  int read_write(int fd, unsigned char *packet, int size, int rw);
                    178: +int read_timeout(int fd, unsigned char *packet, int size, time_t now, int secs);
                    179:  
                    180:  /* log.c */
                    181:  void die(char *message, char *arg1, int exit_code);
                    182: @@ -748,7 +751,7 @@
                    183:  
                    184:  /* dhcp.c */
                    185:  void dhcp_init(void);
                    186: -void dhcp_packet(time_t now);
                    187: +void dhcp_packet(int piperead, time_t now);
                    188:  
                    189:  struct dhcp_context *address_available(struct dhcp_context *context, 
                    190:                                       struct in_addr addr,
                    191: @@ -792,14 +795,16 @@
                    192:  void rerun_scripts(void);
                    193:  
                    194:  /* rfc2131.c */
                    195: -size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
                    196: +size_t dhcp_reply(int pipefd, struct dhcp_context *context, char *iface_name, int int_index,
                    197:                  size_t sz, time_t now, int unicast_dest, int *is_inform);
                    198:  
                    199:  /* dnsmasq.c */
                    200:  int make_icmp_sock(void);
                    201:  int icmp_ping(struct in_addr addr);
                    202: -void send_event(int fd, int event, int data);
                    203: +void send_event(int fd, int event, int data, int priv);
                    204:  void clear_cache_and_reload(time_t now);
                    205: +int wait_for_child(int pipe);
                    206: +int async_event(int pipe, time_t now, struct event_desc*, unsigned int timeout);
                    207:  
                    208:  /* isc.c */
                    209:  #ifdef HAVE_ISC_READER
                    210: @@ -832,9 +837,9 @@
                    211:  /* helper.c */
                    212:  #ifndef NO_FORK
                    213:  int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd);
                    214: -void helper_write(void);
                    215: +int helper_write(void);
                    216:  void queue_script(int action, struct dhcp_lease *lease, 
                    217: -                char *hostname, time_t now);
                    218: +                char *hostname, time_t now, unsigned int uid);
                    219:  int helper_buf_empty(void);
                    220:  #endif
                    221:  
                    222: Index: src/util.c
                    223: ===================================================================
                    224: --- src/util.c (revision 696)
                    225: +++ src/util.c (revision 821)
                    226: @@ -444,3 +444,38 @@
                    227:    return 1;
                    228:  }
                    229:  
                    230: +int read_timeout(int fd, unsigned char *packet, int size, time_t now, int secs)
                    231: +{
                    232: +  ssize_t n, done;
                    233: +  time_t expire;
                    234: +  
                    235: +  expire = now + secs;
                    236: +  
                    237: +  for (done = 0; done < size; done += n)
                    238: +    {
                    239: +    retry:
                    240: +      if (secs > 0) alarm(secs);
                    241: +      n = read(fd, &packet[done], (size_t)(size - done));
                    242: +
                    243: +      if (n == 0)
                    244: +        return 0;
                    245: +      else if (n == -1)
                    246: +        {
                    247: +          if (errno == EINTR) {
                    248: +            my_syslog(LOG_INFO, _("read timed out (errno %d)"), errno);
                    249: +            return 0;
                    250: +          }
                    251: +
                    252: +          if (retry_send() || errno == ENOMEM || errno == ENOBUFS || errno == EAGAIN)
                    253: +            {
                    254: +              if (secs == 0 || (secs > 0 && dnsmasq_time() < expire))
                    255: +                goto retry;
                    256: +            }
                    257: +
                    258: +          my_syslog(LOG_INFO, _("error in read (timeout %d, errno %d)"), secs, errno);
                    259: +          return 0;
                    260: +        }
                    261: +    }
                    262: +  return 1;
                    263: +}
                    264: +
                    265: Index: src/dhcp.c
                    266: ===================================================================
                    267: --- src/dhcp.c (revision 696)
                    268: +++ src/dhcp.c (revision 821)
                    269: @@ -103,7 +103,7 @@
                    270:    daemon->dhcp_packet.iov_base = safe_malloc(daemon->dhcp_packet.iov_len);
                    271:  }
                    272:    
                    273: -void dhcp_packet(time_t now)
                    274: +void dhcp_packet(int piperead, time_t now)
                    275:  {
                    276:    struct dhcp_packet *mess;
                    277:    struct dhcp_context *context;
                    278: @@ -239,7 +239,8 @@
                    279:    if (!iface_enumerate(&parm, complete_context, NULL))
                    280:      return;
                    281:    lease_prune(NULL, now); /* lose any expired leases */
                    282: -  iov.iov_len = dhcp_reply(parm.current, ifr.ifr_name, iface_index, (size_t)sz, 
                    283: +
                    284: +  iov.iov_len = dhcp_reply(piperead, parm.current, ifr.ifr_name, iface_index, (size_t)sz, 
                    285:                           now, unicast_dest, &is_inform);
                    286:    lease_update_file(now);
                    287:    lease_update_dns();
                    288: Index: src/helper.c
                    289: ===================================================================
                    290: --- src/helper.c       (revision 696)
                    291: +++ src/helper.c       (revision 821)
                    292: @@ -45,6 +45,7 @@
                    293:  #endif
                    294:    unsigned char hwaddr[DHCP_CHADDR_MAX];
                    295:    char interface[IF_NAMESIZE];
                    296: +  unsigned int uid;
                    297:  };
                    298:  
                    299:  static struct script_data *buf = NULL;
                    300: @@ -60,7 +61,7 @@
                    301:       then fork our process. */
                    302:    if (pipe(pipefd) == -1 || !fix_fd(pipefd[1]) || (pid = fork()) == -1)
                    303:      {
                    304: -      send_event(err_fd, EVENT_PIPE_ERR, errno);
                    305: +      send_event(err_fd, EVENT_PIPE_ERR, errno, 0);
                    306:        _exit(0);
                    307:      }
                    308:  
                    309: @@ -87,13 +88,13 @@
                    310:        {
                    311:          if (daemon->options & OPT_NO_FORK)
                    312:            /* send error to daemon process if no-fork */
                    313: -          send_event(event_fd, EVENT_HUSER_ERR, errno);
                    314: +          send_event(event_fd, EVENT_HUSER_ERR, errno, 0);
                    315:          else
                    316:            {
                    317:              /* kill daemon */
                    318: -            send_event(event_fd, EVENT_DIE, 0);
                    319: +            send_event(event_fd, EVENT_DIE, 0, 0);
                    320:              /* return error */
                    321: -            send_event(err_fd, EVENT_HUSER_ERR, errno);;
                    322: +            send_event(err_fd, EVENT_HUSER_ERR, errno, 0);
                    323:            }
                    324:          _exit(0);
                    325:        }
                    326: @@ -122,6 +123,8 @@
                    327:        action_str = "del";
                    328:        else if (data.action == ACTION_ADD)
                    329:        action_str = "add";
                    330: +      else if (data.action == ACTION_ACCESS)
                    331: +      action_str = "access";
                    332:        else if (data.action == ACTION_OLD || data.action == ACTION_OLD_HOSTNAME)
                    333:        action_str = "old";
                    334:        else
                    335: @@ -178,9 +181,11 @@
                    336:                {
                    337:                  /* On error send event back to main process for logging */
                    338:                  if (WIFSIGNALED(status))
                    339: -                  send_event(event_fd, EVENT_KILLED, WTERMSIG(status));
                    340: -                else if (WIFEXITED(status) && WEXITSTATUS(status) != 0)
                    341: -                  send_event(event_fd, EVENT_EXITED, WEXITSTATUS(status));
                    342: +                  send_event(event_fd, EVENT_KILLED, WTERMSIG(status), data.uid);
                    343: +                else if (WIFEXITED(status))
                    344: +                  send_event(event_fd, EVENT_EXITED, WEXITSTATUS(status), data.uid);
                    345: +                  else
                    346: +                  send_event(event_fd, EVENT_EXITED, -1, data.uid);
                    347:                  break;
                    348:                }
                    349:              
                    350: @@ -263,7 +268,7 @@
                    351:          err = errno;
                    352:        }
                    353:        /* failed, send event so the main process logs the problem */
                    354: -      send_event(event_fd, EVENT_EXEC_ERR, err);
                    355: +      send_event(event_fd, EVENT_EXEC_ERR, err, data.uid);
                    356:        _exit(0); 
                    357:      }
                    358:  }
                    359: @@ -295,7 +300,7 @@
                    360:  }
                    361:   
                    362:  /* pack up lease data into a buffer */    
                    363: -void queue_script(int action, struct dhcp_lease *lease, char *hostname, time_t now)
                    364: +void queue_script(int action, struct dhcp_lease *lease, char *hostname, time_t now, unsigned int uid)
                    365:  {
                    366:    unsigned char *p;
                    367:    size_t size;
                    368: @@ -332,6 +337,7 @@
                    369:        buf_size = size;
                    370:      }
                    371:  
                    372: +  buf->uid = uid;
                    373:    buf->action = action;
                    374:    buf->hwaddr_len = lease->hwaddr_len;
                    375:    buf->hwaddr_type = lease->hwaddr_type;
                    376: @@ -393,12 +399,15 @@
                    377:    return bytes_in_buf == 0;
                    378:  }
                    379:  
                    380: -void helper_write(void)
                    381: +/* returns -1 if write failed for a reason, 1 if no data exist
                    382: + * and 0 if everything was ok.
                    383: + */
                    384: +int helper_write(void)
                    385:  {
                    386:    ssize_t rc;
                    387:  
                    388:    if (bytes_in_buf == 0)
                    389: -    return;
                    390: +    return 1;
                    391:    
                    392:    if ((rc = write(daemon->helperfd, buf, bytes_in_buf)) != -1)
                    393:      {
                    394: @@ -409,9 +418,11 @@
                    395:    else
                    396:      {
                    397:        if (errno == EAGAIN || errno == EINTR)
                    398: -      return;
                    399: +      return -1;
                    400:        bytes_in_buf = 0;
                    401:      }
                    402: +    
                    403: +  return 0;
                    404:  }
                    405:  
                    406:  #endif
                    407: Index: src/rfc2131.c
                    408: ===================================================================
                    409: --- src/rfc2131.c      (revision 696)
                    410: +++ src/rfc2131.c      (revision 821)
                    411: @@ -100,8 +100,49 @@
                    412:                                      int clid_len, unsigned char *clid, int *len_out);
                    413:  static void match_vendor_opts(unsigned char *opt, struct dhcp_opt *dopt); 
                    414:  
                    415: +static int check_access_script( int piperead, struct dhcp_lease *lease, struct dhcp_packet *mess, time_t now)
                    416: +{
                    417: +#ifndef NO_FORK
                    418: +unsigned int uid;
                    419: +struct event_desc ev;
                    420: +int ret;
                    421: +struct dhcp_lease _lease;
                    422: +
                    423: +  if (daemon->lease_change_command == NULL) return 0; /* ok */
                    424: +
                    425: +  if (!lease) { /* if host has not been seen before lease is NULL */
                    426: +      memset(&_lease, 0, sizeof(_lease));
                    427: +      lease = &_lease;
                    428: +      lease_set_hwaddr(lease, mess->chaddr, NULL, mess->hlen, mess->htype, 0);
                    429: +  }
                    430: +
                    431: +  uid = rand16();
                    432: +  queue_script(ACTION_ACCESS, lease, NULL, now, uid);
                    433: +
                    434: +  /* send all data to helper process */
                    435: +  do 
                    436: +    {
                    437: +      helper_write();
                    438: +    } while (helper_buf_empty() == 0);
                    439: +
                    440: +  /* wait for our event */
                    441: +  ret = 0;
                    442: +  do 
                    443: +    {
                    444: +      ret = async_event( piperead, now, &ev, SCRIPT_TIMEOUT);
                    445: +    }
                    446: +  while(ev.priv != uid && ret >= 0);
                    447: +
                    448: +  if (ret < 0 || ev.data != 0) /* timeout or error */
                    449: +    {
                    450: +      return -1;
                    451: +    }
                    452: +
                    453: +#endif
                    454: +  return 0; /* ok */
                    455: +}
                    456:          
                    457: -size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
                    458: +size_t dhcp_reply(int piperead, struct dhcp_context *context, char *iface_name, int int_index,
                    459:                  size_t sz, time_t now, int unicast_dest, int *is_inform)
                    460:  {
                    461:    unsigned char *opt, *clid = NULL;
                    462: @@ -252,7 +293,7 @@
                    463:        mac->netid.next = netid;
                    464:        netid = &mac->netid;
                    465:        }
                    466: -  
                    467: +
                    468:    /* Determine network for this packet. Our caller will have already linked all the 
                    469:       contexts which match the addresses of the receiving interface but if the 
                    470:       machine has an address already, or came via a relay, or we have a subnet selector, 
                    471: @@ -329,7 +370,7 @@
                    472:            my_syslog(LOG_INFO, _("Available DHCP range: %s -- %s"), daemon->namebuff, inet_ntoa(context_tmp->end));
                    473:        }
                    474:      }
                    475: -
                    476: +    
                    477:    mess->op = BOOTREPLY;
                    478:    
                    479:    config = find_config(daemon->dhcp_conf, context, clid, clid_len, 
                    480: @@ -418,7 +459,7 @@
                    481:              else
                    482:                mess->yiaddr = lease->addr;
                    483:            }
                    484: -        
                    485: +
                    486:          if (!message && 
                    487:              !lease && 
                    488:              (!(lease = lease_allocate(mess->yiaddr))))
                    489: @@ -641,7 +682,14 @@
                    490:        memcpy(req_options, option_ptr(opt, 0), option_len(opt));
                    491:        req_options[option_len(opt)] = OPTION_END;
                    492:      }
                    493: -  
                    494: +
                    495: +  if (mess_type == DHCPREQUEST || mess_type == DHCPDISCOVER)
                    496: +    if (check_access_script(piperead, lease, mess, now) < 0)
                    497: +      {
                    498: +        my_syslog(LOG_INFO, _("Ignoring client due to access script"));
                    499: +        return 0;
                    500: +      }
                    501: +
                    502:    switch (mess_type)
                    503:      {
                    504:      case DHCPDECLINE:
                    505: Index: src/log.c
                    506: ===================================================================
                    507: --- src/log.c  (revision 696)
                    508: +++ src/log.c  (revision 821)
                    509: @@ -73,7 +73,7 @@
                    510:  
                    511:    if (!log_reopen(daemon->log_file))
                    512:      {
                    513: -      send_event(errfd, EVENT_LOG_ERR, errno);
                    514: +      send_event(errfd, EVENT_LOG_ERR, errno, 0);
                    515:        _exit(0);
                    516:      }
                    517:  
                    518: Index: src/lease.c
                    519: ===================================================================
                    520: --- src/lease.c        (revision 696)
                    521: +++ src/lease.c        (revision 821)
                    522: @@ -511,7 +511,7 @@
                    523:        if (lease->old_hostname)
                    524:        {
                    525:  #ifndef NO_FORK
                    526: -        queue_script(ACTION_OLD_HOSTNAME, lease, lease->old_hostname, now);
                    527: +        queue_script(ACTION_OLD_HOSTNAME, lease, lease->old_hostname, now, 0);
                    528:  #endif
                    529:          free(lease->old_hostname);
                    530:          lease->old_hostname = NULL;
                    531: @@ -520,7 +520,7 @@
                    532:        else 
                    533:        {
                    534:  #ifndef NO_FORK
                    535: -        queue_script(ACTION_DEL, lease, lease->hostname, now);
                    536: +        queue_script(ACTION_DEL, lease, lease->hostname, now, 0);
                    537:  #endif
                    538:          old_leases = lease->next;
                    539:          
                    540: @@ -540,7 +540,7 @@
                    541:      if (lease->old_hostname)
                    542:        {       
                    543:  #ifndef NO_FORK
                    544: -      queue_script(ACTION_OLD_HOSTNAME, lease, lease->old_hostname, now);
                    545: +      queue_script(ACTION_OLD_HOSTNAME, lease, lease->old_hostname, now, 0);
                    546:  #endif
                    547:        free(lease->old_hostname);
                    548:        lease->old_hostname = NULL;
                    549: @@ -552,7 +552,7 @@
                    550:        (lease->aux_changed && (daemon->options & OPT_LEASE_RO)))
                    551:        {
                    552:  #ifndef NO_FORK
                    553: -      queue_script(lease->new ? ACTION_ADD : ACTION_OLD, lease, lease->hostname, now);
                    554: +      queue_script(lease->new ? ACTION_ADD : ACTION_OLD, lease, lease->hostname, now, 0);
                    555:  #endif
                    556:        lease->new = lease->changed = lease->aux_changed = 0;
                    557:        
                    558: Index: man/dnsmasq.8
                    559: ===================================================================
                    560: --- man/dnsmasq.8      (revision 696)
                    561: +++ man/dnsmasq.8      (revision 821)
                    562: @@ -724,12 +724,15 @@
                    563:  .B \-6 --dhcp-script=<path>
                    564:  Whenever a new DHCP lease is created, or an old one destroyed, the
                    565:  binary specified by this option is run. The arguments to the process
                    566: -are "add", "old" or "del", the MAC
                    567: +are "add", "old", "access" or "del", the MAC
                    568:  address of the host (or "<null>"), the IP address, and the hostname,
                    569:  if known. "add" means a lease has been created, "del" means it has
                    570:  been destroyed, "old" is a notification of an existing lease when
                    571:  dnsmasq starts or a change to MAC address or hostname of an existing
                    572:  lease (also, lease length or expiry and client-id, if leasefile-ro is set).
                    573: +The "access" keyword means that a request was just received and depending
                    574: +on the script exit status request for address will be granted, if exit status
                    575: +is zero or not if it is non-zero.
                    576:  The process is run as root (assuming that dnsmasq was originally run as
                    577:  root) even if dnsmasq is configured to change UID to an unprivileged user.
                    578:  The environment is inherited from the invoker of dnsmasq, and if the

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