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