source: trunk/samba/source/nsswitch/idmap_ad.c @ 26

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

Updated source to 3.0.25rc1

File size: 21.5 KB
Line 
1/*
2 *  idmap_ad: map between Active Directory and RFC 2307 or "Services for Unix" (SFU) Accounts
3 *
4 * Unix SMB/CIFS implementation.
5 *
6 * Winbind ADS backend functions
7 *
8 * Copyright (C) Andrew Tridgell 2001
9 * Copyright (C) Andrew Bartlett <abartlet@samba.org> 2003
10 * Copyright (C) Gerald (Jerry) Carter 2004-2007
11 * Copyright (C) Luke Howard 2001-2004
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 */
27
28#include "includes.h"
29
30#undef DBGC_CLASS
31#define DBGC_CLASS DBGC_IDMAP
32
33#define WINBIND_CCACHE_NAME "MEMORY:winbind_ccache"
34
35#define IDMAP_AD_MAX_IDS 30
36#define CHECK_ALLOC_DONE(mem) do { \
37     if (!mem) { \
38           DEBUG(0, ("Out of memory!\n")); \
39           ret = NT_STATUS_NO_MEMORY; \
40           goto done; \
41      } \
42} while (0)
43
44struct idmap_ad_context {
45        uint32_t filter_low_id;
46        uint32_t filter_high_id;
47};
48
49NTSTATUS init_module(void);
50
51static ADS_STRUCT *ad_idmap_ads = NULL;
52static struct posix_schema *ad_schema = NULL;
53static enum wb_posix_mapping ad_map_type = WB_POSIX_MAP_UNKNOWN;
54
55/************************************************************************
56 ***********************************************************************/
57
58static ADS_STRUCT *ad_idmap_cached_connection_internal(void)
59{
60        ADS_STRUCT *ads;
61        ADS_STATUS status;
62        BOOL local = False;
63        fstring dc_name;
64        struct in_addr dc_ip;   
65
66        if (ad_idmap_ads != NULL) {
67
68                time_t expire;
69                time_t now = time(NULL);
70
71                ads = ad_idmap_ads;
72
73                expire = MIN(ads->auth.tgt_expire, ads->auth.tgs_expire);
74
75                /* check for a valid structure */
76                DEBUG(7, ("Current tickets expire in %d seconds (at %d, time is now %d)\n",
77                          (uint32)expire-(uint32)now, (uint32) expire, (uint32) now));
78
79                if ( ads->config.realm && (expire > time(NULL))) {
80                        return ads;
81                } else {
82                        /* we own this ADS_STRUCT so make sure it goes away */
83                        DEBUG(7,("Deleting expired krb5 credential cache\n"));
84                        ads->is_mine = True;
85                        ads_destroy( &ads );
86                        ads_kdestroy(WINBIND_CCACHE_NAME);
87                        ad_idmap_ads = NULL;
88                        TALLOC_FREE( ad_schema );                       
89                }
90        }
91
92        if (!local) {
93                /* we don't want this to affect the users ccache */
94                setenv("KRB5CCNAME", WINBIND_CCACHE_NAME, 1);
95        }
96
97        if ( (ads = ads_init(lp_realm(), lp_workgroup(), NULL)) == NULL ) {
98                DEBUG(1,("ads_init failed\n"));
99                return NULL;
100        }
101
102        /* the machine acct password might have change - fetch it every time */
103        SAFE_FREE(ads->auth.password);
104        ads->auth.password = secrets_fetch_machine_password(lp_workgroup(), NULL, NULL);
105
106        SAFE_FREE(ads->auth.realm);
107        ads->auth.realm = SMB_STRDUP(lp_realm());
108
109        /* setup server affinity */
110
111        get_dc_name( NULL, ads->auth.realm, dc_name, &dc_ip );
112       
113        status = ads_connect(ads);
114        if (!ADS_ERR_OK(status)) {
115                DEBUG(1, ("ad_idmap_init: failed to connect to AD\n"));
116                ads_destroy(&ads);
117                return NULL;
118        }
119
120        ads->is_mine = False;
121
122        ad_idmap_ads = ads;
123
124        return ads;
125}
126
127/************************************************************************
128 ***********************************************************************/
129
130static ADS_STRUCT *ad_idmap_cached_connection(void)
131{
132        ADS_STRUCT *ads = ad_idmap_cached_connection_internal();
133       
134        if ( !ads )
135                return NULL;
136
137        /* if we have a valid ADS_STRUCT and the schema model is
138           defined, then we can return here. */
139
140        if ( ad_schema )
141                return ads;
142
143        /* Otherwise, set the schema model */
144
145        if ( (ad_map_type ==  WB_POSIX_MAP_SFU) ||
146             (ad_map_type ==  WB_POSIX_MAP_RFC2307) ) 
147        {
148                ADS_STATUS schema_status;
149               
150                schema_status = ads_check_posix_schema_mapping( NULL, ads, ad_map_type, &ad_schema);
151                if ( !ADS_ERR_OK(schema_status) ) {
152                        DEBUG(2,("ad_idmap_cached_connection: Failed to obtain schema details!\n"));
153                        return NULL;                   
154                }
155        }
156       
157        return ads;
158}
159
160/************************************************************************
161 ***********************************************************************/
162
163static NTSTATUS idmap_ad_initialize(struct idmap_domain *dom, const char *params)
164{
165        struct idmap_ad_context *ctx;
166        char *config_option;
167        const char *range;
168        ADS_STRUCT *ads;
169
170        /* verify AD is reachable (not critical, we may just be offline at start) */
171        if ( (ads = ad_idmap_cached_connection()) == NULL ) {
172                DEBUG(1, ("WARNING: Could not init an AD connection! Mapping might not work.\n"));
173        }
174
175        if ( (ctx = talloc_zero(dom, struct idmap_ad_context)) == NULL ) {
176                DEBUG(0, ("Out of memory!\n"));
177                return NT_STATUS_NO_MEMORY;
178        }
179
180        if ( (config_option = talloc_asprintf(ctx, "idmap config %s", dom->name)) == NULL ) {
181                DEBUG(0, ("Out of memory!\n"));
182                talloc_free(ctx);
183                return NT_STATUS_NO_MEMORY;
184        }
185
186        /* load ranges */
187        range = lp_parm_const_string(-1, config_option, "range", NULL);
188        if (range && range[0]) {
189                if ((sscanf(range, "%u - %u", &ctx->filter_low_id, &ctx->filter_high_id) != 2) ||
190                    (ctx->filter_low_id > ctx->filter_high_id)) {
191                        DEBUG(1, ("ERROR: invalid filter range [%s]", range));
192                        ctx->filter_low_id = 0;
193                        ctx->filter_high_id = 0;
194                }
195        }
196
197        dom->private_data = ctx;
198
199        talloc_free(config_option);
200
201        return NT_STATUS_OK;
202}
203
204/************************************************************************
205 Search up to IDMAP_AD_MAX_IDS entries in maps for a match.
206 ***********************************************************************/
207
208static struct id_map *find_map_by_id(struct id_map **maps, enum id_type type, uint32_t id)
209{
210        int i;
211
212        for (i = 0; maps[i] && i<IDMAP_AD_MAX_IDS; i++) {
213                if ((maps[i]->xid.type == type) && (maps[i]->xid.id == id)) {
214                        return maps[i];
215                }
216        }
217
218        return NULL;   
219}
220
221/************************************************************************
222 Search up to IDMAP_AD_MAX_IDS entries in maps for a match
223 ***********************************************************************/
224
225static struct id_map *find_map_by_sid(struct id_map **maps, DOM_SID *sid)
226{
227        int i;
228
229        for (i = 0; maps[i] && i<IDMAP_AD_MAX_IDS; i++) {
230                if (sid_equal(maps[i]->sid, sid)) {
231                        return maps[i];
232                }
233        }
234
235        return NULL;   
236}
237
238/************************************************************************
239 ***********************************************************************/
240
241static NTSTATUS idmap_ad_unixids_to_sids(struct idmap_domain *dom, struct id_map **ids)
242{
243        NTSTATUS ret;
244        TALLOC_CTX *memctx;
245        struct idmap_ad_context *ctx;
246        ADS_STATUS rc;
247        ADS_STRUCT *ads;
248        const char *attrs[] = { "sAMAccountType", 
249                                "objectSid",
250                                NULL, /* uidnumber */
251                                NULL, /* gidnumber */
252                                NULL };
253        LDAPMessage *res = NULL;
254        char *filter = NULL;
255        int idx = 0;
256        int bidx = 0;
257        int count;
258        int i;
259        char *u_filter = NULL;
260        char *g_filter = NULL;
261
262        ctx = talloc_get_type(dom->private_data, struct idmap_ad_context);
263
264        if ( (memctx = talloc_new(ctx)) == NULL ) {
265                DEBUG(0, ("Out of memory!\n"));
266                return NT_STATUS_NO_MEMORY;
267        }
268
269        if ( (ads = ad_idmap_cached_connection()) == NULL ) {
270                DEBUG(1, ("ADS uninitialized\n"));
271                ret = NT_STATUS_UNSUCCESSFUL;
272                goto done;
273        }
274
275        attrs[2] = ad_schema->posix_uidnumber_attr;
276        attrs[3] = ad_schema->posix_gidnumber_attr;
277
278again:
279        bidx = idx;
280        for (i = 0; (i < IDMAP_AD_MAX_IDS) && ids[idx]; i++, idx++) {
281                switch (ids[idx]->xid.type) {
282                case ID_TYPE_UID:     
283                        if ( ! u_filter) {
284                                u_filter = talloc_asprintf(memctx, "(&(|"
285                                                           "(sAMAccountType=%d)"
286                                                           "(sAMAccountType=%d)"
287                                                           "(sAMAccountType=%d))(|",
288                                                           ATYPE_NORMAL_ACCOUNT,
289                                                           ATYPE_WORKSTATION_TRUST,
290                                                           ATYPE_INTERDOMAIN_TRUST);
291                        }
292                        u_filter = talloc_asprintf_append(u_filter, "(%s=%lu)",
293                                                          ad_schema->posix_uidnumber_attr,
294                                                          (unsigned long)ids[idx]->xid.id);
295                        CHECK_ALLOC_DONE(u_filter);
296                        break;
297                               
298                case ID_TYPE_GID:
299                        if ( ! g_filter) {
300                                g_filter = talloc_asprintf(memctx, "(&(|"
301                                                           "(sAMAccountType=%d)"
302                                                           "(sAMAccountType=%d))(|",
303                                                           ATYPE_SECURITY_GLOBAL_GROUP,
304                                                           ATYPE_SECURITY_LOCAL_GROUP);
305                        }
306                        g_filter = talloc_asprintf_append(g_filter, "(%s=%lu)",
307                                                          ad_schema->posix_gidnumber_attr,
308                                                          (unsigned long)ids[idx]->xid.id);
309                        CHECK_ALLOC_DONE(g_filter);
310                        break;
311
312                default:
313                        DEBUG(3, ("Unknown ID type\n"));
314                        ids[idx]->status = ID_UNKNOWN;
315                        continue;
316                }
317        }
318        filter = talloc_asprintf(memctx, "(|");
319        CHECK_ALLOC_DONE(filter);
320        if ( u_filter) {
321                filter = talloc_asprintf_append(filter, "%s))", u_filter);
322                CHECK_ALLOC_DONE(filter);
323                        TALLOC_FREE(u_filter);
324        }
325        if ( g_filter) {
326                filter = talloc_asprintf_append(filter, "%s))", g_filter);
327                CHECK_ALLOC_DONE(filter);
328                TALLOC_FREE(g_filter);
329        }
330        filter = talloc_asprintf_append(filter, ")");
331        CHECK_ALLOC_DONE(filter);
332        DEBUG(10, ("Filter: [%s]\n", filter));
333        rc = ads_search_retry(ads, &res, filter, attrs);
334        if (!ADS_ERR_OK(rc)) {
335                DEBUG(1, ("ERROR: ads search returned: %s\n", ads_errstr(rc)));
336                ret = NT_STATUS_UNSUCCESSFUL;
337                goto done;
338        }
339
340        if ( (count = ads_count_replies(ads, res)) == 0 ) {
341                DEBUG(10, ("No IDs found\n"));
342        }
343
344        for (i = 0; i < count; i++) {
345                LDAPMessage *entry = NULL;
346                DOM_SID sid;
347                enum id_type type;
348                struct id_map *map;
349                uint32_t id;
350                uint32_t atype;
351
352                if (i == 0) { /* first entry */
353                        entry = ads_first_entry(ads, res);
354                } else { /* following ones */
355                        entry = ads_next_entry(ads, entry);
356                }
357                if ( ! entry) {
358                        DEBUG(2, ("ERROR: Unable to fetch ldap entries from results\n"));
359                        continue;
360                }
361
362                /* first check if the SID is present */
363                if (!ads_pull_sid(ads, entry, "objectSid", &sid)) {
364                        DEBUG(2, ("Could not retrieve SID from entry\n"));
365                        continue;
366                }
367
368                /* get type */
369                if (!ads_pull_uint32(ads, entry, "sAMAccountType", &atype)) {
370                        DEBUG(1, ("could not get SAM account type\n"));
371                        continue;
372                }
373
374                switch (atype & 0xF0000000) {
375                case ATYPE_SECURITY_GLOBAL_GROUP:
376                case ATYPE_SECURITY_LOCAL_GROUP:
377                        type = ID_TYPE_GID;
378                        break;
379                case ATYPE_NORMAL_ACCOUNT:
380                case ATYPE_WORKSTATION_TRUST:
381                case ATYPE_INTERDOMAIN_TRUST:
382                        type = ID_TYPE_UID;
383                        break;
384                default:
385                        DEBUG(1, ("unrecognized SAM account type %08x\n", atype));
386                        continue;
387                }
388
389                if (!ads_pull_uint32(ads, entry, (type==ID_TYPE_UID) ? 
390                                                 ad_schema->posix_uidnumber_attr : 
391                                                 ad_schema->posix_gidnumber_attr, 
392                                     &id)) 
393                {
394                        DEBUG(1, ("Could not get unix ID\n"));
395                        continue;
396                }
397
398                if ((id == 0) ||
399                    (ctx->filter_low_id && (id < ctx->filter_low_id)) ||
400                    (ctx->filter_high_id && (id > ctx->filter_high_id))) {
401                        DEBUG(5, ("Requested id (%u) out of range (%u - %u). Filtered!\n",
402                                id, ctx->filter_low_id, ctx->filter_high_id));
403                        continue;
404                }
405
406                map = find_map_by_id(&ids[bidx], type, id);
407                if (!map) {
408                        DEBUG(2, ("WARNING: couldn't match result with requested ID\n"));
409                        continue;
410                }
411
412                sid_copy(map->sid, &sid);
413
414                /* mapped */
415                map->status = ID_MAPPED;
416
417                DEBUG(10, ("Mapped %s -> %lu (%d)\n",
418                           sid_string_static(map->sid),
419                           (unsigned long)map->xid.id,
420                           map->xid.type));
421        }
422
423        if (res) {
424                ads_msgfree(ads, res);
425        }
426
427        if (ids[idx]) { /* still some values to map */
428                goto again;
429        }
430
431        ret = NT_STATUS_OK;
432
433        /* mark all unknown ones as unmapped */
434        for (i = 0; ids[i]; i++) {
435                if (ids[i]->status == ID_UNKNOWN) 
436                        ids[i]->status = ID_UNMAPPED;
437        }
438
439done:
440        talloc_free(memctx);
441        return ret;
442}
443
444/************************************************************************
445 ***********************************************************************/
446
447static NTSTATUS idmap_ad_sids_to_unixids(struct idmap_domain *dom, struct id_map **ids)
448{
449        NTSTATUS ret;
450        TALLOC_CTX *memctx;
451        struct idmap_ad_context *ctx;
452        ADS_STATUS rc;
453        ADS_STRUCT *ads;
454        const char *attrs[] = { "sAMAccountType", 
455                                "objectSid",
456                                NULL, /* attr_uidnumber */
457                                NULL, /* attr_gidnumber */
458                                NULL };
459        LDAPMessage *res = NULL;
460        char *filter = NULL;
461        int idx = 0;
462        int bidx = 0;
463        int count;
464        int i;
465        char *sidstr;
466
467        ctx = talloc_get_type(dom->private_data, struct idmap_ad_context);     
468
469        if ( (memctx = talloc_new(ctx)) == NULL ) {             
470                DEBUG(0, ("Out of memory!\n"));
471                return NT_STATUS_NO_MEMORY;
472        }
473
474        if ( (ads = ad_idmap_cached_connection()) == NULL ) {
475                DEBUG(1, ("ADS uninitialized\n"));
476                ret = NT_STATUS_UNSUCCESSFUL;
477                goto done;
478        }
479
480        attrs[2] = ad_schema->posix_uidnumber_attr;
481        attrs[3] = ad_schema->posix_gidnumber_attr;
482
483again:
484        filter = talloc_asprintf(memctx, "(&(|"
485                                 "(sAMAccountType=%d)(sAMAccountType=%d)(sAMAccountType=%d)" /* user account types */
486                                 "(sAMAccountType=%d)(sAMAccountType=%d)" /* group account types */
487                                 ")(|",
488                                 ATYPE_NORMAL_ACCOUNT, ATYPE_WORKSTATION_TRUST, ATYPE_INTERDOMAIN_TRUST,
489                                 ATYPE_SECURITY_GLOBAL_GROUP, ATYPE_SECURITY_LOCAL_GROUP);
490               
491        CHECK_ALLOC_DONE(filter);
492
493        bidx = idx;
494        for (i = 0; (i < IDMAP_AD_MAX_IDS) && ids[idx]; i++, idx++) {
495
496                sidstr = sid_binstring(ids[idx]->sid);
497                filter = talloc_asprintf_append(filter, "(objectSid=%s)", sidstr);
498                       
499                free(sidstr);
500                CHECK_ALLOC_DONE(filter);
501        }
502        filter = talloc_asprintf_append(filter, "))");
503        CHECK_ALLOC_DONE(filter);
504        DEBUG(10, ("Filter: [%s]\n", filter));
505
506        rc = ads_search_retry(ads, &res, filter, attrs);
507        if (!ADS_ERR_OK(rc)) {
508                DEBUG(1, ("ERROR: ads search returned: %s\n", ads_errstr(rc)));
509                ret = NT_STATUS_UNSUCCESSFUL;
510                goto done;
511        }
512
513        if ( (count = ads_count_replies(ads, res)) == 0 ) {
514                DEBUG(10, ("No IDs found\n"));
515        }
516
517        for (i = 0; i < count; i++) {
518                LDAPMessage *entry = NULL;
519                DOM_SID sid;
520                enum id_type type;
521                struct id_map *map;
522                uint32_t id;
523                uint32_t atype;
524
525                if (i == 0) { /* first entry */
526                        entry = ads_first_entry(ads, res);
527                } else { /* following ones */
528                        entry = ads_next_entry(ads, entry);
529                }
530                if ( ! entry) {
531                        DEBUG(2, ("ERROR: Unable to fetch ldap entries from results\n"));
532                        continue;
533                }
534
535                /* first check if the SID is present */
536                if (!ads_pull_sid(ads, entry, "objectSid", &sid)) {
537                        DEBUG(2, ("Could not retrieve SID from entry\n"));
538                        continue;
539                }
540
541                map = find_map_by_sid(&ids[bidx], &sid);
542                if (!map) {
543                        DEBUG(2, ("WARNING: couldn't match result with requested SID\n"));
544                        continue;
545                }
546
547                /* get type */
548                if (!ads_pull_uint32(ads, entry, "sAMAccountType", &atype)) {
549                        DEBUG(1, ("could not get SAM account type\n"));
550                        continue;
551                }
552
553                switch (atype & 0xF0000000) {
554                case ATYPE_SECURITY_GLOBAL_GROUP:
555                case ATYPE_SECURITY_LOCAL_GROUP:
556                        type = ID_TYPE_GID;
557                        break;
558                case ATYPE_NORMAL_ACCOUNT:
559                case ATYPE_WORKSTATION_TRUST:
560                case ATYPE_INTERDOMAIN_TRUST:
561                        type = ID_TYPE_UID;
562                        break;
563                default:
564                        DEBUG(1, ("unrecognized SAM account type %08x\n", atype));
565                        continue;
566                }
567
568                if (!ads_pull_uint32(ads, entry, (type==ID_TYPE_UID) ? 
569                                                 ad_schema->posix_uidnumber_attr : 
570                                                 ad_schema->posix_gidnumber_attr, 
571                                     &id)) 
572                {
573                        DEBUG(1, ("Could not get unix ID\n"));
574                        continue;
575                }
576                if ((id == 0) ||
577                    (ctx->filter_low_id && (id < ctx->filter_low_id)) ||
578                    (ctx->filter_high_id && (id > ctx->filter_high_id))) {
579                        DEBUG(5, ("Requested id (%u) out of range (%u - %u). Filtered!\n",
580                                id, ctx->filter_low_id, ctx->filter_high_id));
581                        continue;
582                }
583
584                /* mapped */
585                map->xid.type = type;
586                map->xid.id = id;
587                map->status = ID_MAPPED;
588
589                DEBUG(10, ("Mapped %s -> %lu (%d)\n",
590                           sid_string_static(map->sid),
591                           (unsigned long)map->xid.id,
592                           map->xid.type));
593        }
594
595        if (res) {
596                ads_msgfree(ads, res);
597        }
598
599        if (ids[idx]) { /* still some values to map */
600                goto again;
601        }
602
603        ret = NT_STATUS_OK;
604
605        /* mark all unknwon ones as unmapped */
606        for (i = 0; ids[i]; i++) {
607                if (ids[i]->status == ID_UNKNOWN) 
608                        ids[i]->status = ID_UNMAPPED;
609        }
610
611done:
612        talloc_free(memctx);
613        return ret;
614}
615
616/************************************************************************
617 ***********************************************************************/
618
619static NTSTATUS idmap_ad_close(struct idmap_domain *dom)
620{
621        ADS_STRUCT *ads = ad_idmap_ads;
622
623        if (ads != NULL) {
624                /* we own this ADS_STRUCT so make sure it goes away */
625                ads->is_mine = True;
626                ads_destroy( &ads );
627                ad_idmap_ads = NULL;
628        }
629
630        TALLOC_FREE( ad_schema );
631       
632        return NT_STATUS_OK;
633}
634
635/*
636 * nss_info_{sfu,rfc2307}
637 */
638
639/************************************************************************
640 Initialize the {sfu,rfc2307} state
641 ***********************************************************************/
642
643static NTSTATUS nss_sfu_init( struct nss_domain_entry *e )
644{
645        /* Sanity check if we have previously been called with a
646           different schema model */
647
648        if ( (ad_map_type != WB_POSIX_MAP_UNKNOWN) &&
649             (ad_map_type != WB_POSIX_MAP_SFU) ) 
650        {
651                DEBUG(0,("nss_sfu_init: Posix Map type has already been set.  "
652                         "Mixed schema models not supported!\n"));
653                return NT_STATUS_NOT_SUPPORTED;
654        }
655       
656        ad_map_type =  WB_POSIX_MAP_SFU;       
657
658        if ( !ad_idmap_ads ) 
659                return idmap_ad_initialize( NULL, NULL );       
660
661        return NT_STATUS_OK;
662}
663
664static NTSTATUS nss_rfc2307_init( struct nss_domain_entry *e )
665{
666        /* Sanity check if we have previously been called with a
667           different schema model */
668         
669        if ( (ad_map_type != WB_POSIX_MAP_UNKNOWN) &&
670             (ad_map_type != WB_POSIX_MAP_RFC2307) ) 
671        {
672                DEBUG(0,("nss_rfc2307_init: Posix Map type has already been set.  "
673                         "Mixed schema models not supported!\n"));
674                return NT_STATUS_NOT_SUPPORTED;
675        }
676       
677        ad_map_type =  WB_POSIX_MAP_RFC2307;
678
679        if ( !ad_idmap_ads ) 
680                return idmap_ad_initialize( NULL, NULL );       
681
682        return NT_STATUS_OK;
683}
684
685
686/************************************************************************
687 ***********************************************************************/
688static NTSTATUS nss_ad_get_info( struct nss_domain_entry *e, 
689                                  const DOM_SID *sid, 
690                                  TALLOC_CTX *ctx,
691                                  ADS_STRUCT *ads, 
692                                  LDAPMessage *msg,
693                                  char **homedir,
694                                  char **shell, 
695                                  char **gecos,
696                                  uint32 *gid )
697{
698        ADS_STRUCT *ads_internal = NULL;
699
700        /* We are assuming that the internal ADS_STRUCT is for the
701           same forest as the incoming *ads pointer */
702
703        ads_internal = ad_idmap_cached_connection();
704
705        if ( !ads_internal || !ad_schema )
706                return NT_STATUS_OBJECT_NAME_NOT_FOUND;
707       
708        if ( !homedir || !shell || !gecos )
709                return NT_STATUS_INVALID_PARAMETER;
710
711        *homedir = ads_pull_string( ads, ctx, msg, ad_schema->posix_homedir_attr );
712        *shell   = ads_pull_string( ads, ctx, msg, ad_schema->posix_shell_attr );
713        *gecos   = ads_pull_string( ads, ctx, msg, ad_schema->posix_gecos_attr );
714       
715        if ( gid ) {           
716                if ( !ads_pull_uint32(ads, msg, ad_schema->posix_gidnumber_attr, gid ) )
717                        *gid = 0;               
718        }
719               
720        return NT_STATUS_OK;
721}
722
723/************************************************************************
724 ***********************************************************************/
725
726static NTSTATUS nss_ad_close( void )
727{
728        /* nothing to do.  All memory is free()'d by the idmap close_fn() */
729
730        return NT_STATUS_OK;
731}
732
733/************************************************************************
734 Function dispatch tables for the idmap and nss plugins
735 ***********************************************************************/
736
737static struct idmap_methods ad_methods = {
738        .init            = idmap_ad_initialize,
739        .unixids_to_sids = idmap_ad_unixids_to_sids,
740        .sids_to_unixids = idmap_ad_sids_to_unixids,
741        .close_fn        = idmap_ad_close
742};
743
744/* The SFU and RFC2307 NSS plugins share everything but the init
745   function which sets the intended schema model to use */
746 
747static struct nss_info_methods nss_rfc2307_methods = {
748        .init         = nss_rfc2307_init,
749        .get_nss_info = nss_ad_get_info,
750        .close_fn     = nss_ad_close
751};
752
753static struct nss_info_methods nss_sfu_methods = {
754        .init         = nss_sfu_init,
755        .get_nss_info = nss_ad_get_info,
756        .close_fn     = nss_ad_close
757};
758
759
760/************************************************************************
761 Initialize the plugins
762 ***********************************************************************/
763
764NTSTATUS idmap_ad_init(void)
765{
766        static NTSTATUS status_idmap_ad = NT_STATUS_UNSUCCESSFUL;
767        static NTSTATUS status_nss_rfc2307 = NT_STATUS_UNSUCCESSFUL;
768        static NTSTATUS status_nss_sfu = NT_STATUS_UNSUCCESSFUL;
769
770        /* Always register the AD method first in order to get the
771           idmap_domain interface called */
772
773        if ( !NT_STATUS_IS_OK(status_idmap_ad) ) {
774                status_idmap_ad = smb_register_idmap(SMB_IDMAP_INTERFACE_VERSION, 
775                                                     "ad", &ad_methods);
776                if ( !NT_STATUS_IS_OK(status_idmap_ad) )
777                        return status_idmap_ad;         
778        }
779       
780        if ( !NT_STATUS_IS_OK( status_nss_rfc2307 ) ) {
781                status_nss_rfc2307 = smb_register_idmap_nss(SMB_NSS_INFO_INTERFACE_VERSION,
782                                                            "rfc2307",  &nss_rfc2307_methods );         
783                if ( !NT_STATUS_IS_OK(status_nss_rfc2307) )
784                        return status_nss_rfc2307;
785        }
786
787        if ( !NT_STATUS_IS_OK( status_nss_sfu ) ) {
788                status_nss_sfu = smb_register_idmap_nss(SMB_NSS_INFO_INTERFACE_VERSION,
789                                                        "sfu",  &nss_sfu_methods );             
790                if ( !NT_STATUS_IS_OK(status_nss_sfu) )
791                        return status_nss_sfu;         
792        }
793
794        return NT_STATUS_OK;   
795}
796
Note: See TracBrowser for help on using the repository browser.