1    | /***************************************
2    |   $Revision: 1.1 $
3    | 
4    |   access authorisation (aa). aa.c - functions to check access rights
5    |   for less frequent clients (ripupdate, networkupdate, mirror).
6    | 
7    |   Status: NOT REVUED, NOT TESTED, 
8    | 
9    |   Design and implementation by: Marek Bukowy
10   | 
11   |   ******************/ /******************
12   |   Copyright (c) 1999                              RIPE NCC
13   |  
14   |   All Rights Reserved
15   |   
16   |   Permission to use, copy, modify, and distribute this software and its
17   |   documentation for any purpose and without fee is hereby granted,
18   |   provided that the above copyright notice appear in all copies and that
19   |   both that copyright notice and this permission notice appear in
20   |   supporting documentation, and that the name of the author not be
21   |   used in advertising or publicity pertaining to distribution of the
22   |   software without specific, written prior permission.
23   |   
24   |   THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
25   |   ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS; IN NO EVENT SHALL
26   |   AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
27   |   DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
28   |   AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
29   |   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
30   |   ***************************************/
31   | 
32   | #include "iproutines.h"
33   | #include "mysql_driver.h"
34   | #include "constants.h"
35   | 
36   | /* 
37   | > +---------------+---------------------+------+-----+---------+-------+
38   | > | Field         | Type                | Null | Key | Default | Extra |
39   | > +---------------+---------------------+------+-----+---------+-------+
40   | > | prefix        | int(10) unsigned    |      | PRI | 0       |       |
41   | > | prefix_length | tinyint(3) unsigned |      | PRI | 0       |       |
42   | > | source        | varchar(32)         |      | PRI |         |       |
43   | > | ripupdate     | tinyint(3)          |      |     | 0       |       |
44   | > | netupdate     | tinyint(3)          |      |     | 0       |       |
45   | > | mirror        | tinyint(3)          |      |     | 0       |       |
46   | > | comment       | longblob            | YES  |     | NULL    |       |
47   | > +---------------+---------------------+------+-----+---------+-------+
48   | */
49   | 
50   | typedef struct {
51   |   int ripupdate;
52   |   int netupdate;
53   |   int mirror;
54   | } aa_rights;
55   | 
56   | void aa_parserow(SQ_result_set_t *result, aa_rights *rights)
57   | {
58   |   SQ_row_t *row;
59   |   
60   |   /* zero the rights - so if we don't get any results, we have a valid
61   |    answer "no rights" */
62   | 
63   |   rights->ripupdate = 0;
64   |   rights->netupdate = 0;
65   |   rights->mirror    = 0;
66   | 
67   |   if ( (row = SQ_row_next(result)) != NULL ) {    
68   |     /* read in the order of query */
69   |     if( sscanf(SQ_get_column_string_nocopy(result, row, 0),
70   | 	       "%u", &rights->ripupdate ) < 1 ) { die; }
71   |     if( sscanf(SQ_get_column_string_nocopy(result, row, 1),
72   | 	       "%u", &rights->netupdate ) < 1 ) { die; }
73   |     if( sscanf(SQ_get_column_string_nocopy(result, row, 2),
74   | 	       "%u", &rights->mirror )    < 1 ) { die; }
75   |   }
76   | }
77   | 
78   | 
79   | 
80   | void aa_compose_query(ip_addr_t *address, char *source, char *buf, int len)
81   | {
82   | snprintf(buf,len, "SELECT ripupdate, netupdate, mirror FROM aaa WHERE %lu "  
83   | " BETWEEN prefix AND (prefix+(1<<(32-prefix_length)))"
84   | " AND source = '%s' "
85   | " ORDER BY prefix_length DESC LIMIT 1" /* take the most specific entry */,
86   |   IP_addr_b2v4_addr(address), source );
87   | }
88   | 
89   | 
90   | 
91   | /* finds and fills in the struct */
92   | void
93   | aa_find(ip_addr_t *address, char *source, aa_rights *rights)
94   | {
95   |  SQ_result_set_t *result;
96   |  SQ_connection_t *con=NULL;
97   |  char buf[1024];
98   | 
99   |  /* get the query */
100  |  aa_compose_query(address,source, buf, 1024);
101  |  
102  |  /* open the database */
103  | 
104  |  if( (con = SQ_get_connection(CO_get_host(), CO_get_database_port(), 
105  | 			      "RIPADMIN", CO_get_user(), CO_get_password() )
106  |       ) == NULL ) 
107  |    {
108  |      fprintf(stderr, "ERROR %d: %s\n", SQ_errno(con), SQ_error(con));
109  |      die;
110  |    }
111  | 
112  |  /* select the most specific entry */
113  |  if( SQ_execute_query(con, buf, &result) == -1 ) {
114  |    fprintf(stderr, "ERROR %d: %s\n", SQ_errno(con), SQ_error(con));
115  |    die;
116  |  }
117  |  
118  |  /* read in the rights from the resulting row */
119  |  aa_parserow(result, rights);
120  |  
121  |  /* release everything */
122  |  SQ_free_result(result);
123  |  
124  |  /* Close connection */
125  |  SQ_close_connection(con);
126  | }
127  | 
128  | 
129  | int AA_can_networkupdate( ip_addr_t *address, char *source )
130  | { 
131  |   aa_rights myrights;
132  |   aa_find(address, source, &myrights);
133  |   return (myrights.netupdate != 0);
134  | }
135  | 
136  | int AA_can_ripupdate( ip_addr_t *address, char *source )
137  | { 
138  |   aa_rights myrights;
139  |   aa_find(address, source, &myrights);
140  |   return (myrights.ripupdate != 0);
141  | }
142  | 
143  | int AA_can_mirror( ip_addr_t *address, char *source )
144  | { 
145  |   aa_rights myrights;
146  |   aa_find(address, source, &myrights);
147  |   return (myrights.mirror != 0);
148  | }