summaryrefslogtreecommitdiffstats
path: root/daemon/regmaild/regmaild.c
diff options
context:
space:
mode:
Diffstat (limited to 'daemon/regmaild/regmaild.c')
-rw-r--r--daemon/regmaild/regmaild.c89
1 files changed, 89 insertions, 0 deletions
diff --git a/daemon/regmaild/regmaild.c b/daemon/regmaild/regmaild.c
index 96acf878..9dda4c05 100644
--- a/daemon/regmaild/regmaild.c
+++ b/daemon/regmaild/regmaild.c
@@ -265,6 +265,85 @@ end:
}
///////////////////////////////////////////////////////////////////////
+// Ambiguous user id checking
+
+void
+build_unambiguous_userid(char *uid)
+{
+ int i = 0;
+ const char *ambtbl[] = { // need to also update ambchars if you touch these
+ "0Oo",
+ "1Il",
+ NULL
+ };
+
+ for (i = 0; ambtbl[i]; )
+ {
+ size_t pos = strcspn(uid, ambtbl[i]);
+ if (!uid[pos])
+ {
+ i++;
+ continue;
+ }
+ uid[pos] = ambtbl[i][0];
+ uid += (pos+1); // skip the processed character
+ }
+}
+
+// TODO XXX cache these results someday
+
+int
+find_ambiguous_userid(const char *userid)
+{
+ const char *ambchars = "0Oo1Il"; // super set of ambtbl
+ size_t uidlen = 0, iamb;
+ char ambuid[IDLEN+1], shmuid[IDLEN+1];
+ int i;
+
+ assert(userid && *userid);
+
+ // if NULL, found nothing.
+ iamb = strcspn(userid, ambchars);
+ if (!userid[iamb])
+ return 0;
+
+ // build un-ambiguous uid
+ uidlen = strlcpy(ambuid, userid, sizeof(ambuid));
+ build_unambiguous_userid(ambuid);
+
+ for (i = 0; i < MAX_USERS; i++)
+ {
+ const char *ruid = SHM->userid[i];
+
+ // quick test: same non-amb prefix, and remote uid has amb characters
+ if (iamb > 0 && tolower(*ruid) != tolower(*ambuid))
+ continue;
+ if (!ruid[strcspn(ruid, ambchars)])
+ continue;
+
+ // copy and check remote uid length
+ if (strlcpy(shmuid, ruid, sizeof(shmuid)) != uidlen)
+ continue;
+
+ build_unambiguous_userid(shmuid);
+ if (strcasecmp(shmuid, ambuid) == 0)
+ return 1;
+ }
+
+ return 0;
+}
+
+int
+regcheck_ambiguous_id(const char *userid)
+{
+ if (!userid || !*userid)
+ return 0;
+ if (find_ambiguous_userid(userid))
+ return 1;
+ return 0;
+}
+
+///////////////////////////////////////////////////////////////////////
// Callbacks
// Command syntax:
@@ -325,6 +404,16 @@ client_cb(int fd, short event, void *arg)
}
break;
+ case REGCHECK_REQ_AMBIGUOUS:
+ ret = regcheck_ambiguous_id(req.userid);
+ fprintf(stderr, "%-*s check ambiguous id exist (result: %d)\r\n",
+ IDLEN, req.userid, ret);
+ if (towrite(fd, &ret, sizeof(ret)) != sizeof(ret))
+ {
+ fprintf(stderr, " error: cannot write response...\r\n");
+ }
+ break;
+
default:
fprintf(stderr, "error: invalid operation: %d.\r\n", req.operation);
close(fd);