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:
Code cleanup.
Changed syntax for calling mbpasswd.
mbnewusr:
Changed syntax for calling mbpasswd.
mbsetup:
Added node setup switch to override node Hold or Down status.
Changed syntax for calling mbpasswd.
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

View File

@ -14,14 +14,9 @@
</HEAD>
<BODY>
<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>
<H3>Synopsis.</h3>
<P>
<code><strong>mbpasswd</strong> [-opt] [username] [password]</code>
<P>&nbsp;<P>
<H3>Description.</h3>
<P>
<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.
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>
You never need to run <strong>mbpasswd</strong> by hand, in fact it is protected so that only
members of group <b>bbs</b> are allowed to use it. User <b>mbse</b> can use this
program and if you do, the password for a user are not in sync anymore.
You never need to run <strong>mbpasswd</strong> by hand, in fact it is protected so that
it can only be started by the bbs or mbsetup.
<P>&nbsp;<P>
<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>
<P>
<code><strong>mbpasswd</strong> [-opt] [username] [password]</code> for example:<br>
<pre>
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.
Not mentioned here because <b>mbpasswd</b> is only called by other programs,
running manually is not supported.
<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"));
memset(args, 0, sizeof(args));
args[0] = temp1;
args[1] = (char *)"-n";
args[2] = exitinfo.Name;
args[3] = temp2;
args[4] = NULL;
args[1] = exitinfo.Name;
args[2] = temp2;
args[3] = NULL;
if (execute(args, (char *)"/dev/null", (char *)"/dev/null", (char *)"/dev/null") != 0) {
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"));
memset(args, 0, sizeof(args));
args[0] = progname;
args[1] = (char *)"-f";
args[2] = Name;
args[3] = Password;
args[4] = NULL;
args[1] = Name;
args[2] = Password;
args[3] = NULL;
if ((err = execute(args, (char *)"/dev/null", (char *)"/dev/null", (char *)"/dev/null"))) {
WriteError("Failed to set unix password");

View File

@ -378,14 +378,13 @@ int EditUsrRec2(void)
memset(&usrconfig.Password, 0, sizeof(usrconfig.Password));
strcpy(usrconfig.Password, temp);
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"));
memset(args, 0, sizeof(args));
args[0] = temp;
args[1] = (char *)"-f";
args[2] = usrconfig.Name;
args[3] = usrconfig.Password;
args[4] = NULL;
args[1] = usrconfig.Name;
args[2] = usrconfig.Password;
args[3] = NULL;
if (execute(args, (char *)"/dev/null", (char *)"/dev/null", (char *)"/dev/null")!= 0) {
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.
* Note that this function must run setuid root!
@ -828,9 +840,12 @@ int main(int argc, char *argv[])
#endif
char *cp;
#ifdef _VPOPMAIL_PATH
char temp[PATH_MAX];
char *args[16];
#endif
char temp[PATH_MAX];
pid_t ppid;
char *parent;
FILE *fp;
/*
* 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);
}
// NOOT dit programma moet kontroleren of het is aangeroepen door mbsebbs.
// ook kontroleren of de originele uid en gid correct zijn.
// Gewone stervelingen mogen dit niet kunnen starten.
// Dit programma is een groot security gat.
/*
* 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);
// On Linux: use getppid to get the parent pid.
// cat /proc/<pid>/cmdline gives name of parent.
// check parent name: mbsebbs | mbnewusr | mbsetup
/*
* Find out the name of our parent.
*/
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) {
fprintf(stderr, "\nmbpasswd commandline:\n\n");
fprintf(stderr, "mbpasswd [-opt] [username] [newpassword]\n");
fprintf(stderr, "options are: -n normal password change\n");
fprintf(stderr, " -f forced password change\n");
if (strcmp((char *)"mbsetup", parent) && strcmp((char *)"-mbsebbs", parent) && strcmp((char *)"-mbnewusr", parent)) {
fprintf(stderr, "mbpasswd: illegal parent\n");
syslog(LOG_ERR, "mbpasswd: illegal parent \"%s\"", parent);
free(myname);
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 program runs under account mbse.
* This is a new user setting his password, or the sysop resetting
* the password using mbsetup. This program runs under account mbse.
*/
force = 1;
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);
exit(E_NOPERM);
}
} else if (strncmp(argv[1], "-n", 2) == 0) {
} else if (strcmp((char *)"-mbsebbs", parent) == 0) {
/*
* Normal password change by user, check
* caller is the user.
* Normal password change by user, check caller is the user.
* Calling program is only mbsebbs.
*/
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");
free(myname);
exit(E_NOPERM);
}
} else {
fprintf(stderr, "mbpasswd: wrong option switch.\n");
syslog(LOG_ERR, "mbpasswd: illegal called");
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");
free(myname);
exit(E_FAILURE);
}
if (strlen(argv[3]) > 16) {
if (strlen(argv[2]) > 32) {
fprintf(stderr, "mbpasswd: Password too long\n");
free(myname);
exit(E_FAILURE);
}
/*
* 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]);
name = strdup(argv[1]);
if ((pw = getpwnam(name)) == NULL) {
syslog(LOG_ERR, "mbpasswd: Unknown user %s", name);
fprintf(stderr, "mbpasswd: Unknown user %s\n", name);
@ -959,7 +985,7 @@ int main(int argc, char *argv[])
check_password(pw);
#endif
if (new_password(pw, argv[3])) {
if (new_password(pw, argv[2])) {
fprintf(stderr, "The password for %s is unchanged.\n", name);
syslog(LOG_ERR, "The password for %s is unchanged", name);
closelog();
@ -1031,8 +1057,8 @@ int main(int argc, char *argv[])
sprintf(temp, "%s/vpasswd", (char *)_VPOPMAIL_PATH);
args[0] = temp;
args[1] = argv[2];
args[2] = argv[3];
args[1] = argv[1];
args[2] = argv[2];
args[3] = NULL;
if (execute(args, (char *)"/dev/tty", (char *)"/dev/tty", (char *)"/dev/tty") != 0) {

View File

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

View File

@ -1,13 +1,12 @@
/*****************************************************************************
*
* File ..................: mbuseradd/xmalloc.c
* $Id$
* Purpose ...............: MBSE BBS Shadow Password Suite
* Last modification date : 25-Jul-2000
* Original Source .......: Shadow Password Suite
* Original Copyrioght ...: Julianne Frances Haugh and others.
*
*****************************************************************************
* Copyright (C) 1997-2000
* Copyright (C) 1997-2005
*
* Michiel Broek FIDO: 2:280/2802
* Beekmansbos 10
@ -69,3 +68,16 @@ char *xstrdup(const char *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
#define _XMALLOC_H
/* $Id$ */
char *xmalloc(size_t);
char *xstrdup(const char *);
char *xstrcpy(char *);
#endif