PAM-IPMI module - stores special users password
Special group('ipmi') user's passwords are stored
by pam_ipmicheck and pam_ipmisave module.
pam_ipmicheck will check password restrictions
for the special group user and pam_ipmisave
will update the password in special password
file in encrypted form.
Note: These modules still needs pam_unix support
to store the hashed password and work along
with pam_unix in stacked module concept
Change-Id: Id959107cae1819ff622e5993cd276075bcb92d2a
Signed-off-by: Richard Marian Thomaiyar <richard.marian.thomaiyar@linux.intel.com>
diff --git a/src/pam_ipmicheck/pam_ipmicheck.c b/src/pam_ipmicheck/pam_ipmicheck.c
new file mode 100644
index 0000000..41b3abf
--- /dev/null
+++ b/src/pam_ipmicheck/pam_ipmicheck.c
@@ -0,0 +1,124 @@
+/*
+// Copyright (c) 2018 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+*/
+
+#include <syslog.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+
+#include <security/pam_ext.h>
+#include <security/pam_modules.h>
+#include <security/pam_modutil.h>
+
+#define MAX_SPEC_GRP_PASS_LENGTH 20
+#define MAX_SPEC_GRP_USER_LENGTH 16
+
+
+/*
+ * This module is intended to verify special group user password matches the
+ * restrictions needed.
+ *
+ * Note: Other than for pam_chauthtok(), pam_ipmicheck module should not be
+ * used for other purpose like authentication, session & account management.
+ * This module has to be used along with pam_ipmisave module, which will save
+ * the passwords of the special group users.
+ */
+
+
+static const char *get_option(const pam_handle_t *pamh, const char *option,
+ int argc, const char **argv)
+{
+ int i = 0;
+ size_t len = strlen(option);
+
+ for (i = 0; i < argc; ++i) {
+ if (strncmp(option, argv[i], len) == 0) {
+ if (argv[i][len] == '=') {
+ return &argv[i][len + 1];
+ }
+ }
+ }
+ return NULL;
+}
+
+/* Password Management API's */
+
+int pam_sm_chauthtok(pam_handle_t *pamh, int flags, int argc, const char **argv)
+{
+ int retval = -1;
+ const void *item = NULL;
+ const char *user = NULL;
+ const char *pass_new = NULL, *pass_old = NULL;
+ const char *spec_grp_name =
+ get_option(pamh, "spec_grp_name", argc, argv);
+
+ pam_syslog(pamh, LOG_DEBUG, "Special group name is %s", spec_grp_name);
+
+ if (spec_grp_name == NULL) {
+ return PAM_IGNORE;
+ }
+ if (flags & PAM_PRELIM_CHECK) {
+ // send success to verify other stacked modules prelim check.
+ pam_syslog(pamh, LOG_DEBUG, "PRELIM_CHECK Called");
+ return PAM_SUCCESS;
+ }
+
+ // Read new password.
+ // Note: Subsequent modules must use stacked password option use_authtok
+ retval = pam_get_authtok(pamh, PAM_AUTHTOK, &pass_new, NULL);
+ if (retval != PAM_SUCCESS) {
+ pam_syslog(pamh, LOG_ERR,
+ "password - unable to get new password");
+ return retval;
+ }
+
+ retval = pam_get_user(pamh, &user, NULL);
+ if (retval != PAM_SUCCESS) {
+ return retval;
+ }
+
+ struct group *grp;
+ int spec_grp_usr = 0;
+ // Verify whether the user belongs to special group.
+ grp = pam_modutil_getgrnam(pamh, spec_grp_name);
+ if (grp != NULL) {
+ while (*(grp->gr_mem) != NULL) {
+ if (strcmp(user, *grp->gr_mem) == 0) {
+ spec_grp_usr = 1;
+ break;
+ }
+ (grp->gr_mem)++;
+ }
+ }
+
+ if (spec_grp_usr) {
+ // verify the new password is acceptable.
+ if (strlen(pass_new) > MAX_SPEC_GRP_PASS_LENGTH
+ || strlen(user) > MAX_SPEC_GRP_USER_LENGTH) {
+ pam_syslog(
+ pamh, LOG_ERR,
+ "Password length (%x) / User name length (%x) not acceptable",
+ strlen(pass_new), strlen(user));
+ pass_new = pass_old = NULL;
+ return PAM_NEW_AUTHTOK_REQD;
+ }
+ }
+
+ return PAM_SUCCESS;
+}
+
+/* end of module definition */