diff options
author | Richard Purdie <richard@openedhand.com> | 2005-08-31 10:45:47 +0000 |
---|---|---|
committer | Richard Purdie <richard@openedhand.com> | 2005-08-31 10:45:47 +0000 |
commit | 4b46c1f6e891b1ddd5968536440b888661fade3e (patch) | |
tree | e0ba2c1f56f61b868bf746da5c4feabb25b800b2 /openembedded/packages/tinylogin | |
download | poky-4b46c1f6e891b1ddd5968536440b888661fade3e.tar.gz |
Initial population
git-svn-id: https://svn.o-hand.com/repos/poky@1 311d38ba-8fff-0310-9ca6-ca027cbcb966
Diffstat (limited to 'openembedded/packages/tinylogin')
4 files changed, 1007 insertions, 0 deletions
diff --git a/openembedded/packages/tinylogin/tinylogin-1.4/add-system.patch b/openembedded/packages/tinylogin/tinylogin-1.4/add-system.patch new file mode 100644 index 0000000000..18b4e47ad7 --- /dev/null +++ b/openembedded/packages/tinylogin/tinylogin-1.4/add-system.patch | |||
@@ -0,0 +1,115 @@ | |||
1 | ? add-system.patch | ||
2 | ? cvs-20040608.patch | ||
3 | ? familiar | ||
4 | ? pod2htmd.tmp | ||
5 | ? pod2htmi.tmp | ||
6 | ? system.diff | ||
7 | ? tinylogin_1.4-20030620.1_arm.ipk | ||
8 | ? tinylogin_1.4-20030620.1_arm.ipk.asc | ||
9 | ? tinylogin_1.4-20030620.1_arm.ipk.upload.html | ||
10 | ? tinylogin_1.4-20030620.2_arm.ipk | ||
11 | ? tinylogin_1.4-20030620.2_arm.ipk.asc | ||
12 | ? tinylogin_1.4-20030620.2_arm.ipk.upload.html | ||
13 | ? tinylogin_1.4-20030620_arm.ipk | ||
14 | ? tinylogin_1.4-20030620_arm.ipk.asc | ||
15 | ? tinylogin_1.4-20030620_arm.ipk.upload.html | ||
16 | ? tmp | ||
17 | Index: addgroup.c | ||
18 | =================================================================== | ||
19 | RCS file: /var/cvs/tinylogin/addgroup.c,v | ||
20 | retrieving revision 1.23 | ||
21 | diff -u -r1.23 addgroup.c | ||
22 | --- a/addgroup.c 9 Jan 2003 18:43:29 -0000 1.23 | ||
23 | +++ b/addgroup.c 8 Jun 2004 08:56:08 -0000 | ||
24 | @@ -31,6 +31,7 @@ | ||
25 | #include <sys/stat.h> | ||
26 | #include <sys/types.h> | ||
27 | #include <unistd.h> | ||
28 | +#include <getopt.h> | ||
29 | #include "tinylogin.h" | ||
30 | |||
31 | #define GROUP_FILE "/etc/group" | ||
32 | @@ -124,6 +125,11 @@ | ||
33 | return 0; | ||
34 | } | ||
35 | |||
36 | +static struct option long_options[] = { | ||
37 | + { "system", 0, NULL, 'S' }, | ||
38 | + { 0, 0, 0, 0 } | ||
39 | +}; | ||
40 | + | ||
41 | /* | ||
42 | * addgroup will take a login_name as its first parameter. | ||
43 | * | ||
44 | @@ -136,14 +142,19 @@ | ||
45 | int opt; | ||
46 | char *group; | ||
47 | char *user; | ||
48 | + int option_index = -1; | ||
49 | gid_t gid = 0; | ||
50 | + int system = 0; | ||
51 | |||
52 | /* get remaining args */ | ||
53 | - while ((opt = getopt (argc, argv, "g:")) != -1) { | ||
54 | + while ((opt = getopt_long (argc, argv, "g:S", long_options, &option_index)) != -1) { | ||
55 | switch (opt) { | ||
56 | case 'g': | ||
57 | gid = strtol(optarg, NULL, 10); | ||
58 | break; | ||
59 | + case 'S': | ||
60 | + system = 1; | ||
61 | + break; | ||
62 | default: | ||
63 | show_usage(); | ||
64 | break; | ||
65 | Index: adduser.c | ||
66 | =================================================================== | ||
67 | RCS file: /var/cvs/tinylogin/adduser.c,v | ||
68 | retrieving revision 1.38 | ||
69 | diff -u -r1.38 adduser.c | ||
70 | --- a/adduser.c 21 Jun 2003 19:35:42 -0000 1.38 | ||
71 | +++ b/adduser.c 8 Jun 2004 08:56:09 -0000 | ||
72 | @@ -66,13 +66,13 @@ | ||
73 | |||
74 | /* remix */ | ||
75 | /* EDR recoded such that the uid may be passed in *p */ | ||
76 | -static int passwd_study(const char *filename, struct passwd *p) | ||
77 | +static int passwd_study(const char *filename, struct passwd *p, int system) | ||
78 | { | ||
79 | struct passwd *pw; | ||
80 | FILE *passwd; | ||
81 | |||
82 | - const int min = 500; | ||
83 | - const int max = 65000; | ||
84 | + const int min = system ? 10 : 500; | ||
85 | + const int max = system ? 99 : 65000; | ||
86 | |||
87 | passwd = wfopen(filename, "r"); | ||
88 | if (!passwd) | ||
89 | @@ -142,7 +142,7 @@ | ||
90 | } | ||
91 | |||
92 | /* putpwent(3) remix */ | ||
93 | -static int adduser(const char *filename, struct passwd *p, int makehome, int setpass) | ||
94 | +static int adduser(const char *filename, struct passwd *p, int makehome, int setpass, int system) | ||
95 | { | ||
96 | FILE *passwd; | ||
97 | int r; | ||
98 | @@ -165,7 +165,7 @@ | ||
99 | fseek(passwd, 0, SEEK_END); | ||
100 | |||
101 | /* if (passwd_study(filename, p) == 0) { */ | ||
102 | - r = passwd_study(filename, p); | ||
103 | + r = passwd_study(filename, p, system); | ||
104 | if (r) { | ||
105 | if (r == 1) | ||
106 | error_msg("%s: login already in use", p->pw_name); | ||
107 | @@ -357,7 +357,7 @@ | ||
108 | } | ||
109 | |||
110 | /* grand finale */ | ||
111 | - return adduser(PASSWD_FILE, &pw, makehome, setpass); | ||
112 | + return adduser(PASSWD_FILE, &pw, makehome, setpass, system); | ||
113 | } | ||
114 | |||
115 | /* $Id: adduser.c,v 1.38 2003/06/21 19:35:42 andersen Exp $ */ | ||
diff --git a/openembedded/packages/tinylogin/tinylogin-1.4/adduser-empty_pwd.patch b/openembedded/packages/tinylogin/tinylogin-1.4/adduser-empty_pwd.patch new file mode 100644 index 0000000000..737ac423c4 --- /dev/null +++ b/openembedded/packages/tinylogin/tinylogin-1.4/adduser-empty_pwd.patch | |||
@@ -0,0 +1,43 @@ | |||
1 | --- tinylogin-1.4/adduser.c.orig 2004-09-30 18:01:46.000000000 +0200 | ||
2 | +++ tinylogin-1.4/adduser.c 2004-09-30 18:07:01.000000000 +0200 | ||
3 | @@ -249,6 +249,7 @@ | ||
4 | struct option long_options[] = { | ||
5 | { "home", 1, NULL, 'h' }, | ||
6 | { "disabled-password", 0, NULL, 'D' }, | ||
7 | + { "empty-password", 0, NULL, 'E' }, | ||
8 | { "system", 0, NULL, 'S' }, | ||
9 | { "ingroup", 1, NULL, 'G' }, | ||
10 | { "no-create-home", 0, NULL, 'H' }, | ||
11 | @@ -287,7 +288,7 @@ | ||
12 | shell = default_shell; | ||
13 | |||
14 | /* get args */ | ||
15 | - while ((opt = getopt_long (argc, argv, "h:g:s:G:DSH", long_options, &option_index)) != -1) { | ||
16 | + while ((opt = getopt_long (argc, argv, "h:g:s:G:DESH", long_options, &option_index)) != -1) { | ||
17 | switch (opt) { | ||
18 | case 'h': | ||
19 | home = optarg; | ||
20 | @@ -304,6 +305,9 @@ | ||
21 | case 'D': | ||
22 | setpass = 0; | ||
23 | break; | ||
24 | + case 'E': | ||
25 | + setpass = -1; | ||
26 | + break; | ||
27 | case 'S': | ||
28 | system = 1; | ||
29 | break; | ||
30 | @@ -338,7 +342,12 @@ | ||
31 | |||
32 | /* create a passwd struct */ | ||
33 | pw.pw_name = (char *)login; | ||
34 | - pw.pw_passwd = (char *)default_passwd; | ||
35 | + if (setpass != -1) | ||
36 | + pw.pw_passwd = (char *)default_passwd; | ||
37 | + else { | ||
38 | + pw.pw_passwd = (char *)""; | ||
39 | + setpass = 0; | ||
40 | + } | ||
41 | pw.pw_uid = 0; | ||
42 | pw.pw_gid = 0; | ||
43 | pw.pw_gecos = (char *)gecos; | ||
diff --git a/openembedded/packages/tinylogin/tinylogin-1.4/cvs-20040608.patch b/openembedded/packages/tinylogin/tinylogin-1.4/cvs-20040608.patch new file mode 100644 index 0000000000..1142329a67 --- /dev/null +++ b/openembedded/packages/tinylogin/tinylogin-1.4/cvs-20040608.patch | |||
@@ -0,0 +1,821 @@ | |||
1 | Index: Config.h | ||
2 | =================================================================== | ||
3 | RCS file: /var/cvs/tinylogin/Config.h,v | ||
4 | retrieving revision 1.10 | ||
5 | retrieving revision 1.12 | ||
6 | diff -u -r1.10 -r1.12 | ||
7 | --- a/Config.h 23 Jun 2002 03:09:07 -0000 1.10 | ||
8 | +++ b/Config.h 17 Feb 2003 11:51:55 -0000 1.12 | ||
9 | @@ -27,15 +27,11 @@ | ||
10 | // Enable checking of /etc/securetty by login | ||
11 | #define CONFIG_FEATURE_SECURETTY | ||
12 | // | ||
13 | -// Enable using sha passwords | ||
14 | -#define CONFIG_FEATURE_SHA1_PASSWORDS | ||
15 | -// | ||
16 | // Enable use of a wheel group | ||
17 | #define CONFIG_WHEEL_GROUP | ||
18 | // | ||
19 | -// This compiles out everything but the most | ||
20 | -// trivial --help usage information (i.e. reduces binary size) | ||
21 | -#define CONFIG_FEATURE_TRIVIAL_HELP | ||
22 | +// Show verbose usage messages | ||
23 | +//#define CONFIG_FEATURE_VERBOSE_USAGE | ||
24 | // | ||
25 | // Enable 'tinylogin --install [-s]' to allow tinylogin | ||
26 | // to create links (or symlinks) at runtime for all the | ||
27 | @@ -48,10 +44,6 @@ | ||
28 | // Nothing beyond this point should ever be touched by | ||
29 | // mere mortals so leave this stuff alone. | ||
30 | // | ||
31 | -#ifdef CONFIG_FEATURE_SHA1_PASSWORDS | ||
32 | -#define CONFIG_SHA1 | ||
33 | -#endif | ||
34 | -// | ||
35 | #ifdef CONFIG_FEATURE_SHADOWPASSWDS | ||
36 | #define CONFIG_SHADOW | ||
37 | #endif | ||
38 | Index: addgroup.c | ||
39 | =================================================================== | ||
40 | RCS file: /var/cvs/tinylogin/addgroup.c,v | ||
41 | retrieving revision 1.22 | ||
42 | retrieving revision 1.23 | ||
43 | diff -u -r1.22 -r1.23 | ||
44 | --- a/addgroup.c 12 Dec 2002 08:46:03 -0000 1.22 | ||
45 | +++ b/addgroup.c 9 Jan 2003 18:43:29 -0000 1.23 | ||
46 | @@ -133,23 +133,33 @@ | ||
47 | * ________________________________________________________________________ */ | ||
48 | int addgroup_main(int argc, char **argv) | ||
49 | { | ||
50 | + int opt; | ||
51 | char *group; | ||
52 | char *user; | ||
53 | gid_t gid = 0; | ||
54 | |||
55 | - if (argc < 2) { | ||
56 | - show_usage(); | ||
57 | + /* get remaining args */ | ||
58 | + while ((opt = getopt (argc, argv, "g:")) != -1) { | ||
59 | + switch (opt) { | ||
60 | + case 'g': | ||
61 | + gid = strtol(optarg, NULL, 10); | ||
62 | + break; | ||
63 | + default: | ||
64 | + show_usage(); | ||
65 | + break; | ||
66 | + } | ||
67 | } | ||
68 | |||
69 | - if (strncmp(argv[1], "-g", 2) == 0) { | ||
70 | - gid = strtol(argv[2], NULL, 10); | ||
71 | - group = argv[2]; | ||
72 | + if (optind < argc) { | ||
73 | + group = argv[optind]; | ||
74 | + optind++; | ||
75 | } else { | ||
76 | show_usage(); | ||
77 | } | ||
78 | - | ||
79 | - if (argc == 4) { | ||
80 | - user = argv[3]; | ||
81 | + | ||
82 | + if (optind < argc) { | ||
83 | + user = argv[optind]; | ||
84 | + optind++; | ||
85 | } else { | ||
86 | user = ""; | ||
87 | } | ||
88 | @@ -163,4 +173,4 @@ | ||
89 | return addgroup(GROUP_FILE, group, gid, user); | ||
90 | } | ||
91 | |||
92 | -/* $Id: addgroup.c,v 1.22 2002/12/12 08:46:03 andersen Exp $ */ | ||
93 | +/* $Id: addgroup.c,v 1.23 2003/01/09 18:43:29 andersen Exp $ */ | ||
94 | Index: adduser.c | ||
95 | =================================================================== | ||
96 | RCS file: /var/cvs/tinylogin/adduser.c,v | ||
97 | retrieving revision 1.37 | ||
98 | retrieving revision 1.38 | ||
99 | diff -u -r1.37 -r1.38 | ||
100 | --- a/adduser.c 12 Dec 2002 08:46:03 -0000 1.37 | ||
101 | +++ b/adduser.c 21 Jun 2003 19:35:42 -0000 1.38 | ||
102 | @@ -21,6 +21,9 @@ | ||
103 | * | ||
104 | */ | ||
105 | |||
106 | +#ifndef _GNU_SOURCE | ||
107 | +#define _GNU_SOURCE | ||
108 | +#endif | ||
109 | #include <errno.h> | ||
110 | #include <fcntl.h> | ||
111 | #include <stdarg.h> | ||
112 | @@ -29,6 +32,7 @@ | ||
113 | #include <string.h> | ||
114 | #include <time.h> | ||
115 | #include <unistd.h> | ||
116 | +#include <getopt.h> | ||
117 | #include <sys/param.h> | ||
118 | #include <sys/stat.h> | ||
119 | #include <sys/types.h> | ||
120 | @@ -93,21 +97,23 @@ | ||
121 | } | ||
122 | } | ||
123 | |||
124 | - /* EDR check for an already existing gid */ | ||
125 | - while (getgrgid(p->pw_uid) != NULL) | ||
126 | - p->pw_uid++; | ||
127 | - | ||
128 | - /* EDR also check for an existing group definition */ | ||
129 | - if (getgrnam(p->pw_name) != NULL) | ||
130 | - return 3; | ||
131 | + if (p->pw_gid == 0) { | ||
132 | + /* EDR check for an already existing gid */ | ||
133 | + while (getgrgid(p->pw_uid) != NULL) | ||
134 | + p->pw_uid++; | ||
135 | + | ||
136 | + /* EDR also check for an existing group definition */ | ||
137 | + if (getgrnam(p->pw_name) != NULL) | ||
138 | + return 3; | ||
139 | + | ||
140 | + /* EDR create new gid always = uid */ | ||
141 | + p->pw_gid = p->pw_uid; | ||
142 | + } | ||
143 | |||
144 | /* EDR bounds check */ | ||
145 | if ((p->pw_uid > max) || (p->pw_uid < min)) | ||
146 | return 2; | ||
147 | |||
148 | - /* EDR create new gid always = uid */ | ||
149 | - p->pw_gid = p->pw_uid; | ||
150 | - | ||
151 | /* return 1; */ | ||
152 | return 0; | ||
153 | } | ||
154 | @@ -136,7 +142,7 @@ | ||
155 | } | ||
156 | |||
157 | /* putpwent(3) remix */ | ||
158 | -static int adduser(const char *filename, struct passwd *p) | ||
159 | +static int adduser(const char *filename, struct passwd *p, int makehome, int setpass) | ||
160 | { | ||
161 | FILE *passwd; | ||
162 | int r; | ||
163 | @@ -144,6 +150,11 @@ | ||
164 | FILE *shadow; | ||
165 | struct spwd *sp; | ||
166 | #endif | ||
167 | + int new_group = 1; | ||
168 | + | ||
169 | + /* if using a pre-existing group, don't create one */ | ||
170 | + if (p->pw_gid != 0) | ||
171 | + new_group = 0; | ||
172 | |||
173 | /* make sure everything is kosher and setup uid && gid */ | ||
174 | passwd = wfopen(filename, "a"); | ||
175 | @@ -194,29 +205,36 @@ | ||
176 | } | ||
177 | #endif | ||
178 | |||
179 | - /* add to group */ | ||
180 | - /* addgroup should be responsible for dealing w/ gshadow */ | ||
181 | - addgroup_wrapper(p->pw_name, p->pw_gid); | ||
182 | + if (new_group) { | ||
183 | + /* add to group */ | ||
184 | + /* addgroup should be responsible for dealing w/ gshadow */ | ||
185 | + addgroup_wrapper(p->pw_name, p->pw_gid); | ||
186 | + } | ||
187 | |||
188 | /* Clear the umask for this process so it doesn't | ||
189 | * * screw up the permissions on the mkdir and chown. */ | ||
190 | umask(0); | ||
191 | |||
192 | - /* mkdir */ | ||
193 | - if (mkdir(p->pw_dir, 0755)) { | ||
194 | - perror_msg("%s", p->pw_dir); | ||
195 | - } | ||
196 | - /* Set the owner and group so it is owned by the new user. */ | ||
197 | - if (chown(p->pw_dir, p->pw_uid, p->pw_gid)) { | ||
198 | - perror_msg("%s", p->pw_dir); | ||
199 | - } | ||
200 | - /* Now fix up the permissions to 2755. Can't do it before now | ||
201 | - * since chown will clear the setgid bit */ | ||
202 | - if (chmod(p->pw_dir, 02755)) { | ||
203 | - perror_msg("%s", p->pw_dir); | ||
204 | + if (makehome) { | ||
205 | + /* mkdir */ | ||
206 | + if (mkdir(p->pw_dir, 0755)) { | ||
207 | + perror_msg("%s", p->pw_dir); | ||
208 | + } | ||
209 | + /* Set the owner and group so it is owned by the new user. */ | ||
210 | + if (chown(p->pw_dir, p->pw_uid, p->pw_gid)) { | ||
211 | + perror_msg("%s", p->pw_dir); | ||
212 | + } | ||
213 | + /* Now fix up the permissions to 2755. Can't do it before now | ||
214 | + * since chown will clear the setgid bit */ | ||
215 | + if (chmod(p->pw_dir, 02755)) { | ||
216 | + perror_msg("%s", p->pw_dir); | ||
217 | + } | ||
218 | + } | ||
219 | + | ||
220 | + if (setpass) { | ||
221 | + /* interactively set passwd */ | ||
222 | + passwd_wrapper(p->pw_name); | ||
223 | } | ||
224 | - /* interactively set passwd */ | ||
225 | - passwd_wrapper(p->pw_name); | ||
226 | |||
227 | return 0; | ||
228 | } | ||
229 | @@ -228,6 +246,15 @@ | ||
230 | return geteuid(); | ||
231 | } | ||
232 | |||
233 | +struct option long_options[] = { | ||
234 | + { "home", 1, NULL, 'h' }, | ||
235 | + { "disabled-password", 0, NULL, 'D' }, | ||
236 | + { "system", 0, NULL, 'S' }, | ||
237 | + { "ingroup", 1, NULL, 'G' }, | ||
238 | + { "no-create-home", 0, NULL, 'H' }, | ||
239 | + { 0, 0, 0, 0 } | ||
240 | +}; | ||
241 | + | ||
242 | /* | ||
243 | * adduser will take a login_name as its first parameter. | ||
244 | * | ||
245 | @@ -244,6 +271,11 @@ | ||
246 | const char *gecos; | ||
247 | const char *home = NULL; | ||
248 | const char *shell; | ||
249 | + const char *usegroup = NULL; | ||
250 | + int option_index = -1; | ||
251 | + int setpass = 1; | ||
252 | + int makehome = 1; | ||
253 | + int system = 0; | ||
254 | |||
255 | struct passwd pw; | ||
256 | |||
257 | @@ -255,7 +287,7 @@ | ||
258 | shell = default_shell; | ||
259 | |||
260 | /* get args */ | ||
261 | - while ((opt = getopt (argc, argv, "h:g:s:")) != -1) { | ||
262 | + while ((opt = getopt_long (argc, argv, "h:g:s:G:DSH", long_options, &option_index)) != -1) { | ||
263 | switch (opt) { | ||
264 | case 'h': | ||
265 | home = optarg; | ||
266 | @@ -266,6 +298,18 @@ | ||
267 | case 's': | ||
268 | shell = optarg; | ||
269 | break; | ||
270 | + case 'H': | ||
271 | + makehome = 0; | ||
272 | + break; | ||
273 | + case 'D': | ||
274 | + setpass = 0; | ||
275 | + break; | ||
276 | + case 'S': | ||
277 | + system = 1; | ||
278 | + break; | ||
279 | + case 'G': | ||
280 | + usegroup = optarg; | ||
281 | + break; | ||
282 | default: | ||
283 | show_usage (); | ||
284 | break; | ||
285 | @@ -301,8 +345,19 @@ | ||
286 | pw.pw_dir = (char *)home; | ||
287 | pw.pw_shell = (char *)shell; | ||
288 | |||
289 | + if (usegroup) { | ||
290 | + /* Add user to a group that already exists */ | ||
291 | + struct group *g; | ||
292 | + | ||
293 | + g = getgrnam(usegroup); | ||
294 | + if (g == NULL) | ||
295 | + error_msg_and_die("group %s does not exist", usegroup); | ||
296 | + | ||
297 | + pw.pw_gid = g->gr_gid; | ||
298 | + } | ||
299 | + | ||
300 | /* grand finale */ | ||
301 | - return adduser(PASSWD_FILE, &pw); | ||
302 | + return adduser(PASSWD_FILE, &pw, makehome, setpass); | ||
303 | } | ||
304 | |||
305 | -/* $Id: adduser.c,v 1.37 2002/12/12 08:46:03 andersen Exp $ */ | ||
306 | +/* $Id: adduser.c,v 1.38 2003/06/21 19:35:42 andersen Exp $ */ | ||
307 | Index: install.sh | ||
308 | =================================================================== | ||
309 | RCS file: /var/cvs/tinylogin/install.sh,v | ||
310 | retrieving revision 1.10 | ||
311 | retrieving revision 1.11 | ||
312 | diff -u -r1.10 -r1.11 | ||
313 | --- a/install.sh 23 Jun 2002 03:09:07 -0000 1.10 | ||
314 | +++ b/install.sh 6 Mar 2003 19:29:17 -0000 1.11 | ||
315 | @@ -21,11 +21,11 @@ | ||
316 | h=`sort tinylogin.links | uniq` | ||
317 | |||
318 | |||
319 | -mkdir -p $prefix/bin || exit 1 | ||
320 | +install -d -m 0755 $prefix/bin || exit 1 | ||
321 | |||
322 | for i in $h ; do | ||
323 | appdir=`dirname $i` | ||
324 | - mkdir -p $prefix/$appdir || exit 1 | ||
325 | + install -d -m 0755 $prefix/$appdir || exit 1 | ||
326 | if [ "$2" = "--hardlinks" ]; then | ||
327 | bb_path="$prefix/bin/tinylogin" | ||
328 | else | ||
329 | Index: passwd.c | ||
330 | =================================================================== | ||
331 | RCS file: /var/cvs/tinylogin/passwd.c,v | ||
332 | retrieving revision 1.19 | ||
333 | retrieving revision 1.20 | ||
334 | diff -u -r1.19 -r1.20 | ||
335 | --- a/passwd.c 7 Nov 2002 02:34:15 -0000 1.19 | ||
336 | +++ b/passwd.c 17 Feb 2003 11:51:55 -0000 1.20 | ||
337 | @@ -25,10 +25,6 @@ | ||
338 | { | ||
339 | int x = 0; /* standart: DES */ | ||
340 | |||
341 | -#ifdef CONFIG_FEATURE_SHA1_PASSWORDS | ||
342 | - if (strcasecmp(a, "sha1") == 0) | ||
343 | - x = 2; | ||
344 | -#endif | ||
345 | if (strcasecmp(a, "md5") == 0) | ||
346 | x = 1; | ||
347 | return x; | ||
348 | @@ -394,11 +390,6 @@ | ||
349 | bzero(cp, strlen(cp)); | ||
350 | bzero(orig, sizeof(orig)); | ||
351 | |||
352 | -#ifdef CONFIG_FEATURE_SHA1_PASSWORDS | ||
353 | - if (algo == 2) { | ||
354 | - cp = pw_encrypt(pass, "$2$"); | ||
355 | - } else | ||
356 | -#endif | ||
357 | if (algo == 1) { | ||
358 | cp = pw_encrypt(pass, "$1$"); | ||
359 | } else | ||
360 | Index: sha1.c | ||
361 | =================================================================== | ||
362 | RCS file: sha1.c | ||
363 | diff -N sha1.c | ||
364 | --- a/sha1.c 20 Dec 2000 21:54:28 -0000 1.2 | ||
365 | +++ /dev/null 1 Jan 1970 00:00:00 -0000 | ||
366 | @@ -1,187 +0,0 @@ | ||
367 | -/* vi: set sw=4 ts=4: */ | ||
368 | -/* | ||
369 | - Implements the Secure Hash Algorithm (SHA1) | ||
370 | - | ||
371 | - Copyright (C) 1999 Scott G. Miller | ||
372 | - | ||
373 | - Released under the terms of the GNU General Public License v2 | ||
374 | - see file COPYING for details | ||
375 | - | ||
376 | - Credits: | ||
377 | - Robert Klep <robert@ilse.nl> -- Expansion function fix | ||
378 | - --- | ||
379 | - FIXME: This source takes int to be a 32 bit integer. This | ||
380 | - may vary from system to system. I'd use autoconf if I was familiar | ||
381 | - with it. Anyone want to help me out? | ||
382 | -*/ | ||
383 | - | ||
384 | -void sha_hash(int *, int *); | ||
385 | -void sha_init(int *); | ||
386 | -char *sprint_hash(int *); | ||
387 | -void do_sha_hash(int *, int *); | ||
388 | - | ||
389 | -/* | ||
390 | - added 3 functions for sha passowrd stuff (mainly inspired from stuff seen in main.c from shasum-1.3 package) | ||
391 | -*/ | ||
392 | -#include <stdio.h> | ||
393 | -#include <string.h> | ||
394 | -#include <stdlib.h> | ||
395 | - | ||
396 | -#include <endian.h> | ||
397 | -/* On big endian machines, we need to reverse the input to process | ||
398 | - the blocks correctly */ | ||
399 | - | ||
400 | -#define switch_endianness(x) (x<<24 & 0xff000000) | \ | ||
401 | - (x<<8 & 0x00ff0000) | \ | ||
402 | - (x>>8 & 0x0000ff00) | \ | ||
403 | - (x>>24 & 0x000000ff) | ||
404 | - | ||
405 | -/* Initial hash values */ | ||
406 | -#define Ai 0x67452301 | ||
407 | -#define Bi 0xefcdab89 | ||
408 | -#define Ci 0x98badcfe | ||
409 | -#define Di 0x10325476 | ||
410 | -#define Ei 0xc3d2e1f0 | ||
411 | - | ||
412 | -/* SHA1 round constants */ | ||
413 | -#define K1 0x5a827999 | ||
414 | -#define K2 0x6ed9eba1 | ||
415 | -#define K3 0x8f1bbcdc | ||
416 | -#define K4 0xca62c1d6 | ||
417 | - | ||
418 | -/* Round functions. Note that f2() is used in both rounds 2 and 4 */ | ||
419 | -#define f1(B,C,D) ((B & C) | ((~B) & D)) | ||
420 | -#define f2(B,C,D) (B ^ C ^ D) | ||
421 | -#define f3(B,C,D) ((B & C) | (B & D) | (C & D)) | ||
422 | - | ||
423 | -/* left circular shift functions (rotate left) */ | ||
424 | -#define rol1(x) ((x<<1) | ((x>>31) & 1)) | ||
425 | -#define rol5(A) ((A<<5) | ((A>>27) & 0x1f)) | ||
426 | -#define rol30(B) ((B<<30) | ((B>>2) & 0x3fffffff)) | ||
427 | - | ||
428 | -/* | ||
429 | - Hashes 'data', which should be a pointer to 512 bits of data (sixteen | ||
430 | - 32 bit ints), into the ongoing 160 bit hash value (five 32 bit ints) | ||
431 | - 'hash' | ||
432 | -*/ | ||
433 | -void sha_hash(int *data, int *hash) | ||
434 | -{ | ||
435 | - int W[80]; | ||
436 | - unsigned int A = hash[0], B = hash[1], C = hash[2], D = hash[3], E = | ||
437 | - hash[4]; | ||
438 | - unsigned int t, x, TEMP; | ||
439 | - | ||
440 | - for (t = 0; t < 16; t++) { | ||
441 | -#ifdef BIG_ENDIAN | ||
442 | - W[t] = switch_endianness(data[t]); | ||
443 | -#else | ||
444 | - W[t] = data[t]; | ||
445 | -#endif | ||
446 | - } | ||
447 | - | ||
448 | - | ||
449 | - /* SHA1 Data expansion */ | ||
450 | - for (t = 16; t < 80; t++) { | ||
451 | - x = W[t - 3] ^ W[t - 8] ^ W[t - 14] ^ W[t - 16]; | ||
452 | - W[t] = rol1(x); | ||
453 | - } | ||
454 | - | ||
455 | - /* SHA1 main loop (t=0 to 79) | ||
456 | - This is broken down into four subloops in order to use | ||
457 | - the correct round function and constant */ | ||
458 | - for (t = 0; t < 20; t++) { | ||
459 | - TEMP = rol5(A) + f1(B, C, D) + E + W[t] + K1; | ||
460 | - E = D; | ||
461 | - D = C; | ||
462 | - C = rol30(B); | ||
463 | - B = A; | ||
464 | - A = TEMP; | ||
465 | - } | ||
466 | - for (; t < 40; t++) { | ||
467 | - TEMP = rol5(A) + f2(B, C, D) + E + W[t] + K2; | ||
468 | - E = D; | ||
469 | - D = C; | ||
470 | - C = rol30(B); | ||
471 | - B = A; | ||
472 | - A = TEMP; | ||
473 | - } | ||
474 | - for (; t < 60; t++) { | ||
475 | - TEMP = rol5(A) + f3(B, C, D) + E + W[t] + K3; | ||
476 | - E = D; | ||
477 | - D = C; | ||
478 | - C = rol30(B); | ||
479 | - B = A; | ||
480 | - A = TEMP; | ||
481 | - } | ||
482 | - for (; t < 80; t++) { | ||
483 | - TEMP = rol5(A) + f2(B, C, D) + E + W[t] + K4; | ||
484 | - E = D; | ||
485 | - D = C; | ||
486 | - C = rol30(B); | ||
487 | - B = A; | ||
488 | - A = TEMP; | ||
489 | - } | ||
490 | - hash[0] += A; | ||
491 | - hash[1] += B; | ||
492 | - hash[2] += C; | ||
493 | - hash[3] += D; | ||
494 | - hash[4] += E; | ||
495 | -} | ||
496 | - | ||
497 | -/* | ||
498 | - Takes a pointer to a 160 bit block of data (five 32 bit ints) and | ||
499 | - intializes it to the start constants of the SHA1 algorithm. This | ||
500 | - must be called before using hash in the call to sha_hash | ||
501 | -*/ | ||
502 | -void sha_init(int *hash) | ||
503 | -{ | ||
504 | - hash[0] = Ai; | ||
505 | - hash[1] = Bi; | ||
506 | - hash[2] = Ci; | ||
507 | - hash[3] = Di; | ||
508 | - hash[4] = Ei; | ||
509 | -} | ||
510 | - | ||
511 | - | ||
512 | -/* | ||
513 | - * write the hash to a string | ||
514 | - */ | ||
515 | -char *sprint_sha1_hash(int *hashval) | ||
516 | -{ | ||
517 | - int x = 0; | ||
518 | - char *out = NULL; | ||
519 | - | ||
520 | - if ((out = malloc(43)) == NULL) | ||
521 | - return NULL; | ||
522 | - memset(out, 0x00, 43); | ||
523 | - strcpy(out, "$2$"); | ||
524 | - for (x = 0; x < 5; x++) { | ||
525 | - sprintf(out + (x * 8) + 3, "%08x", hashval[x]); | ||
526 | - } | ||
527 | - out[43] = 0; | ||
528 | - return out; | ||
529 | -} | ||
530 | - | ||
531 | - | ||
532 | -/* | ||
533 | - * hash the password | ||
534 | - */ | ||
535 | -void do_sha_hash(int *hashval, int *pw) | ||
536 | -{ | ||
537 | - sha_init(hashval); | ||
538 | - sha_hash(pw, hashval); | ||
539 | -} | ||
540 | - | ||
541 | - | ||
542 | -/* | ||
543 | - * hash a charakter string and return the 160bit integer in hex as a character string | ||
544 | - */ | ||
545 | -char *sha1_crypt(const char *pw) | ||
546 | -{ | ||
547 | - int hashval[20]; | ||
548 | - | ||
549 | - memset(hashval, 0x00, sizeof(hashval)); | ||
550 | - do_sha_hash(hashval, (int *) ((char *) pw + 3)); | ||
551 | - | ||
552 | - return sprint_sha1_hash(hashval); | ||
553 | -} | ||
554 | Index: vlock.c | ||
555 | =================================================================== | ||
556 | RCS file: /var/cvs/tinylogin/vlock.c,v | ||
557 | retrieving revision 1.13 | ||
558 | retrieving revision 1.14 | ||
559 | diff -u -r1.13 -r1.14 | ||
560 | --- a/vlock.c 19 Sep 2002 03:50:31 -0000 1.13 | ||
561 | +++ b/vlock.c 17 Feb 2003 11:51:56 -0000 1.14 | ||
562 | @@ -26,7 +26,7 @@ | ||
563 | * minimalistic vlock. | ||
564 | */ | ||
565 | /* Fixed by Erik Andersen to do passwords the tinylogin way... | ||
566 | - * It now works with md5, sha1, etc passwords. */ | ||
567 | + * It now works with md5, etc passwords. */ | ||
568 | |||
569 | #include "tinylogin.h" | ||
570 | #include <stdio.h> | ||
571 | Index: docs/tinylogin.busybox.net/index.html | ||
572 | =================================================================== | ||
573 | RCS file: /var/cvs/tinylogin/docs/tinylogin.busybox.net/index.html,v | ||
574 | retrieving revision 1.23 | ||
575 | retrieving revision 1.25 | ||
576 | diff -u -r1.23 -r1.25 | ||
577 | --- a/docs/tinylogin.busybox.net/index.html 3 Jan 2003 10:56:32 -0000 1.23 | ||
578 | +++ b/docs/tinylogin.busybox.net/index.html 3 Jan 2003 11:21:53 -0000 1.25 | ||
579 | @@ -56,6 +56,9 @@ | ||
580 | Erik Andersen</a>, and licensed under the | ||
581 | <a href="http://www.gnu.org/copyleft/gpl.html">GNU GENERAL PUBLIC LICENSE</a>. | ||
582 | |||
583 | +<h3>Mailing List Information</h3> | ||
584 | +Here are the Tinylogin <a href="/lists/tinylogin/">mailing list archives</a><br> | ||
585 | +To subscribe, go and visit <a href= "/mailman/listinfo/tinylogin">this page</a>. | ||
586 | |||
587 | <!-- Begin Download section --> | ||
588 | |||
589 | @@ -222,19 +225,19 @@ | ||
590 | <ul> | ||
591 | <li> <A HREF="http://freshmeat.net/projects/tinylogin/?highlight=tinylogin"> | ||
592 | Freshmeat AppIndex record for TinyLogin</A> | ||
593 | + <p> | ||
594 | |||
595 | <li><a href="http://www.busybox.net/">BusyBox</a> | ||
596 | combines tiny versions of many common UNIX utilities into a single small | ||
597 | executable. It provides minimalist replacements for most of the utilities | ||
598 | you usually find on a standard Linux system. | ||
599 | - | ||
600 | <p> | ||
601 | + | ||
602 | <li><a href="http://uclibc.org/uClibc.html">uClibc</a> | ||
603 | is a C library for embedded systems. You can actually statically link | ||
604 | a "Hello World" application under x86 that only takes 4k (as opposed to | ||
605 | 200k under GNU libc). It can do dynamic linking too and works nicely with | ||
606 | BusyBox to create very small embedded systems. | ||
607 | - | ||
608 | <p> | ||
609 | |||
610 | </ul> | ||
611 | Index: include/libbb.h | ||
612 | =================================================================== | ||
613 | RCS file: /var/cvs/tinylogin/include/libbb.h,v | ||
614 | retrieving revision 1.1 | ||
615 | retrieving revision 1.2 | ||
616 | diff -u -r1.1 -r1.2 | ||
617 | --- a/include/libbb.h 23 Jun 2002 03:09:10 -0000 1.1 | ||
618 | +++ b/include/libbb.h 17 Feb 2003 11:51:57 -0000 1.2 | ||
619 | @@ -39,9 +39,6 @@ | ||
620 | #ifdef CONFIG_FEATURE_SHADOWPASSWDS | ||
621 | #include "shadow_.h" | ||
622 | #endif | ||
623 | -#ifdef CONFIG_FEATURE_SHA1_PASSWORDS | ||
624 | -# include "sha1.h" | ||
625 | -#endif | ||
626 | |||
627 | #if (__GNU_LIBRARY__ < 5) && (!defined __dietlibc__) | ||
628 | /* libc5 doesn't define socklen_t */ | ||
629 | Index: include/sha1.h | ||
630 | =================================================================== | ||
631 | RCS file: include/sha1.h | ||
632 | diff -N include/sha1.h | ||
633 | --- a/include/sha1.h 23 Jun 2002 03:09:10 -0000 1.1 | ||
634 | +++ /dev/null 1 Jan 1970 00:00:00 -0000 | ||
635 | @@ -1,3 +0,0 @@ | ||
636 | -/* SHA1.H - header file for SHA1.C */ | ||
637 | - | ||
638 | -char *sha1_crypt(const char *pw); | ||
639 | Index: include/usage.h | ||
640 | =================================================================== | ||
641 | RCS file: /var/cvs/tinylogin/include/usage.h,v | ||
642 | retrieving revision 1.2 | ||
643 | retrieving revision 1.3 | ||
644 | diff -u -r1.2 -r1.3 | ||
645 | --- a/include/usage.h 3 Jul 2002 05:57:00 -0000 1.2 | ||
646 | +++ b/include/usage.h 17 Feb 2003 11:51:57 -0000 1.3 | ||
647 | @@ -33,11 +33,6 @@ | ||
648 | "\t-h\tName of the remote host for this login.\n" \ | ||
649 | "\t-p\tPreserve environment." | ||
650 | |||
651 | -#ifdef CONFIG_FEATURE_SHA1_PASSWORDS | ||
652 | - #define PASSWORD_ALG_TYPES(a) a | ||
653 | -#else | ||
654 | - #define PASSWORD_ALG_TYPES(a) | ||
655 | -#endif | ||
656 | #define passwd_trivial_usage \ | ||
657 | "[OPTION] [name]" | ||
658 | #define passwd_full_usage \ | ||
659 | @@ -46,7 +41,6 @@ | ||
660 | "Options:\n" \ | ||
661 | "\t-a\tDefine which algorithm shall be used for the password.\n" \ | ||
662 | "\t\t\t(Choices: des, md5" \ | ||
663 | - PASSWORD_ALG_TYPES(", sha1") \ | ||
664 | ")\n\t-d\tDelete the password for the specified user account.\n" \ | ||
665 | "\t-l\tLocks (disables) the specified user account.\n" \ | ||
666 | "\t-u\tUnlocks (re-enables) the specified user account." | ||
667 | Index: libbb/obscure.c | ||
668 | =================================================================== | ||
669 | RCS file: /var/cvs/tinylogin/libbb/obscure.c,v | ||
670 | retrieving revision 1.2 | ||
671 | retrieving revision 1.3 | ||
672 | diff -u -r1.2 -r1.3 | ||
673 | --- a/libbb/obscure.c 23 Jun 2002 04:05:59 -0000 1.2 | ||
674 | +++ b/libbb/obscure.c 30 Jul 2003 08:41:33 -0000 1.3 | ||
675 | @@ -44,7 +44,7 @@ | ||
676 | * can't be a palindrome - like `R A D A R' or `M A D A M' | ||
677 | */ | ||
678 | |||
679 | -static int palindrome(const char *old, const char *newval) | ||
680 | +static int palindrome(const char *newval) | ||
681 | { | ||
682 | int i, j; | ||
683 | |||
684 | @@ -79,24 +79,25 @@ | ||
685 | * a nice mix of characters. | ||
686 | */ | ||
687 | |||
688 | -static int simple(const char *old, const char *newval) | ||
689 | +static int simple(const char *newval) | ||
690 | { | ||
691 | int digits = 0; | ||
692 | int uppers = 0; | ||
693 | int lowers = 0; | ||
694 | int others = 0; | ||
695 | + int c; | ||
696 | int size; | ||
697 | int i; | ||
698 | |||
699 | - for (i = 0; newval[i]; i++) { | ||
700 | - if (isdigit(newval[i])) | ||
701 | - digits++; | ||
702 | - else if (isupper(newval[i])) | ||
703 | - uppers++; | ||
704 | - else if (islower(newval[i])) | ||
705 | - lowers++; | ||
706 | + for (i = 0; (c = *newval++) != 0; i++) { | ||
707 | + if (isdigit(c)) | ||
708 | + digits = c; | ||
709 | + else if (isupper(c)) | ||
710 | + uppers = c; | ||
711 | + else if (islower(c)) | ||
712 | + lowers = c; | ||
713 | else | ||
714 | - others++; | ||
715 | + others = c; | ||
716 | } | ||
717 | |||
718 | /* | ||
719 | @@ -129,49 +130,53 @@ | ||
720 | return string; | ||
721 | } | ||
722 | |||
723 | -static char *password_check(const char *old, const char *newval, const struct passwd *pwdp) | ||
724 | +static const char * | ||
725 | +password_check(const char *old, const char *newval, const struct passwd *pwdp) | ||
726 | { | ||
727 | - char *msg = NULL; | ||
728 | - char *oldmono, *newmono, *wrapped; | ||
729 | + const char *msg; | ||
730 | + char *newmono, *wrapped; | ||
731 | + int lenwrap; | ||
732 | |||
733 | if (strcmp(newval, old) == 0) | ||
734 | return "no change"; | ||
735 | + if (simple(newval)) | ||
736 | + return "too simple"; | ||
737 | |||
738 | + msg = NULL; | ||
739 | newmono = str_lower(xstrdup(newval)); | ||
740 | - oldmono = str_lower(xstrdup(old)); | ||
741 | - wrapped = (char *) xmalloc(strlen(oldmono) * 2 + 1); | ||
742 | - strcpy(wrapped, oldmono); | ||
743 | - strcat(wrapped, oldmono); | ||
744 | + lenwrap = strlen(old) * 2 + 1; | ||
745 | + wrapped = (char *) xmalloc(lenwrap); | ||
746 | + str_lower(strcpy(wrapped, old)); | ||
747 | |||
748 | - if (palindrome(oldmono, newmono)) | ||
749 | + if (palindrome(newmono)) | ||
750 | msg = "a palindrome"; | ||
751 | |||
752 | - if (!msg && strcmp(oldmono, newmono) == 0) | ||
753 | + else if (strcmp(wrapped, newmono) == 0) | ||
754 | msg = "case changes only"; | ||
755 | |||
756 | - if (!msg && similiar(oldmono, newmono)) | ||
757 | + else if (similiar(wrapped, newmono)) | ||
758 | msg = "too similiar"; | ||
759 | |||
760 | - if (!msg && simple(old, newval)) | ||
761 | - msg = "too simple"; | ||
762 | - | ||
763 | - if (!msg && strstr(wrapped, newmono)) | ||
764 | - msg = "rotated"; | ||
765 | + else { | ||
766 | + safe_strncpy(wrapped + lenwrap, wrapped, lenwrap + 1); | ||
767 | + if (strstr(wrapped, newmono)) | ||
768 | + msg = "rotated"; | ||
769 | + } | ||
770 | |||
771 | bzero(newmono, strlen(newmono)); | ||
772 | - bzero(oldmono, strlen(oldmono)); | ||
773 | - bzero(wrapped, strlen(wrapped)); | ||
774 | + bzero(wrapped, lenwrap); | ||
775 | free(newmono); | ||
776 | - free(oldmono); | ||
777 | free(wrapped); | ||
778 | |||
779 | return msg; | ||
780 | } | ||
781 | |||
782 | -static char *obscure_msg(const char *old, const char *newval, const struct passwd *pwdp) | ||
783 | +static const char * | ||
784 | +obscure_msg(const char *old, const char *newval, const struct passwd *pwdp) | ||
785 | { | ||
786 | int maxlen, oldlen, newlen; | ||
787 | - char *new1, *old1, *msg; | ||
788 | + char *new1, *old1; | ||
789 | + const char *msg; | ||
790 | |||
791 | oldlen = strlen(old); | ||
792 | newlen = strlen(newval); | ||
793 | @@ -233,7 +238,7 @@ | ||
794 | |||
795 | extern int obscure(const char *old, const char *newval, const struct passwd *pwdp) | ||
796 | { | ||
797 | - char *msg = obscure_msg(old, newval, pwdp); | ||
798 | + const char *msg = obscure_msg(old, newval, pwdp); | ||
799 | |||
800 | /* if (msg) { */ | ||
801 | if (msg != NULL) { | ||
802 | Index: libbb/pw_encrypt.c | ||
803 | =================================================================== | ||
804 | RCS file: /var/cvs/tinylogin/libbb/pw_encrypt.c,v | ||
805 | retrieving revision 1.1 | ||
806 | retrieving revision 1.2 | ||
807 | diff -u -r1.1 -r1.2 | ||
808 | --- a/libbb/pw_encrypt.c 23 Jun 2002 03:09:12 -0000 1.1 | ||
809 | +++ b/libbb/pw_encrypt.c 17 Feb 2003 11:51:58 -0000 1.2 | ||
810 | @@ -30,11 +30,6 @@ | ||
811 | static char cipher[128]; | ||
812 | char *cp; | ||
813 | |||
814 | -#ifdef CONFIG_FEATURE_SHA1_PASSWORDS | ||
815 | - if (strncmp(salt, "$2$", 3) == 0) { | ||
816 | - return sha1_crypt(clear); | ||
817 | - } | ||
818 | -#endif | ||
819 | cp = (char *) crypt(clear, salt); | ||
820 | /* if crypt (a nonstandard crypt) returns a string too large, | ||
821 | truncate it so we don't overrun buffers and hope there is | ||
diff --git a/openembedded/packages/tinylogin/tinylogin_1.4.bb b/openembedded/packages/tinylogin/tinylogin_1.4.bb new file mode 100644 index 0000000000..33f1c32aed --- /dev/null +++ b/openembedded/packages/tinylogin/tinylogin_1.4.bb | |||
@@ -0,0 +1,28 @@ | |||
1 | SECTION = "base" | ||
2 | DESCRIPTION = "TinyLogin is a suite of tiny UNIX \ | ||
3 | utilities for handling logins, user authentication, \ | ||
4 | changing passwords, and otherwise maintaining users \ | ||
5 | and groups on an embedded system." | ||
6 | HOMEPAGE = "http://tinylogin.busybox.net/" | ||
7 | LICENSE = "GPL" | ||
8 | PR = "r3" | ||
9 | |||
10 | SRC_URI = "http://tinylogin.busybox.net/downloads/tinylogin-${PV}.tar.bz2 \ | ||
11 | file://cvs-20040608.patch;patch=1;pnum=1 \ | ||
12 | file://add-system.patch;patch=1;pnum=1 \ | ||
13 | file://adduser-empty_pwd.patch;patch=1" | ||
14 | |||
15 | EXTRA_OEMAKE = "" | ||
16 | |||
17 | do_compile () { | ||
18 | oe_runmake 'CC=${CC}' 'CROSS=${HOST_PREFIX}' | ||
19 | } | ||
20 | |||
21 | do_install () { | ||
22 | install -d ${D}${base_bindir} | ||
23 | install -m 4755 tinylogin ${D}${base_bindir}/tinylogin | ||
24 | for i in `cat tinylogin.links`; do | ||
25 | mkdir -p ${D}/`dirname $i` | ||
26 | ln -sf /bin/tinylogin ${D}$i | ||
27 | done | ||
28 | } | ||