Ejemplo n.º 1
0
int main(int argc, char *argv[]) {
  if (argc != 2) {
    helpAndLeave(argv[0], EXIT_FAILURE);
  }

  if (effective_access(argv[1], W_OK) == 0) {
    printf("You have permission to write!\n");
  } else {
    printf("No permission to write!\n");
  }

  return EXIT_SUCCESS;
}
Ejemplo n.º 2
0
/*
 * Check per accout or global hush-login setting.
 *
 * Hushed mode is enabled:
 *
 * a) if global (e.g. /etc/hushlogins) hush file exists:
 *     1) for ALL ACCOUNTS if the file is empty
 *     2) for the current user if the username or shell are found in the file
 *
 * b) if ~/.hushlogin file exists
 *
 * The ~/.hushlogin is ignored if the global hush file exists.
 *
 * The HUSHLOGIN_FILE login.def variable overwrites the default hush filename.
 *
 * Note that shadow-utils login(1) does not support "a1)". The "a1)" is
 * necessary if you want to use PAM for "Last login" message.
 *
 * -- Karel Zak <*****@*****.**> (26-Aug-2011)
 *
 *
 * Per-account check requires some explanation: As root we may not be able to
 * read the directory of the user if it is on an NFS mounted filesystem. We
 * temporarily set our effective uid to the user-uid making sure that we keep
 * root privs. in the real uid.
 *
 * A portable solution would require a fork(), but we rely on Linux having the
 * BSD setreuid()
 */
static int get_hushlogin_status(struct passwd *pwd)
{
	const char *files[] = { _PATH_HUSHLOGINS, _PATH_HUSHLOGIN, NULL };
	const char *file;
	char buf[BUFSIZ];
	int i;

	file = getlogindefs_str("HUSHLOGIN_FILE", NULL);
	if (file) {
		if (!*file)
			return 0;	/* empty HUSHLOGIN_FILE defined */

		files[0] = file;
		files[1] = NULL;
	}

	for (i = 0; files[i]; i++) {
		int ok = 0;

		file = files[i];

		/* Global hush-file*/
		if (*file == '/') {
			struct stat st;
			FILE *f;

			if (stat(file, &st) != 0)
				continue;	/* file does not exist */

			if (st.st_size == 0)
				return 1;	/* for all accounts */

			f = fopen(file, "r");
			if (!f)
				continue;	/* ignore errors... */

			while (ok == 0 && fgets(buf, sizeof(buf), f)) {
				buf[strlen(buf) - 1] = '\0';
				ok = !strcmp(buf, *buf == '/' ? pwd->pw_shell :
								pwd->pw_name);
			}
			fclose(f);
			if (ok)
				return 1;	/* found username/shell */

			return 0;		/* ignore per-account files */
		}

		/* Per-account setting */
		if (strlen(pwd->pw_dir) + sizeof(file) + 2 > sizeof(buf))
			continue;
		else {
			uid_t ruid = getuid();
			gid_t egid = getegid();

			sprintf(buf, "%s/%s", pwd->pw_dir, file);
			setregid(-1, pwd->pw_gid);
			setreuid(0, pwd->pw_uid);
			ok = effective_access(buf, O_RDONLY) == 0;
			setuid(0);	/* setreuid doesn't do it alone! */
			setreuid(ruid, 0);
			setregid(-1, egid);

			if (ok)
				return 1;	/* enabled by user */
		}
	}

	return 0;
}