diff options
-rw-r--r-- | daemon/regmaild/regmailc.c | 8 | ||||
-rw-r--r-- | daemon/regmaild/regmaild.c | 89 | ||||
-rw-r--r-- | include/daemons.h | 1 |
3 files changed, 97 insertions, 1 deletions
diff --git a/daemon/regmaild/regmailc.c b/daemon/regmaild/regmailc.c index cd5d2be8..9855fbca 100644 --- a/daemon/regmaild/regmailc.c +++ b/daemon/regmaild/regmailc.c @@ -36,6 +36,12 @@ int main(int argc, char *argv[]) strlcpy(req.userid, argv[2], sizeof(req.userid)); strlcpy(req.email, argv[3], sizeof(req.email)); } + else if (strcmp(argv[1], "amb") == 0) + { + op = REGCHECK_REQ_AMBIGUOUS; + strlcpy(req.userid, argv[2], sizeof(req.userid)); + strlcpy(req.email, "ambiguous@check.nonexist", sizeof(req.email)); + } else return 0; @@ -52,7 +58,7 @@ int main(int argc, char *argv[]) return 1; } - printf("count: %d\n", ret); + printf("result: %d\n", ret); return 0; } 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); diff --git a/include/daemons.h b/include/daemons.h index 84168d11..46b30db1 100644 --- a/include/daemons.h +++ b/include/daemons.h @@ -19,6 +19,7 @@ enum { REGMAILDB_REQ_COUNT = 1, REGMAILDB_REQ_SET, + REGCHECK_REQ_AMBIGUOUS, }; typedef struct |