mirror of
https://github.com/linux-pam/linux-pam.git
synced 2024-11-27 11:43:38 +08:00
Relevant BUGIDs: 490938
Purpose of commit: new feature Commit summary: --------------- Added libpammodutil and link it with every module as its built. The issue here is that there is a lot of code that the various modules use in common, and this staic library can be used to help make this code more maintainable. I do not intend to make this library dynamic. Especially right now, as I want to be free to chop and change the API and don't want to deal with revision control and third party modules. This checkin makes the pam_rhost_auth module make some use of this new library. I don't intend to add support for any other module prior to releasing 0.76.
This commit is contained in:
parent
cb7734d408
commit
da67a7d612
@ -55,6 +55,9 @@ bug report - outstanding bugs are listed here:
|
||||
0.76: please submit patches for this section with actual code/doc
|
||||
patches!
|
||||
|
||||
* added a static module helper library object includes a few changes
|
||||
to examples/xsh.c for testing purposes, and also modified the
|
||||
pam_rhosts_auth module to use this new library. (Bug 490938 - agmorgan)
|
||||
* documentation: random typo fixes from Nalin and more stuff from me
|
||||
(Bug 476949, Tasks 43507, 17426 - agmorgan)
|
||||
* pam_unix: fix 'likeauth' to kill off the memory leak once and for all.
|
||||
|
@ -13,6 +13,10 @@
|
||||
|
||||
#include <security/_pam_aconf.h>
|
||||
|
||||
#include <pwd.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
/* ------ some local (static) functions ------- */
|
||||
|
||||
static void bail_out(pam_handle_t *pamh,int really, int code, const char *fn)
|
||||
@ -56,6 +60,26 @@ int main(int argc, char **argv)
|
||||
retcode = pam_start(service, username, &conv, &pamh);
|
||||
bail_out(pamh,1,retcode,"pam_start");
|
||||
|
||||
/* fill in the RUSER and RHOST fields */
|
||||
{
|
||||
char buffer[100];
|
||||
struct passwd *pw;
|
||||
|
||||
pw = getpwuid(getuid());
|
||||
if (pw != NULL) {
|
||||
retcode = pam_set_item(pamh, PAM_RUSER, pw->pw_name);
|
||||
bail_out(pamh,1,retcode,"pam_set_item(PAM_RUSER)");
|
||||
}
|
||||
retcode = gethostname(buffer, sizeof(buffer)-1);
|
||||
if (retcode) {
|
||||
perror("failed to look up hostname");
|
||||
retcode = pam_end(pamh, PAM_ABORT);
|
||||
bail_out(pamh,1,retcode,"pam_end");
|
||||
}
|
||||
retcode = pam_set_item(pamh, PAM_RHOST, buffer);
|
||||
bail_out(pamh,1,retcode,"pam_set_item(PAM_RHOST)");
|
||||
}
|
||||
|
||||
/* to avoid using goto we abuse a loop here */
|
||||
for (;;) {
|
||||
/* authenticate the user --- `0' here, could have been PAM_SILENT
|
||||
|
@ -11,6 +11,8 @@ include ../Make.Rules
|
||||
MODDIRS=$(shell /bin/ls -d pam_*)
|
||||
|
||||
all:
|
||||
@echo building the static modutil library
|
||||
make -C pammodutil all
|
||||
@echo modules sources available are:
|
||||
@ls -d $(MODDIRS) 2>/dev/null ; echo :--------
|
||||
@echo
|
||||
@ -52,5 +54,5 @@ clean: lclean
|
||||
if [ -d $$i ]; then { \
|
||||
$(MAKE) -C $$i clean ; \
|
||||
} fi ; \
|
||||
done
|
||||
|
||||
done
|
||||
make -C pammodutil clean
|
||||
|
@ -19,6 +19,9 @@ LIBOBJ = $(addsuffix .o,$(LIBFILES))
|
||||
LIBOBJD = $(addprefix dynamic/,$(LIBOBJ))
|
||||
LIBOBJS = $(addprefix static/,$(LIBOBJ))
|
||||
|
||||
LINK_PAMMODUTILS = -L../pammodutil -lpammodutil
|
||||
INCLUDE_PAMMODUTILS = -I../pammodutil/include
|
||||
|
||||
ifdef DYNAMIC
|
||||
LIBSHARED = $(TITLE).so
|
||||
endif
|
||||
@ -32,10 +35,10 @@ endif
|
||||
all: dirs $(LIBSHARED) $(LIBSTATIC) register
|
||||
|
||||
dynamic/%.o : %.c
|
||||
$(CC) $(CFLAGS) $(DYNAMIC) $(TARGET_ARCH) -c $< -o $@
|
||||
$(CC) $(CFLAGS) $(INCLUDE_PAMMODUTILS) $(DYNAMIC) $(TARGET_ARCH) -c $< -o $@
|
||||
|
||||
static/%.o : %.c
|
||||
$(CC) $(CFLAGS) $(STATIC) $(TARGET_ARCH) -c $< -o $@
|
||||
$(CC) $(CFLAGS) $(INCLUDE_PAMMODUTILS) $(STATIC) $(TARGET_ARCH) -c $< -o $@
|
||||
|
||||
dirs:
|
||||
ifdef DYNAMIC
|
||||
@ -56,7 +59,7 @@ endif
|
||||
|
||||
ifdef DYNAMIC
|
||||
$(LIBSHARED): $(LIBOBJD)
|
||||
$(LD_D) -o $@ $(LIBOBJD) $(MODULE_SIMPLE_EXTRALIBS) $(NEED_LINK_LIB_C)
|
||||
$(LD_D) -o $@ $(LIBOBJD) $(MODULE_SIMPLE_EXTRALIBS) $(NEED_LINK_LIB_C) $(LINK_PAMMODUTILS)
|
||||
|
||||
endif
|
||||
|
||||
@ -66,7 +69,7 @@ endif
|
||||
|
||||
ifdef STATIC
|
||||
$(LIBSTATIC): $(LIBOBJS)
|
||||
$(LD) -r -o $@ $(LIBOBJS) $(MODULE_SIMPLE_EXTRALIBS)
|
||||
$(LD) -r -o $@ $(LIBOBJS) $(MODULE_SIMPLE_EXTRALIBS) $(LINK_PAMMODUTILS)
|
||||
endif
|
||||
|
||||
install: all
|
||||
|
@ -96,6 +96,7 @@ int innetgr(const char *, const char *, const char *,const char *);
|
||||
|
||||
#include <security/pam_modules.h>
|
||||
#include <security/_pam_macros.h>
|
||||
#include <security/_pam_modutil.h>
|
||||
|
||||
/* to the best of my knowledge, all modern UNIX boxes have 32 bit integers */
|
||||
#define U32 unsigned int
|
||||
@ -232,15 +233,16 @@ static int pam_get_rhost(pam_handle_t *pamh, const char **rhost
|
||||
* requesting the contents of the PAM_RUSER item.
|
||||
*/
|
||||
|
||||
static int pam_get_ruser(pam_handle_t *pamh, const char **ruser
|
||||
, const char *prompt)
|
||||
static int pam_get_ruser(pam_handle_t *pamh, const char **ruser,
|
||||
const char *prompt)
|
||||
{
|
||||
int retval;
|
||||
const char *current;
|
||||
|
||||
retval = pam_get_item (pamh, PAM_RUSER, (const void **)¤t);
|
||||
if (retval != PAM_SUCCESS)
|
||||
if (retval != PAM_SUCCESS) {
|
||||
return retval;
|
||||
}
|
||||
|
||||
if (current == NULL) {
|
||||
return PAM_AUTH_ERR;
|
||||
@ -491,7 +493,7 @@ pam_iruserok(pam_handle_t *pamh,
|
||||
* Identify user's local .rhosts file
|
||||
*/
|
||||
|
||||
pwd = getpwnam(luser);
|
||||
pwd = _pammodutil_getpwnam(pamh, luser);
|
||||
if (pwd == NULL) {
|
||||
/*
|
||||
* luser is assumed to be valid because of an earlier check for uid = 0
|
||||
@ -660,10 +662,11 @@ static int _pam_auth_rhosts (pam_handle_t *pamh,
|
||||
const char **argv)
|
||||
{
|
||||
int retval;
|
||||
const char *luser;
|
||||
const char *ruser,*rhost;
|
||||
const char *luser = NULL;
|
||||
const char *ruser = NULL, *rhost = NULL;
|
||||
struct _options opts;
|
||||
int as_root = 0;
|
||||
|
||||
/*
|
||||
* Look at the options and set the flags accordingly.
|
||||
*/
|
||||
@ -675,6 +678,7 @@ static int _pam_auth_rhosts (pam_handle_t *pamh,
|
||||
for (;;) { /* abuse loop to avoid goto */
|
||||
|
||||
/* get the remotehost */
|
||||
D(("getting rhost"));
|
||||
retval = pam_get_rhost(pamh, &rhost, NULL);
|
||||
(void) pam_set_item(pamh, PAM_RHOST, rhost);
|
||||
if (retval != PAM_SUCCESS) {
|
||||
@ -685,6 +689,7 @@ static int _pam_auth_rhosts (pam_handle_t *pamh,
|
||||
}
|
||||
|
||||
/* get the remote user */
|
||||
D(("getting ruser"));
|
||||
retval = pam_get_ruser(pamh, &ruser, NULL);
|
||||
(void) pam_set_item(pamh, PAM_RUSER, ruser);
|
||||
if (retval != PAM_SUCCESS) {
|
||||
@ -694,8 +699,8 @@ static int _pam_auth_rhosts (pam_handle_t *pamh,
|
||||
}
|
||||
|
||||
/* get the local user */
|
||||
D(("getting user"));
|
||||
retval = pam_get_user(pamh, &luser, NULL);
|
||||
|
||||
if (retval != PAM_SUCCESS) {
|
||||
if (opts.opt_debug)
|
||||
_pam_log(LOG_DEBUG, "could not determine name of local user");
|
||||
@ -710,7 +715,7 @@ static int _pam_auth_rhosts (pam_handle_t *pamh,
|
||||
if (! opts.opt_no_uid_check) {
|
||||
struct passwd *luser_pwd;
|
||||
|
||||
luser_pwd = getpwnam(luser);
|
||||
luser_pwd = _pammodutil_getpwnam(pamh, luser);
|
||||
if (luser_pwd == NULL) {
|
||||
if (opts.opt_debug)
|
||||
_pam_log(LOG_DEBUG, "user '%s' unknown to this system",
|
||||
|
53
modules/pammodutil/Makefile
Normal file
53
modules/pammodutil/Makefile
Normal file
@ -0,0 +1,53 @@
|
||||
#
|
||||
# $Id$
|
||||
#
|
||||
#
|
||||
|
||||
include ../../Make.Rules
|
||||
|
||||
LIBNAME=libpammodutil
|
||||
|
||||
# ---------------------------------------------
|
||||
|
||||
dummy: all
|
||||
|
||||
# ---------------------------------------------
|
||||
|
||||
CFLAGS += $(PIC) $(STATIC) $(MOREFLAGS) \
|
||||
-DLIBPAM_VERSION_MAJOR=$(MAJOR_REL) \
|
||||
-DLIBPAM_VERSION_MINOR=$(MINOR_REL)
|
||||
|
||||
# all the object files we care about
|
||||
LIBOBJECTS = modutil_cleanup.o modutil_getpwnam.o modutil_getpwuid.o
|
||||
|
||||
# static library name
|
||||
LIBSTATIC = $(LIBNAME).a
|
||||
|
||||
SLIBOBJECTS = $(addprefix static/,$(LIBOBJECTS) $(STATICOBJ))
|
||||
|
||||
# ---------------------------------------------
|
||||
## rules
|
||||
|
||||
all: dirs $(LIBSTATIC) ../../Make.Rules
|
||||
|
||||
dirs:
|
||||
$(MKDIR) static
|
||||
|
||||
static/%.o : %.c
|
||||
$(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
|
||||
|
||||
$(LIBSTATIC): $(SLIBOBJECTS)
|
||||
ar cr $@ $(SLIBOBJECTS)
|
||||
$(RANLIB) $@
|
||||
|
||||
install:
|
||||
@echo "at this time, we're not installing $(LIBSTATIC)"
|
||||
|
||||
remove:
|
||||
@echo "at this time, there is nothing to remove"
|
||||
|
||||
clean:
|
||||
rm -f a.out core *~ static/*.o
|
||||
rm -f *.a *.o
|
||||
if [ -d dynamic ]; then rmdir dynamic ; fi
|
||||
if [ -d static ]; then rmdir static ; fi
|
15
modules/pammodutil/README
Normal file
15
modules/pammodutil/README
Normal file
@ -0,0 +1,15 @@
|
||||
$Id$
|
||||
|
||||
This is a libarary of routines for use by modules. The routines seem
|
||||
to have a common use for modules, but are not part of libpam and never
|
||||
will be. They are also a convenient layer of abstraction for providing
|
||||
thread-safe functions that may require use of pam_handle_t 'data'
|
||||
items to make their thread-safeness tied to the use of a single
|
||||
pam_handle_t per thread.
|
||||
|
||||
Functions provided so far are all listed in
|
||||
|
||||
include/security/_pam_modutil.h
|
||||
|
||||
.
|
||||
|
33
modules/pammodutil/include/security/_pam_modutil.h
Normal file
33
modules/pammodutil/include/security/_pam_modutil.h
Normal file
@ -0,0 +1,33 @@
|
||||
#ifndef _PAM_MODUTIL_H
|
||||
#define _PAM_MODUTIL_H
|
||||
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* This file is a list of handy libc wrappers that attempt to provide some
|
||||
* thread-safe and other convenient functionality to modules in a form that
|
||||
* is common, but not dynamically linked with yet another dynamic pam
|
||||
* library extension.
|
||||
*
|
||||
* A number of these functions reserve space in a pam_[sg]et_data item.
|
||||
* In all cases, the name of the item is prefixed with "_pammodutil_*".
|
||||
*
|
||||
* On systems that simply can't support thread safe programming, these
|
||||
* functions don't support it either - sorry.
|
||||
*
|
||||
* Copyright (c) 2001 Andrew Morgan <morgan@kernel.org>
|
||||
*/
|
||||
|
||||
#include <pwd.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
extern struct passwd *_pammodutil_getpwnam(pam_handle_t *pamh,
|
||||
const char *user);
|
||||
|
||||
extern struct passwd *_pammodutil_getpwuid(pam_handle_t *pamh,
|
||||
uid_t uid);
|
||||
|
||||
extern void _pammodutil_cleanup(pam_handle_t *pamh, void *data,
|
||||
int error_status);
|
||||
|
||||
#endif /* _PAM_MODUTIL_H */
|
16
modules/pammodutil/modutil_cleanup.c
Normal file
16
modules/pammodutil/modutil_cleanup.c
Normal file
@ -0,0 +1,16 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* This function provides a common pam_set_data() friendly version of free().
|
||||
*/
|
||||
|
||||
#include "pammodutil.h"
|
||||
|
||||
void _pammodutil_cleanup(pam_handle_t *pamh, void *data, int error_status)
|
||||
{
|
||||
if (data) {
|
||||
/* junk it */
|
||||
(void) free(data);
|
||||
}
|
||||
}
|
||||
|
80
modules/pammodutil/modutil_getpwnam.c
Normal file
80
modules/pammodutil/modutil_getpwnam.c
Normal file
@ -0,0 +1,80 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* This function provides a thread safer version of getpwnam() for use
|
||||
* with PAM modules that care about this sort of thing.
|
||||
*
|
||||
* XXX - or at least it should provide a thread-safe alternative.
|
||||
*/
|
||||
|
||||
#include "pammodutil.h"
|
||||
|
||||
#include <pwd.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
struct passwd *_pammodutil_getpwnam(pam_handle_t *pamh, const char *user)
|
||||
{
|
||||
#ifdef HAVE_GETPWNAM_R
|
||||
|
||||
void *buffer=NULL;
|
||||
size_t length = PWD_INITIAL_LENGTH;
|
||||
|
||||
do {
|
||||
int status;
|
||||
void *new_buffer;
|
||||
struct passwd *result = NULL;
|
||||
|
||||
new_buffer = realloc(buffer, sizeof(struct passwd) + length);
|
||||
if (new_buffer == NULL) {
|
||||
|
||||
D(("out of memory"));
|
||||
|
||||
/* no memory for the user - so delete the memory */
|
||||
if (buffer) {
|
||||
free(buffer);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
buffer = new_buffer;
|
||||
|
||||
/* make the re-entrant call to get the pwd structure */
|
||||
status = getpwnam_r(user, buffer,
|
||||
sizeof(struct passwd) + (char *) buffer,
|
||||
length, &result);
|
||||
if (!status && result) {
|
||||
status = pam_set_data(pamh, "_pammodutil_getpwnam", result,
|
||||
_pammodutil_cleanup);
|
||||
if (status == PAM_SUCCESS) {
|
||||
D(("success"));
|
||||
return result;
|
||||
}
|
||||
|
||||
D(("was unable to register the data item [%s]",
|
||||
pam_strerror(pamh, status)));
|
||||
|
||||
free(buffer);
|
||||
return NULL;
|
||||
|
||||
}
|
||||
|
||||
length <<= 1;
|
||||
|
||||
} while (length < PWD_ABSURD_PWD_LENGTH);
|
||||
|
||||
D(("pwd structure took %u bytes or so of memory",
|
||||
length+sizeof(struct passwd)));
|
||||
|
||||
free(buffer);
|
||||
return NULL;
|
||||
|
||||
#else /* ie. ifndef HAVE_GETPWNAM_R */
|
||||
|
||||
/*
|
||||
* Sorry, there does not appear to be a reentrant version of
|
||||
* getpwnam(). So, we use the standard libc function.
|
||||
*/
|
||||
|
||||
return getpwnam(user);
|
||||
|
||||
#endif /* def HAVE_GETPWNAM_R */
|
||||
}
|
80
modules/pammodutil/modutil_getpwuid.c
Normal file
80
modules/pammodutil/modutil_getpwuid.c
Normal file
@ -0,0 +1,80 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* This function provides a thread safer version of getpwuid() for use
|
||||
* with PAM modules that care about this sort of thing.
|
||||
*
|
||||
* XXX - or at least it should provide a thread-safe alternative.
|
||||
*/
|
||||
|
||||
#include "pammodutil.h"
|
||||
|
||||
#include <pwd.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
struct passwd *_pammodutil_getpwuid(pam_handle_t *pamh, uid_t uid)
|
||||
{
|
||||
#ifdef HAVE_GETPWNAM_R
|
||||
|
||||
void *buffer=NULL;
|
||||
size_t length = PWD_INITIAL_LENGTH;
|
||||
|
||||
do {
|
||||
int status;
|
||||
void *new_buffer;
|
||||
struct passwd *result = NULL;
|
||||
|
||||
new_buffer = realloc(buffer, sizeof(struct passwd) + length);
|
||||
if (new_buffer == NULL) {
|
||||
|
||||
D(("out of memory"));
|
||||
|
||||
/* no memory for the user - so delete the memory */
|
||||
if (buffer) {
|
||||
free(buffer);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
buffer = new_buffer;
|
||||
|
||||
/* make the re-entrant call to get the pwd structure */
|
||||
status = getpwuid_r(uid, buffer,
|
||||
sizeof(struct passwd) + (char *) buffer,
|
||||
length, &result);
|
||||
if (!status && result) {
|
||||
status = pam_set_data(pamh, "_pammodutil_getpwuid", result,
|
||||
_pammodutil_cleanup);
|
||||
if (status == PAM_SUCCESS) {
|
||||
D(("success"));
|
||||
return result;
|
||||
}
|
||||
|
||||
D(("was unable to register the data item [%s]",
|
||||
pam_strerror(pamh, status)));
|
||||
|
||||
free(buffer);
|
||||
return NULL;
|
||||
|
||||
}
|
||||
|
||||
length <<= 1;
|
||||
|
||||
} while (length < PWD_ABSURD_PWD_LENGTH);
|
||||
|
||||
D(("pwd structure took %u bytes or so of memory",
|
||||
length+sizeof(struct passwd)));
|
||||
|
||||
free(buffer);
|
||||
return NULL;
|
||||
|
||||
#else /* ie. ifndef HAVE_GETPWNAM_R */
|
||||
|
||||
/*
|
||||
* Sorry, there does not appear to be a reentrant version of
|
||||
* getpwnam(). So, we use the standard libc function.
|
||||
*/
|
||||
|
||||
return getpwuid(uid);
|
||||
|
||||
#endif /* def HAVE_GETPWNAM_R */
|
||||
}
|
22
modules/pammodutil/pammodutil.h
Normal file
22
modules/pammodutil/pammodutil.h
Normal file
@ -0,0 +1,22 @@
|
||||
#ifndef PAMMODUTIL_H
|
||||
#define PAMMODUTIL_H
|
||||
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (c) 2001 Andrew Morgan <morgan@kernel.org>
|
||||
*/
|
||||
|
||||
#include <security/_pam_aconf.h>
|
||||
#include <security/_pam_macros.h>
|
||||
#include <security/pam_modules.h>
|
||||
#include <security/_pam_modutil.h>
|
||||
|
||||
#define PWD_INITIAL_LENGTH 0x100
|
||||
#define PWD_ABSURD_PWD_LENGTH 0x1000
|
||||
|
||||
/* This is a simple cleanup, it just free()s the 'data' memory */
|
||||
extern void _pammodutil_cleanup(pam_handle_t *pamh, void *data,
|
||||
int error_status);
|
||||
|
||||
#endif /* PAMMODUTIL_H */
|
Loading…
Reference in New Issue
Block a user