nsswitch/idmap_ad.c

説明を見る。
00001 /*
00002  *  idmap_ad: map between Active Directory and RFC 2307 or "Services for Unix" (SFU) Accounts
00003  *
00004  * Unix SMB/CIFS implementation.
00005  *
00006  * Winbind ADS backend functions
00007  *
00008  * Copyright (C) Andrew Tridgell 2001
00009  * Copyright (C) Andrew Bartlett <abartlet@samba.org> 2003
00010  * Copyright (C) Gerald (Jerry) Carter 2004-2007
00011  * Copyright (C) Luke Howard 2001-2004
00012  *
00013  * This program is free software; you can redistribute it and/or modify
00014  * it under the terms of the GNU General Public License as published by
00015  * the Free Software Foundation; either version 2 of the License, or
00016  * (at your option) any later version.
00017  *
00018  * This program is distributed in the hope that it will be useful,
00019  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00020  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00021  * GNU General Public License for more details.
00022  *
00023  * You should have received a copy of the GNU General Public License
00024  * along with this program; if not, write to the Free Software
00025  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00026  */
00027 
00028 #include "includes.h"
00029 
00030 #undef DBGC_CLASS
00031 #define DBGC_CLASS DBGC_IDMAP
00032 
00033 #define WINBIND_CCACHE_NAME "MEMORY:winbind_ccache"
00034 
00035 #define IDMAP_AD_MAX_IDS 30
00036 #define CHECK_ALLOC_DONE(mem) do { \
00037      if (!mem) { \
00038            DEBUG(0, ("Out of memory!\n")); \
00039            ret = NT_STATUS_NO_MEMORY; \
00040            goto done; \
00041       } \
00042 } while (0)
00043 
00044 struct idmap_ad_context {
00045         uint32_t filter_low_id;
00046         uint32_t filter_high_id;
00047 };
00048 
00049 NTSTATUS init_module(void);
00050 
00051 static ADS_STRUCT *ad_idmap_ads = NULL;
00052 static struct posix_schema *ad_schema = NULL;
00053 static enum wb_posix_mapping ad_map_type = WB_POSIX_MAP_UNKNOWN;
00054 
00055 /************************************************************************
00056  ***********************************************************************/
00057 
00058 static ADS_STRUCT *ad_idmap_cached_connection_internal(void)
00059 {
00060         ADS_STRUCT *ads;
00061         ADS_STATUS status;
00062         BOOL local = False;
00063         fstring dc_name;
00064         struct in_addr dc_ip;   
00065 
00066         if (ad_idmap_ads != NULL) {
00067 
00068                 time_t expire;
00069                 time_t now = time(NULL);
00070 
00071                 ads = ad_idmap_ads;
00072 
00073                 expire = MIN(ads->auth.tgt_expire, ads->auth.tgs_expire);
00074 
00075                 /* check for a valid structure */
00076                 DEBUG(7, ("Current tickets expire in %d seconds (at %d, time is now %d)\n",
00077                           (uint32)expire-(uint32)now, (uint32) expire, (uint32) now));
00078 
00079                 if ( ads->config.realm && (expire > time(NULL))) {
00080                         return ads;
00081                 } else {
00082                         /* we own this ADS_STRUCT so make sure it goes away */
00083                         DEBUG(7,("Deleting expired krb5 credential cache\n"));
00084                         ads->is_mine = True;
00085                         ads_destroy( &ads );
00086                         ads_kdestroy(WINBIND_CCACHE_NAME);
00087                         ad_idmap_ads = NULL;
00088                         TALLOC_FREE( ad_schema );                       
00089                 }
00090         }
00091 
00092         if (!local) {
00093                 /* we don't want this to affect the users ccache */
00094                 setenv("KRB5CCNAME", WINBIND_CCACHE_NAME, 1);
00095         }
00096 
00097         if ( (ads = ads_init(lp_realm(), lp_workgroup(), NULL)) == NULL ) {
00098                 DEBUG(1,("ads_init failed\n"));
00099                 return NULL;
00100         }
00101 
00102         /* the machine acct password might have change - fetch it every time */
00103         SAFE_FREE(ads->auth.password);
00104         ads->auth.password = secrets_fetch_machine_password(lp_workgroup(), NULL, NULL);
00105 
00106         SAFE_FREE(ads->auth.realm);
00107         ads->auth.realm = SMB_STRDUP(lp_realm());
00108 
00109         /* setup server affinity */
00110 
00111         get_dc_name( NULL, ads->auth.realm, dc_name, &dc_ip );
00112         
00113         status = ads_connect(ads);
00114         if (!ADS_ERR_OK(status)) {
00115                 DEBUG(1, ("ad_idmap_init: failed to connect to AD\n"));
00116                 ads_destroy(&ads);
00117                 return NULL;
00118         }
00119 
00120         ads->is_mine = False;
00121 
00122         ad_idmap_ads = ads;
00123 
00124         return ads;
00125 }
00126 
00127 /************************************************************************
00128  ***********************************************************************/
00129 
00130 static ADS_STRUCT *ad_idmap_cached_connection(void)
00131 {
00132         ADS_STRUCT *ads = ad_idmap_cached_connection_internal();
00133         
00134         if ( !ads )
00135                 return NULL;
00136 
00137         /* if we have a valid ADS_STRUCT and the schema model is
00138            defined, then we can return here. */
00139 
00140         if ( ad_schema )
00141                 return ads;
00142 
00143         /* Otherwise, set the schema model */
00144 
00145         if ( (ad_map_type ==  WB_POSIX_MAP_SFU) ||
00146              (ad_map_type ==  WB_POSIX_MAP_RFC2307) ) 
00147         {
00148                 ADS_STATUS schema_status;
00149                 
00150                 schema_status = ads_check_posix_schema_mapping( NULL, ads, ad_map_type, &ad_schema);
00151                 if ( !ADS_ERR_OK(schema_status) ) {
00152                         DEBUG(2,("ad_idmap_cached_connection: Failed to obtain schema details!\n"));
00153                         return NULL;                    
00154                 }
00155         }
00156         
00157         return ads;
00158 }
00159 
00160 /************************************************************************
00161  ***********************************************************************/
00162 
00163 static NTSTATUS idmap_ad_initialize(struct idmap_domain *dom)
00164 {
00165         struct idmap_ad_context *ctx;
00166         char *config_option;
00167         const char *range = NULL;
00168         const char *schema_mode = NULL; 
00169 
00170         if ( (ctx = TALLOC_ZERO_P(dom, struct idmap_ad_context)) == NULL ) {
00171                 DEBUG(0, ("Out of memory!\n"));
00172                 return NT_STATUS_NO_MEMORY;
00173         }
00174 
00175         if ( (config_option = talloc_asprintf(ctx, "idmap config %s", dom->name)) == NULL ) {
00176                 DEBUG(0, ("Out of memory!\n"));
00177                 talloc_free(ctx);
00178                 return NT_STATUS_NO_MEMORY;
00179         }
00180 
00181         /* load ranges */
00182         range = lp_parm_const_string(-1, config_option, "range", NULL);
00183         if (range && range[0]) {
00184                 if ((sscanf(range, "%u - %u", &ctx->filter_low_id, &ctx->filter_high_id) != 2) ||
00185                     (ctx->filter_low_id > ctx->filter_high_id)) {
00186                         DEBUG(1, ("ERROR: invalid filter range [%s]", range));
00187                         ctx->filter_low_id = 0;
00188                         ctx->filter_high_id = 0;
00189                 }
00190         }
00191 
00192         /* schema mode */
00193         if ( ad_map_type == WB_POSIX_MAP_UNKNOWN )
00194                 ad_map_type = WB_POSIX_MAP_RFC2307;
00195         schema_mode = lp_parm_const_string(-1, config_option, "schema_mode", NULL);
00196         if ( schema_mode && schema_mode[0] ) {
00197                 if ( strequal(schema_mode, "sfu") )
00198                         ad_map_type = WB_POSIX_MAP_SFU;
00199                 else if ( strequal(schema_mode, "rfc2307" ) )
00200                         ad_map_type = WB_POSIX_MAP_RFC2307;
00201                 else
00202                         DEBUG(0,("idmap_ad_initialize: Unknown schema_mode (%s)\n",
00203                                  schema_mode));
00204         }
00205 
00206         dom->private_data = ctx;
00207         dom->initialized = True;
00208 
00209         talloc_free(config_option);
00210 
00211         return NT_STATUS_OK;
00212 }
00213 
00214 /************************************************************************
00215  Search up to IDMAP_AD_MAX_IDS entries in maps for a match.
00216  ***********************************************************************/
00217 
00218 static struct id_map *find_map_by_id(struct id_map **maps, enum id_type type, uint32_t id)
00219 {
00220         int i;
00221 
00222         for (i = 0; maps[i] && i<IDMAP_AD_MAX_IDS; i++) {
00223                 if ((maps[i]->xid.type == type) && (maps[i]->xid.id == id)) {
00224                         return maps[i];
00225                 }
00226         }
00227 
00228         return NULL;    
00229 }
00230 
00231 /************************************************************************
00232  Search up to IDMAP_AD_MAX_IDS entries in maps for a match
00233  ***********************************************************************/
00234 
00235 static struct id_map *find_map_by_sid(struct id_map **maps, DOM_SID *sid)
00236 {
00237         int i;
00238 
00239         for (i = 0; maps[i] && i<IDMAP_AD_MAX_IDS; i++) {
00240                 if (sid_equal(maps[i]->sid, sid)) {
00241                         return maps[i];
00242                 }
00243         }
00244 
00245         return NULL;    
00246 }
00247 
00248 /************************************************************************
00249  ***********************************************************************/
00250 
00251 static NTSTATUS idmap_ad_unixids_to_sids(struct idmap_domain *dom, struct id_map **ids)
00252 {
00253         NTSTATUS ret;
00254         TALLOC_CTX *memctx;
00255         struct idmap_ad_context *ctx;
00256         ADS_STATUS rc;
00257         ADS_STRUCT *ads;
00258         const char *attrs[] = { "sAMAccountType", 
00259                                 "objectSid",
00260                                 NULL, /* uidnumber */
00261                                 NULL, /* gidnumber */
00262                                 NULL };
00263         LDAPMessage *res = NULL;
00264         LDAPMessage *entry = NULL;
00265         char *filter = NULL;
00266         int idx = 0;
00267         int bidx = 0;
00268         int count;
00269         int i;
00270         char *u_filter = NULL;
00271         char *g_filter = NULL;
00272 
00273         /* Only do query if we are online */
00274         if (idmap_is_offline()) {
00275                 return NT_STATUS_FILE_IS_OFFLINE;
00276         }
00277 
00278         /* Initilization my have been deferred because we were offline */
00279         if ( ! dom->initialized) {
00280                 ret = idmap_ad_initialize(dom);
00281                 if ( ! NT_STATUS_IS_OK(ret)) {
00282                         return ret;
00283                 }
00284         }
00285 
00286         ctx = talloc_get_type(dom->private_data, struct idmap_ad_context);
00287 
00288         if ( (memctx = talloc_new(ctx)) == NULL ) {
00289                 DEBUG(0, ("Out of memory!\n"));
00290                 return NT_STATUS_NO_MEMORY;
00291         }
00292 
00293         if ( (ads = ad_idmap_cached_connection()) == NULL ) {
00294                 DEBUG(1, ("ADS uninitialized\n"));
00295                 ret = NT_STATUS_UNSUCCESSFUL;
00296                 goto done;
00297         }
00298 
00299         attrs[2] = ad_schema->posix_uidnumber_attr;
00300         attrs[3] = ad_schema->posix_gidnumber_attr;
00301 
00302 again:
00303         bidx = idx;
00304         for (i = 0; (i < IDMAP_AD_MAX_IDS) && ids[idx]; i++, idx++) {
00305                 switch (ids[idx]->xid.type) {
00306                 case ID_TYPE_UID:     
00307                         if ( ! u_filter) {
00308                                 u_filter = talloc_asprintf(memctx, "(&(|"
00309                                                            "(sAMAccountType=%d)"
00310                                                            "(sAMAccountType=%d)"
00311                                                            "(sAMAccountType=%d))(|",
00312                                                            ATYPE_NORMAL_ACCOUNT,
00313                                                            ATYPE_WORKSTATION_TRUST,
00314                                                            ATYPE_INTERDOMAIN_TRUST);
00315                         }
00316                         u_filter = talloc_asprintf_append(u_filter, "(%s=%lu)",
00317                                                           ad_schema->posix_uidnumber_attr,
00318                                                           (unsigned long)ids[idx]->xid.id);
00319                         CHECK_ALLOC_DONE(u_filter);
00320                         break;
00321                                 
00322                 case ID_TYPE_GID:
00323                         if ( ! g_filter) {
00324                                 g_filter = talloc_asprintf(memctx, "(&(|"
00325                                                            "(sAMAccountType=%d)"
00326                                                            "(sAMAccountType=%d))(|",
00327                                                            ATYPE_SECURITY_GLOBAL_GROUP,
00328                                                            ATYPE_SECURITY_LOCAL_GROUP);
00329                         }
00330                         g_filter = talloc_asprintf_append(g_filter, "(%s=%lu)",
00331                                                           ad_schema->posix_gidnumber_attr,
00332                                                           (unsigned long)ids[idx]->xid.id);
00333                         CHECK_ALLOC_DONE(g_filter);
00334                         break;
00335 
00336                 default:
00337                         DEBUG(3, ("Error: mapping requested but Unknown ID type\n"));
00338                         ids[idx]->status = ID_UNKNOWN;
00339                         continue;
00340                 }
00341         }
00342         filter = talloc_asprintf(memctx, "(|");
00343         CHECK_ALLOC_DONE(filter);
00344         if ( u_filter) {
00345                 filter = talloc_asprintf_append(filter, "%s))", u_filter);
00346                 CHECK_ALLOC_DONE(filter);
00347                         TALLOC_FREE(u_filter);
00348         }
00349         if ( g_filter) {
00350                 filter = talloc_asprintf_append(filter, "%s))", g_filter);
00351                 CHECK_ALLOC_DONE(filter);
00352                 TALLOC_FREE(g_filter);
00353         }
00354         filter = talloc_asprintf_append(filter, ")");
00355         CHECK_ALLOC_DONE(filter);
00356 
00357         rc = ads_search_retry(ads, &res, filter, attrs);
00358         if (!ADS_ERR_OK(rc)) {
00359                 DEBUG(1, ("ERROR: ads search returned: %s\n", ads_errstr(rc)));
00360                 ret = NT_STATUS_UNSUCCESSFUL;
00361                 goto done;
00362         }
00363 
00364         if ( (count = ads_count_replies(ads, res)) == 0 ) {
00365                 DEBUG(10, ("No IDs found\n"));
00366         }
00367 
00368         entry = res;
00369         for (i = 0; (i < count) && entry; i++) {
00370                 DOM_SID sid;
00371                 enum id_type type;
00372                 struct id_map *map;
00373                 uint32_t id;
00374                 uint32_t atype;
00375 
00376                 if (i == 0) { /* first entry */
00377                         entry = ads_first_entry(ads, entry);
00378                 } else { /* following ones */
00379                         entry = ads_next_entry(ads, entry);
00380                 }
00381 
00382                 if ( !entry ) {
00383                         DEBUG(2, ("ERROR: Unable to fetch ldap entries from results\n"));
00384                         break;
00385                 }
00386 
00387                 /* first check if the SID is present */
00388                 if (!ads_pull_sid(ads, entry, "objectSid", &sid)) {
00389                         DEBUG(2, ("Could not retrieve SID from entry\n"));
00390                         continue;
00391                 }
00392 
00393                 /* get type */
00394                 if (!ads_pull_uint32(ads, entry, "sAMAccountType", &atype)) {
00395                         DEBUG(1, ("could not get SAM account type\n"));
00396                         continue;
00397                 }
00398 
00399                 switch (atype & 0xF0000000) {
00400                 case ATYPE_SECURITY_GLOBAL_GROUP:
00401                 case ATYPE_SECURITY_LOCAL_GROUP:
00402                         type = ID_TYPE_GID;
00403                         break;
00404                 case ATYPE_NORMAL_ACCOUNT:
00405                 case ATYPE_WORKSTATION_TRUST:
00406                 case ATYPE_INTERDOMAIN_TRUST:
00407                         type = ID_TYPE_UID;
00408                         break;
00409                 default:
00410                         DEBUG(1, ("unrecognized SAM account type %08x\n", atype));
00411                         continue;
00412                 }
00413 
00414                 if (!ads_pull_uint32(ads, entry, (type==ID_TYPE_UID) ? 
00415                                                  ad_schema->posix_uidnumber_attr : 
00416                                                  ad_schema->posix_gidnumber_attr, 
00417                                      &id)) 
00418                 {
00419                         DEBUG(1, ("Could not get unix ID\n"));
00420                         continue;
00421                 }
00422 
00423                 if ((id == 0) ||
00424                     (ctx->filter_low_id && (id < ctx->filter_low_id)) ||
00425                     (ctx->filter_high_id && (id > ctx->filter_high_id))) {
00426                         DEBUG(5, ("Requested id (%u) out of range (%u - %u). Filtered!\n",
00427                                 id, ctx->filter_low_id, ctx->filter_high_id));
00428                         continue;
00429                 }
00430 
00431                 map = find_map_by_id(&ids[bidx], type, id);
00432                 if (!map) {
00433                         DEBUG(2, ("WARNING: couldn't match result with requested ID\n"));
00434                         continue;
00435                 }
00436 
00437                 sid_copy(map->sid, &sid);
00438 
00439                 /* mapped */
00440                 map->status = ID_MAPPED;
00441 
00442                 DEBUG(10, ("Mapped %s -> %lu (%d)\n",
00443                            sid_string_static(map->sid),
00444                            (unsigned long)map->xid.id,
00445                            map->xid.type));
00446         }
00447 
00448         if (res) {
00449                 ads_msgfree(ads, res);
00450         }
00451 
00452         if (ids[idx]) { /* still some values to map */
00453                 goto again;
00454         }
00455 
00456         ret = NT_STATUS_OK;
00457 
00458         /* mark all unknown/expired ones as unmapped */
00459         for (i = 0; ids[i]; i++) {
00460                 if (ids[i]->status != ID_MAPPED) 
00461                         ids[i]->status = ID_UNMAPPED;
00462         }
00463 
00464 done:
00465         talloc_free(memctx);
00466         return ret;
00467 }
00468 
00469 /************************************************************************
00470  ***********************************************************************/
00471 
00472 static NTSTATUS idmap_ad_sids_to_unixids(struct idmap_domain *dom, struct id_map **ids)
00473 {
00474         NTSTATUS ret;
00475         TALLOC_CTX *memctx;
00476         struct idmap_ad_context *ctx;
00477         ADS_STATUS rc;
00478         ADS_STRUCT *ads;
00479         const char *attrs[] = { "sAMAccountType", 
00480                                 "objectSid",
00481                                 NULL, /* attr_uidnumber */
00482                                 NULL, /* attr_gidnumber */
00483                                 NULL };
00484         LDAPMessage *res = NULL;
00485         LDAPMessage *entry = NULL;
00486         char *filter = NULL;
00487         int idx = 0;
00488         int bidx = 0;
00489         int count;
00490         int i;
00491         char *sidstr;
00492 
00493         /* Only do query if we are online */
00494         if (idmap_is_offline()) {
00495                 return NT_STATUS_FILE_IS_OFFLINE;
00496         }
00497 
00498         /* Initilization my have been deferred because we were offline */
00499         if ( ! dom->initialized) {
00500                 ret = idmap_ad_initialize(dom);
00501                 if ( ! NT_STATUS_IS_OK(ret)) {
00502                         return ret;
00503                 }
00504         }
00505 
00506         ctx = talloc_get_type(dom->private_data, struct idmap_ad_context);      
00507 
00508         if ( (memctx = talloc_new(ctx)) == NULL ) {             
00509                 DEBUG(0, ("Out of memory!\n"));
00510                 return NT_STATUS_NO_MEMORY;
00511         }
00512 
00513         if ( (ads = ad_idmap_cached_connection()) == NULL ) {
00514                 DEBUG(1, ("ADS uninitialized\n"));
00515                 ret = NT_STATUS_UNSUCCESSFUL;
00516                 goto done;
00517         }
00518 
00519         attrs[2] = ad_schema->posix_uidnumber_attr;
00520         attrs[3] = ad_schema->posix_gidnumber_attr;
00521 
00522 again:
00523         filter = talloc_asprintf(memctx, "(&(|"
00524                                  "(sAMAccountType=%d)(sAMAccountType=%d)(sAMAccountType=%d)" /* user account types */
00525                                  "(sAMAccountType=%d)(sAMAccountType=%d)" /* group account types */
00526                                  ")(|",
00527                                  ATYPE_NORMAL_ACCOUNT, ATYPE_WORKSTATION_TRUST, ATYPE_INTERDOMAIN_TRUST,
00528                                  ATYPE_SECURITY_GLOBAL_GROUP, ATYPE_SECURITY_LOCAL_GROUP);
00529                 
00530         CHECK_ALLOC_DONE(filter);
00531 
00532         bidx = idx;
00533         for (i = 0; (i < IDMAP_AD_MAX_IDS) && ids[idx]; i++, idx++) {
00534 
00535                 sidstr = sid_binstring(ids[idx]->sid);
00536                 filter = talloc_asprintf_append(filter, "(objectSid=%s)", sidstr);
00537                         
00538                 free(sidstr);
00539                 CHECK_ALLOC_DONE(filter);
00540         }
00541         filter = talloc_asprintf_append(filter, "))");
00542         CHECK_ALLOC_DONE(filter);
00543         DEBUG(10, ("Filter: [%s]\n", filter));
00544 
00545         rc = ads_search_retry(ads, &res, filter, attrs);
00546         if (!ADS_ERR_OK(rc)) {
00547                 DEBUG(1, ("ERROR: ads search returned: %s\n", ads_errstr(rc)));
00548                 ret = NT_STATUS_UNSUCCESSFUL;
00549                 goto done;
00550         }
00551 
00552         if ( (count = ads_count_replies(ads, res)) == 0 ) {
00553                 DEBUG(10, ("No IDs found\n"));
00554         }
00555 
00556         entry = res;    
00557         for (i = 0; (i < count) && entry; i++) {
00558                 DOM_SID sid;
00559                 enum id_type type;
00560                 struct id_map *map;
00561                 uint32_t id;
00562                 uint32_t atype;
00563 
00564                 if (i == 0) { /* first entry */
00565                         entry = ads_first_entry(ads, entry);
00566                 } else { /* following ones */
00567                         entry = ads_next_entry(ads, entry);
00568                 }
00569 
00570                 if ( !entry ) {
00571                         DEBUG(2, ("ERROR: Unable to fetch ldap entries from results\n"));
00572                         break;
00573                 }
00574 
00575                 /* first check if the SID is present */
00576                 if (!ads_pull_sid(ads, entry, "objectSid", &sid)) {
00577                         DEBUG(2, ("Could not retrieve SID from entry\n"));
00578                         continue;
00579                 }
00580 
00581                 map = find_map_by_sid(&ids[bidx], &sid);
00582                 if (!map) {
00583                         DEBUG(2, ("WARNING: couldn't match result with requested SID\n"));
00584                         continue;
00585                 }
00586 
00587                 /* get type */
00588                 if (!ads_pull_uint32(ads, entry, "sAMAccountType", &atype)) {
00589                         DEBUG(1, ("could not get SAM account type\n"));
00590                         continue;
00591                 }
00592 
00593                 switch (atype & 0xF0000000) {
00594                 case ATYPE_SECURITY_GLOBAL_GROUP:
00595                 case ATYPE_SECURITY_LOCAL_GROUP:
00596                         type = ID_TYPE_GID;
00597                         break;
00598                 case ATYPE_NORMAL_ACCOUNT:
00599                 case ATYPE_WORKSTATION_TRUST:
00600                 case ATYPE_INTERDOMAIN_TRUST:
00601                         type = ID_TYPE_UID;
00602                         break;
00603                 default:
00604                         DEBUG(1, ("unrecognized SAM account type %08x\n", atype));
00605                         continue;
00606                 }
00607 
00608                 if (!ads_pull_uint32(ads, entry, (type==ID_TYPE_UID) ? 
00609                                                  ad_schema->posix_uidnumber_attr : 
00610                                                  ad_schema->posix_gidnumber_attr, 
00611                                      &id)) 
00612                 {
00613                         DEBUG(1, ("Could not get unix ID\n"));
00614                         continue;
00615                 }
00616                 if ((id == 0) ||
00617                     (ctx->filter_low_id && (id < ctx->filter_low_id)) ||
00618                     (ctx->filter_high_id && (id > ctx->filter_high_id))) {
00619                         DEBUG(5, ("Requested id (%u) out of range (%u - %u). Filtered!\n",
00620                                 id, ctx->filter_low_id, ctx->filter_high_id));
00621                         continue;
00622                 }
00623 
00624                 /* mapped */
00625                 map->xid.type = type;
00626                 map->xid.id = id;
00627                 map->status = ID_MAPPED;
00628 
00629                 DEBUG(10, ("Mapped %s -> %lu (%d)\n",
00630                            sid_string_static(map->sid),
00631                            (unsigned long)map->xid.id,
00632                            map->xid.type));
00633         }
00634 
00635         if (res) {
00636                 ads_msgfree(ads, res);
00637         }
00638 
00639         if (ids[idx]) { /* still some values to map */
00640                 goto again;
00641         }
00642 
00643         ret = NT_STATUS_OK;
00644 
00645         /* mark all unknwoni/expired ones as unmapped */
00646         for (i = 0; ids[i]; i++) {
00647                 if (ids[i]->status != ID_MAPPED) 
00648                         ids[i]->status = ID_UNMAPPED;
00649         }
00650 
00651 done:
00652         talloc_free(memctx);
00653         return ret;
00654 }
00655 
00656 /************************************************************************
00657  ***********************************************************************/
00658 
00659 static NTSTATUS idmap_ad_close(struct idmap_domain *dom)
00660 {
00661         ADS_STRUCT *ads = ad_idmap_ads;
00662 
00663         if (ads != NULL) {
00664                 /* we own this ADS_STRUCT so make sure it goes away */
00665                 ads->is_mine = True;
00666                 ads_destroy( &ads );
00667                 ad_idmap_ads = NULL;
00668         }
00669 
00670         TALLOC_FREE( ad_schema );
00671         
00672         return NT_STATUS_OK;
00673 }
00674 
00675 /*
00676  * nss_info_{sfu,rfc2307}
00677  */
00678 
00679 /************************************************************************
00680  Initialize the {sfu,rfc2307} state
00681  ***********************************************************************/
00682 
00683 static NTSTATUS nss_sfu_init( struct nss_domain_entry *e )
00684 {
00685         /* Sanity check if we have previously been called with a
00686            different schema model */
00687 
00688         if ( (ad_map_type != WB_POSIX_MAP_UNKNOWN) &&
00689              (ad_map_type != WB_POSIX_MAP_SFU) ) 
00690         {
00691                 DEBUG(0,("nss_sfu_init: Posix Map type has already been set.  "
00692                          "Mixed schema models not supported!\n"));
00693                 return NT_STATUS_NOT_SUPPORTED;
00694         }
00695         
00696         ad_map_type =  WB_POSIX_MAP_SFU;        
00697 
00698         return NT_STATUS_OK;
00699 }
00700 
00701 static NTSTATUS nss_rfc2307_init( struct nss_domain_entry *e )
00702 {
00703         /* Sanity check if we have previously been called with a
00704            different schema model */
00705          
00706         if ( (ad_map_type != WB_POSIX_MAP_UNKNOWN) &&
00707              (ad_map_type != WB_POSIX_MAP_RFC2307) ) 
00708         {
00709                 DEBUG(0,("nss_rfc2307_init: Posix Map type has already been set.  "
00710                          "Mixed schema models not supported!\n"));
00711                 return NT_STATUS_NOT_SUPPORTED;
00712         }
00713         
00714         ad_map_type =  WB_POSIX_MAP_RFC2307;
00715 
00716         return NT_STATUS_OK;
00717 }
00718 
00719 
00720 /************************************************************************
00721  ***********************************************************************/
00722 static NTSTATUS nss_ad_get_info( struct nss_domain_entry *e, 
00723                                   const DOM_SID *sid, 
00724                                   TALLOC_CTX *ctx,
00725                                   ADS_STRUCT *ads, 
00726                                   LDAPMessage *msg,
00727                                   char **homedir,
00728                                   char **shell, 
00729                                   char **gecos,
00730                                   uint32 *gid )
00731 {
00732         ADS_STRUCT *ads_internal = NULL;
00733 
00734         /* Only do query if we are online */
00735         if (idmap_is_offline()) {
00736                 return NT_STATUS_FILE_IS_OFFLINE;
00737         }
00738 
00739         /* We are assuming that the internal ADS_STRUCT is for the 
00740            same forest as the incoming *ads pointer */
00741 
00742         ads_internal = ad_idmap_cached_connection();
00743 
00744         if ( !ads_internal || !ad_schema )
00745                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
00746         
00747         if ( !homedir || !shell || !gecos )
00748                 return NT_STATUS_INVALID_PARAMETER;
00749 
00750         *homedir = ads_pull_string( ads, ctx, msg, ad_schema->posix_homedir_attr );
00751         *shell   = ads_pull_string( ads, ctx, msg, ad_schema->posix_shell_attr );
00752         *gecos   = ads_pull_string( ads, ctx, msg, ad_schema->posix_gecos_attr );
00753        
00754         if ( gid ) {            
00755                 if ( !ads_pull_uint32(ads, msg, ad_schema->posix_gidnumber_attr, gid ) )
00756                         *gid = (uint32)-1;
00757         }
00758                 
00759         return NT_STATUS_OK;
00760 }
00761 
00762 /************************************************************************
00763  ***********************************************************************/
00764 
00765 static NTSTATUS nss_ad_close( void )
00766 {
00767         /* nothing to do.  All memory is free()'d by the idmap close_fn() */
00768 
00769         return NT_STATUS_OK;
00770 }
00771 
00772 /************************************************************************
00773  Function dispatch tables for the idmap and nss plugins
00774  ***********************************************************************/
00775 
00776 static struct idmap_methods ad_methods = {
00777         .init            = idmap_ad_initialize,
00778         .unixids_to_sids = idmap_ad_unixids_to_sids,
00779         .sids_to_unixids = idmap_ad_sids_to_unixids,
00780         .close_fn        = idmap_ad_close
00781 };
00782 
00783 /* The SFU and RFC2307 NSS plugins share everything but the init
00784    function which sets the intended schema model to use */
00785   
00786 static struct nss_info_methods nss_rfc2307_methods = {
00787         .init         = nss_rfc2307_init,
00788         .get_nss_info = nss_ad_get_info,
00789         .close_fn     = nss_ad_close
00790 };
00791 
00792 static struct nss_info_methods nss_sfu_methods = {
00793         .init         = nss_sfu_init,
00794         .get_nss_info = nss_ad_get_info,
00795         .close_fn     = nss_ad_close
00796 };
00797 
00798 
00799 /************************************************************************
00800  Initialize the plugins
00801  ***********************************************************************/
00802 
00803 NTSTATUS idmap_ad_init(void)
00804 {
00805         static NTSTATUS status_idmap_ad = NT_STATUS_UNSUCCESSFUL;
00806         static NTSTATUS status_nss_rfc2307 = NT_STATUS_UNSUCCESSFUL;
00807         static NTSTATUS status_nss_sfu = NT_STATUS_UNSUCCESSFUL;
00808 
00809         /* Always register the AD method first in order to get the
00810            idmap_domain interface called */
00811 
00812         if ( !NT_STATUS_IS_OK(status_idmap_ad) ) {
00813                 status_idmap_ad = smb_register_idmap(SMB_IDMAP_INTERFACE_VERSION, 
00814                                                      "ad", &ad_methods);
00815                 if ( !NT_STATUS_IS_OK(status_idmap_ad) )
00816                         return status_idmap_ad;         
00817         }
00818         
00819         if ( !NT_STATUS_IS_OK( status_nss_rfc2307 ) ) {
00820                 status_nss_rfc2307 = smb_register_idmap_nss(SMB_NSS_INFO_INTERFACE_VERSION,
00821                                                             "rfc2307",  &nss_rfc2307_methods );         
00822                 if ( !NT_STATUS_IS_OK(status_nss_rfc2307) )
00823                         return status_nss_rfc2307;
00824         }
00825 
00826         if ( !NT_STATUS_IS_OK( status_nss_sfu ) ) {
00827                 status_nss_sfu = smb_register_idmap_nss(SMB_NSS_INFO_INTERFACE_VERSION,
00828                                                         "sfu",  &nss_sfu_methods );             
00829                 if ( !NT_STATUS_IS_OK(status_nss_sfu) )
00830                         return status_nss_sfu;          
00831         }
00832 
00833         return NT_STATUS_OK;    
00834 }
00835 

Sambaに対してSat Aug 29 21:23:08 2009に生成されました。  doxygen 1.4.7