source: trunk/samba/source/nsswitch/idmap_rid.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: 6.3 KB
Line 
1/*
2 *  idmap_rid: static map between Active Directory/NT RIDs and RFC 2307 accounts
3 *  Copyright (C) Guenther Deschner, 2004
4 *  Copyright (C) Sumit Bose, 2004
5 *
6 *  This program is free software; you can redistribute it and/or modify
7 *  it under the terms of the GNU General Public License as published by
8 *  the Free Software Foundation; either version 2 of the License, or
9 *  (at your option) any later version.
10 *
11 *  This program is distributed in the hope that it will be useful,
12 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 *  GNU General Public License for more details.
15 *
16 *  You should have received a copy of the GNU General Public License
17 *  along with this program; if not, write to the Free Software
18 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 *
20 */
21
22#include "includes.h"
23#include "winbindd.h"
24
25#undef DBGC_CLASS
26#define DBGC_CLASS DBGC_IDMAP
27
28struct idmap_rid_context {
29        const char *domain_name;
30        uint32_t low_id;
31        uint32_t high_id;
32        uint32_t base_rid;
33};
34
35/******************************************************************************
36  compat params can't be used because of the completely different way
37  we support multiple domains in the new idmap
38 *****************************************************************************/
39
40static NTSTATUS idmap_rid_initialize(struct idmap_domain *dom)
41{
42        NTSTATUS ret;
43        struct idmap_rid_context *ctx;
44        char *config_option = NULL;
45        const char *range;
46
47        if ( (ctx = talloc_zero(dom, struct idmap_rid_context)) == NULL ) {
48                DEBUG(0, ("Out of memory!\n"));
49                return NT_STATUS_NO_MEMORY;
50        }
51
52        config_option = talloc_asprintf(ctx, "idmap config %s", dom->name);
53        if ( ! config_option) {
54                DEBUG(0, ("Out of memory!\n"));
55                ret = NT_STATUS_NO_MEMORY;
56                goto failed;
57        }
58
59        range = lp_parm_const_string(-1, config_option, "range", NULL);
60        if ( !range ||
61            (sscanf(range, "%u - %u", &ctx->low_id, &ctx->high_id) != 2) ||
62            (ctx->low_id > ctx->high_id)) 
63        {
64                ctx->low_id = 0;
65                ctx->high_id = 0;
66        }
67
68        if ( !ctx->low_id || !ctx->high_id ) {
69                DEBUG(1, ("ERROR: Invalid configuration, ID range missing\n"));
70                ret = NT_STATUS_UNSUCCESSFUL;
71                goto failed;
72        }
73
74        ctx->base_rid = lp_parm_int(-1, config_option, "base_rid", 0);
75        ctx->domain_name = talloc_strdup( ctx, dom->name );
76       
77        dom->private_data = ctx;
78
79        talloc_free(config_option);
80        return NT_STATUS_OK;
81
82failed:
83        talloc_free(ctx);
84        return ret;
85}
86
87static NTSTATUS idmap_rid_id_to_sid(TALLOC_CTX *memctx, struct idmap_rid_context *ctx, struct id_map *map)
88{
89        struct winbindd_domain *domain; 
90
91        /* apply filters before checking */
92        if ((map->xid.id < ctx->low_id) || (map->xid.id > ctx->high_id)) {
93                DEBUG(5, ("Requested id (%u) out of range (%u - %u). Filtered!\n",
94                                map->xid.id, ctx->low_id, ctx->high_id));
95                return NT_STATUS_NONE_MAPPED;
96        }
97
98        if ( (domain = find_domain_from_name_noinit(ctx->domain_name)) == NULL ) {
99                return NT_STATUS_NO_SUCH_DOMAIN;
100        }
101       
102        sid_compose(map->sid, &domain->sid, map->xid.id - ctx->low_id + ctx->base_rid);
103
104        /* We **really** should have some way of validating
105           the SID exists and is the correct type here.  But
106           that is a deficiency in the idmap_rid design. */
107
108        map->status = ID_MAPPED;
109
110        return NT_STATUS_OK;
111}
112
113/**********************************
114 Single sid to id lookup function.
115**********************************/
116
117static NTSTATUS idmap_rid_sid_to_id(TALLOC_CTX *memctx, struct idmap_rid_context *ctx, struct id_map *map)
118{
119        uint32_t rid;
120
121        sid_peek_rid(map->sid, &rid);
122        map->xid.id = rid - ctx->base_rid + ctx->low_id;
123
124        /* apply filters before returning result */
125
126        if ((map->xid.id < ctx->low_id) || (map->xid.id > ctx->high_id)) {
127                DEBUG(5, ("Requested id (%u) out of range (%u - %u). Filtered!\n",
128                                map->xid.id, ctx->low_id, ctx->high_id));
129                map->status = ID_UNMAPPED;
130                return NT_STATUS_NONE_MAPPED;
131        }
132
133        /* We **really** should have some way of validating
134           the SID exists and is the correct type here.  But
135           that is a deficiency in the idmap_rid design. */
136
137        map->status = ID_MAPPED;
138
139        return NT_STATUS_OK;
140}
141
142/**********************************
143 lookup a set of unix ids.
144**********************************/
145
146static NTSTATUS idmap_rid_unixids_to_sids(struct idmap_domain *dom, struct id_map **ids)
147{
148        struct idmap_rid_context *ridctx;
149        TALLOC_CTX *ctx;
150        NTSTATUS ret;
151        int i;
152
153        ridctx = talloc_get_type(dom->private_data, struct idmap_rid_context);
154
155        ctx = talloc_new(dom);
156        if ( ! ctx) {
157                DEBUG(0, ("Out of memory!\n"));
158                return NT_STATUS_NO_MEMORY;
159        }
160
161        for (i = 0; ids[i]; i++) {
162
163                ret = idmap_rid_id_to_sid(ctx, ridctx, ids[i]);
164
165                if (( ! NT_STATUS_IS_OK(ret)) &&
166                    ( ! NT_STATUS_EQUAL(ret, NT_STATUS_NONE_MAPPED))) {
167                        /* some fatal error occurred, log it */
168                        DEBUG(3, ("Unexpected error resolving an ID (%d)\n", ids[i]->xid.id));
169                }
170        }
171
172        talloc_free(ctx);
173        return NT_STATUS_OK;
174}
175
176/**********************************
177 lookup a set of sids.
178**********************************/
179
180static NTSTATUS idmap_rid_sids_to_unixids(struct idmap_domain *dom, struct id_map **ids)
181{
182        struct idmap_rid_context *ridctx;
183        TALLOC_CTX *ctx;
184        NTSTATUS ret;
185        int i;
186
187        ridctx = talloc_get_type(dom->private_data, struct idmap_rid_context);
188
189        ctx = talloc_new(dom);
190        if ( ! ctx) {
191                DEBUG(0, ("Out of memory!\n"));
192                return NT_STATUS_NO_MEMORY;
193        }
194
195        for (i = 0; ids[i]; i++) {
196
197                ret = idmap_rid_sid_to_id(ctx, ridctx, ids[i]);
198
199                if (( ! NT_STATUS_IS_OK(ret)) &&
200                    ( ! NT_STATUS_EQUAL(ret, NT_STATUS_NONE_MAPPED))) {
201                        /* some fatal error occurred, log it */
202                        DEBUG(3, ("Unexpected error resolving a SID (%s)\n",
203                                        sid_string_static(ids[i]->sid)));
204                }
205        }
206
207        talloc_free(ctx);
208        return NT_STATUS_OK;
209}
210
211static NTSTATUS idmap_rid_close(struct idmap_domain *dom)
212{
213        if (dom->private_data) {
214                TALLOC_FREE(dom->private_data);
215        }
216        return NT_STATUS_OK;
217}
218
219static struct idmap_methods rid_methods = {
220        .init = idmap_rid_initialize,
221        .unixids_to_sids = idmap_rid_unixids_to_sids,
222        .sids_to_unixids = idmap_rid_sids_to_unixids,
223        .close_fn = idmap_rid_close
224};
225
226NTSTATUS idmap_rid_init(void)
227{
228        return smb_register_idmap(SMB_IDMAP_INTERFACE_VERSION, "rid", &rid_methods);
229}
230
Note: See TracBrowser for help on using the repository browser.