Esempio n. 1
0
/*
 * private_getspnam_r()
 *
 * A private implementation of getspnam_r which does *not* fall back to
 * other services possibly defined in nsswitch.conf.
 *
 * Behaves like getspnam_r(). Since we use fgetspent_t(), all numeric
 * fields that are undefined in /etc/shadow will be set to -1.
 *
 */
struct spwd *
private_getspnam_r(const char *name, struct spwd *result, char *buffer,
    int buflen)
{
	FILE *fp;
	int found;

	fp = fopen(SHADOW, "rF");
	if (fp == NULL)
		return (NULL);

	found = 0;
	while (!found && fgetspent_r(fp, result, buffer, buflen) != NULL) {
		if (strcmp(name, result->sp_namp) == 0)
			found = 1;
	}

	(void) fclose(fp);

	if (!found) {
		(void) memset(buffer, 0, buflen);
		(void) memset(result, 0, sizeof (*result));
		return (NULL);
	}
	return (result);
}
Esempio n. 2
0
struct spwd *
fgetspent(FILE *f)
{
	nss_XbyY_buf_t	*b = get_spbuf();

	return (b == NULL ? NULL :
	    fgetspent_r(f, b->result, b->buffer, b->buflen));
}
struct spwd *fgetspent(FILE * file)
{
    int ret;
    static char line_buff[PWD_BUFFER_SIZE];
    static struct spwd spwd;
    struct spwd *result;

    LOCK;
    if ((ret=fgetspent_r(file, &spwd, line_buff, sizeof(line_buff), &result)) == 0) {
	UNLOCK;
	return &spwd;
    }
    UNLOCK;
    __set_errno(ret);
    return NULL;
}
Esempio n. 4
0
static gboolean
fgetspent_callback (void (* callback) (struct spwd *, gpointer),
                    gpointer user_data)
{
  struct spwd spb;
  struct spwd *sp;
  gchar *buffer;
  gsize buflen;
  FILE *fp;
  int ret;

  fp = fopen (cockpit_bridge_path_shadow, "r");
  if (fp == NULL)
    {
      g_message ("unable to open %s: %s", cockpit_bridge_path_shadow, g_strerror (errno));
      return FALSE;
    }

  buflen = 16 * 1024;
  buffer = g_malloc (buflen);

  for (;;)
    {
      ret = fgetspent_r (fp, &spb, buffer, buflen, &sp);
      if (ret == 0)
        {
          callback (sp, user_data);
        }
      else
        {
          g_free (buffer);
          fclose (fp);
          return (ret == ENOENT);
        }
    }
}
Esempio n. 5
0
/*
 * files_update_shadow(char *name, struct spwd *spwd)
 *
 * update the shadow password file SHADOW to contain the spwd structure
 * "spwd" for user "name"
 */
int
files_update_shadow(char *name, struct spwd *spwd)
{
	struct stat64 stbuf;
	FILE *dst;
	FILE *src;
	struct spwd cur;
	char buf[SPW_SCRATCH_SIZE];
	int tempfd;
	mode_t filemode;
	int result = -1;
	int err = PWU_SUCCESS;

	/* Mode of the shadow file should be 400 or 000 */
	if (stat64(SHADOW, &stbuf) < 0) {
		err = PWU_STAT_FAILED;
		goto shadow_exit;
	}

	/* copy mode from current shadow file (0400 or 0000) */
	filemode = stbuf.st_mode & S_IRUSR;

	/*
	 * we can't specify filemodes to fopen(), and we SHOULD NOT
	 * set umask in multi-thread safe libraries, so we use
	 * a combination of open() and fdopen()
	 */
	tempfd = open(SHADTEMP, O_WRONLY|O_CREAT|O_TRUNC, filemode);
	if (tempfd < 0) {
		err = PWU_OPEN_FAILED;
		goto shadow_exit;
	}
	(void) fchown(tempfd, (uid_t)0, stbuf.st_gid);

	if ((dst = fdopen(tempfd, "wF")) == NULL) {
		err = PWU_OPEN_FAILED;
		goto shadow_exit;
	}

	if ((src = fopen(SHADOW, "rF")) == NULL) {
		err = PWU_OPEN_FAILED;
		(void) fclose(dst);
		(void) unlink(SHADTEMP);
		goto shadow_exit;
	}

	/*
	 * copy old shadow to temporary file while replacing the entry
	 * that matches "name".
	 */
	while (fgetspent_r(src, &cur, buf, sizeof (buf)) != NULL) {

		if (strcmp(cur.sp_namp, name) == 0)
			result = putspent(spwd, dst);
		else
			result = putspent(&cur, dst);

		if (result != 0) {
			err = PWU_WRITE_FAILED;
			(void) fclose(src);
			(void) fclose(dst);
			goto shadow_exit;
		}
	}

	(void) fclose(src);

	if (fclose(dst) != 0) {
		/*
		 * Something went wrong (ENOSPC for example). Don't
		 * use the resulting temporary file!
		 */
		err = PWU_CLOSE_FAILED;
		(void) unlink(SHADTEMP);
		goto shadow_exit;
	}

	/*
	 * Rename stmp to shadow:
	 *   1. make sure /etc/oshadow is gone
	 *   2. ln /etc/shadow /etc/oshadow
	 *   3. mv /etc/stmp /etc/shadow
	 */
	if (unlink(OSHADOW) && access(OSHADOW, 0) == 0) {
		err = PWU_UPDATE_FAILED;
		(void) unlink(SHADTEMP);
		goto shadow_exit;
	}

	if (link(SHADOW, OSHADOW) == -1) {
		err = PWU_UPDATE_FAILED;
		(void) unlink(SHADTEMP);
		goto shadow_exit;
	}

	if (rename(SHADTEMP, SHADOW) == -1) {
		err = PWU_UPDATE_FAILED;
		(void) unlink(SHADTEMP);
		goto shadow_exit;
	}
	(void) unlink(OSHADOW);

shadow_exit:
	return (err);
}