From mboxrd@z Thu Jan 1 00:00:00 1970 From: rmccabe@sourceware.org Date: 19 Feb 2008 15:51:52 -0000 Subject: [Cluster-devel] conga/ricci/ricci main.cpp Message-ID: <20080219155152.28718.qmail@sourceware.org> List-Id: To: cluster-devel.redhat.com MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit CVSROOT: /cvs/cluster Module name: conga Changes by: rmccabe at sourceware.org 2008-02-19 15:51:52 Modified files: ricci/ricci : main.cpp Log message: Clean up error paths when dropping privs Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/conga/ricci/ricci/main.cpp.diff?cvsroot=cluster&r1=1.9&r2=1.10 --- conga/ricci/ricci/main.cpp 2008/02/19 03:14:12 1.9 +++ conga/ricci/ricci/main.cpp 2008/02/19 15:51:52 1.10 @@ -49,52 +49,66 @@ int drop_privs(uid_t new_uid) { int ret; - cap_t caps = cap_get_proc(); cap_value_t saved_caps[] = { CAP_SYS_BOOT, CAP_SETUID }; + + /* + ** Keep the capability to reboot the system for when + ** fencing support is requested (via -F). + */ cap_value_t saved_caps_final[] = { CAP_SYS_BOOT }; + cap_t caps = cap_init(); - ret = prctl(PR_SET_KEEPCAPS, 1); - if (ret != 0) - return -errno; + if (caps == NULL) + return (-errno); + + if (prctl(PR_SET_KEEPCAPS, 1) != 0) + goto out_err; + + if (cap_clear(caps) != 0) + goto out_err; - cap_clear(caps); ret = cap_set_flag(caps, CAP_PERMITTED, sizeof(saved_caps) / sizeof(saved_caps[0]), saved_caps, CAP_SET); if (ret != 0) - return -errno; + goto out_err; ret = cap_set_flag(caps, CAP_EFFECTIVE, sizeof(saved_caps) / sizeof(saved_caps[0]), saved_caps, CAP_SET); if (ret != 0) - return -errno; + goto out_err; - ret = cap_set_proc(caps); - if (ret != 0) - return -errno; + if (cap_set_proc(caps) != 0) + goto out_err; - ret = setuid(new_uid); - if (ret != 0) - return -errno; + /* We don't drop gid=0 so we can read the cluster.conf file. */ + if (setuid(new_uid) != 0) + goto out_err; + + if (cap_clear(caps) != 0) + goto out_err; - cap_clear(caps); ret = cap_set_flag(caps, CAP_PERMITTED, sizeof(saved_caps_final) / sizeof(saved_caps_final[0]), saved_caps_final, CAP_SET); if (ret != 0) - return -errno; + goto out_err; ret = cap_set_flag(caps, CAP_EFFECTIVE, sizeof(saved_caps_final) / sizeof(saved_caps_final[0]), saved_caps_final, CAP_SET); if (ret != 0) - return -errno; + goto out_err; - ret = cap_set_proc(caps); - if (ret != 0) - return -errno; + if (cap_set_proc(caps) != 0) + goto out_err; + cap_free(caps); prctl(PR_SET_KEEPCAPS, 0); return (0); + +out_err: + cap_free(caps); + return (-errno); } int main(int argc, char **argv) {