Esempio n. 1
0
/**
 * prelude_daemonize:
 * @lockfile: Filename to a lockfile.
 *
 * Puts caller in background.
 * If @lockfile is not NULL, a lock for this program is created.
 *
 * The lockfile is automatically unlinked on exit.
 *
 * Returns: 0 on success, -1 if an error occured.
 */
int prelude_daemonize(const char *lockfile)
{
        pid_t pid;
        int fd = 0, ret, i;

        if ( lockfile ) {
                ret = get_absolute_filename(lockfile);
                if ( ret < 0 )
                        return ret;
        }

#if (defined _WIN32 || defined __WIN32__) && !defined __CYGWIN__
        prelude_log(PRELUDE_LOG_ERR, "Daemonize call unsupported in this environment.\n");
        pid = getpid();
#else
        pid = fork();
        if ( pid < 0 )
                return prelude_error_from_errno(errno);

        else if ( pid )
                _exit(0);
#endif

        if ( lockfile ) {
                fd = lockfile_get_exclusive(slockfile);
                if ( fd < 0 )
                        return fd;

                ret = lockfile_write_pid(fd, getpid());
                if ( ret < 0 )
                        return ret;
        }

#if !((defined _WIN32 || defined __WIN32__) && !defined __CYGWIN__)
        setsid();

        ret = chdir("/");
        if ( ret < 0 )
                prelude_log(PRELUDE_LOG_ERR, "could not change working directory to '/': %s.\n", strerror(errno));

        umask(0);

        fd = open("/dev/null", O_RDWR);
        if ( fd < 0 )
                return prelude_error_from_errno(errno);

        for ( i = 0; i <= 2; i++ ) {
                do {
                        ret = dup2(fd, i);
                } while ( ret < 0 && errno == EINTR );

                if ( ret < 0 )
                        return prelude_error_from_errno(errno);
        }

        close(fd);
#endif

        return 0;
}
Esempio n. 2
0
/**
 * prelude_string_get_string_released:
 * @string: Pointer to a #prelude_string_t object.
 * @outptr: Pointer to an address where to store the released string.
 *
 * Get @string content, and release it so that further operation on
 * @string won't modify the returned content.
 *
 * Returns: 0 on success, or a negative value if an error occured.
 */
