From f3d02d1fb9061c802e2796b7d6614ba4ae512904 Mon Sep 17 00:00:00 2001 From: Donald Buczek Date: Tue, 31 May 2016 17:05:59 +0200 Subject: [PATCH 1/5] mxqd: maintain supplementary group IDs of server --- mxqd.c | 14 ++++++++++++++ mxqd.h | 3 +++ 2 files changed, 17 insertions(+) diff --git a/mxqd.c b/mxqd.c index be975b56..7bd9d13e 100644 --- a/mxqd.c +++ b/mxqd.c @@ -554,6 +554,19 @@ int server_init(struct mxq_server *server, int argc, char *argv[]) return -EX_IOERR; } + i=server->supgid_cnt=getgroups(0,NULL); + if (i<0) { + mx_log_err("MAIN: getgroups(0,NULL) : %m"); + return -errno; + } + server->supgid=mx_calloc_forever(i,sizeof(*server->supgid)); + server->supgid_cnt=i; + res=getgroups(i,server->supgid); + if (res<0) { + mx_log_err("MAIN: getgroups() : %m"); + return -errno; + } + if (arg_daemonize) { res = mx_daemon(0, 1); if (res == -1) { @@ -1439,6 +1452,7 @@ void server_free(struct mxq_server *server) mx_free_null(server->host_id); mx_free_null(server->finished_jobsdir); mx_flock_free(server->flock); + mx_free_null(server->supgid); mx_log_finish(); } diff --git a/mxqd.h b/mxqd.h index fb66eddc..3aa599c5 100644 --- a/mxqd.h +++ b/mxqd.h @@ -102,6 +102,9 @@ struct mxq_server { char *initial_path; char *initial_tmpdir; char recoveronly; + + size_t supgid_cnt; + gid_t *supgid; }; From cd2469d7171a2c0039071c7c1095ddef0bf9d377 Mon Sep 17 00:00:00 2001 From: Donald Buczek Date: Tue, 31 May 2016 22:42:32 +0200 Subject: [PATCH 2/5] mxqd: rename output files as user --- mxqd.c | 44 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 41 insertions(+), 3 deletions(-) diff --git a/mxqd.c b/mxqd.c index 7bd9d13e..51b3ac21 100644 --- a/mxqd.c +++ b/mxqd.c @@ -1693,12 +1693,30 @@ int killall_cancelled(struct mxq_server *server) return 0; } -static void rename_outfiles(struct mxq_group *group, struct mxq_job *job) +static void rename_outfiles(struct mxq_server *server, struct mxq_group *group, struct mxq_job *job) { int res; mxq_job_set_tmpfilenames(group, job); + if(RUNNING_AS_ROOT) { + res=initgroups(group->user_name,group->user_gid); + if (res==-1) { + mx_log_err("initgroups(\"%s\",%d): %m",group->user_name,group->user_gid); + exit(-errno); + } + res=setegid(group->user_gid); + if (res==-1) { + mx_log_err("setedid(%d): %m",group->user_gid); + exit(-errno); + } + res=seteuid(group->user_uid); + if (res==-1) { + mx_log_err("seteuid(%d): %m",group->user_uid); + exit(-errno); + } + } + if (!mx_streq(job->job_stdout, "/dev/null")) { res = rename(job->tmp_stdout, job->job_stdout); if (res == -1) { @@ -1722,6 +1740,26 @@ static void rename_outfiles(struct mxq_group *group, struct mxq_job *job) job->host_pid); } } + + if(RUNNING_AS_ROOT) { + uid_t uid=getuid(); + uid_t gid=getgid(); + res=seteuid(uid); + if (res==-1) { + mx_log_err("seteuid(%d): %m",uid); + exit(-errno); + } + res=setegid(gid); + if (res==-1) { + mx_log_err("setegid(%d): %m",gid); + exit(-errno); + } + res=setgroups(server->supgid_cnt,server->supgid); + if (res==-1) { + mx_log_err("setgroups(): %m"); + exit(-errno); + } + } } static int job_has_finished(struct mxq_server *server, struct mxq_group *group, struct mxq_job_list *jlist) @@ -1733,7 +1771,7 @@ static int job_has_finished(struct mxq_server *server, struct mxq_group *group, mxq_set_job_status_exited(server->mysql, job); - rename_outfiles(group, job); + rename_outfiles(server, group, job); cnt = jlist->group->slots_per_job; cpuset_clear_running(&server->cpu_set_running, &job->host_cpu_set); @@ -1756,7 +1794,7 @@ static int job_is_lost(struct mxq_server *server,struct mxq_group *group, struct group->group_jobs_unknown++; group->group_jobs_running--; - rename_outfiles(group, job); + rename_outfiles(server, group, job); cnt = jlist->group->slots_per_job; cpuset_clear_running(&server->cpu_set_running, &job->host_cpu_set); From 6551ba160f19c4c357af78948e9c51e8a40d7636 Mon Sep 17 00:00:00 2001 From: Donald Buczek Date: Wed, 1 Jun 2016 12:34:23 +0200 Subject: [PATCH 3/5] web: don't show the same set of data columns in any group table --- web/pages/mxq/mxq.in | 121 +++++++++++++++++++++++-------------------- 1 file changed, 65 insertions(+), 56 deletions(-) diff --git a/web/pages/mxq/mxq.in b/web/pages/mxq/mxq.in index 89227a67..8b5238e1 100755 --- a/web/pages/mxq/mxq.in +++ b/web/pages/mxq/mxq.in @@ -414,14 +414,40 @@ EOF return $out; } -sub group_table_rows { - my ($sth,$head)=@_; - my $out=''; +sub group_table { - $out.=''; + my ($sql_clause,$sql_binds)=@_; + + $sql_clause||='true'; + + my $out; + my (@cols,@head); - $out.=$q->Tr($q->th($head)); + $out .= '

Active Groups

'; + + @cols=qw( + group_id group_name job_threads user_name + group_mtime + group_status + group_jobs + group_jobs_inq group_jobs_running + group_jobs_finished group_jobs_failed group_jobs_cancelled group_jobs_unknown + ); + @head=qw( + group_id group_name threads user_name + group_mtime + group_status + jobs + inq running + finished failed cancelled unknown + ); + + my $sth=$dbh->prepare('SELECT '.join(',',@cols).' FROM mxq_group WHERE '.$sql_clause.' AND (group_jobs_running>0 OR group_jobs_inq>0) ORDER BY group_id DESC'); + $sth->execute(@$sql_binds); + + $out.='
'; + $out.=$q->Tr($q->th(\@head)); while (my $row=$sth->fetchrow_arrayref()) { my ($group_id,$group_name,$job_threads,$user_name,$group_mtime,$group_status, $group_jobs,$group_jobs_inq,$group_jobs_running,$group_jobs_finished,$group_jobs_failed,$group_jobs_cancelled,$group_jobs_unknown @@ -441,70 +467,53 @@ sub group_table_rows { $q->td({class=>'number'},$group_jobs_failed), $q->td({class=>'number'},$group_jobs_cancelled), $q->td({class=>'number'},$group_jobs_unknown) - ); } $out.='
'; - return $out; -} - -sub group_table { - my ($sql_clause,$sql_binds)=@_; - - $sql_clause||='true'; - - my $out; - - my @cols=qw( - group_id group_name job_threads user_name group_mtime group_status - group_jobs group_jobs_inq group_jobs_running group_jobs_finished group_jobs_failed group_jobs_cancelled group_jobs_unknown - ); - my @head=qw( - group_id group_name threads user_name group_mtime group_status - jobs inq running finished failed cancelled unknown - ); - - - $out .= '

Active Groups

'; - - my $sth=$dbh->prepare('SELECT '.join(',',@cols).' FROM mxq_group WHERE '.$sql_clause.' AND (group_jobs_running>0 OR group_jobs_inq>0) ORDER BY group_id DESC'); - $sth->execute(@$sql_binds); - $out.=group_table_rows($sth,\@head); + $out .= '

Finished Groups (last 7 days)

'; @cols=qw( - group_id - group_name - job_threads - user_name - group_date_end - group_status - group_jobs - group_jobs_finished - group_jobs_failed - group_jobs_cancelled - group_jobs_unknown + group_id group_name job_threads user_name + group_date_end + group_status + group_jobs + group_jobs_finished group_jobs_failed group_jobs_cancelled group_jobs_unknown ); @head=qw( - group_id - group_name - threads - user_name - date_end - group_status - jobs - finished - failed - cancelled - unknown + group_id group_name threads user_name + date_end + group_status + jobs + finished failed cancelled unknown ); - $out .= '

Finished Groups (last 7 days)

'; - $sth=$dbh->prepare('SELECT '.join(',',@cols).' FROM mxq_group WHERE '.$sql_clause.' AND (group_jobs_running=0 AND group_jobs_inq=0) AND group_mtime >= DATE_SUB(NOW(),INTERVAL 7 DAY) ORDER BY group_id DESC'); $sth->execute(@$sql_binds); - $out.=group_table_rows($sth,\@head); + + $out.=''; + $out.=$q->Tr($q->th(\@head)); + while (my $row=$sth->fetchrow_arrayref()) { + my ($group_id,$group_name,$job_threads,$user_name,$group_date_end,$group_status, + $group_jobs,$group_jobs_finished,$group_jobs_failed,$group_jobs_cancelled,$group_jobs_unknown + )=@$row; + + $out.=$q->Tr( + $q->td({class=>'number'},$q->a({href=>selfurl("/group/$group_id")},$group_id)), + $q->td($group_name), + $q->td({class=>'number'},$job_threads), + $q->td($q->a({href=>my_url('groups',{user_name=>$user_name})},$user_name)), + $q->td($group_date_end), + $q->td(group_status($group_status)), + $q->td({class=>'number'},$group_jobs), + $q->td({class=>'number'},$group_jobs_finished), + $q->td({class=>'number'},$group_jobs_failed), + $q->td({class=>'number'},$group_jobs_cancelled), + $q->td({class=>'number'},$group_jobs_unknown) + ); + } + $out.='
'; return $out; } From f71ab9cbfa8c31412724df33597659766cd9f500 Mon Sep 17 00:00:00 2001 From: Donald Buczek Date: Wed, 1 Jun 2016 12:45:06 +0200 Subject: [PATCH 4/5] mxqd: unlink bad (left over) fspool files, so we don't try them over and over --- mxqd.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mxqd.c b/mxqd.c index 51b3ac21..1c7b6e78 100644 --- a/mxqd.c +++ b/mxqd.c @@ -1864,6 +1864,7 @@ static int fspool_process_file(struct mxq_server *server,char *filename, uint64_ jlist = server_remove_job_list_by_job_id(server, job_id); if (!jlist) { mx_log_warning("fspool_process_file: %s : job unknown on server", filename); + unlink(filename); return -(errno=ENOENT); } @@ -1873,6 +1874,7 @@ static int fspool_process_file(struct mxq_server *server,char *filename, uint64_ filename, job->job_id, job_id); + unlink(filename); return -(errno=EINVAL); } From 19b1545dafea4195e52ca8f831f3109a1bdaeb32 Mon Sep 17 00:00:00 2001 From: Donald Buczek Date: Wed, 13 Jul 2016 15:13:33 +0200 Subject: [PATCH 5/5] mx_util: remove inline attribute from mx_stribeginswithany MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit avoid compiler warning "warning: ‘_mx_strbeginswithany’ is static but used in inline function ‘mx_stribeginswithany’ which is not static" --- mx_util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mx_util.c b/mx_util.c index 9f2fd57f..809e1c63 100644 --- a/mx_util.c +++ b/mx_util.c @@ -78,7 +78,7 @@ inline int mx_strbeginswithany(char *str, char **starts, char **endptr) return _mx_strbeginswithany(str, starts, endptr, 0); } -inline int mx_stribeginswithany(char *str, char **starts, char **endptr) +int mx_stribeginswithany(char *str, char **starts, char **endptr) { return _mx_strbeginswithany(str, starts, endptr, 1); }