htdigest.c revision 5df5e943f377522b19786f126097da3a7288e2f0
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb/* Licensed to the Apache Software Foundation (ASF) under one or more
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * contributor license agreements. See the NOTICE file distributed with
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * this work for additional information regarding copyright ownership.
bc8fd1b0b1afdf89b8d28eefa8cd74e26ba97986fielding * The ASF licenses this file to You under the Apache License, Version 2.0
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * (the "License"); you may not use this file except in compliance with
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * the License. You may obtain a copy of the License at
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb *
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * http://www.apache.org/licenses/LICENSE-2.0
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb *
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * Unless required by applicable law or agreed to in writing, software
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * distributed under the License is distributed on an "AS IS" BASIS,
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * See the License for the specific language governing permissions and
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * limitations under the License.
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb */
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb/******************************************************************************
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb ******************************************************************************
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * NOTE! This program is not safe as a setuid executable! Do not make it
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * setuid!
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb ******************************************************************************
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb *****************************************************************************/
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb/*
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * htdigest.c: simple program for manipulating digest passwd file for Apache
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb *
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * by Alexei Kosut, based on htpasswd.c, by Rob McCool
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb */
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb#include "apr.h"
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb#include "apr_file_io.h"
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb#include "apr_md5.h"
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb#include "apr_lib.h" /* for apr_getpass() */
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb#include "apr_general.h"
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb#include "apr_signal.h"
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb#include "apr_strings.h" /* for apr_pstrdup() */
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb#define APR_WANT_STDIO
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb#define APR_WANT_STRFUNC
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb#include "apr_want.h"
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb#if APR_HAVE_SYS_TYPES_H
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb#include <sys/types.h>
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb#endif
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb#if APR_HAVE_STDLIB_H
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb#include <stdlib.h>
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb#endif
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb#ifdef WIN32
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb#include <conio.h>
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb#endif
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb#if APR_CHARSET_EBCDIC
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb#define LF '\n'
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb#define CR '\r'
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb#else
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb#define LF 10
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb#define CR 13
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb#endif /* APR_CHARSET_EBCDIC */
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb#define MAX_STRING_LEN 256
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbbapr_file_t *tfp = NULL;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbbapr_file_t *errfile;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbbapr_pool_t *cntxt;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb#if APR_CHARSET_EBCDIC
b38846b15c8891c6dec44dcc4f96ca40721bf663rbbapr_xlate_t *to_ascii;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb#endif
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbbstatic void cleanup_tempfile_and_exit(int rc)
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb{
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb if (tfp) {
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb apr_file_close(tfp);
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb }
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb exit(rc);
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb}
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbbstatic void getword(char *word, char *line, char stop)
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb{
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb int x = 0, y;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb for (x = 0; ((line[x]) && (line[x] != stop)); x++)
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb word[x] = line[x];
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb word[x] = '\0';
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb if (line[x])
f888346b48f5e5b5e3f0a47dedb8cefd2759a4e2gregames ++x;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb y = 0;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb while ((line[y++] = line[x++]));
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb}
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbbstatic int get_line(char *s, int n, apr_file_t *f)
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb{
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb int i = 0;
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz char ch;
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz apr_status_t rv = APR_EINVAL;
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz /* we need 2 remaining bytes in buffer */
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz while (i < (n - 2) &&
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz ((rv = apr_file_getc(&ch, f)) == APR_SUCCESS) && (ch != '\n')) {
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz s[i++] = ch;
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz }
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz /* First remaining byte potentially used here */
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb if (ch == '\n')
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb s[i++] = ch;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb /* Second remaining byte used here */
4f9c22c4f27571d54197be9674e1fc0d528192aestriker s[i] = '\0';
a2a0abd88b19e042a3eb2a9fa1702c25ad51303dwrowe
4f9c22c4f27571d54197be9674e1fc0d528192aestriker if (rv != APR_SUCCESS)
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb return 1;
4f9c22c4f27571d54197be9674e1fc0d528192aestriker
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb return 0;
4f9c22c4f27571d54197be9674e1fc0d528192aestriker}
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
4f9c22c4f27571d54197be9674e1fc0d528192aestrikerstatic void putline(apr_file_t *f, char *l)
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb{
4f9c22c4f27571d54197be9674e1fc0d528192aestriker int x;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
4f9c22c4f27571d54197be9674e1fc0d528192aestriker for (x = 0; l[x]; x++)
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb apr_file_putc(l[x], f);
4f9c22c4f27571d54197be9674e1fc0d528192aestriker}
4f9c22c4f27571d54197be9674e1fc0d528192aestriker
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowestatic void add_password(const char *user, const char *realm, apr_file_t *f)
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe{
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe char *pw;
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe apr_md5_ctx_t context;
2d399cd7535887fceaa9f8f116eb98ce68ddd602trawick unsigned char digest[16];
c2cf53a40a9814eb91db2cdf820f97d943f21628coar char string[3 * MAX_STRING_LEN]; /* this includes room for 2 * ':' + '\0' */
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe char pwin[MAX_STRING_LEN];
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe char pwv[MAX_STRING_LEN];
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar unsigned int i;
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe apr_size_t len = sizeof(pwin);
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe if (apr_password_get("New password: ", pwin, &len) != APR_SUCCESS) {
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe apr_file_printf(errfile, "password too long");
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe cleanup_tempfile_and_exit(5);
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe }
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe len = sizeof(pwin);
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe apr_password_get("Re-type new password: ", pwv, &len);
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe if (strcmp(pwin, pwv) != 0) {
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe apr_file_printf(errfile, "They don't match, sorry.\n");
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe cleanup_tempfile_and_exit(1);
3e392a5afd51526de3cb15d57ee46d8cb160ae65gregames }
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe pw = pwin;
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe apr_file_printf(f, "%s:%s:", user, realm);
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe /* Do MD5 stuff */
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz apr_snprintf(string, sizeof(string), "%s:%s:%s", user, realm, pw);
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz
2a6e98ba4ffa30ded5d8831664c5cb2a170a56b6coar apr_md5_init(&context);
2a6e98ba4ffa30ded5d8831664c5cb2a170a56b6coar#if APR_CHARSET_EBCDIC
130bd4741181084da8800031c24c2e8fc767c107coar apr_md5_set_xlate(&context, to_ascii);
130bd4741181084da8800031c24c2e8fc767c107coar#endif
2a6e98ba4ffa30ded5d8831664c5cb2a170a56b6coar apr_md5_update(&context, (unsigned char *) string, strlen(string));
2a6e98ba4ffa30ded5d8831664c5cb2a170a56b6coar apr_md5_final(digest, &context);
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz for (i = 0; i < 16; i++)
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe apr_file_printf(f, "%02x", digest[i]);
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe apr_file_printf(f, "\n");
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe}
4f9c22c4f27571d54197be9674e1fc0d528192aestriker
4f9c22c4f27571d54197be9674e1fc0d528192aestrikerstatic void usage(void)
3e392a5afd51526de3cb15d57ee46d8cb160ae65gregames{
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe apr_file_printf(errfile, "Usage: htdigest [-c] passwordfile realm username\n");
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar apr_file_printf(errfile, "The -c flag creates a new file.\n");
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe exit(1);
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe}
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowestatic void interrupted(void)
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe{
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe apr_file_printf(errfile, "Interrupted.\n");
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe cleanup_tempfile_and_exit(1);
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe}
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe
4f9c22c4f27571d54197be9674e1fc0d528192aestrikerstatic void terminate(void)
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe{
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe apr_terminate();
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe#ifdef NETWARE
c2cf53a40a9814eb91db2cdf820f97d943f21628coar pressanykey();
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe#endif
4775dfc34c90fada8c7c4d6a57ed8a3114d55c2dtrawick}
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewroweint main(int argc, const char * const argv[])
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe{
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe apr_file_t *f;
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar apr_status_t rv;
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe char tn[] = "htdigest.tmp.XXXXXX";
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe char *dirname;
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe char user[MAX_STRING_LEN];
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe char realm[MAX_STRING_LEN];
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe char line[3 * MAX_STRING_LEN];
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe char l[3 * MAX_STRING_LEN];
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe char w[MAX_STRING_LEN];
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe char x[MAX_STRING_LEN];
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe int found;
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe apr_app_initialize(&argc, &argv, NULL);
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe atexit(terminate);
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe apr_pool_create(&cntxt, NULL);
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe apr_file_open_stderr(&errfile, cntxt);
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe#if APR_CHARSET_EBCDIC
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe rv = apr_xlate_open(&to_ascii, "ISO-8859-1", APR_DEFAULT_CHARSET, cntxt);
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe if (rv) {
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe apr_file_printf(errfile, "apr_xlate_open(): %pm (%d)\n",
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe &rv, rv);
4f9c22c4f27571d54197be9674e1fc0d528192aestriker exit(1);
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe }
4f9c22c4f27571d54197be9674e1fc0d528192aestriker#endif
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe
4f9c22c4f27571d54197be9674e1fc0d528192aestriker apr_signal(SIGINT, (void (*)(int)) interrupted);
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe if (argc == 5) {
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe if (strcmp(argv[1], "-c"))
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar usage();
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe rv = apr_file_open(&f, argv[2], APR_WRITE | APR_CREATE,
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe APR_OS_DEFAULT, cntxt);
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe if (rv != APR_SUCCESS) {
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe apr_file_printf(errfile, "Could not open passwd file %s for writing: %pm\n",
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe argv[2], &rv);
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe exit(1);
4f9c22c4f27571d54197be9674e1fc0d528192aestriker }
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe apr_cpystrn(user, argv[4], sizeof(user));
c2cf53a40a9814eb91db2cdf820f97d943f21628coar apr_cpystrn(realm, argv[3], sizeof(realm));
c2cf53a40a9814eb91db2cdf820f97d943f21628coar apr_file_printf(errfile, "Adding password for %s in realm %s.\n",
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe user, realm);
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz add_password(user, realm, f);
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz apr_file_close(f);
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz exit(0);
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe }
4f9c22c4f27571d54197be9674e1fc0d528192aestriker else if (argc != 4)
c2cf53a40a9814eb91db2cdf820f97d943f21628coar usage();
c2cf53a40a9814eb91db2cdf820f97d943f21628coar
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe if (apr_temp_dir_get((const char**)&dirname, cntxt) != APR_SUCCESS) {
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz apr_file_printf(errfile, "%s: could not determine temp dir\n",
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz argv[0]);
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz exit(1);
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe }
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe dirname = apr_psprintf(cntxt, "%s/%s", dirname, tn);
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe
4f9c22c4f27571d54197be9674e1fc0d528192aestriker if (apr_file_mktemp(&tfp, dirname, 0, cntxt) != APR_SUCCESS) {
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe apr_file_printf(errfile, "Could not open temp file %s.\n", dirname);
4f9c22c4f27571d54197be9674e1fc0d528192aestriker exit(1);
4f9c22c4f27571d54197be9674e1fc0d528192aestriker }
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe if (apr_file_open(&f, argv[1], APR_READ, APR_OS_DEFAULT, cntxt) != APR_SUCCESS) {
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz apr_file_printf(errfile,
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz "Could not open passwd file %s for reading.\n", argv[1]);
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz apr_file_printf(errfile, "Use -c option to create new one.\n");
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe cleanup_tempfile_and_exit(1);
4f9c22c4f27571d54197be9674e1fc0d528192aestriker }
c2cf53a40a9814eb91db2cdf820f97d943f21628coar apr_cpystrn(user, argv[3], sizeof(user));
c2cf53a40a9814eb91db2cdf820f97d943f21628coar apr_cpystrn(realm, argv[2], sizeof(realm));
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz found = 0;
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz while (!(get_line(line, sizeof(line), f))) {
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz if (found || (line[0] == '#') || (!line[0])) {
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe putline(tfp, line);
4f9c22c4f27571d54197be9674e1fc0d528192aestriker continue;
c2cf53a40a9814eb91db2cdf820f97d943f21628coar }
c2cf53a40a9814eb91db2cdf820f97d943f21628coar strcpy(l, line);
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe getword(w, l, ':');
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz getword(x, l, ':');
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz if (strcmp(user, w) || strcmp(realm, x)) {
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz putline(tfp, line);
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe continue;
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe }
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe else {
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe apr_file_printf(errfile, "Changing password for user %s in realm %s\n",
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe user, realm);
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe add_password(user, realm, tfp);
4f9c22c4f27571d54197be9674e1fc0d528192aestriker found = 1;
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe }
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe }
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe if (!found) {
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz apr_file_printf(errfile, "Adding user %s in realm %s\n", user, realm);
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe add_password(user, realm, tfp);
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe }
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe apr_file_close(f);
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe /* The temporary file has all the data, just copy it to the new location.
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe */
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe if (apr_file_copy(dirname, argv[1], APR_FILE_SOURCE_PERMS, cntxt) !=
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe APR_SUCCESS) {
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe apr_file_printf(errfile, "%s: unable to update file %s\n",
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe argv[0], argv[1]);
cc9582e53aead2a044077c4a92f3dfc3605590b3wrowe }
cc9582e53aead2a044077c4a92f3dfc3605590b3wrowe apr_file_close(tfp);
cc9582e53aead2a044077c4a92f3dfc3605590b3wrowe
cc9582e53aead2a044077c4a92f3dfc3605590b3wrowe return 0;
cc9582e53aead2a044077c4a92f3dfc3605590b3wrowe}
4f9c22c4f27571d54197be9674e1fc0d528192aestriker