Line data Source code
1 : /*
2 : Unix SMB/CIFS implementation.
3 :
4 : idmap NSS backend
5 :
6 : Copyright (C) Simo Sorce 2006
7 :
8 : This program is free software; you can redistribute it and/or modify
9 : it under the terms of the GNU General Public License as published by
10 : the Free Software Foundation; either version 3 of the License, or
11 : (at your option) any later version.
12 :
13 : This program is distributed in the hope that it will be useful,
14 : but WITHOUT ANY WARRANTY; without even the implied warranty of
15 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 : GNU General Public License for more details.
17 :
18 : You should have received a copy of the GNU General Public License
19 : along with this program. If not, see <http://www.gnu.org/licenses/>.
20 : */
21 :
22 : #include "includes.h"
23 : #include "system/passwd.h"
24 : #include "winbindd.h"
25 : #include "nsswitch/winbind_client.h"
26 : #include "idmap.h"
27 : #include "lib/winbind_util.h"
28 : #include "libcli/security/dom_sid.h"
29 :
30 : #undef DBGC_CLASS
31 : #define DBGC_CLASS DBGC_IDMAP
32 :
33 : /*****************************
34 : Initialise idmap database.
35 : *****************************/
36 :
37 0 : static NTSTATUS idmap_nss_int_init(struct idmap_domain *dom)
38 : {
39 0 : return NT_STATUS_OK;
40 : }
41 :
42 : /**********************************
43 : lookup a set of unix ids.
44 : **********************************/
45 :
46 0 : static NTSTATUS idmap_nss_unixids_to_sids(struct idmap_domain *dom, struct id_map **ids)
47 : {
48 : int i;
49 :
50 : /* initialize the status to avoid suprise */
51 0 : for (i = 0; ids[i]; i++) {
52 0 : ids[i]->status = ID_UNKNOWN;
53 : }
54 :
55 0 : for (i = 0; ids[i]; i++) {
56 : struct passwd *pw;
57 : struct group *gr;
58 : const char *name;
59 : struct dom_sid sid;
60 : enum lsa_SidType type;
61 : bool ret;
62 :
63 0 : switch (ids[i]->xid.type) {
64 0 : case ID_TYPE_UID:
65 0 : pw = getpwuid((uid_t)ids[i]->xid.id);
66 :
67 0 : if (!pw) {
68 0 : ids[i]->status = ID_UNMAPPED;
69 0 : continue;
70 : }
71 0 : name = pw->pw_name;
72 0 : break;
73 0 : case ID_TYPE_GID:
74 0 : gr = getgrgid((gid_t)ids[i]->xid.id);
75 :
76 0 : if (!gr) {
77 0 : ids[i]->status = ID_UNMAPPED;
78 0 : continue;
79 : }
80 0 : name = gr->gr_name;
81 0 : break;
82 0 : default: /* ?? */
83 0 : ids[i]->status = ID_UNKNOWN;
84 0 : continue;
85 : }
86 :
87 : /* by default calls to winbindd are disabled
88 : the following call will not recurse so this is safe */
89 0 : (void)winbind_on();
90 : /* Lookup name from PDC using lsa_lookup_names() */
91 0 : ret = winbind_lookup_name(dom->name, name, &sid, &type);
92 0 : (void)winbind_off();
93 :
94 0 : if (!ret) {
95 : /* TODO: how do we know if the name is really not mapped,
96 : * or something just failed ? */
97 0 : ids[i]->status = ID_UNMAPPED;
98 0 : continue;
99 : }
100 :
101 0 : switch (type) {
102 0 : case SID_NAME_USER:
103 0 : if (ids[i]->xid.type == ID_TYPE_UID) {
104 0 : sid_copy(ids[i]->sid, &sid);
105 0 : ids[i]->status = ID_MAPPED;
106 : }
107 0 : break;
108 :
109 0 : case SID_NAME_DOM_GRP:
110 : case SID_NAME_ALIAS:
111 : case SID_NAME_WKN_GRP:
112 0 : if (ids[i]->xid.type == ID_TYPE_GID) {
113 0 : sid_copy(ids[i]->sid, &sid);
114 0 : ids[i]->status = ID_MAPPED;
115 : }
116 0 : break;
117 :
118 0 : default:
119 0 : ids[i]->status = ID_UNKNOWN;
120 0 : break;
121 : }
122 : }
123 0 : return NT_STATUS_OK;
124 : }
125 :
126 : /**********************************
127 : lookup a set of sids.
128 : **********************************/
129 :
130 0 : static NTSTATUS idmap_nss_sids_to_unixids(struct idmap_domain *dom, struct id_map **ids)
131 : {
132 : int i;
133 :
134 : /* initialize the status to avoid suprise */
135 0 : for (i = 0; ids[i]; i++) {
136 0 : ids[i]->status = ID_UNKNOWN;
137 : }
138 :
139 0 : for (i = 0; ids[i]; i++) {
140 : struct group *gr;
141 : enum lsa_SidType type;
142 0 : const char *_domain = NULL;
143 0 : const char *_name = NULL;
144 0 : char *domain = NULL;
145 0 : char *name = NULL;
146 : bool ret;
147 :
148 : /* by default calls to winbindd are disabled
149 : the following call will not recurse so this is safe */
150 0 : (void)winbind_on();
151 0 : ret = winbind_lookup_sid(talloc_tos(),
152 0 : ids[i]->sid,
153 : &_domain,
154 : &_name,
155 : &type);
156 0 : (void)winbind_off();
157 0 : if (!ret) {
158 : /* TODO: how do we know if the name is really not mapped,
159 : * or something just failed ? */
160 0 : ids[i]->status = ID_UNMAPPED;
161 0 : continue;
162 : }
163 :
164 0 : domain = discard_const_p(char, _domain);
165 0 : name = discard_const_p(char, _name);
166 :
167 0 : if (!strequal(domain, dom->name)) {
168 : struct dom_sid_buf buf;
169 0 : DBG_ERR("DOMAIN[%s] ignoring SID[%s] belongs to %s [%s\\%s]\n",
170 : dom->name, dom_sid_str_buf(ids[i]->sid, &buf),
171 : sid_type_lookup(type), domain, name);
172 0 : ids[i]->status = ID_UNMAPPED;
173 0 : continue;
174 : }
175 :
176 0 : switch (type) {
177 0 : case SID_NAME_USER: {
178 : struct passwd *pw;
179 :
180 : /* this will find also all lower case name and use username level */
181 :
182 0 : pw = Get_Pwnam_alloc(talloc_tos(), name);
183 0 : if (pw) {
184 0 : ids[i]->xid.id = pw->pw_uid;
185 0 : ids[i]->xid.type = ID_TYPE_UID;
186 0 : ids[i]->status = ID_MAPPED;
187 : }
188 0 : TALLOC_FREE(pw);
189 0 : break;
190 : }
191 :
192 0 : case SID_NAME_DOM_GRP:
193 : case SID_NAME_ALIAS:
194 : case SID_NAME_WKN_GRP:
195 :
196 0 : gr = getgrnam(name);
197 0 : if (gr) {
198 0 : ids[i]->xid.id = gr->gr_gid;
199 0 : ids[i]->xid.type = ID_TYPE_GID;
200 0 : ids[i]->status = ID_MAPPED;
201 : }
202 0 : break;
203 :
204 0 : default:
205 0 : ids[i]->status = ID_UNKNOWN;
206 0 : break;
207 : }
208 0 : TALLOC_FREE(domain);
209 0 : TALLOC_FREE(name);
210 : }
211 0 : return NT_STATUS_OK;
212 : }
213 :
214 : /**********************************
215 : Close the idmap tdb instance
216 : **********************************/
217 :
218 : static const struct idmap_methods nss_methods = {
219 : .init = idmap_nss_int_init,
220 : .unixids_to_sids = idmap_nss_unixids_to_sids,
221 : .sids_to_unixids = idmap_nss_sids_to_unixids,
222 : };
223 :
224 0 : NTSTATUS idmap_nss_init(TALLOC_CTX *mem_ctx)
225 : {
226 0 : return smb_register_idmap(SMB_IDMAP_INTERFACE_VERSION, "nss", &nss_methods);
227 : }
|