示例#1
0
/*
 * initialized the shared memory block in the parent process
 */
int oidc_cache_shm_post_config(server_rec *s) {
	oidc_cfg *cfg = (oidc_cfg *) ap_get_module_config(s->module_config,
			&auth_openidc_module);

	if (cfg->cache_cfg != NULL) return APR_SUCCESS;
	oidc_cache_cfg_shm_t *context = oidc_cache_shm_cfg_create(s->process->pool);
	cfg->cache_cfg = context;

	/* create the shared memory segment */
	apr_status_t rv = apr_shm_create(&context->shm,
			sizeof(oidc_cache_shm_entry_t) * cfg->cache_shm_size_max,
			NULL, s->process->pool);
	if (rv != APR_SUCCESS) {
		ap_log_error(APLOG_MARK, APLOG_ERR, rv, s,
				"oidc_cache_shm_post_config: apr_shm_create failed to create shared memory segment");
		return HTTP_INTERNAL_SERVER_ERROR;
	}

	/* initialize the whole segment to '/0' */
	int i;
	oidc_cache_shm_entry_t *table = apr_shm_baseaddr_get(context->shm);
	for (i = 0; i < cfg->cache_shm_size_max; i++) {
		table[i].key[0] = '\0';
		table[i].access = 0;
	}

	const char *dir;
	apr_temp_dir_get(&dir, s->process->pool);
	/* construct the mutex filename */
	context->mutex_filename = apr_psprintf(s->process->pool,
			"%s/httpd_mutex.%ld.%pp", dir, (long int) getpid(), s);

	/* create the mutex lock */
	rv = apr_global_mutex_create(&context->mutex,
			(const char *) context->mutex_filename, APR_LOCK_DEFAULT,
			s->process->pool);
	if (rv != APR_SUCCESS) {
		ap_log_error(APLOG_MARK, APLOG_ERR, rv, s,
				"oidc_cache_shm_post_config: apr_global_mutex_create failed to create mutex on file %s",
				context->mutex_filename);
		return HTTP_INTERNAL_SERVER_ERROR;
	}

	/* need this on Linux */
#ifdef AP_NEED_SET_MUTEX_PERMS
#if MODULE_MAGIC_NUMBER_MAJOR >= 20081201
	rv = ap_unixd_set_global_mutex_perms(context->mutex);
#else
	rv = unixd_set_global_mutex_perms(context->mutex);
#endif
	if (rv != APR_SUCCESS) {
		ap_log_error(APLOG_MARK, APLOG_ERR, rv, s,
				"oidc_cache_shm_post_config: unixd_set_global_mutex_perms failed; could not set permissions ");
		return HTTP_INTERNAL_SERVER_ERROR;
	}
#endif

	return OK;
}
示例#2
0
文件: io.c 项目: mah0x211/libkahana
apr_status_t kahanaIOTempDir( apr_pool_t *p, const char **dir )
{
	apr_status_t rc;
	
	// create temp file
	if( ( rc = apr_temp_dir_get( dir, p ) ) ){
		kahanaLogPut( NULL, NULL, "failed to apr_temp_dir_get(): %s", STRERROR_APR( rc ) );
	}
	
	return rc;
}
示例#3
0
文件: path.cpp 项目: Jopie64/GitSvn2
  Path
  Path::getTempDir()
  {
    const char * tempdir = NULL;
    Pool pool;

    if (apr_temp_dir_get(&tempdir, pool) != APR_SUCCESS)
    {
      tempdir = NULL;
    }

    return tempdir;
  }
