Initial merge of all tinylogin applets that do not require crypt.
There is some optimization that can be done to better use libbb in these applets. There is also redundancy between stty and getty which could be eliminated. -Erik
This commit is contained in:
parent
a3e4f455ac
commit
f349e978c4
5
Config.h
5
Config.h
@ -7,6 +7,8 @@
|
||||
//
|
||||
//
|
||||
// BusyBox Applications
|
||||
#define BB_ADDGROUP
|
||||
#define BB_ADDUSER
|
||||
//#define BB_ADJTIMEX
|
||||
//#define BB_AR
|
||||
//#define BB_ASH
|
||||
@ -26,6 +28,8 @@
|
||||
//#define BB_DC
|
||||
#define BB_DD
|
||||
//#define BB_DEALLOCVT
|
||||
#define BB_DELGROUP
|
||||
#define BB_DELUSER
|
||||
#define BB_DF
|
||||
#define BB_DIRNAME
|
||||
#define BB_DMESG
|
||||
@ -45,6 +49,7 @@
|
||||
//#define BB_FREERAMDISK
|
||||
//#define BB_FSCK_MINIX
|
||||
//#define BB_GETOPT
|
||||
#define BB_GETTY
|
||||
#define BB_GREP
|
||||
#define BB_GUNZIP
|
||||
#define BB_GZIP
|
||||
|
178
addgroup.c
Normal file
178
addgroup.c
Normal file
@ -0,0 +1,178 @@
|
||||
/* vi: set sw=4 ts=4: */
|
||||
/*
|
||||
* addgroup - add users to /etc/passwd and /etc/shadow
|
||||
*
|
||||
*
|
||||
* Copyright (C) 1999 by Lineo, inc.
|
||||
* Written by John Beppu <beppu@lineo.com>
|
||||
*
|
||||
* 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 <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include "busybox.h"
|
||||
#include "pwd_grp/pwd.h"
|
||||
#include "pwd_grp/grp.h"
|
||||
|
||||
#define GROUP_FILE "/etc/group"
|
||||
#define SHADOW_FILE "/etc/gshadow"
|
||||
|
||||
|
||||
/* structs __________________________ */
|
||||
|
||||
/* data _____________________________ */
|
||||
|
||||
/* defaults : should this be in an external file? */
|
||||
static char *default_passwd = "x";
|
||||
|
||||
|
||||
/* make sure gr_name isn't taken, make sure gid is kosher
|
||||
* return 1 on failure */
|
||||
static int group_study(const char *filename, struct group *g)
|
||||
{
|
||||
FILE *etc_group;
|
||||
gid_t desired;
|
||||
|
||||
struct group *grp;
|
||||
const int max = 65000;
|
||||
|
||||
/* FIXME : make an fopen_wrapper */
|
||||
etc_group = fopen(filename, "r");
|
||||
if (!etc_group) {
|
||||
perror_msg_and_die("%s", filename);
|
||||
}
|
||||
|
||||
/* make sure gr_name isn't taken, make sure gid is kosher */
|
||||
desired = g->gr_gid;
|
||||
while ((grp = fgetgrent(etc_group))) {
|
||||
if ((strcmp(grp->gr_name, g->gr_name)) == 0) {
|
||||
error_msg_and_die("%s: group already in use\n", g->gr_name);
|
||||
}
|
||||
if ((desired) && grp->gr_gid == desired) {
|
||||
error_msg_and_die("%d: gid has already been allocated\n",
|
||||
desired);
|
||||
}
|
||||
if ((grp->gr_gid > g->gr_gid) && (grp->gr_gid < max)) {
|
||||
g->gr_gid = grp->gr_gid;
|
||||
}
|
||||
}
|
||||
fclose(etc_group);
|
||||
|
||||
/* gid */
|
||||
if (desired) {
|
||||
g->gr_gid = desired;
|
||||
} else {
|
||||
g->gr_gid++;
|
||||
}
|
||||
/* return 1; */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* append a new user to the passwd file */
|
||||
static int addgroup(const char *filename, char *group, gid_t gid)
|
||||
{
|
||||
FILE *etc_group;
|
||||
FILE *etc_gshadow;
|
||||
char *gshadow = SHADOW_FILE;
|
||||
|
||||
struct group gr;
|
||||
|
||||
/* group:passwd:gid:userlist */
|
||||
const char *entryfmt = "%s:%s:%d:%s\n";
|
||||
|
||||
/* make sure gid and group haven't already been allocated */
|
||||
gr.gr_gid = gid;
|
||||
gr.gr_name = group;
|
||||
if (group_study(filename, &gr))
|
||||
return 1;
|
||||
|
||||
/* add entry to group */
|
||||
etc_group = fopen(filename, "a");
|
||||
if (!etc_group) {
|
||||
perror_msg_and_die("%s", filename);
|
||||
}
|
||||
fprintf(etc_group, entryfmt, group, default_passwd, gr.gr_gid, "");
|
||||
fclose(etc_group);
|
||||
|
||||
/* add entry to gshadow if necessary */
|
||||
if (access(gshadow, F_OK|W_OK) == 0) {
|
||||
etc_gshadow = xfopen(gshadow, "a");
|
||||
fprintf(etc_gshadow, "%s:!::\n", group);
|
||||
fclose(etc_gshadow);
|
||||
}
|
||||
|
||||
/* return 1; */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* addgroup will take a login_name as its first parameter.
|
||||
*
|
||||
* gid
|
||||
*
|
||||
* can be customized via command-line parameters.
|
||||
* ________________________________________________________________________ */
|
||||
int addgroup_main(int argc, char **argv)
|
||||
{
|
||||
int i;
|
||||
char opt;
|
||||
char *group;
|
||||
gid_t gid = 0;
|
||||
|
||||
/* get remaining args */
|
||||
for (i = 1; i < argc; i++) {
|
||||
if (argv[i][0] == '-') {
|
||||
opt = argv[i][1];
|
||||
switch (opt) {
|
||||
case 'h':
|
||||
show_usage();
|
||||
break;
|
||||
case 'g':
|
||||
gid = strtol(argv[++i], NULL, 10);
|
||||
break;
|
||||
default:
|
||||
error_msg_and_die("addgroup: invalid option -- %c\n", opt);
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i >= argc) {
|
||||
show_usage();
|
||||
} else {
|
||||
group = argv[i];
|
||||
}
|
||||
|
||||
if (geteuid() != 0) {
|
||||
error_msg_and_die
|
||||
("addgroup: Only root may add a group to the system.\n");
|
||||
}
|
||||
|
||||
/* werk */
|
||||
return addgroup(GROUP_FILE, group, gid);
|
||||
}
|
||||
|
||||
/* $Id: addgroup.c,v 1.1 2001/08/21 16:18:59 andersen Exp $ */
|
366
adduser.c
Normal file
366
adduser.c
Normal file
@ -0,0 +1,366 @@
|
||||
/* vi: set sw=4 ts=4: */
|
||||
/*
|
||||
* adduser - add users to /etc/passwd and /etc/shadow
|
||||
*
|
||||
*
|
||||
* Copyright (C) 1999 by Lineo, inc.
|
||||
* Written by John Beppu <beppu@lineo.com>
|
||||
*
|
||||
* 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 <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <shadow.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include "busybox.h"
|
||||
#include "pwd_grp/pwd.h"
|
||||
#include "pwd_grp/grp.h"
|
||||
|
||||
#define PASSWD_FILE "/etc/passwd"
|
||||
#define SHADOW_FILE "/etc/gshadow"
|
||||
|
||||
#if 0
|
||||
# define PASSWD_FILE "passwd"
|
||||
# define SHADOW_FILE "shadow"
|
||||
#endif
|
||||
|
||||
/* structs __________________________ */
|
||||
|
||||
typedef struct {
|
||||
uid_t u;
|
||||
gid_t g;
|
||||
} Id;
|
||||
|
||||
/* data _____________________________ */
|
||||
|
||||
/* defaults : should this be in an external file? */
|
||||
static char *default_passwd = "x";
|
||||
static char *default_gecos = "Embedix User,,,";
|
||||
static char *default_home_prefix = "/home";
|
||||
static char *default_shell = "/bin/sh";
|
||||
|
||||
/* shadow in use? */
|
||||
static int shadow_enabled = 0;
|
||||
|
||||
/* I was doing this all over the place */
|
||||
static FILE *fopen_wrapper(const char *filename, const char *mode)
|
||||
{
|
||||
FILE *f;
|
||||
|
||||
f = fopen(filename, mode);
|
||||
if (f == NULL) {
|
||||
fprintf(stderr, "adduser: %s: %s\n", filename, strerror(errno));
|
||||
}
|
||||
return f;
|
||||
}
|
||||
|
||||
/* remix */
|
||||
/* EDR recoded such that the uid may be passed in *p */
|
||||
static int passwd_study(const char *filename, struct passwd *p)
|
||||
{
|
||||
struct passwd *pw;
|
||||
FILE *passwd;
|
||||
|
||||
const int min = 500;
|
||||
const int max = 65000;
|
||||
|
||||
passwd = fopen_wrapper(filename, "r");
|
||||
if (!passwd)
|
||||
return 4;
|
||||
|
||||
/* EDR if uid is out of bounds, set to min */
|
||||
if ((p->pw_uid > max) || (p->pw_uid < min))
|
||||
p->pw_uid = min;
|
||||
|
||||
/* stuff to do:
|
||||
* make sure login isn't taken;
|
||||
* find free uid and gid;
|
||||
*/
|
||||
while ((pw = fgetpwent(passwd))) {
|
||||
if (strcmp(pw->pw_name, p->pw_name) == 0) {
|
||||
/* return 0; */
|
||||
return 1;
|
||||
}
|
||||
if ((pw->pw_uid >= p->pw_uid) && (pw->pw_uid < max)
|
||||
&& (pw->pw_uid >= min)) {
|
||||
p->pw_uid = pw->pw_uid + 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* EDR check for an already existing gid */
|
||||
while (getgrgid(p->pw_uid) != NULL)
|
||||
p->pw_uid++;
|
||||
|
||||
/* EDR also check for an existing group definition */
|
||||
if (getgrnam(p->pw_name) != NULL)
|
||||
return 3;
|
||||
|
||||
/* EDR bounds check */
|
||||
if ((p->pw_uid > max) || (p->pw_uid < min))
|
||||
return 2;
|
||||
|
||||
/* EDR create new gid always = uid */
|
||||
p->pw_gid = p->pw_uid;
|
||||
|
||||
/* return 1; */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void addgroup_wrapper(const char *login, gid_t gid)
|
||||
{
|
||||
int argc = 4;
|
||||
char *argv[] = { "addgroup", "-g", NULL, NULL };
|
||||
char group_id[8];
|
||||
char group_name[32];
|
||||
|
||||
strncpy(group_name, login, 32);
|
||||
argv[3] = group_name;
|
||||
sprintf(group_id, "%d", gid);
|
||||
argv[2] = group_id;
|
||||
addgroup_main(argc, argv);
|
||||
}
|
||||
|
||||
static void passwd_wrapper(const char *login)
|
||||
{
|
||||
char *prog = "passwd";
|
||||
execlp(prog, prog, login, NULL);
|
||||
error_msg_and_die("Failed to execute 'passwd', you must set the password for '%s' manually\n", login);
|
||||
}
|
||||
|
||||
/*
|
||||
* pwd_to_spwd - create entries for new spwd structure
|
||||
*
|
||||
* pwd_to_spwd() creates a new (struct spwd) containing the
|
||||
* information in the pointed-to (struct passwd).
|
||||
*/
|
||||
#define DAY (24L*3600L)
|
||||
#define WEEK (7*DAY)
|
||||
#define SCALE DAY
|
||||
static struct spwd *pwd_to_spwd(const struct passwd *pw)
|
||||
{
|
||||
static struct spwd sp;
|
||||
|
||||
/*
|
||||
* Nice, easy parts first. The name and passwd map directly
|
||||
* from the old password structure to the new one.
|
||||
*/
|
||||
sp.sp_namp = pw->pw_name;
|
||||
sp.sp_pwdp = pw->pw_passwd;
|
||||
|
||||
/*
|
||||
* Defaults used if there is no pw_age information.
|
||||
*/
|
||||
sp.sp_min = 0;
|
||||
sp.sp_max = (10000L * DAY) / SCALE;
|
||||
sp.sp_lstchg = time((time_t *) 0) / SCALE;
|
||||
|
||||
/*
|
||||
* These fields have no corresponding information in the password
|
||||
* file. They are set to uninitialized values.
|
||||
*/
|
||||
sp.sp_warn = -1;
|
||||
sp.sp_expire = -1;
|
||||
sp.sp_inact = -1;
|
||||
sp.sp_flag = -1;
|
||||
|
||||
return &sp;
|
||||
}
|
||||
|
||||
/* putpwent(3) remix */
|
||||
static int adduser(const char *filename, struct passwd *p)
|
||||
{
|
||||
FILE *passwd;
|
||||
int r;
|
||||
FILE *shadow;
|
||||
struct spwd *sp;
|
||||
|
||||
/* make sure everything is kosher and setup uid && gid */
|
||||
passwd = fopen_wrapper(filename, "a");
|
||||
if (passwd == NULL) {
|
||||
/* return -1; */
|
||||
return 1;
|
||||
}
|
||||
fseek(passwd, 0, SEEK_END);
|
||||
|
||||
/* if (passwd_study(filename, p) == 0) { */
|
||||
r = passwd_study(filename, p);
|
||||
if (r) {
|
||||
if (r == 1)
|
||||
error_msg("%s: login already in use\n", p->pw_name);
|
||||
else if (r == 2)
|
||||
error_msg("illegal uid or no uids left\n");
|
||||
else if (r == 3)
|
||||
error_msg("group name %s already in use\n", p->pw_name);
|
||||
else
|
||||
error_msg("generic error.\n");
|
||||
/* return -1; */
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* add to passwd */
|
||||
if (putpwent(p, passwd) == -1) {
|
||||
/* return -1; */
|
||||
return 1;
|
||||
}
|
||||
fclose(passwd);
|
||||
|
||||
/* add to shadow if necessary */
|
||||
if (shadow_enabled) {
|
||||
shadow = fopen_wrapper(SHADOW_FILE, "a");
|
||||
if (shadow == NULL) {
|
||||
/* return -1; */
|
||||
return 1;
|
||||
}
|
||||
fseek(shadow, 0, SEEK_END);
|
||||
sp = pwd_to_spwd(p);
|
||||
sp->sp_max = 99999; /* debianish */
|
||||
sp->sp_warn = 7;
|
||||
fprintf(shadow, "%s:!:%ld:%ld:%ld:%ld:::\n",
|
||||
sp->sp_namp, sp->sp_lstchg, sp->sp_min, sp->sp_max,
|
||||
sp->sp_warn);
|
||||
fclose(shadow);
|
||||
}
|
||||
|
||||
/* add to group */
|
||||
/* addgroup should be responsible for dealing w/ gshadow */
|
||||
addgroup_wrapper(p->pw_name, p->pw_gid);
|
||||
|
||||
/* Clear the umask for this process so it doesn't
|
||||
* * screw up the permissions on the mkdir and chown. */
|
||||
umask(0);
|
||||
|
||||
/* mkdir */
|
||||
if (mkdir(p->pw_dir, 0755)) {
|
||||
perror_msg("%s", p->pw_dir);
|
||||
}
|
||||
/* Set the owner and group so it is owned by the new user. */
|
||||
if (chown(p->pw_dir, p->pw_uid, p->pw_gid)) {
|
||||
perror_msg("%s", p->pw_dir);
|
||||
}
|
||||
/* Now fix up the permissions to 2755. Can't do it before now
|
||||
* since chown will clear the setgid bit */
|
||||
if (chmod(p->pw_dir, 02755)) {
|
||||
perror_msg("%s", p->pw_dir);
|
||||
}
|
||||
/* interactively set passwd */
|
||||
passwd_wrapper(p->pw_name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* return current uid (root is always uid == 0, right?) */
|
||||
static uid_t i_am_not_root()
|
||||
{
|
||||
return geteuid();
|
||||
}
|
||||
|
||||
/*
|
||||
* adduser will take a login_name as its first parameter.
|
||||
*
|
||||
* home
|
||||
* shell
|
||||
* gecos
|
||||
*
|
||||
* can be customized via command-line parameters.
|
||||
* ________________________________________________________________________ */
|
||||
int adduser_main(int argc, char **argv)
|
||||
{
|
||||
int i;
|
||||
char opt;
|
||||
char *login;
|
||||
char *gecos;
|
||||
char *home = NULL;
|
||||
char *shell;
|
||||
char path[MAXPATHLEN];
|
||||
|
||||
struct passwd pw;
|
||||
|
||||
/* init */
|
||||
if (argc < 2) {
|
||||
show_usage();
|
||||
}
|
||||
gecos = default_gecos;
|
||||
shell = default_shell;
|
||||
|
||||
/* get args */
|
||||
for (i = 1; i < argc; i++) {
|
||||
if (argv[i][0] == '-') {
|
||||
opt = argv[i][1];
|
||||
switch (opt) {
|
||||
case 'h':
|
||||
home = argv[++i];
|
||||
break;
|
||||
case 'g':
|
||||
gecos = argv[++i];
|
||||
break;
|
||||
case 's':
|
||||
shell = argv[++i];
|
||||
break;
|
||||
default:
|
||||
error_msg("invalid option -- %c\n", opt);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* got root? */
|
||||
if (i_am_not_root()) {
|
||||
error_msg_and_die( "Only root may add a user or group to the system.\n");
|
||||
}
|
||||
|
||||
/* get login */
|
||||
if (i >= argc) {
|
||||
error_msg_and_die( "adduser: no user specified\n");
|
||||
}
|
||||
login = argv[i];
|
||||
|
||||
/* create string for $HOME if not specified already */
|
||||
if (!home) {
|
||||
snprintf(path, MAXPATHLEN, "%s/%s", default_home_prefix, login);
|
||||
path[MAXPATHLEN - 1] = 0;
|
||||
home = path;
|
||||
}
|
||||
/* is /etc/shadow in use? */
|
||||
shadow_enabled = (0 == access(SHADOW_FILE, F_OK));
|
||||
|
||||
/* create a passwd struct */
|
||||
pw.pw_name = login;
|
||||
pw.pw_passwd = default_passwd;
|
||||
pw.pw_uid = 0;
|
||||
pw.pw_gid = 0;
|
||||
pw.pw_gecos = gecos;
|
||||
pw.pw_dir = home;
|
||||
pw.pw_shell = shell;
|
||||
|
||||
/* grand finale */
|
||||
i = adduser(PASSWD_FILE, &pw);
|
||||
|
||||
return (i);
|
||||
}
|
||||
|
||||
/* $Id: adduser.c,v 1.1 2001/08/21 16:18:59 andersen Exp $ */
|
16
applets.h
16
applets.h
@ -46,6 +46,12 @@
|
||||
#ifdef BB_TEST
|
||||
APPLET_NOUSAGE("[", test_main, _BB_DIR_USR_BIN)
|
||||
#endif
|
||||
#ifdef BB_ADDGROUP
|
||||
APPLET(addgroup, addgroup_main, _BB_DIR_BIN)
|
||||
#endif
|
||||
#ifdef BB_ADDUSER
|
||||
APPLET(adduser, adduser_main, _BB_DIR_BIN)
|
||||
#endif
|
||||
#ifdef BB_ADJTIMEX
|
||||
APPLET(adjtimex, adjtimex_main, _BB_DIR_SBIN)
|
||||
#endif
|
||||
@ -104,6 +110,12 @@
|
||||
#ifdef BB_DEALLOCVT
|
||||
APPLET(deallocvt, deallocvt_main, _BB_DIR_USR_BIN)
|
||||
#endif
|
||||
#ifdef BB_DELGROUP
|
||||
APPLET(delgroup, delgroup_main, _BB_DIR_BIN)
|
||||
#endif
|
||||
#ifdef BB_DELUSER
|
||||
APPLET(deluser, deluser_main, _BB_DIR_BIN)
|
||||
#endif
|
||||
#ifdef BB_DF
|
||||
APPLET(df, df_main, _BB_DIR_BIN)
|
||||
#endif
|
||||
@ -167,6 +179,9 @@
|
||||
#ifdef BB_GETOPT
|
||||
APPLET(getopt, getopt_main, _BB_DIR_BIN)
|
||||
#endif
|
||||
#ifdef BB_GETTY
|
||||
APPLET(getty, getty_main, _BB_DIR_SBIN)
|
||||
#endif
|
||||
#ifdef BB_GREP
|
||||
APPLET(grep, grep_main, _BB_DIR_BIN)
|
||||
#endif
|
||||
@ -479,3 +494,4 @@
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -1,3 +1,19 @@
|
||||
#define addgroup_trivial_usage \
|
||||
"[OPTIONS] <group_name>"
|
||||
#define addgroup_full_usage \
|
||||
"Adds a group to the system" \
|
||||
"Options:\n" \
|
||||
"\t-g\t\tspecify gid\n"
|
||||
|
||||
#define adduser_trivial_usage \
|
||||
"[OPTIONS] <user_name>"
|
||||
#define adduser_full_usage \
|
||||
"Adds a user to the system" \
|
||||
"Options:\n" \
|
||||
"\t-h\t\thome directory\n" \
|
||||
"\t-s\t\tshell\n" \
|
||||
"\t-g\t\tGECOS string\n"
|
||||
|
||||
#define adjtimex_trivial_usage \
|
||||
"[-q] [-o offset] [-f frequency] [-p timeconstant] [-t tick]"
|
||||
#define adjtimex_full_usage \
|
||||
@ -215,6 +231,15 @@
|
||||
#define deallocvt_full_usage \
|
||||
"Deallocate unused virtual terminal /dev/ttyN"
|
||||
|
||||
#define delgroup_trivial_usage \
|
||||
"GROUP"
|
||||
#define delgroup_full_usage \
|
||||
"Deletes group GROUP from the system"
|
||||
|
||||
#define deluser_trivial_usage \
|
||||
"USER"
|
||||
#define deluser_full_usage \
|
||||
"Deletes user USER from the system"
|
||||
|
||||
#ifdef BB_FEATURE_HUMAN_READABLE
|
||||
#define USAGE_HUMAN_READABLE(a) a
|
||||
@ -533,6 +558,22 @@
|
||||
" esac\n" \
|
||||
"done\n"
|
||||
|
||||
#define getty_trivial_usage \
|
||||
"getty [OPTIONS]... baud_rate,... line [termtype]"
|
||||
#define getty_full_usage \
|
||||
"\nOpens a tty, prompts for a login name, then invokes /bin/login\n\n" \
|
||||
"Options:\n" \
|
||||
"\t-h\t\tEnable hardware (RTS/CTS) flow control.\n" \
|
||||
"\t-i\t\tDo not display /etc/issue before running login.\n" \
|
||||
"\t-L\t\tLocal line, so do not do carrier detect.\n" \
|
||||
"\t-m\t\tGet baud rate from modem's CONNECT status message.\n" \
|
||||
"\t-w\t\tWait for a CR or LF before sending /etc/issue.\n" \
|
||||
"\t-l login_app\tInvoke login_app instead of /bin/login.\n" \
|
||||
"\t-t timeout\tTerminate after timeout if no username is read.\n" \
|
||||
"\t-I initstring\tSets the init string to send before anything else.\n" \
|
||||
"\t-H login_host\tLog login_host into the utmp file as the hostname."
|
||||
|
||||
|
||||
#define grep_trivial_usage \
|
||||
"[-ihHnqvs] PATTERN [FILEs...]"
|
||||
#define grep_full_usage \
|
||||
|
175
deluser.c
Normal file
175
deluser.c
Normal file
@ -0,0 +1,175 @@
|
||||
/* vi: set sw=4 ts=4: */
|
||||
/*
|
||||
* deluser (remove lusers from the system ;) for TinyLogin
|
||||
*
|
||||
*
|
||||
* Copyright (C) 1999 by Lineo, inc.
|
||||
* Written by John Beppu <beppu@lineo.com>
|
||||
*
|
||||
* 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 <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "busybox.h"
|
||||
|
||||
#define PASSWD_FILE "/etc/passwd"
|
||||
#define GROUP_FILE "/etc/group"
|
||||
|
||||
/* where to start and stop deletion */
|
||||
typedef struct {
|
||||
size_t start;
|
||||
size_t stop;
|
||||
} Bounds;
|
||||
|
||||
/* An interesting side-effect of boundary()'s
|
||||
* implementation is that the first user (typically root)
|
||||
* cannot be removed. Let's call it a feature. */
|
||||
static Bounds boundary(const char *buffer, const char *login)
|
||||
{
|
||||
char needle[256];
|
||||
char *start;
|
||||
char *stop;
|
||||
Bounds b;
|
||||
|
||||
snprintf(needle, 256, "\n%s", login);
|
||||
needle[255] = 0;
|
||||
start = strstr(buffer, needle);
|
||||
if (!start) {
|
||||
b.start = 0;
|
||||
b.stop = 0;
|
||||
return b;
|
||||
}
|
||||
start++;
|
||||
|
||||
stop = index(start, '\n'); /* index is a BSD-ism */
|
||||
b.start = start - buffer;
|
||||
b.stop = stop - buffer;
|
||||
return b;
|
||||
}
|
||||
|
||||
/* grep -v ^login (except it only deletes the first match) */
|
||||
/* ...in fact, I think I'm going to simplify this later */
|
||||
static int del_line_matching(char *login, char *filename)
|
||||
{
|
||||
char *buffer;
|
||||
FILE *passwd;
|
||||
size_t len;
|
||||
Bounds b;
|
||||
struct stat statbuf;
|
||||
|
||||
/* load into buffer */
|
||||
passwd = fopen(filename, "r");
|
||||
if (!passwd) {
|
||||
return 1;
|
||||
}
|
||||
stat(filename, &statbuf);
|
||||
len = statbuf.st_size;
|
||||
buffer = (char *) malloc(len * sizeof(char));
|
||||
|
||||
if (!buffer) {
|
||||
fclose(passwd);
|
||||
return 1;
|
||||
}
|
||||
fread(buffer, len, sizeof(char), passwd);
|
||||
|
||||
fclose(passwd);
|
||||
|
||||
/* find the user to remove */
|
||||
b = boundary(buffer, login);
|
||||
if (b.stop == 0) {
|
||||
free(buffer);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* write the file w/o the user */
|
||||
passwd = fopen(filename, "w");
|
||||
if (!passwd) {
|
||||
return 1;
|
||||
}
|
||||
fwrite(buffer, (b.start - 1), sizeof(char), passwd);
|
||||
fwrite(&buffer[b.stop], (len - b.stop), sizeof(char), passwd);
|
||||
|
||||
fclose(passwd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ________________________________________________________________________ */
|
||||
int delgroup_main(int argc, char **argv)
|
||||
{
|
||||
/* int successful; */
|
||||
int failure;
|
||||
|
||||
if (argc != 2) {
|
||||
show_usage();
|
||||
} else {
|
||||
|
||||
failure = del_line_matching(argv[1], GROUP_FILE);
|
||||
#ifdef TLG_FEATURE_SHADOWPASSWDS
|
||||
if (access(GSHADOW_FILE, W_OK) == 0) {
|
||||
/* EDR the |= works if the error is not 0, so he had it wrong */
|
||||
failure |= del_line_matching(argv[1], GSHADOW_FILE);
|
||||
}
|
||||
#endif /* TLG_FEATURE_SHADOWPASSWDS */
|
||||
/* if (!successful) { */
|
||||
if (failure) {
|
||||
error_msg_and_die("%s: Group could not be removed\n", argv[1]);
|
||||
}
|
||||
|
||||
}
|
||||
return (EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
/* ________________________________________________________________________ */
|
||||
int deluser_main(int argc, char **argv)
|
||||
{
|
||||
/* int successful; */
|
||||
int failure;
|
||||
|
||||
if (argc != 2) {
|
||||
show_usage();
|
||||
} else {
|
||||
|
||||
failure = del_line_matching(argv[1], PASSWD_FILE);
|
||||
/* if (!successful) { */
|
||||
if (failure) {
|
||||
error_msg_and_die("%s: User could not be removed from %s\n",
|
||||
argv[1], PASSWD_FILE);
|
||||
}
|
||||
#ifdef TLG_FEATURE_SHADOWPASSWDS
|
||||
failure = del_line_matching(argv[1], SHADOW_FILE);
|
||||
/* if (!successful) { */
|
||||
if (failure) {
|
||||
error_msg_and_die("%s: User could not be removed from %s\n",
|
||||
argv[1], SHADOW_FILE);
|
||||
}
|
||||
#endif /* TLG_FEATURE_SHADOWPASSWDS */
|
||||
failure = del_line_matching(argv[1], GROUP_FILE);
|
||||
/* if (!successful) { */
|
||||
if (failure) {
|
||||
error_msg_and_die("%s: User could not be removed from %s\n",
|
||||
argv[1], GROUP_FILE);
|
||||
}
|
||||
|
||||
}
|
||||
return (EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
/* $Id: deluser.c,v 1.1 2001/08/21 16:18:59 andersen Exp $ */
|
@ -46,6 +46,12 @@
|
||||
#ifdef BB_TEST
|
||||
APPLET_NOUSAGE("[", test_main, _BB_DIR_USR_BIN)
|
||||
#endif
|
||||
#ifdef BB_ADDGROUP
|
||||
APPLET(addgroup, addgroup_main, _BB_DIR_BIN)
|
||||
#endif
|
||||
#ifdef BB_ADDUSER
|
||||
APPLET(adduser, adduser_main, _BB_DIR_BIN)
|
||||
#endif
|
||||
#ifdef BB_ADJTIMEX
|
||||
APPLET(adjtimex, adjtimex_main, _BB_DIR_SBIN)
|
||||
#endif
|
||||
@ -104,6 +110,12 @@
|
||||
#ifdef BB_DEALLOCVT
|
||||
APPLET(deallocvt, deallocvt_main, _BB_DIR_USR_BIN)
|
||||
#endif
|
||||
#ifdef BB_DELGROUP
|
||||
APPLET(delgroup, delgroup_main, _BB_DIR_BIN)
|
||||
#endif
|
||||
#ifdef BB_DELUSER
|
||||
APPLET(deluser, deluser_main, _BB_DIR_BIN)
|
||||
#endif
|
||||
#ifdef BB_DF
|
||||
APPLET(df, df_main, _BB_DIR_BIN)
|
||||
#endif
|
||||
@ -167,6 +179,9 @@
|
||||
#ifdef BB_GETOPT
|
||||
APPLET(getopt, getopt_main, _BB_DIR_BIN)
|
||||
#endif
|
||||
#ifdef BB_GETTY
|
||||
APPLET(getty, getty_main, _BB_DIR_SBIN)
|
||||
#endif
|
||||
#ifdef BB_GREP
|
||||
APPLET(grep, grep_main, _BB_DIR_BIN)
|
||||
#endif
|
||||
@ -479,3 +494,4 @@
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -1,3 +1,19 @@
|
||||
#define addgroup_trivial_usage \
|
||||
"[OPTIONS] <group_name>"
|
||||
#define addgroup_full_usage \
|
||||
"Adds a group to the system" \
|
||||
"Options:\n" \
|
||||
"\t-g\t\tspecify gid\n"
|
||||
|
||||
#define adduser_trivial_usage \
|
||||
"[OPTIONS] <user_name>"
|
||||
#define adduser_full_usage \
|
||||
"Adds a user to the system" \
|
||||
"Options:\n" \
|
||||
"\t-h\t\thome directory\n" \
|
||||
"\t-s\t\tshell\n" \
|
||||
"\t-g\t\tGECOS string\n"
|
||||
|
||||
#define adjtimex_trivial_usage \
|
||||
"[-q] [-o offset] [-f frequency] [-p timeconstant] [-t tick]"
|
||||
#define adjtimex_full_usage \
|
||||
@ -215,6 +231,15 @@
|
||||
#define deallocvt_full_usage \
|
||||
"Deallocate unused virtual terminal /dev/ttyN"
|
||||
|
||||
#define delgroup_trivial_usage \
|
||||
"GROUP"
|
||||
#define delgroup_full_usage \
|
||||
"Deletes group GROUP from the system"
|
||||
|
||||
#define deluser_trivial_usage \
|
||||
"USER"
|
||||
#define deluser_full_usage \
|
||||
"Deletes user USER from the system"
|
||||
|
||||
#ifdef BB_FEATURE_HUMAN_READABLE
|
||||
#define USAGE_HUMAN_READABLE(a) a
|
||||
@ -533,6 +558,22 @@
|
||||
" esac\n" \
|
||||
"done\n"
|
||||
|
||||
#define getty_trivial_usage \
|
||||
"getty [OPTIONS]... baud_rate,... line [termtype]"
|
||||
#define getty_full_usage \
|
||||
"\nOpens a tty, prompts for a login name, then invokes /bin/login\n\n" \
|
||||
"Options:\n" \
|
||||
"\t-h\t\tEnable hardware (RTS/CTS) flow control.\n" \
|
||||
"\t-i\t\tDo not display /etc/issue before running login.\n" \
|
||||
"\t-L\t\tLocal line, so do not do carrier detect.\n" \
|
||||
"\t-m\t\tGet baud rate from modem's CONNECT status message.\n" \
|
||||
"\t-w\t\tWait for a CR or LF before sending /etc/issue.\n" \
|
||||
"\t-l login_app\tInvoke login_app instead of /bin/login.\n" \
|
||||
"\t-t timeout\tTerminate after timeout if no username is read.\n" \
|
||||
"\t-I initstring\tSets the init string to send before anything else.\n" \
|
||||
"\t-H login_host\tLog login_host into the utmp file as the hostname."
|
||||
|
||||
|
||||
#define grep_trivial_usage \
|
||||
"[-ihHnqvs] PATTERN [FILEs...]"
|
||||
#define grep_full_usage \
|
||||
|
41
usage.h
41
usage.h
@ -1,3 +1,19 @@
|
||||
#define addgroup_trivial_usage \
|
||||
"[OPTIONS] <group_name>"
|
||||
#define addgroup_full_usage \
|
||||
"Adds a group to the system" \
|
||||
"Options:\n" \
|
||||
"\t-g\t\tspecify gid\n"
|
||||
|
||||
#define adduser_trivial_usage \
|
||||
"[OPTIONS] <user_name>"
|
||||
#define adduser_full_usage \
|
||||
"Adds a user to the system" \
|
||||
"Options:\n" \
|
||||
"\t-h\t\thome directory\n" \
|
||||
"\t-s\t\tshell\n" \
|
||||
"\t-g\t\tGECOS string\n"
|
||||
|
||||
#define adjtimex_trivial_usage \
|
||||
"[-q] [-o offset] [-f frequency] [-p timeconstant] [-t tick]"
|
||||
#define adjtimex_full_usage \
|
||||
@ -215,6 +231,15 @@
|
||||
#define deallocvt_full_usage \
|
||||
"Deallocate unused virtual terminal /dev/ttyN"
|
||||
|
||||
#define delgroup_trivial_usage \
|
||||
"GROUP"
|
||||
#define delgroup_full_usage \
|
||||
"Deletes group GROUP from the system"
|
||||
|
||||
#define deluser_trivial_usage \
|
||||
"USER"
|
||||
#define deluser_full_usage \
|
||||
"Deletes user USER from the system"
|
||||
|
||||
#ifdef BB_FEATURE_HUMAN_READABLE
|
||||
#define USAGE_HUMAN_READABLE(a) a
|
||||
@ -533,6 +558,22 @@
|
||||
" esac\n" \
|
||||
"done\n"
|
||||
|
||||
#define getty_trivial_usage \
|
||||
"getty [OPTIONS]... baud_rate,... line [termtype]"
|
||||
#define getty_full_usage \
|
||||
"\nOpens a tty, prompts for a login name, then invokes /bin/login\n\n" \
|
||||
"Options:\n" \
|
||||
"\t-h\t\tEnable hardware (RTS/CTS) flow control.\n" \
|
||||
"\t-i\t\tDo not display /etc/issue before running login.\n" \
|
||||
"\t-L\t\tLocal line, so do not do carrier detect.\n" \
|
||||
"\t-m\t\tGet baud rate from modem's CONNECT status message.\n" \
|
||||
"\t-w\t\tWait for a CR or LF before sending /etc/issue.\n" \
|
||||
"\t-l login_app\tInvoke login_app instead of /bin/login.\n" \
|
||||
"\t-t timeout\tTerminate after timeout if no username is read.\n" \
|
||||
"\t-I initstring\tSets the init string to send before anything else.\n" \
|
||||
"\t-H login_host\tLog login_host into the utmp file as the hostname."
|
||||
|
||||
|
||||
#define grep_trivial_usage \
|
||||
"[-ihHnqvs] PATTERN [FILEs...]"
|
||||
#define grep_full_usage \
|
||||
|
Loading…
Reference in New Issue
Block a user