#include #include #include #include #include #include #include #include #include #include #include #include #include //#include #define align(ptr, blen, TYPE) \ do { \ char *qtr = ptr; \ ptr += sizeof(TYPE) - 1; \ ptr -= ((ptr - (char *)NULL) % sizeof(TYPE)); \ blen -= (ptr - qtr); \ } while (0) static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; static int gnIdxPwd = 0; static int gnIdxSpw = 0; static int gnIdxGrp = 0; //static NSAutoreleasePool* mainPool = nil; int _nss_objc_getpwuid_r (uid_t, struct passwd *, char *, size_t, int *); int _nss_objc_setpwent (void); int _nss_objc_getpwent_r (struct passwd *, char *, size_t, int *); int _nss_objc_endpwent (void); int _nss_objc_getpwnam_r (const char *, struct passwd *, char *, size_t, int *); int _nss_objc_getspnam_r (const char *, struct spwd *, char *, size_t, int *); int _nss_objc_setspend (void); int _nss_objc_getspent_r (struct spwd *, char *buffer, size_t, int *); int _nss_objc_endspent (void); int _nss_objc_initgroups (const char *user, gid_t group, long *start, long int *size, gid_t *groups, long int limit, int *errnop); int _nss_objc_setgrent (void); int _nss_objc_endgrent (void); int _nss_objc_getgrent_r (struct group *gr, char *buffer, size_t buflen, int *erronp); int _nss_objc_getgrnam_r (const char *name, struct group *gr, char *buffer, size_t buflen, int *errnop); int _nss_objc_getgrgid_r (const gid_t gid, struct group *gr, char *buffer, size_t buflen, int *errnop); static int _nss_objc_client_initialize (void); static char *_nss_objc_copy_to_buffer (char **buffer, size_t *buflen, const char *string); static void _nss_objc_log (int err, const char *format, ...); static int _nss_objc_account_to_pwd (struct passwd *, void *, int *, char *, size_t); static int _nss_objc_account_to_spw (struct spwd *, void *, int *, char *, size_t); static int _nss_objc_group_to_grp (struct group *, void *, int *, char *, size_t); int _nss_objc_getpwuid_r (uid_t uid, struct passwd *pw, char *buffer, size_t buflen, int *errnop) { uid_t nUID = uid; int status; if (_nss_objc_client_initialize()) { return NSS_STATUS_NOTFOUND; } if (uid == 10000) status = _nss_objc_account_to_pwd(pw, NULL, errnop, buffer, buflen); else status = NSS_STATUS_NOTFOUND; return status; } int _nss_objc_setpwent (void) { __libc_lock_lock(lock); gnIdxPwd = 0; __libc_lock_unlock(lock); return NSS_STATUS_SUCCESS; } int _nss_objc_getpwent_r (struct passwd *pw, char *buffer, size_t buflen, int *errnop) { int status; __libc_lock_lock(lock); if (_nss_objc_client_initialize()) { __libc_lock_unlock(lock); return NSS_STATUS_NOTFOUND; } if (gnIdxPwd == 0) { status = _nss_objc_account_to_pwd(pw, NULL, errnop, buffer, buflen); gnIdxPwd++; } else status = NSS_STATUS_NOTFOUND; __libc_lock_unlock(lock); return status; } int _nss_objc_endpwent (void) { __libc_lock_lock(lock); gnIdxPwd = 0; __libc_lock_unlock(lock); return NSS_STATUS_SUCCESS; } int _nss_objc_getpwnam_r (const char *name, struct passwd *pw, char *buffer, size_t buflen, int *errnop) { int status; __libc_lock_lock(lock); if (_nss_objc_client_initialize()) { __libc_lock_unlock(lock); return NSS_STATUS_NOTFOUND; } if (strcmp(name, "testuser") == 0) status = _nss_objc_account_to_pwd(pw, NULL, errnop, buffer, buflen); else status = NSS_STATUS_NOTFOUND; __libc_lock_unlock(lock); return status; } int _nss_objc_getspnam_r (const char *name, struct spwd *spw, char *buffer, size_t buflen, int *errnop) { int status; __libc_lock_lock(lock); if (getuid() != 0) { __libc_lock_unlock(lock); return NSS_STATUS_NOTFOUND; } if (_nss_objc_client_initialize()) { return NSS_STATUS_NOTFOUND; } if (strcmp(name, "testuser") == 0) status = _nss_objc_account_to_spw(spw, NULL, errnop, buffer, buflen); else status = NSS_STATUS_NOTFOUND; __libc_lock_unlock(lock); return status; } int _nss_objc_setspent (void) { __libc_lock_lock(lock); gnIdxSpw = 0; __libc_lock_unlock(lock); return NSS_STATUS_SUCCESS; } int _nss_objc_getspent_r (struct spwd *spw, char *buffer, size_t buflen, int *errnop) { int status; __libc_lock_lock(lock); if (getuid() != 0) { __libc_lock_unlock(lock); return NSS_STATUS_NOTFOUND; } if (_nss_objc_client_initialize()) { return NSS_STATUS_NOTFOUND; } if (gnIdxSpw == 0) { status = _nss_objc_account_to_spw(spw, NULL, errnop, buffer, buflen); gnIdxSpw++; } else status = NSS_STATUS_NOTFOUND; __libc_lock_unlock(lock); return status; } int _nss_objc_endspent (void) { __libc_lock_lock(lock); gnIdxSpw = 0; __libc_lock_unlock(lock); return NSS_STATUS_SUCCESS; } static int _nss_objc_client_initialize (void) { static int bInitialized = 0; if (!bInitialized) { //mainPool = [[NSAutoreleasePool alloc] init]; bInitialized = 1; } return 0; } static char * _nss_objc_copy_to_buffer (char **buffer, size_t *buflen, const char *string) { size_t len = strlen(string) + 1; char *ptr; if (buflen && len > (*buflen)) { return NULL; } memcpy(*buffer, string, len); if (buflen) *buflen -= len; ptr = *buffer; (*buffer) += len; return ptr; } static void _nss_objc_log (int err, const char *format, ...) { static int openlog_ac = 0; va_list ap; va_start(ap, format); if (!openlog_ac) { ++openlog_ac; openlog("nss-objc", LOG_PID, LOG_AUTH); } vsyslog(err, format, ap); va_end(ap); closelog(); openlog_ac--; } static int _nss_objc_account_to_pwd (struct passwd *pw, void *pacnt, int *errnop, char *buffer, size_t buflen) { *errnop = ENOENT; pw->pw_name = _nss_objc_copy_to_buffer(&buffer, &buflen, "testuser"); if (!pw->pw_name) { *errnop = ERANGE; return NSS_STATUS_TRYAGAIN; } pw->pw_passwd = _nss_objc_copy_to_buffer(&buffer, &buflen, "x"); if (!pw->pw_passwd) { *errnop = ERANGE; return NSS_STATUS_TRYAGAIN; } pw->pw_uid = 10000; pw->pw_gid = 100; pw->pw_gecos = _nss_objc_copy_to_buffer(&buffer, &buflen, "Gecos"); if (!pw->pw_gecos) { *errnop = ERANGE; return NSS_STATUS_TRYAGAIN; } pw->pw_dir = _nss_objc_copy_to_buffer(&buffer, &buflen, "/tmp"); if (!pw->pw_dir) { *errnop = ERANGE; return NSS_STATUS_TRYAGAIN; } pw->pw_shell = _nss_objc_copy_to_buffer(&buffer, &buflen, "/bin/bash"); if (!pw->pw_shell) { *errnop = ERANGE; return NSS_STATUS_TRYAGAIN; } *errnop = 0; return NSS_STATUS_SUCCESS; } static int _nss_objc_account_to_spw (struct spwd *spw, void *pacnt, int *errnop, char *buffer, size_t buflen) { *errnop = ENOENT; spw->sp_namp = _nss_objc_copy_to_buffer(&buffer, &buflen, "testuser"); if (!spw->sp_namp) { *errnop = ERANGE; return NSS_STATUS_TRYAGAIN; } spw->sp_pwdp = _nss_objc_copy_to_buffer(&buffer, &buflen, "8ws.Mm8zU6fbU"); if (!spw->sp_pwdp) { *errnop = ERANGE; return NSS_STATUS_TRYAGAIN; } spw->sp_lstchg = 12459; spw->sp_min = 0; spw->sp_max = 99999; spw->sp_warn = 7; spw->sp_inact = -1; spw->sp_expire = -1; spw->sp_flag = -1; *errnop = 0; return NSS_STATUS_SUCCESS; } int _nss_objc_initgroups (const char *user, gid_t group, long *start, long int *size, gid_t *groups, long int limit, int *errnop) { return NSS_STATUS_SUCCESS; } int _nss_objc_setgrent (void) { gnIdxGrp = 0; return NSS_STATUS_SUCCESS; } int _nss_objc_endgrent (void) { gnIdxGrp = 0; return NSS_STATUS_SUCCESS; } int _nss_objc_getgrent_r (struct group *gr, char *buffer, size_t buflen, int *errnop) { int status; if (_nss_objc_client_initialize()) { return NSS_STATUS_NOTFOUND; } status = _nss_objc_group_to_grp(gr, NULL, errnop, buffer, buflen); return status; } int _nss_objc_getgrnam_r (const char *name, struct group *gr, char *buffer, size_t buflen, int *errnop) { int status; if (_nss_objc_client_initialize()) { return NSS_STATUS_NOTFOUND; } status = _nss_objc_group_to_grp(gr, NULL, errnop, buffer, buflen); return status; } int _nss_objc_getgrgid_r (const gid_t gid, struct group *gr, char *buffer, size_t buflen, int *errnop) { gid_t nGID = gid; int status; if (_nss_objc_client_initialize()) { return NSS_STATUS_NOTFOUND; } status = _nss_objc_group_to_grp(gr, NULL, errnop, buffer, buflen); return status; } static int _nss_objc_group_to_grp (struct group *gr, void *pgrp, int *errnop, char *buffer, size_t buflen) { char *pszMembers; char **members; char *pszMember; int n, i; char *pch; int stringOffset; *errnop = ENOENT; if (1) { return NSS_STATUS_NOTFOUND; } *errnop = 0; return NSS_STATUS_SUCCESS; }