aboutsummaryrefslogtreecommitdiff
path: root/ident/system.c
diff options
context:
space:
mode:
Diffstat (limited to 'ident/system.c')
-rw-r--r--ident/system.c137
1 files changed, 137 insertions, 0 deletions
diff --git a/ident/system.c b/ident/system.c
new file mode 100644
index 0000000..bde667c
--- /dev/null
+++ b/ident/system.c
@@ -0,0 +1,137 @@
+/* This file is part of GNU Pies.
+ Copyright (C) 2015 Sergey Poznyakoff
+
+ GNU Pies is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ GNU Pies 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 General Public License
+ along with GNU Pies. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "ident.h"
+#include <sys/types.h>
+#include <pwd.h>
+#include <grp.h>
+#include <unistd.h>
+#include <string.h>
+#include <time.h>
+#if defined(HAVE_CRYPT_H)
+# include <crypt.h>
+#endif
+#if defined(HAVE_SHADOW_H)
+# include <shadow.h>
+#endif
+
+struct system_identity_data
+{
+ gid_t gid;
+};
+
+static int
+system_authenticate (pies_identity_provider_t pr, pies_identity_t id,
+ char const *passwd)
+{
+ struct passwd *pwd;
+ char *encrypted_pass = NULL;
+
+ pwd = getpwnam (id->username);
+ if (!pwd)
+ return -1;
+
+ encrypted_pass = pwd->pw_passwd;
+
+#if defined(HAVE_SHADOW_H)
+ {
+ struct spwd *sp;
+ if ((sp = getspnam (id->username)) != NULL)
+ {
+ if (sp->sp_expire > 0 && time (NULL) > sp->sp_expire * 86400)
+ return -1;
+ encrypted_pass = sp->sp_pwdp;
+ }
+ }
+#endif
+
+ if (strcmp (crypt (passwd, encrypted_pass), encrypted_pass) == 0)
+ {
+ struct system_identity_data *data = xmalloc (sizeof (*data));
+ data->gid = pwd->pw_gid;
+ id->data = data;
+ return 0;
+ }
+ return -1;
+}
+
+static int
+system_is_group_member (pies_identity_provider_t provider,
+ pies_identity_t id, char * const * groups)
+{
+ struct system_identity_data *data = id->data;
+ struct group *gr;
+ int result = 0;
+
+ setgrent ();
+ while ((gr = getgrent ()))
+ {
+ char **p;
+
+ if (!is_array_member (groups, gr->gr_name))
+ continue;
+
+ if (gr->gr_gid == data->gid)
+ {
+ result = 1;
+ break;
+ }
+
+ for (p = gr->gr_mem; *p; p++)
+ if (strcmp (*p, id->username) == 0)
+ {
+ result = 1;
+ break;
+ }
+ }
+ endgrent ();
+ return result;
+}
+
+static void
+system_destroy_identity (pies_identity_provider_t p, pies_identity_t id)
+{
+ if (id->data)
+ free (id->data);
+}
+
+static void
+confhelp (void)
+{
+ static struct grecs_keyword kw[] = {
+ { "type", "'system", "Set mechanism type", grecs_type_null },
+ { NULL }
+ };
+
+ static struct grecs_keyword top[] = {
+ { "identity-provider", "name: string",
+ "Configuration for system identity provider",
+ grecs_type_section, GRECS_INAC, NULL, 0, NULL, NULL,
+ kw },
+ { NULL }
+ };
+ grecs_print_statement_array (top, 1, 0, stdout);
+}
+
+struct pies_identity_mechanism system_identity_mechanism = {
+ "system",
+ system_authenticate,
+ system_is_group_member,
+ system_destroy_identity,
+ NULL,
+ confhelp
+};
+

Return to:

Send suggestions and report system problems to the System administrator.