1 /* $Id: passwd.c,v 1.1 2005-07-30 13:00:15 bjk Exp $ */
3 Copyright (C) 2001-2005 Ben Kibbey <bjk@arbornet.org>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 #include <sys/types.h>
42 void ui_module_init(int *chainable
)
45 fprintf(stderr
, "%s: ui_module_init()\n", __FILE__
);
49 * Keep the password file open if possible (*BSD).
51 #ifdef HAVE_SETPASSENT
65 fprintf(stderr
, "%s: ui_module_exit()\n", __FILE__
);
78 /* See if the gecos options are valid. */
79 static int parse_gecos_options(const char *args
)
83 for (i
= 0; i
< strlen(args
); i
++) {
99 /* Break up the gecos string into sections and add the sections to the output
100 * string array if needed. */
101 static void gecos_strings(char *str
)
105 const char *name
, *first
, *second
, *third
;
107 name
= first
= second
= third
= "-";
109 while ((buf
= strsep(&str
, ",")) != NULL
) {
131 for (i
= 0; i
< strlen(gecos_options
); i
++) {
132 switch (gecos_options
[i
]) {
134 add_string(&strings
, name
);
137 add_string(&strings
, first
);
140 add_string(&strings
, second
);
143 add_string(&strings
, third
);
146 add_string(&strings
, name
);
147 add_string(&strings
, first
);
148 add_string(&strings
, second
);
149 add_string(&strings
, third
);
159 /* Get all groups that a user is a member of. The primary group will be the
161 static void groups(const struct passwd
*pw
, const int multi
,
171 if ((grp
= getgrgid(pw
->pw_gid
)) == NULL
) {
172 snprintf(tmp
, sizeof(tmp
), "%li%s%s%s", (long) pw
->pw_gid
,
173 (verbose
) ? "(" : "", (verbose
) ? "!" : "",
174 (verbose
) ? ")" : "");
175 add_string(&strings
, tmp
);
179 primary
= grp
->gr_gid
;
180 snprintf(tmp
, sizeof(tmp
), "%li%s%s%s%c", (long) pw
->pw_gid
,
181 (verbose
) ? "(" : "", (verbose
) ? grp
->gr_name
: "",
182 (verbose
) ? ")" : "", multi
);
183 strncat(line
, tmp
, sizeof(line
));
185 #ifdef HAVE_SETGROUPENT
191 while ((grp
= getgrent()) != NULL
) {
192 char **members
= grp
->gr_mem
;
195 if (strcmp(*members
++, pw
->pw_name
) == 0) {
196 if (grp
->gr_gid
== primary
)
199 snprintf(tmp
, sizeof(tmp
), "%li%s%s%s%c", (long) grp
->gr_gid
,
200 (verbose
) ? "(" : "", (verbose
) ? grp
->gr_name
: "",
201 (verbose
) ? ")" : "", multi
);
202 strncat(line
, tmp
, sizeof(line
));
208 * Trim the remaining multi-string deliminator.
210 line
[strlen(line
) - 1] = '\0';
212 add_string(&strings
, line
);
216 /* This is output if the -h command line option is passed to the main program.
218 void ui_module_help()
221 fprintf(stderr
, "%s: ui_module_help()\n", __FILE__
);
224 printf(" Password/Group file information [-P (-%s)]:\n",
225 PASSWD_OPTION_ORDER
);
226 printf("\t-l login name\t\t");
227 printf("\t-p encrypted password\n");
228 printf("\t-u user id (uid)\t");
229 printf("\t-g group id (gid)\n");
230 printf("\t-c password change time");
231 printf("\t-e password expire time\n");
232 printf("\t-d home directory\t");
233 printf("\t-m home directory mode\n");
234 printf("\t-s login shell\n");
235 printf("\t-i gecos (any of [n]ame,[1]st,[2]nd,[3]rd or [a]ll)\n\n");
239 /* This is the equivalent to main() only without argc and argv available. */
240 int ui_module_exec(char ***s
, const struct passwd
*pw
, const int multi_char
,
241 const int verbose
, char *tf
)
247 struct spwd
*spwd
= NULL
;
251 fprintf(stderr
, "%s: ui_module_exec()\n", __FILE__
);
256 if ((spwd
= getspnam(pw
->pw_name
)) == NULL
)
257 warnx("%s", "getspnam(): unknown error");
270 add_string(&strings
, "!");
274 snprintf(tmp
, sizeof(tmp
), "%li", (long) spwd
->sp_max
);
275 add_string(&strings
, tmp
);
279 add_string(&strings
, "!");
283 snprintf(tmp
, sizeof(tmp
), "%li", (long) spwd
->sp_expire
);
284 add_string(&strings
, tmp
);
288 snprintf(tmp
, sizeof(tmp
), "%li", (long) pw
->pw_change
);
289 add_string(&strings
, tmp
);
292 snprintf(tmp
, sizeof(tmp
), "%li", (long) pw
->pw_expire
);
293 add_string(&strings
, tmp
);
297 add_string(&strings
, pw
->pw_name
);
300 add_string(&strings
, (pw
->pw_dir
&& pw
->pw_dir
[0]) ? pw
->pw_dir
: "-");
303 add_string(&strings
, (pw
->pw_shell
&& pw
->pw_shell
[0]) ? pw
->pw_shell
: "-");
308 add_string(&strings
, (pw
->pw_passwd
309 && pw
->pw_passwd
[0]) ? pw
->pw_passwd
: "-");
311 add_string(&strings
, (spwd
->sp_pwdp
312 && spwd
->sp_pwdp
[0]) ? spwd
->sp_pwdp
: "-");
314 add_string(&strings
, (pw
->pw_passwd
315 && pw
->pw_passwd
[0]) ? pw
->pw_passwd
: "-");
319 sprintf(tmp
, "%li", (long) pw
->pw_uid
);
320 add_string(&strings
, tmp
);
323 groups(pw
, multi_char
, verbose
);
326 if (stat(pw
->pw_dir
, &st
) == -1) {
327 add_string(&strings
, "!");
331 sprintf(tmp
, "%.4o", (unsigned) st
.st_mode
& ALLPERMS
);
332 add_string(&strings
, tmp
);
335 gecos_strings(pw
->pw_gecos
);
348 char *ui_module_options_init(char **defaults
)
351 return PASSWD_OPTION_STRING
;
354 /* Check module option validity. */
355 int ui_module_options(int argc
, char **argv
)
361 fprintf(stderr
, "%s: ui_module_options()\n", __FILE__
);
364 while ((opt
= getopt(argc
, argv
, PASSWD_OPTION_STRING
)) != -1) {
367 gecos_options
= optarg
;
381 warnx("passwd: invalid option -- %c", optopt
);
387 if (parse_gecos_options(gecos_options
))
392 * This option '-P' sets all available options for this module.
395 strncpy(options
, PASSWD_OPTION_ORDER
, sizeof(options
));