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