Source File up/UP_util.c

    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)
    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)
    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)
    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()
    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)
    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)
    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)
    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)
    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)
    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)
    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)
    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)
    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)
    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)
    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)
    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)
    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)
    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)
    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)
    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)
    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)
    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)
    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)
    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)
    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)
    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)
    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)
    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)
    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)
    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)
    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)
    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)
    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)
    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)
    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)
    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)
    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)
    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)
    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)
    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)
    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)
    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)
    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)
    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)
    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)
    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)
    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)
    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)
    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)
    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)
    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)
    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)
    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)
    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)
    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)
    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)
    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)
    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)
    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)
    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)
    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)
    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)
    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)
    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)
    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)
    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)
    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)
    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)
    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)
    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 )
    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){
    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){
    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 | }