/*********************************************************************** * File: modinstall.c * Author: Juan Carlos Luciani (jluciani@novell.com) * * Abstract: Implements a utility to install or un-install the * pam_pwcapture module. * * Copyright (C) 2004 Novell, Inc. * * This library 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 2 of the License, or (at your option) any later version. * * This library 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 * Library General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this library; if not, write to the Free * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ***********************************************************************/ #include "stdio.h" #include "errno.h" #include #include typedef int BOOL; #define TRUE 1 #define FALSE 0 // Usage string char usage[] = "\nmodinstall: usage: [-i InstallPamConfigFilePath] [-u UninstallPamConfigFilePath]\n"; // Our PAM Configuration Line char pamConfigLine[] = "auth required\tpam_pwcapture.so\n"; /* ************************************************************************ * InstallModule() * * Installs the pam_pwcapture file in the specified file. * * ************************************************************************/ void InstallModule(char *pFilePath) { FILE *fp; FILE *fpTemp; fpos_t currLinePosition; char currLine[512]; BOOL authLineFound = FALSE; BOOL insertedOurLine = FALSE; // Open temporary file if ((fpTemp = tmpfile()) != NULL) { // Open the PAM config file for reading if ((fp = fopen(pFilePath, "r")) != NULL) { // Copy the PAM config file onto the temp file while (fgets(currLine, 512, fp) != NULL) if (fputs(currLine, fpTemp) < 0) fprintf(stderr, "Error writing line to temp file\n"); // Close the PAM Config file and reopen it for writing fclose(fp); if ((fp = fopen(pFilePath, "w")) != NULL) { // Reset the file position on the temp file to the beginning if (fseek(fpTemp, 0, SEEK_SET) == 0) { // Now move the lines from the temp file onto the clean // PAM config file looking for a place to insert our own // line. while (fgets(currLine, 512, fpTemp) != NULL) { // Check if we are dealing with a line configuring an authentication service if (strlen(currLine) > 4 && tolower(currLine[0]) == 'a' && tolower(currLine[1]) == 'u' && tolower(currLine[2]) == 't' && tolower(currLine[3]) == 'h') { authLineFound = TRUE; } else { // This line is not configuring an authentication service, check if we // now need to add a line for our module. if (authLineFound && insertedOurLine == FALSE) { // Do not add our line if the line is commented out if (strlen(currLine) > 1 && currLine[0] != '#') { // Ok, now insert our line into the configuration. if (fputs(pamConfigLine, fp) < 0) fprintf(stderr, "Error writing line to PAM Config file\n"); insertedOurLine = TRUE; } } } if (fputs(currLine, fp) < 0) fprintf(stderr, "Error writing line to PAM Config file\n"); } } else { fprintf(stderr, "Error resetting position in temp file\n"); } // Close the PAM Config file fclose(fp); } else { fprintf(stderr, "Error reopening PAM Config file\n"); } } else { fprintf(stderr, "Error opening PAM Config file for reading\n"); } // Close the temporary file fclose(fpTemp); } else { fprintf(stderr, "Unable to open temporary file\n"); } } /* ************************************************************************ * UninstallModule() * * Uninstalls the pam_pwcapture file from the specified file. * * ************************************************************************/ void UninstallModule(char *pFilePath) { FILE *fp; FILE *fpTemp; char currLine[512]; // Open temporary file if ((fpTemp = tmpfile()) != NULL) { // Open the PAM config file for reading if ((fp = fopen(pFilePath, "r")) != NULL) { // Copy the PAM config file onto the temp file while (fgets(currLine, 512, fp) != NULL) if (fputs(currLine, fpTemp) < 0) fprintf(stderr, "Error writing line to temp file\n"); // Close the PAM Config file and reopen it for writing fclose(fp); if ((fp = fopen(pFilePath, "w")) != NULL) { // Reset the file position on the temp file to the beginning if (fseek(fpTemp, 0, SEEK_SET) == 0) { // Now move the lines from the temp file onto the clean // PAM config file looking for our own line. while (fgets(currLine, 512, fpTemp) != NULL) { // Write lines other than our own back to the PAM Config file if (strcmp(currLine, pamConfigLine) != 0) { if (fputs(currLine, fp) < 0) fprintf(stderr, "Error writing line to PAM Config file\n"); } } } else { fprintf(stderr, "Error resetting position in temp file\n"); } // Close the PAM Config file fclose(fp); } else { fprintf(stderr, "Error reopening PAM Config file\n"); } } else { fprintf(stderr, "Error opening PAM Config file for reading\n"); } // Close the temporary file fclose(fpTemp); } else { fprintf(stderr, "Unable to open temporary file\n"); } } /* ************************************************************************ * main() * * Entry point for console application. * * ************************************************************************/ int main(int argc, char* argv[]) { int option; int optionsSpecified = 0; BOOL doneScanning = FALSE; BOOL invalidUsage = FALSE; char *pInstallFile = NULL; char *pUninstallFile = NULL; // Scan options while (!doneScanning) { opterr = 0; option = getopt(argc, argv, "i:u:?"); // Proceed based on the result switch (option) { case 'i': // Install option, check the argument. if (optarg != NULL) { // Record location of argument pInstallFile = optarg; optionsSpecified ++; } else { // No install file path specified doneScanning = TRUE; invalidUsage = TRUE; } break; case 'u': // Uninstall option, check the argument. if (optarg != NULL) { // Record location of argument pUninstallFile = optarg; optionsSpecified ++; } else { // No uninstall file path specified doneScanning = TRUE; invalidUsage = TRUE; } break; case '?': // Invalid option detected doneScanning = TRUE; invalidUsage = TRUE; break; default: // Done scanning doneScanning = TRUE; break; } } // Do some sanity checking if (!invalidUsage && optionsSpecified) { // Check if we need to install the module if (pInstallFile) { InstallModule(pInstallFile); } // Check if we need to uninstall the module if (pUninstallFile) { UninstallModule(pUninstallFile); } } else { // Invalid option detected, print usage message. printf(usage, argv[0]); } return 0; }