示例#4
0
文件: io.c 项目: mah0x211/libkahana
apr_status_t kahanaIOTempFile( apr_pool_t *p, apr_file_t **fp, apr_int32_t flags )
{
	int rc = APR_SUCCESS;
	const char *tmpdir = NULL;
	
	// create temp file
	if( ( rc = apr_temp_dir_get( &tmpdir, p ) ) ){
		kahanaLogPut( NULL, NULL, "failed to apr_temp_dir_get(): %s", STRERROR_APR( rc ) );
	}
	else if( ( rc = apr_file_mktemp( fp, (char*)apr_pstrcat( p, tmpdir, "/XXXXXX", NULL ), flags, p ) ) ){
		kahanaLogPut( NULL, NULL, "failed to apr_file_mktemp(): %s", STRERROR_APR( rc ) );
	}
	
	return rc;
}
示例#5
0
文件: io_dir.c 项目: LuaDist/lua-apr
int lua_apr_temp_dir_get(lua_State *L)
{
  apr_pool_t* memory_pool;
  const char *filepath;
  apr_status_t status;

  memory_pool = to_pool(L);
  status = apr_temp_dir_get(&filepath, memory_pool);
  if (status != APR_SUCCESS) {
    return push_error_status(L, status);
  } else {
    lua_pushstring(L, filepath);
    return 1;
  }
}
示例#6
0
static int 
Ganglia_cfg_include(cfg_t *cfg, cfg_opt_t *opt, int argc,
                          const char **argv)
{
    char *fname = (char*)argv[0];
    struct stat statbuf;
    DIR *dir;
    struct dirent *entry;

    if(argc != 1)
    {
        cfg_error(cfg, "wrong number of arguments to cfg_include()");
        return 1;
    }

    if (stat (fname, &statbuf) == 0) 
    {
        return cfg_include(cfg, opt, argc, argv);
    }
    else if (has_wildcard(fname))
    {
        int ret;
        char *path = calloc(strlen(fname) + 1, sizeof(char));
        char *pattern = NULL;
        char *idx = strrchr(fname, '/');
        apr_pool_t *p;
        apr_file_t *ftemp;
        char *dirname = NULL;
        char tn[] = "gmond.tmp.XXXXXX";

        if (idx == NULL) {
            idx = strrchr(fname, '\\');
        }

        if (idx == NULL) {
            strncpy (path, ".", 1);
            pattern = fname;
        }
        else {
            strncpy (path, fname, idx - fname);
            pattern = idx + 1;
        }

        apr_pool_create(&p, NULL);
        if (apr_temp_dir_get((const char**)&dirname, p) != APR_SUCCESS) {
#ifndef LINUX
            cfg_error(cfg, "failed to determine the temp dir");
            apr_pool_destroy(p);
            return 1;
#else
            /*
             * workaround APR BUG46297 by using the POSIX shared memory
             * ramdrive that is available since glibc 2.2
             */
            dirname = apr_psprintf(p, "%s", "/dev/shm");
#endif
        }
        dirname = apr_psprintf(p, "%s/%s", dirname, tn);

        if (apr_file_mktemp(&ftemp, dirname, 
                            APR_CREATE | APR_READ | APR_WRITE | APR_DELONCLOSE, 
                            p) != APR_SUCCESS) {
            cfg_error(cfg, "unable to create a temporary file %s", dirname);
            apr_pool_destroy(p);
            return 1;
        }

        dir = opendir(path);

        if(dir != NULL){
            while((entry = readdir(dir)) != NULL) {
                ret = fnmatch(pattern, entry->d_name, 
                              FNM_PATHNAME|FNM_PERIOD);
                if (ret == 0) {
                    char *newpath, *line;

                    newpath = apr_psprintf (p, "%s/%s", path, entry->d_name);
                    line = apr_pstrcat(p, "include ('", newpath, "')\n", NULL);
                    apr_file_puts(line, ftemp);
                }
            }
            closedir(dir);
            free (path);

            argv[0] = dirname;
            if (cfg_include(cfg, opt, argc, argv))
                cfg_error(cfg, "failed to process include file %s", fname);
            else
                debug_msg("processed include file %s\n", fname);
        }

        apr_file_close(ftemp);
        apr_pool_destroy(p);

        argv[0] = fname;
    }
    else 
    {
        cfg_error(cfg, "invalid include path");
        return 1;
    }

    return 0;
}
示例#7
0
/*
 * Let's do it.  We end up doing a lot of file opening and closing,
 * but what do we care?  This application isn't run constantly.
 */
