Example #1
0
static void
edit_file(int is_shadow)
{
	struct stat begin, end;

	pw_init();
	pw_lock();

	if (stat(tmp_file, &begin))
		pw_error(tmp_file, 1, 1);

	pw_edit(0);

	if (stat(tmp_file, &end))
		pw_error(tmp_file, 1, 1);
	if (begin.st_mtime == end.st_mtime) {
		(void)fprintf(stderr, _("%s: no changes made\n"), progname);
		pw_error((char *)NULL, 0, 0);
	}
	if (!is_shadow)
		chmod(tmp_file, 0644);
#if 0
	/* if shadow file, then mode is 0600 now */
	else
		chmod(tmp_file, 0400);
#endif
	pw_unlock();
}
Example #2
0
main()
{
	register int pfd, tfd;
	struct stat begin, end;

	pw_init();
	pfd = pw_lock();
	tfd = pw_tmp();
	copyfile(pfd, tfd);
	(void)close(tfd);

	for (;;) {
		if (stat(tempname, &begin))
			pw_error(tempname, 1, 1);
		pw_edit(0);
		if (stat(tempname, &end))
			pw_error(tempname, 1, 1);
		if (begin.st_mtime == end.st_mtime) {
			(void)fprintf(stderr, "vipw: no changes made\n");
			pw_error((char *)NULL, 0, 0);
		}
		if (pw_mkdb())
			break;
		pw_prompt();
	}
	exit(0);
}
Example #3
0
void xmp_init_callback(xmp_context ctx, void (*callback) (void *, int))
{
	struct xmp_options *o = &((struct xmp_context *)ctx)->o;

	xmp_drv_register(&drv_callback);
	xmp_init_formats(ctx);
	pw_init();

	xmp_register_driver_callback(ctx, callback);

	o->drv_id = "callback";
}
Example #4
0
File: xrt0.c Project: aunali1/exopc
void 
__start () 
{
  char xstack[2048];   

  /* No reason for this to be in a function, except that gcc seems to
   * require it. */
  DEF_SYM (UAREA, UADDR);

  DEF_SYM (__u_xesp, &UAREA.u_xsp);
  DEF_SYM (__u_ppc, &UAREA.u_ppc);
  DEF_SYM (__u_donate, &UAREA.u_donate);
  DEF_SYM (__u_in_critical, &UAREA.u_in_critical);
  DEF_SYM (__u_interrupted, &UAREA.u_interrupted);
  
  DEF_SYM (__envs, UENVS);
  DEF_SYM (__ppages, UPPAGES);
  DEF_SYM (__sysinfo, SYSINFO);
  DEF_SYM (__si_system_ticks, &__sysinfo.si_system_ticks);
  DEF_SYM (__bc, UBC);
  DEF_SYM (__xr, UXN);
  DEF_SYM (__xn_free_map, UXNMAP);

  DEF_SYM (vpt, UVPT);
#define SRL(val, shamt) (((val) >> (shamt)) & ~(-1 << (32 - (shamt))))
  DEF_SYM (vpd, UVPT + SRL(UVPT, 10));

  UAREA.u_xsp = (u_int) xstack + sizeof (xstack);
  UAREA.u_entipc1 = UAREA.u_entipc2 = 0;
  UAREA.u_entfault = (u_int) xue_fault;
  UAREA.u_entprologue = (u_int) xue_prologue;
  UAREA.u_entepilogue = (u_int) xue_epilogue;
  UAREA.u_fpu = 0;
  UAREA.pid = sys_geteid();

  __brkpt = ((u_int) &end + PGMASK) & ~PGMASK;

  /* UAREA.u_ppc is inited to 0 in parent so if it is none zero it means that
     the quantum expired since the beginning of the program and we need to
     yield before our slice gets yanked */

  if (UAREA.u_ppc) 
    yield(-1);

  pw_init ();

  /* and off we go */
  main ();

  __exit();

  start_text_addr = __start;
}
Example #5
0
static void edit_file(int is_shadow)
{
	struct stat begin, end;
	int passwd_file, ch_ret;
	FILE *tmp_fd;

	pw_init();

	/* acquire exclusive lock */
	if (lckpwdf() < 0)
		err(EXIT_FAILURE, _("cannot get lock"));

	passwd_file = open(orig_file, O_RDONLY, 0);
	if (passwd_file < 0)
		err(EXIT_FAILURE, _("cannot open %s"), orig_file);
	tmp_fd = pw_tmpfile(passwd_file);

	if (fstat(fileno(tmp_fd), &begin))
		pw_error(tmp_file, 1, 1);

	pw_edit();

	if (fstat(fileno(tmp_fd), &end))
		pw_error(tmp_file, 1, 1);
	/* Some editors, such as Vim with 'writebackup' mode enabled,
	 * use "atomic save" in which the old file is deleted and a new
	 * one with the same name created in its place.  */
	if (end.st_nlink == 0) {
		if (close_stream(tmp_fd) != 0)
			err(EXIT_FAILURE, _("write error"));
		tmp_fd = fopen(tmp_file, "r");
		if (!tmp_file)
			err(EXIT_FAILURE, _("cannot open %s"), tmp_file);
		if (fstat(fileno(tmp_fd), &end))
			pw_error(tmp_file, 1, 1);
	}
	if (begin.st_mtime == end.st_mtime) {
		warnx(_("no changes made"));
		pw_error((char *)NULL, 0, 0);
	}
	/* pw_tmpfile() will create the file with mode 600 */
	if (!is_shadow)
		ch_ret = fchmod(fileno(tmp_fd), 0644);
	else
		ch_ret = fchmod(fileno(tmp_fd), 0400);
	if (ch_ret < 0)
		err(EXIT_FAILURE, "%s: %s", _("cannot chmod file"), orig_file);
	if (close_stream(tmp_fd) != 0)
		err(EXIT_FAILURE, _("write error"));
	pw_write();
	close(passwd_file);
	ulckpwdf();
}
Example #6
0
File: ipwd.c Project: Raffprta/core
int i_getpwuid(uid_t uid, struct passwd *pwd_r)
{
	struct passwd *result;

	errno = 0;
	do {
		pw_init();
		errno = getpwuid_r(uid, pwd_r, pwbuf, pwbuf_size, &result);
	} while (errno == ERANGE);
	if (result != NULL)
		return 1;
	return errno == 0 ? 0 : -1;
}
Example #7
0
File: ipwd.c Project: Raffprta/core
int i_getpwnam(const char *name, struct passwd *pwd_r)
{
	struct passwd *result;

	errno = 0;
	do {
		pw_init();
		errno = getpwnam_r(name, pwd_r, pwbuf, pwbuf_size, &result);
	} while (errno == ERANGE);
	if (result != NULL)
		return 1;
	if (errno == EINVAL) {
		/* FreeBSD fails here when name="user@domain" */
		return 0;
	}
	return errno == 0 ? 0 : -1;
}
Example #8
0
static int
pw_update(struct passwd * pwd, char const * user)
{
	struct passwd	*pw = NULL;
	struct passwd	*old_pw = NULL;
	int		 rc, pfd, tfd;

	if ((rc = pwdb_check()) != 0)
		return (rc);

	if (pwd != NULL)
		pw = pw_dup(pwd);

	if (user != NULL)
		old_pw = GETPWNAM(user);

	if (pw_init(conf.etcpath, NULL))
		err(1, "pw_init()");
	if ((pfd = pw_lock()) == -1) {
		pw_fini();
		err(1, "pw_lock()");
	}
	if ((tfd = pw_tmp(-1)) == -1) {
		pw_fini();
		err(1, "pw_tmp()");
	}
	if (pw_copy(pfd, tfd, pw, old_pw) == -1) {
		pw_fini();
		close(tfd);
		err(1, "pw_copy()");
	}
	fsync(tfd);
	close(tfd);
	/*
	 * in case of deletion of a user, the whole database
	 * needs to be regenerated
	 */
	if (pw_mkdb(pw != NULL ? pw->pw_name : NULL) == -1) {
		pw_fini();
		err(1, "pw_mkdb()");
	}
	free(pw);
	pw_fini();

	return (0);
}
void xmp_init(xmp_context ctx, int argc, char **argv)
{
	struct xmp_player_context *p = &((struct xmp_context *)ctx)->p;
	int num;

	xmp_init_formats(ctx);
	pw_init();

	p->event_callback = NULL;

	/* must be parsed before loading the rc file. */
	for (num = 1; num < argc; num++) {
		if (!strcmp(argv[num], "--norc"))
			break;
	}
	if (num >= argc)
		_xmp_read_rc((struct xmp_context *)ctx);
}
Example #10
0
static int
pw_update(struct passwd * pwd, char const * user)
{
	int             rc = 0;

	rc = pwdb("-C", (char *)NULL);	/* Check only */
	if (rc == 0) {
		int pfd, tfd;
		struct passwd *pw = NULL;
		struct passwd *old_pw = NULL;

		if (pwd != NULL)
			pw = pw_dup(pwd);

		if (user != NULL)
			old_pw = GETPWNAM(user);

		if (pw_init(pwpath, NULL))
			err(1, "pw_init()");
		if ((pfd = pw_lock()) == -1) {
			pw_fini();
			err(1, "pw_lock()");
		}
		if ((tfd = pw_tmp(-1)) == -1) {
			pw_fini();
			err(1, "pw_tmp()");
		}
		if (pw_copy(pfd, tfd, pw, old_pw) == -1) {
			pw_fini();
			err(1, "pw_copy()");
		}
		/*
		 * in case of deletion of a user, the whole database
		 * needs to be regenerated
		 */
		if (pw_mkdb(pw != NULL ? pw->pw_name : NULL) == -1) {
			pw_fini();
			err(1, "pw_mkdb()");
		}
		free(pw);
		pw_fini();
	}
	return 0;
}
Example #11
0
void xmp_init(xmp_context ctx, int argc, char **argv)
{
	int num;

	xmp_init_drivers();
	xmp_init_formats(ctx);
	pw_init();

	xmp_event_callback = NULL;

	/* must be parsed before loading the rc file. */
	for (num = 1; num < argc; num++) {
		if (!strcmp(argv[num], "--norc"))
			break;
	}
	if (num >= argc)
		xmpi_read_rc((struct xmp_context *)ctx);

	xmpi_tell_wait();
}
Example #12
0
static int
pw_nisupdate(const char * path, struct passwd * pwd, char const * user)
{
	int pfd, tfd;
	struct passwd *pw = NULL;
	struct passwd *old_pw = NULL;

	printf("===> %s\n", path);
	if (pwd != NULL)
		pw = pw_dup(pwd);

	if (user != NULL)
		old_pw = GETPWNAM(user);

	if (pw_init(NULL, path))
		err(1,"pw_init()");
	if ((pfd = pw_lock()) == -1) {
		pw_fini();
		err(1, "pw_lock()");
	}
	if ((tfd = pw_tmp(-1)) == -1) {
		pw_fini();
		err(1, "pw_tmp()");
	}
	if (pw_copy(pfd, tfd, pw, old_pw) == -1) {
		pw_fini();
		close(tfd);
		err(1, "pw_copy()");
	}
	close(tfd);
	if (chmod(pw_tempname(), 0644) == -1)
		err(1, "chmod()");
	if (rename(pw_tempname(), path) == -1)
		err(1, "rename()");

	free(pw);
	pw_fini();

	return (0);
}
Example #13
0
void
pwlocal_process(const char *username, int argc, char **argv)
{
	struct passwd *pw;
	struct passwd old_pw;
	time_t old_change;
	int pfd, tfd;
	int min_pw_len = 0;
	int pw_expiry  = 0;
	int ch;
#ifdef LOGIN_CAP
	login_cap_t *lc;
#endif

	while ((ch = getopt(argc, argv, "l")) != -1) {
		switch (ch) {
		case 'l':
			/*
			 * Aborb the -l 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 (!(pw = getpwnam(username)))
		errx(1, "unknown user %s", username);

	uid = getuid();
	if (uid && uid != pw->pw_uid)
		errx(1, "%s", strerror(EACCES));

	/* Save the old pw information for comparing on pw_copy(). */
	old_pw = *pw;

	/*
	 * Get class restrictions for this user, then get the new password. 
	 */
#ifdef LOGIN_CAP
	if((lc = login_getclass(pw->pw_class)) != NULL) {
		min_pw_len = (int) login_getcapnum(lc, "minpasswordlen", 0, 0);
		pw_expiry  = (int) login_getcaptime(lc, "passwordtime", 0, 0);
		login_close(lc);
	}
#endif
#if 0
	printf("AAA: pw_expiry = %x\n", pw_expiry);
#endif
	pw->pw_passwd = getnewpasswd(pw, min_pw_len);
	old_change = pw->pw_change;
	pw->pw_change = pw_expiry ? pw_expiry + time(NULL) : 0;

	/*
	 * Now that the user has given us a new password, let us
	 * change the database.
	 */
	pw_init();
	tfd = pw_lock(0);
	if (tfd < 0) {
		warnx ("The passwd file is busy, waiting...");
		tfd = pw_lock(10);
		if (tfd < 0)
			errx(1, "The passwd file is still busy, "
			     "try again later.");
	}

	pfd = open(_PATH_MASTERPASSWD, O_RDONLY, 0);
	if (pfd < 0)
		pw_error(_PATH_MASTERPASSWD, 1, 1);

	pw_copy(pfd, tfd, pw, &old_pw);

	if (pw_mkdb(username, old_change == pw->pw_change) < 0)
		pw_error((char *)NULL, 0, 1);

	syslog(LOG_AUTH | LOG_INFO,
	       "user %s (UID %lu) successfully changed "
	       "the local password of user %s",
	       uid ? username : "******", (unsigned long)uid, username);
}
Example #14
0
/*
 *  setpwnam () --
 *	takes a struct passwd in which every field is filled in and valid.
 *	If the given username exists in the passwd file, the entry is
 *	replaced with the given entry.
 */
int setpwnam(struct passwd *pwd)
{
	FILE *fp = NULL, *pwf = NULL;
	int save_errno;
	int found;
	int namelen;
	int buflen = 256;
	int contlen, rc;
	char *linebuf = NULL;
	char *tmpname = NULL;

	pw_init();

	if ((fp = xfmkstemp(&tmpname)) == NULL)
		return -1;

	/* ptmp should be owned by root.root or root.wheel */
	if (fchown(fileno(fp), (uid_t) 0, (gid_t) 0) < 0)
		goto fail;

	/* acquire exclusive lock */
	if (lckpwdf() < 0)
		goto fail;
	pwf = fopen(PASSWD_FILE, "r");
	if (!pwf)
		goto fail;

	namelen = strlen(pwd->pw_name);

	linebuf = malloc(buflen);
	if (!linebuf)
		goto fail;

	/* parse the passwd file */
	found = false;

	/* Do you wonder why I don't use getpwent? Read comments at top of
	 * file */
	while (fgets(linebuf, buflen, pwf) != NULL) {
		contlen = strlen(linebuf);
		while (linebuf[contlen - 1] != '\n' && !feof(pwf)) {
			char *tmp;
			/* Extend input buffer if it failed getting the whole line,
			 * so now we double the buffer size */
			buflen *= 2;
			tmp = realloc(linebuf, buflen);
			if (tmp == NULL)
				goto fail;
			linebuf = tmp;
			/* And fill the rest of the buffer */
			if (fgets(&linebuf[contlen], buflen / 2, pwf) == NULL)
				break;
			contlen = strlen(linebuf);
			/* That was a lot of work for nothing. Gimme perl! */
		}

		/* Is this the username we were sent to change? */
		if (!found && linebuf[namelen] == ':' &&
		    !strncmp(linebuf, pwd->pw_name, namelen)) {
			/* Yes! So go forth in the name of the Lord and
			 * change it!  */
			if (putpwent(pwd, fp) < 0)
				goto fail;
			found = true;
			continue;
		}
		/* Nothing in particular happened, copy input to output */
		fputs(linebuf, fp);
	}

	/* xfmkstemp is too restrictive by default for passwd file */
	if (fchmod(fileno(fp), 0644) < 0)
		goto fail;
	rc = close_stream(fp);
	fp = NULL;
	if (rc != 0)
		goto fail;

	fclose(pwf);	/* I don't think I want to know if this failed */
	pwf = NULL;

	if (!found) {
		errno = ENOENT;	/* give me something better */
		goto fail;
	}

	/* we don't care if we can't remove the backup file */
	unlink(PASSWD_FILE ".OLD");
	/* we don't care if we can't create the backup file */
	ignore_result(link(PASSWD_FILE, PASSWD_FILE ".OLD"));
	/* we DO care if we can't rename to the passwd file */
	if (rename(tmpname, PASSWD_FILE) < 0)
		goto fail;
	/* finally:  success */
	ulckpwdf();
	return 0;

 fail:
	save_errno = errno;
	ulckpwdf();
	if (fp != NULL)
		fclose(fp);
	if (tmpname != NULL)
		unlink(tmpname);
	free(tmpname);
	if (pwf != NULL)
		fclose(pwf);
	free(linebuf);
	errno = save_errno;
	return -1;
}
Example #15
0
/*
 *  setpwnam () --
 *	takes a struct passwd in which every field is filled in and valid.
 *	If the given username exists in the passwd file, the entry is
 *	replaced with the given entry.
 */
int 
setpwnam (struct passwd *pwd)
{
    FILE *fp = NULL, *pwf = NULL;
    int x, save_errno, fd, ret;
    boolean found;
    int oldumask;
    int namelen;
    int buflen = 256;
    int contlen;
    char *linebuf = malloc(buflen);

    if (!linebuf) return -1;

    oldumask = umask(0);   /* Create with exact permissions */

    pw_init();

    /* sanity check */
    for (x = 0; x < 3; x++) {
	if (x > 0) sleep(1);
	fd = open(PTMPTMP_FILE, O_WRONLY|O_CREAT, 0644);
	if (fd == -1) {
	    umask(oldumask);
	    return -1;
	}
	ret = link(PTMPTMP_FILE, PTMP_FILE);
	unlink(PTMPTMP_FILE);
	if (ret == -1)
	    close(fd);
	else
	    break;
    }
    umask(oldumask);
    if (ret == -1) return -1;

    /* ptmp should be owned by root.root or root.wheel */
    if (chown(PTMP_FILE, (uid_t) 0, (gid_t) 0) < 0) return -1;

    /* open ptmp for writing and passwd for reading */
    fp = fdopen(fd, "w");
    if (!fp) goto fail;

    pwf = fopen(PASSWD_FILE, "r");
    if (!pwf) goto fail;

    namelen = strlen(pwd->pw_name);

    /* parse the passwd file */
    found = false;
    /* Do you wonder why I don't use getpwent? Read comments at top of file */
    while (fgets(linebuf, buflen, pwf) != NULL) {
	contlen = strlen(linebuf);
	while (linebuf[contlen-1] != '\n' && !feof(pwf)) {
	    /* Extend input buffer if it failed getting the whole line */

	    /* So now we double the buffer size */
	    buflen *= 2;

	    linebuf = realloc(linebuf, buflen);
	    if (linebuf == NULL) goto fail;

	    /* And fill the rest of the buffer */
	    if (fgets(&linebuf[contlen], buflen/2, pwf) == NULL) break;
	    contlen = strlen(linebuf);
      
	    /* That was a lot of work for nothing.  Gimme perl! */
	}

	/* Is this the username we were sent to change? */
	if (!found && linebuf[namelen] == ':' &&
	    !strncmp(linebuf, pwd->pw_name, namelen)) {
	    /* Yes! So go forth in the name of the Lord and change it! */
	    if (putpwent(pwd, fp) < 0) goto fail;
	    found = true;
	    continue;
	}
	/* Nothing in particular happened, copy input to output */
	fputs(linebuf, fp);
    }

    if (fclose(fp) < 0) goto fail;
    fp = NULL;
    close (fd);
    fd = -1;
    fclose (pwf); /* I don't think I want to know if this failed */
    pwf = NULL;

    if (!found) {
	errno = ENOENT; /* give me something better */
	goto fail;
    }

    /* we don't care if we can't remove the backup file */
    unlink(PASSWD_FILE".OLD");
    /* we don't care if we can't create the backup file */
    link(PASSWD_FILE, PASSWD_FILE".OLD");
    /* we DO care if we can't rename to the passwd file */
    if(rename(PTMP_FILE, PASSWD_FILE) < 0)
	goto fail;
    /* finally:  success */
    return 0;

fail:
    save_errno = errno;
    if (fp != NULL) fclose (fp);
    if (pwf != NULL) fclose(pwf);
    if (fd >= 0) close (fd);
    if (linebuf != NULL) free(linebuf);
    unlink(PTMP_FILE);
    errno = save_errno;
    return -1;
}
Example #16
0
int
main(int argc, char *argv[])
{
	const char *passwd_dir = NULL;
	int ch, pfd, tfd;
	char *line;
	size_t len;

	while ((ch = getopt(argc, argv, "d:")) != -1)
		switch (ch) {
		case 'd':
			passwd_dir = optarg;
			break;
		case '?':
		default:
			usage();
		}

	argc -= optind;
	argv += optind;

	if (argc != 0)
		usage();

	if (pw_init(passwd_dir, NULL) == -1)
		err(1, "pw_init()");
	if ((pfd = pw_lock()) == -1) {
		pw_fini();
		err(1, "pw_lock()");
	}
	if ((tfd = pw_tmp(pfd)) == -1) {
		pw_fini();
		err(1, "pw_tmp()");
	}
	close(tfd);
	/* Force umask for partial writes made in the edit phase */
	umask(077);

	for (;;) {
		switch (pw_edit(0)) {
		case -1:
			pw_fini();
			err(1, "pw_edit()");
		case 0:
			pw_fini();
			errx(0, "no changes made");
		default:
			break;
		}
		if (pw_mkdb(NULL) == 0) {
			pw_fini();
			errx(0, "password list updated");
		}
		printf("re-edit the password file? ");
		fflush(stdout);
		if ((line = fgetln(stdin, &len)) == NULL) {
			pw_fini();
			err(1, "fgetln()");
		}
		if (len > 0 && (*line == 'N' || *line == 'n'))
			break;
	}
	pw_fini();
	exit(0);
}
Example #17
0
int
main(int argc, char **argv)
{
	enum { NEWSH, LOADENTRY, EDITENTRY } op;
	struct passwd *pw, lpw, old_pw;
	int ch, dfd, pfd, tfd;
#ifdef YP
	int yflag = 0;
#endif
	char *arg, *username = NULL;

#ifdef __GNUC__
	pw = NULL;		/* XXX gcc -Wuninitialized */
	arg = NULL;
#endif
#ifdef	YP
	use_yp = _yp_check(NULL);
#endif

	op = EDITENTRY;
	while ((ch = getopt(argc, argv, "a:s:ly")) != -1)
		switch (ch) {
		case 'a':
			op = LOADENTRY;
			arg = optarg;
			break;
		case 's':
			op = NEWSH;
			arg = optarg;
			break;
		case 'l':
			use_yp = 0;
			break;
		case 'y':
#ifdef	YP
			if (!use_yp)
				errx(1, "YP not in use.");
			yflag = 1;
#else
			errx(1, "YP support not compiled in.");
#endif
			break;
		default:
			usage();
		}
	argc -= optind;
	argv += optind;

	uid = getuid();
	switch (argc) {
	case 0:
		/* nothing */
		break;

	case 1:
		username = argv[0];
		break;

	default:
		usage();
	}

#ifdef YP
	/*
	 * We need to determine if we _really_ want to use YP.
	 * If we defaulted to YP (i.e. were not given the -y flag),
	 * and the master is not running rpc.yppasswdd, we check
	 * to see if the user exists in the local passwd database.
	 * If so, we use it, otherwise we error out.
	 */
	if (use_yp && yflag == 0) {
		if (check_yppasswdd()) {
			/*
			 * We weren't able to contact rpc.yppasswdd.
			 * Check to see if we're in the local
			 * password database.  If we are, use it.
			 */
			if (username != NULL)
				pw = getpwnam(username);
			else
				pw = getpwuid(uid);
			if (pw != NULL)
				use_yp = 0;
			else {
				warnx("master YP server not running yppasswd"
				    " daemon.");
				errx(1, "Can't change password.");
			}
		}
	}
#endif

#ifdef YP
	if (use_yp)
		Pw_error = yppw_error;
	else
#endif
		Pw_error = pw_error;

#ifdef	YP
	if (op == LOADENTRY && use_yp)
		errx(1, "cannot load entry using YP.\n"
		    "\tUse the -l flag to load local.");
#endif

	if (op == EDITENTRY || op == NEWSH) {
		if (username != NULL) {
			pw = getpwnam(username);
			if (pw == NULL)
				errx(1, "unknown user: %s", username);
			if (uid && uid != pw->pw_uid)
				baduser();
		} else {
			pw = getpwuid(uid);
			if (pw == NULL)
				errx(1, "unknown user: uid %u", uid);
		}

		/* Make a copy for later verification */
		old_pw = *pw;
		old_pw.pw_gecos = strdup(old_pw.pw_gecos);
		if (!old_pw.pw_gecos) {
			err(1, "strdup");
			/*NOTREACHED*/
		}
	}

	if (op == NEWSH) {
		/* protect p_shell -- it thinks NULL is /bin/sh */
		if (!arg[0])
			usage();
		if (p_shell(arg, pw, NULL))
			(*Pw_error)(NULL, 0, 1);
	}

	if (op == LOADENTRY) {
		if (uid)
			baduser();
		pw = &lpw;
		if (!pw_scan(arg, pw, NULL))
			exit(1);
	}

	/* Edit the user passwd information if requested. */
	if (op == EDITENTRY) {
		struct stat sb;

		dfd = mkstemp(tempname);
		if (dfd < 0 || fcntl(dfd, F_SETFD, 1) < 0)
			(*Pw_error)(tempname, 1, 1);
		if (atexit(cleanup)) {
			cleanup();
			errx(1, "couldn't register cleanup");
		}
		if (stat(dirname(tempname), &sb) == -1)
			err(1, "couldn't stat `%s'", dirname(tempname));
		if (!(sb.st_mode & S_ISTXT))
			errx(1, "temporary directory `%s' is not sticky",
			    dirname(tempname));

		display(tempname, dfd, pw);
		edit(tempname, pw);
	}

#ifdef	YP
	if (use_yp) {
		if (pw_yp(pw, uid))
			yppw_error(NULL, 0, 1);
		else
			exit(0);
		/* Will not exit from this if. */
	}
#endif	/* YP */


	/*
	 * Get the passwd lock file and open the passwd file for
	 * reading.
	 */
	pw_init();
	tfd = pw_lock(0);
	if (tfd < 0) {
		if (errno != EEXIST)
			err(1, "%s", _PATH_MASTERPASSWD_LOCK);
		warnx("The passwd file is busy, waiting...");
		tfd = pw_lock(10);
		if (tfd < 0) {
			if (errno != EEXIST)
				err(1, "%s", _PATH_MASTERPASSWD_LOCK);
			errx(1, "The passwd file is still busy, "
			     "try again later.");
		}
	}
	if (fcntl(tfd, F_SETFD, 1) < 0)
		pw_error(_PATH_MASTERPASSWD_LOCK, 1, 1);

	pfd = open(_PATH_MASTERPASSWD, O_RDONLY, 0);
	if (pfd < 0 || fcntl(pfd, F_SETFD, 1) < 0)
		pw_error(_PATH_MASTERPASSWD, 1, 1);

	/* Copy the passwd file to the lock file, updating pw. */
	pw_copy(pfd, tfd, pw, (op == LOADENTRY) ? NULL : &old_pw);

	close(pfd);
	close(tfd);

	/* Now finish the passwd file update. */
	if (pw_mkdb(username, 0) < 0)
		pw_error(NULL, 0, 1);

	exit(0);
}
Example #18
0
static int
pw_update(struct passwd * pwd, char const * user)
{
	int             rc = 0;

	/*
	 * First, let's check the see if the database is alright
	 * Note: -C is only available in FreeBSD 2.2 and above
	 */
#ifdef HAVE_PWDB_C
	rc = pwdb("-C", (char *)NULL);	/* Check only */
	if (rc == 0) {
#else
	{				/* No -C */
#endif
		int pfd, tfd;
		struct passwd *pw = NULL;
		struct passwd *old_pw = NULL;

	       	if (pwd != NULL)
		       pw = pw_dup(pwd);

		if (user != NULL)
			old_pw = GETPWNAM(user);

		if (pw_init(pwpath, NULL))
			err(1, "pw_init()");
		if ((pfd = pw_lock()) == -1) {
			pw_fini();
			err(1, "pw_lock()");
		}
		if ((tfd = pw_tmp(-1)) == -1) {
			pw_fini();
			err(1, "pw_tmp()");
		}
		if (pw_copy(pfd, tfd, pw, old_pw) == -1) {
			pw_fini();
			err(1, "pw_copy()");
		}
		if (pw_mkdb(user) == -1) {
			pw_fini();
			err(1, "pw_mkdb()");
		}
		free(pw);
		pw_fini();
	}
	return 0;
}

int
addpwent(struct passwd * pwd)
{
	return pw_update(pwd, NULL);
}

int
chgpwent(char const * login, struct passwd * pwd)
{
	return pw_update(pwd, login);
}

int
delpwent(struct passwd * pwd)
{
	char login[MAXLOGNAME];
	
	strlcpy(login, pwd->pw_name, MAXLOGNAME);
	return pw_update(NULL, login);
}
Example #19
0
int
main(int argc, char *argv[])
{
	enum { NEWSH, LOADENTRY, EDITENTRY, NEWPW, NEWEXP } op;
	struct passwd lpw, *old_pw, *pw;
	int ch, pfd, tfd;
	const char *password;
	char *arg = NULL;
	uid_t uid;
#ifdef YP
	struct ypclnt *ypclnt;
	const char *yp_domain = NULL, *yp_host = NULL;
#endif

	pw = old_pw = NULL;
	op = EDITENTRY;
#ifdef YP
	while ((ch = getopt(argc, argv, "a:p:s:e:d:h:loy")) != -1)
#else
	while ((ch = getopt(argc, argv, "a:p:s:e:")) != -1)
#endif
		switch (ch) {
		case 'a':
			op = LOADENTRY;
			arg = optarg;
			break;
		case 's':
			op = NEWSH;
			arg = optarg;
			break;
		case 'p':
			op = NEWPW;
			arg = optarg;
			break;
		case 'e':
			op = NEWEXP;
			arg = optarg;
			break;
#ifdef YP
		case 'd':
			yp_domain = optarg;
			break;
		case 'h':
			yp_host = optarg;
			break;
		case 'l':
		case 'o':
		case 'y':
			/* compatibility */
			break;
#endif
		case '?':
		default:
			usage();
		}

	argc -= optind;
	argv += optind;

	if (argc > 1)
		usage();

	uid = getuid();

	if (op == EDITENTRY || op == NEWSH || op == NEWPW || op == NEWEXP) {
		if (argc == 0) {
			if ((pw = getpwuid(uid)) == NULL)
				errx(1, "unknown user: uid %lu",
				    (unsigned long)uid);
		} else {
			if ((pw = getpwnam(*argv)) == NULL)
				errx(1, "unknown user: %s", *argv);
			if (uid != 0 && uid != pw->pw_uid)
				baduser();
		}

		/* Make a copy for later verification */
		if ((pw = pw_dup(pw)) == NULL ||
		    (old_pw = pw_dup(pw)) == NULL)
			err(1, "pw_dup");
	}

#ifdef YP
	if (pw != NULL && (pw->pw_fields & _PWF_SOURCE) == _PWF_NIS) {
		ypclnt = ypclnt_new(yp_domain, "passwd.byname", yp_host);
		master_mode = (ypclnt != NULL &&
		    ypclnt_connect(ypclnt) != -1 &&
		    ypclnt_havepasswdd(ypclnt) == 1);
		ypclnt_free(ypclnt);
	} else
#endif
	master_mode = (uid == 0);

	if (op == NEWSH) {
		/* protect p_shell -- it thinks NULL is /bin/sh */
		if (!arg[0])
			usage();
		if (p_shell(arg, pw, (ENTRY *)NULL) == -1)
			exit(1);
	}

	if (op == NEWEXP) {
		if (uid)	/* only root can change expire */
			baduser();
		if (p_expire(arg, pw, (ENTRY *)NULL) == -1)
			exit(1);
	}

	if (op == LOADENTRY) {
		if (uid)
			baduser();
		pw = &lpw;
		old_pw = NULL;
		if (!__pw_scan(arg, pw, _PWSCAN_WARN|_PWSCAN_MASTER))
			exit(1);
	}

	if (op == NEWPW) {
		if (uid)
			baduser();

		if (strchr(arg, ':'))
			errx(1, "invalid format for password");
		pw->pw_passwd = arg;
	}

	if (op == EDITENTRY) {
		/*
		 * We don't really need pw_*() here, but pw_edit() (used
		 * by edit()) is just too useful...
		 */
		if (pw_init(NULL, NULL))
			err(1, "pw_init()");
		if ((tfd = pw_tmp(-1)) == -1) {
			pw_fini();
			err(1, "pw_tmp()");
		}
		free(pw);
		pw = edit(pw_tempname(), old_pw);
		pw_fini();
		if (pw == NULL)
			err(1, "edit()");
		/* 
		 * pw_equal does not check for crypted passwords, so we
		 * should do it explicitly
		 */
		if (pw_equal(old_pw, pw) && 
		    strcmp(old_pw->pw_passwd, pw->pw_passwd) == 0)
			errx(0, "user information unchanged");
	}

	if (old_pw && !master_mode) {
		password = getpass("Password: "******"";
	}

	if (old_pw != NULL)
		pw->pw_fields |= (old_pw->pw_fields & _PWF_SOURCE);
	switch (pw->pw_fields & _PWF_SOURCE) {
#ifdef YP
	case _PWF_NIS:
		ypclnt = ypclnt_new(yp_domain, "passwd.byname", yp_host);
		if (ypclnt == NULL) {
			warnx("ypclnt_new failed");
			exit(1);
		}
		if (ypclnt_connect(ypclnt) == -1 ||
		    ypclnt_passwd(ypclnt, pw, password) == -1) {
			warnx("%s", ypclnt->error);
			ypclnt_free(ypclnt);
			exit(1);
		}
		ypclnt_free(ypclnt);
		errx(0, "NIS user information updated");
#endif /* YP */
	case 0:
	case _PWF_FILES:
		if (pw_init(NULL, NULL))
			err(1, "pw_init()");
		if ((pfd = pw_lock()) == -1) {
			pw_fini();
			err(1, "pw_lock()");
		}
		if ((tfd = pw_tmp(-1)) == -1) {
			pw_fini();
			err(1, "pw_tmp()");
		}
		if (pw_copy(pfd, tfd, pw, old_pw) == -1) {
			pw_fini();
			err(1, "pw_copy");
		}
		if (pw_mkdb(pw->pw_name) == -1) {
			pw_fini();
			err(1, "pw_mkdb()");
		}
		pw_fini();
		errx(0, "user information updated");
		break;
	default:
		errx(1, "unsupported passwd source");
	}
}
Example #20
0
int
main(int argc, char *argv[])
{
	struct passwd *pw = NULL, *opw = NULL, lpw;
	int i, ch, pfd, tfd, dfd;
	char *tz, *arg = NULL;
	sigset_t fullset;

#ifdef	YP
	use_yp = _yp_check(NULL);
#endif
	/* We need to use the system timezone for date conversions. */
	if ((tz = getenv("TZ")) != NULL) {
	    unsetenv("TZ");
	    tzset();
	    setenv("TZ", tz, 1);
	}

	op = EDITENTRY;
	while ((ch = getopt(argc, argv, "a:s:ly")) != -1)
		switch(ch) {
		case 'a':
			op = LOADENTRY;
			arg = optarg;
			break;
		case 's':
			op = NEWSH;
			arg = optarg;
			break;
#ifdef	YP
		case 'l':
			use_yp = 0;
			break;
		case 'y':
			if (!use_yp) {
				warnx("YP not in use.");
				usage();
			}
			force_yp = 1;
			break;
#endif
		case '?':
		default:
			usage();
		}
	argc -= optind;
	argv += optind;

#ifdef	YP
	if (op == LOADENTRY && use_yp)
		errx(1, "cannot load using YP, use -l to load local.");
#endif
	uid = getuid();

	if (op == EDITENTRY || op == NEWSH)
		switch(argc) {
		case 0:
			pw = getpwuid(uid);
#ifdef	YP
			if (pw && !force_yp)
				use_yp = 0;
			else if (use_yp)
				pw = ypgetpwuid(uid);
#endif	/* YP */
			if (!pw)
				errx(1, "unknown user: uid %u", uid);
			break;
		case 1:
			pw = getpwnam(*argv);
#ifdef	YP
			if (pw && !force_yp)
				use_yp = 0;
			else if (use_yp)
				pw = ypgetpwnam(*argv);
#endif	/* YP */
			if (!pw)
				errx(1, "unknown user: %s", *argv);
			if (uid && uid != pw->pw_uid)
				baduser();
			break;
		default:
			usage();
		}

	if (op == LOADENTRY) {
		if (argc != 0)
			errx(1, "option -a does not accept user argument");
		if (uid)
			baduser();
		pw = &lpw;
		if (!pw_scan(arg, pw, NULL))
			exit(1);
		opw = getpwnam(pw->pw_name);
	}
	if (opw == NULL && (opw = pw_dup(pw)) == NULL)
		err(1, NULL);

	/* Edit the user passwd information if requested. */
	if (op == EDITENTRY) {
		char tempname[] = _PATH_VARTMP "pw.XXXXXXXXXX";
		int edit_status;

		if ((pw = pw_dup(pw)) == NULL)
			pw_error(NULL, 1, 1);
		dfd = mkstemp(tempname);
		if (dfd == -1 || fcntl(dfd, F_SETFD, 1) == -1)
			pw_error(tempname, 1, 1);
		display(tempname, dfd, pw);
		edit_status = edit(tempname, pw);
		close(dfd);
		unlink(tempname);

		switch (edit_status) {
		case EDIT_OK:
			break;
		case EDIT_NOCHANGE:
			pw_error(NULL, 0, 0);
			break;
		case EDIT_ERROR:
		default:
			pw_error(tempname, 1, 1);
			break;
		}
	}

	if (op == NEWSH) {
		/* protect p_shell -- it thinks NULL is /bin/sh */
		if (!arg[0])
			usage();
		if (p_shell(arg, pw, NULL))
			pw_error(NULL, 0, 1);
	}

	/* Drop user's real uid and block all signals to avoid a DoS. */
	setuid(0);
	sigfillset(&fullset);
	sigdelset(&fullset, SIGINT);
	sigprocmask(SIG_BLOCK, &fullset, NULL);

	/* Get the passwd lock file and open the passwd file for reading. */
	pw_init();
	for (i = 1; (tfd = pw_lock(0)) == -1; i++) {
		if (i == 4)
			(void)fputs("Attempting to lock password file, "
			    "please wait or press ^C to abort", stderr);
		(void)signal(SIGINT, kbintr);
		if (i % 16 == 0)
			fputc('.', stderr);
		usleep(250000);
		(void)signal(SIGINT, SIG_IGN);
	}
	if (i >= 4)
		fputc('\n', stderr);
	pfd = open(_PATH_MASTERPASSWD, O_RDONLY, 0);
	if (pfd == -1 || fcntl(pfd, F_SETFD, 1) == -1)
		pw_error(_PATH_MASTERPASSWD, 1, 1);

#ifdef	YP
	if (use_yp) {
		if (pw_yp(pw, uid))
			pw_error(NULL, 0, 1);
		else {
			pw_abort();
			exit(0);
		}
	} else
#endif	/* YP */
	{
		/* Copy the passwd file to the lock file, updating pw. */
		pw_copy(pfd, tfd, pw, opw);

		/* If username changed we need to rebuild the entire db. */
		arg = !strcmp(opw->pw_name, pw->pw_name) ? pw->pw_name : NULL;

		/* Now finish the passwd file update. */
		if (pw_mkdb(arg, 0) == -1)
			pw_error(NULL, 0, 1);
	}

	exit(0);
}