Ignore:
Timestamp:
Nov 27, 2012, 4:43:17 PM (13 years ago)
Author:
Silvan Scherrer
Message:

Samba Server: updated trunk to 3.6.0

Location:
trunk/server
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/server

  • trunk/server/source3/winbindd/idmap_ldap.c

    r414 r745  
    88   Copyright (C) Gerald Carter          2003
    99   Copyright (C) Simo Sorce             2003-2007
     10   Copyright (C) Michael Adam           2010
    1011
    1112   This program is free software; you can redistribute it and/or modify
     
    2526#include "includes.h"
    2627#include "winbindd.h"
     28#include "secrets.h"
     29#include "idmap.h"
     30#include "idmap_rw.h"
     31#include "../libcli/security/security.h"
    2732
    2833#undef DBGC_CLASS
     
    3439#include "smbldap.h"
    3540
    36 static char *idmap_fetch_secret(const char *backend, bool alloc,
     41static char *idmap_fetch_secret(const char *backend,
    3742                                const char *domain, const char *identity)
    3843{
     
    4045        int r;
    4146
    42         if (alloc) {
    43                 r = asprintf(&tmp, "IDMAP_ALLOC_%s", backend);
    44         } else {
    45                 r = asprintf(&tmp, "IDMAP_%s_%s", backend, domain);
    46         }
     47        r = asprintf(&tmp, "IDMAP_%s_%s", backend, domain);
    4748
    4849        if (r < 0)
     
    6263        char *suffix;
    6364        char *user_dn;
    64         uint32_t filter_low_id, filter_high_id;         /* Filter range */
    6565        bool anon;
    66 };
    67 
    68 struct idmap_ldap_alloc_context {
    69         struct smbldap_state *smbldap_state;
    70         char *url;
    71         char *suffix;
    72         char *user_dn;
    73         uid_t low_uid, high_uid;      /* Range of uids */
    74         gid_t low_gid, high_gid;      /* Range of gids */
    75 
     66        struct idmap_rw_ops *rw_ops;
    7667};
    7768
     
    8778**********************************************************************/
    8879
    89 static struct idmap_ldap_alloc_context *idmap_alloc_ldap;
    90 
    9180/*********************************************************************
    9281 ********************************************************************/
     
    11099        if ( tmp ) {
    111100                if (!dom) {
    112                         /* only the alloc backend can pass in a NULL dom */
    113                         secret = idmap_fetch_secret("ldap", True,
    114                                                     NULL, tmp);
     101                        DEBUG(0, ("get_credentials: Invalid domain 'NULL' "
     102                                  "encountered for user DN %s\n",
     103                                  tmp));
     104                        ret = NT_STATUS_UNSUCCESSFUL;
     105                        goto done;
    115106                } else {
    116                         secret = idmap_fetch_secret("ldap", False,
    117                                                     dom->name, tmp);
     107                        secret = idmap_fetch_secret("ldap", dom->name, tmp);
    118108                }
    119109
     
    154144**********************************************************************/
    155145
    156 static NTSTATUS verify_idpool(void)
     146static NTSTATUS verify_idpool(struct idmap_domain *dom)
    157147{
    158148        NTSTATUS ret;
    159         TALLOC_CTX *ctx;
     149        TALLOC_CTX *mem_ctx;
    160150        LDAPMessage *result = NULL;
    161151        LDAPMod **mods = NULL;
     
    164154        int count;
    165155        int rc;
    166 
    167         if ( ! idmap_alloc_ldap) {
    168                 return NT_STATUS_UNSUCCESSFUL;
    169         }
    170 
    171         ctx = talloc_new(idmap_alloc_ldap);
    172         if ( ! ctx) {
     156        struct idmap_ldap_context *ctx;
     157
     158        ctx = talloc_get_type(dom->private_data, struct idmap_ldap_context);
     159
     160        mem_ctx = talloc_new(ctx);
     161        if (mem_ctx == NULL) {
    173162                DEBUG(0, ("Out of memory!\n"));
    174163                return NT_STATUS_NO_MEMORY;
    175164        }
    176165
    177         filter = talloc_asprintf(ctx, "(objectclass=%s)", LDAP_OBJ_IDPOOL);
     166        filter = talloc_asprintf(mem_ctx, "(objectclass=%s)", LDAP_OBJ_IDPOOL);
    178167        CHECK_ALLOC_DONE(filter);
    179168
    180         attr_list = get_attr_list(ctx, idpool_attr_list);
     169        attr_list = get_attr_list(mem_ctx, idpool_attr_list);
    181170        CHECK_ALLOC_DONE(attr_list);
    182171
    183         rc = smbldap_search(idmap_alloc_ldap->smbldap_state,
    184                                 idmap_alloc_ldap->suffix,
     172        rc = smbldap_search(ctx->smbldap_state,
     173                                ctx->suffix,
    185174                                LDAP_SCOPE_SUBTREE,
    186175                                filter,
     
    195184        }
    196185
    197         count = ldap_count_entries(idmap_alloc_ldap->smbldap_state->ldap_struct,
    198                                    result);
     186        count = ldap_count_entries(ctx->smbldap_state->ldap_struct, result);
    199187
    200188        ldap_msgfree(result);
     
    202190        if ( count > 1 ) {
    203191                DEBUG(0,("Multiple entries returned from %s (base == %s)\n",
    204                         filter, idmap_alloc_ldap->suffix));
     192                        filter, ctx->suffix));
    205193                ret = NT_STATUS_UNSUCCESSFUL;
    206194                goto done;
     
    209197                char *uid_str, *gid_str;
    210198
    211                 uid_str = talloc_asprintf(ctx, "%lu",
    212                                 (unsigned long)idmap_alloc_ldap->low_uid);
    213                 gid_str = talloc_asprintf(ctx, "%lu",
    214                                 (unsigned long)idmap_alloc_ldap->low_gid);
     199                uid_str = talloc_asprintf(mem_ctx, "%lu",
     200                                (unsigned long)dom->low_id);
     201                gid_str = talloc_asprintf(mem_ctx, "%lu",
     202                                (unsigned long)dom->low_id);
    215203
    216204                smbldap_set_mod(&mods, LDAP_MOD_ADD,
     
    225213                                gid_str);
    226214                if (mods) {
    227                         rc = smbldap_modify(idmap_alloc_ldap->smbldap_state,
    228                                                 idmap_alloc_ldap->suffix,
     215                        rc = smbldap_modify(ctx->smbldap_state,
     216                                                ctx->suffix,
    229217                                                mods);
    230218                        ldap_mods_free(mods, True);
     
    237225        ret = (rc == LDAP_SUCCESS)?NT_STATUS_OK:NT_STATUS_UNSUCCESSFUL;
    238226done:
    239         talloc_free(ctx);
    240         return ret;
    241 }
    242 
    243 /*****************************************************************************
    244  Initialise idmap database.
    245 *****************************************************************************/
    246 
    247 static NTSTATUS idmap_ldap_alloc_init(const char *params)
    248 {
    249         NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
    250         const char *tmp;
    251         uid_t low_uid = 0;
    252         uid_t high_uid = 0;
    253         gid_t low_gid = 0;
    254         gid_t high_gid = 0;
    255 
    256         /* Only do init if we are online */
    257         if (idmap_is_offline()) {
    258                 return NT_STATUS_FILE_IS_OFFLINE;
    259         }
    260 
    261         idmap_alloc_ldap = TALLOC_ZERO_P(NULL, struct idmap_ldap_alloc_context);
    262         CHECK_ALLOC_DONE( idmap_alloc_ldap );
    263 
    264         /* load ranges */
    265 
    266         if (!lp_idmap_uid(&low_uid, &high_uid)
    267             || !lp_idmap_gid(&low_gid, &high_gid)) {
    268                 DEBUG(1, ("idmap uid or idmap gid missing\n"));
    269                 ret = NT_STATUS_UNSUCCESSFUL;
    270                 goto done;
    271         }
    272 
    273         idmap_alloc_ldap->low_uid = low_uid;
    274         idmap_alloc_ldap->high_uid = high_uid;
    275         idmap_alloc_ldap->low_gid = low_gid;
    276         idmap_alloc_ldap->high_gid= high_gid;
    277 
    278         if (idmap_alloc_ldap->high_uid <= idmap_alloc_ldap->low_uid) {
    279                 DEBUG(1, ("idmap uid range invalid\n"));
    280                 DEBUGADD(1, ("idmap will be unable to map foreign SIDs\n"));
    281                 ret = NT_STATUS_UNSUCCESSFUL;
    282                 goto done;
    283         }
    284 
    285         if (idmap_alloc_ldap->high_gid <= idmap_alloc_ldap->low_gid) {
    286                 DEBUG(1, ("idmap gid range invalid\n"));
    287                 DEBUGADD(1, ("idmap will be unable to map foreign SIDs\n"));
    288                 ret = NT_STATUS_UNSUCCESSFUL;
    289                 goto done;
    290         }
    291 
    292         if (params && *params) {
    293                 /* assume location is the only parameter */
    294                 idmap_alloc_ldap->url = talloc_strdup(idmap_alloc_ldap, params);
    295         } else {
    296                 tmp = lp_parm_const_string(-1, "idmap alloc config",
    297                                            "ldap_url", NULL);
    298 
    299                 if ( ! tmp) {
    300                         DEBUG(1, ("ERROR: missing idmap ldap url\n"));
    301                         ret = NT_STATUS_UNSUCCESSFUL;
    302                         goto done;
    303                 }
    304 
    305                 idmap_alloc_ldap->url = talloc_strdup(idmap_alloc_ldap, tmp);
    306         }
    307         CHECK_ALLOC_DONE( idmap_alloc_ldap->url );
    308 
    309         trim_char(idmap_alloc_ldap->url, '\"', '\"');
    310 
    311         tmp = lp_parm_const_string(-1, "idmap alloc config",
    312                                    "ldap_base_dn", NULL);
    313         if ( ! tmp || ! *tmp) {
    314                 tmp = lp_ldap_idmap_suffix();
    315                 if ( ! tmp) {
    316                         DEBUG(1, ("ERROR: missing idmap ldap suffix\n"));
    317                         ret = NT_STATUS_UNSUCCESSFUL;
    318                         goto done;
    319                 }
    320         }
    321 
    322         idmap_alloc_ldap->suffix = talloc_strdup(idmap_alloc_ldap, tmp);
    323         CHECK_ALLOC_DONE( idmap_alloc_ldap->suffix );
    324 
    325         ret = smbldap_init(idmap_alloc_ldap, winbind_event_context(),
    326                            idmap_alloc_ldap->url,
    327                            &idmap_alloc_ldap->smbldap_state);
    328         if (!NT_STATUS_IS_OK(ret)) {
    329                 DEBUG(1, ("ERROR: smbldap_init (%s) failed!\n",
    330                           idmap_alloc_ldap->url));
    331                 goto done;
    332         }
    333 
    334         ret = get_credentials( idmap_alloc_ldap,
    335                                idmap_alloc_ldap->smbldap_state,
    336                                "idmap alloc config", NULL,
    337                                &idmap_alloc_ldap->user_dn );
    338         if ( !NT_STATUS_IS_OK(ret) ) {
    339                 DEBUG(1,("idmap_ldap_alloc_init: Failed to get connection "
    340                          "credentials (%s)\n", nt_errstr(ret)));
    341                 goto done;
    342         }
    343 
    344         /* see if the idmap suffix and sub entries exists */
    345 
    346         ret = verify_idpool();
    347 
    348  done:
    349         if ( !NT_STATUS_IS_OK( ret ) )
    350                 TALLOC_FREE( idmap_alloc_ldap );
    351 
     227        talloc_free(mem_ctx);
    352228        return ret;
    353229}
     
    357233********************************/
    358234
    359 static NTSTATUS idmap_ldap_allocate_id(struct unixid *xid)
    360 {
    361         TALLOC_CTX *ctx;
     235static NTSTATUS idmap_ldap_allocate_id_internal(struct idmap_domain *dom,
     236                                                struct unixid *xid)
     237{
     238        TALLOC_CTX *mem_ctx;
    362239        NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
    363240        int rc = LDAP_SERVER_DOWN;
     
    372249        const char **attr_list;
    373250        const char *type;
     251        struct idmap_ldap_context *ctx;
    374252
    375253        /* Only do query if we are online */
     
    378256        }
    379257
    380         if ( ! idmap_alloc_ldap) {
    381                 return NT_STATUS_UNSUCCESSFUL;
    382         }
    383 
    384         ctx = talloc_new(idmap_alloc_ldap);
    385         if ( ! ctx) {
     258        ctx = talloc_get_type(dom->private_data, struct idmap_ldap_context);
     259
     260        mem_ctx = talloc_new(ctx);
     261        if (!mem_ctx) {
    386262                DEBUG(0, ("Out of memory!\n"));
    387263                return NT_STATUS_NO_MEMORY;
     
    406282        }
    407283
    408         filter = talloc_asprintf(ctx, "(objectClass=%s)", LDAP_OBJ_IDPOOL);
     284        filter = talloc_asprintf(mem_ctx, "(objectClass=%s)", LDAP_OBJ_IDPOOL);
    409285        CHECK_ALLOC_DONE(filter);
    410286
    411         attr_list = get_attr_list(ctx, idpool_attr_list);
     287        attr_list = get_attr_list(mem_ctx, idpool_attr_list);
    412288        CHECK_ALLOC_DONE(attr_list);
    413289
    414290        DEBUG(10, ("Search of the id pool (filter: %s)\n", filter));
    415291
    416         rc = smbldap_search(idmap_alloc_ldap->smbldap_state,
    417                                 idmap_alloc_ldap->suffix,
    418                                LDAP_SCOPE_SUBTREE, filter,
    419                                attr_list, 0, &result);
     292        rc = smbldap_search(ctx->smbldap_state,
     293                           ctx->suffix,
     294                           LDAP_SCOPE_SUBTREE, filter,
     295                           attr_list, 0, &result);
    420296
    421297        if (rc != LDAP_SUCCESS) {
     
    424300        }
    425301
    426         talloc_autofree_ldapmsg(ctx, result);
    427 
    428         count = ldap_count_entries(idmap_alloc_ldap->smbldap_state->ldap_struct,
    429                                    result);
     302        talloc_autofree_ldapmsg(mem_ctx, result);
     303
     304        count = ldap_count_entries(ctx->smbldap_state->ldap_struct, result);
    430305        if (count != 1) {
    431306                DEBUG(0,("Single %s object not found\n", LDAP_OBJ_IDPOOL));
     
    433308        }
    434309
    435         entry = ldap_first_entry(idmap_alloc_ldap->smbldap_state->ldap_struct,
    436                                  result);
    437 
    438         dn = smbldap_talloc_dn(ctx,
    439                                idmap_alloc_ldap->smbldap_state->ldap_struct,
     310        entry = ldap_first_entry(ctx->smbldap_state->ldap_struct, result);
     311
     312        dn = smbldap_talloc_dn(mem_ctx,
     313                               ctx->smbldap_state->ldap_struct,
    440314                               entry);
    441315        if ( ! dn) {
     
    443317        }
    444318
    445         if ( ! (id_str = smbldap_talloc_single_attribute(idmap_alloc_ldap->smbldap_state->ldap_struct,
    446                                 entry, type, ctx))) {
     319        id_str = smbldap_talloc_single_attribute(
     320                                ctx->smbldap_state->ldap_struct,
     321                                entry, type, mem_ctx);
     322        if (id_str == NULL) {
    447323                DEBUG(0,("%s attribute not found\n", type));
    448                 goto done;
    449         }
    450         if ( ! id_str) {
    451                 DEBUG(0,("Out of memory\n"));
    452                 ret = NT_STATUS_NO_MEMORY;
     324                ret = NT_STATUS_UNSUCCESSFUL;
    453325                goto done;
    454326        }
     
    460332        switch (xid->type) {
    461333        case ID_TYPE_UID:
    462                 if (xid->id > idmap_alloc_ldap->high_uid) {
     334                if (xid->id > dom->high_id) {
    463335                        DEBUG(0,("Cannot allocate uid above %lu!\n",
    464                                  (unsigned long)idmap_alloc_ldap->high_uid));
     336                                 (unsigned long)dom->high_id));
    465337                        goto done;
    466338                }
     
    468340
    469341        case ID_TYPE_GID:
    470                 if (xid->id > idmap_alloc_ldap->high_gid) {
     342                if (xid->id > dom->high_id) {
    471343                        DEBUG(0,("Cannot allocate gid above %lu!\n",
    472                                  (unsigned long)idmap_alloc_ldap->high_uid));
     344                                 (unsigned long)dom->high_id));
    473345                        goto done;
    474346                }
     
    480352        }
    481353
    482         new_id_str = talloc_asprintf(ctx, "%lu", (unsigned long)xid->id + 1);
     354        new_id_str = talloc_asprintf(mem_ctx, "%lu", (unsigned long)xid->id + 1);
    483355        if ( ! new_id_str) {
    484356                DEBUG(0,("Out of memory\n"));
     
    498370                   id_str, new_id_str));
    499371
    500         rc = smbldap_modify(idmap_alloc_ldap->smbldap_state, dn, mods);
     372        rc = smbldap_modify(ctx->smbldap_state, dn, mods);
    501373
    502374        ldap_mods_free(mods, True);
     
    511383
    512384done:
    513         talloc_free(ctx);
     385        talloc_free(mem_ctx);
    514386        return ret;
    515387}
    516388
    517 /**********************************
    518  Get current highest id.
    519 **********************************/
    520 
    521 static NTSTATUS idmap_ldap_get_hwm(struct unixid *xid)
    522 {
    523         TALLOC_CTX *memctx;
    524         NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
    525         int rc = LDAP_SERVER_DOWN;
    526         int count = 0;
    527         LDAPMessage *result = NULL;
    528         LDAPMessage *entry = NULL;
    529         char *id_str;
    530         char *filter = NULL;
    531         const char **attr_list;
    532         const char *type;
    533 
    534         /* Only do query if we are online */
    535         if (idmap_is_offline()) {
    536                 return NT_STATUS_FILE_IS_OFFLINE;
    537         }
    538 
    539         if ( ! idmap_alloc_ldap) {
    540                 return NT_STATUS_UNSUCCESSFUL;
    541         }
    542 
    543         memctx = talloc_new(idmap_alloc_ldap);
    544         if ( ! memctx) {
    545                 DEBUG(0, ("Out of memory!\n"));
    546                 return NT_STATUS_NO_MEMORY;
    547         }
    548 
    549         /* get type */
    550         switch (xid->type) {
    551 
    552         case ID_TYPE_UID:
    553                 type = get_attr_key2string(idpool_attr_list,
    554                                            LDAP_ATTR_UIDNUMBER);
    555                 break;
    556 
    557         case ID_TYPE_GID:
    558                 type = get_attr_key2string(idpool_attr_list,
    559                                            LDAP_ATTR_GIDNUMBER);
    560                 break;
    561 
    562         default:
    563                 DEBUG(2, ("Invalid ID type (0x%x)\n", xid->type));
    564                 return NT_STATUS_INVALID_PARAMETER;
    565         }
    566 
    567         filter = talloc_asprintf(memctx, "(objectClass=%s)", LDAP_OBJ_IDPOOL);
    568         CHECK_ALLOC_DONE(filter);
    569 
    570         attr_list = get_attr_list(memctx, idpool_attr_list);
    571         CHECK_ALLOC_DONE(attr_list);
    572 
    573         rc = smbldap_search(idmap_alloc_ldap->smbldap_state,
    574                                 idmap_alloc_ldap->suffix,
    575                                LDAP_SCOPE_SUBTREE, filter,
    576                                attr_list, 0, &result);
    577 
    578         if (rc != LDAP_SUCCESS) {
    579                 DEBUG(0,("%s object not found\n", LDAP_OBJ_IDPOOL));
    580                 goto done;
    581         }
    582 
    583         talloc_autofree_ldapmsg(memctx, result);
    584 
    585         count = ldap_count_entries(idmap_alloc_ldap->smbldap_state->ldap_struct,
    586                                    result);
    587         if (count != 1) {
    588                 DEBUG(0,("Single %s object not found\n", LDAP_OBJ_IDPOOL));
    589                 goto done;
    590         }
    591 
    592         entry = ldap_first_entry(idmap_alloc_ldap->smbldap_state->ldap_struct,
    593                                  result);
    594 
    595         id_str = smbldap_talloc_single_attribute(idmap_alloc_ldap->smbldap_state->ldap_struct,
    596                         entry, type, memctx);
    597         if ( ! id_str) {
    598                 DEBUG(0,("%s attribute not found\n", type));
    599                 goto done;
    600         }
    601         if ( ! id_str) {
    602                 DEBUG(0,("Out of memory\n"));
    603                 ret = NT_STATUS_NO_MEMORY;
    604                 goto done;
    605         }
    606 
    607         xid->id = strtoul(id_str, NULL, 10);
    608 
    609         ret = NT_STATUS_OK;
    610 done:
    611         talloc_free(memctx);
     389/**
     390 * Allocate a new unix-ID.
     391 * For now this is for the default idmap domain only.
     392 * Should be extended later on.
     393 */
     394static NTSTATUS idmap_ldap_allocate_id(struct idmap_domain *dom,
     395                                       struct unixid *id)
     396{
     397        NTSTATUS ret;
     398
     399        if (!strequal(dom->name, "*")) {
     400                DEBUG(3, ("idmap_ldap_allocate_id: "
     401                          "Refusing allocation of a new unixid for domain'%s'. "
     402                          "This is only supported for the default "
     403                          "domain \"*\".\n",
     404                           dom->name));
     405                return NT_STATUS_NOT_IMPLEMENTED;
     406        }
     407
     408        ret = idmap_ldap_allocate_id_internal(dom, id);
     409
    612410        return ret;
    613 }
    614 /**********************************
    615  Set highest id.
    616 **********************************/
    617 
    618 static NTSTATUS idmap_ldap_set_hwm(struct unixid *xid)
    619 {
    620         TALLOC_CTX *ctx;
    621         NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
    622         int rc = LDAP_SERVER_DOWN;
    623         int count = 0;
    624         LDAPMessage *result = NULL;
    625         LDAPMessage *entry = NULL;
    626         LDAPMod **mods = NULL;
    627         char *new_id_str;
    628         char *filter = NULL;
    629         const char *dn = NULL;
    630         const char **attr_list;
    631         const char *type;
    632 
    633         /* Only do query if we are online */
    634         if (idmap_is_offline()) {
    635                 return NT_STATUS_FILE_IS_OFFLINE;
    636         }
    637 
    638         if ( ! idmap_alloc_ldap) {
    639                 return NT_STATUS_UNSUCCESSFUL;
    640         }
    641 
    642         ctx = talloc_new(idmap_alloc_ldap);
    643         if ( ! ctx) {
    644                 DEBUG(0, ("Out of memory!\n"));
    645                 return NT_STATUS_NO_MEMORY;
    646         }
    647 
    648         /* get type */
    649         switch (xid->type) {
    650 
    651         case ID_TYPE_UID:
    652                 type = get_attr_key2string(idpool_attr_list,
    653                                            LDAP_ATTR_UIDNUMBER);
    654                 break;
    655 
    656         case ID_TYPE_GID:
    657                 type = get_attr_key2string(idpool_attr_list,
    658                                            LDAP_ATTR_GIDNUMBER);
    659                 break;
    660 
    661         default:
    662                 DEBUG(2, ("Invalid ID type (0x%x)\n", xid->type));
    663                 return NT_STATUS_INVALID_PARAMETER;
    664         }
    665 
    666         filter = talloc_asprintf(ctx, "(objectClass=%s)", LDAP_OBJ_IDPOOL);
    667         CHECK_ALLOC_DONE(filter);
    668 
    669         attr_list = get_attr_list(ctx, idpool_attr_list);
    670         CHECK_ALLOC_DONE(attr_list);
    671 
    672         rc = smbldap_search(idmap_alloc_ldap->smbldap_state,
    673                                 idmap_alloc_ldap->suffix,
    674                                LDAP_SCOPE_SUBTREE, filter,
    675                                attr_list, 0, &result);
    676 
    677         if (rc != LDAP_SUCCESS) {
    678                 DEBUG(0,("%s object not found\n", LDAP_OBJ_IDPOOL));
    679                 goto done;
    680         }
    681 
    682         talloc_autofree_ldapmsg(ctx, result);
    683 
    684         count = ldap_count_entries(idmap_alloc_ldap->smbldap_state->ldap_struct,
    685                                    result);
    686         if (count != 1) {
    687                 DEBUG(0,("Single %s object not found\n", LDAP_OBJ_IDPOOL));
    688                 goto done;
    689         }
    690 
    691         entry = ldap_first_entry(idmap_alloc_ldap->smbldap_state->ldap_struct,
    692                                  result);
    693 
    694         dn = smbldap_talloc_dn(ctx,
    695                                 idmap_alloc_ldap->smbldap_state->ldap_struct,
    696                                 entry);
    697         if ( ! dn) {
    698                 goto done;
    699         }
    700 
    701         new_id_str = talloc_asprintf(ctx, "%lu", (unsigned long)xid->id);
    702         if ( ! new_id_str) {
    703                 DEBUG(0,("Out of memory\n"));
    704                 ret = NT_STATUS_NO_MEMORY;
    705                 goto done;
    706         }
    707 
    708         smbldap_set_mod(&mods, LDAP_MOD_REPLACE, type, new_id_str);
    709 
    710         if (mods == NULL) {
    711                 DEBUG(0,("smbldap_set_mod() failed.\n"));
    712                 goto done;
    713         }
    714 
    715         rc = smbldap_modify(idmap_alloc_ldap->smbldap_state, dn, mods);
    716 
    717         ldap_mods_free(mods, True);
    718 
    719         if (rc != LDAP_SUCCESS) {
    720                 DEBUG(1,("Failed to allocate new %s. "
    721                          "smbldap_modify() failed.\n", type));
    722                 goto done;
    723         }
    724 
    725         ret = NT_STATUS_OK;
    726 
    727 done:
    728         talloc_free(ctx);
    729         return ret;
    730 }
    731 
    732 /**********************************
    733  Close idmap ldap alloc
    734 **********************************/
    735 
    736 static NTSTATUS idmap_ldap_alloc_close(void)
    737 {
    738         if (idmap_alloc_ldap) {
    739                 smbldap_free_struct(&idmap_alloc_ldap->smbldap_state);
    740                 DEBUG(5,("The connection to the LDAP server was closed\n"));
    741                 /* maybe free the results here --metze */
    742                 TALLOC_FREE(idmap_alloc_ldap);
    743         }
    744         return NT_STATUS_OK;
    745411}
    746412
     
    763429********************************/
    764430
    765 static NTSTATUS idmap_ldap_db_init(struct idmap_domain *dom,
    766                                    const char *params)
     431static NTSTATUS idmap_ldap_set_mapping(struct idmap_domain *dom,
     432                                       const struct id_map *map);
     433
     434static NTSTATUS idmap_ldap_db_init(struct idmap_domain *dom)
    767435{
    768436        NTSTATUS ret;
     
    782450        }
    783451
    784         if (strequal(dom->name, "*")) {
    785                 uid_t low_uid = 0;
    786                 uid_t high_uid = 0;
    787                 gid_t low_gid = 0;
    788                 gid_t high_gid = 0;
    789 
    790                 ctx->filter_low_id = 0;
    791                 ctx->filter_high_id = 0;
    792 
    793                 if (lp_idmap_uid(&low_uid, &high_uid)) {
    794                         ctx->filter_low_id = low_uid;
    795                         ctx->filter_high_id = high_uid;
    796                 } else {
    797                         DEBUG(3, ("Warning: 'idmap uid' not set!\n"));
    798                 }
    799 
    800                 if (lp_idmap_gid(&low_gid, &high_gid)) {
    801                         if ((low_gid != low_uid) || (high_gid != high_uid)) {
    802                                 DEBUG(1, ("Warning: 'idmap uid' and 'idmap gid'"
    803                                       " ranges do not agree -- building "
    804                                       "intersection\n"));
    805                                 ctx->filter_low_id = MAX(ctx->filter_low_id,
    806                                                          low_gid);
    807                                 ctx->filter_high_id = MIN(ctx->filter_high_id,
    808                                                           high_gid);
    809                         }
    810                 } else {
    811                         DEBUG(3, ("Warning: 'idmap gid' not set!\n"));
    812                 }
    813         } else {
    814                 const char *range = NULL;
    815 
    816                 config_option = talloc_asprintf(ctx, "idmap config %s", dom->name);
    817                 if ( ! config_option) {
    818                         DEBUG(0, ("Out of memory!\n"));
    819                         ret = NT_STATUS_NO_MEMORY;
    820                         goto done;
    821                 }
    822 
    823                 /* load ranges */
    824                 range = lp_parm_const_string(-1, config_option, "range", NULL);
    825                 if (range && range[0]) {
    826                         if ((sscanf(range, "%u - %u", &ctx->filter_low_id,
    827                                                         &ctx->filter_high_id) != 2))
    828                         {
    829                                 DEBUG(1, ("ERROR: invalid filter range [%s]", range));
    830                                 ctx->filter_low_id = 0;
    831                                 ctx->filter_high_id = 0;
    832                         }
    833                 }
    834         }
    835 
    836         if (ctx->filter_low_id > ctx->filter_high_id) {
    837                 DEBUG(1, ("ERROR: invalid filter range [%u-%u]",
    838                       ctx->filter_low_id, ctx->filter_high_id));
    839                 ctx->filter_low_id = 0;
    840                 ctx->filter_high_id = 0;
    841         }
    842 
    843         if (params != NULL) {
    844                 /* assume location is the only parameter */
    845                 ctx->url = talloc_strdup(ctx, params);
    846         } else {
    847                 tmp = lp_parm_const_string(-1, config_option, "ldap_url", NULL);
    848 
     452        config_option = talloc_asprintf(ctx, "idmap config %s", dom->name);
     453        if (!config_option) {
     454                DEBUG(0, ("Out of memory!\n"));
     455                ret = NT_STATUS_NO_MEMORY;
     456                goto done;
     457        }
     458
     459        tmp = lp_parm_const_string(-1, config_option, "ldap_url", NULL);
     460
     461        if ( ! tmp) {
     462                DEBUG(1, ("ERROR: missing idmap ldap url\n"));
     463                ret = NT_STATUS_UNSUCCESSFUL;
     464                goto done;
     465        }
     466
     467        ctx->url = talloc_strdup(ctx, tmp);
     468
     469        trim_char(ctx->url, '\"', '\"');
     470
     471        tmp = lp_parm_const_string(-1, config_option, "ldap_base_dn", NULL);
     472        if ( ! tmp || ! *tmp) {
     473                tmp = lp_ldap_idmap_suffix();
    849474                if ( ! tmp) {
    850                         DEBUG(1, ("ERROR: missing idmap ldap url\n"));
     475                        DEBUG(1, ("ERROR: missing idmap ldap suffix\n"));
    851476                        ret = NT_STATUS_UNSUCCESSFUL;
    852477                        goto done;
    853478                }
    854 
    855                 ctx->url = talloc_strdup(ctx, tmp);
    856         }
    857         CHECK_ALLOC_DONE(ctx->url);
    858 
    859         trim_char(ctx->url, '\"', '\"');
    860 
    861         tmp = lp_parm_const_string(-1, config_option, "ldap_base_dn", NULL);
    862         if ( ! tmp || ! *tmp) {
    863                 tmp = lp_ldap_idmap_suffix();
    864                 if ( ! tmp) {
    865                         DEBUG(1, ("ERROR: missing idmap ldap suffix\n"));
    866                         ret = NT_STATUS_UNSUCCESSFUL;
    867                         goto done;
    868                 }
    869         }
     479        }
    870480
    871481        ctx->suffix = talloc_strdup(ctx, tmp);
    872482        CHECK_ALLOC_DONE(ctx->suffix);
     483
     484        ctx->rw_ops = talloc_zero(ctx, struct idmap_rw_ops);
     485        CHECK_ALLOC_DONE(ctx->rw_ops);
     486
     487        ctx->rw_ops->get_new_id = idmap_ldap_allocate_id_internal;
     488        ctx->rw_ops->set_mapping = idmap_ldap_set_mapping;
    873489
    874490        ret = smbldap_init(ctx, winbind_event_context(), ctx->url,
     
    879495        }
    880496
    881         ret = get_credentials( ctx, ctx->smbldap_state, config_option,
     497        ret = get_credentials( ctx, ctx->smbldap_state, config_option,
    882498                               dom, &ctx->user_dn );
    883499        if ( !NT_STATUS_IS_OK(ret) ) {
     
    887503        }
    888504
    889         /* set the destructor on the context, so that resource are properly
    890            freed if the contexts is released */
    891 
     505        /*
     506         * Set the destructor on the context, so that resources are
     507         * properly freed when the context is released.
     508         */
    892509        talloc_set_destructor(ctx, idmap_ldap_close_destructor);
    893510
    894511        dom->private_data = ctx;
     512
     513        ret = verify_idpool(dom);
     514        if (!NT_STATUS_IS_OK(ret)) {
     515                DEBUG(1, ("idmap_ldap_db_init: failed to verify ID pool (%s)\n",
     516                         nt_errstr(ret)));
     517                goto done;
     518        }
    895519
    896520        talloc_free(config_option);
     
    902526        return ret;
    903527}
     528
     529/**
     530 * set a mapping.
     531 */
     532
     533/* TODO: change this:  This function cannot be called to modify a mapping,
     534 * only set a new one */
     535
     536static NTSTATUS idmap_ldap_set_mapping(struct idmap_domain *dom,
     537                                       const struct id_map *map)
     538{
     539        NTSTATUS ret;
     540        TALLOC_CTX *memctx;
     541        struct idmap_ldap_context *ctx;
     542        LDAPMessage *entry = NULL;
     543        LDAPMod **mods = NULL;
     544        const char *type;
     545        char *id_str;
     546        char *sid;
     547        char *dn;
     548        int rc = -1;
     549
     550        /* Only do query if we are online */
     551        if (idmap_is_offline()) {
     552                return NT_STATUS_FILE_IS_OFFLINE;
     553        }
     554
     555        ctx = talloc_get_type(dom->private_data, struct idmap_ldap_context);
     556
     557        switch(map->xid.type) {
     558        case ID_TYPE_UID:
     559                type = get_attr_key2string(sidmap_attr_list,
     560                                           LDAP_ATTR_UIDNUMBER);
     561                break;
     562
     563        case ID_TYPE_GID:
     564                type = get_attr_key2string(sidmap_attr_list,
     565                                           LDAP_ATTR_GIDNUMBER);
     566                break;
     567
     568        default:
     569                return NT_STATUS_INVALID_PARAMETER;
     570        }
     571
     572        memctx = talloc_new(ctx);
     573        if ( ! memctx) {
     574                DEBUG(0, ("Out of memory!\n"));
     575                return NT_STATUS_NO_MEMORY;
     576        }
     577
     578        id_str = talloc_asprintf(memctx, "%lu", (unsigned long)map->xid.id);
     579        CHECK_ALLOC_DONE(id_str);
     580
     581        sid = talloc_strdup(memctx, sid_string_talloc(memctx, map->sid));
     582        CHECK_ALLOC_DONE(sid);
     583
     584        dn = talloc_asprintf(memctx, "%s=%s,%s",
     585                        get_attr_key2string(sidmap_attr_list, LDAP_ATTR_SID),
     586                        sid,
     587                        ctx->suffix);
     588        CHECK_ALLOC_DONE(dn);
     589
     590        smbldap_set_mod(&mods, LDAP_MOD_ADD,
     591                        "objectClass", LDAP_OBJ_IDMAP_ENTRY);
     592
     593        smbldap_make_mod(ctx->smbldap_state->ldap_struct,
     594                         entry, &mods, type, id_str);
     595
     596        smbldap_make_mod(ctx->smbldap_state->ldap_struct, entry, &mods,
     597                         get_attr_key2string(sidmap_attr_list, LDAP_ATTR_SID),
     598                         sid);
     599
     600        if ( ! mods) {
     601                DEBUG(2, ("ERROR: No mods?\n"));
     602                ret = NT_STATUS_UNSUCCESSFUL;
     603                goto done;
     604        }
     605
     606        /* TODO: remove conflicting mappings! */
     607
     608        smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_SID_ENTRY);
     609
     610        DEBUG(10, ("Set DN %s (%s -> %s)\n", dn, sid, id_str));
     611
     612        rc = smbldap_add(ctx->smbldap_state, dn, mods);
     613        ldap_mods_free(mods, True);
     614
     615        if (rc != LDAP_SUCCESS) {
     616                char *ld_error = NULL;
     617                ldap_get_option(ctx->smbldap_state->ldap_struct,
     618                                LDAP_OPT_ERROR_STRING, &ld_error);
     619                DEBUG(0,("ldap_set_mapping_internals: Failed to add %s to %lu "
     620                         "mapping [%s]\n", sid,
     621                         (unsigned long)map->xid.id, type));
     622                DEBUG(0, ("ldap_set_mapping_internals: Error was: %s (%s)\n",
     623                        ld_error ? ld_error : "(NULL)", ldap_err2string (rc)));
     624                if (ld_error) {
     625                        ldap_memfree(ld_error);
     626                }
     627                ret = NT_STATUS_UNSUCCESSFUL;
     628                goto done;
     629        }
     630
     631        DEBUG(10,("ldap_set_mapping: Successfully created mapping from %s to "
     632                  "%lu [%s]\n", sid, (unsigned long)map->xid.id, type));
     633
     634        ret = NT_STATUS_OK;
     635
     636done:
     637        talloc_free(memctx);
     638        return ret;
     639}
     640
     641/**
     642 * Create a new mapping for an unmapped SID, also allocating a new ID.
     643 * If possible, this should be run inside a transaction to make the
     644 * action atomic.
     645 */
     646static NTSTATUS idmap_ldap_new_mapping(struct idmap_domain *dom, struct id_map *map)
     647{
     648        NTSTATUS ret;
     649        struct idmap_ldap_context *ctx;
     650
     651        ctx = talloc_get_type(dom->private_data, struct idmap_ldap_context);
     652
     653        ret = idmap_rw_new_mapping(dom, ctx->rw_ops, map);
     654
     655        return ret;
     656}
     657
    904658
    905659/* max number of ids requested per batch query */
     
    1026780        for (i = 0; i < count; i++) {
    1027781                char *sidstr = NULL;
    1028                 char *tmp = NULL;
     782                char *tmp = NULL;
    1029783                enum id_type type;
    1030784                struct id_map *map;
     
    1075829
    1076830                id = strtoul(tmp, NULL, 10);
    1077                 if ((id == 0) ||
    1078                     (ctx->filter_low_id && (id < ctx->filter_low_id)) ||
    1079                     (ctx->filter_high_id && (id > ctx->filter_high_id))) {
     831                if (!idmap_unix_id_is_in_range(id, dom)) {
    1080832                        DEBUG(5, ("Requested id (%u) out of range (%u - %u). "
    1081833                                  "Filtered!\n", id,
    1082                                   ctx->filter_low_id, ctx->filter_high_id));
     834                                  dom->low_id, dom->high_id));
    1083835                        TALLOC_FREE(sidstr);
    1084836                        TALLOC_FREE(tmp);
     
    1146898/* this function searches up to IDMAP_LDAP_MAX_IDS entries
    1147899 * in maps for a match */
    1148 static struct id_map *find_map_by_sid(struct id_map **maps, DOM_SID *sid)
     900static struct id_map *find_map_by_sid(struct id_map **maps, struct dom_sid *sid)
    1149901{
    1150902        int i;
     
    1154906                        return NULL;
    1155907                }
    1156                 if (sid_equal(maps[i]->sid, sid)) {
     908                if (dom_sid_equal(maps[i]->sid, sid)) {
    1157909                        return maps[i];
    1158910                }
     
    1165917                                           struct id_map **ids)
    1166918{
    1167         LDAPMessage *entry = NULL;
     919        LDAPMessage *entry = NULL;
    1168920        NTSTATUS ret;
    1169921        TALLOC_CTX *memctx;
     
    12631015                enum id_type type;
    12641016                struct id_map *map;
    1265                 DOM_SID sid;
     1017                struct dom_sid sid;
    12661018                uint32_t id;
    12671019
     
    13241076
    13251077                id = strtoul(tmp, NULL, 10);
    1326                 if ((id == 0) ||
    1327                     (ctx->filter_low_id && (id < ctx->filter_low_id)) ||
    1328                     (ctx->filter_high_id && (id > ctx->filter_high_id))) {
     1078                if (!idmap_unix_id_is_in_range(id, dom)) {
    13291079                        DEBUG(5, ("Requested id (%u) out of range (%u - %u). "
    13301080                                  "Filtered!\n", id,
    1331                                   ctx->filter_low_id, ctx->filter_high_id));
     1081                                  dom->low_id, dom->high_id));
    13321082                        TALLOC_FREE(sidstr);
    13331083                        TALLOC_FREE(tmp);
     
    13641114        }
    13651115
     1116        /*
     1117         *  try to create new mappings for unmapped sids
     1118         */
     1119        for (i = 0; ids[i]; i++) {
     1120                if (ids[i]->status != ID_MAPPED) {
     1121                        ids[i]->status = ID_UNMAPPED;
     1122                        if (ids[i]->sid != NULL) {
     1123                                ret = idmap_ldap_new_mapping(dom, ids[i]);
     1124                                if (!NT_STATUS_IS_OK(ret)) {
     1125                                        goto done;
     1126                                }
     1127                        }
     1128                }
     1129        }
     1130
    13661131        ret = NT_STATUS_OK;
    1367 
    1368         /* mark all unknwon/expired ones as unmapped */
    1369         for (i = 0; ids[i]; i++) {
    1370                 if (ids[i]->status != ID_MAPPED)
    1371                         ids[i]->status = ID_UNMAPPED;
    1372         }
    13731132
    13741133done:
     
    13781137
    13791138/**********************************
    1380  set a mapping.
    1381 **********************************/
    1382 
    1383 /* TODO: change this:  This function cannot be called to modify a mapping,
    1384  * only set a new one */
    1385 
    1386 static NTSTATUS idmap_ldap_set_mapping(struct idmap_domain *dom,
    1387                                        const struct id_map *map)
    1388 {
    1389         NTSTATUS ret;
    1390         TALLOC_CTX *memctx;
    1391         struct idmap_ldap_context *ctx;
    1392         LDAPMessage *entry = NULL;
    1393         LDAPMod **mods = NULL;
    1394         const char *type;
    1395         char *id_str;
    1396         char *sid;
    1397         char *dn;
    1398         int rc = -1;
    1399 
    1400         /* Only do query if we are online */
    1401         if (idmap_is_offline()) {
    1402                 return NT_STATUS_FILE_IS_OFFLINE;
    1403         }
    1404 
    1405         ctx = talloc_get_type(dom->private_data, struct idmap_ldap_context);
    1406 
    1407         switch(map->xid.type) {
    1408         case ID_TYPE_UID:
    1409                 type = get_attr_key2string(sidmap_attr_list,
    1410                                            LDAP_ATTR_UIDNUMBER);
    1411                 break;
    1412 
    1413         case ID_TYPE_GID:
    1414                 type = get_attr_key2string(sidmap_attr_list,
    1415                                            LDAP_ATTR_GIDNUMBER);
    1416                 break;
    1417 
    1418         default:
    1419                 return NT_STATUS_INVALID_PARAMETER;
    1420         }
    1421 
    1422         memctx = talloc_new(ctx);
    1423         if ( ! memctx) {
    1424                 DEBUG(0, ("Out of memory!\n"));
    1425                 return NT_STATUS_NO_MEMORY;
    1426         }
    1427 
    1428         id_str = talloc_asprintf(memctx, "%lu", (unsigned long)map->xid.id);
    1429         CHECK_ALLOC_DONE(id_str);
    1430 
    1431         sid = talloc_strdup(memctx, sid_string_talloc(memctx, map->sid));
    1432         CHECK_ALLOC_DONE(sid);
    1433 
    1434         dn = talloc_asprintf(memctx, "%s=%s,%s",
    1435                         get_attr_key2string(sidmap_attr_list, LDAP_ATTR_SID),
    1436                         sid,
    1437                         ctx->suffix);
    1438         CHECK_ALLOC_DONE(dn);
    1439 
    1440         smbldap_set_mod(&mods, LDAP_MOD_ADD,
    1441                         "objectClass", LDAP_OBJ_IDMAP_ENTRY);
    1442 
    1443         smbldap_make_mod(ctx->smbldap_state->ldap_struct,
    1444                          entry, &mods, type, id_str);
    1445 
    1446         smbldap_make_mod(ctx->smbldap_state->ldap_struct, entry, &mods,
    1447                          get_attr_key2string(sidmap_attr_list, LDAP_ATTR_SID),
    1448                          sid);
    1449 
    1450         if ( ! mods) {
    1451                 DEBUG(2, ("ERROR: No mods?\n"));
    1452                 ret = NT_STATUS_UNSUCCESSFUL;
    1453                 goto done;
    1454         }
    1455 
    1456         /* TODO: remove conflicting mappings! */
    1457 
    1458         smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_SID_ENTRY);
    1459 
    1460         DEBUG(10, ("Set DN %s (%s -> %s)\n", dn, sid, id_str));
    1461 
    1462         rc = smbldap_add(ctx->smbldap_state, dn, mods);
    1463         ldap_mods_free(mods, True);
    1464 
    1465         if (rc != LDAP_SUCCESS) {
    1466                 char *ld_error = NULL;
    1467                 ldap_get_option(ctx->smbldap_state->ldap_struct,
    1468                                 LDAP_OPT_ERROR_STRING, &ld_error);
    1469                 DEBUG(0,("ldap_set_mapping_internals: Failed to add %s to %lu "
    1470                          "mapping [%s]\n", sid,
    1471                          (unsigned long)map->xid.id, type));
    1472                 DEBUG(0, ("ldap_set_mapping_internals: Error was: %s (%s)\n",
    1473                         ld_error ? ld_error : "(NULL)", ldap_err2string (rc)));
    1474                 if (ld_error) {
    1475                         ldap_memfree(ld_error);
    1476                 }
    1477                 ret = NT_STATUS_UNSUCCESSFUL;
    1478                 goto done;
    1479         }
    1480 
    1481         DEBUG(10,("ldap_set_mapping: Successfully created mapping from %s to "
    1482                   "%lu [%s]\n", sid, (unsigned long)map->xid.id, type));
    1483 
    1484         ret = NT_STATUS_OK;
    1485 
    1486 done:
    1487         talloc_free(memctx);
    1488         return ret;
    1489 }
    1490 
    1491 /**********************************
    14921139 Close the idmap ldap instance
    14931140**********************************/
    1494 
    1495 static NTSTATUS idmap_ldap_close(struct idmap_domain *dom)
    1496 {
    1497         struct idmap_ldap_context *ctx;
    1498 
    1499         if (dom->private_data) {
    1500                 ctx = talloc_get_type(dom->private_data,
    1501                                       struct idmap_ldap_context);
    1502 
    1503                 talloc_free(ctx);
    1504                 dom->private_data = NULL;
    1505         }
    1506 
    1507         return NT_STATUS_OK;
    1508 }
    15091141
    15101142static struct idmap_methods idmap_ldap_methods = {
     
    15131145        .unixids_to_sids = idmap_ldap_unixids_to_sids,
    15141146        .sids_to_unixids = idmap_ldap_sids_to_unixids,
    1515         .set_mapping = idmap_ldap_set_mapping,
    1516         .close_fn = idmap_ldap_close
     1147        .allocate_id = idmap_ldap_allocate_id,
    15171148};
    1518 
    1519 static struct idmap_alloc_methods idmap_ldap_alloc_methods = {
    1520 
    1521         .init = idmap_ldap_alloc_init,
    1522         .allocate_id = idmap_ldap_allocate_id,
    1523         .get_id_hwm = idmap_ldap_get_hwm,
    1524         .set_id_hwm = idmap_ldap_set_hwm,
    1525         .close_fn = idmap_ldap_alloc_close,
    1526         /* .dump_data = TODO */
    1527 };
    1528 
    1529 static NTSTATUS idmap_alloc_ldap_init(void)
    1530 {
    1531         return smb_register_idmap_alloc(SMB_IDMAP_INTERFACE_VERSION, "ldap",
    1532                                         &idmap_ldap_alloc_methods);
    1533 }
    15341149
    15351150NTSTATUS idmap_ldap_init(void);
    15361151NTSTATUS idmap_ldap_init(void)
    15371152{
    1538         NTSTATUS ret;
    1539 
    1540         /* FIXME: bad hack to actually register also the alloc_ldap module
    1541          * without changining configure.in */
    1542         ret = idmap_alloc_ldap_init();
    1543         if (! NT_STATUS_IS_OK(ret)) {
    1544                 return ret;
    1545         }
    15461153        return smb_register_idmap(SMB_IDMAP_INTERFACE_VERSION, "ldap",
    15471154                                  &idmap_ldap_methods);
Note: See TracChangeset for help on using the changeset viewer.