int prelude_string_get_string_released(prelude_string_t *string, char **outptr)
{
        prelude_return_val_if_fail(string, prelude_error(PRELUDE_ERROR_ASSERTION));
        *outptr = NULL;

        if ( ! string->index )
                return 0;

        if ( ! (string->flags & PRELUDE_STRING_OWN_DATA) ) {
                *outptr = strdup(string->data.robuf);
                return (*outptr) ? 0 : prelude_error_from_errno(errno);
        }

        if ( string->index + 1 <= string->index )
                return prelude_error(PRELUDE_ERROR_INVAL_LENGTH);

        *outptr = _prelude_realloc(string->data.rwbuf, string->index + 1);
        if ( ! *outptr )
                return prelude_error_from_errno(errno);

        string->size = 0;
        string->index = 0;
        string->data.rwbuf = NULL;

        return 0;
}
Esempio n. 3
0
int _prelude_get_file_name_and_path(const char *str, char **name, char **path)
{
        int ret = 0;
        char *ptr, pathname[PATH_MAX] = { 0 };

        ptr = strrchr(str, '/');
        if ( ! ptr ) {
                ret = find_absolute_path(_prelude_init_cwd, str, path);
                if ( ret < 0 )
                        return ret;

                *name = strdup(str);
                return (*name) ? 0 :  prelude_error_from_errno(errno);
        }

        if ( *str != '/' ) {
                char needsep = 0;
                size_t cwdlen = strlen(_prelude_init_cwd);

                if ( cwdlen )
                        needsep = (_prelude_init_cwd[cwdlen - 1] != '/' ) ? '/' : '\0';

                ret = snprintf(pathname, sizeof(pathname), "%s%c", _prelude_init_cwd, needsep);
                if ( ret < 0 || (size_t) ret >= sizeof(pathname) )
                        return prelude_error_from_errno(errno);
        }

        strncat(pathname, str, sizeof(pathname) - strlen(pathname));
        normalize_path(pathname);

        ret = access(pathname, F_OK);
        if ( ret < 0 )
                return prelude_error_from_errno(errno);

        ptr = strrchr(pathname, '/');

        *path = strndup(pathname, ptr - pathname);
        if ( ! *path )
                return prelude_error_from_errno(errno);

        *name = strdup(ptr + 1);
        if ( ! *name ) {
                free(*path);
                return prelude_error_from_errno(errno);
        }

        return 0;
}
Esempio n. 4
0
static int op_delete_line(config_t *cfg, unsigned int start, unsigned int end)
{
        unsigned int i, j;

        if ( ! cfg->elements )
                return 0;

        if ( start >= end || end > cfg->elements )
                return -1;

        for ( i = start; i < end; i++ ) {
                free(cfg->content[i]);
                cfg->content[i] = NULL;
        }

        for ( i = end, j = start; i < cfg->elements; i++ )
                cfg->content[j++] = cfg->content[i];

        cfg->elements -= end - start;

        cfg->content = _prelude_realloc(cfg->content, cfg->elements * sizeof(char **));
        if ( ! cfg->content )
                return prelude_error_from_errno(errno);

        return 0;
}
Esempio n. 5
0
/**
 * prelude_string_clone:
 * @src: Pointer to an existing #prelude_string_t object.
 * @dst: Pointer to an address where to store the created #prelude_string_t object.
 *
 * Clone @src within a new #prelude_string_t object stored into @dst.
 * Data carried by @dst and @src are independant.
 *
 * Returns: 0 on success, or a negative value if an error occured.
 */
int prelude_string_clone(const prelude_string_t *src, prelude_string_t **dst)
{
        int ret;

        prelude_return_val_if_fail(src, prelude_error(PRELUDE_ERROR_ASSERTION));

        ret = prelude_string_new(dst);
        if ( ret < 0 )
                return ret;

        (*dst)->size = src->size;
        (*dst)->index = src->index;
        (*dst)->flags |= PRELUDE_STRING_OWN_DATA;

        if ( src->size ) {
                (*dst)->data.rwbuf = malloc(src->size);
                if ( ! (*dst)->data.rwbuf ) {
                        prelude_string_destroy(*dst);
                        return prelude_error_from_errno(errno);
                }

                string_buf_copy(*dst, src->data.robuf, src->index);
        }

        return 0;
}
/**
 * prelude_client_profile_new:
 * @ret: Pointer where to store the address of the created object.
 * @name: Name for this profile.
 *
 * Creates a new #prelude_client_profile_t object and store its
 * address into @ret.
 *
 * Returns: 0 on success or a negative value if an error occured.
 */
int prelude_client_profile_new(prelude_client_profile_t **ret, const char *name)
{
        int retval;
        prelude_client_profile_t *cp;

        prelude_return_val_if_fail(name, prelude_error(PRELUDE_ERROR_ASSERTION));

        retval = _prelude_client_profile_new(&cp);
        if ( retval < 0 )
                return retval;

        cp->name = strdup(name);
        if ( ! cp->name ) {
                free(cp);
                return prelude_error_from_errno(errno);
        }

        retval = _prelude_client_profile_init(cp);
        if ( retval < 0 )
                return retval;

        *ret = cp;

        return 0;
}
Esempio n. 7
0
static int allocate_more_chunk_if_needed(prelude_string_t *s, size_t needed_len)
{
        int ret;
        char *ptr;
        size_t len;

        if ( ! needed_len )
                len = BUFFER_CHUNK_SIZE;
        else
                len = MAX(needed_len - (s->size - s->index), s->size * BUFFER_GROWTH_FACTOR);

        if ( s->size + len < s->size )
                return prelude_error(PRELUDE_ERROR_INVAL_LENGTH);

        if ( s->flags & PRELUDE_STRING_OWN_DATA ) {
                ptr = _prelude_realloc(s->data.rwbuf, s->size + len);
                if ( ! ptr )
                        return prelude_error_from_errno(errno);

                s->size += len;
                s->data.rwbuf = ptr;
        }

        else {
                ret = make_string_own(s, s->size + len);
                if ( ret < 0 )
                        return ret;
        }

        return 0;
}
Esempio n. 8
0
/**
 * idmef_time_new:
 * @time: Address where to store the created #idmef_time_t object.
 *
 * Creates an empty #idmef_time_t object and store it in @time.
 *
 * Returns: 0 on success, a negative value if an error occured.
 */
