## 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. delete_override
6. up_get_transaction_id
7. send_object_db
8. get_class_type
9. get_search_key
10. send_and_get
11. count_objects
12. strip_lines
13. take_objects
14. take_object
15. get_as_block
16. get_aut_num_object
17. get_less_specific_domain
18. get_less_specific_set
19. get_less_specific
20. get_less_spec_inetnum
21. get_exact_match_inetnum
22. get_exact_match_routes
23. get_less_spec_routes
24. get_mntners
25. get_attributes
26. get_attribute
27. strstr_in_list
28. get_auths
29. get_attr_list
30. get_mnt_lowers
31. get_mnt_routes
32. get_mnt_routes_from_list
33. get_mnt_lowers_from_list
34. get_override
35. check_override
36. add_to_auth_vector
37. get_auth_vector
38. get_mntnfy_vector
39. get_updto_vector
40. filter_out_diff_origins
41. check_auth
42. get_old_version
43. process_mail_header
44. stringPack
45. delete_delete_attrib
46. identical
47. find_initials
48. get_combination_from_autonic
49. replace_AUTO_NIC_hdl
50. replace_refs_to_AUTO_NIC_hdl
51. has_AUTO_NIC_hdl
52. has_ref_to_AUTO_nic_hdl
53. process_object
54. find_email_address
55. replace_strings
56. replace_globals
57. get_class_type_char

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

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