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