|
From: <ssm...@us...> - 2006-11-13 23:47:22
|
Revision: 2078
http://svn.sourceforge.net/selinux/?rev=2078&view=rev
Author: ssmalley
Date: 2006-11-13 15:47:17 -0800 (Mon, 13 Nov 2006)
Log Message:
-----------
Author: Michael C Thompson
Email: tho...@us...
Subject: make newrole suid (take 3)
Date: Thu, 02 Nov 2006 19:03:34 -0600
Michael C Thompson wrote:
> The 8 patches are as follows:
> 1) Modifications to Makefile to support future patch needs
> Add newrole-lspp.pamd
> 2) New extract_pw_data function and use in main()
This is the 2nd of 8 patches.
This patch applies against policycoreutils-1.30.30-1.
This patch moves the parse /etc/passwd functionality from
main() into a separate function.
Changes:
* Introduces the extract_pw_data() function and uses it in main()
Signed-off-by: Michael Thompson <tho...@us...>
Modified Paths:
--------------
trunk/policycoreutils/newrole/newrole.c
Modified: trunk/policycoreutils/newrole/newrole.c
===================================================================
--- trunk/policycoreutils/newrole/newrole.c 2006-11-13 23:45:08 UTC (rev 2077)
+++ trunk/policycoreutils/newrole/newrole.c 2006-11-13 23:47:17 UTC (rev 2078)
@@ -332,6 +332,61 @@
return found;
}
+/**
+ * Determine the Linux user identity to re-authenticate.
+ * If supported and set, use the login uid, as this should be more stable.
+ * Otherwise, use the real uid.
+ *
+ * This function assigns malloc'd memory into the pw_copy struct.
+ * Returns zero on success, non-zero otherwise
+ */
+int extract_pw_data(struct passwd *pw_copy)
+{
+ uid_t uid;
+ struct passwd *pw;
+
+#ifdef USE_AUDIT
+ uid = audit_getloginuid();
+ if (uid == (uid_t) - 1)
+ uid = getuid();
+#else
+ uid = getuid();
+#endif
+
+ setpwent();
+ pw = getpwuid(uid);
+ endpwent();
+ if (!(pw && pw->pw_name && pw->pw_name[0] && pw->pw_shell
+ && pw->pw_shell[0] && pw->pw_dir && pw->pw_dir[0])) {
+ fprintf(stderr,
+ _("cannot find valid entry in the passwd file.\n"));
+ return -1;
+ }
+
+ *pw_copy = *pw;
+ pw = pw_copy;
+ pw->pw_name = strdup(pw->pw_name);
+ pw->pw_dir = strdup(pw->pw_dir);
+ pw->pw_shell = strdup(pw->pw_shell);
+
+ if (! (pw->pw_name && pw->pw_dir && pw->pw_shell)) {
+ fprintf(stderr, _("Out of memory!\n"));
+ goto out_free;
+ }
+
+ if (verify_shell(pw->pw_shell) == 0) {
+ fprintf(stderr, _("Error! Shell is not valid.\n"));
+ goto out_free;
+ }
+ return 0;
+
+out_free:
+ free(pw->pw_name);
+ free(pw->pw_dir);
+ free(pw->pw_shell);
+ return -1;
+}
+
/*
* This function will drop the capabilities so that we are left
* only with access to the audit system. If the user is root, we leave
@@ -460,8 +515,7 @@
context_t context; /* manipulatable form of new_context */
- struct passwd *pw; /* struct derived from passwd file line */
- struct passwd pw_copy;
+ struct passwd pw; /* struct derived from passwd file line */
int clflag; /* holds codes for command line flags */
int flag_index; /* flag index in argv[] */
@@ -639,23 +693,9 @@
#endif
/* Get the passwd info for the Linux user identity. */
- pw = getpwuid(uid);
- if (!pw) {
- fprintf(stderr,
- _("cannot find your entry in the passwd file.\n"));
- exit(-1);
- }
- pw_copy = *pw;
- pw = &pw_copy;
- pw->pw_name = xstrdup(pw->pw_name);
- pw->pw_dir = xstrdup(pw->pw_dir);
- pw->pw_shell = xstrdup(pw->pw_shell);
+ if (extract_pw_data(&pw))
+ return -1;
- if (verify_shell(pw->pw_shell) == 0) {
- fprintf(stderr, _("Error! Shell is not valid.\n"));
- exit(-1);
- }
-
/* Get the tty name. Pam will need it. */
ttyn = ttyname(0);
if (!ttyn || *ttyn == '\0') {
@@ -664,7 +704,7 @@
exit(-1);
}
- printf(_("Authenticating %s.\n"), pw->pw_name);
+ printf(_("Authenticating %s.\n"), pw.pw_name);
/*
* Re-authenticate the user running this program.
@@ -673,13 +713,13 @@
* by policy). Trusted path mechanism would be preferred.
*/
#ifdef USE_PAM
- if (!authenticate_via_pam(pw, ttyn))
+ if (!authenticate_via_pam(&pw, ttyn))
#else /* !USE_PAM */
- if (!authenticate_via_shadow_passwd(pw))
+ if (!authenticate_via_shadow_passwd(&pw))
#endif /* if/else USE_PAM */
{
fprintf(stderr, _("newrole: incorrect password for %s\n"),
- pw->pw_name);
+ pw.pw_name);
return (-1);
}
/* If we reach here, then we have authenticated the user. */
@@ -904,7 +944,7 @@
if (optind < 1)
optind = 1;
- if (asprintf(&argv[optind - 1], "-%s", pw->pw_shell) < 0) {
+ if (asprintf(&argv[optind - 1], "-%s", pw.pw_shell) < 0) {
fprintf(stderr, _("Error allocating shell.\n"));
exit(-1);
}
@@ -925,7 +965,7 @@
if (send_audit_message(1, old_context, new_context, ttyn))
exit(-1);
freecon(old_context);
- execv(pw->pw_shell, argv + optind - 1);
+ execv(pw.pw_shell, argv + optind - 1);
/* If we reach here, then we failed to exec the new shell. */
perror(_("failed to exec shell\n"));
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|