login_get_lastlog - nss enviornment - works in shell env, doesn't work when sshd calls it.
Anton Blajev - Valqk
valqk at lozenetz.org
Wed Jan 17 19:05:34 EST 2007
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Hello to every one!
Maybe this is not exactly the right place,
but I don't know where to ask, so...
I have a FreeBSD-6-STABLE machine,
setuped with custom nss lib which reads from pgsql database.
It seems to be working just fine except
that I can't login trought ssh, when trying the normal method.
When I do
$>ssh host.com tcsh
I get logged and everything works - getpwent etc.
but with no accounting and enviornment setuped.
in the messages logs I get
after a quite hard debuging and nothing found,
I've decided to do some coding...
C isn't my strong side, I can read(and understand) code,
but I can't write good C apps....just a hacks.
I've researched and exracted the function that appears in the logs:
$>tail /var/log/message
Jan 16 23:59:01 user sshd[74154]: fatal: login_get_lastlog: Cannot find account for uid 1010
Jan 16 23:59:01 user sshd[74148]: fatal: login_init_entry: Cannot find user "test"
(the login_init_entry is there because I've turned on
PrintLastLog yes
before that it wasn't showing.
I've found a similar problem with nss_ldap in this list but there was no answer to it.
http://marc.theaimsgroup.com/?l=sun-managers&m=110686236715213&w=2
I hope I'll et one ;-)
I've extracted some fucntions from loginrec.c and at the bottom of the mail is the src.
The main idea is that I got the 'login_get_lastlog' function in a separate executable
so I can see if it's working ok and if not I can gdb it.
The interesting thing is that this app is workign just fine!
The only app where the getpwuid is not wokring is sshd and I can't understand why...
maybe it's in the nss implementation but please
gime me ANY ideas!!
Thanks and any help will be useful!
BTW, I'm _not_ subscribed to this list because I'm not C dev.
Please 'reply all' or to me personal.10q.
Have a nice day :)
Laters.
[--code getpwuid.c --]
#include <sys/types.h>
#include <pwd.h>
#include <stdarg.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
union login_netinfo {
struct sockaddr sa;
struct sockaddr_in sa_in;
struct sockaddr_storage sa_storage;
};
/*
* * logininfo structure *
*/
/* types - different to utmp.h 'type' macros */
/* (though set to the same value as linux, openbsd and others...) */
#define LTYPE_LOGIN 7
#define LTYPE_LOGOUT 8
/* string lengths - set very long */
#define LINFO_PROGSIZE 64
#define LINFO_LINESIZE 64
#define LINFO_NAMESIZE 128
#define LINFO_HOSTSIZE 256
struct logininfo {
char progname[LINFO_PROGSIZE]; /* name of program (for PAM) */
int progname_null;
short int type; /* type of login (LTYPE_*) */
int pid; /* PID of login process */
int uid; /* UID of this user */
char line[LINFO_LINESIZE]; /* tty/pty name */
char username[LINFO_NAMESIZE]; /* login username */
char hostname[LINFO_HOSTSIZE]; /* remote hostname */
/* 'exit_status' structure components */
int exit; /* process exit status */
int termination; /* process termination status */
/* struct timeval (sys/time.h) isn't always available, if it isn't we'll
* use time_t's value as tv_sec and set tv_usec to 0
*/
unsigned int tv_sec;
unsigned int tv_usec;
union login_netinfo hostaddr; /* caller's host address(es) */
}; /* struct logininfo */
/* construct a new login entry */
struct logininfo *login_alloc_entry(int pid, const char *username,
const char *hostname, const char *line);
/* lastlog *entry* functions fill out a logininfo */
struct logininfo *login_get_lastlog(struct logininfo *li, const int uid);
int main() {
int uid=1010;
struct passwd *pw;
struct logininfo li;
pw = getpwuid(uid);
printf("Starting...\n");
login_get_lastlog(&li,uid);
printf("U: %s\n",li.username);
printf("Done.\n");
}
/*
* Returns the time when the user last logged in. Returns 0 if the
* information is not available. This must be called before record_login.
* The host the user logged in from will be returned in buf.
*/
time_t
get_last_login_time(uid_t uid, const char *logname,
char *buf, size_t bufsize)
{
struct logininfo li;
login_get_lastlog(&li, uid);
strlcpy(buf, li.hostname, bufsize);
return (time_t)li.tv_sec;
}
/**
** getlast_entry: Call low-level functions to retrieve the last login
** time.
**/
/* take the uid in li and return the last login time */
int
getlast_entry(struct logininfo *li)
{
#ifdef USE_LASTLOG
return(lastlog_get_entry(li));
#else /* !USE_LASTLOG */
#if defined(DISABLE_LASTLOG)
/* On some systems we shouldn't even try to obtain last login
* time, e.g. AIX */
return (0);
# elif defined(USE_WTMP) && \
(defined(HAVE_TIME_IN_UTMP) || defined(HAVE_TV_IN_UTMP))
/* retrieve last login time from utmp */
return (wtmp_get_entry(li));
# elif defined(USE_WTMPX) && \
(defined(HAVE_TIME_IN_UTMPX) || defined(HAVE_TV_IN_UTMPX))
/* If wtmp isn't available, try wtmpx */
return (wtmpx_get_entry(li));
# else
/* Give up: No means of retrieving last login time */
return (0);
# endif /* DISABLE_LASTLOG */
#endif /* USE_LASTLOG */
}
struct logininfo *
login_get_lastlog(struct logininfo *li, const int uid)
{
struct passwd *pw;
memset(li, '\0', sizeof(*li));
li->uid = uid;
/*
* If we don't have a 'real' lastlog, we need the username to
* reliably search wtmp(x) for the last login (see
* wtmp_get_entry().)
*/
pw = getpwuid(uid);
if (pw == NULL) {
printf("FATAL::: %s: Cannot find account for uid %i", __func__, uid);
exit(1);
}
/* No MIN_SIZEOF here - we absolutely *must not* truncate the
* username (XXX - so check for trunc!) */
strlcpy(li->username, pw->pw_name, sizeof(li->username));
if (getlast_entry(li))
return (li);
else
return (NULL);
}
[--endcode--]
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org
iD8DBQFFrdjOzpU6eaWiiWgRAvLEAJ9k1JsYcJKqqZHBHAWdVW4zxX8/ogCeIJtA
8ZDq6uy5Eeq8m2egG7Gkwqw=
=2xpF
-----END PGP SIGNATURE-----
--
This message has been scanned for viruses and
dangerous content by MailScanner, and is
believed to be clean.
More information about the openssh-unix-dev
mailing list