LCOV - code coverage report
Current view: top level - source3/winbindd - idmap_tdb2.c (source / functions) Hit Total Coverage
Test: coverage report for fix-15632 9995c5c2 Lines: 0 249 0.0 %
Date: 2024-04-13 12:30:31 Functions: 0 9 0.0 %

          Line data    Source code
       1             : /*
       2             :    Unix SMB/CIFS implementation.
       3             : 
       4             :    idmap TDB2 backend, used for clustered Samba setups.
       5             : 
       6             :    This uses dbwrap to access tdb files. The location can be set
       7             :    using tdb:idmap2.tdb =" in smb.conf
       8             : 
       9             :    Copyright (C) Andrew Tridgell 2007
      10             : 
      11             :    This is heavily based upon idmap_tdb.c, which is:
      12             : 
      13             :    Copyright (C) Tim Potter 2000
      14             :    Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003
      15             :    Copyright (C) Jeremy Allison 2006
      16             :    Copyright (C) Simo Sorce 2003-2006
      17             :    Copyright (C) Michael Adam 2009-2010
      18             : 
      19             :    This program is free software; you can redistribute it and/or modify
      20             :    it under the terms of the GNU General Public License as published by
      21             :    the Free Software Foundation; either version 2 of the License, or
      22             :    (at your option) any later version.
      23             : 
      24             :    This program is distributed in the hope that it will be useful,
      25             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      26             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      27             :    GNU General Public License for more details.
      28             : 
      29             :    You should have received a copy of the GNU General Public License
      30             :    along with this program; if not, write to the Free Software
      31             :    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
      32             : */
      33             : 
      34             : #include "includes.h"
      35             : #include "system/filesys.h"
      36             : #include "winbindd.h"
      37             : #include "idmap.h"
      38             : #include "idmap_rw.h"
      39             : #include "dbwrap/dbwrap.h"
      40             : #include "dbwrap/dbwrap_open.h"
      41             : #include "../libcli/security/dom_sid.h"
      42             : #include "util_tdb.h"
      43             : #include "idmap_tdb_common.h"
      44             : 
      45             : #undef DBGC_CLASS
      46             : #define DBGC_CLASS DBGC_IDMAP
      47             : 
      48             : struct idmap_tdb2_context {
      49             :         const char *script; /* script to provide idmaps */
      50             : };
      51             : 
      52             : /* High water mark keys */
      53             : #define HWM_GROUP  "GROUP HWM"
      54             : #define HWM_USER   "USER HWM"
      55             : 
      56             : /*
      57             :  * check and initialize high/low water marks in the db
      58             :  */
      59           0 : static NTSTATUS idmap_tdb2_init_hwm(struct idmap_domain *dom)
      60             : {
      61             :         NTSTATUS status;
      62             :         uint32_t low_id;
      63             :         struct idmap_tdb_common_context *ctx;
      64             : 
      65           0 :         ctx = talloc_get_type(dom->private_data,
      66             :                               struct idmap_tdb_common_context);
      67             : 
      68             :         /* Create high water marks for group and user id */
      69             : 
      70           0 :         status = dbwrap_fetch_uint32_bystring(ctx->db, HWM_USER, &low_id);
      71           0 :         if (!NT_STATUS_IS_OK(status) || (low_id < dom->low_id)) {
      72           0 :                 status = dbwrap_trans_store_uint32_bystring(ctx->db, HWM_USER,
      73             :                                                             dom->low_id);
      74           0 :                 if (!NT_STATUS_IS_OK(status)) {
      75           0 :                         DEBUG(0, ("Unable to initialise user hwm in idmap "
      76             :                                   "database: %s\n", nt_errstr(status)));
      77           0 :                         return NT_STATUS_INTERNAL_DB_ERROR;
      78             :                 }
      79             :         }
      80             : 
      81           0 :         status = dbwrap_fetch_uint32_bystring(ctx->db, HWM_GROUP, &low_id);
      82           0 :         if (!NT_STATUS_IS_OK(status) || (low_id < dom->low_id)) {
      83           0 :                 status = dbwrap_trans_store_uint32_bystring(ctx->db, HWM_GROUP,
      84             :                                                             dom->low_id);
      85           0 :                 if (!NT_STATUS_IS_OK(status)) {
      86           0 :                         DEBUG(0, ("Unable to initialise group hwm in idmap "
      87             :                                   "database: %s\n", nt_errstr(status)));
      88           0 :                         return NT_STATUS_INTERNAL_DB_ERROR;
      89             :                 }
      90             :         }
      91             : 
      92           0 :         return NT_STATUS_OK;
      93             : }
      94             : 
      95             : 
      96             : /*
      97             :   open the permanent tdb
      98             :  */
      99           0 : static NTSTATUS idmap_tdb2_open_db(struct idmap_domain *dom)
     100             : {
     101             :         char *db_path;
     102             :         struct idmap_tdb_common_context *ctx;
     103             : 
     104           0 :         ctx = talloc_get_type(dom->private_data,
     105             :                               struct idmap_tdb_common_context);
     106             : 
     107           0 :         if (ctx->db) {
     108             :                 /* its already open */
     109           0 :                 return NT_STATUS_OK;
     110             :         }
     111             : 
     112           0 :         db_path = talloc_asprintf(NULL, "%s/idmap2.tdb", lp_private_dir());
     113           0 :         NT_STATUS_HAVE_NO_MEMORY(db_path);
     114             : 
     115             :         /* Open idmap repository */
     116           0 :         ctx->db = db_open(ctx, db_path, 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0644,
     117             :                           DBWRAP_LOCK_ORDER_1, DBWRAP_FLAG_NONE);
     118           0 :         if (ctx->db == NULL) {
     119           0 :                 DEBUG(0, ("Unable to open idmap_tdb2 database '%s'\n",
     120             :                           db_path));
     121           0 :                 TALLOC_FREE(db_path);
     122           0 :                 return NT_STATUS_UNSUCCESSFUL;
     123             :         }
     124           0 :         TALLOC_FREE(db_path);
     125             : 
     126           0 :         return idmap_tdb2_init_hwm(dom);
     127             : }
     128             : 
     129             : /**
     130             :  * store a mapping in the database.
     131             :  */
     132             : 
     133             : struct idmap_tdb2_set_mapping_context {
     134             :         const char *ksidstr;
     135             :         const char *kidstr;
     136             : };
     137             : 
     138           0 : static NTSTATUS idmap_tdb2_set_mapping_action(struct db_context *db,
     139             :                                               void *private_data)
     140             : {
     141             :         TDB_DATA data;
     142             :         NTSTATUS ret;
     143             :         struct idmap_tdb2_set_mapping_context *state;
     144           0 :         TALLOC_CTX *tmp_ctx = talloc_stackframe();
     145             : 
     146           0 :         state = (struct idmap_tdb2_set_mapping_context *)private_data;
     147             : 
     148           0 :         DEBUG(10, ("Storing %s <-> %s map\n", state->ksidstr, state->kidstr));
     149             : 
     150             :         /* check whether sid mapping is already present in db */
     151           0 :         ret = dbwrap_fetch_bystring(db, tmp_ctx, state->ksidstr, &data);
     152           0 :         if (NT_STATUS_IS_OK(ret)) {
     153           0 :                 ret = NT_STATUS_OBJECT_NAME_COLLISION;
     154           0 :                 goto done;
     155             :         }
     156             : 
     157           0 :         ret = dbwrap_store_bystring(db, state->ksidstr,
     158             :                                     string_term_tdb_data(state->kidstr),
     159             :                                     TDB_INSERT);
     160           0 :         if (!NT_STATUS_IS_OK(ret)) {
     161           0 :                 DEBUG(0, ("Error storing SID -> ID: %s\n", nt_errstr(ret)));
     162           0 :                 goto done;
     163             :         }
     164             : 
     165           0 :         ret = dbwrap_store_bystring(db, state->kidstr,
     166             :                                     string_term_tdb_data(state->ksidstr),
     167             :                                     TDB_INSERT);
     168           0 :         if (!NT_STATUS_IS_OK(ret)) {
     169           0 :                 DEBUG(0, ("Error storing ID -> SID: %s\n", nt_errstr(ret)));
     170             :                 /* try to remove the previous stored SID -> ID map */
     171           0 :                 dbwrap_delete_bystring(db, state->ksidstr);
     172           0 :                 goto done;
     173             :         }
     174             : 
     175           0 :         DEBUG(10,("Stored %s <-> %s\n", state->ksidstr, state->kidstr));
     176             : 
     177           0 : done:
     178           0 :         talloc_free(tmp_ctx);
     179           0 :         return ret;
     180             : }
     181             : 
     182           0 : static NTSTATUS idmap_tdb2_set_mapping(struct idmap_domain *dom, const struct id_map *map)
     183             : {
     184             :         struct idmap_tdb2_context *ctx;
     185             :         NTSTATUS ret;
     186             :         char *kidstr;
     187             :         struct dom_sid_buf sid_str;
     188             :         struct idmap_tdb_common_context *commonctx;
     189             :         struct idmap_tdb2_set_mapping_context state;
     190             : 
     191           0 :         if (!map || !map->sid) {
     192           0 :                 return NT_STATUS_INVALID_PARAMETER;
     193             :         }
     194             : 
     195           0 :         kidstr = NULL;
     196             : 
     197             :         /* TODO: should we filter a set_mapping using low/high filters ? */
     198             : 
     199           0 :         commonctx = talloc_get_type(dom->private_data,
     200             :                                     struct idmap_tdb_common_context);
     201             : 
     202           0 :         ctx = talloc_get_type(commonctx->private_data,
     203             :                               struct idmap_tdb2_context);
     204             : 
     205           0 :         switch (map->xid.type) {
     206             : 
     207           0 :         case ID_TYPE_UID:
     208           0 :                 kidstr = talloc_asprintf(ctx, "UID %lu", (unsigned long)map->xid.id);
     209           0 :                 break;
     210             : 
     211           0 :         case ID_TYPE_GID:
     212           0 :                 kidstr = talloc_asprintf(ctx, "GID %lu", (unsigned long)map->xid.id);
     213           0 :                 break;
     214             : 
     215           0 :         default:
     216           0 :                 DEBUG(2, ("INVALID unix ID type: 0x02%x\n", map->xid.type));
     217           0 :                 return NT_STATUS_INVALID_PARAMETER;
     218             :         }
     219             : 
     220           0 :         if (kidstr == NULL) {
     221           0 :                 DEBUG(0, ("ERROR: Out of memory!\n"));
     222           0 :                 ret = NT_STATUS_NO_MEMORY;
     223           0 :                 goto done;
     224             :         }
     225             : 
     226           0 :         state.ksidstr = dom_sid_str_buf(map->sid, &sid_str);
     227           0 :         state.kidstr = kidstr;
     228             : 
     229           0 :         ret = dbwrap_trans_do(commonctx->db, idmap_tdb2_set_mapping_action,
     230             :                               &state);
     231             : 
     232           0 : done:
     233           0 :         talloc_free(kidstr);
     234           0 :         return ret;
     235             : }
     236             : 
     237             : /*
     238             :   run a script to perform a mapping
     239             : 
     240             :   The script should the following command lines:
     241             : 
     242             :       SIDTOID S-1-xxxx
     243             :       IDTOSID UID xxxx
     244             :       IDTOSID GID xxxx
     245             : 
     246             :   and should return one of the following as a single line of text
     247             :      UID:xxxx
     248             :      GID:xxxx
     249             :      SID:xxxx
     250             :      ERR:xxxx
     251             :  */
     252             : static NTSTATUS idmap_tdb2_script(struct idmap_tdb2_context *ctx,
     253             :                                   struct id_map *map, const char *fmt, ...)
     254             :                                   PRINTF_ATTRIBUTE(3,4);
     255             : 
     256           0 : static NTSTATUS idmap_tdb2_script(struct idmap_tdb2_context *ctx, struct id_map *map,
     257             :                                   const char *fmt, ...)
     258             : {
     259             :         va_list ap;
     260             :         char *cmd;
     261             :         FILE *p;
     262             :         char line[64];
     263             :         unsigned long v;
     264             : 
     265           0 :         cmd = talloc_asprintf(ctx, "%s ", ctx->script);
     266           0 :         NT_STATUS_HAVE_NO_MEMORY(cmd);
     267             : 
     268           0 :         va_start(ap, fmt);
     269           0 :         cmd = talloc_vasprintf_append(cmd, fmt, ap);
     270           0 :         va_end(ap);
     271           0 :         NT_STATUS_HAVE_NO_MEMORY(cmd);
     272             : 
     273           0 :         p = popen(cmd, "r");
     274           0 :         talloc_free(cmd);
     275           0 :         if (p == NULL) {
     276           0 :                 return NT_STATUS_NONE_MAPPED;
     277             :         }
     278             : 
     279           0 :         if (fgets(line, sizeof(line)-1, p) == NULL) {
     280           0 :                 pclose(p);
     281           0 :                 return NT_STATUS_NONE_MAPPED;
     282             :         }
     283           0 :         pclose(p);
     284             : 
     285           0 :         DEBUG(10,("idmap script gave: %s\n", line));
     286             : 
     287           0 :         if (sscanf(line, "UID:%lu", &v) == 1) {
     288           0 :                 map->xid.id   = v;
     289           0 :                 map->xid.type = ID_TYPE_UID;
     290           0 :         } else if (sscanf(line, "GID:%lu", &v) == 1) {
     291           0 :                 map->xid.id   = v;
     292           0 :                 map->xid.type = ID_TYPE_GID;
     293           0 :         } else if (strncmp(line, "SID:S-", 6) == 0) {
     294           0 :                 if (!string_to_sid(map->sid, &line[4])) {
     295           0 :                         DEBUG(0,("Bad SID in '%s' from idmap script %s\n",
     296             :                                  line, ctx->script));
     297           0 :                         return NT_STATUS_NONE_MAPPED;
     298             :                 }
     299             :         } else {
     300           0 :                 DEBUG(0,("Bad reply '%s' from idmap script %s\n",
     301             :                          line, ctx->script));
     302           0 :                 return NT_STATUS_NONE_MAPPED;
     303             :         }
     304             : 
     305           0 :         return NT_STATUS_OK;
     306             : }
     307             : 
     308             : 
     309             : 
     310             : /*
     311             :   Single id to sid lookup function.
     312             : */
     313           0 : static NTSTATUS idmap_tdb2_id_to_sid(struct idmap_domain *dom, struct id_map *map)
     314             : {
     315             :         NTSTATUS ret;
     316             :         TDB_DATA data;
     317             :         char *keystr;
     318             :         NTSTATUS status;
     319             :         struct idmap_tdb_common_context *commonctx;
     320             :         struct idmap_tdb2_context *ctx;
     321             : 
     322             : 
     323           0 :         if (!dom || !map) {
     324           0 :                 return NT_STATUS_INVALID_PARAMETER;
     325             :         }
     326             : 
     327           0 :         status = idmap_tdb2_open_db(dom);
     328           0 :         NT_STATUS_NOT_OK_RETURN(status);
     329             : 
     330           0 :         commonctx = talloc_get_type(dom->private_data,
     331             :                                     struct idmap_tdb_common_context);
     332             : 
     333           0 :         ctx = talloc_get_type(commonctx->private_data,
     334             :                               struct idmap_tdb2_context);
     335             : 
     336             :         /* apply filters before checking */
     337           0 :         if (!idmap_unix_id_is_in_range(map->xid.id, dom)) {
     338           0 :                 DEBUG(5, ("Requested id (%u) out of range (%u - %u). Filtered!\n",
     339             :                                 map->xid.id, dom->low_id, dom->high_id));
     340           0 :                 return NT_STATUS_NONE_MAPPED;
     341             :         }
     342             : 
     343           0 :         switch (map->xid.type) {
     344             : 
     345           0 :         case ID_TYPE_UID:
     346           0 :                 keystr = talloc_asprintf(ctx, "UID %lu", (unsigned long)map->xid.id);
     347           0 :                 break;
     348             : 
     349           0 :         case ID_TYPE_GID:
     350           0 :                 keystr = talloc_asprintf(ctx, "GID %lu", (unsigned long)map->xid.id);
     351           0 :                 break;
     352             : 
     353           0 :         default:
     354           0 :                 DEBUG(2, ("INVALID unix ID type: 0x02%x\n", map->xid.type));
     355           0 :                 return NT_STATUS_INVALID_PARAMETER;
     356             :         }
     357             : 
     358           0 :         if (keystr == NULL) {
     359           0 :                 DEBUG(0, ("Out of memory!\n"));
     360           0 :                 ret = NT_STATUS_NO_MEMORY;
     361           0 :                 goto done;
     362             :         }
     363             : 
     364           0 :         DEBUG(10,("Fetching record %s\n", keystr));
     365             : 
     366             :         /* Check if the mapping exists */
     367           0 :         status = dbwrap_fetch_bystring(commonctx->db, keystr, keystr, &data);
     368             : 
     369           0 :         if (!NT_STATUS_IS_OK(status)) {
     370             :                 struct dom_sid_buf sidstr;
     371             :                 struct idmap_tdb2_set_mapping_context store_state;
     372             : 
     373           0 :                 DEBUG(10,("Record %s not found\n", keystr));
     374           0 :                 if (ctx->script == NULL) {
     375           0 :                         ret = NT_STATUS_NONE_MAPPED;
     376           0 :                         goto done;
     377             :                 }
     378             : 
     379           0 :                 ret = idmap_tdb2_script(ctx, map, "IDTOSID %s", keystr);
     380           0 :                 if (!NT_STATUS_IS_OK(ret)) {
     381           0 :                         goto done;
     382             :                 }
     383             : 
     384           0 :                 store_state.ksidstr = dom_sid_str_buf(map->sid, &sidstr);
     385           0 :                 store_state.kidstr = keystr;
     386             : 
     387           0 :                 ret = dbwrap_trans_do(commonctx->db,
     388             :                                       idmap_tdb2_set_mapping_action,
     389             :                                       &store_state);
     390           0 :                 goto done;
     391             :         }
     392             : 
     393           0 :         if (!string_to_sid(map->sid, (const char *)data.dptr)) {
     394           0 :                 DEBUG(10,("INVALID SID (%s) in record %s\n",
     395             :                         (const char *)data.dptr, keystr));
     396           0 :                 ret = NT_STATUS_INTERNAL_DB_ERROR;
     397           0 :                 goto done;
     398             :         }
     399             : 
     400           0 :         DEBUG(10,("Found record %s -> %s\n", keystr, (const char *)data.dptr));
     401           0 :         ret = NT_STATUS_OK;
     402             : 
     403           0 : done:
     404           0 :         talloc_free(keystr);
     405           0 :         return ret;
     406             : }
     407             : 
     408             : 
     409             : /*
     410             :  Single sid to id lookup function.
     411             : */
     412           0 : static NTSTATUS idmap_tdb2_sid_to_id(struct idmap_domain *dom, struct id_map *map)
     413             : {
     414             :         NTSTATUS ret;
     415             :         TDB_DATA data;
     416             :         struct dom_sid_buf keystr;
     417           0 :         unsigned long rec_id = 0;
     418             :         struct idmap_tdb_common_context *commonctx;
     419             :         struct idmap_tdb2_context *ctx;
     420           0 :         TALLOC_CTX *tmp_ctx = talloc_stackframe();
     421             : 
     422           0 :         ret = idmap_tdb2_open_db(dom);
     423           0 :         NT_STATUS_NOT_OK_RETURN(ret);
     424             : 
     425           0 :         commonctx = talloc_get_type(dom->private_data,
     426             :                                     struct idmap_tdb_common_context);
     427             : 
     428           0 :         ctx = talloc_get_type(commonctx->private_data,
     429             :                               struct idmap_tdb2_context);
     430             : 
     431           0 :         dom_sid_str_buf(map->sid, &keystr);
     432             : 
     433           0 :         DEBUG(10, ("Fetching record %s\n", keystr.buf));
     434             : 
     435             :         /* Check if sid is present in database */
     436           0 :         ret = dbwrap_fetch_bystring(commonctx->db, tmp_ctx, keystr.buf, &data);
     437           0 :         if (!NT_STATUS_IS_OK(ret)) {
     438             :                 char *idstr;
     439             :                 struct idmap_tdb2_set_mapping_context store_state;
     440             : 
     441           0 :                 DBG_DEBUG("Record %s not found\n", keystr.buf);
     442             : 
     443           0 :                 if (ctx->script == NULL) {
     444           0 :                         ret = NT_STATUS_NONE_MAPPED;
     445           0 :                         goto done;
     446             :                 }
     447             : 
     448           0 :                 ret = idmap_tdb2_script(ctx, map, "SIDTOID %s", keystr.buf);
     449           0 :                 if (!NT_STATUS_IS_OK(ret)) {
     450           0 :                         goto done;
     451             :                 }
     452             : 
     453             :                 /* apply filters before returning result */
     454           0 :                 if (!idmap_unix_id_is_in_range(map->xid.id, dom)) {
     455           0 :                         DEBUG(5, ("Script returned id (%u) out of range "
     456             :                                   "(%u - %u). Filtered!\n",
     457             :                                   map->xid.id, dom->low_id, dom->high_id));
     458           0 :                         ret = NT_STATUS_NONE_MAPPED;
     459           0 :                         goto done;
     460             :                 }
     461             : 
     462           0 :                 idstr = talloc_asprintf(tmp_ctx, "%cID %lu",
     463           0 :                                         map->xid.type == ID_TYPE_UID?'U':'G',
     464           0 :                                         (unsigned long)map->xid.id);
     465           0 :                 if (idstr == NULL) {
     466           0 :                         ret = NT_STATUS_NO_MEMORY;
     467           0 :                         goto done;
     468             :                 }
     469             : 
     470           0 :                 store_state.ksidstr = keystr.buf;
     471           0 :                 store_state.kidstr = idstr;
     472             : 
     473           0 :                 ret = dbwrap_trans_do(commonctx->db,
     474             :                                       idmap_tdb2_set_mapping_action,
     475             :                                       &store_state);
     476           0 :                 goto done;
     477             :         }
     478             : 
     479             :         /* What type of record is this ? */
     480           0 :         if (sscanf((const char *)data.dptr, "UID %lu", &rec_id) == 1) { /* Try a UID record. */
     481           0 :                 map->xid.id = rec_id;
     482           0 :                 map->xid.type = ID_TYPE_UID;
     483           0 :                 DBG_DEBUG("Found uid record %s -> %s \n",
     484             :                           keystr.buf,
     485             :                           (const char *)data.dptr );
     486           0 :                 ret = NT_STATUS_OK;
     487             : 
     488           0 :         } else if (sscanf((const char *)data.dptr, "GID %lu", &rec_id) == 1) { /* Try a GID record. */
     489           0 :                 map->xid.id = rec_id;
     490           0 :                 map->xid.type = ID_TYPE_GID;
     491           0 :                 DBG_DEBUG("Found gid record %s -> %s \n",
     492             :                           keystr.buf,
     493             :                           (const char *)data.dptr );
     494           0 :                 ret = NT_STATUS_OK;
     495             : 
     496             :         } else { /* Unknown record type ! */
     497           0 :                 DBG_WARNING("Found INVALID record %s -> %s\n",
     498             :                             keystr.buf,
     499             :                             (const char *)data.dptr);
     500           0 :                 ret = NT_STATUS_INTERNAL_DB_ERROR;
     501           0 :                 goto done;
     502             :         }
     503             : 
     504             :         /* apply filters before returning result */
     505           0 :         if (!idmap_unix_id_is_in_range(map->xid.id, dom)) {
     506           0 :                 DEBUG(5, ("Requested id (%u) out of range (%u - %u). Filtered!\n",
     507             :                                 map->xid.id, dom->low_id, dom->high_id));
     508           0 :                 ret = NT_STATUS_NONE_MAPPED;
     509             :         }
     510             : 
     511           0 : done:
     512           0 :         talloc_free(tmp_ctx);
     513           0 :         return ret;
     514             : }
     515             : 
     516             : /*
     517             :   Initialise idmap database.
     518             : */
     519           0 : static NTSTATUS idmap_tdb2_db_init(struct idmap_domain *dom)
     520             : {
     521             :         NTSTATUS ret;
     522             :         struct idmap_tdb_common_context *commonctx;
     523             :         struct idmap_tdb2_context *ctx;
     524           0 :         const char * idmap_script = NULL;
     525           0 :         const char *ctx_script = NULL;
     526             : 
     527           0 :         commonctx = talloc_zero(dom, struct idmap_tdb_common_context);
     528           0 :         if(!commonctx) {
     529           0 :                 DEBUG(0, ("Out of memory!\n"));
     530           0 :                 return NT_STATUS_NO_MEMORY;
     531             :         }
     532             : 
     533           0 :         commonctx->rw_ops = talloc_zero(commonctx, struct idmap_rw_ops);
     534           0 :         if (commonctx->rw_ops == NULL) {
     535           0 :                 DEBUG(0, ("Out of memory!\n"));
     536           0 :                 ret = NT_STATUS_NO_MEMORY;
     537           0 :                 goto failed;
     538             :         }
     539             : 
     540           0 :         ctx = talloc_zero(commonctx, struct idmap_tdb2_context);
     541           0 :         if (!ctx) {
     542           0 :                 DEBUG(0, ("Out of memory!\n"));
     543           0 :                 ret = NT_STATUS_NO_MEMORY;
     544           0 :                 goto failed;
     545             :         }
     546             : 
     547           0 :         ctx_script = idmap_config_const_string(dom->name, "script", NULL);
     548             : 
     549           0 :         idmap_script = lp_parm_const_string(-1, "idmap", "script", NULL);
     550           0 :         if (idmap_script != NULL) {
     551           0 :                 DEBUG(0, ("Warning: 'idmap:script' is deprecated. "
     552             :                           " Please use 'idmap config * : script' instead!\n"));
     553             :         }
     554             : 
     555           0 :         if (strequal(dom->name, "*") && ctx_script == NULL) {
     556             :                 /* fall back to idmap:script for backwards compatibility */
     557           0 :                 ctx_script = idmap_script;
     558             :         }
     559             : 
     560           0 :         if (ctx_script) {
     561           0 :                 DEBUG(1, ("using idmap script '%s'\n", ctx_script));
     562             :                 /*
     563             :                  * We must ensure this memory is owned by ctx.
     564             :                  * The ctx_script const pointer is a pointer into
     565             :                  * the config file data and may become invalid
     566             :                  * on config file reload. BUG: 13956
     567             :                  */
     568           0 :                 ctx->script = talloc_strdup(ctx, ctx_script);
     569           0 :                 if (ctx->script == NULL) {
     570           0 :                         ret = NT_STATUS_NO_MEMORY;
     571           0 :                         goto failed;
     572             :                 }
     573             :         }
     574             : 
     575           0 :         commonctx->max_id = dom->high_id;
     576           0 :         commonctx->hwmkey_uid = HWM_USER;
     577           0 :         commonctx->hwmkey_gid = HWM_GROUP;
     578             : 
     579           0 :         commonctx->sid_to_unixid_fn = idmap_tdb2_sid_to_id;
     580           0 :         commonctx->unixid_to_sid_fn = idmap_tdb2_id_to_sid;
     581             : 
     582           0 :         commonctx->rw_ops->get_new_id = idmap_tdb_common_get_new_id;
     583           0 :         commonctx->rw_ops->set_mapping = idmap_tdb2_set_mapping;
     584             : 
     585           0 :         commonctx->private_data = ctx;
     586           0 :         dom->private_data = commonctx;
     587             : 
     588           0 :         ret = idmap_tdb2_open_db(dom);
     589           0 :         if (!NT_STATUS_IS_OK(ret)) {
     590           0 :                 goto failed;
     591             :         }
     592             : 
     593           0 :         return NT_STATUS_OK;
     594             : 
     595           0 : failed:
     596           0 :         talloc_free(commonctx);
     597           0 :         return ret;
     598             : }
     599             : 
     600             : 
     601             : static const struct idmap_methods db_methods = {
     602             :         .init            = idmap_tdb2_db_init,
     603             :         .unixids_to_sids = idmap_tdb_common_unixids_to_sids,
     604             :         .sids_to_unixids = idmap_tdb_common_sids_to_unixids,
     605             :         .allocate_id     = idmap_tdb_common_get_new_id
     606             : };
     607             : 
     608             : static_decl_idmap;
     609           0 : NTSTATUS idmap_tdb2_init(TALLOC_CTX *ctx)
     610             : {
     611           0 :         return smb_register_idmap(SMB_IDMAP_INTERFACE_VERSION, "tdb2", &db_methods);
     612             : }

Generated by: LCOV version 1.14