#undef NIS
#include "mt.h"
#include "rpc_mt.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <ctype.h>
#include <string.h>
#include <syslog.h>
#include <sys/param.h>
#include <rpc/rpc.h>
#include <rpcsvc/nis.h>
#include <rpcsvc/nis_dhext.h>
#include <nsswitch.h>
#include <syslog.h>
#include <errno.h>
#ifndef MAXHOSTNAMELEN
#define MAXHOSTNAMELEN 256
#endif
#ifndef NGROUPS
#define NGROUPS 16
#endif
#define NOBODY_UID 60001
extern int getdomainname();
extern int key_call();
#define OPSYS_LEN 4
static const char *OPSYS = "unix";
#define DEF_ACTION {__NSW_RETURN, __NSW_RETURN, __NSW_CONTINUE, __NSW_CONTINUE}
static struct __nsw_lookup lookup_files = {"files", DEF_ACTION, NULL, NULL},
lookup_nis = {"nis", DEF_ACTION, NULL, &lookup_files};
static struct __nsw_switchconfig publickey_default =
{0, "publickey", 2, &lookup_nis};
static mutex_t serialize_netname = ERRORCHECKMUTEX;
#define MAXIPRINT (11)
static int
user2netname_nis(int *err, char netname[MAXNETNAMELEN + 1], uid_t uid,
char *domain)
{
int i;
char *dfltdom;
if (domain == NULL) {
if (__rpc_get_default_domain(&dfltdom) != 0) {
*err = __NSW_UNAVAIL;
return (0);
}
domain = dfltdom;
}
if ((strlen(domain) + OPSYS_LEN + 3 + MAXIPRINT) >
(size_t)MAXNETNAMELEN) {
*err = __NSW_UNAVAIL;
return (0);
}
(void) snprintf(netname, MAXNETNAMELEN + 1,
"%s.%d@%s", OPSYS, (int)uid, domain);
i = strlen(netname);
if (netname[i-1] == '.')
netname[i-1] = '\0';
*err = __NSW_SUCCESS;
return (1);
}
int
getnetname(char *name)
{
uid_t uid;
uid = geteuid();
if (uid == 0)
return (host2netname(name, NULL, NULL));
return (user2netname(name, uid, NULL));
}
int
__getnetnamebyuid(char name[MAXNETNAMELEN + 1], uid_t uid)
{
if (uid == 0)
return (host2netname(name, NULL, NULL));
return (user2netname(name, uid, NULL));
}
int
user2netname(char *netname, const uid_t uid, const char *domain)
{
struct __nsw_switchconfig *conf;
struct __nsw_lookup *look;
int needfree = 1, res = 0;
enum __nsw_parse_err perr;
int err;
if (uid == NOBODY_UID) {
(void) strlcpy(netname, "nobody", MAXNETNAMELEN + 1);
return (1);
}
netname[0] = '\0';
if (mutex_lock(&serialize_netname) == EDEADLK) {
(void) strlcpy(netname, "nobody", MAXNETNAMELEN + 1);
return (1);
}
conf = __nsw_getconfig("publickey", &perr);
if (!conf) {
conf = &publickey_default;
needfree = 0;
}
for (look = conf->lookups; look; look = look->next) {
if (strcmp(look->service_name, "ldap") == 0 ||
strcmp(look->service_name, "nis") == 0 ||
strcmp(look->service_name, "files") == 0)
res = user2netname_nis(&err,
netname, uid, (char *)domain);
else {
syslog(LOG_INFO,
"user2netname: unknown nameservice \
for publickey info '%s'\n",
look->service_name);
err = __NSW_UNAVAIL;
}
switch (look->actions[err]) {
case __NSW_CONTINUE :
break;
case __NSW_RETURN :
if (needfree)
(void) __nsw_freeconfig(conf);
(void) mutex_unlock(&serialize_netname);
return (res);
default :
syslog(LOG_ERR,
"user2netname: Unknown action for nameservice '%s'",
look->service_name);
}
}
if (needfree)
(void) __nsw_freeconfig(conf);
(void) mutex_unlock(&serialize_netname);
return (0);
}
int
host2netname(char *netname, const char *host, const char *domain)
{
char *p;
char hostname[MAXHOSTNAMELEN + 1];
char domainname[MAXHOSTNAMELEN + 1];
char *dot_in_host;
int i;
size_t len;
netname[0] = '\0';
if (host == NULL) {
(void) strncpy(hostname, nis_local_host(), sizeof (hostname));
p = (char *)strchr(hostname, '.');
if (p) {
*p++ = '\0';
if (domain == NULL) {
domain = p;
}
}
} else {
len = strlen(host);
if (len >= sizeof (hostname)) {
return (0);
}
(void) strcpy(hostname, host);
}
dot_in_host = (char *)strchr(hostname, '.');
if (domain == NULL) {
p = dot_in_host;
if (p) {
p = (char *)nis_domain_of(hostname);
len = strlen(p);
if (len >= sizeof (domainname)) {
return (0);
}
(void) strcpy(domainname, p);
} else {
domainname[0] = '\0';
if (getdomainname(domainname, MAXHOSTNAMELEN) < 0)
return (0);
}
} else {
len = strlen(domain);
if (len >= sizeof (domainname)) {
return (0);
}
(void) strcpy(domainname, domain);
}
i = strlen(domainname);
if (i == 0)
return (0);
if (domainname[i - 1] == '.')
domainname[i - 1] = 0;
if (dot_in_host) {
*dot_in_host = '\0';
}
if ((strlen(domainname) + strlen(hostname) + OPSYS_LEN + 3)
> (size_t)MAXNETNAMELEN) {
return (0);
}
(void) snprintf(netname, MAXNETNAMELEN + 1,
"%s.%s@%s", OPSYS, hostname, domainname);
return (1);
}