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#include "testutil.h"
18#include "apr_errno.h"
19#include "apr_general.h"
20#include "apr_user.h"
21
22#if APR_HAS_USER
23static void uid_current(abts_case *tc, void *data)
24{
25    apr_uid_t uid;
26    apr_gid_t gid;
27
28    APR_ASSERT_SUCCESS(tc, "apr_uid_current failed",
29                       apr_uid_current(&uid, &gid, p));
30}
31
32static void username(abts_case *tc, void *data)
33{
34    apr_uid_t uid;
35    apr_gid_t gid;
36    apr_uid_t retreived_uid;
37    apr_gid_t retreived_gid;
38    char *uname = NULL;
39
40    APR_ASSERT_SUCCESS(tc, "apr_uid_current failed",
41                       apr_uid_current(&uid, &gid, p));
42
43    APR_ASSERT_SUCCESS(tc, "apr_uid_name_get failed",
44                       apr_uid_name_get(&uname, uid, p));
45    ABTS_PTR_NOTNULL(tc, uname);
46
47    if (uname == NULL)
48        return;
49
50    APR_ASSERT_SUCCESS(tc, "apr_uid_get failed",
51                       apr_uid_get(&retreived_uid, &retreived_gid, uname, p));
52
53    APR_ASSERT_SUCCESS(tc, "apr_uid_compare failed",
54                       apr_uid_compare(uid, retreived_uid));
55#ifdef WIN32
56    /* ### this fudge was added for Win32 but makes the test return NotImpl
57     * on Unix if run as root, when !gid is also true. */
58    if (!gid || !retreived_gid) {
59        /* The function had no way to recover the gid (this would have been
60         * an ENOTIMPL if apr_uid_ functions didn't try to double-up and
61         * also return apr_gid_t values, which was bogus.
62         */
63        if (!gid) {
64            ABTS_NOT_IMPL(tc, "Groups from apr_uid_current");
65        }
66        else {
67            ABTS_NOT_IMPL(tc, "Groups from apr_uid_get");
68        }
69    }
70    else {
71#endif
72        APR_ASSERT_SUCCESS(tc, "apr_gid_compare failed",
73                           apr_gid_compare(gid, retreived_gid));
74#ifdef WIN32
75    }
76#endif
77}
78
79static void groupname(abts_case *tc, void *data)
80{
81    apr_uid_t uid;
82    apr_gid_t gid;
83    apr_gid_t retreived_gid;
84    char *gname = NULL;
85
86    APR_ASSERT_SUCCESS(tc, "apr_uid_current failed",
87                       apr_uid_current(&uid, &gid, p));
88
89    APR_ASSERT_SUCCESS(tc, "apr_gid_name_get failed",
90                       apr_gid_name_get(&gname, gid, p));
91    ABTS_PTR_NOTNULL(tc, gname);
92
93    if (gname == NULL)
94        return;
95
96    APR_ASSERT_SUCCESS(tc, "apr_gid_get failed",
97                       apr_gid_get(&retreived_gid, gname, p));
98
99    APR_ASSERT_SUCCESS(tc, "apr_gid_compare failed",
100                       apr_gid_compare(gid, retreived_gid));
101}
102
103#ifdef APR_UID_GID_NUMERIC
104
105static void fail_userinfo(abts_case *tc, void *data)
106{
107    apr_uid_t uid;
108    apr_gid_t gid;
109    apr_status_t rv;
110    char *tmp;
111
112    errno = 0;
113    gid = uid = 9999999;
114    tmp = NULL;
115    rv = apr_uid_name_get(&tmp, uid, p);
116    ABTS_ASSERT(tc, "apr_uid_name_get should fail or "
117                "return a user name",
118                rv != APR_SUCCESS || tmp != NULL);
119
120    errno = 0;
121    tmp = NULL;
122    rv = apr_gid_name_get(&tmp, gid, p);
123    ABTS_ASSERT(tc, "apr_gid_name_get should fail or "
124                "return a group name",
125                rv != APR_SUCCESS || tmp != NULL);
126
127    gid = 424242;
128    errno = 0;
129    rv = apr_gid_get(&gid, "I_AM_NOT_A_GROUP", p);
130    ABTS_ASSERT(tc, "apr_gid_get should fail or "
131                "set a group number",
132                rv != APR_SUCCESS || gid == 424242);
133
134    gid = uid = 424242;
135    errno = 0;
136    rv = apr_uid_get(&uid, &gid, "I_AM_NOT_A_USER", p);
137    ABTS_ASSERT(tc, "apr_gid_get should fail or "
138                "set a user and group number",
139                rv != APR_SUCCESS || uid == 424242 || gid == 4242442);
140
141    errno = 0;
142    tmp = NULL;
143    rv = apr_uid_homepath_get(&tmp, "I_AM_NOT_A_USER", p);
144    ABTS_ASSERT(tc, "apr_uid_homepath_get should fail or "
145                "set a path name",
146                rv != APR_SUCCESS || tmp != NULL);
147}
148
149#endif
150
151#else
152static void users_not_impl(abts_case *tc, void *data)
153{
154    ABTS_NOT_IMPL(tc, "Users not implemented on this platform");
155}
156#endif
157
158abts_suite *testuser(abts_suite *suite)
159{
160    suite = ADD_SUITE(suite)
161
162#if !APR_HAS_USER
163    abts_run_test(suite, users_not_impl, NULL);
164#else
165    abts_run_test(suite, uid_current, NULL);
166    abts_run_test(suite, username, NULL);
167    abts_run_test(suite, groupname, NULL);
168#ifdef APR_UID_GID_NUMERIC
169    abts_run_test(suite, fail_userinfo, NULL);
170#endif
171#endif
172
173    return suite;
174}
175