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 | }