modules/up/UP_util.cc
/* [<][>][^][v][top][bottom][index][help] */
FUNCTIONS
This source file includes following functions.
- authorise
- error_msg_cat
- interpret_ripdb_result
- get_assigned_nic
- send_object_db
- get_type
- get_search_key
- send_and_get
- count_objects
- strip_lines
- take_objects
- take_object
- get_as_block
- get_aut_num_object
- get_less_specific_domain
- get_less_specific_set
- get_less_specific
- get_less_spec_inetnum
- get_exact_match_inetnum
- get_exact_match_routes
- get_less_spec_routes
- get_mntners
- get_attributes
- get_attribute
- strstr_in_list
- get_auths
- get_mnt_lowers
- get_mnt_routes
- get_mnt_routes_from_list
- get_mnt_lowers_from_list
- get_override
- check_override
- add_to_auth_vector
- get_auth_vector
- filter_out_diff_origins
- check_auth
- get_old_version
- process_mail_header
- stringPack
- delete_delete_attrib
- identical
- find_initials
- replace_AUTO_NIC_hdl
- replace_refs_to_AUTO_NIC_hdl
- has_AUTO_NIC_hdl
- has_ref_to_AUTO_nic_hdl
- add_to_ack
- add_to_ack_string
- process_object
- find_to_address
1 /***************************************
2 $Revision: 1.18 $
3
4 UP module utilities
5
6 Status: NOT REVIEWED, NOT TESTED
7
8 Author(s): Engin Gunduz
9
10 ******************/ /******************
11 Modification History:
12 engin (17/01/2000) Created.
13 ******************/ /******************
14 Copyright (c) 2000 RIPE NCC
15
16 All Rights Reserved
17
18 Permission to use, copy, modify, and distribute this software and its
19 documentation for any purpose and without fee is hereby granted,
20 provided that the above copyright notice appear in all copies and that
21 both that copyright notice and this permission notice appear in
22 supporting documentation, and that the name of the author not be
23 used in advertising or publicity pertaining to distribution of the
24 software without specific, written prior permission.
25
26 THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
27 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS; IN NO EVENT SHALL
28 AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
29 DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
30 AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
31 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
32 ***************************************/
33
34 #include "dbupdate.h"
35
36 int error = 0; // a global variable to store the errors
37 char * error_msg = NULL; // a global variable to store the error messages
38 extern int tracing;
39
40 /* authorise function takes the auth_vector, credentials struct, and 'overriden'
41 variable. If overriden == 1, then it immediately returns UP_AUTH_OK
42 (because this means that the update contained a valid override attribute).
43 Else, it goes through the auth_vector and when it finds a an "auth:"
44 attribute which passes, then it returns UP_AUTH_OK. Otherwise, it returns
45 UP_AUF (authorisation failed) */
46
47 int authorise(GSList * auth_vector, credentials_struct credentials, int overriden){
/* [<][>][^][v][top][bottom][index][help] */
48
49 int result = 0;
50
51 if(tracing){
52 printf("TRACING: authorise started with override: %i\n", overriden);
53 }
54
55 /* If 'overriden' variable is 1, then return UP_AUTH_OK immediately */
56 if(overriden == 1){
57 return UP_AUTH_OK;
58 }
59 else{
60 result = AU_authorise(auth_vector, credentials);
61 if(tracing){
62 printf("TRACING: authorise: AU_authorise returned %i\n", result);
63 }
64 if(result > 0){
65 return UP_AUTH_OK;
66 }
67 else{
68 return UP_AUF; /* authorisation failed */
69 }
70 }
71 }
72
73 /* concatanates the string at the end of error_msg */
74 void error_msg_cat(const char * string){
/* [<][>][^][v][top][bottom][index][help] */
75
76 if(string == NULL){
77 return;
78 }
79 if(error_msg == NULL){
80 error_msg = strdup(string);
81 }else{
82 error_msg = (char *)realloc(error_msg, strlen(error_msg) + strlen(string) + 2);
83 error_msg = strcat(error_msg, "\n");
84 error_msg = strcat(error_msg, string);
85 }
86 }
87
88
89 /* interprets the result string coming from RIPupd
90 It is called by send_object_db.
91 It returns the error no returned from RIPupd. */
92
93 int interpret_ripdb_result(const char * string){
/* [<][>][^][v][top][bottom][index][help] */
94 char * error_no = NULL;
95 char ** temp = NULL, ** temp2 = NULL;
96 int i;
97 int err = 0;
98
99 /* if the string is NULL or empty, then return error */
100 if(string == NULL || strlen(string) == 0){
101 error = UP_INT; /* internal error, RIPupd should return something */
102 error_msg_cat("Internal error. RIPupd didn't return anything.");
103 return 0;
104 }
105
106 /* split the string into lines */
107 temp = g_strsplit(string , "\n", 0);
108 for(i = 0; temp[i] != NULL; i++){
109 if(i == 0){/* this line must contain "%ERROR " string in the beginning */
110 temp2 = g_strsplit(temp[0], " ", 0);
111 error_no = strdup(temp2[1]);
112 g_strfreev(temp2);
113 err = atoi(error_no);
114 printf("TRACING: interpret_ripdb_result: error_no is [%s]\n", error_no);
115 }else if(error_no != NULL && strcmp(error_no, "0") != 0){
116 error_msg_cat(temp[i]);
117 }
118 }
119 g_strfreev(temp);
120 //if(error_no != NULL && error_msg != NULL){
121 // printf("TRACING: interpret_ripdb_result: Error: [%s][%s]\n", error_no, error_msg);
122 //}
123 if(error_no != NULL){
124 free(error_no);
125 }
126 return err; /* 0 means no error in this context */
127 }
128
129
130
131 /* Gets assigned NIC hdl from the string that is returned from
132 RIPupdate */
133 void get_assigned_nic(char * nic_hdl, const char * string){
/* [<][>][^][v][top][bottom][index][help] */
134 char * error_no = NULL;
135 char ** temp = NULL, ** temp2 = NULL;
136 int i;
137 //char * to_be_returned = NULL;
138
139 /* if the string is NULL or empty, then return error */
140 if(string == NULL || strlen(string) == 0){
141 error = UP_INT; /* internal error, RIPupd should return something */
142 error_msg_cat("Internal error. RIPupd didn't return anything.");
143 return;
144 }
145
146 /* split the string into lines */
147 temp = g_strsplit(string , "\n", 0);
148 for(i = 0; temp[i] != NULL; i++){
149 if(i == 0){/* this line must contain "%ERROR " string in the beginning */
150 temp2 = g_strsplit(temp[0], " ", 0);
151 error_no = strdup(temp2[1]);
152 g_strfreev(temp2);
153 printf("TRACING: get_assigned_nic: error_no is [%s]\n", error_no);
154 }else if(error_no != NULL && strcmp(error_no, "0") != 0){
155 error_msg_cat(temp[i]);
156 }else if(error_no != NULL && strcmp(error_no, "0") == 0 && i == 1){/* look for assigned NIC hdl */
157 printf("error_no != NULL && strcmp(error_no, \"0\") == 0 && i == 1\n");
158 /* in the second line RIPupdate returns for example "I[65][EK3-RIPE]" We
159 need to extract EK3-RIPE part */
160 //to_be_returned = (char *)malloc(128); /* 128 should be enough for a NIC hdl */
161 nic_hdl = strncpy(nic_hdl, rindex(temp[i],'[') + 1 ,
162 rindex(temp[i],']') - rindex(temp[i],'[') - 1);
163 nic_hdl[rindex(temp[i],']') - rindex(temp[i],'[') - 1] = '\0';
164 if(nic_hdl != NULL){
165 printf("DEBUG: get_assigned_nic will return [%s]\n", nic_hdl);
166 }
167 g_strfreev(temp);
168 //return to_be_returned;
169 return;
170 }
171 }
172 g_strfreev(temp);
173 if(error_no != NULL && error_msg != NULL){
174 printf("TRACING: interpret_ripdb_result: Error: [%s][%s]\n", error_no, error_msg);
175 }
176 return;
177 }
178
179
180
181 /* sends the object to the database. char * operation is either 'ADD' ,'DEL' or 'UPD'
182 assigned_NIC is filled in if this is a person/role creation with AUTO nic hdl
183 assigned_NIC must be allocated enough memory before send_object_db is called
184
185 If the called do not expect a NIC hdl back, then assigned_NIC can be given NULL
186 */
187 int send_object_db(char * arg, char * assigned_NIC, char * operation){
/* [<][>][^][v][top][bottom][index][help] */
188
189 int sockfd, numbytes;
190 char buf[MAXDATASIZE];
191 struct hostent *he;
192 struct sockaddr_in their_addr; /* connector's address information */
193 char *result_string = NULL;
194 char *to_be_returned = NULL;
195 int err = 0;
196
197
198 if ((he=gethostbyname(UPDATE_HOST)) == NULL) { /* get the host info */
199 perror("gethostbyname");
200 exit(1);
201 }
202
203 if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
204 perror("socket");
205 exit(1);
206 }
207
208 their_addr.sin_family = AF_INET; /* host byte order */
209 their_addr.sin_port = htons(UPDATE_PORT); /* short, network byte order */
210 their_addr.sin_addr = *((struct in_addr *)he->h_addr);
211 bzero(&(their_addr.sin_zero), 8); /* zero the rest of the struct */
212
213
214 if (connect(sockfd, (struct sockaddr *)&their_addr,
215 sizeof(struct sockaddr)) == -1) {
216 perror("connect");
217 exit(1);
218 }
219
220 if (send(sockfd, operation , strlen(operation), 0) == -1)
221 perror("send");
222 if (send(sockfd, "\n\n" , strlen("\n\n"), 0) == -1)
223 perror("send");
224 if (send(sockfd, arg , strlen(arg), 0) == -1)
225 perror("send");
226 if (send(sockfd, "\n\n",2,0) == -1)
227 perror("send");
228
229
230 while ((numbytes=recv(sockfd, buf, MAXDATASIZE, 0)) != 0) {
231 buf[numbytes] = '\0';
232 printf("%s",buf);
233 if(result_string == NULL){
234 result_string = strdup(buf);
235 }else{
236 result_string = (char *)realloc(result_string,
237 strlen(result_string) + strlen(buf) + 1);
238 result_string = strcat(result_string, buf);
239 }
240 }
241
242 err = interpret_ripdb_result(result_string);
243 if(assigned_NIC != NULL){ /* if the caller of the function expected to get a NIC handle */
244 get_assigned_nic(assigned_NIC, result_string);
245 }
246 close(sockfd);
247 return err; /* 0 means no error in this context */
248 }
249
250
251
252
253
254
255 /* takes a pre-parsed object, and returns its type */
256 char * get_type(Object *arg){
/* [<][>][^][v][top][bottom][index][help] */
257
258 char * be_returned = NULL;
259 if(arg == NULL) return NULL;
260 be_returned = strdup(arg->type->getName());
261 return g_strstrip(be_returned);
262 }
263
264
265
266
267
268
269 /* takes an object (pre-parsed) and returns its first attrib if it is not
270 a person, and returns the nic-hdl if it is a person object */
271 char * get_search_key(Object *arg, char * type, const char * text){
/* [<][>][^][v][top][bottom][index][help] */
272
273
274 Attr *attr;
275 char *primary_key = NULL, *value = NULL;
276
277 if(arg == NULL) return NULL;
278
279 for(attr = arg->attrs.head(); attr; attr = arg->attrs.next(attr)){
280 value = (char*)malloc((*attr).len - strlen(attr->type->name()) - 1);
281 strncpy(value, (char *)(text+attr->offset) + strlen(attr->type->name())+1,
282 attr->len - strlen(attr->type->name()) -2 );
283 value[attr->len - strlen(attr->type->name()) - 2 ] = '\0';
284 //cout << "value: #" << value << "#" << endl;
285 if(strcmp(attr->type->name(),type) == 0 &&
286 strcmp(type,"person") != 0){
287 primary_key = strdup(value);
288 }
289 if(strcmp(attr->type->name(),"nic-hdl") == 0 &&
290 strcmp(type,"person") == 0){
291 primary_key = strdup(value);
292 }
293 }
294 if(primary_key != NULL){
295 return g_strstrip(primary_key);
296 }else{
297 return NULL;
298 }
299 }
300
301
302
303
304 /* sends char * arg to the specified host's specified port, and
305 returns the reply as a string. This is used to query the
306 whois host. Probably we must use WC (whois client) module here,
307 but it must be extented */
308 char * send_and_get(char * host, int port, char * arg){
/* [<][>][^][v][top][bottom][index][help] */
309
310 int sockfd, numbytes;
311 char * result = NULL;
312 char buf[MAXDATASIZE];
313 struct hostent *he;
314 struct sockaddr_in their_addr; /* connector's address information */
315
316 if(tracing) {
317 printf("TRACING: send_and_get: arg : [%s]; port: [%i]; host: [%s]\n", arg, port, host);
318 }
319
320 if ((he=gethostbyname(host)) == NULL) { /* get the host info */
321 perror("gethostbyname");
322 exit(1);
323 }
324
325 if(tracing) {
326 printf("TRACING: send_and_get: called gethostbyname\n");
327 }
328
329 if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
330 perror("socket");
331 exit(1);
332 }
333
334 if(tracing) {
335 printf("TRACING: send_and_get: called socket\n");
336 }
337
338
339 their_addr.sin_family = AF_INET; /* host byte order */
340 their_addr.sin_port = htons(port); /* short, network byte order */
341 their_addr.sin_addr = *((struct in_addr *)he->h_addr);
342 bzero(&(their_addr.sin_zero), 8); /* zero the rest of the struct */
343
344 if (connect(sockfd, (struct sockaddr *)&their_addr,
345 sizeof(struct sockaddr)) == -1) {
346 perror("connect");
347 exit(1);
348 }
349 if (send(sockfd, arg , strlen(arg), 0) == -1)
350 perror("send");
351 if (send(sockfd, "\n",1,0) == -1)
352 perror("send");
353
354
355 while ((numbytes=recv(sockfd, buf, MAXDATASIZE, 0)) != 0) {
356 buf[numbytes] = '\0';
357 if(result == NULL){
358 result = strdup(buf);
359 }else{
360 result = (char *)realloc(result, strlen(result) + strlen(buf));
361 result = strcat(result, buf);
362 }
363 }
364
365 close(sockfd);
366 return result;
367
368
369 }
370
371 /* counts the number of objects in a string */
372 int count_objects(char * arg){
/* [<][>][^][v][top][bottom][index][help] */
373 int count = 0;
374 char *pos = NULL;
375 char *temp = NULL;
376
377 if(tracing) {
378 printf("TRACING: count_objects running\n");
379 }
380
381 if(arg != NULL){
382 temp = strdup(arg);
383 }else{
384 return 0;
385 }
386
387 if(isalpha(arg[0])){
388 count++;
389 }else if(arg[0] == '\n' && isalpha(arg[1])){
390 count++;
391 }
392 while(pos = strstr(temp,"\n\n")){
393 pos[0] = 'a'; /* something non-EOL so that it won't be caught in the next loop */
394 if(isalpha(pos[2])){
395 count++;
396 }
397 }
398 if(tracing) {
399 cout << "TRACING: count_objects returning " << count << endl;
400 }
401 return count;
402 }
403
404
405 /* strips lines beginning with '%' off */
406 char * strip_lines(char * arg){
/* [<][>][^][v][top][bottom][index][help] */
407
408 char ** temp = NULL;
409 char * string = NULL;
410 int i;
411
412 if(arg == NULL){
413 return NULL;
414 }
415
416 /* split the string into lines */
417 temp = g_strsplit (arg, "\n", 0);
418
419 for(i=0; temp[i] != NULL; i++){
420 if(temp[i][0] != '%'){
421 if(string == NULL){
422 string = strdup(temp[i]);
423 }else{
424 string = (char *)realloc(string, strlen(string) + strlen(temp[i]) + 1);
425 string = strcat(string, "\n");
426 string = strcat(string, temp[i]);
427 }
428 }
429 }
430 return string;
431 }
432
433 /* Separates the objects in the given char * arg using "\n\n" as
434 separator. Returns a linked list whose data consist of separated
435 objects as char * */
436
437 GSList * take_objects(char * arg){
/* [<][>][^][v][top][bottom][index][help] */
438 char ** objects=NULL;
439 char ** temp = NULL;
440 GSList * tobereturned = NULL;
441 int i;
442
443 arg = strip_lines(arg);
444
445 objects = g_strsplit(arg, "\n\n", 1000);
446 temp = objects;
447 for(i=0; temp[i] != NULL; i++){
448 /* stripe off the trailing and leading white spaces-eols*/
449 g_strstrip(temp[i]);
450 if(strlen(temp[i]) > 0){/* if not an empty string */
451 tobereturned = g_slist_append(tobereturned, temp[i]);
452 }
453 }
454 return tobereturned;
455 }
456
457
458
459
460
461 /* takes the first object in the given char *, using empty lines as
462 separator */
463 char * take_object(char * arg){
/* [<][>][^][v][top][bottom][index][help] */
464 char * object = NULL, * pos = NULL;
465 char * temp = strdup(arg);
466
467 if(isalpha(temp[0])){
468 if(strstr(temp,"\n\n") == NULL){
469 return temp;
470 }else{
471 pos = strstr(temp,"\n\n");
472 pos[0] = '\0';
473 return temp;
474 }
475 }else if(temp[0] == '\n' && isalpha(temp[1])){
476 if(strstr(temp,"\n\n") == NULL){
477 return (char *)temp[1];
478 }else{
479 pos = strstr(temp,"\n\n");
480 pos[0] = '\0';
481 return (char *)temp[1];
482 }
483 }else{
484 temp = strstr(temp,"\n\n");
485 temp = temp + 2;
486 if(strstr(temp,"\n\n") == NULL){
487 return temp;
488 }else{
489 pos = strstr(temp,"\n\n");
490 pos[0] = '\0';
491 return temp;
492 }
493 }
494 }
495
496
497
498
499
500 /* Takes an autnum_object, and returns the as-block containing this aut-num */
501 char * get_as_block(char *autnum_object){
/* [<][>][^][v][top][bottom][index][help] */
502 bool code;
503 char * search_key = NULL, * query_string = NULL;
504 char * result = NULL;
505 Object * o = new Object();
506
507 code = o->scan(autnum_object, strlen(autnum_object));
508 search_key = get_search_key(o,"aut-num",autnum_object);
509
510 query_string = (char *)malloc(strlen("-Tas-block -r ")+strlen(search_key)+1);
511 sprintf(query_string, "-Tas-block -r %s",search_key);
512 result = send_and_get(QUERY_HOST, QUERY_PORT, query_string);
513 if(count_objects(result) == 0){
514 cout << "No such as-block" << endl;
515 return NULL;
516 }else if(count_objects(result) > 1){
517 cout << "More than one as-block returned" << endl;
518 return NULL;
519 }else{ /* count_objects(result) == 1 */
520 return take_object(result);
521 }
522
523 }
524
525
526 /* Takes a route_object, and returns the aut-num mentioned in origin
527 attribute of this route */
528 char * get_aut_num_object(char *route_object){
/* [<][>][^][v][top][bottom][index][help] */
529 bool code;
530 char * search_key = NULL, * query_string = NULL;
531 char * result = NULL;
532 Object * o = new Object();
533
534 code = o->scan(route_object, strlen(route_object));
535 search_key = get_search_key(o,"origin",route_object);
536
537 query_string = (char *)malloc(strlen("-Tas-block -r ")+strlen(search_key)+1);
538 sprintf(query_string, "-Taut-num -r %s",search_key);
539 result = send_and_get(QUERY_HOST, QUERY_PORT, query_string);
540 if(count_objects(result) == 0){
541 cout << "No such aut-num" << endl;
542 return NULL;
543 }else if(count_objects(result) > 1){
544 cout << "More than one aut-num returned" << endl;
545 return NULL;
546 }else{ /* count_objects(result) == 1 */
547 return take_object(result);
548 }
549
550 }
551
552
553
554
555 /* Takes a domain_object, and returns the less specific domain of it */
556 char * get_less_specific_domain(char *domain_object){
/* [<][>][^][v][top][bottom][index][help] */
557 bool code;
558 char * search_key = NULL, * query_string = NULL;
559 char * result = NULL, * domain = NULL;
560 Object * o = new Object();
561 int i,j, length;
562 char * temp = NULL;
563 char ** splitted;
564
565 code = o->scan(domain_object, strlen(domain_object));
566 domain = get_search_key(o,"domain",domain_object);
567
568 /* split the domain from its dots ('50' is the max # of pieces, this number is just arbitrary) */
569 splitted = g_strsplit((char *)strdup(domain), ".", 50);
570
571 for(i=1; splitted[i] != NULL; i++){
572 /* in the following for loop, we will construct the 'less spec' domains
573 to be looked up in the DB */
574 for(j=i; splitted[j] !=NULL; j++){
575 length = 0;
576 if(temp!=NULL){
577 length = strlen(temp);
578 }
579 temp = (char *)realloc(temp, length + strlen(splitted[j]) + 2);
580 if(j==i){
581 temp = (char *)strdup(splitted[j]);
582 }else{
583 sprintf(temp, "%s.%s", temp, splitted[j]);
584 }
585 }
586 query_string = (char *)malloc(strlen("-Tdomain -r -R ")+strlen(temp)+1);
587 sprintf(query_string, "-Tdomain -r -R %s", temp);
588 result = send_and_get(QUERY_HOST, QUERY_PORT, query_string);
589 if(count_objects(result) == 0){
590 }else if(count_objects(result) > 1){
591 if(tracing){
592 cout << "TRACING: get_less_specific_domain: More than one domains returned" << endl;
593 }
594 return NULL; /* error condition */
595 }else{ /* count_objects(result) == 1 */
596 return take_object(result);
597 }
598
599 }
600 /* release the memory allocated to **splitted */
601 for(i=0; splitted[i] != NULL; i++){
602 free(splitted[i]);
603 }
604 /* so, we couldn't find any 'less specific' domain */
605 return NULL;
606 }
607
608
609
610
611
612 /* Takes a hierarchical set_object, and returns the less specific set or auth-num of it
613 by striping down the object's name ( eg, for as35:rs-trial:rs-myset,
614 as35:rs-trial is tried ) */
615 char * get_less_specific_set(char *set_object, char *type){
/* [<][>][^][v][top][bottom][index][help] */
616 bool code;
617 char * search_key = NULL, * query_string = NULL;
618 char * result = NULL;
619 Object * o = new Object();
620 int i;
621
622 code = o->scan(set_object, strlen(set_object));
623 search_key = get_search_key(o, type, set_object);
624 delete(o);
625
626 for(i = strlen(search_key) -1; i > -1; i--){
627 if(search_key[i] == ':'){
628 search_key[i] = '\0'; /* truncate the string */
629 break;
630 }
631 if(i == 0){/* if we've reached the beginning of the string
632 (this means there wasn't any ';' in the string) */
633 free(search_key);
634 search_key = NULL;
635 }
636 }
637 if( search_key == NULL || strlen(search_key) == 0){/* this mustn't happen in fact, since
638 we make sure that the name of the
639 set_object contains a ':' in a proper place */
640 return NULL;
641 }
642
643
644 query_string = (char *)malloc(strlen("-Taut-num,as-set,rtr-set,peering-set,filter-set -r ")+strlen(search_key)+1);
645 sprintf(query_string, "-Taut-num,as-set,rtr-set,peering-set,filter-set -r %s", search_key);
646 result = send_and_get(QUERY_HOST, QUERY_PORT, query_string);
647 if(count_objects(result) == 0){
648 cout << "No such object" << endl;
649 return NULL;
650 }else if(count_objects(result) > 1){
651 cout << "More than one objects returned" << endl;
652 return NULL;
653 }else{ // count_objects(result) == 1
654 return take_object(result);
655 }
656
657 }
658
659
660
661
662
663
664
665 /* Takes an inetnum or inet6num object and returnes one less specific of it */
666 char * get_less_specific(char *inetnum_object, char *type){
/* [<][>][^][v][top][bottom][index][help] */
667 bool code;
668 char * search_key = NULL, * query_string = NULL;
669 char * result = NULL;
670 Object * o = new Object();
671
672 code = o->scan(inetnum_object, strlen(inetnum_object));
673 search_key = get_search_key(o, type, inetnum_object);
674
675 query_string = (char *)malloc(strlen("-Tinet6num -r -l ") + strlen(search_key) + 1);
676 sprintf(query_string, "-T%s -r -l %s",type, search_key);
677 result = send_and_get(QUERY_HOST, QUERY_PORT, query_string);
678 if(count_objects(result) == 0){
679 cout << "No such " << type << endl;
680 return NULL;
681 }else if(count_objects(result) > 1){
682 cout << "More than one " << type << " returned" << endl;
683 return NULL;
684 }else{ /* count_objects(result) == 1 */
685 return take_object(result);
686 }
687
688 }
689
690
691
692 /* Takes a route object and returnes one less specific inetnum */
693 char * get_less_spec_inetnum(char *route_object){
/* [<][>][^][v][top][bottom][index][help] */
694 bool code;
695 char * search_key = NULL, * query_string = NULL;
696 char * result = NULL;
697 Object * o = new Object();
698
699 code = o->scan(route_object, strlen(route_object));
700 search_key = get_search_key(o, "route", route_object);
701
702 query_string = (char *)malloc(strlen("-Tinetnum -r -l ") + strlen(search_key) + 1);
703 sprintf(query_string, "-Tinetnum -r -l %s", search_key);
704 result = send_and_get(QUERY_HOST, QUERY_PORT, query_string);
705 if(count_objects(result) == 0){
706 cout << "No such inetnum" << endl;
707 return NULL;
708 }else if(count_objects(result) > 1){
709 cout << "More than one inetnums returned" << endl;
710 return NULL;
711 }else{ /* count_objects(result) == 1 */
712 return take_object(result);
713 }
714
715 }
716
717
718 /* Takes a route object and returnes exact match inetnum */
719 char * get_exact_match_inetnum(char *route_object){
/* [<][>][^][v][top][bottom][index][help] */
720 bool code;
721 char * search_key = NULL, * query_string = NULL;
722 char * result = NULL;
723 Object * o = new Object();
724
725 code = o->scan(route_object, strlen(route_object));
726 search_key = get_search_key(o, "route", route_object);
727
728 query_string = (char *)malloc(strlen("-Tinetnum -r -x ") + strlen(search_key) + 1);
729 sprintf(query_string, "-Tinetnum -r -x %s", search_key);
730 result = send_and_get(QUERY_HOST, QUERY_PORT, query_string);
731 if(count_objects(result) == 0){
732 cout << "No such inetnum" << endl;
733 return NULL;
734 }else if(count_objects(result) > 1){
735 cout << "More than one inetnums returned" << endl;
736 return NULL;
737 }else{ /* count_objects(result) == 1 */
738 return take_object(result);
739 }
740
741 }
742
743
744
745 /* Takes a route object and returnes exact matches of this route */
746 GSList * get_exact_match_routes(char *route_object){
/* [<][>][^][v][top][bottom][index][help] */
747 bool code;
748 char * search_key = NULL, * query_string = NULL;
749 char * result = NULL;
750 Object * o = new Object();
751
752 code = o->scan(route_object, strlen(route_object));
753 search_key = get_search_key(o, "route", route_object);
754
755 query_string = (char *)malloc(strlen("-Troute -r -x ") + strlen(search_key) + 1);
756 sprintf(query_string, "-Troute -r -x %s", search_key);
757 result = send_and_get(QUERY_HOST, QUERY_PORT, query_string);
758 if(count_objects(result) == 0){
759 cout << "get_exact_match_routes: No such route" << endl;
760 return NULL;
761 }else{ /* count_objects(result) == 1 */
762 return take_objects(result);
763 }
764
765 }
766
767
768
769 /* Takes a route object and returns (immediate) less specifics of this route */
770 GSList * get_less_spec_routes(char *route_object){
/* [<][>][^][v][top][bottom][index][help] */
771 bool code;
772 char * search_key = NULL, * query_string = NULL;
773 char * result = NULL;
774 Object * o = new Object();
775
776 code = o->scan(route_object, strlen(route_object));
777 search_key = get_search_key(o, "route", route_object);
778
779 query_string = (char *)malloc(strlen("-Troute -r -l ") + strlen(search_key) + 1);
780 sprintf(query_string, "-Troute -r -l %s", search_key);
781 result = send_and_get(QUERY_HOST, QUERY_PORT, query_string);
782 if(count_objects(result) == 0){
783 cout << "get_less_spec_routes: No such route" << endl;
784 return NULL;
785 }else{ /* count_objects(result) == 1 */
786 return take_objects(result);
787 }
788
789 }
790
791
792
793 /* Gets an object as a string and returns its 'mnt-by' attributes as a
794 GSList (linked list) */
795
796 GSList *get_mntners(char * object){
/* [<][>][^][v][top][bottom][index][help] */
797 bool code;
798 Object * o;
799 Attr *attr;
800 char *value = NULL;
801 GSList *list_of_mntners = NULL;
802
803 if(tracing) {
804 printf("TRACING: get_mntners is running\n");
805 }
806 o = new Object;
807 code = o->scan(object,strlen(object));
808
809 for(attr = o->attrs.head(); attr; attr = o->attrs.next(attr)){
810 value = (char*)malloc((*attr).len - strlen(attr->type->name()) - 1);
811 strncpy(value, (char *)(object+attr->offset) + strlen(attr->type->name())+1,
812 attr->len - strlen(attr->type->name()) -2 );
813 value[attr->len - strlen(attr->type->name()) - 2 ] = '\0';
814 //cout << "value: #" << value << "#" << endl;
815 if(strcmp(attr->type->name(),"mnt-by") == 0){
816 if(tracing) {
817 cout << "TRACING: get_mntners: adding " << g_strstrip(value) << endl;
818 }
819 list_of_mntners = g_slist_append(list_of_mntners, strdup(g_strstrip(value)));
820 }
821 free(value);
822 }
823
824
825 return list_of_mntners;
826 }
827
828
829 /* Gets a preparsed object, its text and an attribute name. Returns a list of
830 attribute values */
831 GSList *get_attributes(Object * o, const char * attrib, const char * text){
/* [<][>][^][v][top][bottom][index][help] */
832
833 char * value = NULL;
834 Attr *attr;
835 GSList *list_of_attributes = NULL;
836
837 //if(tracing) {
838 // printf("TRACING: get_attributes is running\n");
839 //}
840
841 for(attr = o->attrs.head(); attr; attr = o->attrs.next(attr)){
842 value = (char*)malloc((*attr).len - strlen(attr->type->name()) - 1);
843 strncpy(value, (char *)(text+attr->offset) + strlen(attr->type->name())+1,
844 attr->len - strlen(attr->type->name()) -2 );
845 value[attr->len - strlen(attr->type->name()) - 2 ] = '\0';
846 if(strcmp(attr->type->name(), attrib) == 0){
847 if(tracing) {
848 cout << "TRACING: get_attributes: adding " << g_strstrip(value) << endl;
849 }
850 list_of_attributes = g_slist_append(list_of_attributes, strdup(g_strstrip(value)));
851 }
852 //free(value);
853 }
854
855 //if(tracing) {
856 // printf("TRACING: get_attributes is returning\n");
857 //}
858
859 return list_of_attributes;
860 }
861
862
863 /* Gets a preparsed object, an attribute name. Returns the value of first occurence
864 of this attribute */
865 char *get_attribute(Object * o, const char * attrib, char * text){
/* [<][>][^][v][top][bottom][index][help] */
866
867 char * value = NULL;
868 Attr *attr;
869
870 if(tracing) {
871 printf("TRACING: get_attributes is running\n");
872 }
873
874 for(attr = o->attrs.head(); attr; attr = o->attrs.next(attr)){
875 value = (char*)malloc((*attr).len - strlen(attr->type->name()) - 1);
876 strncpy(value, (char *)(text+attr->offset) + strlen(attr->type->name())+1,
877 attr->len - strlen(attr->type->name()) -2 );
878 value[attr->len - strlen(attr->type->name()) - 2 ] = '\0';
879 if(strcmp(attr->type->name(), attrib) == 0){
880 if(tracing) {
881 cout << "TRACING: get_attribute: will return " << value << endl;
882 }
883 return value;
884 }else{
885 free(value);
886 }
887 }
888
889 if(tracing) {
890 printf("TRACING: get_attribute is returning\n");
891 }
892
893 return NULL;
894 }
895
896
897
898 /* Gets a GSList of strings and returns 1 if one of them starts with substr, 0 otherwise */
899 int strstr_in_list(GSList * list, const char * substr){
/* [<][>][^][v][top][bottom][index][help] */
900
901 GSList * next = NULL;
902 char * word;
903
904 if(tracing) {
905 printf("TRACING: strstr_in_list is running\n");
906 }
907
908 for( next = list; next != NULL ; next = g_slist_next(next) ){
909 word = strdup((char *)next->data);
910 g_strup(word);
911 if(strstr(word, substr) == word){
912 free(word);
913 return 1;
914 }
915 free(word);
916 }
917 /* none of them matched, so return 0 */
918 return 0;
919 }
920
921
922
923
924
925 /* Gets a (maintainer) object as a string and returns its 'auth' attributes
926 as a GSList (linked list) */
927
928 GSList *get_auths(char * object){
/* [<][>][^][v][top][bottom][index][help] */
929 bool code;
930 Object * o;
931 Attr *attr;
932 char *value = NULL;
933 GSList *list_of_auths = NULL;
934
935 if(tracing){
936 printf("TRACING: get_auths is running\n");
937 }
938 o = new Object;
939 code = o->scan(object,strlen(object));
940
941 for(attr = o->attrs.head(); attr; attr = o->attrs.next(attr)){
942 value = (char*)malloc((*attr).len - strlen(attr->type->name()) - 1);
943 strncpy(value, (char *)(object+attr->offset) + strlen(attr->type->name())+1,
944 attr->len - strlen(attr->type->name()) -2 );
945 value[attr->len - strlen(attr->type->name()) - 2 ] = '\0';
946 //cout << "value: #" << value << "#" << endl;
947 if(strcmp(attr->type->name(),"auth") == 0){
948 if(tracing) {
949 cout << "TRACING: get_auths: adding " << g_strstrip(value) << endl;
950 }
951 list_of_auths = g_slist_append(list_of_auths, strdup(g_strstrip(value)));
952 if(tracing) {
953 cout << "TRACING: get_auths: # of nodes in list_of_auths is now " << g_slist_length(list_of_auths) << endl;
954 }
955 }
956 }
957
958 if(tracing) {
959 cout << "TRACING: get_auths: returning (with " << g_slist_length(list_of_auths) << " nodes)" << endl;
960 }
961 return list_of_auths;
962 }
963
964
965
966
967
968 /* Gets an object as a string an returns its mnt_lower attributes as a
969 GSList (linked list) */
970
971 GSList *get_mnt_lowers(char * object){
/* [<][>][^][v][top][bottom][index][help] */
972 bool code;
973 Object * o;
974 Attr *attr;
975 char *value = NULL;
976 GSList *list_of_mnt_lowers = NULL;
977
978
979 if(tracing) {
980 printf("TRACING: get_mnt_lowers is running\n");
981 }
982 o = new Object;
983 code = o->scan(object,strlen(object));
984
985 for(attr = o->attrs.head(); attr; attr = o->attrs.next(attr)){
986 value = (char*)malloc((*attr).len - strlen(attr->type->name()) - 1);
987 strncpy(value, (char *)(object+attr->offset) + strlen(attr->type->name())+1,
988 attr->len - strlen(attr->type->name()) -2 );
989 value[attr->len - strlen(attr->type->name()) - 2 ] = '\0';
990 //cout << "value: #" << value << "#" << endl;
991 if(strcmp(attr->type->name(),"mnt-lower") == 0){
992 if(tracing) {
993 cout << "TRACING: get_mnt_lowers: adding " << g_strstrip(value) << endl;
994 }
995 list_of_mnt_lowers = g_slist_append(list_of_mnt_lowers, strdup(g_strstrip(value)));
996 }
997 }
998
999
1000 return list_of_mnt_lowers;
1001 }
1002
1003
1004 /* Gets an object as a string an returns its mnt_routes attributes as a
1005 GSList (linked list) */
1006
1007 GSList *get_mnt_routes(char * object){
/* [<][>][^][v][top][bottom][index][help] */
1008 bool code;
1009 Object * o;
1010 Attr *attr;
1011 char *value = NULL;
1012 GSList *list_of_mnt_routes = NULL;
1013
1014 if(tracing) {
1015 cout << "TRACING: get_mnt_routes is running" << endl;
1016 }
1017 o = new Object;
1018 code = o->scan(object,strlen(object));
1019
1020 for(attr = o->attrs.head(); attr; attr = o->attrs.next(attr)){
1021 value = (char*)malloc((*attr).len - strlen(attr->type->name()) - 1);
1022 strncpy(value, (char *)(object+attr->offset) + strlen(attr->type->name())+1,
1023 attr->len - strlen(attr->type->name()) -2 );
1024 value[attr->len - strlen(attr->type->name()) - 2 ] = '\0';
1025 //cout << "value: #" << value << "#" << endl;
1026 if(strcmp(attr->type->name(),"mnt-routes") == 0){
1027 if(tracing) {
1028 cout << "TRACING: get_mnt_routes: adding " << g_strstrip(value) << endl;
1029 }
1030 list_of_mnt_routes = g_slist_append(list_of_mnt_routes, strdup(g_strstrip(value)));
1031 }
1032 }
1033
1034 return list_of_mnt_routes;
1035 }
1036
1037
1038 /* Gets a linked list of objects and returns the mnt_routes attribs of
1039 them in a linked list */
1040 GSList *get_mnt_routes_from_list(GSList * objects){
/* [<][>][^][v][top][bottom][index][help] */
1041 GSList *next = NULL;
1042 GSList *list_of_mnt_routes = NULL;
1043
1044 for( next = objects; next != NULL ; next = g_slist_next(next) ){
1045 list_of_mnt_routes = g_slist_concat(list_of_mnt_routes, get_mnt_routes((char *)next->data));
1046 }
1047
1048 return list_of_mnt_routes;
1049 }
1050
1051
1052
1053 /* Gets a linked list of objects and returns the mnt_routes attribs of
1054 them in a linked list */
1055 GSList *get_mnt_lowers_from_list(GSList * objects){
/* [<][>][^][v][top][bottom][index][help] */
1056 GSList *next = NULL;
1057 GSList *list_of_mnt_lowers = NULL;
1058
1059 for( next = objects; next != NULL ; next = g_slist_next(next) ){
1060 list_of_mnt_lowers = g_slist_concat(list_of_mnt_lowers, get_mnt_lowers((char *)next->data));
1061 }
1062
1063 return list_of_mnt_lowers;
1064 }
1065
1066
1067
1068 /* retrieves the override password from the 'override' attribute
1069 of the object. If none, it returns NULL */
1070 char *get_override(char * object){
/* [<][>][^][v][top][bottom][index][help] */
1071 bool code;
1072 Object * o;
1073 Attr *attr;
1074 char *value = NULL;
1075
1076 if(tracing){
1077 printf("TRACING: get_override is running\n");
1078 }
1079 o = new Object;
1080 code = o->scan(object,strlen(object));
1081
1082 for(attr = o->attrs.head(); attr; attr = o->attrs.next(attr)){
1083 value = (char*)malloc((*attr).len - strlen(attr->type->name()) - 1);
1084 strncpy(value, (char *)(object+attr->offset) + strlen(attr->type->name())+1,
1085 attr->len - strlen(attr->type->name()) -2 );
1086 value[attr->len - strlen(attr->type->name()) - 2 ] = '\0';
1087 //cout << "value: #" << value << "#" << endl;
1088 if(strcmp(attr->type->name(),"override") == 0){
1089 if(tracing) {
1090 cout << "TRACING: get_override: returning " << g_strstrip(value) << endl;
1091 }
1092 return strdup(g_strstrip(value));
1093 }
1094 }
1095 /* there was no 'override' attrib, so return NULL */
1096 return NULL;
1097 }
1098
1099
1100
1101
1102
1103
1104 /* checks override string (password)
1105 returns OVR_OK if it is correct password */
1106 int check_override(char * string){
/* [<][>][^][v][top][bottom][index][help] */
1107 char ** temp;
1108 int i;
1109 char * crypted_password = strdup(CRYPTEDPASSWD);
1110 if(string == NULL) {
1111 if(tracing) {
1112 printf("TRACING: check_override is returning FAILED\n");
1113 }
1114 return UP_OVF; /* override attempt failed */
1115 }else{
1116 /* split the string */
1117 temp = g_strsplit (string, " ", 0);
1118
1119 for(i=0; temp[i] != NULL; i++){
1120 if(strlen(temp[i]) != 0){
1121 printf("%s\n", temp[i]);
1122 if(strcmp(AU_crypt(temp[i], crypted_password), crypted_password) == 0){
1123 g_strfreev(temp);
1124 if(tracing) {
1125 printf("TRACING: check_override is returning OK\n", string);
1126 }
1127 return OVR_OK;
1128 }
1129 }
1130 }
1131
1132 g_strfreev(temp);
1133 /* we couldn't find a word matching the override password */
1134 return UP_OVF; /* override attempt failed */
1135 }
1136 }
1137
1138
1139
1140
1141
1142
1143
1144 /* takes a GSList of struct auth_struct and a GSList of auths, and a mntner name,
1145 add new elements to GSList of struct auth_struct and returns the new
1146 GSList of struct auth_struct */
1147
1148 GSList * add_to_auth_vector(GSList * list_of_auth_struct, GSList * auths, char * mntner_name){
/* [<][>][^][v][top][bottom][index][help] */
1149 //GSList * to_be_returned = NULL;
1150 GSList * next;
1151 char * auth_attrib = NULL;
1152 char * auth_attrib_uppercase = NULL, * argument = NULL;
1153 //struct auth_struct * temp = NULL;
1154 auth_struct * temp = NULL;
1155 int index = 1;
1156
1157 for(next = auths; next != NULL; next = g_slist_next(next)){
1158 auth_attrib = strdup((char *)next->data);
1159 auth_attrib = g_strstrip(auth_attrib);
1160 if(tracing) {
1161 cout << "TRACING: add_to_auth_vector: " << auth_attrib << endl;
1162 }
1163 /* Take the auth attribute and convert it into uppercase for comparisons */
1164 auth_attrib_uppercase = strdup(auth_attrib);
1165 g_strup(auth_attrib_uppercase);
1166
1167 if(strstr(auth_attrib_uppercase,"CRYPT-PW") == auth_attrib_uppercase){
1168 /* take the argument of the auth attribute */
1169 argument = strdup(auth_attrib + strlen("CRYPT-PW"));
1170 g_strstrip(argument);
1171 if(tracing) {
1172 cout << "TRACING: add_to_auth_vector: adding new argument: " << argument << endl;
1173 }
1174 //temp = (struct auth_struct *)malloc(sizeof(auth_struct));
1175 temp = (auth_struct *)malloc(sizeof(auth_struct));
1176 temp->type = AU_CRYPT_PW;
1177 temp->auth = argument;
1178 temp->mntner_name = mntner_name;
1179 temp->index = index++;
1180 list_of_auth_struct = g_slist_append(list_of_auth_struct, temp);
1181 }else if(strstr(auth_attrib_uppercase,"MAIL-FROM") == auth_attrib_uppercase){
1182 /* take the argument of the auth attribute */
1183 argument = strdup(auth_attrib + strlen("MAIL-FROM"));
1184 g_strstrip(argument);
1185 if(tracing) {
1186 cout << "TRACING: add_to_auth_vector: adding new argument: " << argument << endl;
1187 }
1188 //temp = (struct auth_struct *)malloc(sizeof(auth_struct));
1189 temp = (auth_struct *)malloc(sizeof(auth_struct));
1190 temp->type = AU_MAIL_FROM;
1191 temp->auth = argument;
1192 temp->mntner_name = mntner_name;
1193 temp->index = index++;
1194 list_of_auth_struct = g_slist_append(list_of_auth_struct, temp);
1195 }else if(strstr(auth_attrib_uppercase,"NONE") == auth_attrib_uppercase){
1196 /* take the argument of the auth attribute */
1197 //argument = strdup(auth_attrib + strlen("NONE"));
1198 //g_strstrip(argument);
1199 //cout << "DEBUG: add_to_auth_vector: adding new argument: " << argument << endl;
1200 //temp = (struct auth_struct *)malloc(sizeof(auth_struct));
1201 temp = (auth_struct *)malloc(sizeof(auth_struct));
1202 temp->type = AU_NONE;
1203 temp->auth = NULL;
1204 temp->mntner_name = mntner_name;
1205 temp->index = index++;
1206 list_of_auth_struct = g_slist_append(list_of_auth_struct, temp);
1207 }else if(strstr(auth_attrib_uppercase,"PGP-") == auth_attrib_uppercase){
1208 //temp = (struct auth_struct *)malloc(sizeof(auth_struct));
1209 temp = (auth_struct *)malloc(sizeof(auth_struct));
1210 temp->type = AU_PGP;
1211 temp->mntner_name = mntner_name;
1212 temp->index = index++;
1213 /* temp->pgp_struct must be assigned, not yet implemented */
1214 cout << "Not implemented totally (PGP)" << endl;
1215 }else{
1216 cout << "DEBUG: Error: invalid auth attrib: " << auth_attrib << endl;
1217 return NULL;
1218 }
1219 }
1220 free(auth_attrib_uppercase);
1221 free(auth_attrib);
1222 return list_of_auth_struct;
1223
1224 }
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235 /* constructs the authorisation vector, which is a GSList of
1236 struct auth_struct */
1237
1238 GSList * get_auth_vector(GSList * mntners){
/* [<][>][^][v][top][bottom][index][help] */
1239 GSList * list_of_auths = NULL;
1240 GSList * next = NULL;
1241 GSList * to_be_returned = NULL;
1242 char * query_string = NULL, * result = NULL, * object = NULL;
1243 GSList * temp;
1244
1245 for( next = mntners; next != NULL ; next = g_slist_next(next) ){
1246 if(tracing) {
1247 cout << "=====" << endl << "Got a mntner" << endl;
1248 cout << (char *)next->data << endl;
1249 }
1250 query_string = (char *)malloc(strlen("-Tmntner -r ")+strlen((char *)next->data)+1);
1251 sprintf(query_string, "-Tmntner -r %s",(char *)next->data);
1252 result = send_and_get(QUERY_HOST, QUERY_PORT, query_string);
1253 if(count_objects(result) == 0){
1254 //if(tracing) {
1255 // cout << "No such maintainer, exiting" << endl;
1256 //}
1257 //exit(1);
1258 /* no such maintainer */
1259 return NULL;
1260 }else if(count_objects(result) > 1){
1261 if(tracing) {
1262 cout << "More than one objects returned" << endl;
1263 }
1264 }else{ /* count_objects(result) == 1 */
1265 object = take_object(result);
1266 if(tracing) {
1267 printf("TRACING: get_auth_vector: Calling get_auths(char *)\n");
1268 }
1269 temp = get_auths(object);
1270 if(tracing) {
1271 cout << "TRACING: get_auth_vector: get_auths(char *) returned (with " << g_slist_length(temp) << " nodes)" << endl;
1272 }
1273 list_of_auths = g_slist_concat(list_of_auths, temp);
1274 if(tracing) {
1275 cout << "TRACING: get_auth_vector: list_of_auths has now " << g_slist_length(list_of_auths) << " nodes" << endl;
1276 }
1277 /* add this to the auth_vector. ( next->data is the name of the maintainer ) */
1278 if(tracing) {
1279 cout << "TRACING: get_auth_vector: to_be_returned has now " << g_slist_length(to_be_returned) << " nodes" << endl;
1280 }
1281 to_be_returned = add_to_auth_vector(to_be_returned, list_of_auths, (char *)next->data);
1282 }
1283 }
1284
1285 if(tracing) {
1286 printf("TRACING: get_auth_vector: to_be_returned has %i nodes\n", g_slist_length(to_be_returned));
1287 }
1288 return to_be_returned;
1289 }
1290
1291
1292 /* gets one or more route objects filters out the ones which don't have the same
1293 origin as 'char * origin' argument */
1294 char * filter_out_diff_origins(char * objects, char * origin){
/* [<][>][^][v][top][bottom][index][help] */
1295 GSList * object_list = NULL, * next =NULL;
1296 char * objects_to_be_returned = NULL;
1297 bool code;
1298 char * key = NULL;
1299 Object * o = new Object();
1300
1301
1302 if(tracing) {
1303 printf("TRACING: filter_out_diff_origins\n");
1304 }
1305
1306 /* strip the lines beginning with '%' off */
1307 objects = strip_lines(objects);
1308
1309 /* separate the objects, store them in a linked list */
1310 object_list = take_objects(objects);
1311
1312 for(next = object_list; next != NULL; next = g_slist_next(next)){
1313 code = o->scan((char *)next->data, strlen((char *)next->data));
1314 key = get_search_key(o, "origin", (char *)next->data);
1315 if(key != NULL && strcasecmp(g_strstrip(origin), key) == 0){
1316 if(objects_to_be_returned == NULL){
1317 objects_to_be_returned = strdup((char *)next->data);
1318 }else{
1319 objects_to_be_returned = (char *)realloc(objects_to_be_returned,
1320 strlen(objects_to_be_returned) + strlen((char *)next->data) + 2);
1321 objects_to_be_returned = strcat(objects_to_be_returned, "\n");
1322 objects_to_be_returned = strcat(objects_to_be_returned, (char *)next->data);
1323 }
1324 }
1325 }
1326
1327 delete(o);
1328 if(tracing) {
1329 if(objects_to_be_returned != NULL){
1330 printf("TRACING: filter_out_diff_origins: returning:\n%s\n", objects_to_be_returned? "(NULL)":objects_to_be_returned);
1331 }else {
1332 printf("TRACING: filter_out_diff_origins: returning NULL\n");
1333
1334 }
1335 }
1336 return objects_to_be_returned;
1337
1338 }
1339
1340
1341
1342
1343 /* Check authorisation
1344 Applies authorisation rules according to the object type
1345
1346 Arguments:
1347 char *new_object: the new object,
1348 char *old_object: the old object, as found in the database,
1349 char *type: type of the object
1350 credentials_struct credentials: a struct which
1351 contains credentials of the update, such as 'From:' field of
1352 the e-mail header and passwords in the update */
1353
1354 int check_auth(char *new_object, char *old_object, char *type, credentials_struct credentials){
/* [<][>][^][v][top][bottom][index][help] */
1355
1356 GSList *old_mntners = NULL, *new_mntners = NULL;
1357 GSList *old_auths = NULL, *new_auths = NULL;
1358 GSList *as_block_mnt_lowers = NULL;
1359 GSList *old_auth_vector = NULL, *new_auth_vector = NULL, *as_block_auth_vector = NULL;
1360 GSList *less_specific_auth_vector = NULL, *less_specific_mnt_lowers = NULL;
1361 GSList *less_specific_mntners = NULL;
1362 GSList *aut_num_maintainers = NULL;
1363 GSList *aut_num_auth_vector = NULL;
1364 GSList *exact_match_routes = NULL;
1365 GSList *exact_match_routes_maintainers = NULL;
1366 GSList *exact_match_routes_auth_vector = NULL;
1367 GSList *less_spec_routes = NULL;
1368 GSList *less_spec_routes_mntners = NULL;
1369 GSList *less_spec_routes_auth_vector = NULL;
1370 GSList *exact_match_inetnum_mnt_routes = NULL;
1371 GSList *exact_match_inetnum_auth_vector = NULL;
1372 GSList *less_spec_inetnum_mntners = NULL;
1373 GSList *less_spec_inetnum_auth_vector = NULL;
1374 GSList *exact_match_intenum_auth_vector = NULL;
1375 GSList *exact_match_auth_vector = NULL;
1376
1377 char *as_block_object = NULL, *less_specific_object = NULL;
1378 char *less_specific_domain = NULL;
1379 char *less_spec_inetnum = NULL;
1380 char *exact_match_inetnum = NULL;
1381 char *less_specific_object_type = NULL;
1382 char *override_string = NULL;
1383 char *set_name = NULL;
1384 char * aut_num_object = NULL;
1385 Object *set_object = new Object();
1386 Object *temp_obj;
1387 bool code;
1388 bool aut_num_auth_OK = false;
1389
1390 int overriden = 0;
1391
1392 /* first check if it is overriden or not. if overriden, check the override
1393 password. If it is correct, continue, setting "overriden" to 1. If not,
1394 immediately exit returning ERR_UP_OVF */
1395 override_string = get_override((new_object == NULL) ? old_object : new_object );
1396 if(override_string == NULL){
1397 overriden = 0;
1398 }else if(check_override(override_string) == OVR_OK){
1399 overriden = 1; /* authorisation is overriden */
1400 }else if(check_override(override_string) == UP_OVS){
1401 return UP_OVS; /* override syntax error --it must have at least two words */
1402 }else{
1403 return UP_OVF; /* override failed! */
1404 }
1405
1406
1407 /*
1408 * Handle the "person", "role", "limerick", "inet-rtr" types
1409 */
1410 if(strcmp(type,"person") == 0 || strcmp(type,"role") == 0 ||
1411 strcmp(type,"limerick") == 0 || strcmp(type,"inet-rtr") == 0 ){
1412 if( new_object == NULL && old_object != NULL ){ /* the object is to be deleted */
1413 old_mntners = get_mntners(old_object);
1414 old_auth_vector = get_auth_vector(old_mntners);
1415 return authorise(old_auth_vector, credentials, overriden);
1416 }else if( new_object != NULL && old_object == NULL ){ /* the object is to be created */
1417 new_mntners = get_mntners(new_object);
1418 new_auth_vector = get_auth_vector(new_mntners);
1419 if(new_mntners != NULL && new_auth_vector == NULL){
1420 /* then, the mntners in 'new_mntners' do not exist. Problem. */
1421 return UP_AUF; /* auth failed */
1422 }
1423 /*printf("DEBUG: check_auth: new_auth_vector has %i, new_mntners has %i nodes\n",
1424 g_slist_length(new_auth_vector) ,g_slist_length(new_mntners));*/
1425 return authorise(new_auth_vector, credentials, overriden);
1426 }else if( new_object != NULL && old_object != NULL ){ /* this is an update */
1427 old_mntners = get_mntners(old_object);
1428 old_auth_vector = get_auth_vector(old_mntners);
1429 if(old_mntners != NULL && old_auth_vector == NULL){
1430 /* then, the mntners in 'old_mntners' do not exist. Problem. */
1431 return UP_AUF; /* auth failed */
1432 }
1433 if(old_auth_vector){ /* if we have mntners in the old object, use them */
1434 return authorise(old_auth_vector, credentials, overriden);
1435 }else{
1436 new_mntners = get_mntners(new_object);
1437 new_auth_vector = get_auth_vector(new_mntners);
1438 if(new_mntners != NULL && new_auth_vector == NULL){
1439 /* then, the mntners in 'new_mntners' do not exist. Problem. */
1440 return UP_AUF; /* auth failed */
1441 }
1442 return authorise(new_auth_vector, credentials, overriden);
1443 }
1444 }else{ // both are NULL, mustn't happen
1445 cout << "DEBUG: check_auth: internal error: Both pointers are NULL" << endl;
1446 return UP_INT; /* internal error */
1447 }
1448 }
1449
1450 /*
1451 * Handle the "auth-num" type
1452 */
1453 else if(strcmp(type,"aut-num") == 0 ){
1454 if( new_object == NULL && old_object != NULL ){ /* the object is to be deleted */
1455 old_mntners = get_mntners(old_object);
1456 old_auth_vector = get_auth_vector(old_mntners);
1457 if(old_mntners != NULL && old_auth_vector == NULL){
1458 /* then, the mntners in 'old_mntners' do not exist. Problem. */
1459 return UP_AUF; /* auth failed */
1460 }
1461 return authorise(old_auth_vector, credentials, overriden);
1462 }else if( new_object != NULL && old_object == NULL ){ /* the object is to be created */
1463 as_block_object = get_as_block(new_object);
1464 if(as_block_object == NULL ){
1465 return UP_ABN; /* As-block does not exist */
1466 }else{
1467 as_block_mnt_lowers = get_mnt_lowers(as_block_object);
1468 as_block_auth_vector = get_auth_vector(as_block_mnt_lowers);
1469 if(as_block_mnt_lowers != NULL && as_block_auth_vector == NULL){
1470 /* then, the mntners in 'as_block_mnt_lowers' do not exist. Problem. */
1471 return UP_AUF; /* auth failed */
1472 }
1473 if(authorise(as_block_auth_vector, credentials, overriden) == UP_AUTH_OK ){
1474 new_mntners = get_mntners(new_object);
1475 new_auth_vector = get_auth_vector(new_mntners);
1476 if(new_mntners != NULL && new_auth_vector == NULL){
1477 /* then, the mntners in 'new_auth_vector' do not exist. Problem. */
1478 return UP_AUF; /* auth failed */
1479 }
1480 return authorise(new_auth_vector, credentials, overriden);
1481 }else{
1482 return UP_HOF; /* hierarchical auth failed */
1483 }
1484 }
1485 }else if( new_object != NULL && old_object != NULL ){ /* this is an update */
1486 old_mntners = get_mntners(old_object);
1487 old_auth_vector = get_auth_vector(old_mntners);
1488 if(old_mntners != NULL && old_auth_vector == NULL){
1489 /* then, the mntners in 'old_mntners' do not exist. Problem. */
1490 return UP_AUF; /* auth failed */
1491 }
1492 if(old_auth_vector){ /* if we have mntners in the old object, use them */
1493 return authorise(old_auth_vector, credentials, overriden);
1494 }else{
1495 new_mntners = get_mntners(new_object);
1496 new_auth_vector = get_auth_vector(new_mntners);
1497 if(new_mntners != NULL && new_auth_vector == NULL){
1498 /* then, the mntners in 'new_mntners' do not exist. Problem. */
1499 return UP_AUF; /* auth failed */
1500 }
1501 return authorise(new_auth_vector, credentials, overriden);
1502 }
1503 }else{ /* both are NULL, mustn't happen */
1504 if(tracing) {
1505 cout << "TRACING: check_auth: internal error: Both pointers are NULL" << endl;
1506 }
1507 return UP_INT; /* internal error */
1508 }
1509 }
1510
1511 /*
1512 * Handle the "mntner/as-block" types
1513 */
1514 else if(strcmp(type,"mntner") == 0 || strcmp(type,"as-block") == 0 ){
1515 if( new_object == NULL && old_object != NULL ){ /* the object is to be deleted */
1516 old_mntners = get_mntners(old_object);
1517 old_auth_vector = get_auth_vector(old_mntners);
1518 if(old_mntners != NULL && old_auth_vector == NULL){
1519 /* then, the mntners in 'old_mntners' do not exist. Problem. */
1520 return UP_AUF; /* auth failed */
1521 }
1522 return authorise(old_auth_vector, credentials, overriden);
1523 }else if( new_object != NULL && old_object == NULL ){ /* the object is to be created */
1524 if(overriden){
1525 return UP_AUTH_OK;
1526 }else{/* If not overriden, and if not coming from ripe-dbm, must be forwarded to ripe-dbm */
1527 if(tracing) {
1528 cout << "DEBUG: check_auth: '" << type << "' creation requested" << endl;
1529 }
1530 return UP_AUF; /* authorisation failed */
1531 }
1532 }else if( new_object != NULL && old_object != NULL ){ /* this is an update */
1533 old_mntners = get_mntners(old_object);
1534 old_auth_vector = get_auth_vector(old_mntners);
1535 if(old_mntners != NULL && old_auth_vector == NULL){
1536 /* then, the mntners in 'old_mntners' do not exist. Problem. */
1537 return UP_AUF; /* auth failed */
1538 }
1539 if(old_auth_vector){ /* if we have mntners in the old object, use them */
1540 return authorise(old_auth_vector, credentials, overriden);
1541 }else{
1542 new_mntners = get_mntners(new_object);
1543 new_auth_vector = get_auth_vector(new_mntners);
1544 if(new_mntners != NULL && new_auth_vector == NULL){
1545 /* then, the mntners in 'new_mntners' do not exist. Problem. */
1546 return UP_AUF; /* auth failed */
1547 }
1548 return authorise(new_auth_vector, credentials, overriden);
1549 }
1550 }else{ // both are NULL, mustn't happen
1551 cout << "DEBUG: check_auth: internal error: Both pointers are NULL" << endl;
1552 return UP_INT; /* internal error */
1553 }
1554 }
1555
1556 /*
1557 * Handle the "inetnum/inet6num" types
1558 */
1559 else if(strcmp(type,"inetnum") == 0 || strcmp(type,"inet6num") == 0 ){
1560 if( new_object == NULL && old_object != NULL ){ /* the object is to be deleted */
1561 old_mntners = get_mntners(old_object);
1562 old_auth_vector = get_auth_vector(old_mntners);
1563 if(old_mntners != NULL && old_auth_vector == NULL){
1564 /* then, the mntners in 'old_mntners' do not exist. Problem. */
1565 return UP_AUF; /* auth failed */
1566 }
1567 return authorise(old_auth_vector, credentials, overriden);
1568 }else if( new_object != NULL && old_object == NULL ){ /* the object is to be created */
1569 less_specific_object = get_less_specific(new_object, type);
1570 if(less_specific_object == NULL){
1571 if(overriden){
1572 return UP_AUTH_OK;
1573 }else{
1574 return UP_HOF; /* hierarchical authorisation failed */
1575 }
1576 }else{ /* if we got an inet(6)num object */
1577 less_specific_mnt_lowers = get_mnt_lowers(less_specific_object);
1578 less_specific_auth_vector = get_auth_vector(less_specific_mnt_lowers);
1579 if(less_specific_mnt_lowers != NULL && less_specific_auth_vector == NULL){
1580 /* then, the mntners in 'less_specific_mnt_lowers' do not exist. Problem. */
1581 return UP_AUF; /* auth failed */
1582 }
1583 if(authorise(less_specific_auth_vector, credentials, overriden) == UP_AUTH_OK){
1584 new_mntners = get_mntners(new_object);
1585 new_auth_vector = get_auth_vector(new_mntners);
1586 if(new_mntners != NULL && new_auth_vector == NULL){
1587 /* then, the mntners in 'new_mntners' do not exist. Problem. */
1588 return UP_AUF; /* auth failed */
1589 }
1590 return authorise(new_auth_vector, credentials, overriden);
1591 }else{
1592 return UP_HOF; /* hierarchical authorisation failed */
1593 }
1594 }
1595 }else if( new_object != NULL && old_object != NULL ){ /* this is an update */
1596 old_mntners = get_mntners(old_object);
1597 old_auth_vector = get_auth_vector(old_mntners);
1598 if(old_mntners != NULL && old_auth_vector == NULL){
1599 /* then, the mntners in 'old_mntners' do not exist. Problem. */
1600 return UP_AUF; /* auth failed */
1601 }
1602 if(old_auth_vector){ /* if we have mntners in the old object, use them */
1603 return authorise(old_auth_vector, credentials, overriden);
1604 }else{
1605 new_mntners = get_mntners(new_object);
1606 new_auth_vector = get_auth_vector(new_mntners);
1607 if(new_mntners != NULL && new_auth_vector == NULL){
1608 /* then, the mntners in 'new_mntners' do not exist. Problem. */
1609 return UP_AUF; /* auth failed */
1610 }
1611 return authorise(new_auth_vector, credentials, overriden);
1612 }
1613 }else{ /* both are NULL, mustn't happen */
1614 cout << "DEBUG: check_auth: internal error: Both pointers are NULL" << endl;
1615 return UP_INT; /* internal error */
1616 }
1617 }
1618
1619
1620
1621 /*
1622 * Handle the "domain" type
1623 */
1624 else if(strcmp(type,"domain") == 0){
1625 if( new_object == NULL && old_object != NULL ){ /* the object is to be deleted */
1626 old_mntners = get_mntners(old_object);
1627 old_auth_vector = get_auth_vector(old_mntners);
1628 if(old_mntners != NULL && old_auth_vector == NULL){
1629 /* then, the mntners in 'old_mntners' do not exist. Problem. */
1630 return UP_AUF; /* auth failed */
1631 }
1632 return authorise(old_auth_vector, credentials, overriden);
1633 }else if( new_object != NULL && old_object == NULL ){ /* the object is to be created */
1634 /* now, we have to find a 'less specific domain object' for this.
1635 If there is no less specific object, then creation is possible
1636 only with overriding. */
1637 less_specific_domain = get_less_specific_domain(new_object);
1638 if(less_specific_domain == NULL){
1639 if(overriden){/* we didn't get a 'less specific' domain object */
1640 return UP_AUTH_OK;
1641 }else{
1642 return UP_HOF; /* hierarchical authorisation failed */
1643 }
1644 }else{ /* we get a 'less specific' domain object */
1645 less_specific_mnt_lowers = get_mnt_lowers(less_specific_domain);
1646 less_specific_auth_vector = get_auth_vector(less_specific_mnt_lowers);
1647 if(less_specific_mnt_lowers != NULL && less_specific_auth_vector == NULL){
1648 /* then, the mntners in 'less_specific_mnt_lowers' do not exist. Problem. */
1649 return UP_AUF; /* auth failed */
1650 }
1651 if(authorise(less_specific_auth_vector, credentials, overriden) == UP_AUTH_OK){
1652 new_mntners = get_mntners(new_object);
1653 new_auth_vector = get_auth_vector(new_mntners);
1654 if(new_mntners != NULL && new_auth_vector == NULL){
1655 /* then, the mntners in 'new_mntners' do not exist. Problem. */
1656 return UP_AUF; /* auth failed */
1657 }
1658 return authorise(new_auth_vector, credentials, overriden);
1659 }else{
1660 return UP_HOF; /* hierarchical authorisation failed */
1661 }
1662
1663 }
1664 }else if( new_object != NULL && old_object != NULL ){ /* this is an update */
1665 old_mntners = get_mntners(old_object);
1666 old_auth_vector = get_auth_vector(old_mntners);
1667 if(old_mntners != NULL && old_auth_vector == NULL){
1668 /* then, the mntners in 'old_mntners' do not exist. Problem. */
1669 return UP_AUF; /* auth failed */
1670 }
1671 if(old_auth_vector){ /* if we have mntners in the old object, use them */
1672 return authorise(old_auth_vector, credentials, overriden);
1673 }else{
1674 new_mntners = get_mntners(new_object);
1675 new_auth_vector = get_auth_vector(new_mntners);
1676 if(new_mntners != NULL && new_auth_vector == NULL){
1677 /* then, the mntners in 'new_mntners' do not exist. Problem. */
1678 return UP_AUF; /* auth failed */
1679 }
1680 return authorise(new_auth_vector, credentials, overriden);
1681 }
1682 }else{ /* both are NULL, mustn't happen */
1683 cout << "DEBUG: check_auth: internal error: Both pointers are NULL" << endl;
1684 return UP_INT; /* internal error */
1685 }
1686 }
1687
1688
1689 /*
1690 * Handle the "route" type
1691 */
1692 else if(strcmp(type,"route") == 0){
1693 if( new_object == NULL && old_object != NULL ){ /* the object is to be deleted */
1694 old_mntners = get_mntners(old_object);
1695 old_auth_vector = get_auth_vector(old_mntners);
1696 if(old_mntners != NULL && old_auth_vector == NULL){
1697 /* then, the mntners in 'old_mntners' do not exist. Problem. */
1698 return UP_AUF; /* auth failed */
1699 }
1700 return authorise(old_auth_vector, credentials, overriden);
1701 }else if( new_object != NULL && old_object == NULL ){ /* the object is to be created */
1702 /* first we have to find the aut-num object mentioned in the
1703 origin attribute */
1704
1705 aut_num_object = get_aut_num_object(new_object);
1706 if(aut_num_object == NULL){
1707 if(overriden){
1708 return UP_AUTH_OK;
1709 }else{
1710 return UP_HOF; /* hierarchical authorisation failed */
1711 }
1712 }else{/* there is a corresponding aut-num in the db */
1713 printf("DEBUG: check_auth: will try to authorise the route using aut-num\n");
1714 aut_num_maintainers = get_mnt_routes(aut_num_object);
1715 if(aut_num_maintainers != NULL){
1716 aut_num_auth_vector = get_auth_vector(aut_num_maintainers);
1717 if(authorise(aut_num_auth_vector, credentials, overriden) == UP_AUTH_OK){
1718 aut_num_auth_OK = true;
1719 }else{/* authorise(aut_num_auth_vector, credentials, overriden) != UP_AUTH_OK */
1720 return UP_HOF;
1721 }
1722 }else{/* aut_num_maintainers is NULL */
1723 aut_num_maintainers = get_mnt_lowers(aut_num_object);
1724 if(aut_num_maintainers != NULL){
1725 aut_num_auth_vector = get_auth_vector(aut_num_maintainers);
1726 if(authorise(aut_num_auth_vector, credentials, overriden) == UP_AUTH_OK){
1727 aut_num_auth_OK = TRUE;
1728 }else{/* authorise(aut_num_auth_vector, credentials, overriden) != UP_AUTH_OK */
1729 return UP_HOF; /* hierarchical authorisation failed */
1730 }
1731 }else{/* aut_num_maintainers is NULL */
1732 aut_num_maintainers = get_mntners(aut_num_object);
1733 if(aut_num_maintainers != NULL){
1734 aut_num_auth_vector = get_auth_vector(aut_num_maintainers);
1735 if(authorise(aut_num_auth_vector, credentials, overriden) == UP_AUTH_OK){
1736 aut_num_auth_OK = TRUE;
1737 }else{/* authorise(aut_num_auth_vector, credentials, overriden) != UP_AUTH_OK */
1738 return UP_HOF; /* hierarchical authorisation failed */
1739 }
1740 }else{/* aut_num_maintainers is NULL */
1741 aut_num_auth_OK = TRUE;
1742 }
1743
1744 }
1745 }
1746 if(aut_num_auth_OK){
1747 /* now, we have to find an exact match for this route object.
1748 If there is no exact match object, then we will go on to find
1749 less specific. */
1750 exact_match_routes = get_exact_match_routes(new_object);
1751 if(exact_match_routes != NULL){
1752 exact_match_routes_maintainers = get_mnt_routes_from_list(exact_match_routes);
1753 exact_match_routes_auth_vector = get_auth_vector(exact_match_routes_maintainers);
1754 if(exact_match_routes_maintainers != NULL && exact_match_routes_auth_vector == NULL){
1755 /* then, the mntners in 'exact_match_routes_maintainers' do not exist. Problem. */
1756 return UP_AUF; /* auth failed */
1757 }
1758 if(authorise(exact_match_routes_auth_vector, credentials, overriden) == UP_AUTH_OK){
1759 /* then, check mnt_bys of the route itself */
1760 new_mntners = get_mntners(new_object);
1761 new_auth_vector = get_auth_vector(new_mntners);
1762 if(new_mntners != NULL && new_auth_vector == NULL){
1763 /* then, the mntners in 'new_mntners' do not exist. Problem. */
1764 return UP_AUF; /* auth failed */
1765 }
1766 return authorise(new_auth_vector, credentials, overriden);
1767 }else{/*authorise(exact_match_routes_auth_vector, credentials, overriden) != UP_AUTH_OK*/
1768 return UP_HOF; /* hierarchical authorisation failed */
1769 }
1770 }else{ /* exact_match_routes == NULL */
1771 /* then we have to look for less specific route objs */
1772 less_spec_routes = get_less_spec_routes(new_object);
1773 if(less_spec_routes != NULL){
1774 less_spec_routes_mntners = get_mnt_routes_from_list(less_spec_routes);
1775 less_spec_routes_mntners = g_slist_concat(less_spec_routes_mntners,
1776 get_mnt_lowers_from_list(less_spec_routes));
1777 less_spec_routes_auth_vector = get_auth_vector(less_spec_routes_mntners);
1778 if(less_spec_routes_mntners != NULL && less_spec_routes_auth_vector == NULL){
1779 /* then, the mntners in 'less_spec_routes_mntners' do not exist. Problem. */
1780 return UP_AUF; /* auth failed */
1781 }
1782 if(authorise(less_spec_routes_auth_vector, credentials, overriden) == UP_AUTH_OK){
1783 /* then, check mnt_bys of the route itself */
1784 new_mntners = get_mntners(new_object);
1785 new_auth_vector = get_auth_vector(new_mntners);
1786 if(new_mntners != NULL && new_auth_vector == NULL){
1787 /* then, the mntners in 'new_auth_vector' do not exist. Problem. */
1788 return UP_AUF; /* auth failed */
1789 }
1790 return authorise(new_auth_vector, credentials, overriden);
1791 }else{/*authorise(less_spec_routes_auth_vector, credentials, overriden) != UP_AUTH_OK*/
1792 return UP_HOF; /* hierarchical authorisation failed */
1793 }
1794 }else{/* less_spec_routes == NULL */
1795 /* so, we have to get the exact match inetnum */
1796 exact_match_inetnum = get_exact_match_inetnum(new_object);
1797 if(exact_match_inetnum != NULL){
1798 exact_match_inetnum_mnt_routes = get_mnt_routes(exact_match_inetnum);
1799 exact_match_inetnum_auth_vector = get_auth_vector(exact_match_inetnum_mnt_routes);
1800 if(exact_match_inetnum_mnt_routes != NULL && exact_match_inetnum_auth_vector == NULL){
1801 /* then, the mntners in 'exact_match_inetnum_mnt_routes' do not exist. Problem. */
1802 return UP_AUF; /* auth failed */
1803 }
1804 if(authorise(exact_match_intenum_auth_vector, credentials, overriden) == UP_AUTH_OK){
1805 /* then, check mnt_bys of the route itself */
1806 new_mntners = get_mntners(new_object);
1807 new_auth_vector = get_auth_vector(new_mntners);
1808 if(new_mntners != NULL && new_auth_vector == NULL){
1809 /* then, the mntners in 'new_auth_vector' do not exist. Problem. */
1810 return UP_AUF; /* auth failed */
1811 }
1812 return authorise(new_auth_vector, credentials, overriden);
1813 }else{
1814 return UP_HOF; /* hierarchical authorisation failed */
1815 }
1816 }else{/* exact_match_inetnum == NULL */
1817 /* then, we will try to find less spec inetnums */
1818 less_spec_inetnum = get_less_spec_inetnum(new_object);
1819 if(less_spec_inetnum != NULL){
1820 less_spec_inetnum_mntners = get_mnt_routes(less_spec_inetnum);
1821 less_spec_inetnum_mntners = g_slist_concat(less_spec_inetnum_mntners,
1822 get_mnt_lowers(less_spec_inetnum));
1823 less_spec_inetnum_auth_vector = get_auth_vector(less_spec_inetnum_mntners);
1824 if(less_spec_inetnum_mntners != NULL && less_spec_inetnum_auth_vector == NULL){
1825 /* then, the mntners in 'less_spec_inetnum_mntners' do not exist. Problem. */
1826 return UP_AUF; /* auth failed */
1827 }
1828 if(authorise(exact_match_auth_vector, credentials, overriden) == UP_AUTH_OK){
1829 /* then, check mnt_bys of the route itself */
1830 new_mntners = get_mntners(new_object);
1831 new_auth_vector = get_auth_vector(new_mntners);
1832 if(new_mntners != NULL && new_auth_vector == NULL){
1833 /* then, the mntners in 'new_auth_vector' do not exist. Problem. */
1834 return UP_AUF; /* auth failed */
1835 }
1836 return authorise(new_auth_vector, credentials, overriden);
1837 }else{/* authorise(exact_match_auth_vector, credentials, overriden) != UP_AUTH_OK */
1838 return UP_HOF; /* hierarchical authorisation failed */
1839 }
1840 }else{/* less_spec_inetnum == NULL */
1841 /* now that we couldn't find any route or inetnum object
1842 to be used in authentication. So, only if the auth is
1843 overriden the object will be created. */
1844 if(overriden){
1845 return UP_AUTH_OK;
1846 }else{
1847 return UP_HOF; /* hierarchical authorisation failed */
1848 }
1849 }
1850 }
1851 }
1852 }
1853 }else{/* ! aut_num_auth_OK */
1854 return UP_HOF; /* hierarchical auth failed */
1855 }
1856
1857 }
1858
1859 }else if( new_object != NULL && old_object != NULL ){ /* this is an update */
1860 old_mntners = get_mntners(old_object);
1861 old_auth_vector = get_auth_vector(old_mntners);
1862 if(old_mntners != NULL && old_auth_vector == NULL){
1863 /* then, the mntners in 'old_auth_vector' do not exist. Problem. */
1864 return UP_AUF; /* auth failed */
1865 }
1866 if(old_auth_vector){ /* if we have mntners in the old object, use them */
1867 return authorise(old_auth_vector, credentials, overriden);
1868 }else{
1869 new_mntners = get_mntners(new_object);
1870 new_auth_vector = get_auth_vector(new_mntners);
1871 if(new_mntners != NULL && new_auth_vector == NULL){
1872 /* then, the mntners in 'new_auth_vector' do not exist. Problem. */
1873 return UP_AUF; /* auth failed */
1874 }
1875 return authorise(new_auth_vector, credentials, overriden);
1876 }
1877 }else{ /* both are NULL, mustn't happen */
1878 cout << "DEBUG: check_auth: internal error: Both pointers are NULL" << endl;
1879 return UP_INT; /* internal error */
1880 }
1881 }
1882
1883
1884 /*
1885 * Handle the set objects ("as-set","rtr-set", "peering-set", "route-set" and "filter-set" types
1886 */
1887 else if(strcmp(type,"as-set") == 0 || strcmp(type,"rtr-set") == 0 ||
1888 strcmp(type,"peering-set") == 0 || strcmp(type,"filter-set") == 0 ||
1889 strcmp(type,"route-set") == 0 ){
1890 if( new_object == NULL && old_object != NULL ){ /* the object is to be deleted */
1891 old_mntners = get_mntners(old_object);
1892 old_auth_vector = get_auth_vector(old_mntners);
1893 if(old_mntners != NULL && old_auth_vector == NULL){
1894 /* then, the mntners in 'old_auth_vector' do not exist. Problem. */
1895 return UP_AUF; /* auth failed */
1896 }
1897 return authorise(old_auth_vector, credentials, overriden);
1898 }else if( new_object != NULL && old_object == NULL ){ /* the object is to be created */
1899 code = set_object->scan(new_object, strlen(new_object));
1900 set_name = get_search_key(set_object, type, new_object);
1901 if(strstr(set_name,":") == NULL ){/* if the name is _not_ hierarchical */
1902 new_mntners = get_mntners(new_object);
1903 new_auth_vector = get_auth_vector(new_mntners);
1904 if(new_mntners != NULL && new_auth_vector == NULL){
1905 /* then, the mntners in 'new_auth_vector' do not exist. Problem. */
1906 return UP_AUF; /* auth failed */
1907 }
1908 return authorise(new_auth_vector, credentials, overriden);
1909 }else{/* the name is hierarchical */
1910 less_specific_object = get_less_specific_set(new_object, type);
1911 if(less_specific_object != NULL){/* such an object exists */
1912 temp_obj = new Object();
1913 code = temp_obj->scan(less_specific_object, strlen(less_specific_object));
1914 less_specific_object_type = get_type(temp_obj);
1915 delete(temp_obj);
1916 if(strcmp(less_specific_object_type, "aut-num") == 0){/* if this is an aut-num object */
1917 less_specific_mnt_lowers = get_mnt_lowers(less_specific_object);
1918 less_specific_auth_vector = get_auth_vector(less_specific_mnt_lowers);
1919 if(less_specific_mnt_lowers != NULL && less_specific_auth_vector == NULL){
1920 /* then, the mntners in 'less_specific_auth_vector' do not exist. Problem. */
1921 return UP_AUF; /* auth failed */
1922 }
1923 if(less_specific_auth_vector != NULL){
1924 return authorise(less_specific_auth_vector, credentials, overriden);
1925 }else{/* the less specific object doesn't contain any mnt-lower */
1926 less_specific_mntners = get_mntners(less_specific_object);
1927 less_specific_auth_vector = get_auth_vector(less_specific_mntners);
1928 if(less_specific_mntners != NULL && less_specific_auth_vector == NULL){
1929 /* then, the mntners in 'less_specific_mntners' do not exist. Problem. */
1930 return UP_AUF; /* auth failed */
1931 }
1932 if(less_specific_auth_vector != NULL){/* less spec object has some mnt-by attribs,
1933 use them */
1934 return authorise(less_specific_auth_vector, credentials, overriden);
1935 }else{/* the less specific object doesn't contain any mnt-by either */
1936 if(overriden){
1937 return UP_AUTH_OK;
1938 }else{
1939 return UP_HOF; /* hierarchical authorisation failed */
1940 }
1941 }
1942 }
1943 }else{ /* this is _not_ an aut-num object*/
1944 less_specific_mntners = get_mntners(less_specific_object);
1945 less_specific_auth_vector = get_auth_vector(less_specific_mntners);
1946 if(less_specific_mntners != NULL && less_specific_auth_vector == NULL){
1947 /* then, the mntners in 'less_specific_mntners' do not exist. Problem. */
1948 return UP_AUF; /* auth failed */
1949 }
1950 if(less_specific_auth_vector != NULL ){/* the set obj has some mnt-by attribs */
1951 return authorise(less_specific_auth_vector, credentials, overriden);
1952 }else{
1953 if(overriden){
1954 return UP_AUTH_OK;
1955 }else{
1956 return UP_HOF; /* hierarchical authorisation failed */
1957 }
1958 }
1959 }
1960
1961 }else{/* we don't have a less specific of this set object in the DB */
1962 return UP_HOF; /* hierarchical authorisation failed */
1963 }
1964 }
1965 }else if( new_object != NULL && old_object != NULL ){ /* this is an update */
1966 old_mntners = get_mntners(old_object);
1967 old_auth_vector = get_auth_vector(old_mntners);
1968 if(old_mntners != NULL && old_auth_vector == NULL){
1969 /* then, the mntners in 'old_auth_vector' do not exist. Problem. */
1970 return UP_AUF; /* auth failed */
1971 }
1972 if(old_auth_vector){ /* if we have mntners in the old object, use them */
1973 return authorise(old_auth_vector, credentials, overriden);
1974 }else{
1975 new_mntners = get_mntners(new_object);
1976 new_auth_vector = get_auth_vector(new_mntners);
1977 if(new_mntners != NULL && new_auth_vector == NULL){
1978 /* then, the mntners in 'new_mntners' do not exist. Problem. */
1979 return UP_AUF; /* auth failed */
1980 }
1981 return authorise(new_auth_vector, credentials, overriden);
1982 }
1983 }else{ /* both are NULL, mustn't happen */
1984 cout << "DEBUG: check_auth: internal error: Both pointers are NULL" << endl;
1985 return UP_INT; /* internal error */
1986 }
1987
1988
1989
1990
1991
1992 }else{ /* We exhausted all object classes. If we are here, then there is a problem */
1993 cout << "check_auth: This type '" << type << "' is unknown" << endl;
1994 return UP_NIY; /* not implemented yet */
1995 }
1996 return UP_AUF; /* if we come to this point, then auth failed */
1997 }
1998
1999
2000
2001
2002
2003
2004 /* Gets the old version of the given "arg" object, which is in char * format
2005 and returns the old version again in char * format */
2006
2007 char * get_old_version(char * arg){
/* [<][>][^][v][top][bottom][index][help] */
2008
2009 bool code = true;
2010 char *type=NULL, *primary_search_key = NULL, *search_string = NULL;
2011 Object *o;
2012 o = new Object;
2013 char *result = NULL, *origin = NULL;
2014
2015 error = 0;
2016 code = o->scan(arg,strlen(arg));
2017 type = get_type(o);
2018 primary_search_key = get_search_key(o, type, arg);
2019 if(tracing) {
2020 cout << "type=" << type << endl;
2021 cout << "primary_search_key=" << primary_search_key << endl;
2022 }
2023 /* prepare the search string */
2024 //search_string = (char *)malloc(strlen(primary_search_key) + strlen("-x -R -r -T")
2025 // + strlen(type) + 1);
2026 /* if the object is a pn ro a ro object, then get all pn/ro's with the
2027 same NIC hdl */
2028 if(strcmp(type,"person") == 0 || strcmp(type,"role") == 0){
2029 /* prepare the search string */
2030 search_string = (char *)malloc(strlen(primary_search_key) + strlen("-x -R -r -T")
2031 + strlen("person,role") + 1);
2032 sprintf(search_string, "-x -R -r -Tperson,role %s", primary_search_key);
2033 }else{
2034 /* prepare the search string */
2035 search_string = (char *)malloc(strlen(primary_search_key) + strlen("-x -R -r -T")
2036 + strlen(type) + 1);
2037 sprintf(search_string, "-x -R -r -T%s %s",type, primary_search_key);
2038 }
2039 result = send_and_get(QUERY_HOST, QUERY_PORT, search_string);
2040 if(tracing) {
2041 cout << "TRACING: send_and_get has returned" << endl;
2042 cout << "TRACING: send_and_get returned (with search '"<< search_string <<"'): " << endl
2043 << result << endl;
2044 }
2045 /* Attention: here we must also check these:
2046 for ro/pn objects: The name must also the same. When the NIC hdl is the
2047 same but names are different, we must somehow return an error.
2048 Also, when we search for a person, we must also look for role objects
2049 (and vice versa) since the RIPupdate does not distinguish between
2050 role & person objects. We have to check it here.
2051 for rt objects: We also have to check the identicalness of origin
2052 attributes.
2053
2054 These are not yet implemented.
2055 */
2056
2057 if(strcmp(type,"route") == 0){
2058 if(tracing) {
2059 printf("TRACING: This is a route\n");
2060 }
2061 /* if this is a route, then we must filter out the routes with different
2062 origin attributes */
2063 origin = get_search_key(o, "origin", arg);
2064 if(tracing) {
2065 printf("TRACING: Got origin of route: %s\n", origin);
2066 }
2067 result = filter_out_diff_origins(result, origin);
2068 if(tracing) {
2069 printf("TRACING: Filtered routes\n");
2070 }
2071 }
2072 // count the objects
2073 if(count_objects(result) == 0){
2074 result = NULL; /* we don't have such an object */
2075 }else if(count_objects(result) == 1){
2076 result = take_object(result);
2077 if(tracing) {
2078 cout << "TRACING: Take_object returned ***\n" << result << "***" << endl;
2079 }
2080 }else{ /* we have more than one objects, error! */
2081 error = UP_MOR;
2082 return NULL;
2083 }
2084 return result;
2085 }
2086
2087
2088
2089
2090 /* Gets a credentials_struct whose 'from' field will be filled in and
2091 the mail header. Finds the 'From:' line in the header and sets
2092 the 'from' field to this line (all line, including the 'From:' string,
2093 since some users have put regexps which match the whole line in their
2094 'auth' attributes.) */
2095 void process_mail_header(credentials_struct * credentials_ptr, char * arg){
/* [<][>][^][v][top][bottom][index][help] */
2096 char * header = strdup(arg);
2097 char * temp = (char *)malloc(strlen(header));
2098 while(index(header, '\n') != NULL){
2099 temp = strdup(header);
2100 temp[index(temp, '\n') - temp] = '\0';
2101 if(strstr(temp, "From:") == temp){
2102 if(tracing) {
2103 printf("TRACING: process_mail_header: Assigning %s\n", temp);
2104 }
2105 credentials_ptr->from = strdup(temp);
2106 free(temp);
2107 return;
2108 }
2109 header = header + (index(header, '\n') - header + 1);
2110 }
2111 free(temp);
2112 }
2113
2114
2115
2116
2117
2118
2119 void stringPack(char *dest, const char *source)
/* [<][>][^][v][top][bottom][index][help] */
2120 {
2121
2122 if(tracing) {
2123 printf("TRACING: stringPack running\n");
2124 }
2125
2126
2127
2128 /*----------------------------------------------------------------------*\
2129
2130 * Function to rewrite a line of text with only one blankspace between *
2131 * each word.
2132 *
2133
2134 \*----------------------------------------------------------------------*/
2135
2136
2137 /*
2138 * This while loop continues until the NULL character is copied into
2139 * the destination string. If a tab character is copied into the
2140 * destination string, it is replaced with a blank-space character.
2141 *
2142 * Multiple blank-space and/or tab characters are skipped in the source
2143 * string until any other character is found.
2144 */
2145
2146 while (1)
2147 {
2148 *dest = *source;
2149
2150 if (*dest == '\t')
2151 (*dest = ' ');
2152
2153 /* Exit if have copied the end of the string. */
2154 if (*dest == '\0')
2155 return;
2156
2157 /*
2158 * If the source character was a blank-space or a tab, move to the next
2159 * source character. While the source character is a blank-space or a
2160 * tab, move to the next character (i.e. ignore these characters). When
2161 * any other character is found in the source string, move to the next
2162 * element of the destination string.
2163 *
2164 * Otherwise, simultaneously, move to the next elements of the destination
2165 * and the source strings.
2166 */
2167
2168
2169
2170 if ( (*source == ' ') || (*source == '\t') )
2171 {
2172 ++source;
2173 while ( (*source == ' ') || (*source == '\t') )
2174 {
2175 ++source;
2176 }
2177
2178 ++dest;
2179 }
2180 else
2181 {
2182 ++dest;
2183 ++source;
2184 }
2185 }
2186 }
2187
2188 /* strips lines beginning with "delete:" off */
2189 char * delete_delete_attrib(char * arg){
/* [<][>][^][v][top][bottom][index][help] */
2190
2191 char ** temp = NULL;
2192 char * string = NULL;
2193 int i;
2194
2195 if(arg == NULL){
2196 return NULL;
2197 }
2198
2199 /* split the string into lines */
2200 temp = g_strsplit (arg, "\n", 0);
2201
2202 for(i=0; temp[i] != NULL; i++){
2203 if(strstr(temp[i], "delete:") != temp[0]){
2204 //printf("DEBUG: temp[i] = %s\n", temp[i]);
2205 if(string == NULL){
2206 string = strdup(temp[i]);
2207 }else{
2208 string = (char *)realloc(string, strlen(string) + strlen(temp[i]) + 1);
2209 string = strcat(string, "\n");
2210 string = strcat(string, temp[i]);
2211 }
2212 }
2213 }
2214 g_strfreev(temp);
2215 return string;
2216 }
2217
2218
2219
2220 int identical(const char * old_version, const char * new_version){
/* [<][>][^][v][top][bottom][index][help] */
2221 char * arg1 = strdup(old_version);
2222 char * arg2 = strdup(new_version);
2223 int result = 0;
2224 char *temp1, *temp2;
2225
2226
2227 arg1 = g_strstrip(arg1);
2228 arg2 = g_strstrip(arg2);
2229
2230 /* delete the 'delete:' attrib */
2231 arg1 = delete_delete_attrib(arg2);
2232 /* convert tabs to white spaces */
2233 arg1 = g_strdelimit(arg1, "\t", ' ');
2234 arg2 = g_strdelimit(arg2, "\t", ' ');
2235
2236 temp1 = (char *)malloc(strlen(arg1));
2237 temp2 = (char *)malloc(strlen(arg2));
2238 stringPack(temp1, arg1);
2239 stringPack(temp2, arg2);
2240
2241 result = strcmp(temp1, temp2);
2242 //printf("TRACING: identical: the objects are:\n[%s]\n[%s]\n", temp1, temp2);
2243 free(arg1);
2244 free(arg2);
2245 free(temp1);
2246 free(temp2);
2247 if(result == 0){
2248 if(tracing) {
2249 printf("TRACING: identical returning 1\n");
2250 }
2251 return 1;
2252 }else{
2253 if(tracing) {
2254 printf("TRACING: identical returning 0\n");
2255 }
2256 return 0;
2257 }
2258 }
2259
2260
2261
2262
2263
2264
2265 /* constructs an initials string from a given name (for NIC hdl generation) */
2266 char * find_initials(const char * arg){
/* [<][>][^][v][top][bottom][index][help] */
2267
2268 char * temp, * temp2;
2269 char * initials = NULL;
2270 int len, i;
2271 char ** vector;
2272
2273 temp = strdup(arg);
2274 g_strstrip(temp);
2275 temp2 = (char *)malloc(strlen(temp) + 1);
2276 stringPack(temp2, temp);
2277 vector = g_strsplit(temp2, " ", 0);
2278 for(i = 0; vector[i] != NULL && i < 4; i++){
2279 //printf("%i\n",i);
2280 if(strlen(vector[i]) > 0){
2281 if(initials == NULL){
2282 initials = (char *)malloc(2);
2283 initials[0] = vector[i][0]; initials[1] = '\0';
2284 }else{
2285 len = strlen(initials);
2286 initials = (char *)realloc(initials, len + 2 );
2287 initials[len] = vector[i][0];
2288 initials[len + 1] = '\0';
2289 }
2290 }
2291 }
2292 free(temp);free(temp2);g_strfreev(vector);
2293 return initials;
2294 }
2295
2296
2297
2298
2299
2300
2301
2302 /* Gets an object whose NIC hdl is AUTO and to be modified (to be sent to RIPupdate)
2303 and modifies the nic-hdl: attribute, returns the new object.
2304 For example, "nic-hdl: AUTO-1" becomes "nic-hdl: HG*-RIPE . Also,
2305 auto_nic is set to "AUTO-1"
2306 auto_nic must be allocated enough memory before replace_AUTO_NIC_hdl called */
2307
2308 char * replace_AUTO_NIC_hdl(char * arg, char * auto_nic_hdl){
/* [<][>][^][v][top][bottom][index][help] */
2309
2310 GString* temp_string;
2311 char * to_be_returned = NULL;
2312 char * person_role_name= NULL;
2313 char * initials = NULL;
2314 char ** temp = NULL;
2315 int i, pos;
2316 Object * o = new Object;
2317
2318 temp = g_strsplit(arg, "\n", 0);
2319
2320 for(i = 0; temp[i] != NULL; i++){
2321 //printf("Line: %s\n", temp[i]);
2322 if(strstr(temp[i], "nic-hdl:") == temp[i]){/* if it starts with nic-hdl */
2323 temp_string = g_string_new(temp[i]);
2324 if(strstr(temp_string->str, "AUTO-") != NULL){
2325 auto_nic_hdl = strncpy(auto_nic_hdl, strstr(temp_string->str, "AUTO-"),
2326 temp_string->len + temp_string->str - strstr(temp_string->str, "AUTO-") );
2327 auto_nic_hdl[temp_string->len + temp_string->str - strstr(temp_string->str, "AUTO-")] = '\0';
2328 g_strstrip(auto_nic_hdl);
2329 printf("DEBUG: auto_nic is [%s]\n", auto_nic_hdl);
2330 pos = strstr(temp_string->str, "AUTO-") - temp_string->str;
2331 temp_string = g_string_erase(temp_string,
2332 strstr(temp_string->str, "AUTO-") - temp_string->str, strlen(auto_nic_hdl)/*strlen("AUTO-")*/);
2333
2334 temp_string = g_string_insert(temp_string, pos, UPDATE_SOURCE);
2335 temp_string = g_string_insert(temp_string, pos, "*-");
2336 o->scan(arg, strlen(arg));
2337 person_role_name = get_attribute(o, get_type(o), arg);
2338 delete(o);
2339 initials = find_initials(person_role_name);
2340 free(person_role_name);
2341 temp_string = g_string_insert(temp_string, pos, initials);
2342 free(initials);
2343
2344 if(to_be_returned == NULL){
2345 to_be_returned = strdup(temp_string->str);
2346 g_string_free(temp_string, TRUE);
2347 }else{
2348 to_be_returned = (char *)realloc(to_be_returned, strlen(to_be_returned) + temp_string->len + 2);
2349 to_be_returned = strcat(to_be_returned, "\n");
2350 to_be_returned = strcat(to_be_returned, temp_string->str);
2351 g_string_free(temp_string, TRUE);
2352 }
2353 }else{
2354 if(to_be_returned == NULL){
2355 to_be_returned = strdup(temp[i]);
2356 }else{
2357 to_be_returned = (char *)realloc(to_be_returned, strlen(to_be_returned) + strlen(temp[i]) + 2);
2358 to_be_returned = strcat(to_be_returned, "\n");
2359 to_be_returned = strcat(to_be_returned, temp[i]);
2360 }
2361 }
2362 }else{/* if it doesn't begin with nic-hdl */
2363 if(to_be_returned == NULL){
2364 to_be_returned = strdup(temp[i]);
2365 }else{
2366 to_be_returned = (char *)realloc(to_be_returned, strlen(to_be_returned) + strlen(temp[i]) + 2);
2367 strcat(to_be_returned, "\n");
2368 strcat(to_be_returned, temp[i]);
2369 }
2370
2371 }
2372
2373 }
2374 g_strfreev (temp);
2375 return to_be_returned;
2376 }
2377
2378
2379
2380 /* replaces the refs to AUTO NIC hdls with the assigned one */
2381
2382 char * replace_refs_to_AUTO_NIC_hdl(char * changed_obj, char * arg, GHashTable * auto_nic_hash){
/* [<][>][^][v][top][bottom][index][help] */
2383
2384 char * auto_nic = NULL;
2385 GString* temp_string;
2386 char * to_be_returned = NULL;
2387 char ** temp = NULL;
2388 int i, pos;
2389
2390 //printf("DEBUG: replace_first_ref_to_AUTO_NIC_hdl is running\n");
2391
2392 temp = g_strsplit(arg, "\n", 0);
2393
2394 for(i = 0; temp[i] != NULL; i++){
2395 //printf("Line: %s\n", temp[i]);
2396 if( strstr(temp[i], "admin-c:") == temp[i] /* if it starts with admin-c */
2397 || strstr(temp[i], "tech-c:" ) == temp[i] /* or if it starts with tech-c */
2398 || strstr(temp[i], "zone-c:" ) == temp[i] /* or if it starts with zone-c */
2399 || strstr(temp[i], "author:" ) == temp[i]){ /* or if it starts with author */
2400 temp_string = g_string_new(temp[i]);
2401 if(strstr(temp_string->str, "AUTO-") != NULL){
2402 auto_nic = (char *)malloc(temp_string->len + temp_string->str - strstr(temp_string->str, "AUTO-") + 1);
2403 auto_nic = strncpy(auto_nic, strstr(temp_string->str, "AUTO-"),
2404 temp_string->len + temp_string->str - strstr(temp_string->str, "AUTO-") );
2405 auto_nic[temp_string->str + temp_string->len - strstr(temp_string->str, "AUTO-")] = '\0';
2406 g_strstrip(auto_nic);
2407 printf("DEBUG: auto_nic is [%s]\n", auto_nic);
2408 pos = strstr(temp_string->str, "AUTO-") - temp_string->str;
2409 temp_string = g_string_erase(temp_string,
2410 strstr(temp_string->str, "AUTO-") - temp_string->str, strlen(auto_nic)/*strlen("AUTO-")*/);
2411
2412 //temp_string = g_string_insert(temp_string, pos, UPDATE_SOURCE);
2413 //temp_string = g_string_insert(temp_string, pos, "*-");
2414 /* if we have this AUTO NIC hdl in the hash, put it. */
2415 if(g_hash_table_lookup(auto_nic_hash, auto_nic)){
2416 temp_string = g_string_insert(temp_string, pos, (char *)g_hash_table_lookup(auto_nic_hash, auto_nic));
2417 }else{/* else, return 0 immediately */
2418 g_strfreev (temp);
2419 return NULL;
2420 }
2421
2422 if(to_be_returned == NULL){
2423 to_be_returned = strdup(temp_string->str);
2424 g_string_free(temp_string, TRUE);
2425 }else{
2426 to_be_returned = (char *)realloc(to_be_returned, strlen(to_be_returned) + temp_string->len + 2);
2427 to_be_returned = strcat(to_be_returned, "\n");
2428 to_be_returned = strcat(to_be_returned, temp_string->str);
2429 g_string_free(temp_string, TRUE);
2430 }
2431 }else{
2432 if(to_be_returned == NULL){
2433 to_be_returned = strdup(temp[i]);
2434 }else{
2435 to_be_returned = (char *)realloc(to_be_returned, strlen(to_be_returned) + strlen(temp[i]) + 2);
2436 to_be_returned = strcat(to_be_returned, "\n");
2437 to_be_returned = strcat(to_be_returned, temp[i]);
2438 }
2439 }
2440 }else{/* if it doesn't begin with ac,tc,ac or author */
2441 if(to_be_returned == NULL){
2442 to_be_returned = strdup(temp[i]);
2443 }else{
2444 to_be_returned = (char *)realloc(to_be_returned, strlen(to_be_returned) + strlen(temp[i]) + 2);
2445 strcat(to_be_returned, "\n");
2446 strcat(to_be_returned, temp[i]);
2447 }
2448
2449 }
2450
2451 }
2452 g_strfreev (temp);
2453 //free(arg);
2454 //changed_obj = strdup(to_be_returned);
2455 //free(to_be_returned);
2456 printf("DEBUG: replace_first_ref_to_AUTO_NIC_hdl is returning,\nto_be_returned=[%s]\n", to_be_returned);
2457 return to_be_returned;
2458 }
2459
2460
2461
2462
2463
2464
2465
2466
2467 /* Takes an object in a char * , and returns 1 if this object has
2468 an AUTO NIC handle. Otherwise, returns 0 */
2469 int has_AUTO_NIC_hdl(const char * object){
/* [<][>][^][v][top][bottom][index][help] */
2470
2471 Object * o = new Object();
2472 GSList * attributes = NULL;
2473 bool code;
2474
2475 code = o->scan(object, strlen(object));
2476
2477 if(code && !(o->isDeleted)){
2478 attributes = get_attributes(o, "nic-hdl", object);
2479 if(attributes != NULL){
2480 if(strstr_in_list(attributes, "AUTO-") == 1){/* if it contains a ref to AUTO nic */
2481 g_slist_free(attributes);
2482 delete(o);
2483 return 1;
2484 }
2485 }
2486 /* if control reaches here, then we will return 0 */
2487 g_slist_free(attributes);
2488 delete(o);
2489 return 0;
2490 }else{/* it doesn't pass syntax check. So, it doesn't matter if
2491 it contains refs to AUTO NIC hdls. */
2492 delete(o);
2493 return 0;
2494 }
2495
2496 }
2497
2498
2499 /* Takes an object in a char * , and returns 1 if this object contains
2500 a reference to an AUTO NIC handle. Otherwise, returns 0 */
2501 int has_ref_to_AUTO_nic_hdl(const char * object){
/* [<][>][^][v][top][bottom][index][help] */
2502
2503 Object * o = new Object();
2504 GSList * attributes = NULL;
2505 bool code;
2506
2507 code = o->scan(object, strlen(object));
2508
2509 if(code && !(o->isDeleted)){
2510 attributes = get_attributes(o, "admin-c", object);
2511 if(attributes != NULL){
2512 if(strstr_in_list(attributes, "AUTO-") == 1){/* if it contains a ref to AUTO nic */
2513 g_slist_free(attributes);
2514 delete(o);
2515 return 1;
2516 }
2517 }
2518 g_slist_free(attributes);
2519 attributes = get_attributes(o, "tech-c", object);
2520 if(attributes != NULL){
2521 if(strstr_in_list(attributes, "AUTO-") == 1){/* if it contains a ref to AUTO nic */
2522 g_slist_free(attributes);
2523 delete(o);
2524 return 1;
2525 }
2526 }
2527
2528 g_slist_free(attributes);
2529 attributes = get_attributes(o, "zone-c", object);
2530 if(attributes != NULL){
2531 if(strstr_in_list(attributes, "AUTO-") == 1){/* if it contains a ref to AUTO nic */
2532 g_slist_free(attributes);
2533 delete(o);
2534 return 1;
2535 }
2536 }
2537 g_slist_free(attributes);
2538 attributes = get_attributes(o, "author", object);
2539 if(attributes != NULL){
2540 if(strstr_in_list(attributes, "AUTO-") == 1){/* if it contains a ref to AUTO nic */
2541 g_slist_free(attributes);
2542 delete(o);
2543 return 1;
2544 }
2545 }
2546 /* if control reaches here, then we will return 0 */
2547 delete(o);
2548 return 0;
2549 }else{/* it doesn't pass syntax check. So, it doesn't matter if
2550 it contains refs to AUTO NIC hdls. */
2551 delete(o);
2552 return 0;
2553 }
2554
2555 }
2556
2557
2558 /* */
2559 void add_to_ack(const char * msg, const char * file_name){
/* [<][>][^][v][top][bottom][index][help] */
2560
2561 FILE * ack_file;
2562
2563 if((ack_file = fopen(file_name, "a")) == NULL){
2564 perror("Couldn't open ack file");
2565 return;
2566 }
2567 fprintf(ack_file, "%s\n", msg);
2568 fclose(ack_file);
2569 }
2570
2571 /* */
2572 void add_to_ack_string(const string msg, const char * file_name){
/* [<][>][^][v][top][bottom][index][help] */
2573
2574 ofstream ack_file(file_name, ios::app);
2575
2576 if(!ack_file){
2577 cerr << "Couldn't open ack file" << endl;
2578 return;
2579 }
2580 ack_file << msg << endl;
2581 ack_file.close();
2582 }
2583
2584
2585 /* Checks the object's syntax, retrives the old version of it from the db,
2586 and checks auth2. If everything is OK, then sends it to RIPdb, where referential
2587 integrity is checked, and the object is really committed to the db.
2588
2589 Arguments:
2590 char * arg: The object,
2591 credentials_struct credentials: The struct containing the credentials, such as
2592 'From:' field of the e-mail update,
2593 GHashTable * NIC_hdl_hash: A hash containing
2594 char * ack_file_name: The file name, to be used to store ACK message
2595 */
2596
2597 int process_object(char * arg, credentials_struct credentials, GHashTable * NIC_hdl_hash, char * ack_file_name){
/* [<][>][^][v][top][bottom][index][help] */
2598 bool code = true;
2599 Object *o;
2600 char * old_version = NULL;
2601 o = new Object;
2602 int result = 0;
2603 int result_from_RIPupd = 0;
2604 char * auto_nic = NULL;
2605 char * changed_obj = NULL;
2606 char * obj_with_AUTO_NIC_hdl;
2607 char * assigned_NIC;
2608
2609 char * value = NULL;/* these two are for */
2610 Attr * attr; /* ack messages only */
2611
2612 if(has_ref_to_AUTO_nic_hdl(arg)){/* if this object has refs to AUTO NIC hdls*/
2613 /* then first replace AUTO NIC hdls with assigned NIC hdls (in NIC_hdl_hash) */
2614 if((arg = replace_refs_to_AUTO_NIC_hdl(changed_obj, arg, NIC_hdl_hash)) == NULL){
2615 return UP_ANE; /* AUTO NIC hdl error */
2616 };
2617 }
2618
2619 code = o->scan(arg,strlen(arg));
2620 if(code){
2621 /* is the object to be deleted? */
2622 if(o->isDeleted){
2623 printf("This object is to be deleted\n");
2624 old_version = get_old_version(arg);
2625 if(old_version == NULL){ // the object doesn't exist in the db!
2626 add_to_ack("\nDeletion Failed: Object doesn't exist", ack_file_name);
2627 add_to_ack(o->type->getName(), ack_file_name);
2628 add_to_ack(get_search_key(o, o->type->getName(), arg), ack_file_name);
2629 return UP_NSO; /* no such object */
2630 }else {/* the object is in the db */
2631 if(identical(old_version, arg)){/* if the old & new versions are identical */
2632 result = check_auth(NULL, old_version, o->type->getName(), credentials);
2633 if(result == UP_AUTH_OK){
2634 if(tracing) {
2635 printf("TRACING: Will send the obj to be deleted\n");
2636 }
2637 result_from_RIPupd = send_object_db(arg, NULL, "DEL");
2638 if(result_from_RIPupd == 0){
2639 add_to_ack("\nDeletion succeeded", ack_file_name);
2640 add_to_ack(o->type->getName(), ack_file_name);
2641 add_to_ack(get_search_key(o, o->type->getName(), arg), ack_file_name);
2642 }else{
2643 add_to_ack("\nDeletion failed: Referential intergrity failure", ack_file_name);
2644 add_to_ack(o->type->getName(), ack_file_name);
2645 add_to_ack(get_search_key(o, o->type->getName(), arg), ack_file_name);
2646 }
2647 result_from_RIPupd = 0;
2648 }else{ /* auth failed */
2649 if(tracing) {
2650 printf("TRACING: Auth failed\n");
2651 }
2652 if(error_msg != NULL){
2653 cout << error_msg << endl;
2654 }
2655 add_to_ack("\nDeletion failed: Auth failed", ack_file_name);
2656 add_to_ack(o->type->getName(), ack_file_name);
2657 add_to_ack(get_search_key(o, o->type->getName(), arg), ack_file_name);
2658 return UP_AUF; /* Auth failed */
2659 }
2660 }else{/* the new & old versions do not match */
2661 add_to_ack("Deletion failed: new & old versions do not match", ack_file_name);
2662 return UP_NOM; /* new & old versions do not match */
2663 }
2664 }
2665 }else {/* the object is _not_ to be deleted */
2666 if(has_AUTO_NIC_hdl(arg)){/* it the object has an AUTO NIC hdl */
2667 /* then its nic-hdl attribute must be modified so that RIPupdate
2668 would understand that it must assign a NIC handle to it */
2669 /* but first check the auth */
2670 result = check_auth(arg, NULL, o->type->getName(), credentials);
2671 if(result == UP_AUTH_OK){
2672 if(tracing) {
2673 printf("TRACING: Will send the obj to be created with AUTO NIC hdl\n");
2674 }
2675 auto_nic = (char *)malloc(1024); /* should be enough for a NIC hdl */
2676 obj_with_AUTO_NIC_hdl = replace_AUTO_NIC_hdl(arg, auto_nic);
2677 if(tracing) {
2678 printf("TRACING: Called replace_AUTO_NIC_hdl, get [%s]\n", obj_with_AUTO_NIC_hdl);
2679 printf("TRACING: Will send the obj to be added\n");
2680 }
2681 assigned_NIC = (char *)malloc(128); /* this should be enough for a NIC hdl */
2682 result_from_RIPupd = send_object_db(obj_with_AUTO_NIC_hdl, assigned_NIC, "ADD");
2683 if(result_from_RIPupd == 0){
2684 add_to_ack("\nCreation succeeded", ack_file_name);
2685 add_to_ack(o->type->getName(), ack_file_name);
2686 add_to_ack(assigned_NIC, ack_file_name);
2687 }else{
2688 add_to_ack("\nCreation failed: Referential integrity failure", ack_file_name);
2689 add_to_ack(o->type->getName(), ack_file_name);
2690 add_to_ack(arg, ack_file_name);
2691 }
2692 result_from_RIPupd = 0;
2693 if(tracing && assigned_NIC != NULL) {
2694 printf("TRACING: send_object_db returned [%s] as assigned NIC hdl\n", assigned_NIC);
2695 }
2696 if(assigned_NIC != NULL){
2697 printf("DEBUG: auto_nic=[%s], assigned_NIC=[%s]\n", auto_nic, assigned_NIC);
2698 g_hash_table_insert(NIC_hdl_hash, auto_nic, assigned_NIC);
2699 printf("DEBUG: NIC_hdl_hash has %i pairs\n",g_hash_table_size(NIC_hdl_hash));
2700 }
2701
2702 }else{
2703 // auth failed !
2704 if(tracing) {
2705 printf("TRACING: Auth failed\n");
2706 }
2707 if(error_msg != NULL){
2708 cout << error_msg << endl;
2709 }
2710 ER_perror(0, result, "");
2711 add_to_ack("\nCreation failed: Auth failed", ack_file_name);
2712 add_to_ack(o->type->getName(), ack_file_name);
2713 add_to_ack(get_search_key(o, o->type->getName(), arg), ack_file_name);
2714 return UP_AUF; /* Auth failed */
2715 }
2716 }
2717 else{
2718 old_version = get_old_version(arg);
2719 if(old_version != NULL){/* so, this is an update operation */
2720 result = check_auth(arg, old_version, o->type->getName(), credentials);
2721 if(result == UP_AUTH_OK){
2722 if(tracing) {
2723 printf("TRACING: Will send the obj to be updated\n");
2724 }
2725 result_from_RIPupd = send_object_db(arg, NULL, "UPD");
2726 if(result_from_RIPupd == 0){
2727 add_to_ack("\nUpdate succeeded", ack_file_name);
2728 add_to_ack(o->type->getName(), ack_file_name);
2729 add_to_ack(get_search_key(o, o->type->getName(), arg), ack_file_name);
2730 }else{
2731 add_to_ack("\nUpdate failed: Referential integrity failure", ack_file_name);
2732 add_to_ack(o->type->getName(), ack_file_name);
2733 add_to_ack(get_search_key(o, o->type->getName(), arg), ack_file_name);
2734 }
2735 result_from_RIPupd = 0;
2736 }else{
2737 // auth failed !
2738 if(tracing) {
2739 printf("TRACING: Auth failed\n");
2740 }
2741 if(error_msg != NULL){
2742 cout << error_msg << endl;
2743 }
2744 add_to_ack("\nUpdate failed: Auth failed", ack_file_name);
2745 add_to_ack(o->type->getName(), ack_file_name);
2746 add_to_ack(get_search_key(o, o->type->getName(), arg), ack_file_name);
2747 return UP_AUF; /* Auth failed */
2748 }
2749 }else { /* old_version == NULL, so, creation */
2750 result = check_auth(arg, NULL, o->type->getName(), credentials);
2751 if(result == UP_AUTH_OK){
2752 if(tracing) {
2753 printf("TRACING: Will send the obj to be added\n");
2754 }
2755 result_from_RIPupd = send_object_db(arg, NULL, "ADD");
2756 if(result_from_RIPupd == 0){
2757 add_to_ack("\nCreation succeeded", ack_file_name);
2758 add_to_ack(o->type->getName(), ack_file_name);
2759 add_to_ack(get_search_key(o, o->type->getName(), arg), ack_file_name);
2760 }else{
2761 add_to_ack("\nCreation failed: Referential integrity failure", ack_file_name);
2762 add_to_ack(o->type->getName(), ack_file_name);
2763 add_to_ack(get_search_key(o, o->type->getName(), arg), ack_file_name);
2764 }
2765 result_from_RIPupd = 0;
2766 }else{
2767 // auth failed !
2768 if(tracing) {
2769 printf("TRACING: Auth failed\n");
2770 }
2771 if(error_msg != NULL){
2772 cout << error_msg << endl;
2773 }
2774 ER_perror(0, result, "");
2775 add_to_ack("\nCreation failed: Auth failed", ack_file_name);
2776 add_to_ack(o->type->getName(), ack_file_name);
2777 add_to_ack(get_search_key(o, o->type->getName(), arg), ack_file_name);
2778 return UP_AUF; /* Auth failed */
2779 }
2780 }
2781 }
2782 }
2783 }else{// even if obj doesn't parse properly, it may be a legacy object
2784 // which the user wants to delete...
2785 printf("DEBUG: Object didn't parse\n");
2786 add_to_ack("\nFailed: Syntax error in object", ack_file_name);
2787 add_to_ack(arg, ack_file_name);
2788 //for(attr = o->attrs.head(); attr; attr = o->attrs.next(attr)){
2789 // value = (char*)malloc((*attr).len );
2790 // strncpy(value, (char *)(arg+attr->offset) ,
2791 // attr->len - 1);
2792 // value[attr->len - 1] = '\0';
2793 // add_to_ack(value, ack_file_name);
2794 // if(!attr->errors.empty()){
2795 // add_to_ack_string(attr->errors, ack_file_name);
2796 // }
2797 // free(value);
2798 // }
2799 // if(o->has_error){
2800 // add_to_ack_string(o->errors, ack_file_name);
2801 // }
2802
2803 return UP_NIY; /* Not implemented yet */
2804 }
2805 }
2806
2807
2808
2809
2810 /* Gets the "From" line of the incoming mail message and finds out an
2811 address to send the acknowledgement */
2812 char * find_to_address(const char * from_line){
/* [<][>][^][v][top][bottom][index][help] */
2813 char * pos1 = NULL, * pos2 = NULL;
2814 char * temp = NULL;
2815
2816 if(from_line == NULL){
2817 return NULL;
2818 }
2819 if(strstr(from_line, "From:") != from_line){/* there is a problem, the line must start with
2820 "From:" */
2821 fprintf(stderr, "The line doesn't start with 'From:'\n");
2822 return NULL;
2823 }
2824 temp = strdup(from_line + strlen("From:"));
2825 g_strstrip(temp);
2826 if(index(temp, '<')){/* then the line is something like '"John White" <john@inter.net>' */
2827 pos1 = index(temp, '<');
2828 pos2 = index(temp, '>');
2829 temp = strncpy(temp, pos1 + 1, pos2 - pos1 -1);
2830 temp[pos2 - pos1 - 1] = '\0';
2831 printf("DEBUG: find_to_address\n");
2832 printf("DEBUG: find_to_address temp=[%s]\n", temp);
2833 return temp;
2834 }else{/* the line contains only the address, then */
2835 return temp;
2836 }
2837 }
2838