Added security checks for mbuseradd

This commit is contained in:
Michiel Broek 2005-08-27 14:17:14 +00:00
parent b79e9b07bc
commit eb6b73e0c6
4 changed files with 79 additions and 12 deletions

View File

@ -56,6 +56,9 @@ v0.71.5 18-Aug-2005
Added security checks to see if this program is legally called.
Changed commandline syntax.
mbuseradd:
Added security checks to see if this program is legally called.
v0.71.4 12-Aug-2005 - 18-Aug-2005

View File

@ -14,7 +14,7 @@
</HEAD>
<BODY>
<BLOCKQUOTE>
<div align="right"><h5>Last update 02-Feb-2001</h5></div>
<div align="right"><h5>Last update 27-Aug-2005</h5></div>
<div align="center"><H1>mbuseradd - The useradd wrapper.</H1></div>
<H3>Sysnopsis.</H3>
@ -31,8 +31,8 @@ things that need to be done as <strong>root</strong> to create a new Unix
account that can be used with MBSE BBS. The solution for these problems is
<strong>mbuseradd</strong>, this little program runs setuid root and setgid
root. If it fails to do that it aborts. <strong>mbuseradd</strong> is called
by <strong>mbsebbs</strong> from the newuser function. You never need to
run <strong>mbuseradd</strong> by hand. If it is successfull the user will
by <strong>mbnewusr</strong> and checks if it's called like that.
If it is successfull the user will
have an entry in /etc/passwd, the comment is his Fidonet name, and his shell
is $MBSE_ROOT/bin/mbsebbs.
<P>
@ -58,9 +58,8 @@ installed setuid root and setgid root, ls -la looks like this:<br>
<H3>Commands.</H3>
<P>
<code><strong>mbuseradd</strong> [gid] [name] [comment] [usersdir]</code> for example:<br>
<pre>
mbuseradd bbs mbroek "Michiel Broek" /opt/mbse/home
Not mentioned here because <b>mbuseradd</b> is only called by mbnewusr,
running manually is not supported.
</pre>
<P>

View File

@ -12,7 +12,7 @@ HDRS = commonio.h putpwent.h salt.h sgetpwent.h xmalloc.h myname.h encrypt.h \
pwio.h shadowio.h mbpasswd.h mbuseradd.h rad64.h getdef.h pw_util.h \
mblogin.h env.h chowntty.h shell.h basename.h pwdcheck.h pwauth.h \
loginprompt.h utmp.h limits.h setupenv.h sub.h log.h setugid.h
MBUSERADD_OBJS = mbuseradd.o
MBUSERADD_OBJS = mbuseradd.o xmalloc.o
MBPASSWD_OBJS = mbpasswd.o commonio.o pwio.o shadowio.o sgetpwent.o \
xmalloc.o myname.o rad64.o salt.o getdef.o encrypt.o putpwent.o pw_util.o
MBLOGIN_OBJS = getdef.o env.o chowntty.o shell.o basename.o pwdcheck.o pwauth.o encrypt.o \
@ -94,7 +94,7 @@ encrypt.o: ../config.h encrypt.h
pwio.o: ../config.h sgetpwent.h commonio.h putpwent.h pwio.h
shadowio.o: ../config.h commonio.h shadowio.h
mbpasswd.o: ../config.h encrypt.h rad64.h myname.h xmalloc.h pwio.h shadowio.h pw_util.h getdef.h mbpasswd.h
mbuseradd.o: ../config.h mbuseradd.h
mbuseradd.o: ../config.h xmalloc.h mbuseradd.h
rad64.o: ../config.h rad64.h
getdef.o: ../config.h getdef.h
pw_util.o: ../config.h pw_util.h

View File

@ -4,7 +4,7 @@
* Purpose ...............: setuid root version of useradd
*
*****************************************************************************
* Copyright (C) 1997-2004
* Copyright (C) 1997-2005
*
* Michiel Broek FIDO: 2:280/2802
* Beekmansbos 10
@ -33,6 +33,7 @@
#include <stdlib.h>
#include <pwd.h>
#include <sys/types.h>
#include <grp.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
@ -44,6 +45,7 @@
#include <syslog.h>
#include <time.h>
#include "xmalloc.h"
#include "mbuseradd.h"
@ -86,6 +88,7 @@ int execute(char **args, char *in, char *out, char *err)
char buf[PATH_MAX];
int i, pid, status = 0, rc = 0;
memset(&buf, 0, sizeof(buf));
for (i = 0; i < 16; i++) {
if (args[i])
sprintf(buf, "%s %s", buf, args[i]);
@ -148,15 +151,30 @@ void makedir(char *path, mode_t mode, uid_t owner, gid_t group)
/*
* Internal version of basename to make this better portable.
*/
char *Basename(char *str)
{
char *cp = strrchr(str, '/');
return cp ? cp+1 : str;
}
/*
* Function will create the users name in the passwd file
* Note that this function must run setuid root!
*/
int main(int argc, char *argv[])
{
char *temp, *shell, *homedir, *args[16];
char *temp, *shell, *homedir, *args[16], *parent;
int i;
struct passwd *pwent, *pwuser;
struct group *gr;
pid_t ppid;
FILE *fp;
if (argc != 5)
Help();
@ -171,13 +189,60 @@ int main(int argc, char *argv[])
}
}
/*
* Check calling username
*/
ppid = getuid();
pwent = getpwuid(ppid);
if (!pwent) {
fprintf(stderr, "mbuseradd: Cannot determine your user name.\n");
exit(1);
}
if (strcmp(pwent->pw_name, (char *)"mbse") && strcmp(pwent->pw_name, (char *)"bbs")) {
fprintf(stderr, "mbuseradd: only users `mbse' and `bbs' may do this.\n");
exit(1);
}
/*
* Get my groupname, this must be "bbs", other users may not
* use this program, not even root.
*/
gr = getgrgid(pwent->pw_gid);
if (!gr) {
fprintf(stderr, "mbuseradd: Cannot determine group name.\n");
exit(1);
}
if (strcmp(gr->gr_name, (char *)"bbs")) {
fprintf(stderr, "mbuseradd: You are not a member of group `bbs'.\n");
exit(1);
}
/*
* Find out the name of our parent.
*/
temp = calloc(PATH_MAX, sizeof(char));
ppid = getppid();
sprintf(temp, "/proc/%d/cmdline", ppid);
if ((fp = fopen(temp, "r")) == NULL) {
fprintf(stderr, "mbuseradd: can't read %s\n", temp);
exit(1);
}
fgets(temp, PATH_MAX-1, fp);
fclose(fp);
parent = xstrcpy(Basename(temp));
if (strcmp((char *)"-mbnewusr", parent)) {
fprintf(stderr, "mbpasswd: illegal parent\n");
free(temp);
free(parent);
exit(1);
}
memset(args, 0, sizeof(args));
temp = calloc(PATH_MAX, sizeof(char));
shell = calloc(PATH_MAX, sizeof(char));
homedir = calloc(PATH_MAX, sizeof(char));
if (setuid(0) == -1 || setgid(1) == -1) {
perror("");
fprintf(stderr, "mbuseradd: Unable to setuid(root) or setgid(root)\n");