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.29 $
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->pgp_struct must be assigned, not yet implemented */
1280 temp->auth = argument;
1281 list_of_auth_struct = g_slist_append(list_of_auth_struct, temp);
1282 cout << "Not implemented totally (PGP)" << endl;
1283 }else{
1284 cout << "DEBUG: Error: invalid auth attrib: " << auth_attrib << endl;
1285 return NULL;
1286 }
1287 }
1288 free(auth_attrib_uppercase);
1289 free(auth_attrib);
1290 return list_of_auth_struct;
1291
1292 }
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302 /* Gets a list of mntner names, retrieves those mntners from
1303 the database and extracts the 'auth' attributes, and
1304 constructs the authorisation vector, which is a GSList of
1305 struct auth_struct */
1306
1307 GSList * get_auth_vector(GSList * mntners){
/* [<][>][^][v][top][bottom][index][help] */
1308 GSList * list_of_auths = NULL;
1309 GSList * next = NULL;
1310 GSList * to_be_returned = NULL;
1311 char * query_string = NULL, * result = NULL, * object = NULL;
1312 GSList * temp;
1313
1314 for( next = mntners; next != NULL ; next = g_slist_next(next) ){
1315 if(tracing) {
1316 cout << "=====" << endl << "Got a mntner" << endl;
1317 cout << (char *)next->data << endl;
1318 }
1319 query_string = (char *)malloc(strlen("-Tmntner -r ")+strlen((char *)next->data)+1);
1320 sprintf(query_string, "-Tmntner -r %s",(char *)next->data);
1321 result = send_and_get(QUERY_HOST, QUERY_PORT, query_string);
1322 if(count_objects(result) == 0){
1323 //if(tracing) {
1324 // cout << "No such maintainer, exiting" << endl;
1325 //}
1326 //exit(1);
1327 /* no such maintainer */
1328 return NULL;
1329 }else if(count_objects(result) > 1){
1330 if(tracing) {
1331 cout << "More than one objects returned" << endl;
1332 }
1333 }else{ /* count_objects(result) == 1 */
1334 object = take_object(result);
1335 if(tracing) {
1336 printf("TRACING: get_auth_vector: Calling get_auths(char *)\n");
1337 }
1338 temp = get_auths(object);
1339 if(tracing) {
1340 cout << "TRACING: get_auth_vector: get_auths(char *) returned (with " << g_slist_length(temp) << " nodes)" << endl;
1341 }
1342 list_of_auths = g_slist_concat(list_of_auths, temp);
1343 if(tracing) {
1344 cout << "TRACING: get_auth_vector: list_of_auths has now " << g_slist_length(list_of_auths) << " nodes" << endl;
1345 }
1346 /* add this to the auth_vector. ( next->data is the name of the maintainer ) */
1347 if(tracing) {
1348 cout << "TRACING: get_auth_vector: to_be_returned has now " << g_slist_length(to_be_returned) << " nodes" << endl;
1349 }
1350 to_be_returned = add_to_auth_vector(to_be_returned, list_of_auths, (char *)next->data);
1351 }
1352 }
1353
1354 if(tracing) {
1355 printf("TRACING: get_auth_vector: to_be_returned has %i nodes\n", g_slist_length(to_be_returned));
1356 }
1357 return to_be_returned;
1358 }
1359
1360
1361
1362
1363
1364
1365
1366 /* Gets a list of mntner names, retrieves those mntners from
1367 the database and extracts the 'mnt-by' attributes, and
1368 returns them as a GSList */
1369
1370 GSList * get_mntnfy_vector(GSList * mntners){
/* [<][>][^][v][top][bottom][index][help] */
1371 GSList * list_of_mntnfy = NULL;
1372 GSList * next = NULL;
1373 //GSList * to_be_returned = NULL;
1374 char * query_string = NULL, * result = NULL, * object = NULL;
1375 GSList * temp;
1376
1377 for( next = mntners; next != NULL ; next = g_slist_next(next) ){
1378 if(tracing) {
1379 cout << "=====" << endl << "Got a mntner" << endl;
1380 cout << (char *)next->data << endl;
1381 }
1382 query_string = (char *)malloc(strlen("-Tmntner -r ")+strlen((char *)next->data)+1);
1383 sprintf(query_string, "-Tmntner -r %s",(char *)next->data);
1384 result = send_and_get(QUERY_HOST, QUERY_PORT, query_string);
1385 if(count_objects(result) == 0){
1386 /* no such maintainer */
1387 }else if(count_objects(result) > 1){
1388 if(tracing) {
1389 cout << "More than one objects returned" << endl;
1390 }
1391 }else{ /* count_objects(result) == 1 */
1392 object = take_object(result);
1393 if(tracing) {
1394 printf("TRACING: get_mntnfy_vector: Calling get_attr_list\n");
1395 }
1396 temp = get_attr_list(object, "mnt-nfy");
1397 if(tracing) {
1398 cout << "TRACING: get_mntnfy_vector: get_attr_list returned (with " << g_slist_length(temp) << " nodes)" << endl;
1399 }
1400 list_of_mntnfy = g_slist_concat(list_of_mntnfy, temp);
1401 if(tracing) {
1402 cout << "TRACING: get_mntnfy_vector: list_of_mntnfy has now " << g_slist_length(list_of_mntnfy) << " nodes" << endl;
1403 }
1404 /* add this to the auth_vector. ( next->data is the name of the maintainer ) */
1405 //if(tracing) {
1406 // cout << "TRACING: get_mntnfy_vector: to_be_returned has now " << g_slist_length(to_be_returned) << " nodes" << endl;
1407 //}
1408 //to_be_returned = add_to_auth_vector(to_be_returned, list_of_mntnfy, (char *)next->data);
1409 }
1410 }
1411
1412 if(tracing) {
1413 printf("TRACING: get_auth_vector: list_of_mntnfy has %i nodes\n", g_slist_length(list_of_mntnfy));
1414 }
1415 return list_of_mntnfy;
1416 }
1417
1418
1419
1420
1421
1422
1423 /* Gets a list of mntner names, retrieves those mntners from
1424 the database and extracts the 'upd-to' attributes, and
1425 returns them as a GSList */
1426
1427 GSList * get_updto_vector(GSList * mntners){
/* [<][>][^][v][top][bottom][index][help] */
1428 GSList * list_of_updto = NULL;
1429 GSList * next = NULL;
1430 //GSList * to_be_returned = NULL;
1431 char * query_string = NULL, * result = NULL, * object = NULL;
1432 GSList * temp;
1433
1434 for( next = mntners; next != NULL ; next = g_slist_next(next) ){
1435 if(tracing) {
1436 cout << "=====" << endl << "Got a mntner" << endl;
1437 cout << (char *)next->data << endl;
1438 }
1439 query_string = (char *)malloc(strlen("-Tmntner -r ")+strlen((char *)next->data)+1);
1440 sprintf(query_string, "-Tmntner -r %s",(char *)next->data);
1441 result = send_and_get(QUERY_HOST, QUERY_PORT, query_string);
1442 if(count_objects(result) == 0){
1443 /* no such maintainer */
1444 }else if(count_objects(result) > 1){
1445 if(tracing) {
1446 cout << "More than one objects returned" << endl;
1447 }
1448 }else{ /* count_objects(result) == 1 */
1449 object = take_object(result);
1450 if(tracing) {
1451 printf("TRACING: get_mntnfy_vector: Calling get_attr_list\n");
1452 }
1453 temp = get_attr_list(object, "upd-to");
1454 if(tracing) {
1455 cout << "TRACING: get_updto_vector: get_attr_list returned (with " << g_slist_length(temp) << " nodes)" << endl;
1456 }
1457 list_of_updto = g_slist_concat(list_of_updto, temp);
1458 if(tracing) {
1459 cout << "TRACING: get_updto_vector: list_of_mntnfy has now " << g_slist_length(list_of_updto) << " nodes" << endl;
1460 }
1461 /* add this to the auth_vector. ( next->data is the name of the maintainer ) */
1462 //if(tracing) {
1463 // cout << "TRACING: get_mntnfy_vector: to_be_returned has now " << g_slist_length(to_be_returned) << " nodes" << endl;
1464 //}
1465 //to_be_returned = add_to_auth_vector(to_be_returned, list_of_mntnfy, (char *)next->data);
1466 }
1467 }
1468
1469 if(tracing) {
1470 printf("TRACING: get_updto_vector: list_of_updto has %i nodes\n", g_slist_length(list_of_updto));
1471 }
1472 return list_of_updto;
1473 }
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484 /* gets one or more route objects filters out the ones which don't have the same
1485 origin as 'char * origin' argument */
1486 char * filter_out_diff_origins(char * objects, char * origin){
/* [<][>][^][v][top][bottom][index][help] */
1487 GSList * object_list = NULL, * next =NULL;
1488 char * objects_to_be_returned = NULL;
1489 bool code;
1490 char * key = NULL;
1491 Object * o = new Object();
1492
1493
1494 if(tracing) {
1495 printf("TRACING: filter_out_diff_origins\n");
1496 }
1497
1498 /* strip the lines beginning with '%' off */
1499 objects = strip_lines(objects);
1500
1501 /* separate the objects, store them in a linked list */
1502 object_list = take_objects(objects);
1503
1504 for(next = object_list; next != NULL; next = g_slist_next(next)){
1505 code = o->scan((char *)next->data, strlen((char *)next->data));
1506 key = get_search_key(o, "origin", (char *)next->data);
1507 if(key != NULL && strcasecmp(g_strstrip(origin), key) == 0){
1508 if(objects_to_be_returned == NULL){
1509 objects_to_be_returned = strdup((char *)next->data);
1510 }else{
1511 objects_to_be_returned = (char *)realloc(objects_to_be_returned,
1512 strlen(objects_to_be_returned) + strlen((char *)next->data) + 2);
1513 objects_to_be_returned = strcat(objects_to_be_returned, "\n");
1514 objects_to_be_returned = strcat(objects_to_be_returned, (char *)next->data);
1515 }
1516 }
1517 }
1518
1519 delete(o);
1520 if(tracing) {
1521 if(objects_to_be_returned != NULL){
1522 printf("TRACING: filter_out_diff_origins: returning:\n%s\n", objects_to_be_returned? "(NULL)":objects_to_be_returned);
1523 }else {
1524 printf("TRACING: filter_out_diff_origins: returning NULL\n");
1525
1526 }
1527 }
1528 return objects_to_be_returned;
1529
1530 }
1531
1532
1533
1534
1535 /* Check authorisation
1536 Applies authorisation rules according to the object type
1537
1538 Arguments:
1539 char *new_object: the new object,
1540 char *old_object: the old object, as found in the database,
1541 char *type: type of the object
1542 credentials_struct credentials: a struct which
1543 contains credentials of the update, such as 'From:' field of
1544 the e-mail header and passwords in the update */
1545
1546 int check_auth(char *new_object, char *old_object, char *type, credentials_struct credentials){
/* [<][>][^][v][top][bottom][index][help] */
1547
1548 GSList *old_mntners = NULL, *new_mntners = NULL;
1549 GSList *old_auths = NULL, *new_auths = NULL;
1550 GSList *as_block_mnt_lowers = NULL;
1551 GSList *old_auth_vector = NULL, *new_auth_vector = NULL, *as_block_auth_vector = NULL;
1552 GSList *less_specific_auth_vector = NULL, *less_specific_mnt_lowers = NULL;
1553 GSList *less_specific_mntners = NULL;
1554 GSList *aut_num_maintainers = NULL;
1555 GSList *aut_num_auth_vector = NULL;
1556 GSList *exact_match_routes = NULL;
1557 GSList *exact_match_routes_maintainers = NULL;
1558 GSList *exact_match_routes_auth_vector = NULL;
1559 GSList *less_spec_routes = NULL;
1560 GSList *less_spec_routes_mntners = NULL;
1561 GSList *less_spec_routes_auth_vector = NULL;
1562 GSList *exact_match_inetnum_mnt_routes = NULL;
1563 GSList *exact_match_inetnum_auth_vector = NULL;
1564 GSList *less_spec_inetnum_mntners = NULL;
1565 GSList *less_spec_inetnum_auth_vector = NULL;
1566 GSList *exact_match_intenum_auth_vector = NULL;
1567 GSList *exact_match_auth_vector = NULL;
1568
1569 char *as_block_object = NULL, *less_specific_object = NULL;
1570 char *less_specific_domain = NULL;
1571 char *less_spec_inetnum = NULL;
1572 char *exact_match_inetnum = NULL;
1573 char *less_specific_object_type = NULL;
1574 char *override_string = NULL;
1575 char *set_name = NULL;
1576 char * aut_num_object = NULL;
1577 Object *set_object = new Object();
1578 Object *temp_obj;
1579 bool code;
1580 bool aut_num_auth_OK = false;
1581
1582 int overriden = 0;
1583
1584 /* first check if it is overriden or not. if overriden, check the override
1585 password. If it is correct, continue, setting "overriden" to 1. If not,
1586 immediately exit returning ERR_UP_OVF */
1587 override_string = get_override((new_object == NULL) ? old_object : new_object );
1588 if(override_string == NULL){
1589 overriden = 0;
1590 }else if(check_override(override_string) == OVR_OK){
1591 overriden = 1; /* authorisation is overriden */
1592 }else if(check_override(override_string) == UP_OVS){
1593 return UP_OVS; /* override syntax error --it must have at least two words */
1594 }else{
1595 return UP_OVF; /* override failed! */
1596 }
1597
1598
1599 /*
1600 * Handle the "person", "role", "limerick", "inet-rtr" types
1601 */
1602 if(strcmp(type,"person") == 0 || strcmp(type,"role") == 0 ||
1603 strcmp(type,"limerick") == 0 || strcmp(type,"inet-rtr") == 0 ){
1604 if( new_object == NULL && old_object != NULL ){ /* the object is to be deleted */
1605 old_mntners = get_mntners(old_object);
1606 old_auth_vector = get_auth_vector(old_mntners);
1607 return authorise(old_auth_vector, credentials, overriden);
1608 }else if( new_object != NULL && old_object == NULL ){ /* the object is to be created */
1609 new_mntners = get_mntners(new_object);
1610 new_auth_vector = get_auth_vector(new_mntners);
1611 if(new_mntners != NULL && new_auth_vector == NULL){
1612 /* then, the mntners in 'new_mntners' do not exist. Problem. */
1613 return UP_AUF; /* auth failed */
1614 }
1615 /*printf("DEBUG: check_auth: new_auth_vector has %i, new_mntners has %i nodes\n",
1616 g_slist_length(new_auth_vector) ,g_slist_length(new_mntners));*/
1617 return authorise(new_auth_vector, credentials, overriden);
1618 }else if( new_object != NULL && old_object != NULL ){ /* this is an update */
1619 old_mntners = get_mntners(old_object);
1620 old_auth_vector = get_auth_vector(old_mntners);
1621 if(old_mntners != NULL && old_auth_vector == NULL){
1622 /* then, the mntners in 'old_mntners' do not exist. Problem. */
1623 return UP_AUF; /* auth failed */
1624 }
1625 if(old_auth_vector){ /* if we have mntners in the old object, use them */
1626 return authorise(old_auth_vector, credentials, overriden);
1627 }else{
1628 new_mntners = get_mntners(new_object);
1629 new_auth_vector = get_auth_vector(new_mntners);
1630 if(new_mntners != NULL && new_auth_vector == NULL){
1631 /* then, the mntners in 'new_mntners' do not exist. Problem. */
1632 return UP_AUF; /* auth failed */
1633 }
1634 return authorise(new_auth_vector, credentials, overriden);
1635 }
1636 }else{ // both are NULL, mustn't happen
1637 cout << "DEBUG: check_auth: internal error: Both pointers are NULL" << endl;
1638 return UP_INT; /* internal error */
1639 }
1640 }
1641
1642 /*
1643 * Handle the "auth-num" type
1644 */
1645 else if(strcmp(type,"aut-num") == 0 ){
1646 if( new_object == NULL && old_object != NULL ){ /* the object is to be deleted */
1647 old_mntners = get_mntners(old_object);
1648 old_auth_vector = get_auth_vector(old_mntners);
1649 if(old_mntners != NULL && old_auth_vector == NULL){
1650 /* then, the mntners in 'old_mntners' do not exist. Problem. */
1651 return UP_AUF; /* auth failed */
1652 }
1653 return authorise(old_auth_vector, credentials, overriden);
1654 }else if( new_object != NULL && old_object == NULL ){ /* the object is to be created */
1655 as_block_object = get_as_block(new_object);
1656 if(as_block_object == NULL ){
1657 return UP_ABN; /* As-block does not exist */
1658 }else{
1659 as_block_mnt_lowers = get_mnt_lowers(as_block_object);
1660 as_block_auth_vector = get_auth_vector(as_block_mnt_lowers);
1661 if(as_block_mnt_lowers != NULL && as_block_auth_vector == NULL){
1662 /* then, the mntners in 'as_block_mnt_lowers' do not exist. Problem. */
1663 return UP_AUF; /* auth failed */
1664 }
1665 if(authorise(as_block_auth_vector, credentials, overriden) == UP_AUTH_OK ){
1666 new_mntners = get_mntners(new_object);
1667 new_auth_vector = get_auth_vector(new_mntners);
1668 if(new_mntners != NULL && new_auth_vector == NULL){
1669 /* then, the mntners in 'new_auth_vector' do not exist. Problem. */
1670 return UP_AUF; /* auth failed */
1671 }
1672 return authorise(new_auth_vector, credentials, overriden);
1673 }else{
1674 return UP_HOF; /* hierarchical auth failed */
1675 }
1676 }
1677 }else if( new_object != NULL && old_object != NULL ){ /* this is an update */
1678 old_mntners = get_mntners(old_object);
1679 old_auth_vector = get_auth_vector(old_mntners);
1680 if(old_mntners != NULL && old_auth_vector == NULL){
1681 /* then, the mntners in 'old_mntners' do not exist. Problem. */
1682 return UP_AUF; /* auth failed */
1683 }
1684 if(old_auth_vector){ /* if we have mntners in the old object, use them */
1685 return authorise(old_auth_vector, credentials, overriden);
1686 }else{
1687 new_mntners = get_mntners(new_object);
1688 new_auth_vector = get_auth_vector(new_mntners);
1689 if(new_mntners != NULL && new_auth_vector == NULL){
1690 /* then, the mntners in 'new_mntners' do not exist. Problem. */
1691 return UP_AUF; /* auth failed */
1692 }
1693 return authorise(new_auth_vector, credentials, overriden);
1694 }
1695 }else{ /* both are NULL, mustn't happen */
1696 if(tracing) {
1697 cout << "TRACING: check_auth: internal error: Both pointers are NULL" << endl;
1698 }
1699 return UP_INT; /* internal error */
1700 }
1701 }
1702
1703 /*
1704 * Handle the "mntner/as-block" types
1705 */
1706 else if(strcmp(type,"mntner") == 0 || strcmp(type,"as-block") == 0 ){
1707 if( new_object == NULL && old_object != NULL ){ /* the object is to be deleted */
1708 old_mntners = get_mntners(old_object);
1709 old_auth_vector = get_auth_vector(old_mntners);
1710 if(old_mntners != NULL && old_auth_vector == NULL){
1711 /* then, the mntners in 'old_mntners' do not exist. Problem. */
1712 return UP_AUF; /* auth failed */
1713 }
1714 return authorise(old_auth_vector, credentials, overriden);
1715 }else if( new_object != NULL && old_object == NULL ){ /* the object is to be created */
1716 if(overriden || test_mode){
1717 return UP_AUTH_OK;
1718 }else{/* If not overriden, and if not coming from ripe-dbm, must be forwarded to ripe-dbm */
1719 if(tracing) {
1720 cout << "DEBUG: check_auth: '" << type << "' creation requested" << endl;
1721 }
1722 return UP_AUF; /* authorisation failed */
1723 }
1724 }else if( new_object != NULL && old_object != NULL ){ /* this is an update */
1725 old_mntners = get_mntners(old_object);
1726 old_auth_vector = get_auth_vector(old_mntners);
1727 if(old_mntners != NULL && old_auth_vector == NULL){
1728 /* then, the mntners in 'old_mntners' do not exist. Problem. */
1729 return UP_AUF; /* auth failed */
1730 }
1731 if(old_auth_vector){ /* if we have mntners in the old object, use them */
1732 return authorise(old_auth_vector, credentials, overriden);
1733 }else{
1734 new_mntners = get_mntners(new_object);
1735 new_auth_vector = get_auth_vector(new_mntners);
1736 if(new_mntners != NULL && new_auth_vector == NULL){
1737 /* then, the mntners in 'new_mntners' do not exist. Problem. */
1738 return UP_AUF; /* auth failed */
1739 }
1740 return authorise(new_auth_vector, credentials, overriden);
1741 }
1742 }else{ // both are NULL, mustn't happen
1743 cout << "DEBUG: check_auth: internal error: Both pointers are NULL" << endl;
1744 return UP_INT; /* internal error */
1745 }
1746 }
1747
1748 /*
1749 * Handle the "inetnum/inet6num" types
1750 */
1751 else if(strcmp(type,"inetnum") == 0 || strcmp(type,"inet6num") == 0 ){
1752 if( new_object == NULL && old_object != NULL ){ /* the object is to be deleted */
1753 old_mntners = get_mntners(old_object);
1754 old_auth_vector = get_auth_vector(old_mntners);
1755 if(old_mntners != NULL && old_auth_vector == NULL){
1756 /* then, the mntners in 'old_mntners' do not exist. Problem. */
1757 return UP_AUF; /* auth failed */
1758 }
1759 return authorise(old_auth_vector, credentials, overriden);
1760 }else if( new_object != NULL && old_object == NULL ){ /* the object is to be created */
1761 less_specific_object = get_less_specific(new_object, type);
1762 if(less_specific_object == NULL){
1763 if(overriden){
1764 return UP_AUTH_OK;
1765 }else{
1766 return UP_HOF; /* hierarchical authorisation failed */
1767 }
1768 }else{ /* if we got an inet(6)num object */
1769 less_specific_mnt_lowers = get_mnt_lowers(less_specific_object);
1770 less_specific_auth_vector = get_auth_vector(less_specific_mnt_lowers);
1771 if(less_specific_mnt_lowers != NULL && less_specific_auth_vector == NULL){
1772 /* then, the mntners in 'less_specific_mnt_lowers' do not exist. Problem. */
1773 return UP_AUF; /* auth failed */
1774 }
1775 if(authorise(less_specific_auth_vector, credentials, overriden) == UP_AUTH_OK){
1776 new_mntners = get_mntners(new_object);
1777 new_auth_vector = get_auth_vector(new_mntners);
1778 if(new_mntners != NULL && new_auth_vector == NULL){
1779 /* then, the mntners in 'new_mntners' do not exist. Problem. */
1780 return UP_AUF; /* auth failed */
1781 }
1782 return authorise(new_auth_vector, credentials, overriden);
1783 }else{
1784 return UP_HOF; /* hierarchical authorisation failed */
1785 }
1786 }
1787 }else if( new_object != NULL && old_object != NULL ){ /* this is an update */
1788 old_mntners = get_mntners(old_object);
1789 old_auth_vector = get_auth_vector(old_mntners);
1790 if(old_mntners != NULL && old_auth_vector == NULL){
1791 /* then, the mntners in 'old_mntners' do not exist. Problem. */
1792 return UP_AUF; /* auth failed */
1793 }
1794 if(old_auth_vector){ /* if we have mntners in the old object, use them */
1795 return authorise(old_auth_vector, credentials, overriden);
1796 }else{
1797 new_mntners = get_mntners(new_object);
1798 new_auth_vector = get_auth_vector(new_mntners);
1799 if(new_mntners != NULL && new_auth_vector == NULL){
1800 /* then, the mntners in 'new_mntners' do not exist. Problem. */
1801 return UP_AUF; /* auth failed */
1802 }
1803 return authorise(new_auth_vector, credentials, overriden);
1804 }
1805 }else{ /* both are NULL, mustn't happen */
1806 cout << "DEBUG: check_auth: internal error: Both pointers are NULL" << endl;
1807 return UP_INT; /* internal error */
1808 }
1809 }
1810
1811
1812
1813 /*
1814 * Handle the "domain" type
1815 */
1816 else if(strcmp(type,"domain") == 0){
1817 if( new_object == NULL && old_object != NULL ){ /* the object is to be deleted */
1818 old_mntners = get_mntners(old_object);
1819 old_auth_vector = get_auth_vector(old_mntners);
1820 if(old_mntners != NULL && old_auth_vector == NULL){
1821 /* then, the mntners in 'old_mntners' do not exist. Problem. */
1822 return UP_AUF; /* auth failed */
1823 }
1824 return authorise(old_auth_vector, credentials, overriden);
1825 }else if( new_object != NULL && old_object == NULL ){ /* the object is to be created */
1826 /* now, we have to find a 'less specific domain object' for this.
1827 If there is no less specific object, then creation is possible
1828 only with overriding. */
1829 less_specific_domain = get_less_specific_domain(new_object);
1830 if(less_specific_domain == NULL){
1831 if(overriden){/* we didn't get a 'less specific' domain object */
1832 return UP_AUTH_OK;
1833 }else{
1834 return UP_HOF; /* hierarchical authorisation failed */
1835 }
1836 }else{ /* we get a 'less specific' domain object */
1837 less_specific_mnt_lowers = get_mnt_lowers(less_specific_domain);
1838 less_specific_auth_vector = get_auth_vector(less_specific_mnt_lowers);
1839 if(less_specific_mnt_lowers != NULL && less_specific_auth_vector == NULL){
1840 /* then, the mntners in 'less_specific_mnt_lowers' do not exist. Problem. */
1841 return UP_AUF; /* auth failed */
1842 }
1843 if(authorise(less_specific_auth_vector, credentials, overriden) == UP_AUTH_OK){
1844 new_mntners = get_mntners(new_object);
1845 new_auth_vector = get_auth_vector(new_mntners);
1846 if(new_mntners != NULL && new_auth_vector == NULL){
1847 /* then, the mntners in 'new_mntners' do not exist. Problem. */
1848 return UP_AUF; /* auth failed */
1849 }
1850 return authorise(new_auth_vector, credentials, overriden);
1851 }else{
1852 return UP_HOF; /* hierarchical authorisation failed */
1853 }
1854
1855 }
1856 }else if( new_object != NULL && old_object != NULL ){ /* this is an update */
1857 old_mntners = get_mntners(old_object);
1858 old_auth_vector = get_auth_vector(old_mntners);
1859 if(old_mntners != NULL && old_auth_vector == NULL){
1860 /* then, the mntners in 'old_mntners' do not exist. Problem. */
1861 return UP_AUF; /* auth failed */
1862 }
1863 if(old_auth_vector){ /* if we have mntners in the old object, use them */
1864 return authorise(old_auth_vector, credentials, overriden);
1865 }else{
1866 new_mntners = get_mntners(new_object);
1867 new_auth_vector = get_auth_vector(new_mntners);
1868 if(new_mntners != NULL && new_auth_vector == NULL){
1869 /* then, the mntners in 'new_mntners' do not exist. Problem. */
1870 return UP_AUF; /* auth failed */
1871 }
1872 return authorise(new_auth_vector, credentials, overriden);
1873 }
1874 }else{ /* both are NULL, mustn't happen */
1875 cout << "DEBUG: check_auth: internal error: Both pointers are NULL" << endl;
1876 return UP_INT; /* internal error */
1877 }
1878 }
1879
1880
1881 /*
1882 * Handle the "route" type
1883 */
1884 else if(strcmp(type,"route") == 0){
1885 if( new_object == NULL && old_object != NULL ){ /* the object is to be deleted */
1886 old_mntners = get_mntners(old_object);
1887 old_auth_vector = get_auth_vector(old_mntners);
1888 if(old_mntners != NULL && old_auth_vector == NULL){
1889 /* then, the mntners in 'old_mntners' do not exist. Problem. */
1890 return UP_AUF; /* auth failed */
1891 }
1892 return authorise(old_auth_vector, credentials, overriden);
1893 }else if( new_object != NULL && old_object == NULL ){ /* the object is to be created */
1894 /* first we have to find the aut-num object mentioned in the
1895 origin attribute */
1896
1897 aut_num_object = get_aut_num_object(new_object);
1898 if(aut_num_object == NULL){
1899 if(overriden){
1900 return UP_AUTH_OK;
1901 }else{
1902 return UP_HOF; /* hierarchical authorisation failed */
1903 }
1904 }else{/* there is a corresponding aut-num in the db */
1905 printf("DEBUG: check_auth: will try to authorise the route using aut-num\n");
1906 aut_num_maintainers = get_mnt_routes(aut_num_object);
1907 if(aut_num_maintainers != NULL){
1908 aut_num_auth_vector = get_auth_vector(aut_num_maintainers);
1909 if(authorise(aut_num_auth_vector, credentials, overriden) == UP_AUTH_OK){
1910 aut_num_auth_OK = true;
1911 }else{/* authorise(aut_num_auth_vector, credentials, overriden) != UP_AUTH_OK */
1912 return UP_HOF;
1913 }
1914 }else{/* aut_num_maintainers is NULL */
1915 aut_num_maintainers = get_mnt_lowers(aut_num_object);
1916 if(aut_num_maintainers != NULL){
1917 aut_num_auth_vector = get_auth_vector(aut_num_maintainers);
1918 if(authorise(aut_num_auth_vector, credentials, overriden) == UP_AUTH_OK){
1919 aut_num_auth_OK = TRUE;
1920 }else{/* authorise(aut_num_auth_vector, credentials, overriden) != UP_AUTH_OK */
1921 return UP_HOF; /* hierarchical authorisation failed */
1922 }
1923 }else{/* aut_num_maintainers is NULL */
1924 aut_num_maintainers = get_mntners(aut_num_object);
1925 if(aut_num_maintainers != NULL){
1926 aut_num_auth_vector = get_auth_vector(aut_num_maintainers);
1927 if(authorise(aut_num_auth_vector, credentials, overriden) == UP_AUTH_OK){
1928 aut_num_auth_OK = TRUE;
1929 }else{/* authorise(aut_num_auth_vector, credentials, overriden) != UP_AUTH_OK */
1930 return UP_HOF; /* hierarchical authorisation failed */
1931 }
1932 }else{/* aut_num_maintainers is NULL */
1933 aut_num_auth_OK = TRUE;
1934 }
1935
1936 }
1937 }
1938 if(aut_num_auth_OK){
1939 /* now, we have to find an exact match for this route object.
1940 If there is no exact match object, then we will go on to find
1941 less specific. */
1942 exact_match_routes = get_exact_match_routes(new_object);
1943 if(exact_match_routes != NULL){
1944 exact_match_routes_maintainers = get_mnt_routes_from_list(exact_match_routes);
1945 exact_match_routes_auth_vector = get_auth_vector(exact_match_routes_maintainers);
1946 if(exact_match_routes_maintainers != NULL && exact_match_routes_auth_vector == NULL){
1947 /* then, the mntners in 'exact_match_routes_maintainers' do not exist. Problem. */
1948 return UP_AUF; /* auth failed */
1949 }
1950 if(authorise(exact_match_routes_auth_vector, credentials, overriden) == UP_AUTH_OK){
1951 /* then, check mnt_bys of the route itself */
1952 new_mntners = get_mntners(new_object);
1953 new_auth_vector = get_auth_vector(new_mntners);
1954 if(new_mntners != NULL && new_auth_vector == NULL){
1955 /* then, the mntners in 'new_mntners' do not exist. Problem. */
1956 return UP_AUF; /* auth failed */
1957 }
1958 return authorise(new_auth_vector, credentials, overriden);
1959 }else{/*authorise(exact_match_routes_auth_vector, credentials, overriden) != UP_AUTH_OK*/
1960 return UP_HOF; /* hierarchical authorisation failed */
1961 }
1962 }else{ /* exact_match_routes == NULL */
1963 /* then we have to look for less specific route objs */
1964 less_spec_routes = get_less_spec_routes(new_object);
1965 if(less_spec_routes != NULL){
1966 less_spec_routes_mntners = get_mnt_routes_from_list(less_spec_routes);
1967 less_spec_routes_mntners = g_slist_concat(less_spec_routes_mntners,
1968 get_mnt_lowers_from_list(less_spec_routes));
1969 less_spec_routes_auth_vector = get_auth_vector(less_spec_routes_mntners);
1970 if(less_spec_routes_mntners != NULL && less_spec_routes_auth_vector == NULL){
1971 /* then, the mntners in 'less_spec_routes_mntners' do not exist. Problem. */
1972 return UP_AUF; /* auth failed */
1973 }
1974 if(authorise(less_spec_routes_auth_vector, credentials, overriden) == UP_AUTH_OK){
1975 /* then, check mnt_bys of the route itself */
1976 new_mntners = get_mntners(new_object);
1977 new_auth_vector = get_auth_vector(new_mntners);
1978 if(new_mntners != NULL && new_auth_vector == NULL){
1979 /* then, the mntners in 'new_auth_vector' do not exist. Problem. */
1980 return UP_AUF; /* auth failed */
1981 }
1982 return authorise(new_auth_vector, credentials, overriden);
1983 }else{/*authorise(less_spec_routes_auth_vector, credentials, overriden) != UP_AUTH_OK*/
1984 return UP_HOF; /* hierarchical authorisation failed */
1985 }
1986 }else{/* less_spec_routes == NULL */
1987 /* so, we have to get the exact match inetnum */
1988 exact_match_inetnum = get_exact_match_inetnum(new_object);
1989 if(exact_match_inetnum != NULL){
1990 exact_match_inetnum_mnt_routes = get_mnt_routes(exact_match_inetnum);
1991 exact_match_inetnum_auth_vector = get_auth_vector(exact_match_inetnum_mnt_routes);
1992 if(exact_match_inetnum_mnt_routes != NULL && exact_match_inetnum_auth_vector == NULL){
1993 /* then, the mntners in 'exact_match_inetnum_mnt_routes' do not exist. Problem. */
1994 return UP_AUF; /* auth failed */
1995 }
1996 if(authorise(exact_match_intenum_auth_vector, credentials, overriden) == UP_AUTH_OK){
1997 /* then, check mnt_bys of the route itself */
1998 new_mntners = get_mntners(new_object);
1999 new_auth_vector = get_auth_vector(new_mntners);
2000 if(new_mntners != NULL && new_auth_vector == NULL){
2001 /* then, the mntners in 'new_auth_vector' do not exist. Problem. */
2002 return UP_AUF; /* auth failed */
2003 }
2004 return authorise(new_auth_vector, credentials, overriden);
2005 }else{
2006 return UP_HOF; /* hierarchical authorisation failed */
2007 }
2008 }else{/* exact_match_inetnum == NULL */
2009 /* then, we will try to find less spec inetnums */
2010 less_spec_inetnum = get_less_spec_inetnum(new_object);
2011 if(less_spec_inetnum != NULL){
2012 less_spec_inetnum_mntners = get_mnt_routes(less_spec_inetnum);
2013 less_spec_inetnum_mntners = g_slist_concat(less_spec_inetnum_mntners,
2014 get_mnt_lowers(less_spec_inetnum));
2015 less_spec_inetnum_auth_vector = get_auth_vector(less_spec_inetnum_mntners);
2016 if(less_spec_inetnum_mntners != NULL && less_spec_inetnum_auth_vector == NULL){
2017 /* then, the mntners in 'less_spec_inetnum_mntners' do not exist. Problem. */
2018 return UP_AUF; /* auth failed */
2019 }
2020 if(authorise(exact_match_auth_vector, credentials, overriden) == UP_AUTH_OK){
2021 /* then, check mnt_bys of the route itself */
2022 new_mntners = get_mntners(new_object);
2023 new_auth_vector = get_auth_vector(new_mntners);
2024 if(new_mntners != NULL && new_auth_vector == NULL){
2025 /* then, the mntners in 'new_auth_vector' do not exist. Problem. */
2026 return UP_AUF; /* auth failed */
2027 }
2028 return authorise(new_auth_vector, credentials, overriden);
2029 }else{/* authorise(exact_match_auth_vector, credentials, overriden) != UP_AUTH_OK */
2030 return UP_HOF; /* hierarchical authorisation failed */
2031 }
2032 }else{/* less_spec_inetnum == NULL */
2033 /* now that we couldn't find any route or inetnum object
2034 to be used in authentication. So, only if the auth is
2035 overriden the object will be created. */
2036 if(overriden){
2037 return UP_AUTH_OK;
2038 }else{
2039 return UP_HOF; /* hierarchical authorisation failed */
2040 }
2041 }
2042 }
2043 }
2044 }
2045 }else{/* ! aut_num_auth_OK */
2046 return UP_HOF; /* hierarchical auth failed */
2047 }
2048
2049 }
2050
2051 }else if( new_object != NULL && old_object != NULL ){ /* this is an update */
2052 old_mntners = get_mntners(old_object);
2053 old_auth_vector = get_auth_vector(old_mntners);
2054 if(old_mntners != NULL && old_auth_vector == NULL){
2055 /* then, the mntners in 'old_auth_vector' do not exist. Problem. */
2056 return UP_AUF; /* auth failed */
2057 }
2058 if(old_auth_vector){ /* if we have mntners in the old object, use them */
2059 return authorise(old_auth_vector, credentials, overriden);
2060 }else{
2061 new_mntners = get_mntners(new_object);
2062 new_auth_vector = get_auth_vector(new_mntners);
2063 if(new_mntners != NULL && new_auth_vector == NULL){
2064 /* then, the mntners in 'new_auth_vector' do not exist. Problem. */
2065 return UP_AUF; /* auth failed */
2066 }
2067 return authorise(new_auth_vector, credentials, overriden);
2068 }
2069 }else{ /* both are NULL, mustn't happen */
2070 cout << "DEBUG: check_auth: internal error: Both pointers are NULL" << endl;
2071 return UP_INT; /* internal error */
2072 }
2073 }
2074
2075
2076 /*
2077 * Handle the set objects ("as-set","rtr-set", "peering-set", "route-set" and "filter-set" types
2078 */
2079 else if(strcmp(type,"as-set") == 0 || strcmp(type,"rtr-set") == 0 ||
2080 strcmp(type,"peering-set") == 0 || strcmp(type,"filter-set") == 0 ||
2081 strcmp(type,"route-set") == 0 ){
2082 if( new_object == NULL && old_object != NULL ){ /* the object is to be deleted */
2083 old_mntners = get_mntners(old_object);
2084 old_auth_vector = get_auth_vector(old_mntners);
2085 if(old_mntners != NULL && old_auth_vector == NULL){
2086 /* then, the mntners in 'old_auth_vector' do not exist. Problem. */
2087 return UP_AUF; /* auth failed */
2088 }
2089 return authorise(old_auth_vector, credentials, overriden);
2090 }else if( new_object != NULL && old_object == NULL ){ /* the object is to be created */
2091 code = set_object->scan(new_object, strlen(new_object));
2092 set_name = get_search_key(set_object, type, new_object);
2093 if(strstr(set_name,":") == NULL ){/* if the name is _not_ hierarchical */
2094 new_mntners = get_mntners(new_object);
2095 new_auth_vector = get_auth_vector(new_mntners);
2096 if(new_mntners != NULL && new_auth_vector == NULL){
2097 /* then, the mntners in 'new_auth_vector' do not exist. Problem. */
2098 return UP_AUF; /* auth failed */
2099 }
2100 return authorise(new_auth_vector, credentials, overriden);
2101 }else{/* the name is hierarchical */
2102 less_specific_object = get_less_specific_set(new_object, type);
2103 if(less_specific_object != NULL){/* such an object exists */
2104 temp_obj = new Object();
2105 code = temp_obj->scan(less_specific_object, strlen(less_specific_object));
2106 less_specific_object_type = get_type(temp_obj);
2107 delete(temp_obj);
2108 if(strcmp(less_specific_object_type, "aut-num") == 0){/* if this is an aut-num object */
2109 less_specific_mnt_lowers = get_mnt_lowers(less_specific_object);
2110 less_specific_auth_vector = get_auth_vector(less_specific_mnt_lowers);
2111 if(less_specific_mnt_lowers != NULL && less_specific_auth_vector == NULL){
2112 /* then, the mntners in 'less_specific_auth_vector' do not exist. Problem. */
2113 return UP_AUF; /* auth failed */
2114 }
2115 if(less_specific_auth_vector != NULL){
2116 return authorise(less_specific_auth_vector, credentials, overriden);
2117 }else{/* the less specific object doesn't contain any mnt-lower */
2118 less_specific_mntners = get_mntners(less_specific_object);
2119 less_specific_auth_vector = get_auth_vector(less_specific_mntners);
2120 if(less_specific_mntners != NULL && less_specific_auth_vector == NULL){
2121 /* then, the mntners in 'less_specific_mntners' do not exist. Problem. */
2122 return UP_AUF; /* auth failed */
2123 }
2124 if(less_specific_auth_vector != NULL){/* less spec object has some mnt-by attribs,
2125 use them */
2126 return authorise(less_specific_auth_vector, credentials, overriden);
2127 }else{/* the less specific object doesn't contain any mnt-by either */
2128 if(overriden){
2129 return UP_AUTH_OK;
2130 }else{
2131 return UP_HOF; /* hierarchical authorisation failed */
2132 }
2133 }
2134 }
2135 }else{ /* this is _not_ an aut-num object*/
2136 less_specific_mntners = get_mntners(less_specific_object);
2137 less_specific_auth_vector = get_auth_vector(less_specific_mntners);
2138 if(less_specific_mntners != NULL && less_specific_auth_vector == NULL){
2139 /* then, the mntners in 'less_specific_mntners' do not exist. Problem. */
2140 return UP_AUF; /* auth failed */
2141 }
2142 if(less_specific_auth_vector != NULL ){/* the set obj has some mnt-by attribs */
2143 return authorise(less_specific_auth_vector, credentials, overriden);
2144 }else{
2145 if(overriden){
2146 return UP_AUTH_OK;
2147 }else{
2148 return UP_HOF; /* hierarchical authorisation failed */
2149 }
2150 }
2151 }
2152
2153 }else{/* we don't have a less specific of this set object in the DB */
2154 return UP_HOF; /* hierarchical authorisation failed */
2155 }
2156 }
2157 }else if( new_object != NULL && old_object != NULL ){ /* this is an update */
2158 old_mntners = get_mntners(old_object);
2159 old_auth_vector = get_auth_vector(old_mntners);
2160 if(old_mntners != NULL && old_auth_vector == NULL){
2161 /* then, the mntners in 'old_auth_vector' do not exist. Problem. */
2162 return UP_AUF; /* auth failed */
2163 }
2164 if(old_auth_vector){ /* if we have mntners in the old object, use them */
2165 return authorise(old_auth_vector, credentials, overriden);
2166 }else{
2167 new_mntners = get_mntners(new_object);
2168 new_auth_vector = get_auth_vector(new_mntners);
2169 if(new_mntners != NULL && new_auth_vector == NULL){
2170 /* then, the mntners in 'new_mntners' do not exist. Problem. */
2171 return UP_AUF; /* auth failed */
2172 }
2173 return authorise(new_auth_vector, credentials, overriden);
2174 }
2175 }else{ /* both are NULL, mustn't happen */
2176 cout << "DEBUG: check_auth: internal error: Both pointers are NULL" << endl;
2177 return UP_INT; /* internal error */
2178 }
2179
2180
2181
2182
2183
2184 }else{ /* We exhausted all object classes. If we are here, then there is a problem */
2185 cout << "check_auth: This type '" << type << "' is unknown" << endl;
2186 return UP_NIY; /* not implemented yet */
2187 }
2188 return UP_AUF; /* if we come to this point, then auth failed */
2189 }
2190
2191
2192
2193
2194
2195
2196 /* Gets the old version of the given "arg" object, which is in char * format
2197 and returns the old version again in char * format */
2198
2199 char * get_old_version(char * arg){
/* [<][>][^][v][top][bottom][index][help] */
2200
2201 bool code = true;
2202 char *type=NULL, *primary_search_key = NULL, *search_string = NULL;
2203 Object *o;
2204 o = new Object;
2205 char *result = NULL, *origin = NULL;
2206
2207 error = 0;
2208 code = o->scan(arg,strlen(arg));
2209 type = get_type(o);
2210 primary_search_key = get_search_key(o, type, arg);
2211 if(tracing) {
2212 cout << "type=" << type << endl;
2213 cout << "primary_search_key=" << primary_search_key << endl;
2214 }
2215 /* prepare the search string */
2216 //search_string = (char *)malloc(strlen(primary_search_key) + strlen("-x -R -r -T")
2217 // + strlen(type) + 1);
2218 /* if the object is a pn ro a ro object, then get all pn/ro's with the
2219 same NIC hdl */
2220 if(strcmp(type,"person") == 0 || strcmp(type,"role") == 0){
2221 /* prepare the search string */
2222 search_string = (char *)malloc(strlen(primary_search_key) + strlen("-x -R -r -T")
2223 + strlen("person,role") + 1);
2224 sprintf(search_string, "-x -R -r -Tperson,role %s", primary_search_key);
2225 }else{
2226 /* prepare the search string */
2227 search_string = (char *)malloc(strlen(primary_search_key) + strlen("-x -R -r -T")
2228 + strlen(type) + 1);
2229 sprintf(search_string, "-x -R -r -T%s %s",type, primary_search_key);
2230 }
2231 result = send_and_get(QUERY_HOST, QUERY_PORT, search_string);
2232 if(tracing) {
2233 cout << "TRACING: send_and_get has returned" << endl;
2234 cout << "TRACING: send_and_get returned (with search '"<< search_string <<"'): " << endl
2235 << result << endl;
2236 }
2237 /* Attention: here we must also check these:
2238 for ro/pn objects: The name must also the same. When the NIC hdl is the
2239 same but names are different, we must somehow return an error.
2240 Also, when we search for a person, we must also look for role objects
2241 (and vice versa) since the RIPupdate does not distinguish between
2242 role & person objects. We have to check it here.
2243 for rt objects: We also have to check the identicalness of origin
2244 attributes.
2245
2246 These are not yet implemented.
2247 */
2248
2249 if(strcmp(type,"route") == 0){
2250 if(tracing) {
2251 printf("TRACING: This is a route\n");
2252 }
2253 /* if this is a route, then we must filter out the routes with different
2254 origin attributes */
2255 origin = get_search_key(o, "origin", arg);
2256 if(tracing) {
2257 printf("TRACING: Got origin of route: %s\n", origin);
2258 }
2259 result = filter_out_diff_origins(result, origin);
2260 if(tracing) {
2261 printf("TRACING: Filtered routes\n");
2262 }
2263 }
2264 // count the objects
2265 if(count_objects(result) == 0){
2266 result = NULL; /* we don't have such an object */
2267 }else if(count_objects(result) == 1){
2268 result = take_object(result);
2269 if(tracing) {
2270 cout << "TRACING: Take_object returned ***\n" << result << "***" << endl;
2271 }
2272 }else{ /* we have more than one objects, error! */
2273 error = UP_MOR;
2274 return NULL;
2275 }
2276 return result;
2277 }
2278
2279
2280
2281
2282 /* Gets a credentials_struct whose 'from' field will be filled in and
2283 the mail header. Finds the 'From:' line in the header and sets
2284 the 'from' field to this line (all line, including the 'From:' string,
2285 since some users have put regexps which match the whole line in their
2286 'auth' attributes.) */
2287 void process_mail_header(credentials_struct * credentials_ptr, char * arg){
/* [<][>][^][v][top][bottom][index][help] */
2288 char * header = strdup(arg);
2289 char * temp = (char *)malloc(strlen(header));
2290 while(index(header, '\n') != NULL){
2291 temp = strdup(header);
2292 temp[index(temp, '\n') - temp] = '\0';
2293 if(strstr(temp, "From:") == temp){
2294 if(tracing) {
2295 printf("TRACING: process_mail_header: Assigning %s\n", temp);
2296 }
2297 credentials_ptr->from = strdup(temp);
2298 free(temp);
2299 return;
2300 }
2301 header = header + (index(header, '\n') - header + 1);
2302 }
2303 free(temp);
2304 }
2305
2306
2307
2308
2309
2310
2311 void stringPack(char *dest, const char *source)
/* [<][>][^][v][top][bottom][index][help] */
2312 {
2313
2314 if(tracing) {
2315 printf("TRACING: stringPack running\n");
2316 }
2317
2318
2319
2320 /*----------------------------------------------------------------------*\
2321
2322 * Function to rewrite a line of text with only one blankspace between *
2323 * each word.
2324 *
2325
2326 \*----------------------------------------------------------------------*/
2327
2328
2329 /*
2330 * This while loop continues until the NULL character is copied into
2331 * the destination string. If a tab character is copied into the
2332 * destination string, it is replaced with a blank-space character.
2333 *
2334 * Multiple blank-space and/or tab characters are skipped in the source
2335 * string until any other character is found.
2336 */
2337
2338 while (1)
2339 {
2340 *dest = *source;
2341
2342 if (*dest == '\t')
2343 (*dest = ' ');
2344
2345 /* Exit if have copied the end of the string. */
2346 if (*dest == '\0')
2347 return;
2348
2349 /*
2350 * If the source character was a blank-space or a tab, move to the next
2351 * source character. While the source character is a blank-space or a
2352 * tab, move to the next character (i.e. ignore these characters). When
2353 * any other character is found in the source string, move to the next
2354 * element of the destination string.
2355 *
2356 * Otherwise, simultaneously, move to the next elements of the destination
2357 * and the source strings.
2358 */
2359
2360
2361
2362 if ( (*source == ' ') || (*source == '\t') )
2363 {
2364 ++source;
2365 while ( (*source == ' ') || (*source == '\t') )
2366 {
2367 ++source;
2368 }
2369
2370 ++dest;
2371 }
2372 else
2373 {
2374 ++dest;
2375 ++source;
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
2413 int identical(const char * old_version, const char * new_version){
/* [<][>][^][v][top][bottom][index][help] */
2414 char * arg1 = strdup(old_version);
2415 char * arg2 = strdup(new_version);
2416 int result = 0;
2417 char *temp1, *temp2;
2418
2419
2420 arg1 = g_strstrip(arg1);
2421 arg2 = g_strstrip(arg2);
2422
2423 /* delete the 'delete:' attrib */
2424 arg2 = delete_delete_attrib(arg2);
2425 /* convert tabs to white spaces */
2426 arg1 = g_strdelimit(arg1, "\t", ' ');
2427 arg2 = g_strdelimit(arg2, "\t", ' ');
2428
2429 temp1 = (char *)malloc(strlen(arg1));
2430 temp2 = (char *)malloc(strlen(arg2));
2431 stringPack(temp1, arg1);
2432 stringPack(temp2, arg2);
2433
2434 result = strcmp(temp1, temp2);
2435 //printf("DEBUG: identical: the objects are:\n[%s]\n[%s]\n", temp1, temp2);
2436 free(arg1);
2437 free(arg2);
2438 free(temp1);
2439 free(temp2);
2440 if(result == 0){
2441 if(tracing) {
2442 printf("TRACING: identical returning 1\n");
2443 }
2444 return 1;
2445 }else{
2446 if(tracing) {
2447 printf("TRACING: identical returning 0\n");
2448 }
2449 return 0;
2450 }
2451 }
2452
2453
2454
2455
2456
2457
2458 /* constructs an initials string from a given name (for NIC hdl generation) */
2459 char * find_initials(const char * arg){
/* [<][>][^][v][top][bottom][index][help] */
2460
2461 char * temp, * temp2;
2462 char * initials = NULL;
2463 int len, i;
2464 char ** vector;
2465
2466 temp = strdup(arg);
2467 g_strstrip(temp);
2468 temp2 = (char *)malloc(strlen(temp) + 1);
2469 stringPack(temp2, temp);
2470 vector = g_strsplit(temp2, " ", 0);
2471 for(i = 0; vector[i] != NULL && i < 4; i++){
2472 //printf("%i\n",i);
2473 if(strlen(vector[i]) > 0){
2474 if(initials == NULL){
2475 initials = (char *)malloc(2);
2476 initials[0] = vector[i][0]; initials[1] = '\0';
2477 }else{
2478 len = strlen(initials);
2479 initials = (char *)realloc(initials, len + 2 );
2480 initials[len] = vector[i][0];
2481 initials[len + 1] = '\0';
2482 }
2483 }
2484 }
2485 free(temp);free(temp2);g_strfreev(vector);
2486 return initials;
2487 }
2488
2489
2490
2491
2492
2493 /* Gets the letter combination to be used in the automatically
2494 generated NIc handle. It the letter combination is specified
2495 in the AUTO NIC handle, return that. If not, return NULL
2496 (in which case the initials of the name must be used) */
2497 char * get_combination_from_autonic(const char * autonic){
/* [<][>][^][v][top][bottom][index][help] */
2498
2499 GString * temp;
2500 char * str = NULL;
2501
2502 temp = g_string_new(autonic);
2503 temp = g_string_up(temp);
2504 temp = g_string_erase(temp, 0, strlen("AUTO-"));
2505 /* delete all digits from the beginning of the string */
2506 while(temp->len > 0 && ((temp->str)[0] >= '0' && (temp->str)[0] <= '9')){
2507 temp = g_string_erase(temp, 0, 1);
2508 }
2509 if(temp->len == 0){
2510 g_string_free(temp, TRUE);
2511 return NULL;
2512 }else{
2513 str = temp->str;
2514 g_string_free(temp, FALSE);
2515 return str;
2516 }
2517
2518 }
2519
2520
2521
2522
2523
2524
2525 /* Gets an object whose NIC hdl is AUTO and to be modified (to be sent to RIPupdate)
2526 and modifies the nic-hdl: attribute, returns the new object.
2527 For example, "nic-hdl: AUTO-1" becomes "nic-hdl: HG*-RIPE . Also,
2528 auto_nic is set to "AUTO-1"
2529 auto_nic must be allocated enough memory before replace_AUTO_NIC_hdl called */
2530 #if 0
2531 char * replace_AUTO_NIC_hdl(char * arg, char * auto_nic_hdl){
/* [<][>][^][v][top][bottom][index][help] */
2532
2533 GString* temp_string;
2534 char * to_be_returned = NULL;
2535 char * person_role_name= NULL;
2536 char * initials = NULL;
2537 char ** temp = NULL;
2538 int i, pos;
2539 Object * o = new Object;
2540
2541 temp = g_strsplit(arg, "\n", 0);
2542
2543 for(i = 0; temp[i] != NULL; i++){
2544 //printf("Line: %s\n", temp[i]);
2545 if(strstr(temp[i], "nic-hdl:") == temp[i]){/* if it starts with nic-hdl */
2546 temp_string = g_string_new(temp[i]);
2547 if(strstr(temp_string->str, "AUTO-") != NULL){
2548 auto_nic_hdl = strncpy(auto_nic_hdl, strstr(temp_string->str, "AUTO-"),
2549 temp_string->len + temp_string->str - strstr(temp_string->str, "AUTO-") );
2550 auto_nic_hdl[temp_string->len + temp_string->str - strstr(temp_string->str, "AUTO-")] = '\0';
2551 g_strstrip(auto_nic_hdl);
2552 printf("DEBUG: auto_nic is [%s]\n", auto_nic_hdl);
2553 pos = strstr(temp_string->str, "AUTO-") - temp_string->str;
2554 temp_string = g_string_erase(temp_string,
2555 strstr(temp_string->str, "AUTO-") - temp_string->str, strlen(auto_nic_hdl)/*strlen("AUTO-")*/);
2556
2557 temp_string = g_string_insert(temp_string, pos, UPDATE_SOURCE);
2558 temp_string = g_string_insert(temp_string, pos, "*-");
2559 o->scan(arg, strlen(arg));
2560 person_role_name = get_attribute(o, get_type(o), arg);
2561 delete(o);
2562 initials = find_initials(person_role_name);
2563 free(person_role_name);
2564 temp_string = g_string_insert(temp_string, pos, initials);
2565 free(initials);
2566
2567 if(to_be_returned == NULL){
2568 to_be_returned = strdup(temp_string->str);
2569 g_string_free(temp_string, TRUE);
2570 }else{
2571 to_be_returned = (char *)realloc(to_be_returned, strlen(to_be_returned) + temp_string->len + 2);
2572 to_be_returned = strcat(to_be_returned, "\n");
2573 to_be_returned = strcat(to_be_returned, temp_string->str);
2574 g_string_free(temp_string, TRUE);
2575 }
2576 }else{
2577 if(to_be_returned == NULL){
2578 to_be_returned = strdup(temp[i]);
2579 }else{
2580 to_be_returned = (char *)realloc(to_be_returned, strlen(to_be_returned) + strlen(temp[i]) + 2);
2581 to_be_returned = strcat(to_be_returned, "\n");
2582 to_be_returned = strcat(to_be_returned, temp[i]);
2583 }
2584 }
2585 }else{/* if it doesn't begin with nic-hdl */
2586 if(to_be_returned == NULL){
2587 to_be_returned = strdup(temp[i]);
2588 }else{
2589 to_be_returned = (char *)realloc(to_be_returned, strlen(to_be_returned) + strlen(temp[i]) + 2);
2590 strcat(to_be_returned, "\n");
2591 strcat(to_be_returned, temp[i]);
2592 }
2593
2594 }
2595
2596 }
2597 g_strfreev (temp);
2598 return to_be_returned;
2599 }
2600 #endif
2601 char * replace_AUTO_NIC_hdl(char * arg, char * auto_nic_hdl){
/* [<][>][^][v][top][bottom][index][help] */
2602
2603 GString* temp_string;
2604 char * to_be_returned = NULL;
2605 char * person_role_name= NULL;
2606 char * initials = NULL;
2607 char ** temp = NULL;
2608 int i, pos;
2609 Object * o = new Object;
2610
2611 temp = g_strsplit(arg, "\n", 0);
2612
2613 for(i = 0; temp[i] != NULL; i++){
2614 //printf("Line: %s\n", temp[i]);
2615 if(strstr(temp[i], "nic-hdl:") == temp[i]){/* if it starts with nic-hdl */
2616 temp_string = g_string_new(temp[i]);
2617 temp_string = g_string_down(temp_string);
2618 if(strstr(temp_string->str, "auto-") != NULL){
2619 auto_nic_hdl = strncpy(auto_nic_hdl, strstr(temp_string->str, "auto-"),
2620 temp_string->len + temp_string->str - strstr(temp_string->str, "auto-") );
2621 auto_nic_hdl[temp_string->len + temp_string->str - strstr(temp_string->str, "auto-")] = '\0';
2622 g_strstrip(auto_nic_hdl);
2623 printf("DEBUG: auto_nic is [%s]\n", auto_nic_hdl);
2624 pos = strstr(temp_string->str, "auto-") - temp_string->str;
2625 temp_string = g_string_erase(temp_string,
2626 strstr(temp_string->str, "auto-") - temp_string->str, strlen(auto_nic_hdl)/*strlen("AUTO-")*/);
2627
2628 temp_string = g_string_insert(temp_string, pos, UPDATE_SOURCE);
2629 temp_string = g_string_insert(temp_string, pos, "*-");
2630 o->scan(arg, strlen(arg));
2631 person_role_name = get_attribute(o, get_type(o), arg);
2632 delete(o);
2633 /* if the letter combination is already specified, get it */
2634 initials = get_combination_from_autonic(auto_nic_hdl);
2635 /* if the letter combination is not in the AUTO nichdl, obtain it from the name */
2636 if(initials == NULL){
2637 initials = find_initials(person_role_name);
2638 }
2639 free(person_role_name);
2640 temp_string = g_string_insert(temp_string, pos, initials);
2641 free(initials);
2642
2643 if(to_be_returned == NULL){
2644 to_be_returned = strdup(temp_string->str);
2645 g_string_free(temp_string, TRUE);
2646 }else{
2647 to_be_returned = (char *)realloc(to_be_returned, strlen(to_be_returned) + temp_string->len + 2);
2648 to_be_returned = strcat(to_be_returned, "\n");
2649 to_be_returned = strcat(to_be_returned, temp_string->str);
2650 g_string_free(temp_string, TRUE);
2651 }
2652 }else{
2653 if(to_be_returned == NULL){
2654 to_be_returned = strdup(temp[i]);
2655 }else{
2656 to_be_returned = (char *)realloc(to_be_returned, strlen(to_be_returned) + strlen(temp[i]) + 2);
2657 to_be_returned = strcat(to_be_returned, "\n");
2658 to_be_returned = strcat(to_be_returned, temp[i]);
2659 }
2660 }
2661 }else{/* if it doesn't begin with nic-hdl */
2662 if(to_be_returned == NULL){
2663 to_be_returned = strdup(temp[i]);
2664 }else{
2665 to_be_returned = (char *)realloc(to_be_returned, strlen(to_be_returned) + strlen(temp[i]) + 2);
2666 strcat(to_be_returned, "\n");
2667 strcat(to_be_returned, temp[i]);
2668 }
2669
2670 }
2671
2672 }
2673 g_strfreev (temp);
2674 return to_be_returned;
2675 }
2676
2677
2678
2679 /* replaces the refs to AUTO NIC hdls with the assigned one */
2680
2681 char * replace_refs_to_AUTO_NIC_hdl(char * changed_obj, char * arg, GHashTable * auto_nic_hash){
/* [<][>][^][v][top][bottom][index][help] */
2682
2683 char * auto_nic = NULL;
2684 GString* temp_string;
2685 char * to_be_returned = NULL;
2686 char ** temp = NULL;
2687 int i, pos;
2688
2689 //printf("DEBUG: replace_first_ref_to_AUTO_NIC_hdl is running\n");
2690
2691 temp = g_strsplit(arg, "\n", 0);
2692
2693 for(i = 0; temp[i] != NULL; i++){
2694 //printf("Line: %s\n", temp[i]);
2695 if( strstr(temp[i], "admin-c:") == temp[i] /* if it starts with admin-c */
2696 || strstr(temp[i], "tech-c:" ) == temp[i] /* or if it starts with tech-c */
2697 || strstr(temp[i], "zone-c:" ) == temp[i] /* or if it starts with zone-c */
2698 || strstr(temp[i], "author:" ) == temp[i]){ /* or if it starts with author */
2699 temp_string = g_string_new(temp[i]);
2700 temp_string = g_string_down(temp_string);
2701 if(strstr(temp_string->str, "auto-") != NULL){
2702 auto_nic = (char *)malloc(temp_string->len + temp_string->str - strstr(temp_string->str, "auto-") + 1);
2703 auto_nic = strncpy(auto_nic, strstr(temp_string->str, "auto-"),
2704 temp_string->len + temp_string->str - strstr(temp_string->str, "auto-") );
2705 auto_nic[temp_string->str + temp_string->len - strstr(temp_string->str, "auto-")] = '\0';
2706 g_strstrip(auto_nic);
2707 printf("DEBUG: auto_nic is [%s]\n", auto_nic);
2708 pos = strstr(temp_string->str, "auto-") - temp_string->str;
2709 temp_string = g_string_erase(temp_string,
2710 strstr(temp_string->str, "auto-") - temp_string->str, strlen(auto_nic)/*strlen("AUTO-")*/);
2711
2712 //temp_string = g_string_insert(temp_string, pos, UPDATE_SOURCE);
2713 //temp_string = g_string_insert(temp_string, pos, "*-");
2714 /* if we have this AUTO NIC hdl in the hash, put it. */
2715 if(g_hash_table_lookup(auto_nic_hash, auto_nic)){
2716 temp_string = g_string_insert(temp_string, pos, (char *)g_hash_table_lookup(auto_nic_hash, auto_nic));
2717 }else{/* else, return 0 immediately */
2718 g_strfreev (temp);
2719 return NULL;
2720 }
2721
2722 if(to_be_returned == NULL){
2723 to_be_returned = strdup(temp_string->str);
2724 g_string_free(temp_string, TRUE);
2725 }else{
2726 to_be_returned = (char *)realloc(to_be_returned, strlen(to_be_returned) + temp_string->len + 2);
2727 to_be_returned = strcat(to_be_returned, "\n");
2728 to_be_returned = strcat(to_be_returned, temp_string->str);
2729 g_string_free(temp_string, TRUE);
2730 }
2731 }else{
2732 if(to_be_returned == NULL){
2733 to_be_returned = strdup(temp[i]);
2734 }else{
2735 to_be_returned = (char *)realloc(to_be_returned, strlen(to_be_returned) + strlen(temp[i]) + 2);
2736 to_be_returned = strcat(to_be_returned, "\n");
2737 to_be_returned = strcat(to_be_returned, temp[i]);
2738 }
2739 }
2740 }else{/* if it doesn't begin with ac,tc,ac or author */
2741 if(to_be_returned == NULL){
2742 to_be_returned = strdup(temp[i]);
2743 }else{
2744 to_be_returned = (char *)realloc(to_be_returned, strlen(to_be_returned) + strlen(temp[i]) + 2);
2745 strcat(to_be_returned, "\n");
2746 strcat(to_be_returned, temp[i]);
2747 }
2748
2749 }
2750
2751 }
2752 g_strfreev (temp);
2753 //free(arg);
2754 //changed_obj = strdup(to_be_returned);
2755 //free(to_be_returned);
2756 printf("DEBUG: replace_first_ref_to_AUTO_NIC_hdl is returning,\nto_be_returned=[%s]\n", to_be_returned);
2757 return to_be_returned;
2758 }
2759
2760
2761
2762
2763
2764
2765
2766
2767 /* Takes an object in a char * , and returns 1 if this object has
2768 an AUTO NIC handle. Otherwise, returns 0 */
2769 int has_AUTO_NIC_hdl(const char * object){
/* [<][>][^][v][top][bottom][index][help] */
2770
2771 Object * o = new Object();
2772 GSList * attributes = NULL;
2773 bool code;
2774
2775 code = o->scan(object, strlen(object));
2776
2777 if(code && !(o->isDeleted)){
2778 attributes = get_attributes(o, "nic-hdl", object);
2779 if(attributes != NULL){
2780 if(strstr_in_list(attributes, "AUTO-") == 1){/* if it contains a ref to AUTO nic */
2781 g_slist_free(attributes);
2782 delete(o);
2783 return 1;
2784 }
2785 }
2786 /* if control reaches here, then we will return 0 */
2787 g_slist_free(attributes);
2788 delete(o);
2789 return 0;
2790 }else{/* it doesn't pass syntax check. So, it doesn't matter if
2791 it contains refs to AUTO NIC hdls. */
2792 delete(o);
2793 return 0;
2794 }
2795
2796 }
2797
2798
2799 /* Takes an object in a char * , and returns 1 if this object contains
2800 a reference to an AUTO NIC handle. Otherwise, returns 0 */
2801 int has_ref_to_AUTO_nic_hdl(const char * object){
/* [<][>][^][v][top][bottom][index][help] */
2802
2803 Object * o = new Object();
2804 GSList * attributes = NULL;
2805 bool code;
2806
2807 code = o->scan(object, strlen(object));
2808
2809 if(code && !(o->isDeleted)){
2810 attributes = get_attributes(o, "admin-c", object);
2811 if(attributes != NULL){
2812 if(strstr_in_list(attributes, "AUTO-") == 1){/* if it contains a ref to AUTO nic */
2813 g_slist_free(attributes);
2814 delete(o);
2815 return 1;
2816 }
2817 }
2818 g_slist_free(attributes);
2819 attributes = get_attributes(o, "tech-c", object);
2820 if(attributes != NULL){
2821 if(strstr_in_list(attributes, "AUTO-") == 1){/* if it contains a ref to AUTO nic */
2822 g_slist_free(attributes);
2823 delete(o);
2824 return 1;
2825 }
2826 }
2827
2828 g_slist_free(attributes);
2829 attributes = get_attributes(o, "zone-c", object);
2830 if(attributes != NULL){
2831 if(strstr_in_list(attributes, "AUTO-") == 1){/* if it contains a ref to AUTO nic */
2832 g_slist_free(attributes);
2833 delete(o);
2834 return 1;
2835 }
2836 }
2837 g_slist_free(attributes);
2838 attributes = get_attributes(o, "author", object);
2839 if(attributes != NULL){
2840 if(strstr_in_list(attributes, "AUTO-") == 1){/* if it contains a ref to AUTO nic */
2841 g_slist_free(attributes);
2842 delete(o);
2843 return 1;
2844 }
2845 }
2846 /* if control reaches here, then we will return 0 */
2847 delete(o);
2848 return 0;
2849 }else{/* it doesn't pass syntax check. So, it doesn't matter if
2850 it contains refs to AUTO NIC hdls. */
2851 delete(o);
2852 return 0;
2853 }
2854
2855 }
2856
2857
2858 #if 0
2859 /* Checks the object's syntax, retrives the old version of it from the db,
2860 and checks auth2. If everything is OK, then sends it to RIPdb, where referential
2861 integrity is checked, and the object is really committed to the db.
2862
2863 Arguments:
2864 char * arg: The object,
2865 credentials_struct credentials: The struct containing the credentials, such as
2866 'From:' field of the e-mail update,
2867 GHashTable * NIC_hdl_hash: A hash containing
2868 char * ack_file_name: The file name, to be used to store ACK message
2869 */
2870
2871
2872
2873 int process_object(char * arg, credentials_struct credentials, GHashTable * NIC_hdl_hash, char * ack_file_name){
/* [<][>][^][v][top][bottom][index][help] */
2874 bool code = true;
2875 Object *o;
2876 char * old_version = NULL;
2877 o = new Object;
2878 int result = 0;
2879 int result_from_RIPupd = 0;
2880 char * auto_nic = NULL;
2881 char * changed_obj = NULL;
2882 char * obj_with_AUTO_NIC_hdl;
2883 char * assigned_NIC;
2884
2885 char * value = NULL;/* these two are for */
2886 Attr * attr; /* ack messages only */
2887
2888 if(has_ref_to_AUTO_nic_hdl(arg)){/* if this object has refs to AUTO NIC hdls*/
2889 /* then first replace AUTO NIC hdls with assigned NIC hdls (in NIC_hdl_hash) */
2890 if((arg = replace_refs_to_AUTO_NIC_hdl(changed_obj, arg, NIC_hdl_hash)) == NULL){
2891 return UP_ANE; /* AUTO NIC hdl error */
2892 };
2893 }
2894
2895 code = o->scan(arg,strlen(arg));
2896 if(code){
2897 /* is the object to be deleted? */
2898 if(o->isDeleted){
2899 //printf("DEBUG: This object is to be deleted\n");
2900 old_version = get_old_version(arg);
2901 if(old_version == NULL){ // the object doesn't exist in the db!
2902 //add_to_ack("\nDeletion Failed: Object doesn't exist", ack_file_name);
2903 //add_to_ack(o->type->getName(), ack_file_name);
2904 //add_to_ack(get_search_key(o, o->type->getName(), arg), ack_file_name);
2905 AK_add_to_ack(ack_file_name, "\nDel FAILED: [%s] %s\nObject doesn't exist\n",
2906 o->type->getName(), get_search_key(o, o->type->getName(), arg));
2907 return UP_NSO; /* no such object */
2908 }else {/* the object is in the db */
2909 if(identical(old_version, arg)){/* if the old & new versions are identical */
2910 result = check_auth(NULL, old_version, o->type->getName(), credentials);
2911 if(result == UP_AUTH_OK){
2912 if(tracing) {
2913 printf("TRACING: Will send the obj to be deleted\n");
2914 }
2915 result_from_RIPupd = send_object_db(arg, NULL, "DEL");
2916 if(result_from_RIPupd == 0){
2917 //add_to_ack("\nDeletion succeeded", ack_file_name);
2918 //add_to_ack(o->type->getName(), ack_file_name);
2919 //add_to_ack(get_search_key(o, o->type->getName(), arg), ack_file_name);
2920 AK_add_to_ack(ack_file_name, "\nDel OK: [%s] %s\n",
2921 o->type->getName(), get_search_key(o, o->type->getName(), arg));
2922 }else{
2923 //add_to_ack("\nDeletion failed: Referential intergrity failure", ack_file_name);
2924 //add_to_ack(o->type->getName(), ack_file_name);
2925 //add_to_ack(get_search_key(o, o->type->getName(), arg), ack_file_name);
2926 AK_add_to_ack(ack_file_name, "\nDel FAILED: [%s] %s\nReferential intergrity failure\n",
2927 o->type->getName(), get_search_key(o, o->type->getName(), arg));
2928 }
2929 result_from_RIPupd = 0;
2930 }else{ /* auth failed */
2931 if(tracing) {
2932 printf("TRACING: Auth failed\n");
2933 }
2934 if(error_msg != NULL){
2935 cout << error_msg << endl;
2936 }
2937 //add_to_ack("\nDeletion failed: Auth failed", 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]\n%s\nAuth failed\n",
2941 o->type->getName(), get_search_key(o, o->type->getName(), arg));
2942 return UP_AUF; /* Auth failed */
2943 }
2944 }else{/* the new & old versions do not match */
2945 //add_to_ack("Deletion failed: new & old versions do not match", ack_file_name);
2946 AK_add_to_ack(ack_file_name, "\nDel FAILED: new & old versions do not match\n");
2947 return UP_NOM; /* new & old versions do not match */
2948 }
2949 }
2950 }else {/* the object is _not_ to be deleted */
2951 if(has_AUTO_NIC_hdl(arg)){/* it the object has an AUTO NIC hdl */
2952 /* then its nic-hdl attribute must be modified so that RIPupdate
2953 would understand that it must assign a NIC handle to it */
2954 /* but first check the auth */
2955 result = check_auth(arg, NULL, o->type->getName(), credentials);
2956 if(result == UP_AUTH_OK){
2957 if(tracing) {
2958 printf("TRACING: Will send the obj to be created with AUTO NIC hdl\n");
2959 }
2960 auto_nic = (char *)malloc(1024); /* should be enough for a NIC hdl */
2961 obj_with_AUTO_NIC_hdl = replace_AUTO_NIC_hdl(arg, auto_nic);
2962 if(tracing) {
2963 printf("TRACING: Called replace_AUTO_NIC_hdl, get [%s]\n", obj_with_AUTO_NIC_hdl);
2964 printf("TRACING: Will send the obj to be added\n");
2965 }
2966 assigned_NIC = (char *)malloc(128); /* this should be enough for a NIC hdl */
2967 result_from_RIPupd = send_object_db(obj_with_AUTO_NIC_hdl, assigned_NIC, "ADD");
2968 if(result_from_RIPupd == 0){
2969 //add_to_ack("\nCreation succeeded", ack_file_name);
2970 //add_to_ack(o->type->getName(), ack_file_name);
2971 //add_to_ack(assigned_NIC, ack_file_name);
2972 AK_add_to_ack(ack_file_name, "\nNew OK: [%s] %s\n",
2973 o->type->getName(), assigned_NIC);
2974 }else{
2975 //add_to_ack("\nCreation failed: Referential integrity failure", ack_file_name);
2976 //add_to_ack(o->type->getName(), ack_file_name);
2977 //add_to_ack(arg, ack_file_name);
2978 AK_add_to_ack(ack_file_name, "\nNew FAILED: [%s] %s\nReferential integrity failure\n",
2979 o->type->getName(), arg);
2980 }
2981 result_from_RIPupd = 0;
2982 if(tracing && assigned_NIC != NULL) {
2983 printf("TRACING: send_object_db returned [%s] as assigned NIC hdl\n", assigned_NIC);
2984 }
2985 if(assigned_NIC != NULL){
2986 printf("DEBUG: auto_nic=[%s], assigned_NIC=[%s]\n", auto_nic, assigned_NIC);
2987 g_hash_table_insert(NIC_hdl_hash, auto_nic, assigned_NIC);
2988 printf("DEBUG: NIC_hdl_hash has %i pairs\n",g_hash_table_size(NIC_hdl_hash));
2989 }
2990
2991 }else{
2992 // auth failed !
2993 if(tracing) {
2994 printf("TRACING: Auth failed\n");
2995 }
2996 if(error_msg != NULL){
2997 cout << error_msg << endl;
2998 }
2999 ER_perror(0, result, "");
3000 //add_to_ack("\nCreation failed: Auth failed", ack_file_name);
3001 //add_to_ack(o->type->getName(), ack_file_name);
3002 //add_to_ack(get_search_key(o, o->type->getName(), arg), ack_file_name);
3003 AK_add_to_ack(ack_file_name, "\nNew FAILED: [%s] %s\nAuth failed\n",
3004 o->type->getName(), get_search_key(o, o->type->getName(), arg));
3005 return UP_AUF; /* Auth failed */
3006 }
3007 }
3008 else{
3009 old_version = get_old_version(arg);
3010 if(old_version != NULL){/* so, this is an update operation */
3011 result = check_auth(arg, old_version, o->type->getName(), credentials);
3012 if(result == UP_AUTH_OK){
3013 if(tracing) {
3014 printf("TRACING: Will send the obj to be updated\n");
3015 }
3016 result_from_RIPupd = send_object_db(arg, NULL, "UPD");
3017 if(result_from_RIPupd == 0){
3018 //add_to_ack("\nUpdate succeeded", ack_file_name);
3019 //add_to_ack(o->type->getName(), ack_file_name);
3020 //add_to_ack(get_search_key(o, o->type->getName(), arg), ack_file_name);
3021 AK_add_to_ack(ack_file_name, "\nUpdate OK: [%s] %s\n",
3022 o->type->getName(), get_search_key(o, o->type->getName(), arg));
3023 }else{
3024 //add_to_ack("\nUpdate failed: Referential integrity failure", ack_file_name);
3025 //add_to_ack(o->type->getName(), ack_file_name);
3026 //add_to_ack(get_search_key(o, o->type->getName(), arg), ack_file_name);
3027 AK_add_to_ack(ack_file_name, "\nUpdate FAILED: [%s]\n%s\nReferential integrity failure\n",
3028 o->type->getName(), get_search_key(o, o->type->getName(), arg));
3029 }
3030 result_from_RIPupd = 0;
3031 }else{
3032 // auth failed !
3033 if(tracing) {
3034 printf("TRACING: Auth failed\n");
3035 }
3036 if(error_msg != NULL){
3037 cout << error_msg << endl;
3038 }
3039 //add_to_ack("\nUpdate failed: Auth failed", ack_file_name);
3040 //add_to_ack(o->type->getName(), ack_file_name);
3041 //add_to_ack(get_search_key(o, o->type->getName(), arg), ack_file_name);
3042 AK_add_to_ack(ack_file_name, "\nUpdate FAILED: [%s] %s\nAuth failed\n",
3043 o->type->getName(), get_search_key(o, o->type->getName(), arg));
3044 return UP_AUF; /* Auth failed */
3045 }
3046 }else { /* old_version == NULL, so, creation */
3047 result = check_auth(arg, NULL, o->type->getName(), credentials);
3048 if(result == UP_AUTH_OK){
3049 if(tracing) {
3050 printf("TRACING: Will send the obj to be added\n");
3051 }
3052 result_from_RIPupd = send_object_db(arg, NULL, "ADD");
3053 if(result_from_RIPupd == 0){
3054 //add_to_ack("\nCreation succeeded", ack_file_name);
3055 //add_to_ack(o->type->getName(), ack_file_name);
3056 //add_to_ack(get_search_key(o, o->type->getName(), arg), ack_file_name);
3057 AK_add_to_ack(ack_file_name, "\nNew OK [%s] %s\n",
3058 o->type->getName(), get_search_key(o, o->type->getName(), arg));
3059 }else{
3060 //add_to_ack("\nCreation failed: Referential integrity failure", ack_file_name);
3061 //add_to_ack(o->type->getName(), ack_file_name);
3062 //add_to_ack(get_search_key(o, o->type->getName(), arg), ack_file_name);
3063 AK_add_to_ack(ack_file_name, "\nNew FAILED: [%s] %s\nReferential integrity failure\n",
3064 o->type->getName(), get_search_key(o, o->type->getName(), arg));
3065 }
3066 result_from_RIPupd = 0;
3067 }else{
3068 // auth failed !
3069 if(tracing) {
3070 printf("TRACING: Auth failed\n");
3071 }
3072 if(error_msg != NULL){
3073 cout << error_msg << endl;
3074 }
3075 ER_perror(0, result, "");
3076 //add_to_ack("\nCreation failed: Auth failed", ack_file_name);
3077 //add_to_ack(o->type->getName(), ack_file_name);
3078 //add_to_ack(get_search_key(o, o->type->getName(), arg), ack_file_name);
3079 AK_add_to_ack(ack_file_name, "\nNew FAILED: [%s] %s\nAuth failed\n",
3080 o->type->getName(), get_search_key(o, o->type->getName(), arg));
3081 return UP_AUF; /* Auth failed */
3082 }
3083 }
3084 }
3085 }
3086 }else{// even if obj doesn't parse properly, it may be a legacy object
3087 // which the user wants to delete...
3088 if(tracing){
3089 printf("TRACING: Object didn't parse\n");
3090 }
3091 //add_to_ack("\nFailed: Syntax error in object", ack_file_name);
3092 //add_to_ack(arg, ack_file_name);
3093 AK_add_to_ack(ack_file_name, "\nUpdate FAILED: Syntax error in object\n");
3094 //////////////////////////////////
3095 if(o->attrs.head() != NULL){
3096 for(attr = o->attrs.head(); attr; attr = o->attrs.next(attr)){
3097 value = (char*)malloc((*attr).len );
3098 strncpy(value, (char *)(arg+attr->offset) ,
3099 attr->len - 1);
3100 value[attr->len - 1] = '\0';
3101 //add_to_ack(value, ack_file_name);
3102 AK_add_to_ack(ack_file_name, "%s\n", value);
3103 if(!attr->errors.empty()){
3104 //add_to_ack_string(attr->errors, ack_file_name);
3105 //cout << "Error: " << attr->errors << endl;
3106 AK_add_to_ack_string(ack_file_name, attr->errors);
3107 }
3108 free(value);
3109 }
3110 }
3111 if(o->has_error){
3112 //add_to_ack_string(o->errors, ack_file_name);
3113 //cout << "Object Error: " << o->errors << endl;
3114 AK_add_to_ack_string(ack_file_name, o->errors);
3115 }
3116 //////////////////////////////////
3117 return UP_NIY; /* Not implemented yet */
3118 }
3119 }
3120
3121
3122 #endif
3123
3124 /* Gets the "From" line of the incoming mail message and finds out an
3125 address to send the acknowledgement */
3126 char * find_to_address(const char * from_line){
/* [<][>][^][v][top][bottom][index][help] */
3127 char * pos1 = NULL, * pos2 = NULL;
3128 char * temp = NULL;
3129
3130 if(from_line == NULL){
3131 return NULL;
3132 }
3133 if(strstr(from_line, "From:") != from_line){/* there is a problem, the line must start with
3134 "From:" */
3135 fprintf(stderr, "The line doesn't start with 'From:'\n");
3136 return NULL;
3137 }
3138 temp = strdup(from_line + strlen("From:"));
3139 g_strstrip(temp);
3140 if(index(temp, '<')){/* then the line is something like '"John White" <john@inter.net>' */
3141 pos1 = index(temp, '<');
3142 pos2 = index(temp, '>');
3143 temp = strncpy(temp, pos1 + 1, pos2 - pos1 -1);
3144 temp[pos2 - pos1 - 1] = '\0';
3145 printf("DEBUG: find_to_address\n");
3146 printf("DEBUG: find_to_address temp=[%s]\n", temp);
3147 return temp;
3148 }else{/* the line contains only the address, then */
3149 return temp;
3150 }
3151 }
3152