LCOV - code coverage report
Current view: top level - source3/winbindd - idmap_ldap.c (source / functions) Hit Total Coverage
Test: coverage report for master 2b515b7d Lines: 0 555 0.0 %
Date: 2024-02-28 12:06:22 Functions: 0 11 0.0 %

          Line data    Source code
       1             : /*
       2             :    Unix SMB/CIFS implementation.
       3             : 
       4             :    idmap LDAP backend
       5             : 
       6             :    Copyright (C) Tim Potter             2000
       7             :    Copyright (C) Jim McDonough <jmcd@us.ibm.com>  2003
       8             :    Copyright (C) Gerald Carter          2003
       9             :    Copyright (C) Simo Sorce             2003-2007
      10             :    Copyright (C) Michael Adam           2010
      11             : 
      12             :    This program is free software; you can redistribute it and/or modify
      13             :    it under the terms of the GNU General Public License as published by
      14             :    the Free Software Foundation; either version 3 of the License, or
      15             :    (at your option) any later version.
      16             : 
      17             :    This program is distributed in the hope that it will be useful,
      18             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      19             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      20             :    GNU General Public License for more details.
      21             : 
      22             :    You should have received a copy of the GNU General Public License
      23             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      24             : */
      25             : 
      26             : #include "includes.h"
      27             : #include "winbindd.h"
      28             : #include "secrets.h"
      29             : #include "idmap.h"
      30             : #include "idmap_rw.h"
      31             : #include "../libcli/security/security.h"
      32             : #include "lib/util/smb_strtox.h"
      33             : #include "lib/global_contexts.h"
      34             : 
      35             : #undef DBGC_CLASS
      36             : #define DBGC_CLASS DBGC_IDMAP
      37             : 
      38             : #include <lber.h>
      39             : #include <ldap.h>
      40             : 
      41             : #include "smbldap.h"
      42             : #include "passdb/pdb_ldap_schema.h"
      43             : 
      44             : struct idmap_ldap_context {
      45             :         struct smbldap_state *smbldap_state;
      46             :         char *url;
      47             :         char *suffix;
      48             :         char *user_dn;
      49             :         bool anon;
      50             :         struct idmap_rw_ops *rw_ops;
      51             : };
      52             : 
      53             : #define CHECK_ALLOC_DONE(mem) do { \
      54             :         if (!mem) { \
      55             :                 DEBUG(0, ("Out of memory!\n")); \
      56             :                 ret = NT_STATUS_NO_MEMORY; \
      57             :                 goto done; \
      58             :         } } while (0)
      59             : 
      60             : /**********************************************************************
      61             :  IDMAP ALLOC TDB BACKEND
      62             : **********************************************************************/
      63             : 
      64             : /*********************************************************************
      65             :  ********************************************************************/
      66             : 
      67           0 : static NTSTATUS get_credentials( TALLOC_CTX *mem_ctx,
      68             :                                  struct smbldap_state *ldap_state,
      69             :                                  struct idmap_domain *dom,
      70             :                                  char **dn )
      71             : {
      72           0 :         NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
      73           0 :         char *secret = NULL;
      74           0 :         const char *tmp = NULL;
      75           0 :         char *user_dn = NULL;
      76           0 :         bool anon = False;
      77             : 
      78             :         /* assume anonymous if we don't have a specified user */
      79             : 
      80           0 :         tmp = idmap_config_const_string(dom->name, "ldap_user_dn", NULL);
      81             : 
      82           0 :         if ( tmp ) {
      83           0 :                 secret = idmap_fetch_secret("ldap", dom->name, tmp);
      84           0 :                 if (!secret) {
      85           0 :                         DEBUG(0, ("get_credentials: Unable to fetch "
      86             :                                   "auth credentials for %s in %s\n",
      87             :                                   tmp, (dom==NULL)?"ALLOC":dom->name));
      88           0 :                         ret = NT_STATUS_ACCESS_DENIED;
      89           0 :                         goto done;
      90             :                 }
      91           0 :                 *dn = talloc_strdup(mem_ctx, tmp);
      92           0 :                 CHECK_ALLOC_DONE(*dn);
      93             :         } else {
      94           0 :                 if (!fetch_ldap_pw(&user_dn, &secret)) {
      95           0 :                         DEBUG(2, ("get_credentials: Failed to lookup ldap "
      96             :                                   "bind creds. Using anonymous connection.\n"));
      97           0 :                         anon = True;
      98           0 :                         *dn = NULL;
      99             :                 } else {
     100           0 :                         *dn = talloc_strdup(mem_ctx, user_dn);
     101           0 :                         SAFE_FREE( user_dn );
     102           0 :                         CHECK_ALLOC_DONE(*dn);
     103             :                 }
     104             :         }
     105             : 
     106           0 :         smbldap_set_creds(ldap_state, anon, *dn, secret);
     107           0 :         ret = NT_STATUS_OK;
     108             : 
     109           0 : done:
     110           0 :         BURN_FREE_STR(secret);
     111             : 
     112           0 :         return ret;
     113             : }
     114             : 
     115             : 
     116             : /**********************************************************************
     117             :  Verify the sambaUnixIdPool entry in the directory.
     118             : **********************************************************************/
     119             : 
     120           0 : static NTSTATUS verify_idpool(struct idmap_domain *dom)
     121             : {
     122           0 :         NTSTATUS ret;
     123           0 :         TALLOC_CTX *mem_ctx;
     124           0 :         LDAPMessage *result = NULL;
     125           0 :         LDAPMod **mods = NULL;
     126           0 :         const char **attr_list;
     127           0 :         char *filter;
     128           0 :         int count;
     129           0 :         int rc;
     130           0 :         struct idmap_ldap_context *ctx;
     131             : 
     132           0 :         ctx = talloc_get_type(dom->private_data, struct idmap_ldap_context);
     133             : 
     134           0 :         mem_ctx = talloc_new(ctx);
     135           0 :         if (mem_ctx == NULL) {
     136           0 :                 DEBUG(0, ("Out of memory!\n"));
     137           0 :                 return NT_STATUS_NO_MEMORY;
     138             :         }
     139             : 
     140           0 :         filter = talloc_asprintf(mem_ctx, "(objectclass=%s)", LDAP_OBJ_IDPOOL);
     141           0 :         CHECK_ALLOC_DONE(filter);
     142             : 
     143           0 :         attr_list = get_attr_list(mem_ctx, idpool_attr_list);
     144           0 :         CHECK_ALLOC_DONE(attr_list);
     145             : 
     146           0 :         rc = smbldap_search(ctx->smbldap_state,
     147           0 :                                 ctx->suffix,
     148             :                                 LDAP_SCOPE_SUBTREE,
     149             :                                 filter,
     150             :                                 attr_list,
     151             :                                 0,
     152             :                                 &result);
     153             : 
     154           0 :         if (rc != LDAP_SUCCESS) {
     155           0 :                 DEBUG(1, ("Unable to verify the idpool, "
     156             :                           "cannot continue initialization!\n"));
     157           0 :                 return NT_STATUS_UNSUCCESSFUL;
     158             :         }
     159             : 
     160           0 :         count = ldap_count_entries(smbldap_get_ldap(ctx->smbldap_state),
     161             :                                    result);
     162             : 
     163           0 :         ldap_msgfree(result);
     164             : 
     165           0 :         if ( count > 1 ) {
     166           0 :                 DEBUG(0,("Multiple entries returned from %s (base == %s)\n",
     167             :                         filter, ctx->suffix));
     168           0 :                 ret = NT_STATUS_UNSUCCESSFUL;
     169           0 :                 goto done;
     170             :         }
     171           0 :         else if (count == 0) {
     172           0 :                 char *uid_str, *gid_str;
     173             : 
     174           0 :                 uid_str = talloc_asprintf(mem_ctx, "%lu",
     175           0 :                                 (unsigned long)dom->low_id);
     176           0 :                 gid_str = talloc_asprintf(mem_ctx, "%lu",
     177           0 :                                 (unsigned long)dom->low_id);
     178             : 
     179           0 :                 smbldap_set_mod(&mods, LDAP_MOD_ADD,
     180             :                                 "objectClass", LDAP_OBJ_IDPOOL);
     181           0 :                 smbldap_set_mod(&mods, LDAP_MOD_ADD,
     182             :                                 get_attr_key2string(idpool_attr_list,
     183             :                                                     LDAP_ATTR_UIDNUMBER),
     184             :                                 uid_str);
     185           0 :                 smbldap_set_mod(&mods, LDAP_MOD_ADD,
     186             :                                 get_attr_key2string(idpool_attr_list,
     187             :                                                     LDAP_ATTR_GIDNUMBER),
     188             :                                 gid_str);
     189           0 :                 if (mods) {
     190           0 :                         rc = smbldap_modify(ctx->smbldap_state,
     191           0 :                                                 ctx->suffix,
     192             :                                                 mods);
     193           0 :                         ldap_mods_free(mods, True);
     194             :                 } else {
     195           0 :                         ret = NT_STATUS_UNSUCCESSFUL;
     196           0 :                         goto done;
     197             :                 }
     198             :         }
     199             : 
     200           0 :         ret = (rc == LDAP_SUCCESS)?NT_STATUS_OK:NT_STATUS_UNSUCCESSFUL;
     201           0 : done:
     202           0 :         talloc_free(mem_ctx);
     203           0 :         return ret;
     204             : }
     205             : 
     206             : /********************************
     207             :  Allocate a new uid or gid
     208             : ********************************/
     209             : 
     210           0 : static NTSTATUS idmap_ldap_allocate_id_internal(struct idmap_domain *dom,
     211             :                                                 struct unixid *xid)
     212             : {
     213           0 :         TALLOC_CTX *mem_ctx;
     214           0 :         NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
     215           0 :         int rc = LDAP_SERVER_DOWN;
     216           0 :         int count = 0;
     217           0 :         LDAPMessage *result = NULL;
     218           0 :         LDAPMessage *entry = NULL;
     219           0 :         LDAPMod **mods = NULL;
     220           0 :         char *id_str;
     221           0 :         char *new_id_str;
     222           0 :         char *filter = NULL;
     223           0 :         const char *dn = NULL;
     224           0 :         const char **attr_list;
     225           0 :         const char *type;
     226           0 :         struct idmap_ldap_context *ctx;
     227           0 :         int error = 0;
     228             : 
     229             :         /* Only do query if we are online */
     230           0 :         if (idmap_is_offline()) {
     231           0 :                 return NT_STATUS_FILE_IS_OFFLINE;
     232             :         }
     233             : 
     234           0 :         ctx = talloc_get_type(dom->private_data, struct idmap_ldap_context);
     235             : 
     236           0 :         mem_ctx = talloc_new(ctx);
     237           0 :         if (!mem_ctx) {
     238           0 :                 DEBUG(0, ("Out of memory!\n"));
     239           0 :                 return NT_STATUS_NO_MEMORY;
     240             :         }
     241             : 
     242             :         /* get type */
     243           0 :         switch (xid->type) {
     244             : 
     245           0 :         case ID_TYPE_UID:
     246           0 :                 type = get_attr_key2string(idpool_attr_list,
     247             :                                            LDAP_ATTR_UIDNUMBER);
     248           0 :                 break;
     249             : 
     250           0 :         case ID_TYPE_GID:
     251           0 :                 type = get_attr_key2string(idpool_attr_list,
     252             :                                            LDAP_ATTR_GIDNUMBER);
     253           0 :                 break;
     254             : 
     255           0 :         case ID_TYPE_BOTH:
     256             :                 /*
     257             :                  * This is not supported here yet and
     258             :                  * already handled in idmap_rw_new_mapping()
     259             :                  */
     260           0 :                 FALL_THROUGH;
     261             :         case ID_TYPE_NOT_SPECIFIED:
     262             :                 /*
     263             :                  * This is handled in idmap_rw_new_mapping()
     264             :                  */
     265           0 :                 FALL_THROUGH;
     266             :         default:
     267           0 :                 DEBUG(2, ("Invalid ID type (0x%x)\n", xid->type));
     268           0 :                 return NT_STATUS_INVALID_PARAMETER;
     269             :         }
     270             : 
     271           0 :         filter = talloc_asprintf(mem_ctx, "(objectClass=%s)", LDAP_OBJ_IDPOOL);
     272           0 :         CHECK_ALLOC_DONE(filter);
     273             : 
     274           0 :         attr_list = get_attr_list(mem_ctx, idpool_attr_list);
     275           0 :         CHECK_ALLOC_DONE(attr_list);
     276             : 
     277           0 :         DEBUG(10, ("Search of the id pool (filter: %s)\n", filter));
     278             : 
     279           0 :         rc = smbldap_search(ctx->smbldap_state,
     280           0 :                            ctx->suffix,
     281             :                            LDAP_SCOPE_SUBTREE, filter,
     282             :                            attr_list, 0, &result);
     283             : 
     284           0 :         if (rc != LDAP_SUCCESS) {
     285           0 :                 DEBUG(0,("%s object not found\n", LDAP_OBJ_IDPOOL));
     286           0 :                 goto done;
     287             :         }
     288             : 
     289           0 :         smbldap_talloc_autofree_ldapmsg(mem_ctx, result);
     290             : 
     291           0 :         count = ldap_count_entries(smbldap_get_ldap(ctx->smbldap_state),
     292             :                                    result);
     293           0 :         if (count != 1) {
     294           0 :                 DEBUG(0,("Single %s object not found\n", LDAP_OBJ_IDPOOL));
     295           0 :                 goto done;
     296             :         }
     297             : 
     298           0 :         entry = ldap_first_entry(smbldap_get_ldap(ctx->smbldap_state), result);
     299             : 
     300           0 :         dn = smbldap_talloc_dn(mem_ctx,
     301             :                                smbldap_get_ldap(ctx->smbldap_state),
     302             :                                entry);
     303           0 :         if ( ! dn) {
     304           0 :                 goto done;
     305             :         }
     306             : 
     307           0 :         id_str = smbldap_talloc_single_attribute(
     308             :                                 smbldap_get_ldap(ctx->smbldap_state),
     309             :                                 entry, type, mem_ctx);
     310           0 :         if (id_str == NULL) {
     311           0 :                 DEBUG(0,("%s attribute not found\n", type));
     312           0 :                 ret = NT_STATUS_UNSUCCESSFUL;
     313           0 :                 goto done;
     314             :         }
     315             : 
     316           0 :         xid->id = smb_strtoul(id_str, NULL, 10, &error, SMB_STR_STANDARD);
     317           0 :         if (error != 0) {
     318           0 :                 ret = NT_STATUS_UNSUCCESSFUL;
     319           0 :                 goto done;
     320             :         }
     321             : 
     322             :         /* make sure we still have room to grow */
     323             : 
     324           0 :         switch (xid->type) {
     325           0 :         case ID_TYPE_UID:
     326           0 :                 if (xid->id > dom->high_id) {
     327           0 :                         DEBUG(0,("Cannot allocate uid above %lu!\n",
     328             :                                  (unsigned long)dom->high_id));
     329           0 :                         goto done;
     330             :                 }
     331           0 :                 break;
     332             : 
     333           0 :         case ID_TYPE_GID:
     334           0 :                 if (xid->id > dom->high_id) {
     335           0 :                         DEBUG(0,("Cannot allocate gid above %lu!\n",
     336             :                                  (unsigned long)dom->high_id));
     337           0 :                         goto done;
     338             :                 }
     339           0 :                 break;
     340             : 
     341           0 :         default:
     342             :                 /* impossible */
     343           0 :                 goto done;
     344             :         }
     345             : 
     346           0 :         new_id_str = talloc_asprintf(mem_ctx, "%lu", (unsigned long)xid->id + 1);
     347           0 :         if ( ! new_id_str) {
     348           0 :                 DEBUG(0,("Out of memory\n"));
     349           0 :                 ret = NT_STATUS_NO_MEMORY;
     350           0 :                 goto done;
     351             :         }
     352             : 
     353           0 :         smbldap_set_mod(&mods, LDAP_MOD_DELETE, type, id_str);
     354           0 :         smbldap_set_mod(&mods, LDAP_MOD_ADD, type, new_id_str);
     355             : 
     356           0 :         if (mods == NULL) {
     357           0 :                 DEBUG(0,("smbldap_set_mod() failed.\n"));
     358           0 :                 goto done;
     359             :         }
     360             : 
     361           0 :         DEBUG(10, ("Try to atomically increment the id (%s -> %s)\n",
     362             :                    id_str, new_id_str));
     363             : 
     364           0 :         rc = smbldap_modify(ctx->smbldap_state, dn, mods);
     365             : 
     366           0 :         ldap_mods_free(mods, True);
     367             : 
     368           0 :         if (rc != LDAP_SUCCESS) {
     369           0 :                 DEBUG(1,("Failed to allocate new %s. "
     370             :                          "smbldap_modify() failed.\n", type));
     371           0 :                 goto done;
     372             :         }
     373             : 
     374           0 :         ret = NT_STATUS_OK;
     375             : 
     376           0 : done:
     377           0 :         talloc_free(mem_ctx);
     378           0 :         return ret;
     379             : }
     380             : 
     381             : /**
     382             :  * Allocate a new unix-ID.
     383             :  * For now this is for the default idmap domain only.
     384             :  * Should be extended later on.
     385             :  */
     386           0 : static NTSTATUS idmap_ldap_allocate_id(struct idmap_domain *dom,
     387             :                                        struct unixid *id)
     388             : {
     389           0 :         NTSTATUS ret;
     390             : 
     391           0 :         if (!strequal(dom->name, "*")) {
     392           0 :                 DEBUG(3, ("idmap_ldap_allocate_id: "
     393             :                           "Refusing allocation of a new unixid for domain'%s'. "
     394             :                           "This is only supported for the default "
     395             :                           "domain \"*\".\n",
     396             :                            dom->name));
     397           0 :                 return NT_STATUS_NOT_IMPLEMENTED;
     398             :         }
     399             : 
     400           0 :         ret = idmap_ldap_allocate_id_internal(dom, id);
     401             : 
     402           0 :         return ret;
     403             : }
     404             : 
     405             : 
     406             : /**********************************************************************
     407             :  IDMAP MAPPING LDAP BACKEND
     408             : **********************************************************************/
     409             : 
     410           0 : static int idmap_ldap_close_destructor(struct idmap_ldap_context *ctx)
     411             : {
     412           0 :         smbldap_free_struct(&ctx->smbldap_state);
     413           0 :         DEBUG(5,("The connection to the LDAP server was closed\n"));
     414             :         /* maybe free the results here --metze */
     415             : 
     416           0 :         return 0;
     417             : }
     418             : 
     419             : /********************************
     420             :  Initialise idmap database.
     421             : ********************************/
     422             : 
     423             : static NTSTATUS idmap_ldap_set_mapping(struct idmap_domain *dom,
     424             :                                        const struct id_map *map);
     425             : 
     426           0 : static NTSTATUS idmap_ldap_db_init(struct idmap_domain *dom)
     427             : {
     428           0 :         NTSTATUS ret;
     429           0 :         struct idmap_ldap_context *ctx = NULL;
     430           0 :         const char *tmp = NULL;
     431             : 
     432             :         /* Only do init if we are online */
     433           0 :         if (idmap_is_offline()) {
     434           0 :                 return NT_STATUS_FILE_IS_OFFLINE;
     435             :         }
     436             : 
     437           0 :         ctx = talloc_zero(dom, struct idmap_ldap_context);
     438           0 :         if ( ! ctx) {
     439           0 :                 DEBUG(0, ("Out of memory!\n"));
     440           0 :                 return NT_STATUS_NO_MEMORY;
     441             :         }
     442             : 
     443           0 :         tmp = idmap_config_const_string(dom->name, "ldap_url", NULL);
     444             : 
     445           0 :         if ( ! tmp) {
     446           0 :                 DEBUG(1, ("ERROR: missing idmap ldap url\n"));
     447           0 :                 ret = NT_STATUS_UNSUCCESSFUL;
     448           0 :                 goto done;
     449             :         }
     450             : 
     451           0 :         ctx->url = talloc_strdup(ctx, tmp);
     452             : 
     453           0 :         trim_char(ctx->url, '\"', '\"');
     454             : 
     455           0 :         tmp = idmap_config_const_string(dom->name, "ldap_base_dn", NULL);
     456           0 :         if ( ! tmp || ! *tmp) {
     457           0 :                 tmp = lp_ldap_idmap_suffix(talloc_tos());
     458           0 :                 if ( ! tmp) {
     459           0 :                         DEBUG(1, ("ERROR: missing idmap ldap suffix\n"));
     460           0 :                         ret = NT_STATUS_UNSUCCESSFUL;
     461           0 :                         goto done;
     462             :                 }
     463             :         }
     464             : 
     465           0 :         ctx->suffix = talloc_strdup(ctx, tmp);
     466           0 :         CHECK_ALLOC_DONE(ctx->suffix);
     467             : 
     468           0 :         ctx->rw_ops = talloc_zero(ctx, struct idmap_rw_ops);
     469           0 :         CHECK_ALLOC_DONE(ctx->rw_ops);
     470             : 
     471           0 :         ctx->rw_ops->get_new_id = idmap_ldap_allocate_id_internal;
     472           0 :         ctx->rw_ops->set_mapping = idmap_ldap_set_mapping;
     473             : 
     474             :         /* get_credentials deals with setting up creds */
     475             : 
     476           0 :         ret = smbldap_init(ctx, global_event_context(), ctx->url,
     477             :                            false, NULL, NULL, &ctx->smbldap_state);
     478           0 :         if (!NT_STATUS_IS_OK(ret)) {
     479           0 :                 DEBUG(1, ("ERROR: smbldap_init (%s) failed!\n", ctx->url));
     480           0 :                 goto done;
     481             :         }
     482             : 
     483           0 :         ret = get_credentials( ctx, ctx->smbldap_state,
     484             :                                dom, &ctx->user_dn );
     485           0 :         if ( !NT_STATUS_IS_OK(ret) ) {
     486           0 :                 DEBUG(1,("idmap_ldap_db_init: Failed to get connection "
     487             :                          "credentials (%s)\n", nt_errstr(ret)));
     488           0 :                 goto done;
     489             :         }
     490             : 
     491             :         /*
     492             :          * Set the destructor on the context, so that resources are
     493             :          * properly freed when the context is released.
     494             :          */
     495           0 :         talloc_set_destructor(ctx, idmap_ldap_close_destructor);
     496             : 
     497           0 :         dom->private_data = ctx;
     498             : 
     499           0 :         ret = verify_idpool(dom);
     500           0 :         if (!NT_STATUS_IS_OK(ret)) {
     501           0 :                 DEBUG(1, ("idmap_ldap_db_init: failed to verify ID pool (%s)\n",
     502             :                          nt_errstr(ret)));
     503           0 :                 goto done;
     504             :         }
     505             : 
     506           0 :         return NT_STATUS_OK;
     507             : 
     508             : /*failed */
     509           0 : done:
     510           0 :         talloc_free(ctx);
     511           0 :         return ret;
     512             : }
     513             : 
     514             : /**
     515             :  * set a mapping.
     516             :  */
     517             : 
     518             : /* TODO: change this:  This function cannot be called to modify a mapping,
     519             :  * only set a new one */
     520             : 
     521           0 : static NTSTATUS idmap_ldap_set_mapping(struct idmap_domain *dom,
     522             :                                        const struct id_map *map)
     523             : {
     524           0 :         NTSTATUS ret;
     525           0 :         TALLOC_CTX *memctx;
     526           0 :         struct idmap_ldap_context *ctx;
     527           0 :         LDAPMessage *entry = NULL;
     528           0 :         LDAPMod **mods = NULL;
     529           0 :         const char *type;
     530           0 :         char *id_str;
     531           0 :         struct dom_sid_buf sid;
     532           0 :         char *dn;
     533           0 :         int rc = -1;
     534             : 
     535             :         /* Only do query if we are online */
     536           0 :         if (idmap_is_offline()) {
     537           0 :                 return NT_STATUS_FILE_IS_OFFLINE;
     538             :         }
     539             : 
     540           0 :         ctx = talloc_get_type(dom->private_data, struct idmap_ldap_context);
     541             : 
     542           0 :         switch(map->xid.type) {
     543           0 :         case ID_TYPE_UID:
     544           0 :                 type = get_attr_key2string(sidmap_attr_list,
     545             :                                            LDAP_ATTR_UIDNUMBER);
     546           0 :                 break;
     547             : 
     548           0 :         case ID_TYPE_GID:
     549           0 :                 type = get_attr_key2string(sidmap_attr_list,
     550             :                                            LDAP_ATTR_GIDNUMBER);
     551           0 :                 break;
     552             : 
     553           0 :         default:
     554           0 :                 return NT_STATUS_INVALID_PARAMETER;
     555             :         }
     556             : 
     557           0 :         memctx = talloc_new(ctx);
     558           0 :         if ( ! memctx) {
     559           0 :                 DEBUG(0, ("Out of memory!\n"));
     560           0 :                 return NT_STATUS_NO_MEMORY;
     561             :         }
     562             : 
     563           0 :         id_str = talloc_asprintf(memctx, "%lu", (unsigned long)map->xid.id);
     564           0 :         CHECK_ALLOC_DONE(id_str);
     565             : 
     566           0 :         dn = talloc_asprintf(memctx, "%s=%s,%s",
     567             :                         get_attr_key2string(sidmap_attr_list, LDAP_ATTR_SID),
     568           0 :                         dom_sid_str_buf(map->sid, &sid),
     569             :                         ctx->suffix);
     570           0 :         CHECK_ALLOC_DONE(dn);
     571             : 
     572           0 :         smbldap_set_mod(&mods, LDAP_MOD_ADD,
     573             :                         "objectClass", LDAP_OBJ_IDMAP_ENTRY);
     574             : 
     575           0 :         smbldap_make_mod(smbldap_get_ldap(ctx->smbldap_state),
     576             :                          entry, &mods, type, id_str);
     577             : 
     578           0 :         smbldap_make_mod(smbldap_get_ldap(ctx->smbldap_state), entry, &mods,
     579             :                          get_attr_key2string(sidmap_attr_list, LDAP_ATTR_SID),
     580             :                          sid.buf);
     581             : 
     582           0 :         if ( ! mods) {
     583           0 :                 DEBUG(2, ("ERROR: No mods?\n"));
     584           0 :                 ret = NT_STATUS_UNSUCCESSFUL;
     585           0 :                 goto done;
     586             :         }
     587             : 
     588             :         /* TODO: remove conflicting mappings! */
     589             : 
     590           0 :         smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_SID_ENTRY);
     591             : 
     592           0 :         DEBUG(10, ("Set DN %s (%s -> %s)\n", dn, sid.buf, id_str));
     593             : 
     594           0 :         rc = smbldap_add(ctx->smbldap_state, dn, mods);
     595           0 :         ldap_mods_free(mods, True);
     596             : 
     597           0 :         if (rc != LDAP_SUCCESS) {
     598           0 :                 char *ld_error = NULL;
     599           0 :                 ldap_get_option(smbldap_get_ldap(ctx->smbldap_state),
     600             :                                 LDAP_OPT_ERROR_STRING, &ld_error);
     601           0 :                 DEBUG(0,("ldap_set_mapping_internals: Failed to add %s to %lu "
     602             :                          "mapping [%s]\n", sid.buf,
     603             :                          (unsigned long)map->xid.id, type));
     604           0 :                 DEBUG(0, ("ldap_set_mapping_internals: Error was: %s (%s)\n",
     605             :                         ld_error ? ld_error : "(NULL)", ldap_err2string (rc)));
     606           0 :                 if (ld_error) {
     607           0 :                         ldap_memfree(ld_error);
     608             :                 }
     609           0 :                 ret = NT_STATUS_UNSUCCESSFUL;
     610           0 :                 goto done;
     611             :         }
     612             : 
     613           0 :         DEBUG(10,("ldap_set_mapping: Successfully created mapping from %s to "
     614             :                   "%lu [%s]\n",       sid.buf, (unsigned long)map->xid.id, type));
     615             : 
     616           0 :         ret = NT_STATUS_OK;
     617             : 
     618           0 : done:
     619           0 :         talloc_free(memctx);
     620           0 :         return ret;
     621             : }
     622             : 
     623             : /**
     624             :  * Create a new mapping for an unmapped SID, also allocating a new ID.
     625             :  * If possible, this should be run inside a transaction to make the
     626             :  * action atomic.
     627             :  */
     628           0 : static NTSTATUS idmap_ldap_new_mapping(struct idmap_domain *dom, struct id_map *map)
     629             : {
     630           0 :         NTSTATUS ret;
     631           0 :         struct idmap_ldap_context *ctx;
     632             : 
     633           0 :         ctx = talloc_get_type(dom->private_data, struct idmap_ldap_context);
     634             : 
     635           0 :         ret = idmap_rw_new_mapping(dom, ctx->rw_ops, map);
     636             : 
     637           0 :         return ret;
     638             : }
     639             : 
     640             : /**********************************
     641             :  lookup a set of unix ids.
     642             : **********************************/
     643             : 
     644           0 : static NTSTATUS idmap_ldap_unixids_to_sids(struct idmap_domain *dom,
     645             :                                            struct id_map **ids)
     646             : {
     647           0 :         NTSTATUS ret;
     648           0 :         TALLOC_CTX *memctx;
     649           0 :         struct idmap_ldap_context *ctx;
     650           0 :         LDAPMessage *result = NULL;
     651           0 :         LDAPMessage *entry = NULL;
     652           0 :         const char *uidNumber;
     653           0 :         const char *gidNumber;
     654           0 :         const char **attr_list;
     655           0 :         char *filter = NULL;
     656           0 :         bool multi = False;
     657           0 :         int idx = 0;
     658           0 :         int bidx = 0;
     659           0 :         int count;
     660           0 :         int rc;
     661           0 :         int i;
     662           0 :         int error = 0;
     663             : 
     664             :         /* Only do query if we are online */
     665           0 :         if (idmap_is_offline()) {
     666           0 :                 return NT_STATUS_FILE_IS_OFFLINE;
     667             :         }
     668             : 
     669           0 :         ctx = talloc_get_type(dom->private_data, struct idmap_ldap_context);
     670             : 
     671           0 :         memctx = talloc_new(ctx);
     672           0 :         if ( ! memctx) {
     673           0 :                 DEBUG(0, ("Out of memory!\n"));
     674           0 :                 return NT_STATUS_NO_MEMORY;
     675             :         }
     676             : 
     677           0 :         uidNumber = get_attr_key2string(idpool_attr_list, LDAP_ATTR_UIDNUMBER);
     678           0 :         gidNumber = get_attr_key2string(idpool_attr_list, LDAP_ATTR_GIDNUMBER);
     679             : 
     680           0 :         attr_list = get_attr_list(memctx, sidmap_attr_list);
     681             : 
     682           0 :         if ( ! ids[1]) {
     683             :                 /* if we are requested just one mapping use the simple filter */
     684             : 
     685           0 :                 filter = talloc_asprintf(memctx, "(&(objectClass=%s)(%s=%lu))",
     686             :                                 LDAP_OBJ_IDMAP_ENTRY,
     687           0 :                                 (ids[0]->xid.type==ID_TYPE_UID)?uidNumber:gidNumber,
     688           0 :                                 (unsigned long)ids[0]->xid.id);
     689           0 :                 CHECK_ALLOC_DONE(filter);
     690           0 :                 DEBUG(10, ("Filter: [%s]\n", filter));
     691             :         } else {
     692             :                 /* multiple mappings */
     693           0 :                 multi = True;
     694             :         }
     695             : 
     696           0 :         for (i = 0; ids[i]; i++) {
     697           0 :                 ids[i]->status = ID_UNKNOWN;
     698             :         }
     699             : 
     700           0 : again:
     701           0 :         if (multi) {
     702             : 
     703           0 :                 talloc_free(filter);
     704           0 :                 filter = talloc_asprintf(memctx,
     705             :                                          "(&(objectClass=%s)(|",
     706             :                                          LDAP_OBJ_IDMAP_ENTRY);
     707           0 :                 CHECK_ALLOC_DONE(filter);
     708             : 
     709           0 :                 bidx = idx;
     710           0 :                 for (i = 0; (i < IDMAP_LDAP_MAX_IDS) && ids[idx]; i++, idx++) {
     711           0 :                         filter = talloc_asprintf_append_buffer(filter, "(%s=%lu)",
     712           0 :                                         (ids[idx]->xid.type==ID_TYPE_UID)?uidNumber:gidNumber,
     713           0 :                                         (unsigned long)ids[idx]->xid.id);
     714           0 :                         CHECK_ALLOC_DONE(filter);
     715             :                 }
     716           0 :                 filter = talloc_asprintf_append_buffer(filter, "))");
     717           0 :                 CHECK_ALLOC_DONE(filter);
     718           0 :                 DEBUG(10, ("Filter: [%s]\n", filter));
     719             :         } else {
     720           0 :                 bidx = 0;
     721           0 :                 idx = 1;
     722             :         }
     723             : 
     724           0 :         rc = smbldap_search(ctx->smbldap_state, ctx->suffix, LDAP_SCOPE_SUBTREE,
     725             :                 filter, attr_list, 0, &result);
     726             : 
     727           0 :         if (rc != LDAP_SUCCESS) {
     728           0 :                 DEBUG(3,("Failure looking up ids (%s)\n", ldap_err2string(rc)));
     729           0 :                 ret = NT_STATUS_UNSUCCESSFUL;
     730           0 :                 goto done;
     731             :         }
     732             : 
     733           0 :         count = ldap_count_entries(smbldap_get_ldap(ctx->smbldap_state),
     734             :                                    result);
     735             : 
     736           0 :         if (count == 0) {
     737           0 :                 DEBUG(10, ("NO SIDs found\n"));
     738             :         }
     739             : 
     740           0 :         for (i = 0; i < count; i++) {
     741           0 :                 char *sidstr = NULL;
     742           0 :                 char *tmp = NULL;
     743           0 :                 enum id_type type;
     744           0 :                 struct id_map *map;
     745           0 :                 uint32_t id;
     746           0 :                 struct dom_sid_buf buf;
     747             : 
     748           0 :                 if (i == 0) { /* first entry */
     749           0 :                         entry = ldap_first_entry(
     750             :                                 smbldap_get_ldap(ctx->smbldap_state), result);
     751             :                 } else { /* following ones */
     752           0 :                         entry = ldap_next_entry(
     753             :                                 smbldap_get_ldap(ctx->smbldap_state), entry);
     754             :                 }
     755           0 :                 if ( ! entry) {
     756           0 :                         DEBUG(2, ("ERROR: Unable to fetch ldap entries "
     757             :                                   "from results\n"));
     758           0 :                         break;
     759             :                 }
     760             : 
     761             :                 /* first check if the SID is present */
     762           0 :                 sidstr = smbldap_talloc_single_attribute(
     763             :                                 smbldap_get_ldap(ctx->smbldap_state),
     764             :                                 entry, LDAP_ATTRIBUTE_SID, memctx);
     765           0 :                 if ( ! sidstr) { /* no sid, skip entry */
     766           0 :                         DEBUG(2, ("WARNING SID not found on entry\n"));
     767           0 :                         continue;
     768             :                 }
     769             : 
     770             :                 /* now try to see if it is a uid, if not try with a gid
     771             :                  * (gid is more common, but in case both uidNumber and
     772             :                  * gidNumber are returned the SID is mapped to the uid
     773             :                  *not the gid) */
     774           0 :                 type = ID_TYPE_UID;
     775           0 :                 tmp = smbldap_talloc_single_attribute(
     776             :                                 smbldap_get_ldap(ctx->smbldap_state),
     777             :                                 entry, uidNumber, memctx);
     778           0 :                 if ( ! tmp) {
     779           0 :                         type = ID_TYPE_GID;
     780           0 :                         tmp = smbldap_talloc_single_attribute(
     781             :                                         smbldap_get_ldap(ctx->smbldap_state),
     782             :                                         entry, gidNumber, memctx);
     783             :                 }
     784           0 :                 if ( ! tmp) { /* wow very strange entry, how did it match ? */
     785           0 :                         DEBUG(5, ("Improbable match on (%s), no uidNumber, "
     786             :                                   "nor gidNumber returned\n", sidstr));
     787           0 :                         TALLOC_FREE(sidstr);
     788           0 :                         continue;
     789             :                 }
     790             : 
     791           0 :                 id = smb_strtoul(tmp, NULL, 10, &error, SMB_STR_STANDARD);
     792           0 :                 TALLOC_FREE(tmp);
     793           0 :                 if (error != 0) {
     794           0 :                         DEBUG(5, ("Requested id (%u) out of range (%u - %u). "
     795             :                                   "Filtered!\n", id,
     796             :                                   dom->low_id, dom->high_id));
     797           0 :                         TALLOC_FREE(sidstr);
     798           0 :                         continue;
     799             :                 }
     800             : 
     801           0 :                 if (!idmap_unix_id_is_in_range(id, dom)) {
     802           0 :                         DEBUG(5, ("Requested id (%u) out of range (%u - %u). "
     803             :                                   "Filtered!\n", id,
     804             :                                   dom->low_id, dom->high_id));
     805           0 :                         TALLOC_FREE(sidstr);
     806           0 :                         continue;
     807             :                 }
     808             : 
     809           0 :                 map = idmap_find_map_by_id(&ids[bidx], type, id);
     810           0 :                 if (!map) {
     811           0 :                         DEBUG(2, ("WARNING: couldn't match sid (%s) "
     812             :                                   "with requested ids\n", sidstr));
     813           0 :                         TALLOC_FREE(sidstr);
     814           0 :                         continue;
     815             :                 }
     816             : 
     817           0 :                 if ( ! string_to_sid(map->sid, sidstr)) {
     818           0 :                         DEBUG(2, ("ERROR: Invalid SID on entry\n"));
     819           0 :                         TALLOC_FREE(sidstr);
     820           0 :                         continue;
     821             :                 }
     822             : 
     823           0 :                 if (map->status == ID_MAPPED) {
     824           0 :                         DEBUG(1, ("WARNING: duplicate %s mapping in LDAP. "
     825             :                               "overwriting mapping %u -> %s with %u -> %s\n",
     826             :                               (type == ID_TYPE_UID) ? "UID" : "GID",
     827             :                               id,
     828             :                               dom_sid_str_buf(map->sid, &buf),
     829             :                               id,
     830             :                               sidstr));
     831             :                 }
     832             : 
     833           0 :                 TALLOC_FREE(sidstr);
     834             : 
     835             :                 /* mapped */
     836           0 :                 map->status = ID_MAPPED;
     837             : 
     838           0 :                 DEBUG(10, ("Mapped %s -> %lu (%d)\n",
     839             :                            dom_sid_str_buf(map->sid, &buf),
     840             :                            (unsigned long)map->xid.id, map->xid.type));
     841             :         }
     842             : 
     843             :         /* free the ldap results */
     844           0 :         if (result) {
     845           0 :                 ldap_msgfree(result);
     846           0 :                 result = NULL;
     847             :         }
     848             : 
     849           0 :         if (multi && ids[idx]) { /* still some values to map */
     850           0 :                 goto again;
     851             :         }
     852             : 
     853           0 :         ret = NT_STATUS_OK;
     854             : 
     855             :         /* mark all unknown/expired ones as unmapped */
     856           0 :         for (i = 0; ids[i]; i++) {
     857           0 :                 if (ids[i]->status != ID_MAPPED)
     858           0 :                         ids[i]->status = ID_UNMAPPED;
     859             :         }
     860             : 
     861           0 : done:
     862           0 :         talloc_free(memctx);
     863           0 :         return ret;
     864             : }
     865             : 
     866             : /**********************************
     867             :  lookup a set of sids.
     868             : **********************************/
     869             : 
     870           0 : static NTSTATUS idmap_ldap_sids_to_unixids(struct idmap_domain *dom,
     871             :                                            struct id_map **ids)
     872             : {
     873           0 :         LDAPMessage *entry = NULL;
     874           0 :         NTSTATUS ret;
     875           0 :         TALLOC_CTX *memctx;
     876           0 :         struct idmap_ldap_context *ctx;
     877           0 :         LDAPMessage *result = NULL;
     878           0 :         const char *uidNumber;
     879           0 :         const char *gidNumber;
     880           0 :         const char **attr_list;
     881           0 :         char *filter = NULL;
     882           0 :         bool multi = False;
     883           0 :         size_t num_required = 0;
     884           0 :         int idx = 0;
     885           0 :         int bidx = 0;
     886           0 :         int count;
     887           0 :         int rc;
     888           0 :         int i;
     889             : 
     890             :         /* Only do query if we are online */
     891           0 :         if (idmap_is_offline()) {
     892           0 :                 return NT_STATUS_FILE_IS_OFFLINE;
     893             :         }
     894             : 
     895           0 :         ctx = talloc_get_type(dom->private_data, struct idmap_ldap_context);
     896             : 
     897           0 :         memctx = talloc_new(ctx);
     898           0 :         if ( ! memctx) {
     899           0 :                 DEBUG(0, ("Out of memory!\n"));
     900           0 :                 return NT_STATUS_NO_MEMORY;
     901             :         }
     902             : 
     903           0 :         uidNumber = get_attr_key2string(idpool_attr_list, LDAP_ATTR_UIDNUMBER);
     904           0 :         gidNumber = get_attr_key2string(idpool_attr_list, LDAP_ATTR_GIDNUMBER);
     905             : 
     906           0 :         attr_list = get_attr_list(memctx, sidmap_attr_list);
     907             : 
     908           0 :         if ( ! ids[1]) {
     909           0 :                 struct dom_sid_buf buf;
     910             :                 /* if we are requested just one mapping use the simple filter */
     911             : 
     912           0 :                 filter = talloc_asprintf(memctx, "(&(objectClass=%s)(%s=%s))",
     913             :                                 LDAP_OBJ_IDMAP_ENTRY,
     914             :                                 LDAP_ATTRIBUTE_SID,
     915           0 :                                 dom_sid_str_buf(ids[0]->sid, &buf));
     916           0 :                 CHECK_ALLOC_DONE(filter);
     917           0 :                 DEBUG(10, ("Filter: [%s]\n", filter));
     918             :         } else {
     919             :                 /* multiple mappings */
     920           0 :                 multi = True;
     921             :         }
     922             : 
     923           0 :         for (i = 0; ids[i]; i++) {
     924           0 :                 ids[i]->status = ID_UNKNOWN;
     925             :         }
     926             : 
     927           0 : again:
     928           0 :         if (multi) {
     929             : 
     930           0 :                 TALLOC_FREE(filter);
     931           0 :                 filter = talloc_asprintf(memctx,
     932             :                                          "(&(objectClass=%s)(|",
     933             :                                          LDAP_OBJ_IDMAP_ENTRY);
     934           0 :                 CHECK_ALLOC_DONE(filter);
     935             : 
     936           0 :                 bidx = idx;
     937           0 :                 for (i = 0; (i < IDMAP_LDAP_MAX_IDS) && ids[idx]; i++, idx++) {
     938           0 :                         struct dom_sid_buf buf;
     939           0 :                         filter = talloc_asprintf_append_buffer(filter, "("LDAP_ATTRIBUTE_SID"=%s)",
     940           0 :                                         dom_sid_str_buf(ids[idx]->sid, &buf));
     941           0 :                         CHECK_ALLOC_DONE(filter);
     942             :                 }
     943           0 :                 filter = talloc_asprintf_append_buffer(filter, "))");
     944           0 :                 CHECK_ALLOC_DONE(filter);
     945           0 :                 DEBUG(10, ("Filter: [%s]\n", filter));
     946             :         } else {
     947           0 :                 bidx = 0;
     948           0 :                 idx = 1;
     949             :         }
     950             : 
     951           0 :         rc = smbldap_search(ctx->smbldap_state, ctx->suffix, LDAP_SCOPE_SUBTREE,
     952             :                 filter, attr_list, 0, &result);
     953             : 
     954           0 :         if (rc != LDAP_SUCCESS) {
     955           0 :                 DEBUG(3,("Failure looking up sids (%s)\n",
     956             :                          ldap_err2string(rc)));
     957           0 :                 ret = NT_STATUS_UNSUCCESSFUL;
     958           0 :                 goto done;
     959             :         }
     960             : 
     961           0 :         count = ldap_count_entries(smbldap_get_ldap(ctx->smbldap_state),
     962             :                                    result);
     963             : 
     964           0 :         if (count == 0) {
     965           0 :                 DEBUG(10, ("NO SIDs found\n"));
     966             :         }
     967             : 
     968           0 :         for (i = 0; i < count; i++) {
     969           0 :                 char *sidstr = NULL;
     970           0 :                 char *tmp = NULL;
     971           0 :                 enum id_type type;
     972           0 :                 struct id_map *map;
     973           0 :                 struct dom_sid sid;
     974           0 :                 struct dom_sid_buf buf;
     975           0 :                 uint32_t id;
     976           0 :                 int error = 0;
     977             : 
     978           0 :                 if (i == 0) { /* first entry */
     979           0 :                         entry = ldap_first_entry(
     980             :                                 smbldap_get_ldap(ctx->smbldap_state), result);
     981             :                 } else { /* following ones */
     982           0 :                         entry = ldap_next_entry(
     983             :                                 smbldap_get_ldap(ctx->smbldap_state), entry);
     984             :                 }
     985           0 :                 if ( ! entry) {
     986           0 :                         DEBUG(2, ("ERROR: Unable to fetch ldap entries "
     987             :                                   "from results\n"));
     988           0 :                         break;
     989             :                 }
     990             : 
     991             :                 /* first check if the SID is present */
     992           0 :                 sidstr = smbldap_talloc_single_attribute(
     993             :                                 smbldap_get_ldap(ctx->smbldap_state),
     994             :                                 entry, LDAP_ATTRIBUTE_SID, memctx);
     995           0 :                 if ( ! sidstr) { /* no sid ??, skip entry */
     996           0 :                         DEBUG(2, ("WARNING SID not found on entry\n"));
     997           0 :                         continue;
     998             :                 }
     999             : 
    1000           0 :                 if ( ! string_to_sid(&sid, sidstr)) {
    1001           0 :                         DEBUG(2, ("ERROR: Invalid SID on entry\n"));
    1002           0 :                         TALLOC_FREE(sidstr);
    1003           0 :                         continue;
    1004             :                 }
    1005             : 
    1006           0 :                 map = idmap_find_map_by_sid(&ids[bidx], &sid);
    1007           0 :                 if (!map) {
    1008           0 :                         DEBUG(2, ("WARNING: couldn't find entry sid (%s) "
    1009             :                                   "in ids\n", sidstr));
    1010           0 :                         TALLOC_FREE(sidstr);
    1011           0 :                         continue;
    1012             :                 }
    1013             : 
    1014             :                 /* now try to see if it is a uid, if not try with a gid
    1015             :                  * (gid is more common, but in case both uidNumber and
    1016             :                  * gidNumber are returned the SID is mapped to the uid
    1017             :                  * not the gid) */
    1018           0 :                 type = ID_TYPE_UID;
    1019           0 :                 tmp = smbldap_talloc_single_attribute(
    1020             :                                 smbldap_get_ldap(ctx->smbldap_state),
    1021             :                                 entry, uidNumber, memctx);
    1022           0 :                 if ( ! tmp) {
    1023           0 :                         type = ID_TYPE_GID;
    1024           0 :                         tmp = smbldap_talloc_single_attribute(
    1025             :                                         smbldap_get_ldap(ctx->smbldap_state),
    1026             :                                         entry, gidNumber, memctx);
    1027             :                 }
    1028           0 :                 if ( ! tmp) { /* no ids ?? */
    1029           0 :                         DEBUG(5, ("no uidNumber, "
    1030             :                                   "nor gidNumber attributes found\n"));
    1031           0 :                         TALLOC_FREE(sidstr);
    1032           0 :                         continue;
    1033             :                 }
    1034             : 
    1035           0 :                 id = smb_strtoul(tmp, NULL, 10, &error, SMB_STR_STANDARD);
    1036           0 :                 TALLOC_FREE(tmp);
    1037           0 :                 if (error != 0) {
    1038           0 :                         DEBUG(5, ("Requested id (%u) out of range (%u - %u). "
    1039             :                                   "Filtered!\n", id,
    1040             :                                   dom->low_id, dom->high_id));
    1041           0 :                         TALLOC_FREE(sidstr);
    1042           0 :                         continue;
    1043             :                 }
    1044             : 
    1045           0 :                 if (error != 0 || !idmap_unix_id_is_in_range(id, dom)) {
    1046           0 :                         DEBUG(5, ("Requested id (%u) out of range (%u - %u). "
    1047             :                                   "Filtered!\n", id,
    1048             :                                   dom->low_id, dom->high_id));
    1049           0 :                         TALLOC_FREE(sidstr);
    1050           0 :                         continue;
    1051             :                 }
    1052             : 
    1053           0 :                 if (map->status == ID_MAPPED) {
    1054           0 :                         DEBUG(1, ("WARNING: duplicate %s mapping in LDAP. "
    1055             :                               "overwriting mapping %s -> %u with %s -> %u\n",
    1056             :                               (type == ID_TYPE_UID) ? "UID" : "GID",
    1057             :                               sidstr, map->xid.id, sidstr, id));
    1058             :                 }
    1059             : 
    1060           0 :                 TALLOC_FREE(sidstr);
    1061             : 
    1062             :                 /* mapped */
    1063           0 :                 map->xid.type = type;
    1064           0 :                 map->xid.id = id;
    1065           0 :                 map->status = ID_MAPPED;
    1066             : 
    1067           0 :                 DEBUG(10, ("Mapped %s -> %lu (%d)\n",
    1068             :                            dom_sid_str_buf(map->sid, &buf),
    1069             :                            (unsigned long)map->xid.id,
    1070             :                            map->xid.type));
    1071             :         }
    1072             : 
    1073             :         /* free the ldap results */
    1074           0 :         if (result) {
    1075           0 :                 ldap_msgfree(result);
    1076           0 :                 result = NULL;
    1077             :         }
    1078             : 
    1079           0 :         if (multi && ids[idx]) { /* still some values to map */
    1080           0 :                 goto again;
    1081             :         }
    1082             : 
    1083             :         /*
    1084             :          *  try to create new mappings for unmapped sids
    1085             :          */
    1086           0 :         for (i = 0; ids[i]; i++) {
    1087           0 :                 if (ids[i]->status != ID_MAPPED) {
    1088           0 :                         ids[i]->status = ID_UNMAPPED;
    1089           0 :                         if (ids[i]->sid != NULL) {
    1090           0 :                                 ret = idmap_ldap_new_mapping(dom, ids[i]);
    1091           0 :                                 DBG_DEBUG("idmap_ldap_new_mapping returned %s\n",
    1092             :                                           nt_errstr(ret));
    1093           0 :                                 if (NT_STATUS_EQUAL(ret, STATUS_SOME_UNMAPPED)) {
    1094           0 :                                         if (ids[i]->status == ID_REQUIRE_TYPE) {
    1095           0 :                                                 num_required += 1;
    1096           0 :                                                 continue;
    1097             :                                         }
    1098             :                                 }
    1099           0 :                                 if (!NT_STATUS_IS_OK(ret)) {
    1100             :                                         /*
    1101             :                                          * If we can't create
    1102             :                                          * a new mapping it's unlikely
    1103             :                                          * that it will work for the
    1104             :                                          * next entry.
    1105             :                                          */
    1106           0 :                                         goto done;
    1107             :                                 }
    1108             :                         }
    1109             :                 }
    1110             :         }
    1111             : 
    1112           0 :         ret = NT_STATUS_OK;
    1113           0 :         if (num_required > 0) {
    1114           0 :                 ret = STATUS_SOME_UNMAPPED;
    1115             :         }
    1116             : 
    1117           0 : done:
    1118           0 :         talloc_free(memctx);
    1119           0 :         return ret;
    1120             : }
    1121             : 
    1122             : /**********************************
    1123             :  Close the idmap ldap instance
    1124             : **********************************/
    1125             : 
    1126             : static const struct idmap_methods idmap_ldap_methods = {
    1127             : 
    1128             :         .init = idmap_ldap_db_init,
    1129             :         .unixids_to_sids = idmap_ldap_unixids_to_sids,
    1130             :         .sids_to_unixids = idmap_ldap_sids_to_unixids,
    1131             :         .allocate_id = idmap_ldap_allocate_id,
    1132             : };
    1133             : 
    1134             : NTSTATUS idmap_ldap_init(TALLOC_CTX *);
    1135           0 : NTSTATUS idmap_ldap_init(TALLOC_CTX *ctx)
    1136             : {
    1137           0 :         return smb_register_idmap(SMB_IDMAP_INTERFACE_VERSION, "ldap",
    1138             :                                   &idmap_ldap_methods);
    1139             : }
    1140             : 

Generated by: LCOV version 1.14