aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2006-12-01 21:34:20 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2006-12-01 21:34:20 +0000
commitbecd8c538cc689460dca83ecc92222969059c5f4 (patch)
tree70be5c3624b5a9ead8ae771f0cfbc2da5f6815df
parent732268fe69739411c8e1373e688381253a04efe6 (diff)
downloadbusybox-w32-becd8c538cc689460dca83ecc92222969059c5f4.tar.gz
busybox-w32-becd8c538cc689460dca83ecc92222969059c5f4.tar.bz2
busybox-w32-becd8c538cc689460dca83ecc92222969059c5f4.zip
passwd: made smaller by ~130 bytes. size can go negative
if current trend will continue ;)
-rw-r--r--include/libbb.h2
-rw-r--r--libbb/bb_pwd.c68
-rw-r--r--loginutils/passwd.c106
3 files changed, 84 insertions, 92 deletions
diff --git a/include/libbb.h b/include/libbb.h
index f891e1bc4..ef5086d6c 100644
--- a/include/libbb.h
+++ b/include/libbb.h
@@ -320,7 +320,7 @@ uint16_t xatou16(const char *numstr);
320 * increases target size and is often not needed on embedded systems. */ 320 * increases target size and is often not needed on embedded systems. */
321extern long bb_xgetpwnam(const char *name); 321extern long bb_xgetpwnam(const char *name);
322extern long bb_xgetgrnam(const char *name); 322extern long bb_xgetgrnam(const char *name);
323extern char *bb_getug(char *buffer, char *idname, long id, int bufsize, char prefix); 323/*extern char *bb_getug(char *buffer, char *idname, long id, int bufsize, char prefix);*/
324extern char *bb_getpwuid(char *name, long uid, int bufsize); 324extern char *bb_getpwuid(char *name, long uid, int bufsize);
325extern char *bb_getgrgid(char *group, long gid, int bufsize); 325extern char *bb_getgrgid(char *group, long gid, int bufsize);
326/* from chpst */ 326/* from chpst */
diff --git a/libbb/bb_pwd.c b/libbb/bb_pwd.c
index 48a5c1539..b5125b0f4 100644
--- a/libbb/bb_pwd.c
+++ b/libbb/bb_pwd.c
@@ -12,6 +12,35 @@
12#include <assert.h> 12#include <assert.h>
13#include "libbb.h" 13#include "libbb.h"
14 14
15 /*
16 * if bufsize is > 0 char *buffer cannot be set to NULL.
17 * If idname is not NULL it is written on the static
18 * allocated buffer (and a pointer to it is returned).
19 * if idname is NULL, id as string is written to the static
20 * allocated buffer and NULL is returned.
21 * if bufsize is = 0 char *buffer can be set to NULL.
22 * If idname exists a pointer to it is returned,
23 * else NULL is returned.
24 * if bufsize is < 0 char *buffer can be set to NULL.
25 * If idname exists a pointer to it is returned,
26 * else an error message is printed and the program exits.
27 */
28
29/* internal function for bb_getpwuid and bb_getgrgid */
30static char * bb_getug(char *buffer, char *idname, long id, int bufsize, char prefix)
31{
32 if (bufsize > 0 ) {
33 assert(buffer!=NULL);
34 if(idname) {
35 return safe_strncpy(buffer, idname, bufsize);
36 }
37 snprintf(buffer, bufsize, "%ld", id);
38 } else if (bufsize < 0 && !idname) {
39 bb_error_msg_and_die("unknown %cid %ld", prefix, id);
40 }
41 return idname;
42}
43
15 /* Hacked by Tito Ragusa (c) 2004 <farmatito@tiscali.it> to make it more 44 /* Hacked by Tito Ragusa (c) 2004 <farmatito@tiscali.it> to make it more
16 * flexible : 45 * flexible :
17 * 46 *
@@ -84,49 +113,18 @@ char * bb_getpwuid(char *name, long uid, int bufsize)
84{ 113{
85 struct passwd *myuser = getpwuid(uid); 114 struct passwd *myuser = getpwuid(uid);
86 115
87 return bb_getug(name, (myuser) ? 116 return bb_getug(name, myuser ? myuser->pw_name : (char *)myuser,
88 myuser->pw_name : (char *)myuser , uid, bufsize, 'u'); 117 uid, bufsize, 'u');
89}
90
91 /*
92 * if bufsize is > 0 char *buffer cannot be set to NULL.
93 * If idname is not NULL it is written on the static
94 * allocated buffer (and a pointer to it is returned).
95 * if idname is NULL, id as string is written to the static
96 * allocated buffer and NULL is returned.
97 * if bufsize is = 0 char *buffer can be set to NULL.
98 * If idname exists a pointer to it is returned,
99 * else NULL is returned.
100 * if bufsize is < 0 char *buffer can be set to NULL.
101 * If idname exists a pointer to it is returned,
102 * else an error message is printed and the program exits.
103 */
104
105/* internal function for bb_getpwuid and bb_getgrgid */
106char * bb_getug(char *buffer, char *idname, long id, int bufsize, char prefix)
107{
108 if(bufsize > 0 ) {
109 assert(buffer!=NULL);
110 if(idname) {
111 return safe_strncpy(buffer, idname, bufsize);
112 }
113 snprintf(buffer, bufsize, "%ld", id);
114 } else if(bufsize < 0 && !idname) {
115 bb_error_msg_and_die("unknown %cid %ld", prefix, id);
116 }
117 return idname;
118} 118}
119 119
120unsigned long get_ug_id(const char *s, 120unsigned long get_ug_id(const char *s,
121 long (*__bb_getxxnam)(const char *)) 121 long (*__bb_getxxnam)(const char *))
122{ 122{
123 unsigned long r; 123 unsigned long r;
124 char *p;
125 124
126 r = strtoul(s, &p, 10); 125 r = bb_strtoul(s, NULL, 10);
127 if (*p || (s == p)) { 126 if (errno)
128 r = __bb_getxxnam(s); 127 r = __bb_getxxnam(s);
129 }
130 128
131 return r; 129 return r;
132} 130}
diff --git a/loginutils/passwd.c b/loginutils/passwd.c
index 35dee019b..1f488290a 100644
--- a/loginutils/passwd.c
+++ b/loginutils/passwd.c
@@ -52,8 +52,7 @@ static void crypt_make_salt(char *p, int cnt)
52} 52}
53 53
54 54
55static char* new_password(const struct passwd *pw, const char *old_crypted, 55static char* new_password(const struct passwd *pw, uid_t myuid, int algo)
56 uid_t myuid, int algo)
57{ 56{
58 char salt[sizeof("$N$XXXXXXXX")]; /* "$N$XXXXXXXX" or "XX" */ 57 char salt[sizeof("$N$XXXXXXXX")]; /* "$N$XXXXXXXX" or "XX" */
59 char *orig = ""; 58 char *orig = "";
@@ -62,12 +61,12 @@ static char* new_password(const struct passwd *pw, const char *old_crypted,
62 char *cp = NULL; 61 char *cp = NULL;
63 char *ret = NULL; /* failure so far */ 62 char *ret = NULL; /* failure so far */
64 63
65 if (myuid && old_crypted[0]) { 64 if (myuid && pw->pw_passwd[0]) {
66 orig = bb_askpass(0, "Old password:"); /* returns ptr to static */ 65 orig = bb_askpass(0, "Old password:"); /* returns ptr to static */
67 if (!orig) 66 if (!orig)
68 goto err_ret; 67 goto err_ret;
69 cipher = pw_encrypt(orig, old_crypted); /* returns ptr to static */ 68 cipher = pw_encrypt(orig, pw->pw_passwd); /* returns ptr to static */
70 if (strcmp(cipher, old_crypted) != 0) { 69 if (strcmp(cipher, pw->pw_passwd) != 0) {
71 syslog(LOG_WARNING, "incorrect password for '%s'", 70 syslog(LOG_WARNING, "incorrect password for '%s'",
72 pw->pw_name); 71 pw->pw_name);
73 bb_do_delay(FAIL_DELAY); 72 bb_do_delay(FAIL_DELAY);
@@ -76,23 +75,19 @@ static char* new_password(const struct passwd *pw, const char *old_crypted,
76 } 75 }
77 } 76 }
78 orig = xstrdup(orig); /* or else bb_askpass() will destroy it */ 77 orig = xstrdup(orig); /* or else bb_askpass() will destroy it */
79 newp = bb_askpass(0, "Enter the new password (minimum of 5 characters).\n" 78 newp = bb_askpass(0, "New password:"); /* returns ptr to static */
80 "Please use a combination of upper and lower case letters and numbers.\n"
81 "Enter new password:"); /* returns ptr to static */
82 if (!newp) 79 if (!newp)
83 goto err_ret; 80 goto err_ret;
84 newp = xstrdup(newp); /* we are going to bb_askpass() again, so save it */ 81 newp = xstrdup(newp); /* we are going to bb_askpass() again, so save it */
85 if (obscure(orig, newp, pw)) { 82 if (obscure(orig, newp, pw) && myuid) {
86 if (myuid)
87 goto err_ret; /* non-root is not allowed to have weak passwd */ 83 goto err_ret; /* non-root is not allowed to have weak passwd */
88 puts("\nWarning: weak password (continuing)");
89 } 84 }
90 85
91 cp = bb_askpass(0, "Re-enter new password:"); 86 cp = bb_askpass(0, "Retype password:");
92 if (!cp) 87 if (!cp)
93 goto err_ret; 88 goto err_ret;
94 if (strcmp(cp, newp)) { 89 if (strcmp(cp, newp)) {
95 puts("Passwords do not match"); 90 puts("Passwords don't match");
96 goto err_ret; 91 goto err_ret;
97 } 92 }
98 93
@@ -116,15 +111,6 @@ static char* new_password(const struct passwd *pw, const char *old_crypted,
116} 111}
117 112
118 113
119static void set_filesize_limit(int blocks)
120{
121 struct rlimit rlimit_fsize;
122
123 rlimit_fsize.rlim_cur = rlimit_fsize.rlim_max = 512L * blocks;
124 setrlimit(RLIMIT_FSIZE, &rlimit_fsize);
125}
126
127
128#if 0 114#if 0
129static int get_algo(char *a) 115static int get_algo(char *a)
130{ 116{
@@ -152,6 +138,7 @@ static int update_passwd(const char *filename, const char *username,
152 int i; 138 int i;
153 int ret = 1; /* failure */ 139 int ret = 1; /* failure */
154 140
141 logmode = LOGMODE_STDIO;
155 /* New passwd file, "/etc/passwd+" for now */ 142 /* New passwd file, "/etc/passwd+" for now */
156 new_name = xasprintf("%s+", filename); 143 new_name = xasprintf("%s+", filename);
157 last_char = &new_name[strlen(new_name)-1]; 144 last_char = &new_name[strlen(new_name)-1];
@@ -239,6 +226,7 @@ static int update_passwd(const char *filename, const char *username,
239 free_mem: 226 free_mem:
240 if (ENABLE_FEATURE_CLEAN_UP) free(new_name); 227 if (ENABLE_FEATURE_CLEAN_UP) free(new_name);
241 if (ENABLE_FEATURE_CLEAN_UP) free((char*)username); 228 if (ENABLE_FEATURE_CLEAN_UP) free((char*)username);
229 logmode = LOGMODE_BOTH;
242 return ret; 230 return ret;
243} 231}
244 232
@@ -252,19 +240,21 @@ int passwd_main(int argc, char **argv)
252 OPT_delete = 0x8, /* -d - delete password */ 240 OPT_delete = 0x8, /* -d - delete password */
253 OPT_lud = 0xe, 241 OPT_lud = 0xe,
254 STATE_ALGO_md5 = 0x10, 242 STATE_ALGO_md5 = 0x10,
255 /*STATE_ALGO_des = 0x20, not yet needed */ 243 /*STATE_ALGO_des = 0x20, not needed yet */
256 }; 244 };
257 unsigned opt; 245 unsigned opt;
258 char *opt_a = ""; 246 char *opt_a = "";
259 const char *filename; 247 const char *filename;
260 char *myname; 248 char *myname;
261 char *name; 249 char *name;
262 char *oldp; 250 char *newp;
263 char *newp = NULL; /* gcc happiness */ 251 struct passwd *pw;
264 const struct passwd *pw;
265 uid_t myuid; 252 uid_t myuid;
253 struct rlimit rlimit_fsize;
254 char c;
266 255
267 openlog("passwd", LOG_NOWAIT, LOG_AUTH); 256 logmode = LOGMODE_BOTH;
257 openlog(applet_name, LOG_NOWAIT, LOG_AUTH);
268 opt = getopt32(argc, argv, "a:lud", &opt_a); 258 opt = getopt32(argc, argv, "a:lud", &opt_a);
269 argc -= optind; 259 argc -= optind;
270 argv += optind; 260 argv += optind;
@@ -278,71 +268,75 @@ int passwd_main(int argc, char **argv)
278 bb_show_usage(); 268 bb_show_usage();
279 269
280 myname = xstrdup(bb_getpwuid(NULL, myuid, -1)); 270 myname = xstrdup(bb_getpwuid(NULL, myuid, -1));
281 name = myname; 271 name = argc ? argv[0] : myname;
282 if (argc) name = argv[0];
283 272
284 pw = getpwnam(name); 273 pw = getpwnam(name);
285 if (!pw) bb_error_msg_and_die("unknown user %s", name); 274 if (!pw) bb_error_msg_and_die("unknown user %s", name);
286 if (myuid && pw->pw_uid != myuid) { 275 if (myuid && pw->pw_uid != myuid) {
287 syslog(LOG_WARNING, "can't change pwd for '%s'", name); 276 /* LOGMODE_BOTH */
288 bb_error_msg_and_die("permission denied"); 277 bb_error_msg_and_die("%s can't change password for %s", myname, name);
289 } 278 }
290 279
291 filename = bb_path_passwd_file; 280 filename = bb_path_passwd_file;
292 oldp = pw->pw_passwd;
293 if (ENABLE_FEATURE_SHADOWPASSWDS) { 281 if (ENABLE_FEATURE_SHADOWPASSWDS) {
294 struct spwd *sp = getspnam(name); 282 struct spwd *sp = getspnam(name);
295 if (!sp) { 283 if (!sp) {
296 bb_error_msg("no shadow record for user %s found, " 284 /* LOGMODE_BOTH */
297 "changing ordinary password instead", name); 285 bb_error_msg("no record of %s in %s, using %s",
286 name, bb_path_shadow_file,
287 bb_path_passwd_file);
298 } else { 288 } else {
299 filename = bb_path_shadow_file; 289 filename = bb_path_shadow_file;
300 oldp = sp->sp_pwdp; 290 pw->pw_passwd = sp->sp_pwdp;
301 } 291 }
302 } 292 }
303 293
304 /* Decide what the new password will be */ 294 /* Decide what the new password will be */
295 newp = NULL;
296 c = pw->pw_passwd[0] - '!';
305 if (!(opt & OPT_lud)) { 297 if (!(opt & OPT_lud)) {
306 if (myuid) { 298 if (myuid && !c) { /* passwd starts with '!' */
307 if (oldp[0] == '!') { 299 /* LOGMODE_BOTH */
308 syslog(LOG_WARNING, "password locked for '%s'", name); 300 bb_error_msg_and_die("cannot change "
309 bb_error_msg_and_die("the password for %s cannot be changed", name); 301 "locked password for %s", name);
310 }
311 } 302 }
312 printf("Changing password for %s\n", name); 303 printf("Changing password for %s\n", name);
313 newp = new_password(pw, oldp, 304 newp = new_password(pw, myuid, opt & STATE_ALGO_md5);
314 myuid,
315 opt & STATE_ALGO_md5);
316 if (!newp) { 305 if (!newp) {
317 bb_error_msg_and_die("the password for %s is unchanged", name); 306 logmode = LOGMODE_STDIO;
307 bb_error_msg_and_die("password for %s is unchanged", name);
318 } 308 }
319 } else if (opt & OPT_lock) { 309 } else if (opt & OPT_lock) {
320 if (oldp[0] == '!') goto skip; 310 if (!c) goto skip; /* passwd starts with '!' */
321 newp = xasprintf("!%s", oldp); 311 newp = xasprintf("!%s", pw->pw_passwd);
322 } else if (opt & OPT_unlock) { 312 } else if (opt & OPT_unlock) {
323 if (oldp[0] != '!') goto skip; 313 if (c) goto skip; /* not '!' */
324 newp = xstrdup(oldp + 1); 314 newp = xstrdup(&pw->pw_passwd[1]);
325 } else if (opt & OPT_delete) { 315 } else if (opt & OPT_delete) {
326 newp = xstrdup(""); 316 newp = xstrdup("");
327 } 317 }
328 318
329 set_filesize_limit(30000); 319 rlimit_fsize.rlim_cur = rlimit_fsize.rlim_max = 512L * 30000;
320 setrlimit(RLIMIT_FSIZE, &rlimit_fsize);
330 signal(SIGHUP, SIG_IGN); 321 signal(SIGHUP, SIG_IGN);
331 signal(SIGINT, SIG_IGN); 322 signal(SIGINT, SIG_IGN);
332 signal(SIGQUIT, SIG_IGN); 323 signal(SIGQUIT, SIG_IGN);
333 umask(077); 324 umask(077);
334 xsetuid(0); 325 xsetuid(0);
335 if (update_passwd(filename, name, newp) == 0) { 326 if (update_passwd(filename, name, newp) != 0) {
336 syslog(LOG_INFO, "password for '%s' changed by user '%s'", name, 327 /* LOGMODE_BOTH */
337 myname); 328 bb_error_msg_and_die("cannot update password file %s",
338 puts("Password changed"); 329 filename);
339 } else {
340 syslog(LOG_WARNING, "cannot update password file");
341 bb_error_msg_and_die("cannot update password file");
342 } 330 }
331 /* LOGMODE_BOTH */
332 bb_info_msg("Password for %s changed by %s", name, myname);
343 333
344 if (ENABLE_FEATURE_CLEAN_UP) free(newp); 334 if (ENABLE_FEATURE_CLEAN_UP) free(newp);
345skip: 335skip:
336 if (!newp) {
337 bb_error_msg_and_die("password for %s is already %slocked",
338 name, (opt & OPT_unlock) ? "un" : "");
339 }
346 if (ENABLE_FEATURE_CLEAN_UP) free(myname); 340 if (ENABLE_FEATURE_CLEAN_UP) free(myname);
347 return 0; 341 return 0;
348} 342}