source: trunk/samba/source/nsswitch/idmap_nss.c @ 30

Last change on this file since 30 was 30, checked in by Paul Smedley, 14 years ago

Code updated to Samba 3.0.25rc2 level

File size: 4.9 KB
Line 
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        ctx = talloc_new(dom);
49        if ( ! ctx) {
50                DEBUG(0, ("Out of memory!\n"));
51                return NT_STATUS_NO_MEMORY;
52        }
53
54        for (i = 0; ids[i]; i++) {
55                struct passwd *pw;
56                struct group *gr;
57                const char *name;
58                enum lsa_SidType type;
59                BOOL ret;
60               
61                switch (ids[i]->xid.type) {
62                case ID_TYPE_UID:
63                        pw = getpwuid((uid_t)ids[i]->xid.id);
64
65                        if (!pw) {
66                                ids[i]->status = ID_UNMAPPED;
67                                continue;
68                        }
69                        name = pw->pw_name;
70                        break;
71                case ID_TYPE_GID:
72                        gr = getgrgid((gid_t)ids[i]->xid.id);
73
74                        if (!gr) {
75                                ids[i]->status = ID_UNMAPPED;
76                                continue;
77                        }
78                        name = gr->gr_name;
79                        break;
80                default: /* ?? */
81                        ids[i]->status = ID_UNKNOWN;
82                        continue;
83                }
84
85                /* by default calls to winbindd are disabled
86                   the following call will not recurse so this is safe */
87                winbind_on();
88                /* Lookup name from PDC using lsa_lookup_names() */
89                ret = winbind_lookup_name(dom->name, name, ids[i]->sid, &type);
90                winbind_off();
91
92                if (!ret) {
93                        /* TODO: how do we know if the name is really not mapped,
94                         * or something just failed ? */
95                        ids[i]->status = ID_UNMAPPED;
96                        continue;
97                }
98
99                switch (type) {
100                case SID_NAME_USER:
101                        if (ids[i]->xid.type == ID_TYPE_UID) {
102                                ids[i]->status = ID_MAPPED;
103                        }
104                        break;
105
106                case SID_NAME_DOM_GRP:
107                case SID_NAME_ALIAS:
108                case SID_NAME_WKN_GRP:
109                        if (ids[i]->xid.type == ID_TYPE_GID) {
110                                ids[i]->status = ID_MAPPED;
111                        }
112                        break;
113
114                default:
115                        ids[i]->status = ID_UNKNOWN;
116                        break;
117                }
118        }
119
120
121        talloc_free(ctx);
122        return NT_STATUS_OK;
123}
124
125/**********************************
126 lookup a set of sids.
127**********************************/
128
129static NTSTATUS idmap_nss_sids_to_unixids(struct idmap_domain *dom, struct id_map **ids)
130{
131        TALLOC_CTX *ctx;
132        int i;
133
134        ctx = talloc_new(dom);
135        if ( ! ctx) {
136                DEBUG(0, ("Out of memory!\n"));
137                return NT_STATUS_NO_MEMORY;
138        }
139
140        for (i = 0; ids[i]; i++) {
141                struct passwd *pw;
142                struct group *gr;
143                enum lsa_SidType type;
144                const char *dom_name = NULL;
145                const 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                winbind_on();
151                ret = winbind_lookup_sid(ctx, ids[i]->sid, &dom_name, &name, &type);
152                winbind_off();
153
154                if (!ret) {
155                        /* TODO: how do we know if the name is really not mapped,
156                         * or something just failed ? */
157                        ids[i]->status = ID_UNMAPPED;
158                        continue;
159                }
160
161                switch (type) {
162                case SID_NAME_USER:
163
164                        /* this will find also all lower case name and use username level */
165                       
166                        pw = Get_Pwnam(name);
167                        if (pw) {
168                                ids[i]->xid.id = pw->pw_uid;
169                                ids[i]->xid.type = ID_TYPE_UID;
170                                ids[i]->status = ID_MAPPED;
171                        }
172                        break;
173
174                case SID_NAME_DOM_GRP:
175                case SID_NAME_ALIAS:
176                case SID_NAME_WKN_GRP:
177
178                        gr = getgrnam(name);
179                        if (gr) {
180                                ids[i]->xid.id = gr->gr_gid;
181                                ids[i]->xid.type = ID_TYPE_GID;
182                                ids[i]->status = ID_MAPPED;
183                        }
184                        break;
185
186                default:
187                        ids[i]->status = ID_UNKNOWN;
188                        break;
189                }
190        }
191
192        talloc_free(ctx);
193        return NT_STATUS_OK;
194}
195
196/**********************************
197 Close the idmap tdb instance
198**********************************/
199
200static NTSTATUS idmap_nss_close(struct idmap_domain *dom)
201{
202        return NT_STATUS_OK;
203}
204
205static struct idmap_methods nss_methods = {
206
207        .init = idmap_nss_int_init,
208        .unixids_to_sids = idmap_nss_unixids_to_sids,
209        .sids_to_unixids = idmap_nss_sids_to_unixids,
210        .close_fn = idmap_nss_close
211};
212
213NTSTATUS idmap_nss_init(void)
214{
215        return smb_register_idmap(SMB_IDMAP_INTERFACE_VERSION, "nss", &nss_methods);
216}
Note: See TracBrowser for help on using the repository browser.