2018-06-01 20:15:15 +00:00
|
|
|
// Golang bindings for basic login/utmp accounting
|
2018-06-27 21:57:26 +00:00
|
|
|
package goutmp
|
2018-06-01 20:15:15 +00:00
|
|
|
|
|
|
|
//#include <stdio.h>
|
|
|
|
//#include <stdlib.h>
|
|
|
|
//#include <sys/file.h>
|
|
|
|
//#include <string.h>
|
|
|
|
//#include <bsd/string.h>
|
|
|
|
//#include <unistd.h>
|
|
|
|
//#include <stdint.h>
|
|
|
|
//#include <time.h>
|
|
|
|
//#include <pwd.h>
|
|
|
|
//
|
|
|
|
//#include <utmp.h>
|
|
|
|
//#include <utmpx.h>
|
|
|
|
//#include <lastlog.h>
|
|
|
|
//
|
|
|
|
//typedef char char_t;
|
|
|
|
//
|
|
|
|
//
|
|
|
|
//void pututmp(struct utmpx* entry, char* name, char* host) {
|
2018-06-09 05:55:50 +00:00
|
|
|
// //int32_t stat = system("echo ---- pre ----;who");
|
2018-06-01 20:15:15 +00:00
|
|
|
//
|
|
|
|
// entry->ut_type = USER_PROCESS;
|
|
|
|
// entry->ut_pid = getpid();
|
|
|
|
// strcpy(entry->ut_line, ttyname(STDIN_FILENO) + strlen("/dev/"));
|
|
|
|
// /* only correct for ptys named /dev/tty[pqr][0-9a-z] */
|
|
|
|
//
|
|
|
|
// strcpy(entry->ut_id, ttyname(STDIN_FILENO) + strlen("/dev/tty"));
|
|
|
|
// entry->ut_time = time(NULL);
|
|
|
|
// strcpy(entry->ut_user, name);
|
|
|
|
// strcpy(entry->ut_host, host);
|
|
|
|
// entry->ut_addr = 0;
|
|
|
|
// setutxent();
|
|
|
|
// pututxline(entry);
|
|
|
|
//
|
2018-06-09 05:55:50 +00:00
|
|
|
// //stat = system("echo ---- post ----;who");
|
2018-06-01 20:15:15 +00:00
|
|
|
//}
|
|
|
|
//
|
|
|
|
//void unpututmp(struct utmpx* entry) {
|
|
|
|
// entry->ut_type = DEAD_PROCESS;
|
|
|
|
// memset(entry->ut_line, 0, UT_LINESIZE);
|
|
|
|
// entry->ut_time = 0;
|
|
|
|
// memset(entry->ut_user, 0, UT_NAMESIZE);
|
|
|
|
// setutxent();
|
|
|
|
// pututxline(entry);
|
|
|
|
//
|
2018-06-09 05:55:50 +00:00
|
|
|
// //int32_t stat = system("echo ---- cleanup ----;who; lastlog");
|
2018-06-01 20:15:15 +00:00
|
|
|
//
|
|
|
|
// endutxent();
|
|
|
|
//}
|
|
|
|
//
|
|
|
|
//int putlastlogentry(int64_t t, int uid, char* line, char* host) {
|
|
|
|
// int retval = 0;
|
|
|
|
// FILE *f;
|
|
|
|
// struct lastlog l;
|
|
|
|
//
|
|
|
|
// strncpy(l.ll_line, line, UT_LINESIZE);
|
|
|
|
// l.ll_line[UT_LINESIZE-1] = '\0';
|
|
|
|
// strncpy(l.ll_host, host, UT_HOSTSIZE);
|
|
|
|
// l.ll_host[UT_HOSTSIZE-1] = '\0';
|
|
|
|
//
|
|
|
|
// l.ll_time = (time_t)t;
|
2018-06-28 00:31:55 +00:00
|
|
|
// //printf("l: ll_line '%s', ll_host '%s', ll_time %d\n", l.ll_line, l.ll_host, l.ll_time);
|
2018-06-01 20:15:15 +00:00
|
|
|
//
|
|
|
|
// /* Write lastlog entry at fixed offset (uid * sizeof(struct lastlog) */
|
|
|
|
// if( NULL != (f = fopen("/var/log/lastlog", "rw+")) ) {
|
|
|
|
// if( !fseek(f, (uid * sizeof(struct lastlog)), SEEK_SET) ) {
|
|
|
|
// int fd = fileno(f);
|
|
|
|
// if( write(fd, &l, sizeof(l)) == sizeof(l) ) {
|
|
|
|
// retval = 1;
|
2018-06-09 05:55:50 +00:00
|
|
|
// //int32_t stat = system("echo ---- lastlog ----; lastlog");
|
2018-06-01 20:15:15 +00:00
|
|
|
// }
|
|
|
|
// }
|
|
|
|
// fclose(f);
|
|
|
|
// }
|
|
|
|
// return retval;
|
|
|
|
//}
|
|
|
|
import "C"
|
|
|
|
|
|
|
|
import (
|
2018-06-28 02:08:56 +00:00
|
|
|
"fmt"
|
|
|
|
"net"
|
|
|
|
"os/user"
|
|
|
|
"strings"
|
|
|
|
"time"
|
2018-06-01 20:15:15 +00:00
|
|
|
)
|
|
|
|
|
2018-06-27 22:18:28 +00:00
|
|
|
// UtmpEntry wraps the C struct utmpx
|
2018-06-09 03:30:00 +00:00
|
|
|
type UtmpEntry struct {
|
|
|
|
entry C.struct_utmpx
|
|
|
|
}
|
|
|
|
|
2018-06-28 02:08:56 +00:00
|
|
|
// return remote client hostname or IP if host lookup fails
|
|
|
|
func GetHost(addr string) (h string) {
|
|
|
|
// Strip off the port after IP addr
|
|
|
|
hList, e := net.LookupAddr(strings.Split(addr,":")[0])
|
|
|
|
fmt.Printf("lookupAddr:%v\n", hList)
|
|
|
|
if e != nil {
|
|
|
|
h = strings.Split(addr,":")[0]
|
|
|
|
} else {
|
|
|
|
h = hList[0]
|
|
|
|
}
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2018-06-27 22:18:28 +00:00
|
|
|
// Put a username and the originating host/IP to utmp
|
2018-06-09 03:30:00 +00:00
|
|
|
func Put_utmp(user string, host string) (UtmpEntry) {
|
|
|
|
var entry UtmpEntry
|
2018-06-01 20:15:15 +00:00
|
|
|
|
2018-06-09 03:30:00 +00:00
|
|
|
C.pututmp(&entry.entry, C.CString(user), C.CString(host))
|
|
|
|
return entry
|
2018-06-01 20:15:15 +00:00
|
|
|
}
|
|
|
|
|
2018-06-27 22:18:28 +00:00
|
|
|
// Remove a username/host entry from utmp
|
2018-06-09 03:30:00 +00:00
|
|
|
func Unput_utmp(entry UtmpEntry) {
|
|
|
|
C.unpututmp(&entry.entry)
|
2018-06-01 20:15:15 +00:00
|
|
|
}
|
|
|
|
|
2018-06-27 22:18:28 +00:00
|
|
|
// Put the login app, username and originating host/IP to lastlog
|
2018-06-01 20:15:15 +00:00
|
|
|
func Put_lastlog_entry(app string, usr string, host string) {
|
|
|
|
u, e := user.Lookup(usr)
|
|
|
|
if e != nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
var uid uint32
|
|
|
|
fmt.Sscanf(u.Uid, "%d", &uid)
|
|
|
|
|
|
|
|
t := time.Now().Unix()
|
2018-06-09 05:55:50 +00:00
|
|
|
_ = C.putlastlogentry(C.int64_t(t), C.int(uid), C.CString(app), C.CString(host))
|
|
|
|
//stat := C.putlastlogentry(C.int64_t(t), C.int(uid), C.CString(app), C.CString(host))
|
|
|
|
//fmt.Println("stat was:",stat)
|
2018-06-01 20:15:15 +00:00
|
|
|
}
|