Anton Blajev - Valqk
2007-Jan-17 08:05 UTC
login_get_lastlog - nss enviornment - works in shell env, doesn't work when sshd calls it.
-----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.
Reasonably Related Threads
- Server option PrintLastLog does not work on AIX
- PATCH: UseLogin fix for 2.9p1 (w/improved last-login time)
- [Bug 855] doesn't properly log logout event in utmp entry when pts bigger than 999
- [Bug 1595] New: Server option PrintLastLog does not work on AIX
- FW: LDAP Problem