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