On 7/19/07, Tito <[EMAIL PROTECTED]> wrote:
Hi, would you mind to send the patch as attachment and
in diff -uN format.
I'm experiencing some difficulties to apply and test it.
Oh, sorry about this. I always get a bit too carried away with git
these days. :)
Please find the patch attached.

Regards,
--
Alex
diff -purN busybox.orig/include/applets.h busybox-trybuild/include/applets.h
--- busybox.orig/include/applets.h	2007-07-19 02:03:40.000000000 +0400
+++ busybox-trybuild/include/applets.h	2007-07-19 16:56:37.000000000 +0400
@@ -89,6 +89,7 @@ USE_CHCON(APPLET(chcon, _BB_DIR_USR_BIN,
 USE_CHGRP(APPLET_NOEXEC(chgrp, chgrp, _BB_DIR_BIN, _BB_SUID_NEVER, chgrp))
 USE_CHMOD(APPLET_NOEXEC(chmod, chmod, _BB_DIR_BIN, _BB_SUID_NEVER, chmod))
 USE_CHOWN(APPLET_NOEXEC(chown, chown, _BB_DIR_BIN, _BB_SUID_NEVER, chown))
+USE_CHPASSWD(APPLET(chpasswd, _BB_DIR_USR_SBIN, _BB_SUID_NEVER))
 USE_CHPST(APPLET(chpst, _BB_DIR_USR_BIN, _BB_SUID_NEVER))
 USE_CHROOT(APPLET(chroot, _BB_DIR_USR_SBIN, _BB_SUID_NEVER))
 USE_CHRT(APPLET(chrt, _BB_DIR_USR_BIN, _BB_SUID_NEVER))
diff -purN busybox.orig/include/libbb.h busybox-trybuild/include/libbb.h
--- busybox.orig/include/libbb.h	2007-07-19 02:03:40.000000000 +0400
+++ busybox-trybuild/include/libbb.h	2007-07-19 16:56:37.000000000 +0400
@@ -778,6 +778,9 @@ extern void print_login_prompt(void);
 
 extern void crypt_make_salt(char *p, int cnt);
 
+extern int update_passwd(const char *filename, const char *username,
+			const char *new_pw);
+
 int get_terminal_width_height(const int fd, int *width, int *height);
 
 int ioctl_or_perror(int fd, int request, void *argp, const char *fmt,...) __attribute__ ((format (printf, 4, 5)));
diff -purN busybox.orig/include/usage.h busybox-trybuild/include/usage.h
--- busybox.orig/include/usage.h	2007-07-19 02:03:40.000000000 +0400
+++ busybox-trybuild/include/usage.h	2007-07-19 16:56:37.000000000 +0400
@@ -2520,6 +2520,18 @@
        "	-l	Locks (disables) the specified user account\n" \
        "	-u	Unlocks (re-enables) the specified user account"
 
+#define chpasswd_trivial_usage \
+       "[--md5|--encrypt]"
+#define chpasswd_full_usage \
+       "Read user:password information from stdin\n" \
+       "and update /etc/passwd accordingly." \
+       "\n\nOptions:\n" \
+       "	-e, --encrypt\n" \
+       "               Supplied passwords are in encrypted form.\n" \
+       "	-m, --md5\n" \
+       "               Use MD5 encryption instead DES when the supplied\n" \
+       "               passwords are not encrypted.\n"
+
 #define patch_trivial_usage \
        "[-p<num>] [-i <diff>]"
 #define patch_full_usage \
diff -purN busybox.orig/libbb/Kbuild busybox-trybuild/libbb/Kbuild
--- busybox.orig/libbb/Kbuild	2007-07-19 02:03:40.000000000 +0400
+++ busybox-trybuild/libbb/Kbuild	2007-07-19 16:56:37.000000000 +0400
@@ -104,7 +104,8 @@ lib-y += xreadlink.o
 lib-$(CONFIG_FEATURE_MOUNT_LOOP) += loop.o
 lib-$(CONFIG_LOSETUP) += loop.o
 lib-$(CONFIG_FEATURE_MTAB_SUPPORT) += mtab.o
-lib-$(CONFIG_PASSWD) += pw_encrypt.o crypt_make_salt.o
+lib-$(CONFIG_PASSWD) += pw_encrypt.o crypt_make_salt.o update_passwd.o
+lib-$(CONFIG_CHPASSWD) += pw_encrypt.o crypt_make_salt.o update_passwd.o
 lib-$(CONFIG_CRYPTPW) += pw_encrypt.o crypt_make_salt.o
 lib-$(CONFIG_SULOGIN) += pw_encrypt.o
 lib-$(CONFIG_FEATURE_HTTPD_AUTH_MD5) += pw_encrypt.o
diff -purN busybox.orig/libbb/update_passwd.c busybox-trybuild/libbb/update_passwd.c
--- busybox.orig/libbb/update_passwd.c	1970-01-01 03:00:00.000000000 +0300
+++ busybox-trybuild/libbb/update_passwd.c	2007-07-19 16:56:37.000000000 +0400
@@ -0,0 +1,120 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * update_passwd
+ *
+ * update_passwd is a common function for passwd and chpasswd applets;
+ * it is responsible for updating password file (i.e. /etc/passwd or
+ * /etc/shadow) for a given user and password.
+ *
+ * Moved from loginutils/passwd.c by Alexander Shishkin <[EMAIL PROTECTED]>
+ */
+
+#include "libbb.h"
+
+int update_passwd(const char *filename, const char *username,
+			const char *new_pw)
+{
+	struct stat sb;
+	struct flock lock;
+	FILE *old_fp;
+	FILE *new_fp;
+	char *new_name;
+	char *last_char;
+	unsigned user_len;
+	int old_fd;
+	int new_fd;
+	int i;
+	int ret = 1; /* failure */
+
+	logmode = LOGMODE_STDIO;
+	/* New passwd file, "/etc/passwd+" for now */
+	new_name = xasprintf("%s+", filename);
+	last_char = &new_name[strlen(new_name)-1];
+	username = xasprintf("%s:", username);
+	user_len = strlen(username);
+
+	old_fp = fopen(filename, "r+");
+	if (!old_fp)
+		goto free_mem;
+	old_fd = fileno(old_fp);
+
+	/* Try to create "/etc/passwd+". Wait if it exists. */
+	i = 30;
+	do {
+		// FIXME: on last iteration try w/o O_EXCL but with O_TRUNC?
+		new_fd = open(new_name, O_WRONLY|O_CREAT|O_EXCL,0600);
+		if (new_fd >= 0) goto created;
+		if (errno != EEXIST) break;
+		usleep(100000); /* 0.1 sec */
+	} while (--i);
+	bb_perror_msg("cannot create '%s'", new_name);
+	goto close_old_fp;
+ created:
+	if (!fstat(old_fd, &sb)) {
+		fchmod(new_fd, sb.st_mode & 0777); /* ignore errors */
+		fchown(new_fd, sb.st_uid, sb.st_gid);
+	}
+	new_fp = fdopen(new_fd, "w");
+	if (!new_fp) {
+		close(new_fd);
+		goto unlink_new;
+	}
+
+	/* Backup file is "/etc/passwd-" */
+	last_char[0] = '-';
+	/* Delete old one, create new as a hardlink to current */
+	i = (unlink(new_name) && errno != ENOENT);
+	if (i || link(filename, new_name))
+		bb_perror_msg("warning: cannot create backup copy '%s'", new_name);
+	last_char[0] = '+';
+
+	/* Lock the password file before updating */
+	lock.l_type = F_WRLCK;
+	lock.l_whence = SEEK_SET;
+	lock.l_start = 0;
+	lock.l_len = 0;
+	if (fcntl(old_fd, F_SETLK, &lock) < 0)
+		bb_perror_msg("warning: cannot lock '%s'", filename);
+	lock.l_type = F_UNLCK;
+
+	/* Read current password file, write updated one */
+	while (1) {
+		char *line = xmalloc_fgets(old_fp);
+		if (!line) break; /* EOF/error */
+		if (strncmp(username, line, user_len) == 0) {
+			/* we have a match with "username:"... */
+			const char *cp = line + user_len;
+			/* now cp -> old passwd, skip it: */
+			cp = strchr(cp, ':');
+			if (!cp) cp = "";
+			/* now cp -> ':' after old passwd or -> "" */
+			fprintf(new_fp, "%s%s%s", username, new_pw, cp);
+			/* Erase password in memory */
+		} else
+			fputs(line, new_fp);
+		free(line);
+	}
+	fcntl(old_fd, F_SETLK, &lock);
+
+	/* We do want all of them to execute, thus | instead of || */
+	if ((ferror(old_fp) | fflush(new_fp) | fsync(new_fd) | fclose(new_fp))
+	 || rename(new_name, filename)
+	) {
+		/* At least one of those failed */
+		goto unlink_new;
+	}
+	ret = 0; /* whee, success! */
+
+ unlink_new:
+	if (ret) unlink(new_name);
+
+ close_old_fp:
+	fclose(old_fp);
+
+ free_mem:
+	if (ENABLE_FEATURE_CLEAN_UP) free(new_name);
+	if (ENABLE_FEATURE_CLEAN_UP) free((char*)username);
+	logmode = LOGMODE_BOTH;
+	return ret;
+}
+
diff -purN busybox.orig/loginutils/chpasswd.c busybox-trybuild/loginutils/chpasswd.c
--- busybox.orig/loginutils/chpasswd.c	1970-01-01 03:00:00.000000000 +0300
+++ busybox-trybuild/loginutils/chpasswd.c	2007-07-19 16:56:37.000000000 +0400
@@ -0,0 +1,120 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * chpasswd.c
+ *
+ * Written for SLIND (from passwd.c) by Alexander Shishkin <[EMAIL PROTECTED]>
+ * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
+ */
+
+#include <getopt.h> /* for struct option */
+#include <syslog.h>
+#include "libbb.h"
+
+static struct option const chpasswd_opts[] = {
+    { "encrypted", no_argument, 0, 'e' },
+    { "md5", no_argument, 0, 'm' }
+};
+
+int chpasswd_main(int argc, char **argv);
+int chpasswd_main(int argc, char **argv)
+{
+	char *name, *cp, *myname, *ret;
+	char buf[80];
+	char salt[sizeof("$N$XXXXXXXX")];
+	int enc = 0;
+	int md5 = 0;
+	int flag, amroot;
+	const struct passwd *pw;
+	struct rlimit rlimit_fsize;
+	char *pwfile =
+#ifndef ENABLE_FEATURE_SHADOWPASSWDS
+		bb_path_passwd_file;
+#else
+		bb_path_shadow_file;
+#endif
+
+	amroot = (getuid() == 0);
+	myname = (char *) xstrdup(bb_getpwuid(NULL, getuid(), -1));
+	while ((flag = getopt_long(argc, argv, "me", chpasswd_opts, NULL)) != EOF) {
+		switch (flag) {
+			case 'e':
+				enc = 1;
+				break;
+			case 'm':
+				md5 = 1;
+				break;
+			default:
+				bb_show_usage();
+		}
+	}
+
+	if (enc && md5)
+		bb_show_usage();
+
+	rlimit_fsize.rlim_cur = rlimit_fsize.rlim_max = 512L * 30000;
+	setrlimit(RLIMIT_FSIZE, &rlimit_fsize);
+	signal(SIGHUP, SIG_IGN);
+	signal(SIGINT, SIG_IGN);
+	signal(SIGQUIT, SIG_IGN);
+	umask(077);
+
+	while (fgets(buf, sizeof buf, stdin) != NULL) {
+		cp = strchr(buf, '\n');
+		if (cp)
+			*cp = '\0';
+		else {
+			puts("Line too long.\n");
+			continue;
+		}
+
+		name = buf;
+		cp = strchr(name, ':');
+		if (cp)
+			*cp++ = '\0';
+		else {
+			puts("Missing new password.\n");
+			continue;
+		}
+
+		pw = getpwnam(name);
+		if (!pw)
+			bb_error_msg_and_die("Unknown user %s\n", name);
+
+		if (!amroot && cp[0] == '!') {
+			syslog(LOG_WARNING, "password locked for `%s'", name);
+			bb_error_msg_and_die(
+					"The password for `%s' cannot be changed.\n", name
+					);
+		}
+
+		if (!enc) {
+			crypt_make_salt(salt, 1);
+
+			if (md5) {
+				strcpy(salt, "$1$");
+				crypt_make_salt(salt + 3, 4);
+			}
+
+			ret = xstrdup(pw_encrypt(cp, salt));
+		} else
+			ret = xstrdup(cp);
+
+		if (!update_passwd(pwfile, pw->pw_name, ret)) {
+			syslog(LOG_INFO, "password for `%s' changed by user `%s'", name,
+					myname);
+			puts("Password changed.\n");
+		} else {
+			syslog(LOG_WARNING, "an error occurred updating the password file");
+			bb_error_msg_and_die(
+					"An error occurred updating the password file.\n"
+					);
+		}
+
+		free(ret);
+	}
+
+	if (ENABLE_FEATURE_CLEAN_UP) free(myname);
+
+	return 0;
+}
+
diff -purN busybox.orig/loginutils/Config.in busybox-trybuild/loginutils/Config.in
--- busybox.orig/loginutils/Config.in	2007-07-19 02:03:40.000000000 +0400
+++ busybox-trybuild/loginutils/Config.in	2007-07-19 16:56:37.000000000 +0400
@@ -180,6 +180,14 @@ config CRYPTPW
 	help
 	  Applet for crypting a string.
 
+config CHPASSWD
+       bool "chpasswd"
+       default n
+       help
+         chpasswd  reads  a  file  of user name and password pairs from
+         standard input and uses this information to update a group of
+         existing users.
+
 config SU
 	bool "su"
 	default n
diff -purN busybox.orig/loginutils/Kbuild busybox-trybuild/loginutils/Kbuild
--- busybox.orig/loginutils/Kbuild	2007-07-19 02:03:40.000000000 +0400
+++ busybox-trybuild/loginutils/Kbuild	2007-07-19 16:56:37.000000000 +0400
@@ -8,6 +8,7 @@ lib-y:=
 lib-$(CONFIG_ADDGROUP)	+= addgroup.o
 lib-$(CONFIG_ADDUSER)	+= adduser.o
 lib-$(CONFIG_CRYPTPW)	+= cryptpw.o
+lib-$(CONFIG_CHPASSWD)	+= chpasswd.o
 lib-$(CONFIG_GETTY)	+= getty.o
 lib-$(CONFIG_LOGIN)	+= login.o
 lib-$(CONFIG_PASSWD)	+= passwd.o
diff -purN busybox.orig/loginutils/passwd.c busybox-trybuild/loginutils/passwd.c
--- busybox.orig/loginutils/passwd.c	2007-07-19 02:03:40.000000000 +0400
+++ busybox-trybuild/loginutils/passwd.c	2007-07-19 16:56:37.000000000 +0400
@@ -70,115 +70,6 @@ static char* new_password(const struct p
 	return ret;
 }
 
-
-static int update_passwd(const char *filename, const char *username,
-			const char *new_pw)
-{
-	struct stat sb;
-	struct flock lock;
-	FILE *old_fp;
-	FILE *new_fp;
-	char *new_name;
-	char *last_char;
-	unsigned user_len;
-	int old_fd;
-	int new_fd;
-	int i;
-	int ret = 1; /* failure */
-
-	logmode = LOGMODE_STDIO;
-	/* New passwd file, "/etc/passwd+" for now */
-	new_name = xasprintf("%s+", filename);
-	last_char = &new_name[strlen(new_name)-1];
-	username = xasprintf("%s:", username);
-	user_len = strlen(username);
-
-	old_fp = fopen(filename, "r+");
-	if (!old_fp)
-		goto free_mem;
-	old_fd = fileno(old_fp);
-
-	/* Try to create "/etc/passwd+". Wait if it exists. */
-	i = 30;
-	do {
-		// FIXME: on last iteration try w/o O_EXCL but with O_TRUNC?
-		new_fd = open(new_name, O_WRONLY|O_CREAT|O_EXCL,0600);
-		if (new_fd >= 0) goto created;
-		if (errno != EEXIST) break;
-		usleep(100000); /* 0.1 sec */
-	} while (--i);
-	bb_perror_msg("cannot create '%s'", new_name);
-	goto close_old_fp;
- created:
-	if (!fstat(old_fd, &sb)) {
-		fchmod(new_fd, sb.st_mode & 0777); /* ignore errors */
-		fchown(new_fd, sb.st_uid, sb.st_gid);
-	}
-	new_fp = fdopen(new_fd, "w");
-	if (!new_fp) {
-		close(new_fd);
-		goto unlink_new;
-	}
-
-	/* Backup file is "/etc/passwd-" */
-	last_char[0] = '-';
-	/* Delete old one, create new as a hardlink to current */
-	i = (unlink(new_name) && errno != ENOENT);
-	if (i || link(filename, new_name))
-		bb_perror_msg("warning: cannot create backup copy '%s'", new_name);
-	last_char[0] = '+';
-
-	/* Lock the password file before updating */
-	lock.l_type = F_WRLCK;
-	lock.l_whence = SEEK_SET;
-	lock.l_start = 0;
-	lock.l_len = 0;
-	if (fcntl(old_fd, F_SETLK, &lock) < 0)
-		bb_perror_msg("warning: cannot lock '%s'", filename);
-	lock.l_type = F_UNLCK;
-
-	/* Read current password file, write updated one */
-	while (1) {
-		char *line = xmalloc_fgets(old_fp);
-		if (!line) break; /* EOF/error */
-		if (strncmp(username, line, user_len) == 0) {
-			/* we have a match with "username:"... */
-			const char *cp = line + user_len;
-			/* now cp -> old passwd, skip it: */
-			cp = strchr(cp, ':');
-			if (!cp) cp = "";
-			/* now cp -> ':' after old passwd or -> "" */
-			fprintf(new_fp, "%s%s%s", username, new_pw, cp);
-			/* Erase password in memory */
-		} else
-			fputs(line, new_fp);
-		free(line);
-	}
-	fcntl(old_fd, F_SETLK, &lock);
-
-	/* We do want all of them to execute, thus | instead of || */
-	if ((ferror(old_fp) | fflush(new_fp) | fsync(new_fd) | fclose(new_fp))
-	 || rename(new_name, filename)
-	) {
-		/* At least one of those failed */
-		goto unlink_new;
-	}
-	ret = 0; /* whee, success! */
-
- unlink_new:
-	if (ret) unlink(new_name);
-
- close_old_fp:
-	fclose(old_fp);
-
- free_mem:
-	if (ENABLE_FEATURE_CLEAN_UP) free(new_name);
-	if (ENABLE_FEATURE_CLEAN_UP) free((char*)username);
-	logmode = LOGMODE_BOTH;
-	return ret;
-}
-
-
 int passwd_main(int argc, char **argv);
 int passwd_main(int argc, char **argv)
 {
_______________________________________________
busybox mailing list
[email protected]
http://busybox.net/cgi-bin/mailman/listinfo/busybox

Reply via email to