[Date Prev][Date Next] [Chronological] [Thread] [Top]

API Question

This question is regarding making a shared object out of some of the OpenLDAP API function calls, specfically a PAM module that does a simple search like the ldapsearch binary.

Here is how it is compiled...
gcc -fPIC -o pam_ldap.o -c pam_ldap.c
ld -x --shared -o pam_ldap_search.so pam_ldap.o -lpam -lldap
install -m 755 pam_ldap_search.so /lib/security;

My problem is in a defined function show here which does a simple lookup for the username entered when logging into a SuSe 9.0 box...

#include <stdio.h>
#include <syslog.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/file.h>
#include <sys/types.h>
#include <sys/time.h>

/* PAM definitions */
#define PAM_SM_AUTH

/* PAM includes */
#include <security/pam_modules.h>
#include <security/_pam_macros.h>
#include <security/pam_appl.h>

/* LDAP includes */
#include <ldap.h>

/* OOP-esque structure to keep user data contiguous */
typedef struct usrData * udataptr;
struct usrData {
   const char * usrname;
   char uidnum[10], gidnum[10];
   char shell[15], homedir[25];
   char pass[15];
   int ldap_res;
} localUser;

#define CONFIG_FILE "/etc/pam_ldap_search.conf"

//Array for default data input (file paths, permissions, GID, etc)
char dflts[10][80];

// Logging for SYSLOG
static void _pam_log(int err, const char *format, ...)
   va_list  args;

   va_start(args, format);
   openlog("PAM-lame", LOG_PID | LOG_NDELAY, LOG_SYSLOG);
   vsyslog(err, format, args);

// Read the config file options
static void _read_config()
   float config;
   FILE *cfg;
   int i=0;

   if((cfg = fopen(CONFIG_FILE, "r")) == NULL) {
       _pam_log(LOG_ERR, "Could not open file: /etc/looser.conf");
   } else {
       while(!feof(cfg)) {
           if(i > 12) {
               break; }
           if(dflts[i][0] != '#') {
               if(dflts[i][strlen(dflts[i])-1] == '\n') {
                   dflts[i][strlen(dflts[i])-1] = '\0';}
               i++;  }

// start the shared object as a PAM module
int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc,
                       const char **argv)
   int retval;
   udataptr myUser = &localUser;
   char user[15];
   char error_msg[30];
   LDAP *ld;
   LDAP            *ld;
   LDAPMessage     *res, *e, **result;
   LDAPMessage     *entry;
   LDAPMessage     *msg;
   int             i, y;
   char            *x, *dn;
   char            *attr;
   char            **vals;
   char            buffer[80];
   char            errors[256];
   BerElement      **berptr;
   BerElement      * ber;

   struct timeval myTime;
   struct timeval *timeout = &myTime;

   berptr = &ber;

   sprintf(buffer, "\"(uid=%s,%s)\"", myUser->usrname, dflts[10]);

   /* initialize a connection */
   if((ld = ldap_init(dflts[7], *dflts[8])) == NULL) {
       _pam_log(LOG_ERR, "Connection failed for %s", dflts[7]);
       return 0;
   _pam_log(LOG_ERR, "Connection succeeded for %s", dflts[7]);

   if(!ldap_simple_bind(ld, dflts[9], dflts[12])) {
       _pam_log(LOG_ERR, "Couldn't bind to %s", dflts[9]);
       return 0;
   _pam_log(LOG_ERR, "Bind to %s successful", dflts[9]);

 if((ldap_first_entry(ld, res)) == NULL) {
       _pam_log(LOG_ERR, "ldap_first_entry() failed returning %d", res);
       return 0;
  _pam_log(LOG_ERR, "ldap_first_entry() succeeded returning %d", res);

Can anyone tell me why it fails when trying to get a valid username from the correct DN? I have tried a few things such as modifying the path informat etc but it fails every time with valid or in-valid usernames.

Jason Gerfen

"...Sometimes I just yell at myself. And it
makes me sad, sometimes I make myself cry..."
			~ My nephew Dawsyn