• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/router/samba-3.5.8/source3/winbindd/
1/*
2   Unix SMB/CIFS implementation.
3
4   idmap PASSDB 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 "winbindd.h"
24
25#undef DBGC_CLASS
26#define DBGC_CLASS DBGC_IDMAP
27
28/*****************************
29 Initialise idmap database.
30*****************************/
31
32static NTSTATUS idmap_nss_int_init(struct idmap_domain *dom,
33				   const char *params)
34{
35	return NT_STATUS_OK;
36}
37
38/**********************************
39 lookup a set of unix ids.
40**********************************/
41
42static NTSTATUS idmap_nss_unixids_to_sids(struct idmap_domain *dom, struct id_map **ids)
43{
44	TALLOC_CTX *ctx;
45	int i;
46
47	/* initialize the status to avoid suprise */
48	for (i = 0; ids[i]; i++) {
49		ids[i]->status = ID_UNKNOWN;
50	}
51
52	ctx = talloc_new(dom);
53	if ( ! ctx) {
54		DEBUG(0, ("Out of memory!\n"));
55		return NT_STATUS_NO_MEMORY;
56	}
57
58	for (i = 0; ids[i]; i++) {
59		struct passwd *pw;
60		struct group *gr;
61		const char *name;
62		enum lsa_SidType type;
63		bool ret;
64
65		switch (ids[i]->xid.type) {
66		case ID_TYPE_UID:
67			pw = getpwuid((uid_t)ids[i]->xid.id);
68
69			if (!pw) {
70				ids[i]->status = ID_UNMAPPED;
71				continue;
72			}
73			name = pw->pw_name;
74			break;
75		case ID_TYPE_GID:
76			gr = getgrgid((gid_t)ids[i]->xid.id);
77
78			if (!gr) {
79				ids[i]->status = ID_UNMAPPED;
80				continue;
81			}
82			name = gr->gr_name;
83			break;
84		default: /* ?? */
85			ids[i]->status = ID_UNKNOWN;
86			continue;
87		}
88
89		/* by default calls to winbindd are disabled
90		   the following call will not recurse so this is safe */
91		(void)winbind_on();
92		/* Lookup name from PDC using lsa_lookup_names() */
93		ret = winbind_lookup_name(dom->name, name, ids[i]->sid, &type);
94		(void)winbind_off();
95
96		if (!ret) {
97			/* TODO: how do we know if the name is really not mapped,
98			 * or something just failed ? */
99			ids[i]->status = ID_UNMAPPED;
100			continue;
101		}
102
103		switch (type) {
104		case SID_NAME_USER:
105			if (ids[i]->xid.type == ID_TYPE_UID) {
106				ids[i]->status = ID_MAPPED;
107			}
108			break;
109
110		case SID_NAME_DOM_GRP:
111		case SID_NAME_ALIAS:
112		case SID_NAME_WKN_GRP:
113			if (ids[i]->xid.type == ID_TYPE_GID) {
114				ids[i]->status = ID_MAPPED;
115			}
116			break;
117
118		default:
119			ids[i]->status = ID_UNKNOWN;
120			break;
121		}
122	}
123
124
125	talloc_free(ctx);
126	return NT_STATUS_OK;
127}
128
129/**********************************
130 lookup a set of sids.
131**********************************/
132
133static NTSTATUS idmap_nss_sids_to_unixids(struct idmap_domain *dom, struct id_map **ids)
134{
135	TALLOC_CTX *ctx;
136	int i;
137
138	/* initialize the status to avoid suprise */
139	for (i = 0; ids[i]; i++) {
140		ids[i]->status = ID_UNKNOWN;
141	}
142
143	ctx = talloc_new(dom);
144	if ( ! ctx) {
145		DEBUG(0, ("Out of memory!\n"));
146		return NT_STATUS_NO_MEMORY;
147	}
148
149	for (i = 0; ids[i]; i++) {
150		struct group *gr;
151		enum lsa_SidType type;
152		const char *dom_name = NULL;
153		const char *name = NULL;
154		bool ret;
155
156		/* by default calls to winbindd are disabled
157		   the following call will not recurse so this is safe */
158		(void)winbind_on();
159		ret = winbind_lookup_sid(ctx, ids[i]->sid, &dom_name, &name, &type);
160		(void)winbind_off();
161
162		if (!ret) {
163			/* TODO: how do we know if the name is really not mapped,
164			 * or something just failed ? */
165			ids[i]->status = ID_UNMAPPED;
166			continue;
167		}
168
169		switch (type) {
170		case SID_NAME_USER: {
171			struct passwd *pw;
172
173			/* this will find also all lower case name and use username level */
174
175			pw = Get_Pwnam_alloc(talloc_tos(), name);
176			if (pw) {
177				ids[i]->xid.id = pw->pw_uid;
178				ids[i]->xid.type = ID_TYPE_UID;
179				ids[i]->status = ID_MAPPED;
180			}
181			TALLOC_FREE(pw);
182			break;
183		}
184
185		case SID_NAME_DOM_GRP:
186		case SID_NAME_ALIAS:
187		case SID_NAME_WKN_GRP:
188
189			gr = getgrnam(name);
190			if (gr) {
191				ids[i]->xid.id = gr->gr_gid;
192				ids[i]->xid.type = ID_TYPE_GID;
193				ids[i]->status = ID_MAPPED;
194			}
195			break;
196
197		default:
198			ids[i]->status = ID_UNKNOWN;
199			break;
200		}
201	}
202
203	talloc_free(ctx);
204	return NT_STATUS_OK;
205}
206
207/**********************************
208 Close the idmap tdb instance
209**********************************/
210
211static NTSTATUS idmap_nss_close(struct idmap_domain *dom)
212{
213	return NT_STATUS_OK;
214}
215
216static struct idmap_methods nss_methods = {
217
218	.init = idmap_nss_int_init,
219	.unixids_to_sids = idmap_nss_unixids_to_sids,
220	.sids_to_unixids = idmap_nss_sids_to_unixids,
221	.close_fn = idmap_nss_close
222};
223
224NTSTATUS idmap_nss_init(void)
225{
226	return smb_register_idmap(SMB_IDMAP_INTERFACE_VERSION, "nss", &nss_methods);
227}
228