int main(int argc, const char * const argv[])
{
    apr_file_t *fpw = NULL;
    char record[MAX_STRING_LEN];
    char line[MAX_STRING_LEN];
    char *password = NULL;
    char *pwfilename = NULL;
    char *user = NULL;
    char tn[] = "htpasswd.tmp.XXXXXX";
    char *dirname;
    char *scratch, cp[MAX_STRING_LEN];
    int found = 0;
    int i;
    int alg = ALG_APMD5;
    int mask = 0;
    apr_pool_t *pool;
    int existing_file = 0;
#if APR_CHARSET_EBCDIC
    apr_status_t rv;
    apr_xlate_t *to_ascii;
#endif

    apr_app_initialize(&argc, &argv, NULL);
    atexit(terminate);
    apr_pool_create(&pool, NULL);
    apr_file_open_stderr(&errfile, pool);

#if APR_CHARSET_EBCDIC
    rv = apr_xlate_open(&to_ascii, "ISO-8859-1", APR_DEFAULT_CHARSET, pool);
    if (rv) {
        apr_file_printf(errfile, "apr_xlate_open(to ASCII)->%d" NL, rv);
        exit(1);
    }
    rv = apr_SHA1InitEBCDIC(to_ascii);
    if (rv) {
        apr_file_printf(errfile, "apr_SHA1InitEBCDIC()->%d" NL, rv);
        exit(1);
    }
    rv = apr_MD5InitEBCDIC(to_ascii);
    if (rv) {
        apr_file_printf(errfile, "apr_MD5InitEBCDIC()->%d" NL, rv);
        exit(1);
    }
#endif /*APR_CHARSET_EBCDIC*/

    check_args(pool, argc, argv, &alg, &mask, &user, &pwfilename, &password);


#if defined(WIN32) || defined(NETWARE)
    if (alg == ALG_CRYPT) {
        alg = ALG_APMD5;
        apr_file_printf(errfile, "Automatically using MD5 format." NL);
    }
#endif

#if (!(defined(WIN32) || defined(TPF) || defined(NETWARE)))
    if (alg == ALG_PLAIN) {
        apr_file_printf(errfile,"Warning: storing passwords as plain text "
                        "might just not work on this platform." NL);
    }
#endif

    /*
     * Only do the file checks if we're supposed to frob it.
     */
    if (!(mask & APHTP_NOFILE)) {
        existing_file = exists(pwfilename, pool);
        if (existing_file) {
            /*
             * Check that this existing file is readable and writable.
             */
            if (!accessible(pool, pwfilename, APR_READ | APR_APPEND)) {
                apr_file_printf(errfile, "%s: cannot open file %s for "
                                "read/write access" NL, argv[0], pwfilename);
                exit(ERR_FILEPERM);
            }
        }
        else {
            /*
             * Error out if -c was omitted for this non-existant file.
             */
            if (!(mask & APHTP_NEWFILE)) {
                apr_file_printf(errfile,
                        "%s: cannot modify file %s; use '-c' to create it" NL,
                        argv[0], pwfilename);
                exit(ERR_FILEPERM);
            }
            /*
             * As it doesn't exist yet, verify that we can create it.
             */
            if (!accessible(pool, pwfilename, APR_CREATE | APR_WRITE)) {
                apr_file_printf(errfile, "%s: cannot create file %s" NL,
                                argv[0], pwfilename);
                exit(ERR_FILEPERM);
            }
        }
    }

    /*
     * All the file access checks (if any) have been made.  Time to go to work;
     * try to create the record for the username in question.  If that
     * fails, there's no need to waste any time on file manipulations.
     * Any error message text is returned in the record buffer, since
     * the mkrecord() routine doesn't have access to argv[].
     */
    if (!(mask & APHTP_DELUSER)) {
        i = mkrecord(user, record, sizeof(record) - 1,
                     password, alg);
        if (i != 0) {
            apr_file_printf(errfile, "%s: %s" NL, argv[0], record);
            exit(i);
        }
        if (mask & APHTP_NOFILE) {
            printf("%s" NL, record);
            exit(0);
        }
    }

    /*
     * We can access the files the right way, and we have a record
     * to add or update.  Let's do it..
     */
    if (apr_temp_dir_get((const char**)&dirname, pool) != APR_SUCCESS) {
        apr_file_printf(errfile, "%s: could not determine temp dir" NL,
                        argv[0]);
        exit(ERR_FILEPERM);
    }
    dirname = apr_psprintf(pool, "%s/%s", dirname, tn);

    if (apr_file_mktemp(&ftemp, dirname, 0, pool) != APR_SUCCESS) {
        apr_file_printf(errfile, "%s: unable to create temporary file %s" NL,
                        argv[0], dirname);
        exit(ERR_FILEPERM);
    }

    /*
     * If we're not creating a new file, copy records from the existing
     * one to the temporary file until we find the specified user.
     */
    if (existing_file && !(mask & APHTP_NEWFILE)) {
        if (apr_file_open(&fpw, pwfilename, APR_READ | APR_BUFFERED,
                          APR_OS_DEFAULT, pool) != APR_SUCCESS) {
            apr_file_printf(errfile, "%s: unable to read file %s" NL,
                            argv[0], pwfilename);
            exit(ERR_FILEPERM);
        }
        while (apr_file_gets(line, sizeof(line), fpw) == APR_SUCCESS) {
            char *colon;

            strcpy(cp, line);
            scratch = cp;
            while (apr_isspace(*scratch)) {
                ++scratch;
            }

            if (!*scratch || (*scratch == '#')) {
                putline(ftemp, line);
                continue;
            }
            /*
             * See if this is our user.
             */
            colon = strchr(scratch, ':');
            if (colon != NULL) {
                *colon = '\0';
            }
            else {
                /*
                 * If we've not got a colon on the line, this could well
                 * not be a valid htpasswd file.
                 * We should bail at this point.
                 */
                apr_file_printf(errfile, "%s: The file %s does not appear "
                                         "to be a valid htpasswd file." NL,
                                argv[0], pwfilename);
                apr_file_close(fpw);
                exit(ERR_INVALID);
            }
            if (strcmp(user, scratch) != 0) {
                putline(ftemp, line);
                continue;
            }
            else {
                if (!(mask & APHTP_DELUSER)) {
                    /* We found the user we were looking for.
                     * Add him to the file.
                    */
                    apr_file_printf(errfile, "Updating ");
                    putline(ftemp, record);
                    found++;
                }
                else {
                    /* We found the user we were looking for.
                     * Delete them from the file.
                     */
                    apr_file_printf(errfile, "Deleting ");
                    found++;
                }
            }
        }
        apr_file_close(fpw);
    }
    if (!found && !(mask & APHTP_DELUSER)) {
        apr_file_printf(errfile, "Adding ");
        putline(ftemp, record);
    }
    else if (!found && (mask & APHTP_DELUSER)) {
        apr_file_printf(errfile, "User %s not found" NL, user);
        exit(0);
    }
    apr_file_printf(errfile, "password for user %s" NL, user);

    /* The temporary file has all the data, just copy it to the new location.
     */
    if (apr_file_copy(dirname, pwfilename, APR_FILE_SOURCE_PERMS, pool) !=
        APR_SUCCESS) {
        apr_file_printf(errfile, "%s: unable to update file %s" NL,
                        argv[0], pwfilename);
        exit(ERR_FILEPERM);
    }
    apr_file_close(ftemp);
    return 0;
}
static int exipc_post_config(apr_pool_t *pconf, apr_pool_t *plog, 
                             apr_pool_t *ptemp, server_rec *s)
{
    void *data; /* These two help ensure that we only init once. */
    const char *userdata_key;
    apr_status_t rs;
    exipc_data *base;
    const char *tempdir; 


    /* 
     * The following checks if this routine has been called before. 
     * This is necessary because the parent process gets initialized
     * a couple of times as the server starts up, and we don't want 
     * to create any more mutexes and shared memory segments than
     * we're actually going to use. 
     * 
     * The key needs to be unique for the entire web server, so put
     * the module name in it.
     */ 
    userdata_key = "example_ipc_init_module";
    apr_pool_userdata_get(&data, userdata_key, s->process->pool);
    if (!data) {
        /* 
         * If no data was found for our key, this must be the first
         * time the module is initialized. Put some data under that
         * key and return.
         */
        apr_pool_userdata_set((const void *) 1, userdata_key, 
                              apr_pool_cleanup_null, s->process->pool);
        return OK;
    } /* Kilroy was here */

    /* 
     * Both the shared memory and mutex allocation routines take a
     * file name. Depending on system-specific implementation of these
     * routines, that file may or may not actually be created. We'd
     * like to store those files in the operating system's designated
     * temporary directory, which APR can point us to.
     */
    rs = apr_temp_dir_get(&tempdir, pconf);
    if (APR_SUCCESS != rs) {
        ap_log_error(APLOG_MARK, APLOG_ERR, rs, s, 
                     "Failed to find temporary directory");
        return HTTP_INTERNAL_SERVER_ERROR;
    }

    /* Create the shared memory segment */

    /* 
     * Create a unique filename using our pid. This information is 
     * stashed in the global variable so the children inherit it.
     */
    shmfilename = apr_psprintf(pconf, "%s/httpd_shm.%ld", tempdir, 
                               (long int)getpid());

    /* Now create that segment */
    rs = apr_shm_create(&exipc_shm, sizeof(exipc_data), 
                        (const char *) shmfilename, pconf);
    if (APR_SUCCESS != rs) {
        ap_log_error(APLOG_MARK, APLOG_ERR, rs, s, 
                     "Failed to create shared memory segment on file %s", 
                     shmfilename);
        return HTTP_INTERNAL_SERVER_ERROR;
    }

    /* Created it, now let's zero it out */
    base = (exipc_data *)apr_shm_baseaddr_get(exipc_shm);
    base->counter = 0;

    /* Create global mutex */

    /* 
     * Create another unique filename to lock upon. Note that
     * depending on OS and locking mechanism of choice, the file
     * may or may not be actually created. 
     */
    mutexfilename = apr_psprintf(pconf, "%s/httpd_mutex.%ld", tempdir,
                                 (long int) getpid());
  
    rs = apr_global_mutex_create(&exipc_mutex, (const char *) mutexfilename, 
                                 APR_LOCK_DEFAULT, pconf);
    if (APR_SUCCESS != rs) {
        ap_log_error(APLOG_MARK, APLOG_ERR, rs, s, 
                     "Failed to create mutex on file %s", 
                     mutexfilename);
        return HTTP_INTERNAL_SERVER_ERROR;
    }

    /* 
     * After the mutex is created, its permissions need to be adjusted
     * on unix platforms so that the child processe can acquire
     * it. This call takes care of that. The preprocessor define was
     * set up early in this source file since Apache doesn't provide
     * it.
     */
#ifdef MOD_EXIPC_SET_MUTEX_PERMS
    rs = unixd_set_global_mutex_perms(exipc_mutex);
    if (APR_SUCCESS != rs) {
        ap_log_error(APLOG_MARK, APLOG_CRIT, rs, s, 
                     "Parent could not set permissions on Example IPC "
                     "mutex: check User and Group directives");
        return HTTP_INTERNAL_SERVER_ERROR;
    }
#endif /* MOD_EXIPC_SET_MUTEX_PERMS */

    /* 
     * Destroy the shm segment when the configuration pool gets destroyed. This
     * happens on server restarts. The parent will then (above) allocate a new
     * shm segment that the new children will bind to. 
     */
    apr_pool_cleanup_register(pconf, NULL, shm_cleanup_wrapper, 
                              apr_pool_cleanup_null);    
    return OK;
}
示例#9
0
/*
 * fstream_open
 *
 * Allocate a new file stream given a path (a url). in case of wildcards,
 * expand them here. we end up with a final list of files and include them
 * in our filestream that we return.
 *
 * In case of errors we set the proper http response code to send to the client.
 */
