Source File up/UP_util.c

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