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

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