## modules/up/UP_util.cc

/* [<][>][^][v][top][bottom][index][help] */

## FUNCTIONS

This source file includes following functions.

1. authorise
2. error_msg_cat
3. interpret_ripdb_result
4. get_assigned_nic
5. send_object_db
6. get_type
7. get_search_key
8. send_and_get
9. count_objects
10. strip_lines
11. take_objects
12. take_object
13. get_as_block
14. get_aut_num_object
15. get_less_specific_domain
16. get_less_specific_set
17. get_less_specific
18. get_less_spec_inetnum
19. get_exact_match_inetnum
20. get_exact_match_routes
21. get_less_spec_routes
22. get_mntners
23. get_attributes
24. get_attribute
25. strstr_in_list
26. get_auths
27. get_attr_list
28. get_mnt_lowers
29. get_mnt_routes
30. get_mnt_routes_from_list
31. get_mnt_lowers_from_list
32. get_override
33. check_override
34. add_to_auth_vector
35. get_auth_vector
36. get_mntnfy_vector
37. get_updto_vector
38. filter_out_diff_origins
39. check_auth
40. get_old_version
41. process_mail_header
42. stringPack
43. delete_delete_attrib
44. identical
45. find_initials
46. replace_AUTO_NIC_hdl
47. replace_refs_to_AUTO_NIC_hdl
48. has_AUTO_NIC_hdl
49. has_ref_to_AUTO_nic_hdl
50. process_object
51. 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

/* [<][>][^][v][top][bottom][index][help] */