Hi,
The patch enables htdbm utility to manage the groups.
The group management enables that both passwords and groups exists in the
same database or in different ones.
for example:
htdbm -cmbgt .htdbm username password group1,group2 "Some comment"
will create the record with
key=username and value=encryptedpassword:group1,group2:Some comment
there is other addon switch that enables one to modify the record without
the need to retype the password (switch u).
htdbm -gtu .htdbm username group1,group3 "The user moved from group2"
will preserve the old username password and the record will look like
key=username and value=oldencryptedpassword:group1,group3:Some comment
MT.
Index: htdbm.c
===================================================================
RCS file: /home/cvspublic/httpd-2.0/support/htdbm.c,v
retrieving revision 1.3
diff -u -r1.3 htdbm.c
--- htdbm.c 2001/11/06 21:11:45 1.3
+++ htdbm.c 2001/11/24 19:41:13
@@ -103,12 +103,12 @@
#endif /*APR_CHARSET_EBCDIC*/
#define MAX_STRING_LEN 256
-#define ALG_PLAIN 0
-#define ALG_APMD5 1
-#define ALG_APSHA 2
+#define ALG_PLAIN 1
+#define ALG_APMD5 2
+#define ALG_APSHA 3
#if APR_HAVE_CRYPT_H
-#define ALG_CRYPT 3
+#define ALG_CRYPT 4
#endif
@@ -133,6 +133,7 @@
char *username;
char *userpass;
char *comment;
+ char *groups;
int create;
int rdonly;
int alg;
@@ -234,23 +235,45 @@
static apr_status_t htdbm_save(htdbm_t *htdbm, int *changed)
{
apr_datum_t key, val;
+ char *record, *old = NULL;
if (!htdbm->username)
return APR_SUCCESS;
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->userpass) {
+ if (apr_dbm_fetch(htdbm->dbm, key, &val) != APR_SUCCESS)
+ return APR_ENOENT;
+ old = apr_pstrndup(htdbm->pool, val.dptr, val.dsize);
+ record = strchr(old, ':');
+ if (record) {
+ *record = '\0';
+ htdbm->userpass = old;
+ }
+ }
*changed = 1;
-
- val.dsize = strlen(htdbm->userpass);
- if (!htdbm->comment)
- val.dptr = htdbm->userpass;
+ }
+ if (!htdbm->userpass)
+ htdbm->userpass = "";
+ if (htdbm->groups) {
+ if (htdbm->comment)
+ record = apr_pstrcat(htdbm->pool, htdbm->userpass, ":",
+ htdbm->groups, ":", htdbm->comment, NULL);
+ else
+ record = apr_pstrcat(htdbm->pool, htdbm->userpass, ":",
+ htdbm->groups, NULL);
+ }
else {
- val.dptr = apr_pstrcat(htdbm->pool, htdbm->userpass, ";",
+ if (htdbm->comment)
+ record = apr_pstrcat(htdbm->pool, htdbm->userpass, ";",
htdbm->comment, NULL);
- val.dsize += (strlen(htdbm->comment) + 1);
+ else
+ record = htdbm->userpass;
}
+ val.dptr = record;
+ val.dsize = strlen(record);
return apr_dbm_store(htdbm->dbm, key, val);
}
@@ -280,6 +303,9 @@
return APR_ENOENT;
rec = apr_pstrndup(htdbm->pool, val.dptr, val.dsize);
cmnt = strchr(rec, ';');
+ if (!cmnt)
+ cmnt = strchr(rec, ';');
+
if (cmnt)
strncpy(pwd, rec, cmnt - rec);
else
@@ -291,7 +317,7 @@
{
apr_status_t rv;
apr_datum_t key, val;
- char *rec, *cmnt;
+ char *rec, *cmnt, *grp;
char kb[MAX_STRING_LEN];
int i = 0;
@@ -303,7 +329,7 @@
rec = apr_pcalloc(htdbm->pool, HUGE_STRING_LEN);
fprintf(stderr, "Dumping records from database -- %s\n", htdbm->filename);
- fprintf(stderr, " %-32sComment\n", "Username");
+ fprintf(stderr, " %-25s%-25sComment\n", "Username", "Group(s)");
while (key.dptr != NULL) {
rv = apr_dbm_fetch(htdbm->dbm, key, &val);
if (rv != APR_SUCCESS) {
@@ -312,10 +338,16 @@
}
strncpy(kb, key.dptr, key.dsize);
kb[key.dsize] = '\0';
- fprintf(stderr, " %-32s", kb);
+ fprintf(stderr, " %-25s", kb);
strncpy(rec, val.dptr, val.dsize);
rec[val.dsize] = '\0';
- cmnt = strchr(rec, ';');
+ grp = strchr(rec, ':');
+ if (grp)
+ cmnt = strchr(grp+1, ':');
+ else
+ cmnt = strchr(rec, ';');
+ *cmnt = '\0';
+ fprintf(stderr, "%-25s", grp ? grp + 1 : " ");
if (cmnt)
fprintf(stderr, cmnt + 1);
fprintf(stderr, "\n");
@@ -345,6 +377,9 @@
char cpw[MAX_STRING_LEN];
char salt[9];
+ if (!htdbm->userpass)
+ return APR_SUCCESS;
+
switch (htdbm->alg) {
case ALG_APSHA:
/* XXX cpw >= 28 + strlen(sha1) chars - fixed len SHA */
@@ -371,6 +406,7 @@
fprintf(stderr, "CRYPT is now depriciated, use MD5 instead !\n");
#endif
default:
+ cpw[0] = '\0';
break;
}
htdbm->userpass = apr_pstrdup(htdbm->pool, cpw);
@@ -395,8 +431,10 @@
#if APR_HAVE_CRYPT_H
#define CRYPT_OPTION "d"
+#define IDENT_OPTION " "
#else
#define CRYPT_OPTION ""
+#define IDENT_OPTION ""
#endif
fprintf(stderr, "htdbm -- program for manipulating DBM password databases.\n\n");
fprintf(stderr, "Usage: htdbm [-cm"CRYPT_OPTION"pstvx] database username\n");
@@ -406,9 +444,10 @@
fprintf(stderr, " -v[m"CRYPT_OPTION"ps] database username\n");
fprintf(stderr, " -vb[m"CRYPT_OPTION"ps] database username
password\n");
fprintf(stderr, " -x[m"CRYPT_OPTION"ps] database username\n");
- fprintf(stderr, " -l database\n");
+ fprintf(stderr, " -g[u]"IDENT_OPTION" database username
+group(s)\n");
+ fprintf(stderr, " -l"IDENT_OPTION" database\n");
fprintf(stderr, "Options:\n");
- fprintf(stderr, " -b Use the password from the command line rather"
+ fprintf(stderr, " -b Use the password from the command line rather "
"than prompting for it.\n");
fprintf(stderr, " -c Create a new database.\n");
fprintf(stderr, " -n Don't update database; display results on stdout.\n");
@@ -419,9 +458,11 @@
fprintf(stderr, " -p Do not encrypt the password (plaintext).\n");
fprintf(stderr, " -s Force SHA encryption of the password.\n");
fprintf(stderr, " -l Display usernames from database on stdout.\n");
- fprintf(stderr, " -t The last param is username comment.\n");
+ fprintf(stderr, " -t The last param is the record comment.\n");
fprintf(stderr, " -v Verify the username/password.\n");
fprintf(stderr, " -x Remove the username record from database.\n");
+ fprintf(stderr, " -g Add the username to specified group(s).\n");
+ fprintf(stderr, " -u Update the username record if exists.\n");
exit(ERR_SYNTAX);
}
@@ -440,6 +481,7 @@
int need_user = 1;
int need_pwd = 1;
int need_cmnt = 0;
+ int need_grp = 0;
int pwd_supplied = 0;
int changed;
int cmd = HTDBM_MAKE;
@@ -474,6 +516,9 @@
need_pwd = 0;
args_left++;
break;
+ case 'u':
+ need_pwd = 0;
+ break;
case 'c':
h->create = 1;
break;
@@ -493,6 +538,10 @@
need_cmnt = 1;
args_left++;
break;
+ case 'g':
+ need_grp = 1;
+ args_left++;
+ break;
case 'v':
h->rdonly = 1;
cmd = HTDBM_VERIFY;
@@ -539,13 +588,14 @@
exit(ERR_FILEPERM);
}
}
+ ++i;
if (need_user) {
- h->username = apr_pstrdup(pool, argv[i+1]);
+ h->username = apr_pstrdup(pool, argv[i++]);
if (htdbm_valid_username(h) != APR_SUCCESS)
exit(ERR_BADUSER);
}
if (pwd_supplied)
- h->userpass = apr_pstrdup(pool, argv[i+2]);
+ h->userpass = apr_pstrdup(pool, argv[i++]);
if (need_pwd) {
l = sizeof(pwc);
@@ -565,10 +615,12 @@
h->userpass = apr_pstrdup(pool, pwi);
}
- if (need_cmnt && pwd_supplied)
- h->comment = apr_pstrdup(pool, argv[i+3]);
- else if (need_cmnt)
- h->comment = apr_pstrdup(pool, argv[i+2]);
+
+ if (need_grp)
+ h->groups = apr_pstrdup(pool, argv[i++]);
+
+ if (need_cmnt)
+ h->comment = apr_pstrdup(pool, argv[i]);
switch (cmd) {
case HTDBM_VERIFY: