Added more security checks to mbpasswd

This commit is contained in:
Michiel Broek 2005-08-27 12:06:48 +00:00
parent efccc2e9fa
commit b79e9b07bc
9 changed files with 259 additions and 222 deletions

View File

@ -40,13 +40,22 @@ v0.71.5 18-Aug-2005
mbsebbs: mbsebbs:
Code cleanup. Code cleanup.
Changed syntax for calling mbpasswd.
mbnewusr:
Changed syntax for calling mbpasswd.
mbsetup: mbsetup:
Added node setup switch to override node Hold or Down status. Added node setup switch to override node Hold or Down status.
Changed syntax for calling mbpasswd.
script: script:
Added mbfile check to monthly maintenance script. Added mbfile check to monthly maintenance script.
mbpasswd:
Added security checks to see if this program is legally called.
Changed commandline syntax.
v0.71.4 12-Aug-2005 - 18-Aug-2005 v0.71.4 12-Aug-2005 - 18-Aug-2005

View File

@ -14,14 +14,9 @@
</HEAD> </HEAD>
<BODY> <BODY>
<BLOCKQUOTE> <BLOCKQUOTE>
<div align="right"><h5>Last update 21-Jan-2002</h5></div> <div align="right"><h5>Last update 27-Aug-2005</h5></div>
<div align="center"><H1>mbpasswd - The password wrapper.</H1></div> <div align="center"><H1>mbpasswd - The password wrapper.</H1></div>
<H3>Synopsis.</h3>
<P>
<code><strong>mbpasswd</strong> [-opt] [username] [password]</code>
<P>&nbsp;<P>
<H3>Description.</h3> <H3>Description.</h3>
<P> <P>
<strong>mbpasswd</strong> is the wrapper for the <strong>passwd</strong> program <strong>mbpasswd</strong> is the wrapper for the <strong>passwd</strong> program
@ -33,9 +28,8 @@ bbs when an existing user changes his password. If you as sysop use
<strong>mbsetup</strong> to change a users password it will be used too. <strong>mbsetup</strong> to change a users password it will be used too.
His password under Unix is then always the same as his password in the bbs program. His password under Unix is then always the same as his password in the bbs program.
This is necessary for the user to be able to get his email using the pop3 protocol.<P> This is necessary for the user to be able to get his email using the pop3 protocol.<P>
You never need to run <strong>mbpasswd</strong> by hand, in fact it is protected so that only You never need to run <strong>mbpasswd</strong> by hand, in fact it is protected so that
members of group <b>bbs</b> are allowed to use it. User <b>mbse</b> can use this it can only be started by the bbs or mbsetup.
program and if you do, the password for a user are not in sync anymore.
<P>&nbsp;<P> <P>&nbsp;<P>
<H3>Environment.</H3> <H3>Environment.</H3>
@ -48,15 +42,8 @@ program and if you do, the password for a user are not in sync anymore.
<H3>Commands.</H3> <H3>Commands.</H3>
<P> <P>
<code><strong>mbpasswd</strong> [-opt] [username] [password]</code> for example:<br> Not mentioned here because <b>mbpasswd</b> is only called by other programs,
<pre> running manually is not supported.
mbpasswd -f michiel secret
</pre>
Valid options are <strong>-f</strong> (forced), this will also change locked passwords,
this has only effect if your system uses shadow passwords. This is used for new
users or from the <b>mbsetup</b> program to reset users passwords.<br>
If you use <strong>-n</strong> as option, locked passwords cannot be changed.
This mode is used when a user changes his password from the bbs.
<P> <P>

View File

