Index: support/htdbm.c =================================================================== --- support/htdbm.c (revision 1872030) +++ support/htdbm.c (working copy) @@ -68,6 +68,9 @@ char *comment; char *type; int create; + int allowcolon; + int keep; + int writevalue; int rdonly; }; @@ -161,8 +164,11 @@ key.dptr = htdbm->username; key.dsize = strlen(htdbm->username); - if (apr_dbm_exists(htdbm->dbm, key)) + if (apr_dbm_exists(htdbm->dbm, key)) { + if (htdbm->keep) + return APR_EEXIST; *changed = 1; + } val.dsize = strlen(htdbm->ctx.passwd); if (!htdbm->comment) @@ -205,6 +211,7 @@ pwd = apr_pstrndup(htdbm->ctx.pool, rec, cmnt - rec); else pwd = apr_pstrdup(htdbm->ctx.pool, rec); + if (htdbm->writevalue) fwrite(val.dptr, 1, val.dsize, stdout); return apr_password_validate(htdbm->ctx.passwd, pwd); } @@ -266,7 +273,7 @@ fprintf(stderr, "Invalid username length\n"); return APR_EINVAL; } - if (strchr(htdbm->username, ':')) { + if (!htdbm->allowcolon && strchr(htdbm->username, ':')) { fprintf(stderr, "Username contains invalid characters\n"); return APR_EINVAL; } @@ -277,14 +284,14 @@ { fprintf(stderr, "htdbm -- program for manipulating DBM password databases.\n\n" - "Usage: htdbm [-cimBdpstvx] [-C cost] [-TDBTYPE] database username\n" - " -b[cmBdptsv] [-C cost] [-TDBTYPE] database username password\n" - " -n[imBdpst] [-C cost] username\n" - " -nb[mBdpst] [-C cost] username password\n" - " -v[imBdps] [-C cost] [-TDBTYPE] database username\n" - " -vb[mBdps] [-C cost] [-TDBTYPE] database username password\n" - " -x [-TDBTYPE] database username\n" - " -l [-TDBTYPE] database\n" + "Usage: htdbm [-cimBdpstvxak] [-C cost] [-TDBTYPE] database username\n" + " -b[cmBdptsvak] [-C cost] [-TDBTYPE] database username password\n" + " -n[imBdpst] [-C cost] username\n" + " -nb[mBdpst] [-C cost] username password\n" + " -v[imBdpsw] [-C cost] [-TDBTYPE] database username\n" + " -vb[mBdpsw] [-C cost] [-TDBTYPE] database username password\n" + " -x [-TDBTYPE] database username\n" + " -l [-TDBTYPE] database\n" "Options:\n" " -c Create a new database.\n" " -n Don't update database; display results on stdout.\n" @@ -302,6 +309,9 @@ " -v Verify the username/password.\n" " -x Remove the username record from database.\n" " -t The last param is username comment.\n" + " -a Allow colons in username.\n" + " -k Keep existing entries; only new entries may be added.\n" + " -w Write database value to stdout (when verifying).\n" "The SHA algorithm does not use a salt and is less secure than the " "MD5 algorithm.\n", BCRYPT_DEFAULT_COST); @@ -337,7 +347,7 @@ if (rv != APR_SUCCESS) exit(ERR_SYNTAX); - while ((rv = apr_getopt(state, "cnmspdBbtivxlC:T:", &opt, &opt_arg)) == APR_SUCCESS) { + while ((rv = apr_getopt(state, "acknmspdBbtivwxlC:T:", &opt, &opt_arg)) == APR_SUCCESS) { switch (opt) { case 'c': h->create = 1; @@ -369,6 +379,15 @@ need_pwd = 0; cmd = HTDBM_DELETE; break; + case 'a': + h->allowcolon = 1; + break; + case 'k': + h->keep = 1; + break; + case 'w': + h->writevalue = 1; + break; default: ret = parse_common_options(&h->ctx, opt, opt_arg); if (ret) {