コード例 #1
0
ファイル: nilib2.c プロジェクト: 9crk/EasyDarwin
ni_status ni2_mergedirprop(void *domain, ni_id *dir, const ni_name key, ni_namelist values)
{
    /* mergeprop given a directory rather than a pathname */

    ni_status ret;
    ni_property p;
    ni_namelist nl;
    ni_index where, whereval;
    int i;

    /* need to be talking to the master */
    ni_needwrite(domain, 1);

    /* fetch list of property keys from directory */
    NI_INIT(&nl);
    ret = ni_listprops(domain, dir, &nl);
    if (ret != NI_OK) {
        return ret;
    }

    /* check for existing property with this key */
    where = ni_namelist_match(nl, key);
    ni_namelist_free(&nl);

    /* if property doesn't exist, create it */
    if (where == NI_INDEX_NULL) {
        NI_INIT(&p);
        p.nip_name = ni_name_dup(key);
        p.nip_val = ni_namelist_dup(values);
        ret = ni_createprop(domain, dir, p, NI_INDEX_NULL);
        ni_prop_free(&p);
        return ret;
    }


    /* property exists: replace the existing values */
    /* fetch existing namelist for this property */
    NI_INIT(&nl);
    ret = ni_readprop(domain, dir, where, &nl);
    if (ret != NI_OK) {
        return ret;
    }

    /* merge new values */
    for (i = 0; i < values.ni_namelist_len; i++) {
        whereval = ni_namelist_match(nl, values.ni_namelist_val[i]);
        if (whereval == NI_INDEX_NULL) {
            ni_namelist_insert(&nl, values.ni_namelist_val[i], NI_INDEX_NULL);
        }
    }

    /* write the new list back */
    ret = ni_writeprop(domain, dir, where, nl);
    ni_namelist_free(&nl);
    return ret;
}
コード例 #2
0
ファイル: nilib2.c プロジェクト: 9crk/EasyDarwin
ni_status ni2_destroydirval(void *domain, ni_id *dir, const ni_name key, ni_namelist values)
{
    /* destroyval given a directory rather than a pathname */

    ni_status ret;
    ni_namelist nl;
    ni_index where, whereval;
    int i;

    /* need to be talking to the master */
    ni_needwrite(domain, 1);

    /* fetch list of property keys from directory */
    NI_INIT(&nl);
    ret = ni_listprops(domain, dir, &nl);
    if (ret != NI_OK) {
        return ret;
    }

    /* check for existing property with this key */
    where = ni_namelist_match(nl, key);
    ni_namelist_free(&nl);

    /* if property doesn't exist, nothing to do */
    if (where == NI_INDEX_NULL) {
        return NI_OK;
    }

    /* fetch existing namelist for this property */
    NI_INIT(&nl);
    ret = ni_readprop(domain, dir, where, &nl);
    if (ret != NI_OK) {
        return ret;
    }

    /* delete values */
    for (i = 0; i < values.ni_namelist_len; i++) {
        whereval = ni_namelist_match(nl, values.ni_namelist_val[i]);
        while (whereval != NI_INDEX_NULL) {
            ni_namelist_delete(&nl, whereval);
            whereval = ni_namelist_match(nl, values.ni_namelist_val[i]);
        }
    }

    /* write the new list back */
    ret = ni_writeprop(domain, dir, where, nl);
    ni_namelist_free(&nl);

    return ret;
}
コード例 #3
0
ファイル: pam_netinfo.c プロジェクト: OpenDarwin-CVS/SEDarwin
static int
secure_passwords()
{
	void           *d, *d1;
	int             status;
	ni_index        where;
	ni_id           dir;
	ni_namelist     nl;

	status = ni_open(NULL, ".", &d);
	while (status == NI_OK)
	{
		dir.nii_object = 0;
		status = ni_lookupprop(d, &dir, "security_options", &nl);
		if (status == NI_OK)
		{
			where = ni_namelist_match(nl, "secure_passwords");
			if (where != NI_INDEX_NULL)
			{
				ni_free(d);
				return 1;
			}
		}
		d1 = d;
		status = ni_open(d1, "..", &d);
		ni_free(d1);
	}

	return 0;
}
コード例 #4
0
ファイル: nilib2.c プロジェクト: 9crk/EasyDarwin
ni_status ni2_statpropdir(void *domain, ni_id *dir, const ni_name key, ni_index *where)
{
    /* statprop given a directory rather than a pathname */

    ni_status ret;
    ni_namelist nl;

    /* assume there's no match */
    *where = NI_INDEX_NULL;

    /* fetch list of property keys from directory */
    NI_INIT(&nl);
    ret = ni_listprops(domain, dir, &nl);
    if (ret != NI_OK) {
        return ret;
    }

    /* check for property with this key */
    *where = ni_namelist_match(nl, key);
    ni_namelist_free(&nl);

    /* if property doesn't exist, no match */
    if (*where == NI_INDEX_NULL) {
        return NI_NOPROP;
    }

    return NI_OK;
}
コード例 #5
0
ファイル: nilib2.c プロジェクト: 9crk/EasyDarwin
ni_status ni2_renamedirprop(void *domain, ni_id *dir, const ni_name oldname, const ni_name newname)
{
    /* renameprop given a directory rather than a pathname */

    ni_status ret;
    ni_index where;
    ni_namelist nl;

    /* need to be talking to the master */
    ni_needwrite(domain, 1);

    /* fetch list of property keys from directory */
    NI_INIT(&nl);
    ret = ni_listprops(domain, dir, &nl);
    if (ret != NI_OK) {
        return ret;
    }

    /* look up old name */
    where = ni_namelist_match(nl, oldname);
    ni_namelist_free(&nl);

    /* if it's not there, return an error */
    if (where == NI_INDEX_NULL) {
        return NI_NOPROP;
    }

    return ni_renameprop(domain, dir, where, newname);
}
コード例 #6
0
ファイル: nilib2.c プロジェクト: 9crk/EasyDarwin
ni_status ni2_statvaldir(void *domain, ni_id *dir, const ni_name key, const ni_name value, ni_index *where)
{
    /* statval given a directory rather than a pathname */

    ni_status ret;
    ni_namelist nl;
    ni_index wh;

    /* assume there's no match */
    *where = NI_INDEX_NULL;

    /* fetch list of property keys from directory */
    NI_INIT(&nl);
    ret = ni_listprops(domain, dir, &nl);
    if (ret != NI_OK) {
        return ret;
    }

    /* check for property with this key */
    wh = ni_namelist_match(nl, key);
    ni_namelist_free(&nl);

    /* if property doesn't exist, no match */
    if (wh == NI_INDEX_NULL) {
        return NI_NOPROP;
    }

    /* fetch existing namelist for this property */
    NI_INIT(&nl);
    ret = ni_readprop(domain, dir, wh, &nl);
    if (ret != NI_OK) {
        return ret;
    }

    /* check for this value */
    wh = ni_namelist_match(nl, value);
    ni_namelist_free(&nl);

    /* if value doesn't exist, no match */
    if (wh == NI_INDEX_NULL) {
        return NI_NONAME;
    }

    *where = wh;
    return NI_OK;
}
コード例 #7
0
ファイル: nilib2.c プロジェクト: 9crk/EasyDarwin
ni_status ni2_destroydirprop(void *domain, ni_id *dir, ni_namelist keys)
{
    /* destroyprop given a directory rather than a pathname */

    ni_status ret;
    ni_index where;
    ni_namelist nl;
    int i;

    /* need to be talking to the master */
    ni_needwrite(domain, 1);

    /* fetch list of property keys from directory */
    NI_INIT(&nl);
    ret = ni_listprops(domain, dir, &nl);
    if (ret != NI_OK) {
        return ret;
    }

    /* destroy all occurrences of each key */
    for (i = 0; i < keys.ni_namelist_len; i++) {

        where = ni_namelist_match(nl, keys.ni_namelist_val[i]);

        /* keep looking for all occurrences */
        while (where != NI_INDEX_NULL) {
            ret = ni_destroyprop(domain, dir, where);
            if (ret != NI_OK) {
                ni_namelist_free(&nl);
                return ret;
            }

            /* update the namelist */  
            ni_namelist_delete(&nl, where);
            where = ni_namelist_match(nl, keys.ni_namelist_val[i]);
        }
    }
    ni_namelist_free(&nl);
    return NI_OK;
}
コード例 #8
0
ファイル: nilib2.c プロジェクト: 9crk/EasyDarwin
void nipl_mergeprop(ni_proplist *l, const ni_name n, const ni_name v)
{
    /* property list utility */
    /* merge a value into a property in a property list */

    ni_index where;

    where = ni_proplist_match(*l, n, NULL);
    if (where == NI_INDEX_NULL) {
        nipl_createprop(l, n);
        where = ni_proplist_match(*l, n, NULL);
    }
    where = ni_namelist_match(l->nipl_val[where].nip_val, v);
    if (where == NI_INDEX_NULL) {
        ni_namelist_insert(&(l->nipl_val[where].nip_val), v, NI_INDEX_NULL);
    }
}
コード例 #9
0
ファイル: nilib2.c プロジェクト: 9crk/EasyDarwin
ni_status ni2_reappropdir(void *domain, ni_id *dir, const ni_name key)
{
    /* reapprop given a directory rather than a pathname */

    ni_status ret;
    ni_namelist nl;
    ni_index where;

    /* fetch list of property keys from directory */
    NI_INIT(&nl);
    ret = ni_listprops(domain, dir, &nl);
    if (ret != NI_OK) {
        return ret;
    }

    /* check for property with this key */
    where = ni_namelist_match(nl, key);
    ni_namelist_free(&nl);

    /* if property doesn't exist, return */
    if (where == NI_INDEX_NULL) {
        return NI_OK;
    }

    /* fetch existing namelist for this property */
    NI_INIT(&nl);
    ret = ni_readprop(domain, dir, where, &nl);
    if (ret != NI_OK) {
        return ret;
    }

    /* if the property contains any values, leave it alone */
    if (nl.ni_namelist_len > 0) {
        ni_namelist_free(&nl);
        return NI_OK;
    }

    /* property is empty, delete it */
    ni_namelist_free(&nl);
    return ni_destroyprop(domain, dir, where);
}
コード例 #10
0
ファイル: nilib2.c プロジェクト: 9crk/EasyDarwin
ni_status ni2_createdirprop(void *domain, ni_id *dir, const ni_name key, ni_namelist values)
{
    /* createprop given a directory rather than a pathname */

    ni_status ret;
    ni_property p;
    ni_namelist nl;
    ni_index where;

    /* need to be talking to the master */
    ni_needwrite(domain, 1);

    /* fetch list of property keys from directory */
    NI_INIT(&nl);
    ret = ni_listprops(domain, dir, &nl);
    if (ret != NI_OK) {
        return ret;
    }

    /* check for existing property with this key */
    where = ni_namelist_match(nl, key);
    ni_namelist_free(&nl);

    /* if property doesn't exist, create it */
    if (where == NI_INDEX_NULL) {
        NI_INIT(&p);
        p.nip_name = ni_name_dup(key);
        p.nip_val = ni_namelist_dup(values);
        ret = ni_createprop(domain, dir, p, NI_INDEX_NULL);
        ni_prop_free(&p);
        return ret;
    }

    /* property exists: replace the existing values */
    ret = ni_writeprop(domain, dir, where, values);
    return ret;
}
コード例 #11
0
ファイル: sanitycheck.c プロジェクト: OpenDarwin-CVS/SEDarwin
ni_status checkserves(unsigned long masteraddr, ni_name mastertag, unsigned long myaddr, ni_name mytag)
{
	struct sockaddr_in mastersin;
	struct in_addr myinaddr;
	char myserves[MAXPATHLEN + 16];
	ni_index where;
	int status;
	int sock;
	CLIENT *cl;
	struct timeval tv;
	nibind_getregister_res res;
	ni_id_res id_res;
	ni_lookup_res lu_res;
	ni_lookup_args childdir;
	ni_namelist_res prop_res;
	ni_prop_args pa;

	mastersin.sin_addr.s_addr = masteraddr;
	mastersin.sin_port = 0;
	mastersin.sin_family = AF_INET;

	myinaddr.s_addr = myaddr;

	/* connect to master hosts's nibindd */
	sock = socket_connect(&mastersin, NIBIND_PROG, NIBIND_VERS);
	if (sock < 0)
	{
		system_log(LOG_WARNING,
			"sanitycheck can't connect to %s/%s - %m",
			inet_ntoa(mastersin.sin_addr), mastertag);
		return NI_FAILED;
	}
	FD_SET(sock, &clnt_fdset);	/* protect client socket */
	cl = clnttcp_create(&mastersin, NIBIND_PROG, NIBIND_VERS, &sock, 0, 0);
	if (cl == NULL) {
		socket_close(sock);
		FD_CLR(sock, &clnt_fdset);	/* unprotect client socket */
		return NI_FAILED;
	}
	tv.tv_sec = READALL_TIMEOUT;
	tv.tv_usec = 0;

	/* get the ports for master's tag */
	bzero((char *)&res, sizeof(res));
	if (clnt_call(cl, NIBIND_GETREGISTER,
			xdr_ni_name, &mastertag, 
			xdr_nibind_getregister_res, &res, tv) != RPC_SUCCESS) {
		/* call failed */
		socket_lock();
		clnt_destroy(cl);
		(void)close(sock);
		socket_unlock();
		FD_CLR(sock, &clnt_fdset);	/* unprotect client socket */
		return NI_FAILED;
	}
	socket_lock();
	clnt_destroy(cl);
	(void)close(sock);
	socket_unlock();
	FD_CLR(sock, &clnt_fdset);	/* unprotect client socket */

	if (res.status != NI_OK) {
		/* no server for the master's tag */
		system_log(LOG_ERR,
			"tag %s: master's tag %s is not served at master's addresss",
			mytag, mastertag);
		return res.status;
	}

	/* connect to the master */
	mastersin.sin_port = htons(res.nibind_getregister_res_u.addrs.tcp_port);
	xdr_free(xdr_nibind_getregister_res, (void *)&res);
	sock = socket_connect(&mastersin, NI_PROG, NI_VERS);
	if (sock < 0) {
		system_log(LOG_WARNING, "sanitycheck can't connect to "
		       "%s/%s - %m",
		       inet_ntoa(mastersin.sin_addr), mastertag);
		return NI_FAILED;
	}
	FD_SET(sock, &clnt_fdset);	/* protect client socket */
	cl = clnttcp_create(&mastersin, NI_PROG, NI_VERS, &sock, 0, 0);
	if (cl == NULL) {
		/* can't connect to master */
		socket_close(sock);
		FD_CLR(sock, &clnt_fdset);	/* unprotect client socket */
		return NI_FAILED;
	}
	FD_SET(sock, &clnt_fdset);	/* protect client socket */

	/* get root directory */
	bzero((char *)&id_res, sizeof(id_res));
	status = clnt_call(cl, _NI_ROOT,
		xdr_void, NULL, xdr_ni_id_res, &id_res, tv);
	if (status != NI_OK) {
		/* can't get root! */
		socket_lock();
		clnt_destroy(cl);
		(void)close(sock);
		socket_unlock();
		FD_CLR(sock, &clnt_fdset);	/* unprotect client socket */
		system_log(LOG_ERR,
			"tag %s: can't get master's root directory",
			mytag);
		return status;
	}
	if (id_res.status != NI_OK) {
		/* can't get root! */
		socket_lock();
		clnt_destroy(cl);
		(void)close(sock);
		socket_unlock();
		FD_CLR(sock, &clnt_fdset);	/* unprotect client socket */
		system_log(LOG_ERR,
			"tag %s: master has no root directory",
			mytag);
		return status;
	}

	childdir.key = malloc(16);
	childdir.value = malloc(16);

	/* get machines subdirectory */
	childdir.id = id_res.ni_id_res_u.id;
	xdr_free(xdr_ni_id_res, (void *)&id_res);
	strcpy(childdir.key,"name");
	strcpy(childdir.value,"machines");

	bzero((char *)&lu_res, sizeof(lu_res));
	status = clnt_call(cl, _NI_LOOKUP,
		xdr_ni_lookup_args, &childdir, xdr_ni_lookup_res, &lu_res, tv);
	if (status != NI_OK) {
		/* can't get /machines! */
		free(childdir.key);
		free(childdir.value);
		socket_lock();
		clnt_destroy(cl);
		(void)close(sock);
		socket_unlock();
		FD_CLR(sock, &clnt_fdset);	/* unprotect client socket */
		system_log(LOG_ERR,
			"tag %s: can't get master's /machines directory",
			mytag);
		return status;
	}
	if (lu_res.status != NI_OK) {
		/* no /machines! */
		free(childdir.key);
		free(childdir.value);
		socket_lock();
		clnt_destroy(cl);
		(void)close(sock);
		socket_unlock();
		FD_CLR(sock, &clnt_fdset);	/* unprotect client socket */
		system_log(LOG_ERR,
			"tag %s: can't get master's /machines directory",
			mytag);
		return lu_res.status;
	}
	if (lu_res.ni_lookup_res_u.stuff.idlist.ni_idlist_len == 0) {
		/* no /machines! */
		xdr_free(xdr_ni_lookup_res, (void *)&lu_res);
		free(childdir.key);
		free(childdir.value);
		socket_lock();
		clnt_destroy(cl);
		(void)close(sock);
		socket_unlock();
		FD_CLR(sock, &clnt_fdset);	/* unprotect client socket */
		system_log(LOG_ERR,
			"tag %s: master has no /machines directory",
			mytag);
		return NI_NODIR;
	}

	/* get my subdirectory */
	childdir.id.nii_object = lu_res.ni_lookup_res_u.stuff.idlist.ni_idlist_val[0];
	xdr_free(xdr_ni_lookup_res, (void *)&lu_res);
	strcpy(childdir.key,"ip_address");
	strcpy(childdir.value,(char *)inet_ntoa(myinaddr));

	bzero((char *)&lu_res, sizeof(lu_res));
	status = clnt_call(cl, _NI_LOOKUP,
		xdr_ni_lookup_args, &childdir, xdr_ni_lookup_res, &lu_res, tv);
	if (status != NI_OK) {
		/* can't get /machines/ip_address=<myaddr>! */
		free(childdir.key);
		free(childdir.value);
		socket_lock();
		clnt_destroy(cl);
		(void)close(sock);
		socket_unlock();
		FD_CLR(sock, &clnt_fdset);	/* unprotect client socket */
		system_log(LOG_ERR,
			"tag %s: can't get master's /machines/ip_address=%s directory",
			mytag,(char *)inet_ntoa(myinaddr));
		return status;
	}
	if (lu_res.status != NI_OK) {
		/* no /machines! */
		free(childdir.key);
		free(childdir.value);
		socket_lock();
		clnt_destroy(cl);
		(void)close(sock);
		socket_unlock();
		FD_CLR(sock, &clnt_fdset);	/* unprotect client socket */
		system_log(LOG_ERR,
			"tag %s: can't get master's /machines/ip_address=%s directory",
			mytag,(char *)inet_ntoa(myinaddr));
		return lu_res.status;
	}
	if (lu_res.ni_lookup_res_u.stuff.idlist.ni_idlist_len == 0) {
		/* can't get /machines/ip_address=<myaddr>! */
		xdr_free(xdr_ni_lookup_res, (void *)&lu_res);
		free(childdir.key);
		free(childdir.value);
		socket_lock();
		clnt_destroy(cl);
		(void)close(sock);
		socket_unlock();
		FD_CLR(sock, &clnt_fdset);	/* unprotect client socket */
		system_log(LOG_ERR,
			"tag %s: master has no /machines/ip_address=%s directory",
			mytag,(char *)inet_ntoa(myinaddr));
		return NI_NODIR;
	}

	/* list properties */
	prop_res.ni_namelist_res_u.stuff.values.ni_namelist_val = NULL;
	childdir.id.nii_object = lu_res.ni_lookup_res_u.stuff.idlist.ni_idlist_val[0];
	xdr_free(xdr_ni_lookup_res, (void *)&lu_res);
	bzero((char *)&prop_res, sizeof(prop_res));
	status = clnt_call(cl, _NI_LISTPROPS,
		xdr_ni_id, &childdir.id, xdr_ni_namelist_res, &prop_res, tv);
	if (status != NI_OK) {
		/* can't get proplist! */
		free(childdir.key);
		free(childdir.value);
		socket_lock();
		clnt_destroy(cl);
		(void)close(sock);
		socket_unlock();
		FD_CLR(sock, &clnt_fdset);	/* unprotect client socket */
		system_log(LOG_ERR,
			"tag %s: can't get master's property list for /machines/ip_address=%s",
			mytag,(char *)inet_ntoa(myinaddr));
		return status;
	}
	free(childdir.key);
	free(childdir.value);

	if (prop_res.status != NI_OK) {
		/* no /machines! */
		socket_lock();
		clnt_destroy(cl);
		(void)close(sock);
		socket_unlock();
		FD_CLR(sock, &clnt_fdset);	/* unprotect client socket */
		system_log(LOG_ERR,
			"tag %s: can't get master's property list for /machines/ip_address=%s",
			mytag,(char *)inet_ntoa(myinaddr));
		return prop_res.status;
	}
	if (prop_res.ni_namelist_res_u.stuff.values.ni_namelist_len == 0) {
		/* can't get proplist! */
		xdr_free(xdr_ni_namelist_res, (void *)&prop_res);
		socket_lock();
		clnt_destroy(cl);
		(void)close(sock);
		socket_unlock();
		FD_CLR(sock, &clnt_fdset);	/* unprotect client socket */
		system_log(LOG_ERR,
			"tag %s: master has no property list for /machines/ip_address=%s",
			mytag,(char *)inet_ntoa(myinaddr));
		return NI_NOPROP;
	}

	/* find "serves" property */
	where = ni_namelist_match(prop_res.ni_namelist_res_u.stuff.values, "serves");
	xdr_free(xdr_ni_namelist_res, (void *)&prop_res);
	if (where == NI_INDEX_NULL) {
		/* no serves property! */
		socket_lock();
		clnt_destroy(cl);
		(void)close(sock);
		socket_unlock();
		FD_CLR(sock, &clnt_fdset);	/* unprotect client socket */
		system_log(LOG_ERR,
			"tag %s: master has no serves property for /machines/ip_address=%s",
			mytag,(char *)inet_ntoa(myinaddr));
		return NI_NOPROP;
	}

	/* fetch serves property */
	pa.id = childdir.id;

	pa.prop_index = where;
	bzero((char *)&prop_res, sizeof(prop_res));
	status = clnt_call(cl, _NI_READPROP,
		xdr_ni_prop_args, &pa, xdr_ni_namelist_res, &prop_res, tv);
	if (status != NI_OK) {
		/* can't get proplist! */
		socket_lock();
		clnt_destroy(cl);
		(void)close(sock);
		socket_unlock();
		FD_CLR(sock, &clnt_fdset);	/* unprotect client socket */
		system_log(LOG_ERR,
			"tag %s: can't get master's serves property for /machines/ip_address=%s",
			mytag,(char *)inet_ntoa(myinaddr));
		return status;
	}
	if (prop_res.status != NI_OK) {
		/* can't get proplist! */
		socket_lock();
		clnt_destroy(cl);
		(void)close(sock);
		socket_unlock();
		FD_CLR(sock, &clnt_fdset);	/* unprotect client socket */
		system_log(LOG_ERR,
			"tag %s: can't get master's serves property for /machines/ip_address=%s",
			mytag,(char *)inet_ntoa(myinaddr));
		return prop_res.status;
	}
	if (prop_res.ni_namelist_res_u.stuff.values.ni_namelist_len == 0) {
		/* no values in serves property! */
		xdr_free(xdr_ni_namelist_res, (void *)&prop_res);
		socket_lock();
		clnt_destroy(cl);
		(void)close(sock);
		socket_unlock();
		FD_CLR(sock, &clnt_fdset);	/* unprotect client socket */
		system_log(LOG_ERR,
			"tag %s: master has no values for serves property in /machines/ip_address=%s",
			mytag,(char *)inet_ntoa(myinaddr));
		return NI_NOPROP;
	}

	/* find my "serves" property */
	sprintf(myserves, "./%s", mytag);
	where = ni_namelist_match(prop_res.ni_namelist_res_u.stuff.values, myserves);
	xdr_free(xdr_ni_namelist_res, (void *)&prop_res);

	if (where == NI_INDEX_NULL) {
		/* no serves property! */
		socket_lock();
		clnt_destroy(cl);
		(void)close(sock);
		socket_unlock();
		FD_CLR(sock, &clnt_fdset);	/* unprotect client socket */
		system_log(LOG_ERR,
			"tag %s: master has no serves ./%s property in /machines/ip_address=%s",
			mytag,mytag,(char *)inet_ntoa(myinaddr));
		return NI_NONAME;
	}
	
	socket_lock();
	clnt_destroy(cl);
	(void)close(sock);
	socket_unlock();
	FD_CLR(sock, &clnt_fdset);	/* unprotect client socket */
	return NI_OK;
}
コード例 #12
0
ファイル: nibind_main.c プロジェクト: OpenDarwin-CVS/SEDarwin
int
main(int argc, char *argv[])
{
	SVCXPRT *utransp, *ttransp;
	struct sockaddr_in addr;
	DIR *dp;
	struct direct *d;
	ni_name tag = NULL;
	ni_namelist nl;
	ni_index i;
	int pid, localonly, nctoken = -1;
	int log_pri = LOG_NOTICE;
	struct rlimit rlim;
	char *netinfod_argv[16]; /* XXX */
	int netinfod_argc, x;
	union wait wait_stat;
	pid_t child_pid;
	char *pri;
#ifdef _UNIX_BSD_43_
	int ttyfd;
#endif

	localonly = 1;

	netinfod_argc = 0;
	netinfod_argv[netinfod_argc++] = (char *)NETINFO_PROG;

	debug = 0;

	for (i = 1; i < argc; i++)
	{
		if (!strcmp(argv[i], "-n"))
		{
			netinfod_argv[netinfod_argc++] = argv[i];
		}

		if (!strcmp(argv[i], "-d"))
		{
			debug = 1;
			log_pri = LOG_DEBUG;
			if ((argc > (i+1)) && (argv[i+1][0] != '-'))
				debug = atoi(argv[++i]);
		}

		if (!strcmp(argv[i], "-l"))
		{
			if ((argc > (i+1)) && (argv[i+1][0] != '-'))
				log_pri = atoi(argv[++i]);
		}

		if (!strcmp(argv[i], "-D"))
		{
			netinfod_argv[netinfod_argc++] = "-d";

			if ((argc > (i+1)) && (argv[i+1][0] != '-'))
			{
				netinfod_argv[netinfod_argc++] = argv[i];
			}
		}

		if (!strcmp(argv[i], "-L"))
		{
			netinfod_argv[netinfod_argc++] = "-l";

			if ((argc > (i+1)) && (argv[i+1][0] != '-'))
			{
				netinfod_argv[netinfod_argc++] = argv[i];
			}
			else
			{
				pri = malloc(sizeof("999"));
				sprintf(pri, "%d", LOG_DEBUG);
				netinfod_argv[netinfod_argc++] = pri;
			}
		}
	}

	if (debug == 1)
	{
		system_log_open("nibindd", LOG_NDELAY | LOG_PID, LOG_NETINFO, stderr);
		system_log_set_max_priority(log_pri);
		system_log(LOG_DEBUG, "version %s - debug mode\n", _PROJECT_VERSION_);
	}
	else
	{
		closeall();
		system_log_open("nibindd", LOG_NDELAY | LOG_PID, LOG_NETINFO, NULL);
		system_log_set_max_priority(log_pri);
		system_log(LOG_DEBUG, "version %s - starting\n", _PROJECT_VERSION_);

		child_pid = fork();
		if (child_pid == -1)
		{
			system_log(LOG_ALERT, "fork() failed: %m, aborting");
			system_log_close();
			exit(1);
		}
		else if (child_pid > 0)
		{
			signal(SIGTERM, parentexit);
			system_log(LOG_DEBUG, "parent waiting for child to start");
			wait4(child_pid, (_WAIT_TYPE_ *)&wait_stat, 0, 0);

			if (WIFEXITED(wait_stat))
			{
				system_log(LOG_DEBUG,
					"unexpected child exit, status=%d",
					WEXITSTATUS(wait_stat));
			}
			else
			{
				system_log(LOG_DEBUG,
					"unexpected child exit, received signal=%d",
					WTERMSIG(wait_stat));
			}
			system_log_close();
			exit(1);
		}
	}

	restart = 0;

	rlim.rlim_cur = rlim.rlim_max = RLIM_INFINITY;
	setrlimit(RLIMIT_CORE, &rlim);
	signal(SIGCHLD, catchchild);
	signal(SIGTERM, killchildren);
	signal(SIGHUP, catchhup);
	signal(SIGINT, SIG_IGN);

	notify_register_signal(NETWORK_CHANGE_NOTIFICATION, SIGHUP, &nctoken);

	writepid();

	/*
	 * cd to netinfo directory, find out which databases should
	 * be served and lock the directory before registering service.
	 */
	if (chdir(NETINFO_DIR) < 0)
	{
		killparent();
		system_log(LOG_ALERT, "cannot chdir to netinfo directory");
		exit(1);
	}

	dp = opendir(NETINFO_DIR);
	if (dp == NULL)
	{
		killparent();
		system_log(LOG_ALERT, "cannot open netinfo directory");
		exit(1);
	}

	MM_ZERO(&nl);
	while ((d = readdir(dp)))
	{
		if (isnidir(d->d_name, &tag))
		{
			if (ni_namelist_match(nl, tag) == NI_INDEX_NULL)
			{
				system_log(LOG_DEBUG, "found database: %s", tag);
				ni_namelist_insert(&nl, tag, NI_INDEX_NULL);
				if (strcmp(tag, "local")) localonly = 0;
			} 
			ni_name_free(&tag);
		}
	}

#ifdef _NETINFO_FLOCK_
	/*
	 * Do not close the directory: keep it locked so another nibindd
	 * won't run.
	 */
	if (flock(dp->dd_fd, LOCK_EX|LOCK_NB) < 0)
	{
		killparent();
		system_log(LOG_ALERT, "nibindd already running");
		exit(1);
	}
	fcntl(dp->dd_fd, F_SETFD, 1);
#else
	closedir(dp);
#endif

	/*
	 * Register as a SUNRPC service
	 */
	memset(&addr, 0, sizeof(struct sockaddr_in));
	addr.sin_family = AF_INET;
	if (localonly == 1) addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);

	pmap_unset(NIBIND_PROG, NIBIND_VERS);
	utransp = svcudp_bind(RPC_ANYSOCK, addr);
	if (utransp == NULL)
	{
		killparent();
		system_log(LOG_ALERT, "cannot start udp service");
		exit(1);
	}

	if (!svc_register(utransp, NIBIND_PROG, NIBIND_VERS, nibind_prog_1, IPPROTO_UDP))
	{
		killparent();
		system_log(LOG_ALERT, "cannot register udp service");
		exit(1);
	}

	udp_sock = utransp->xp_sock;

	ttransp = svctcp_bind(RPC_ANYSOCK, addr, 0, 0);
	if (ttransp == NULL)
	{
		killparent();
		system_log(LOG_ALERT, "cannot start tcp service");
		exit(1);
	}

	if (!svc_register(ttransp, NIBIND_PROG, NIBIND_VERS, nibind_prog_1, IPPROTO_TCP))
	{
		killparent();
		system_log(LOG_ALERT, "cannot register tcp service");
		exit(1);
	}

	waitreg = 0;
	for (i = 0; i < nl.ninl_len; i++)
	{
		netinfod_argv[netinfod_argc] = nl.ninl_val[i];
		netinfod_argv[netinfod_argc + 1] = NULL;

		system_log(LOG_DEBUG, "starting netinfod %s", nl.ninl_val[i]);
		system_log(LOG_DEBUG, "execv debug 0: %s", NETINFO_PROG);
		for (x = 0; netinfod_argv[x] != NULL; x++)
		{
			system_log(LOG_DEBUG, "execv debug %d: %s", x, netinfod_argv[x]);
		}

		pid = fork();
		if (pid == 0)
		{
			/* child */
			execv(NETINFO_PROG, netinfod_argv);
			exit(-1);
		}

#ifdef DEBUG
		system_log(LOG_DEBUG, "netinfod %s pid = %d", nl.ninl_val[i], pid);
#endif

		if (pid > 0)
		{
			waitreg++;
			storepid(pid, nl.ninl_val[i]);
		}
		else
		{
			system_log(LOG_ERR, "server for tag %s failed to start", nl.ninl_val[i]);
		}
	}

	ni_namelist_free(&nl);
		
	/*
	 * Detach from controlling tty.
	 * Do this AFTER starting netinfod so "type c to continue..." works.
	 */
#ifdef _UNIX_BSD_43_
	ttyfd = open("/dev/tty", O_RDWR, 0);
	if (ttyfd > 0)
	{
		ioctl(ttyfd, TIOCNOTTY, NULL);
		close(ttyfd);
	}

	setpgrp(0, getpid());
#else
	if (setsid() < 0) syslog(LOG_ERR, "nibindd: setsid() failed: %m");
#endif

	system_log(LOG_DEBUG, "starting RPC service");

	nibind_svc_run();
	system_log(LOG_ALERT, "svc_run returned");
	system_log_close();
	exit(1);
}