int idmef_time_new(idmef_time_t **time)
{
        *time = calloc(1, sizeof(**time));
        if ( ! *time )
                return prelude_error_from_errno(errno);

        (*time)->refcount = 1;

        return 0;
}
Esempio n. 9
0
/**
 * idmef_time_new_from_gettimeofday:
 * @time: Address where to store the created #idmef_time_t object.
 *
 * Creates an #idmef_time_t object filled with information retrieved
 * using gettimeofday(), and stores it in @time.
 *
 * Returns: 0 on success, a negative value if an error occured.
 */
int idmef_time_new_from_gettimeofday(idmef_time_t **time)
{
        int ret;
        struct timeval tv;

        ret = gettimeofday(&tv, NULL);
        if ( ret < 0 )
                return prelude_error_from_errno(errno);

        return idmef_time_new_from_timeval(time, &tv);
}
static int file_access_table_name_resolver(const idmef_path_t *path, char **table_name)
{
        const char *child_name = idmef_path_get_name(path, idmef_path_get_depth(path) - 1);

        if ( strcmp(child_name, "permission") == 0 )
                *table_name = strdup("Prelude_FileAccess_Permission");
        else
                *table_name = strdup("Prelude_FileAccess");

        return *table_name ? 0 : prelude_error_from_errno(errno);
}
static int web_service_table_name_resolver(const idmef_path_t *path, char **table_name)
{
        const char *child_name = idmef_path_get_name(path, idmef_path_get_depth(path) - 1);

        if ( strcmp(child_name, "arg") == 0 )
                *table_name = strdup("Prelude_WebServiceArg");
        else
                *table_name = strdup("Prelude_WebService");

        return *table_name ? 0 : prelude_error_from_errno(errno);
}
Esempio n. 12
0
/**
 * prelude_string_new:
 * @string: Pointer where to store the created #prelude_string_t.
 *
 * Create a new #prelude_string_t object, and store in in @string.
 *
 * Returns: 0 on success, or a negative value if an error occured.
 */
int prelude_string_new(prelude_string_t **string)
{
        *string = calloc(1, sizeof(**string));
        if ( ! *string )
                return prelude_error_from_errno(errno);

        (*string)->refcount = 1;
        prelude_list_init(&(*string)->_list);
        (*string)->flags = PRELUDE_STRING_OWN_STRUCTURE;

        return 0;
}
int _prelude_client_profile_new(prelude_client_profile_t **ret)
{
        *ret = calloc(1, sizeof(**ret));
        if ( ! *ret )
                return prelude_error_from_errno(errno);

        (*ret)->refcount = 1;
        (*ret)->uid = geteuid();
        (*ret)->gid = getegid();

        return 0;
}
static int process_table_name_resolver(const idmef_path_t *path, char **table_name)
{
        const char *child_name = idmef_path_get_name(path, idmef_path_get_depth(path) - 1);

        if ( strcmp(child_name, "arg") == 0 )
                *table_name = strdup("Prelude_ProcessArg");
        else if ( strcmp(child_name, "env") == 0 )
                *table_name = strdup("Prelude_ProcessEnv");
        else
                *table_name = strdup("Prelude_Process");

        return *table_name ? 0 : prelude_error_from_errno(errno);
}
Esempio n. 15
0
/**
 * idmef_time_set_from_gettimeofday:
 * @time: Pointer to an #idmef_time_t object.
 *
 * Fills @time with information retrieved using gettimeofday().
 *
 * Returns: 0 on success, a negative value if an error occured.
 */