fstream_t*
fstream_open(const char *path, const struct fstream_options *options,
			 int *response_code, const char **response_string)
{
	int i;
	fstream_t* fs;

	*response_code = 500;
	*response_string = "Internal Server Error";

	if (0 == (fs = gfile_malloc(sizeof *fs)))
	{
		gfile_printf_then_putc_newline("fstream out of memory");
		return 0;
	}

	memset(fs, 0, sizeof *fs);
	fs->options = *options;
	fs->buffer = gfile_malloc(options->bufsize);
	
	/*
	 * get a list of all files that were requested to be read and include them
	 * in our fstream. This includes any wildcard pattern matching.
	 */
	if (glob_path(fs, path))
	{
		fstream_close(fs);
		return 0;
	}

	/*
	 * If the list of files in our filestrem includes a directory name, expand
	 * the directory and add all the files inside of it.
	 */
	if (fpath_all_directories(&fs->glob))
	{
		if (expand_directories(fs))
		{
			fstream_close(fs);
			return 0;
		}
	}

	/*
	 * check if we don't have any matching files
	 */
	if (fs->glob.gl_pathc == 0)
	{
		gfile_printf_then_putc_newline("fstream bad path: %s", path);
		fstream_close(fs);
		*response_code = 404;
		*response_string = "No matching file(s) found";
		return 0;
	}

	if (fs->glob.gl_pathc != 1 && options->forwrite)
	{
		gfile_printf_then_putc_newline("fstream open for write found more than one file (%d)",
										fs->glob.gl_pathc);
		*response_code = 404;
		*response_string = "More than 1 file found for writing. Unsupported operation.";

		fstream_close(fs);
		return 0;
	}


#ifdef GPFXDIST
	/*
	 * when the subprocess transformation wants to handle iteration over the files
	 * we write the paths to a temporary file and replace the fs->glob items with
	 * just a single entry referencing the path to the temporary file.
	 */
	if (options->transform && options->transform->pass_paths)
	{
		apr_pool_t*  mp = options->transform->mp;
		apr_file_t*  f = NULL;
		const char*  tempdir = NULL;
		char*        tempfilename = NULL;
		apr_status_t rv;

		if ((rv = apr_temp_dir_get(&tempdir, mp)) != APR_SUCCESS)
		{
			*response_code = 500;
			*response_string = "failed to get temporary directory for paths file";
			gfile_printf_then_putc_newline(*response_string);
			fstream_close(fs);
			return 0;
		}

	    tempfilename = apr_pstrcat(mp, tempdir, "/pathsXXXXXX", NULL);
		if ((rv = apr_file_mktemp(&f, tempfilename, APR_CREATE|APR_WRITE|APR_EXCL, mp)) != APR_SUCCESS)
		{
			*response_code = 500;
			*response_string = "failed to open temporary paths file";
			gfile_printf_then_putc_newline(*response_string);
			fstream_close(fs);
			return 0;
		}

		options->transform->tempfilename = tempfilename;

		for (i = 0; i<fs->glob.gl_pathc; i++)
		{
			char* filename      = fs->glob.gl_pathv[i];
			apr_size_t expected = strlen(filename) + 1;
			
			if (apr_file_printf(f, "%s\n", filename) < expected)
			{
				apr_file_close(f);

				*response_code = 500;
				*response_string = "failed to fully write path to temporary paths file";
				gfile_printf_then_putc_newline(*response_string);
				fstream_close(fs);
				return 0;
			}
		}

		apr_file_close(f);

		if (glob_adjust(fs, tempfilename, response_code, response_string)) 
		{
			fstream_close(fs);
			return 0;
		}
	}
#endif

	/*
	 * if writing - check write access rights for the one file.
	 * if reading - check read access right for all files, and 
	 * then close them, leaving the first file open.
	 * 
	 */
	for (i = fs->glob.gl_pathc; --i >= 0;)
	{
		/*
		 * CR-2173 - the fstream code allows the upper level logic to treat a
		 * collection of input sources as a single stream.  One problem it has
		 * to handle is the possibility that some of the underlying sources may
		 * not be readable.  Here we're trying to detect potential problems in
		 * advance by checking that we can open and close each source in our
		 * list in reverse order.
		 *
		 * However in the case of subprocess transformations, we don't want to 
		 * start and stop each transformation in this manner.  The check that 
		 * each transformation's underlying input source can be read is still 
		 * useful so we do those until we get to the first source, at which 
		 * point we proceed to just setup the tranformation for it.
		 */
		struct gpfxdist_t* transform = (i == 0) ? options->transform : NULL;

		gfile_close(&fs->fd);

		if (gfile_open(&fs->fd, fs->glob.gl_pathv[i], gfile_open_flags(options->forwrite, options->usesync),
					   response_code, response_string, transform))
		{
			gfile_printf_then_putc_newline("fstream unable to open file %s",
					fs->glob.gl_pathv[i]);
			fstream_close(fs);
			return 0;
		}

		fs->compressed_size += gfile_get_compressed_size(&fs->fd);
	}

	fs->line_number = 1;
	fs->skip_header_line = options->header;

	return fs;
}
示例#10
0
int main(int argc, const char * const argv[])
{
    apr_file_t *f;
    apr_status_t rv;
    char tn[] = "htdigest.tmp.XXXXXX";
    char *dirname;
    char user[MAX_STRING_LEN];
    char realm[MAX_STRING_LEN];
    char line[MAX_STRING_LEN];
    char l[MAX_STRING_LEN];
    char w[MAX_STRING_LEN];
    char x[MAX_STRING_LEN];
    int found;
   
    apr_app_initialize(&argc, &argv, NULL);
    atexit(terminate); 
    apr_pool_create(&cntxt, NULL);
    apr_file_open_stderr(&errfile, cntxt);

#if APR_CHARSET_EBCDIC
    rv = apr_xlate_open(&to_ascii, "ISO8859-1", APR_DEFAULT_CHARSET, cntxt);
    if (rv) {
        apr_file_printf(errfile, "apr_xlate_open(): %s (%d)\n",
                apr_strerror(rv, line, sizeof(line)), rv);
        exit(1);
    }
#endif
    
    apr_signal(SIGINT, (void (*)(int)) interrupted);
    if (argc == 5) {
        if (strcmp(argv[1], "-c"))
            usage();
        rv = apr_file_open(&f, argv[2], APR_WRITE | APR_CREATE,
                           APR_OS_DEFAULT, cntxt);
        if (rv != APR_SUCCESS) {
            char errmsg[120];

            apr_file_printf(errfile, "Could not open passwd file %s for writing: %s\n",
                    argv[2],
                    apr_strerror(rv, errmsg, sizeof errmsg));
            exit(1);
        }
        apr_file_printf(errfile, "Adding password for %s in realm %s.\n", 
                    argv[4], argv[3]);
        add_password(argv[4], argv[3], f);
        apr_file_close(f);
        exit(0);
    }
    else if (argc != 4)
        usage();

    if (apr_temp_dir_get((const char**)&dirname, cntxt) != APR_SUCCESS) {
        apr_file_printf(errfile, "%s: could not determine temp dir\n",
                        argv[0]);
        exit(1);
    }
    dirname = apr_psprintf(cntxt, "%s/%s", dirname, tn);

    if (apr_file_mktemp(&tfp, dirname, 0, cntxt) != APR_SUCCESS) {
        apr_file_printf(errfile, "Could not open temp file %s.\n", dirname);
        exit(1);
    }

    if (apr_file_open(&f, argv[1], APR_READ, APR_OS_DEFAULT, cntxt) != APR_SUCCESS) {
        apr_file_printf(errfile,
                "Could not open passwd file %s for reading.\n", argv[1]);
        apr_file_printf(errfile, "Use -c option to create new one.\n");
        cleanup_tempfile_and_exit(1);
    }
    apr_cpystrn(user, argv[3], sizeof(user));
    apr_cpystrn(realm, argv[2], sizeof(realm));

    found = 0;
    while (!(get_line(line, MAX_STRING_LEN, f))) {
        if (found || (line[0] == '#') || (!line[0])) {
            putline(tfp, line);
            continue;
        }
        strcpy(l, line);
        getword(w, l, ':');
        getword(x, l, ':');
        if (strcmp(user, w) || strcmp(realm, x)) {
            putline(tfp, line);
            continue;
        }
        else {
            apr_file_printf(errfile, "Changing password for user %s in realm %s\n", 
                    user, realm);
            add_password(user, realm, tfp);
            found = 1;
        }
    }
    if (!found) {
        apr_file_printf(errfile, "Adding user %s in realm %s\n", user, realm);
        add_password(user, realm, tfp);
    }
    apr_file_close(f);

    /* The temporary file has all the data, just copy it to the new location.
     */
    if (apr_file_copy(dirname, argv[1], APR_FILE_SOURCE_PERMS, cntxt) !=
                APR_SUCCESS) {
        apr_file_printf(errfile, "%s: unable to update file %s\n", 
                        argv[0], argv[1]);
    }
    apr_file_close(tfp);

    return 0;
}
示例#11
0
/*
 * This routine is called in the parent, so we'll set up the shared
 * memory segments and mutexs here.
 */
