## modules/up/UP_util.c

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

## DEFINITIONS

This source file includes following functions.

1. authorise
2. interpret_ripdb_result
3. get_assigned_nic
4. up_get_transaction_id
5. send_object_db
6. get_search_key
7. send_and_get
8. count_objects
9. strip_lines
10. take_objects
11. take_object
12. get_as_block
13. get_aut_num_object
14. get_less_specific_domain
15. get_less_specific_set
16. get_specific
17. get_less_spec_inetnum
18. get_exact_match_inetnum
19. get_exact_match_routes
20. get_less_spec_routes
21. get_mntners
22. get_irts
23. strstr_in_list
24. strstr_in_attr_list
25. get_auths
26. get_attr_list
27. get_mnt_lowers
28. get_mnt_routes
29. get_mnt_routes_from_list
30. get_mnt_lowers_from_list
31. get_mntners_from_list
32. get_override
33. check_override
34. add_to_auth_vector
35. get_auth_vector
36. get_irt_auth_vector
37. get_mntnfy_vector
38. get_irtnfy_vector
39. get_updto_vector
40. up_filter_out_diff_origins
41. up_filter_out_diff_nichdls
42. UP_filter_out_same_origins
43. up_check_reserved_status
44. up_get_status
45. up_get_specific_status
46. up_find_more_specific
47. up_check_inetnum_status_rules
48. up_check_inet6num_status_rules
49. up_check_status
50. check_auth
51. get_old_version
52. process_mail_header
53. up_string_pack
54. UP_replace_strings
55. UP_replace_GStrings
56. identical
57. find_initials
58. get_combination_from_autonic
59. replace_AUTO_NIC_hdl
60. replace_refs_to_AUTO_NIC_hdl
61. UP_put_assigned_NIC
62. has_AUTO_NIC_hdl
63. has_ref_to_AUTO_nic_hdl
64. find_email_address
65. UP_remove_EOLs
66. UP_replace_globals
67. UP_add_to_upd_log
68. UP_log_networkupdate
69. UP_is_object
70. UP_remove_override_attr
71. delete_override
72. delete_delete_attrib

       1 /***************************************
       2   $Revision: 1.27 $
       3
       4   UP module utilities
       5
       6   Status: REVIEWED, NOT TESTED
       7
       8   Author(s):       Engin Gunduz
       9
      10   ******************/ /******************
      11   Modification History:
      12         engin (17/01/2000) Created.
      13                 denis (31/08/2001) Modified for new API
      14   ******************/ /******************
      15   Copyright (c) 2000,2001,2002                    RIPE NCC
      16
      17   All Rights Reserved
      18
      19   Permission to use, copy, modify, and distribute this software and its
      20   documentation for any purpose and without fee is hereby granted,
      21   provided that the above copyright notice appear in all copies and that
      22   both that copyright notice and this permission notice appear in
      23   supporting documentation, and that the name of the author not be
      24   used in advertising or publicity pertaining to distribution of the
      25   software without specific, written prior permission.
      26
      27   THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
      28   ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS; IN NO EVENT SHALL
      29   AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
      30   DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
      31   AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
      32   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
      33  ***************************************/
      34
      35 #include <time.h>
      36 #include "dbupdate.h"
      37 #include "UP_extrnl_syntax.h"
      38 #include "ud.h"
      39 #include "notification.h"
      40
      41 extern int tracing;
      42 extern char * overridecryptedpw;
      43 extern int test_mode;
      44 extern char * updlog;
      45 extern char * update_host;
      46 extern int update_port;
      47 extern char * query_host;
      48 extern int query_port;
      49 extern char * humailbox;
      50 extern char * autobox;
      51 extern char * netupdclientIP;
      52
      53 extern int reading_from_mail;
      54 extern int networkupdate;
      55 extern int webupdate;
      56 extern char *netupdclientIP;
      57
      58 extern char *update_mail_sender;
      59 extern char *update_mail_subject;
      60 extern char *update_mail_date;
      61 extern char *update_mail_ID;
      62 extern char *update_mail_cc;
      63
      64 extern char *header_type;
      65 extern char *text_type;
      66
      67 extern char *current_source;
      68 extern char *DBhost;
      69 extern int  DBport;
      70 extern char *DBuser;
      71 extern char *DBname;
      72 extern char *DBpasswd;
      73
      74 extern char * allocmnt;
      75
      76
      77 /* authorise function takes the auth_vector, credentials struct, and 'overriden'
      78    variable. If overriden == 1, then it immediately returns UP_AUTH_OK
      79    (because this means that the update contained a valid override attribute).
      80    Else, it goes through the auth_vector and when it finds a an "auth:"
      81    attribute which passes, then it returns UP_AUTH_OK. Otherwise, it returns
      82    UP_AUF (authorisation failed) */
      83
      84 int authorise(GSList * auth_vector, credentials_struct credentials, int overriden)
         /* [<][>][^][v][top][bottom][index][help] */
      85 {
      86   int result = 0;
      87
      88   if (tracing)
      89   {
      90     printf("TRACING: authorise started with override: %i\n", overriden);
      91   }
      92
      93   /* If 'overriden' variable is 1, then return UP_AUTH_OK immediately */
      94   if (overriden == 1)
      95   {
      96     return UP_AUTH_OK;
      97   }
      98   else
      99   {
     100     result = AU_authorise(auth_vector, credentials);
     101     if (tracing)
     102         {
     103       printf("TRACING: authorise: AU_authorise returned %i\n", result);
     104     }
     105
     106     if (result > 0)
     107         {
     108       return UP_AUTH_OK;
     109     }
     110     else
     111         {
     112       return UP_AUF; /* authorisation failed */
     113     }
     114   }
     115 }
     116
     117
     118
     119 /* interprets the result string coming from RIPupd
     120    It is called by send_object_db.
     121    It returns the error no returned from RIPupd.  */
     122
     123 int interpret_ripdb_result(const char * string)
         /* [<][>][^][v][top][bottom][index][help] */
     124 {
     125    char * error_no = NULL;
     126    char ** temp = NULL, ** temp2 = NULL;
     127    int i;
     128    int err = 0;
     129
     130   /* if the string is NULL or empty, then return error */
     131   if (string == NULL || strlen(string) == 0)
     132   {
     133     return 0;
     134   }
     135
     136   /* split the string into lines */
     137   temp = g_strsplit(string , "\n", 0);
     138   for (i = 0; temp[i] != NULL; i++)
     139   {
     140     if (i == 0)
     141         { /* this line must contain "%ERROR " string in the beginning */
     142       temp2 = g_strsplit(temp[0], " ", 0);
     143       error_no = strdup(temp2[1]);
     144       g_strfreev(temp2);
     145       err = atoi(error_no);
     146       if (tracing)
     147           {
     148         printf("TRACING: interpret_ripdb_result: error_no is [%s]\n", error_no);
     149       }
     150     }
     151         else if (error_no != NULL && strcmp(error_no, "0") != 0)
     152         {
     153     }
     154   }
     155   g_strfreev(temp);
     156   if (error_no != NULL)
     157   {
     158     free(error_no);
     159   }
     160   return err; /* 0 means no error in this context */
     161 }
     162
     163
     164
     165 /* Gets assigned NIC hdl from the string that is returned from
     166    RIPupdate */
     167 void get_assigned_nic(char * nic_hdl, const char * string)
         /* [<][>][^][v][top][bottom][index][help] */
     168 {
     169    char * error_no = NULL;
     170    char ** temp = NULL, ** temp2 = NULL;
     171    int i;
     172
     173   if (tracing)
     174   {
     175       printf("TRACING: get_assigned_nic is running\n");
     176   }
     177
     178   /* if the string is NULL or empty, then return error */
     179   if (string == NULL || strlen(string) == 0)
     180   {
     181     return;
     182   }
     183
     184   /* split the string into lines */
     185   temp = g_strsplit(string , "\n", 0);
     186   for (i = 0; temp[i] != NULL; i++)
     187   {
     188     if (i == 0)
     189         { /* this line must contain "%ERROR " string in the beginning */
     190       temp2 = g_strsplit(temp[0], " ", 0);
     191       error_no = strdup(temp2[1]);
     192       g_strfreev(temp2);
     193       if (tracing)
     194           {
     195         printf("TRACING: get_assigned_nic: error_no is [%s]\n", error_no);
     196       }
     197     }
     198         else if (error_no != NULL && strcmp(error_no, "0") != 0)
     199         {
     200     }
     201         else if (error_no != NULL && strcmp(error_no, "0") == 0 && i == 1)
     202         { /* look for assigned NIC hdl */
     203       /* in the second line RIPupdate returns for example "I[65][EK3-RIPE]" We
     204          need to extract EK3-RIPE part */
     205       nic_hdl = strncpy(nic_hdl, rindex(temp[i],'[') + 1 ,
     206                                  rindex(temp[i],']') - rindex(temp[i],'[') - 1);
     207       nic_hdl[rindex(temp[i],']') - rindex(temp[i],'[') - 1] = '\0';
     208       if (tracing && nic_hdl != NULL)
     209           {
     210         printf("TRACING: get_assigned_nic will return [%s]\n", nic_hdl);
     211       }
     212       g_strfreev(temp);
     213       return;
     214     }
     215   }
     216   g_strfreev(temp);
     217   return;
     218 }
     219
     220
     221
     222 /* Obtains a transaction ID for an object. Will be called from send_object_db */
     223 int up_get_transaction_id()
         /* [<][>][^][v][top][bottom][index][help] */
     224 {
     225   SQ_connection_t * sql_connection;
     226   SQ_result_set_t *result;
     227   int error;
     228   long new_id;
     229
     230   sql_connection = SQ_get_connection(DBhost, DBport, DBname, DBuser, DBpasswd);
     231   if (!sql_connection)
     232   {
     233     fprintf(stderr, "No SQL connection\n");
     234     exit(1);
     235   }
     236   error = SQ_execute_query(sql_connection, "INSERT INTO tid VALUES(NULL)", &result);
     237   if (error)
     238   {
     239     fprintf(stderr,"ERROR: %s\n", SQ_error(sql_connection));
     240     exit(1);
     241   }
     242
     243   new_id = mysql_insert_id(sql_connection);
     244
     245   SQ_close_connection(sql_connection);
     246
     247   return new_id;
     248 }
     249
     250
     251
     252 /* sends the object to the database. char * operation is either 'ADD' ,'DEL' or 'UPD'
     253    assigned_NIC is filled in if this is a person/role creation with AUTO nic hdl
     254    assigned_NIC must be allocated enough memory before send_object_db is called
     255
     256    If the called do not expect a NIC hdl back, then assigned_NIC can be given NULL
     257    */
     258 up_ripupd_result_struct * send_object_db(rpsl_object_t *object, char * assigned_NIC, char * operation)
         /* [<][>][^][v][top][bottom][index][help] */
     259 {
     260   int sockfd, numbytes;
     261   char buf[MAXDATASIZE + 1];
     262   struct hostent *he;
     263   struct sockaddr_in their_addr; /* connector's address information */
     264   char *result_string = NULL;
     265   int err = 0;
     266   char *to_be_sent = NULL;
     267   int tr_id;
     268   char * tr_id_str;
     269   char * tempstr;
     270   rpsl_object_t *sent_object;
     271   rpsl_attr_t *removed_attr;
     272   rpsl_error_t return_error;
     273
     274   up_ripupd_result_struct * return_struct;
     275
     276   if (tracing)
     277   {
     278     printf("TRACING: send_object_db is running: assigned_NIC : [%s]; operation: [%s]\n", assigned_NIC ? assigned_NIC : "", operation);
     279   }
     280   return_struct = (up_ripupd_result_struct *)malloc(sizeof(up_ripupd_result_struct));
     281   return_struct->error_str = NULL;
     282
     283   /* copy the object, remove the override password and create a text string */
     284   sent_object = rpsl_object_copy(object);
     285   removed_attr = rpsl_object_remove_attr_name(sent_object,"override",&return_error);
     286   to_be_sent = rpsl_object_get_text(sent_object,0);
     287   rpsl_object_delete(sent_object);
     288
     289   if (tracing)
     290   {
     291     printf("TRACING: send_object_db: to_be_sent : [\n%s]\n", to_be_sent);
     292   }
     293
     294   /* get the transaction ID, to be sent to RIPupdate*/
     295   tr_id = up_get_transaction_id();
     296
     297   /* convert it into a string */
     298   tr_id_str = (char *)malloc(64);
     299   sprintf(tr_id_str, "%d", tr_id);
     300
     301   if (tracing)
     302   {
     303     printf("TRACING: send_object_db: tr_id_str : [%s]\n", tr_id_str);
     304   }
     305
     306   if ((he=gethostbyname(update_host)) == NULL)
     307   {  /* get the host info */
     308       perror("gethostbyname");
     309       exit(1);
     310   }
     311
     312   if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
     313   {
     314       perror("socket");
     315       exit(1);
     316   }
     317
     318   their_addr.sin_family = AF_INET;      /* host byte order */
     319   their_addr.sin_port = htons(update_port);    /* short, network byte order */
     320   their_addr.sin_addr = *((struct in_addr *)he->h_addr);
     321   bzero(&(their_addr.sin_zero), 8);     /* zero the rest of the struct */
     322
     323
     324   if (connect(sockfd, (struct sockaddr *)&their_addr,
     325                                                                         sizeof(struct sockaddr)) == -1)
     326   {
     327       perror("connect");
     328       exit(1);
     329   }
     330
     331   if (send(sockfd, operation , strlen(operation), 0) == -1)
     332       perror("send");
     333   if (send(sockfd, " ", strlen(" "), 0) == -1)
     334       perror("send");
     335   if (send(sockfd, tr_id_str, strlen(tr_id_str), 0) == -1)
     336       perror("send");
     337   if (send(sockfd, "\n\n" , strlen("\n\n"), 0) == -1)
     338       perror("send");
     339   if (send(sockfd, to_be_sent, strlen(to_be_sent), 0) == -1)
     340       perror("send");
     341   if (send(sockfd, "\n\n", 2, 0)  == -1)
     342       perror("send");
     343   /* send the ACK now */
     344   if (send(sockfd, "ACK ",strlen("ACK "), 0)  == -1)
     345       perror("send");
     346   if (send(sockfd, tr_id_str, strlen(tr_id_str), 0) == -1)
     347       perror("send");
     348   if (send(sockfd, "\n\n",strlen("\n\n"), 0)  == -1)
     349       perror("send");
     350
     351   if (tracing)
     352   {
     353     printf("TRACING: send_object_db: send complete\n");
     354   }
     355
     356
     357   while ((numbytes=recv(sockfd, buf, MAXDATASIZE, 0)) != 0)
     358   {
     359       buf[numbytes] = '\0';
     360       if (tracing)
     361       {
     362         printf("received from socket [\n%s]\n",buf);
     363       }
     364       if (result_string == NULL)
     365       {
     366         result_string = strdup(buf);
     367       }
     368       else
     369       {
     370         result_string = (char *)realloc(result_string,
     371                                            strlen(result_string) + strlen(buf) + 1);
     372         result_string = strcat(result_string, buf);
     373       }
     374       if (strstr(result_string,"\n\n") != NULL)
     375       { /* if the result_string contains
     376          an empty line at the end, we will close */
     377         break;
     378       };
     379   }
     380
     381   free(tr_id_str);
     382   err = interpret_ripdb_result(result_string);
     383
     384   if (tracing)
     385   {
     386     printf("TRACING: send_object_db: interpret_ripdb_result returned : [%i]\n", err);
     387   }
     388
     389   if (assigned_NIC != NULL)
     390   { /* if the caller of the function expected to get a NIC handle */
     391     get_assigned_nic(assigned_NIC, result_string);
     392   }
     393   close(sockfd);
     394   free(to_be_sent);
     395   return_struct->result = err;
     396
     397   /*return_struct->error_str = strdup(result_string); */
     398   /* According to the error no got from RIPupdate, construct an error string  */
     399   switch (return_struct->result)
     400   {
     401     case 0: break;
     402     case ERROR_U_MEM:
     403     case ERROR_U_DBS:
     404     case ERROR_U_BADOP:
     405     case ERROR_U_COP:
     406     case ERROR_U_NSUP:
     407     case ERROR_U_BUG:
     408       tempstr = (char *)malloc(1024);
     409       snprintf(tempstr, 1024, "***Error: Please contact database admin: Error no %i",
     410           return_struct->result);
     411       return_struct->error_str = tempstr;
     412       break;
     413     case ERROR_U_OBJ:
     414       if (tracing)
     415       {
     416          printf("\nresult_string [%s]\n\n", result_string);
     417       }
     418       tempstr = (char *)malloc(1024);
     419       /* if the object contains refs to unknown objects */
     420       if (strstr(result_string, "dummy") != NULL ||
     421             strstr(result_string, "reference cannot be resolved") != NULL )
     422       {
     423         /* if the response from RIPupd contains "dummy not allowed" string
     424            or a reference that cannot be resolved */
     425         snprintf(tempstr, 1024, "***Error: Unknown object referenced");
     426       }
     427           else if (strstr(result_string, "key-cert") != NULL)
     428           {
     429       /* if the response from RIPupd contains "no key-cert object" string */
     430       snprintf(tempstr, 1024, "***Error: Unknown key-cert object referenced");
     431       }
     432       else
     433       {
     434       /* then, the object is referenced from other objects */
     435         snprintf(tempstr, 1024, "***Error: Object is referenced from other objects");
     436       }
     437       return_struct->error_str = tempstr;
     438       break;
     439     case ERROR_U_AUT:
     440       tempstr = (char *)malloc(1024);
     441       snprintf(tempstr, 1024, "***Error: Membership authorisation failure");
     442       return_struct->error_str = tempstr;
     443       break;
     444     default:
     445       tempstr = (char *)malloc(1024);
     446       snprintf(tempstr, 1024, "***Error: Please contact database admin: Error no %i",
     447           return_struct->result);
     448       return_struct->error_str = tempstr;
     449       break;
     450   }
     451   return return_struct;
     452 }
     453
     454
     455
     456 /* takes an object (pre-parsed) and returns its first attrib if it is not
     457    a person/role, and returns the nic-hdl if it is a person/role object */
     458 char * get_search_key(rpsl_object_t *object, const char * type)
         /* [<][>][^][v][top][bottom][index][help] */
     459 {
     460     char *primary_key = NULL;
     461         char *lctype;
     462         GList *attr_list;
     463
     464     if(object == NULL) return NULL;
     465
     466         lctype = strdup(type);
     467         g_strdown(lctype);
     468         if ( strcmp(lctype, "person") == 0 || strcmp(lctype, "role") == 0 )
     469         {
     470                 /* this is a person or role object */
     471                 /* get the nic-hdl attribute */
     472                 attr_list = rpsl_object_get_attr(object, "nic-hdl");
     473         }
     474         else
     475         {
     476                 /* this is NOT a person or role object */
     477                 /* get the class attribute */
     478                 attr_list = rpsl_object_get_attr(object, type);
     479         }
     480
     481         if ( attr_list )
     482         {
     483                 primary_key = rpsl_attr_get_clean_value((rpsl_attr_t *)(attr_list->data));
     484         }
     485         free(lctype);
     486         return primary_key ;
     487 }
     488
     489
     490
     491 /* sends char * arg to the specified host's specified port, and
     492    returns the reply as a string. This is used to query the
     493    whois host. Probably we must use WC (whois client) module here,
     494    but it must be extented */
     495 char * send_and_get(char * host, int port, char * arg)
         /* [<][>][^][v][top][bottom][index][help] */
     496 {
     497         int sockfd, numbytes;
     498         char * result = NULL;
     499         char buf[MAXDATASIZE + 1];
     500         struct hostent *he;
     501         struct sockaddr_in their_addr; /* connector's address information */
     502
     503         if(tracing)
     504                 {
     505           printf("TRACING: send_and_get: arg : [%s]; port: [%i]; host: [%s]\n", arg, port, host);
     506         }
     507
     508         if ((he=gethostbyname(host)) == NULL)
     509                 {  /* get the host info */
     510             perror("gethostbyname");
     511             exit(1);
     512         }
     513
     514         if(tracing)
     515                 {
     516           printf("TRACING: send_and_get: called gethostbyname\n");
     517         }
     518
     519         if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
     520                 {
     521             perror("socket");
     522             exit(1);
     523         }
     524
     525         if(tracing)
     526                 {
     527           printf("TRACING: send_and_get: called socket\n");
     528         }
     529
     530         their_addr.sin_family = AF_INET;      /* host byte order */
     531         their_addr.sin_port = htons(port);    /* short, network byte order */
     532         their_addr.sin_addr = *((struct in_addr *)he->h_addr);
     533         bzero(&(their_addr.sin_zero), 8);     /* zero the rest of the struct */
     534
     535         if (connect(sockfd, (struct sockaddr *)&their_addr,
     536                                               sizeof(struct sockaddr)) == -1)
     537         {
     538             perror("connect");
     539             exit(1);
     540         }
     541         if (send(sockfd, arg , strlen(arg), 0) == -1)
     542                perror("send");
     543         if (send(sockfd, "\n",1,0)  == -1)
     544                perror("send");
     545
     546         while ((numbytes=recv(sockfd, buf, MAXDATASIZE, 0)) != 0)
     547                 {
     548             buf[numbytes] = '\0';
     549             if (result == NULL)
     550                         {
     551               result = strdup(buf);
     552             }
     553                         else
     554                         {
     555               result = (char *)realloc(result, strlen(result) + strlen(buf) + 1);
     556               result = strcat(result, buf);
     557             }
     558         }
     559
     560         close(sockfd);
     561         return result;
     562 }
     563
     564
     565
     566 /* counts the number of objects in a string */
     567 int count_objects(char * arg)
         /* [<][>][^][v][top][bottom][index][help] */
     568 {
     569     int count = 0;
     570     char *pos = NULL;
     571     char *temp = NULL;
     572
     573     if(tracing)
     574         {
     575       printf("TRACING: count_objects running\n");
     576     }
     577
     578     if(arg != NULL)
     579         {
     580       temp = strdup(arg);
     581     }
     582         else
     583         {
     584       return 0;
     585     }
     586
     587     if ( isalpha( (int)(arg[0]) ) )
     588         {
     589       count++;
     590     }
     591         else if (arg[0] == '\n' && isalpha( (int)(arg[1]) ) )
     592         {
     593       count++;
     594     }
     595     while ( (pos = strstr(temp,"\n\n")) )
     596         {
     597       pos[0] = 'a'; /* something non-EOL so that it won't be caught in the next loop */
     598       if ( isalpha( (int)(pos[2]) ) )
     599           {
     600         count++;
     601       }
     602     }
     603     if(tracing)
     604         {
     605       printf("TRACING: count_objects returning %d\n", count);
     606     }
     607     free(temp);
     608     return count;
     609 }
     610
     611
     612
     613 /* strips lines beginning with '%' off  */
     614 char * strip_lines(char * arg)
         /* [<][>][^][v][top][bottom][index][help] */
     615 {
     616     char ** temp = NULL;
     617     char * string = NULL;
     618     int i;
     619
     620     if (arg == NULL)
     621         {
     622        return NULL;
     623     }
     624
     625     /* split the string into lines */
     626     temp = g_strsplit (arg, "\n", 0);
     627
     628     for (i=0; temp[i] != NULL; i++)
     629         {
     630       if (temp[i][0] != '%')
     631           {
     632         if (string == NULL)
     633                 {
     634           string = strdup(temp[i]);
     635         }
     636                 else
     637                 {
     638           string = (char *)realloc(string, strlen(string) + strlen(temp[i]) + 2);
     639           string = strcat(string, "\n");
     640           string = strcat(string, temp[i]);
     641         }
     642       }
     643     }
     644     return string;
     645 }
     646
     647
     648 /* Separates the objects in the given char * arg using "\n\n" as
     649    separator. Returns a linked list whose data consist of separated
     650    objects as  char *  */
     651
     652 GList * take_objects(char * arg)
         /* [<][>][^][v][top][bottom][index][help] */
     653 {
     654     char ** objects=NULL;
     655     char ** temp = NULL;
     656     char * temp_object;
     657     GList * tobereturned = NULL;
     658     int i;
     659
     660     arg = strip_lines(arg);
     661
     662     objects =  g_strsplit(arg, "\n\n", 1000);
     663     temp = objects;
     664     for (i=0; temp[i] != NULL; i++)
     665         {
     666       /* strip off the trailing and leading white spaces-eols*/
     667       g_strstrip(temp[i]);
     668       if (strlen(temp[i]) > 0)
     669           { /* if not an empty string */
     670         /* here we must add a "\n" at the end of the object, since RAToolSet parser can't
     671           find the last attrib otherwise */
     672         temp_object = (char *)malloc(strlen(temp[i]) + 2);
     673         snprintf(temp_object, strlen(temp[i]) + 2, "%s\n", temp[i]);
     674         tobereturned = g_list_append(tobereturned, temp_object);
     675       }
     676     }
     677     return tobereturned;
     678 }
     679
     680
     681
     682 /* takes the first object in the given char *, using empty lines as
     683    separator */
     684 char * take_object(char * arg)
         /* [<][>][^][v][top][bottom][index][help] */
     685 {
     686     GList * objects;
     687     char * object;
     688
     689     objects = take_objects(arg);
     690     if (g_list_length(objects) > 0)
     691         {
     692       object = strdup((char *)(g_list_nth_data(objects, 0)));
     693     }
     694         else
     695         {
     696       return NULL;
     697     }
     698     g_list_free(objects);
     699
     700     return object;
     701 }
     702
     703
     704
     705 /* Takes an autnum_object, and returns the as-block containing this aut-num */
     706 char * get_as_block(rpsl_object_t *autnum_object)
         /* [<][>][^][v][top][bottom][index][help] */
     707 {
     708   char * search_key = NULL, * query_string = NULL;
     709   char * result = NULL;
     710   char *return_value = NULL;
     711
     712   search_key = get_search_key(autnum_object,"aut-num");
     713
     714   query_string = (char *)malloc(strlen("-Tas-block -s  -r ")+strlen(current_source)+strlen(search_key)+1);
     715   sprintf(query_string, "-Tas-block -s %s -r %s", current_source,search_key);
     716   result = send_and_get(query_host, query_port, query_string);
     717   free(query_string);
     718
     719   if (count_objects(result) == 0)
     720   {
     721     if (tracing)
     722         {
     723       printf("No such as-block\n");
     724     }
     725         free(result);
     726     return NULL;
     727   }
     728   else if (count_objects(result) > 1)
     729   {
     730     if (tracing)
     731         {
     732       printf("More than one as-block returned\n");
     733     }
     734         free(result);
     735     return NULL;
     736   }
     737   else
     738   { /* count_objects(result) == 1 */
     739     return_value = take_object(result);
     740         free(result);
     741     return return_value;
     742   }
     743 }
     744
     745
     746 /* Takes a route_object, and returns the aut-num mentioned in origin
     747    attribute of this route */
     748 char * get_aut_num_object(rpsl_object_t *route_object)
         /* [<][>][^][v][top][bottom][index][help] */
     749 {
     750   char * search_key = NULL, * query_string = NULL;
     751   char * result = NULL;
     752   char *return_value = NULL;
     753
     754   search_key = get_search_key(route_object,"origin");
     755
     756   query_string = (char *)malloc(strlen("-Taut-num -s  -r ")+strlen(current_source)+strlen(search_key)+1);
     757   sprintf(query_string, "-Taut-num -s %s -r %s", current_source,search_key);
     758   result = send_and_get(query_host, query_port, query_string);
     759   free(query_string);
     760
     761   if (count_objects(result) == 0)
     762   {
     763     if (tracing)
     764         {
     765       printf("No such aut-num\n");
     766     }
     767         free(result);
     768     return NULL;
     769   }
     770   else if (count_objects(result) > 1)
     771   {
     772     if (tracing)
     773         {
     774       printf("More than one aut-num returned\n");
     775     }
     776         free(result);
     777     return NULL;
     778   }
     779   else
     780   { /* count_objects(result) == 1 */
     781     return_value = take_object(result);
     782         free(result);
     783     return return_value;
     784   }
     785 }
     786
     787
     788
     789 /* Takes a parsed domain_object, and returns the less specific domain of it */
     790 char * get_less_specific_domain(rpsl_object_t *domain_object)
         /* [<][>][^][v][top][bottom][index][help] */
     791 {
     792   char *query_string = NULL;
     793   char *result = NULL, *domain = NULL;
     794   char *return_value = NULL;
     795   int i,j, length;
     796   char *temp = NULL;
     797   char **splitted;
     798
     799   domain = get_search_key(domain_object,"domain");
     800
     801   /* split the domain from its dots ('50' is the max # of pieces, this number is just arbitrary) */
     802   splitted =   g_strsplit((char *)strdup(domain), ".", 50);
     803
     804   for (i=1; splitted[i] != NULL; i++)
     805   {
     806     /* in the following for loop, we will construct the 'less spec' domains
     807        to be looked up in the DB */
     808     for (j=i; splitted[j] !=NULL; j++)
     809         {
     810       if (j==i)
     811           {
     812         temp = (char *)strdup(splitted[j]);
     813       }
     814           else
     815           {
     816         length = strlen(temp);
     817         temp = (char *)realloc(temp, length + strlen(splitted[j]) + 2);
     818                 strcat(temp, ".");
     819                 strcat(temp, splitted[j]);
     820       }
     821     }
     822
     823     query_string = (char *)malloc( strlen("-Tdomain -s  -r -R ")+strlen(current_source)+strlen(temp)+1 );
     824     sprintf(query_string, "-Tdomain -s %s -r -R %s", current_source,temp);
     825     result = send_and_get(query_host, query_port, query_string);
     826     free(query_string);
     827         free(temp);
     828
     829     if (count_objects(result) == 0)
     830         {
     831           /* do nothing */
     832           free(result);
     833     }
     834         else if (count_objects(result) > 1)
     835         {
     836       if (tracing)
     837           {
     838         printf("TRACING: get_less_specific_domain: More than one domains returned\n");
     839       }
     840           free(result);
     841       return NULL; /* error condition */
     842     }
     843         else
     844         { /* count_objects(result) == 1 */
     845       return_value = take_object(result);
     846           free(result);
     847       return return_value;
     848     }
     849   }
     850   g_strfreev(splitted);
     851
     852   /* so, we couldn't  find any 'less specific' domain */
     853   return NULL;
     854 }
     855
     856
     857
     858 /* Takes a hierarchical set_object, and returns the less specific set or auth-num of it
     859    by striping down the object's name ( eg, for as35:rs-trial:rs-myset,
     860    as35:rs-trial is tried ) */
     861 char * get_less_specific_set(rpsl_object_t *set_object, const char *type)
         /* [<][>][^][v][top][bottom][index][help] */
     862 {
     863   char *search_key = NULL, *query_string = NULL;
     864   char *result = NULL;
     865   char *return_value = NULL;
     866   int i;
     867
     868   search_key = get_search_key(set_object, type);
     869
     870   for (i = strlen(search_key) -1; i > -1; i--)
     871   {
     872     if (search_key[i] == ':')
     873         {
     874       search_key[i] = '\0'; /* truncate the string */
     875       break;
     876     }
     877     if (i == 0)
     878         { /* if we've reached the beginning of the string
     879       (this means there wasn't any ';' in the string) */
     880       free(search_key);
     881       search_key = NULL;
     882     }
     883   }
     884   if ( search_key == NULL || strlen(search_key) == 0)
     885   { /* this mustn't happen in fact, since
     886     we make sure that the name of the
     887     set_object contains a ':' in a proper place */
     888     return NULL;
     889   }
     890
     891   query_string = (char *)malloc(strlen("-Taut-num,as-set,rtr-set,peering-set,filter-set,route-set -s  -r ")
     892            + strlen(current_source) + strlen(search_key) + 1);
     893   sprintf(query_string, "-Taut-num,as-set,rtr-set,peering-set,filter-set,route-set -s %s -r %s", current_source,search_key);
     894   result = send_and_get(query_host, query_port, query_string);
     895   free(search_key);
     896   free(query_string);
     897
     898   if (count_objects(result) == 0)
     899   {
     900     if (tracing)
     901     {
     902       printf("get_less_specific_set: No such object\n");
     903         }
     904         free(result);
     905     return NULL;
     906   }
     907   else if (count_objects(result) > 1)
     908   {
     909     if (tracing)
     910     {
     911       printf("get_less_specific_set: More than one objects returned\n");
     912         }
     913         free(result);
     914     return NULL;
     915   }
     916   else
     917   { /* count_objects(result) == 1 */
     918     return_value = take_object(result);
     919         free(result);
     920     return return_value;
     921   }
     922 }
     923
     924
     925
     926 /* Takes an inetnum or inet6num object and returns one more/less specific of it */
     927 char * get_specific(rpsl_object_t *inetnum_object, const char *type, char *flag)
         /* [<][>][^][v][top][bottom][index][help] */
     928 {
     929   char *search_key = NULL, *query_string = NULL;
     930   char *result = NULL;
     931   char *return_value = NULL;
     932
     933   search_key = get_search_key(inetnum_object, type);
     934
     935   query_string = (char *)malloc(strlen("-Tinet6num  -s  -r  ")+strlen(current_source) + strlen(flag) + strlen(search_key) + 1);
     936   sprintf(query_string, "-T%s -s %s -r %s %s",type, current_source, flag, search_key);
     937   result = send_and_get(query_host, query_port, query_string);
     938   free(search_key);
     939   free(query_string);
     940
     941   if (count_objects(result) == 0)
     942   {
     943     if (tracing)
     944       printf("TRACING: get_specific: No %s %s returned\n", flag, type);
     945         free(result);
     946     return NULL;
     947   }
     948 /*  else if (count_objects(result) > 1)
     949   {
     950     if (tracing)
     951       printf("TRACING: get_specific: More than one %s %s returned\n", flag, type);
     952         free(result);
     953     return NULL;
     954   }   */
     955   else
     956   { /* count_objects(result) >= 1 */
     957     return_value = take_object(result);
     958         free(result);
     959     return return_value;
     960   }
     961 }
     962
     963
     964
     965 /* Takes a parsed route object and returns one less specific inetnum */
     966 char * get_less_spec_inetnum(rpsl_object_t *route_object)
         /* [<][>][^][v][top][bottom][index][help] */
     967 {
     968   char * search_key = NULL, * query_string = NULL;
     969   char * result = NULL;
     970   char * return_value = NULL;
     971
     972   search_key = get_search_key(route_object, "route");
     973
     974   query_string = (char *)malloc(strlen("-Tinetnum -s  -r -l ")+strlen(current_source) + strlen(search_key) + 1);
     975   sprintf(query_string, "-Tinetnum -s %s -r -l %s", current_source,search_key);
     976   result = send_and_get(query_host, query_port, query_string);
     977   free(search_key);
     978   free(query_string);
     979
     980   if (count_objects(result) == 0)
     981   {
     982     if (tracing)
     983         {
     984       printf("get_less_spec_inetnum: No such inetnum\n");
     985         }
     986         free(result);
     987     return NULL;
     988   }
     989   else if (count_objects(result) > 1)
     990   {
     991     if (tracing)
     992         {
     993       printf("get_less_spec_inetnum: More than one inetnums returned\n");
     994         }
     995         free(result);
     996     return NULL;
     997   }
     998   else
     999   { /* count_objects(result) == 1 */
    1000     return_value = take_object(result);
    1001         free(result);
    1002     return return_value;
    1003   }
    1004 }
    1005
    1006
    1007 /* Takes a parsed route object and returns exact match inetnum */
    1008 char * get_exact_match_inetnum(rpsl_object_t *route_object)
         /* [<][>][^][v][top][bottom][index][help] */
    1009 {
    1010   char * search_key = NULL, * query_string = NULL;
    1011   char * result = NULL;
    1012   char * return_value = NULL;
    1013
    1014   search_key = get_search_key(route_object, "route");
    1015
    1016   query_string = (char *)malloc(strlen("-Tinetnum -s  -r -x ")+strlen(current_source) + strlen(search_key) + 1);
    1017   sprintf(query_string, "-Tinetnum -s %s -r -x %s", current_source,search_key);
    1018   result = send_and_get(query_host, query_port, query_string);
    1019   free(search_key);
    1020   free(query_string);
    1021
    1022   if (count_objects(result) == 0)
    1023   {
    1024     if (tracing)
    1025         {
    1026       printf("get_exact_match_inetnum: No such inetnum\n");
    1027         }
    1028         free(result);
    1029     return NULL;
    1030   }
    1031   else if (count_objects(result) > 1)
    1032   {
    1033     if (tracing)
    1034         {
    1035       printf("get_exact_match_inetnum: More than one inetnums returned\n");
    1036         }
    1037         free(result);
    1038     return NULL;
    1039   }
    1040   else
    1041   { /* count_objects(result) == 1 */
    1042     return_value = take_object(result);
    1043         free(result);
    1044     return return_value;
    1045   }
    1046 }
    1047
    1048
    1049
    1050 /* Takes a route object and returns exact matches of this route */
    1051 GList *get_exact_match_routes(rpsl_object_t *route_object)
         /* [<][>][^][v][top][bottom][index][help] */
    1052 {
    1053   char *search_key = NULL, *query_string = NULL;
    1054   char *result = NULL;
    1055   GList * return_value = NULL;
    1056
    1057   search_key = get_search_key(route_object, "route");
    1058
    1059   query_string = (char *)malloc(strlen("-Troute -s  -r -x ")+strlen(current_source) + strlen(search_key) + 1);
    1060   sprintf(query_string, "-Troute -s %s -r -x %s", current_source,search_key);
    1061   result = send_and_get(query_host, query_port, query_string);
    1062   free(search_key);
    1063   free(query_string);
    1064
    1065   if (count_objects(result) == 0)
    1066   {
    1067     if (tracing)
    1068         {
    1069       printf("get_exact_match_routes: No such route\n");
    1070         }
    1071         free(result);
    1072     return NULL;
    1073   }
    1074   else
    1075   { /* count_objects(result) >= 1 */
    1076     return_value = take_objects(result);
    1077         free(result);
    1078     return return_value;
    1079   }
    1080 }
    1081
    1082
    1083
    1084 /* Takes a route object and returns (immediate) less specifics of this route */
    1085 GList *get_less_spec_routes(rpsl_object_t *route_object)
         /* [<][>][^][v][top][bottom][index][help] */
    1086 {
    1087   char *search_key = NULL, *query_string = NULL;
    1088   char *result = NULL;
    1089   GList * return_value = NULL;
    1090
    1091   search_key = get_search_key(route_object, "route");
    1092
    1093   query_string = (char *)malloc(strlen("-Troute -s  -r -l ")+strlen(current_source) + strlen(search_key) + 1);
    1094   sprintf(query_string, "-Troute -s %s -r -l %s", current_source,search_key);
    1095   result = send_and_get(query_host, query_port, query_string);
    1096   free(search_key);
    1097   free(query_string);
    1098
    1099   if (count_objects(result) == 0)
    1100   {
    1101     if(tracing)
    1102         {
    1103       printf("get_less_spec_routes: No such route\n");
    1104         }
    1105         free(result);
    1106     return NULL;
    1107   }
    1108   else
    1109   { /* count_objects(result) >= 1 */
    1110     return_value = take_objects(result);
    1111         free(result);
    1112     return return_value;
    1113   }
    1114 }
    1115
    1116
    1117
    1118 /* Gets an object as a parsed structure and returns its 'mnt-by' attributes as a
    1119    GList (linked list)   */
    1120
    1121 GList *get_mntners(rpsl_object_t *object)
         /* [<][>][^][v][top][bottom][index][help] */
    1122 {
    1123   GList *list_of_mntners = NULL;
    1124
    1125   if(tracing)
    1126   {
    1127     printf("TRACING: get_mntners is running\n");
    1128   }
    1129
    1130   list_of_mntners = rpsl_object_get_attr(object, "mnt-by");
    1131
    1132   rpsl_attr_split_multiple(&list_of_mntners);
    1133
    1134   return list_of_mntners;
    1135 }
    1136
    1137
    1138
    1139 /* Gets an object as a parsed structure and returns its 'mnt-irt' attributes as a
    1140    GList (linked list)   */
    1141
    1142 GList *get_irts(rpsl_object_t *object)
         /* [<][>][^][v][top][bottom][index][help] */
    1143 {
    1144   GList *list_of_irts = NULL;
    1145
    1146   if(tracing)
    1147   {
    1148     printf("TRACING: get_irts is running\n");
    1149   }
    1150
    1151   list_of_irts = rpsl_object_get_attr(object, "mnt-irt");
    1152   rpsl_attr_split_multiple(&list_of_irts);
    1153
    1154   return list_of_irts;
    1155 }
    1156
    1157
    1158
    1159 /* Gets a GList of strings and returns 1 if one of them starts with substr, 0 otherwise */
    1160 int strstr_in_list(GList *list, const char *substr)
         /* [<][>][^][v][top][bottom][index][help] */
    1161 {
    1162  GList * item = NULL;
    1163  char * word;
    1164
    1165   if (tracing)
    1166   {
    1167     printf("TRACING: strstr_in_list is running\n");
    1168   }
    1169
    1170  for ( item = list; item != NULL ; item = g_list_next(item) )
    1171  {
    1172    word = strdup((char *)(item->data));
    1173    g_strup(word);
    1174    if (strstr(word, substr) == word)
    1175    {
    1176      free(word);
    1177      return 1;
    1178    }
    1179    free(word);
    1180  }
    1181  /* none of them matched, so return 0 */
    1182  return 0;
    1183 }
    1184
    1185 /* Gets a GList of attr structures and returns 1 if one of their (upper case)values
    1186    starts with substr, otherwise returns 0 */
    1187 int strstr_in_attr_list(GList * list, const char * substr)
         /* [<][>][^][v][top][bottom][index][help] */
    1188 {
    1189  GList * item = NULL;
    1190  char * word;
    1191
    1192   if (tracing)
    1193   {
    1194     printf("TRACING: strstr_in_attr_list is running\n");
    1195   }
    1196
    1197  for( item = list; item != NULL ; item = g_list_next(item) )
    1198  {
    1199    word = rpsl_attr_get_clean_value((rpsl_attr_t *)(item->data));
    1200    g_strup(word);
    1201    if (strstr(word, substr) == word)
    1202    {
    1203      free(word);
    1204      return 1;
    1205    }
    1206    free(word);
    1207  }
    1208  /* none of them matched, so return 0 */
    1209  return 0;
    1210 }
    1211
    1212
    1213
    1214 /* Gets a (maintainer/irt) object as a string and returns its 'auth' attributes
    1215    as a GList (linked list) */
    1216
    1217 GList *get_auths(char * object_str)
         /* [<][>][^][v][top][bottom][index][help] */
    1218 {
    1219   const char *name = NULL;
    1220   char *value = NULL;
    1221   GList *attr;
    1222   rpsl_object_t *object;
    1223   GList *list_of_auths = NULL;
    1224
    1225   if(tracing)
    1226   {
    1227     printf("TRACING: get_auths is running\n");
    1228   }
    1229   object = rpsl_object_init(object_str);
    1230
    1231   list_of_auths = rpsl_object_get_attr(object, "auth");
    1232   rpsl_attr_split_multiple(&list_of_auths);
    1233
    1234   if(tracing)
    1235   {
    1236         if ( rpsl_object_has_error(object, RPSL_ERRLVL_ERROR) )
    1237         {
    1238           /* thre was an error during the parsing */
    1239           name = rpsl_object_get_class(object);
    1240           if ( name )
    1241           {
    1242                 attr = rpsl_object_get_attr(object, name);
    1243                 if ( attr )
    1244                 {
    1245                   value = rpsl_attr_get_clean_value( (rpsl_attr_t *)(attr->data) );
    1246                   if ( value )
    1247                   {
    1248                         printf("TRACING: get_auths: error parsing object %s\n", value );
    1249                         free(value);
    1250                   }
    1251                   else
    1252                         printf("TRACING: get_auths: error parsing object\n");
    1253
    1254                   rpsl_attr_delete_list(attr);
    1255                 }
    1256           }
    1257         }
    1258     printf("TRACING: get_auths: returning (with %d nodes)\n", g_list_length(list_of_auths));
    1259   }
    1260
    1261   rpsl_object_delete(object);
    1262   return list_of_auths;
    1263 }
    1264
    1265
    1266
    1267 /* Gets a parsed object and returns its 'attr_type' attributes as a
    1268    GList (linked list) */
    1269
    1270 GList *get_attr_list(rpsl_object_t *object, const char *attr_type)
         /* [<][>][^][v][top][bottom][index][help] */
    1271 {
    1272   GList *list_of_attrs = NULL;
    1273   char *object_str = NULL;
    1274
    1275   if (tracing)
    1276   {
    1277     object_str = rpsl_object_get_text(object,0);
    1278     printf("TRACING: get_attr_list is running searching for %s, object is [\n%s]\n", attr_type ? attr_type : "NULL", object_str ? object_str : "NULL");
    1279     free(object_str);
    1280   }
    1281
    1282   list_of_attrs = rpsl_object_get_attr(object, attr_type);
    1283   rpsl_attr_split_multiple(&list_of_attrs);
    1284
    1285   return list_of_attrs;
    1286 }
    1287
    1288
    1289
    1290 /* Gets a parsed object and returns its mnt_lower attributes as a
    1291    GList (linked list) */
    1292
    1293 GList *get_mnt_lowers(rpsl_object_t *object)
         /* [<][>][^][v][top][bottom][index][help] */
    1294 {
    1295   GList *list_of_mnt_lowers = NULL;
    1296
    1297   if (tracing)
    1298   {
    1299     printf("TRACING: get_mnt_lowers is running\n");
    1300   }
    1301
    1302   list_of_mnt_lowers = rpsl_object_get_attr(object, "mnt-lower");
    1303   rpsl_attr_split_multiple(&list_of_mnt_lowers);
    1304
    1305   return list_of_mnt_lowers;
    1306 }
    1307
    1308
    1309 /* Gets a parsed object and returns its mnt_routes attributes as a
    1310    GList (linked list) */
    1311
    1312 GList *get_mnt_routes(rpsl_object_t *object)
         /* [<][>][^][v][top][bottom][index][help] */
    1313 {
    1314   GList *list_of_mnt_routes = NULL;
    1315
    1316   if (tracing)
    1317   {
    1318     printf("TRACING: get_mnt_routes is running\n");
    1319   }
    1320
    1321   list_of_mnt_routes = rpsl_object_get_attr(object, "mnt-routes");
    1322   rpsl_attr_split_multiple(&list_of_mnt_routes );
    1323
    1324   return list_of_mnt_routes;
    1325 }
    1326
    1327
    1328 /* Gets a linked list of object strings and returns the mnt_routes attribs of
    1329    them in a linked list */
    1330 GList *get_mnt_routes_from_list(GList *objects_str)
         /* [<][>][^][v][top][bottom][index][help] */
    1331 {
    1332   GList *objects_str_item = NULL;
    1333   GList *list_of_mnt_routes = NULL;
    1334   const char *name = NULL;
    1335   char *value = NULL;
    1336   GList *attr;
    1337   rpsl_object_t *object;
    1338
    1339   for ( objects_str_item = objects_str; objects_str_item != NULL ; objects_str_item = g_list_next(objects_str_item) )
    1340   {
    1341         object = rpsl_object_init((char *)(objects_str_item->data));
    1342
    1343         if (tracing)
    1344         {
    1345       if ( rpsl_object_has_error(object, RPSL_ERRLVL_ERROR) )
    1346           {
    1347                 /* thre was an error during the parsing */
    1348                 name = rpsl_object_get_class(object);
    1349                 if ( name )
    1350                 {
    1351                   attr = rpsl_object_get_attr(object, name);
    1352                   if ( attr )
    1353                   {
    1354                     value = rpsl_attr_get_clean_value( (rpsl_attr_t *)(attr->data) );
    1355                         if ( value )
    1356                         {
    1357                       printf("TRACING: get_mnt_routes_from_list: error parsing object %s\n", value );
    1358                           free(value);
    1359                         }
    1360                         else
    1361                       printf("TRACING: get_mnt_routes_from_list: error parsing object\n");
    1362
    1363                         rpsl_attr_delete_list(attr);
    1364                   }
    1365                 }
    1366           }
    1367         }
    1368
    1369     list_of_mnt_routes = g_list_concat(list_of_mnt_routes, get_mnt_routes(object));
    1370     rpsl_object_delete(object);
    1371   }
    1372
    1373   return list_of_mnt_routes;
    1374 }
    1375
    1376
    1377 /* Gets a linked list of object strings and returns the mnt_lowers attribs of
    1378    them in a linked list */
    1379 GList *get_mnt_lowers_from_list(GList * objects_str)
         /* [<][>][^][v][top][bottom][index][help] */
    1380 {
    1381   GList *objects_str_item = NULL;
    1382   GList *list_of_mnt_lowers = NULL;
    1383   const char *name = NULL;
    1384   char *value = NULL;
    1385   GList *attr;
    1386   rpsl_object_t *object;
    1387
    1388   for( objects_str_item = objects_str; objects_str_item != NULL ; objects_str_item = g_list_next(objects_str_item) )
    1389   {
    1390         object = rpsl_object_init((char *)(objects_str_item->data));
    1391
    1392         if (tracing)
    1393         {
    1394       if ( rpsl_object_has_error(object, RPSL_ERRLVL_ERROR) )
    1395           {
    1396                 /* thre was an error during the parsing */
    1397                 name = rpsl_object_get_class(object);
    1398                 if ( name )
    1399                 {
    1400                   attr = rpsl_object_get_attr(object, name);
    1401                   if ( attr )
    1402                   {
    1403                     value = rpsl_attr_get_clean_value( (rpsl_attr_t *)(attr->data) );
    1404                         if ( value )
    1405                         {
    1406                       printf("TRACING: get_mnt_routes_from_list: error parsing object %s\n", value );
    1407                           free(value);
    1408                         }
    1409                         else
    1410                       printf("TRACING: get_mnt_routes_from_list: error parsing object\n");
    1411
    1412                         rpsl_attr_delete_list(attr);
    1413                   }
    1414                 }
    1415           }
    1416         }
    1417
    1418     list_of_mnt_lowers = g_list_concat(list_of_mnt_lowers, get_mnt_lowers(object));
    1419     rpsl_object_delete(object);
    1420   }
    1421
    1422   return list_of_mnt_lowers;
    1423 }
    1424
    1425
    1426 /* Gets a linked list of object strings and returns the mnt-by attribs of
    1427    them in a linked list */
    1428 GList *get_mntners_from_list(GList *objects_str)
         /* [<][>][^][v][top][bottom][index][help] */
    1429 {
    1430   GList *objects_str_item = NULL;
    1431   GList *list_of_mntners = NULL;
    1432   const char *name = NULL;
    1433   char *value = NULL;
    1434   GList *attr;
    1435   rpsl_object_t *object;
    1436
    1437   for ( objects_str_item = objects_str; objects_str_item != NULL ; objects_str_item = g_list_next(objects_str_item) )
    1438   {
    1439         object = rpsl_object_init((char *)(objects_str_item->data));
    1440
    1441         if (tracing)
    1442         {
    1443       if ( rpsl_object_has_error(object, RPSL_ERRLVL_ERROR) )
    1444           {
    1445                 /* thre was an error during the parsing */
    1446                 name = rpsl_object_get_class(object);
    1447                 if ( name )
    1448                 {
    1449                   attr = rpsl_object_get_attr(object, name);
    1450                   if ( attr )
    1451                   {
    1452                     value = rpsl_attr_get_clean_value( (rpsl_attr_t *)(attr->data) );
    1453                         if ( value )
    1454                         {
    1455                       printf("TRACING: get_mnt_routes_from_list: error parsing object %s\n", value );
    1456                           free(value);
    1457                         }
    1458                         else
    1459                       printf("TRACING: get_mnt_routes_from_list: error parsing object\n");
    1460
    1461                         rpsl_attr_delete_list(attr);
    1462                   }
    1463                 }
    1464           }
    1465         }
    1466
    1467     list_of_mntners = g_list_concat(list_of_mntners, get_mntners(object));
    1468     rpsl_object_delete(object);
    1469   }
    1470
    1471   return list_of_mntners;
    1472 }
    1473
    1474
    1475
    1476 /* retrieves the override password from the 'override' attribute
    1477    of the object. If none, it returns NULL   */
    1478 char *get_override(rpsl_object_t * object)
         /* [<][>][^][v][top][bottom][index][help] */
    1479 {
    1480
    1481   GList *attr_list;
    1482
    1483   if(tracing)
    1484   {
    1485     printf("TRACING: get_override is running\n");
    1486   }
    1487
    1488   attr_list = rpsl_object_get_attr(object, "override");
    1489   if ( ! attr_list )
    1490   {
    1491     /* there was no 'override' attrib, so return NULL */
    1492     return NULL;
    1493   }
    1494
    1495   /* there should only be one item in this list,
    1496      return the clean value of that attribute */
    1497   return strdup(rpsl_attr_get_value((rpsl_attr_t *)(attr_list->data)));
    1498 }
    1499
    1500
    1501
    1502 /* checks override string (password)
    1503    returns OVR_OK if it is correct password */
    1504 int check_override(char * string)
         /* [<][>][^][v][top][bottom][index][help] */
    1505 {
    1506    char ** temp;
    1507    int i;
    1508    char * crypted_password = strdup(overridecryptedpw);
    1509
    1510    if(string == NULL)
    1511    {
    1512      if(tracing)
    1513          {
    1514        printf("TRACING: check_override is returning FAILED\n");
    1515      }
    1516          free (crypted_password);
    1517      return UP_OVF; /* override attempt failed */
    1518    }
    1519    else
    1520    {
    1521     /* split the string */
    1522      temp = g_strsplit (string, " ", 0);
    1523
    1524      for(i=0; temp[i] != NULL; i++)
    1525          {
    1526        if(strlen(temp[i]) != 0)
    1527            {
    1528          if(strcmp(AU_crypt(temp[i], crypted_password), crypted_password) == 0)
    1529                  {
    1530            if(tracing)
    1531                    {
    1532              printf("TRACING: check_override is returning %s OK\n", string);
    1533            }
    1534            g_strfreev(temp);
    1535                    free (crypted_password);
    1536            return OVR_OK;
    1537          }
    1538        }
    1539      }
    1540
    1541      /* we couldn't find a word matching the override password */
    1542      g_strfreev(temp);
    1543          free (crypted_password);
    1544      return UP_OVF; /* override attempt failed */
    1545    }
    1546 }
    1547
    1548
    1549
    1550
    1551 /* takes a GSList of struct auth_struct and a GList of auths, and a mntner/irt name,
    1552    add new elements to GSList of struct auth_struct and  returns the new
    1553    GSList of struct auth_struct  */
    1554
    1555 GSList * add_to_auth_vector(GSList * list_of_auth_struct, GList * auths, char * mntner_name)
         /* [<][>][^][v][top][bottom][index][help] */
    1556 {
    1557    GList * auth_item;
    1558    char * auth_attrib = NULL;
    1559    char * auth_attrib_uppercase = NULL, * argument = NULL;
    1560    auth_struct * temp = NULL;
    1561    int index = 1;
    1562
    1563    for (auth_item = auths; auth_item != NULL; auth_item = g_list_next(auth_item))
    1564    {
    1565      auth_attrib = rpsl_attr_get_clean_value((rpsl_attr_t *)(auth_item->data));
    1566      if(tracing)
    1567          {
    1568        printf("TRACING: add_to_auth_vector: %s\n", auth_attrib);
    1569      }
    1570      /* Take the auth attribute and convert it into uppercase for comparisons */
    1571      auth_attrib_uppercase = strdup(auth_attrib);
    1572      g_strup(auth_attrib_uppercase);
    1573
    1574      if ( strstr(auth_attrib_uppercase,"CRYPT-PW") == auth_attrib_uppercase )
    1575          {
    1576        /* take the argument of the auth attribute */
    1577        argument = strdup(auth_attrib + strlen("CRYPT-PW"));
    1578        g_strstrip(argument);
    1579        if(tracing)
    1580            {
    1581          printf("TRACING: add_to_auth_vector: adding new CRYPT-PW argument: %s\n", argument);
    1582        }
    1583        temp = (auth_struct *)malloc(sizeof(auth_struct));
    1584        temp->type = AU_CRYPT_PW;
    1585        temp->auth = argument;
    1586        temp->mntner_name = mntner_name;
    1587        temp->index = index++;
    1588        list_of_auth_struct = g_slist_append(list_of_auth_struct, temp);
    1589      }
    1590      else if ( strstr(auth_attrib_uppercase,"MD5-PW") == auth_attrib_uppercase )
    1591          {
    1592        /* take the argument of the auth attribute */
    1593        argument = strdup(auth_attrib + strlen("MD5-PW"));
    1594        g_strstrip(argument);
    1595        if(tracing)
    1596            {
    1597          printf("TRACING: add_to_auth_vector: adding new MD5-PW argument: %s\n", argument);
    1598        }
    1599        temp = (auth_struct *)malloc(sizeof(auth_struct));
    1600        temp->type = AU_MD5_PW;
    1601        temp->auth = argument;
    1602        temp->mntner_name = mntner_name;
    1603        temp->index = index++;
    1604        list_of_auth_struct = g_slist_append(list_of_auth_struct, temp);
    1605      }
    1606          else if (strstr(auth_attrib_uppercase,"MAIL-FROM") == auth_attrib_uppercase)
    1607          {
    1608        /* take the argument of the auth attribute */
    1609        argument = strdup(auth_attrib + strlen("MAIL-FROM"));
    1610        g_strstrip(argument);
    1611        if(tracing)
    1612            {
    1613          printf("TRACING: add_to_auth_vector: adding new MAIL-FROM argument: %s\n", argument);
    1614        }
    1615        temp = (auth_struct *)malloc(sizeof(auth_struct));
    1616        temp->type = AU_MAIL_FROM;
    1617        temp->auth = argument;
    1618        temp->mntner_name = mntner_name;
    1619        temp->index = index++;
    1620        list_of_auth_struct = g_slist_append(list_of_auth_struct, temp);
    1621      }
    1622          else if (strstr(auth_attrib_uppercase,"NONE") == auth_attrib_uppercase)
    1623          {
    1624        /* take the argument of the auth attribute */
    1625        if(tracing)
    1626            {
    1627          printf("TRACING: add_to_auth_vector: adding new NONE argument\n");
    1628        }
    1629        temp = (auth_struct *)malloc(sizeof(auth_struct));
    1630        temp->type = AU_NONE;
    1631        temp->auth = NULL;
    1632        temp->mntner_name = mntner_name;
    1633        temp->index = index++;
    1634        list_of_auth_struct = g_slist_append(list_of_auth_struct, temp);
    1635     }
    1636         else if (strstr(auth_attrib_uppercase,"PGPKEY-") == auth_attrib_uppercase)
    1637         {
    1638        argument = strdup(auth_attrib + strlen("PGPKEY-"));
    1639        g_strstrip(argument);
    1640        if(tracing)
    1641            {
    1642          printf("TRACING: add_to_auth_vector: adding new PGPKEY argument: %s\n", argument);
    1643        }
    1644        temp = (auth_struct *)malloc(sizeof(auth_struct));
    1645        temp->type = AU_PGP;
    1646        temp->mntner_name = mntner_name;
    1647        temp->index = index++;
    1648        temp->auth = argument;
    1649        list_of_auth_struct = g_slist_append(list_of_auth_struct, temp);
    1650      }
    1651          else
    1652          {
    1653        if (tracing)
    1654            {
    1655          printf("TRACING: Error: invalid auth attrib: %s\n", auth_attrib);
    1656        }
    1657        return NULL;
    1658      }
    1659
    1660      free(auth_attrib_uppercase);
    1661      free(auth_attrib);
    1662    }
    1663
    1664    return list_of_auth_struct;
    1665 }
    1666
    1667
    1668
    1669
    1670 /* Gets a list of mntner names, retrieves those mntners from
    1671    the database and extracts the 'auth' attributes, and
    1672    constructs the authorisation vector, which is a GSList of
    1673    struct auth_struct */
    1674
    1675 GSList * get_auth_vector(GList * mntners)
         /* [<][>][^][v][top][bottom][index][help] */
    1676 {
    1677   GList * list_of_auths = NULL;
    1678   GList * mntner_item = NULL;
    1679   GSList * to_be_returned = NULL;
    1680   char * query_string = NULL, * result = NULL, * object_str = NULL;
    1681   char *value;
    1682
    1683   for( mntner_item = mntners; mntner_item != NULL ; mntner_item = g_list_next(mntner_item) )
    1684   {
    1685     value = rpsl_attr_get_clean_value((rpsl_attr_t *)(mntner_item->data));
    1686     if(tracing)
    1687         {
    1688       printf("=====\nget_auth_vector: Got a mntner\n%s\n", value  );
    1689     }
    1690     query_string = (char *)malloc(strlen("-Tmntner -s  -r ")+strlen(current_source)+strlen(value)+1);
    1691     sprintf(query_string, "-Tmntner -s %s -r %s",current_source,value);
    1692     result = send_and_get(query_host, query_port, query_string);
    1693         free(query_string);
    1694     if (count_objects(result) == 0)
    1695         {
    1696       /* no such maintainer */
    1697       if(tracing)
    1698           {
    1699         printf("get_auth_vector: No such maintainer %s\n", value);
    1700       }
    1701           free(result);
    1702           free(value);
    1703       return NULL;
    1704     }
    1705         else if (count_objects(result) > 1)
    1706         {
    1707       if(tracing)
    1708           {
    1709         printf("get_auth_vector: More than one objects returned for %s\n", value);
    1710       }
    1711     }
    1712         else
    1713         { /* count_objects(result) == 1 */
    1714       object_str = take_object(result);
    1715       if(tracing)
    1716           {
    1717         printf("TRACING: get_auth_vector: Calling get_auths with object [\n%s]\n", object_str);
    1718       }
    1719
    1720       list_of_auths = get_auths(object_str);
    1721       if(tracing)
    1722           {
    1723         printf("TRACING: get_auth_vector: get_auths returned (with %d nodes)\n", g_list_length(list_of_auths)) ;
    1724       }
    1725
    1726       /* add this to the auth_vector. ( mntner_item->data->value is the name of the maintainer  ) */
    1727       to_be_returned = add_to_auth_vector(to_be_returned, list_of_auths, (char *)value);
    1728       if(tracing)
    1729           {
    1730        printf("TRACING: get_auth_vector: to_be_returned has now %d nodes\n",  g_slist_length(to_be_returned));
    1731       }
    1732
    1733           rpsl_attr_delete_list(list_of_auths);
    1734     }
    1735         free(value);
    1736         free(result);
    1737   }
    1738
    1739   if(tracing)
    1740   {
    1741     printf("TRACING: get_auth_vector: to_be_returned has %i nodes\n", g_slist_length(to_be_returned));
    1742   }
    1743   return to_be_returned;
    1744 }
    1745
    1746
    1747
    1748 /* Gets a list of irt names, retrieves those irts from
    1749    the database and extracts the 'auth' attributes, and
    1750    constructs the authorisation vector, which is a GSList of
    1751    struct auth_struct */
    1752
    1753 GSList * get_irt_auth_vector(GList * irts)
         /* [<][>][^][v][top][bottom][index][help] */
    1754 {
    1755   GList * list_of_auths = NULL;
    1756   GList * irt_item = NULL;
    1757   GSList * to_be_returned = NULL;
    1758   char * query_string = NULL, * result = NULL, * object_str = NULL;
    1759   char *value;
    1760
    1761   for( irt_item = irts; irt_item != NULL ; irt_item = g_list_next(irt_item) )
    1762   {
    1763     value = rpsl_attr_get_clean_value((rpsl_attr_t *)(irt_item->data));
    1764     if(tracing)
    1765         {
    1766       printf("=====\nget_irt_auth_vector: Got an irt\n%s\n", value  );
    1767     }
    1768     query_string = (char *)malloc(strlen("-Tirt -s  -r ")+strlen(current_source)+strlen(value)+1);
    1769     sprintf(query_string, "-Tirt -s %s -r %s",current_source,value);
    1770     result = send_and_get(query_host, query_port, query_string);
    1771         free(query_string);
    1772     if (count_objects(result) == 0)
    1773         {
    1774       /* no such irt */
    1775       if(tracing)
    1776           {
    1777         printf("get_irt_auth_vector: No such irt %s\n", value);
    1778       }
    1779           free(result);
    1780           free(value);
    1781       return NULL;
    1782     }
    1783         else if (count_objects(result) > 1)
    1784         {
    1785       if(tracing)
    1786           {
    1787         printf("get_irt_auth_vector: More than one objects returned for %s\n", value);
    1788       }
    1789     }
    1790         else
    1791         { /* count_objects(result) == 1 */
    1792       object_str = take_object(result);
    1793       if(tracing)
    1794           {
    1795         printf("TRACING: get_irt_auth_vector: Calling get_auths with object [\n%s]\n", object_str);
    1796       }
    1797
    1798       list_of_auths = get_auths(object_str);
    1799       if(tracing)
    1800           {
    1801         printf("TRACING: get_irt_auth_vector: get_auths returned (with %d nodes)\n", g_list_length(list_of_auths)) ;
    1802       }
    1803
    1804       /* add this to the auth_vector. ( irt_item->data->value is the name of the irt  ) */
    1805       to_be_returned = add_to_auth_vector(to_be_returned, list_of_auths, (char *)value);
    1806       if(tracing)
    1807           {
    1808        printf("TRACING: get_irt_auth_vector: to_be_returned has now %d nodes\n",  g_slist_length(to_be_returned));
    1809       }
    1810
    1811           rpsl_attr_delete_list(list_of_auths);
    1812     }
    1813         free(value);
    1814         free(result);
    1815   }
    1816
    1817   if(tracing)
    1818   {
    1819     printf("TRACING: get_irt_auth_vector: to_be_returned has %i nodes\n", g_slist_length(to_be_returned));
    1820   }
    1821   return to_be_returned;
    1822 }
    1823
    1824
    1825
    1826
    1827 /* Gets a list of mntner attributes, retrieves those mntners from
    1828    the database and extracts the 'mnt-nfy' attributes, and
    1829    returns them as a GList */
    1830
    1831 GList * get_mntnfy_vector(GList *mntners)
         /* [<][>][^][v][top][bottom][index][help] */
    1832 {
    1833   GList * list_of_mntnfy = NULL;
    1834   GList * mntner_item = NULL;
    1835   GList * temp;
    1836   const GList * error_list = NULL;
    1837   char * query_string = NULL, * result = NULL, * object_str = NULL;
    1838   char *value;
    1839   rpsl_object_t *object;
    1840
    1841   for ( mntner_item = mntners; mntner_item != NULL ; mntner_item = g_list_next(mntner_item) )
    1842   {
    1843         value = rpsl_attr_get_clean_value( (rpsl_attr_t *)(mntner_item->data) );
    1844     if (tracing)
    1845         {
    1846       printf( "=====\nGot a mntner\n%s\n", value );
    1847     }
    1848     query_string = (char *)malloc(strlen("-Tmntner -s  -r ")+strlen(current_source)+strlen(value)+1);
    1849     sprintf(query_string, "-Tmntner -s %s -r %s", current_source,value);
    1850     result = send_and_get(query_host, query_port, query_string);
    1851         free(query_string);
    1852     if (count_objects(result) == 0)
    1853         {
    1854       /* no such maintainer */
    1855       if(tracing)
    1856           {
    1857         printf("get_mntnfy_vector: No such maintainer %s\n", value);
    1858       }
    1859     }
    1860         else if (count_objects(result) > 1)
    1861         {
    1862       if (tracing)
    1863           {
    1864         printf("get_mntnfy_vector: More than one objects returned for maintainer %s\n", value);
    1865       }
    1866     }
    1867         else
    1868         { /* count_objects(result) == 1 */
    1869       object_str = take_object(result);
    1870           object = rpsl_object_init(object_str);
    1871           error_list = rpsl_object_errors(object);
    1872
    1873       if (tracing)
    1874           {
    1875         printf("TRACING: get_mntnfy_vector: Calling get_attr_list\n");
    1876       }
    1877
    1878       temp = get_attr_list(object, "mnt-nfy");
    1879
    1880       if (tracing)
    1881           {
    1882         printf("TRACING: get_mntnfy_vector: get_attr_list returned (with %i nodes)\n", g_list_length(temp));
    1883       }
    1884
    1885       list_of_mntnfy = g_list_concat(list_of_mntnfy, temp);
    1886
    1887       if (tracing)
    1888           {
    1889         printf("TRACING: get_mntnfy_vector: list_of_mntnfy has now %i nodes\n", g_list_length(list_of_mntnfy));
    1890       }
    1891       rpsl_object_delete(object);
    1892     }
    1893         free(value);
    1894         free(result);
    1895   }
    1896
    1897   if (tracing)
    1898   {
    1899     printf("TRACING: get_mntnfy_vector: list_of_mntnfy has %i nodes\n", g_list_length(list_of_mntnfy));
    1900   }
    1901   return list_of_mntnfy;
    1902 }
    1903
    1904
    1905
    1906
    1907 /* Gets a list of irt attributes, retrieves those irts from
    1908    the database and extracts the 'irt-nfy' attributes, and
    1909    returns them as a GList */
    1910
    1911 GList * get_irtnfy_vector(GList *irts)
         /* [<][>][^][v][top][bottom][index][help] */
    1912 {
    1913   GList * list_of_irtnfy = NULL;
    1914   GList * irt_item = NULL;
    1915   GList * temp;
    1916   const GList * error_list = NULL;
    1917   char * query_string = NULL, * result = NULL, * object_str = NULL;
    1918   char *value;
    1919   rpsl_object_t *object;
    1920
    1921   for ( irt_item = irts; irt_item != NULL ; irt_item = g_list_next(irt_item) )
    1922   {
    1923         value = rpsl_attr_get_clean_value( (rpsl_attr_t *)(irt_item->data) );
    1924     if (tracing)
    1925         {
    1926       printf( "=====\nGot a irt\n%s\n", value );
    1927     }
    1928     query_string = (char *)malloc(strlen("-Tirt -s  -r ")+strlen(current_source)+strlen(value)+1);
    1929     sprintf(query_string, "-Tirt -s %s -r %s", current_source,value);
    1930     result = send_and_get(query_host, query_port, query_string);
    1931         free(query_string);
    1932     if (count_objects(result) == 0)
    1933         {
    1934       /* no such irt */
    1935       if(tracing)
    1936           {
    1937         printf("get_irtnfy_vector: No such irt %s\n", value);
    1938       }
    1939     }
    1940         else if (count_objects(result) > 1)
    1941         {
    1942       if (tracing)
    1943           {
    1944         printf("get_irtnfy_vector: More than one objects returned for irt %s\n", value);
    1945       }
    1946     }
    1947         else
    1948         { /* count_objects(result) == 1 */
    1949       object_str = take_object(result);
    1950           object = rpsl_object_init(object_str);
    1951           error_list = rpsl_object_errors(object);
    1952
    1953       if (tracing)
    1954           {
    1955         printf("TRACING: get_irtnfy_vector: Calling get_attr_list\n");
    1956       }
    1957
    1958       temp = get_attr_list(object, "irt-nfy");
    1959
    1960       if (tracing)
    1961           {
    1962         printf("TRACING: get_irtnfy_vector: get_attr_list returned (with %i nodes)\n", g_list_length(temp));
    1963       }
    1964
    1965       list_of_irtnfy = g_list_concat(list_of_irtnfy, temp);
    1966
    1967       if (tracing)
    1968           {
    1969         printf("TRACING: get_irtnfy_vector: list_of_irtnfy has now %i nodes\n", g_list_length(list_of_irtnfy));
    1970       }
    1971       rpsl_object_delete(object);
    1972     }
    1973         free(value);
    1974         free(result);
    1975   }
    1976
    1977   if (tracing)
    1978   {
    1979     printf("TRACING: get_irtnfy_vector: list_of_irtnfy has %i nodes\n", g_list_length(list_of_irtnfy));
    1980   }
    1981   return list_of_irtnfy;
    1982 }
    1983
    1984
    1985
    1986 /* Gets a list of mntner names, retrieves those mntners from
    1987    the database and extracts the 'upd-to' attributes, and
    1988    returns them as a GList */
    1989
    1990 GList * get_updto_vector(GList * mntners)
         /* [<][>][^][v][top][bottom][index][help] */
    1991 {
    1992   GList * list_of_updto = NULL;
    1993   GList * mntner_item = NULL;
    1994   char * query_string = NULL, * result = NULL, * object_str = NULL;
    1995   GList * temp;
    1996   const GList * error_list = NULL;
    1997   char *value;
    1998   rpsl_object_t *object;
    1999
    2000   for ( mntner_item = mntners; mntner_item != NULL ; mntner_item = g_list_next(mntner_item) )
    2001   {
    2002         value = rpsl_attr_get_clean_value( (rpsl_attr_t *)(mntner_item->data) );
    2003     if (tracing)
    2004         {
    2005       printf( "=====\nGot a mntner\n%s\n", value );
    2006     }
    2007     query_string = (char *)malloc(strlen("-Tmntner -s  -r ")+strlen(current_source)+strlen(value)+1);
    2008     sprintf(query_string, "-Tmntner -s %s -r %s", current_source,value);
    2009     result = send_and_get(query_host, query_port, query_string);
    2010     if (count_objects(result) == 0)
    2011         {
    2012       /* no such maintainer */
    2013       if(tracing)
    2014           {
    2015         printf("get_updto_vector: No such maintainer %s\n", value);
    2016       }
    2017     }
    2018         else if(count_objects(result) > 1)
    2019         {
    2020       if (tracing)
    2021           {
    2022         printf("get_updto_vector: More than one objects returned for maintainer %s\n", value);
    2023       }
    2024     }
    2025         else
    2026         { /* count_objects(result) == 1 */
    2027       object_str = take_object(result);
    2028           object = rpsl_object_init(object_str);
    2029           error_list = rpsl_object_errors(object);
    2030
    2031       if (tracing)
    2032           {
    2033         printf("TRACING: get_updto_vector: Calling get_attr_list\n");
    2034       }
    2035
    2036       temp = get_attr_list(object, "upd-to");
    2037
    2038       if (tracing)
    2039           {
    2040         printf("TRACING: get_updto_vector: get_attr_list returned (with %i nodes)\n", g_list_length(temp));
    2041       }
    2042
    2043       list_of_updto = g_list_concat(list_of_updto, temp);
    2044
    2045       if (tracing)
    2046           {
    2047         printf("TRACING: get_updto_vector: list_of_mntnfy has now %i nodes\n",  g_list_length(list_of_updto));
    2048       }
    2049       rpsl_object_delete(object);
    2050     }
    2051         free(value);
    2052         free(result);
    2053   }
    2054
    2055   if (tracing)
    2056   {
    2057     printf("TRACING: get_updto_vector: list_of_updto has %i nodes\n", g_list_length(list_of_updto));
    2058   }
    2059   return list_of_updto;
    2060 }
    2061
    2062
    2063
    2064
    2065 /* gets one or more route objects filters out the ones which don't have the same
    2066    origin as 'char * origin' argument */
    2067 char * up_filter_out_diff_origins(char * objects_str, char * origin)
         /* [<][>][^][v][top][bottom][index][help] */
    2068 {
    2069   GList * object_str_list = NULL, * object_str_item =NULL;
    2070   const GList *error_list = NULL;
    2071   char * objects_to_be_returned = NULL;
    2072   char * key = NULL;
    2073   rpsl_object_t *object;
    2074
    2075   if (tracing)
    2076   {
    2077     printf("TRACING: up_filter_out_diff_origins\n");
    2078   }
    2079
    2080   /* strip the lines beginning with '%' off */
    2081   objects_str = strip_lines(objects_str);
    2082
    2083   /* separate the objects, store them in a linked list */
    2084   object_str_list = take_objects(objects_str);
    2085
    2086   for (object_str_item = object_str_list; object_str_item != NULL; object_str_item = g_list_next(object_str_item))
    2087   {
    2088     object = rpsl_object_init((char *)(object_str_item->data));
    2089         error_list = rpsl_object_errors(object);
    2090     key = get_search_key(object, "origin");
    2091     if (key != NULL && strcasecmp(g_strstrip(origin), key) == 0)
    2092         {
    2093       if (objects_to_be_returned == NULL)
    2094           {
    2095         objects_to_be_returned = strdup((char *)(object_str_item->data));
    2096       }
    2097           else
    2098           {
    2099         objects_to_be_returned = (char *)realloc(objects_to_be_returned,
    2100                       strlen(objects_to_be_returned) + strlen((char *)(object_str_item->data)) + 2);
    2101         objects_to_be_returned = strcat(objects_to_be_returned, "\n");
    2102         objects_to_be_returned = strcat(objects_to_be_returned, (char *)(object_str_item->data));
    2103       }
    2104     }
    2105     rpsl_object_delete(object);
    2106         free(key);
    2107   }
    2108
    2109   if(tracing)
    2110   {
    2111       printf("TRACING: up_filter_out_diff_origins: returning:\n%s\n", objects_to_be_returned ? objects_to_be_returned : "(NULL)");
    2112   }
    2113
    2114   return objects_to_be_returned;
    2115 }
    2116
    2117
    2118
    2119 /* gets one or more person/role objects filters out the ones which don't have the same
    2120    nic_hdl as 'char * nic_hdl' argument */
    2121 char * up_filter_out_diff_nichdls(char * objects_str, char * nic_hdl)
         /* [<][>][^][v][top][bottom][index][help] */
    2122 {
    2123   GList * object_str_list = NULL, * object_str_item =NULL;
    2124   char * objects_to_be_returned = NULL;
    2125   char * key = NULL;
    2126   rpsl_object_t *object;
    2127
    2128   if (tracing)
    2129   {
    2130     printf("TRACING: up_filter_out_diff_nichdls\n");
    2131   }
    2132
    2133   /* strip the lines beginning with '%' off */
    2134   objects_str = strip_lines(objects_str);
    2135
    2136   /* separate the objects strings, store them in a linked list */
    2137   object_str_list = take_objects(objects_str);
    2138
    2139   for (object_str_item = object_str_list; object_str_item != NULL; object_str_item = g_list_next(object_str_item))
    2140   {
    2141     object = rpsl_object_init((char *)(object_str_item->data));
    2142     key = get_search_key(object, "nic-hdl");
    2143     if (key != NULL && strcasecmp(g_strstrip(nic_hdl), key) == 0)
    2144         {
    2145       if (objects_to_be_returned == NULL)
    2146           {
    2147         objects_to_be_returned = strdup((char *)(object_str_item->data));
    2148       }
    2149           else
    2150           {
    2151         objects_to_be_returned = (char *)realloc(objects_to_be_returned,
    2152                       strlen(objects_to_be_returned) + strlen((char *)(object_str_item->data)) + 2);
    2153         objects_to_be_returned = strcat(objects_to_be_returned, "\n");
    2154         objects_to_be_returned = strcat(objects_to_be_returned, (char *)(object_str_item->data));
    2155       }
    2156     }
    2157     rpsl_object_delete(object);
    2158   }
    2159
    2160   if(tracing)
    2161   {
    2162       printf("TRACING: up_filter_out_diff_nichdls: returning:\n%s\n", objects_to_be_returned ? objects_to_be_returned :"(NULL)");
    2163   }
    2164
    2165   return objects_to_be_returned;
    2166 }
    2167
    2168
    2169
    2170 /* gets one or more route objects, filters out the ones which have the same
    2171    origin as 'char * origin' argument */
    2172 char * UP_filter_out_same_origins(char * objects_str, rpsl_object_t * object)
         /* [<][>][^][v][top][bottom][index][help] */
    2173 {
    2174   GList * object_list = NULL, * object_item =NULL;
    2175   const GList *error_list = NULL;
    2176   char * objects_to_be_returned = NULL;
    2177   char * key = NULL;
    2178   rpsl_object_t  *obj;
    2179   char * origin;
    2180
    2181   if (tracing)
    2182   {
    2183     printf("TRACING: UP_filter_out_same_origins\n");
    2184   }
    2185
    2186   origin = get_search_key(object, "origin");
    2187
    2188   /* strip the lines beginning with '%' off */
    2189   objects_str = strip_lines(objects_str);
    2190
    2191   /* separate the objects, store them in a linked list */
    2192   object_list = take_objects(objects_str);
    2193
    2194   for (object_item = object_list; object_item != NULL; object_item = g_list_next(object_item))
    2195   {
    2196     obj = rpsl_object_init((char *)(object_item->data));
    2197         error_list = rpsl_object_errors(obj);
    2198
    2199     key = get_search_key(obj, "origin");
    2200     if (key != NULL && strcasecmp(g_strstrip(origin), key) != 0)
    2201         {
    2202       if (objects_to_be_returned == NULL)
    2203           {
    2204         objects_to_be_returned = strdup((char *)(object_item->data));
    2205       }
    2206           else
    2207           {
    2208         objects_to_be_returned = (char *)realloc(objects_to_be_returned,
    2209                       strlen(objects_to_be_returned) + strlen((char *)(object_item->data)) + 2);
    2210         objects_to_be_returned = strcat(objects_to_be_returned, "\n");
    2211         objects_to_be_returned = strcat(objects_to_be_returned, (char *)(object_item->data));
    2212       }
    2213     }
    2214         rpsl_object_delete(obj);
    2215   }
    2216
    2217   if (tracing)
    2218   {
    2219       printf("TRACING: up_filter_out_same_origins: returning:\n%s\n", objects_to_be_returned ? objects_to_be_returned : "(NULL)");
    2220   }
    2221
    2222   return objects_to_be_returned;
    2223 }
    2224
    2225
    2226
    2227 /* If the status is ALLOCATED PI or ALLOCATED PA (inetnum)
    2228    or ALLOCATED-BY-RIR (inet6num)
    2229    only valid if the maintainers in the mnt-by attributes contain
    2230    at least one of the names mentioned in ALLOCMNT config variable.
    2231    Receives an object as a parsed object
    2232             the type (inetnum or inet6num)
    2233             the new status value
    2234    Returns UP_AUTH_OK if the status/mnt-by combination is valid
    2235            UP_AUF     if the status/mnt-by combination is not valid
    2236 */
    2237 int up_check_reserved_status(rpsl_object_t *object, const char *type, char *new_status)
         /* [<][>][^][v][top][bottom][index][help] */
    2238 {
    2239   GList * mnt_by_list = NULL;
    2240   GList *item;
    2241
    2242   char *status;
    2243   char *mnt_by;
    2244   char **allocmnt_list;
    2245   int i;
    2246
    2247   /* Gather a list of mnt-by attributes */
    2248   mnt_by_list = rpsl_object_get_attr(object, "mnt-by");
    2249   rpsl_attr_split_multiple(&mnt_by_list);
    2250
    2251   status = strdup(new_status);
    2252   g_strdown(status);
    2253
    2254   /* construct a list of mntners that are in allocmnt */
    2255   allocmnt_list = g_strsplit(allocmnt, " ", 0); /* delimited by " " */
    2256
    2257   if ( (! strcmp(type, "inetnum") && strstr(status, "allocated") != NULL)
    2258       || (! strcmp(type, "inet6num") && strstr(status, "allocated-by-rir") != NULL) )
    2259   {
    2260     free(status);
    2261
    2262     for ( item = mnt_by_list; item != NULL ; item = g_list_next(item) )
    2263         {
    2264       mnt_by = rpsl_attr_get_clean_value((rpsl_attr_t *)(item->data));
    2265       for (i=0; allocmnt_list[i] != NULL; i++)
    2266           {
    2267         /* loop thru the list of allocmnt maintainers */
    2268         if ((strlen(allocmnt_list[i]) != 0) && strcasecmp(mnt_by, allocmnt_list[i]) == 0)
    2269                 {
    2270           /* this mnt-by is in the allocmnt list */
    2271           free(mnt_by);
    2272           g_strfreev(allocmnt_list);
    2273           rpsl_attr_delete_list(mnt_by_list);
    2274           return UP_AUTH_OK;
    2275         }
    2276       }
    2277       free(mnt_by);
    2278     }
    2279
    2280     g_strfreev(allocmnt_list);
    2281     rpsl_attr_delete_list(mnt_by_list);
    2282
    2283     /* none of the mnt-by are in the allocmnt list */
    2284     return UP_AUF;
    2285   }
    2286   else
    2287   {  /* the status attribute is not a reserved category */
    2288     free(status);
    2289     g_strfreev(allocmnt_list);
    2290     rpsl_attr_delete_list(mnt_by_list);
    2291
    2292     return UP_AUTH_OK;
    2293   }
    2294 }
    2295
    2296
    2297
    2298
    2299 /*  Get the value of the status of an inet(6)num object
    2300     Receives an object as a parsed object
    2301     Returns the status value or NULL if none found
    2302 */
    2303
    2304 char * up_get_status(rpsl_object_t *object)
         /* [<][>][^][v][top][bottom][index][help] */
    2305 {
    2306    GList *status_attrs;
    2307    char *status;
    2308
    2309    status_attrs = rpsl_object_get_attr(object, "status");
    2310    if ( status_attrs != NULL )
    2311    {
    2312      status = rpsl_attr_get_clean_value((rpsl_attr_t *)(status_attrs->data));
    2313      rpsl_attr_delete_list(status_attrs);
    2314      return status;
    2315    }
    2316    else
    2317      return NULL;
    2318 }
    2319
    2320
    2321
    2322 /*  Get the value of the status of the more/less specific object for an inet(6)num object
    2323     Receives an object as a parsed object
    2324              the type (inetnum or inet6num)
    2325              address of the status value pointer
    2326              flag (-m or -l)
    2327     Returns NULL   if there is no more/less specific inet(6)num object
    2328             1 if there is a more/less specific inet(6)num object
    2329             status value (or NULL if none found) set in the address
    2330 */
    2331
    2332 int up_get_specific_status(rpsl_object_t *object, const char *type, char **status, char *flag)
         /* [<][>][^][v][top][bottom][index][help] */
    2333 {
    2334    const GList *error_list = NULL;
    2335    char *specific_object_str = NULL;
    2336
    2337    rpsl_object_t *specific_obj = NULL;
    2338
    2339    /* get the one more/less specific inet(6)num object */
    2340    specific_object_str = get_specific(object, type, flag);
    2341    if (specific_object_str == NULL)
    2342    {
    2343      /* there is no more/less specific inet(6)num object */
    2344      if (tracing)
    2345      {
    2346        printf("TRACING: up_get_specific_status: no %s inet(6)num object found\n", flag);
    2347      }
    2348
    2349      *status = NULL;
    2350      return NULL;
    2351    }
    2352
    2353    /* don't try to parse the object if the -K flag was used */
    2354    if ( ! strstr(flag, "K") )
    2355    {
    2356      specific_obj = rpsl_object_init(specific_object_str);
    2357      error_list = rpsl_object_errors(specific_obj);
    2358      free (specific_object_str);
    2359
    2360      /* get the status of the more/less specific object */
    2361      *status = up_get_status(specific_obj);
    2362      rpsl_object_delete(specific_obj);
    2363    }
    2364
    2365    if (tracing)
    2366    {
    2367      printf("TRACING: up_get_specific_status: %s specific_status [%s] \n",
    2368                   flag, *status ? *status : "NONE");
    2369    }
    2370
    2371    return 1;
    2372 }
    2373
    2374 /*  Find if the inet(6)num object has any more specific objects
    2375     Receives an object as a parsed object
    2376              the type (inetnum or inet6num)
    2377     Returns NULL   if there is no more specific inet(6)num object
    2378             1 if there is a more specific inet(6)num object
    2379 */
    2380
    2381 int up_find_more_specific(rpsl_object_t *object, const char *type)
         /* [<][>][^][v][top][bottom][index][help] */
    2382 {
    2383    char *more_specific_object_str = NULL;
    2384
    2385    /* get the one more specific inet(6)num object */
    2386    more_specific_object_str = get_specific(object, type, "-m -K");
    2387    if (more_specific_object_str == NULL)
    2388      return NULL;
    2389    else
    2390    {
    2391      /* there is a more specific inet(6)num object */
    2392      if (tracing)
    2393      {
    2394        printf("TRACING: up_get_more_specific_status: more specific inet(6)num object found\n");
    2395      }
    2396
    2397      return 1;
    2398    }
    2399 }
    2400
    2401
    2402 /* check the new status and less specific status according to the defined rules for inetnum
    2403    Receives an object as a parsed object
    2404             the new status
    2405             the less specific status
    2406             flag for existance of less specific object
    2407                 (NULL - does not exist, not NULL - does exist)
    2408             the override value
    2409    Returns standard auth return codes:
    2410            UP_AUTH_OK         if all the status checks are OK
    2411            UP_HOF or UP_AUF   if any of the status checks fail
    2412 */
    2413
    2414 int up_check_inetnum_status_rules(rpsl_object_t *object, char *new_status, char *less_specific_status, int ls_obj_exists, int overriden)
         /* [<][>][^][v][top][bottom][index][help] */
    2415 {
    2416   int result;
    2417
    2418   if ( ! ls_obj_exists )
    2419   {
    2420      /* there is no less specific inetnum object */
    2421      if (overriden)
    2422      {
    2423        /* override the status check when no less specific object found */
    2424        return UP_AUTH_OK;
    2425      }
    2426      else
    2427      {
    2428        return UP_HOF; /* hierarchical authorisation failed */
    2429      }
    2430   }
    2431
    2432   if ( ! less_specific_status )
    2433   {
    2434     /* the less specific object exists but has no status value */
    2435     return UP_HOF; /* hierarchical authorisation failed */
    2436   }
    2437
    2438   /* check if the status/mnt-by combination is valid */
    2439   result = up_check_reserved_status(object, "inetnum", new_status);
    2440   if ( result != UP_AUTH_OK)
    2441     return result;
    2442
    2443   /* now check the relative status values */
    2444   if ( ! strcmp(new_status, "LIR-PARTITIONED PA") || ! strcmp(new_status, "LIR-PARTITIONED PI") )
    2445   {
    2446     if (
    2447              ( (! strcmp(new_status, "LIR-PARTITIONED PA")) && strcmp(less_specific_status, "ALLOCATED PA") && strcmp(less_specific_status, "LIR-PARTITIONED PA") && strcmp(less_specific_status, "ALLOCATED UNSPECIFIED") )
    2448            ||
    2449              ( (! strcmp(new_status, "LIR-PARTITIONED PI")) && strcmp(less_specific_status, "ALLOCATED PI") && strcmp(less_specific_status, "LIR-PARTITIONED PI") && strcmp(less_specific_status, "ALLOCATED UNSPECIFIED") )
    2450            )
    2451     {
    2452           return UP_HOF; /* hierarchical authorisation failed */
    2453     }
    2454   }
    2455
    2456   /* all check passed */
    2457   return UP_AUTH_OK;
    2458 }
    2459
    2460
    2461 /* check the new status and less specific status according to the defined rules for inet6num
    2462    Receives an object as a parsed object
    2463             the new status
    2464             the less specific status
    2465             flag for existance of less specific object
    2466                 (NULL - does not exist, not NULL - does exist)
    2467             flag for existance of more specific object
    2468             the override value
    2469    Returns standard auth return codes:
    2470            UP_AUTH_OK         if all the status checks are OK
    2471            UP_HOF or UP_AUF   if the any of status checks fail
    2472 */
    2473
    2474 int up_check_inet6num_status_rules(rpsl_object_t *object, char *new_status, char *less_specific_status, int ls_obj_exists, int ms_obj_exists, int overriden)
         /* [<][>][^][v][top][bottom][index][help] */
    2475 {
    2476   int result;
    2477
    2478   if (tracing)
    2479   {
    2480     printf("TRACING: up_check_inet6num_status_rules:\n");
    2481     printf("    new_status [%s] less_specific_status [%s]\n",
    2482                    new_status, less_specific_status ? less_specific_status : "NONE");
    2483     printf("    ls_obj_exists [%d] ms_obj_exists [%d] overriden [%d]\n",
    2484                    ls_obj_exists, ms_obj_exists, overriden);
    2485   }
    2486
    2487   if ( ! ls_obj_exists )
    2488   {
    2489      /* there is no less specific inet6num object */
    2490      if (overriden)
    2491      {
    2492        /* override the status check when no less specific object found */
    2493        return UP_AUTH_OK;
    2494      }
    2495      else
    2496      {
    2497        return UP_HOF; /* hierarchical authorisation failed */
    2498      }
    2499   }
    2500
    2501   if ( ! less_specific_status )
    2502   {
    2503     /* the less specific object has no status value */
    2504     return UP_HOF; /* hierarchical authorisation failed */
    2505   }
    2506
    2507   if ( strcasecmp(less_specific_status, "ALLOCATED-BY-RIR")
    2508     && strcasecmp(less_specific_status, "ALLOCATED-BY-LIR")
    2509     && strcasecmp(less_specific_status, "ASSIGNED") )
    2510   {
    2511     /* the less specific inet6num status is not recognised */
    2512         return UP_HOF; /* hierarchical authorisation failed */
    2513   }
    2514
    2515   /* check if the status/mnt-by combination is valid */
    2516   result = up_check_reserved_status(object, "inet6num", new_status);
    2517   if ( result != UP_AUTH_OK)
    2518     return result;
    2519
    2520   /* check the relative status rules */
    2521   if ( ! strcasecmp(new_status, "ASSIGNED") || ! strcasecmp(new_status, "ALLOCATED-BY-LIR") )
    2522   {
    2523     /* less specific status must be ALLOCATED-BY-LIR or ALLOCATED-BY-RIR */
    2524     if ( strcasecmp(less_specific_status, "ALLOCATED-BY-RIR")
    2525       && strcasecmp(less_specific_status, "ALLOCATED-BY-LIR") )
    2526     {
    2527       /* invalid status */
    2528           return UP_HOF; /* hierarchical authorisation failed */
    2529     }
    2530   }
    2531
    2532   if ( ! strcasecmp(new_status, "ASSIGNED") && ms_obj_exists )
    2533   {
    2534     /* invalid status */
    2535         return UP_HOF; /* hierarchical authorisation failed */
    2536   }
    2537
    2538   return UP_AUTH_OK;
    2539 }
    2540
    2541
    2542 /*  Check the status value of an inet(6)num object against the hierarchical rules.
    2543     Receives the new object and old (or NULL if creation) object as parsed objects.
    2544              the type (inetnum or inet6num)
    2545              the override value
    2546     Returns standard auth return codes:
    2547             UP_AUTH_OK if the status checks are OK
    2548             UP_HOF     if the status checks fail
    2549 */
    2550
    2551 int up_check_status(rpsl_object_t *new_object, rpsl_object_t *old_object, const char *type, int overriden)
         /* [<][>][^][v][top][bottom][index][help] */
    2552 {
    2553   rpsl_object_t *object;
    2554   const GList *error_list = NULL;
    2555   char *old_status = NULL;
    2556   char *new_status = NULL;
    2557   char *less_specific_status = NULL;
    2558   char *more_specific_status = NULL;
    2559   int result = NULL;
    2560   int ls_obj_exists = NULL;
    2561   int ms_obj_exists = NULL;
    2562   int update = NULL;
    2563
    2564   if (tracing)
    2565   {
    2566     printf("TRACING: up_check_status running\n");
    2567   }
    2568
    2569   if ( new_object != NULL && old_object == NULL )
    2570   {
    2571     /* this is a creation */
    2572     update = NULL;
    2573     object = new_object;
    2574   }
    2575   else if ( new_object != NULL && old_object != NULL )
    2576   {
    2577     /* this is an update */
    2578     update = 1;
    2579     object = old_object;
    2580   }
    2581   else
    2582   {
    2583     /* this is a deletion, no status checks required */
    2584     return UP_AUTH_OK;
    2585   }
    2586
    2587   /* get the status of the new inetnum object */
    2588   new_status = up_get_status(new_object);
    2589   if ( ! new_status )
    2590   {
    2591     die;  /* should not happen, syntax error should already have been trapped */
    2592   }
    2593
    2594   if ( update )
    2595   {
    2596     /* get the status of the old inetnum object */
    2597     old_status = up_get_status(old_object);
    2598     if ( ! old_status )
    2599     {
    2600           old_status = strdup("");  /* to allow for legacy objects with no status */
    2601     }
    2602   }
    2603
    2604   if (tracing)
    2605   {
    2606     printf("TRACING: check_status: old_status [%s] new status [%s]\n",
    2607                   update ? old_status : "N/A", new_status );
    2608   }
    2609
    2610   if ( ! update || strcmp(new_status, old_status) )
    2611   {
    2612     /* this is a creation or
    2613        it is an update and the status has changed,
    2614        make sure the new value is allowed */
    2615
    2616     /* get the status of the less specific and more specific objects */
    2617     ls_obj_exists = up_get_specific_status(object, type, &less_specific_status, "-l");
    2618     if ( ! strcmp(type, "inet6num") )
    2619       ms_obj_exists = up_get_specific_status(object, type, &more_specific_status, "-m -K");
    2620
    2621     if ( ! strcmp(type, "inetnum") )
    2622       result = up_check_inetnum_status_rules(object, new_status, less_specific_status, ls_obj_exists, overriden);
    2623     else
    2624       result = up_check_inet6num_status_rules(object, new_status, less_specific_status, ls_obj_exists, ms_obj_exists, overriden);
    2625
    2626     if ( less_specific_status )
    2627       free(less_specific_status);
    2628     if ( old_status )
    2629           free (old_status);
    2630     free (new_status);
    2631
    2632     return result;
    2633   }
    2634   else
    2635   {
    2636     /* update with no change in status, so no checks required */
    2637     return UP_AUTH_OK;
    2638   }
    2639 }
    2640
    2641
    2642 /* Check authorisation
    2643    Applies authorisation rules according to the object type
    2644
    2645    Arguments:
    2646       char *new_object: the new object,
    2647       char *old_object: the old object, as found in the database,
    2648       char *type: type of the object
    2649       credentials_struct credentials: a struct which
    2650         contains credentials of the update, such as 'From:' field of
    2651         the e-mail header and passwords in the update   */
    2652
    2653 int check_auth(rpsl_object_t *new_object, rpsl_object_t *old_object, const char *type, credentials_struct credentials)
         /* [<][>][^][v][top][bottom][index][help] */
    2654 {
    2655    GList *old_mntners = NULL, *new_mntners = NULL;
    2656    GList *old_irts = NULL, *new_irts = NULL;
    2657    GList *changed_irts = NULL;
    2658    GList *as_block_mnt_lowers = NULL;
    2659    GSList *old_auth_vector = NULL, *new_auth_vector = NULL;
    2660    GSList *changed_auth_vector = NULL;
    2661    GSList *as_block_auth_vector = NULL;
    2662    GSList *less_specific_auth_vector = NULL;
    2663    GList *less_specific_mnt_lowers = NULL;
    2664    GList *less_specific_mntners = NULL;
    2665    GList *aut_num_maintainers = NULL;
    2666    GSList *aut_num_auth_vector = NULL;
    2667    GList *exact_match_routes_str = NULL;
    2668    GList *exact_match_routes_maintainers = NULL;
    2669    GSList *exact_match_routes_auth_vector = NULL;
    2670    GList *exact_match_maintainers = NULL;
    2671    GSList *exact_match_auth_vector = NULL;
    2672    GList *less_spec_routes_str = NULL;
    2673    GList *less_spec_routes_mntners = NULL;
    2674    GSList *less_spec_routes_auth_vector = NULL;
    2675    GList *exact_match_inetnum_mnt_routes = NULL;
    2676    GSList *exact_match_inetnum_auth_vector = NULL;
    2677    GList *less_spec_inetnum_mntners = NULL;
    2678    GSList *less_spec_inetnum_auth_vector = NULL;
    2679    GList *less_spec_inetnum_mnt_bys = NULL;
    2680    GList *exact_match_inetnum_mnt_bys;
    2681
    2682    GList *old_name = NULL;
    2683    GList *new_name = NULL;
    2684    GList *attr;
    2685    const GList *error_list = NULL;
    2686    GList *status_attrs;
    2687
    2688    char *less_specific_status;
    2689    char *old_status;
    2690    char *new_status;
    2691    int status_result;
    2692    char *as_block_object_str = NULL;
    2693    char *less_specific_object_str = NULL;
    2694    char *less_specific_domain_str = NULL;
    2695    char *less_spec_inetnum_str = NULL;
    2696    char *exact_match_inetnum_str = NULL;
    2697    const char *less_specific_object_type = NULL;
    2698    char *override_string = NULL;
    2699    char *set_name = NULL;
    2700    char * aut_num_object_str = NULL;
    2701    char * name_old = NULL;
    2702    char * name_new = NULL;
    2703    const char *name;
    2704    int aut_num_auth_OK = FALSE;
    2705
    2706    int auth_return, saved_auth_return;
    2707    char *value;
    2708
    2709    rpsl_object_t *as_block_obj = NULL;
    2710    rpsl_object_t *less_specific_obj = NULL;
    2711    rpsl_object_t *less_specific_domain_obj = NULL;
    2712    rpsl_object_t *aut_num_obj = NULL;
    2713    rpsl_object_t *exact_match_inetnum_obj = NULL;
    2714    rpsl_object_t *less_spec_inetnum_obj = NULL;
    2715
    2716    int overriden = 0;
    2717
    2718    if (tracing)
    2719    {
    2720          printf("TRACING: check_auth is running with object type [%s]\n", type);
    2721    }
    2722
    2723    /* first check if it is overriden or not. if overriden, check the override
    2724       password. If it is correct, continue, setting "overriden" to 1. If not,
    2725       immediately exit returning ERR_UP_OVF                                   */
    2726    override_string = get_override((new_object == NULL) ? old_object : new_object );
    2727    if(override_string == NULL)
    2728    {
    2729          if (tracing)
    2730          {
    2731            printf("TRACING: overriden not set\n");
    2732          }
    2733      overriden = 0;
    2734    }
    2735    else if ( check_override(override_string) == OVR_OK )
    2736    {
    2737          if (tracing)
    2738          {
    2739            printf("TRACING: overriden set\n");
    2740          }
    2741      overriden = 1; /* authorisation is overriden */
    2742      free(override_string);
    2743          override_string = NULL;
    2744    }
    2745    else
    2746    {
    2747          if (tracing)
    2748          {
    2749            printf("TRACING: override failed\n");
    2750          }
    2751      free(override_string);
    2752          override_string = NULL;
    2753      return UP_OVF; /* override failed! */
    2754    }
    2755
    2756
    2757    /*
    2758     *  Handle the "person", "role", "limerick", "inet-rtr", "key-cert" types
    2759     */
    2760    if(strcmp(type,"person")   == 0 || strcmp(type,"role")     == 0 ||
    2761       strcmp(type,"limerick") == 0 || strcmp(type,"inet-rtr") == 0 ||
    2762       strcmp(type,"key-cert") == 0 )
    2763    {
    2764      if( new_object == NULL && old_object != NULL )
    2765          { /* the object is to be deleted */
    2766        old_mntners = get_mntners(old_object);
    2767        old_auth_vector = get_auth_vector(old_mntners);
    2768        if (old_mntners != NULL && old_auth_vector == NULL)
    2769            {
    2770          /* then, the mntners in 'old_mntners' do not exist. Problem. */
    2771                  rpsl_attr_delete_list(old_mntners);
    2772          return UP_AUF; /* auth failed */
    2773        }
    2774        auth_return = authorise(old_auth_vector, credentials, overriden);
    2775        if (old_auth_vector)
    2776              g_slist_free(old_auth_vector);
    2777            return auth_return;
    2778      }
    2779          else if ( new_object != NULL && old_object == NULL )
    2780          { /* the object is to be created */
    2781        new_mntners = get_mntners(new_object);
    2782        new_auth_vector = get_auth_vector(new_mntners);
    2783        if(new_mntners != NULL && new_auth_vector == NULL)
    2784            {
    2785          /* then, the mntners in 'new_mntners' do not exist. Problem. */
    2786                  rpsl_attr_delete_list(new_mntners);
    2787          return UP_AUF; /* auth failed */
    2788        }
    2789        auth_return = authorise(new_auth_vector, credentials, overriden);
    2790            if (new_auth_vector)
    2791              g_slist_free(new_auth_vector);
    2792            return auth_return;
    2793      }
    2794          else if ( new_object != NULL && old_object != NULL )
    2795          { /* this is an update */
    2796        /* check name change of person/role */
    2797        if ( strcmp(type,"person") == 0 || strcmp(type,"role") == 0 )
    2798            {
    2799          old_name = get_attr_list(old_object, type);
    2800          new_name = get_attr_list(new_object, type);
    2801
    2802          if(old_name != NULL && new_name != NULL
    2803              && g_list_nth(old_name, 0) != NULL && g_list_nth(new_name, 0) != NULL
    2804              && (g_list_nth(old_name, 0)->data) != NULL
    2805              && (g_list_nth(new_name, 0)->data) != NULL)
    2806          {
    2807
    2808            name_old = rpsl_attr_get_clean_value((rpsl_attr_t *)(g_list_nth(old_name, 0)->data));
    2809            name_new = rpsl_attr_get_clean_value((rpsl_attr_t *)(g_list_nth(new_name, 0)->data));
    2810                    rpsl_attr_delete_list(old_name);
    2811                    rpsl_attr_delete_list(new_name);
    2812
    2813            if ( strcmp(name_old, name_new) )
    2814                    {
    2815              free(name_old); free(name_new);
    2816              return UP_NAM; /* name of a person/role object can't be changed */
    2817            }
    2818            free(name_old);free(name_new);
    2819          }
    2820                  else
    2821                  {
    2822                    rpsl_attr_delete_list(old_name);
    2823                    rpsl_attr_delete_list(new_name);
    2824            return UP_INT; /* there was a problem with obtaining the name of person obj */
    2825          }
    2826        }
    2827
    2828        old_mntners = get_mntners(old_object);
    2829        old_auth_vector = get_auth_vector(old_mntners);
    2830        if (old_mntners != NULL && old_auth_vector == NULL)
    2831            {
    2832          /* then, the mntners in 'old_mntners' do not exist. Problem. */
    2833                  rpsl_attr_delete_list(old_mntners);
    2834          return UP_AUF; /* auth failed */
    2835        }
    2836        if (old_auth_vector)
    2837            { /* if we have mntners in the old object, use them */
    2838          auth_return = authorise(old_auth_vector, credentials, overriden);
    2839              g_slist_free(old_auth_vector);
    2840              return auth_return;
    2841        }
    2842            else
    2843            {
    2844          new_mntners = get_mntners(new_object);
    2845          new_auth_vector = get_auth_vector(new_mntners);
    2846          if (new_mntners != NULL && new_auth_vector == NULL)
    2847                  {
    2848            /* then, the mntners in 'new_mntners' do not exist. Problem. */
    2849                    rpsl_attr_delete_list(new_mntners);
    2850            return UP_AUF; /* auth failed */
    2851          }
    2852          auth_return = authorise(new_auth_vector, credentials, overriden);
    2853                  if (new_auth_vector)
    2854                g_slist_free(new_auth_vector);
    2855              return auth_return;
    2856        }
    2857      }
    2858          else
    2859          { /* both are NULL, mustn't happen */
    2860          if (tracing)
    2861                  {
    2862            printf("TRACING: check_auth: internal error: Both pointers are NULL\n");
    2863          }
    2864          return UP_INT; /* internal error */
    2865      }
    2866    }
    2867
    2868    /*
    2869     *  Handle the "aut-num" type
    2870     */
    2871    else if (strcmp(type,"aut-num")  == 0 )
    2872    {
    2873      if ( new_object == NULL && old_object != NULL )
    2874          { /* the object is to be deleted */
    2875        old_mntners = get_mntners(old_object);
    2876        old_auth_vector = get_auth_vector(old_mntners);
    2877        if (old_mntners != NULL && old_auth_vector == NULL)
    2878            {
    2879          /* then, the mntners in 'old_mntners' do not exist. Problem. */
    2880                  rpsl_attr_delete_list(old_mntners);
    2881          return UP_AUF; /* auth failed */
    2882        }
    2883        auth_return = authorise(old_auth_vector, credentials, overriden);
    2884            g_slist_free(old_auth_vector);
    2885            return auth_return;
    2886      }
    2887          else if ( new_object != NULL && old_object == NULL )
    2888          { /* the object is to be created */
    2889        as_block_object_str = get_as_block(new_object);
    2890        if (as_block_object_str == NULL )
    2891            {
    2892          return UP_ABN; /* As-block does not exist */
    2893        }
    2894            else
    2895            {
    2896              as_block_obj = rpsl_object_init(as_block_object_str);
    2897                  if (tracing)
    2898                  {
    2899            if ( rpsl_object_has_error(as_block_obj, RPSL_ERRLVL_ERROR) )
    2900                    {
    2901                          /* thre was an error during the parsing */
    2902                          name = rpsl_object_get_class(as_block_obj);
    2903                          if ( name )
    2904                          {
    2905                            attr = rpsl_object_get_attr(as_block_obj, name);
    2906                            if ( attr )
    2907                            {
    2908                          value = rpsl_attr_get_clean_value( (rpsl_attr_t *)(attr->data) );
    2909                                  if ( value )
    2910                                  {
    2911                            printf("TRACING: get_mnt_routes_from_list: error parsing as_block object %s\n", value );
    2912                                    free(value);
    2913                                  }
    2914                                  else
    2915                            printf("TRACING: get_mnt_routes_from_list: error parsing as_block object\n");
    2916
    2917                                  rpsl_attr_delete_list(attr);
    2918                            }
    2919                          }
    2920                    }
    2921                  }
    2922
    2923          as_block_mnt_lowers = get_mnt_lowers(as_block_obj);
    2924          as_block_auth_vector = get_auth_vector(as_block_mnt_lowers);
    2925                  rpsl_object_delete(as_block_obj);
    2926          if (as_block_mnt_lowers != NULL && as_block_auth_vector == NULL)
    2927                  {
    2928            /* then, the mntners in 'as_block_mnt_lowers' do not exist. Problem. */
    2929                    rpsl_attr_delete_list(as_block_mnt_lowers);
    2930            return UP_AUF; /* auth failed */
    2931          }
    2932          auth_return = authorise(as_block_auth_vector, credentials, overriden);
    2933          if (auth_return == UP_AUTH_OK || auth_return == UP_OKM)
    2934                  {
    2935            saved_auth_return = auth_return;
    2936            new_mntners = get_mntners(new_object);
    2937            new_auth_vector = get_auth_vector(new_mntners);
    2938            if(new_mntners != NULL && new_auth_vector == NULL)
    2939                    {
    2940              /* then, the mntners in 'new_auth_vector' do not exist. Problem. */
    2941                      rpsl_attr_delete_list(new_mntners);
    2942              return UP_AUF; /* auth failed */
    2943            }
    2944            auth_return = authorise(new_auth_vector, credentials, overriden);
    2945                    if (new_auth_vector)
    2946                  g_slist_free(new_auth_vector);
    2947            if ( auth_return == UP_AUTH_OK && saved_auth_return == UP_OKM)
    2948              return UP_OKM;
    2949            else
    2950              return auth_return;
    2951          }
    2952                  else
    2953                  {
    2954            return UP_HOF; /* hierarchical auth failed */
    2955          }
    2956        }
    2957      }
    2958          else if( new_object != NULL && old_object != NULL )
    2959          { /* this is an update */
    2960        old_mntners = get_mntners(old_object);
    2961        old_auth_vector = get_auth_vector(old_mntners);
    2962        if (old_mntners != NULL && old_auth_vector == NULL)
    2963            {
    2964          /* then, the mntners in 'old_mntners' do not exist. Problem. */
    2965                  rpsl_attr_delete_list(old_mntners);
    2966          return UP_AUF; /* auth failed */
    2967        }
    2968        if (old_auth_vector)
    2969            { /* if we have mntners in the old object, use them */
    2970          auth_return = authorise(old_auth_vector, credentials, overriden);
    2971              g_slist_free(old_auth_vector);
    2972              return auth_return;
    2973        }
    2974            else
    2975            {
    2976          new_mntners = get_mntners(new_object);
    2977          new_auth_vector = get_auth_vector(new_mntners);
    2978          if (new_mntners != NULL && new_auth_vector == NULL)
    2979                  {
    2980            /* then, the mntners in 'new_mntners' do not exist. Problem. */
    2981                    rpsl_attr_delete_list(new_mntners);
    2982            return UP_AUF; /* auth failed */
    2983          }
    2984          auth_return = authorise(new_auth_vector, credentials, overriden);
    2985                  if (new_auth_vector)
    2986            g_slist_free(new_auth_vector);
    2987              return auth_return;
    2988        }
    2989      }
    2990          else
    2991          { /* both are NULL, mustn't happen */
    2992          if(tracing)
    2993                  {
    2994            printf("TRACING: check_auth: internal error: Both pointers are NULL\n");
    2995          }
    2996          return UP_INT; /* internal error */
    2997      }
    2998    }
    2999
    3000    /*
    3001     *  Handle the "mntner/as-block/irt" types
    3002     */
    3003    else if (strcmp(type,"mntner")  == 0 || strcmp(type,"as-block")  == 0 || strcmp(type,"irt")  == 0 )
    3004    {
    3005      if ( new_object == NULL && old_object != NULL )
    3006          { /* the object is to be deleted */
    3007        old_mntners = get_mntners(old_object);
    3008        old_auth_vector = get_auth_vector(old_mntners);
    3009        if (old_mntners != NULL && old_auth_vector == NULL)
    3010            {
    3011          /* then, the mntners in 'old_mntners' do not exist. Problem. */
    3012                  rpsl_attr_delete_list(old_mntners);
    3013          return UP_AUF; /* auth failed */
    3014        }
    3015        auth_return = authorise(old_auth_vector, credentials, overriden);
    3016            g_slist_free(old_auth_vector);
    3017            return auth_return;
    3018      }
    3019          else if ( new_object != NULL && old_object == NULL )
    3020          { /* the object is to be created */
    3021        if (overriden || test_mode)
    3022            {
    3023          return UP_AUTH_OK;
    3024        }
    3025            else
    3026            { /* If not overriden, must be forwarded to <HUMAILBOX> */
    3027          if (tracing)
    3028                  {
    3029            printf("TRACING: check_auth: '%s' creation requested\n", type);
    3030          }
    3031          return UP_FWD; /* must be forwarded to <HUMAILBOX> */
    3032        }
    3033      }
    3034          else if ( new_object != NULL && old_object != NULL )
    3035          { /* this is an update */
    3036        old_mntners = get_mntners(old_object);
    3037        old_auth_vector = get_auth_vector(old_mntners);
    3038        if (old_mntners != NULL && old_auth_vector == NULL)
    3039            {
    3040          /* then, the mntners in 'old_mntners' do not exist. Problem. */
    3041                  rpsl_attr_delete_list(old_mntners);
    3042          return UP_AUF; /* auth failed */
    3043        }
    3044        if (old_auth_vector)
    3045            { /* if we have mntners in the old object, use them */
    3046          auth_return = authorise(old_auth_vector, credentials, overriden);
    3047              g_slist_free(old_auth_vector);
    3048              return auth_return;
    3049        }
    3050            else
    3051            {
    3052          new_mntners = get_mntners(new_object);
    3053          new_auth_vector = get_auth_vector(new_mntners);
    3054          if (new_mntners != NULL && new_auth_vector == NULL)
    3055                  {
    3056            /* then, the mntners in 'new_mntners' do not exist. Problem. */
    3057                    rpsl_attr_delete_list(new_mntners);
    3058            return UP_AUF; /* auth failed */
    3059          }
    3060          auth_return = authorise(new_auth_vector, credentials, overriden);
    3061                  if (new_auth_vector)
    3062                g_slist_free(new_auth_vector);
    3063              return auth_return;
    3064        }
    3065      }
    3066          else
    3067          { /* both are NULL, mustn't happen */
    3068          if (tracing)
    3069                  {
    3070            printf("TRACING: check_auth: internal error: Both pointers are NULL\n");
    3071          }
    3072          return UP_INT; /* internal error */
    3073      }
    3074    }
    3075
    3076    /*
    3077     *  Handle the "inetnum/inet6num" types
    3078     */
    3079    else if (strcmp(type,"inetnum")  == 0 || strcmp(type,"inet6num")  == 0 )
    3080    {
    3081      if ( new_object == NULL && old_object != NULL )
    3082          {
    3083        /* the object is to be deleted */
    3084        /* dont check for mnt-irt on deletion */
    3085
    3086        /******* status check **********/
    3087        status_result = up_check_status(new_object, old_object, type, overriden);
    3088        if ( status_result != UP_AUTH_OK )
    3089          return status_result;
    3090
    3091        /******* mntner check **********/
    3092        old_mntners = get_mntners(old_object);
    3093        old_auth_vector = get_auth_vector(old_mntners);
    3094        if (old_mntners != NULL && old_auth_vector == NULL)
    3095            {
    3096          /* then, the mntners in 'old_mntners' do not exist. Problem. */
    3097                  rpsl_attr_delete_list(old_mntners);
    3098          return UP_AUF; /* auth failed */
    3099        }
    3100        auth_return = authorise(old_auth_vector, credentials, overriden);
    3101            g_slist_free(old_auth_vector);
    3102            return auth_return;
    3103      }
    3104          else if ( new_object != NULL && old_object == NULL )
    3105          {
    3106        /* the object is to be created */
    3107        /******* irt check **********/
    3108            /* if an object is created with an mnt-irt attribute, then it must
    3109           pass the authorisation for the mnt-irt */
    3110        new_irts = get_irts(new_object);
    3111        new_auth_vector = get_irt_auth_vector(new_irts);
    3112        if (new_irts != NULL && new_auth_vector == NULL)
    3113            {
    3114          /* then, the irts in 'new_irts' do not exist. Problem. */
    3115                  rpsl_attr_delete_list(new_irts);
    3116          return UP_AUF; /* auth failed */
    3117        }
    3118        auth_return = authorise(new_auth_vector, credentials, overriden);
    3119            if (new_auth_vector)
    3120              g_slist_free(new_auth_vector);
    3121        rpsl_attr_delete_list(new_irts);
    3122            if ( auth_return == UP_AUF || auth_return == UP_MFF || auth_return == UP_MIX )
    3123            {
    3124              return UP_HOF; /* hierarchical authorisation failed */
    3125            }
    3126
    3127        /* get the one less specific inet(6)num object */
    3128        less_specific_object_str = get_specific(new_object, type, "-l");
    3129        if (less_specific_object_str == NULL)
    3130            {
    3131          /* there is no less specific object, fail if not overriden */
    3132          if ( ! overriden )
    3133                  {
    3134            return UP_HOF; /* hierarchical authorisation failed */
    3135          }
    3136        }
    3137            else
    3138            { /* we got a less specific inet(6)num object */
    3139              less_specific_obj = rpsl_object_init(less_specific_object_str);
    3140              error_list = rpsl_object_errors(less_specific_obj);
    3141                  if (tracing)
    3142                  {
    3143            if ( rpsl_object_has_error(less_specific_obj, RPSL_ERRLVL_ERROR) )
    3144                    {
    3145                          /* thre was an error during the parsing */
    3146                          name = rpsl_object_get_class(less_specific_obj);
    3147                          if ( name )
    3148                          {
    3149                            attr = rpsl_object_get_attr(less_specific_obj, name);
    3150                            if ( attr )
    3151                            {
    3152                          value = rpsl_attr_get_clean_value( (rpsl_attr_t *)(attr->data) );
    3153                                  if ( value )
    3154                                  {
    3155                            printf("TRACING: check_auth: error parsing object %s\n", value );
    3156                                    free(value);
    3157                                  }
    3158                                  else
    3159                            printf("TRACING: check_auth: error parsing object\n");
    3160
    3161                                  rpsl_attr_delete_list(attr);
    3162                            }
    3163                          }
    3164                    }
    3165                  }
    3166
    3167          /******* status check **********/
    3168          status_result = up_check_status(new_object, old_object, type, overriden);
    3169          if ( status_result != UP_AUTH_OK )
    3170          {
    3171                    rpsl_object_delete(less_specific_obj);
    3172            return status_result;
    3173          }
    3174
    3175          /******* less_specific check **********/
    3176          less_specific_mnt_lowers = get_mnt_lowers(less_specific_obj);
    3177          less_specific_auth_vector = get_auth_vector(less_specific_mnt_lowers);
    3178                  rpsl_object_delete(less_specific_obj);
    3179
    3180          if (less_specific_mnt_lowers != NULL && less_specific_auth_vector == NULL)
    3181                  {
    3182            /* then, the mntners in 'less_specific_mnt_lowers' do not exist. Problem. */
    3183                    rpsl_attr_delete_list(less_specific_mnt_lowers);
    3184            return UP_AUF; /* auth failed */
    3185          }
    3186          auth_return = authorise(less_specific_auth_vector, credentials, overriden);
    3187          if (less_specific_auth_vector != NULL)
    3188          {
    3189                    g_slist_free(less_specific_auth_vector);
    3190          }
    3191          if (auth_return == UP_AUTH_OK || auth_return == UP_OKM)
    3192                  {
    3193            /******* mntner check **********/
    3194            new_mntners = get_mntners(new_object);
    3195            new_auth_vector = get_auth_vector(new_mntners);
    3196            if (new_mntners != NULL && new_auth_vector == NULL)
    3197                    {
    3198              /* then, the mntners in 'new_mntners' do not exist. Problem. */
    3199                      rpsl_attr_delete_list(new_mntners);
    3200              return UP_AUF; /* auth failed */
    3201            }
    3202            auth_return = authorise(new_auth_vector, credentials, overriden);
    3203                    if (new_auth_vector)
    3204                  g_slist_free(new_auth_vector);
    3205                return auth_return;
    3206          }
    3207                  else
    3208                  {
    3209            return UP_HOF; /* hierarchical authorisation failed */
    3210          }
    3211        }
    3212      }
    3213          else if ( new_object != NULL && old_object != NULL )
    3214          {
    3215        /* this is an update */
    3216        /******* status check **********/
    3217        status_result = up_check_status(new_object, old_object, type, overriden);
    3218        if ( status_result != UP_AUTH_OK )
    3219          return status_result;
    3220
    3221        /******* irt check **********/
    3222            /* check for mnt-irt in both old and new object */
    3223        /* it only needs to pass the authorisation of an mnt-irt when the
    3224           mnt-irt is first added to the object */
    3225        old_irts = get_irts(old_object);
    3226        new_irts = get_irts(new_object);
    3227        /* find irts that have just been added to this object */
    3228        changed_irts = NT_compare_lists(old_irts, new_irts, 2);  /* 2 means 'just added' */
    3229
    3230        changed_auth_vector = get_irt_auth_vector(changed_irts);
    3231        if (changed_irts != NULL && changed_auth_vector == NULL)
    3232            {
    3233          /* then, the irts in 'changed_irts' do not exist. Problem. */
    3234          rpsl_attr_delete_list(old_irts);
    3235          rpsl_attr_delete_list(new_irts);
    3236          return UP_AUF; /* auth failed */
    3237        }
    3238        auth_return = authorise(changed_auth_vector, credentials, overriden);
    3239            g_slist_free(changed_auth_vector);
    3240        rpsl_attr_delete_list(old_irts);
    3241        rpsl_attr_delete_list(new_irts);
    3242            if ( auth_return == UP_AUF || auth_return == UP_MFF || auth_return == UP_MIX)
    3243            {
    3244              return UP_HOF; /* hierarchical authorisation failed */
    3245            }
    3246
    3247        /******* mntner check **********/
    3248        old_mntners = get_mntners(old_object);
    3249        old_auth_vector = get_auth_vector(old_mntners);
    3250        if (old_mntners != NULL && old_auth_vector == NULL)
    3251            {
    3252          /* then, the mntners in 'old_mntners' do not exist. Problem. */
    3253                  rpsl_attr_delete_list(old_mntners);
    3254          return UP_AUF; /* auth failed */
    3255        }
    3256        if (old_auth_vector)
    3257            { /* if we have mntners in the old object, use them */
    3258          auth_return = authorise(old_auth_vector, credentials, overriden);
    3259              g_slist_free(old_auth_vector);
    3260              return auth_return;
    3261        }
    3262            else
    3263            {
    3264          new_mntners = get_mntners(new_object);
    3265          new_auth_vector = get_auth_vector(new_mntners);
    3266          if (new_mntners != NULL && new_auth_vector == NULL)
    3267                  {
    3268            /* then, the mntners in 'new_mntners' do not exist. Problem. */
    3269                    rpsl_attr_delete_list(new_mntners);
    3270            return UP_AUF; /* auth failed */
    3271          }
    3272          auth_return = authorise(new_auth_vector, credentials, overriden);
    3273                  if (new_auth_vector)
    3274                g_slist_free(new_auth_vector);
    3275              return auth_return;
    3276        }
    3277      }
    3278          else
    3279          { /* both are NULL, mustn't happen */
    3280          if (tracing)
    3281                  {
    3282            printf("TRACING: check_auth: internal error: Both pointers are NULL\n");
    3283          }
    3284          return UP_INT; /* internal error */
    3285      }
    3286    }
    3287
    3288    /*
    3289     *  Handle the "domain" type
    3290     */
    3291    else if (strcmp(type,"domain")  == 0)
    3292    {
    3293      if ( new_object == NULL && old_object != NULL )
    3294          { /* the object is to be deleted */
    3295        old_mntners = get_mntners(old_object);
    3296        old_auth_vector = get_auth_vector(old_mntners);
    3297        if (old_mntners != NULL && old_auth_vector == NULL)
    3298            {
    3299          /* then, the mntners in 'old_mntners' do not exist. Problem. */
    3300                  rpsl_attr_delete_list(old_mntners);
    3301          return UP_AUF; /* auth failed */
    3302        }
    3303        auth_return = authorise(old_auth_vector, credentials, overriden);
    3304            g_slist_free(old_auth_vector);
    3305            return auth_return;
    3306      }
    3307          else if ( new_object != NULL && old_object == NULL )
    3308          { /* the object is to be created */
    3309        /* now, we have to find a 'less specific domain object' for this.
    3310           If there is no less specific object, then creation is possible
    3311           only with overriding. */
    3312       less_specific_domain_str = get_less_specific_domain(new_object);
    3313       if (less_specific_domain_str == NULL)
    3314           {
    3315         if (overriden)
    3316                 {/* we didn't get a 'less specific' domain object */
    3317            return UP_AUTH_OK;
    3318          }
    3319                  else
    3320                  {
    3321            return UP_HOF; /* hierarchical authorisation failed */
    3322          }
    3323       }
    3324           else
    3325           { /* we get a 'less specific' domain object */
    3326              less_specific_domain_obj = rpsl_object_init(less_specific_domain_str);
    3327                  if (tracing)
    3328                  {
    3329            if ( rpsl_object_has_error(less_specific_domain_obj, RPSL_ERRLVL_ERROR) )
    3330                    {
    3331                          /* thre was an error during the parsing */
    3332                          name = rpsl_object_get_class(less_specific_domain_obj);
    3333                          if ( name )
    3334                          {
    3335                            attr = rpsl_object_get_attr(less_specific_domain_obj, name);
    3336                            if ( attr )
    3337                            {
    3338                          value = rpsl_attr_get_clean_value( (rpsl_attr_t *)(attr->data) );
    3339                                  if ( value )
    3340                                  {
    3341                            printf("TRACING: get_mnt_routes_from_list: error parsing object %s\n", value );
    3342                                    free(value);
    3343                                  }
    3344                                  else
    3345                            printf("TRACING: get_mnt_routes_from_list: error parsing object\n");
    3346
    3347                                  rpsl_attr_delete_list(attr);
    3348                            }
    3349                          }
    3350                    }
    3351                  }
    3352
    3353          less_specific_mnt_lowers = get_mnt_lowers(less_specific_domain_obj);
    3354          less_specific_auth_vector = get_auth_vector(less_specific_mnt_lowers);
    3355          rpsl_object_delete(less_specific_domain_obj);
    3356
    3357          if (less_specific_mnt_lowers != NULL && less_specific_auth_vector == NULL)
    3358                  {
    3359            /* then, the mntners in 'less_specific_mnt_lowers' do not exist. Problem. */
    3360                    rpsl_attr_delete_list(less_specific_mnt_lowers);
    3361            return UP_AUF; /* auth failed */
    3362          }
    3363          auth_return = authorise(less_specific_auth_vector, credentials, overriden);
    3364          if (auth_return == UP_AUTH_OK || auth_return == UP_OKM)
    3365                  {
    3366            saved_auth_return = auth_return;
    3367            new_mntners = get_mntners(new_object);
    3368            new_auth_vector = get_auth_vector(new_mntners);
    3369            if (new_mntners != NULL && new_auth_vector == NULL)
    3370                    {
    3371              /* then, the mntners in 'new_mntners' do not exist. Problem. */
    3372                      rpsl_attr_delete_list(new_mntners);
    3373              return UP_AUF; /* auth failed */
    3374            }
    3375            auth_return = authorise(new_auth_vector, credentials, overriden);
    3376                    if (new_auth_vector)
    3377                  g_slist_free(new_auth_vector);
    3378            if ( auth_return == UP_AUTH_OK && saved_auth_return == UP_OKM )
    3379              return UP_OKM;
    3380            else
    3381                  return auth_return;
    3382          }
    3383                  else
    3384                  {
    3385            return UP_HOF; /* hierarchical authorisation failed */
    3386          }
    3387       }
    3388      }
    3389          else if ( new_object != NULL && old_object != NULL )
    3390          { /* this is an update */
    3391        old_mntners = get_mntners(old_object);
    3392        old_auth_vector = get_auth_vector(old_mntners);
    3393        if (old_mntners != NULL && old_auth_vector == NULL)
    3394            {
    3395          /* then, the mntners in 'old_mntners' do not exist. Problem. */
    3396                  rpsl_attr_delete_list(old_mntners);
    3397          return UP_AUF; /* auth failed */
    3398        }
    3399        if (old_auth_vector)
    3400            { /* if we have mntners in the old object, use them */
    3401          auth_return = authorise(old_auth_vector, credentials, overriden);
    3402              g_slist_free(old_auth_vector);
    3403              return auth_return;
    3404        }
    3405            else
    3406            {
    3407          new_mntners = get_mntners(new_object);
    3408          new_auth_vector = get_auth_vector(new_mntners);
    3409          if (new_mntners != NULL && new_auth_vector == NULL)
    3410                  {
    3411            /* then, the mntners in 'new_mntners' do not exist. Problem. */
    3412                    rpsl_attr_delete_list(new_mntners);
    3413            return UP_AUF; /* auth failed */
    3414          }
    3415          auth_return = authorise(new_auth_vector, credentials, overriden);
    3416                  if (new_auth_vector)
    3417                g_slist_free(new_auth_vector);
    3418              return auth_return;
    3419        }
    3420      }
    3421          else
    3422          { /* both are NULL, mustn't happen */
    3423          if (tracing)
    3424                  {
    3425            printf("TRACING: check_auth: internal error: Both pointers are NULL\n");
    3426          }
    3427          return UP_INT; /* internal error */
    3428      }
    3429    }
    3430
    3431
    3432    /*
    3433     *  Handle the "route" type
    3434     */
    3435    else if (strcmp(type,"route")  == 0)
    3436    {
    3437      if ( new_object == NULL && old_object != NULL )
    3438          { /* the object is to be deleted */
    3439        old_mntners = get_mntners(old_object);
    3440        old_auth_vector = get_auth_vector(old_mntners);
    3441        if (old_mntners != NULL && old_auth_vector == NULL)
    3442            {
    3443          /* then, the mntners in 'old_mntners' do not exist. Problem. */
    3444                  rpsl_attr_delete_list(old_mntners);
    3445          return UP_AUF; /* auth failed */
    3446        }
    3447        auth_return = authorise(old_auth_vector, credentials, overriden);
    3448            g_slist_free(old_auth_vector);
    3449            return auth_return;
    3450      }
    3451          else if ( new_object != NULL && old_object == NULL )
    3452          { /* the object is to be created */
    3453        /* first we have to find the aut-num object mentioned in the
    3454           origin attribute */
    3455
    3456        aut_num_object_str = get_aut_num_object(new_object);
    3457        if (aut_num_object_str == NULL)
    3458            {
    3459          if (overriden)
    3460                  {
    3461            return UP_AUTH_OK;
    3462          }
    3463                  else
    3464                  {
    3465            return UP_HOF; /* hierarchical authorisation failed */
    3466          }
    3467        }
    3468            else
    3469            { /* there is a corresponding aut-num in the db */
    3470          if (tracing)
    3471                  {
    3472            printf("TRACING: check_auth: will try to authorise the route using aut-num\n");
    3473          }
    3474              aut_num_obj = rpsl_object_init(aut_num_object_str);
    3475                  if (tracing)
    3476                  {
    3477            if ( rpsl_object_has_error(aut_num_obj, RPSL_ERRLVL_ERROR) )
    3478                    {
    3479                          /* thre was an error during the parsing */
    3480                          name = rpsl_object_get_class(aut_num_obj);
    3481                          if ( name )
    3482                          {
    3483                            attr = rpsl_object_get_attr(aut_num_obj, name);
    3484                            if ( attr )
    3485                            {
    3486                          value = rpsl_attr_get_clean_value( (rpsl_attr_t *)(attr->data) );
    3487                                  if ( value )
    3488                                  {
    3489                            printf("TRACING: get_mnt_routes_from_list: error parsing object %s\n", value );
    3490                                    free(value);
    3491                                  }
    3492                                  else
    3493                            printf("TRACING: get_mnt_routes_from_list: error parsing object\n");
    3494
    3495                                  rpsl_attr_delete_list(attr);
    3496                            }
    3497                          }
    3498                    }
    3499                  }
    3500
    3501          aut_num_maintainers = get_mnt_routes(aut_num_obj);
    3502          if (aut_num_maintainers != NULL)
    3503                  {
    3504            aut_num_auth_vector = get_auth_vector(aut_num_maintainers);
    3505            auth_return = authorise(aut_num_auth_vector, credentials, overriden);
    3506            if (auth_return == UP_AUTH_OK || auth_return == UP_OKM)
    3507                    {
    3508              aut_num_auth_OK = TRUE;
    3509            }
    3510                    else
    3511                    {/* authorise(aut_num_auth_vector, credentials, overriden) != UP_AUTH_OK */
    3512                      rpsl_attr_delete_list(aut_num_maintainers);
    3513              return UP_HOF;
    3514            }
    3515          }
    3516                  else
    3517                  {/* aut_num_maintainers is NULL */
    3518             aut_num_maintainers = get_mnt_lowers(aut_num_obj);
    3519             if (aut_num_maintainers != NULL)
    3520                         {
    3521               aut_num_auth_vector = get_auth_vector(aut_num_maintainers);
    3522               auth_return = authorise(aut_num_auth_vector, credentials, overriden);
    3523               if (auth_return == UP_AUTH_OK || auth_return == UP_OKM)
    3524                           {
    3525                 aut_num_auth_OK = TRUE;
    3526               }
    3527                           else
    3528                           {/* authorise(aut_num_auth_vector, credentials, overriden) != UP_AUTH_OK */
    3529                         rpsl_attr_delete_list(aut_num_maintainers);
    3530                 return UP_HOF; /* hierarchical authorisation failed */
    3531               }
    3532             }
    3533                         else
    3534                         {/* aut_num_maintainers is NULL */
    3535               aut_num_maintainers = get_mntners(aut_num_obj);
    3536               if (aut_num_maintainers != NULL)
    3537                           {
    3538                 aut_num_auth_vector = get_auth_vector(aut_num_maintainers);
    3539                 auth_return = authorise(aut_num_auth_vector, credentials, overriden);
    3540                 if (auth_return == UP_AUTH_OK || auth_return == UP_OKM)
    3541                                 {
    3542                   aut_num_auth_OK = TRUE;
    3543                 }
    3544                                 else
    3545                                 {/* authorise(aut_num_auth_vector, credentials, overriden) != UP_AUTH_OK */
    3546                           rpsl_attr_delete_list(aut_num_maintainers);
    3547                   return UP_HOF; /* hierarchical authorisation failed */
    3548                 }
    3549               }
    3550                           else
    3551                           {/* aut_num_maintainers is NULL */
    3552                 aut_num_auth_OK = TRUE;
    3553               }
    3554
    3555             }
    3556          }
    3557          rpsl_object_delete(aut_num_obj);
    3558
    3559          if (aut_num_auth_OK)
    3560                  {
    3561            /* now, we have to find an exact match for this route object.
    3562               If there is no exact match object, then we will go on to find
    3563               less specific. */
    3564            exact_match_routes_str = get_exact_match_routes(new_object);
    3565            if (exact_match_routes_str != NULL)
    3566                    {
    3567              /* there are one or more exact match routes */
    3568              exact_match_routes_maintainers = get_mnt_routes_from_list(exact_match_routes_str);
    3569              if ( exact_match_routes_maintainers )
    3570              {
    3571                /* the exact match(s) has some mnt-routes */
    3572                exact_match_routes_auth_vector = get_auth_vector(exact_match_routes_maintainers);
    3573                if (exact_match_routes_maintainers != NULL && exact_match_routes_auth_vector == NULL)
    3574                            {
    3575                  /* then, the mntners in 'exact_match_routes_maintainers' do not exist. Problem. */
    3576                          rpsl_attr_delete_list(exact_match_routes_maintainers);
    3577                  return UP_AUF; /* auth failed */
    3578                }
    3579                auth_return = authorise(exact_match_routes_auth_vector, credentials, overriden);
    3580              }
    3581              else
    3582              {
    3583                /* no mnt-routes so check the mnt-by of the exact match */
    3584                exact_match_maintainers = get_mntners_from_list(exact_match_routes_str);
    3585                exact_match_auth_vector = get_auth_vector(exact_match_maintainers);
    3586                if (exact_match_maintainers != NULL && exact_match_auth_vector == NULL)
    3587                            {
    3588                  /* then, the mntners in 'exact_match_maintainers' do not exist. Problem. */
    3589                          rpsl_attr_delete_list(exact_match_maintainers);
    3590                  return UP_AUF; /* auth failed */
    3591                }
    3592                auth_return = authorise(exact_match_auth_vector, credentials, overriden);
    3593              }
    3594              if (auth_return == UP_AUTH_OK || auth_return == UP_OKM)
    3595                          {
    3596                saved_auth_return = auth_return;
    3597                /* then, check mnt_bys of the route itself */
    3598                new_mntners = get_mntners(new_object);
    3599                new_auth_vector = get_auth_vector(new_mntners);
    3600                if (new_mntners != NULL && new_auth_vector == NULL)
    3601                            {
    3602                  /* then, the mntners in 'new_mntners' do not exist. Problem. */
    3603                          rpsl_attr_delete_list(new_mntners);
    3604                  return UP_AUF; /* auth failed */
    3605                }
    3606                auth_return = authorise(new_auth_vector, credentials, overriden);
    3607                        if (new_auth_vector)
    3608                      g_slist_free(new_auth_vector);
    3609                if ( auth_return == UP_AUTH_OK && saved_auth_return == UP_OKM)
    3610                  return UP_OKM;
    3611                else
    3612                      return auth_return;
    3613              }
    3614                          else
    3615                          { /*authorise(exact_match_routes_auth_vector, credentials, overriden) != UP_AUTH_OK*/
    3616                return UP_HOF; /* hierarchical authorisation failed */
    3617              }
    3618            }
    3619                    else
    3620                    { /* exact_match_routes == NULL */
    3621              /* then we have to look for less specific route objs */
    3622              less_spec_routes_str = get_less_spec_routes(new_object);
    3623              if (less_spec_routes_str != NULL)
    3624                          {
    3625                less_spec_routes_mntners = get_mnt_routes_from_list(less_spec_routes_str);
    3626                less_spec_routes_mntners = g_list_concat(less_spec_routes_mntners,
    3627                                              get_mnt_lowers_from_list(less_spec_routes_str));
    3628                less_spec_routes_auth_vector = get_auth_vector(less_spec_routes_mntners);
    3629                if (less_spec_routes_mntners != NULL && less_spec_routes_auth_vector == NULL)
    3630                            {
    3631                  /* then, the mntners in 'less_spec_routes_mntners' do not exist. Problem. */
    3632                          rpsl_attr_delete_list(less_spec_routes_mntners);
    3633                  return UP_AUF; /* auth failed */
    3634                }
    3635                if ( less_spec_routes_mntners != NULL )
    3636                {
    3637                  auth_return = authorise(less_spec_routes_auth_vector, credentials, overriden);
    3638                  if (auth_return == UP_AUTH_OK || auth_return == UP_OKM)
    3639                              {
    3640                    saved_auth_return = auth_return;
    3641                    /* then, check mnt_bys of the route itself */
    3642                    new_mntners = get_mntners(new_object);
    3643                    new_auth_vector = get_auth_vector(new_mntners);
    3644                    if (new_mntners != NULL && new_auth_vector == NULL)
    3645                                    {
    3646                      /* then, the mntners in 'new_auth_vector' do not exist. Problem. */
    3647                              rpsl_attr_delete_list(new_mntners);
    3648                      return UP_AUF; /* auth failed */
    3649                    }
    3650                    auth_return = authorise(new_auth_vector, credentials, overriden);
    3651                            if (new_auth_vector)
    3652                          g_slist_free(new_auth_vector);
    3653                    if ( auth_return == UP_AUTH_OK && saved_auth_return == UP_OKM )
    3654                      return UP_OKM;
    3655                    else
    3656                          return auth_return;
    3657                  }
    3658                              else
    3659                              { /*authorise(less_spec_routes_auth_vector, credentials, overriden) != UP_AUTH_OK*/
    3660                    return UP_HOF; /* hierarchical authorisation failed */
    3661                  }
    3662                }
    3663                else
    3664                {
    3665                  /* there are no mnt-routes or mnt-lower in less specific route objs */
    3666                  /* check mnt-by of less specific route objs */
    3667                  less_spec_routes_mntners = get_mntners_from_list(less_spec_routes_str);
    3668                  less_spec_routes_auth_vector = get_auth_vector(less_spec_routes_mntners);
    3669                  if (less_spec_routes_mntners != NULL && less_spec_routes_auth_vector == NULL)
    3670                              {
    3671                    /* then, the mntners in 'less_spec_routes_mntners' do not exist. Problem. */
    3672                            rpsl_attr_delete_list(less_spec_routes_mntners);
    3673                    return UP_AUF; /* auth failed */
    3674                  }
    3675                  auth_return = authorise(less_spec_routes_auth_vector, credentials, overriden);
    3676                  if (auth_return == UP_AUTH_OK || auth_return == UP_OKM)
    3677                              {
    3678                    saved_auth_return = auth_return;
    3679                    /* then, check mnt_bys of the route itself */
    3680                    new_mntners = get_mntners(new_object);
    3681                    new_auth_vector = get_auth_vector(new_mntners);
    3682                    if (new_mntners != NULL && new_auth_vector == NULL)
    3683                                    {
    3684                      /* then, the mntners in 'new_auth_vector' do not exist. Problem. */
    3685                              rpsl_attr_delete_list(new_mntners);
    3686                      return UP_AUF; /* auth failed */
    3687                    }
    3688                    auth_return = authorise(new_auth_vector, credentials, overriden);
    3689                            if (new_auth_vector)
    3690                          g_slist_free(new_auth_vector);
    3691                    if (auth_return == UP_AUTH_OK && saved_auth_return == UP_OKM)
    3692                      return UP_OKM;
    3693                    else
    3694                          return auth_return;
    3695                  }
    3696                              else
    3697                              { /*authorise(less_spec_routes_auth_vector, credentials, overriden) != UP_AUTH_OK*/
    3698                    return UP_HOF; /* hierarchical authorisation failed */
    3699                  }
    3700                }
    3701              }
    3702                          else
    3703                          {  /* less_spec_routes == NULL */
    3704                /* so, we have to get the exact match inetnum */
    3705                exact_match_inetnum_str = get_exact_match_inetnum(new_object);
    3706                if (exact_match_inetnum_str != NULL)
    3707                            {
    3708                                  exact_match_inetnum_obj = rpsl_object_init(exact_match_inetnum_str);
    3709                                  if (tracing)
    3710                                  {
    3711                            if ( rpsl_object_has_error(exact_match_inetnum_obj, RPSL_ERRLVL_ERROR) )
    3712                                    {
    3713                                          /* thre was an error during the parsing */
    3714                                          name = rpsl_object_get_class(exact_match_inetnum_obj);
    3715                                          if ( name )
    3716                                          {
    3717                                            attr = rpsl_object_get_attr(exact_match_inetnum_obj, name);
    3718                                            if ( attr )
    3719                                            {
    3720                                          value = rpsl_attr_get_clean_value( (rpsl_attr_t *)(attr->data) );
    3721                                                  if ( value )
    3722                                                  {
    3723                                            printf("TRACING: get_mnt_routes_from_list: error parsing object %s\n", value );
    3724                                                    free(value);
    3725                                                  }
    3726                                                  else
    3727                                            printf("TRACING: get_mnt_routes_from_list: error parsing object\n");
    3728
    3729                                                  rpsl_attr_delete_list(attr);
    3730                                            }
    3731                                          }
    3732                                    }
    3733                                  }
    3734
    3735                  exact_match_inetnum_mnt_routes = get_mnt_routes(exact_match_inetnum_obj);
    3736                                  exact_match_inetnum_mnt_bys = get_mntners(exact_match_inetnum_obj);
    3737                                  rpsl_object_delete(exact_match_inetnum_obj);
    3738
    3739                  exact_match_inetnum_auth_vector = get_auth_vector(exact_match_inetnum_mnt_routes);
    3740                  if (exact_match_inetnum_mnt_routes != NULL && exact_match_inetnum_auth_vector == NULL)
    3741                                  {
    3742                    /* then, the mntners in 'exact_match_inetnum_mnt_routes' do not exist. Problem. */
    3743                            rpsl_attr_delete_list(exact_match_inetnum_mnt_routes);
    3744                    return UP_AUF; /* auth failed */
    3745                  }
    3746
    3747                                  /* if there are mnt_routes in the exact match inetnum */
    3748                                  if (exact_match_inetnum_mnt_routes != NULL)
    3749                                  {
    3750                                    auth_return = authorise(exact_match_inetnum_auth_vector, credentials, overriden);
    3751                                    if (auth_return == UP_AUTH_OK || auth_return == UP_OKM)
    3752                                    {
    3753                      saved_auth_return = auth_return;
    3754                                          /* then, check mnt_bys of the route itself */
    3755                                          new_mntners = get_mntners(new_object);
    3756                                          new_auth_vector = get_auth_vector(new_mntners);
    3757                                          if (new_mntners != NULL && new_auth_vector == NULL)
    3758                                          {
    3759                                            /* then, the mntners in 'new_auth_vector' do not exist. Problem. */
    3760                                rpsl_attr_delete_list(new_mntners);
    3761                                            return UP_AUF; /* auth failed */
    3762                                          }
    3763                      auth_return = authorise(new_auth_vector, credentials, overriden);
    3764                              if (new_auth_vector)
    3765                            g_slist_free(new_auth_vector);
    3766                      if (auth_return == UP_AUTH_OK && saved_auth_return == UP_OKM)
    3767                        return UP_OKM;
    3768                      else
    3769                            return auth_return;
    3770                                    }
    3771                                    else
    3772                                    {
    3773                                          return UP_HOF; /* hierarchical authorisation failed */
    3774                                    }
    3775                                  }
    3776                                  else
    3777                                  { /* if there was no mnt_routes in the exact match inetnum, then use mnt-by of it */
    3778                                    exact_match_inetnum_auth_vector = get_auth_vector(exact_match_inetnum_mnt_bys);
    3779                                    if (exact_match_inetnum_mnt_bys != NULL && exact_match_inetnum_auth_vector == NULL)
    3780                                    {
    3781                                          /* then, the mntners in 'exact_match_inetnum_mnt_bys' do not exist. Problem. */
    3782                              rpsl_attr_delete_list(exact_match_inetnum_mnt_bys);
    3783                      return UP_AUF; /* auth failed */
    3784                    }
    3785
    3786                    /* check mnt-by of exact match inetnum */
    3787                    auth_return = authorise(exact_match_inetnum_auth_vector, credentials, overriden);
    3788                    if (auth_return == UP_AUTH_OK || auth_return == UP_OKM)
    3789                                    {
    3790                      saved_auth_return = auth_return;
    3791                      /* then, check mnt_bys of the route itself */
    3792                      new_mntners = get_mntners(new_object);
    3793                      new_auth_vector = get_auth_vector(new_mntners);
    3794                      if (new_mntners != NULL && new_auth_vector == NULL)
    3795                                      {
    3796                        /* then, the mntners in 'new_auth_vector' do not exist. Problem. */
    3797                                rpsl_attr_delete_list(new_mntners);
    3798                        return UP_AUF; /* auth failed */
    3799                      }
    3800                      auth_return = authorise(new_auth_vector, credentials, overriden);
    3801                              if (new_auth_vector)
    3802                            g_slist_free(new_auth_vector);
    3803                      if (auth_return == UP_AUTH_OK && saved_auth_return == UP_OKM)
    3804                        return UP_OKM;
    3805                      else
    3806                            return auth_return;
    3807                    }
    3808                                    else
    3809                                    {
    3810                      return UP_HOF; /* hierarchical authorisation failed */
    3811                    }
    3812                  }
    3813                }
    3814                            else
    3815                            {/* exact_match_inetnum == NULL */
    3816                  /* then, we will try to find less spec inetnums */
    3817                  less_spec_inetnum_str = get_less_spec_inetnum(new_object);
    3818                  if (less_spec_inetnum_str != NULL)
    3819                                  {
    3820                                    less_spec_inetnum_obj = rpsl_object_init(less_spec_inetnum_str);
    3821                                    if (tracing)
    3822                                    {
    3823                                  if ( rpsl_object_has_error(less_spec_inetnum_obj, RPSL_ERRLVL_ERROR) )
    3824                                          {
    3825                                            /* thre was an error during the parsing */
    3826                                            name = rpsl_object_get_class(less_spec_inetnum_obj);
    3827                                            if ( name )
    3828                                            {
    3829                                                  attr = rpsl_object_get_attr(less_spec_inetnum_obj, name);
    3830                                                  if ( attr )
    3831                                                  {
    3832                                            value = rpsl_attr_get_clean_value( (rpsl_attr_t *)(attr->data) );
    3833                                                    if ( value )
    3834                                                    {
    3835                                                  printf("TRACING: get_mnt_routes_from_list: error parsing object %s\n", value );
    3836                                                          free(value);
    3837                                                    }
    3838                                                    else
    3839                                                  printf("TRACING: get_mnt_routes_from_list: error parsing object\n");
    3840
    3841                                                    rpsl_attr_delete_list(attr);
    3842                                                  }
    3843                                            }
    3844                                          }
    3845                                    }
    3846
    3847                    less_spec_inetnum_mntners = get_mnt_routes(less_spec_inetnum_obj);
    3848                    less_spec_inetnum_mntners = g_list_concat(less_spec_inetnum_mntners,
    3849                                   get_mnt_lowers(less_spec_inetnum_obj));
    3850                    less_spec_inetnum_auth_vector = get_auth_vector(less_spec_inetnum_mntners);
    3851
    3852                                    less_spec_inetnum_mnt_bys = get_mntners(less_spec_inetnum_obj);
    3853
    3854                                    rpsl_object_delete(less_spec_inetnum_obj);
    3855
    3856                    if (less_spec_inetnum_mntners != NULL && less_spec_inetnum_auth_vector == NULL)
    3857                                    {
    3858                      /* then, the mntners in 'less_spec_inetnum_mntners' do not exist. Problem. */
    3859                              rpsl_attr_delete_list(less_spec_inetnum_mntners);
    3860                      return UP_AUF; /* auth failed */
    3861                    }
    3862                                    if (less_spec_inetnum_mntners != NULL)
    3863                                    { /* if there are mntners in mnt-lower and/or mnt-routes */
    3864                                          auth_return = authorise(less_spec_inetnum_auth_vector, credentials, overriden);
    3865                                          if (auth_return == UP_AUTH_OK || auth_return == UP_OKM)
    3866                                          {
    3867                        saved_auth_return = auth_return;
    3868                                            /* then, check mnt_bys of the route itself */
    3869                                            new_mntners = get_mntners(new_object);
    3870                                            new_auth_vector = get_auth_vector(new_mntners);
    3871                                            if (new_mntners != NULL && new_auth_vector == NULL)
    3872                                            {
    3873                                                  /* then, the mntners in 'new_auth_vector' do not exist. Problem. */
    3874                                  rpsl_attr_delete_list(new_mntners);
    3875                                                  return UP_AUF; /* auth failed */
    3876                                            }
    3877                        auth_return = authorise(new_auth_vector, credentials, overriden);
    3878                                if (new_auth_vector)
    3879                              g_slist_free(new_auth_vector);
    3880                        if (auth_return == UP_AUTH_OK && saved_auth_return == UP_OKM)
    3881                          return UP_OKM;
    3882                        else
    3883                              return auth_return;
    3884                                          }
    3885                                          else
    3886                                          { /* authorise(exact_match_auth_vector, credentials, overriden) != UP_AUTH_OK */
    3887                                            return UP_HOF; /* hierarchical authorisation failed */
    3888                                          }
    3889                                    }
    3890                                    else
    3891                                    { /* there isn't any mnt-lower or mnt-routes in the less spec inetnum */
    3892                                                  /* so we must use mnt-by of less spec inetum */
    3893                                          less_spec_inetnum_auth_vector = get_auth_vector(less_spec_inetnum_mnt_bys);
    3894                                          if (less_spec_inetnum_mnt_bys != NULL && less_spec_inetnum_auth_vector == NULL)
    3895                                          {
    3896                                            /* then, the mntners in 'less_spec_inetnum_mnt_bys' do not exist. Problem. */
    3897
    3898                                rpsl_attr_delete_list(less_spec_inetnum_mnt_bys);
    3899                        return UP_AUF; /* auth failed */
    3900                      }
    3901                                          auth_return = authorise(less_spec_inetnum_auth_vector, credentials, overriden);
    3902                                          if (auth_return == UP_AUTH_OK  ||  auth_return == UP_OKM)
    3903                                          {
    3904                        saved_auth_return = auth_return;
    3905                                            /* then, check mnt_bys of the route itself */
    3906                                            new_mntners = get_mntners(new_object);
    3907                                            new_auth_vector = get_auth_vector(new_mntners);
    3908                                            if (new_mntners != NULL && new_auth_vector == NULL)
    3909                                            {
    3910                                                  /* then, the mntners in 'new_auth_vector' do not exist. Problem. */
    3911                                  rpsl_attr_delete_list(new_mntners);
    3912                                                  return UP_AUF; /* auth failed */
    3913                                            }
    3914                        auth_return = authorise(new_auth_vector, credentials, overriden);
    3915                                if (new_auth_vector)
    3916                              g_slist_free(new_auth_vector);
    3917                        if (auth_return == UP_AUTH_OK  && saved_auth_return == UP_OKM)
    3918                          return UP_OKM;
    3919                        else
    3920                              return auth_return;
    3921                                          }
    3922                                          else
    3923                                          {
    3924                                            return UP_HOF; /* hierarchical authorisation failed */
    3925                                          }
    3926                    }
    3927                  }
    3928                                  else
    3929                                  {/* less_spec_inetnum == NULL */
    3930                    /* now that we couldn't find any route or inetnum object
    3931                       to be used in authentication. So, only if the auth is
    3932                       overriden the object will be created. */
    3933                    if (overriden)
    3934                                    {
    3935                      return UP_AUTH_OK;
    3936                    }
    3937                                    else
    3938                                    {
    3939                      return UP_HOF; /* hierarchical authorisation failed */
    3940                    }
    3941                  }
    3942                }
    3943              }
    3944            }
    3945          }
    3946                  else
    3947                  {/* ! aut_num_auth_OK */
    3948            return UP_HOF; /* hierarchical auth failed */
    3949          }
    3950        }
    3951
    3952      }
    3953          else if ( new_object != NULL && old_object != NULL )
    3954          { /* this is an update */
    3955        old_mntners = get_mntners(old_object);
    3956        old_auth_vector = get_auth_vector(old_mntners);
    3957        if (old_mntners != NULL && old_auth_vector == NULL)
    3958            {
    3959          /* then, the mntners in 'old_auth_vector' do not exist. Problem. */
    3960                  rpsl_attr_delete_list(old_mntners);
    3961          return UP_AUF; /* auth failed */
    3962        }
    3963        if (old_auth_vector)
    3964            { /* if we have mntners in the old object, use them */
    3965          auth_return = authorise(old_auth_vector, credentials, overriden);
    3966              g_slist_free(old_auth_vector);
    3967              return auth_return;
    3968        }
    3969            else
    3970            {
    3971          new_mntners = get_mntners(new_object);
    3972          new_auth_vector = get_auth_vector(new_mntners);
    3973          if (new_mntners != NULL && new_auth_vector == NULL)
    3974                  {
    3975            /* then, the mntners in 'new_auth_vector' do not exist. Problem. */
    3976                    rpsl_attr_delete_list(new_mntners);
    3977            return UP_AUF; /* auth failed */
    3978          }
    3979          auth_return = authorise(new_auth_vector, credentials, overriden);
    3980                  if (new_auth_vector)
    3981                g_slist_free(new_auth_vector);
    3982              return auth_return;
    3983        }
    3984      }
    3985          else
    3986          { /* both are NULL, mustn't happen */
    3987          if (tracing)
    3988                  {
    3989            printf("TRACING: check_auth: internal error: Both pointers are NULL\n");
    3990          }
    3991          return UP_INT; /* internal error */
    3992      }
    3993    }
    3994
    3995
    3996    /*
    3997     *  Handle the set objects ("as-set","rtr-set", "peering-set", "route-set" and "filter-set" types
    3998     */
    3999    else if (strcmp(type,"as-set")       == 0 || strcmp(type,"rtr-set")     == 0 ||
    4000            strcmp(type,"peering-set")  == 0 || strcmp(type,"filter-set")  == 0 ||
    4001            strcmp(type,"route-set")    == 0 )
    4002    {
    4003      if ( new_object == NULL && old_object != NULL )
    4004          { /* the object is to be deleted */
    4005        old_mntners = get_mntners(old_object);
    4006        old_auth_vector = get_auth_vector(old_mntners);
    4007        if (old_mntners != NULL && old_auth_vector == NULL)
    4008            {
    4009          /* then, the mntners in 'old_auth_vector' do not exist. Problem. */
    4010                  rpsl_attr_delete_list(old_mntners);
    4011          return UP_AUF; /* auth failed */
    4012        }
    4013        auth_return = authorise(old_auth_vector, credentials, overriden);
    4014            g_slist_free(old_auth_vector);
    4015            return auth_return;
    4016      }
    4017          else if ( new_object != NULL && old_object == NULL )
    4018          { /* the object is to be created */
    4019         set_name = get_search_key(new_object, type);
    4020        if (strstr(set_name,":") == NULL )
    4021            { /* if the name is _not_ hierarchical */
    4022          new_mntners = get_mntners(new_object);
    4023          new_auth_vector = get_auth_vector(new_mntners);
    4024          if (new_mntners != NULL && new_auth_vector == NULL)
    4025                  {
    4026            /* then, the mntners in 'new_auth_vector' do not exist. Problem. */
    4027                    rpsl_attr_delete_list(new_mntners);
    4028            return UP_AUF; /* auth failed */
    4029          }
    4030          auth_return = authorise(new_auth_vector, credentials, overriden);
    4031                  if (new_auth_vector)
    4032                g_slist_free(new_auth_vector);
    4033              return auth_return;
    4034        }
    4035            else
    4036            { /* the name is hierarchical */
    4037          less_specific_object_str = get_less_specific_set(new_object, type);
    4038          if (less_specific_object_str != NULL)
    4039                  { /* such an object exists */
    4040                    less_specific_obj = rpsl_object_init(less_specific_object_str);
    4041                    if (tracing)
    4042                    {
    4043                  if ( rpsl_object_has_error(less_specific_obj, RPSL_ERRLVL_ERROR) )
    4044                          {
    4045                            /* thre was an error during the parsing */
    4046                            name = rpsl_object_get_class(less_specific_obj);
    4047                            if ( name )
    4048                            {
    4049                                  attr = rpsl_object_get_attr(less_specific_obj, name);
    4050                                  if ( attr )
    4051                                  {
    4052                            value = rpsl_attr_get_clean_value( (rpsl_attr_t *)(attr->data) );
    4053                                    if ( value )
    4054                                    {
    4055                                  printf("TRACING: get_mnt_routes_from_list: error parsing object %s\n", value );
    4056                                          free(value);
    4057                                    }
    4058                                    else
    4059                                  printf("TRACING: get_mnt_routes_from_list: error parsing object\n");
    4060
    4061                                    rpsl_attr_delete_list(attr);
    4062                                  }
    4063                            }
    4064                          }
    4065                    }
    4066
    4067            less_specific_object_type = rpsl_object_get_class(less_specific_obj);
    4068
    4069            if (strcmp(less_specific_object_type, "aut-num") == 0)
    4070                    { /* if this is an aut-num object */
    4071              less_specific_mnt_lowers = get_mnt_lowers(less_specific_obj);
    4072              less_specific_auth_vector = get_auth_vector(less_specific_mnt_lowers);
    4073              if (less_specific_mnt_lowers != NULL && less_specific_auth_vector == NULL)
    4074                          {
    4075                /* then, the mntners in 'less_specific_auth_vector' do not exist. Problem. */
    4076                       rpsl_attr_delete_list(less_specific_mnt_lowers);
    4077               rpsl_object_delete(less_specific_obj);
    4078               return UP_AUF; /* auth failed */
    4079              }
    4080              if (less_specific_auth_vector != NULL)
    4081                          {
    4082                auth_return = authorise(less_specific_auth_vector, credentials, overriden);
    4083                    g_slist_free(less_specific_auth_vector);
    4084                rpsl_object_delete(less_specific_obj);
    4085                    return auth_return;
    4086              }
    4087                          else
    4088                          { /* the less specific object doesn't contain any mnt-lower */
    4089                less_specific_mntners = get_mntners(less_specific_obj);
    4090                less_specific_auth_vector = get_auth_vector(less_specific_mntners);
    4091                if (less_specific_mntners != NULL && less_specific_auth_vector == NULL)
    4092                            {
    4093                  /* then, the mntners in 'less_specific_mntners' do not exist. Problem. */
    4094                          rpsl_attr_delete_list(less_specific_mntners);
    4095                  rpsl_object_delete(less_specific_obj);
    4096                  return UP_AUF; /* auth failed */
    4097                }
    4098                if (less_specific_auth_vector != NULL)
    4099                            {  /* less spec object has some mnt-by attribs,
    4100                                                         use them  */
    4101                    auth_return = authorise(less_specific_auth_vector, credentials, overriden);
    4102                        g_slist_free(less_specific_auth_vector);
    4103                    rpsl_object_delete(less_specific_obj);
    4104                        return auth_return;
    4105                }
    4106                            else
    4107                            { /* the less specific object doesn't contain any mnt-by either */
    4108                  if (overriden)
    4109                                  {
    4110                    rpsl_object_delete(less_specific_obj);
    4111                    return UP_AUTH_OK;
    4112                  }
    4113                                  else
    4114                                  {
    4115                    rpsl_object_delete(less_specific_obj);
    4116                    return UP_HOF; /* hierarchical authorisation failed */
    4117                  }
    4118                }
    4119              }
    4120            }
    4121                    else
    4122                    { /* this is _not_ an aut-num object*/
    4123              less_specific_mntners = get_mntners(less_specific_obj);
    4124              less_specific_auth_vector = get_auth_vector(less_specific_mntners);
    4125              if (less_specific_mntners != NULL && less_specific_auth_vector == NULL)
    4126                          {
    4127                /* then, the mntners in 'less_specific_mntners' do not exist. Problem. */
    4128                        rpsl_attr_delete_list(less_specific_mntners);
    4129                rpsl_object_delete(less_specific_obj);
    4130                return UP_AUF; /* auth failed */
    4131              }
    4132              if (less_specific_auth_vector != NULL )
    4133                          { /* the set obj has some mnt-by attribs */
    4134                auth_return = authorise(less_specific_auth_vector, credentials, overriden);
    4135                    g_slist_free(less_specific_auth_vector);
    4136                rpsl_object_delete(less_specific_obj);
    4137                    return auth_return;
    4138              }
    4139                          else
    4140                          {
    4141                if (overriden)
    4142                            {
    4143                  rpsl_object_delete(less_specific_obj);
    4144                  return UP_AUTH_OK;
    4145                }
    4146                            else
    4147                            {
    4148                  rpsl_object_delete(less_specific_obj);
    4149                  return UP_HOF; /* hierarchical authorisation failed */
    4150                }
    4151              }
    4152            }
    4153          }
    4154                  else
    4155                  { /* we don't have a less specific of this set object in the DB  */
    4156            return UP_HOF; /* hierarchical authorisation failed */
    4157          }
    4158        }
    4159      }
    4160          else if ( new_object != NULL && old_object != NULL )
    4161          { /* this is an update */
    4162        old_mntners = get_mntners(old_object);
    4163        old_auth_vector = get_auth_vector(old_mntners);
    4164        if (old_mntners != NULL && old_auth_vector == NULL)
    4165            {
    4166          /* then, the mntners in 'old_auth_vector' do not exist. Problem. */
    4167                  rpsl_attr_delete_list(old_mntners);
    4168          return UP_AUF; /* auth failed */
    4169        }
    4170        if (old_auth_vector)
    4171            { /* if we have mntners in the old object, use them */
    4172          auth_return = authorise(old_auth_vector, credentials, overriden);
    4173              g_slist_free(old_auth_vector);
    4174              return auth_return;
    4175        }
    4176            else
    4177            {
    4178          new_mntners = get_mntners(new_object);
    4179          new_auth_vector = get_auth_vector(new_mntners);
    4180          if (new_mntners != NULL && new_auth_vector == NULL)
    4181                  {
    4182            /* then, the mntners in 'new_mntners' do not exist. Problem. */
    4183                    rpsl_attr_delete_list(new_mntners);
    4184            return UP_AUF; /* auth failed */
    4185          }
    4186          auth_return = authorise(new_auth_vector, credentials, overriden);
    4187                  if (new_auth_vector)
    4188                g_slist_free(new_auth_vector);
    4189              return auth_return;
    4190        }
    4191      }
    4192          else
    4193          { /* both are NULL, mustn't happen */
    4194          if (tracing)
    4195                  {
    4196            printf("TRACING: check_auth: internal error: Both pointers are NULL\n");
    4197          }
    4198          return UP_INT; /* internal error */
    4199      }
    4200
    4201    }
    4202    else
    4203    { /* We exhausted all object classes. If we are here, then there is a problem */
    4204      printf("check_auth: This type '%s' is unknown\n", type);
    4205      return UP_NIY; /* not implemented yet */
    4206    }
    4207    return UP_AUF; /* if we come to this point, then auth failed */
    4208 }
    4209
    4210
    4211
    4212 /* Gets the old version of the given "arg" object, which is in char * format
    4213    and returns the old version again in char * format */
    4214
    4215 char * get_old_version(rpsl_object_t *object, char * arg)
         /* [<][>][^][v][top][bottom][index][help] */
    4216 {
    4217     const char *type=NULL;
    4218         char *lctype = NULL;
    4219         char *primary_search_key = NULL, *search_string = NULL;
    4220     char *result = NULL, *origin = NULL, *nic_hdl = NULL;
    4221
    4222     type = rpsl_object_get_class(object);
    4223         lctype = strdup(type);
    4224         g_strdown(lctype);
    4225
    4226     primary_search_key = get_search_key(object, lctype);
    4227     if ( primary_search_key == NULL )
    4228     {
    4229       if(tracing)
    4230       {
    4231         printf("type=%s\n", type);
    4232         printf("primary_search_key is NULL\n");
    4233       }
    4234           return NULL;
    4235         }
    4236
    4237     if(tracing)
    4238         {
    4239       printf("TRACING: type= %s\n", type);
    4240       printf("TRACING: primary_search_key= %s\n", primary_search_key);
    4241     }
    4242
    4243     /* if the object is a pn or a ro object, then get all pn/ro's with the same NIC hdl */
    4244     if ( strcmp(lctype,"person") == 0 || strcmp(lctype,"role") == 0 )
    4245         {
    4246       /* prepare the search string */
    4247       search_string = (char *)malloc(strlen(primary_search_key) + strlen("-x -R -r -T -s ")
    4248                                           +strlen(current_source)+ strlen("person,role") + 2);
    4249       sprintf(search_string, "-x -R -r -Tperson,role -s %s %s", current_source, primary_search_key);
    4250     }
    4251         else
    4252         {
    4253       /* prepare the search string */
    4254       search_string = (char *)malloc(strlen(primary_search_key) + strlen("-x -R -r -T -s ")
    4255                                           +strlen(current_source)+ strlen(lctype) + 2);
    4256       sprintf(search_string, "-x -R -r -T%s -s %s %s",lctype, current_source, primary_search_key);
    4257     }
    4258
    4259     result = send_and_get(query_host, query_port, search_string);
    4260     if(tracing)
    4261         {
    4262       printf("TRACING: send_and_get returned with search %s result %s\n", search_string, result);
    4263     }
    4264         free(search_string);
    4265         free(primary_search_key);
    4266         if ( result == NULL )
    4267           return NULL;
    4268
    4269     /* and here, we must filter the 'result' with NIC handle */
    4270     if ( strcmp(lctype,"person") == 0 )
    4271         {
    4272       if(tracing)
    4273           {
    4274         printf("TRACING: This is a person\n");
    4275       }
    4276       /* if this is a person, then we must filter out the persons with different
    4277          nic-hdl attributes (since it is possible to have this NIC hdl in the name
    4278          of a person object, and whois will return that object too) */
    4279       nic_hdl = get_search_key(object, "nic-hdl");
    4280       if(tracing)
    4281           {
    4282         printf("TRACING: Got nic-hdl of person: %s\n", nic_hdl);
    4283       }
    4284       result = up_filter_out_diff_nichdls(result, nic_hdl);
    4285       if(tracing)
    4286           {
    4287         printf("TRACING: Filtered person\n");
    4288       }
    4289           free(nic_hdl);
    4290     }
    4291
    4292     /* also, we must filter the 'result' with NIC handle for roles */
    4293     if(strcmp(type,"role") == 0)
    4294         {
    4295       if(tracing)
    4296           {
    4297         printf("TRACING: This is a role\n");
    4298       }
    4299       /* if this is a role, then we must filter out the roles with different
    4300          nic-hdl attributes (since it is possible to have this NIC hdl in the name
    4301          of a role object, and whois will return that object too) */
    4302       nic_hdl = get_search_key(object, "nic-hdl");
    4303       if(tracing)
    4304           {
    4305         printf("TRACING: Got nic-hdl of role: %s\n", nic_hdl);
    4306       }
    4307       result = up_filter_out_diff_nichdls(result, nic_hdl);
    4308       if(tracing)
    4309           {
    4310         printf("TRACING: Filtered role\n");
    4311       }
    4312           free(nic_hdl);
    4313     }
    4314
    4315     if(strcmp(type,"route") == 0)
    4316         {
    4317       if(tracing)
    4318           {
    4319         printf("TRACING: This is a route\n");
    4320       }
    4321       /* if this is a route, then we must filter out the routes with different
    4322          origin attributes */
    4323       origin = get_search_key(object, "origin");
    4324       if(tracing)
    4325           {
    4326         printf("TRACING: Got origin of route: %s\n", origin);
    4327       }
    4328       result = up_filter_out_diff_origins(result, origin);
    4329       if(tracing)
    4330           {
    4331         printf("TRACING: Filtered routes\n");
    4332       }
    4333           free(origin);
    4334     }
    4335
    4336     /* count the objects */
    4337     if(count_objects(result) == 0)
    4338         {
    4339       result = NULL; /* we don't have such an object */
    4340     }
    4341         else if(count_objects(result) == 1)
    4342         {
    4343       result = take_object(result);
    4344       if(tracing)
    4345           {
    4346       printf("TRACING: Take_object returned ***%s\n", result);
    4347       }
    4348     }
    4349         else
    4350         { /* we have more than one objects, error! */
    4351       result = NULL;
    4352     }
    4353
    4354     return result;
    4355 }
    4356
    4357
    4358
    4359
    4360 /* Gets a credentials_struct whose 'from' field will be filled in and
    4361    the mail header. Finds the 'From:' line in the header and sets
    4362    the 'from' field to this line (all line, including the 'From:' string,
    4363    since some users have put regexps which match the whole line in their
    4364    'auth' attributes.) */
    4365 void process_mail_header(credentials_struct * credentials_ptr, char * arg)
         /* [<][>][^][v][top][bottom][index][help] */
    4366 {
    4367   char * header = strdup(arg);
    4368   char * temp = (char *)malloc(strlen(header));
    4369
    4370   while (index(header, '\n') != NULL)
    4371   {
    4372     temp = strdup(header);
    4373     temp[index(temp, '\n') - temp] = '\0';
    4374     if (strstr(temp, "From:") == temp)
    4375         {
    4376       if (tracing)
    4377           {
    4378         printf("TRACING: process_mail_header: Assigning %s\n", temp);
    4379       }
    4380       credentials_ptr->from = strdup(temp);
    4381       free(temp);
    4382       return;
    4383     }
    4384     header = header + (index(header, '\n') - header + 1);
    4385   }
    4386   free(temp);
    4387 }
    4388
    4389
    4390
    4391 void up_string_pack(char *dest, const char *source)
         /* [<][>][^][v][top][bottom][index][help] */
    4392 {
    4393   if(tracing)
    4394   {
    4395     printf("TRACING: up_string_pack running\n");
    4396   }
    4397
    4398 /*----------------------------------------------------------------------*\
    4399
    4400 *  Function to rewrite a line of text with only one blankspace between  *
    4401 *  each word.
    4402 *
    4403 \*----------------------------------------------------------------------*/
    4404 /*
    4405  * This while loop continues until the NULL character is copied into
    4406  * the destination string.  If a tab character is copied into the
    4407  * destination string, it is replaced with a blank-space character.
    4408  *
    4409  * Multiple blank-space and/or tab characters are skipped in the source
    4410  * string until any other character is found.
    4411  */
    4412
    4413   while (1)
    4414   {
    4415     *dest = *source;
    4416
    4417     if (*dest == '\t')
    4418             (*dest = ' ');
    4419
    4420     /* Exit if have copied the end of the string. */
    4421     if (*dest == '\0')
    4422             return;
    4423
    4424 /*
    4425 * If the source character was a blank-space or a tab, move to the next
    4426 * source character.  While the source character is a blank-space or a
    4427 * tab, move to the next character (i.e. ignore these characters).  When
    4428 * any other character is found in the source string, move to the next
    4429 * element of the destination string.
    4430 *
    4431 * Otherwise, simultaneously, move to the next elements of the destination
    4432 * and the source strings.
    4433 */
    4434
    4435     if ( (*source == ' ') || (*source == '\t') )
    4436     {
    4437         ++source;
    4438         while ( (*source == ' ') || (*source == '\t') )
    4439                 {
    4440                 ++source;
    4441                 }
    4442
    4443         ++dest;
    4444     }
    4445     else
    4446     {
    4447         ++dest;
    4448         ++source;
    4449     }
    4450   }
    4451 }
    4452
    4453
    4454 /* replaces the erase_str occurences with insert_str in str (which is a ptr to GString) */
    4455 char * UP_replace_strings(char * str, const char * erase_str, const char * insert_str)
         /* [<][>][^][v][top][bottom][index][help] */
    4456 {
    4457   GString * g_str;
    4458   int pos;
    4459   char * result_str;
    4460
    4461   /* erase_str mustn't be NULL */
    4462   assert(erase_str != NULL);
    4463
    4464   /* if insert str is NULL, make it empty string */
    4465   if(insert_str == NULL)
    4466   {
    4467     insert_str = strdup("");
    4468   }
    4469
    4470   g_str = g_string_new(str);
    4471
    4472   /* replace erase_str with insert_str */
    4473   while(strstr(g_str->str, erase_str) != NULL)
    4474   {
    4475     pos = strstr(g_str->str, erase_str) - g_str->str;
    4476     g_str = g_string_erase(g_str, pos, strlen(erase_str));
    4477     if(insert_str != NULL)
    4478         {
    4479       g_str = g_string_insert(g_str, pos, insert_str);
    4480     }
    4481   }
    4482
    4483   /* save the result string */
    4484   result_str = strdup(g_str->str);
    4485
    4486   /* free the GString structure (TRUE means 'also free the char string') */
    4487   g_string_free(g_str, TRUE);
    4488
    4489   return result_str;
    4490 }
    4491
    4492
    4493
    4494 /* replaces the erase_str occurences with insert_str in g_str (which is a ptr to GString) */
    4495 GString * UP_replace_GStrings(GString * g_str, const char * erase_str, const char * insert_str)
         /* [<][>][^][v][top][bottom][index][help] */
    4496 {
    4497   int pos;
    4498
    4499   if (insert_str == NULL)
    4500   { /* then don't do anything */
    4501     return g_str;
    4502   }
    4503
    4504   /* replace erase_str with insert_str */
    4505   while (strstr(g_str->str, erase_str) != NULL)
    4506   {
    4507     pos = strstr(g_str->str, erase_str) - g_str->str;
    4508     g_str = g_string_erase(g_str, pos, strlen(erase_str));
    4509     g_str = g_string_insert(g_str, pos, insert_str);
    4510   }
    4511   return g_str;
    4512 }
    4513
    4514
    4515
    4516 /* looks if two objects are identical or not.
    4517     Takes two objects, one as char *, the other as
    4518         a parsed object, and returns 1 if
    4519     they are identical, returns 0 if not.
    4520
    4521     Algorithm is very simple: All strings of tabs and
    4522     white spaces are collapsed into a single white space,
    4523     and then the strings are compared (strcmp) */
    4524 int identical(const char * old_version, rpsl_object_t *object)
         /* [<][>][^][v][top][bottom][index][help] */
    4525 {
    4526   char * arg1 = strdup(old_version);
    4527   char * arg2 = NULL;
    4528   rpsl_object_t *object2;
    4529   rpsl_error_t error;
    4530   int result = 0;
    4531   char *temp1, *temp2;
    4532   char *temp;
    4533
    4534   object2 = rpsl_object_copy(object);
    4535   rpsl_object_remove_attr_name(object2, "delete", &error);
    4536   rpsl_object_remove_attr_name(object2, "override", &error);
    4537   arg2 = rpsl_object_get_text(object2,RPSL_STD_COLUMN);
    4538
    4539   arg1 = g_strstrip(arg1);
    4540   arg2 = g_strstrip(arg2);
    4541
    4542   /* convert tabs to white spaces */
    4543   arg1 = g_strdelimit(arg1, "\t", ' ');
    4544   arg2 = g_strdelimit(arg2, "\t", ' ');
    4545
    4546   temp1 = (char *)malloc(strlen(arg1) + 1);
    4547   temp2 = (char *)malloc(strlen(arg2) + 1);
    4548   up_string_pack(temp1, arg1);
    4549   up_string_pack(temp2, arg2);
    4550
    4551   /* if there are still \r's at the end of strings, remove them */
    4552   if((temp1[strlen(temp1) - 1]) == '\r')
    4553   {
    4554     temp1[strlen(temp1) - 1] = '\0';
    4555   }
    4556   if((temp2[strlen(temp2) - 1]) == '\r')
    4557   {
    4558     temp2[strlen(temp2) - 1] = '\0';
    4559   }
    4560
    4561   /* there may be white spaces at the end of the strings now, remove them */
    4562   if((temp1[strlen(temp1) - 1]) == ' ')
    4563   {
    4564     temp1[strlen(temp1) - 1] = '\0';
    4565   }
    4566   if((temp2[strlen(temp2) - 1]) == ' ')
    4567   {
    4568     temp2[strlen(temp2) - 1] = '\0';
    4569   }
    4570
    4571   /* remove the white spaces just before the EOLs (since this is not taken care of by
    4572      the up_string_pack func) */
    4573   temp = UP_replace_strings(temp1, " \n", "\n");
    4574   free(temp1);
    4575   temp1 = temp;
    4576
    4577   temp = UP_replace_strings(temp2, " \n", "\n");
    4578   free(temp2);
    4579   temp2 = temp;
    4580
    4581   result = strcmp(temp1, temp2);
    4582   if(tracing){
    4583     printf("TRACING: identical: the objects are:\n[%s]\n[%s]\n", temp1, temp2);
    4584     printf("TRACING: identical: the lengths are:\n[%i]\n[%i]\n", strlen(temp1), strlen(temp2));
    4585   }
    4586   free(arg1);
    4587   free(arg2);
    4588   free(temp1);
    4589   free(temp2);
    4590   if(result  == 0)
    4591   {
    4592     if(tracing)
    4593         {
    4594       printf("TRACING: identical returning 1\n");
    4595     }
    4596     return 1;
    4597   }
    4598   else
    4599   {
    4600     if(tracing)
    4601         {
    4602       printf("TRACING: identical returning 0\n");
    4603     }
    4604     return 0;
    4605   }
    4606 }
    4607
    4608
    4609 /* constructs an initials string from a given name (for NIC hdl generation) */
    4610 char * find_initials(const char * person_role_name)
         /* [<][>][^][v][top][bottom][index][help] */
    4611 {
    4612    char * temp, *pos;
    4613    char * initials = NULL;
    4614    int len, i;
    4615    char ** vector;
    4616
    4617    temp = strdup(person_role_name);
    4618    if ((pos = index(temp, '#')) != NULL)
    4619    { /* delete the EOL comment */
    4620      pos[0] = '\0';
    4621    }
    4622
    4623    vector = g_strsplit(temp, " ", 0);
    4624    for (i = 0; vector[i] != NULL && i < 4; i++)
    4625    {
    4626      if ( (strlen(vector[i]) > 0 ) && isalpha( (int)(vector[i][0]) ) )
    4627          {
    4628        if (initials == NULL)
    4629            {
    4630          initials = (char *)malloc(2);
    4631          initials[0] = vector[i][0];
    4632                  initials[1] = '\0';
    4633        }
    4634            else
    4635            {
    4636          len = strlen(initials);
    4637          initials = (char *)realloc(initials, len + 2 );
    4638          initials[len] = vector[i][0];
    4639          initials[len + 1] = '\0';
    4640        }
    4641      }
    4642    }
    4643    free(temp);
    4644    g_strfreev(vector);
    4645    return initials;
    4646 }
    4647
    4648
    4649
    4650
    4651 /*  Gets the letter combination to be used in the automatically
    4652     generated NIc handle. It the letter combination is specified
    4653     in the AUTO NIC handle, return that. If not, return NULL
    4654     (in which case the initials of the name must be used) */
    4655 char * get_combination_from_autonic(const char * autonic)
         /* [<][>][^][v][top][bottom][index][help] */
    4656 {
    4657   GString * temp;
    4658   char * str = NULL;
    4659   char * pos;
    4660
    4661   temp = g_string_new(autonic);
    4662   temp = g_string_up(temp);
    4663   if ((pos = index(temp->str, '#')) != NULL)
    4664   {
    4665     /* delete the EOL comment */
    4666     pos[0] = '\0';
    4667   }
    4668   g_strstrip(temp->str);
    4669   temp->len = strlen(temp->str);/* we directly played with temp->str, so adjust temp->len accordingly */
    4670
    4671   temp = g_string_erase(temp, 0, strlen("AUTO-"));
    4672   /* delete all digits from the beginning of the string */
    4673   while (temp->len > 0 && ((temp->str)[0] >= '0' && (temp->str)[0] <= '9'))
    4674   {
    4675     temp = g_string_erase(temp, 0, 1);
    4676   }
    4677
    4678   if (temp->len < 2 )
    4679   {
    4680     g_string_free(temp, TRUE);
    4681     return NULL;
    4682   }
    4683   else
    4684   {
    4685     str = temp->str;
    4686     g_string_free(temp, FALSE);
    4687     g_strup(str);
    4688     if(strlen(str) > 4)
    4689         {
    4690       str[4] = '\0';
    4691     }
    4692     return str;
    4693   }
    4694 }
    4695
    4696
    4697
    4698
    4699 /* Gets an object whose NIC hdl is an auto NIC handle and to be modified (to be sent to RIPupdate)
    4700    and  modifies the nic-hdl: attribute.
    4701    For example, "nic-hdl: AUTO-1" becomes "nic-hdl: HG*-RIPE . Also,
    4702    auto_nic is set to "AUTO-1"
    4703    auto_nic must be allocated enough memory before replace_AUTO_NIC_hdl called */
    4704 rpsl_object_t * replace_AUTO_NIC_hdl(rpsl_object_t *object, char * auto_nic_hdl)
         /* [<][>][^][v][top][bottom][index][help] */
    4705 {
    4706   GList *nichdl_item;
    4707   rpsl_object_t *object2 = NULL;
    4708   rpsl_attr_t *attr;
    4709   GList *class_attr;
    4710   char * person_role_name = NULL;
    4711   char * initials = NULL;
    4712   char *value, *new_value = NULL;
    4713   const char *type;
    4714   int pos;
    4715
    4716   if (tracing)
    4717   {
    4718       printf("TRACING: replace_AUTO_NIC_hdl running\n");
    4719   }
    4720
    4721   nichdl_item = rpsl_object_get_attr(object, "nic-hdl"); /* list with one item only */
    4722
    4723   value = rpsl_attr_get_clean_value((rpsl_attr_t *)(nichdl_item->data));
    4724   g_strdown(value);
    4725   if (tracing)
    4726   {
    4727       printf("TRACING: auto nic-hdl value is [%s]\n", value);
    4728   }
    4729
    4730   if (strstr(value, "auto-") != NULL)
    4731   {
    4732     /* this attribute must be replaced with a new attribute containing a nic-hdl */
    4733     strcpy(auto_nic_hdl, value);
    4734     pos = rpsl_attr_get_ofs((rpsl_attr_t *)(nichdl_item->data));
    4735
    4736         if (tracing)
    4737         {
    4738         printf("TRACING: pos [%d]\n", pos);
    4739         }
    4740
    4741      /* if the letter combination is already specified, get it */
    4742     initials = get_combination_from_autonic(auto_nic_hdl);
    4743     /* if the letter combination is not in the AUTO nichdl, obtain it from the name */
    4744     if(initials == NULL)
    4745         {
    4746           type = rpsl_object_get_class(object);
    4747           class_attr = rpsl_object_get_attr(object, type);
    4748           person_role_name = rpsl_attr_get_clean_value((rpsl_attr_t *)(class_attr->data));
    4749           rpsl_attr_delete_list(class_attr);
    4750       initials = find_initials(person_role_name);
    4751           free(person_role_name);
    4752     }
    4753         if (tracing)
    4754         {
    4755         printf("TRACING: initials [%s]\n", initials ? initials : "NULL");
    4756         }
    4757
    4758         object2 = rpsl_object_copy(object);
    4759     new_value = (char *)malloc(strlen(initials) + strlen(current_source) + 3);
    4760         strcpy(new_value, initials);
    4761         strcat(new_value, "*-");
    4762         strcat(new_value, current_source);
    4763         if (tracing)
    4764         {
    4765         printf("TRACING: new_value [%s]\n", new_value);
    4766         }
    4767
    4768         /* now copy original attribute, replace value, remove old attr and add replacement */
    4769         attr = rpsl_attr_copy((rpsl_attr_t *)(nichdl_item->data));
    4770         rpsl_attr_replace_value(attr, new_value);
    4771         free(initials);
    4772         free(new_value);
    4773         free(value);
    4774
    4775         /* remove the attribute with the auto- */
    4776         rpsl_object_remove_attr(object2, pos, NULL);
    4777
    4778         /* insert new attribute with nic-hdl */
    4779         rpsl_object_add_attr(object2, attr, pos, NULL);
    4780   }
    4781   rpsl_attr_delete_list(nichdl_item);
    4782
    4783   return(object2);
    4784 }
    4785
    4786
    4787
    4788
    4789 /* replaces the refs to AUTO NIC hdls with the assigned one */
    4790
    4791 char * replace_refs_to_AUTO_NIC_hdl(rpsl_object_t *object, GHashTable * auto_nic_hash, char *arg)
         /* [<][>][^][v][top][bottom][index][help] */
    4792 {
    4793   char * nic_hdl = NULL;
    4794   char *name;
    4795   char *value;
    4796   char *return_str;
    4797   char *tempstr;
    4798   rpsl_attr_t *attr;
    4799   const GList * attr_list = NULL;
    4800   const GList * list_item = NULL;
    4801   int pos;
    4802
    4803   if(tracing)
    4804   {
    4805     printf("TRACING: replace_refs_to_AUTO_NIC_hdl is running: arg:[%s]\n", arg ? arg : "NULL");
    4806   }
    4807
    4808   attr_list = rpsl_object_get_all_attr(object);
    4809
    4810 //  for (list_item = attr_list; list_item != NULL; list_item = g_list_next(list_item ))
    4811 //  {
    4812   list_item = attr_list;
    4813   while (list_item != NULL)
    4814   {
    4815         name = strdup(rpsl_attr_get_name((rpsl_attr_t *)(list_item->data)));
    4816         g_strdown(name);
    4817         value = rpsl_attr_get_clean_value((rpsl_attr_t *)(list_item->data));
    4818         g_strdown(value);
    4819         pos = rpsl_attr_get_ofs((rpsl_attr_t *)(list_item->data));
    4820         if (    strstr(name, "admin-c") == name
    4821              || strstr(name, "tech-c")  == name
    4822              || strstr(name, "zone-c")  == name
    4823              || strstr(name, "author")  == name )
    4824         {
    4825           /* attr starts with admin-c, tech-c, zone-c or author */
    4826           if ( strstr(value, "auto-") != NULL)
    4827           {
    4828         if(tracing)
    4829                 {
    4830                         printf("TRACING: replace_refs_to_AUTO_NIC_hdl: auto_nic is [%s]\n", value);
    4831         }
    4832
    4833         /* if we have this AUTO NIC hdl in the hash, put it in. */
    4834         if( (nic_hdl = (char *)g_hash_table_lookup(auto_nic_hash, value)) )
    4835                 {
    4836                 if(tracing)
    4837                         {
    4838                                 printf("TRACING: replace_refs_to_AUTO_NIC_hdl: nic_hdl is [%s]\n", nic_hdl);
    4839                 }
    4840                         /* create a new attribute with the auto nic handle */
    4841                         attr = rpsl_attr_copy((rpsl_attr_t *)(list_item->data));
    4842             rpsl_attr_replace_value(attr, nic_hdl);
    4843
    4844                         /* remove the attribute with the auto- */
    4845                         rpsl_object_remove_attr(object, pos, NULL);
    4846
    4847                         /* insert new attribute with nic-hdl */
    4848                         rpsl_object_add_attr(object, attr, pos, NULL);
    4849
    4850             /* replacing the attr destroys the list, so start the list again */
    4851             attr_list = rpsl_object_get_all_attr(object);
    4852             list_item = attr_list;
    4853         }
    4854                 else
    4855                 { /* else, return 0 immediately */
    4856                         free(name);
    4857                         free (value);
    4858                         return NULL;
    4859         }
    4860           }
    4861         }
    4862
    4863         free(name);
    4864         free (value);
    4865
    4866         list_item = g_list_next(list_item);
    4867   }
    4868
    4869   return_str =  rpsl_object_get_text(object,RPSL_STD_COLUMN);
    4870
    4871   /* now, if we don't have a '\n' at the end of the return_str  string, we will
    4872      add one, since RAToolSet parser cannot deal with objects without a '\n' at the end */
    4873   if(return_str[strlen(return_str) - 1] != '\n')
    4874   {
    4875     /* so, add a '\n' */
    4876     tempstr = (char *)malloc(strlen(return_str) + 2);
    4877     sprintf(tempstr, "%s\n", return_str);
    4878     free(return_str);
    4879     return_str = tempstr;
    4880   }
    4881
    4882   if (tracing)
    4883   {
    4884     printf("TRACING: replace_refs_to_AUTO_NIC_hdl is returning,\nreturn_str=[%s]\n", return_str);
    4885   }
    4886
    4887   return return_str;
    4888 }
    4889
    4890
    4891
    4892
    4893 /* UP_put_assigned_NIC will replace the auto NIC handle of the object with its
    4894    assigned NIC handle and return an amended copy of the object */
    4895 rpsl_object_t * UP_put_assigned_NIC(rpsl_object_t *object, char * assigned_NIC)
         /* [<][>][^][v][top][bottom][index][help] */
    4896 {
    4897   rpsl_object_t *object2;
    4898   rpsl_attr_t *attr;
    4899   GList * nichdl_item;
    4900   char *value;
    4901   int pos;
    4902
    4903   nichdl_item = rpsl_object_get_attr(object, "nic-hdl");  /* a list with only one item */
    4904
    4905   value = rpsl_attr_get_clean_value((rpsl_attr_t *)(nichdl_item->data));
    4906   g_strdown(value);
    4907   if (strstr(value, "auto-") != NULL)
    4908   {
    4909     /* replace the AUTO-NIC hdl with the assigned one  */
    4910
    4911     if (tracing)
    4912     {
    4913       printf("TRACING: UP_put_assigned_NIC: auto_nic is [%s]\n", value);
    4914     }
    4915
    4916         object2 = rpsl_object_copy(object);
    4917         /* now copy original attribute, replace value, remove old attr and add replacement */
    4918         attr = rpsl_attr_copy((rpsl_attr_t *)(nichdl_item->data));
    4919         rpsl_attr_replace_value(attr, assigned_NIC);
    4920     pos = rpsl_attr_get_ofs((rpsl_attr_t *)(nichdl_item->data));
    4921
    4922         /* remove the attribute with the auto- */
    4923         rpsl_object_remove_attr(object2, pos, NULL);
    4924
    4925         /* insert new attribute with nic-hdl */
    4926         rpsl_object_add_attr(object2, attr, pos, NULL);
    4927   }
    4928   rpsl_attr_delete_list(nichdl_item);
    4929
    4930   return object2;
    4931 }
    4932
    4933
    4934
    4935
    4936 /* Takes a parsed object, and returns 1 if this object has
    4937    an AUTO NIC handle. Otherwise, returns 0 */
    4938 int has_AUTO_NIC_hdl(const rpsl_object_t * object)
         /* [<][>][^][v][top][bottom][index][help] */
    4939 {
    4940   GList *attributes = NULL;
    4941
    4942   if ( !rpsl_object_is_deleted(object) )
    4943   {
    4944     attributes = rpsl_object_get_attr(object, "nic-hdl");
    4945     if (attributes != NULL)
    4946         {
    4947       if (strstr_in_attr_list(attributes, "AUTO-") == 1)
    4948           { /* if it contains a ref to AUTO nic */
    4949         rpsl_attr_delete_list(attributes);
    4950         return 1;
    4951       }
    4952     }
    4953     /* if control reaches here, then we will return 0 */
    4954     rpsl_attr_delete_list(attributes);
    4955     return 0;
    4956   }
    4957   else
    4958   { /* it doesn't pass syntax check. So, it doesn't matter if
    4959            it contains refs to AUTO NIC hdls. */
    4960     return 0;
    4961   }
    4962 }
    4963
    4964
    4965 /* Takes an rpsl_object_t structure , and returns 1 if this object contains
    4966    a reference to an AUTO NIC handle. Otherwise, returns 0 */
    4967 int has_ref_to_AUTO_nic_hdl(rpsl_object_t *object)
         /* [<][>][^][v][top][bottom][index][help] */
    4968 {
    4969   GList * attributes = NULL;
    4970
    4971   if (! rpsl_object_is_deleted(object) )
    4972   {
    4973     attributes = rpsl_object_get_attr(object, "admin-c");
    4974     rpsl_attr_split_multiple(&attributes);
    4975     if (attributes != NULL)
    4976         {
    4977       if (strstr_in_attr_list(attributes, "AUTO-") == 1)
    4978           { /* if it contains a ref to AUTO nic */
    4979         rpsl_attr_delete_list(attributes);
    4980         return 1;
    4981       }
    4982     }
    4983     rpsl_attr_delete_list(attributes);
    4984     attributes = rpsl_object_get_attr(object, "tech-c");
    4985     rpsl_attr_split_multiple(&attributes);
    4986     if (attributes != NULL)
    4987         {
    4988       if (strstr_in_attr_list(attributes, "AUTO-") == 1)
    4989           { /* if it contains a ref to AUTO nic */
    4990         rpsl_attr_delete_list(attributes);
    4991         return 1;
    4992       }
    4993     }
    4994
    4995     rpsl_attr_delete_list(attributes);
    4996     attributes = rpsl_object_get_attr(object, "zone-c");
    4997     rpsl_attr_split_multiple(&attributes);
    4998     if (attributes != NULL)
    4999         {
    5000       if(strstr_in_attr_list(attributes, "AUTO-") == 1)
    5001           { /* if it contains a ref to AUTO nic */
    5002         rpsl_attr_delete_list(attributes);
    5003         return 1;
    5004       }
    5005     }
    5006     rpsl_attr_delete_list(attributes);
    5007     attributes = rpsl_object_get_attr(object, "author");
    5008     rpsl_attr_split_multiple(&attributes);
    5009     if (attributes != NULL)
    5010         {
    5011       if (strstr_in_attr_list(attributes, "AUTO-") == 1)
    5012           { /* if it contains a ref to AUTO nic */
    5013         rpsl_attr_delete_list(attributes);
    5014         return 1;
    5015       }
    5016     }
    5017     rpsl_attr_delete_list(attributes);
    5018     /* if control reaches here, then we will return 0 */
    5019     return 0;
    5020   }
    5021   else
    5022   {  /* it doesn't pass syntax check. So, it doesn't matter if
    5023            it contains refs to AUTO NIC hdls. */
    5024     return 0;
    5025   }
    5026 }
    5027
    5028
    5029
    5030 /* Gets the "From" line of the incoming mail message and finds out an
    5031    address to send the acknowledgement */
    5032 char * find_email_address(const char * from_line)
         /* [<][>][^][v][top][bottom][index][help] */
    5033 {
    5034   char * pos1 = NULL, * pos2 = NULL, * pos = NULL;
    5035   char * temp = NULL;
    5036   char * part1 = NULL, * part2 = NULL;
    5037
    5038   if (from_line == NULL)
    5039   {
    5040     return NULL;
    5041   }
    5042   if (strstr(from_line, "From:") != from_line)
    5043   {
    5044     temp = strdup(from_line);
    5045   }
    5046   else
    5047   {
    5048     temp = strdup(from_line + strlen("From:"));
    5049   }
    5050   g_strstrip(temp);
    5051   if (index(temp, '<'))
    5052   { /* then the line is something like '"John White" <john@inter.net>' */
    5053     pos1 = index(temp, '<');
    5054     pos2 = index(temp, '>');
    5055     temp = strncpy(temp, pos1 + 1, pos2 - pos1 -1);
    5056     temp[pos2 - pos1 - 1] = '\0';
    5057     if (tracing)
    5058         {
    5059      printf("TRACING: find_email_address temp=[%s]\n", temp);
    5060     }
    5061   }
    5062
    5063   /* and now, we have to remove the parts in parantheses */
    5064   while (   index(temp, '(') != NULL && index(temp, ')') != NULL
    5065           && index(temp, '(') < index(temp, ')') )
    5066   {
    5067     part1 = strdup(temp);
    5068     /* terminate the string */
    5069     pos = index(part1, '(');
    5070     *pos = '\0';
    5071
    5072     part2 = strdup(index(temp, ')') + 1);
    5073     strcat(part1, part2);
    5074     free(temp);
    5075     temp = strdup(part1);
    5076     free(part1);
    5077     free(part2);
    5078   }
    5079
    5080   g_strstrip(temp);
    5081   return temp;
    5082 }
    5083
    5084
    5085
    5086 /* removes the '\n's and '\r's at the end of the arg, and returns it  */
    5087 char * UP_remove_EOLs(char * arg)
         /* [<][>][^][v][top][bottom][index][help] */
    5088 {
    5089   while ( strlen(arg) > 0 &&
    5090           (arg[strlen(arg) - 1] == '\n' ||
    5091            arg[strlen(arg) - 1] == '\r') )
    5092   {
    5093     arg[strlen(arg) - 1] = '\0';
    5094   }
    5095
    5096   return arg;
    5097 }
    5098
    5099
    5100
    5101 /* Duplicates the given arg, and replaces
    5102     $FROM,
    5103     $SUBJECT,
    5104     $MDATE,
    5105     $MSGID,
    5106     $CC,
    5107     $HUMAILBOX
    5108     $AUTOBOX
    5109     $FROMHOST
    5110
    5111     and $TIME & $DATE
    5112
    5113     strings with the corresponding variables.
    5114
    5115 */
    5116 char * UP_replace_globals(const char * arg)
         /* [<][>][^][v][top][bottom][index][help] */
    5117 {
    5118   GString * g_str;
    5119   char * to_be_returned;
    5120   time_t cur_time;
    5121   char * temp, * time_str, * date_str;
    5122
    5123   /* get time */
    5124   cur_time = time(NULL);
    5125   temp = strdup(ctime(&cur_time));
    5126   /* temp is now something like "Fri Sep 13 00:00:00 1986\n\0", fields are const width */
    5127
    5128   time_str = (char *)malloc(9);
    5129   time_str = strncpy(time_str, temp + 11, 8);
    5130   time_str[8] = '\0';
    5131
    5132   date_str = (char *)malloc(16);
    5133   date_str = strncpy(date_str, temp, 11);
    5134   date_str[11] = '\0';
    5135   date_str = strncat(date_str, temp + 20, 4);
    5136
    5137
    5138   free(temp);
    5139
    5140   g_str = g_string_new(arg);
    5141
    5142   g_str = UP_replace_GStrings(g_str, "$FROMHOST", netupdclientIP);
    5143
    5144   g_str = UP_replace_GStrings(g_str, "$TIME", time_str);
    5145
    5146   g_str = UP_replace_GStrings(g_str, "$DATE", date_str);
    5147
    5148   g_str = UP_replace_GStrings(g_str, "$SUBJECT", update_mail_subject);
    5149
    5150   g_str = UP_replace_GStrings(g_str, "$FROM", update_mail_sender);
    5151
    5152   g_str = UP_replace_GStrings(g_str, "$MDATE", update_mail_date);
    5153
    5154   g_str = UP_replace_GStrings(g_str, "$MSGID", update_mail_ID);
    5155
    5156   if (update_mail_cc == NULL)
    5157     g_str = UP_replace_GStrings(g_str, "$CC", "");
    5158   else
    5159     g_str = UP_replace_GStrings(g_str, "$CC", update_mail_cc);
    5160
    5161   g_str = UP_replace_GStrings(g_str, "$HUMAILBOX", humailbox);
    5162
    5163   g_str = UP_replace_GStrings(g_str, "$AUTOBOX", autobox);
    5164
    5165   g_str = UP_replace_GStrings(g_str, "$HEADERTYPE", header_type);
    5166
    5167   g_str = UP_replace_GStrings(g_str, "$TEXTTYPE", text_type);
    5168
    5169   free(time_str);
    5170   free(date_str);
    5171
    5172   to_be_returned = strdup(g_str->str);
    5173   g_string_free(g_str, 1);
    5174   return to_be_returned;
    5175 }
    5176
    5177
    5178
    5179
    5180 /* Adds the given file to the update log */
    5181 void UP_add_to_upd_log(const char * filename)
         /* [<][>][^][v][top][bottom][index][help] */
    5182 {
    5183   time_t now;
    5184   struct tm * tmstr;
    5185   time_t cur_time;
    5186   char * time_str;
    5187   char datestr[10];
    5188   char * updlogfile;
    5189   FILE * infile, * log_file;
    5190   char   buf[1024];
    5191
    5192
    5193   if (( infile = fopen(filename, "r")) == NULL)
    5194   {
    5195     fprintf(stderr, "UP_add_to_upd_log: Can't open upd file, %s\n", filename);
    5196     return;
    5197   }
    5198
    5199   /* We need to get the a date string to construct the updlog file name */
    5200   time(&now);
    5201   tmstr = localtime(&now);
    5202   strftime(datestr, 10, "%Y%m%d", tmstr);
    5203
    5204   /* now that we have the date string, we can construct updlog file name */
    5205   updlogfile = (char *)malloc(strlen(updlog) + strlen(datestr) + 2);
    5206   snprintf(updlogfile, strlen(updlog) + strlen(datestr) + 2,
    5207            "%s.%s", updlog, datestr);
    5208
    5209
    5210   if (( log_file = fopen(updlogfile, "a")) == NULL)
    5211   {
    5212     fprintf(stderr, "UP_add_to_upd_log: Can't open upd log file, %s\n", updlogfile);
    5213         free(updlogfile);
    5214     return;
    5215   }
    5216
    5217   /* get time */
    5218   cur_time = time(NULL);
    5219   time_str = strdup(ctime(&cur_time));
    5220   /* cut the '\n' at the end */
    5221   time_str[strlen(time_str) - 1] = '\0';
    5222
    5223   if (reading_from_mail)
    5224   {
    5225     fprintf(log_file, ">>> time: %s MAIL UPDATE <<<\n\n", time_str);
    5226   }
    5227   else if (networkupdate)
    5228   {
    5229     fprintf(log_file, ">>> time: %s NETWORKUPDATE UPDATE (%s) <<<\n\n",
    5230                       time_str, netupdclientIP ? netupdclientIP : "NULL");
    5231   }
    5232   else if (webupdate)
    5233   {
    5234     fprintf(log_file, ">>> time: %s WEB UPDATE (%s) <<<\n\n",
    5235                        time_str, netupdclientIP ? netupdclientIP : "NULL");
    5236   }
    5237   else
    5238   {
    5239     fprintf(log_file, ">>> time: %s UPDATE <<<\n\n", time_str);
    5240   }
    5241
    5242   free(time_str);
    5243   while ( fgets(buf, 1023, infile) != NULL )
    5244   {
    5245     fprintf(log_file, "%s", buf);
    5246   }
    5247   free(updlogfile);
    5248
    5249   fclose(infile);
    5250   fclose(log_file);
    5251 }
    5252
    5253
    5254
    5255 /* Logs the object to the update log */
    5256 void UP_log_networkupdate(const char * object_str, const char * host)
         /* [<][>][^][v][top][bottom][index][help] */
    5257 {
    5258   time_t now;
    5259   struct tm * tmstr;
    5260   time_t cur_time;
    5261   char * time_str;
    5262   char datestr[10];
    5263   char * updlogfile;
    5264   FILE * log_file;
    5265
    5266   /* We need to get the a date string to construct the updlog file name */
    5267   time(&now);
    5268   tmstr = localtime(&now);
    5269   strftime(datestr, 10, "%Y%m%d", tmstr);
    5270
    5271   /* now that we have the date string, we can construct updlog file name */
    5272   updlogfile = (char *)malloc(strlen(updlog) + strlen(datestr) + 2);
    5273   snprintf(updlogfile, strlen(updlog) + strlen(datestr) + 2,
    5274            "%s.%s", updlog, datestr);
    5275
    5276   if (( log_file = fopen(updlogfile, "a")) == NULL)
    5277   {
    5278     fprintf(stderr, "UP_add_to_upd_log: Can't open upd log file, %s\n", updlogfile);
    5279         free(updlogfile);
    5280     return;
    5281   }
    5282   free(updlogfile);
    5283
    5284   /* get time */
    5285   cur_time = time(NULL);
    5286   time_str = strdup(ctime(&cur_time));
    5287   /* cut the '\n' at the end */
    5288   time_str[strlen(time_str) - 1] = '\0';
    5289
    5290   fprintf(log_file, ">>> time: %s NETWORKUPDATE UPDATE (%s) <<<\n\n", time_str, host);
    5291
    5292   free(time_str);
    5293
    5294   fprintf(log_file, "%s\n", object_str);
    5295
    5296   fclose(log_file);
    5297 }
    5298
    5299
    5300
    5301
    5302 /* Performs a preliminary check on a string: Tries to guess if the arg is an object or not.
    5303    The criteria is: If we have a colon (":") in the first line of the string, then it is
    5304    probably an object */
    5305 int UP_is_object(const char * arg)
         /* [<][>][^][v][top][bottom][index][help] */
    5306 {
    5307    if (arg == NULL)
    5308    {
    5309      return 0; /* not an object */
    5310    }
    5311
    5312    if (index(arg ,'\n'))
    5313    { /* does it consist of multiple lines? */
    5314      if (index(arg ,':') != NULL  && (index(arg ,':') < index(arg ,'\n')))
    5315          {
    5316        return 1;
    5317      }
    5318          else
    5319          { /* it doesn't have any ":" or, first ":" is not in the first line */
    5320        return 0;
    5321      }
    5322    }
    5323    else
    5324    { /* it has a single line, possibly not an object */
    5325      return 0;
    5326    }
    5327 }
    5328
    5329
    5330 int UP_remove_override_attr( rpsl_object_t *object )
         /* [<][>][^][v][top][bottom][index][help] */
    5331 {
    5332   rpsl_error_t return_error;
    5333   rpsl_attr_t *removed_attr;
    5334
    5335   return_error.code = (gint)NULL;
    5336   removed_attr = rpsl_object_remove_attr_name(object,"override",&return_error);
    5337   if ( (removed_attr == NULL) && return_error.level >= RPSL_ERRLVL_ERROR )
    5338   {
    5339          /* error returned */
    5340          /* could be that there was no override attribute in this object */
    5341      if ( return_error.code == RPSL_ERR_NOSUCHATTR )
    5342            return 1;  /* This is OK, object has no override attribute */
    5343          else
    5344            /* there was an override attr in this object and it has not been removed */
    5345            return 0;
    5346   }
    5347   else
    5348     /* no errors, override attribute has been removed */
    5349          return 1;
    5350 }
    5351
    5352
    5353 /****************************************************************************************************/
    5354
    5355 /*******************  Redundant Functions ***********************************************************/
    5356
    5357
    5358
    5359 /* strips lines beginning with "override:" off  */
    5360 char * delete_override(char * arg){
         /* [<][>][^][v][top][bottom][index][help] */
    5361
    5362     char ** temp = NULL;
    5363     char * string = NULL;
    5364     int i;
    5365
    5366     if(arg == NULL){
    5367        return NULL;
    5368     }
    5369
    5370     /* split the string into lines */
    5371     temp = g_strsplit (arg, "\n", 0);
    5372
    5373     for(i=0; temp[i] != NULL; i++){
    5374       /* if the line begins with "override:", then do not copy it */
    5375       if(strstr(temp[i], "override:") != temp[i]){
    5376         if(string == NULL){
    5377           string = strdup(temp[i]);
    5378         }else{
    5379           string = (char *)realloc(string, strlen(string) + strlen(temp[i]) + 2);
    5380           string = strcat(string, "\n");
    5381           string = strcat(string, temp[i]);
    5382         }
    5383       }
    5384     }
    5385     g_strfreev(temp);
    5386     return string;
    5387 }
    5388
    5389
    5390 /* takes a pre-parsed object, and returns its type */
    5391 /* char * get_class_type(Object *arg){
    5392
    5393     char * be_returned = NULL;
    5394     if(arg == NULL) return NULL;
    5395     be_returned = strdup(arg->type->getName());
    5396     return g_strstrip(be_returned);
    5397 }
    5398 */
    5399
    5400
    5401
    5402
    5403
    5404
    5405
    5406 /*************** still used in nt module **************/
    5407 /* strips lines beginning with "delete:" off  */
    5408 char * delete_delete_attrib(char * arg){
         /* [<][>][^][v][top][bottom][index][help] */
    5409
    5410     char ** temp = NULL;
    5411     char * string = NULL;
    5412     int i;
    5413
    5414     if(arg == NULL){
    5415        return NULL;
    5416     }
    5417
    5418     /* split the string into lines */
    5419     temp = g_strsplit (arg, "\n", 0);
    5420
    5421     for(i=0; temp[i] != NULL; i++){
    5422       /* if the line begins with "delete:", then do not copy it */
    5423       if(strstr(temp[i], "delete:") != temp[i]){
    5424         if(string == NULL){
    5425           string = strdup(temp[i]);
    5426         }else{
    5427           string = (char *)realloc(string, strlen(string) + strlen(temp[i]) + 2);
    5428           string = strcat(string, "\n");
    5429           string = strcat(string, temp[i]);
    5430         }
    5431       }
    5432     }
    5433     g_strfreev(temp);
    5434     return string;
    5435 }

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