modules/up/src/rpslcheck/separateobjects.cc
/* [<][>][^][v][top][bottom][index][help] */
FUNCTIONS
This source file includes following functions.
- start_tracing
- start_debugging
- init_and_set_options
- send_object_db
- get_type
- get_search_key
- send_and_get
- count_objects
- take_object
- get_as_block
- get_less_specific_domain
- get_less_specific_set
- get_less_specific
- get_mntners
- get_auths
- get_mnt_lowers
- get_override
- check_override
- add_to_auth_vector
- get_auth_vector
- check_auth
- get_old_version
- process_object
- main
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <glib.h>
#include <iostream.h>
#include <netdb.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <errno.h>
#include <config.h>
#include <istream.h>
#include "rpsl/object.hh"
#include "util/rusage.hh"
#include "util/debug.hh"
#include "util/trace.hh"
#include "util/Argv.hh"
#include "util/version.hh"
#ifdef IRR_NEEDED
#include "irr/irr.hh"
#include "irr/rawhoisc.hh"
#endif // IRR_NEEDED
#include "rpsl/schema.hh"
Rusage ru;
bool opt_stats = false;
bool opt_rusage = false;
char *opt_prompt = "RtConfig> ";
bool opt_echo = false;
#ifdef DEBUG
bool opt_debug_rpsl = false;
#endif // DEBUG
int start_tracing(char *dst, char *key, char *nextArg) {
/* [<][>][^][v][top][bottom][index][help] */
if (nextArg) {
trace.enable(nextArg);
return 1; // return 1 to signify nextArg is used by us
}
return 0;
}
int start_debugging(char *dst, char *key, char *nextArg) {
/* [<][>][^][v][top][bottom][index][help] */
if (nextArg) {
Debug(dbg.enable(atoi(nextArg)));
return 1; // return 1 to signify nextArg is used by us
}
return 0;
}
void init_and_set_options (int argc, char **argv, char **envp) {
/* [<][>][^][v][top][bottom][index][help] */
ArgvInfo argTable[] = {
// RAToolSet common arguments
// key, type, src, dst, help
{"-T", ARGV_FUNC, (char *) &start_tracing, (char *) NULL,
"Start tracing the next argument"},
{"-D", ARGV_FUNC, (char *) &start_debugging, (char *) NULL,
"Start debugging the next argument"},
{"-version", ARGV_FUNC, (char *) &version, (char *) NULL,
"Show version"},
#ifdef IRR_NEEDED
{"-h", ARGV_FUNC, (char *) &IRR::ArgvHost, (char *) NULL,
"Host name of the RAWhoisd server"},
{"-p", ARGV_FUNC, (char *) &IRR::ArgvPort, (char *) NULL,
"Port number of the RAWhoisd server"},
{"-s", ARGV_FUNC, (char *) &IRR::ArgvSources, (char *) NULL,
"Order of databases"},
{"-ignore_errors", ARGV_FUNC, (char *)&IRR::IgnoreErrors, (char *)NULL,
"Ignore IRR error and warning messages"},
{"-report_errors", ARGV_FUNC, (char *)&IRR::ReportErrors, (char *)NULL,
"Print IRR error and warning messages"},
#endif // IRR_NEEDED
{"-rusage", ARGV_BOOL, (char *) NULL, (char *) &opt_rusage,
"On termination print resource usage"},
{"-stats", ARGV_BOOL, (char *) NULL, (char *) &opt_stats,
"On termination print class statistics"},
{"-prompt", ARGV_STRING, (char *) NULL, (char *) &opt_prompt,
"Prompt"},
{"-echo", ARGV_BOOL, (char *) NULL, (char *) &opt_echo,
"Echo each object parsed"},
#ifdef DEBUG
{"-debug_rpsl", ARGV_BOOL, (char *) NULL, (char *) &opt_debug_rpsl,
"Turn on bison debugging. Intended for developers."},
#endif // DEBUG
{(char *) NULL, ARGV_END, (char *) NULL, (char *) NULL,
(char *) NULL}
};
#ifdef IRR_NEEDED
IRR::handleEnvironmentVariables(envp);
#endif // IRR_NEEDED
if (ParseArgv(&argc, argv, argTable, ARGV_NO_LEFTOVERS) != ARGV_OK) {
cerr << endl;
exit(1);
}
#ifdef IRR_NEEDED
irr = IRR::newClient();
#endif // IRR_NEEDED
// have a prompt only if the input is coming from a tty
if (!isatty(fileno(stdin)) || !isatty(fileno(stdout)))
opt_prompt = NULL;
}
#define MAXDATASIZE 100 /* max number of bytes we can get at once */
#define PORT 11111
#define UP_AUTH_OK 0 /* Authorisation succeeded */
#define ERROR_UP_MOR 1 /* Got more than one objects from the db, error */
#define ERROR_UP_NSO 2 /* so such object */
#define ERROR_UP_AUF 3 /* auth failed */
#define ERROR_UP_NIY 4 /* not implemented yet */
#define ERROR_UP_ABN 5 /* As-block does not exist */
#define ERROR_UP_HOF 6 /* Hierarchical authorisation failed */
#define ERROR_UP_OVF 7 /* override failed */
#define ERROR_UP_OVS 8 /* override syntax error */
#define ERROR_UP_INT 9 /* internal error */
#define OVR_OK 0 /* override succeded */
#define AU_MAIL_FROM 1
#define AU_CRYPT_PW 2
#define AU_PGP 3
#define AU_NONE 4
struct credentials{
char * password;
char * from;
char * pgp_struct;
};
typedef struct _auth_struct{
int type;
char * auth;
char * mntner_name;
int index;
char * pgp_struct;
} auth_struct;
int error = 0; // a global variable to store the errors
char * error_msg = NULL; // a global variable to store the error messages
/* sends the object to the database. char * operation is either 'ADD' or 'DEL' */
void send_object_db(char * arg, char * operation){
/* [<][>][^][v][top][bottom][index][help] */
int sockfd, numbytes;
char buf[MAXDATASIZE];
struct hostent *he;
struct sockaddr_in their_addr; /* connector's address information */
if ((he=gethostbyname("rowan")) == NULL) { /* get the host info */
perror("gethostbyname");
exit(1);
}
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
perror("socket");
exit(1);
}
their_addr.sin_family = AF_INET; /* host byte order */
their_addr.sin_port = htons(PORT); /* short, network byte order */
their_addr.sin_addr = *((struct in_addr *)he->h_addr);
bzero(&(their_addr.sin_zero), 8); /* zero the rest of the struct */
if (connect(sockfd, (struct sockaddr *)&their_addr,
sizeof(struct sockaddr)) == -1) {
perror("connect");
exit(1);
}
if (send(sockfd, operation , strlen(operation), 0) == -1)
perror("send");
if (send(sockfd, "\n\n" , strlen("\n\n"), 0) == -1)
perror("send");
if (send(sockfd, arg , strlen(arg), 0) == -1)
perror("send");
if (send(sockfd, "\n",1,0) == -1)
perror("send");
while ((numbytes=recv(sockfd, buf, MAXDATASIZE, 0)) != 0) {
buf[numbytes] = '\0';
printf("%s",buf);
/*perror("recv");
exit(1);*/
}
/*buf[numbytes] = '\0';
printf("Received: %s",buf);*/
close(sockfd);
}
/* takes a pre-parsed object, and returns its type */
char * get_type(Object *arg){
/* [<][>][^][v][top][bottom][index][help] */
char * be_returned = NULL;
if(arg == NULL) return NULL;
be_returned = strdup(arg->type->getName());
return g_strstrip(be_returned);
}
/* takes an object (pre-parsed) and returns its first attrib if it is not
a person, and returns the nic-hdl if it is a person object */
char * get_search_key(Object *arg, char * type, char * text){
/* [<][>][^][v][top][bottom][index][help] */
Attr *attr;
char *primary_key = NULL, *value = NULL;
if(arg == NULL) return NULL;
for(attr = arg->attrs.head(); attr; attr = arg->attrs.next(attr)){
value = (char*)malloc((*attr).len - strlen(attr->type->name()) - 1);
strncpy(value, (char *)(text+attr->offset) + strlen(attr->type->name())+1,
attr->len - strlen(attr->type->name()) -2 );
value[attr->len - strlen(attr->type->name()) - 2 ] = '\0';
//cout << "value: #" << value << "#" << endl;
if(strcmp(attr->type->name(),type) == 0 &&
strcmp(type,"person") != 0){
primary_key = strdup(value);
}
if(strcmp(attr->type->name(),"nic-hdl") == 0 &&
strcmp(type,"person") == 0){
primary_key = strdup(value);
}
}
return g_strstrip(primary_key);
}
/* sends char * arg to the specified host's specified port, and
returns the reply as a string */
char * send_and_get(char * host, int port, char * arg){
/* [<][>][^][v][top][bottom][index][help] */
int sockfd, numbytes;
char * result = NULL;
char buf[MAXDATASIZE];
struct hostent *he;
struct sockaddr_in their_addr; /* connector's address information */
if ((he=gethostbyname(host)) == NULL) { /* get the host info */
perror("gethostbyname");
exit(1);
}
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
perror("socket");
exit(1);
}
their_addr.sin_family = AF_INET; /* host byte order */
their_addr.sin_port = htons(port); /* short, network byte order */
their_addr.sin_addr = *((struct in_addr *)he->h_addr);
bzero(&(their_addr.sin_zero), 8); /* zero the rest of the struct */
if (connect(sockfd, (struct sockaddr *)&their_addr,
sizeof(struct sockaddr)) == -1) {
perror("connect");
exit(1);
}
if (send(sockfd, arg , strlen(arg), 0) == -1)
perror("send");
if (send(sockfd, "\n",1,0) == -1)
perror("send");
while ((numbytes=recv(sockfd, buf, MAXDATASIZE, 0)) != 0) {
buf[numbytes] = '\0';
if(result == NULL){
result = strdup(buf);
}else{
result = (char *)realloc(result, strlen(result) + strlen(buf));
result = strcat(result, buf);
}
}
close(sockfd);
return result;
}
/* counts the number of objects in a string */
int count_objects(char * arg){
/* [<][>][^][v][top][bottom][index][help] */
int count = 0;
char *pos = NULL;
char *temp = strdup(arg);
if(isalpha(arg[0])){
count++;
}else if(arg[0] == '\n' && isalpha(arg[1])){
count++;
}
while(pos = strstr(temp,"\n\n")){
pos[0] = 'a'; // something non-EOL so that it won't be caught in the next loop
if(isalpha(pos[2])){
count++;
}
}
cout << "DEBUG: count_objects returning " << count << endl;
return count;
}
/* */
char * take_object(char * arg){
/* [<][>][^][v][top][bottom][index][help] */
char * returned;
char * object = NULL, * pos = NULL;
char * temp = strdup(arg);
if(isalpha(temp[0])){
if(strstr(temp,"\n\n") == NULL){
return temp;
}else{
pos = strstr(temp,"\n\n");
pos[0] = '\0';
return temp;
}
}else if(temp[0] == '\n' && isalpha(temp[1])){
if(strstr(temp,"\n\n") == NULL){
return (char *)temp[1];
}else{
pos = strstr(temp,"\n\n");
pos[0] = '\0';
return (char *)temp[1];
}
}else{
temp = strstr(temp,"\n\n");
temp = temp + 2;
if(strstr(temp,"\n\n") == NULL){
return temp;
}else{
pos = strstr(temp,"\n\n");
pos[0] = '\0';
return temp;
}
}
}
/* Takes an autnum_object, and returns the as-block containing this aut-num */
char * get_as_block(char *autnum_object){
/* [<][>][^][v][top][bottom][index][help] */
bool code;
char * search_key = NULL, * query_string = NULL;
char * result = NULL;
Object * o = new Object();
code = o->scan(autnum_object, strlen(autnum_object));
search_key = get_search_key(o,"aut-num",autnum_object);
query_string = (char *)malloc(strlen("-Tas-block -r ")+strlen(search_key)+1);
sprintf(query_string, "-Tas-block -r %s",search_key);
result = send_and_get("reimp", 43, query_string);
if(count_objects(result) == 0){
cout << "No such as-block" << endl;
return NULL;
}else if(count_objects(result) > 1){
cout << "More than one as-block returned" << endl;
return NULL;
}else{ // count_objects(result) == 1
return take_object(result);
}
}
/* Takes a domain_object, and returns the less specific domain of it */
char * get_less_specific_domain(char *domain_object){
/* [<][>][^][v][top][bottom][index][help] */
bool code;
char * search_key = NULL, * query_string = NULL;
char * result = NULL, * domain = NULL;
Object * o = new Object();
int i,j, length;
char * temp = NULL;
char ** splitted;
code = o->scan(domain_object, strlen(domain_object));
domain = get_search_key(o,"domain",domain_object);
/* split the domain from its dots ('50' is the max # of pieces, this number is just arbitrary) */
splitted = g_strsplit((char *)strdup(domain), ".", 50);
for(i=1; splitted[i] != NULL; i++){
/* in the following for loop, we will construct the 'less spec' domains
to be looked up in the DB */
for(j=i; splitted[j] !=NULL; j++){
length = 0;
if(temp!=NULL){
length = strlen(temp);
}
temp = (char *)realloc(temp, length + strlen(splitted[j]) + 2);
if(j==i){
temp = (char *)strdup(splitted[j]);
}else{
sprintf(temp, "%s.%s", temp, splitted[j]);
}
}
query_string = (char *)malloc(strlen("-Tdomain -r -R ")+strlen(temp)+1);
sprintf(query_string, "-Tdomain -r -R %s", temp);
result = send_and_get("reimp", 43, query_string);
if(count_objects(result) == 0){
}else if(count_objects(result) > 1){
cout << "DEBUG: get_less_specific_domain: More than one domains returned" << endl;
return NULL; /* error condition */
}else{ /* count_objects(result) == 1 */
return take_object(result);
}
}
/* release the memory allocated to **splitted */
for(i=0; splitted[i] != NULL; i++){
free(splitted[i]);
}
/* so, we couldn't find any 'less specific' domain */
return NULL;
}
/* Takes a hierarchical set_object, and returns the less specific set or auth-num of it
by striping down the object's name ( eg, for as35:rs-trial:rs-myset,
as35:rs-trial is tried ) */
char * get_less_specific_set(char *set_object, char *type){
/* [<][>][^][v][top][bottom][index][help] */
bool code;
char * search_key = NULL, * query_string = NULL;
char * result = NULL;
Object * o = new Object();
int i;
code = o->scan(set_object, strlen(set_object));
search_key = get_search_key(o, type, set_object);
delete(o);
for(i = strlen(search_key) -1; i > -1; i--){
if(search_key[i] == ':'){
search_key[i] = '\0'; /* truncate the string */
break;
}
if(i == 0){/* if we've reached the beginning of the string
(this means there wasn't any ';' in the string) */
free(search_key);
search_key = NULL;
}
}
if( search_key == NULL || strlen(search_key) == 0){/* this mustn't happen in fact, since
we make sure that the name of the
set_object contains a ':' in a proper place */
return NULL;
}
query_string = (char *)malloc(strlen("-Taut-num,as-set,rtr-set,peering-set,filter-set -r ")+strlen(search_key)+1);
sprintf(query_string, "-Taut-num,as-set,rtr-set,peering-set,filter-set -r %s", search_key);
result = send_and_get("reimp", 43, query_string);
if(count_objects(result) == 0){
cout << "No such object" << endl;
return NULL;
}else if(count_objects(result) > 1){
cout << "More than one objects returned" << endl;
return NULL;
}else{ // count_objects(result) == 1
return take_object(result);
}
}
/* Takes an inetnum or inet6num object and returnes one less specific of it */
char * get_less_specific(char *inetnum_object, char *type){
/* [<][>][^][v][top][bottom][index][help] */
bool code;
char * search_key = NULL, * query_string = NULL;
char * result = NULL;
Object * o = new Object();
code = o->scan(inetnum_object, strlen(inetnum_object));
search_key = get_search_key(o, type, inetnum_object);
query_string = (char *)malloc(strlen("-Tinet6num -r -l")+strlen(search_key)+1);
sprintf(query_string, "-T%s -r -l %s",type, search_key);
result = send_and_get("reimp", 43, query_string);
if(count_objects(result) == 0){
cout << "No such " << type << endl;
return NULL;
}else if(count_objects(result) > 1){
cout << "More than one " << type << " returned" << endl;
return NULL;
}else{ // count_objects(result) == 1
return take_object(result);
}
}
/* Gets an object as a string and returns its 'mnt-by' attributes as a
GSList (linked list) */
GSList *get_mntners(char * object){
/* [<][>][^][v][top][bottom][index][help] */
bool code;
Object * o;
Attr *attr;
char *value = NULL;
GSList *list_of_mntners = NULL;
cout << "DEBUG: get_mntners is running" << endl;
o = new Object;
code = o->scan(object,strlen(object));
for(attr = o->attrs.head(); attr; attr = o->attrs.next(attr)){
value = (char*)malloc((*attr).len - strlen(attr->type->name()) - 1);
strncpy(value, (char *)(object+attr->offset) + strlen(attr->type->name())+1,
attr->len - strlen(attr->type->name()) -2 );
value[attr->len - strlen(attr->type->name()) - 2 ] = '\0';
//cout << "value: #" << value << "#" << endl;
if(strcmp(attr->type->name(),"mnt-by") == 0){
cout << "DEBUG: get_mntners: adding " << g_strstrip(value) << endl;
list_of_mntners = g_slist_append(list_of_mntners, strdup(g_strstrip(value)));
}
}
return list_of_mntners;
}
/* Gets a (maintainer) object as a string and returns its 'auth' attributes
as a GSList (linked list) */
GSList *get_auths(char * object){
/* [<][>][^][v][top][bottom][index][help] */
bool code;
Object * o;
Attr *attr;
char *value = NULL;
GSList *list_of_auths = NULL;
cout << "DEBUG: get_auths is running" << endl;
o = new Object;
code = o->scan(object,strlen(object));
for(attr = o->attrs.head(); attr; attr = o->attrs.next(attr)){
value = (char*)malloc((*attr).len - strlen(attr->type->name()) - 1);
strncpy(value, (char *)(object+attr->offset) + strlen(attr->type->name())+1,
attr->len - strlen(attr->type->name()) -2 );
value[attr->len - strlen(attr->type->name()) - 2 ] = '\0';
//cout << "value: #" << value << "#" << endl;
if(strcmp(attr->type->name(),"auth") == 0){
cout << "DEBUG: get_auths: adding " << g_strstrip(value) << endl;
list_of_auths = g_slist_append(list_of_auths, strdup(g_strstrip(value)));
cout << "DEBUG: get_auths: # of nodes in list_of_auths is now " << g_slist_length(list_of_auths) << endl;
}
}
cout << "DEBUG: get_auths: returning" << endl;
return list_of_auths;
}
/* Gets an object as a string an returns its mnt_lower attributes as a
GSList (linked list) */
GSList *get_mnt_lowers(char * object){
/* [<][>][^][v][top][bottom][index][help] */
bool code;
Object * o;
Attr *attr;
char *value = NULL;
GSList *list_of_mnt_lowers = NULL;
cout << "DEBUG: get_mnt_lowers is running" << endl;
o = new Object;
code = o->scan(object,strlen(object));
for(attr = o->attrs.head(); attr; attr = o->attrs.next(attr)){
value = (char*)malloc((*attr).len - strlen(attr->type->name()) - 1);
strncpy(value, (char *)(object+attr->offset) + strlen(attr->type->name())+1,
attr->len - strlen(attr->type->name()) -2 );
value[attr->len - strlen(attr->type->name()) - 2 ] = '\0';
//cout << "value: #" << value << "#" << endl;
if(strcmp(attr->type->name(),"mnt-lower") == 0){
cout << "DEBUG: get_mnt_lowers: adding " << g_strstrip(value) << endl;
list_of_mnt_lowers = g_slist_append(list_of_mnt_lowers, strdup(g_strstrip(value)));
}
}
return list_of_mnt_lowers;
}
/* retrieves the override password from the 'override' attribute
of the object. If none, it returns NULL */
char *get_override(char * object){
/* [<][>][^][v][top][bottom][index][help] */
bool code;
Object * o;
Attr *attr;
char *value = NULL;
cout << "DEBUG: get_override is running" << endl;
o = new Object;
code = o->scan(object,strlen(object));
for(attr = o->attrs.head(); attr; attr = o->attrs.next(attr)){
value = (char*)malloc((*attr).len - strlen(attr->type->name()) - 1);
strncpy(value, (char *)(object+attr->offset) + strlen(attr->type->name())+1,
attr->len - strlen(attr->type->name()) -2 );
value[attr->len - strlen(attr->type->name()) - 2 ] = '\0';
//cout << "value: #" << value << "#" << endl;
if(strcmp(attr->type->name(),"override") == 0){
cout << "DEBUG: get_override: returning " << g_strstrip(value) << endl;
return strdup(g_strstrip(value));
}
}
/* there was no 'override' attrib, so return NULL */
return NULL;
}
/* checks override string (password)
returns OVR_OK if it is correct password */
int check_override(char * string){
/* [<][>][^][v][top][bottom][index][help] */
return OVR_OK; // for now
}
/* takes a GSList of struct auth_struct and a GSList of auths, and a mntner name,
add new elements to GSList of struct auth_struct and returns the new
GSList of struct auth_struct */
GSList * add_to_auth_vector(GSList * list_of_auth_struct, GSList * auths, char * mntner_name){
/* [<][>][^][v][top][bottom][index][help] */
//GSList * to_be_returned = NULL;
GSList * next;
char * auth_attrib = NULL;
char * auth_attrib_uppercase = NULL, * argument = NULL;
struct auth_struct * temp = NULL;
int index = 1;
for(next = auths; next != NULL; next = g_slist_next(next)){
auth_attrib = strdup((char *)next->data);
auth_attrib = g_strstrip(auth_attrib);
cout << "DEBUG: add_to_auth_vector: " << auth_attrib << endl;
/* Take the auth attribute and convert it into uppercase for comparisons */
auth_attrib_uppercase = strdup(auth_attrib);
g_strup(auth_attrib_uppercase);
if(strstr(auth_attrib_uppercase,"CRYPT-PW") == auth_attrib_uppercase){
/* take the argument of the auth attribute */
argument = strdup(auth_attrib + strlen("CRYPT-PW"));
g_strstrip(argument);
cout << "DEBUG: add_to_auth_vector: adding new argument: " << argument << endl;
temp = (struct auth_struct *)malloc(sizeof(auth_struct));
temp->type = AU_CRYPT_PW;
temp->auth = argument;
temp->mntner_name = mntner_name;
temp->index = index++;
list_of_auth_struct = g_slist_append(list_of_auth_struct, temp);
}else if(strstr(auth_attrib_uppercase,"MAIL-FROM") == auth_attrib_uppercase){
/* take the argument of the auth attribute */
argument = strdup(auth_attrib + strlen("MAIL-FROM"));
g_strstrip(argument);
cout << "DEBUG: add_to_auth_vector: adding new argument: " << argument << endl;
temp = (struct auth_struct *)malloc(sizeof(auth_struct));
temp->type = AU_MAIL_FROM;
temp->auth = argument;
temp->mntner_name = mntner_name;
temp->index = index++;
list_of_auth_struct = g_slist_append(list_of_auth_struct, temp);
}else if(strstr(auth_attrib_uppercase,"PGP-") == auth_attrib_uppercase){
temp = (struct auth_struct *)malloc(sizeof(auth_struct));
temp->type = AU_PGP;
temp->mntner_name = mntner_name;
temp->index = index++;
/* temp->pgp_struct must be assigned, not yet implemented */
cout << "Not implemented totally (PGP)" << endl;
}else{
cout << "Error: invalid auth attrib: " << auth_attrib << endl;
return NULL;
}
}
free(auth_attrib_uppercase);
free(auth_attrib);
return list_of_auth_struct;
}
/* constructs the authorisation vector, which is a GSList of
struct auth_struct */
GSList * get_auth_vector(GSList * mntners){
/* [<][>][^][v][top][bottom][index][help] */
GSList * list_of_auths = NULL;
GSList * next = NULL;
GSList * to_be_returned = NULL;
char * query_string = NULL, * result = NULL, * object = NULL;
GSList * temp;
for( next = mntners; next != NULL ; next = g_slist_next(next) ){
cout << "=====" << endl << "Got a mntner" << endl;
cout << (char *)next->data << endl;
query_string = (char *)malloc(strlen("-Tmntner -r ")+strlen((char *)next->data)+1);
sprintf(query_string, "-Tmntner -r %s",(char *)next->data);
result = send_and_get("reimp", 43, query_string);
if(count_objects(result) == 0){
cout << "No such maintainer, exiting" << endl;
exit(1);
}else if(count_objects(result) > 1){
cout << "More than one objects returned" << endl;
}else{ /* count_objects(result) == 1 */
object = take_object(result);
cout << "DEBUG: get_auth_vector: Calling get_auths(char *)" << endl;
temp = get_auths(object);
cout << "DEBUG: get_auth_vector: get_auths(char *) returned" << endl;
list_of_auths = g_slist_concat(list_of_auths, temp);
to_be_returned = add_to_auth_vector(to_be_returned, list_of_auths, (char *)next->data);
}
}
return to_be_returned;
}
/* Check authorisation
Applies authorisation rules according to the object type */
int check_auth(char *new_object, char *old_object, char *type){
/* [<][>][^][v][top][bottom][index][help] */
GSList *old_mntners = NULL, *new_mntners = NULL;
GSList *old_auths = NULL, *new_auths = NULL;
GSList *as_block_mnt_lowers = NULL;
GSList *old_auth_vector = NULL, *new_auth_vector = NULL, *as_block_auth_vector = NULL;
GSList *less_specific_auth_vector = NULL, *less_specific_mnt_lowers = NULL;
GSList *less_specific_mntners = NULL;
char *as_block_object = NULL, *less_specific_object = NULL;
char *less_specific_domain = NULL;
char *less_specific_object_type = NULL;
int overriden = 0;
char *override_string = NULL;
char *set_name = NULL;
Object *set_object = new Object();
Object *temp_obj;
bool code;
/* first check if it is overriden or not. if overriden, check the override
password. If it is correct, continue, setting "overriden" to 1. If not,
immediately exit returning ERR_UP_OVF */
override_string = get_override((new_object == NULL) ? old_object : new_object );
if(override_string == NULL){
overriden = 0;
}else if(check_override(override_string) == OVR_OK){
overriden = 1; // authorisation is overriden
}else if(check_override(override_string) == ERROR_UP_OVS){
return ERROR_UP_OVS; // override syntax error --it must have at least two words
}else{
return ERROR_UP_OVF; // override failed!
}
/*
* Handle the "person", "role", "limerick", "inet-rtr" types
*/
if(strcmp(type,"person") == 0 || strcmp(type,"role") == 0 ||
strcmp(type,"limerick") == 0 || strcmp(type,"inet-rtr") == 0 ){
if( new_object == NULL && old_object != NULL ){ // the object is to be deleted
old_mntners = get_mntners(old_object);
old_auth_vector = get_auth_vector(old_mntners);
//return authorise(old_auth_vector, overriden, ...);
}else if( new_object != NULL && old_object == NULL ){ // the object is to be created
new_mntners = get_mntners(new_object);
new_auth_vector = get_auth_vector(new_mntners);
//return authorise(new_auth_vector, overriden, ...);
}else if( new_object != NULL && old_object != NULL ){ // this is an update
old_mntners = get_mntners(old_object);
old_auth_vector = get_auth_vector(old_mntners);
if(old_auth_vector){ // if we have mntners in the old object, use them
//return authorise(old_auths_vector, overriden, ...);
}else{
new_mntners = get_mntners(new_object);
new_auth_vector = get_auth_vector(new_mntners);
//return authorise(new_auth_vector, overriden, ...);
}
}else{ // both are NULL, mustn't happen
cout << "DEBUG: check_auth: internal error: Both pointers are NULL" << endl;
return ERROR_UP_INT; /* internal error */
}
}
/*
* Handle the "auth-num" type
*/
else if(strcmp(type,"aut-num") == 0 ){
if( new_object == NULL && old_object != NULL ){ /* the object is to be deleted */
old_mntners = get_mntners(old_object);
old_auth_vector = get_auth_vector(old_mntners);
//return authorise(old_auth_vector, overriden, ...);
}else if( new_object != NULL && old_object == NULL ){ /* the object is to be created */
as_block_object = get_as_block(new_object);
if(as_block_object == NULL ){
return ERROR_UP_ABN; /* As-block does not exist */
}else{
as_block_mnt_lowers = get_mnt_lowers(as_block_object);
as_block_auth_vector = get_auth_vector(as_block_mnt_lowers);
if(1/* authorise(as_block_auth_vector, overriden, ...) == UP_AUTH_OK */){
new_mntners = get_mntners(new_object);
new_auth_vector = get_auth_vector(new_mntners);
//return authorise(new_auth_vector, overriden, ...);
}else{
return ERROR_UP_HOF; /* hierarchical auth failed */
}
}
}else if( new_object != NULL && old_object != NULL ){ /* this is an update */
old_mntners = get_mntners(old_object);
old_auth_vector = get_auth_vector(old_mntners);
if(old_auth_vector){ /* if we have mntners in the old object, use them */
//return authorise(old_auth_vector, overriden, ...);
}else{
new_mntners = get_mntners(new_object);
new_auth_vector = get_auth_vector(new_mntners);
//return authorise(new_auth_vector, overriden, ...);
}
}else{ /* both are NULL, mustn't happen */
cout << "DEBUG: check_auth: internal error: Both pointers are NULL" << endl;
return ERROR_UP_INT; /* internal error */
}
}
/*
* Handle the "mntner/as-block" types
*/
else if(strcmp(type,"mntner") == 0 || strcmp(type,"as-block") == 0 ){
if( new_object == NULL && old_object != NULL ){ /* the object is to be deleted */
old_mntners = get_mntners(old_object);
old_auth_vector = get_auth_vector(old_mntners);
//return authorise(old_auth_vector, overriden, ...);
}else if( new_object != NULL && old_object == NULL ){ /* the object is to be created */
if(overriden){
return UP_AUTH_OK;
}else{/* If not overriden, and if not coming from ripe-dbm, must be forwarded to ripe-dbm */
cout << "DEBUG: check_auth: '" << type << "' creation requested" << endl;
}
}else if( new_object != NULL && old_object != NULL ){ /* this is an update */
old_mntners = get_mntners(old_object);
old_auth_vector = get_auth_vector(old_mntners);
if(old_auth_vector){ /* if we have mntners in the old object, use them */
//return authorise(old_auth_vector, overriden, ...);
}else{
new_mntners = get_mntners(new_object);
new_auth_vector = get_auth_vector(new_mntners);
//return authorise(new_auth_vector, overriden, ...);
}
}else{ // both are NULL, mustn't happen
cout << "DEBUG: check_auth: internal error: Both pointers are NULL" << endl;
return ERROR_UP_INT; /* internal error */
}
}
/*
* Handle the "inetnum/inet6num" types
*/
else if(strcmp(type,"inetnum") == 0 || strcmp(type,"inet6num") == 0 ){
if( new_object == NULL && old_object != NULL ){ /* the object is to be deleted */
old_mntners = get_mntners(old_object);
old_auth_vector = get_auth_vector(old_mntners);
//return authorise(old_auth_vector, overriden, ...);
}else if( new_object != NULL && old_object == NULL ){ /* the object is to be created */
less_specific_object = get_less_specific(new_object, type);
if(less_specific_object == NULL){
if(overriden){
return UP_AUTH_OK;
}else{
return ERROR_UP_HOF; /* hierarchical authorisation failed */
}
}else{ /* if we got an inet(6)num object */
less_specific_mnt_lowers = get_mnt_lowers(less_specific_object);
less_specific_auth_vector = get_auth_vector(less_specific_mnt_lowers);
if(1/* authorise(less_specific_auth_vector, overriden, ...) == UP_AUTH_OK */){
new_mntners = get_mntners(new_object);
new_auth_vector = get_auth_vector(new_mntners);
//return authorise(new_auth_vector, overriden, ...);
}else{
return ERROR_UP_HOF; /* hierarchical authorisation failed */
}
}
}else if( new_object != NULL && old_object != NULL ){ /* this is an update */
old_mntners = get_mntners(old_object);
old_auth_vector = get_auth_vector(old_mntners);
if(old_auth_vector){ // if we have mntners in the old object, use them
//return authorise(old_auth_vector, overriden, ...);
}else{
new_mntners = get_mntners(new_object);
new_auth_vector = get_auth_vector(new_mntners);
//return authorise(new_auth_vector, overriden, ...);
}
}else{ // both are NULL, mustn't happen
cout << "DEBUG: check_auth: internal error: Both pointers are NULL" << endl;
return ERROR_UP_INT; /* internal error */
}
}
/*
* Handle the "domain" type
*/
else if(strcmp(type,"domain") == 0){
if( new_object == NULL && old_object != NULL ){ /* the object is to be deleted */
old_mntners = get_mntners(old_object);
old_auth_vector = get_auth_vector(old_mntners);
//return authorise(old_auth_vector, overriden, ...);
}else if( new_object != NULL && old_object == NULL ){ /* the object is to be created */
/* now, we have to find a 'less specific domain object' for this.
If there is no less specific object, then creation is possible
only with overriding. */
less_specific_domain = get_less_specific_domain(new_object);
if(less_specific_domain == NULL){
if(overriden){/* we didn't get a 'less specific' domain object */
return UP_AUTH_OK;
}else{
return ERROR_UP_HOF; /* hierarchical authorisation failed */
}
}else{ /* we get a 'less specific' domain object */
less_specific_mnt_lowers = get_mnt_lowers(less_specific_domain);
less_specific_auth_vector = get_auth_vector(less_specific_mnt_lowers);
if(1/* authorise(less_specific_auth_vector, overriden, ...) == UP_AUTH_OK */){
new_mntners = get_mntners(new_object);
new_auth_vector = get_auth_vector(new_mntners);
//return authorise(new_auth_vector, overriden, ...);
}else{
return ERROR_UP_HOF; /* hierarchical authorisation failed */
}
}
}else if( new_object != NULL && old_object != NULL ){ /* this is an update */
old_mntners = get_mntners(old_object);
old_auth_vector = get_auth_vector(old_mntners);
if(old_auth_vector){ /* if we have mntners in the old object, use them */
//return authorise(old_auth_vector, overriden, ...);
}else{
new_mntners = get_mntners(new_object);
new_auth_vector = get_auth_vector(new_mntners);
//return authorise(new_auth_vector, overriden, ...);
}
}else{ // both are NULL, mustn't happen
cout << "DEBUG: check_auth: internal error: Both pointers are NULL" << endl;
return ERROR_UP_INT; /* internal error */
}
}
/*
* Handle the set objects ("as-set","rtr-set","peering-set" and "filter-set" types
*/
else if(strcmp(type,"as-set") == 0 || strcmp(type,"rtr-set") == 0 ||
strcmp(type,"peering-set") == 0 || strcmp(type,"filter-set") == 0 ){
if( new_object == NULL && old_object != NULL ){ /* the object is to be deleted */
old_mntners = get_mntners(old_object);
old_auth_vector = get_auth_vector(old_mntners);
//return authorise(old_auth_vector, overriden, ...);
}else if( new_object != NULL && old_object == NULL ){ /* the object is to be created */
code = set_object->scan(new_object, strlen(new_object));
set_name = get_search_key(set_object, type, new_object);
if(strstr(set_name,":") == NULL ){/* if the name is _not_ hierarchical */
new_mntners = get_mntners(new_object);
new_auth_vector = get_auth_vector(new_mntners);
//return authorise(new_auth_vector, overriden, ...);
}else{/* the name is hierarchical */
less_specific_object = get_less_specific_set(new_object, type);
if(less_specific_object != NULL){/* such an object exists */
temp_obj = new Object();
code = temp_obj->scan(less_specific_object, strlen(less_specific_object));
less_specific_object_type = get_type(temp_obj);
delete(temp_obj);
if(strcmp(less_specific_object_type, "aut-num") == 0){/* if this is an aut-num object */
less_specific_mnt_lowers = get_mnt_lowers(less_specific_object);
less_specific_auth_vector = get_auth_vector(less_specific_mnt_lowers);
if(less_specific_auth_vector != NULL){
//return authorise((less_specific_auth_vector, overriden, ...);
}else{/* the less specific object doesn't contain any mnt-lower */
less_specific_mntners = get_mntners(less_specific_object);
less_specific_auth_vector = get_auth_vector(less_specific_mntners);
if(less_specific_auth_vector != NULL){/* less spec object has some mnt-by attribs,
use them */
//return authorise((less_specific_auth_vector, overriden, ...);
}else{/* the less specific object doesn't contain any mnt-by either */
if(overriden){
return UP_AUTH_OK;
}else{
return ERROR_UP_HOF; /* hierarchical authorisation failed */
}
}
}
}else{ /* this is _not_ an aut-num object*/
less_specific_mntners = get_mntners(less_specific_object);
less_specific_auth_vector = get_auth_vector(less_specific_mntners);
if(less_specific_auth_vector != NULL ){/* the set obj has some mnt-by attribs */
//return authorise((less_specific_auth_vector, overriden, ...);
}else{
if(overriden){
return UP_AUTH_OK;
}else{
return ERROR_UP_HOF; /* hierarchical authorisation failed */
}
}
}
}else{/* we don't have a less specific of this set object in the DB */
return ERROR_UP_HOF; /* hierarchical authorisation failed */
}
}
}else if( new_object != NULL && old_object != NULL ){ /* this is an update */
old_mntners = get_mntners(old_object);
old_auth_vector = get_auth_vector(old_mntners);
if(old_auth_vector){ /* if we have mntners in the old object, use them */
//return authorise(old_auth_vector, overriden, ...);
}else{
new_mntners = get_mntners(new_object);
new_auth_vector = get_auth_vector(new_mntners);
//return authorise(new_auth_vector, overriden, ...);
}
}else{ /* both are NULL, mustn't happen */
cout << "DEBUG: check_auth: internal error: Both pointers are NULL" << endl;
return ERROR_UP_INT; /* internal error */
}
}else{ /* other types are not implemented yet */
cout << "check_auth: This type '" << type << "' is not implemented yet" << endl;
return ERROR_UP_NIY; /* not implemented yet */
}
return UP_AUTH_OK; // for now
}
/* Gets the old version of the given "arg" object, which is in char * format
and returns the old version again in char * format */
char * get_old_version(char * arg){
/* [<][>][^][v][top][bottom][index][help] */
bool code = true;
char *type=NULL, *primary_search_key = NULL, *search_string = NULL;
Object *o;
o = new Object;
char *result = NULL;
code = o->scan(arg,strlen(arg));
type = get_type(o);
primary_search_key = get_search_key(o,type, arg);
cout << "type=" << type << endl;
cout << "primary_search_key=" << primary_search_key << endl;
// prepare the search string
search_string = (char *)malloc(strlen(primary_search_key) + strlen("-x -R -r -T")
+ strlen(type) + 1);
sprintf(search_string, "-x -R -r -T%s %s",type, primary_search_key);
result = send_and_get("reimp", 43, search_string);
cout << "send_and_get returned (with search '"<< search_string <<"'): " << endl
<< result << endl;
// count the objects
if(count_objects(result) == 0){
result = NULL; // we don't have any object
}else if(count_objects(result) == 1){
result = take_object(result);
cout << "DEBUG: Take_object returned ***\n" << result << "***" << endl;
}else{ // we have more than one objects, error!
error = ERROR_UP_MOR;
return NULL;
}
return result;
}
int process_object(char * arg){
/* [<][>][^][v][top][bottom][index][help] */
bool code = true;
Object *o;
char * old_version = NULL;
o = new Object;
code = o->scan(arg,strlen(arg));
if(code){
if(o->isDeleted){
old_version = get_old_version(arg);
if(old_version == NULL){ // the object doesn't exist in the db!
return ERROR_UP_NSO; /* no such object */
}else
if(check_auth(NULL, old_version, o->type->getName()) == UP_AUTH_OK){ // check_auth will know that this is a deletion
cout << "DEBUG: Will send the obj to be deleted" << endl;
//send_object_db(arg,"DEL");
}else{
//auth failed !
cout << error_msg << endl;
return ERROR_UP_AUF; /* Auth failed */
}
}else{
old_version = get_old_version(arg);
if(check_auth(arg, old_version,o->type->getName() ) == UP_AUTH_OK){ // note: if the obj is to-be-created,
// old_version becomes NULL
cout << "DEBUG: Will send the obj to be added/updated" << endl;
//send_object_db(arg,"ADD");
}else{
// auth failed !
cout << error_msg << endl;
return ERROR_UP_AUF; /* Auth failed */
}
}
}else{// even if obj doesn't parse properly, it may be a legacy object
// which the user wants to delete...
return ERROR_UP_NIY; /* Not implemented yet */
}
}
void main(int argc, char **argv, char **envp){
/* [<][>][^][v][top][bottom][index][help] */
schema.initialize();
//init_and_set_options(argc, argv, envp);
int count = 0;
char *line;
char *object = NULL;
char *password = NULL;
GSList *list_of_objects = NULL, *next = NULL;
object = NULL;
line = (char *)malloc(1024);
while(fgets(line, 1024,stdin ) != NULL){
/* first, if it is a pasword, save it, but do not regard it as an attrib */
if(strstr(line, "password:") == line){
cout << "This is a password" << endl;
free(password);
password = strdup(line + strlen("password:"));
continue;
}
if(strlen(line) == 1){
cout << endl;
if(object != NULL){
cout << "The object was" << endl << object << endl;
list_of_objects = g_slist_append(list_of_objects, object);
//free(object);
object = NULL;
}
}else{
/* if the line contains only the EOL char */
if(object == NULL && strlen(line) != 1){
object = (char *)malloc(strlen(line));
object = strdup(line);
}
else{
object = (char *)realloc(object, strlen(object) + strlen(line));
object = strcat(object, line);
}
}
}
if(password != NULL){
password = g_strstrip(password);
cout << "This was the password: " << password << endl;
}
cout << "Now, printing out the objects in the list " << endl;
next = list_of_objects;
for( next = list_of_objects; next != NULL ; next = g_slist_next(next) ){
cout << "=====" << endl << "Got a member" << endl;
cout << (char *)next->data << endl;
process_object((char *)next->data);
cout << "=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=" << endl;
}
}