static char *getNISserver(pam_handle_t *pamh)
{
	char *master;
	char *domainname;
	int port, err;

	if ((err = yp_get_default_domain(&domainname)) != 0) {
		_log_err(LOG_WARNING, pamh, "can't get local yp domain: %s\n",
			 yperr_string(err));
		return NULL;
	}
	if ((err = yp_master(domainname, "passwd.byname", &master)) != 0) {
		_log_err(LOG_WARNING, pamh, "can't find the master ypserver: %s\n",
			 yperr_string(err));
		return NULL;
	}
	port = getrpcport(master, YPPASSWDPROG, YPPASSWDPROC_UPDATE, IPPROTO_UDP);
	if (port == 0) {
		_log_err(LOG_WARNING, pamh,
		         "yppasswdd not running on NIS master host\n");
		return NULL;
	}
	if (port >= IPPORT_RESERVED) {
		_log_err(LOG_WARNING, pamh,
		         "yppasswd daemon running on illegal port.\n");
		return NULL;
	}
	return master;
}
Example #2
0
int
_yppasswd(char *oldpass, struct x_passwd *newpw)
{
	char *server;
	char *domain;
	int rval, result;
	struct yppasswd yppasswd;

	yppasswd.newpw = *newpw;
	yppasswd.oldpass = oldpass;

	if (yp_get_default_domain(&domain))
		return (-1);

	if (yp_master(domain, "passwd.byname", &server))
		return(-1);

	rval = getrpcport(server, YPPASSWDPROG,
				YPPASSWDPROC_UPDATE, IPPROTO_UDP);

	if (rval == 0 || rval >= IPPORT_RESERVED) {
		free(server);
		return(-1);
	}

	rval = callrpc(server, YPPASSWDPROG, YPPASSWDVERS, YPPASSWDPROC_UPDATE,
		       (xdrproc_t)xdr_yppasswd, (char *)&yppasswd,
		       (xdrproc_t)xdr_int, (char *)&result);

	free(server);
	if (rval || result)
		return(-1);
	else
		return(0);
}
Example #3
0
static int
bind_tohost(struct sockaddr_in *sin, char *dom, char *server)
{
	struct ypbind_setdom ypsd;
	struct in_addr iaddr;
	struct hostent *hp;
	struct timeval tv;
	CLIENT *client;
	int sock, port, r;

	port = getrpcport(server, YPPROG, YPPROC_NULL, IPPROTO_UDP);
	if (port == 0)
		errx(1, "%s not running ypserv", server);
	port = htons(port);

	memset(&ypsd, 0, sizeof ypsd);

	if (inet_aton(server, &iaddr) == 0) {
		hp = gethostbyname(server);
		if (hp == NULL)
			errx(1, "can't find address for %s", server);
		memmove(&iaddr.s_addr, hp->h_addr, sizeof(iaddr.s_addr));
	}
	ypsd.ypsetdom_domain = dom;
	bcopy(&iaddr.s_addr, &ypsd.ypsetdom_binding.ypbind_binding_addr,
	    sizeof(ypsd.ypsetdom_binding.ypbind_binding_addr));
	bcopy(&port, &ypsd.ypsetdom_binding.ypbind_binding_port,
	    sizeof(ypsd.ypsetdom_binding.ypbind_binding_port));
	ypsd.ypsetdom_vers = YPVERS;

	tv.tv_sec = 15;
	tv.tv_usec = 0;
	sock = RPC_ANYSOCK;
	client = clntudp_create(sin, YPBINDPROG, YPBINDVERS, tv, &sock);
	if (client == NULL) {
		warnx("can't yp_bind: reason: %s", yperr_string(YPERR_YPBIND));
		return YPERR_YPBIND;
	}
	client->cl_auth = authunix_create_default();

	r = clnt_call(client, YPBINDPROC_SETDOM,
	    xdr_ypbind_setdom, &ypsd, xdr_void, NULL, tv);
	if (r) {
		warnx("Cannot ypset for domain %s on host %s: %s", dom,
		    server, clnt_sperrno(r));
		clnt_destroy(client);
		return YPERR_YPBIND;
	}
	clnt_destroy(client);
	return 0;
}
Example #4
0
/*
 * Determines the availability of rpc.yppasswdd.  Returns -1 for not
 * available (or unable to determine), 0 for available, 1 for available in
 * master mode.
 */
