Line data Source code
1 : /*
2 : SSSD
3 :
4 : Proxy netgroup handler
5 :
6 : Authors:
7 :
8 : Sumit Bose <sbose@redhat.com>
9 :
10 : Copyright (C) 2010 Red Hat
11 :
12 : This program is free software; you can redistribute it and/or modify
13 : it under the terms of the GNU General Public License as published by
14 : the Free Software Foundation; either version 3 of the License, or
15 : (at your option) any later version.
16 :
17 : This program is distributed in the hope that it will be useful,
18 : but WITHOUT ANY WARRANTY; without even the implied warranty of
19 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 : GNU General Public License for more details.
21 :
22 : You should have received a copy of the GNU General Public License
23 : along with this program. If not, see <http://www.gnu.org/licenses/>.
24 : */
25 :
26 : #include "providers/proxy/proxy.h"
27 : #include "util/util.h"
28 :
29 : #define BUFLEN 1024
30 :
31 : #define get_triple_el(s) ((s) ? (s) : "")
32 :
33 0 : static errno_t make_netgroup_attr(struct __netgrent netgrent,
34 : struct sysdb_attrs *attrs)
35 : {
36 : int ret;
37 : char *dummy;
38 :
39 0 : if (netgrent.type == group_val) {
40 0 : ret =sysdb_attrs_add_string(attrs, SYSDB_NETGROUP_MEMBER,
41 : netgrent.val.group);
42 0 : if (ret != EOK) {
43 0 : DEBUG(SSSDBG_CRIT_FAILURE, "sysdb_attrs_add_string failed.\n");
44 0 : return ret;
45 : }
46 0 : } else if (netgrent.type == triple_val) {
47 0 : dummy = talloc_asprintf(attrs, "(%s,%s,%s)",
48 0 : get_triple_el(netgrent.val.triple.host),
49 0 : get_triple_el(netgrent.val.triple.user),
50 0 : get_triple_el(netgrent.val.triple.domain));
51 0 : if (dummy == NULL) {
52 0 : DEBUG(SSSDBG_CRIT_FAILURE, "talloc_asprintf failed.\n");
53 0 : return ENOMEM;
54 : }
55 :
56 0 : ret = sysdb_attrs_add_string(attrs, SYSDB_NETGROUP_TRIPLE, dummy);
57 0 : if (ret != EOK) {
58 0 : DEBUG(SSSDBG_CRIT_FAILURE, "sysdb_attrs_add_string failed.\n");
59 0 : return ret;
60 : }
61 : } else {
62 0 : DEBUG(SSSDBG_CRIT_FAILURE,
63 : "Unknown netgrent entry type [%d].\n", netgrent.type);
64 0 : return EINVAL;
65 : }
66 :
67 0 : return EOK;
68 : }
69 :
70 0 : static errno_t save_netgroup(struct sss_domain_info *domain,
71 : const char *name,
72 : struct sysdb_attrs *attrs,
73 : bool lowercase,
74 : uint64_t cache_timeout)
75 : {
76 : errno_t ret;
77 :
78 0 : if (lowercase) {
79 0 : ret = sysdb_attrs_add_lc_name_alias(attrs, name);
80 0 : if (ret) {
81 0 : DEBUG(SSSDBG_OP_FAILURE, "Could not add name alias\n");
82 0 : return ret;
83 : }
84 : }
85 :
86 0 : ret = sysdb_add_netgroup(domain, name, NULL, attrs, NULL,
87 : cache_timeout, 0);
88 0 : if (ret != EOK) {
89 0 : DEBUG(SSSDBG_OP_FAILURE, "sysdb_add_netgroup failed.\n");
90 0 : return ret;
91 : }
92 :
93 0 : return EOK;
94 : }
95 :
96 0 : static errno_t handle_error(enum nss_status status,
97 : struct sss_domain_info *domain, const char *name)
98 : {
99 : errno_t ret;
100 :
101 0 : switch (status) {
102 : case NSS_STATUS_SUCCESS:
103 0 : DEBUG(SSSDBG_TRACE_INTERNAL, "Netgroup lookup succeeded\n");
104 0 : ret = EOK;
105 0 : break;
106 :
107 : case NSS_STATUS_NOTFOUND:
108 0 : DEBUG(SSSDBG_MINOR_FAILURE, "The netgroup was not found\n");
109 0 : ret = sysdb_delete_netgroup(domain, name);
110 0 : if (ret != EOK) {
111 0 : DEBUG(SSSDBG_CRIT_FAILURE, "Cannot delete netgroup: %d\n", ret);
112 0 : ret = EIO;
113 : }
114 0 : break;
115 :
116 : case NSS_STATUS_UNAVAIL:
117 0 : DEBUG(SSSDBG_TRACE_LIBS,
118 : "The proxy target did not respond, going offline\n");
119 0 : ret = ENXIO;
120 0 : break;
121 :
122 : default:
123 0 : DEBUG(SSSDBG_CRIT_FAILURE, "Unexpected error looking up netgroup\n");
124 0 : ret = EIO;
125 0 : break;
126 : }
127 :
128 0 : return ret;
129 : }
130 :
131 0 : errno_t get_netgroup(struct proxy_id_ctx *ctx,
132 : struct sss_domain_info *dom,
133 : const char *name)
134 : {
135 : struct __netgrent result;
136 : enum nss_status status;
137 : char buffer[BUFLEN];
138 : int ret;
139 0 : TALLOC_CTX *tmp_ctx = NULL;
140 : struct sysdb_attrs *attrs;
141 :
142 0 : memset(&result, 0, sizeof(result));
143 0 : status = ctx->ops.setnetgrent(name, &result);
144 0 : if (status != NSS_STATUS_SUCCESS) {
145 0 : DEBUG(SSSDBG_OP_FAILURE,
146 : "setnetgrent failed for netgroup [%s].\n", name);
147 0 : ret = handle_error(status, dom, name);
148 0 : goto done;
149 : }
150 :
151 0 : tmp_ctx = talloc_new(NULL);
152 0 : if (tmp_ctx == NULL) {
153 0 : DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new failed.\n");
154 0 : ret = ENOMEM;
155 0 : goto done;
156 : }
157 :
158 0 : attrs = sysdb_new_attrs(tmp_ctx);
159 0 : if (attrs == NULL) {
160 0 : DEBUG(SSSDBG_CRIT_FAILURE, "sysdb_new_attrs failed.\n");
161 0 : ret = ENOMEM;
162 0 : goto done;
163 : }
164 :
165 : do {
166 0 : status = ctx->ops.getnetgrent_r(&result, buffer, BUFLEN, &ret);
167 0 : if (status != NSS_STATUS_SUCCESS &&
168 0 : status != NSS_STATUS_RETURN &&
169 : status != NSS_STATUS_NOTFOUND) {
170 0 : ret = handle_error(status, dom, name);
171 0 : DEBUG(SSSDBG_OP_FAILURE,
172 : "getnetgrent_r failed for netgroup [%s]: [%d][%s].\n",
173 : name, ret, strerror(ret));
174 0 : goto done;
175 : }
176 :
177 0 : if (status == NSS_STATUS_SUCCESS) {
178 0 : ret = make_netgroup_attr(result, attrs);
179 0 : if (ret != EOK) {
180 0 : DEBUG(SSSDBG_CRIT_FAILURE, "make_netgroup_attr failed.\n");
181 0 : goto done;
182 : }
183 : }
184 0 : } while (status != NSS_STATUS_RETURN && status != NSS_STATUS_NOTFOUND);
185 :
186 0 : status = ctx->ops.endnetgrent(&result);
187 0 : if (status != NSS_STATUS_SUCCESS) {
188 0 : DEBUG(SSSDBG_OP_FAILURE, "endnetgrent failed.\n");
189 0 : ret = handle_error(status, dom, name);
190 0 : goto done;
191 : }
192 :
193 0 : ret = save_netgroup(dom, name, attrs,
194 0 : !dom->case_sensitive,
195 0 : dom->netgroup_timeout);
196 0 : if (ret != EOK) {
197 0 : DEBUG(SSSDBG_OP_FAILURE, "save_netgroup failed.\n");
198 0 : goto done;
199 : }
200 :
201 0 : ret = EOK;
202 :
203 : done:
204 0 : talloc_free(tmp_ctx);
205 0 : return ret;
206 : }
|