## 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. up_string_pack
45. delete_delete_attrib
46. UP_replace_strings
47. UP_replace_GStrings
48. identical
49. find_initials
50. get_combination_from_autonic
51. replace_AUTO_NIC_hdl
52. replace_refs_to_AUTO_NIC_hdl
53. has_AUTO_NIC_hdl
54. has_ref_to_AUTO_nic_hdl
55. find_email_address
56. UP_remove_EOLs
57. UP_replace_globals
58. get_class_type_char

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

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