Changing Passwords Source File
Submitted by Daryle on Thu, 05/17/2012 - 15:53
Filename: | cs_password.c |
Project Name: | Pluggable Authentication Module (PAM) |
Language: | C |
Description: | |
Code:
/************************************************************ ** Library functions to interact with the Linux-PAM ** ** modules in order to update a user's password on ** ** the system. ** ** ** ** Make sure you add the following lines to the ** ** pam.conf file (ore equivalent): ** ** cs_password auth required ** ** /lib/security/pam_unix_auth.so ** ** cs_password account required ** ** /lib/security/pam_unix_acct.so ** ** cs_password password required ** ** /lib/security/pam_unix_passwd.so ** ** cs_password session required ** ** /lib/security/pam_unix_acct.so ** ** ** ** Author: Daryle Niedermayer (dpn) ** ** daryle@niedermayer.ca ** ** Date: 2002-06-17 ** ** ** ** $Id: cs_password.c,v 1.2 2002/06/20 19:51:24 root Exp root $ ** $Log: cs_password.c,v $ ** Revision 1.2 2002/06/20 19:51:24 root ** Fully documented and debugged test of how to change a password. ** ** Revision 1.1 2002/06/19 16:26:19 root ** Initial revision **: ************************************************************/ #include <stdio.h> #include <stdlib.h> #include <security/pam_appl.h> #include <security/pam_misc.h> #include <crack.h> #define CS_WEAK_PASSWORD -3 #define CS_BAD_DATA -2 #define CS_BAD_USAGE -1 #define CS_SUCCESS 0 #define COPY_STRING(s) (s) ? strdup(s) : NULL /* DEFINE STATIC EXTERNAL STRUCTURES AND VARIABLES SO THAT THEY ONLY HAVE SCOPE WITHIN THE METHODS AND FUNCTIONS OF THIS SOURCE FILE */ static char* service_name = "cs_password"; static char* user; static char* old_password; static char* new_password; static int PAM_conv (int, const struct pam_message**, struct pam_response**, void*); static struct pam_conv PAM_converse = {PAM_conv, NULL}; /************************************************* ** PAM Conversation function ** *************************************************/ static int PAM_conv (int num_msg, const struct pam_message **msg, struct pam_response **resp, void *appdata_ptr) { int replies = 0; struct pam_response *reply = NULL; reply = malloc(sizeof(struct pam_response) * num_msg); if (!reply) return PAM_CONV_ERR; for (replies = 0; replies < num_msg; replies++) { printf("***Message from PAM is: |%s|\n", msg[replies]->msg); printf("***Msg_style to PAM is: |%d|\n", msg[replies]->msg_style); if (! strcmp(msg[replies]->msg,"Password: ")) { printf("***Sending old password\n"); reply[replies].resp = COPY_STRING(old_password); } if (! strcmp(msg[replies]->msg,"Enter new UNIX password: ")) { printf("***Sending new password\n"); reply[replies].resp = COPY_STRING(new_password); } if (! strcmp(msg[replies]->msg,"Retype new UNIX password: ")) { printf("***Sending new password again\n"); reply[replies].resp = COPY_STRING(new_password); } printf("***Response to PAM is: |%s|\n", reply[replies].resp); } *resp = reply; return PAM_SUCCESS; } /************************************************* ** MAIN PROCEDURE ** *************************************************/ int main(int argc, char *argv[]) { /* DEFINITIONS */ pam_handle_t* pamh = NULL; int retval; char* pw_check; char* dict_path = "/usr/lib/cracklib_dict"; /* DETERMINE IF VARIABLE COUNT IS CORRECT */ if (argc != 4) { printf("Usage: pam_passwd <USER> <OLD_PASSWORD> <NEW_PASSWORD>\n"); exit (CS_BAD_USAGE); } /* PARSE PARAMETERS FROM INPUTS */ user = argv[1]; old_password = argv[2]; new_password = argv[3]; if (!(user && old_password && strlen(user) && strlen(old_password))) { printf("Incorrect/invalid username or old password"); exit (CS_BAD_DATA); } /* SEE IF THE NEW PASSWORD IS SUITABLY TOUGH */ /* This should be preprocessed outside of this function. */ printf("Testing for weak passwords...\n"); pw_check = FascistCheck(new_password, dict_path); if (pw_check != NULL) { printf("***Weak Password!: |%s|\n",pw_check); exit(CS_WEAK_PASSWORD); } /* GET A HANDLE TO A PAM INSTANCE */ printf("Trying to get a handle to the PAM service...\n"); retval = pam_start(service_name, user, &PAM_converse, &pamh); /* IS THE USER REALLY A USER? */ if (retval == PAM_SUCCESS) { printf("...Service handle was created.\n"); printf("Trying to see if the user is a valid system user...\n"); retval = pam_authenticate(pamh, 0); } else { printf("...Call to create service handle failed with error: %d\n",retval); } /* IS USER PERMITTED ACCESS? */ if (retval == PAM_SUCCESS) { printf("...User %s is a real user.\n",user); printf("Trying to pass info to the pam_acct_mgmt function...\n"); retval = pam_acct_mgmt(pamh, 0); } else { if (retval == PAM_USER_UNKNOWN) printf("...Failed to find user %s with error: %d\n",user,retval); else printf("...Failed to authenticate for an unknown error: %d\n",retval); } if (retval == PAM_SUCCESS) { printf("...User %s is permitted access.\n",user); } else { printf("...cs_password error: User %s is not authenticated\n",user); printf("...Call returned with error: %d\n",retval); } /* TRYING TO CHANGE THE PASSWORD AUTHENTICATION TOKEN */ if (retval == PAM_SUCCESS) { printf("Trying to update the password token...\n"); retval = pam_chauthtok(pamh, PAM_SILENT); } if (retval == PAM_SUCCESS) { printf("...Successfully updated password!\n"); } else { printf("...Failed to update password: error %d\n",retval); printf("...%s\n",pam_strerror(pamh, retval)); } /* CLEAN UP OUR HANDLES AND VARIABLES */ if (pam_end(pamh, retval) != PAM_SUCCESS) { pamh = NULL; fprintf(stderr, "cs_password error: Failed to release authenticator\n"); } exit (CS_SUCCESS); }