/* $Cambridge: hermes/src/prayer/accountd/password.c,v 1.2 2004/10/01 12:42:27 dpc22 Exp $ */ /************************************************ * Prayer - a Webmail Interface * ************************************************/ /* Copyright (c) University of Cambridge 2000 - 2002 */ /* See the file NOTICE for conditions of use and distribution. */ #include "accountd.h" /* password_change_internal() ********************************************* * * Change passwd using the passwd program * config: Accountd configuration * old: Old password * new: New password * * Returns: Error response from passwd program. NIL => okay ************************************************************************/ static char *password_change_internal(struct config *config, char *old, char *new) { struct pool *pool = pool_create(0); struct assoc *h = assoc_create(pool, 16, T); struct process process; char *msg; char *cmdline; assoc_update(h, "old", old, T); assoc_update(h, "new", new, T); /* Expand */ cmdline = string_expand(pool, h, config->pwd_cmdline); process_clear(&process); if (!process_start(&process, cmdline, config->pwd_pty, config->child_timeout)) { pool_free(pool); return ("Couldn't start the password program"); } msg = process_run_script(&process, pool, h, pool_strdup(pool, config->pwd_script), NIL, 0L); if (!process_stop(&process)) { pool_free(pool); return ("Error code from password program"); } pool_free(pool); return (msg); } /* password_change() ***************************************************** * * Change passwd using the passwd program * config: Accountd configuration * stream: iostream connection to client * line: Arguments for PASSWORD command. * Should be old password, then new password canon encoded * * Returns: T in all situations * OK [text]. Password changed * NO [text]. Failed to change password * BAD [text]. Protocol error ************************************************************************/ BOOL password_change(struct config * config, struct iostream * stream, char *line) { char *old, *new; char *errmsg; if (!((old = string_get_token(&line)) && (old[0]))) { ioputs(stream, "BAD No old password" CRLF); ioflush(stream); return (T); } string_canon_decode(old); if (!((new = string_get_token(&line)) && (new[0]))) { ioputs(stream, "BAD No new password" CRLF); ioflush(stream); return (T); } string_canon_decode(new); if (!(errmsg = password_change_internal(config, old, new))) ioprintf(stream, "OK Changed password" CRLF); else if (errmsg[0]) ioprintf(stream, "NO %s" CRLF, errmsg); else ioprintf(stream, "NO Failed to change password" CRLF); ioflush(stream); return (T); }