/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <stdio.h>
#include <stdlib.h>
#include <stropts.h>
#include <signal.h>
#include <fcntl.h>
#include <door.h>
#include <thread.h>
#include <priv_utils.h>
#include <locale.h>
#include <strings.h>
#include <syslog.h>
#include <unistd.h>
#include <nfs/nfsid_map.h>
#include <rpcsvc/daemon_utils.h>
#include <errno.h>
#include <pwd.h>
#include <grp.h>
char *, int);
char *, int);
/*
* seconds to cache nfsmapid domain info
*/
extern void check_domain(int);
extern void idmap_kcall(int);
extern void open_diag_file(void);
static char *MyName;
/*
* nfscfg_domain_tmout is used by nfsv4-test scripts to query
* the nfsmapid daemon for the proper timeout. Don't delete !
*/
/*
* Processing for daemonization
*/
static void
daemonize(void)
{
switch (fork()) {
case -1:
perror("nfsmapid: can't fork");
exit(2);
/* NOTREACHED */
case 0: /* child */
break;
default: /* parent */
_exit(0);
}
if (chdir("/") < 0)
/*
* Close stdin, stdout, and stderr.
* Open again to redirect input+output
*/
(void) close(0);
(void) close(1);
(void) close(2);
(void) dup(1);
(void) setsid();
}
/* ARGSUSED */
static void *
{
int ret;
(void) sigemptyset(&sigset);
#ifdef DEBUG
#endif
/*CONSTCOND*/
while (1) {
/*
* EAGAIN: no signals arrived during timeout.
*/
check_domain(0);
continue;
}
case SIGHUP:
check_domain(1);
break;
#ifdef DEBUG
case SIGINT:
exit(0);
#endif
case SIGTERM:
default:
}
}
}
/*NOTREACHED*/
return (NULL);
}
/*
* Thread initialization. Mask out all signals we want our
* signal handler to handle for us from any other threads.
*/
static void
thr_init(void)
{
/*
* Before we kick off any other threads, mask out desired
* signals from main thread so that any subsequent threads
* don't receive said signals.
*/
#ifdef DEBUG
#endif
/*
* Create the signal handler thread suspended ! We do things
* this way at setup time to minimize the probability of
* introducing any race conditions _if_ the process were to
* get a SIGHUP signal while creating a new DNS query thread
* in get_dns_txt_domain().
*/
gettext("Failed to create signal handling thread"));
exit(4);
}
}
static void
daemon_init(void)
{
char *pwd_buf;
char *grp_buf;
/*
*/
/*
* MT initialization is done first so that if there is the
* need to fire an additional thread to continue to query
* DNS, that thread is started off with the main thread's
* sigmask.
*/
thr_init();
/*
* Determine nfsmapid domain.
*/
check_domain(0);
/*
* In the case of nfsmapid running diskless, it is important
* to get the initial connections to the nameservices
* established to prevent problems like opening a devfs
* node to contact a nameservice being blocked by the
* resolution of an active devfs lookup.
* First issue a set*ent to "open" the databases and then
* get an entry and finally lookup a bogus entry to trigger
* any lazy opens.
*/
setpwent();
setgrent();
(void) getpwent();
(void) getgrent();
return;
return;
}
}
static int
start_svcs(void)
{
#ifdef DEBUG
int dfd;
#endif
return (1);
}
#ifdef DEBUG
/*
* Create a file system path for the door
*/
return (1);
}
/*
* Clean up any stale associations
*/
(void) fdetach(NFSMAPID_DOOR);
/*
* Register in namespace to pass to the kernel to door_ki_open
*/
return (1);
}
#endif
/*
* Now that we're actually running, go
* ahead and flush the kernel flushes
* Pass door name to kernel for door_ki_open
*/
/*
* Wait for incoming calls
*/
/*CONSTCOND*/
while (1)
(void) pause();
return (10);
}
/* ARGSUSED */
int
{
(void) textdomain(TEXT_DOMAIN);
/* _check_services() framework setup */
/*
*/
/*
* Initialize the daemon to basic + sys_nfs
*/
#ifndef DEBUG
"missing\n"), MyName);
exit(1);
}
#endif
/*
* Take away a subset of basic, while this is not the absolute
* minimum, it is important that it is unique among other
* daemons to insure that we get a unique cred that will
* result in a unique open_owner. If not, we run the risk
* of a diskless client deadlocking with a thread holding
* the open_owner seqid lock while upcalling the daemon.
* XXX This restriction will go away once we stop holding
* XXX open_owner lock across rfscalls!
*/
(char *)NULL);
#ifndef DEBUG
daemonize();
switch (_enter_daemon_lock(NFSMAPID)) {
case 0:
break;
case -1:
exit(3);
default:
/* daemon was already running */
exit(0);
}
#endif
/* Initialize daemon subsystems */
daemon_init();
/* start services */
return (start_svcs());
}