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