/
githubmirror
/
libuser
Обзор
Документация
Войти
/
githubmirror
/
libuser
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
libuser-0.57
apps/lchage.c
267 строк
8 KB
Miloslav Trmač
2009-06-23 Miloslav Trmač <mitr@redhat.com>
23 июн 2009, 18:19
23 июн 2009, 18:19
d461b6b
Код
Авторство
О чём код?
/* * Copyright (C) 2000-2002, 2004 Red Hat, Inc. * * This is free software; you can redistribute it and/or modify it under * the terms of the GNU Library 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 Library General Public * License along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include <config.h> #include <sys/time.h> #include <errno.h> #include <limits.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <libintl.h> #include <locale.h> #include <popt.h> #include <glib.h> #include "../lib/user.h" #include "apputil.h" #define INVALID_LONG LONG_MIN /* Parse the first element of a (non-NULL, non-empty) value array for a count * of days in G_TYPE_LONG, and return the value. If the array is invalid, * return the default of -1. */ static glong read_ndays(GValueArray *array) { GValue *value; value = g_value_array_get_nth(array, 0); if (value != NULL) { g_assert(G_VALUE_HOLDS_LONG(value)); return g_value_get_long(value); } else return -1; } /* Format a count of days into a string that's intelligible to a user. */ static void date_to_string(glong n_days, char *buf, size_t len) { if ((n_days >= 0) && (n_days < 99999)) { GDate *date; date = g_date_new_dmy(1, G_DATE_JANUARY, 1970); g_date_add_days(date, n_days); g_date_strftime(buf, len, "%x", date); g_date_free(date); } } int main(int argc, const char **argv) { long shadowMin = INVALID_LONG, shadowMax = INVALID_LONG, shadowLastChange = INVALID_LONG, shadowInactive = INVALID_LONG, shadowExpire = INVALID_LONG, shadowWarning = INVALID_LONG; const char *user; struct lu_context *ctx; struct lu_ent *ent; struct lu_error *error = NULL; int interactive = FALSE; int list_only = FALSE; int c; poptContext popt; struct poptOption options[] = { {"interactive", 'i', POPT_ARG_NONE, &interactive, 0, "prompt for all information", NULL}, {"list", 'l', POPT_ARG_NONE, &list_only, 0, "list aging parameters for the user", NULL}, {"mindays", 'm', POPT_ARG_LONG, &shadowMin, 0, "minimum days between password changes", "NUM"}, {"maxdays", 'M', POPT_ARG_LONG, &shadowMax, 0, "maximum days between password changes", "NUM"}, {"date", 'd', POPT_ARG_LONG, &shadowLastChange, 0, "date of last password change, relative to days since " "1/1/70", "NUM"}, {"inactive", 'I', POPT_ARG_LONG, &shadowInactive, 0, "number of days after expiration date when account " "is considered inactive", "NUM"}, {"expire", 'E', POPT_ARG_LONG, &shadowExpire, 0, "password expiration date", "NUM"}, {"warndays", 'W', POPT_ARG_LONG, &shadowWarning, 0, "days before expiration to begin warning user", "NUM"}, POPT_AUTOHELP POPT_TABLEEND }; /* Set up i18n. */ bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); setlocale(LC_ALL, ""); /* Parse arguments. */ popt = poptGetContext("lchage", argc, argv, options, 0); poptSetOtherOptionHelp(popt, _("[OPTION...] user")); c = poptGetNextOpt(popt); if (c != -1) { fprintf(stderr, _("Error parsing arguments: %s.\n"), poptStrerror(c)); poptPrintUsage(popt, stderr, 0); exit(1); } user = poptGetArg(popt); /* We need exactly one argument, and that's the user's name. */ if (user == NULL) { fprintf(stderr, _("No user name specified.\n")); poptPrintUsage(popt, stderr, 0); return 1; } /* Start up the library. */ ctx = lu_start(user, lu_user, NULL, NULL, interactive ? lu_prompt_console : lu_prompt_console_quiet, NULL, &error); if (ctx == NULL) { fprintf(stderr, _("Error initializing %s: %s.\n"), PACKAGE, lu_strerror(error)); return 1; } ent = lu_ent_new(); /* Look up information about the user. */ if (lu_user_lookup_name(ctx, user, ent, &error) == FALSE) { fprintf(stderr, _("User %s does not exist.\n"), user); return 2; } if (list_only) { char buf[LINE_MAX]; GValueArray *values, *values2, *values3; /* Just print out what we can find out, in a format similar * to the chage(1) utility from the shadow suite. */ if (lu_user_islocked(ctx, ent, &error)) { printf(_("Account is locked.\n")); } else { printf(_("Account is not locked.\n")); } values = lu_ent_get(ent, LU_SHADOWMIN); if (values != NULL) printf(_("Minimum:\t%ld\n"), read_ndays(values)); values = lu_ent_get(ent, LU_SHADOWMAX); if (values != NULL) printf(_("Maximum:\t%ld\n"), read_ndays(values)); values = lu_ent_get(ent, LU_SHADOWWARNING); if (values != NULL) printf(_("Warning:\t%ld\n"), read_ndays(values)); values = lu_ent_get(ent, LU_SHADOWINACTIVE); if (values != NULL) printf(_("Inactive:\t%ld\n"), read_ndays(values)); values = lu_ent_get(ent, LU_SHADOWLASTCHANGE); if (values != NULL) { strcpy(buf, _("Never")); date_to_string(read_ndays(values), buf, sizeof(buf)); printf(_("Last Change:\t%s\n"), buf); } values2 = lu_ent_get(ent, LU_SHADOWMAX); if (values != NULL && values2 != NULL) { strcpy(buf, _("Never")); date_to_string(read_ndays(values) + read_ndays(values2), buf, sizeof(buf)); printf(_("Password Expires:\t%s\n"), buf); } values3 = lu_ent_get(ent, LU_SHADOWINACTIVE); if (values != NULL && values2 != NULL && values3 != NULL) { strcpy(buf, _("Never")); date_to_string(read_ndays(values) + read_ndays(values2) + read_ndays(values3), buf, sizeof(buf)); printf(_("Password Inactive:\t%s\n"), buf); } values = lu_ent_get(ent, LU_SHADOWEXPIRE); if (values != NULL) { strcpy(buf, _("Never")); date_to_string(read_ndays(values), buf, sizeof(buf)); printf(_("Account Expires:\t%s\n"), buf); } } else { GValue value; /* Set values using parameters given on the command-line. */ memset(&value, 0, sizeof(value)); g_value_init(&value, G_TYPE_LONG); if (shadowLastChange != INVALID_LONG) { g_value_set_long(&value, shadowLastChange); lu_ent_clear(ent, LU_SHADOWLASTCHANGE); lu_ent_add(ent, LU_SHADOWLASTCHANGE, &value); g_value_reset(&value); } if (shadowMin != INVALID_LONG) { g_value_set_long(&value, shadowMin); lu_ent_clear(ent, LU_SHADOWMIN); lu_ent_add(ent, LU_SHADOWMIN, &value); g_value_reset(&value); } if (shadowMax != INVALID_LONG) { g_value_set_long(&value, shadowMax); lu_ent_clear(ent, LU_SHADOWMAX); lu_ent_add(ent, LU_SHADOWMAX, &value); g_value_reset(&value); } if (shadowWarning != INVALID_LONG) { g_value_set_long(&value, shadowWarning); lu_ent_clear(ent, LU_SHADOWWARNING); lu_ent_add(ent, LU_SHADOWWARNING, &value); g_value_reset(&value); } if (shadowInactive != INVALID_LONG) { g_value_set_long(&value, shadowInactive); lu_ent_clear(ent, LU_SHADOWINACTIVE); lu_ent_add(ent, LU_SHADOWINACTIVE, &value); g_value_reset(&value); } if (shadowExpire != INVALID_LONG) { g_value_set_long(&value, shadowExpire); lu_ent_clear(ent, LU_SHADOWEXPIRE); lu_ent_add(ent, LU_SHADOWEXPIRE, &value); g_value_reset(&value); } g_value_unset(&value); /* Now actually modify the user's data in the system * information store. */ if (lu_user_modify(ctx, ent, &error) == FALSE) { fprintf(stderr, _("Failed to modify aging information for %s: " "%s\n"), user, lu_strerror(error)); return 3; } lu_nscd_flush_cache("passwd"); } lu_ent_free(ent); lu_end(ctx); return 0; }