int
ypclnt_havepasswdd(ypclnt_t *ypclnt)
{
	struct netconfig *nc = NULL;
	void *localhandle = 0;
	CLIENT *clnt = NULL;
	int ret;

	/* check if rpc.yppasswdd is running */
	if (getrpcport(ypclnt->server, YPPASSWDPROG,
		YPPASSWDPROC_UPDATE, IPPROTO_UDP) == 0) {
		ypclnt_error(ypclnt, __func__, "no rpc.yppasswdd on server");
		return (-1);
	}

	/* if we're not root, use remote method */
	if (getuid() != 0)
		return (0);

	/* try to connect to rpc.yppasswdd */
	localhandle = setnetconfig();
	while ((nc = getnetconfig(localhandle)) != NULL) {
		if (nc->nc_protofmly != NULL &&
			strcmp(nc->nc_protofmly, NC_LOOPBACK) == 0)
				break;
	}
	if (nc == NULL) {
		ypclnt_error(ypclnt, __func__,
		    "getnetconfig: %s", nc_sperror());
		ret = 0;
		goto done;
	}
	if ((clnt = clnt_tp_create(NULL, MASTER_YPPASSWDPROG,
	    MASTER_YPPASSWDVERS, nc)) == NULL) {
		ypclnt_error(ypclnt, __func__,
		    "failed to connect to rpc.yppasswdd: %s",
		    clnt_spcreateerror(ypclnt->server));
		ret = 0;
		goto done;
	} else 
		ret = 1;

done:
	if (clnt != NULL) {
		clnt_destroy(clnt);
	}
	endnetconfig(localhandle);
	return (ret);
}
static char *getNISserver(pam_handle_t *pamh, unsigned int ctrl)
{
	char *master;
	char *domainname;
	int port, err;

#ifdef HAVE_YP_GET_DEFAULT_DOMAIN
	if ((err = yp_get_default_domain(&domainname)) != 0) {
		pam_syslog(pamh, LOG_WARNING, "can't get local yp domain: %s",
			 yperr_string(err));
		return NULL;
	}
#elif defined(HAVE_GETDOMAINNAME)
	char domainname_res[256];

	if (getdomainname (domainname_res, sizeof (domainname_res)) == 0)
	  {
	    if (strcmp (domainname_res, "(none)") == 0)
	      {
		/* If domainname is not set, some systems will return "(none)" */
		domainname_res[0] = '\0';
	      }
	    domainname = domainname_res;
	  }
	else domainname = NULL;
#endif

	if ((err = yp_master(domainname, "passwd.byname", &master)) != 0) {
		pam_syslog(pamh, LOG_WARNING, "can't find the master ypserver: %s",
			 yperr_string(err));
		return NULL;
	}
	port = getrpcport(master, YPPASSWDPROG, YPPASSWDPROC_UPDATE, IPPROTO_UDP);
	if (port == 0) {
		pam_syslog(pamh, LOG_WARNING,
		         "yppasswdd not running on NIS master host");
		return NULL;
	}
	if (port >= IPPORT_RESERVED) {
		pam_syslog(pamh, LOG_WARNING,
		         "yppasswd daemon running on illegal port");
		return NULL;
	}
	if (on(UNIX_DEBUG, ctrl)) {
	  pam_syslog(pamh, LOG_DEBUG, "Use NIS server on %s with port %d",
		     master, port);
	}
	return master;
}
Example #6
0
static int
ypxfrd_transfer (char *host, char *map, char *domain, char *tmpname)
{
  CLIENT *clnt;
  struct ypxfr_mapname req;
  struct xfr resp;
  struct timeval timeout = {25, 0};

  if (debug_flag)
    fprintf (stderr, "Trying ypxfrd ...");

  if (!getrpcport (host, YPXFRD_FREEBSD_PROG, YPXFRD_FREEBSD_VERS,
                   IPPROTO_TCP))
    {
      if (debug_flag)
        log_msg (" not running");
      return 1;
    }

  req.xfrmap = map;
  req.xfrdomain = domain;
  req.xfrmap_filename = map;
#if defined(HAVE_LIBGDBM)
#if SIZEOF_LONG == 8
  req.xfr_db_type = XFR_DB_GNU_GDBM64;
#else
  req.xfr_db_type = XFR_DB_GNU_GDBM;
#endif
#if defined(WORDS_BIGENDIAN)
  req.xfr_byte_order = XFR_ENDIAN_BIG;
#else
  req.xfr_byte_order = XFR_ENDIAN_LITTLE;
#endif
#elif defined (HAVE_NDBM)
#if defined(__sun__) || defined (sun)
  req.xfr_db_type = XFR_DB_NDBM;
#if defined(WORDS_BIGENDIAN)
  req.xfr_byte_order = XFR_ENDIAN_BIG;
#else
  req.xfr_byte_order = XFR_ENDIAN_LITTLE;
#endif
#else
  req.xfr_db_type = XFR_DB_BSD_NDBM;
  req.xfr_byte_order = XFR_ENDIAN_ANY;
#endif
#elif defined (HAVE_LIBQDBM)
  req.xfr_db_type = XFR_DB_QDBM;
#if defined(WORDS_BIGENDIAN)
  req.xfr_byte_order = XFR_ENDIAN_BIG;
#else
  req.xfr_byte_order = XFR_ENDIAN_LITTLE;
#endif
#elif defined (HAVE_LIBTC)
  req.xfr_db_type = XFR_DB_TC;
  req.xfr_byte_order = XFR_ENDIAN_ANY;
#endif
  memset (&resp, 0, sizeof (resp));

  if ((clnt = clnt_create (host, YPXFRD_FREEBSD_PROG,
                           YPXFRD_FREEBSD_VERS, "tcp")) == NULL)
    goto error;

  if ((ypxfrd_file = open (tmpname, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR)) == -1)
    {
      clnt_destroy (clnt);
      log_msg ("couldn't open %s: %s", tmpname, strerror (errno));
      goto error;
    }

  if (clnt_call (clnt, YPXFRD_GETMAP, (xdrproc_t) xdr_ypxfr_mapname,
                 (caddr_t) &req, (xdrproc_t) xdr_ypxfr_xfr,
                 (caddr_t) &resp, timeout) != RPC_SUCCESS)
    {
      log_msg ("%s", clnt_sperror (clnt, "call to rpc.ypxfrd failed"));
      unlink (tmpname);
      clnt_destroy (clnt);
      close (ypxfrd_file);
      goto error;
    }

  clnt_destroy (clnt);
  close (ypxfrd_file);

  if (debug_flag)
    log_msg (" success\n");

  return 0;

error:
  if (debug_flag)
    log_msg (" (failed, fallback to enumeration)\n");
  return 1;
}
Example #7
0
int
yp_update(char *domain, char *map, unsigned int ypop, char *key, int keylen,
	  char *data, int datalen)
{
	char *master;
	int rval;
	unsigned int res;
	struct ypupdate_args upargs;
	struct ypdelete_args delargs;
	CLIENT *clnt;
	char netname[MAXNETNAMELEN+1];
	des_block des_key;
	struct timeval timeout;

	/* Get the master server name for 'domain.' */
	if ((rval = yp_master(domain, map, &master)))
		return(rval);

	/* Check that ypupdated is running there. */
	if (getrpcport(master, YPU_PROG, YPU_VERS, ypop))
		return(YPERR_DOMAIN);

	/* Get a handle. */
	if ((clnt = clnt_create(master, YPU_PROG, YPU_VERS, "tcp")) == NULL)
		return(YPERR_RPC);

	/*
	 * Assemble netname of server.
	 * NOTE: It's difficult to discern from the documentation, but
	 * when you make a Secure RPC call, the netname you pass should
	 * be the netname of the guy on the other side, not your own
	 * netname. This is how the client side knows what public key
	 * to use for the initial exchange. Passing your own netname
	 * only works if the server on the other side is running under
	 * your UID.
	 */
	if (!host2netname(netname, master, domain)) {
		clnt_destroy(clnt);
		return(YPERR_BADARGS);
	}

	/* Make up a DES session key. */
	key_gendes(&des_key);

	/* Set up DES authentication. */
	if ((clnt->cl_auth = (AUTH *)authdes_create(netname, WINDOW, NULL,
			&des_key)) == NULL) {
		clnt_destroy(clnt);
		return(YPERR_RESRC);
	}

	/* Set a timeout for clnt_call(). */
	timeout.tv_usec = 0;
	timeout.tv_sec = TIMEOUT;

	/*
	 * Make the call. Note that we use clnt_call() here rather than
	 * the rpcgen-erated client stubs. We could use those stubs, but
	 * then we'd have to do some gymnastics to get at the error
	 * information to figure out what error code to send back to the
	 * caller. With clnt_call(), we get the error status returned to
	 * us right away, and we only have to exert a small amount of
	 * extra effort.
	 */
	switch (ypop) {
	case YPOP_CHANGE:
		upargs.mapname = map;
		upargs.key.yp_buf_len = keylen;
		upargs.key.yp_buf_val = key;
		upargs.datum.yp_buf_len = datalen;
		upargs.datum.yp_buf_val = data;

		if ((rval = clnt_call(clnt, YPU_CHANGE,
			(xdrproc_t)xdr_ypupdate_args, &upargs,
			(xdrproc_t)xdr_u_int, &res, timeout)) != RPC_SUCCESS) {
			if (rval == RPC_AUTHERROR)
				res = YPERR_ACCESS;
			else
				res = YPERR_RPC;
		}

		break;
	case YPOP_INSERT:
		upargs.mapname = map;
		upargs.key.yp_buf_len = keylen;
		upargs.key.yp_buf_val = key;
		upargs.datum.yp_buf_len = datalen;
		upargs.datum.yp_buf_val = data;

		if ((rval = clnt_call(clnt, YPU_INSERT,
			(xdrproc_t)xdr_ypupdate_args, &upargs,
			(xdrproc_t)xdr_u_int, &res, timeout)) != RPC_SUCCESS) {
			if (rval == RPC_AUTHERROR)
				res = YPERR_ACCESS;
			else
				res = YPERR_RPC;
		}

		break;
	case YPOP_DELETE:
		delargs.mapname = map;
		delargs.key.yp_buf_len = keylen;
		delargs.key.yp_buf_val = key;

		if ((rval = clnt_call(clnt, YPU_DELETE,
			(xdrproc_t)xdr_ypdelete_args, &delargs,
			(xdrproc_t)xdr_u_int, &res, timeout)) != RPC_SUCCESS) {
			if (rval == RPC_AUTHERROR)
				res = YPERR_ACCESS;
			else
				res = YPERR_RPC;
		}

		break;
	case YPOP_STORE:
		upargs.mapname = map;
		upargs.key.yp_buf_len = keylen;
		upargs.key.yp_buf_val = key;
		upargs.datum.yp_buf_len = datalen;
		upargs.datum.yp_buf_val = data;

		if ((rval = clnt_call(clnt, YPU_STORE,
			(xdrproc_t)xdr_ypupdate_args, &upargs,
			(xdrproc_t)xdr_u_int, &res, timeout)) != RPC_SUCCESS) {
			if (rval == RPC_AUTHERROR)
				res = YPERR_ACCESS;
			else
				res = YPERR_RPC;
		}

		break;
	default:
		res = YPERR_BADARGS;
		break;
	}

	/* All done: tear down the connection. */
	auth_destroy(clnt->cl_auth);
	clnt_destroy(clnt);
	free(master);

	return(res);
}
Example #8
0
int
yp_passwd(char *username)
{
	struct yppasswd yppwd;
	int r, rpcport, status, secure=0;
	struct passwd *pw;
	struct timeval tv;
	login_cap_t *lc;
	CLIENT *client;
	char *master;
	uid_t uid;

	/*
	 * Get local domain
	 */
	if ((r = yp_get_default_domain(&domain)) != 0) {
		warnx("can't get local YP domain. Reason: %s",
		    yperr_string(r));
		return (1);
	}

	/*
	 * Find the host for the passwd map; it should be running
	 * the daemon.
	 */
	if ((r = yp_master(domain, "master.passwd.byname", &master)) == 0) {
		secure=1;
	} else if ((r = yp_master(domain, "passwd.byname", &master)) != 0) {
		warnx("can't find the master YP server. Reason: %s",
		    yperr_string(r));
		return (1);
	}

	/*
	 * Ask the portmapper for the port of the daemon.
	 */
	if ((rpcport = getrpcport(master, YPPASSWDPROG,
	    YPPASSWDPROC_UPDATE, IPPROTO_UDP)) == 0) {
		warnx("master YP server not running yppasswd daemon.");
		warnx("Can't change password.");
		return (1);
	}

	/*
	 * Be sure the port is privileged
	 */
	if (rpcport >= IPPORT_RESERVED) {
		warnx("yppasswd daemon is on an invalid port.");
		return (1);
	}

	/* Get user's login identity */
	if (!(pw = ypgetpwnam(username, secure))) {
		warnx("unknown user %s.", username);
		return (1);
	}
	if ((lc = login_getclass(pw->pw_class)) == NULL) {
		warnx("unable to get login class for user %s.", username);
		return (1);
	}

	uid = getuid();
	if (uid && uid != pw->pw_uid) {
		warnx("you may only change your own password: %s",
		    strerror(EACCES));
		return (1);
	}

	/* prompt for new password */
	yppwd.newpw.pw_passwd = ypgetnewpasswd(pw, lc, &yppwd.oldpass);

	/* tell rpc.yppasswdd */
	yppwd.newpw.pw_name	= pw->pw_name;
	yppwd.newpw.pw_uid	= pw->pw_uid;
	yppwd.newpw.pw_gid	= pw->pw_gid;
	yppwd.newpw.pw_gecos = pw->pw_gecos;
	yppwd.newpw.pw_dir	= pw->pw_dir;
	yppwd.newpw.pw_shell	= pw->pw_shell;

	client = clnt_create(master, YPPASSWDPROG, YPPASSWDVERS, "udp");
	if (client==NULL) {
		warnx("cannot contact yppasswdd on %s: Reason: %s",
		    master, yperr_string(YPERR_YPBIND));
		free(yppwd.newpw.pw_passwd);
		return (YPERR_YPBIND);
	}
	client->cl_auth = authunix_create_default();
	tv.tv_sec = 2;
	tv.tv_usec = 0;
	r = clnt_call(client, YPPASSWDPROC_UPDATE,
	    xdr_yppasswd, &yppwd, xdr_int, &status, tv);
	if (r) {
		printf("rpc to yppasswdd failed.\n");
		free(yppwd.newpw.pw_passwd);
		return (1);
	} else if (status) {
		printf("Couldn't change YP password.\n");
		free(yppwd.newpw.pw_passwd);
		return (1);
	} else {
		printf("The YP password has been changed on %s, "
	 	    "the master YP passwd server.\n", master);
		free(yppwd.newpw.pw_passwd);
		return (0);
	}
}
void
yp_chpass(char *username)
{
	char *master;
	int r, rpcport, status;
	struct yppasswd yppasswd;
	struct passwd *pw;
	struct timeval tv;
	CLIENT *client;
	extern char *domain;

	(void)signal(SIGINT, kbintr);
	(void)signal(SIGQUIT, kbintr);

	if ((r = yp_get_default_domain(&domain)) != 0) {
		warnx("can't get local YP domain. Reason: %s", yperr_string(r));
		exit(1);
	}

	/*
	 * Find the host for the passwd map; it should be running
	 * the daemon.
	 */
	if ((r = yp_master(domain, "passwd.byname", &master)) != 0) {
		warnx("can't find the master YP server. Reason: %s",
		    yperr_string(r));
		exit(1);
	}

	/* Ask the portmapper for the port of the daemon. */
	if ((rpcport = getrpcport(master, YPPASSWDPROG,
	    YPPASSWDPROC_UPDATE, IPPROTO_UDP)) == 0) {
		warnx("master YP server not running yppasswd daemon.");
		warnx("Can't change password.");
		exit(1);
	}

	if (rpcport >= IPPORT_RESERVED) {
		warnx("yppasswd daemon is on an invalid port.");
		exit(1);
	}

	/* If user doesn't exist, just prompt for old password and exit. */
	pw = ypgetpwnam(username);
	if (pw) {
		if (pw->pw_uid == 0) {
			syslog(LOG_ERR, "attempted root password change");
			pw = NULL;
		} else if (*pw->pw_passwd == '\0') {
			syslog(LOG_ERR, "%s attempting to add password",
			    username);
			pw = NULL;
		}
	}
	if (pw == NULL) {
		char *p, salt[_PASSWORD_LEN + 1];
		login_cap_t *lc;

		/* no such user, get appropriate salt to thwart timing attack */
		if ((p = getpass("Old password:"******"xx", sizeof(salt));
			crypt(p, salt);
			memset(p, 0, strlen(p));
		}
		warnx("YP passwd database unchanged.");
		exit(1);
	}

	/* prompt for new password */
	yppasswd.newpw.pw_passwd = ypgetnewpasswd(pw, &yppasswd.oldpass);

	/* tell rpc.yppasswdd */
	yppasswd.newpw.pw_name	= pw->pw_name;
	yppasswd.newpw.pw_uid	= pw->pw_uid;
	yppasswd.newpw.pw_gid	= pw->pw_gid;
	yppasswd.newpw.pw_gecos = pw->pw_gecos;
	yppasswd.newpw.pw_dir	= pw->pw_dir;
	yppasswd.newpw.pw_shell	= pw->pw_shell;

	client = clnt_create(master, YPPASSWDPROG, YPPASSWDVERS, "udp");
	if (client == NULL) {
		warnx("cannot contact yppasswdd on %s: Reason: %s",
		    master, yperr_string(YPERR_YPBIND));
		free(yppasswd.newpw.pw_passwd);
		exit(1);
	}
	client->cl_auth = authunix_create_default();
	tv.tv_sec = 2;
	tv.tv_usec = 0;
	r = clnt_call(client, YPPASSWDPROC_UPDATE,
	    xdr_yppasswd, &yppasswd, xdr_int, &status, tv);
	if (r)
		warnx("rpc to yppasswdd failed.");
	else if (status) {
		printf("Couldn't change YP password.\n");
		free(yppasswd.newpw.pw_passwd);
		exit(1);
	}
	printf("The YP password has been changed on %s, the master YP passwd server.\n",
	    master);
	free(yppasswd.newpw.pw_passwd);
	(void)writev(BACK_CHANNEL, iov, 2);
	exit(0);
}
Example #10
0
void
pwyp_process(const char *username, int argc, char **argv)
{
	char *master;
	int ch, r, rpcport, status;
	enum clnt_stat yr;
	struct yppasswd ypp;
	struct passwd pwb, pwb2, *pw;
	char pwbuf[1024];
	struct timeval tv;
	CLIENT *client;

	while ((ch = getopt(argc, argv, "y")) != -1) {
		switch (ch) {
		case 'y':
			/*
			 * Abosrb the -y that may have gotten us here.
			 */
			break;

		default:
			usage();
			/* NOTREACHED */
		}
	}

	argc -= optind;
	argv += optind;

	switch (argc) {
	case 0:
		/* username already provided */
		break;
	case 1:
		username = argv[0];
		break;
	default:
		usage();
		/*NOTREACHED*/
	}

	if (_yp_check(NULL) == 0) {
		/* can't use YP. */
		errx(EXIT_FAILURE, "NIS not in use.");
	}

	uid = getuid();

	/*
	 * Get local domain
	 */
	if ((r = yp_get_default_domain(&domain)) != 0)
		errx(EXIT_FAILURE, "Can't get local NIS domain (%s)",
		    yperr_string(r));

	/*
	 * Find the host for the passwd map; it should be running
	 * the daemon.
	 */
	if ((r = yp_master(domain, "passwd.byname", &master)) != 0)
		errx(EXIT_FAILURE, "Can't find the master NIS server (%s)",
		    yperr_string(r));

	/*
	 * Ask the portmapper for the port of the daemon.
	 */
	if ((rpcport = getrpcport(master, YPPASSWDPROG,
	    YPPASSWDPROC_UPDATE, IPPROTO_UDP)) == 0)
		errx(EXIT_FAILURE, "Master NIS server not running yppasswd "
		    "daemon");

	/*
	 * Be sure the port is privileged
	 */
	if (rpcport >= IPPORT_RESERVED)
		errx(EXIT_FAILURE, "Yppasswd daemon is on an invalid port");

	/* Bail out if this is a local (non-yp) user, */
	/* then get user's login identity */
	if (!ypgetpwnam(username, &pwb) ||
	    getpwnam_r(username, &pwb2, pwbuf, sizeof(pwbuf), &pw) ||
	    pw == NULL)
		errx(EXIT_FAILURE, "NIS unknown user %s", username);

	if (uid && uid != pwb.pw_uid) {
		errno = EACCES;
		err(EXIT_FAILURE, "You may only change your own password");
	}

	makeypp(&ypp, &pwb);

	client = clnt_create(master, YPPASSWDPROG, YPPASSWDVERS, "udp");
	if (client == NULL)
		errx(EXIT_FAILURE, "Cannot contact yppasswdd on %s (%s)",
		    master, yperr_string(YPERR_YPBIND));

	client->cl_auth = authunix_create_default();
	tv.tv_sec = 2;
	tv.tv_usec = 0;
	yr = clnt_call(client, YPPASSWDPROC_UPDATE,
	    xdr_yppasswd, &ypp, xdr_int, &status, tv);
	if (yr != RPC_SUCCESS)
		errx(EXIT_FAILURE, "RPC to yppasswdd failed (%s)",
		    clnt_sperrno(yr));
	else if (status)
		printf("Couldn't change NIS password.\n");
	else
		printf("The NIS password has been changed on %s, %s\n",
		    master, "the master NIS passwd server.");
}
Example #11
0
int
main(int argc, char *argv[])
{
	int	 cflag = 0, fflag = 0, Cflag = 0;
	char	 *domain, *host = NULL, *srcdomain = NULL;
	char	 *tid = NULL, *prog = NULL, *ipadd = NULL;
	char	 *port = NULL, *map = NULL;
	int	 status, xfr_status, ch, srvport;
	u_int32_t ordernum, new_ordernum;
	struct	 ypall_callback callback;
	CLIENT   *client = NULL;
	extern	 char *optarg;

	yp_get_default_domain(&domain);

	while ((ch = getopt(argc, argv, "cd:fh:s:C:")) != -1)
		switch (ch) {
		case 'c':
			cflag++;
			break;
		case 'd':
			if (strchr(optarg, '/')) /* Ha ha, we are not listening */
				break;
			domain = optarg;
			break;
		case 'f':
			fflag++;
			break;
		case 'h':
			host = optarg;
			break;
		case 's':
			if (strchr(optarg, '/')) /* Ha ha, we are not listening */
				break;
			srcdomain = optarg;
			break;
		case 'C':
			if (optind + 3 >= argc)
				usage();
			Cflag++;
			tid = optarg;
			prog = argv[optind++];
			ipadd = argv[optind++];
			port = argv[optind++];
			break;
		default:
			usage();
			break;
		}

	status = YPPUSH_SUCC;

	if (optind + 1 != argc)
		usage();

	map = argv[optind];

	if (status > 0) {
		ypopenlog();

		yplog("ypxfr: Arguments:");
		yplog("YP clear to local: %s", (cflag) ? "no" : "yes");
		yplog("   Force transfer: %s", (fflag) ? "yes" : "no");
		yplog("           domain: %s", domain);
		yplog("             host: %s", host);
		yplog("    source domain: %s", srcdomain);
		yplog("          transid: %s", tid);
		yplog("             prog: %s", prog);
		yplog("             port: %s", port);
		yplog("            ipadd: %s", ipadd);
		yplog("              map: %s", map);

		if (fflag != 0) {
			ordernum = 0;
		} else {
			status = get_local_ordernum(domain, map, &ordernum);
		}
	}

	if (status > 0) {
		yplog("Get Master");

		if (host == NULL) {
			if (srcdomain == NULL) {
				status = yp_master(domain, map, &host);
			} else {
				status = yp_master(srcdomain, map, &host);
			}
			if (status == 0) {
				status = YPPUSH_SUCC;
			} else {
				status = -status;
			}
		}
	}

	/* XXX this is raceable if portmap has holes! */
	if (status > 0) {
		yplog("Check for reserved port on host: %s", host);

		srvport = getrpcport(host, YPPROG, YPVERS, IPPROTO_TCP);
		if (srvport >= IPPORT_RESERVED)
			status = YPPUSH_REFUSED;
	}

	if (status > 0) {
		yplog("Connect host: %s", host);

		client = yp_bind_host(host, YPPROG, YPVERS, 0, 1);

		status = get_remote_ordernum(client, domain, map,
		    ordernum, &new_ordernum);
	}

	if (status == YPPUSH_SUCC) {
		char	tmpmapname[MAXPATHLEN];
		int	fd;

		/* Create temporary db */
		snprintf(tmpmapname, sizeof tmpmapname,
		    "%s/%s/ypdbXXXXXXXXXX", YP_DB_PATH, domain);
		fd = mkstemp(tmpmapname);
		if (fd == -1)
			status = YPPUSH_DBM;
		else
			close(fd);

		if (status > 0) {
			db = create_db(domain, map, tmpmapname);
			if (db == NULL)
				status = YPPUSH_DBM;
		}

		/* Add ORDER */
		if (status > 0)
			status = add_order(db, new_ordernum);

		/* Add MASTER */
		if (status > 0)
			status = add_master(client, domain, map, db);

		/* Add INTERDOMAIN */
		if (status > 0)
			status = add_interdomain(client, domain, map, db);

		/* Add SECURE */
		if (status > 0)
			status = add_secure(client, domain, map, db);

		if (status > 0) {
			callback.foreach = ypxfr_foreach;
			status = get_map(client, domain, map, &callback);
		}

		/* Close db */
		if (db != NULL)
			ypdb_close(db);

		/* Rename db */
		if (status > 0) {
			status = install_db(domain, map, tmpmapname);
		} else {
			unlink(tmpmapname);
			status = YPPUSH_SUCC;
		}
	}

	xfr_status = status;

	if (client != NULL)
		clnt_destroy(client);

	/* YP_CLEAR */

	if (!cflag) {
		client = yp_bind_local(YPPROG, YPVERS);
		status = send_clear(client);
		clnt_destroy(client);
	}

	if (Cflag > 0) {
		/* Send Response */
		client = yp_bind_host(ipadd, atoi(prog), 1, atoi(port), 0);
		status = send_reply(client, xfr_status, atoi(tid));
		clnt_destroy(client);
	}
	return (0);
}
Example #12
0
int
main(int argc, char *argv[])
{
	int ch;
	int ypxfr_force = 0;
	char *ypxfr_dest_domain = NULL;
	char *ypxfr_source_host = NULL;
	char *ypxfr_source_domain = NULL;
	char *ypxfr_local_domain = NULL;
	char *ypxfr_master = NULL;
	unsigned long ypxfr_order = -1, ypxfr_skew_check = -1;
	char *ypxfr_mapname = NULL;
	int ypxfr_args = 0;
	char ypxfr_temp_map[MAXPATHLEN + 2];
	char tempmap[MAXPATHLEN + 2];
	char buf[MAXPATHLEN + 2];
	DBT key, data;
	int remoteport;
	int interdom = 0;
	int secure = 0;

	debug = 1;

	if (!isatty(fileno(stderr))) {
		openlog("ypxfr", LOG_PID, LOG_DAEMON);
		_rpcpmstart = 1;
	}

	if (argc < 2)
		usage();

	while ((ch = getopt(argc, argv, "fcd:h:s:p:C:")) != -1) {
		int my_optind;
		switch (ch) {
		case 'f':
			ypxfr_force++;
			ypxfr_args++;
			break;
		case 'c':
			ypxfr_clear = 0;
			ypxfr_args++;
			break;
		case 'd':
			ypxfr_dest_domain = optarg;
			ypxfr_args += 2;
			break;
		case 'h':
			ypxfr_source_host = optarg;
			ypxfr_args += 2;
			break;
		case 's':
			ypxfr_source_domain = optarg;
			ypxfr_args += 2;
			break;
		case 'p':
			yp_dir = optarg;
			ypxfr_args += 2;
			break;
		case 'C':
			/*
			 * Whoever decided that the -C flag should take
			 * four arguments is a twit.
			 */
			my_optind = optind - 1;
			if (argv[my_optind] == NULL || !strlen(argv[my_optind])) {
				yp_error("transaction ID not specified");
				usage();
			}
			ypxfr_resp.transid = atol(argv[my_optind]);
			my_optind++;
			if (argv[my_optind] == NULL || !strlen(argv[my_optind])) {
				yp_error("RPC program number not specified");
				usage();
			}
			ypxfr_prognum = atol(argv[my_optind]);
			my_optind++;
			if (argv[my_optind] == NULL || !strlen(argv[my_optind])) {
				yp_error("address not specified");
				usage();
			}
			if (!inet_aton(argv[my_optind], &ypxfr_callback_addr.sin_addr)) {
				yp_error("failed to convert '%s' to IP addr",
					argv[my_optind]);
				exit(1);
			}
			my_optind++;
			if (argv[my_optind] == NULL || !strlen(argv[my_optind])) {
				yp_error("port not specified");
				usage();
			}
			ypxfr_callback_addr.sin_port = htons((u_short)atoi(argv[my_optind]));
			ypxfr_args += 5;
			break;
		default:
			usage();
			break;
		}
	}

	ypxfr_mapname = argv[ypxfr_args + 1];

	if (ypxfr_mapname == NULL) {
		yp_error("no map name specified");
		usage();
	}

	/* Always the case. */
	ypxfr_callback_addr.sin_family = AF_INET;

	/* Determine if local NIS client facilities are turned on. */
	if (!yp_get_default_domain(&ypxfr_local_domain) &&
	    _yp_check(&ypxfr_local_domain))
		ypxfr_use_yplib = 1;

	/*
	 * If no destination domain is specified, assume that the
	 * local default domain is to be used and try to obtain it.
	 * Fails if NIS client facilities are turned off.
	 */
	if (ypxfr_dest_domain == NULL) {
		if (ypxfr_use_yplib) {
			yp_get_default_domain(&ypxfr_dest_domain);
		} else {
			yp_error("no destination domain specified and \
the local domain name isn't set");
			ypxfr_exit(YPXFR_BADARGS,NULL);
		}
	}

	/*
	 * If a source domain is not specified, assume it to
	 * be the same as the destination domain.
	 */
	if (ypxfr_source_domain == NULL) {
		ypxfr_source_domain = ypxfr_dest_domain;
	}

	/*
	 * If the source host is not specified, assume it to be the
	 * master for the specified map. If local NIS client facilities
	 * are turned on, we can figure this out using yp_master().
	 * If not, we have to see if a local copy of the map exists
	 * and extract its YP_MASTER_NAME record. If _that_ fails,
	 * we are stuck and must ask the user for more information.
	 */
	if (ypxfr_source_host == NULL) {
		if (!ypxfr_use_yplib) {
		/*
		 * Double whammy: NIS isn't turned on and the user
		 * didn't specify a source host.
		 */
			char *dptr;
			key.data = "YP_MASTER_NAME";
			key.size = sizeof("YP_MASTER_NAME") - 1;

			if (yp_get_record(ypxfr_dest_domain, ypxfr_mapname,
					 &key, &data, 1) != YP_TRUE) {
				yp_error("no source host specified");
				ypxfr_exit(YPXFR_BADARGS,NULL);
			}
			dptr = data.data;
			dptr[data.size] = '\0';
			ypxfr_master = ypxfr_source_host = strdup(dptr);
		}
	} else {
		if (ypxfr_use_yplib)
			ypxfr_use_yplib = 0;
	}

	if (ypxfr_master == NULL) {
		if ((ypxfr_master = ypxfr_get_master(ypxfr_source_domain,
					    	 ypxfr_mapname,
					     	ypxfr_source_host,
					     	ypxfr_use_yplib)) == NULL) {
			yp_error("failed to find master of %s in domain %s: %s",
				  ypxfr_mapname, ypxfr_source_domain,
				  ypxfrerr_string((ypxfrstat)yp_errno));
			ypxfr_exit(YPXFR_MADDR,NULL);
		}
	}

	/*
	 * If we got here and ypxfr_source_host is still undefined,
	 * it means we had to resort to using yp_master() to find the
	 * master server for the map. The source host and master should
	 * be identical.
	 */
	if (ypxfr_source_host == NULL)
		ypxfr_source_host = ypxfr_master;

	/*
	 * Don't talk to ypservs on unprivileged ports.
	 */
	remoteport = getrpcport(ypxfr_source_host, YPPROG, YPVERS, IPPROTO_UDP);
	if (remoteport >= IPPORT_RESERVED) {
		yp_error("ypserv on %s not running on reserved port",
						ypxfr_source_host);
		ypxfr_exit(YPXFR_REFUSED, NULL);
	}

	if ((ypxfr_order = ypxfr_get_order(ypxfr_source_domain,
					     ypxfr_mapname,
					     ypxfr_master, 0)) == 0) {
		yp_error("failed to get order number of %s: %s",
				ypxfr_mapname, yp_errno == YP_TRUE ?
				"map has order 0" :
				ypxfrerr_string((ypxfrstat)yp_errno));
		ypxfr_exit(YPXFR_YPERR,NULL);
	}

	if (ypxfr_match(ypxfr_master, ypxfr_source_domain, ypxfr_mapname,
			"YP_INTERDOMAIN", sizeof("YP_INTERDOMAIN") - 1))
		interdom++;

	if (ypxfr_match(ypxfr_master, ypxfr_source_domain, ypxfr_mapname,
			"YP_SECURE", sizeof("YP_SECURE") - 1))
		secure++;

	key.data = "YP_LAST_MODIFIED";
	key.size = sizeof("YP_LAST_MODIFIED") - 1;

	/* The order number is immaterial when the 'force' flag is set. */

	if (!ypxfr_force) {
		int ignore = 0;
		if (yp_get_record(ypxfr_dest_domain,ypxfr_mapname,&key,&data,1) != YP_TRUE) {
			switch (yp_errno) {
			case YP_NOKEY:
				ypxfr_exit(YPXFR_FORCE,NULL);
				break;
			case YP_NOMAP:
				/*
				 * If the map doesn't exist, we're
				 * creating it. Ignore the error.
				 */
				ignore++;
				break;
			case YP_BADDB:
			default:
				ypxfr_exit(YPXFR_DBM,NULL);
				break;
			}
		}
		if (!ignore && ypxfr_order <= atoi(data.data))
			ypxfr_exit(YPXFR_AGE, NULL);

	}

	/* Construct a temporary map file name */
	snprintf(tempmap, sizeof(tempmap), "%s.%d",ypxfr_mapname, getpid());
	snprintf(ypxfr_temp_map, sizeof(ypxfr_temp_map), "%s/%s/%s", yp_dir,
		 ypxfr_dest_domain, tempmap);

	if ((remoteport = getrpcport(ypxfr_source_host, YPXFRD_FREEBSD_PROG,
					YPXFRD_FREEBSD_VERS, IPPROTO_TCP))) {

		/* Don't talk to rpc.ypxfrds on unprovileged ports. */
		if (remoteport >= IPPORT_RESERVED) {
			yp_error("rpc.ypxfrd on %s not using privileged port",
							ypxfr_source_host);
			ypxfr_exit(YPXFR_REFUSED, NULL);
		}

		/* Try to send using ypxfrd. If it fails, use old method. */
		if (!ypxfrd_get_map(ypxfr_source_host, ypxfr_mapname,
					ypxfr_source_domain, ypxfr_temp_map))
			goto leave;
	}

	/* Open the temporary map read/write. */
	if ((dbp = yp_open_db_rw(ypxfr_dest_domain, tempmap, 0)) == NULL) {
		yp_error("failed to open temporary map file");
		ypxfr_exit(YPXFR_DBM,NULL);
	}

	/*
	 * Fill in the keys we already know, such as the order number,
	 * master name, input file name (we actually make up a bogus
	 * name for that) and output file name.
	 */
	snprintf(buf, sizeof(buf), "%lu", ypxfr_order);
	data.data = buf;
	data.size = strlen(buf);

	if (yp_put_record(dbp, &key, &data, 0) != YP_TRUE) {
		yp_error("failed to write order number to database");
		ypxfr_exit(YPXFR_DBM,ypxfr_temp_map);
	}

	key.data = "YP_MASTER_NAME";
	key.size = sizeof("YP_MASTER_NAME") - 1;
	data.data = ypxfr_master;
	data.size = strlen(ypxfr_master);

	if (yp_put_record(dbp, &key, &data, 0) != YP_TRUE) {
		yp_error("failed to write master name to database");
		ypxfr_exit(YPXFR_DBM,ypxfr_temp_map);
	}

	key.data = "YP_DOMAIN_NAME";
	key.size = sizeof("YP_DOMAIN_NAME") - 1;
	data.data = ypxfr_dest_domain;
	data.size = strlen(ypxfr_dest_domain);

	if (yp_put_record(dbp, &key, &data, 0) != YP_TRUE) {
		yp_error("failed to write domain name to database");
		ypxfr_exit(YPXFR_DBM,ypxfr_temp_map);
	}

	snprintf (buf, sizeof(buf), "%s:%s", ypxfr_source_host, ypxfr_mapname);

	key.data = "YP_INPUT_NAME";
	key.size = sizeof("YP_INPUT_NAME") - 1;
	data.data = &buf;
	data.size = strlen(buf);

	if (yp_put_record(dbp, &key, &data, 0) != YP_TRUE) {
		yp_error("failed to write input name to database");
		ypxfr_exit(YPXFR_DBM,ypxfr_temp_map);

	}

	snprintf(buf, sizeof(buf), "%s/%s/%s", yp_dir, ypxfr_dest_domain,
							ypxfr_mapname);

	key.data = "YP_OUTPUT_NAME";
	key.size = sizeof("YP_OUTPUT_NAME") - 1;
	data.data = &buf;
	data.size = strlen(buf);

	if (yp_put_record(dbp, &key, &data, 0) != YP_TRUE) {
		yp_error("failed to write output name to database");
		ypxfr_exit(YPXFR_DBM,ypxfr_temp_map);
	}

	if (interdom) {
		key.data = "YP_INTERDOMAIN";
		key.size = sizeof("YP_INTERDOMAIN") - 1;
		data.data = "";
		data.size = 0;

		if (yp_put_record(dbp, &key, &data, 0) != YP_TRUE) {
			yp_error("failed to add interdomain flag to database");
			ypxfr_exit(YPXFR_DBM,ypxfr_temp_map);
		}
	}

	if (secure) {
		key.data = "YP_SECURE";
		key.size = sizeof("YP_SECURE") - 1;
		data.data = "";
		data.size = 0;

		if (yp_put_record(dbp, &key, &data, 0) != YP_TRUE) {
			yp_error("failed to add secure flag to database");
			ypxfr_exit(YPXFR_DBM,ypxfr_temp_map);
		}
	}

	/* Now suck over the contents of the map from the master. */

	if (ypxfr_get_map(ypxfr_mapname,ypxfr_source_domain,
			  ypxfr_source_host, ypxfr_foreach)){
		yp_error("failed to retrieve map from source host");
		ypxfr_exit(YPXFR_YPERR,ypxfr_temp_map);
	}

	(void)(dbp->close)(dbp);
	dbp = NULL; /* <- yes, it seems this is necessary. */

leave:

	snprintf(buf, sizeof(buf), "%s/%s/%s", yp_dir, ypxfr_dest_domain,
							ypxfr_mapname);

	/* Peek at the order number again and check for skew. */
	if ((ypxfr_skew_check = ypxfr_get_order(ypxfr_source_domain,
					     ypxfr_mapname,
					     ypxfr_master, 0)) == 0) {
		yp_error("failed to get order number of %s: %s",
				ypxfr_mapname, yp_errno == YP_TRUE ?
				"map has order 0" :
				ypxfrerr_string((ypxfrstat)yp_errno));
		ypxfr_exit(YPXFR_YPERR,ypxfr_temp_map);
	}

	if (ypxfr_order != ypxfr_skew_check)
		ypxfr_exit(YPXFR_SKEW,ypxfr_temp_map);

	/*
	 * Send a YPPROC_CLEAR to the local ypserv.
	 */
	if (ypxfr_clear) {
		char in = 0;
		char *out = NULL;
		int stat;
		if ((stat = callrpc("localhost",YPPROG,YPVERS,YPPROC_CLEAR,
			(xdrproc_t)xdr_void, (void *)&in,
			(xdrproc_t)xdr_void, (void *)out)) != RPC_SUCCESS) {
			yp_error("failed to send 'clear' to local ypserv: %s",
				 clnt_sperrno((enum clnt_stat) stat));
			ypxfr_exit(YPXFR_CLEAR, ypxfr_temp_map);
		}
	}

	/*
	 * Put the new map in place immediately. I'm not sure if the
	 * kernel does an unlink() and rename() atomically in the event
	 * that we move a new copy of a map over the top of an existing
	 * one, but there's less chance of a race condition happening
	 * than if we were to do the unlink() ourselves.
	 */
	if (rename(ypxfr_temp_map, buf) == -1) {
		yp_error("rename(%s,%s) failed: %s", ypxfr_temp_map, buf,
							strerror(errno));
		ypxfr_exit(YPXFR_FILE,NULL);
	}

	ypxfr_exit(YPXFR_SUCC,NULL);

	return(1);
}
Example #13
0
int
pw_yp(struct passwd *pw, uid_t uid)
{
	char uidbuf[20], gidbuf[20], *master, *p;
	int r, rpcport, status, alen;
	struct yppasswd yppasswd;
	struct timeval tv;
	CLIENT *client;

	/*
	 * Get local domain
	 */
	if (!domain && (r = yp_get_default_domain(&domain))) {
		fprintf(stderr, "%s: can't get local YP domain. Reason: %s\n",
		    __progname, yperr_string(r));
		return(0);
	}

	/*
	 * Find the host for the passwd map; it should be running
	 * the daemon.
	 */
	if ((r = yp_master(domain, "passwd.byname", &master)) != 0) {
		fprintf(stderr,
		    "%s: can't find the master YP server. Reason: %s\n",
		    __progname, yperr_string(r));
		return(0);
	}

	/*
	 * Ask the portmapper for the port of the daemon.
	 */
	if ((rpcport = getrpcport(master, YPPASSWDPROG, YPPASSWDPROC_UPDATE,
	    IPPROTO_UDP)) == 0) {
		fprintf(stderr,
		    "%s: master YP server not running yppasswd daemon.\n",
		    __progname);
		fprintf(stderr,	"\tCan't change password.\n");
		return(0);
	}

	/*
	 * Be sure the port is privileged
	 */
	if (rpcport >= IPPORT_RESERVED) {
		(void)fprintf(stderr,
		    "%s: yppasswd daemon running on an invalid port.\n",
		    __progname);
		return(0);
	}

	/* prompt for old password */
	bzero(&yppasswd, sizeof yppasswd);
	yppasswd.oldpass = "******";
	yppasswd.oldpass = getpass("Old password:"******"Cancelled.\n");
		return(0);
	}

	for (alen = 0, p = pw->pw_gecos; *p; p++)
		if (*p == '&')
			alen = alen + strlen(pw->pw_name) - 1;
	(void)snprintf(uidbuf, sizeof uidbuf, "%u", pw->pw_uid);
	(void)snprintf(gidbuf, sizeof gidbuf, "%u", pw->pw_gid);

	if (strlen(pw->pw_name) + 1 + strlen(pw->pw_passwd) + 1 +
	    strlen(uidbuf) + 1 + strlen(gidbuf) + 1 +
	    strlen(pw->pw_gecos) + alen + 1 + strlen(pw->pw_dir) + 1 +
	    strlen(pw->pw_shell) >= 1023) {
		warnx("entries too long");
		return (0);
	}

	/* tell rpc.yppasswdd */
	yppasswd.newpw.pw_name	= pw->pw_name;
	yppasswd.newpw.pw_passwd= pw->pw_passwd;
	yppasswd.newpw.pw_uid	= pw->pw_uid;
	yppasswd.newpw.pw_gid	= pw->pw_gid;
	yppasswd.newpw.pw_gecos = pw->pw_gecos;
	yppasswd.newpw.pw_dir	= pw->pw_dir;
	yppasswd.newpw.pw_shell	= pw->pw_shell;

	client = clnt_create(master, YPPASSWDPROG, YPPASSWDVERS, "udp");
	if (client==NULL) {
		fprintf(stderr, "can't contact yppasswdd on %s: Reason: %s\n",
		    master, yperr_string(YPERR_YPBIND));
		return(1);
	}
	client->cl_auth = authunix_create_default();
	tv.tv_sec = 5;
	tv.tv_usec = 0;
	r = clnt_call(client, YPPASSWDPROC_UPDATE,
	    xdr_yppasswd, &yppasswd, xdr_int, &status, tv);
	if (r) {
		fprintf(stderr, "%s: rpc to yppasswdd failed. %d\n",
		    __progname, r);
		clnt_destroy(client);
		return(1);
	} else if (status) {
		printf("Couldn't change YP password information.\n");
		clnt_destroy(client);
		return(1);
	}
	printf("The YP password information has been changed on %s, the master YP passwd server.\n", master);

	clnt_destroy(client);
	return(0);
}