• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt/router/samba-3.0.25b/source/nsswitch/
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 2 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, write to the Free Software
20   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21*/
22
23#include "includes.h"
24#include "winbindd.h"
25
26#undef DBGC_CLASS
27#define DBGC_CLASS DBGC_IDMAP
28
29/*****************************
30 Initialise idmap database.
31*****************************/
32
33static NTSTATUS idmap_nss_int_init(struct idmap_domain *dom)
34{
35	dom->initialized = True;
36	return NT_STATUS_OK;
37}
38
39/**********************************
40 lookup a set of unix ids.
41**********************************/
42
43static NTSTATUS idmap_nss_unixids_to_sids(struct idmap_domain *dom, struct id_map **ids)
44{
45	TALLOC_CTX *ctx;
46	int i;
47
48	if (! dom->initialized) {
49		return NT_STATUS_UNSUCCESSFUL;
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		winbind_on();
92		/* Lookup name from PDC using lsa_lookup_names() */
93		ret = winbind_lookup_name(dom->name, name, ids[i]->sid, &type);
94		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	if (! dom->initialized) {
139		return NT_STATUS_UNSUCCESSFUL;
140	}
141
142	ctx = talloc_new(dom);
143	if ( ! ctx) {
144		DEBUG(0, ("Out of memory!\n"));
145		return NT_STATUS_NO_MEMORY;
146	}
147
148	for (i = 0; ids[i]; i++) {
149		struct passwd *pw;
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		winbind_on();
159		ret = winbind_lookup_sid(ctx, ids[i]->sid, &dom_name, &name, &type);
160		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
172			/* this will find also all lower case name and use username level */
173
174			pw = Get_Pwnam(name);
175			if (pw) {
176				ids[i]->xid.id = pw->pw_uid;
177				ids[i]->xid.type = ID_TYPE_UID;
178				ids[i]->status = ID_MAPPED;
179			}
180			break;
181
182		case SID_NAME_DOM_GRP:
183		case SID_NAME_ALIAS:
184		case SID_NAME_WKN_GRP:
185
186			gr = getgrnam(name);
187			if (gr) {
188				ids[i]->xid.id = gr->gr_gid;
189				ids[i]->xid.type = ID_TYPE_GID;
190				ids[i]->status = ID_MAPPED;
191			}
192			break;
193
194		default:
195			ids[i]->status = ID_UNKNOWN;
196			break;
197		}
198	}
199
200	talloc_free(ctx);
201	return NT_STATUS_OK;
202}
203
204/**********************************
205 Close the idmap tdb instance
206**********************************/
207
208static NTSTATUS idmap_nss_close(struct idmap_domain *dom)
209{
210	return NT_STATUS_OK;
211}
212
213static struct idmap_methods nss_methods = {
214
215	.init = idmap_nss_int_init,
216	.unixids_to_sids = idmap_nss_unixids_to_sids,
217	.sids_to_unixids = idmap_nss_sids_to_unixids,
218	.close_fn = idmap_nss_close
219};
220
221NTSTATUS idmap_nss_init(void)
222{
223	return smb_register_idmap(SMB_IDMAP_INTERFACE_VERSION, "nss", &nss_methods);
224}
225