[tpop3d-discuss] Memory leak?

Chris Lightfoot chris at ex-parrot.com
Wed, 8 May 2002 11:48:20 +0100


--HlL+5n6rz5pIUxbD
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

On Wed, May 08, 2002 at 11:40:56AM +0100, Chris Lightfoot wrote:
> I've attached a trivial test of the PAM code, pamtest.c.

And like an idiot, I forgot to send this. It's attached to
this message.

-- 
If all else fails, immortality can always
be assured by spectacular error.  (Galbraith)

--HlL+5n6rz5pIUxbD
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="pamtest.c"

#include <errno.h>
#include <grp.h>
#include <pwd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <security/pam_appl.h>
#include <sys/resource.h>
#include <sys/types.h>

int auth_pam_conversation(int num_msg, const struct pam_message **msg, struct pam_response **resp, void *appdata_ptr) {
    const struct pam_message **m;
    struct pam_response *r;

    if (!num_msg || !msg || !appdata_ptr) return PAM_CONV_ERR;
    
    *resp = (struct pam_response*)calloc(num_msg, sizeof(struct pam_response));
    if (!*resp) return PAM_CONV_ERR;

    /* Assume that any prompt is asking for a password */
    for (m = msg, r = *resp; m < msg + num_msg; ++m, ++r) {
        if ((*m)->msg_style == PAM_PROMPT_ECHO_OFF) {
            char *x;
            r->resp = (x = strdup((char*)appdata_ptr));
            r->resp_retcode = 0;
        }
    }

    return PAM_SUCCESS;
}

int auth_pam_new_user_pass(const char *user, const char *pass) {
    pam_handle_t *pamh = NULL;
    struct passwd pw, *pw2;
    int r, n = PAM_SUCCESS;
    struct pam_conv conv = {0};
    char *facility;
    int use_gid = 0;
    gid_t gid;

    pw2 = getpwnam(user);
    if (!pw2) {
        fprintf(stderr, "getpwnam(%s): unknown user (%s)", user, strerror(errno));
        return 0;
    } else
        pw = *pw2;

    /* Obtain facility name. */
    facility = "tpop3d";

    conv.conv = auth_pam_conversation;
    conv.appdata_ptr = (void*)pass;
    
    r = pam_start(facility, user, &conv, &pamh);

    if (r != PAM_SUCCESS) {
        fprintf(stderr, "pam_start: %s\n", pam_strerror(pamh, r));
        return 0;
    }

    /* Authenticate user. */
    r = pam_authenticate(pamh, 0);

    if (r == PAM_SUCCESS) {
        /* OK, is the account presently allowed to log in? */
        r = pam_acct_mgmt(pamh, 0);
        if (r == PAM_SUCCESS)
            fprintf(stderr, ".");
        else fprintf(stderr, "pam_acct_mgmt(%s): %s\n", user, pam_strerror(pamh, r));
    } else fprintf(stderr, "pam_authenticate(%s): %s\n", user, pam_strerror(pamh, r));

    r = pam_end(pamh, n);
    if (r != PAM_SUCCESS) fprintf(stderr, "pam_end: %s\n", pam_strerror(pamh, r));

    return 1;
}

int main() {
    fprintf(stderr, "I am PID %d\n", (int)getpid());
    while(1) auth_pam_new_user_pass("user", "password");
}

--HlL+5n6rz5pIUxbD--