int idmef_time_set_from_gettimeofday(idmef_time_t *time)
{
        int ret;
        struct timeval tv;

        prelude_return_val_if_fail(time, prelude_error(PRELUDE_ERROR_ASSERTION));

        ret = gettimeofday(&tv, NULL);
        if ( ret < 0 )
                return prelude_error_from_errno(errno);

        return idmef_time_set_from_timeval(time, &tv);
}
/**
 * prelude_client_profile_set_name:
 * @cp: Pointer to a #prelude_client_profile_t object.
 * @name: Name to associate the profile with.
 *
 * Sets the prelude client profile name.
 *
 * Returns: 0 on success or a negative value if an error occured.
 */
int prelude_client_profile_set_name(prelude_client_profile_t *cp, const char *name)
{
        prelude_return_val_if_fail(cp, prelude_error(PRELUDE_ERROR_ASSERTION));
        prelude_return_val_if_fail(name, prelude_error(PRELUDE_ERROR_ASSERTION));

        if ( cp->name )
                free(cp->name);

        cp->name = strdup(name);
        if ( ! cp->name )
                return prelude_error_from_errno(errno);

        return 0;
}
Esempio n. 17
0
int prelude_get_gmt_offset_from_time(const time_t *utc, long *gmtoff)
{
        time_t local;
        struct tm lt;

        if ( ! localtime_r(utc, &lt) )
                return prelude_error_from_errno(errno);

        local = timegm(&lt);

        *gmtoff = local - *utc;

        return 0;
}
Esempio n. 18
0
static int string_buf_alloc(prelude_string_t *string, size_t len)
{
        /*
         * include room for terminating \0.
         */
        string->data.rwbuf = malloc(len + 1);
        if ( ! string->data.rwbuf )
                return prelude_error_from_errno(errno);

        string->index = len;
        string->size = len + 1;

        return 0;
}
static int message_table_name_resolver(const idmef_path_t *path, char **table_name)
{
        const char *child_name = idmef_path_get_name(path, idmef_path_get_depth(path) - 1);

        if ( strcmp(child_name, "create_time") == 0 )
                *table_name = strdup("Prelude_CreateTime");
        else if ( strcmp(child_name, "detect_time") == 0 )
                *table_name = strdup("Prelude_DetectTime");
        else if ( strcmp(child_name, "analyzer_time") == 0 )
                *table_name = strdup("Prelude_AnalyzerTime");
        else
                return default_table_name_resolver(path, table_name);

        return *table_name ? 0 : prelude_error_from_errno(errno);
}
Esempio n. 20
0
static int lockfile_get_exclusive(const char *lockfile)
{
        int fd;
#if !((defined _WIN32 || defined __WIN32__) && !defined __CYGWIN__)
        int ret;
        struct flock lock;
#endif

        fd = open(lockfile, O_WRONLY|O_CREAT, S_IRUSR|S_IWUSR);
        if ( fd < 0 )
                return prelude_error_from_errno(errno);

#if !((defined _WIN32 || defined __WIN32__) && !defined __CYGWIN__)
        fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC);

        lock.l_type = F_WRLCK;    /* write lock */
        lock.l_start = 0;         /* from offset 0 */
        lock.l_whence = SEEK_SET; /* at the beginning of the file */
        lock.l_len = 0;           /* until EOF */

        ret = fcntl(fd, F_SETLK, &lock);
        if ( ret < 0 ) {
                if ( errno == EACCES || errno == EAGAIN )
                        return prelude_error_verbose(PRELUDE_ERROR_DAEMONIZE_LOCK_HELD,
                                                     "'%s' lock is held by another process", slockfile);

                close(fd);
                return prelude_error_from_errno(errno);
        }
