1/* Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements.  See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache License, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License.  You may obtain a copy of the License at
7 *
8 *     http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17/*
18 * Given one or more group identifers on the command line (e.g.,
19 * "httpd" or "#-1"), figure out whether they'll be valid for
20 * the server to use at run-time.
21 *
22 * If a groupname isn't found, or we can't setgid() to it, return
23 * -1.  If all groups are valid, return 0.
24 *
25 * This may need to be run as the superuser for the setgid() to
26 * succeed; running it as any other user may result in a false
27 * negative.
28 */
29
30#include "ap_config.h"
31#if APR_HAVE_STDIO_H
32#include <stdio.h>
33#endif
34#if APR_HAVE_STDLIB_H
35#include <stdlib.h>
36#endif
37#if APR_HAVE_SYS_TYPES_H
38#include <sys/types.h>
39#endif
40#if HAVE_GRP_H
41#include <grp.h>
42#endif
43#if APR_HAVE_UNISTD_H
44#include <unistd.h>
45#endif
46
47int main(int argc, char *argv[])
48{
49    int i;
50    int result;
51    gid_t gid;
52    struct group *grent;
53    struct group fake_grent;
54
55    /*
56     * Assume success. :-)
57     */
58    result = 0;
59    for (i = 1; i < argc; ++i) {
60        char *arg;
61        arg = argv[i];
62
63        /*
64         * If it's from a 'Group #-1' statement, get the numeric value
65         * and skip the group lookup stuff.
66         */
67        if (*arg == '#') {
68            gid = atoi(&arg[1]);
69            fake_grent.gr_gid = gid;
70            grent = &fake_grent;
71        }
72        else {
73            grent = getgrnam(arg);
74        }
75
76        /*
77         * A NULL return means no such group was found, so we're done
78         * with this one.
79         */
80        if (grent == NULL) {
81            fprintf(stderr, "%s: group '%s' not found\n", argv[0], arg);
82            result = -1;
83        }
84        else {
85            int check;
86
87            /*
88             * See if we can switch to the numeric GID we have. If so,
89             * all well and good; if not, well..
90             */
91            gid = grent->gr_gid;
92            check = setgid(gid);
93            if (check != 0) {
94                fprintf(stderr, "%s: invalid group '%s'\n", argv[0], arg);
95                perror(argv[0]);
96                result = -1;
97            }
98        }
99    }
100    /*
101     * Worst-case return value.
102     */
103    return result;
104}
105/*
106 * Local Variables:
107 * mode: C
108 * c-file-style: "bsd"
109 * End:
110 */
111