305 lines
9.2 KiB
C
305 lines
9.2 KiB
C
/***********************************************************************
|
|
* 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 <unistd.h>
|
|
#include <getopt.h>
|
|
|
|
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;
|
|
}
|
|
|