#endif

        /*
         * lock is now held until program exits.
         */
        return fd;
}
Esempio n. 21
0
int prelude_log_set_logfile(const char *filename)
{
        if ( ! filename && debug_logfile ) {
                fclose(debug_logfile);
                debug_logfile = NULL;
        }

        else {
                debug_logfile = fopen(filename, "a");
                if ( ! debug_logfile )
                        return prelude_error_from_errno(errno);
        }

        return 0;
}
Esempio n. 22
0
static int lockfile_write_pid(int fd, pid_t pid)
{
        int ret = -1;
        char buf[50];

        /*
         * Resets file size to 0.
         */
#ifdef HAVE_FTRUNCATE
        ret = ftruncate(fd, 0);
#elif HAVE_CHSIZE
        ret = chsize(fd, 0);
#endif
        if ( ret < 0 )
                return prelude_error_from_errno(errno);

        snprintf(buf, sizeof(buf), "%d\n", (int) pid);

        ret = write(fd, buf, strlen(buf));
        if ( ret < 0 )
                return prelude_error_from_errno(errno);

        return 0;
}
Esempio n. 23
0
static int resolve_addr(server_generic_t *server, const char *addr, unsigned int port)
{
        struct addrinfo *ai;
        int ret, ai_family, ai_addrlen;

#if ! ((defined _WIN32 || defined __WIN32__) && !defined __CYGWIN__)
        const char *unixpath = NULL;

        if ( is_unix_addr(&unixpath, addr) ) {
                ai_family = AF_UNIX;
                ai_addrlen = sizeof(struct sockaddr_un);
        }

        else {
#endif
                ret = do_getaddrinfo(&ai, addr, port);
                if ( ret < 0 )
                        return ret;

                ai_family = ai->ai_family;
                ai_addrlen = ai->ai_addrlen;
#if ! ((defined _WIN32 || defined __WIN32__) && !defined __CYGWIN__)
        }
#endif

        server->sa = malloc(ai_addrlen);
        if ( ! server->sa ) {
                freeaddrinfo(ai);
                return prelude_error_from_errno(errno);
        }

        server->slen = ai_addrlen;
        server->sa->sa_family = ai_family;

        if ( ai_family != AF_UNIX ) {
                memcpy(server->sa, ai->ai_addr, ai->ai_addrlen);
                freeaddrinfo(ai);
        }

#if ! ((defined _WIN32 || defined __WIN32__) && !defined __CYGWIN__)
        else {
                struct sockaddr_un *un = (struct sockaddr_un *) server->sa;
                strncpy(un->sun_path, unixpath, sizeof(un->sun_path));
        }
#endif

        return 0;
}
/**
 * prelude_client_profile_set_prefix:
 * @cp: pointer on a #prelude_client_profile_t object.
 * @prefix: Prefix to use for various libprelude files.
 *
 * This function allow to dynamically change the prefix used to acess
 * libprelude related file. This is particularly usefull in case of
 * application running under certain condition (chroot).
 *
 * Returns: 0 on success, a negative value if an error occured.
 */
int prelude_client_profile_set_prefix(prelude_client_profile_t *cp, const char *prefix)
{
        char *n;

        n = strdup(prefix);

        gl_lock_lock(lock);

        if ( user_prefix )
                free(user_prefix);

        user_prefix = n;

        gl_lock_unlock(lock);

        return (n) ? 0 : prelude_error_from_errno(errno);
}
Esempio n. 25
0
static int make_string_own(prelude_string_t *s, size_t len)
{
        char *ptr;

        ptr = malloc(len);
        if ( ! ptr )
                return prelude_error_from_errno(errno);

        if ( s->data.robuf )
                memcpy(ptr, s->data.robuf, s->index + 1);

        s->size = len;
        s->data.rwbuf = ptr;
        s->flags |= PRELUDE_STRING_OWN_DATA;

        return 0;
}
Esempio n. 26
0
/*
 * Appends a line to an array of line.
 * Takes the address of the array and the line to append as arguments.
 *
 * list must be NULL the first time this function is called,
 * in order to initialize indexing variable.
 */
