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