@ -194,14 +194,13 @@ void Chg_Password()
} }
} }
Syslog('+', "%s/bin/mbpasswd -n %s ******", getenv("MBSE_ROOT"), exitinfo.Name); Syslog('+', "%s/bin/mbpasswd %s ******", getenv("MBSE_ROOT"), exitinfo.Name);
sprintf(temp1, "%s/bin/mbpasswd", getenv("MBSE_ROOT")); sprintf(temp1, "%s/bin/mbpasswd", getenv("MBSE_ROOT"));
memset(args, 0, sizeof(args)); memset(args, 0, sizeof(args));
args[0] = temp1; args[0] = temp1;
args[1] = (char *)"-n"; args[1] = exitinfo.Name;
args[2] = exitinfo.Name; args[2] = temp2;
args[3] = temp2; args[3] = NULL;
args[4] = NULL;
if (execute(args, (char *)"/dev/null", (char *)"/dev/null", (char *)"/dev/null") != 0) { if (execute(args, (char *)"/dev/null", (char *)"/dev/null", (char *)"/dev/null") != 0) {
WriteError("Failed to set new Unix password"); WriteError("Failed to set new Unix password");

View File

@ -723,10 +723,9 @@ char *NameCreate(char *Name, char *Comment, char *Password)
sprintf(progname, "%s/bin/mbpasswd", getenv("MBSE_ROOT")); sprintf(progname, "%s/bin/mbpasswd", getenv("MBSE_ROOT"));
memset(args, 0, sizeof(args)); memset(args, 0, sizeof(args));
args[0] = progname; args[0] = progname;
args[1] = (char *)"-f"; args[1] = Name;
args[2] = Name; args[2] = Password;
args[3] = Password; args[3] = NULL;
args[4] = NULL;
if ((err = execute(args, (char *)"/dev/null", (char *)"/dev/null", (char *)"/dev/null"))) { if ((err = execute(args, (char *)"/dev/null", (char *)"/dev/null", (char *)"/dev/null"))) {
WriteError("Failed to set unix password"); WriteError("Failed to set unix password");

View File

@ -378,14 +378,13 @@ int EditUsrRec2(void)
memset(&usrconfig.Password, 0, sizeof(usrconfig.Password)); memset(&usrconfig.Password, 0, sizeof(usrconfig.Password));
strcpy(usrconfig.Password, temp); strcpy(usrconfig.Password, temp);
usrconfig.tLastPwdChange = time(NULL); usrconfig.tLastPwdChange = time(NULL);
Syslog('+', "%s/bin/mbpasswd -f %s ******", getenv("MBSE_ROOT"), usrconfig.Name); Syslog('+', "%s/bin/mbpasswd %s ******", getenv("MBSE_ROOT"), usrconfig.Name);
sprintf(temp, "%s/bin/mbpasswd", getenv("MBSE_ROOT")); sprintf(temp, "%s/bin/mbpasswd", getenv("MBSE_ROOT"));
memset(args, 0, sizeof(args)); memset(args, 0, sizeof(args));
args[0] = temp; args[0] = temp;
args[1] = (char *)"-f"; args[1] = usrconfig.Name;
args[2] = usrconfig.Name; args[2] = usrconfig.Password;
args[3] = usrconfig.Password; args[3] = NULL;
args[4] = NULL;
if (execute(args, (char *)"/dev/null", (char *)"/dev/null", (char *)"/dev/null")!= 0) { if (execute(args, (char *)"/dev/null", (char *)"/dev/null", (char *)"/dev/null")!= 0) {
WriteError("$Failed to set new Unix password"); WriteError("$Failed to set new Unix password");

View File

@ -809,6 +809,18 @@ static void update_shadow(void)
/*
* Internal version of basename to make this better portable.
*/
char *Basename(char *str)
{
char *cp = strrchr(str, '/');
return cp ? cp+1 : str;
}
/* /*
* Function will set a new password in the users password file. * Function will set a new password in the users password file.
* Note that this function must run setuid root! * Note that this function must run setuid root!
@ -828,9 +840,12 @@ int main(int argc, char *argv[])
#endif #endif
char *cp; char *cp;
#ifdef _VPOPMAIL_PATH #ifdef _VPOPMAIL_PATH
char temp[PATH_MAX];
char *args[16]; char *args[16];
#endif #endif
char temp[PATH_MAX];
pid_t ppid;
char *parent;
FILE *fp;
/* /*
* Init $MBSE_ROOT/etc/login.defs file before the *pw gets overwritten. * Init $MBSE_ROOT/etc/login.defs file before the *pw gets overwritten.
@ -863,28 +878,45 @@ int main(int argc, char *argv[])
exit(E_NOPERM); exit(E_NOPERM);
} }
// NOOT dit programma moet kontroleren of het is aangeroepen door mbsebbs. /*
// ook kontroleren of de originele uid en gid correct zijn. * We don't log into MBSE BBS logfiles but to the system logfiles,
// Gewone stervelingen mogen dit niet kunnen starten. * because we are modifying system files not belonging to MBSE BBS.
// Dit programma is een groot security gat. */
openlog("mbpasswd", LOG_PID|LOG_CONS|LOG_NOWAIT, LOG_AUTH);
// On Linux: use getppid to get the parent pid. /*
// cat /proc/<pid>/cmdline gives name of parent. * Find out the name of our parent.
// check parent name: mbsebbs | mbnewusr | mbsetup */
ppid = getppid();
sprintf(temp, "/proc/%d/cmdline", ppid);
if ((fp = fopen(temp, "r")) == NULL) {
fprintf(stderr, "mbpasswd: can't read %s\n", temp);
syslog(LOG_ERR, "mbpasswd: can't read %s", temp);
free(myname);
exit(E_FAILURE);
}
fgets(temp, PATH_MAX-1, fp);
fclose(fp);
parent = xstrcpy(Basename(temp));
if (argc != 4) { if (strcmp((char *)"mbsetup", parent) && strcmp((char *)"-mbsebbs", parent) && strcmp((char *)"-mbnewusr", parent)) {
fprintf(stderr, "\nmbpasswd commandline:\n\n"); fprintf(stderr, "mbpasswd: illegal parent\n");
fprintf(stderr, "mbpasswd [-opt] [username] [newpassword]\n"); syslog(LOG_ERR, "mbpasswd: illegal parent \"%s\"", parent);
fprintf(stderr, "options are: -n normal password change\n");
fprintf(stderr, " -f forced password change\n");
free(myname); free(myname);
exit(E_FAILURE); exit(E_FAILURE);
} }
if (strncmp(argv[1], "-f", 2) == 0) { if (argc != 3) {
fprintf(stderr, "\nmbpasswd commandline:\n\n");
fprintf(stderr, "mbpasswd [username] [newpassword]\n");
free(myname);
exit(E_FAILURE);
}
if ((strcmp((char *)"-mbnewusr", parent) == 0) || (strcmp((char *)"mbsetup", parent) == 0)) {
/* /*
* This is a new user setting his password, * This is a new user setting his password, or the sysop resetting
* this program runs under account mbse. * the password using mbsetup. This program runs under account mbse.
*/ */
force = 1; force = 1;
if (strcmp(pw->pw_name, (char *)"mbse") && strcmp(pw->pw_name, (char *)"bbs")) { if (strcmp(pw->pw_name, (char *)"mbse") && strcmp(pw->pw_name, (char *)"bbs")) {
@ -892,44 +924,38 @@ int main(int argc, char *argv[])
free(myname); free(myname);
exit(E_NOPERM); exit(E_NOPERM);
} }
} else if (strncmp(argv[1], "-n", 2) == 0) { } else if (strcmp((char *)"-mbsebbs", parent) == 0) {
/* /*
* Normal password change by user, check * Normal password change by user, check caller is the user.
* caller is the user. * Calling program is only mbsebbs.
*/ */
force = 0; force = 0;
if (strcmp(pw->pw_name, argv[2])) { if (strcmp(pw->pw_name, argv[1])) {
fprintf(stderr, "mbpasswd: only owner may do this.\n"); fprintf(stderr, "mbpasswd: only owner may do this.\n");
free(myname); free(myname);
exit(E_NOPERM); exit(E_NOPERM);
} }
} else { } else {
fprintf(stderr, "mbpasswd: wrong option switch.\n"); syslog(LOG_ERR, "mbpasswd: illegal called");
free(myname); free(myname);
exit(E_FAILURE); exit(E_NOPERM);
} }
/* /*
* Check stringlengths * Check commandline arguments
*/ */
if (strlen(argv[2]) > 16) { if (strlen(argv[1]) > 32) {
fprintf(stderr, "mbpasswd: Username too long\n"); fprintf(stderr, "mbpasswd: Username too long\n");
free(myname); free(myname);
exit(E_FAILURE); exit(E_FAILURE);
} }
if (strlen(argv[3]) > 16) { if (strlen(argv[2]) > 32) {
fprintf(stderr, "mbpasswd: Password too long\n"); fprintf(stderr, "mbpasswd: Password too long\n");
free(myname); free(myname);
exit(E_FAILURE); exit(E_FAILURE);
} }
/* name = strdup(argv[1]);
* We don't log into MBSE BBS logfiles but to the system logfiles,
* because we are modifying system files not belonging to MBSE BBS.
*/
openlog("mbpasswd", LOG_PID|LOG_CONS|LOG_NOWAIT, LOG_AUTH);
name = strdup(argv[2]);
if ((pw = getpwnam(name)) == NULL) { if ((pw = getpwnam(name)) == NULL) {
syslog(LOG_ERR, "mbpasswd: Unknown user %s", name); syslog(LOG_ERR, "mbpasswd: Unknown user %s", name);
fprintf(stderr, "mbpasswd: Unknown user %s\n", name); fprintf(stderr, "mbpasswd: Unknown user %s\n", name);
@ -959,7 +985,7 @@ int main(int argc, char *argv[])
check_password(pw); check_password(pw);
#endif #endif
if (new_password(pw, argv[3])) { if (new_password(pw, argv[2])) {
fprintf(stderr, "The password for %s is unchanged.\n", name); fprintf(stderr, "The password for %s is unchanged.\n", name);
syslog(LOG_ERR, "The password for %s is unchanged", name); syslog(LOG_ERR, "The password for %s is unchanged", name);
closelog(); closelog();
@ -1031,8 +1057,8 @@ int main(int argc, char *argv[])
sprintf(temp, "%s/vpasswd", (char *)_VPOPMAIL_PATH); sprintf(temp, "%s/vpasswd", (char *)_VPOPMAIL_PATH);
args[0] = temp; args[0] = temp;
args[1] = argv[2]; args[1] = argv[1];
args[2] = argv[3]; args[2] = argv[2];
args[3] = NULL; args[3] = NULL;
if (execute(args, (char *)"/dev/tty", (char *)"/dev/tty", (char *)"/dev/tty") != 0) { if (execute(args, (char *)"/dev/tty", (char *)"/dev/tty", (char *)"/dev/tty") != 0) {

View File

@ -1,5 +1,7 @@
#ifndef _MBUSERADD_H #ifndef _MBPASSWD_H
#define _MBUSERADD_H #define _MBPASSWD_H
/* $Id$ */
/* danger - side effects */ /* danger - side effects */
@ -39,6 +41,7 @@ static void update_noshadow(int);
struct spwd *pwd_to_spwd(const struct passwd *); struct spwd *pwd_to_spwd(const struct passwd *);
static void update_shadow(void); static void update_shadow(void);
#endif #endif
char *Basename(char *);
#endif #endif

View File

@ -1,13 +1,12 @@
/***************************************************************************** /*****************************************************************************
* *
* File ..................: mbuseradd/xmalloc.c * $Id$
* Purpose ...............: MBSE BBS Shadow Password Suite * Purpose ...............: MBSE BBS Shadow Password Suite
* Last modification date : 25-Jul-2000
* Original Source .......: Shadow Password Suite * Original Source .......: Shadow Password Suite
* Original Copyrioght ...: Julianne Frances Haugh and others. * Original Copyrioght ...: Julianne Frances Haugh and others.
* *
***************************************************************************** *****************************************************************************
* Copyright (C) 1997-2000 * Copyright (C) 1997-2005
* *
* Michiel Broek FIDO: 2:280/2802 * Michiel Broek FIDO: 2:280/2802
* Beekmansbos 10 * Beekmansbos 10
@ -69,3 +68,16 @@ char *xstrdup(const char *str)
return strcpy(xmalloc(strlen(str) + 1), str); return strcpy(xmalloc(strlen(str) + 1), str);
} }
char *xstrcpy(char *src)
{
char *tmp;
if (src == NULL)
return(NULL);
tmp = xmalloc(strlen(src)+1);
strcpy(tmp, src);
return tmp;
}

View File

@ -1,8 +1,11 @@
#ifndef _XMALLOC_H #ifndef _XMALLOC_H
#define _XMALLOC_H #define _XMALLOC_H
/* $Id$ */
char *xmalloc(size_t); char *xmalloc(size_t);
char *xstrdup(const char *); char *xstrdup(const char *);
char *xstrcpy(char *);
#endif #endif