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:

Reply via email to