## 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. get_combination_from_autonic
47. replace_AUTO_NIC_hdl
48. replace_AUTO_NIC_hdl
49. replace_refs_to_AUTO_NIC_hdl
50. has_AUTO_NIC_hdl
51. has_ref_to_AUTO_nic_hdl
52. process_object
53. find_to_address

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

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