home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 35 Internet / 35-Internet.zip / rsync221.zip / access.c next >
C/C++ Source or Header  |  1999-03-04  |  3KB  |  131 lines

  1. /* 
  2.    Copyright (C) Andrew Tridgell 1998
  3.    
  4.    This program is free software; you can redistribute it and/or modify
  5.    it under the terms of the GNU General Public License as published by
  6.    the Free Software Foundation; either version 2 of the License, or
  7.    (at your option) any later version.
  8.    
  9.    This program is distributed in the hope that it will be useful,
  10.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.    GNU General Public License for more details.
  13.    
  14.    You should have received a copy of the GNU General Public License
  15.    along with this program; if not, write to the Free Software
  16.    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17. */
  18.  
  19. /*
  20.   hosts allow/deny code for rsync
  21.  
  22.   */
  23.  
  24. #include "rsync.h"
  25.  
  26.  
  27. static int match_hostname(char *host, char *tok)
  28. {
  29.     if (!host || !*host) return 0;
  30.     return (fnmatch(tok, host, 0) == 0);
  31. }
  32.  
  33.  
  34. static int match_address(char *addr, char *tok)
  35. {
  36.     char *p;
  37.     unsigned long a, t, mask = (unsigned long)~0;
  38.  
  39.     if (!addr || !*addr) return 0;
  40.  
  41.     if (!isdigit(tok[0])) return 0;
  42.  
  43.     p = strchr(tok,'/');
  44.     if (p) *p = 0;
  45.  
  46.     a = inet_addr(addr);
  47.     t = inet_addr(tok);
  48.  
  49.     if (p) {
  50.         *p = '/';
  51.     }
  52.  
  53.     if (t == INADDR_NONE) {
  54.         rprintf(FERROR,"malformed address %s\n", tok);
  55.         return 0;
  56.     }
  57.  
  58.     a = ntohl(a);
  59.     t = ntohl(t);
  60.  
  61.     if (p) {
  62.         if (strchr(p+1,'.')) {
  63.             mask = inet_addr(p+1);
  64.             if (mask == INADDR_NONE) {
  65.                 rprintf(FERROR,"malformed mask in %s\n", tok);
  66.                 return 0;
  67.             }
  68.             mask = ntohl(mask);
  69.         } else {
  70.             int bits = atoi(p+1);
  71.             if (bits <= 0 || bits > 32) {
  72.                 rprintf(FERROR,"malformed mask in %s\n", tok);
  73.                 return 0;
  74.             }
  75.             mask &= (mask << (32-bits));
  76.         }
  77.     }
  78.  
  79.     return ((a&mask) == (t&mask));
  80. }
  81.  
  82. static int access_match(char *list, char *addr, char *host)
  83. {
  84.     char *tok;
  85.     char *list2 = strdup(list);
  86.  
  87.     if (!list2) out_of_memory("access_match");
  88.  
  89.     strlower(list2);
  90.     if (host) strlower(host);
  91.  
  92.     for (tok=strtok(list2," ,\t"); tok; tok=strtok(NULL," ,\t")) {
  93.         if (match_hostname(host, tok) || match_address(addr, tok)) {
  94.             free(list2);
  95.             return 1;
  96.         }
  97.     }
  98.  
  99.     free(list2);
  100.     return 0;
  101. }
  102.  
  103. int allow_access(char *addr, char *host, char *allow_list, char *deny_list)
  104. {
  105.     /* if theres no deny list and no allow list then allow access */
  106.     if ((!deny_list || !*deny_list) && (!allow_list || !*allow_list))
  107.         return 1;
  108.  
  109.     /* if there is an allow list but no deny list then allow only hosts
  110.        on the allow list */
  111.     if (!deny_list || !*deny_list)
  112.         return(access_match(allow_list, addr, host));
  113.  
  114.     /* if theres a deny list but no allow list then allow
  115.        all hosts not on the deny list */
  116.     if (!allow_list || !*allow_list)
  117.         return(!access_match(deny_list,addr,host));
  118.  
  119.     /* if there are both type of list then allow all hosts on the
  120.            allow list */
  121.     if (access_match(allow_list,addr,host))
  122.         return 1;
  123.  
  124.     /* if there are both type of list and it's not on the allow then
  125.        allow it if its not on the deny */
  126.     if (access_match(deny_list,addr,host))
  127.         return 0;
  128.  
  129.     return 1;
  130. }
  131.