/***************************************************************************** POPular -- A POP3 server and proxy for large mail systems $Id: libpdm_cdb.c,v 1.1 2001/04/08 18:50:10 sqrt Exp $ http://www.remote.org/jochen/mail/popular/ ****************************************************************************** Copyright (C) 1999-2001 Jochen Topf This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA *****************************************************************************/ #include #include static struct pdm_mvar *mv; struct pdm_ctx_cdb { char dirname[MAXBUF]; }; /***************************************************************************** pdm_init() Currently the filename is only saved in the init function and the file will be opened every time an authentication is done. This might change in a future version. *****************************************************************************/ char * pdm_init(int argc, char *argv[], struct pdm_mvar *mvar, void **pdmctx) { struct pdm_ctx_cdb *ctx; mv = mvar; PDM_DEBUG3("pdm_init", "start with argc=%d id='%s' name='%s'", argc, argv[0], argv[1]); if (argc != 3) { PDM_DEBUG0("pdm_init", "argc != 1"); return("not enough or too many arguments"); } ctx = malloc(sizeof(struct pdm_ctx_cdb)); if (! ctx) { PDM_DEBUG0("pdm_init", "out of memory"); return("out of memory"); } strlcpy(ctx->dirname, argv[2], sizeof(ctx->dirname)); *pdmctx = ctx; PDM_DEBUG1("pdm_init", "module initialized (dirname='%s')", ctx->dirname); return NULL; } /***************************************************************************** pdm_close() *****************************************************************************/ int pdm_close(void *pdmctx) { free(pdmctx); return 0; } /***************************************************************************** pdm_check() *****************************************************************************/ pdm_result_t pdm_check(void *pdmctx, const struct pdm_request *pdmr, struct pdm_data *pdmd) { struct pdm_ctx_cdb *ctx = pdmctx; int fd; struct cdb c; int result; char *pw, *ho, *li; char namebuf[80]; char resbuf[1024]; int dberrno; int len; PDM_DEBUG1("pdm_check", "started ns='%s'", pdmr->namespace); /* translate user name to lowercase */ { char *p; for (p=pdmr->user; *p; p++) *p = tolower(*p); } /* Name of cdb file */ snprintf(namebuf, sizeof(namebuf), "%s/%s.cdb", ctx->dirname, pdmr->namespace); /* Open cdb file */ fd = open(namebuf, O_RDONLY); if (fd < 0) { PDM_DEBUG3("pdm_check", "open_error errno=%d errstr='%s' file='%s'", dberrno, strerror(dberrno), namebuf); return pdmError; } cdb_init(&c, fd); PDM_DEBUG1("pdm_check", "cdb file '%s' opened", namebuf); /* Get data from cdb */ result = cdb_find(&c, pdmr->user, strlen(pdmr->user)); switch (result) { case 0: PDM_DEBUG0("pdm_check", "user not found"); cdb_free(&c); close(fd); return pdmUnknown; case -1: PDM_DEBUG2("pdm_check", "cdb_error errno=%d errstr='%s'", errno, strerror(errno)); cdb_free(&c); close(fd); return pdmError; } if (cdb_datalen(&c) > sizeof(resbuf)) { PDM_DEBUG0("pdm_check", "data size too large"); cdb_free(&c); close(fd); return pdmError; } result = cdb_read(&c, resbuf, cdb_datalen(&c), cdb_datapos(&c)); if (result == -1) { PDM_DEBUG0("pdm_check", "cdb_read error"); cdb_free(&c); close(fd); return pdmError; } resbuf[cdb_datalen(&c)] = 0; cdb_free(&c); close(fd); pw = strtok(resbuf, ":"); /* password */ ho = strtok(NULL, ":"); /* server number */ li = strtok(NULL, ":"); /* mailbox file */ if (!ho || !li) { PDM_DEBUG0("pdm_check", "format error"); return pdmError; } len = strlcpy(pdmd->backend, ho, MAXLEN_ID); if (len >= MAXLEN_ID) { PDM_DEBUG0("pdm_check", "backend id too long"); return pdmError; } len = strlcpy(pdmd->user, li, MAXLEN_USERNAME); if (len >= MAXLEN_USERNAME) { PDM_DEBUG0("pdm_check", "user name too long"); return pdmError; } PDM_DEBUG2("pdm_check", "got user/mailbox='%s' backend='%s'", pdmd->user, pdmd->backend); /* Check password */ if (!strcmp(pw, crypt(pdmr->pass, pw))) { PDM_DEBUG0("pdm_check", "password match, returning"); len = strlcpy(pdmd->pass, pdmr->pass, MAXLEN_PASSWORD); if (len >= MAXLEN_PASSWORD) return pdmError; return pdmAccept; } PDM_DEBUG0("pdm_check", "password mismatch, returning"); pdmd->reason = pdmFailPassword; return pdmFail; } /** THE END *****************************************************************/