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