static int op_append_line(config_t *cfg, char *line)
{
        if ( ! line )
                return 0;

        if ( cfg->elements + 1 < cfg->elements )
                return -1;

        cfg->elements++;

        cfg->content = _prelude_realloc(cfg->content, cfg->elements * sizeof(char **));
        if ( ! cfg->content )
                return prelude_error_from_errno(errno);

        cfg->content[cfg->elements - 1] = line;

        return 0;
}
static int config_save_value(config_t *cfg, int rtype, prelude_option_t *last, int is_last_cmd,
                             char **prev, const char *option, const char *value, unsigned int *line)
{
        int ret = 0;
        char buf[1024];

        if ( ! (prelude_option_get_type(last) & PRELUDE_OPTION_TYPE_CFG) )
                return -1;

        if ( rtype != PRELUDE_MSG_OPTION_SET && rtype != PRELUDE_MSG_OPTION_DESTROY )
                return -1;

        if ( prelude_option_has_optlist(last) ) {

                if ( prelude_option_get_type(last) & PRELUDE_OPTION_TYPE_CONTEXT )
                        snprintf(buf, sizeof(buf), "%s=%s", option, (value) ? value : "default");
                else
                        snprintf(buf, sizeof(buf), "%s", option);

                if ( *prev )
                        free(*prev);

                *prev = strdup(buf);
                if ( ! *prev )
                        return prelude_error_from_errno(errno);

                if ( rtype == PRELUDE_MSG_OPTION_SET )
                        return _config_set(cfg, buf, NULL, NULL, line);

                else if ( is_last_cmd )
                        return _config_del(cfg, buf, NULL);

        }

        if ( rtype == PRELUDE_MSG_OPTION_SET )
                ret = _config_set(cfg, *prev, option, value, line);

        else if ( is_last_cmd )
                ret = _config_del(cfg, *prev, option);

        return ret;
}
Esempio n. 28
0
int prelude_get_gmt_offset_from_tm(struct tm *tm, long *gmtoff)
{
        int tmp;
        time_t local, utc;

        /*
         * timegm will reset tm_isdst to 0
         */
        tmp = tm->tm_isdst;
        utc = timegm(tm);
        tm->tm_isdst = tmp;

        local = mktime(tm);
        if ( local == (time_t) -1 )
                return prelude_error_from_errno(errno);

        *gmtoff = utc - mktime(tm);

        return 0;
}
Esempio n. 29
0
int server_generic_bind_numeric(server_generic_t *server, struct sockaddr *sa, socklen_t len, unsigned int port)
{
        int ret;

        server->sa = malloc(len);
        if ( ! server->sa )
                return prelude_error_from_errno(errno);

        server->slen = len;
        memcpy(server->sa, sa, len);

        ret = inet_server_start(server, server->sa, server->slen);
        if ( ret < 0 ) {
                free(server->sa);
                server->sa = NULL;
                return ret;
        }

        return sg_bind_common(server, port);
}
Esempio n. 30
0
/**
 * prelude_string_copy_dup:
 * @src: Pointer to a #prelude_string_t object to copy data from.
 * @dst: Pointer to a #prelude_string_t object to copy data to.
 *
 * Copy @src content within @dst.
 * The content is owned by @src and independent of @dst.
 *
 * Returns: 0 on success, or a negative value if an error occured.
 */
int prelude_string_copy_dup(const prelude_string_t *src, prelude_string_t *dst)
{
        prelude_return_val_if_fail(src, prelude_error(PRELUDE_ERROR_ASSERTION));
        prelude_return_val_if_fail(dst, prelude_error(PRELUDE_ERROR_ASSERTION));

        prelude_string_destroy_internal(dst);

        dst->size = src->size;
        dst->index = src->index;
        dst->flags |= PRELUDE_STRING_OWN_DATA;

        if ( src->size ) {
                dst->data.rwbuf = malloc(src->size);
                if ( ! dst->data.rwbuf )
                        return prelude_error_from_errno(errno);

                string_buf_copy(dst, src->data.robuf, src->index);
        }

        return 0;
}