7 messages in net.java.dev.jna.usersRE: [jna-users] Help mapping libpam i...
FromSent OnAttachments
Crump, MichaelNov 12, 2008 11:12 am 
Stefan EndrullisNov 12, 2008 1:33 pm 
Timothy WallNov 12, 2008 1:57 pm 
Crump, MichaelNov 12, 2008 2:44 pm 
Timothy WallNov 12, 2008 4:01 pm 
Crump, MichaelNov 13, 2008 10:44 am 
Timothy WallNov 13, 2008 12:06 pm 
Actions with this message:
Paste this link in email or IM:
Paste this link in email or IM:
Atom feed for this thread
Paste this URL into your reader:
Subject:RE: [jna-users] Help mapping libpam in LinuxActions...
From:Crump, Michael (mcr@leadscope.com)
Date:Nov 13, 2008 10:44:23 am
List:net.java.dev.jna.users

The pam library's documentation of the callback function is a little ambiguous but here it is - the answer is that sometimes it's an array of structs but maybe its an array of struct pointers.

The PAM library uses an application-defined callback to allow a direct communication between a loaded module and the application. This callback is specified by the struct pam_conv passed to pam_start(3) at the start of the transaction.

When a module calls the referenced conv() function, the argument appdata_ptr is set to the second element of this structure.

The other arguments of a call to conv() concern the information exchanged by module and application. That is to say, num_msg holds the length of the array of pointers, msg. After a successful return, the pointer resp points to an array of pam_response structures, holding the application supplied text. The resp_retcode member of this struct is unused and should be set to zero. It is the caller's responsibility to release both, this array and the responses themselves, using free(3). Note, *resp is a struct pam_response array and not an array of pointers.

The number of responses is always equal to the num_msg conversation function argument. This does require that the response array is free(3)'d after every call to the conversation function. The index of the responses corresponds directly to the prompt index in the pam_message array.

On failure, the conversation function should release any resources it has allocated, and return one of the predefined PAM error codes.

-----Original Message----- From: Timothy Wall [mailto:twal@dev.java.net] Sent: Wednesday, November 12, 2008 7:02 PM To: use@jna.dev.java.net Subject: Re: [jna-users] Help mapping libpam in Linux

In this case, just use a pointer, then use Pointer.getPointer(0) to get the structure memory for use with Structure.useMemory. Why is it passing "struct**" instead of just "struct*", if not to pass an array of struct*?

The ByReference classes are intended for use when you'd normally pass the address of a given variable.

On Nov 12, 2008, at 5:45 PM, Crump, Michael wrote:

Thanks, I've already fixed the public problem. struct** is correct. Would it be better to use Pointer or PointerByReference for the struct**? I'm a little unsure of when to use PointerByReference.

-----Original Message----- From: Timothy Wall [mailto:twal@dev.java.net] Sent: Wednesday, November 12, 2008 4:58 PM To: use@jna.dev.java.net Subject: Re: [jna-users] Help mapping libpam in Linux

See comments below.

On Nov 12, 2008, at 2:12 PM, Crump, Michael wrote:

Hello,

I'm still working on mapping libpam in Linux using jna. I think once I get an understanding of the first couple of functions it won't be too bad. Anyhow here are the declarations of the first two functions I am trying to map:

int pam_start(const char *service_name, const char *user, const struct pam_conv *pam_conversation, pam_handle_t **pamh); int pam_end(pam_handle_t *pamh, int pam_status);

and here are the related c structs:

struct pam_message { int msg_style; const char *msg; };

Don't forget to make the fields public.

struct pam_response { char *resp; int resp_retcode; };

struct pam_conv { int (*conv)(int num_msg, const struct pam_message **msg, struct pam_response **resp, void *appdata_ptr); void *appdata_ptr; };

Here is what I've come up with so far. I would appreciate it if someone could tell me whether or not what I have come up with so far will work.

public class PamMessage extends Structure { int msgStyle; String msg; }

public class PamResponse extends Structure { public String resp; public int respRetCode; }

public class PamConv extends Structure { public static interface Conv extends Callback { int callback(int numMsg, PamMessage pamMessage, PamResponse resp, Pointer appDataPtr); }

struct * => Structure

You've got struct**, which would most simply be Pointer. If it's a null-terminated array, you can auto-map to Pointer[] or (maybe) Structure.ByReference[] (tho' I'm not sure if the latter will work without extra effort).

I'm assuming the arguments passed in are arrays of pointer to structure; if it's only a typo and you really meant "struct *" then your mappings are ok.

Conv conv; Pointer appDataPtr; }

public interface LibPam extends Library { public int pam_start(String service_name, String user, PamConv pam_conversation, PointerByReference pamh);

public int pam_end(Pointer pamh, int pam_status); }

You might consider making "pamh" derive from PointerType, but that's a matter of style.