static int dosblock_post_config(apr_pool_t *pconf, apr_pool_t *plog,
                             apr_pool_t *ptemp, server_rec *s)
{
    void *data; /* These two help ensure that we only init once. */
    const char *userdata_key;
    apr_status_t rs;
    const char *tempdir;
    dosblockipc_data *base;
    dosblock_cfg *cfg = (dosblock_cfg *)ap_get_module_config(s->module_config, &mod_dosblock_module);
    /*
     * The following checks if this routine has been called before.
     * This is necessary because the parent process gets initialized
     * a couple of times as the server starts up, and we don't want
     * to create any more mutexes and shared memory segments than
     * we're actually going to use.
     *
     * The key needs to be unique for the entire web server, so put
     * the module name in it.
     */
    userdata_key = "dosblock_ipc_init_module";
    apr_pool_userdata_get(&data, userdata_key, s->process->pool);

    if (!data) {
        /*
         * If no data was found for our key, this must be the first
         * time the module is initialized. Put some data under that
         * key and return.
         */
        apr_pool_userdata_set((const void *) 1, userdata_key,
                              apr_pool_cleanup_null, s->process->pool);
        return OK;
    }

    /*
     * The shared memory allocation routines take a file name.
     * Depending on system-specific implementation of these
     * routines, that file may or may not actually be created. We'd
     * like to store those files in the operating system's designated
     * temporary directory, which APR can point us to.
     */
    rs = apr_temp_dir_get(&tempdir, pconf);
    if (APR_SUCCESS != rs) {
        ap_log_error(APLOG_MARK, APLOG_ERR, rs, s,
                     "Failed to find temporary directory");
        return HTTP_INTERNAL_SERVER_ERROR;
    }

    /* Create the shared memory segments. We also populate a dosrule to shared
     * memory mapping table with all the shared memory segments
     */

    const apr_array_header_t *tarr = apr_table_elts(cfg->dosrulemap);
    const apr_table_entry_t *telts = (const apr_table_entry_t*)tarr->elts;
    int i;

    for (i = 0; i < tarr->nelts; ++i) {
     /*
      * Create a unique filename using our pid. This information is
      * stashed in the global variable so the children inherit it.
      */
       shmfilename = apr_psprintf(pconf, "%s/httpd_shm_%s.%ld", tempdir,
                               telts[i].key, (long int)getpid());
       mutex_filename = apr_psprintf(pconf, "%s/httpd_mutex_%s.%ld", tempdir,
                               telts[i].key, (long int)getpid());

       /* Now create that shm segment. We prefer anonymous shm */
       rs = apr_shm_create(&dosblockipc_shm[i], sizeof(dosblockipc_data),
                        NULL, pconf);
       if (APR_ENOTIMPL == rs) {
         rs = apr_shm_create(&dosblockipc_shm[i], sizeof(dosblockipc_data),
                        (const char *) shmfilename, pconf);
         }
       if (APR_SUCCESS != rs) {
           ap_log_error(APLOG_MARK, APLOG_ERR, rs, s,
                       "Failed to create shared memory segment on file %s",
                       shmfilename);
           return HTTP_INTERNAL_SERVER_ERROR;
       }
       apr_hash_set(cfg->dosrule_shm_map, telts[i].key, APR_HASH_KEY_STRING, apr_psprintf(pconf, "%d",i));
       if (cfg->verbosity)
          ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, "Dos Rule configured is %s", telts[i].key);

       base = (dosblockipc_data *)apr_shm_baseaddr_get(dosblockipc_shm[i]);
       /* Now initialise the array of structs. Zero it out */
       base->ds.t = 0;
       base->ds.isblocked = 0;
       base->ds.rate_when_blocked = 0;
       base->next = 0;
       int j;
       for (j=0; j<ARSIZE; j++) {
         base->dh[j].t = 0;
         base->dh[j].counter = 0;

       }
       /* Create global mutex */

       rs = apr_global_mutex_create(&dosblockipc_mutex[i], mutex_filename, APR_LOCK_DEFAULT, pconf);
      if (APR_SUCCESS != rs) {
          return HTTP_INTERNAL_SERVER_ERROR;
       }
       #ifdef AP_NEED_SET_MUTEX_PERMS
          rs = unixd_set_global_mutex_perms(dosblockipc_mutex[i]);
          if (rs != APR_SUCCESS) {
              ap_log_error(APLOG_MARK, APLOG_CRIT, rs, s,
                 "mod_dosblock: Parent could not set permissions "
                 "on shared memory; check User and Group directives");
              return rs;
           }
       #endif

      apr_table_set(cfg->dosrule_mutex_map, telts[i].key, mutex_filename);

    }
    /*
     * Destroy the shm segment when the configuration pool gets destroyed. This
     *happens on server restarts. The parent will then (above) allocate a new
     * shm segment that the new children will bind to.
     */

    /*
     apr_pool_cleanup_register(pconf, NULL, shm_cleanup_wrapper(),
                              apr_pool_cleanup_null);
    */
     return OK;
}