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