~ubuntu-branches/ubuntu/raring/sudo/raring

« back to all changes in this revision

Viewing changes to plugins/system_group/system_group.c

  • Committer: Package Import Robot
  • Author(s): Tyler Hicks
  • Date: 2012-07-16 14:01:42 UTC
  • mfrom: (1.3.22 sid)
  • Revision ID: package-import@ubuntu.com-20120716140142-b0tgau0k6nid4mrf
Tags: 1.8.5p2-1ubuntu1
* Merge from debian/testing (LP: #1024154), remaining changes:
  - debian/patches/keep_home_by_default.patch:
    + Set HOME in initial_keepenv_table.
  - debian/rules:
    + compile with --without-lecture --with-tty-tickets (Ubuntu specific)
    + install man/man8/sudo_root.8 in both flavours (Ubuntu specific)
    + install apport hooks
    + The ubuntu-sudo-as-admin-successful.patch was taken upstream by
      Debian however it requires a --enable-admin-flag configure flag to
      actually enable it in both flavours.
  - debian/control:
    + Mark Debian Vcs-* as XS-Debian-Vcs-*
    + update debian/control
  - debian/sudoers:
    + grant admin group sudo access
  - debian/source_sudo.py, debian/sudo-ldap.dirs, debian/sudo.dirs:
    + add usr/share/apport/package-hooks
  - debian/sudo.pam:
    + Use pam_env to read /etc/environment and /etc/default/locale
      environment files. Reading ~/.pam_environment is not permitted due to
      security reasons.
* Dropped changes:
  - debian/patches/lp927828-fix-abort-in-pam-modules-when-timestamp-valid.patch
    + Fixed upstream in 1.8.5
  - debian/patches/CVE-2012-2337.patch:
    + Fixed upstream in 1.8.4p5
  - debian/patches/pam_env_merge.patch:
    + Feature released upstream in 1.8.5
  - debian/{sudo,sudo-ldap}.{preinst,postinst,postrm}:
    + Drop Ubuntu-specific sudoers file migration code because the only
      upgrade path to quantal is from precise. All necessary sudoers file
      migration will have already been done by the time this version of the
      sudo package is installed.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (c) 2010, 2012 Todd C. Miller <Todd.Miller@courtesan.com>
 
3
 *
 
4
 * Permission to use, copy, modify, and distribute this software for any
 
5
 * purpose with or without fee is hereby granted, provided that the above
 
6
 * copyright notice and this permission notice appear in all copies.
 
7
 *
 
8
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 
9
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 
10
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 
11
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 
12
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 
13
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 
14
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
15
 */
 
16
 
 
17
#include <config.h>
 
18
 
 
19
#include <sys/types.h>
 
20
#include <sys/param.h>
 
21
#include <sys/stat.h>
 
22
 
 
23
#include <stdio.h>
 
24
#ifdef STDC_HEADERS
 
25
# include <stdlib.h>
 
26
# include <stddef.h>
 
27
#else
 
28
# ifdef HAVE_STDLIB_H
 
29
#  include <stdlib.h>
 
30
# endif
 
31
#endif /* STDC_HEADERS */
 
32
#ifdef HAVE_STDBOOL_H
 
33
# include <stdbool.h>
 
34
#else
 
35
# include "compat/stdbool.h"
 
36
#endif /* HAVE_STDBOOL_H */
 
37
#ifdef HAVE_STRING_H
 
38
# if defined(HAVE_MEMORY_H) && !defined(STDC_HEADERS)
 
39
#  include <memory.h>
 
40
# endif
 
41
# include <string.h>
 
42
#endif /* HAVE_STRING_H */
 
43
#ifdef HAVE_STRINGS_H
 
44
# include <strings.h>
 
45
#endif /* HAVE_STRINGS_H */
 
46
#ifdef HAVE_UNISTD_H
 
47
# include <unistd.h>
 
48
#endif /* HAVE_UNISTD_H */
 
49
#ifdef HAVE_DLOPEN
 
50
# include <dlfcn.h>
 
51
#else
 
52
# include "compat/dlfcn.h"
 
53
#endif
 
54
#include <ctype.h>
 
55
#include <errno.h>
 
56
#include <fcntl.h>
 
57
#include <limits.h>
 
58
#include <grp.h>
 
59
#include <pwd.h>
 
60
 
 
61
#include "sudo_plugin.h"
 
62
#include "missing.h"
 
63
 
 
64
#ifndef RTLD_DEFAULT
 
65
# define RTLD_DEFAULT   NULL
 
66
#endif
 
67
 
 
68
/*
 
69
 * Sudoers group plugin that does group name-based lookups using the system
 
70
 * group database functions, similar to how sudo behaved prior to 1.7.3.
 
71
 * This can be used on systems where lookups by group ID are problematic.
 
72
 */
 
73
 
 
74
static sudo_printf_t sudo_log;
 
75
 
 
76
typedef struct group * (*sysgroup_getgrnam_t)(const char *);
 
77
typedef struct group * (*sysgroup_getgrgid_t)(gid_t);
 
78
typedef void (*sysgroup_gr_delref_t)(struct group *);
 
79
 
 
80
static sysgroup_getgrnam_t sysgroup_getgrnam;
 
81
static sysgroup_getgrgid_t sysgroup_getgrgid;
 
82
static sysgroup_gr_delref_t sysgroup_gr_delref;
 
83
static bool need_setent;
 
84
 
 
85
static int
 
86
sysgroup_init(int version, sudo_printf_t sudo_printf, char *const argv[])
 
87
{
 
88
    void *handle;
 
89
 
 
90
    sudo_log = sudo_printf;
 
91
 
 
92
    if (GROUP_API_VERSION_GET_MAJOR(version) != GROUP_API_VERSION_MAJOR) {
 
93
        sudo_log(SUDO_CONV_ERROR_MSG,
 
94
            "sysgroup_group: incompatible major version %d, expected %d\n",
 
95
            GROUP_API_VERSION_GET_MAJOR(version),
 
96
            GROUP_API_VERSION_MAJOR);
 
97
        return -1;
 
98
    }
 
99
 
 
100
    /* Share group cache with sudo if possible. */
 
101
    handle = dlsym(RTLD_DEFAULT, "sudo_getgrnam");
 
102
    if (handle != NULL) {
 
103
        sysgroup_getgrnam = (sysgroup_getgrnam_t)handle;
 
104
    } else {
 
105
        sysgroup_getgrnam = (sysgroup_getgrnam_t)getgrnam;
 
106
        need_setent = true;
 
107
    }
 
108
 
 
109
    handle = dlsym(RTLD_DEFAULT, "sudo_getgrgid");
 
110
    if (handle != NULL) {
 
111
        sysgroup_getgrgid = (sysgroup_getgrgid_t)handle;
 
112
    } else {
 
113
        sysgroup_getgrgid = (sysgroup_getgrgid_t)getgrgid;
 
114
        need_setent = true;
 
115
    }
 
116
 
 
117
    handle = dlsym(RTLD_DEFAULT, "gr_delref");
 
118
    if (handle != NULL)
 
119
        sysgroup_gr_delref = (sysgroup_gr_delref_t)handle;
 
120
 
 
121
    if (need_setent)
 
122
        setgrent();
 
123
 
 
124
    return true;
 
125
}
 
126
 
 
127
static void
 
128
sysgroup_cleanup(void)
 
129
{
 
130
    if (need_setent)
 
131
        endgrent();
 
132
}
 
133
 
 
134
/*
 
135
 * Returns true if "user" is a member of "group", else false.
 
136
 */
 
137
static int
 
138
sysgroup_query(const char *user, const char *group, const struct passwd *pwd)
 
139
{
 
140
    char **member, *ep = '\0';
 
141
    struct group *grp;
 
142
 
 
143
    grp = sysgroup_getgrnam(group);
 
144
    if (grp == NULL && group[0] == '#' && group[1] != '\0') {
 
145
        long lval = strtol(group + 1, &ep, 10);
 
146
        if (*ep == '\0') {
 
147
            if ((lval != LONG_MAX && lval != LONG_MIN) || errno != ERANGE)
 
148
                grp = sysgroup_getgrgid((gid_t)lval);
 
149
        }
 
150
    }
 
151
    if (grp != NULL) {
 
152
        for (member = grp->gr_mem; *member != NULL; member++) {
 
153
            if (strcasecmp(user, *member) == 0) {
 
154
                if (sysgroup_gr_delref)
 
155
                    sysgroup_gr_delref(grp);
 
156
                return true;
 
157
            }
 
158
        }
 
159
        if (sysgroup_gr_delref)
 
160
            sysgroup_gr_delref(grp);
 
161
    }
 
162
 
 
163
    return false;
 
164
}
 
165
 
 
166
struct sudoers_group_plugin group_plugin = {
 
167
    GROUP_API_VERSION,
 
168
    sysgroup_init,
 
169
    sysgroup_cleanup,
 
170
    sysgroup_query
 
171
};